github.com/rohankumardubey/aresdb@v0.0.2-0.20190517170215-e54e3ca06b9c/query/aql.go (about)

     1  //  Copyright (c) 2017-2018 Uber Technologies, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package query
    16  
    17  import (
    18  	queryCom "github.com/uber/aresdb/query/common"
    19  	"github.com/uber/aresdb/query/expr"
    20  )
    21  
    22  // Ares only supports a subset of AQL; missing features are provided by Apollo.
    23  // See https://github.com/uber/aresdb/wiki/aql#notice
    24  
    25  // Dimension specifies a row level dimension for grouping by.
    26  type Dimension struct {
    27  	// Alias/name of the dimension, to be referenced by other dimensions and measures.
    28  	Alias string `json:"alias,omitempty"`
    29  	// The SQL expression for computing the dimension.
    30  	// Expr can be empty when TimeBucketizer is specified, which implies the
    31  	// designated time column from the main table is used as the expresssion.
    32  	Expr string `json:"sqlExpression"`
    33  	expr expr.Expr
    34  
    35  	// Decides how to bucketize a timestamp Dimension before grouping by.
    36  	// See https://github.com/uber/aresdb/wiki/aql#time_bucketizer
    37  	TimeBucketizer string `json:"timeBucketizer,omitempty"`
    38  
    39  	TimeUnit string `json:"timeUnit,omitempty"`
    40  
    41  	// Bucketizes numeric dimensions for integers and floating point numbers.
    42  	NumericBucketizer NumericBucketizerDef `json:"numericBucketizer,omitempty"`
    43  }
    44  
    45  // NumericBucketizerDef defines how numbers should be bucketized before being
    46  // grouped by as a dimension. The returned dimension is a string in the format
    47  // of `lower_bound`, representing `[lower_bound, uper_bound)`.
    48  type NumericBucketizerDef struct {
    49  	// Only one of the following field should be specified.
    50  
    51  	// Generates equal-width buckets. BucketWidth should be positive.
    52  	// The generated buckets are:
    53  	// ... [-2w, -w), [-w, 0), [0, w), [w, 2w) ...
    54  	BucketWidth float64 `json:"bucketWidth,omitempty"`
    55  
    56  	// Generates exponential/log buckets. LogBase should be positive.
    57  	// The generated buckets are:
    58  	// ... [pow(b, -2), pow(b, -1)), [pow(b, -1), 1), [1, pow(b, 1)), [pow(b, 1), pow(b, 2)) ...
    59  	LogBase float64 `json:"logBase,omitempty"`
    60  
    61  	// Generates a fixed number of buckets using the specified partitions.
    62  	// The numbers should be in sorted order. The generated buckets are:
    63  	// [-inf, p0), [p0, p1), [p1, p2), ... [pn-1, inf)
    64  	ManualPartitions []float64 `json:"manualPartitions,omitempty"`
    65  }
    66  
    67  // Measure specifies a group level aggregation measure.
    68  type Measure struct {
    69  	// Alias/name of the measure, to be referenced by other (derived) measures.
    70  	Alias string `json:"alias,omitempty"`
    71  	// The SQL expression for computing the measure.
    72  	Expr string `json:"sqlExpression"`
    73  	expr expr.Expr
    74  
    75  	// Row level filters to apply for this measure.
    76  	// The filters are ANDed togther.
    77  	Filters []string `json:"rowFilters,omitempty"`
    78  	filters []expr.Expr
    79  }
    80  
    81  // Join specifies a secondary table to be explicitly joined in the query.
    82  type Join struct {
    83  	// Name of the table to join against.
    84  	Table string `json:"table"`
    85  
    86  	// Alias for the table. Empty means the table name will be used as alias.
    87  	Alias string `json:"alias"`
    88  
    89  	// Condition expressions to be ANDed together for the join.
    90  	Conditions []string `json:"conditions"`
    91  	conditions []expr.Expr
    92  }
    93  
    94  // TimeFilter is a syntax sugar for specifying time range.
    95  type TimeFilter struct {
    96  	// A table time column in the format of column, or table_alias.column.
    97  	// When empty, it defaults to the designated time column of the main table.
    98  	Column string `json:"column"`
    99  
   100  	// The time specified in from and to are both inclusive.
   101  	// See https://github.com/uber/aresdb/wiki/aql#time_filter
   102  	From string `json:"from"`
   103  	To   string `json:"to"`
   104  }
   105  
   106  // SortField represents a field to sort results by.
   107  type SortField struct {
   108  	// Name or alias of the field
   109  	Name string `json:"name"`
   110  
   111  	// Order the column, will be asc or desc
   112  	Order string `json:"order"`
   113  }
   114  
   115  // AQLQuery specifies the query on top of tables.
   116  type AQLQuery struct {
   117  	// Name of the main table.
   118  	Table string `json:"table"`
   119  
   120  	// Foreign tables to be joined.
   121  	Joins []Join `json:"joins,omitempty"`
   122  
   123  	// Dimensions to group by on.
   124  	Dimensions []Dimension `json:"dimensions,omitempty"`
   125  
   126  	// Measures/metrics to report.
   127  	Measures []Measure `json:"measures"`
   128  
   129  	// Row level filters to apply for all measures. The filters are ANDed togther.
   130  	Filters []string `json:"rowFilters,omitempty"`
   131  	filters []expr.Expr
   132  
   133  	// Syntax sugar for specifying a time based range filter.
   134  	TimeFilter TimeFilter `json:"timeFilter,omitempty"`
   135  
   136  	// Additional supporting dimensions, these dimensions will not be grouped by,
   137  	// but they may be referenced in Dimensions, Measures, SupportingDimensions and SupportingMeasures.
   138  	SupportingDimensions []Dimension `json:"supportingDimensions,omitempty"`
   139  	// Additional supporting measures, these measures will not be reported,
   140  	// but they may be referenced in Measures and SupportingMeasures.
   141  	SupportingMeasures []Measure `json:"supportingMeasures,omitempty"`
   142  
   143  	// Timezone to use when converting timestamp to calendar time, specified as:
   144  	//   - -8:00
   145  	//   - GMT
   146  	//   - America/Los_Angeles
   147  	//   - timezone(city_id)
   148  	//   - region_timezone(city_id)
   149  	//   - mega_region_timezone(city_id)
   150  	//   - sub_region_timezone(city_id)
   151  	//   - country_timezone(city_id)
   152  	Timezone string `json:"timezone,omitempty"`
   153  
   154  	// This overrides "now" (in seconds)
   155  	Now int64 `json:"now,omitempty"`
   156  
   157  	// Limit is the max number of rows need to be return, and only used for non-aggregation
   158  	Limit int `json:"limit,omitempty"`
   159  
   160  	Sorts []SortField `json:"sorts, omitempty" yaml:"sorts"`
   161  
   162  	// SQLQuery
   163  	SQLQuery string `json:"sql, omitempty"`
   164  }
   165  
   166  // AQLRequest contains multiple of AQLQueries.
   167  type AQLRequest struct {
   168  	Queries []AQLQuery `json:"queries"`
   169  }
   170  
   171  // AQLResponse contains results for multiple AQLQueries.
   172  type AQLResponse struct {
   173  	Results      []queryCom.AQLQueryResult `json:"results"`
   174  	Errors       []error                   `json:"errors,omitempty"`
   175  	QueryContext []*AQLQueryContext        `json:"context,omitempty"`
   176  }
   177  
   178  func (d Dimension) isTimeDimension() bool {
   179  	return d.TimeBucketizer != "" || d.TimeUnit != ""
   180  }