// expandWildcards returns a new SelectStatement with wildcards expanded // If only a `SELECT *` is present, without a `GROUP BY *`, both tags and fields expand in the SELECT // If a `SELECT *` and a `GROUP BY *` are both present, then only fiels are expanded in the `SELECT` and only // tags are expanded in the `GROUP BY` func (lm *SelectMapper) expandWildcards(stmt *influxql.SelectStatement) (*influxql.SelectStatement, error) { // If there are no wildcards in the statement, return it as-is. if !stmt.HasWildcard() { return stmt, nil } // Use sets to avoid duplicate field names. fieldSet := map[string]struct{}{} dimensionSet := map[string]struct{}{} var fields influxql.Fields var dimensions influxql.Dimensions // keep track of where the wildcards are in the select statement hasFieldWildcard := stmt.HasFieldWildcard() hasDimensionWildcard := stmt.HasDimensionWildcard() // Iterate measurements in the FROM clause getting the fields & dimensions for each. for _, src := range stmt.Sources { if m, ok := src.(*influxql.Measurement); ok { // Lookup the measurement in the database. mm := lm.shard.index.Measurement(m.Name) if mm == nil { // This shard have never received data for the measurement. No Mapper // required. return stmt, nil } // Get the fields for this measurement. for _, name := range mm.FieldNames() { if _, ok := fieldSet[name]; ok { continue } fieldSet[name] = struct{}{} fields = append(fields, &influxql.Field{Expr: &influxql.VarRef{Val: name}}) } // Add tags to fields if a field wildcard was provided and a dimension wildcard was not. if hasFieldWildcard && !hasDimensionWildcard { for _, t := range mm.TagKeys() { if _, ok := fieldSet[t]; ok { continue } fieldSet[t] = struct{}{} fields = append(fields, &influxql.Field{Expr: &influxql.VarRef{Val: t}}) } } // Get the dimensions for this measurement. if hasDimensionWildcard { for _, t := range mm.TagKeys() { if _, ok := dimensionSet[t]; ok { continue } dimensionSet[t] = struct{}{} dimensions = append(dimensions, &influxql.Dimension{Expr: &influxql.VarRef{Val: t}}) } } } } // Return a new SelectStatement with the wild cards rewritten. return stmt.RewriteWildcards(fields, dimensions), nil }