github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/opt_exec_factory.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 sql
    12  
    13  import (
    14  	"bytes"
    15  	"compress/zlib"
    16  	"context"
    17  	"encoding/base64"
    18  	"fmt"
    19  	"net/url"
    20  	"strings"
    21  
    22  	"github.com/cockroachdb/cockroach/pkg/geo/geoindex"
    23  	"github.com/cockroachdb/cockroach/pkg/sql/execinfra"
    24  	"github.com/cockroachdb/cockroach/pkg/sql/opt"
    25  	"github.com/cockroachdb/cockroach/pkg/sql/opt/cat"
    26  	"github.com/cockroachdb/cockroach/pkg/sql/opt/constraint"
    27  	"github.com/cockroachdb/cockroach/pkg/sql/opt/exec"
    28  	"github.com/cockroachdb/cockroach/pkg/sql/row"
    29  	"github.com/cockroachdb/cockroach/pkg/sql/rowexec"
    30  	"github.com/cockroachdb/cockroach/pkg/sql/sem/builtins"
    31  	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
    32  	"github.com/cockroachdb/cockroach/pkg/sql/span"
    33  	"github.com/cockroachdb/cockroach/pkg/sql/sqlbase"
    34  	"github.com/cockroachdb/cockroach/pkg/sql/types"
    35  	"github.com/cockroachdb/cockroach/pkg/util"
    36  	"github.com/cockroachdb/cockroach/pkg/util/encoding"
    37  	"github.com/cockroachdb/errors"
    38  )
    39  
    40  type execFactory struct {
    41  	planner         *planner
    42  	allowAutoCommit bool
    43  }
    44  
    45  var _ exec.Factory = &execFactory{}
    46  
    47  func newExecFactory(p *planner) *execFactory {
    48  	return &execFactory{
    49  		planner:         p,
    50  		allowAutoCommit: p.autoCommit,
    51  	}
    52  }
    53  
    54  func (ef *execFactory) disableAutoCommit() {
    55  	ef.allowAutoCommit = false
    56  }
    57  
    58  // ConstructValues is part of the exec.Factory interface.
    59  func (ef *execFactory) ConstructValues(
    60  	rows [][]tree.TypedExpr, cols sqlbase.ResultColumns,
    61  ) (exec.Node, error) {
    62  	if len(cols) == 0 && len(rows) == 1 {
    63  		return &unaryNode{}, nil
    64  	}
    65  	if len(rows) == 0 {
    66  		return &zeroNode{columns: cols}, nil
    67  	}
    68  	return &valuesNode{
    69  		columns:          cols,
    70  		tuples:           rows,
    71  		specifiedInQuery: true,
    72  	}, nil
    73  }
    74  
    75  // ConstructScan is part of the exec.Factory interface.
    76  func (ef *execFactory) ConstructScan(
    77  	table cat.Table,
    78  	index cat.Index,
    79  	needed exec.TableColumnOrdinalSet,
    80  	indexConstraint *constraint.Constraint,
    81  	hardLimit int64,
    82  	softLimit int64,
    83  	reverse bool,
    84  	maxResults uint64,
    85  	reqOrdering exec.OutputOrdering,
    86  	rowCount float64,
    87  	locking *tree.LockingItem,
    88  ) (exec.Node, error) {
    89  	if table.IsVirtualTable() {
    90  		return ef.constructVirtualScan(
    91  			table, index, needed, indexConstraint, hardLimit, softLimit, reverse, maxResults,
    92  			reqOrdering, rowCount, locking,
    93  		)
    94  	}
    95  
    96  	tabDesc := table.(*optTable).desc
    97  	indexDesc := index.(*optIndex).desc
    98  	// Create a scanNode.
    99  	scan := ef.planner.Scan()
   100  	colCfg := makeScanColumnsConfig(table, needed)
   101  
   102  	sb := span.MakeBuilder(ef.planner.ExecCfg().Codec, tabDesc.TableDesc(), indexDesc)
   103  
   104  	// initTable checks that the current user has the correct privilege to access
   105  	// the table. However, the privilege has already been checked in optbuilder,
   106  	// and does not need to be rechecked. In fact, it's an error to check the
   107  	// privilege if the table was originally part of a view, since lower privilege
   108  	// users might be able to access a view that uses a higher privilege table.
   109  	ef.planner.skipSelectPrivilegeChecks = true
   110  	defer func() { ef.planner.skipSelectPrivilegeChecks = false }()
   111  	if err := scan.initTable(context.TODO(), ef.planner, tabDesc, nil, colCfg); err != nil {
   112  		return nil, err
   113  	}
   114  
   115  	if indexConstraint != nil && indexConstraint.IsContradiction() {
   116  		return newZeroNode(scan.resultColumns), nil
   117  	}
   118  
   119  	scan.index = indexDesc
   120  	scan.hardLimit = hardLimit
   121  	scan.softLimit = softLimit
   122  
   123  	scan.reverse = reverse
   124  	scan.maxResults = maxResults
   125  	scan.parallelScansEnabled = sqlbase.ParallelScans.Get(&ef.planner.extendedEvalCtx.Settings.SV)
   126  	var err error
   127  	scan.spans, err = sb.SpansFromConstraint(indexConstraint, needed, false /* forDelete */)
   128  	if err != nil {
   129  		return nil, err
   130  	}
   131  	scan.isFull = len(scan.spans) == 1 && scan.spans[0].EqualValue(
   132  		scan.desc.IndexSpan(ef.planner.ExecCfg().Codec, scan.index.ID),
   133  	)
   134  	for i := range reqOrdering {
   135  		if reqOrdering[i].ColIdx >= len(colCfg.wantedColumns) {
   136  			return nil, errors.Errorf("invalid reqOrdering: %v", reqOrdering)
   137  		}
   138  	}
   139  	scan.reqOrdering = ReqOrdering(reqOrdering)
   140  	scan.estimatedRowCount = uint64(rowCount)
   141  	if locking != nil {
   142  		scan.lockingStrength = sqlbase.ToScanLockingStrength(locking.Strength)
   143  		scan.lockingWaitPolicy = sqlbase.ToScanLockingWaitPolicy(locking.WaitPolicy)
   144  	}
   145  	return scan, nil
   146  }
   147  
   148  func (ef *execFactory) constructVirtualScan(
   149  	table cat.Table,
   150  	index cat.Index,
   151  	needed exec.TableColumnOrdinalSet,
   152  	indexConstraint *constraint.Constraint,
   153  	hardLimit int64,
   154  	softLimit int64,
   155  	reverse bool,
   156  	maxResults uint64,
   157  	reqOrdering exec.OutputOrdering,
   158  	rowCount float64,
   159  	locking *tree.LockingItem,
   160  ) (exec.Node, error) {
   161  	tn := &table.(*optVirtualTable).name
   162  	virtual, err := ef.planner.getVirtualTabler().getVirtualTableEntry(tn)
   163  	if err != nil {
   164  		return nil, err
   165  	}
   166  	indexDesc := index.(*optVirtualIndex).desc
   167  	columns, constructor := virtual.getPlanInfo(
   168  		table.(*optVirtualTable).desc.TableDesc(),
   169  		indexDesc, indexConstraint)
   170  
   171  	var n exec.Node
   172  	n = &delayedNode{
   173  		name:            fmt.Sprintf("%s@%s", table.Name(), index.Name()),
   174  		columns:         columns,
   175  		indexConstraint: indexConstraint,
   176  		constructor: func(ctx context.Context, p *planner) (planNode, error) {
   177  			return constructor(ctx, p, tn.Catalog())
   178  		},
   179  	}
   180  
   181  	// Check for explicit use of the dummy column.
   182  	if needed.Contains(0) {
   183  		return nil, errors.Errorf("use of %s column not allowed.", table.Column(0).ColName())
   184  	}
   185  	if locking != nil {
   186  		// We shouldn't have allowed SELECT FOR UPDATE for a virtual table.
   187  		return nil, errors.AssertionFailedf("locking cannot be used with virtual table")
   188  	}
   189  	if needed.Len() != len(columns) {
   190  		// We are selecting a subset of columns; we need a projection.
   191  		cols := make([]exec.NodeColumnOrdinal, 0, needed.Len())
   192  		colNames := make([]string, len(cols))
   193  		for ord, ok := needed.Next(0); ok; ord, ok = needed.Next(ord + 1) {
   194  			cols = append(cols, exec.NodeColumnOrdinal(ord-1))
   195  			colNames = append(colNames, columns[ord-1].Name)
   196  		}
   197  		n, err = ef.ConstructSimpleProject(n, cols, colNames, nil /* reqOrdering */)
   198  		if err != nil {
   199  			return nil, err
   200  		}
   201  	}
   202  	if hardLimit != 0 {
   203  		n, err = ef.ConstructLimit(n, tree.NewDInt(tree.DInt(hardLimit)), nil /* offset */)
   204  		if err != nil {
   205  			return nil, err
   206  		}
   207  	}
   208  	// reqOrdering will be set if the optimizer expects that the output of the
   209  	// exec.Node that we're returning will actually have a legitimate ordering.
   210  	// Virtual indexes never provide a legitimate ordering, so we have to make
   211  	// sure to sort if we have a required ordering.
   212  	if len(reqOrdering) != 0 {
   213  		n, err = ef.ConstructSort(n, sqlbase.ColumnOrdering(reqOrdering), 0)
   214  		if err != nil {
   215  			return nil, err
   216  		}
   217  	}
   218  	return n, nil
   219  }
   220  
   221  func asDataSource(n exec.Node) planDataSource {
   222  	plan := n.(planNode)
   223  	return planDataSource{
   224  		columns: planColumns(plan),
   225  		plan:    plan,
   226  	}
   227  }
   228  
   229  // ConstructFilter is part of the exec.Factory interface.
   230  func (ef *execFactory) ConstructFilter(
   231  	n exec.Node, filter tree.TypedExpr, reqOrdering exec.OutputOrdering,
   232  ) (exec.Node, error) {
   233  	// Push the filter into the scanNode. We cannot do this if the scanNode has a
   234  	// limit (it would make the limit apply AFTER the filter).
   235  	if s, ok := n.(*scanNode); ok && s.filter == nil && s.hardLimit == 0 {
   236  		s.filter = s.filterVars.Rebind(filter, true /* alsoReset */, false /* normalizeToNonNil */)
   237  		// Note: if the filter statically evaluates to true, s.filter stays nil.
   238  		s.reqOrdering = ReqOrdering(reqOrdering)
   239  		return s, nil
   240  	}
   241  	// Create a filterNode.
   242  	src := asDataSource(n)
   243  	f := &filterNode{
   244  		source: src,
   245  	}
   246  	f.ivarHelper = tree.MakeIndexedVarHelper(f, len(src.columns))
   247  	f.filter = f.ivarHelper.Rebind(filter, true /* alsoReset */, false /* normalizeToNonNil */)
   248  	if f.filter == nil {
   249  		// Filter statically evaluates to true. Just return the input plan.
   250  		return n, nil
   251  	}
   252  	f.reqOrdering = ReqOrdering(reqOrdering)
   253  
   254  	// If there's a spool, pull it up.
   255  	if spool, ok := f.source.plan.(*spoolNode); ok {
   256  		f.source.plan = spool.source
   257  		spool.source = f
   258  		return spool, nil
   259  	}
   260  	return f, nil
   261  }
   262  
   263  // ConstructSimpleProject is part of the exec.Factory interface.
   264  func (ef *execFactory) ConstructSimpleProject(
   265  	n exec.Node, cols []exec.NodeColumnOrdinal, colNames []string, reqOrdering exec.OutputOrdering,
   266  ) (exec.Node, error) {
   267  	// If the top node is already a renderNode, just rearrange the columns. But
   268  	// we don't want to duplicate a rendering expression (in case it is expensive
   269  	// to compute or has side-effects); so if we have duplicates we avoid this
   270  	// optimization (and add a new renderNode).
   271  	if r, ok := n.(*renderNode); ok && !hasDuplicates(cols) {
   272  		oldCols, oldRenders := r.columns, r.render
   273  		r.columns = make(sqlbase.ResultColumns, len(cols))
   274  		r.render = make([]tree.TypedExpr, len(cols))
   275  		for i, ord := range cols {
   276  			r.columns[i] = oldCols[ord]
   277  			if colNames != nil {
   278  				r.columns[i].Name = colNames[i]
   279  			}
   280  			r.render[i] = oldRenders[ord]
   281  		}
   282  		r.reqOrdering = ReqOrdering(reqOrdering)
   283  		return r, nil
   284  	}
   285  	var inputCols sqlbase.ResultColumns
   286  	if colNames == nil {
   287  		// We will need the names of the input columns.
   288  		inputCols = planColumns(n.(planNode))
   289  	}
   290  
   291  	var rb renderBuilder
   292  	rb.init(n, reqOrdering)
   293  
   294  	exprs := make(tree.TypedExprs, len(cols))
   295  	resultCols := make(sqlbase.ResultColumns, len(cols))
   296  	for i, col := range cols {
   297  		v := rb.r.ivarHelper.IndexedVar(int(col))
   298  		if colNames == nil {
   299  			resultCols[i] = inputCols[col]
   300  			// If we have a SimpleProject, we should clear the hidden bit on any
   301  			// column since it indicates it's been explicitly selected.
   302  			resultCols[i].Hidden = false
   303  		} else {
   304  			resultCols[i] = sqlbase.ResultColumn{
   305  				Name: colNames[i],
   306  				Typ:  v.ResolvedType(),
   307  			}
   308  		}
   309  		exprs[i] = v
   310  	}
   311  	rb.setOutput(exprs, resultCols)
   312  	return rb.res, nil
   313  }
   314  
   315  func hasDuplicates(cols []exec.NodeColumnOrdinal) bool {
   316  	var set util.FastIntSet
   317  	for _, c := range cols {
   318  		if set.Contains(int(c)) {
   319  			return true
   320  		}
   321  		set.Add(int(c))
   322  	}
   323  	return false
   324  }
   325  
   326  // ConstructRender is part of the exec.Factory interface.
   327  // N.B.: The input exprs will be modified.
   328  func (ef *execFactory) ConstructRender(
   329  	n exec.Node,
   330  	columns sqlbase.ResultColumns,
   331  	exprs tree.TypedExprs,
   332  	reqOrdering exec.OutputOrdering,
   333  ) (exec.Node, error) {
   334  	var rb renderBuilder
   335  	rb.init(n, reqOrdering)
   336  	for i, expr := range exprs {
   337  		expr = rb.r.ivarHelper.Rebind(expr, false /* alsoReset */, true /* normalizeToNonNil */)
   338  		exprs[i] = expr
   339  	}
   340  	rb.setOutput(exprs, columns)
   341  	return rb.res, nil
   342  }
   343  
   344  // RenameColumns is part of the exec.Factory interface.
   345  func (ef *execFactory) RenameColumns(n exec.Node, colNames []string) (exec.Node, error) {
   346  	inputCols := planMutableColumns(n.(planNode))
   347  	for i := range inputCols {
   348  		inputCols[i].Name = colNames[i]
   349  	}
   350  	return n, nil
   351  }
   352  
   353  // ConstructHashJoin is part of the exec.Factory interface.
   354  func (ef *execFactory) ConstructHashJoin(
   355  	joinType sqlbase.JoinType,
   356  	left, right exec.Node,
   357  	leftEqCols, rightEqCols []exec.NodeColumnOrdinal,
   358  	leftEqColsAreKey, rightEqColsAreKey bool,
   359  	extraOnCond tree.TypedExpr,
   360  ) (exec.Node, error) {
   361  	p := ef.planner
   362  	leftSrc := asDataSource(left)
   363  	rightSrc := asDataSource(right)
   364  	pred, err := makePredicate(joinType, leftSrc.columns, rightSrc.columns)
   365  	if err != nil {
   366  		return nil, err
   367  	}
   368  
   369  	numEqCols := len(leftEqCols)
   370  	// Save some allocations by putting both sides in the same slice.
   371  	intBuf := make([]int, 2*numEqCols)
   372  	pred.leftEqualityIndices = intBuf[:numEqCols:numEqCols]
   373  	pred.rightEqualityIndices = intBuf[numEqCols:]
   374  	nameBuf := make(tree.NameList, 2*numEqCols)
   375  	pred.leftColNames = nameBuf[:numEqCols:numEqCols]
   376  	pred.rightColNames = nameBuf[numEqCols:]
   377  
   378  	for i := range leftEqCols {
   379  		pred.leftEqualityIndices[i] = int(leftEqCols[i])
   380  		pred.rightEqualityIndices[i] = int(rightEqCols[i])
   381  		pred.leftColNames[i] = tree.Name(leftSrc.columns[leftEqCols[i]].Name)
   382  		pred.rightColNames[i] = tree.Name(rightSrc.columns[rightEqCols[i]].Name)
   383  	}
   384  	pred.leftEqKey = leftEqColsAreKey
   385  	pred.rightEqKey = rightEqColsAreKey
   386  
   387  	pred.onCond = pred.iVarHelper.Rebind(
   388  		extraOnCond, false /* alsoReset */, false, /* normalizeToNonNil */
   389  	)
   390  
   391  	return p.makeJoinNode(leftSrc, rightSrc, pred), nil
   392  }
   393  
   394  // ConstructApplyJoin is part of the exec.Factory interface.
   395  func (ef *execFactory) ConstructApplyJoin(
   396  	joinType sqlbase.JoinType,
   397  	left exec.Node,
   398  	rightColumns sqlbase.ResultColumns,
   399  	onCond tree.TypedExpr,
   400  	planRightSideFn exec.ApplyJoinPlanRightSideFn,
   401  ) (exec.Node, error) {
   402  	leftSrc := asDataSource(left)
   403  	pred, err := makePredicate(joinType, leftSrc.columns, rightColumns)
   404  	if err != nil {
   405  		return nil, err
   406  	}
   407  	pred.onCond = pred.iVarHelper.Rebind(
   408  		onCond, false /* alsoReset */, false, /* normalizeToNonNil */
   409  	)
   410  	return newApplyJoinNode(joinType, leftSrc, rightColumns, pred, planRightSideFn)
   411  }
   412  
   413  // ConstructMergeJoin is part of the exec.Factory interface.
   414  func (ef *execFactory) ConstructMergeJoin(
   415  	joinType sqlbase.JoinType,
   416  	left, right exec.Node,
   417  	onCond tree.TypedExpr,
   418  	leftOrdering, rightOrdering sqlbase.ColumnOrdering,
   419  	reqOrdering exec.OutputOrdering,
   420  	leftEqColsAreKey, rightEqColsAreKey bool,
   421  ) (exec.Node, error) {
   422  	p := ef.planner
   423  	leftSrc := asDataSource(left)
   424  	rightSrc := asDataSource(right)
   425  	pred, err := makePredicate(joinType, leftSrc.columns, rightSrc.columns)
   426  	if err != nil {
   427  		return nil, err
   428  	}
   429  	pred.onCond = pred.iVarHelper.Rebind(
   430  		onCond, false /* alsoReset */, false, /* normalizeToNonNil */
   431  	)
   432  	pred.leftEqKey = leftEqColsAreKey
   433  	pred.rightEqKey = rightEqColsAreKey
   434  
   435  	n := len(leftOrdering)
   436  	if n == 0 || len(rightOrdering) != n {
   437  		return nil, errors.Errorf("orderings from the left and right side must be the same non-zero length")
   438  	}
   439  	pred.leftEqualityIndices = make([]int, n)
   440  	pred.rightEqualityIndices = make([]int, n)
   441  	pred.leftColNames = make(tree.NameList, n)
   442  	pred.rightColNames = make(tree.NameList, n)
   443  	for i := 0; i < n; i++ {
   444  		leftColIdx, rightColIdx := leftOrdering[i].ColIdx, rightOrdering[i].ColIdx
   445  		pred.leftEqualityIndices[i] = leftColIdx
   446  		pred.rightEqualityIndices[i] = rightColIdx
   447  		pred.leftColNames[i] = tree.Name(leftSrc.columns[leftColIdx].Name)
   448  		pred.rightColNames[i] = tree.Name(rightSrc.columns[rightColIdx].Name)
   449  	}
   450  
   451  	node := p.makeJoinNode(leftSrc, rightSrc, pred)
   452  	node.mergeJoinOrdering = make(sqlbase.ColumnOrdering, n)
   453  	for i := 0; i < n; i++ {
   454  		// The mergeJoinOrdering "columns" are equality column indices.  Because of
   455  		// the way we constructed the equality indices, the ordering will always be
   456  		// 0,1,2,3..
   457  		node.mergeJoinOrdering[i].ColIdx = i
   458  		node.mergeJoinOrdering[i].Direction = leftOrdering[i].Direction
   459  	}
   460  
   461  	// Set up node.props, which tells the distsql planner to maintain the
   462  	// resulting ordering (if needed).
   463  	node.reqOrdering = ReqOrdering(reqOrdering)
   464  
   465  	return node, nil
   466  }
   467  
   468  // ConstructScalarGroupBy is part of the exec.Factory interface.
   469  func (ef *execFactory) ConstructScalarGroupBy(
   470  	input exec.Node, aggregations []exec.AggInfo,
   471  ) (exec.Node, error) {
   472  	n := &groupNode{
   473  		plan:     input.(planNode),
   474  		funcs:    make([]*aggregateFuncHolder, 0, len(aggregations)),
   475  		columns:  make(sqlbase.ResultColumns, 0, len(aggregations)),
   476  		isScalar: true,
   477  	}
   478  	if err := ef.addAggregations(n, aggregations); err != nil {
   479  		return nil, err
   480  	}
   481  	return n, nil
   482  }
   483  
   484  // ConstructGroupBy is part of the exec.Factory interface.
   485  func (ef *execFactory) ConstructGroupBy(
   486  	input exec.Node,
   487  	groupCols []exec.NodeColumnOrdinal,
   488  	groupColOrdering sqlbase.ColumnOrdering,
   489  	aggregations []exec.AggInfo,
   490  	reqOrdering exec.OutputOrdering,
   491  ) (exec.Node, error) {
   492  	n := &groupNode{
   493  		plan:             input.(planNode),
   494  		funcs:            make([]*aggregateFuncHolder, 0, len(groupCols)+len(aggregations)),
   495  		columns:          make(sqlbase.ResultColumns, 0, len(groupCols)+len(aggregations)),
   496  		groupCols:        make([]int, len(groupCols)),
   497  		groupColOrdering: groupColOrdering,
   498  		isScalar:         false,
   499  		reqOrdering:      ReqOrdering(reqOrdering),
   500  	}
   501  	inputCols := planColumns(n.plan)
   502  	for i := range groupCols {
   503  		col := int(groupCols[i])
   504  		n.groupCols[i] = col
   505  
   506  		// TODO(radu): only generate the grouping columns we actually need.
   507  		f := n.newAggregateFuncHolder(
   508  			builtins.AnyNotNull,
   509  			inputCols[col].Typ,
   510  			[]int{col},
   511  			builtins.NewAnyNotNullAggregate,
   512  			nil, /* arguments */
   513  			ef.planner.EvalContext().Mon.MakeBoundAccount(),
   514  		)
   515  		n.funcs = append(n.funcs, f)
   516  		n.columns = append(n.columns, inputCols[col])
   517  	}
   518  	if err := ef.addAggregations(n, aggregations); err != nil {
   519  		return nil, err
   520  	}
   521  	return n, nil
   522  }
   523  
   524  func (ef *execFactory) addAggregations(n *groupNode, aggregations []exec.AggInfo) error {
   525  	inputCols := planColumns(n.plan)
   526  	for i := range aggregations {
   527  		agg := &aggregations[i]
   528  		builtin := agg.Builtin
   529  		renderIdxs := make([]int, len(agg.ArgCols))
   530  		params := make([]*types.T, len(agg.ArgCols))
   531  		for j, col := range agg.ArgCols {
   532  			renderIdx := int(col)
   533  			renderIdxs[j] = renderIdx
   534  			params[j] = inputCols[renderIdx].Typ
   535  		}
   536  		aggFn := func(evalCtx *tree.EvalContext, arguments tree.Datums) tree.AggregateFunc {
   537  			return builtin.AggregateFunc(params, evalCtx, arguments)
   538  		}
   539  
   540  		f := n.newAggregateFuncHolder(
   541  			agg.FuncName,
   542  			agg.ResultType,
   543  			renderIdxs,
   544  			aggFn,
   545  			agg.ConstArgs,
   546  			ef.planner.EvalContext().Mon.MakeBoundAccount(),
   547  		)
   548  		if agg.Distinct {
   549  			f.setDistinct()
   550  		}
   551  
   552  		if agg.Filter == -1 {
   553  			// A value of -1 means the aggregate had no filter.
   554  			f.filterRenderIdx = noRenderIdx
   555  		} else {
   556  			f.filterRenderIdx = int(agg.Filter)
   557  		}
   558  
   559  		n.funcs = append(n.funcs, f)
   560  		n.columns = append(n.columns, sqlbase.ResultColumn{
   561  			Name: agg.FuncName,
   562  			Typ:  agg.ResultType,
   563  		})
   564  	}
   565  	return nil
   566  }
   567  
   568  // ConstructDistinct is part of the exec.Factory interface.
   569  func (ef *execFactory) ConstructDistinct(
   570  	input exec.Node,
   571  	distinctCols, orderedCols exec.NodeColumnOrdinalSet,
   572  	reqOrdering exec.OutputOrdering,
   573  	nullsAreDistinct bool,
   574  	errorOnDup string,
   575  ) (exec.Node, error) {
   576  	return &distinctNode{
   577  		plan:              input.(planNode),
   578  		distinctOnColIdxs: distinctCols,
   579  		columnsInOrder:    orderedCols,
   580  		reqOrdering:       ReqOrdering(reqOrdering),
   581  		nullsAreDistinct:  nullsAreDistinct,
   582  		errorOnDup:        errorOnDup,
   583  	}, nil
   584  }
   585  
   586  // ConstructSetOp is part of the exec.Factory interface.
   587  func (ef *execFactory) ConstructSetOp(
   588  	typ tree.UnionType, all bool, left, right exec.Node,
   589  ) (exec.Node, error) {
   590  	return ef.planner.newUnionNode(typ, all, left.(planNode), right.(planNode))
   591  }
   592  
   593  // ConstructSort is part of the exec.Factory interface.
   594  func (ef *execFactory) ConstructSort(
   595  	input exec.Node, ordering sqlbase.ColumnOrdering, alreadyOrderedPrefix int,
   596  ) (exec.Node, error) {
   597  	return &sortNode{
   598  		plan:                 input.(planNode),
   599  		ordering:             ordering,
   600  		alreadyOrderedPrefix: alreadyOrderedPrefix,
   601  	}, nil
   602  }
   603  
   604  // ConstructOrdinality is part of the exec.Factory interface.
   605  func (ef *execFactory) ConstructOrdinality(input exec.Node, colName string) (exec.Node, error) {
   606  	plan := input.(planNode)
   607  	inputColumns := planColumns(plan)
   608  	cols := make(sqlbase.ResultColumns, len(inputColumns)+1)
   609  	copy(cols, inputColumns)
   610  	cols[len(cols)-1] = sqlbase.ResultColumn{
   611  		Name: colName,
   612  		Typ:  types.Int,
   613  	}
   614  	return &ordinalityNode{
   615  		source:  plan,
   616  		columns: cols,
   617  		run: ordinalityRun{
   618  			row:    make(tree.Datums, len(cols)),
   619  			curCnt: 1,
   620  		},
   621  	}, nil
   622  }
   623  
   624  // ConstructIndexJoin is part of the exec.Factory interface.
   625  func (ef *execFactory) ConstructIndexJoin(
   626  	input exec.Node,
   627  	table cat.Table,
   628  	keyCols []exec.NodeColumnOrdinal,
   629  	tableCols exec.TableColumnOrdinalSet,
   630  	reqOrdering exec.OutputOrdering,
   631  ) (exec.Node, error) {
   632  	tabDesc := table.(*optTable).desc
   633  	colCfg := makeScanColumnsConfig(table, tableCols)
   634  	colDescs := makeColDescList(table, tableCols)
   635  
   636  	tableScan := ef.planner.Scan()
   637  
   638  	if err := tableScan.initTable(context.TODO(), ef.planner, tabDesc, nil, colCfg); err != nil {
   639  		return nil, err
   640  	}
   641  
   642  	primaryIndex := tabDesc.GetPrimaryIndex()
   643  	tableScan.index = &primaryIndex
   644  	tableScan.disableBatchLimit()
   645  
   646  	n := &indexJoinNode{
   647  		input:         input.(planNode),
   648  		table:         tableScan,
   649  		cols:          colDescs,
   650  		resultColumns: sqlbase.ResultColumnsFromColDescs(tabDesc.GetID(), colDescs),
   651  		reqOrdering:   ReqOrdering(reqOrdering),
   652  	}
   653  
   654  	n.keyCols = make([]int, len(keyCols))
   655  	for i, c := range keyCols {
   656  		n.keyCols[i] = int(c)
   657  	}
   658  
   659  	return n, nil
   660  }
   661  
   662  // ConstructLookupJoin is part of the exec.Factory interface.
   663  func (ef *execFactory) ConstructLookupJoin(
   664  	joinType sqlbase.JoinType,
   665  	input exec.Node,
   666  	table cat.Table,
   667  	index cat.Index,
   668  	eqCols []exec.NodeColumnOrdinal,
   669  	eqColsAreKey bool,
   670  	lookupCols exec.TableColumnOrdinalSet,
   671  	onCond tree.TypedExpr,
   672  	reqOrdering exec.OutputOrdering,
   673  ) (exec.Node, error) {
   674  	if table.IsVirtualTable() {
   675  		return ef.constructVirtualTableLookupJoin(joinType, input, table, index, eqCols, lookupCols, onCond)
   676  	}
   677  	tabDesc := table.(*optTable).desc
   678  	indexDesc := index.(*optIndex).desc
   679  	colCfg := makeScanColumnsConfig(table, lookupCols)
   680  	tableScan := ef.planner.Scan()
   681  
   682  	if err := tableScan.initTable(context.TODO(), ef.planner, tabDesc, nil, colCfg); err != nil {
   683  		return nil, err
   684  	}
   685  
   686  	tableScan.index = indexDesc
   687  
   688  	n := &lookupJoinNode{
   689  		input:        input.(planNode),
   690  		table:        tableScan,
   691  		joinType:     joinType,
   692  		eqColsAreKey: eqColsAreKey,
   693  		reqOrdering:  ReqOrdering(reqOrdering),
   694  	}
   695  	if onCond != nil && onCond != tree.DBoolTrue {
   696  		n.onCond = onCond
   697  	}
   698  	n.eqCols = make([]int, len(eqCols))
   699  	for i, c := range eqCols {
   700  		n.eqCols[i] = int(c)
   701  	}
   702  	// Build the result columns.
   703  	inputCols := planColumns(input.(planNode))
   704  	var scanCols sqlbase.ResultColumns
   705  	if joinType != sqlbase.LeftSemiJoin && joinType != sqlbase.LeftAntiJoin {
   706  		scanCols = planColumns(tableScan)
   707  	}
   708  	n.columns = make(sqlbase.ResultColumns, 0, len(inputCols)+len(scanCols))
   709  	n.columns = append(n.columns, inputCols...)
   710  	n.columns = append(n.columns, scanCols...)
   711  	return n, nil
   712  }
   713  
   714  func (ef *execFactory) constructVirtualTableLookupJoin(
   715  	joinType sqlbase.JoinType,
   716  	input exec.Node,
   717  	table cat.Table,
   718  	index cat.Index,
   719  	eqCols []exec.NodeColumnOrdinal,
   720  	lookupCols exec.TableColumnOrdinalSet,
   721  	onCond tree.TypedExpr,
   722  ) (exec.Node, error) {
   723  	tn := &table.(*optVirtualTable).name
   724  	virtual, err := ef.planner.getVirtualTabler().getVirtualTableEntry(tn)
   725  	if err != nil {
   726  		return nil, err
   727  	}
   728  	if len(eqCols) > 1 {
   729  		return nil, errors.AssertionFailedf("vtable indexes with more than one column aren't supported yet")
   730  	}
   731  	// Check for explicit use of the dummy column.
   732  	if lookupCols.Contains(0) {
   733  		return nil, errors.Errorf("use of %s column not allowed.", table.Column(0).ColName())
   734  	}
   735  	indexDesc := index.(*optVirtualIndex).desc
   736  	tableDesc := table.(*optVirtualTable).desc
   737  	// Build the result columns.
   738  	inputCols := planColumns(input.(planNode))
   739  
   740  	if onCond == tree.DBoolTrue {
   741  		onCond = nil
   742  	}
   743  
   744  	var tableScan scanNode
   745  	// Set up a scanNode that we won't actually use, just to get the needed
   746  	// column analysis.
   747  	colCfg := makeScanColumnsConfig(table, lookupCols)
   748  	if err := tableScan.initTable(context.TODO(), ef.planner, tableDesc, nil, colCfg); err != nil {
   749  		return nil, err
   750  	}
   751  	tableScan.index = indexDesc
   752  	vtableCols := sqlbase.ResultColumnsFromColDescs(tableDesc.ID, tableDesc.Columns)
   753  	projectedVtableCols := planColumns(&tableScan)
   754  	outputCols := make(sqlbase.ResultColumns, 0, len(inputCols)+len(projectedVtableCols))
   755  	outputCols = append(outputCols, inputCols...)
   756  	outputCols = append(outputCols, projectedVtableCols...)
   757  	// joinType is either INNER or LEFT_OUTER.
   758  	pred, err := makePredicate(joinType, inputCols, projectedVtableCols)
   759  	if err != nil {
   760  		return nil, err
   761  	}
   762  	pred.onCond = pred.iVarHelper.Rebind(
   763  		onCond, false /* alsoReset */, false, /* normalizeToNonNil */
   764  	)
   765  	n := &vTableLookupJoinNode{
   766  		input:             input.(planNode),
   767  		joinType:          joinType,
   768  		virtualTableEntry: virtual,
   769  		dbName:            tn.Catalog(),
   770  		table:             tableDesc.TableDesc(),
   771  		index:             indexDesc,
   772  		eqCol:             int(eqCols[0]),
   773  		inputCols:         inputCols,
   774  		vtableCols:        vtableCols,
   775  		lookupCols:        lookupCols,
   776  		columns:           outputCols,
   777  		pred:              pred,
   778  	}
   779  	return n, nil
   780  }
   781  
   782  func (ef *execFactory) ConstructGeoLookupJoin(
   783  	joinType sqlbase.JoinType,
   784  	geoRelationshipType geoindex.RelationshipType,
   785  	input exec.Node,
   786  	table cat.Table,
   787  	index cat.Index,
   788  	geoCol exec.NodeColumnOrdinal,
   789  	lookupCols exec.TableColumnOrdinalSet,
   790  	onCond tree.TypedExpr,
   791  	reqOrdering exec.OutputOrdering,
   792  ) (exec.Node, error) {
   793  	// TODO(rytaft, sumeerbhola): Fill this in.
   794  	return nil, errors.Errorf("Geospatial joins are not yet supported")
   795  }
   796  
   797  // Helper function to create a scanNode from just a table / index descriptor
   798  // and requested cols.
   799  func (ef *execFactory) constructScanForZigzag(
   800  	indexDesc *sqlbase.IndexDescriptor,
   801  	tableDesc *sqlbase.ImmutableTableDescriptor,
   802  	cols exec.NodeColumnOrdinalSet,
   803  ) (*scanNode, error) {
   804  
   805  	colCfg := scanColumnsConfig{
   806  		wantedColumns: make([]tree.ColumnID, 0, cols.Len()),
   807  	}
   808  
   809  	for c, ok := cols.Next(0); ok; c, ok = cols.Next(c + 1) {
   810  		colCfg.wantedColumns = append(colCfg.wantedColumns, tree.ColumnID(tableDesc.Columns[c].ID))
   811  	}
   812  
   813  	scan := ef.planner.Scan()
   814  	if err := scan.initTable(context.TODO(), ef.planner, tableDesc, nil, colCfg); err != nil {
   815  		return nil, err
   816  	}
   817  
   818  	scan.index = indexDesc
   819  
   820  	return scan, nil
   821  }
   822  
   823  // ConstructZigzagJoin is part of the exec.Factory interface.
   824  func (ef *execFactory) ConstructZigzagJoin(
   825  	leftTable cat.Table,
   826  	leftIndex cat.Index,
   827  	rightTable cat.Table,
   828  	rightIndex cat.Index,
   829  	leftEqCols []exec.NodeColumnOrdinal,
   830  	rightEqCols []exec.NodeColumnOrdinal,
   831  	leftCols exec.NodeColumnOrdinalSet,
   832  	rightCols exec.NodeColumnOrdinalSet,
   833  	onCond tree.TypedExpr,
   834  	fixedVals []exec.Node,
   835  	reqOrdering exec.OutputOrdering,
   836  ) (exec.Node, error) {
   837  	leftIndexDesc := leftIndex.(*optIndex).desc
   838  	leftTabDesc := leftTable.(*optTable).desc
   839  	rightIndexDesc := rightIndex.(*optIndex).desc
   840  	rightTabDesc := rightTable.(*optTable).desc
   841  
   842  	leftScan, err := ef.constructScanForZigzag(leftIndexDesc, leftTabDesc, leftCols)
   843  	if err != nil {
   844  		return nil, err
   845  	}
   846  	rightScan, err := ef.constructScanForZigzag(rightIndexDesc, rightTabDesc, rightCols)
   847  	if err != nil {
   848  		return nil, err
   849  	}
   850  
   851  	n := &zigzagJoinNode{
   852  		reqOrdering: ReqOrdering(reqOrdering),
   853  	}
   854  	if onCond != nil && onCond != tree.DBoolTrue {
   855  		n.onCond = onCond
   856  	}
   857  	n.sides = make([]zigzagJoinSide, 2)
   858  	n.sides[0].scan = leftScan
   859  	n.sides[1].scan = rightScan
   860  	n.sides[0].eqCols = make([]int, len(leftEqCols))
   861  	n.sides[1].eqCols = make([]int, len(rightEqCols))
   862  
   863  	if len(leftEqCols) != len(rightEqCols) {
   864  		panic("creating zigzag join with unequal number of equated cols")
   865  	}
   866  
   867  	for i, c := range leftEqCols {
   868  		n.sides[0].eqCols[i] = int(c)
   869  		n.sides[1].eqCols[i] = int(rightEqCols[i])
   870  	}
   871  	// The resultant columns are identical to those from individual index scans; so
   872  	// reuse the resultColumns generated in the scanNodes.
   873  	n.columns = make(
   874  		sqlbase.ResultColumns,
   875  		0,
   876  		len(leftScan.resultColumns)+len(rightScan.resultColumns),
   877  	)
   878  	n.columns = append(n.columns, leftScan.resultColumns...)
   879  	n.columns = append(n.columns, rightScan.resultColumns...)
   880  
   881  	// Fixed values are the values fixed for a prefix of each side's index columns.
   882  	// See the comment in pkg/sql/rowexec/zigzagjoiner.go for how they are used.
   883  	for i := range fixedVals {
   884  		valNode, ok := fixedVals[i].(*valuesNode)
   885  		if !ok {
   886  			panic("non-values node passed as fixed value to zigzag join")
   887  		}
   888  		if i >= len(n.sides) {
   889  			panic("more fixed values passed than zigzag join sides")
   890  		}
   891  		n.sides[i].fixedVals = valNode
   892  	}
   893  	return n, nil
   894  }
   895  
   896  // ConstructLimit is part of the exec.Factory interface.
   897  func (ef *execFactory) ConstructLimit(
   898  	input exec.Node, limit, offset tree.TypedExpr,
   899  ) (exec.Node, error) {
   900  	plan := input.(planNode)
   901  	// If the input plan is also a limitNode that has just an offset, and we are
   902  	// only applying a limit, update the existing node. This is useful because
   903  	// Limit and Offset are separate operators which result in separate calls to
   904  	// this function.
   905  	if l, ok := plan.(*limitNode); ok && l.countExpr == nil && offset == nil {
   906  		l.countExpr = limit
   907  		return l, nil
   908  	}
   909  	// If the input plan is a spoolNode, then propagate any constant limit to it.
   910  	if spool, ok := plan.(*spoolNode); ok {
   911  		if val, ok := limit.(*tree.DInt); ok {
   912  			spool.hardLimit = int64(*val)
   913  		}
   914  	}
   915  	return &limitNode{
   916  		plan:       plan,
   917  		countExpr:  limit,
   918  		offsetExpr: offset,
   919  	}, nil
   920  }
   921  
   922  // ConstructMax1Row is part of the exec.Factory interface.
   923  func (ef *execFactory) ConstructMax1Row(input exec.Node, errorText string) (exec.Node, error) {
   924  	plan := input.(planNode)
   925  	return &max1RowNode{
   926  		plan:      plan,
   927  		errorText: errorText,
   928  	}, nil
   929  }
   930  
   931  // ConstructBuffer is part of the exec.Factory interface.
   932  func (ef *execFactory) ConstructBuffer(input exec.Node, label string) (exec.BufferNode, error) {
   933  	return &bufferNode{
   934  		plan:  input.(planNode),
   935  		label: label,
   936  	}, nil
   937  }
   938  
   939  // ConstructScanBuffer is part of the exec.Factory interface.
   940  func (ef *execFactory) ConstructScanBuffer(ref exec.BufferNode, label string) (exec.Node, error) {
   941  	return &scanBufferNode{
   942  		buffer: ref.(*bufferNode),
   943  		label:  label,
   944  	}, nil
   945  }
   946  
   947  // ConstructRecursiveCTE is part of the exec.Factory interface.
   948  func (ef *execFactory) ConstructRecursiveCTE(
   949  	initial exec.Node, fn exec.RecursiveCTEIterationFn, label string,
   950  ) (exec.Node, error) {
   951  	return &recursiveCTENode{
   952  		initial:        initial.(planNode),
   953  		genIterationFn: fn,
   954  		label:          label,
   955  	}, nil
   956  }
   957  
   958  // ConstructProjectSet is part of the exec.Factory interface.
   959  func (ef *execFactory) ConstructProjectSet(
   960  	n exec.Node, exprs tree.TypedExprs, zipCols sqlbase.ResultColumns, numColsPerGen []int,
   961  ) (exec.Node, error) {
   962  	src := asDataSource(n)
   963  	cols := append(src.columns, zipCols...)
   964  	p := &projectSetNode{
   965  		source:          src.plan,
   966  		sourceCols:      src.columns,
   967  		columns:         cols,
   968  		numColsInSource: len(src.columns),
   969  		exprs:           exprs,
   970  		funcs:           make([]*tree.FuncExpr, len(exprs)),
   971  		numColsPerGen:   numColsPerGen,
   972  		run: projectSetRun{
   973  			gens:      make([]tree.ValueGenerator, len(exprs)),
   974  			done:      make([]bool, len(exprs)),
   975  			rowBuffer: make(tree.Datums, len(cols)),
   976  		},
   977  	}
   978  
   979  	for i, expr := range exprs {
   980  		if tFunc, ok := expr.(*tree.FuncExpr); ok && tFunc.IsGeneratorApplication() {
   981  			// Set-generating functions: generate_series() etc.
   982  			p.funcs[i] = tFunc
   983  		}
   984  	}
   985  
   986  	return p, nil
   987  }
   988  
   989  // ConstructWindow is part of the exec.Factory interface.
   990  func (ef *execFactory) ConstructWindow(root exec.Node, wi exec.WindowInfo) (exec.Node, error) {
   991  	p := &windowNode{
   992  		plan:         root.(planNode),
   993  		columns:      wi.Cols,
   994  		windowRender: make([]tree.TypedExpr, len(wi.Cols)),
   995  	}
   996  
   997  	partitionIdxs := make([]int, len(wi.Partition))
   998  	for i, idx := range wi.Partition {
   999  		partitionIdxs[i] = int(idx)
  1000  	}
  1001  
  1002  	p.funcs = make([]*windowFuncHolder, len(wi.Exprs))
  1003  	for i := range wi.Exprs {
  1004  		argsIdxs := make([]uint32, len(wi.ArgIdxs[i]))
  1005  		for j := range argsIdxs {
  1006  			argsIdxs[j] = uint32(wi.ArgIdxs[i][j])
  1007  		}
  1008  
  1009  		p.funcs[i] = &windowFuncHolder{
  1010  			expr:           wi.Exprs[i],
  1011  			args:           wi.Exprs[i].Exprs,
  1012  			argsIdxs:       argsIdxs,
  1013  			window:         p,
  1014  			filterColIdx:   wi.FilterIdxs[i],
  1015  			outputColIdx:   wi.OutputIdxs[i],
  1016  			partitionIdxs:  partitionIdxs,
  1017  			columnOrdering: wi.Ordering,
  1018  			frame:          wi.Exprs[i].WindowDef.Frame,
  1019  		}
  1020  		if len(wi.Ordering) == 0 {
  1021  			frame := p.funcs[i].frame
  1022  			if frame.Mode == tree.RANGE && frame.Bounds.HasOffset() {
  1023  				// We have an empty ordering, but RANGE mode when at least one bound
  1024  				// has 'offset' requires a single column in ORDER BY. We have optimized
  1025  				// it out, but the execution still needs information about which column
  1026  				// it was, so we reconstruct the "original" ordering (note that the
  1027  				// direction of the ordering doesn't actually matter, so we leave it
  1028  				// with the default value).
  1029  				p.funcs[i].columnOrdering = sqlbase.ColumnOrdering{
  1030  					sqlbase.ColumnOrderInfo{
  1031  						ColIdx: int(wi.RangeOffsetColumn),
  1032  					},
  1033  				}
  1034  			}
  1035  		}
  1036  
  1037  		p.windowRender[wi.OutputIdxs[i]] = p.funcs[i]
  1038  	}
  1039  
  1040  	return p, nil
  1041  }
  1042  
  1043  // ConstructPlan is part of the exec.Factory interface.
  1044  func (ef *execFactory) ConstructPlan(
  1045  	root exec.Node, subqueries []exec.Subquery, cascades []exec.Cascade, checks []exec.Node,
  1046  ) (exec.Plan, error) {
  1047  	// No need to spool at the root.
  1048  	if spool, ok := root.(*spoolNode); ok {
  1049  		root = spool.source
  1050  	}
  1051  	res := &planTop{
  1052  		// TODO(radu): these fields can be modified by planning various opaque
  1053  		// statements. We should have a cleaner way of plumbing these.
  1054  		avoidBuffering:  ef.planner.curPlan.avoidBuffering,
  1055  		auditEvents:     ef.planner.curPlan.auditEvents,
  1056  		instrumentation: ef.planner.curPlan.instrumentation,
  1057  	}
  1058  	res.main.planNode = root.(planNode)
  1059  	if len(subqueries) > 0 {
  1060  		res.subqueryPlans = make([]subquery, len(subqueries))
  1061  		for i := range subqueries {
  1062  			in := &subqueries[i]
  1063  			out := &res.subqueryPlans[i]
  1064  			out.subquery = in.ExprNode
  1065  			switch in.Mode {
  1066  			case exec.SubqueryExists:
  1067  				out.execMode = rowexec.SubqueryExecModeExists
  1068  			case exec.SubqueryOneRow:
  1069  				out.execMode = rowexec.SubqueryExecModeOneRow
  1070  			case exec.SubqueryAnyRows:
  1071  				out.execMode = rowexec.SubqueryExecModeAllRowsNormalized
  1072  			case exec.SubqueryAllRows:
  1073  				out.execMode = rowexec.SubqueryExecModeAllRows
  1074  			default:
  1075  				return nil, errors.Errorf("invalid SubqueryMode %d", in.Mode)
  1076  			}
  1077  			out.expanded = true
  1078  			out.plan.planNode = in.Root.(planNode)
  1079  		}
  1080  	}
  1081  	if len(cascades) > 0 {
  1082  		res.cascades = make([]cascadeMetadata, len(cascades))
  1083  		for i := range cascades {
  1084  			res.cascades[i].Cascade = cascades[i]
  1085  		}
  1086  	}
  1087  	if len(checks) > 0 {
  1088  		res.checkPlans = make([]checkPlan, len(checks))
  1089  		for i := range checks {
  1090  			res.checkPlans[i].plan.planNode = checks[i].(planNode)
  1091  		}
  1092  	}
  1093  
  1094  	return res, nil
  1095  }
  1096  
  1097  // urlOutputter handles writing strings into an encoded URL for EXPLAIN (OPT,
  1098  // ENV). It also ensures that (in the text that is encoded by the URL) each
  1099  // entry gets its own line and there's exactly one blank line between entries.
  1100  type urlOutputter struct {
  1101  	buf bytes.Buffer
  1102  }
  1103  
  1104  func (e *urlOutputter) writef(format string, args ...interface{}) {
  1105  	if e.buf.Len() > 0 {
  1106  		e.buf.WriteString("\n")
  1107  	}
  1108  	fmt.Fprintf(&e.buf, format, args...)
  1109  }
  1110  
  1111  func (e *urlOutputter) finish() (url.URL, error) {
  1112  	// Generate a URL that encodes all the text.
  1113  	var compressed bytes.Buffer
  1114  	encoder := base64.NewEncoder(base64.URLEncoding, &compressed)
  1115  	compressor := zlib.NewWriter(encoder)
  1116  	if _, err := e.buf.WriteTo(compressor); err != nil {
  1117  		return url.URL{}, err
  1118  	}
  1119  	if err := compressor.Close(); err != nil {
  1120  		return url.URL{}, err
  1121  	}
  1122  	if err := encoder.Close(); err != nil {
  1123  		return url.URL{}, err
  1124  	}
  1125  	return url.URL{
  1126  		Scheme:   "https",
  1127  		Host:     "cockroachdb.github.io",
  1128  		Path:     "text/decode.html",
  1129  		Fragment: compressed.String(),
  1130  	}, nil
  1131  }
  1132  
  1133  // showEnv implements EXPLAIN (opt, env). It returns a node which displays
  1134  // the environment a query was run in.
  1135  func (ef *execFactory) showEnv(plan string, envOpts exec.ExplainEnvData) (exec.Node, error) {
  1136  	var out urlOutputter
  1137  
  1138  	c := makeStmtEnvCollector(
  1139  		ef.planner.EvalContext().Context,
  1140  		ef.planner.extendedEvalCtx.InternalExecutor.(*InternalExecutor),
  1141  	)
  1142  
  1143  	// Show the version of Cockroach running.
  1144  	if err := c.PrintVersion(&out.buf); err != nil {
  1145  		return nil, err
  1146  	}
  1147  	out.writef("")
  1148  	// Show the values of any non-default session variables that can impact
  1149  	// planning decisions.
  1150  	if err := c.PrintSettings(&out.buf); err != nil {
  1151  		return nil, err
  1152  	}
  1153  
  1154  	// Show the definition of each referenced catalog object.
  1155  	for i := range envOpts.Sequences {
  1156  		out.writef("")
  1157  		if err := c.PrintCreateSequence(&out.buf, &envOpts.Sequences[i]); err != nil {
  1158  			return nil, err
  1159  		}
  1160  	}
  1161  
  1162  	// TODO(justin): it might also be relevant in some cases to print the create
  1163  	// statements for tables referenced via FKs in these tables.
  1164  	for i := range envOpts.Tables {
  1165  		out.writef("")
  1166  		if err := c.PrintCreateTable(&out.buf, &envOpts.Tables[i]); err != nil {
  1167  			return nil, err
  1168  		}
  1169  		out.writef("")
  1170  
  1171  		// In addition to the schema, it's important to know what the table
  1172  		// statistics on each table are.
  1173  
  1174  		// NOTE: We don't include the histograms because they take up a ton of
  1175  		// vertical space. Unfortunately this means that in some cases we won't be
  1176  		// able to reproduce a particular plan.
  1177  		err := c.PrintTableStats(&out.buf, &envOpts.Tables[i], true /* hideHistograms */)
  1178  		if err != nil {
  1179  			return nil, err
  1180  		}
  1181  	}
  1182  
  1183  	for i := range envOpts.Views {
  1184  		out.writef("")
  1185  		if err := c.PrintCreateView(&out.buf, &envOpts.Views[i]); err != nil {
  1186  			return nil, err
  1187  		}
  1188  	}
  1189  
  1190  	// Show the query running. Note that this is the *entire* query, including
  1191  	// the "EXPLAIN (opt, env)" preamble.
  1192  	out.writef("%s;\n----\n%s", ef.planner.stmt.AST.String(), plan)
  1193  
  1194  	url, err := out.finish()
  1195  	if err != nil {
  1196  		return nil, err
  1197  	}
  1198  	return &valuesNode{
  1199  		columns:          sqlbase.ExplainOptColumns,
  1200  		tuples:           [][]tree.TypedExpr{{tree.NewDString(url.String())}},
  1201  		specifiedInQuery: true,
  1202  	}, nil
  1203  }
  1204  
  1205  // ConstructExplainOpt is part of the exec.Factory interface.
  1206  func (ef *execFactory) ConstructExplainOpt(
  1207  	planText string, envOpts exec.ExplainEnvData,
  1208  ) (exec.Node, error) {
  1209  	// If this was an EXPLAIN (opt, env), we need to run a bunch of auxiliary
  1210  	// queries to fetch the environment info.
  1211  	if envOpts.ShowEnv {
  1212  		return ef.showEnv(planText, envOpts)
  1213  	}
  1214  
  1215  	var rows [][]tree.TypedExpr
  1216  	ss := strings.Split(strings.Trim(planText, "\n"), "\n")
  1217  	for _, line := range ss {
  1218  		rows = append(rows, []tree.TypedExpr{tree.NewDString(line)})
  1219  	}
  1220  
  1221  	return &valuesNode{
  1222  		columns:          sqlbase.ExplainOptColumns,
  1223  		tuples:           rows,
  1224  		specifiedInQuery: true,
  1225  	}, nil
  1226  }
  1227  
  1228  // ConstructExplain is part of the exec.Factory interface.
  1229  func (ef *execFactory) ConstructExplain(
  1230  	options *tree.ExplainOptions, stmtType tree.StatementType, plan exec.Plan,
  1231  ) (exec.Node, error) {
  1232  	p := plan.(*planTop)
  1233  
  1234  	analyzeSet := options.Flags[tree.ExplainFlagAnalyze]
  1235  
  1236  	if options.Flags[tree.ExplainFlagEnv] {
  1237  		return nil, errors.New("ENV only supported with (OPT) option")
  1238  	}
  1239  
  1240  	switch options.Mode {
  1241  	case tree.ExplainDistSQL:
  1242  		return &explainDistSQLNode{
  1243  			options:  options,
  1244  			plan:     p.planComponents,
  1245  			analyze:  analyzeSet,
  1246  			stmtType: stmtType,
  1247  		}, nil
  1248  
  1249  	case tree.ExplainVec:
  1250  		return &explainVecNode{
  1251  			options:       options,
  1252  			plan:          p.main,
  1253  			subqueryPlans: p.subqueryPlans,
  1254  			stmtType:      stmtType,
  1255  		}, nil
  1256  
  1257  	case tree.ExplainPlan:
  1258  		if analyzeSet {
  1259  			return nil, errors.New("EXPLAIN ANALYZE only supported with (DISTSQL) option")
  1260  		}
  1261  		return ef.planner.makeExplainPlanNodeWithPlan(
  1262  			context.TODO(),
  1263  			options,
  1264  			&p.planComponents,
  1265  			stmtType,
  1266  		)
  1267  
  1268  	default:
  1269  		panic(fmt.Sprintf("unsupported explain mode %v", options.Mode))
  1270  	}
  1271  }
  1272  
  1273  // ConstructShowTrace is part of the exec.Factory interface.
  1274  func (ef *execFactory) ConstructShowTrace(typ tree.ShowTraceType, compact bool) (exec.Node, error) {
  1275  	var node planNode = ef.planner.makeShowTraceNode(compact, typ == tree.ShowTraceKV)
  1276  
  1277  	// Ensure the messages are sorted in age order, so that the user
  1278  	// does not get confused.
  1279  	ageColIdx := sqlbase.GetTraceAgeColumnIdx(compact)
  1280  	node = &sortNode{
  1281  		plan: node,
  1282  		ordering: sqlbase.ColumnOrdering{
  1283  			sqlbase.ColumnOrderInfo{ColIdx: ageColIdx, Direction: encoding.Ascending},
  1284  		},
  1285  	}
  1286  
  1287  	if typ == tree.ShowTraceReplica {
  1288  		node = &showTraceReplicaNode{plan: node}
  1289  	}
  1290  	return node, nil
  1291  }
  1292  
  1293  func (ef *execFactory) ConstructInsert(
  1294  	input exec.Node,
  1295  	table cat.Table,
  1296  	insertColOrdSet exec.TableColumnOrdinalSet,
  1297  	returnColOrdSet exec.TableColumnOrdinalSet,
  1298  	checkOrdSet exec.CheckOrdinalSet,
  1299  	allowAutoCommit bool,
  1300  	skipFKChecks bool,
  1301  ) (exec.Node, error) {
  1302  	ctx := ef.planner.extendedEvalCtx.Context
  1303  
  1304  	// Derive insert table and column descriptors.
  1305  	rowsNeeded := !returnColOrdSet.Empty()
  1306  	tabDesc := table.(*optTable).desc
  1307  	colDescs := makeColDescList(table, insertColOrdSet)
  1308  
  1309  	if err := ef.planner.maybeSetSystemConfig(tabDesc.GetID()); err != nil {
  1310  		return nil, err
  1311  	}
  1312  
  1313  	var fkTables row.FkTableMetadata
  1314  	checkFKs := row.SkipFKs
  1315  	if !skipFKChecks {
  1316  		checkFKs = row.CheckFKs
  1317  		// Determine the foreign key tables involved in the update.
  1318  		var err error
  1319  		fkTables, err = ef.makeFkMetadata(tabDesc, row.CheckInserts)
  1320  		if err != nil {
  1321  			return nil, err
  1322  		}
  1323  	}
  1324  	// Create the table inserter, which does the bulk of the work.
  1325  	ri, err := row.MakeInserter(
  1326  		ctx, ef.planner.txn, ef.planner.ExecCfg().Codec, tabDesc, colDescs, checkFKs, fkTables, ef.planner.alloc,
  1327  	)
  1328  	if err != nil {
  1329  		return nil, err
  1330  	}
  1331  
  1332  	// Regular path for INSERT.
  1333  	ins := insertNodePool.Get().(*insertNode)
  1334  	*ins = insertNode{
  1335  		source: input.(planNode),
  1336  		run: insertRun{
  1337  			ti:         tableInserter{ri: ri},
  1338  			checkOrds:  checkOrdSet,
  1339  			insertCols: ri.InsertCols,
  1340  		},
  1341  	}
  1342  
  1343  	// If rows are not needed, no columns are returned.
  1344  	if rowsNeeded {
  1345  		returnColDescs := makeColDescList(table, returnColOrdSet)
  1346  		ins.columns = sqlbase.ResultColumnsFromColDescs(tabDesc.GetID(), returnColDescs)
  1347  
  1348  		// Set the tabColIdxToRetIdx for the mutation. Insert always returns
  1349  		// non-mutation columns in the same order they are defined in the table.
  1350  		ins.run.tabColIdxToRetIdx = row.ColMapping(tabDesc.Columns, returnColDescs)
  1351  		ins.run.rowsNeeded = true
  1352  	}
  1353  
  1354  	if allowAutoCommit && ef.allowAutoCommit {
  1355  		ins.enableAutoCommit()
  1356  	}
  1357  
  1358  	// serialize the data-modifying plan to ensure that no data is
  1359  	// observed that hasn't been validated first. See the comments
  1360  	// on BatchedNext() in plan_batch.go.
  1361  	if rowsNeeded {
  1362  		return &spoolNode{source: &serializeNode{source: ins}}, nil
  1363  	}
  1364  
  1365  	// We could use serializeNode here, but using rowCountNode is an
  1366  	// optimization that saves on calls to Next() by the caller.
  1367  	return &rowCountNode{source: ins}, nil
  1368  }
  1369  
  1370  func (ef *execFactory) ConstructInsertFastPath(
  1371  	rows [][]tree.TypedExpr,
  1372  	table cat.Table,
  1373  	insertColOrdSet exec.TableColumnOrdinalSet,
  1374  	returnColOrdSet exec.TableColumnOrdinalSet,
  1375  	checkOrdSet exec.CheckOrdinalSet,
  1376  	fkChecks []exec.InsertFastPathFKCheck,
  1377  ) (exec.Node, error) {
  1378  	ctx := ef.planner.extendedEvalCtx.Context
  1379  
  1380  	// Derive insert table and column descriptors.
  1381  	rowsNeeded := !returnColOrdSet.Empty()
  1382  	tabDesc := table.(*optTable).desc
  1383  	colDescs := makeColDescList(table, insertColOrdSet)
  1384  
  1385  	if err := ef.planner.maybeSetSystemConfig(tabDesc.GetID()); err != nil {
  1386  		return nil, err
  1387  	}
  1388  
  1389  	// Create the table inserter, which does the bulk of the work.
  1390  	ri, err := row.MakeInserter(
  1391  		ctx, ef.planner.txn, ef.planner.ExecCfg().Codec, tabDesc, colDescs, row.SkipFKs, nil /* fkTables */, ef.planner.alloc,
  1392  	)
  1393  	if err != nil {
  1394  		return nil, err
  1395  	}
  1396  
  1397  	// Regular path for INSERT.
  1398  	ins := insertFastPathNodePool.Get().(*insertFastPathNode)
  1399  	*ins = insertFastPathNode{
  1400  		input: rows,
  1401  		run: insertFastPathRun{
  1402  			insertRun: insertRun{
  1403  				ti:         tableInserter{ri: ri},
  1404  				checkOrds:  checkOrdSet,
  1405  				insertCols: ri.InsertCols,
  1406  			},
  1407  		},
  1408  	}
  1409  
  1410  	if len(fkChecks) > 0 {
  1411  		ins.run.fkChecks = make([]insertFastPathFKCheck, len(fkChecks))
  1412  		for i := range fkChecks {
  1413  			ins.run.fkChecks[i].InsertFastPathFKCheck = fkChecks[i]
  1414  		}
  1415  	}
  1416  
  1417  	// If rows are not needed, no columns are returned.
  1418  	if rowsNeeded {
  1419  		returnColDescs := makeColDescList(table, returnColOrdSet)
  1420  		ins.columns = sqlbase.ResultColumnsFromColDescs(tabDesc.GetID(), returnColDescs)
  1421  
  1422  		// Set the tabColIdxToRetIdx for the mutation. Insert always returns
  1423  		// non-mutation columns in the same order they are defined in the table.
  1424  		ins.run.tabColIdxToRetIdx = row.ColMapping(tabDesc.Columns, returnColDescs)
  1425  		ins.run.rowsNeeded = true
  1426  	}
  1427  
  1428  	if len(rows) == 0 {
  1429  		return &zeroNode{columns: ins.columns}, nil
  1430  	}
  1431  
  1432  	if ef.allowAutoCommit {
  1433  		ins.enableAutoCommit()
  1434  	}
  1435  
  1436  	// serialize the data-modifying plan to ensure that no data is
  1437  	// observed that hasn't been validated first. See the comments
  1438  	// on BatchedNext() in plan_batch.go.
  1439  	if rowsNeeded {
  1440  		return &spoolNode{source: &serializeNode{source: ins}}, nil
  1441  	}
  1442  
  1443  	// We could use serializeNode here, but using rowCountNode is an
  1444  	// optimization that saves on calls to Next() by the caller.
  1445  	return &rowCountNode{source: ins}, nil
  1446  }
  1447  
  1448  func (ef *execFactory) ConstructUpdate(
  1449  	input exec.Node,
  1450  	table cat.Table,
  1451  	fetchColOrdSet exec.TableColumnOrdinalSet,
  1452  	updateColOrdSet exec.TableColumnOrdinalSet,
  1453  	returnColOrdSet exec.TableColumnOrdinalSet,
  1454  	checks exec.CheckOrdinalSet,
  1455  	passthrough sqlbase.ResultColumns,
  1456  	allowAutoCommit bool,
  1457  	skipFKChecks bool,
  1458  ) (exec.Node, error) {
  1459  	ctx := ef.planner.extendedEvalCtx.Context
  1460  
  1461  	// Derive table and column descriptors.
  1462  	rowsNeeded := !returnColOrdSet.Empty()
  1463  	tabDesc := table.(*optTable).desc
  1464  	fetchColDescs := makeColDescList(table, fetchColOrdSet)
  1465  
  1466  	if err := ef.planner.maybeSetSystemConfig(tabDesc.GetID()); err != nil {
  1467  		return nil, err
  1468  	}
  1469  
  1470  	// Add each column to update as a sourceSlot. The CBO only uses scalarSlot,
  1471  	// since it compiles tuples and subqueries into a simple sequence of target
  1472  	// columns.
  1473  	updateColDescs := makeColDescList(table, updateColOrdSet)
  1474  	sourceSlots := make([]sourceSlot, len(updateColDescs))
  1475  	for i := range sourceSlots {
  1476  		sourceSlots[i] = scalarSlot{column: updateColDescs[i], sourceIndex: len(fetchColDescs) + i}
  1477  	}
  1478  
  1479  	var fkTables row.FkTableMetadata
  1480  	checkFKs := row.SkipFKs
  1481  	if !skipFKChecks {
  1482  		checkFKs = row.CheckFKs
  1483  		// Determine the foreign key tables involved in the update.
  1484  		var err error
  1485  		fkTables, err = ef.makeFkMetadata(tabDesc, row.CheckUpdates)
  1486  		if err != nil {
  1487  			return nil, err
  1488  		}
  1489  	}
  1490  
  1491  	// Create the table updater, which does the bulk of the work.
  1492  	ru, err := row.MakeUpdater(
  1493  		ctx,
  1494  		ef.planner.txn,
  1495  		ef.planner.ExecCfg().Codec,
  1496  		tabDesc,
  1497  		fkTables,
  1498  		updateColDescs,
  1499  		fetchColDescs,
  1500  		row.UpdaterDefault,
  1501  		checkFKs,
  1502  		ef.planner.EvalContext(),
  1503  		ef.planner.alloc,
  1504  	)
  1505  	if err != nil {
  1506  		return nil, err
  1507  	}
  1508  
  1509  	// Truncate any FetchCols added by MakeUpdater. The optimizer has already
  1510  	// computed a correct set that can sometimes be smaller.
  1511  	ru.FetchCols = ru.FetchCols[:len(fetchColDescs)]
  1512  
  1513  	// updateColsIdx inverts the mapping of UpdateCols to FetchCols. See
  1514  	// the explanatory comments in updateRun.
  1515  	updateColsIdx := make(map[sqlbase.ColumnID]int, len(ru.UpdateCols))
  1516  	for i := range ru.UpdateCols {
  1517  		id := ru.UpdateCols[i].ID
  1518  		updateColsIdx[id] = i
  1519  	}
  1520  
  1521  	upd := updateNodePool.Get().(*updateNode)
  1522  	*upd = updateNode{
  1523  		source: input.(planNode),
  1524  		run: updateRun{
  1525  			tu:        tableUpdater{ru: ru},
  1526  			checkOrds: checks,
  1527  			iVarContainerForComputedCols: sqlbase.RowIndexedVarContainer{
  1528  				CurSourceRow: make(tree.Datums, len(ru.FetchCols)),
  1529  				Cols:         ru.FetchCols,
  1530  				Mapping:      ru.FetchColIDtoRowIndex,
  1531  			},
  1532  			sourceSlots:    sourceSlots,
  1533  			updateValues:   make(tree.Datums, len(ru.UpdateCols)),
  1534  			updateColsIdx:  updateColsIdx,
  1535  			numPassthrough: len(passthrough),
  1536  		},
  1537  	}
  1538  
  1539  	// If rows are not needed, no columns are returned.
  1540  	if rowsNeeded {
  1541  		returnColDescs := makeColDescList(table, returnColOrdSet)
  1542  
  1543  		upd.columns = sqlbase.ResultColumnsFromColDescs(tabDesc.GetID(), returnColDescs)
  1544  		// Add the passthrough columns to the returning columns.
  1545  		upd.columns = append(upd.columns, passthrough...)
  1546  
  1547  		// Set the rowIdxToRetIdx for the mutation. Update returns the non-mutation
  1548  		// columns specified, in the same order they are defined in the table.
  1549  		//
  1550  		// The Updater derives/stores the fetch columns of the mutation and
  1551  		// since the return columns are always a subset of the fetch columns,
  1552  		// we can use use the fetch columns to generate the mapping for the
  1553  		// returned rows.
  1554  		upd.run.rowIdxToRetIdx = row.ColMapping(ru.FetchCols, returnColDescs)
  1555  		upd.run.rowsNeeded = true
  1556  	}
  1557  
  1558  	if allowAutoCommit && ef.allowAutoCommit {
  1559  		upd.enableAutoCommit()
  1560  	}
  1561  
  1562  	// Serialize the data-modifying plan to ensure that no data is observed that
  1563  	// hasn't been validated first. See the comments on BatchedNext() in
  1564  	// plan_batch.go.
  1565  	if rowsNeeded {
  1566  		return &spoolNode{source: &serializeNode{source: upd}}, nil
  1567  	}
  1568  
  1569  	// We could use serializeNode here, but using rowCountNode is an
  1570  	// optimization that saves on calls to Next() by the caller.
  1571  	return &rowCountNode{source: upd}, nil
  1572  }
  1573  
  1574  func (ef *execFactory) makeFkMetadata(
  1575  	tabDesc *sqlbase.ImmutableTableDescriptor, fkCheckType row.FKCheckType,
  1576  ) (row.FkTableMetadata, error) {
  1577  	ctx := ef.planner.extendedEvalCtx.Context
  1578  
  1579  	// Create a CheckHelper, used in case of cascading actions that cause changes
  1580  	// in the original table. This is only possible with UPDATE (together with
  1581  	// cascade loops or self-references).
  1582  	var checkHelper *sqlbase.CheckHelper
  1583  	if fkCheckType == row.CheckUpdates {
  1584  		var err error
  1585  		checkHelper, err = sqlbase.NewEvalCheckHelper(ctx, ef.planner.analyzeExpr, tabDesc)
  1586  		if err != nil {
  1587  			return nil, err
  1588  		}
  1589  	}
  1590  	// Determine the foreign key tables involved in the upsert.
  1591  	return row.MakeFkMetadata(
  1592  		ef.planner.extendedEvalCtx.Context,
  1593  		tabDesc,
  1594  		fkCheckType,
  1595  		ef.planner.LookupTableByID,
  1596  		ef.planner.CheckPrivilege,
  1597  		ef.planner.analyzeExpr,
  1598  		checkHelper,
  1599  	)
  1600  }
  1601  
  1602  func (ef *execFactory) ConstructUpsert(
  1603  	input exec.Node,
  1604  	table cat.Table,
  1605  	canaryCol exec.NodeColumnOrdinal,
  1606  	insertColOrdSet exec.TableColumnOrdinalSet,
  1607  	fetchColOrdSet exec.TableColumnOrdinalSet,
  1608  	updateColOrdSet exec.TableColumnOrdinalSet,
  1609  	returnColOrdSet exec.TableColumnOrdinalSet,
  1610  	checks exec.CheckOrdinalSet,
  1611  	allowAutoCommit bool,
  1612  	skipFKChecks bool,
  1613  ) (exec.Node, error) {
  1614  	ctx := ef.planner.extendedEvalCtx.Context
  1615  
  1616  	// Derive table and column descriptors.
  1617  	rowsNeeded := !returnColOrdSet.Empty()
  1618  	tabDesc := table.(*optTable).desc
  1619  	insertColDescs := makeColDescList(table, insertColOrdSet)
  1620  	fetchColDescs := makeColDescList(table, fetchColOrdSet)
  1621  	updateColDescs := makeColDescList(table, updateColOrdSet)
  1622  
  1623  	if err := ef.planner.maybeSetSystemConfig(tabDesc.GetID()); err != nil {
  1624  		return nil, err
  1625  	}
  1626  
  1627  	var fkTables row.FkTableMetadata
  1628  	checkFKs := row.SkipFKs
  1629  	if !skipFKChecks {
  1630  		checkFKs = row.CheckFKs
  1631  
  1632  		// Determine the foreign key tables involved in the upsert.
  1633  		var err error
  1634  		fkTables, err = ef.makeFkMetadata(tabDesc, row.CheckUpdates)
  1635  		if err != nil {
  1636  			return nil, err
  1637  		}
  1638  	}
  1639  
  1640  	// Create the table inserter, which does the bulk of the insert-related work.
  1641  	ri, err := row.MakeInserter(
  1642  		ctx,
  1643  		ef.planner.txn,
  1644  		ef.planner.ExecCfg().Codec,
  1645  		tabDesc,
  1646  		insertColDescs,
  1647  		checkFKs,
  1648  		fkTables,
  1649  		ef.planner.alloc,
  1650  	)
  1651  	if err != nil {
  1652  		return nil, err
  1653  	}
  1654  
  1655  	// Create the table updater, which does the bulk of the update-related work.
  1656  	ru, err := row.MakeUpdater(
  1657  		ctx,
  1658  		ef.planner.txn,
  1659  		ef.planner.ExecCfg().Codec,
  1660  		tabDesc,
  1661  		fkTables,
  1662  		updateColDescs,
  1663  		fetchColDescs,
  1664  		row.UpdaterDefault,
  1665  		checkFKs,
  1666  		ef.planner.EvalContext(),
  1667  		ef.planner.alloc,
  1668  	)
  1669  	if err != nil {
  1670  		return nil, err
  1671  	}
  1672  
  1673  	// Truncate any FetchCols added by MakeUpdater. The optimizer has already
  1674  	// computed a correct set that can sometimes be smaller.
  1675  	ru.FetchCols = ru.FetchCols[:len(fetchColDescs)]
  1676  
  1677  	// updateColsIdx inverts the mapping of UpdateCols to FetchCols. See
  1678  	// the explanatory comments in updateRun.
  1679  	updateColsIdx := make(map[sqlbase.ColumnID]int, len(ru.UpdateCols))
  1680  	for i := range ru.UpdateCols {
  1681  		id := ru.UpdateCols[i].ID
  1682  		updateColsIdx[id] = i
  1683  	}
  1684  
  1685  	// Instantiate the upsert node.
  1686  	ups := upsertNodePool.Get().(*upsertNode)
  1687  	*ups = upsertNode{
  1688  		source: input.(planNode),
  1689  		run: upsertRun{
  1690  			checkOrds:  checks,
  1691  			insertCols: ri.InsertCols,
  1692  			tw: optTableUpserter{
  1693  				ri:            ri,
  1694  				alloc:         ef.planner.alloc,
  1695  				canaryOrdinal: int(canaryCol),
  1696  				fkTables:      fkTables,
  1697  				fetchCols:     fetchColDescs,
  1698  				updateCols:    updateColDescs,
  1699  				ru:            ru,
  1700  			},
  1701  		},
  1702  	}
  1703  
  1704  	// If rows are not needed, no columns are returned.
  1705  	if rowsNeeded {
  1706  		returnColDescs := makeColDescList(table, returnColOrdSet)
  1707  		ups.columns = sqlbase.ResultColumnsFromColDescs(tabDesc.GetID(), returnColDescs)
  1708  
  1709  		// Update the tabColIdxToRetIdx for the mutation. Upsert returns
  1710  		// non-mutation columns specified, in the same order they are defined
  1711  		// in the table.
  1712  		ups.run.tw.tabColIdxToRetIdx = row.ColMapping(tabDesc.Columns, returnColDescs)
  1713  		ups.run.tw.returnCols = returnColDescs
  1714  		ups.run.tw.collectRows = true
  1715  	}
  1716  
  1717  	if allowAutoCommit && ef.allowAutoCommit {
  1718  		ups.enableAutoCommit()
  1719  	}
  1720  
  1721  	// Serialize the data-modifying plan to ensure that no data is observed that
  1722  	// hasn't been validated first. See the comments on BatchedNext() in
  1723  	// plan_batch.go.
  1724  	if rowsNeeded {
  1725  		return &spoolNode{source: &serializeNode{source: ups}}, nil
  1726  	}
  1727  
  1728  	// We could use serializeNode here, but using rowCountNode is an
  1729  	// optimization that saves on calls to Next() by the caller.
  1730  	return &rowCountNode{source: ups}, nil
  1731  }
  1732  
  1733  func (ef *execFactory) ConstructDelete(
  1734  	input exec.Node,
  1735  	table cat.Table,
  1736  	fetchColOrdSet exec.TableColumnOrdinalSet,
  1737  	returnColOrdSet exec.TableColumnOrdinalSet,
  1738  	allowAutoCommit bool,
  1739  	skipFKChecks bool,
  1740  ) (exec.Node, error) {
  1741  	ctx := ef.planner.extendedEvalCtx.Context
  1742  
  1743  	// Derive table and column descriptors.
  1744  	rowsNeeded := !returnColOrdSet.Empty()
  1745  	tabDesc := table.(*optTable).desc
  1746  	fetchColDescs := makeColDescList(table, fetchColOrdSet)
  1747  
  1748  	if err := ef.planner.maybeSetSystemConfig(tabDesc.GetID()); err != nil {
  1749  		return nil, err
  1750  	}
  1751  
  1752  	var fkTables row.FkTableMetadata
  1753  	checkFKs := row.SkipFKs
  1754  	if !skipFKChecks {
  1755  		checkFKs = row.CheckFKs
  1756  		// Determine the foreign key tables involved in the update.
  1757  		var err error
  1758  		fkTables, err = ef.makeFkMetadata(tabDesc, row.CheckDeletes)
  1759  		if err != nil {
  1760  			return nil, err
  1761  		}
  1762  	}
  1763  	// Create the table deleter, which does the bulk of the work. In the HP,
  1764  	// the deleter derives the columns that need to be fetched. By contrast, the
  1765  	// CBO will have already determined the set of fetch columns, and passes
  1766  	// those sets into the deleter (which will basically be a no-op).
  1767  	rd, err := row.MakeDeleter(
  1768  		ctx,
  1769  		ef.planner.txn,
  1770  		ef.planner.ExecCfg().Codec,
  1771  		tabDesc,
  1772  		fkTables,
  1773  		fetchColDescs,
  1774  		checkFKs,
  1775  		ef.planner.EvalContext(),
  1776  		ef.planner.alloc,
  1777  	)
  1778  	if err != nil {
  1779  		return nil, err
  1780  	}
  1781  
  1782  	// Truncate any FetchCols added by MakeUpdater. The optimizer has already
  1783  	// computed a correct set that can sometimes be smaller.
  1784  	rd.FetchCols = rd.FetchCols[:len(fetchColDescs)]
  1785  
  1786  	// Now make a delete node. We use a pool.
  1787  	del := deleteNodePool.Get().(*deleteNode)
  1788  	*del = deleteNode{
  1789  		source: input.(planNode),
  1790  		run: deleteRun{
  1791  			td: tableDeleter{rd: rd, alloc: ef.planner.alloc},
  1792  		},
  1793  	}
  1794  
  1795  	// If rows are not needed, no columns are returned.
  1796  	if rowsNeeded {
  1797  		returnColDescs := makeColDescList(table, returnColOrdSet)
  1798  		// Delete returns the non-mutation columns specified, in the same
  1799  		// order they are defined in the table.
  1800  		del.columns = sqlbase.ResultColumnsFromColDescs(tabDesc.GetID(), returnColDescs)
  1801  
  1802  		del.run.rowIdxToRetIdx = row.ColMapping(rd.FetchCols, returnColDescs)
  1803  		del.run.rowsNeeded = true
  1804  	}
  1805  
  1806  	if allowAutoCommit && ef.allowAutoCommit {
  1807  		del.enableAutoCommit()
  1808  	}
  1809  
  1810  	// Serialize the data-modifying plan to ensure that no data is observed that
  1811  	// hasn't been validated first. See the comments on BatchedNext() in
  1812  	// plan_batch.go.
  1813  	if rowsNeeded {
  1814  		return &spoolNode{source: &serializeNode{source: del}}, nil
  1815  	}
  1816  
  1817  	// We could use serializeNode here, but using rowCountNode is an
  1818  	// optimization that saves on calls to Next() by the caller.
  1819  	return &rowCountNode{source: del}, nil
  1820  }
  1821  
  1822  func (ef *execFactory) ConstructDeleteRange(
  1823  	table cat.Table,
  1824  	needed exec.TableColumnOrdinalSet,
  1825  	indexConstraint *constraint.Constraint,
  1826  	interleavedTables []cat.Table,
  1827  	maxReturnedKeys int,
  1828  	allowAutoCommit bool,
  1829  ) (exec.Node, error) {
  1830  	tabDesc := table.(*optTable).desc
  1831  	indexDesc := &tabDesc.PrimaryIndex
  1832  	sb := span.MakeBuilder(ef.planner.ExecCfg().Codec, tabDesc.TableDesc(), indexDesc)
  1833  
  1834  	if err := ef.planner.maybeSetSystemConfig(tabDesc.GetID()); err != nil {
  1835  		return nil, err
  1836  	}
  1837  
  1838  	// Setting the "forDelete" flag includes all column families in case where a
  1839  	// single record is deleted.
  1840  	spans, err := sb.SpansFromConstraint(indexConstraint, needed, true /* forDelete */)
  1841  	if err != nil {
  1842  		return nil, err
  1843  	}
  1844  
  1845  	// Permitting autocommit in DeleteRange is very important, because DeleteRange
  1846  	// is used for simple deletes from primary indexes like
  1847  	// DELETE FROM t WHERE key = 1000
  1848  	// When possible, we need to make this a 1pc transaction for performance
  1849  	// reasons. At the same time, we have to be careful, because DeleteRange
  1850  	// returns all of the keys that it deleted - so we have to set a limit on the
  1851  	// DeleteRange request. But, trying to set autocommit and a limit on the
  1852  	// request doesn't work properly if the limit is hit. So, we permit autocommit
  1853  	// here if we can guarantee that the number of returned keys is finite and
  1854  	// relatively small.
  1855  	autoCommitEnabled := allowAutoCommit && ef.allowAutoCommit
  1856  	// If maxReturnedKeys is 0, it indicates that we weren't able to determine
  1857  	// the maximum number of returned keys, so we'll give up and not permit
  1858  	// autocommit.
  1859  	if maxReturnedKeys == 0 || maxReturnedKeys > TableTruncateChunkSize {
  1860  		autoCommitEnabled = false
  1861  	}
  1862  
  1863  	dr := &deleteRangeNode{
  1864  		interleavedFastPath: false,
  1865  		spans:               spans,
  1866  		desc:                tabDesc,
  1867  		autoCommitEnabled:   autoCommitEnabled,
  1868  	}
  1869  
  1870  	if len(interleavedTables) > 0 {
  1871  		dr.interleavedFastPath = true
  1872  		dr.interleavedDesc = make([]*sqlbase.ImmutableTableDescriptor, len(interleavedTables))
  1873  		for i := range dr.interleavedDesc {
  1874  			dr.interleavedDesc[i] = interleavedTables[i].(*optTable).desc
  1875  		}
  1876  	}
  1877  	return dr, nil
  1878  }
  1879  
  1880  // ConstructCreateTable is part of the exec.Factory interface.
  1881  func (ef *execFactory) ConstructCreateTable(
  1882  	input exec.Node, schema cat.Schema, ct *tree.CreateTable,
  1883  ) (exec.Node, error) {
  1884  	nd := &createTableNode{n: ct, dbDesc: schema.(*optSchema).desc}
  1885  	if input != nil {
  1886  		nd.sourcePlan = input.(planNode)
  1887  	}
  1888  	return nd, nil
  1889  }
  1890  
  1891  // ConstructCreateView is part of the exec.Factory interface.
  1892  func (ef *execFactory) ConstructCreateView(
  1893  	schema cat.Schema,
  1894  	viewName string,
  1895  	ifNotExists bool,
  1896  	replace bool,
  1897  	temporary bool,
  1898  	viewQuery string,
  1899  	columns sqlbase.ResultColumns,
  1900  	deps opt.ViewDeps,
  1901  ) (exec.Node, error) {
  1902  
  1903  	planDeps := make(planDependencies, len(deps))
  1904  	for _, d := range deps {
  1905  		desc, err := getDescForDataSource(d.DataSource)
  1906  		if err != nil {
  1907  			return nil, err
  1908  		}
  1909  		var ref sqlbase.TableDescriptor_Reference
  1910  		if d.SpecificIndex {
  1911  			idx := d.DataSource.(cat.Table).Index(d.Index)
  1912  			ref.IndexID = idx.(*optIndex).desc.ID
  1913  		}
  1914  		if !d.ColumnOrdinals.Empty() {
  1915  			ref.ColumnIDs = make([]sqlbase.ColumnID, 0, d.ColumnOrdinals.Len())
  1916  			d.ColumnOrdinals.ForEach(func(ord int) {
  1917  				ref.ColumnIDs = append(ref.ColumnIDs, desc.Columns[ord].ID)
  1918  			})
  1919  		}
  1920  		entry := planDeps[desc.ID]
  1921  		entry.desc = desc
  1922  		entry.deps = append(entry.deps, ref)
  1923  		planDeps[desc.ID] = entry
  1924  	}
  1925  
  1926  	return &createViewNode{
  1927  		viewName:    tree.Name(viewName),
  1928  		ifNotExists: ifNotExists,
  1929  		replace:     replace,
  1930  		temporary:   temporary,
  1931  		viewQuery:   viewQuery,
  1932  		dbDesc:      schema.(*optSchema).desc,
  1933  		columns:     columns,
  1934  		planDeps:    planDeps,
  1935  	}, nil
  1936  }
  1937  
  1938  // ConstructSequenceSelect is part of the exec.Factory interface.
  1939  func (ef *execFactory) ConstructSequenceSelect(sequence cat.Sequence) (exec.Node, error) {
  1940  	return ef.planner.SequenceSelectNode(sequence.(*optSequence).desc)
  1941  }
  1942  
  1943  // ConstructSaveTable is part of the exec.Factory interface.
  1944  func (ef *execFactory) ConstructSaveTable(
  1945  	input exec.Node, table *cat.DataSourceName, colNames []string,
  1946  ) (exec.Node, error) {
  1947  	return ef.planner.makeSaveTable(input.(planNode), table, colNames), nil
  1948  }
  1949  
  1950  // ConstructErrorIfRows is part of the exec.Factory interface.
  1951  func (ef *execFactory) ConstructErrorIfRows(
  1952  	input exec.Node, mkErr func(tree.Datums) error,
  1953  ) (exec.Node, error) {
  1954  	return &errorIfRowsNode{
  1955  		plan:  input.(planNode),
  1956  		mkErr: mkErr,
  1957  	}, nil
  1958  }
  1959  
  1960  // ConstructOpaque is part of the exec.Factory interface.
  1961  func (ef *execFactory) ConstructOpaque(metadata opt.OpaqueMetadata) (exec.Node, error) {
  1962  	o, ok := metadata.(*opaqueMetadata)
  1963  	if !ok {
  1964  		return nil, errors.AssertionFailedf("unexpected OpaqueMetadata object type %T", metadata)
  1965  	}
  1966  	return o.plan, nil
  1967  }
  1968  
  1969  // ConstructAlterTableSplit is part of the exec.Factory interface.
  1970  func (ef *execFactory) ConstructAlterTableSplit(
  1971  	index cat.Index, input exec.Node, expiration tree.TypedExpr,
  1972  ) (exec.Node, error) {
  1973  	expirationTime, err := parseExpirationTime(ef.planner.EvalContext(), expiration)
  1974  	if err != nil {
  1975  		return nil, err
  1976  	}
  1977  
  1978  	return &splitNode{
  1979  		tableDesc:      &index.Table().(*optTable).desc.TableDescriptor,
  1980  		index:          index.(*optIndex).desc,
  1981  		rows:           input.(planNode),
  1982  		expirationTime: expirationTime,
  1983  	}, nil
  1984  }
  1985  
  1986  // ConstructAlterTableUnsplit is part of the exec.Factory interface.
  1987  func (ef *execFactory) ConstructAlterTableUnsplit(
  1988  	index cat.Index, input exec.Node,
  1989  ) (exec.Node, error) {
  1990  	return &unsplitNode{
  1991  		tableDesc: &index.Table().(*optTable).desc.TableDescriptor,
  1992  		index:     index.(*optIndex).desc,
  1993  		rows:      input.(planNode),
  1994  	}, nil
  1995  }
  1996  
  1997  // ConstructAlterTableUnsplitAll is part of the exec.Factory interface.
  1998  func (ef *execFactory) ConstructAlterTableUnsplitAll(index cat.Index) (exec.Node, error) {
  1999  	return &unsplitAllNode{
  2000  		tableDesc: &index.Table().(*optTable).desc.TableDescriptor,
  2001  		index:     index.(*optIndex).desc,
  2002  	}, nil
  2003  }
  2004  
  2005  // ConstructAlterTableRelocate is part of the exec.Factory interface.
  2006  func (ef *execFactory) ConstructAlterTableRelocate(
  2007  	index cat.Index, input exec.Node, relocateLease bool,
  2008  ) (exec.Node, error) {
  2009  	return &relocateNode{
  2010  		relocateLease: relocateLease,
  2011  		tableDesc:     &index.Table().(*optTable).desc.TableDescriptor,
  2012  		index:         index.(*optIndex).desc,
  2013  		rows:          input.(planNode),
  2014  	}, nil
  2015  }
  2016  
  2017  // ConstructControlJobs is part of the exec.Factory interface.
  2018  func (ef *execFactory) ConstructControlJobs(
  2019  	command tree.JobCommand, input exec.Node,
  2020  ) (exec.Node, error) {
  2021  	return &controlJobsNode{
  2022  		rows:          input.(planNode),
  2023  		desiredStatus: jobCommandToDesiredStatus[command],
  2024  	}, nil
  2025  }
  2026  
  2027  // ConstructCancelQueries is part of the exec.Factory interface.
  2028  func (ef *execFactory) ConstructCancelQueries(input exec.Node, ifExists bool) (exec.Node, error) {
  2029  	return &cancelQueriesNode{
  2030  		rows:     input.(planNode),
  2031  		ifExists: ifExists,
  2032  	}, nil
  2033  }
  2034  
  2035  // ConstructCancelSessions is part of the exec.Factory interface.
  2036  func (ef *execFactory) ConstructCancelSessions(input exec.Node, ifExists bool) (exec.Node, error) {
  2037  	return &cancelSessionsNode{
  2038  		rows:     input.(planNode),
  2039  		ifExists: ifExists,
  2040  	}, nil
  2041  }
  2042  
  2043  // renderBuilder encapsulates the code to build a renderNode.
  2044  type renderBuilder struct {
  2045  	r   *renderNode
  2046  	res planNode
  2047  }
  2048  
  2049  // init initializes the renderNode with render expressions.
  2050  func (rb *renderBuilder) init(n exec.Node, reqOrdering exec.OutputOrdering) {
  2051  	src := asDataSource(n)
  2052  	rb.r = &renderNode{
  2053  		source: src,
  2054  	}
  2055  	rb.r.ivarHelper = tree.MakeIndexedVarHelper(rb.r, len(src.columns))
  2056  	rb.r.reqOrdering = ReqOrdering(reqOrdering)
  2057  
  2058  	// If there's a spool, pull it up.
  2059  	if spool, ok := rb.r.source.plan.(*spoolNode); ok {
  2060  		rb.r.source.plan = spool.source
  2061  		spool.source = rb.r
  2062  		rb.res = spool
  2063  	} else {
  2064  		rb.res = rb.r
  2065  	}
  2066  }
  2067  
  2068  // setOutput sets the output of the renderNode. exprs is the list of render
  2069  // expressions, and columns is the list of information about the expressions,
  2070  // including their names, types, and so on. They must be the same length.
  2071  func (rb *renderBuilder) setOutput(exprs tree.TypedExprs, columns sqlbase.ResultColumns) {
  2072  	rb.r.render = exprs
  2073  	rb.r.columns = columns
  2074  }
  2075  
  2076  // makeColDescList returns a list of table column descriptors. Columns are
  2077  // included if their ordinal position in the table schema is in the cols set.
  2078  func makeColDescList(table cat.Table, cols exec.TableColumnOrdinalSet) []sqlbase.ColumnDescriptor {
  2079  	colDescs := make([]sqlbase.ColumnDescriptor, 0, cols.Len())
  2080  	for i, n := 0, table.DeletableColumnCount(); i < n; i++ {
  2081  		if !cols.Contains(i) {
  2082  			continue
  2083  		}
  2084  		colDescs = append(colDescs, *table.Column(i).(*sqlbase.ColumnDescriptor))
  2085  	}
  2086  	return colDescs
  2087  }
  2088  
  2089  // makeScanColumnsConfig builds a scanColumnsConfig struct by constructing a
  2090  // list of descriptor IDs for columns in the given cols set. Columns are
  2091  // identified by their ordinal position in the table schema.
  2092  func makeScanColumnsConfig(table cat.Table, cols exec.TableColumnOrdinalSet) scanColumnsConfig {
  2093  	// Set visibility=execinfra.ScanVisibilityPublicAndNotPublic, since all
  2094  	// columns in the "cols" set should be projected, regardless of whether
  2095  	// they're public or non- public. The caller decides which columns to
  2096  	// include (or not include). Note that when wantedColumns is non-empty,
  2097  	// the visibility flag will never trigger the addition of more columns.
  2098  	colCfg := scanColumnsConfig{
  2099  		wantedColumns: make([]tree.ColumnID, 0, cols.Len()),
  2100  		visibility:    execinfra.ScanVisibilityPublicAndNotPublic,
  2101  	}
  2102  	for c, ok := cols.Next(0); ok; c, ok = cols.Next(c + 1) {
  2103  		desc := table.Column(c).(*sqlbase.ColumnDescriptor)
  2104  		colCfg.wantedColumns = append(colCfg.wantedColumns, tree.ColumnID(desc.ID))
  2105  	}
  2106  	return colCfg
  2107  }