func Filter(query *parser.SelectQuery, series *protocol.Series) (*protocol.Series, error) { if query.GetWhereCondition() == nil { return series, nil } columns := map[string]struct{}{} if query.GetFromClause().Type == parser.FromClauseInnerJoin { outer: for t, cs := range query.GetResultColumns() { for _, c := range cs { // if this is a wildcard select, then drop all columns and // just use '*' if c == "*" { columns = make(map[string]struct{}, 1) columns[c] = struct{}{} break outer } columns[t.Name+"."+c] = struct{}{} } } } else { for _, cs := range query.GetResultColumns() { for _, c := range cs { columns[c] = struct{}{} } } } points := series.Points series.Points = nil for _, point := range points { ok, err := matches(query.GetWhereCondition(), series.Fields, point) if err != nil { return nil, err } if ok { filterColumns(columns, series.Fields, point) series.Points = append(series.Points, point) } } if _, ok := columns["*"]; !ok { newFields := []string{} for _, f := range series.Fields { if _, ok := columns[f]; !ok { continue } newFields = append(newFields, f) } series.Fields = newFields } return series, nil }
func (s *RaftServer) runContinuousQuery(db string, query *parser.SelectQuery, start time.Time, end time.Time) { adminName := s.clusterConfig.GetClusterAdmins()[0] clusterAdmin := s.clusterConfig.GetClusterAdmin(adminName) intoClause := query.GetIntoClause() targetName := intoClause.Target.Name queryString := query.GetQueryStringWithTimesAndNoIntoClause(start, end) writer := NewContinuousQueryWriter(s.coordinator, db, targetName, query) s.coordinator.RunQuery(clusterAdmin, db, queryString, writer) }
func NewQueryEngine(next Processor, query *parser.SelectQuery, shards []uint32) (Processor, error) { limit := query.Limit var engine Processor = NewPassthroughEngineWithLimit(next, 1, limit) var err error if query.HasAggregates() { engine, err = NewAggregatorEngine(query, engine) } else if query.ContainsArithmeticOperators() { engine, err = NewArithmeticEngine(query, engine) } fromClause := query.GetFromClause() switch fromClause.Type { case parser.FromClauseInnerJoin: engine = NewJoinEngine(shards, query, engine) case parser.FromClauseMerge: tables := make([]string, len(fromClause.Names)) for i, name := range fromClause.Names { tables[i] = name.Name.Name } engine = NewMergeEngine(shards, query.Ascending, engine) case parser.FromClauseMergeRegex: // At this point the regex should be expanded to the list of // tables that will be queries panic("QueryEngine cannot be called with merge function") } if err != nil { return nil, err } return engine, nil }
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 }
// Create and return a new JoinEngine given the shards that will be // processed and the query func NewJoinEngine(shards []uint32, query *parser.SelectQuery, next Processor) Processor { tableNames := query.GetFromClause().Names name := query.GetFromClause().GetString() log4go.Debug("NewJoinEngine: shards=%v, query=%s, next=%s, tableNames=%v, name=%s", shards, query.GetQueryString(), next.Name(), tableNames, name) joinEngine := &JoinEngine{ next: next, name: name, tablesState: make([]joinEngineState, len(tableNames)), tableIdx: make(map[string]int, len(tableNames)), query: query, pts: 0, } for i, tn := range tableNames { alias := tn.GetAlias() joinEngine.tablesState[i] = joinEngineState{} joinEngine.tableIdx[alias] = i } mergeEngine := NewCommonMergeEngine(shards, false, query.Ascending, joinEngine) return mergeEngine }
func NewFilteringEngine(query *parser.SelectQuery, processor Processor) *FilteringEngine { shouldFilter := query.GetWhereCondition() != nil return &FilteringEngine{query, processor, shouldFilter} }
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 }