// Plan creates an execution plan for the given SelectStatement and returns an Executor. func (q *QueryExecutor) plan(stmt *sql.SelectStatement, chunkSize int) (*Executor, error) { shards := map[uint64]meta.ShardInfo{} // Shards requiring mappers. // Replace instances of "now()" with the current time, and check the resultant times. stmt.Condition = sql.Reduce(stmt.Condition, &sql.NowValuer{Now: time.Now().UTC()}) tmin, tmax := sql.TimeRange(stmt.Condition) if tmax.IsZero() { tmax = time.Now() } if tmin.IsZero() { tmin = time.Unix(0, 0) } for _, src := range stmt.Sources { mm, ok := src.(*sql.Conversation) if !ok { return nil, fmt.Errorf("invalid source type: %#v", src) } // Build the set of target shards. Using shard IDs as keys ensures each shard ID // occurs only once. shardGroups, err := q.MetaStore.ShardGroupsByTimeRange(mm.Database, mm.RetentionPolicy, tmin, tmax) if err != nil { return nil, err } for _, g := range shardGroups { for _, sh := range g.Shards { shards[sh.ID] = sh } } } // Build the Mappers, one per shard. mappers := []Mapper{} for _, sh := range shards { m, err := q.ShardMapper.CreateMapper(sh, stmt.String(), chunkSize) if err != nil { return nil, err } if m == nil { // No data for this shard, skip it. continue } mappers = append(mappers, m) } executor := NewExecutor(stmt, mappers, chunkSize) return executor, nil }
// createTagSetsAndFields returns the tagsets and various fields given a measurement and // SELECT statement. func createTagSetsAndFields(c *Conversation, stmt *sql.SelectStatement) (*tagSetsAndFields, error) { _, tagKeys, err := stmt.Dimensions.Normalize() if err != nil { return nil, err } sfs := newStringSet() sts := newStringSet() wfs := newStringSet() // Validate the fields and tags asked for exist and keep track of which are in the select vs the where for _, n := range stmt.NamesInSelect() { if c.HasField(n) { sfs.add(n) continue } if c.HasTagKey(n) { sts.add(n) tagKeys = append(tagKeys, n) } } for _, n := range stmt.NamesInWhere() { if n == "time" { continue } if c.HasField(n) { wfs.add(n) continue } } // Get the sorted unique tag sets for this statement. // tagSets, err := c.TagSets(stmt, tagKeys) // if err != nil { // return nil, err // } return &tagSetsAndFields{ // tagSets: tagSets, selectFields: sfs.list(), selectTags: sts.list(), whereFields: wfs.list(), }, nil }
// rewriteSelectStatement performs any necessary query re-writing. func (q *QueryExecutor) rewriteSelectStatement(stmt *sql.SelectStatement) (*sql.SelectStatement, error) { var err error // Expand regex expressions in the FROM clause. sources, err := q.expandSources(stmt.Sources) if err != nil { return nil, err } stmt.Sources = sources // Expand wildcards in the fields or GROUP BY. // if stmt.HasWildcard() { // stmt, err = q.expandWildcards(stmt) // if err != nil { // return nil, err // } // } // stmt.RewriteDistinct() return stmt, nil }