func containsArithmeticOperators(query *parser.SelectQuery) bool { for _, column := range query.GetColumnNames() { if column.Type == parser.ValueExpression { return true } } return false }
func (self *QueryEngine) executeCountQueryWithGroupBy(query *parser.SelectQuery, yield func(*protocol.Series) error) error { self.aggregateYield = yield duration, err := query.GetGroupByClause().GetGroupByTime() if err != nil { return err } self.isAggregateQuery = true self.duration = duration self.aggregators = []Aggregator{} for _, value := range query.GetColumnNames() { if !value.IsFunctionCall() { continue } lowerCaseName := strings.ToLower(value.Name) initializer := registeredAggregators[lowerCaseName] if initializer == nil { return common.NewQueryError(common.InvalidArgument, fmt.Sprintf("Unknown function %s", value.Name)) } aggregator, err := initializer(query, value, query.GetGroupByClause().FillValue) if err != nil { return common.NewQueryError(common.InvalidArgument, fmt.Sprintf("%s", err)) } self.aggregators = append(self.aggregators, aggregator) } for _, elem := range query.GetGroupByClause().Elems { if elem.IsFunctionCall() { continue } self.elems = append(self.elems, elem) } self.fillWithZero = query.GetGroupByClause().FillWithZero // This is a special case for issue #426. If the start time is // specified and there's a group by clause and fill with zero, then // we need to fill the entire range from start time to end time if query.IsStartTimeSpecified() && self.duration != nil && self.fillWithZero { self.startTimeSpecified = true self.startTime = query.GetStartTime().Truncate(*self.duration).UnixNano() / 1000 self.endTime = query.GetEndTime().Truncate(*self.duration).UnixNano() / 1000 } self.initializeFields() err = self.distributeQuery(query, func(series *protocol.Series) error { if len(series.Points) == 0 { return nil } return self.aggregateValuesForSeries(series) }) return err }
func (self *QueryEngine) executeArithmeticQuery(query *parser.SelectQuery, yield func(*protocol.Series) error) error { names := map[string]*parser.Value{} for idx, v := range query.GetColumnNames() { switch v.Type { case parser.ValueSimpleName: names[v.Name] = v case parser.ValueFunctionCall: names[v.Name] = v case parser.ValueExpression: if v.Alias != "" { names[v.Alias] = v } else { names["expr"+strconv.Itoa(idx)] = v } } } return self.distributeQuery(query, func(series *protocol.Series) error { if len(series.Points) == 0 { yield(series) return nil } newSeries := &protocol.Series{ Name: series.Name, } // create the new column names for name := range names { newSeries.Fields = append(newSeries.Fields, name) } for _, point := range series.Points { newPoint := &protocol.Point{ Timestamp: point.Timestamp, SequenceNumber: point.SequenceNumber, } for _, field := range newSeries.Fields { value := names[field] v, err := GetValue(value, series.Fields, point) if err != nil { log.Error("Error in arithmetic computation: %s", err) return err } newPoint.Values = append(newPoint.Values, v) } newSeries.Points = append(newSeries.Points, newPoint) } yield(newSeries) return nil }) }
func NewAggregatorEngine(query *parser.SelectQuery, next Processor) (*AggregatorEngine, error) { ae := &AggregatorEngine{ next: next, seriesStates: make(map[string]*SeriesState), ascending: query.Ascending, } var err error ae.duration, ae.irregularInterval, err = query.GetGroupByClause().GetGroupByTime() if err != nil { return nil, err } ae.aggregators = []Aggregator{} for _, value := range query.GetColumnNames() { if !value.IsFunctionCall() { continue } lowerCaseName := strings.ToLower(value.Name) initializer := registeredAggregators[lowerCaseName] if initializer == nil { return nil, common.NewQueryError(common.InvalidArgument, fmt.Sprintf("Unknown function %s", value.Name)) } aggregator, err := initializer(query, value, query.GetGroupByClause().FillValue) if err != nil { return nil, common.NewQueryError(common.InvalidArgument, fmt.Sprintf("%s", err)) } ae.aggregators = append(ae.aggregators, aggregator) } for _, elem := range query.GetGroupByClause().Elems { if elem.IsFunctionCall() { continue } ae.elems = append(ae.elems, elem) } ae.isFillQuery = query.GetGroupByClause().FillWithZero // This is a special case for issue #426. If the start time is // specified and there's a group by clause and fill with zero, then // we need to fill the entire range from start time to end time if query.IsStartTimeSpecified() && ae.duration != nil && ae.isFillQuery { ae.startTimeSpecified = true ae.startTime = query.GetStartTime().Truncate(*ae.duration).UnixNano() / 1000 ae.endTime = query.GetEndTime().Truncate(*ae.duration).UnixNano() / 1000 } ae.initializeFields() return ae, nil }
func (self *QueryEngine) executeCountQueryWithGroupBy(query *parser.SelectQuery, yield func(*protocol.Series) error) error { self.aggregateYield = yield duration, err := query.GetGroupByClause().GetGroupByTime() if err != nil { return err } self.isAggregateQuery = true self.duration = duration self.aggregators = []Aggregator{} for _, value := range query.GetColumnNames() { if !value.IsFunctionCall() { continue } lowerCaseName := strings.ToLower(value.Name) initializer := registeredAggregators[lowerCaseName] if initializer == nil { return common.NewQueryError(common.InvalidArgument, fmt.Sprintf("Unknown function %s", value.Name)) } aggregator, err := initializer(query, value, query.GetGroupByClause().FillValue) if err != nil { return common.NewQueryError(common.InvalidArgument, fmt.Sprintf("%s", err)) } self.aggregators = append(self.aggregators, aggregator) } for _, elem := range query.GetGroupByClause().Elems { if elem.IsFunctionCall() { continue } self.elems = append(self.elems, elem) } self.fillWithZero = query.GetGroupByClause().FillWithZero self.initializeFields() err = self.distributeQuery(query, func(series *protocol.Series) error { if len(series.Points) == 0 { return nil } return self.aggregateValuesForSeries(series) }) return err }
func NewArithmeticEngine(query *parser.SelectQuery, next Processor) (*ArithmeticEngine, error) { names := map[string]*parser.Value{} for idx, v := range query.GetColumnNames() { switch v.Type { case parser.ValueSimpleName: names[v.Name] = v case parser.ValueFunctionCall: names[v.Name] = v case parser.ValueExpression: if v.Alias != "" { names[v.Alias] = v } else { names["expr"+strconv.Itoa(idx)] = v } } } return &ArithmeticEngine{ next: next, names: names, }, nil }