github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/opt/optbuilder/select.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 optbuilder
    12  
    13  import (
    14  	"github.com/cockroachdb/cockroach/pkg/server/telemetry"
    15  	"github.com/cockroachdb/cockroach/pkg/sql/opt"
    16  	"github.com/cockroachdb/cockroach/pkg/sql/opt/cat"
    17  	"github.com/cockroachdb/cockroach/pkg/sql/opt/memo"
    18  	"github.com/cockroachdb/cockroach/pkg/sql/parser"
    19  	"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode"
    20  	"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror"
    21  	"github.com/cockroachdb/cockroach/pkg/sql/privilege"
    22  	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
    23  	"github.com/cockroachdb/cockroach/pkg/sql/sqlbase"
    24  	"github.com/cockroachdb/cockroach/pkg/sql/sqltelemetry"
    25  	"github.com/cockroachdb/cockroach/pkg/sql/types"
    26  	"github.com/cockroachdb/cockroach/pkg/util/errorutil/unimplemented"
    27  	"github.com/cockroachdb/errors"
    28  )
    29  
    30  const (
    31  	excludeMutations = false
    32  	includeMutations = true
    33  )
    34  
    35  // buildDataSource builds a set of memo groups that represent the given table
    36  // expression. For example, if the tree.TableExpr consists of a single table,
    37  // the resulting set of memo groups will consist of a single group with a
    38  // scanOp operator. Joins will result in the construction of several groups,
    39  // including two for the left and right table scans, at least one for the join
    40  // condition, and one for the join itself.
    41  //
    42  // See Builder.buildStmt for a description of the remaining input and
    43  // return values.
    44  func (b *Builder) buildDataSource(
    45  	texpr tree.TableExpr, indexFlags *tree.IndexFlags, locking lockingSpec, inScope *scope,
    46  ) (outScope *scope) {
    47  	defer func(prevAtRoot bool) {
    48  		inScope.atRoot = prevAtRoot
    49  	}(inScope.atRoot)
    50  	inScope.atRoot = false
    51  	// NB: The case statements are sorted lexicographically.
    52  	switch source := texpr.(type) {
    53  	case *tree.AliasedTableExpr:
    54  		if source.IndexFlags != nil {
    55  			telemetry.Inc(sqltelemetry.IndexHintUseCounter)
    56  			telemetry.Inc(sqltelemetry.IndexHintSelectUseCounter)
    57  			indexFlags = source.IndexFlags
    58  		}
    59  		if source.As.Alias != "" {
    60  			locking = locking.filter(source.As.Alias)
    61  		}
    62  
    63  		outScope = b.buildDataSource(source.Expr, indexFlags, locking, inScope)
    64  
    65  		if source.Ordinality {
    66  			outScope = b.buildWithOrdinality("ordinality", outScope)
    67  		}
    68  
    69  		// Overwrite output properties with any alias information.
    70  		b.renameSource(source.As, outScope)
    71  
    72  		return outScope
    73  
    74  	case *tree.JoinTableExpr:
    75  		return b.buildJoin(source, locking, inScope)
    76  
    77  	case *tree.TableName:
    78  		tn := source
    79  
    80  		// CTEs take precedence over other data sources.
    81  		if cte := inScope.resolveCTE(tn); cte != nil {
    82  			locking.ignoreLockingForCTE()
    83  			outScope = inScope.push()
    84  			inCols := make(opt.ColList, len(cte.cols))
    85  			outCols := make(opt.ColList, len(cte.cols))
    86  			outScope.cols = nil
    87  			for i, col := range cte.cols {
    88  				id := col.ID
    89  				c := b.factory.Metadata().ColumnMeta(id)
    90  				newCol := b.synthesizeColumn(outScope, col.Alias, c.Type, nil, nil)
    91  				newCol.table = *tn
    92  				inCols[i] = id
    93  				outCols[i] = newCol.id
    94  			}
    95  
    96  			outScope.expr = b.factory.ConstructWithScan(&memo.WithScanPrivate{
    97  				With:         cte.id,
    98  				Name:         string(cte.name.Alias),
    99  				InCols:       inCols,
   100  				OutCols:      outCols,
   101  				BindingProps: cte.bindingProps,
   102  				ID:           b.factory.Metadata().NextUniqueID(),
   103  			})
   104  
   105  			return outScope
   106  		}
   107  
   108  		priv := privilege.SELECT
   109  		locking = locking.filter(tn.ObjectName)
   110  		if locking.isSet() {
   111  			// SELECT ... FOR [KEY] UPDATE/SHARE requires UPDATE privileges.
   112  			priv = privilege.UPDATE
   113  		}
   114  
   115  		ds, resName := b.resolveDataSource(tn, priv)
   116  		switch t := ds.(type) {
   117  		case cat.Table:
   118  			tabMeta := b.addTable(t, &resName)
   119  			return b.buildScan(tabMeta, nil /* ordinals */, indexFlags, locking, excludeMutations, inScope)
   120  
   121  		case cat.Sequence:
   122  			return b.buildSequenceSelect(t, &resName, inScope)
   123  
   124  		case cat.View:
   125  			return b.buildView(t, &resName, locking, inScope)
   126  
   127  		default:
   128  			panic(errors.AssertionFailedf("unknown DataSource type %T", ds))
   129  		}
   130  
   131  	case *tree.ParenTableExpr:
   132  		return b.buildDataSource(source.Expr, indexFlags, locking, inScope)
   133  
   134  	case *tree.RowsFromExpr:
   135  		return b.buildZip(source.Items, inScope)
   136  
   137  	case *tree.Subquery:
   138  		// Remove any target relations from the current scope's locking spec, as
   139  		// those only apply to relations in this statement. Interestingly, this
   140  		// would not be necessary if we required all subqueries to have aliases
   141  		// like Postgres does.
   142  		locking = locking.withoutTargets()
   143  
   144  		outScope = b.buildSelectStmt(source.Select, locking, nil /* desiredTypes */, inScope)
   145  
   146  		// Treat the subquery result as an anonymous data source (i.e. column names
   147  		// are not qualified). Remove hidden columns, as they are not accessible
   148  		// outside the subquery.
   149  		outScope.setTableAlias("")
   150  		outScope.removeHiddenCols()
   151  
   152  		return outScope
   153  
   154  	case *tree.StatementSource:
   155  		// This is the special '[ ... ]' syntax. We treat this as syntactic sugar
   156  		// for a top-level CTE, so it cannot refer to anything in the input scope.
   157  		// See #41078.
   158  		emptyScope := b.allocScope()
   159  		innerScope := b.buildStmt(source.Statement, nil /* desiredTypes */, emptyScope)
   160  		if len(innerScope.cols) == 0 {
   161  			panic(pgerror.Newf(pgcode.UndefinedColumn,
   162  				"statement source \"%v\" does not return any columns", source.Statement))
   163  		}
   164  
   165  		id := b.factory.Memo().NextWithID()
   166  		cte := cteSource{
   167  			name:         tree.AliasClause{},
   168  			cols:         innerScope.makePresentationWithHiddenCols(),
   169  			originalExpr: source.Statement,
   170  			expr:         innerScope.expr,
   171  			id:           id,
   172  			bindingProps: innerScope.expr.Relational(),
   173  		}
   174  		b.cteStack[len(b.cteStack)-1] = append(b.cteStack[len(b.cteStack)-1], cte)
   175  
   176  		inCols := make(opt.ColList, len(cte.cols))
   177  		outCols := make(opt.ColList, len(cte.cols))
   178  		for i, col := range cte.cols {
   179  			id := col.ID
   180  			c := b.factory.Metadata().ColumnMeta(id)
   181  			inCols[i] = id
   182  			outCols[i] = b.factory.Metadata().AddColumn(col.Alias, c.Type)
   183  		}
   184  
   185  		locking.ignoreLockingForCTE()
   186  		outScope = inScope.push()
   187  		// Similar to appendColumnsFromScope, but with re-numbering the column IDs.
   188  		for i, col := range innerScope.cols {
   189  			col.scalar = nil
   190  			col.id = outCols[i]
   191  			outScope.cols = append(outScope.cols, col)
   192  		}
   193  
   194  		outScope.expr = b.factory.ConstructWithScan(&memo.WithScanPrivate{
   195  			With:         cte.id,
   196  			Name:         string(cte.name.Alias),
   197  			InCols:       inCols,
   198  			OutCols:      outCols,
   199  			BindingProps: cte.bindingProps,
   200  			ID:           b.factory.Metadata().NextUniqueID(),
   201  		})
   202  
   203  		return outScope
   204  
   205  	case *tree.TableRef:
   206  		priv := privilege.SELECT
   207  		locking = locking.filter(source.As.Alias)
   208  		if locking.isSet() {
   209  			// SELECT ... FOR [KEY] UPDATE/SHARE requires UPDATE privileges.
   210  			priv = privilege.UPDATE
   211  		}
   212  
   213  		ds := b.resolveDataSourceRef(source, priv)
   214  		switch t := ds.(type) {
   215  		case cat.Table:
   216  			outScope = b.buildScanFromTableRef(t, source, indexFlags, locking, inScope)
   217  		case cat.View:
   218  			if source.Columns != nil {
   219  				panic(pgerror.Newf(pgcode.FeatureNotSupported,
   220  					"cannot specify an explicit column list when accessing a view by reference"))
   221  			}
   222  			tn := tree.MakeUnqualifiedTableName(t.Name())
   223  
   224  			outScope = b.buildView(t, &tn, locking, inScope)
   225  		case cat.Sequence:
   226  			tn := tree.MakeUnqualifiedTableName(t.Name())
   227  			// Any explicitly listed columns are ignored.
   228  			outScope = b.buildSequenceSelect(t, &tn, inScope)
   229  		default:
   230  			panic(errors.AssertionFailedf("unsupported catalog object"))
   231  		}
   232  		b.renameSource(source.As, outScope)
   233  		return outScope
   234  
   235  	default:
   236  		panic(errors.AssertionFailedf("unknown table expr: %T", texpr))
   237  	}
   238  }
   239  
   240  // buildView parses the view query text and builds it as a Select expression.
   241  func (b *Builder) buildView(
   242  	view cat.View, viewName *tree.TableName, locking lockingSpec, inScope *scope,
   243  ) (outScope *scope) {
   244  	// Cache the AST so that multiple references won't need to reparse.
   245  	if b.views == nil {
   246  		b.views = make(map[cat.View]*tree.Select)
   247  	}
   248  
   249  	// Check whether view has already been parsed, and if not, parse now.
   250  	sel, ok := b.views[view]
   251  	if !ok {
   252  		stmt, err := parser.ParseOne(view.Query())
   253  		if err != nil {
   254  			wrapped := pgerror.Wrapf(err, pgcode.Syntax,
   255  				"failed to parse underlying query from view %q", view.Name())
   256  			panic(wrapped)
   257  		}
   258  
   259  		sel, ok = stmt.AST.(*tree.Select)
   260  		if !ok {
   261  			panic(errors.AssertionFailedf("expected SELECT statement"))
   262  		}
   263  
   264  		b.views[view] = sel
   265  
   266  		// Keep track of referenced views for EXPLAIN (opt, env).
   267  		b.factory.Metadata().AddView(view)
   268  	}
   269  
   270  	// When building the view, we don't want to check for the SELECT privilege
   271  	// on the underlying tables, just on the view itself. Checking on the
   272  	// underlying tables as well would defeat the purpose of having separate
   273  	// SELECT privileges on the view, which is intended to allow for exposing
   274  	// some subset of a restricted table's data to less privileged users.
   275  	if !b.skipSelectPrivilegeChecks {
   276  		b.skipSelectPrivilegeChecks = true
   277  		defer func() { b.skipSelectPrivilegeChecks = false }()
   278  	}
   279  	trackDeps := b.trackViewDeps
   280  	if trackDeps {
   281  		// We are only interested in the direct dependency on this view descriptor.
   282  		// Any further dependency by the view's query should not be tracked.
   283  		b.trackViewDeps = false
   284  		defer func() { b.trackViewDeps = true }()
   285  	}
   286  
   287  	// We don't want the view to be able to refer to any outer scopes in the
   288  	// query. This shouldn't happen if the view is valid but there may be
   289  	// cornercases (e.g. renaming tables referenced by the view). To be safe, we
   290  	// build the view with an empty scope. But after that, we reattach the scope
   291  	// to the existing scope chain because we want the rest of the query to be
   292  	// able to refer to the higher scopes (see #46180).
   293  	emptyScope := b.allocScope()
   294  	outScope = b.buildSelect(sel, locking, nil /* desiredTypes */, emptyScope)
   295  	emptyScope.parent = inScope
   296  
   297  	// Update data source name to be the name of the view. And if view columns
   298  	// are specified, then update names of output columns.
   299  	hasCols := view.ColumnNameCount() > 0
   300  	for i := range outScope.cols {
   301  		outScope.cols[i].table = *viewName
   302  		if hasCols {
   303  			outScope.cols[i].name = view.ColumnName(i)
   304  		}
   305  	}
   306  
   307  	if trackDeps && !view.IsSystemView() {
   308  		dep := opt.ViewDep{DataSource: view}
   309  		for i := range outScope.cols {
   310  			dep.ColumnOrdinals.Add(i)
   311  		}
   312  		b.viewDeps = append(b.viewDeps, dep)
   313  	}
   314  
   315  	return outScope
   316  }
   317  
   318  // renameSource applies an AS clause to the columns in scope.
   319  func (b *Builder) renameSource(as tree.AliasClause, scope *scope) {
   320  	if as.Alias != "" {
   321  		colAlias := as.Cols
   322  
   323  		// Special case for Postgres compatibility: if a data source does not
   324  		// currently have a name, and it is a set-generating function or a scalar
   325  		// function with just one column, and the AS clause doesn't specify column
   326  		// names, then use the specified table name both as the column name and
   327  		// table name.
   328  		noColNameSpecified := len(colAlias) == 0
   329  		if scope.isAnonymousTable() && noColNameSpecified && scope.singleSRFColumn {
   330  			colAlias = tree.NameList{as.Alias}
   331  		}
   332  
   333  		// If an alias was specified, use that to qualify the column names.
   334  		tableAlias := tree.MakeUnqualifiedTableName(as.Alias)
   335  		scope.setTableAlias(as.Alias)
   336  
   337  		// If input expression is a ScanExpr, then override metadata aliases for
   338  		// pretty-printing.
   339  		scan, isScan := scope.expr.(*memo.ScanExpr)
   340  		if isScan {
   341  			tabMeta := b.factory.Metadata().TableMeta(scan.ScanPrivate.Table)
   342  			tabMeta.Alias = tree.MakeUnqualifiedTableName(as.Alias)
   343  		}
   344  
   345  		if len(colAlias) > 0 {
   346  			// The column aliases can only refer to explicit columns.
   347  			for colIdx, aliasIdx := 0, 0; aliasIdx < len(colAlias); colIdx++ {
   348  				if colIdx >= len(scope.cols) {
   349  					srcName := tree.ErrString(&tableAlias)
   350  					panic(pgerror.Newf(
   351  						pgcode.InvalidColumnReference,
   352  						"source %q has %d columns available but %d columns specified",
   353  						srcName, aliasIdx, len(colAlias),
   354  					))
   355  				}
   356  				col := &scope.cols[colIdx]
   357  				if col.hidden {
   358  					continue
   359  				}
   360  				col.name = colAlias[aliasIdx]
   361  				if isScan {
   362  					// Override column metadata alias.
   363  					colMeta := b.factory.Metadata().ColumnMeta(col.id)
   364  					colMeta.Alias = string(colAlias[aliasIdx])
   365  				}
   366  				aliasIdx++
   367  			}
   368  		}
   369  	}
   370  }
   371  
   372  // buildScanFromTableRef adds support for numeric references in queries.
   373  // For example:
   374  // SELECT * FROM [53 as t]; (table reference)
   375  // SELECT * FROM [53(1) as t]; (+columnar reference)
   376  // SELECT * FROM [53(1) as t]@1; (+index reference)
   377  // Note, the query SELECT * FROM [53() as t] is unsupported. Column lists must
   378  // be non-empty
   379  func (b *Builder) buildScanFromTableRef(
   380  	tab cat.Table,
   381  	ref *tree.TableRef,
   382  	indexFlags *tree.IndexFlags,
   383  	locking lockingSpec,
   384  	inScope *scope,
   385  ) (outScope *scope) {
   386  	var ordinals []int
   387  	if ref.Columns != nil {
   388  		// See tree.TableRef: "Note that a nil [Columns] array means 'unspecified'
   389  		// (all columns). whereas an array of length 0 means 'zero columns'.
   390  		// Lists of zero columns are not supported and will throw an error."
   391  		if len(ref.Columns) == 0 {
   392  			panic(pgerror.Newf(pgcode.Syntax,
   393  				"an explicit list of column IDs must include at least one column"))
   394  		}
   395  		ordinals = cat.ConvertColumnIDsToOrdinals(tab, ref.Columns)
   396  	}
   397  
   398  	tn := tree.MakeUnqualifiedTableName(tab.Name())
   399  	tabMeta := b.addTable(tab, &tn)
   400  	return b.buildScan(tabMeta, ordinals, indexFlags, locking, excludeMutations, inScope)
   401  }
   402  
   403  // addTable adds a table to the metadata and returns the TableMeta. The table
   404  // name is passed separately in order to preserve knowledge of whether the
   405  // catalog and schema names were explicitly specified.
   406  func (b *Builder) addTable(tab cat.Table, alias *tree.TableName) *opt.TableMeta {
   407  	md := b.factory.Metadata()
   408  	tabID := md.AddTable(tab, alias)
   409  	return md.TableMeta(tabID)
   410  }
   411  
   412  // buildScan builds a memo group for a ScanOp expression on the given table.
   413  //
   414  // If the ordinals slice is not nil, then only columns with ordinals in that
   415  // list are projected by the scan. Otherwise, all columns from the table are
   416  // projected.
   417  //
   418  // If scanMutationCols is true, then include columns being added or dropped from
   419  // the table. These are currently required by the execution engine as "fetch
   420  // columns", when performing mutation DML statements (INSERT, UPDATE, UPSERT,
   421  // DELETE).
   422  //
   423  // NOTE: Callers must take care that these mutation columns are never used in
   424  //       any other way, since they may not have been initialized yet by the
   425  //       backfiller!
   426  //
   427  // See Builder.buildStmt for a description of the remaining input and return
   428  // values.
   429  func (b *Builder) buildScan(
   430  	tabMeta *opt.TableMeta,
   431  	ordinals []int,
   432  	indexFlags *tree.IndexFlags,
   433  	locking lockingSpec,
   434  	scanMutationCols bool,
   435  	inScope *scope,
   436  ) (outScope *scope) {
   437  	tab := tabMeta.Table
   438  	tabID := tabMeta.MetaID
   439  
   440  	if indexFlags != nil && indexFlags.IgnoreForeignKeys {
   441  		tabMeta.IgnoreForeignKeys = true
   442  	}
   443  
   444  	colCount := len(ordinals)
   445  	if colCount == 0 {
   446  		// If scanning mutation columns, then include writable and deletable
   447  		// columns in the output, in addition to public columns.
   448  		if scanMutationCols {
   449  			colCount = tab.DeletableColumnCount()
   450  		} else {
   451  			colCount = tab.ColumnCount()
   452  		}
   453  	}
   454  
   455  	getOrdinal := func(i int) int {
   456  		if ordinals == nil {
   457  			return i
   458  		}
   459  		return ordinals[i]
   460  	}
   461  
   462  	var tabColIDs opt.ColSet
   463  	outScope = inScope.push()
   464  	outScope.cols = make([]scopeColumn, 0, colCount)
   465  	for i := 0; i < colCount; i++ {
   466  		ord := getOrdinal(i)
   467  		col := tab.Column(ord)
   468  		colID := tabID.ColumnID(ord)
   469  		tabColIDs.Add(colID)
   470  		name := col.ColName()
   471  		isMutation := cat.IsMutationColumn(tab, ord)
   472  		outScope.cols = append(outScope.cols, scopeColumn{
   473  			id:       colID,
   474  			name:     name,
   475  			table:    tabMeta.Alias,
   476  			typ:      col.DatumType(),
   477  			hidden:   col.IsHidden() || isMutation,
   478  			mutation: isMutation,
   479  		})
   480  	}
   481  
   482  	if tab.IsVirtualTable() {
   483  		if indexFlags != nil {
   484  			panic(pgerror.Newf(pgcode.Syntax,
   485  				"index flags not allowed with virtual tables"))
   486  		}
   487  		if locking.isSet() {
   488  			panic(pgerror.Newf(pgcode.Syntax,
   489  				"%s not allowed with virtual tables", locking.get().Strength))
   490  		}
   491  		private := memo.ScanPrivate{Table: tabID, Cols: tabColIDs}
   492  		outScope.expr = b.factory.ConstructScan(&private)
   493  
   494  		// Virtual tables should not be collected as view dependencies.
   495  	} else {
   496  		private := memo.ScanPrivate{Table: tabID, Cols: tabColIDs}
   497  		if indexFlags != nil {
   498  			private.Flags.NoIndexJoin = indexFlags.NoIndexJoin
   499  			if indexFlags.Index != "" || indexFlags.IndexID != 0 {
   500  				idx := -1
   501  				for i := 0; i < tab.IndexCount(); i++ {
   502  					if tab.Index(i).Name() == tree.Name(indexFlags.Index) ||
   503  						tab.Index(i).ID() == cat.StableID(indexFlags.IndexID) {
   504  						idx = i
   505  						break
   506  					}
   507  				}
   508  				if idx == -1 {
   509  					var err error
   510  					if indexFlags.Index != "" {
   511  						err = errors.Errorf("index %q not found", tree.ErrString(&indexFlags.Index))
   512  					} else {
   513  						err = errors.Errorf("index [%d] not found", indexFlags.IndexID)
   514  					}
   515  					panic(err)
   516  				}
   517  				private.Flags.ForceIndex = true
   518  				private.Flags.Index = idx
   519  				private.Flags.Direction = indexFlags.Direction
   520  			}
   521  		}
   522  		if locking.isSet() {
   523  			private.Locking = locking.get()
   524  		}
   525  
   526  		b.addCheckConstraintsForTable(tabMeta)
   527  		b.addComputedColsForTable(tabMeta)
   528  
   529  		outScope.expr = b.factory.ConstructScan(&private)
   530  
   531  		if b.trackViewDeps {
   532  			dep := opt.ViewDep{DataSource: tab}
   533  			for i := 0; i < colCount; i++ {
   534  				dep.ColumnOrdinals.Add(getOrdinal(i))
   535  			}
   536  			if private.Flags.ForceIndex {
   537  				dep.SpecificIndex = true
   538  				dep.Index = private.Flags.Index
   539  			}
   540  			b.viewDeps = append(b.viewDeps, dep)
   541  		}
   542  	}
   543  	return outScope
   544  }
   545  
   546  // addCheckConstraintsForTable extracts filters from the check constraints that
   547  // apply to the table and adds them to the table metadata (see
   548  // TableMeta.Constraints). To do this, the scalar expressions of the check
   549  // constraints are built here.
   550  func (b *Builder) addCheckConstraintsForTable(tabMeta *opt.TableMeta) {
   551  	tab := tabMeta.Table
   552  
   553  	// Check if we have any validated check constraints. Only validated
   554  	// constraints are known to hold on existing table data.
   555  	numChecks := tab.CheckCount()
   556  	chkIdx := 0
   557  	for ; chkIdx < numChecks; chkIdx++ {
   558  		if tab.Check(chkIdx).Validated {
   559  			break
   560  		}
   561  	}
   562  	if chkIdx == numChecks {
   563  		return
   564  	}
   565  
   566  	// Create a scope that can be used for building the scalar expressions.
   567  	tableScope := b.allocScope()
   568  	tableScope.appendColumnsFromTable(tabMeta, &tabMeta.Alias)
   569  
   570  	// Find the non-nullable table columns.
   571  	var notNullCols opt.ColSet
   572  	for i := 0; i < tab.ColumnCount(); i++ {
   573  		if !tab.Column(i).IsNullable() {
   574  			notNullCols.Add(tabMeta.MetaID.ColumnID(i))
   575  		}
   576  	}
   577  
   578  	var filters memo.FiltersExpr
   579  	// Skip to the first validated constraint we found above.
   580  	for ; chkIdx < numChecks; chkIdx++ {
   581  		checkConstraint := tab.Check(chkIdx)
   582  
   583  		// Only add validated check constraints to the table's metadata.
   584  		if !checkConstraint.Validated {
   585  			continue
   586  		}
   587  		expr, err := parser.ParseExpr(checkConstraint.Constraint)
   588  		if err != nil {
   589  			panic(err)
   590  		}
   591  
   592  		texpr := tableScope.resolveAndRequireType(expr, types.Bool)
   593  		condition := b.buildScalar(texpr, tableScope, nil, nil, nil)
   594  		// Check constraints that are guaranteed to not evaluate to NULL
   595  		// are the only ones converted into filters. This is because a NULL
   596  		// constraint is interpreted as passing, whereas a NULL filter is not.
   597  		if memo.ExprIsNeverNull(condition, notNullCols) {
   598  			filters = append(filters, b.factory.ConstructFiltersItem(condition))
   599  		}
   600  	}
   601  	if len(filters) > 0 {
   602  		tabMeta.SetConstraints(&filters)
   603  	}
   604  }
   605  
   606  // addComputedColsForTable finds all computed columns in the given table and
   607  // caches them in the table metadata as scalar expressions.
   608  func (b *Builder) addComputedColsForTable(tabMeta *opt.TableMeta) {
   609  	var tableScope *scope
   610  	tab := tabMeta.Table
   611  	for i, n := 0, tab.ColumnCount(); i < n; i++ {
   612  		tabCol := tab.Column(i)
   613  		if !tabCol.IsComputed() {
   614  			continue
   615  		}
   616  		expr, err := parser.ParseExpr(tabCol.ComputedExprStr())
   617  		if err != nil {
   618  			continue
   619  		}
   620  
   621  		if tableScope == nil {
   622  			tableScope = b.allocScope()
   623  			tableScope.appendColumnsFromTable(tabMeta, &tabMeta.Alias)
   624  		}
   625  
   626  		if texpr := tableScope.resolveAndRequireType(expr, types.Any); texpr != nil {
   627  			colID := tabMeta.MetaID.ColumnID(i)
   628  			scalar := b.buildScalar(texpr, tableScope, nil, nil, nil)
   629  			tabMeta.AddComputedCol(colID, scalar)
   630  		}
   631  	}
   632  }
   633  
   634  func (b *Builder) buildSequenceSelect(
   635  	seq cat.Sequence, seqName *tree.TableName, inScope *scope,
   636  ) (outScope *scope) {
   637  	md := b.factory.Metadata()
   638  	outScope = inScope.push()
   639  
   640  	cols := make(opt.ColList, len(sqlbase.SequenceSelectColumns))
   641  
   642  	for i, c := range sqlbase.SequenceSelectColumns {
   643  		cols[i] = md.AddColumn(c.Name, c.Typ)
   644  	}
   645  
   646  	outScope.cols = make([]scopeColumn, 3)
   647  	for i, c := range cols {
   648  		col := md.ColumnMeta(c)
   649  		outScope.cols[i] = scopeColumn{
   650  			id:    c,
   651  			name:  tree.Name(col.Alias),
   652  			table: *seqName,
   653  			typ:   col.Type,
   654  		}
   655  	}
   656  
   657  	private := memo.SequenceSelectPrivate{
   658  		Sequence: md.AddSequence(seq),
   659  		Cols:     cols,
   660  	}
   661  	outScope.expr = b.factory.ConstructSequenceSelect(&private)
   662  
   663  	if b.trackViewDeps {
   664  		b.viewDeps = append(b.viewDeps, opt.ViewDep{DataSource: seq})
   665  	}
   666  	return outScope
   667  }
   668  
   669  // buildWithOrdinality builds a group which appends an increasing integer column to
   670  // the output. colName optionally denotes the name this column is given, or can
   671  // be blank for none.
   672  //
   673  // See Builder.buildStmt for a description of the remaining input and
   674  // return values.
   675  func (b *Builder) buildWithOrdinality(colName string, inScope *scope) (outScope *scope) {
   676  	col := b.synthesizeColumn(inScope, colName, types.Int, nil, nil /* scalar */)
   677  
   678  	// See https://www.cockroachlabs.com/docs/stable/query-order.html#order-preservation
   679  	// for the semantics around WITH ORDINALITY and ordering.
   680  
   681  	input := inScope.expr.(memo.RelExpr)
   682  	inScope.expr = b.factory.ConstructOrdinality(input, &memo.OrdinalityPrivate{
   683  		Ordering: inScope.makeOrderingChoice(),
   684  		ColID:    col.id,
   685  	})
   686  
   687  	return inScope
   688  }
   689  
   690  func (b *Builder) buildCTEs(with *tree.With, inScope *scope) (outScope *scope) {
   691  	if with == nil {
   692  		return inScope
   693  	}
   694  
   695  	outScope = inScope.push()
   696  	addedCTEs := make([]cteSource, len(with.CTEList))
   697  	hasRecursive := false
   698  
   699  	// Make a fake subquery to ensure that no CTEs are correlated.
   700  	// TODO(justin): relax this restriction.
   701  	outer := b.subquery
   702  	defer func() { b.subquery = outer }()
   703  	b.subquery = &subquery{}
   704  
   705  	outScope.ctes = make(map[string]*cteSource)
   706  	for i, cte := range with.CTEList {
   707  		hasRecursive = hasRecursive || with.Recursive
   708  		cteExpr, cteCols := b.buildCTE(cte, outScope, with.Recursive)
   709  
   710  		// TODO(justin): lift this restriction when possible. WITH should be hoistable.
   711  		if b.subquery != nil && !b.subquery.outerCols.Empty() {
   712  			panic(pgerror.Newf(pgcode.FeatureNotSupported, "CTEs may not be correlated"))
   713  		}
   714  
   715  		aliasStr := cte.Name.Alias.String()
   716  		if _, ok := outScope.ctes[aliasStr]; ok {
   717  			panic(pgerror.Newf(
   718  				pgcode.DuplicateAlias, "WITH query name %s specified more than once", aliasStr,
   719  			))
   720  		}
   721  
   722  		id := b.factory.Memo().NextWithID()
   723  
   724  		addedCTEs[i] = cteSource{
   725  			name:         cte.Name,
   726  			cols:         cteCols,
   727  			originalExpr: cte.Stmt,
   728  			expr:         cteExpr,
   729  			bindingProps: cteExpr.Relational(),
   730  			id:           id,
   731  			mtr:          cte.Mtr,
   732  		}
   733  		cte := &addedCTEs[i]
   734  		outScope.ctes[cte.name.Alias.String()] = cte
   735  		b.cteStack[len(b.cteStack)-1] = append(b.cteStack[len(b.cteStack)-1], *cte)
   736  
   737  		if cteExpr.Relational().CanMutate && !inScope.atRoot {
   738  			panic(
   739  				pgerror.Newf(
   740  					pgcode.FeatureNotSupported,
   741  					"WITH clause containing a data-modifying statement must be at the top level",
   742  				),
   743  			)
   744  		}
   745  
   746  	}
   747  
   748  	telemetry.Inc(sqltelemetry.CteUseCounter)
   749  	if hasRecursive {
   750  		telemetry.Inc(sqltelemetry.RecursiveCteUseCounter)
   751  	}
   752  
   753  	return outScope
   754  }
   755  
   756  // A WITH constructed within an EXPLAIN should not be hoisted above it, and so
   757  // we need to denote a boundary which blocks them.
   758  func (b *Builder) pushWithFrame() {
   759  	b.cteStack = append(b.cteStack, []cteSource{})
   760  }
   761  
   762  // popWithFrame wraps the given scope's expression in the CTEs that have been
   763  // queued up at this level.
   764  func (b *Builder) popWithFrame(s *scope) {
   765  	s.expr = b.flushCTEs(s.expr)
   766  }
   767  
   768  // flushCTEs adds With expressions on top of an expression.
   769  func (b *Builder) flushCTEs(expr memo.RelExpr) memo.RelExpr {
   770  	ctes := b.cteStack[len(b.cteStack)-1]
   771  	b.cteStack = b.cteStack[:len(b.cteStack)-1]
   772  
   773  	if len(ctes) == 0 {
   774  		return expr
   775  	}
   776  
   777  	// Since later CTEs can refer to earlier ones, we want to add these in
   778  	// reverse order.
   779  	for i := len(ctes) - 1; i >= 0; i-- {
   780  		expr = b.factory.ConstructWith(
   781  			ctes[i].expr,
   782  			expr,
   783  			&memo.WithPrivate{
   784  				ID:           ctes[i].id,
   785  				Name:         string(ctes[i].name.Alias),
   786  				Mtr:          ctes[i].mtr,
   787  				OriginalExpr: ctes[i].originalExpr,
   788  			},
   789  		)
   790  	}
   791  	return expr
   792  }
   793  
   794  // buildSelectStmt builds a set of memo groups that represent the given select
   795  // statement.
   796  //
   797  // See Builder.buildStmt for a description of the remaining input and
   798  // return values.
   799  func (b *Builder) buildSelectStmt(
   800  	stmt tree.SelectStatement, locking lockingSpec, desiredTypes []*types.T, inScope *scope,
   801  ) (outScope *scope) {
   802  	// NB: The case statements are sorted lexicographically.
   803  	switch stmt := stmt.(type) {
   804  	case *tree.ParenSelect:
   805  		return b.buildSelect(stmt.Select, locking, desiredTypes, inScope)
   806  
   807  	case *tree.SelectClause:
   808  		return b.buildSelectClause(stmt, nil /* orderBy */, locking, desiredTypes, inScope)
   809  
   810  	case *tree.UnionClause:
   811  		return b.buildUnionClause(stmt, desiredTypes, inScope)
   812  
   813  	case *tree.ValuesClause:
   814  		return b.buildValuesClause(stmt, desiredTypes, inScope)
   815  
   816  	default:
   817  		panic(errors.AssertionFailedf("unknown select statement type: %T", stmt))
   818  	}
   819  }
   820  
   821  // buildSelect builds a set of memo groups that represent the given select
   822  // expression.
   823  //
   824  // See Builder.buildStmt for a description of the remaining input and
   825  // return values.
   826  func (b *Builder) buildSelect(
   827  	stmt *tree.Select, locking lockingSpec, desiredTypes []*types.T, inScope *scope,
   828  ) (outScope *scope) {
   829  	wrapped := stmt.Select
   830  	with := stmt.With
   831  	orderBy := stmt.OrderBy
   832  	limit := stmt.Limit
   833  	locking.apply(stmt.Locking)
   834  
   835  	for s, ok := wrapped.(*tree.ParenSelect); ok; s, ok = wrapped.(*tree.ParenSelect) {
   836  		stmt = s.Select
   837  		wrapped = stmt.Select
   838  		if stmt.With != nil {
   839  			if with != nil {
   840  				// (WITH ... (WITH ...))
   841  				// Currently we are unable to nest the scopes inside ParenSelect so we
   842  				// must refuse the syntax so that the query does not get invalid results.
   843  				panic(unimplemented.NewWithIssue(
   844  					24303, "multiple WITH clauses in parentheses",
   845  				))
   846  			}
   847  			with = s.Select.With
   848  		}
   849  		if stmt.OrderBy != nil {
   850  			if orderBy != nil {
   851  				panic(pgerror.Newf(
   852  					pgcode.Syntax, "multiple ORDER BY clauses not allowed",
   853  				))
   854  			}
   855  			orderBy = stmt.OrderBy
   856  		}
   857  		if stmt.Limit != nil {
   858  			if limit != nil {
   859  				panic(pgerror.Newf(
   860  					pgcode.Syntax, "multiple LIMIT clauses not allowed",
   861  				))
   862  			}
   863  			limit = stmt.Limit
   864  		}
   865  		if stmt.Locking != nil {
   866  			locking.apply(stmt.Locking)
   867  		}
   868  	}
   869  
   870  	return b.processWiths(with, inScope, func(inScope *scope) *scope {
   871  		return b.buildSelectStmtWithoutParens(
   872  			wrapped, orderBy, limit, locking, desiredTypes, inScope,
   873  		)
   874  	})
   875  }
   876  
   877  // buildSelectStmtWithoutParens builds a set of memo groups that represent
   878  // the given select statement components. The wrapped select statement can
   879  // be any variant except ParenSelect, which should be unwrapped by callers.
   880  //
   881  // See Builder.buildStmt for a description of the remaining input and
   882  // return values.
   883  func (b *Builder) buildSelectStmtWithoutParens(
   884  	wrapped tree.SelectStatement,
   885  	orderBy tree.OrderBy,
   886  	limit *tree.Limit,
   887  	locking lockingSpec,
   888  	desiredTypes []*types.T,
   889  	inScope *scope,
   890  ) (outScope *scope) {
   891  	// NB: The case statements are sorted lexicographically.
   892  	switch t := wrapped.(type) {
   893  	case *tree.ParenSelect:
   894  		panic(errors.AssertionFailedf(
   895  			"%T in buildSelectStmtWithoutParens", wrapped))
   896  
   897  	case *tree.SelectClause:
   898  		outScope = b.buildSelectClause(t, orderBy, locking, desiredTypes, inScope)
   899  
   900  	case *tree.UnionClause:
   901  		b.rejectIfLocking(locking, "UNION/INTERSECT/EXCEPT")
   902  		outScope = b.buildUnionClause(t, desiredTypes, inScope)
   903  
   904  	case *tree.ValuesClause:
   905  		b.rejectIfLocking(locking, "VALUES")
   906  		outScope = b.buildValuesClause(t, desiredTypes, inScope)
   907  
   908  	default:
   909  		panic(pgerror.Newf(pgcode.FeatureNotSupported,
   910  			"unknown select statement: %T", wrapped))
   911  	}
   912  
   913  	if outScope.ordering.Empty() && orderBy != nil {
   914  		projectionsScope := outScope.replace()
   915  		projectionsScope.cols = make([]scopeColumn, 0, len(outScope.cols))
   916  		for i := range outScope.cols {
   917  			expr := &outScope.cols[i]
   918  			col := b.addColumn(projectionsScope, "" /* alias */, expr)
   919  			b.buildScalar(expr, outScope, projectionsScope, col, nil)
   920  		}
   921  		orderByScope := b.analyzeOrderBy(orderBy, outScope, projectionsScope)
   922  		b.buildOrderBy(outScope, projectionsScope, orderByScope)
   923  		b.constructProjectForScope(outScope, projectionsScope)
   924  		outScope = projectionsScope
   925  	}
   926  
   927  	if limit != nil {
   928  		b.buildLimit(limit, inScope, outScope)
   929  	}
   930  
   931  	// TODO(rytaft): Support FILTER expression.
   932  	return outScope
   933  }
   934  
   935  // buildSelectClause builds a set of memo groups that represent the given
   936  // select clause. We pass the entire select statement rather than just the
   937  // select clause in order to handle ORDER BY scoping rules. ORDER BY can sort
   938  // results using columns from the FROM/GROUP BY clause and/or from the
   939  // projection list.
   940  //
   941  // See Builder.buildStmt for a description of the remaining input and
   942  // return values.
   943  func (b *Builder) buildSelectClause(
   944  	sel *tree.SelectClause,
   945  	orderBy tree.OrderBy,
   946  	locking lockingSpec,
   947  	desiredTypes []*types.T,
   948  	inScope *scope,
   949  ) (outScope *scope) {
   950  	fromScope := b.buildFrom(sel.From, locking, inScope)
   951  	b.processWindowDefs(sel, fromScope)
   952  	b.buildWhere(sel.Where, fromScope)
   953  
   954  	projectionsScope := fromScope.replace()
   955  
   956  	// This is where the magic happens. When this call reaches an aggregate
   957  	// function that refers to variables in fromScope or an ancestor scope,
   958  	// buildAggregateFunction is called which adds columns to the appropriate
   959  	// aggInScope and aggOutScope.
   960  	b.analyzeProjectionList(sel.Exprs, desiredTypes, fromScope, projectionsScope)
   961  
   962  	// Any aggregates in the HAVING, ORDER BY and DISTINCT ON clauses (if they
   963  	// exist) will be added here.
   964  	havingExpr := b.analyzeHaving(sel.Having, fromScope)
   965  	orderByScope := b.analyzeOrderBy(orderBy, fromScope, projectionsScope)
   966  	distinctOnScope := b.analyzeDistinctOnArgs(sel.DistinctOn, fromScope, projectionsScope)
   967  
   968  	var having opt.ScalarExpr
   969  	needsAgg := b.needsAggregation(sel, fromScope)
   970  	if needsAgg {
   971  		// Grouping columns must be built before building the projection list so
   972  		// we can check that any column references that appear in the SELECT list
   973  		// outside of aggregate functions are present in the grouping list.
   974  		b.buildGroupingColumns(sel, projectionsScope, fromScope)
   975  		having = b.buildHaving(havingExpr, fromScope)
   976  	}
   977  
   978  	b.buildProjectionList(fromScope, projectionsScope)
   979  	b.buildOrderBy(fromScope, projectionsScope, orderByScope)
   980  	b.buildDistinctOnArgs(fromScope, projectionsScope, distinctOnScope)
   981  	b.buildProjectSet(fromScope)
   982  
   983  	if needsAgg {
   984  		// We must wait to build the aggregation until after the above block since
   985  		// any SRFs found in the SELECT list will change the FROM scope (they
   986  		// create an implicit lateral join).
   987  		outScope = b.buildAggregation(having, fromScope)
   988  	} else {
   989  		outScope = fromScope
   990  	}
   991  
   992  	b.buildWindow(outScope, fromScope)
   993  	b.validateLockingInFrom(sel, locking, fromScope)
   994  
   995  	// Construct the projection.
   996  	b.constructProjectForScope(outScope, projectionsScope)
   997  	outScope = projectionsScope
   998  
   999  	if sel.Distinct {
  1000  		if projectionsScope.distinctOnCols.Empty() {
  1001  			outScope.expr = b.constructDistinct(outScope)
  1002  		} else {
  1003  			outScope = b.buildDistinctOn(
  1004  				projectionsScope.distinctOnCols,
  1005  				outScope,
  1006  				false, /* nullsAreDistinct */
  1007  				"",    /* errorOnDup */
  1008  			)
  1009  		}
  1010  	}
  1011  	return outScope
  1012  }
  1013  
  1014  // buildFrom builds a set of memo groups that represent the given FROM clause.
  1015  //
  1016  // See Builder.buildStmt for a description of the remaining input and return
  1017  // values.
  1018  func (b *Builder) buildFrom(from tree.From, locking lockingSpec, inScope *scope) (outScope *scope) {
  1019  	// The root AS OF clause is recognized and handled by the executor. The only
  1020  	// thing that must be done at this point is to ensure that if any timestamps
  1021  	// are specified, the root SELECT was an AS OF SYSTEM TIME and that the time
  1022  	// specified matches the one found at the root.
  1023  	if from.AsOf.Expr != nil {
  1024  		b.validateAsOf(from.AsOf)
  1025  	}
  1026  
  1027  	if len(from.Tables) > 0 {
  1028  		outScope = b.buildFromTables(from.Tables, locking, inScope)
  1029  	} else {
  1030  		outScope = inScope.push()
  1031  		outScope.expr = b.factory.ConstructValues(memo.ScalarListWithEmptyTuple, &memo.ValuesPrivate{
  1032  			Cols: opt.ColList{},
  1033  			ID:   b.factory.Metadata().NextUniqueID(),
  1034  		})
  1035  	}
  1036  
  1037  	return outScope
  1038  }
  1039  
  1040  // processWindowDefs validates that any window defs have unique names and adds
  1041  // them to the given scope.
  1042  func (b *Builder) processWindowDefs(sel *tree.SelectClause, fromScope *scope) {
  1043  	// Just do an O(n^2) loop since the number of window defs is likely small.
  1044  	for i := range sel.Window {
  1045  		for j := i + 1; j < len(sel.Window); j++ {
  1046  			if sel.Window[i].Name == sel.Window[j].Name {
  1047  				panic(pgerror.Newf(
  1048  					pgcode.Windowing,
  1049  					"window %q is already defined",
  1050  					sel.Window[i].Name,
  1051  				))
  1052  			}
  1053  		}
  1054  	}
  1055  
  1056  	// Pass down the set of window definitions so that they can be referenced
  1057  	// elsewhere in the SELECT.
  1058  	fromScope.windowDefs = sel.Window
  1059  }
  1060  
  1061  // buildWhere builds a set of memo groups that represent the given WHERE clause.
  1062  //
  1063  // See Builder.buildStmt for a description of the remaining input and return
  1064  // values.
  1065  func (b *Builder) buildWhere(where *tree.Where, inScope *scope) {
  1066  	if where == nil {
  1067  		return
  1068  	}
  1069  
  1070  	filter := b.resolveAndBuildScalar(
  1071  		where.Expr,
  1072  		types.Bool,
  1073  		exprKindWhere,
  1074  		tree.RejectGenerators|tree.RejectWindowApplications,
  1075  		inScope,
  1076  	)
  1077  
  1078  	// Wrap the filter in a FiltersOp.
  1079  	inScope.expr = b.factory.ConstructSelect(
  1080  		inScope.expr.(memo.RelExpr),
  1081  		memo.FiltersExpr{b.factory.ConstructFiltersItem(filter)},
  1082  	)
  1083  }
  1084  
  1085  // buildFromTables builds a series of InnerJoin expressions that together
  1086  // represent the given FROM tables.
  1087  //
  1088  // See Builder.buildStmt for a description of the remaining input and
  1089  // return values.
  1090  func (b *Builder) buildFromTables(
  1091  	tables tree.TableExprs, locking lockingSpec, inScope *scope,
  1092  ) (outScope *scope) {
  1093  	// If there are any lateral data sources, we need to build the join tree
  1094  	// left-deep instead of right-deep.
  1095  	for i := range tables {
  1096  		if b.exprIsLateral(tables[i]) {
  1097  			telemetry.Inc(sqltelemetry.LateralJoinUseCounter)
  1098  			return b.buildFromWithLateral(tables, locking, inScope)
  1099  		}
  1100  	}
  1101  	return b.buildFromTablesRightDeep(tables, locking, inScope)
  1102  }
  1103  
  1104  // buildFromTablesRightDeep recursively builds a series of InnerJoin
  1105  // expressions that join together the given FROM tables. The tables are joined
  1106  // in the reverse order that they appear in the list, with the innermost join
  1107  // involving the tables at the end of the list. For example:
  1108  //
  1109  //   SELECT * FROM a,b,c
  1110  //
  1111  // is joined like:
  1112  //
  1113  //   SELECT * FROM a JOIN (b JOIN c ON true) ON true
  1114  //
  1115  // This ordering is guaranteed for queries not involving lateral joins for the
  1116  // time being, to ensure we don't break any queries which have been
  1117  // hand-optimized.
  1118  //
  1119  // See Builder.buildStmt for a description of the remaining input and
  1120  // return values.
  1121  func (b *Builder) buildFromTablesRightDeep(
  1122  	tables tree.TableExprs, locking lockingSpec, inScope *scope,
  1123  ) (outScope *scope) {
  1124  	outScope = b.buildDataSource(tables[0], nil /* indexFlags */, locking, inScope)
  1125  
  1126  	// Recursively build table join.
  1127  	tables = tables[1:]
  1128  	if len(tables) == 0 {
  1129  		return outScope
  1130  	}
  1131  	tableScope := b.buildFromTablesRightDeep(tables, locking, inScope)
  1132  
  1133  	// Check that the same table name is not used multiple times.
  1134  	b.validateJoinTableNames(outScope, tableScope)
  1135  
  1136  	outScope.appendColumnsFromScope(tableScope)
  1137  
  1138  	left := outScope.expr.(memo.RelExpr)
  1139  	right := tableScope.expr.(memo.RelExpr)
  1140  	outScope.expr = b.factory.ConstructInnerJoin(left, right, memo.TrueFilter, memo.EmptyJoinPrivate)
  1141  	return outScope
  1142  }
  1143  
  1144  // exprIsLateral returns whether the table expression should have access to the
  1145  // scope of the tables to the left of it.
  1146  func (b *Builder) exprIsLateral(t tree.TableExpr) bool {
  1147  	ate, ok := t.(*tree.AliasedTableExpr)
  1148  	if !ok {
  1149  		return false
  1150  	}
  1151  	// Expressions which explicitly use the LATERAL keyword are lateral.
  1152  	if ate.Lateral {
  1153  		return true
  1154  	}
  1155  	// SRFs are always lateral.
  1156  	_, ok = ate.Expr.(*tree.RowsFromExpr)
  1157  	return ok
  1158  }
  1159  
  1160  // buildFromWithLateral builds a FROM clause in the case where it contains a
  1161  // LATERAL table.  This differs from buildFromTablesRightDeep because the
  1162  // semantics of LATERAL require that the join tree is built left-deep (from
  1163  // left-to-right) rather than right-deep (from right-to-left) which we do
  1164  // typically for perf backwards-compatibility.
  1165  //
  1166  //   SELECT * FROM a, b, c
  1167  //
  1168  //   buildFromTablesRightDeep: a JOIN (b JOIN c)
  1169  //   buildFromWithLateral:     (a JOIN b) JOIN c
  1170  func (b *Builder) buildFromWithLateral(
  1171  	tables tree.TableExprs, locking lockingSpec, inScope *scope,
  1172  ) (outScope *scope) {
  1173  	outScope = b.buildDataSource(tables[0], nil /* indexFlags */, locking, inScope)
  1174  	for i := 1; i < len(tables); i++ {
  1175  		scope := inScope
  1176  		// Lateral expressions need to be able to refer to the expressions that
  1177  		// have been built already.
  1178  		if b.exprIsLateral(tables[i]) {
  1179  			scope = outScope
  1180  			scope.context = exprKindLateralJoin
  1181  		}
  1182  		tableScope := b.buildDataSource(tables[i], nil /* indexFlags */, locking, scope)
  1183  
  1184  		// Check that the same table name is not used multiple times.
  1185  		b.validateJoinTableNames(outScope, tableScope)
  1186  
  1187  		outScope.appendColumnsFromScope(tableScope)
  1188  
  1189  		left := outScope.expr.(memo.RelExpr)
  1190  		right := tableScope.expr.(memo.RelExpr)
  1191  		outScope.expr = b.factory.ConstructInnerJoinApply(left, right, memo.TrueFilter, memo.EmptyJoinPrivate)
  1192  	}
  1193  
  1194  	return outScope
  1195  }
  1196  
  1197  // validateAsOf ensures that any AS OF SYSTEM TIME timestamp is consistent with
  1198  // that of the root statement.
  1199  func (b *Builder) validateAsOf(asOf tree.AsOfClause) {
  1200  	ts, err := tree.EvalAsOfTimestamp(b.ctx, asOf, b.semaCtx, b.evalCtx)
  1201  	if err != nil {
  1202  		panic(err)
  1203  	}
  1204  
  1205  	if b.semaCtx.AsOfTimestamp == nil {
  1206  		panic(pgerror.Newf(pgcode.Syntax,
  1207  			"AS OF SYSTEM TIME must be provided on a top-level statement"))
  1208  	}
  1209  
  1210  	if *b.semaCtx.AsOfTimestamp != ts {
  1211  		panic(unimplementedWithIssueDetailf(35712, "",
  1212  			"cannot specify AS OF SYSTEM TIME with different timestamps"))
  1213  	}
  1214  }
  1215  
  1216  // validateLockingInFrom checks for operations that are not supported with FOR
  1217  // [KEY] UPDATE/SHARE. If a locking clause was specified with the select and an
  1218  // incompatible operation is in use, a locking error is raised.
  1219  func (b *Builder) validateLockingInFrom(
  1220  	sel *tree.SelectClause, locking lockingSpec, fromScope *scope,
  1221  ) {
  1222  	if !locking.isSet() {
  1223  		// No FOR [KEY] UPDATE/SHARE locking modes in scope.
  1224  		return
  1225  	}
  1226  
  1227  	switch {
  1228  	case sel.Distinct:
  1229  		b.raiseLockingContextError(locking, "DISTINCT clause")
  1230  
  1231  	case sel.GroupBy != nil:
  1232  		b.raiseLockingContextError(locking, "GROUP BY clause")
  1233  
  1234  	case sel.Having != nil:
  1235  		b.raiseLockingContextError(locking, "HAVING clause")
  1236  
  1237  	case fromScope.groupby != nil && fromScope.groupby.hasAggregates():
  1238  		b.raiseLockingContextError(locking, "aggregate functions")
  1239  
  1240  	case len(fromScope.windows) != 0:
  1241  		b.raiseLockingContextError(locking, "window functions")
  1242  
  1243  	case len(fromScope.srfs) != 0:
  1244  		b.raiseLockingContextError(locking, "set-returning functions in the target list")
  1245  	}
  1246  
  1247  	for _, li := range locking {
  1248  		// Validate locking strength.
  1249  		switch li.Strength {
  1250  		case tree.ForNone:
  1251  			// AST nodes should not be created with this locking strength.
  1252  			panic(errors.AssertionFailedf("locking item without strength"))
  1253  		case tree.ForUpdate, tree.ForNoKeyUpdate, tree.ForShare, tree.ForKeyShare:
  1254  			// CockroachDB treats all of the FOR LOCKED modes as no-ops. Since all
  1255  			// transactions are serializable in CockroachDB, clients can't observe
  1256  			// whether or not FOR UPDATE (or any of the other weaker modes) actually
  1257  			// created a lock. This behavior may improve as the transaction model gains
  1258  			// more capabilities.
  1259  		default:
  1260  			panic(errors.AssertionFailedf("unknown locking strength: %s", li.Strength))
  1261  		}
  1262  
  1263  		// Validating locking wait policy.
  1264  		switch li.WaitPolicy {
  1265  		case tree.LockWaitBlock:
  1266  			// Default.
  1267  		case tree.LockWaitSkip:
  1268  			panic(unimplementedWithIssueDetailf(40476, "",
  1269  				"SKIP LOCKED lock wait policy is not supported"))
  1270  		case tree.LockWaitError:
  1271  			panic(unimplementedWithIssueDetailf(40476, "",
  1272  				"NOWAIT lock wait policy is not supported"))
  1273  		default:
  1274  			panic(errors.AssertionFailedf("unknown locking wait policy: %s", li.WaitPolicy))
  1275  		}
  1276  
  1277  		// Validate locking targets by checking that all targets are well-formed
  1278  		// and all point to real relations present in the FROM clause.
  1279  		for _, target := range li.Targets {
  1280  			// Insist on unqualified alias names here. We could probably do
  1281  			// something smarter, but it's better to just mirror Postgres
  1282  			// exactly. See transformLockingClause in Postgres' source.
  1283  			if target.CatalogName != "" || target.SchemaName != "" {
  1284  				panic(pgerror.Newf(pgcode.Syntax,
  1285  					"%s must specify unqualified relation names", li.Strength))
  1286  			}
  1287  
  1288  			// Search for the target in fromScope. If a target is missing from
  1289  			// the scope then raise an error. This will end up looping over all
  1290  			// columns in scope for each of the locking targets. We could use a
  1291  			// more efficient data structure (e.g. a hash map of relation names)
  1292  			// to improve the time complexity here, but we expect the number of
  1293  			// columns to be small enough that doing so is likely not worth it.
  1294  			found := false
  1295  			for _, col := range fromScope.cols {
  1296  				if target.ObjectName == col.table.ObjectName {
  1297  					found = true
  1298  					break
  1299  				}
  1300  			}
  1301  			if !found {
  1302  				panic(pgerror.Newf(
  1303  					pgcode.UndefinedTable,
  1304  					"relation %q in %s clause not found in FROM clause",
  1305  					target.ObjectName, li.Strength,
  1306  				))
  1307  			}
  1308  		}
  1309  	}
  1310  }
  1311  
  1312  // rejectIfLocking raises a locking error if a locking clause was specified.
  1313  func (b *Builder) rejectIfLocking(locking lockingSpec, context string) {
  1314  	if !locking.isSet() {
  1315  		// No FOR [KEY] UPDATE/SHARE locking modes in scope.
  1316  		return
  1317  	}
  1318  	b.raiseLockingContextError(locking, context)
  1319  }
  1320  
  1321  // raiseLockingContextError raises an error indicating that a row-level locking
  1322  // clause is not permitted in the specified context. locking.isSet() must be true.
  1323  func (b *Builder) raiseLockingContextError(locking lockingSpec, context string) {
  1324  	panic(pgerror.Newf(pgcode.FeatureNotSupported,
  1325  		"%s is not allowed with %s", locking.get().Strength, context))
  1326  }