github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/opt/exec/execbuilder/scalar.go (about)

     1  // Copyright 2018 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package execbuilder
    12  
    13  import (
    14  	"github.com/cockroachdb/cockroach/pkg/sql/opt"
    15  	"github.com/cockroachdb/cockroach/pkg/sql/opt/exec"
    16  	"github.com/cockroachdb/cockroach/pkg/sql/opt/memo"
    17  	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
    18  	"github.com/cockroachdb/cockroach/pkg/sql/types"
    19  	"github.com/cockroachdb/cockroach/pkg/util/log"
    20  	"github.com/cockroachdb/errors"
    21  )
    22  
    23  type buildScalarCtx struct {
    24  	ivh tree.IndexedVarHelper
    25  
    26  	// ivarMap is a map from opt.ColumnID to the index of an IndexedVar.
    27  	// If a ColumnID is not in the map, it cannot appear in the expression.
    28  	ivarMap opt.ColMap
    29  }
    30  
    31  type buildFunc func(b *Builder, ctx *buildScalarCtx, scalar opt.ScalarExpr) (tree.TypedExpr, error)
    32  
    33  var scalarBuildFuncMap [opt.NumOperators]buildFunc
    34  
    35  func init() {
    36  	// This code is not inline to avoid an initialization loop error (some of
    37  	// the functions depend on scalarBuildFuncMap which in turn depends on the
    38  	// functions).
    39  	scalarBuildFuncMap = [opt.NumOperators]buildFunc{
    40  		opt.VariableOp:        (*Builder).buildVariable,
    41  		opt.ConstOp:           (*Builder).buildTypedExpr,
    42  		opt.NullOp:            (*Builder).buildNull,
    43  		opt.PlaceholderOp:     (*Builder).buildTypedExpr,
    44  		opt.TupleOp:           (*Builder).buildTuple,
    45  		opt.FunctionOp:        (*Builder).buildFunction,
    46  		opt.CaseOp:            (*Builder).buildCase,
    47  		opt.CastOp:            (*Builder).buildCast,
    48  		opt.CoalesceOp:        (*Builder).buildCoalesce,
    49  		opt.ColumnAccessOp:    (*Builder).buildColumnAccess,
    50  		opt.ArrayOp:           (*Builder).buildArray,
    51  		opt.AnyOp:             (*Builder).buildAny,
    52  		opt.AnyScalarOp:       (*Builder).buildAnyScalar,
    53  		opt.IndirectionOp:     (*Builder).buildIndirection,
    54  		opt.CollateOp:         (*Builder).buildCollate,
    55  		opt.ArrayFlattenOp:    (*Builder).buildArrayFlatten,
    56  		opt.IfErrOp:           (*Builder).buildIfErr,
    57  		opt.UnsupportedExprOp: (*Builder).buildUnsupportedExpr,
    58  
    59  		// Item operators.
    60  		opt.ProjectionsItemOp:  (*Builder).buildItem,
    61  		opt.AggregationsItemOp: (*Builder).buildItem,
    62  
    63  		// Subquery operators.
    64  		opt.ExistsOp:   (*Builder).buildExistsSubquery,
    65  		opt.SubqueryOp: (*Builder).buildSubquery,
    66  	}
    67  
    68  	for _, op := range opt.BoolOperators {
    69  		if scalarBuildFuncMap[op] == nil {
    70  			scalarBuildFuncMap[op] = (*Builder).buildBoolean
    71  		}
    72  	}
    73  
    74  	for _, op := range opt.ComparisonOperators {
    75  		scalarBuildFuncMap[op] = (*Builder).buildComparison
    76  	}
    77  
    78  	for _, op := range opt.BinaryOperators {
    79  		scalarBuildFuncMap[op] = (*Builder).buildBinary
    80  	}
    81  
    82  	for _, op := range opt.UnaryOperators {
    83  		scalarBuildFuncMap[op] = (*Builder).buildUnary
    84  	}
    85  }
    86  
    87  // buildScalar converts a scalar expression to a TypedExpr. Variables are mapped
    88  // according to ctx.
    89  func (b *Builder) buildScalar(ctx *buildScalarCtx, scalar opt.ScalarExpr) (tree.TypedExpr, error) {
    90  	if fn := scalarBuildFuncMap[scalar.Op()]; fn != nil {
    91  		texpr, err := fn(b, ctx, scalar)
    92  		if err != nil {
    93  			return nil, err
    94  		}
    95  		if b.evalCtx != nil && b.isConst(texpr) {
    96  			value, err := texpr.Eval(b.evalCtx)
    97  			if err != nil {
    98  				if errors.IsAssertionFailure(err) {
    99  					return nil, err
   100  				}
   101  				// Ignore any errors here (e.g. division by zero), so they can happen
   102  				// during execution where they are correctly handled. Note that in some
   103  				// cases we might not even get an error (if this particular expression
   104  				// does not get evaluated when the query runs, e.g. it's inside a CASE).
   105  				return texpr, nil
   106  			}
   107  			if value == tree.DNull {
   108  				// We don't want to return an expression that has a different type; cast
   109  				// the NULL if necessary.
   110  				return tree.ReType(tree.DNull, texpr.ResolvedType()), nil
   111  			}
   112  			return value, nil
   113  		}
   114  		return texpr, nil
   115  	}
   116  	return nil, errors.Errorf("unsupported op %s", scalar.Op())
   117  }
   118  
   119  func (b *Builder) buildTypedExpr(
   120  	ctx *buildScalarCtx, scalar opt.ScalarExpr,
   121  ) (tree.TypedExpr, error) {
   122  	return scalar.Private().(tree.TypedExpr), nil
   123  }
   124  
   125  func (b *Builder) buildNull(ctx *buildScalarCtx, scalar opt.ScalarExpr) (tree.TypedExpr, error) {
   126  	return tree.ReType(tree.DNull, scalar.DataType()), nil
   127  }
   128  
   129  func (b *Builder) buildVariable(
   130  	ctx *buildScalarCtx, scalar opt.ScalarExpr,
   131  ) (tree.TypedExpr, error) {
   132  	return b.indexedVar(ctx, b.mem.Metadata(), *scalar.Private().(*opt.ColumnID)), nil
   133  }
   134  
   135  func (b *Builder) indexedVar(
   136  	ctx *buildScalarCtx, md *opt.Metadata, colID opt.ColumnID,
   137  ) tree.TypedExpr {
   138  	idx, ok := ctx.ivarMap.Get(int(colID))
   139  	if !ok {
   140  		panic(errors.AssertionFailedf("cannot map variable %d to an indexed var", log.Safe(colID)))
   141  	}
   142  	return ctx.ivh.IndexedVarWithType(idx, md.ColumnMeta(colID).Type)
   143  }
   144  
   145  func (b *Builder) buildTuple(ctx *buildScalarCtx, scalar opt.ScalarExpr) (tree.TypedExpr, error) {
   146  	if memo.CanExtractConstTuple(scalar) {
   147  		return memo.ExtractConstDatum(scalar), nil
   148  	}
   149  
   150  	tup := scalar.(*memo.TupleExpr)
   151  	typedExprs := make(tree.Exprs, len(tup.Elems))
   152  	var err error
   153  	for i, elem := range tup.Elems {
   154  		typedExprs[i], err = b.buildScalar(ctx, elem)
   155  		if err != nil {
   156  			return nil, err
   157  		}
   158  	}
   159  	return tree.NewTypedTuple(tup.Typ, typedExprs), nil
   160  }
   161  
   162  func (b *Builder) buildBoolean(ctx *buildScalarCtx, scalar opt.ScalarExpr) (tree.TypedExpr, error) {
   163  	switch scalar.Op() {
   164  	case opt.FiltersOp:
   165  		if scalar.ChildCount() == 0 {
   166  			// This can happen if the expression is not normalized (build tests).
   167  			return tree.DBoolTrue, nil
   168  		}
   169  		fallthrough
   170  
   171  	case opt.AndOp, opt.OrOp:
   172  		expr, err := b.buildScalar(ctx, scalar.Child(0).(opt.ScalarExpr))
   173  		if err != nil {
   174  			return nil, err
   175  		}
   176  		for i, n := 1, scalar.ChildCount(); i < n; i++ {
   177  			right, err := b.buildScalar(ctx, scalar.Child(i).(opt.ScalarExpr))
   178  			if err != nil {
   179  				return nil, err
   180  			}
   181  			if scalar.Op() == opt.OrOp {
   182  				expr = tree.NewTypedOrExpr(expr, right)
   183  			} else {
   184  				expr = tree.NewTypedAndExpr(expr, right)
   185  			}
   186  		}
   187  		return expr, nil
   188  
   189  	case opt.NotOp:
   190  		expr, err := b.buildScalar(ctx, scalar.Child(0).(opt.ScalarExpr))
   191  		if err != nil {
   192  			return nil, err
   193  		}
   194  		return tree.NewTypedNotExpr(expr), nil
   195  
   196  	case opt.TrueOp:
   197  		return tree.DBoolTrue, nil
   198  
   199  	case opt.FalseOp:
   200  		return tree.DBoolFalse, nil
   201  
   202  	case opt.FiltersItemOp:
   203  		return b.buildScalar(ctx, scalar.Child(0).(opt.ScalarExpr))
   204  
   205  	case opt.RangeOp:
   206  		return b.buildScalar(ctx, scalar.Child(0).(opt.ScalarExpr))
   207  
   208  	case opt.IsTupleNullOp:
   209  		expr, err := b.buildScalar(ctx, scalar.Child(0).(opt.ScalarExpr))
   210  		if err != nil {
   211  			return nil, err
   212  		}
   213  		return tree.NewTypedIsNullExpr(expr), nil
   214  
   215  	case opt.IsTupleNotNullOp:
   216  		expr, err := b.buildScalar(ctx, scalar.Child(0).(opt.ScalarExpr))
   217  		if err != nil {
   218  			return nil, err
   219  		}
   220  		return tree.NewTypedIsNotNullExpr(expr), nil
   221  
   222  	default:
   223  		panic(errors.AssertionFailedf("invalid op %s", log.Safe(scalar.Op())))
   224  	}
   225  }
   226  
   227  func (b *Builder) buildComparison(
   228  	ctx *buildScalarCtx, scalar opt.ScalarExpr,
   229  ) (tree.TypedExpr, error) {
   230  	left, err := b.buildScalar(ctx, scalar.Child(0).(opt.ScalarExpr))
   231  	if err != nil {
   232  		return nil, err
   233  	}
   234  	right, err := b.buildScalar(ctx, scalar.Child(1).(opt.ScalarExpr))
   235  	if err != nil {
   236  		return nil, err
   237  	}
   238  
   239  	// When the operator is an IsOp, the right is NULL, and the left is not a
   240  	// tuple, return the unary tree.IsNullExpr.
   241  	if scalar.Op() == opt.IsOp && right == tree.DNull && left.ResolvedType().Family() != types.TupleFamily {
   242  		return tree.NewTypedIsNullExpr(left), nil
   243  	}
   244  
   245  	// When the operator is an IsNotOp, the right is NULL, and the left is not a
   246  	// tuple, return the unary tree.IsNotNullExpr.
   247  	if scalar.Op() == opt.IsNotOp && right == tree.DNull && left.ResolvedType().Family() != types.TupleFamily {
   248  		return tree.NewTypedIsNotNullExpr(left), nil
   249  	}
   250  
   251  	operator := opt.ComparisonOpReverseMap[scalar.Op()]
   252  	return tree.NewTypedComparisonExpr(operator, left, right), nil
   253  }
   254  
   255  func (b *Builder) buildUnary(ctx *buildScalarCtx, scalar opt.ScalarExpr) (tree.TypedExpr, error) {
   256  	input, err := b.buildScalar(ctx, scalar.Child(0).(opt.ScalarExpr))
   257  	if err != nil {
   258  		return nil, err
   259  	}
   260  	operator := opt.UnaryOpReverseMap[scalar.Op()]
   261  	return tree.NewTypedUnaryExpr(operator, input, scalar.DataType()), nil
   262  }
   263  
   264  func (b *Builder) buildBinary(ctx *buildScalarCtx, scalar opt.ScalarExpr) (tree.TypedExpr, error) {
   265  	left, err := b.buildScalar(ctx, scalar.Child(0).(opt.ScalarExpr))
   266  	if err != nil {
   267  		return nil, err
   268  	}
   269  	right, err := b.buildScalar(ctx, scalar.Child(1).(opt.ScalarExpr))
   270  	if err != nil {
   271  		return nil, err
   272  	}
   273  	operator := opt.BinaryOpReverseMap[scalar.Op()]
   274  	return tree.NewTypedBinaryExpr(operator, left, right, scalar.DataType()), nil
   275  }
   276  
   277  func (b *Builder) buildFunction(
   278  	ctx *buildScalarCtx, scalar opt.ScalarExpr,
   279  ) (tree.TypedExpr, error) {
   280  	fn := scalar.(*memo.FunctionExpr)
   281  	exprs := make(tree.TypedExprs, len(fn.Args))
   282  	var err error
   283  	for i := range exprs {
   284  		exprs[i], err = b.buildScalar(ctx, fn.Args[i])
   285  		if err != nil {
   286  			return nil, err
   287  		}
   288  	}
   289  	funcRef := tree.WrapFunction(fn.Name)
   290  	return tree.NewTypedFuncExpr(
   291  		funcRef,
   292  		0, /* aggQualifier */
   293  		exprs,
   294  		nil, /* filter */
   295  		nil, /* windowDef */
   296  		fn.Typ,
   297  		fn.Properties,
   298  		fn.Overload,
   299  	), nil
   300  }
   301  
   302  func (b *Builder) buildCase(ctx *buildScalarCtx, scalar opt.ScalarExpr) (tree.TypedExpr, error) {
   303  	cas := scalar.(*memo.CaseExpr)
   304  	input, err := b.buildScalar(ctx, cas.Input)
   305  	if err != nil {
   306  		return nil, err
   307  	}
   308  
   309  	// A searched CASE statement is represented by the optimizer with input=True.
   310  	// The executor expects searched CASE statements to have nil inputs.
   311  	if input == tree.DBoolTrue {
   312  		input = nil
   313  	}
   314  
   315  	// Extract the list of WHEN ... THEN ... clauses.
   316  	whens := make([]*tree.When, len(cas.Whens))
   317  	for i, expr := range cas.Whens {
   318  		whenExpr := expr.(*memo.WhenExpr)
   319  		cond, err := b.buildScalar(ctx, whenExpr.Condition)
   320  		if err != nil {
   321  			return nil, err
   322  		}
   323  		val, err := b.buildScalar(ctx, whenExpr.Value)
   324  		if err != nil {
   325  			return nil, err
   326  		}
   327  		whens[i] = &tree.When{Cond: cond, Val: val}
   328  	}
   329  
   330  	elseExpr, err := b.buildScalar(ctx, cas.OrElse)
   331  	if err != nil {
   332  		return nil, err
   333  	}
   334  	if elseExpr == tree.DNull {
   335  		elseExpr = nil
   336  	}
   337  
   338  	return tree.NewTypedCaseExpr(input, whens, elseExpr, cas.Typ)
   339  }
   340  
   341  func (b *Builder) buildCast(ctx *buildScalarCtx, scalar opt.ScalarExpr) (tree.TypedExpr, error) {
   342  	cast := scalar.(*memo.CastExpr)
   343  	input, err := b.buildScalar(ctx, cast.Input)
   344  	if err != nil {
   345  		return nil, err
   346  	}
   347  	return tree.NewTypedCastExpr(input, cast.Typ), nil
   348  }
   349  
   350  func (b *Builder) buildCoalesce(
   351  	ctx *buildScalarCtx, scalar opt.ScalarExpr,
   352  ) (tree.TypedExpr, error) {
   353  	coalesce := scalar.(*memo.CoalesceExpr)
   354  	exprs := make(tree.TypedExprs, len(coalesce.Args))
   355  	var err error
   356  	for i := range exprs {
   357  		exprs[i], err = b.buildScalar(ctx, coalesce.Args[i])
   358  		if err != nil {
   359  			return nil, err
   360  		}
   361  	}
   362  	return tree.NewTypedCoalesceExpr(exprs, coalesce.Typ), nil
   363  }
   364  
   365  func (b *Builder) buildColumnAccess(
   366  	ctx *buildScalarCtx, scalar opt.ScalarExpr,
   367  ) (tree.TypedExpr, error) {
   368  	colAccess := scalar.(*memo.ColumnAccessExpr)
   369  	input, err := b.buildScalar(ctx, colAccess.Input)
   370  	if err != nil {
   371  		return nil, err
   372  	}
   373  	childTyp := colAccess.Input.DataType()
   374  	colIdx := int(colAccess.Idx)
   375  	// Find a label if there is one. It's OK if there isn't.
   376  	lbl := ""
   377  	if childTyp.TupleLabels() != nil {
   378  		lbl = childTyp.TupleLabels()[colIdx]
   379  	}
   380  	return tree.NewTypedColumnAccessExpr(input, lbl, colIdx), nil
   381  }
   382  
   383  func (b *Builder) buildArray(ctx *buildScalarCtx, scalar opt.ScalarExpr) (tree.TypedExpr, error) {
   384  	arr := scalar.(*memo.ArrayExpr)
   385  	if memo.CanExtractConstDatum(scalar) {
   386  		return memo.ExtractConstDatum(scalar), nil
   387  	}
   388  	exprs := make(tree.TypedExprs, len(arr.Elems))
   389  	var err error
   390  	for i := range exprs {
   391  		exprs[i], err = b.buildScalar(ctx, arr.Elems[i])
   392  		if err != nil {
   393  			return nil, err
   394  		}
   395  	}
   396  	return tree.NewTypedArray(exprs, arr.Typ), nil
   397  }
   398  
   399  func (b *Builder) buildAnyScalar(
   400  	ctx *buildScalarCtx, scalar opt.ScalarExpr,
   401  ) (tree.TypedExpr, error) {
   402  	any := scalar.(*memo.AnyScalarExpr)
   403  	left, err := b.buildScalar(ctx, any.Left)
   404  	if err != nil {
   405  		return nil, err
   406  	}
   407  
   408  	right, err := b.buildScalar(ctx, any.Right)
   409  	if err != nil {
   410  		return nil, err
   411  	}
   412  
   413  	cmp := opt.ComparisonOpReverseMap[any.Cmp]
   414  	return tree.NewTypedComparisonExprWithSubOp(tree.Any, cmp, left, right), nil
   415  }
   416  
   417  func (b *Builder) buildIndirection(
   418  	ctx *buildScalarCtx, scalar opt.ScalarExpr,
   419  ) (tree.TypedExpr, error) {
   420  	expr, err := b.buildScalar(ctx, scalar.Child(0).(opt.ScalarExpr))
   421  	if err != nil {
   422  		return nil, err
   423  	}
   424  
   425  	index, err := b.buildScalar(ctx, scalar.Child(1).(opt.ScalarExpr))
   426  	if err != nil {
   427  		return nil, err
   428  	}
   429  
   430  	return tree.NewTypedIndirectionExpr(expr, index, scalar.DataType()), nil
   431  }
   432  
   433  func (b *Builder) buildCollate(ctx *buildScalarCtx, scalar opt.ScalarExpr) (tree.TypedExpr, error) {
   434  	expr, err := b.buildScalar(ctx, scalar.Child(0).(opt.ScalarExpr))
   435  	if err != nil {
   436  		return nil, err
   437  	}
   438  
   439  	return tree.NewTypedCollateExpr(expr, scalar.(*memo.CollateExpr).Locale), nil
   440  }
   441  
   442  func (b *Builder) buildArrayFlatten(
   443  	ctx *buildScalarCtx, scalar opt.ScalarExpr,
   444  ) (tree.TypedExpr, error) {
   445  	af := scalar.(*memo.ArrayFlattenExpr)
   446  
   447  	// The subquery here should always be uncorrelated: if it were not, we would
   448  	// have converted it to an aggregation.
   449  	if !af.Input.Relational().OuterCols.Empty() {
   450  		panic(errors.AssertionFailedf("input to ArrayFlatten should be uncorrelated"))
   451  	}
   452  
   453  	root, err := b.buildRelational(af.Input)
   454  	if err != nil {
   455  		return nil, err
   456  	}
   457  
   458  	typ := b.mem.Metadata().ColumnMeta(af.RequestedCol).Type
   459  	e := b.addSubquery(exec.SubqueryAllRows, typ, root.root, af.OriginalExpr)
   460  
   461  	return tree.NewTypedArrayFlattenExpr(e), nil
   462  }
   463  
   464  func (b *Builder) buildIfErr(ctx *buildScalarCtx, scalar opt.ScalarExpr) (tree.TypedExpr, error) {
   465  	ifErr := scalar.(*memo.IfErrExpr)
   466  	cond, err := b.buildScalar(ctx, ifErr.Cond.(opt.ScalarExpr))
   467  	if err != nil {
   468  		return nil, err
   469  	}
   470  
   471  	var orElse tree.TypedExpr
   472  	if ifErr.OrElse.ChildCount() > 0 {
   473  		orElse, err = b.buildScalar(ctx, ifErr.OrElse.Child(0).(opt.ScalarExpr))
   474  		if err != nil {
   475  			return nil, err
   476  		}
   477  	}
   478  
   479  	var errCode tree.TypedExpr
   480  	if ifErr.ErrCode.ChildCount() > 0 {
   481  		errCode, err = b.buildScalar(ctx, ifErr.ErrCode.Child(0).(opt.ScalarExpr))
   482  		if err != nil {
   483  			return nil, err
   484  		}
   485  	}
   486  
   487  	return tree.NewTypedIfErrExpr(cond, orElse, errCode), nil
   488  }
   489  
   490  func (b *Builder) buildUnsupportedExpr(
   491  	ctx *buildScalarCtx, scalar opt.ScalarExpr,
   492  ) (tree.TypedExpr, error) {
   493  	return scalar.(*memo.UnsupportedExprExpr).Value, nil
   494  }
   495  
   496  func (b *Builder) buildItem(ctx *buildScalarCtx, scalar opt.ScalarExpr) (tree.TypedExpr, error) {
   497  	return b.buildScalar(ctx, scalar.Child(0).(opt.ScalarExpr))
   498  }
   499  
   500  func (b *Builder) buildAny(ctx *buildScalarCtx, scalar opt.ScalarExpr) (tree.TypedExpr, error) {
   501  	any := scalar.(*memo.AnyExpr)
   502  	// We cannot execute correlated subqueries.
   503  	if !any.Input.Relational().OuterCols.Empty() {
   504  		return nil, b.decorrelationError()
   505  	}
   506  
   507  	// Build the execution plan for the input subquery.
   508  	plan, err := b.buildRelational(any.Input)
   509  	if err != nil {
   510  		return nil, err
   511  	}
   512  
   513  	// Construct tuple type of columns in the row.
   514  	contents := make([]*types.T, plan.numOutputCols())
   515  	plan.outputCols.ForEach(func(key, val int) {
   516  		contents[val] = b.mem.Metadata().ColumnMeta(opt.ColumnID(key)).Type
   517  	})
   518  	typs := types.MakeTuple(contents)
   519  	subqueryExpr := b.addSubquery(exec.SubqueryAnyRows, typs, plan.root, any.OriginalExpr)
   520  
   521  	// Build the scalar value that is compared against each row.
   522  	scalarExpr, err := b.buildScalar(ctx, any.Scalar)
   523  	if err != nil {
   524  		return nil, err
   525  	}
   526  
   527  	cmp := opt.ComparisonOpReverseMap[any.Cmp]
   528  	return tree.NewTypedComparisonExprWithSubOp(tree.Any, cmp, scalarExpr, subqueryExpr), nil
   529  }
   530  
   531  func (b *Builder) buildExistsSubquery(
   532  	ctx *buildScalarCtx, scalar opt.ScalarExpr,
   533  ) (tree.TypedExpr, error) {
   534  	exists := scalar.(*memo.ExistsExpr)
   535  	// We cannot execute correlated subqueries.
   536  	if !exists.Input.Relational().OuterCols.Empty() {
   537  		return nil, b.decorrelationError()
   538  	}
   539  
   540  	// Build the execution plan for the subquery. Note that the subquery could
   541  	// have subqueries of its own which are added to b.subqueries.
   542  	plan, err := b.buildRelational(exists.Input)
   543  	if err != nil {
   544  		return nil, err
   545  	}
   546  
   547  	return b.addSubquery(exec.SubqueryExists, types.Bool, plan.root, exists.OriginalExpr), nil
   548  }
   549  
   550  func (b *Builder) buildSubquery(
   551  	ctx *buildScalarCtx, scalar opt.ScalarExpr,
   552  ) (tree.TypedExpr, error) {
   553  	subquery := scalar.(*memo.SubqueryExpr)
   554  	input := subquery.Input
   555  
   556  	// TODO(radu): for now we only support the trivial projection.
   557  	cols := input.Relational().OutputCols
   558  	if cols.Len() != 1 {
   559  		return nil, errors.Errorf("subquery input with multiple columns")
   560  	}
   561  
   562  	// We cannot execute correlated subqueries.
   563  	if !input.Relational().OuterCols.Empty() {
   564  		return nil, b.decorrelationError()
   565  	}
   566  
   567  	// Build the execution plan for the subquery. Note that the subquery could
   568  	// have subqueries of its own which are added to b.subqueries.
   569  	plan, err := b.buildRelational(input)
   570  	if err != nil {
   571  		return nil, err
   572  	}
   573  
   574  	return b.addSubquery(exec.SubqueryOneRow, subquery.Typ, plan.root, subquery.OriginalExpr), nil
   575  }
   576  
   577  // addSubquery adds an entry to b.subqueries and creates a tree.Subquery
   578  // expression node associated with it.
   579  func (b *Builder) addSubquery(
   580  	mode exec.SubqueryMode, typ *types.T, root exec.Node, originalExpr *tree.Subquery,
   581  ) *tree.Subquery {
   582  	var originalSelect tree.SelectStatement
   583  	if originalExpr != nil {
   584  		originalSelect = originalExpr.Select
   585  	}
   586  	exprNode := &tree.Subquery{
   587  		Select: originalSelect,
   588  		Exists: mode == exec.SubqueryExists,
   589  	}
   590  	exprNode.SetType(typ)
   591  	b.subqueries = append(b.subqueries, exec.Subquery{
   592  		ExprNode: exprNode,
   593  		Mode:     mode,
   594  		Root:     root,
   595  	})
   596  	// Associate the tree.Subquery expression node with this subquery
   597  	// by index (1-based).
   598  	exprNode.Idx = len(b.subqueries)
   599  	return exprNode
   600  }
   601  
   602  func (b *Builder) isConst(expr tree.Expr) bool {
   603  	return b.fastIsConstVisitor.run(expr)
   604  }
   605  
   606  // fastIsConstVisitor determines if an expression is constant by visiting
   607  // at most two levels of the tree (with one exception, see below).
   608  // In essence, it determines whether an expression is constant by checking
   609  // whether its children are const Datums.
   610  //
   611  // This can be used by the execbuilder since constants are evaluated
   612  // bottom-up. If a child is *not* a const Datum, that means it was already
   613  // determined to be non-constant, and therefore was not evaluated.
   614  type fastIsConstVisitor struct {
   615  	isConst bool
   616  
   617  	// visited indicates whether we have already visited one level of the tree.
   618  	// fastIsConstVisitor only visits at most two levels of the tree, with one
   619  	// exception: If the second level has a Cast expression, fastIsConstVisitor
   620  	// may visit three levels.
   621  	visited bool
   622  }
   623  
   624  var _ tree.Visitor = &fastIsConstVisitor{}
   625  
   626  func (v *fastIsConstVisitor) VisitPre(expr tree.Expr) (recurse bool, newExpr tree.Expr) {
   627  	if v.visited {
   628  		if _, ok := expr.(*tree.CastExpr); ok {
   629  			// We recurse one more time for cast expressions, since the
   630  			// execbuilder may have wrapped a NULL.
   631  			return true, expr
   632  		}
   633  		if _, ok := expr.(tree.Datum); !ok || isVar(expr) {
   634  			// If the child expression is not a const Datum, the parent expression is
   635  			// not constant. Note that all constant literals have already been
   636  			// normalized to Datum in TypeCheck.
   637  			v.isConst = false
   638  		}
   639  		return false, expr
   640  	}
   641  	v.visited = true
   642  
   643  	// If the parent expression is a variable or impure function, we know that it
   644  	// is not constant.
   645  
   646  	if isVar(expr) {
   647  		v.isConst = false
   648  		return false, expr
   649  	}
   650  
   651  	switch t := expr.(type) {
   652  	case *tree.FuncExpr:
   653  		if t.IsImpure() {
   654  			v.isConst = false
   655  			return false, expr
   656  		}
   657  	}
   658  
   659  	return true, expr
   660  }
   661  
   662  func (*fastIsConstVisitor) VisitPost(expr tree.Expr) tree.Expr { return expr }
   663  
   664  func (v *fastIsConstVisitor) run(expr tree.Expr) bool {
   665  	v.isConst = true
   666  	v.visited = false
   667  	tree.WalkExprConst(v, expr)
   668  	return v.isConst
   669  }
   670  
   671  // isVar returns true if the expression's value can vary during plan
   672  // execution.
   673  func isVar(expr tree.Expr) bool {
   674  	switch expr.(type) {
   675  	case tree.VariableExpr:
   676  		return true
   677  	case *tree.Placeholder:
   678  		panic(errors.AssertionFailedf("placeholder should have been replaced"))
   679  	}
   680  	return false
   681  }