github.com/influxdata/influxdb/v2@v2.7.6/influxql/query/select.go (about)

     1  package query
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"io"
     7  	"sort"
     8  	"sync"
     9  	"time"
    10  
    11  	iql "github.com/influxdata/influxdb/v2/influxql"
    12  	"github.com/influxdata/influxdb/v2/influxql/query/internal/gota"
    13  	"github.com/influxdata/influxdb/v2/kit/platform"
    14  	"github.com/influxdata/influxql"
    15  	"golang.org/x/sync/errgroup"
    16  )
    17  
    18  var DefaultTypeMapper = influxql.MultiTypeMapper(
    19  	FunctionTypeMapper{},
    20  	MathTypeMapper{},
    21  )
    22  
    23  // SelectOptions are options that customize the select call.
    24  type SelectOptions struct {
    25  	// OrgID is the organization for which this query is being executed.
    26  	OrgID platform.ID
    27  
    28  	// Node to exclusively read from.
    29  	// If zero, all nodes are used.
    30  	NodeID uint64
    31  
    32  	// Maximum number of concurrent series.
    33  	MaxSeriesN int
    34  
    35  	// Maximum number of points to read from the query.
    36  	// This requires the passed in context to have a Monitor that is
    37  	// created using WithMonitor.
    38  	MaxPointN int
    39  
    40  	// Maximum number of buckets for a statement.
    41  	MaxBucketsN int
    42  
    43  	// StatisticsGatherer gathers metrics about the execution of the query.
    44  	StatisticsGatherer *iql.StatisticsGatherer
    45  }
    46  
    47  // ShardMapper retrieves and maps shards into an IteratorCreator that can later be
    48  // used for executing queries.
    49  type ShardMapper interface {
    50  	MapShards(ctx context.Context, sources influxql.Sources, t influxql.TimeRange, opt SelectOptions) (ShardGroup, error)
    51  }
    52  
    53  // TypeMapper maps a data type to the measurement and field.
    54  type TypeMapper interface {
    55  	MapType(ctx context.Context, m *influxql.Measurement, field string) influxql.DataType
    56  }
    57  
    58  // FieldMapper returns the data type for the field inside of the measurement.
    59  type FieldMapper interface {
    60  	TypeMapper
    61  	FieldDimensions(ctx context.Context, m *influxql.Measurement) (fields map[string]influxql.DataType, dimensions map[string]struct{}, err error)
    62  }
    63  
    64  // contextFieldMapper adapts a FieldMapper to an influxql.FieldMapper as
    65  // FieldMapper requires a context.Context and orgID
    66  type fieldMapperAdapter struct {
    67  	fm  FieldMapper
    68  	ctx context.Context
    69  }
    70  
    71  func newFieldMapperAdapter(fm FieldMapper, ctx context.Context) *fieldMapperAdapter {
    72  	return &fieldMapperAdapter{fm: fm, ctx: ctx}
    73  }
    74  
    75  func (c *fieldMapperAdapter) FieldDimensions(m *influxql.Measurement) (fields map[string]influxql.DataType, dimensions map[string]struct{}, err error) {
    76  	return c.fm.FieldDimensions(c.ctx, m)
    77  }
    78  
    79  func (c *fieldMapperAdapter) MapType(measurement *influxql.Measurement, field string) influxql.DataType {
    80  	return c.fm.MapType(c.ctx, measurement, field)
    81  }
    82  
    83  // ShardGroup represents a shard or a collection of shards that can be accessed
    84  // for creating iterators.
    85  // When creating iterators, the resource used for reading the iterators should be
    86  // separate from the resource used to map the shards. When the ShardGroup is closed,
    87  // it should not close any resources associated with the created Iterator. Those
    88  // resources belong to the Iterator and will be closed when the Iterator itself is
    89  // closed.
    90  // The query engine operates under this assumption and will close the shard group
    91  // after creating the iterators, but before the iterators are actually read.
    92  type ShardGroup interface {
    93  	IteratorCreator
    94  	FieldMapper
    95  	io.Closer
    96  }
    97  
    98  // Select is a prepared statement that is ready to be executed.
    99  type PreparedStatement interface {
   100  	// Select creates the Iterators that will be used to read the query.
   101  	Select(ctx context.Context) (Cursor, error)
   102  
   103  	// Explain outputs the explain plan for this statement.
   104  	Explain(ctx context.Context) (string, error)
   105  
   106  	// Close closes the resources associated with this prepared statement.
   107  	// This must be called as the mapped shards may hold open resources such
   108  	// as network connections.
   109  	Close() error
   110  }
   111  
   112  // Prepare will compile the statement with the default compile options and
   113  // then prepare the query.
   114  func Prepare(ctx context.Context, stmt *influxql.SelectStatement, shardMapper ShardMapper, opt SelectOptions) (PreparedStatement, error) {
   115  	c, err := Compile(stmt, CompileOptions{})
   116  	if err != nil {
   117  		return nil, err
   118  	}
   119  	return c.Prepare(ctx, shardMapper, opt)
   120  }
   121  
   122  // Select compiles, prepares, and then initiates execution of the query using the
   123  // default compile options.
   124  func Select(ctx context.Context, stmt *influxql.SelectStatement, shardMapper ShardMapper, opt SelectOptions) (Cursor, error) {
   125  	s, err := Prepare(ctx, stmt, shardMapper, opt)
   126  	if err != nil {
   127  		return nil, err
   128  	}
   129  	// Must be deferred so it runs after Select.
   130  	defer s.Close()
   131  	return s.Select(ctx)
   132  }
   133  
   134  type preparedStatement struct {
   135  	stmt *influxql.SelectStatement
   136  	opt  IteratorOptions
   137  	ic   interface {
   138  		IteratorCreator
   139  		io.Closer
   140  	}
   141  	columns   []string
   142  	maxPointN int
   143  	now       time.Time
   144  }
   145  
   146  type contextKey string
   147  
   148  const nowKey contextKey = "now"
   149  
   150  func (p *preparedStatement) Select(ctx context.Context) (Cursor, error) {
   151  	// TODO(jsternberg): Remove this hacky method of propagating now.
   152  	// Each level of the query should use a time range discovered during
   153  	// compilation, but that requires too large of a refactor at the moment.
   154  	ctx = context.WithValue(ctx, nowKey, p.now)
   155  
   156  	opt := p.opt
   157  	opt.InterruptCh = ctx.Done()
   158  	cur, err := buildCursor(ctx, p.stmt, p.ic, opt)
   159  	if err != nil {
   160  		return nil, err
   161  	}
   162  
   163  	return cur, nil
   164  }
   165  
   166  func (p *preparedStatement) Close() error {
   167  	return p.ic.Close()
   168  }
   169  
   170  // buildExprIterator creates an iterator for an expression.
   171  func buildExprIterator(ctx context.Context, expr influxql.Expr, ic IteratorCreator, sources influxql.Sources, opt IteratorOptions, selector, writeMode bool) (Iterator, error) {
   172  	opt.Expr = expr
   173  	b := exprIteratorBuilder{
   174  		ic:        ic,
   175  		sources:   sources,
   176  		opt:       opt,
   177  		selector:  selector,
   178  		writeMode: writeMode,
   179  	}
   180  
   181  	switch expr := expr.(type) {
   182  	case *influxql.VarRef:
   183  		return b.buildVarRefIterator(ctx, expr)
   184  	case *influxql.Call:
   185  		return b.buildCallIterator(ctx, expr)
   186  	default:
   187  		return nil, fmt.Errorf("invalid expression type: %T", expr)
   188  	}
   189  }
   190  
   191  type exprIteratorBuilder struct {
   192  	ic        IteratorCreator
   193  	sources   influxql.Sources
   194  	opt       IteratorOptions
   195  	selector  bool
   196  	writeMode bool
   197  }
   198  
   199  func (b *exprIteratorBuilder) buildVarRefIterator(ctx context.Context, expr *influxql.VarRef) (Iterator, error) {
   200  	inputs := make([]Iterator, 0, len(b.sources))
   201  	if err := func() error {
   202  		for _, source := range b.sources {
   203  			switch source := source.(type) {
   204  			case *influxql.Measurement:
   205  				input, err := b.ic.CreateIterator(ctx, source, b.opt)
   206  				if err != nil {
   207  					return err
   208  				}
   209  				inputs = append(inputs, input)
   210  			case *influxql.SubQuery:
   211  				subquery := subqueryBuilder{
   212  					ic:   b.ic,
   213  					stmt: source.Statement,
   214  				}
   215  
   216  				input, err := subquery.buildVarRefIterator(ctx, expr, b.opt)
   217  				if err != nil {
   218  					return err
   219  				} else if input != nil {
   220  					inputs = append(inputs, input)
   221  				}
   222  			}
   223  		}
   224  		return nil
   225  	}(); err != nil {
   226  		Iterators(inputs).Close()
   227  		return nil, err
   228  	}
   229  
   230  	// Variable references in this section will always go into some call
   231  	// iterator. Combine it with a merge iterator.
   232  	itr := NewMergeIterator(inputs, b.opt)
   233  	if itr == nil {
   234  		itr = &nilFloatIterator{}
   235  	}
   236  
   237  	if b.opt.InterruptCh != nil {
   238  		itr = NewInterruptIterator(itr, b.opt.InterruptCh)
   239  	}
   240  	return itr, nil
   241  }
   242  
   243  func (b *exprIteratorBuilder) buildCallIterator(ctx context.Context, expr *influxql.Call) (Iterator, error) {
   244  	// TODO(jsternberg): Refactor this. This section needs to die in a fire.
   245  	opt := b.opt
   246  	// Eliminate limits and offsets if they were previously set. These are handled by the caller.
   247  	opt.Limit, opt.Offset = 0, 0
   248  	switch expr.Name {
   249  	case "distinct":
   250  		opt.Ordered = true
   251  		input, err := buildExprIterator(ctx, expr.Args[0].(*influxql.VarRef), b.ic, b.sources, opt, b.selector, false)
   252  		if err != nil {
   253  			return nil, err
   254  		}
   255  		input, err = NewDistinctIterator(input, opt)
   256  		if err != nil {
   257  			return nil, err
   258  		}
   259  		return NewIntervalIterator(input, opt), nil
   260  	case "sample":
   261  		opt.Ordered = true
   262  		input, err := buildExprIterator(ctx, expr.Args[0], b.ic, b.sources, opt, b.selector, false)
   263  		if err != nil {
   264  			return nil, err
   265  		}
   266  		size := expr.Args[1].(*influxql.IntegerLiteral)
   267  
   268  		return newSampleIterator(input, opt, int(size.Val))
   269  	case "holt_winters", "holt_winters_with_fit":
   270  		opt.Ordered = true
   271  		input, err := buildExprIterator(ctx, expr.Args[0], b.ic, b.sources, opt, b.selector, false)
   272  		if err != nil {
   273  			return nil, err
   274  		}
   275  		h := expr.Args[1].(*influxql.IntegerLiteral)
   276  		m := expr.Args[2].(*influxql.IntegerLiteral)
   277  
   278  		includeFitData := expr.Name == "holt_winters_with_fit"
   279  
   280  		interval := opt.Interval.Duration
   281  		// Redefine interval to be unbounded to capture all aggregate results
   282  		opt.StartTime = influxql.MinTime
   283  		opt.EndTime = influxql.MaxTime
   284  		opt.Interval = Interval{}
   285  
   286  		return newHoltWintersIterator(input, opt, int(h.Val), int(m.Val), includeFitData, interval)
   287  	case "count_hll", "derivative", "non_negative_derivative", "difference", "non_negative_difference", "moving_average", "exponential_moving_average", "double_exponential_moving_average", "triple_exponential_moving_average", "relative_strength_index", "triple_exponential_derivative", "kaufmans_efficiency_ratio", "kaufmans_adaptive_moving_average", "chande_momentum_oscillator", "elapsed":
   288  		if !opt.Interval.IsZero() {
   289  			if opt.Ascending {
   290  				opt.StartTime -= int64(opt.Interval.Duration)
   291  			} else {
   292  				opt.EndTime += int64(opt.Interval.Duration)
   293  			}
   294  		}
   295  		opt.Ordered = true
   296  
   297  		input, err := buildExprIterator(ctx, expr.Args[0], b.ic, b.sources, opt, b.selector, false)
   298  		if err != nil {
   299  			return nil, err
   300  		}
   301  
   302  		switch expr.Name {
   303  		case "count_hll":
   304  			return NewCountHllIterator(input, opt)
   305  		case "derivative", "non_negative_derivative":
   306  			interval := opt.DerivativeInterval()
   307  			isNonNegative := (expr.Name == "non_negative_derivative")
   308  			return newDerivativeIterator(input, opt, interval, isNonNegative)
   309  		case "elapsed":
   310  			interval := opt.ElapsedInterval()
   311  			return newElapsedIterator(input, opt, interval)
   312  		case "difference", "non_negative_difference":
   313  			isNonNegative := (expr.Name == "non_negative_difference")
   314  			return newDifferenceIterator(input, opt, isNonNegative)
   315  		case "moving_average":
   316  			n := expr.Args[1].(*influxql.IntegerLiteral)
   317  			if n.Val > 1 && !opt.Interval.IsZero() {
   318  				if opt.Ascending {
   319  					opt.StartTime -= int64(opt.Interval.Duration) * (n.Val - 1)
   320  				} else {
   321  					opt.EndTime += int64(opt.Interval.Duration) * (n.Val - 1)
   322  				}
   323  			}
   324  			return newMovingAverageIterator(input, int(n.Val), opt)
   325  		case "exponential_moving_average", "double_exponential_moving_average", "triple_exponential_moving_average", "relative_strength_index", "triple_exponential_derivative":
   326  			n := expr.Args[1].(*influxql.IntegerLiteral)
   327  			if n.Val > 1 && !opt.Interval.IsZero() {
   328  				if opt.Ascending {
   329  					opt.StartTime -= int64(opt.Interval.Duration) * (n.Val - 1)
   330  				} else {
   331  					opt.EndTime += int64(opt.Interval.Duration) * (n.Val - 1)
   332  				}
   333  			}
   334  
   335  			nHold := -1
   336  			if len(expr.Args) >= 3 {
   337  				nHold = int(expr.Args[2].(*influxql.IntegerLiteral).Val)
   338  			}
   339  
   340  			warmupType := gota.WarmEMA
   341  			if len(expr.Args) >= 4 {
   342  				if warmupType, err = gota.ParseWarmupType(expr.Args[3].(*influxql.StringLiteral).Val); err != nil {
   343  					return nil, err
   344  				}
   345  			}
   346  
   347  			switch expr.Name {
   348  			case "exponential_moving_average":
   349  				return newExponentialMovingAverageIterator(input, int(n.Val), nHold, warmupType, opt)
   350  			case "double_exponential_moving_average":
   351  				return newDoubleExponentialMovingAverageIterator(input, int(n.Val), nHold, warmupType, opt)
   352  			case "triple_exponential_moving_average":
   353  				return newTripleExponentialMovingAverageIterator(input, int(n.Val), nHold, warmupType, opt)
   354  			case "relative_strength_index":
   355  				return newRelativeStrengthIndexIterator(input, int(n.Val), nHold, warmupType, opt)
   356  			case "triple_exponential_derivative":
   357  				return newTripleExponentialDerivativeIterator(input, int(n.Val), nHold, warmupType, opt)
   358  			}
   359  		case "kaufmans_efficiency_ratio", "kaufmans_adaptive_moving_average":
   360  			n := expr.Args[1].(*influxql.IntegerLiteral)
   361  			if n.Val > 1 && !opt.Interval.IsZero() {
   362  				if opt.Ascending {
   363  					opt.StartTime -= int64(opt.Interval.Duration) * (n.Val - 1)
   364  				} else {
   365  					opt.EndTime += int64(opt.Interval.Duration) * (n.Val - 1)
   366  				}
   367  			}
   368  
   369  			nHold := -1
   370  			if len(expr.Args) >= 3 {
   371  				nHold = int(expr.Args[2].(*influxql.IntegerLiteral).Val)
   372  			}
   373  
   374  			switch expr.Name {
   375  			case "kaufmans_efficiency_ratio":
   376  				return newKaufmansEfficiencyRatioIterator(input, int(n.Val), nHold, opt)
   377  			case "kaufmans_adaptive_moving_average":
   378  				return newKaufmansAdaptiveMovingAverageIterator(input, int(n.Val), nHold, opt)
   379  			}
   380  		case "chande_momentum_oscillator":
   381  			n := expr.Args[1].(*influxql.IntegerLiteral)
   382  			if n.Val > 1 && !opt.Interval.IsZero() {
   383  				if opt.Ascending {
   384  					opt.StartTime -= int64(opt.Interval.Duration) * (n.Val - 1)
   385  				} else {
   386  					opt.EndTime += int64(opt.Interval.Duration) * (n.Val - 1)
   387  				}
   388  			}
   389  
   390  			nHold := -1
   391  			if len(expr.Args) >= 3 {
   392  				nHold = int(expr.Args[2].(*influxql.IntegerLiteral).Val)
   393  			}
   394  
   395  			warmupType := gota.WarmupType(-1)
   396  			if len(expr.Args) >= 4 {
   397  				wt := expr.Args[3].(*influxql.StringLiteral).Val
   398  				if wt != "none" {
   399  					if warmupType, err = gota.ParseWarmupType(wt); err != nil {
   400  						return nil, err
   401  					}
   402  				}
   403  			}
   404  
   405  			return newChandeMomentumOscillatorIterator(input, int(n.Val), nHold, warmupType, opt)
   406  		}
   407  		panic(fmt.Sprintf("invalid series aggregate function: %s", expr.Name))
   408  	case "cumulative_sum":
   409  		opt.Ordered = true
   410  		input, err := buildExprIterator(ctx, expr.Args[0], b.ic, b.sources, opt, b.selector, false)
   411  		if err != nil {
   412  			return nil, err
   413  		}
   414  		return newCumulativeSumIterator(input, opt)
   415  	case "integral":
   416  		opt.Ordered = true
   417  		input, err := buildExprIterator(ctx, expr.Args[0].(*influxql.VarRef), b.ic, b.sources, opt, false, false)
   418  		if err != nil {
   419  			return nil, err
   420  		}
   421  		interval := opt.IntegralInterval()
   422  		return newIntegralIterator(input, opt, interval)
   423  	case "top":
   424  		if len(expr.Args) < 2 {
   425  			return nil, fmt.Errorf("top() requires 2 or more arguments, got %d", len(expr.Args))
   426  		}
   427  
   428  		var input Iterator
   429  		if len(expr.Args) > 2 {
   430  			// Create a max iterator using the groupings in the arguments.
   431  			dims := make(map[string]struct{}, len(expr.Args)-2+len(opt.GroupBy))
   432  			for i := 1; i < len(expr.Args)-1; i++ {
   433  				ref := expr.Args[i].(*influxql.VarRef)
   434  				dims[ref.Val] = struct{}{}
   435  			}
   436  			for dim := range opt.GroupBy {
   437  				dims[dim] = struct{}{}
   438  			}
   439  
   440  			call := &influxql.Call{
   441  				Name: "max",
   442  				Args: expr.Args[:1],
   443  			}
   444  			callOpt := opt
   445  			callOpt.Expr = call
   446  			callOpt.GroupBy = dims
   447  			callOpt.Fill = influxql.NoFill
   448  
   449  			builder := *b
   450  			builder.opt = callOpt
   451  			builder.selector = true
   452  			builder.writeMode = false
   453  
   454  			i, err := builder.callIterator(ctx, call, callOpt)
   455  			if err != nil {
   456  				return nil, err
   457  			}
   458  			input = i
   459  		} else {
   460  			// There are no arguments so do not organize the points by tags.
   461  			builder := *b
   462  			builder.opt.Expr = expr.Args[0]
   463  			builder.selector = true
   464  			builder.writeMode = false
   465  
   466  			ref := expr.Args[0].(*influxql.VarRef)
   467  			i, err := builder.buildVarRefIterator(ctx, ref)
   468  			if err != nil {
   469  				return nil, err
   470  			}
   471  			input = i
   472  		}
   473  
   474  		n := expr.Args[len(expr.Args)-1].(*influxql.IntegerLiteral)
   475  		return newTopIterator(input, opt, int(n.Val), b.writeMode)
   476  	case "bottom":
   477  		if len(expr.Args) < 2 {
   478  			return nil, fmt.Errorf("bottom() requires 2 or more arguments, got %d", len(expr.Args))
   479  		}
   480  
   481  		var input Iterator
   482  		if len(expr.Args) > 2 {
   483  			// Create a max iterator using the groupings in the arguments.
   484  			dims := make(map[string]struct{}, len(expr.Args)-2)
   485  			for i := 1; i < len(expr.Args)-1; i++ {
   486  				ref := expr.Args[i].(*influxql.VarRef)
   487  				dims[ref.Val] = struct{}{}
   488  			}
   489  			for dim := range opt.GroupBy {
   490  				dims[dim] = struct{}{}
   491  			}
   492  
   493  			call := &influxql.Call{
   494  				Name: "min",
   495  				Args: expr.Args[:1],
   496  			}
   497  			callOpt := opt
   498  			callOpt.Expr = call
   499  			callOpt.GroupBy = dims
   500  			callOpt.Fill = influxql.NoFill
   501  
   502  			builder := *b
   503  			builder.opt = callOpt
   504  			builder.selector = true
   505  			builder.writeMode = false
   506  
   507  			i, err := builder.callIterator(ctx, call, callOpt)
   508  			if err != nil {
   509  				return nil, err
   510  			}
   511  			input = i
   512  		} else {
   513  			// There are no arguments so do not organize the points by tags.
   514  			builder := *b
   515  			builder.opt.Expr = expr.Args[0]
   516  			builder.selector = true
   517  			builder.writeMode = false
   518  
   519  			ref := expr.Args[0].(*influxql.VarRef)
   520  			i, err := builder.buildVarRefIterator(ctx, ref)
   521  			if err != nil {
   522  				return nil, err
   523  			}
   524  			input = i
   525  		}
   526  
   527  		n := expr.Args[len(expr.Args)-1].(*influxql.IntegerLiteral)
   528  		return newBottomIterator(input, b.opt, int(n.Val), b.writeMode)
   529  	}
   530  
   531  	itr, err := func() (Iterator, error) {
   532  		switch expr.Name {
   533  		case "count":
   534  			switch arg0 := expr.Args[0].(type) {
   535  			case *influxql.Call:
   536  				if arg0.Name == "distinct" {
   537  					input, err := buildExprIterator(ctx, arg0, b.ic, b.sources, opt, b.selector, false)
   538  					if err != nil {
   539  						return nil, err
   540  					}
   541  					return newCountIterator(input, opt)
   542  				}
   543  			}
   544  			fallthrough
   545  		case "min", "max", "sum", "first", "last", "mean", "sum_hll", "merge_hll":
   546  			return b.callIterator(ctx, expr, opt)
   547  		case "median":
   548  			opt.Ordered = true
   549  			input, err := buildExprIterator(ctx, expr.Args[0].(*influxql.VarRef), b.ic, b.sources, opt, false, false)
   550  			if err != nil {
   551  				return nil, err
   552  			}
   553  			return newMedianIterator(input, opt)
   554  		case "mode":
   555  			input, err := buildExprIterator(ctx, expr.Args[0].(*influxql.VarRef), b.ic, b.sources, opt, false, false)
   556  			if err != nil {
   557  				return nil, err
   558  			}
   559  			return NewModeIterator(input, opt)
   560  		case "stddev":
   561  			input, err := buildExprIterator(ctx, expr.Args[0].(*influxql.VarRef), b.ic, b.sources, opt, false, false)
   562  			if err != nil {
   563  				return nil, err
   564  			}
   565  			return newStddevIterator(input, opt)
   566  		case "spread":
   567  			// OPTIMIZE(benbjohnson): convert to map/reduce
   568  			input, err := buildExprIterator(ctx, expr.Args[0].(*influxql.VarRef), b.ic, b.sources, opt, false, false)
   569  			if err != nil {
   570  				return nil, err
   571  			}
   572  			return newSpreadIterator(input, opt)
   573  		case "percentile":
   574  			opt.Ordered = true
   575  			input, err := buildExprIterator(ctx, expr.Args[0].(*influxql.VarRef), b.ic, b.sources, opt, false, false)
   576  			if err != nil {
   577  				return nil, err
   578  			}
   579  			var percentile float64
   580  			switch arg := expr.Args[1].(type) {
   581  			case *influxql.NumberLiteral:
   582  				percentile = arg.Val
   583  			case *influxql.IntegerLiteral:
   584  				percentile = float64(arg.Val)
   585  			}
   586  			return newPercentileIterator(input, opt, percentile)
   587  		default:
   588  			return nil, fmt.Errorf("unsupported call: %s", expr.Name)
   589  		}
   590  	}()
   591  
   592  	if err != nil {
   593  		return nil, err
   594  	}
   595  
   596  	if !b.selector || !opt.Interval.IsZero() {
   597  		itr = NewIntervalIterator(itr, opt)
   598  		if !opt.Interval.IsZero() && opt.Fill != influxql.NoFill {
   599  			itr = NewFillIterator(itr, expr, opt)
   600  		}
   601  	}
   602  	if opt.InterruptCh != nil {
   603  		itr = NewInterruptIterator(itr, opt.InterruptCh)
   604  	}
   605  	return itr, nil
   606  }
   607  
   608  func (b *exprIteratorBuilder) callIterator(ctx context.Context, expr *influxql.Call, opt IteratorOptions) (Iterator, error) {
   609  	inputs := make([]Iterator, 0, len(b.sources))
   610  	if err := func() error {
   611  		for _, source := range b.sources {
   612  			switch source := source.(type) {
   613  			case *influxql.Measurement:
   614  				input, err := b.ic.CreateIterator(ctx, source, opt)
   615  				if err != nil {
   616  					return err
   617  				}
   618  				inputs = append(inputs, input)
   619  			case *influxql.SubQuery:
   620  				// Identify the name of the field we are using.
   621  				arg0 := expr.Args[0].(*influxql.VarRef)
   622  
   623  				opt.Ordered = false
   624  				input, err := buildExprIterator(ctx, arg0, b.ic, []influxql.Source{source}, opt, b.selector, false)
   625  				if err != nil {
   626  					return err
   627  				}
   628  
   629  				// Wrap the result in a call iterator.
   630  				i, err := NewCallIterator(input, opt)
   631  				if err != nil {
   632  					input.Close()
   633  					return err
   634  				}
   635  				inputs = append(inputs, i)
   636  			}
   637  		}
   638  		return nil
   639  	}(); err != nil {
   640  		Iterators(inputs).Close()
   641  		return nil, err
   642  	}
   643  
   644  	itr, err := Iterators(inputs).Merge(opt)
   645  	if err != nil {
   646  		Iterators(inputs).Close()
   647  		return nil, err
   648  	} else if itr == nil {
   649  		itr = &nilFloatIterator{}
   650  	}
   651  	return itr, nil
   652  }
   653  
   654  func buildCursor(ctx context.Context, stmt *influxql.SelectStatement, ic IteratorCreator, opt IteratorOptions) (Cursor, error) {
   655  	switch opt.Fill {
   656  	case influxql.NumberFill:
   657  		if v, ok := opt.FillValue.(int); ok {
   658  			opt.FillValue = int64(v)
   659  		}
   660  	case influxql.PreviousFill:
   661  		opt.FillValue = SkipDefault
   662  	}
   663  
   664  	fields := make([]*influxql.Field, 0, len(stmt.Fields)+1)
   665  	if !stmt.OmitTime {
   666  		// Add a field with the variable "time" if we have not omitted time.
   667  		fields = append(fields, &influxql.Field{
   668  			Expr: &influxql.VarRef{
   669  				Val:  "time",
   670  				Type: influxql.Time,
   671  			},
   672  		})
   673  	}
   674  
   675  	// Iterate through each of the fields to add them to the value mapper.
   676  	valueMapper := newValueMapper()
   677  	for _, f := range stmt.Fields {
   678  		fields = append(fields, valueMapper.Map(f))
   679  
   680  		// If the field is a top() or bottom() call, we need to also add
   681  		// the extra variables if we are not writing into a target.
   682  		if stmt.Target != nil {
   683  			continue
   684  		}
   685  
   686  		switch expr := f.Expr.(type) {
   687  		case *influxql.Call:
   688  			if expr.Name == "top" || expr.Name == "bottom" {
   689  				for i := 1; i < len(expr.Args)-1; i++ {
   690  					nf := influxql.Field{Expr: expr.Args[i]}
   691  					fields = append(fields, valueMapper.Map(&nf))
   692  				}
   693  			}
   694  		}
   695  	}
   696  
   697  	// Set the aliases on each of the columns to what the final name should be.
   698  	columns := stmt.ColumnNames()
   699  	for i, f := range fields {
   700  		f.Alias = columns[i]
   701  	}
   702  
   703  	// Retrieve the refs to retrieve the auxiliary fields.
   704  	var auxKeys []influxql.VarRef
   705  	if len(valueMapper.refs) > 0 {
   706  		opt.Aux = make([]influxql.VarRef, 0, len(valueMapper.refs))
   707  		for ref := range valueMapper.refs {
   708  			opt.Aux = append(opt.Aux, *ref)
   709  		}
   710  		sort.Sort(influxql.VarRefs(opt.Aux))
   711  
   712  		auxKeys = make([]influxql.VarRef, len(opt.Aux))
   713  		for i, ref := range opt.Aux {
   714  			auxKeys[i] = valueMapper.symbols[ref.String()]
   715  		}
   716  	}
   717  
   718  	// If there are no calls, then produce an auxiliary cursor.
   719  	if len(valueMapper.calls) == 0 {
   720  		// If all of the auxiliary keys are of an unknown type,
   721  		// do not construct the iterator and return a null cursor.
   722  		if !hasValidType(auxKeys) {
   723  			return newNullCursor(fields), nil
   724  		}
   725  
   726  		itr, err := buildAuxIterator(ctx, ic, stmt.Sources, opt)
   727  		if err != nil {
   728  			return nil, err
   729  		}
   730  
   731  		// Create a slice with an empty first element.
   732  		keys := []influxql.VarRef{{}}
   733  		keys = append(keys, auxKeys...)
   734  
   735  		scanner := NewIteratorScanner(itr, keys, opt.FillValue)
   736  		return newScannerCursor(scanner, fields, opt), nil
   737  	}
   738  
   739  	// Check to see if this is a selector statement.
   740  	// It is a selector if it is the only selector call and the call itself
   741  	// is a selector.
   742  	selector := len(valueMapper.calls) == 1
   743  	if selector {
   744  		for call := range valueMapper.calls {
   745  			if !influxql.IsSelector(call) {
   746  				selector = false
   747  			}
   748  		}
   749  	}
   750  
   751  	// Produce an iterator for every single call and create an iterator scanner
   752  	// associated with it.
   753  	var g errgroup.Group
   754  	var mu sync.Mutex
   755  	scanners := make([]IteratorScanner, 0, len(valueMapper.calls))
   756  	for call := range valueMapper.calls {
   757  		call := call
   758  
   759  		driver := valueMapper.table[call]
   760  		if driver.Type == influxql.Unknown {
   761  			// The primary driver of this call is of unknown type, so skip this.
   762  			continue
   763  		}
   764  
   765  		g.Go(func() error {
   766  			itr, err := buildFieldIterator(ctx, call, ic, stmt.Sources, opt, selector, stmt.Target != nil)
   767  			if err != nil {
   768  				return err
   769  			}
   770  
   771  			keys := make([]influxql.VarRef, 0, len(auxKeys)+1)
   772  			keys = append(keys, driver)
   773  			keys = append(keys, auxKeys...)
   774  
   775  			scanner := NewIteratorScanner(itr, keys, opt.FillValue)
   776  
   777  			mu.Lock()
   778  			scanners = append(scanners, scanner)
   779  			mu.Unlock()
   780  
   781  			return nil
   782  		})
   783  	}
   784  
   785  	// Close all scanners if any iterator fails.
   786  	if err := g.Wait(); err != nil {
   787  		for _, s := range scanners {
   788  			s.Close()
   789  		}
   790  		return nil, err
   791  	}
   792  
   793  	if len(scanners) == 0 {
   794  		return newNullCursor(fields), nil
   795  	} else if len(scanners) == 1 {
   796  		return newScannerCursor(scanners[0], fields, opt), nil
   797  	}
   798  	return newMultiScannerCursor(scanners, fields, opt), nil
   799  }
   800  
   801  func buildAuxIterator(ctx context.Context, ic IteratorCreator, sources influxql.Sources, opt IteratorOptions) (Iterator, error) {
   802  	inputs := make([]Iterator, 0, len(sources))
   803  	if err := func() error {
   804  		for _, source := range sources {
   805  			switch source := source.(type) {
   806  			case *influxql.Measurement:
   807  				input, err := ic.CreateIterator(ctx, source, opt)
   808  				if err != nil {
   809  					return err
   810  				}
   811  				inputs = append(inputs, input)
   812  			case *influxql.SubQuery:
   813  				b := subqueryBuilder{
   814  					ic:   ic,
   815  					stmt: source.Statement,
   816  				}
   817  
   818  				input, err := b.buildAuxIterator(ctx, opt)
   819  				if err != nil {
   820  					return err
   821  				} else if input != nil {
   822  					inputs = append(inputs, input)
   823  				}
   824  			}
   825  		}
   826  		return nil
   827  	}(); err != nil {
   828  		Iterators(inputs).Close()
   829  		return nil, err
   830  	}
   831  
   832  	// Merge iterators to read auxiliary fields.
   833  	input, err := Iterators(inputs).Merge(opt)
   834  	if err != nil {
   835  		Iterators(inputs).Close()
   836  		return nil, err
   837  	} else if input == nil {
   838  		input = &nilFloatIterator{}
   839  	}
   840  
   841  	// Filter out duplicate rows, if required.
   842  	if opt.Dedupe {
   843  		// If there is no group by and it is a float iterator, see if we can use a fast dedupe.
   844  		if itr, ok := input.(FloatIterator); ok && len(opt.Dimensions) == 0 {
   845  			if sz := len(opt.Aux); sz > 0 && sz < 3 {
   846  				input = newFloatFastDedupeIterator(itr)
   847  			} else {
   848  				input = NewDedupeIterator(itr)
   849  			}
   850  		} else {
   851  			input = NewDedupeIterator(input)
   852  		}
   853  	}
   854  	// Apply limit & offset.
   855  	if opt.Limit > 0 || opt.Offset > 0 {
   856  		input = NewLimitIterator(input, opt)
   857  	}
   858  	return input, nil
   859  }
   860  
   861  func buildFieldIterator(ctx context.Context, expr influxql.Expr, ic IteratorCreator, sources influxql.Sources, opt IteratorOptions, selector, writeMode bool) (Iterator, error) {
   862  	input, err := buildExprIterator(ctx, expr, ic, sources, opt, selector, writeMode)
   863  	if err != nil {
   864  		return nil, err
   865  	}
   866  
   867  	// Apply limit & offset.
   868  	if opt.Limit > 0 || opt.Offset > 0 {
   869  		input = NewLimitIterator(input, opt)
   870  	}
   871  	return input, nil
   872  }
   873  
   874  type valueMapper struct {
   875  	// An index that maps a node's string output to its symbol so that all
   876  	// nodes with the same signature are mapped the same.
   877  	symbols map[string]influxql.VarRef
   878  	// An index that maps a specific expression to a symbol. This ensures that
   879  	// only expressions that were mapped get symbolized.
   880  	table map[influxql.Expr]influxql.VarRef
   881  	// A collection of all of the calls in the table.
   882  	calls map[*influxql.Call]struct{}
   883  	// A collection of all of the calls in the table.
   884  	refs map[*influxql.VarRef]struct{}
   885  	i    int
   886  }
   887  
   888  func newValueMapper() *valueMapper {
   889  	return &valueMapper{
   890  		symbols: make(map[string]influxql.VarRef),
   891  		table:   make(map[influxql.Expr]influxql.VarRef),
   892  		calls:   make(map[*influxql.Call]struct{}),
   893  		refs:    make(map[*influxql.VarRef]struct{}),
   894  	}
   895  }
   896  
   897  func (v *valueMapper) Map(field *influxql.Field) *influxql.Field {
   898  	clone := *field
   899  	clone.Expr = influxql.CloneExpr(field.Expr)
   900  
   901  	influxql.Walk(v, clone.Expr)
   902  	clone.Expr = influxql.RewriteExpr(clone.Expr, v.rewriteExpr)
   903  	return &clone
   904  }
   905  
   906  func (v *valueMapper) Visit(n influxql.Node) influxql.Visitor {
   907  	expr, ok := n.(influxql.Expr)
   908  	if !ok {
   909  		return v
   910  	}
   911  
   912  	key := expr.String()
   913  	symbol, ok := v.symbols[key]
   914  	if !ok {
   915  		// This symbol has not been assigned yet.
   916  		// If this is a call or expression, mark the node
   917  		// as stored in the symbol table.
   918  		switch n := n.(type) {
   919  		case *influxql.Call:
   920  			if isMathFunction(n) {
   921  				return v
   922  			}
   923  			v.calls[n] = struct{}{}
   924  		case *influxql.VarRef:
   925  			v.refs[n] = struct{}{}
   926  		default:
   927  			return v
   928  		}
   929  
   930  		// Determine the symbol name and the symbol type.
   931  		symbolName := fmt.Sprintf("val%d", v.i)
   932  		valuer := influxql.TypeValuerEval{
   933  			TypeMapper: DefaultTypeMapper,
   934  		}
   935  		typ, _ := valuer.EvalType(expr)
   936  
   937  		symbol = influxql.VarRef{
   938  			Val:  symbolName,
   939  			Type: typ,
   940  		}
   941  
   942  		// Assign this symbol to the symbol table if it is not presently there
   943  		// and increment the value index number.
   944  		v.symbols[key] = symbol
   945  		v.i++
   946  	}
   947  	// Store the symbol for this expression so we can later rewrite
   948  	// the query correctly.
   949  	v.table[expr] = symbol
   950  	return nil
   951  }
   952  
   953  func (v *valueMapper) rewriteExpr(expr influxql.Expr) influxql.Expr {
   954  	symbol, ok := v.table[expr]
   955  	if !ok {
   956  		return expr
   957  	}
   958  	return &symbol
   959  }
   960  
   961  func validateTypes(stmt *influxql.SelectStatement) error {
   962  	valuer := influxql.TypeValuerEval{
   963  		TypeMapper: influxql.MultiTypeMapper(
   964  			FunctionTypeMapper{},
   965  			MathTypeMapper{},
   966  		),
   967  	}
   968  	for _, f := range stmt.Fields {
   969  		if _, err := valuer.EvalType(f.Expr); err != nil {
   970  			return err
   971  		}
   972  	}
   973  	return nil
   974  }
   975  
   976  // hasValidType returns true if there is at least one non-unknown type
   977  // in the slice.
   978  func hasValidType(refs []influxql.VarRef) bool {
   979  	for _, ref := range refs {
   980  		if ref.Type != influxql.Unknown {
   981  			return true
   982  		}
   983  	}
   984  	return false
   985  }