github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/internal/sqlsmith/relational.go (about)

     1  // Copyright 2019 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 sqlsmith
    12  
    13  import (
    14  	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
    15  	"github.com/cockroachdb/cockroach/pkg/sql/types"
    16  )
    17  
    18  func (s *Smither) makeStmt() (stmt tree.Statement, ok bool) {
    19  	return s.stmtSampler.Next()(s)
    20  }
    21  
    22  func (s *Smither) makeSelectStmt(
    23  	desiredTypes []*types.T, refs colRefs, withTables tableRefs,
    24  ) (stmt tree.SelectStatement, stmtRefs colRefs, ok bool) {
    25  	if s.canRecurse() {
    26  		for {
    27  			expr, exprRefs, ok := s.selectStmtSampler.Next()(s, desiredTypes, refs, withTables)
    28  			if ok {
    29  				return expr, exprRefs, ok
    30  			}
    31  		}
    32  	}
    33  	return makeValuesSelect(s, desiredTypes, refs, withTables)
    34  }
    35  
    36  func makeSchemaTable(s *Smither, refs colRefs, forJoin bool) (tree.TableExpr, colRefs, bool) {
    37  	// If there's no tables, don't keep failing in this function, just make
    38  	// a values table.
    39  	if len(s.tables) == 0 {
    40  		return makeValuesTable(s, refs, forJoin)
    41  	}
    42  	expr, _, _, exprRefs, ok := s.getSchemaTableWithIndexHint()
    43  	return expr, exprRefs, ok
    44  }
    45  
    46  // getSchemaTable returns a table expression without the index hint.
    47  func (s *Smither) getSchemaTable() (tree.TableExpr, *tree.TableName, *tableRef, colRefs, bool) {
    48  	ate, name, tableRef, refs, ok := s.getSchemaTableWithIndexHint()
    49  	if ate != nil {
    50  		ate.IndexFlags = nil
    51  	}
    52  	return ate, name, tableRef, refs, ok
    53  }
    54  
    55  // getSchemaTableWithIndexHint returns a table expression that might contain an
    56  // index hint.
    57  func (s *Smither) getSchemaTableWithIndexHint() (
    58  	*tree.AliasedTableExpr,
    59  	*tree.TableName,
    60  	*tableRef,
    61  	colRefs,
    62  	bool,
    63  ) {
    64  	table, ok := s.getRandTable()
    65  	if !ok {
    66  		return nil, nil, nil, nil, false
    67  	}
    68  	alias := s.name("tab")
    69  	name := tree.NewUnqualifiedTableName(alias)
    70  	expr, refs := s.tableExpr(table.tableRef, name)
    71  	return &tree.AliasedTableExpr{
    72  		Expr:       expr,
    73  		IndexFlags: table.indexFlags,
    74  		As:         tree.AliasClause{Alias: alias},
    75  	}, name, table.tableRef, refs, true
    76  }
    77  
    78  func (s *Smither) tableExpr(table *tableRef, name *tree.TableName) (tree.TableExpr, colRefs) {
    79  	refs := make(colRefs, len(table.Columns))
    80  	for i, c := range table.Columns {
    81  		refs[i] = &colRef{
    82  			typ: tree.MustBeStaticallyKnownType(c.Type),
    83  			item: tree.NewColumnItem(
    84  				name,
    85  				c.Name,
    86  			),
    87  		}
    88  	}
    89  	return table.TableName, refs
    90  }
    91  
    92  var (
    93  	mutatingStatements = []statementWeight{
    94  		{10, makeInsert},
    95  		{10, makeDelete},
    96  		{10, makeUpdate},
    97  		{1, makeAlter},
    98  		{1, makeBegin},
    99  		{2, makeRollback},
   100  		{6, makeCommit},
   101  		{1, makeBackup},
   102  		{1, makeRestore},
   103  		{1, makeExport},
   104  		{1, makeImport},
   105  	}
   106  	nonMutatingStatements = []statementWeight{
   107  		{10, makeSelect},
   108  	}
   109  	allStatements = append(mutatingStatements, nonMutatingStatements...)
   110  
   111  	mutatingTableExprs = []tableExprWeight{
   112  		{1, makeInsertReturning},
   113  		{1, makeDeleteReturning},
   114  		{1, makeUpdateReturning},
   115  	}
   116  	nonMutatingTableExprs = []tableExprWeight{
   117  		{40, makeMergeJoinExpr},
   118  		{40, makeEquiJoinExpr},
   119  		{20, makeSchemaTable},
   120  		{10, makeJoinExpr},
   121  		{1, makeValuesTable},
   122  		{2, makeSelectTable},
   123  	}
   124  	vectorizableTableExprs = []tableExprWeight{
   125  		{20, makeEquiJoinExpr},
   126  		{20, makeMergeJoinExpr},
   127  		{20, makeSchemaTable},
   128  	}
   129  	allTableExprs = append(mutatingTableExprs, nonMutatingTableExprs...)
   130  
   131  	selectStmts = []selectStatementWeight{
   132  		{1, makeValuesSelect},
   133  		{1, makeSetOp},
   134  		{1, makeSelectClause},
   135  	}
   136  )
   137  
   138  // makeTableExpr returns a tableExpr. If forJoin is true the tableExpr is
   139  // valid to be used as a join reference.
   140  func makeTableExpr(s *Smither, refs colRefs, forJoin bool) (tree.TableExpr, colRefs, bool) {
   141  	if s.canRecurse() {
   142  		for i := 0; i < retryCount; i++ {
   143  			expr, exprRefs, ok := s.tableExprSampler.Next()(s, refs, forJoin)
   144  			if ok {
   145  				return expr, exprRefs, ok
   146  			}
   147  		}
   148  	}
   149  	return makeSchemaTable(s, refs, forJoin)
   150  }
   151  
   152  type typedExpr struct {
   153  	tree.TypedExpr
   154  	typ *types.T
   155  }
   156  
   157  func makeTypedExpr(expr tree.TypedExpr, typ *types.T) tree.TypedExpr {
   158  	return typedExpr{
   159  		TypedExpr: expr,
   160  		typ:       typ,
   161  	}
   162  }
   163  
   164  func (t typedExpr) ResolvedType() *types.T {
   165  	return t.typ
   166  }
   167  
   168  var joinTypes = []string{
   169  	"",
   170  	tree.AstFull,
   171  	tree.AstLeft,
   172  	tree.AstRight,
   173  	tree.AstCross,
   174  	tree.AstInner,
   175  }
   176  
   177  func makeJoinExpr(s *Smither, refs colRefs, forJoin bool) (tree.TableExpr, colRefs, bool) {
   178  	left, leftRefs, ok := makeTableExpr(s, refs, true)
   179  	if !ok {
   180  		return nil, nil, false
   181  	}
   182  	right, rightRefs, ok := makeTableExpr(s, refs, true)
   183  	if !ok {
   184  		return nil, nil, false
   185  	}
   186  
   187  	joinExpr := &tree.JoinTableExpr{
   188  		JoinType: joinTypes[s.rnd.Intn(len(joinTypes))],
   189  		Left:     left,
   190  		Right:    right,
   191  	}
   192  
   193  	if joinExpr.JoinType != tree.AstCross {
   194  		on := makeBoolExpr(s, refs)
   195  		joinExpr.Cond = &tree.OnJoinCond{Expr: on}
   196  	}
   197  	joinRefs := leftRefs.extend(rightRefs...)
   198  
   199  	return joinExpr, joinRefs, true
   200  }
   201  
   202  func makeEquiJoinExpr(s *Smither, refs colRefs, forJoin bool) (tree.TableExpr, colRefs, bool) {
   203  	left, leftRefs, ok := makeTableExpr(s, refs, true)
   204  	if !ok {
   205  		return nil, nil, false
   206  	}
   207  	right, rightRefs, ok := makeTableExpr(s, refs, true)
   208  	if !ok {
   209  		return nil, nil, false
   210  	}
   211  
   212  	// Determine overlapping types.
   213  	var available [][2]tree.TypedExpr
   214  	for _, leftCol := range leftRefs {
   215  		for _, rightCol := range rightRefs {
   216  			if leftCol.typ.Equivalent(rightCol.typ) {
   217  				available = append(available, [2]tree.TypedExpr{
   218  					typedParen(leftCol.item, leftCol.typ),
   219  					typedParen(rightCol.item, rightCol.typ),
   220  				})
   221  			}
   222  		}
   223  	}
   224  	if len(available) == 0 {
   225  		// left and right didn't have any columns with the same type.
   226  		return nil, nil, false
   227  	}
   228  
   229  	s.rnd.Shuffle(len(available), func(i, j int) {
   230  		available[i], available[j] = available[j], available[i]
   231  	})
   232  
   233  	var cond tree.TypedExpr
   234  	for (cond == nil || s.coin()) && len(available) > 0 {
   235  		v := available[0]
   236  		available = available[1:]
   237  		expr := tree.NewTypedComparisonExpr(tree.EQ, v[0], v[1])
   238  		if cond == nil {
   239  			cond = expr
   240  		} else {
   241  			cond = tree.NewTypedAndExpr(cond, expr)
   242  		}
   243  	}
   244  
   245  	joinExpr := &tree.JoinTableExpr{
   246  		Left:  left,
   247  		Right: right,
   248  		Cond:  &tree.OnJoinCond{Expr: cond},
   249  	}
   250  	joinRefs := leftRefs.extend(rightRefs...)
   251  	return joinExpr, joinRefs, true
   252  }
   253  
   254  func makeMergeJoinExpr(s *Smither, _ colRefs, forJoin bool) (tree.TableExpr, colRefs, bool) {
   255  	// A merge join is an equijoin where both sides are sorted in the same
   256  	// direction. Do this by looking for two indexes that have column
   257  	// prefixes that are the same type and direction. Identical indexes
   258  	// are fine.
   259  
   260  	// Start with some random index.
   261  	leftTableName, leftIdx, _, ok := s.getRandIndex()
   262  	if !ok {
   263  		return nil, nil, false
   264  	}
   265  
   266  	leftAlias := s.name("tab")
   267  	rightAlias := s.name("tab")
   268  	leftAliasName := tree.NewUnqualifiedTableName(leftAlias)
   269  	rightAliasName := tree.NewUnqualifiedTableName(rightAlias)
   270  
   271  	// Now look for one that satisfies our constraints (some shared prefix
   272  	// of type + direction), might end up being the same one. We rely on
   273  	// Go's non-deterministic map iteration ordering for randomness.
   274  	rightTableName, cols := func() (*tree.TableIndexName, [][2]colRef) {
   275  		s.lock.RLock()
   276  		defer s.lock.RUnlock()
   277  		for tbl, idxs := range s.indexes {
   278  			for idxName, idx := range idxs {
   279  				rightTableName := &tree.TableIndexName{
   280  					Table: tbl,
   281  					Index: tree.UnrestrictedName(idxName),
   282  				}
   283  				// cols keeps track of matching column pairs.
   284  				var cols [][2]colRef
   285  				for _, rightColElem := range idx.Columns {
   286  					rightCol := s.columns[tbl][rightColElem.Column]
   287  					leftColElem := leftIdx.Columns[len(cols)]
   288  					leftCol := s.columns[leftTableName.Table][leftColElem.Column]
   289  					if rightColElem.Direction != leftColElem.Direction {
   290  						break
   291  					}
   292  					if !tree.MustBeStaticallyKnownType(rightCol.Type).Equivalent(tree.MustBeStaticallyKnownType(leftCol.Type)) {
   293  						break
   294  					}
   295  					cols = append(cols, [2]colRef{
   296  						{
   297  							typ:  tree.MustBeStaticallyKnownType(leftCol.Type),
   298  							item: tree.NewColumnItem(leftAliasName, leftColElem.Column),
   299  						},
   300  						{
   301  							typ:  tree.MustBeStaticallyKnownType(rightCol.Type),
   302  							item: tree.NewColumnItem(rightAliasName, rightColElem.Column),
   303  						},
   304  					})
   305  					if len(cols) >= len(leftIdx.Columns) {
   306  						break
   307  					}
   308  				}
   309  				if len(cols) > 0 {
   310  					return rightTableName, cols
   311  				}
   312  			}
   313  		}
   314  		// Since we can always match leftIdx we should never get here.
   315  		panic("unreachable")
   316  	}()
   317  
   318  	// joinRefs are limited to columns in the indexes (even if they don't
   319  	// appear in the join condition) because non-stored columns will cause
   320  	// a hash join.
   321  	var joinRefs colRefs
   322  	for _, pair := range cols {
   323  		joinRefs = append(joinRefs, &pair[0], &pair[1])
   324  	}
   325  
   326  	var cond tree.TypedExpr
   327  	// Pick some prefix of the available columns. Not randomized because it
   328  	// needs to match the index column order.
   329  	for (cond == nil || s.coin()) && len(cols) > 0 {
   330  		v := cols[0]
   331  		cols = cols[1:]
   332  		expr := tree.NewTypedComparisonExpr(
   333  			tree.EQ,
   334  			typedParen(v[0].item, v[0].typ),
   335  			typedParen(v[1].item, v[1].typ),
   336  		)
   337  		if cond == nil {
   338  			cond = expr
   339  		} else {
   340  			cond = tree.NewTypedAndExpr(cond, expr)
   341  		}
   342  	}
   343  
   344  	joinExpr := &tree.JoinTableExpr{
   345  		Left: &tree.AliasedTableExpr{
   346  			Expr: &leftTableName.Table,
   347  			As:   tree.AliasClause{Alias: leftAlias},
   348  		},
   349  		Right: &tree.AliasedTableExpr{
   350  			Expr: &rightTableName.Table,
   351  			As:   tree.AliasClause{Alias: rightAlias},
   352  		},
   353  		Cond: &tree.OnJoinCond{Expr: cond},
   354  	}
   355  	return joinExpr, joinRefs, true
   356  }
   357  
   358  // STATEMENTS
   359  
   360  func (s *Smither) makeWith() (*tree.With, tableRefs) {
   361  	if s.disableWith {
   362  		return nil, nil
   363  	}
   364  
   365  	// WITHs are pretty rare, so just ignore them a lot.
   366  	if s.coin() {
   367  		return nil, nil
   368  	}
   369  	ctes := make([]*tree.CTE, 0, s.d6()/2)
   370  	if cap(ctes) == 0 {
   371  		return nil, nil
   372  	}
   373  	var tables tableRefs
   374  	for i := 0; i < cap(ctes); i++ {
   375  		var ok bool
   376  		var stmt tree.SelectStatement
   377  		var stmtRefs colRefs
   378  		stmt, stmtRefs, ok = s.makeSelectStmt(s.makeDesiredTypes(), nil /* refs */, tables)
   379  		if !ok {
   380  			continue
   381  		}
   382  		alias := s.name("with")
   383  		tblName := tree.NewUnqualifiedTableName(alias)
   384  		cols := make(tree.NameList, len(stmtRefs))
   385  		defs := make([]*tree.ColumnTableDef, len(stmtRefs))
   386  		for i, r := range stmtRefs {
   387  			var err error
   388  			cols[i] = r.item.ColumnName
   389  			defs[i], err = tree.NewColumnTableDef(r.item.ColumnName, r.typ, false /* isSerial */, nil)
   390  			if err != nil {
   391  				panic(err)
   392  			}
   393  		}
   394  		tables = append(tables, &tableRef{
   395  			TableName: tblName,
   396  			Columns:   defs,
   397  		})
   398  		ctes = append(ctes, &tree.CTE{
   399  			Name: tree.AliasClause{
   400  				Alias: alias,
   401  				Cols:  cols,
   402  			},
   403  			Stmt: stmt,
   404  		})
   405  	}
   406  	return &tree.With{
   407  		CTEList: ctes,
   408  	}, tables
   409  }
   410  
   411  var orderDirections = []tree.Direction{
   412  	tree.DefaultDirection,
   413  	tree.Ascending,
   414  	tree.Descending,
   415  }
   416  
   417  func (s *Smither) randDirection() tree.Direction {
   418  	return orderDirections[s.rnd.Intn(len(orderDirections))]
   419  }
   420  
   421  var nullabilities = []tree.Nullability{
   422  	tree.NotNull,
   423  	tree.Null,
   424  	tree.SilentNull,
   425  }
   426  
   427  func (s *Smither) randNullability() tree.Nullability {
   428  	return nullabilities[s.rnd.Intn(len(nullabilities))]
   429  }
   430  
   431  var dropBehaviors = []tree.DropBehavior{
   432  	tree.DropDefault,
   433  	tree.DropRestrict,
   434  	tree.DropCascade,
   435  }
   436  
   437  func (s *Smither) randDropBehavior() tree.DropBehavior {
   438  	return dropBehaviors[s.rnd.Intn(len(dropBehaviors))]
   439  }
   440  
   441  var stringComparisons = []tree.ComparisonOperator{
   442  	tree.Like,
   443  	tree.NotLike,
   444  	tree.ILike,
   445  	tree.NotILike,
   446  	tree.SimilarTo,
   447  	tree.NotSimilarTo,
   448  	tree.RegMatch,
   449  	tree.NotRegMatch,
   450  	tree.RegIMatch,
   451  	tree.NotRegIMatch,
   452  }
   453  
   454  func (s *Smither) randStringComparison() tree.ComparisonOperator {
   455  	return stringComparisons[s.rnd.Intn(len(stringComparisons))]
   456  }
   457  
   458  // makeSelectTable returns a TableExpr of the form `(SELECT ...)`, which
   459  // would end up looking like `SELECT ... FROM (SELECT ...)`.
   460  func makeSelectTable(s *Smither, refs colRefs, forJoin bool) (tree.TableExpr, colRefs, bool) {
   461  	stmt, stmtRefs, ok := s.makeSelect(nil /* desiredTypes */, refs)
   462  	if !ok {
   463  		return nil, nil, false
   464  	}
   465  
   466  	table := s.name("tab")
   467  	names := make(tree.NameList, len(stmtRefs))
   468  	clauseRefs := make(colRefs, len(stmtRefs))
   469  	for i, ref := range stmtRefs {
   470  		names[i] = s.name("col")
   471  		clauseRefs[i] = &colRef{
   472  			typ: ref.typ,
   473  			item: tree.NewColumnItem(
   474  				tree.NewUnqualifiedTableName(table),
   475  				names[i],
   476  			),
   477  		}
   478  	}
   479  
   480  	return &tree.AliasedTableExpr{
   481  		Expr: &tree.Subquery{
   482  			Select: &tree.ParenSelect{Select: stmt},
   483  		},
   484  		As: tree.AliasClause{
   485  			Alias: table,
   486  			Cols:  names,
   487  		},
   488  	}, clauseRefs, true
   489  }
   490  
   491  func makeSelectClause(
   492  	s *Smither, desiredTypes []*types.T, refs colRefs, withTables tableRefs,
   493  ) (tree.SelectStatement, colRefs, bool) {
   494  	stmt, selectRefs, _, ok := s.makeSelectClause(desiredTypes, refs, withTables)
   495  	return stmt, selectRefs, ok
   496  }
   497  
   498  func (s *Smither) makeSelectClause(
   499  	desiredTypes []*types.T, refs colRefs, withTables tableRefs,
   500  ) (clause *tree.SelectClause, selectRefs, orderByRefs colRefs, ok bool) {
   501  	if desiredTypes == nil && s.d9() == 1 {
   502  		return s.makeOrderedAggregate()
   503  	}
   504  
   505  	clause = &tree.SelectClause{}
   506  
   507  	var fromRefs colRefs
   508  	// Sometimes generate a SELECT with no FROM clause.
   509  	requireFrom := s.vectorizable || s.d6() != 1
   510  	for (requireFrom && len(clause.From.Tables) < 1) || s.canRecurse() {
   511  		var from tree.TableExpr
   512  		if len(withTables) == 0 || s.coin() {
   513  			// Add a normal data source.
   514  			source, sourceRefs, sourceOk := makeTableExpr(s, refs, false)
   515  			if !sourceOk {
   516  				return nil, nil, nil, false
   517  			}
   518  			from = source
   519  			fromRefs = append(fromRefs, sourceRefs...)
   520  		} else {
   521  			// Add a CTE reference.
   522  			table := withTables[s.rnd.Intn(len(withTables))]
   523  
   524  			alias := s.name("cte_ref")
   525  			name := tree.NewUnqualifiedTableName(alias)
   526  			expr, exprRefs := s.tableExpr(table, name)
   527  
   528  			from = &tree.AliasedTableExpr{
   529  				Expr: expr,
   530  				As:   tree.AliasClause{Alias: alias},
   531  			}
   532  			fromRefs = append(fromRefs, exprRefs...)
   533  		}
   534  		clause.From.Tables = append(clause.From.Tables, from)
   535  		// Restrict so that we don't have a crazy amount of rows due to many joins.
   536  		if len(clause.From.Tables) >= 4 {
   537  			break
   538  		}
   539  	}
   540  
   541  	selectListRefs := refs
   542  	ctx := emptyCtx
   543  
   544  	if len(clause.From.Tables) > 0 {
   545  		clause.Where = s.makeWhere(fromRefs)
   546  		orderByRefs = fromRefs
   547  		selectListRefs = selectListRefs.extend(fromRefs...)
   548  
   549  		// TODO(mjibson): vec only supports GROUP BYs on fully-ordered
   550  		// columns, which we could support here. Also see #39240 which
   551  		// will support this more generally.
   552  		if !s.vectorizable && s.d6() <= 2 && s.canRecurse() {
   553  			// Enable GROUP BY. Choose some random subset of the
   554  			// fromRefs.
   555  			// TODO(mjibson): Refence handling and aggregation functions
   556  			// aren't quite handled correctly here. This currently
   557  			// does well enough to at least find some bugs but should
   558  			// be improved to do the correct thing wrt aggregate
   559  			// functions. That is, the select and having exprs can
   560  			// either reference a group by column or a non-group by
   561  			// column in an aggregate function. It's also possible
   562  			// the where and order by exprs are not correct.
   563  			groupByRefs := fromRefs.extend()
   564  			s.rnd.Shuffle(len(groupByRefs), func(i, j int) {
   565  				groupByRefs[i], groupByRefs[j] = groupByRefs[j], groupByRefs[i]
   566  			})
   567  			var groupBy tree.GroupBy
   568  			for (len(groupBy) < 1 || s.coin()) && len(groupBy) < len(groupByRefs) {
   569  				groupBy = append(groupBy, groupByRefs[len(groupBy)].item)
   570  			}
   571  			groupByRefs = groupByRefs[:len(groupBy)]
   572  			clause.GroupBy = groupBy
   573  			clause.Having = s.makeHaving(fromRefs)
   574  			selectListRefs = groupByRefs
   575  			orderByRefs = groupByRefs
   576  			// TODO(mjibson): also use this context sometimes in
   577  			// non-aggregate mode (select sum(x) from a).
   578  			ctx = groupByCtx
   579  		} else if s.d6() <= 1 && s.canRecurse() {
   580  			// Enable window functions. This will enable them for all
   581  			// exprs, but makeFunc will only let a few through.
   582  			ctx = windowCtx
   583  		}
   584  	}
   585  
   586  	selectList, selectRefs, ok := s.makeSelectList(ctx, desiredTypes, selectListRefs)
   587  	if !ok {
   588  		return nil, nil, nil, false
   589  	}
   590  	clause.Exprs = selectList
   591  
   592  	// TODO(mjibson): Vectorized only supports ordered distinct, and so
   593  	// this often produces queries that won't vec. However since it will
   594  	// also sometimes produce vec queries with the distinctChainOps node,
   595  	// we allow this here. Teach this how to correctly limit itself to
   596  	// distinct only on ordered columns.
   597  	if s.d100() == 1 {
   598  		clause.Distinct = true
   599  		// For SELECT DISTINCT, ORDER BY expressions must appear in select list.
   600  		orderByRefs = selectRefs
   601  	}
   602  
   603  	return clause, selectRefs, orderByRefs, true
   604  }
   605  
   606  func (s *Smither) makeOrderedAggregate() (
   607  	clause *tree.SelectClause,
   608  	selectRefs, orderByRefs colRefs,
   609  	ok bool,
   610  ) {
   611  	// We need a SELECT with a GROUP BY on ordered columns. Choose a random
   612  	// table and index from that table and pick a random prefix from it.
   613  	tableExpr, tableAlias, table, tableColRefs, ok := s.getSchemaTableWithIndexHint()
   614  	if !ok {
   615  		return nil, nil, nil, false
   616  	}
   617  	_, _, idxRefs, ok := s.getRandTableIndex(*table.TableName, *tableAlias)
   618  	if !ok {
   619  		return nil, nil, nil, false
   620  	}
   621  
   622  	var groupBy tree.GroupBy
   623  	for (len(groupBy) < 1 || s.coin()) && len(groupBy) < len(idxRefs) {
   624  		groupBy = append(groupBy, idxRefs[len(groupBy)].item)
   625  	}
   626  	idxRefs = idxRefs[:len(groupBy)]
   627  	alias := s.name("col")
   628  	selectRefs = colRefs{
   629  		{
   630  			typ:  types.Int,
   631  			item: &tree.ColumnItem{ColumnName: alias},
   632  		},
   633  	}
   634  	return &tree.SelectClause{
   635  		Exprs: tree.SelectExprs{
   636  			{
   637  				Expr: countStar,
   638  				As:   tree.UnrestrictedName(alias),
   639  			},
   640  		},
   641  		From: tree.From{
   642  			Tables: tree.TableExprs{tableExpr},
   643  		},
   644  		Where:   s.makeWhere(tableColRefs),
   645  		GroupBy: groupBy,
   646  		Having:  s.makeHaving(idxRefs),
   647  	}, selectRefs, idxRefs, true
   648  }
   649  
   650  var countStar = func() tree.TypedExpr {
   651  	fn := tree.FunDefs["count"]
   652  	typ := types.Int
   653  	return tree.NewTypedFuncExpr(
   654  		tree.ResolvableFunctionReference{FunctionReference: fn},
   655  		0, /* aggQualifier */
   656  		tree.TypedExprs{tree.UnqualifiedStar{}},
   657  		nil, /* filter */
   658  		nil, /* window */
   659  		typ,
   660  		&fn.FunctionProperties,
   661  		fn.Definition[0].(*tree.Overload),
   662  	)
   663  }()
   664  
   665  func makeSelect(s *Smither) (tree.Statement, bool) {
   666  	stmt, refs, ok := s.makeSelect(nil, nil)
   667  	if !ok {
   668  		return stmt, ok
   669  	}
   670  	if s.outputSort {
   671  		order := make(tree.OrderBy, len(refs))
   672  		for i, r := range refs {
   673  			order[i] = &tree.Order{
   674  				Expr:       r.item,
   675  				NullsOrder: tree.NullsFirst,
   676  			}
   677  		}
   678  		stmt = &tree.Select{
   679  			Select: &tree.SelectClause{
   680  				Exprs: tree.SelectExprs{
   681  					tree.SelectExpr{
   682  						Expr: tree.UnqualifiedStar{},
   683  					},
   684  				},
   685  				From: tree.From{
   686  					Tables: tree.TableExprs{
   687  						&tree.AliasedTableExpr{
   688  							Expr: &tree.Subquery{
   689  								Select: &tree.ParenSelect{Select: stmt},
   690  							},
   691  							As: tree.AliasClause{
   692  								Alias: s.name("tab"),
   693  							},
   694  						},
   695  					},
   696  				},
   697  			},
   698  			OrderBy: order,
   699  		}
   700  	}
   701  	return stmt, ok
   702  }
   703  
   704  func (s *Smither) makeSelect(desiredTypes []*types.T, refs colRefs) (*tree.Select, colRefs, bool) {
   705  	withStmt, withTables := s.makeWith()
   706  
   707  	clause, selectRefs, orderByRefs, ok := s.makeSelectClause(desiredTypes, refs, withTables)
   708  	if !ok {
   709  		return nil, nil, ok
   710  	}
   711  
   712  	stmt := tree.Select{
   713  		Select:  clause,
   714  		With:    withStmt,
   715  		OrderBy: s.makeOrderBy(orderByRefs),
   716  		Limit:   makeLimit(s),
   717  	}
   718  
   719  	return &stmt, selectRefs, true
   720  }
   721  
   722  // makeSelectList generates SelectExprs corresponding to
   723  // desiredTypes. desiredTypes can be nil which causes types to be randomly
   724  // selected from refs, improving the chance they are chosen during
   725  // makeScalar. Especially useful with the AvoidConsts option.
   726  func (s *Smither) makeSelectList(
   727  	ctx Context, desiredTypes []*types.T, refs colRefs,
   728  ) (tree.SelectExprs, colRefs, bool) {
   729  	// If we don't have any desired types, generate some from the given refs.
   730  	if len(desiredTypes) == 0 {
   731  		s.sample(len(refs), 6, func(i int) {
   732  			desiredTypes = append(desiredTypes, refs[i].typ)
   733  		})
   734  	}
   735  	// If we still don't have any then there weren't any refs.
   736  	if len(desiredTypes) == 0 {
   737  		desiredTypes = s.makeDesiredTypes()
   738  	}
   739  	result := make(tree.SelectExprs, len(desiredTypes))
   740  	selectRefs := make(colRefs, len(desiredTypes))
   741  	for i, t := range desiredTypes {
   742  		result[i].Expr = makeScalarContext(s, ctx, t, refs)
   743  		alias := s.name("col")
   744  		result[i].As = tree.UnrestrictedName(alias)
   745  		selectRefs[i] = &colRef{
   746  			typ:  t,
   747  			item: &tree.ColumnItem{ColumnName: alias},
   748  		}
   749  	}
   750  	return result, selectRefs, true
   751  }
   752  
   753  func makeDelete(s *Smither) (tree.Statement, bool) {
   754  	stmt, _, ok := s.makeDelete(nil)
   755  	return stmt, ok
   756  }
   757  
   758  func (s *Smither) makeDelete(refs colRefs) (*tree.Delete, *tableRef, bool) {
   759  	table, _, tableRef, tableRefs, ok := s.getSchemaTable()
   760  	if !ok {
   761  		return nil, nil, false
   762  	}
   763  
   764  	del := &tree.Delete{
   765  		Table:     table,
   766  		Where:     s.makeWhere(tableRefs),
   767  		OrderBy:   s.makeOrderBy(tableRefs),
   768  		Limit:     makeLimit(s),
   769  		Returning: &tree.NoReturningClause{},
   770  	}
   771  	if del.Limit == nil {
   772  		del.OrderBy = nil
   773  	}
   774  
   775  	return del, tableRef, true
   776  }
   777  
   778  func makeDeleteReturning(s *Smither, refs colRefs, forJoin bool) (tree.TableExpr, colRefs, bool) {
   779  	if forJoin {
   780  		return nil, nil, false
   781  	}
   782  	return s.makeDeleteReturning(refs)
   783  }
   784  
   785  func (s *Smither) makeDeleteReturning(refs colRefs) (tree.TableExpr, colRefs, bool) {
   786  	del, delRef, ok := s.makeDelete(refs)
   787  	if !ok {
   788  		return nil, nil, false
   789  	}
   790  	var returningRefs colRefs
   791  	del.Returning, returningRefs = s.makeReturning(delRef)
   792  	return &tree.StatementSource{
   793  		Statement: del,
   794  	}, returningRefs, true
   795  }
   796  
   797  func makeUpdate(s *Smither) (tree.Statement, bool) {
   798  	stmt, _, ok := s.makeUpdate(nil)
   799  	return stmt, ok
   800  }
   801  
   802  func (s *Smither) makeUpdate(refs colRefs) (*tree.Update, *tableRef, bool) {
   803  	table, _, tableRef, tableRefs, ok := s.getSchemaTable()
   804  	if !ok {
   805  		return nil, nil, false
   806  	}
   807  	cols := make(map[tree.Name]*tree.ColumnTableDef)
   808  	for _, c := range tableRef.Columns {
   809  		cols[c.Name] = c
   810  	}
   811  
   812  	update := &tree.Update{
   813  		Table:     table,
   814  		Where:     s.makeWhere(tableRefs),
   815  		OrderBy:   s.makeOrderBy(tableRefs),
   816  		Limit:     makeLimit(s),
   817  		Returning: &tree.NoReturningClause{},
   818  	}
   819  	// Each row can be set at most once. Copy tableRefs to upRefs and remove
   820  	// elements from it as we use them.
   821  	upRefs := tableRefs.extend()
   822  	for (len(update.Exprs) < 1 || s.coin()) && len(upRefs) > 0 {
   823  		n := s.rnd.Intn(len(upRefs))
   824  		ref := upRefs[n]
   825  		upRefs = append(upRefs[:n], upRefs[n+1:]...)
   826  		col := cols[ref.item.ColumnName]
   827  		// Ignore computed columns.
   828  		if col == nil || col.Computed.Computed {
   829  			continue
   830  		}
   831  		var expr tree.TypedExpr
   832  		for {
   833  			expr = makeScalar(s, ref.typ, tableRefs)
   834  			// Make sure expr isn't null if that's not allowed.
   835  			if col.Nullable.Nullability != tree.NotNull || expr != tree.DNull {
   836  				break
   837  			}
   838  		}
   839  		update.Exprs = append(update.Exprs, &tree.UpdateExpr{
   840  			Names: tree.NameList{ref.item.ColumnName},
   841  			Expr:  expr,
   842  		})
   843  	}
   844  	if len(update.Exprs) == 0 {
   845  		panic("empty")
   846  	}
   847  	if update.Limit == nil {
   848  		update.OrderBy = nil
   849  	}
   850  
   851  	return update, tableRef, true
   852  }
   853  
   854  func makeUpdateReturning(s *Smither, refs colRefs, forJoin bool) (tree.TableExpr, colRefs, bool) {
   855  	if forJoin {
   856  		return nil, nil, false
   857  	}
   858  	return s.makeUpdateReturning(refs)
   859  }
   860  
   861  func (s *Smither) makeUpdateReturning(refs colRefs) (tree.TableExpr, colRefs, bool) {
   862  	update, updateRef, ok := s.makeUpdate(refs)
   863  	if !ok {
   864  		return nil, nil, false
   865  	}
   866  	var returningRefs colRefs
   867  	update.Returning, returningRefs = s.makeReturning(updateRef)
   868  	return &tree.StatementSource{
   869  		Statement: update,
   870  	}, returningRefs, true
   871  }
   872  
   873  func makeInsert(s *Smither) (tree.Statement, bool) {
   874  	stmt, _, ok := s.makeInsert(nil)
   875  	return stmt, ok
   876  }
   877  
   878  func makeBegin(s *Smither) (tree.Statement, bool) {
   879  	return &tree.BeginTransaction{}, true
   880  }
   881  
   882  func makeSavepoint(s *Smither) (tree.Statement, bool) {
   883  	savepointName := s.randString(s.d9(), letters)
   884  	s.activeSavepoints = append(s.activeSavepoints, savepointName)
   885  	return &tree.Savepoint{Name: tree.Name(savepointName)}, true
   886  }
   887  
   888  func makeReleaseSavepoint(s *Smither) (tree.Statement, bool) {
   889  	if len(s.activeSavepoints) == 0 {
   890  		return nil, false
   891  	}
   892  	idx := s.rnd.Intn(len(s.activeSavepoints))
   893  	savepoint := s.activeSavepoints[idx]
   894  	// Remove the released savepoint from our set of active savepoints.
   895  	s.activeSavepoints = append(s.activeSavepoints[:idx], s.activeSavepoints[idx+1:]...)
   896  	return &tree.ReleaseSavepoint{Savepoint: tree.Name(savepoint)}, true
   897  }
   898  
   899  func makeRollbackToSavepoint(s *Smither) (tree.Statement, bool) {
   900  	if len(s.activeSavepoints) == 0 {
   901  		return nil, false
   902  	}
   903  	idx := s.rnd.Intn(len(s.activeSavepoints))
   904  	savepoint := s.activeSavepoints[idx]
   905  	// Destroy all savepoints that come after the savepoint we rollback to.
   906  	s.activeSavepoints = s.activeSavepoints[:idx+1]
   907  	return &tree.RollbackToSavepoint{Savepoint: tree.Name(savepoint)}, true
   908  }
   909  
   910  func makeCommit(s *Smither) (tree.Statement, bool) {
   911  	return &tree.CommitTransaction{}, true
   912  }
   913  
   914  func makeRollback(s *Smither) (tree.Statement, bool) {
   915  	return &tree.RollbackTransaction{}, true
   916  }
   917  
   918  // makeInsert has only one valid reference: its table source, which can be
   919  // used only in the optional returning section. Hence the irregular return
   920  // signature.
   921  func (s *Smither) makeInsert(refs colRefs) (*tree.Insert, *tableRef, bool) {
   922  	table, _, tableRef, _, ok := s.getSchemaTable()
   923  	if !ok {
   924  		return nil, nil, false
   925  	}
   926  
   927  	insert := &tree.Insert{
   928  		Table:     table,
   929  		Rows:      &tree.Select{},
   930  		Returning: &tree.NoReturningClause{},
   931  	}
   932  
   933  	// Use DEFAULT VALUES only sometimes. A nil insert.Rows.Select indicates
   934  	// DEFAULT VALUES.
   935  	if s.d9() != 1 {
   936  		var desiredTypes []*types.T
   937  		var names tree.NameList
   938  
   939  		unnamed := s.coin()
   940  
   941  		// Grab some subset of the columns of the table to attempt to insert into.
   942  		for _, c := range tableRef.Columns {
   943  			// We *must* write a column if it's writable and non-nullable.
   944  			// We *can* write a column if it's writable and nullable.
   945  			if c.Computed.Computed {
   946  				continue
   947  			}
   948  			if unnamed || c.Nullable.Nullability == tree.NotNull || s.coin() {
   949  				desiredTypes = append(desiredTypes, tree.MustBeStaticallyKnownType(c.Type))
   950  				names = append(names, c.Name)
   951  			}
   952  		}
   953  		if len(desiredTypes) == 0 {
   954  			return nil, nil, false
   955  		}
   956  		if !unnamed {
   957  			insert.Columns = names
   958  		}
   959  
   960  		insert.Rows, _, ok = s.makeSelect(desiredTypes, refs)
   961  		if !ok {
   962  			return nil, nil, false
   963  		}
   964  	}
   965  
   966  	return insert, tableRef, true
   967  }
   968  
   969  func makeInsertReturning(s *Smither, refs colRefs, forJoin bool) (tree.TableExpr, colRefs, bool) {
   970  	if forJoin {
   971  		return nil, nil, false
   972  	}
   973  	return s.makeInsertReturning(refs)
   974  }
   975  
   976  func (s *Smither) makeInsertReturning(refs colRefs) (tree.TableExpr, colRefs, bool) {
   977  	insert, insertRef, ok := s.makeInsert(refs)
   978  	if !ok {
   979  		return nil, nil, false
   980  	}
   981  	var returningRefs colRefs
   982  	insert.Returning, returningRefs = s.makeReturning(insertRef)
   983  	return &tree.StatementSource{
   984  		Statement: insert,
   985  	}, returningRefs, true
   986  }
   987  
   988  func makeValuesTable(s *Smither, refs colRefs, forJoin bool) (tree.TableExpr, colRefs, bool) {
   989  	types := s.makeDesiredTypes()
   990  	values, valuesRefs := makeValues(s, types, refs)
   991  	return values, valuesRefs, true
   992  }
   993  
   994  func makeValues(s *Smither, desiredTypes []*types.T, refs colRefs) (tree.TableExpr, colRefs) {
   995  	numRowsToInsert := s.d6()
   996  	values := tree.ValuesClause{
   997  		Rows: make([]tree.Exprs, numRowsToInsert),
   998  	}
   999  
  1000  	for i := 0; i < numRowsToInsert; i++ {
  1001  		tuple := make([]tree.Expr, len(desiredTypes))
  1002  		for j, t := range desiredTypes {
  1003  			tuple[j] = makeScalar(s, t, refs)
  1004  		}
  1005  		values.Rows[i] = tuple
  1006  	}
  1007  	table := s.name("tab")
  1008  	names := make(tree.NameList, len(desiredTypes))
  1009  	valuesRefs := make(colRefs, len(desiredTypes))
  1010  	for i, typ := range desiredTypes {
  1011  		names[i] = s.name("col")
  1012  		valuesRefs[i] = &colRef{
  1013  			typ: typ,
  1014  			item: tree.NewColumnItem(
  1015  				tree.NewUnqualifiedTableName(table),
  1016  				names[i],
  1017  			),
  1018  		}
  1019  	}
  1020  
  1021  	return &tree.AliasedTableExpr{
  1022  		Expr: &tree.Subquery{
  1023  			Select: &tree.ParenSelect{
  1024  				Select: &tree.Select{
  1025  					Select: &values,
  1026  				},
  1027  			},
  1028  		},
  1029  		As: tree.AliasClause{
  1030  			Alias: table,
  1031  			Cols:  names,
  1032  		},
  1033  	}, valuesRefs
  1034  }
  1035  
  1036  func makeValuesSelect(
  1037  	s *Smither, desiredTypes []*types.T, refs colRefs, withTables tableRefs,
  1038  ) (tree.SelectStatement, colRefs, bool) {
  1039  	values, valuesRefs := makeValues(s, desiredTypes, refs)
  1040  
  1041  	// Returning just &values here would result in a query like `VALUES (...)` where
  1042  	// the columns are arbitrarily named by index (column1, column2, etc.). Since
  1043  	// we want to be able to reference the columns in other places we need to
  1044  	// name them deterministically. We can use `SELECT * FROM (VALUES (...)) AS
  1045  	// tbl (c1, c2, etc.)` to achieve this. There's quite a lot of indirection
  1046  	// for how to achieve exactly that syntax as tree nodes, but it works.
  1047  	return &tree.SelectClause{
  1048  		Exprs: tree.SelectExprs{tree.StarSelectExpr()},
  1049  		From: tree.From{
  1050  			Tables: tree.TableExprs{values},
  1051  		},
  1052  	}, valuesRefs, true
  1053  }
  1054  
  1055  var setOps = []tree.UnionType{
  1056  	tree.UnionOp,
  1057  	tree.IntersectOp,
  1058  	tree.ExceptOp,
  1059  }
  1060  
  1061  func makeSetOp(
  1062  	s *Smither, desiredTypes []*types.T, refs colRefs, withTables tableRefs,
  1063  ) (tree.SelectStatement, colRefs, bool) {
  1064  	left, leftRefs, ok := s.makeSelectStmt(desiredTypes, refs, withTables)
  1065  	if !ok {
  1066  		return nil, nil, false
  1067  	}
  1068  
  1069  	right, _, ok := s.makeSelectStmt(desiredTypes, refs, withTables)
  1070  	if !ok {
  1071  		return nil, nil, false
  1072  	}
  1073  
  1074  	return &tree.UnionClause{
  1075  		Type:  setOps[s.rnd.Intn(len(setOps))],
  1076  		Left:  &tree.Select{Select: left},
  1077  		Right: &tree.Select{Select: right},
  1078  		All:   s.coin(),
  1079  	}, leftRefs, true
  1080  }
  1081  
  1082  func (s *Smither) makeWhere(refs colRefs) *tree.Where {
  1083  	if s.coin() {
  1084  		where := makeBoolExpr(s, refs)
  1085  		return tree.NewWhere("WHERE", where)
  1086  	}
  1087  	return nil
  1088  }
  1089  
  1090  func (s *Smither) makeHaving(refs colRefs) *tree.Where {
  1091  	if s.coin() {
  1092  		where := makeBoolExprContext(s, havingCtx, refs)
  1093  		return tree.NewWhere("HAVING", where)
  1094  	}
  1095  	return nil
  1096  }
  1097  
  1098  func (s *Smither) makeOrderBy(refs colRefs) tree.OrderBy {
  1099  	if len(refs) == 0 {
  1100  		return nil
  1101  	}
  1102  	var ob tree.OrderBy
  1103  	for s.coin() {
  1104  		ref := refs[s.rnd.Intn(len(refs))]
  1105  		// We don't support order by jsonb columns.
  1106  		if ref.typ.Family() == types.JsonFamily {
  1107  			continue
  1108  		}
  1109  		ob = append(ob, &tree.Order{
  1110  			Expr:      ref.item,
  1111  			Direction: s.randDirection(),
  1112  		})
  1113  	}
  1114  	return ob
  1115  }
  1116  
  1117  func makeLimit(s *Smither) *tree.Limit {
  1118  	if s.disableLimits {
  1119  		return nil
  1120  	}
  1121  	if s.d6() > 2 {
  1122  		return &tree.Limit{Count: tree.NewDInt(tree.DInt(s.d100()))}
  1123  	}
  1124  	return nil
  1125  }
  1126  
  1127  func (s *Smither) makeReturning(table *tableRef) (*tree.ReturningExprs, colRefs) {
  1128  	desiredTypes := s.makeDesiredTypes()
  1129  
  1130  	refs := make(colRefs, len(table.Columns))
  1131  	for i, c := range table.Columns {
  1132  		refs[i] = &colRef{
  1133  			typ:  tree.MustBeStaticallyKnownType(c.Type),
  1134  			item: &tree.ColumnItem{ColumnName: c.Name},
  1135  		}
  1136  	}
  1137  
  1138  	returning := make(tree.ReturningExprs, len(desiredTypes))
  1139  	returningRefs := make(colRefs, len(desiredTypes))
  1140  	for i, t := range desiredTypes {
  1141  		returning[i].Expr = makeScalar(s, t, refs)
  1142  		alias := s.name("ret")
  1143  		returning[i].As = tree.UnrestrictedName(alias)
  1144  		returningRefs[i] = &colRef{
  1145  			typ: t,
  1146  			item: &tree.ColumnItem{
  1147  				ColumnName: alias,
  1148  			},
  1149  		}
  1150  	}
  1151  	return &returning, returningRefs
  1152  }