github.com/cockroachdb/cockroachdb-parser@v0.23.3-0.20240213214944-911057d40c9a/pkg/sql/sem/tree/create.go (about)

     1  // Copyright 2012, Google Inc. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in licenses/BSD-vitess.txt.
     4  
     5  // Portions of this file are additionally subject to the following
     6  // license and copyright.
     7  //
     8  // Copyright 2015 The Cockroach Authors.
     9  //
    10  // Use of this software is governed by the Business Source License
    11  // included in the file licenses/BSL.txt.
    12  //
    13  // As of the Change Date specified in that file, in accordance with
    14  // the Business Source License, use of this software will be governed
    15  // by the Apache License, Version 2.0, included in the file
    16  // licenses/APL.txt.
    17  
    18  // This code was derived from https://github.com/youtube/vitess.
    19  
    20  package tree
    21  
    22  import (
    23  	"fmt"
    24  	"math/rand"
    25  	"strconv"
    26  	"strings"
    27  
    28  	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/lexbase"
    29  	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode"
    30  	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror"
    31  	"github.com/cockroachdb/cockroachdb-parser/pkg/sql/types"
    32  	"github.com/cockroachdb/cockroachdb-parser/pkg/util/collatedstring"
    33  	"github.com/cockroachdb/cockroachdb-parser/pkg/util/pretty"
    34  	"github.com/cockroachdb/errors"
    35  	"github.com/cockroachdb/redact"
    36  	"golang.org/x/text/language"
    37  )
    38  
    39  // CreateDatabase represents a CREATE DATABASE statement.
    40  type CreateDatabase struct {
    41  	IfNotExists     bool
    42  	Name            Name
    43  	Template        string
    44  	Encoding        string
    45  	Collate         string
    46  	CType           string
    47  	ConnectionLimit int32
    48  	PrimaryRegion   Name
    49  	Regions         NameList
    50  	SurvivalGoal    SurvivalGoal
    51  	Placement       DataPlacement
    52  	Owner           RoleSpec
    53  	SuperRegion     SuperRegion
    54  	SecondaryRegion Name
    55  }
    56  
    57  // Format implements the NodeFormatter interface.
    58  func (node *CreateDatabase) Format(ctx *FmtCtx) {
    59  	ctx.WriteString("CREATE DATABASE ")
    60  	if node.IfNotExists {
    61  		ctx.WriteString("IF NOT EXISTS ")
    62  	}
    63  	ctx.FormatNode(&node.Name)
    64  	if node.Template != "" {
    65  		// NB: the template is not currently edited out under FmtAnonymize,
    66  		// because we don't support custom templates. If/when custom
    67  		// templates are supported, this should call ctx.FormatNode
    68  		// on the template expr.
    69  		ctx.WriteString(" TEMPLATE = ")
    70  		lexbase.EncodeSQLStringWithFlags(&ctx.Buffer, node.Template, ctx.flags.EncodeFlags())
    71  	}
    72  	if node.Encoding != "" {
    73  		// NB: the encoding is not currently edited out under FmtAnonymize,
    74  		// because we don't support custom encodings. If/when custom
    75  		// encodings are supported, this should call ctx.FormatNode
    76  		// on the encoding expr.
    77  		ctx.WriteString(" ENCODING = ")
    78  		lexbase.EncodeSQLStringWithFlags(&ctx.Buffer, node.Encoding, ctx.flags.EncodeFlags())
    79  	}
    80  	if node.Collate != "" {
    81  		// NB: the collation is not currently edited out under FmtAnonymize,
    82  		// because we don't support custom collations. If/when custom
    83  		// collations are supported, this should call ctx.FormatNode
    84  		// on the collation expr.
    85  		ctx.WriteString(" LC_COLLATE = ")
    86  		lexbase.EncodeSQLStringWithFlags(&ctx.Buffer, node.Collate, ctx.flags.EncodeFlags())
    87  	}
    88  	if node.CType != "" {
    89  		// NB: the ctype (formatting customization) is not currently
    90  		// edited out under FmtAnonymize, because we don't support custom
    91  		// cutomizations. If/when custom customizations are supported,
    92  		// this should call ctx.FormatNode on the ctype expr.
    93  		ctx.WriteString(" LC_CTYPE = ")
    94  		lexbase.EncodeSQLStringWithFlags(&ctx.Buffer, node.CType, ctx.flags.EncodeFlags())
    95  	}
    96  	if node.ConnectionLimit != -1 {
    97  		ctx.WriteString(" CONNECTION LIMIT = ")
    98  		if ctx.flags.HasFlags(FmtHideConstants) {
    99  			ctx.WriteByte('0')
   100  		} else {
   101  			// NB: use ctx.FormatNode when the connection limit becomes an expression.
   102  			ctx.WriteString(strconv.Itoa(int(node.ConnectionLimit)))
   103  		}
   104  	}
   105  	if node.PrimaryRegion != "" {
   106  		ctx.WriteString(" PRIMARY REGION ")
   107  		ctx.FormatNode(&node.PrimaryRegion)
   108  	}
   109  	if node.Regions != nil {
   110  		ctx.WriteString(" REGIONS = ")
   111  		ctx.FormatNode(&node.Regions)
   112  	}
   113  	if node.SurvivalGoal != SurvivalGoalDefault {
   114  		ctx.WriteString(" ")
   115  		ctx.FormatNode(&node.SurvivalGoal)
   116  	}
   117  	if node.Placement != DataPlacementUnspecified {
   118  		ctx.WriteString(" ")
   119  		ctx.FormatNode(&node.Placement)
   120  	}
   121  
   122  	if node.Owner.Name != "" {
   123  		ctx.WriteString(" OWNER = ")
   124  		ctx.FormatNode(&node.Owner)
   125  	}
   126  
   127  	if node.SuperRegion.Name != "" {
   128  		ctx.FormatNode(&node.SuperRegion)
   129  	}
   130  
   131  	if node.SecondaryRegion != "" {
   132  		ctx.WriteString(" SECONDARY REGION ")
   133  		ctx.FormatNode(&node.SecondaryRegion)
   134  	}
   135  }
   136  
   137  // IndexElem represents a column with a direction in a CREATE INDEX statement.
   138  type IndexElem struct {
   139  	// Column is set if this is a simple column reference (the common case).
   140  	Column Name
   141  	// Expr is set if the index element is an expression (part of an expression
   142  	// index). If set, Column is empty.
   143  	Expr       Expr
   144  	Direction  Direction
   145  	NullsOrder NullsOrder
   146  
   147  	// OpClass is set if an index element was created using a named opclass.
   148  	OpClass Name
   149  }
   150  
   151  // Format implements the NodeFormatter interface.
   152  func (node *IndexElem) Format(ctx *FmtCtx) {
   153  	if node.Expr == nil {
   154  		ctx.FormatNode(&node.Column)
   155  	} else {
   156  		// Expressions in indexes need an extra set of parens, unless they are a
   157  		// simple function call.
   158  		_, isFunc := node.Expr.(*FuncExpr)
   159  		if !isFunc {
   160  			ctx.WriteByte('(')
   161  		}
   162  		ctx.FormatNode(node.Expr)
   163  		if !isFunc {
   164  			ctx.WriteByte(')')
   165  		}
   166  	}
   167  	if node.OpClass != "" {
   168  		ctx.WriteByte(' ')
   169  		ctx.WriteString(node.OpClass.String())
   170  	}
   171  	if node.Direction != DefaultDirection {
   172  		ctx.WriteByte(' ')
   173  		ctx.WriteString(node.Direction.String())
   174  	}
   175  	if node.NullsOrder != DefaultNullsOrder {
   176  		ctx.WriteByte(' ')
   177  		ctx.WriteString(node.NullsOrder.String())
   178  	}
   179  }
   180  
   181  func (node *IndexElem) doc(p *PrettyCfg) pretty.Doc {
   182  	var d pretty.Doc
   183  	if node.Expr == nil {
   184  		d = p.Doc(&node.Column)
   185  	} else {
   186  		// Expressions in indexes need an extra set of parens, unless they are a
   187  		// simple function call.
   188  		d = p.Doc(node.Expr)
   189  		if _, isFunc := node.Expr.(*FuncExpr); !isFunc {
   190  			d = p.bracket("(", d, ")")
   191  		}
   192  	}
   193  	if node.OpClass != "" {
   194  		d = pretty.ConcatSpace(d, pretty.Text(node.OpClass.String()))
   195  	}
   196  	if node.Direction != DefaultDirection {
   197  		d = pretty.ConcatSpace(d, pretty.Keyword(node.Direction.String()))
   198  	}
   199  	if node.NullsOrder != DefaultNullsOrder {
   200  		d = pretty.ConcatSpace(d, pretty.Keyword(node.NullsOrder.String()))
   201  	}
   202  	return d
   203  }
   204  
   205  // IndexElemList is list of IndexElem.
   206  type IndexElemList []IndexElem
   207  
   208  // Format pretty-prints the contained names separated by commas.
   209  // Format implements the NodeFormatter interface.
   210  func (l *IndexElemList) Format(ctx *FmtCtx) {
   211  	for i := range *l {
   212  		if i > 0 {
   213  			ctx.WriteString(", ")
   214  		}
   215  		ctx.FormatNode(&(*l)[i])
   216  	}
   217  }
   218  
   219  // doc is part of the docer interface.
   220  func (l *IndexElemList) doc(p *PrettyCfg) pretty.Doc {
   221  	if l == nil || len(*l) == 0 {
   222  		return pretty.Nil
   223  	}
   224  	d := make([]pretty.Doc, len(*l))
   225  	for i := range *l {
   226  		d[i] = p.Doc(&(*l)[i])
   227  	}
   228  	return p.commaSeparated(d...)
   229  }
   230  
   231  type IndexInvisibility struct {
   232  	Value         float64
   233  	FloatProvided bool
   234  }
   235  
   236  // CreateIndex represents a CREATE INDEX statement.
   237  type CreateIndex struct {
   238  	Name        Name
   239  	Table       TableName
   240  	Unique      bool
   241  	Inverted    bool
   242  	IfNotExists bool
   243  	Columns     IndexElemList
   244  	Sharded     *ShardedIndexDef
   245  	// Extra columns to be stored together with the indexed ones as an optimization
   246  	// for improved reading performance.
   247  	Storing          NameList
   248  	PartitionByIndex *PartitionByIndex
   249  	StorageParams    StorageParams
   250  	Predicate        Expr
   251  	Concurrently     bool
   252  	Invisibility     IndexInvisibility
   253  }
   254  
   255  // Format implements the NodeFormatter interface.
   256  func (node *CreateIndex) Format(ctx *FmtCtx) {
   257  	// Please also update indexForDisplay function in
   258  	// pkg/sql/catalog/catformat/index.go if there's any update to index
   259  	// definition components.
   260  	ctx.WriteString("CREATE ")
   261  	if node.Unique {
   262  		ctx.WriteString("UNIQUE ")
   263  	}
   264  	if node.Inverted {
   265  		ctx.WriteString("INVERTED ")
   266  	}
   267  	ctx.WriteString("INDEX ")
   268  	if node.Concurrently {
   269  		ctx.WriteString("CONCURRENTLY ")
   270  	}
   271  	if node.IfNotExists {
   272  		ctx.WriteString("IF NOT EXISTS ")
   273  	}
   274  	if node.Name != "" {
   275  		ctx.FormatNode(&node.Name)
   276  		ctx.WriteByte(' ')
   277  	}
   278  	ctx.WriteString("ON ")
   279  	ctx.FormatNode(&node.Table)
   280  
   281  	ctx.WriteString(" (")
   282  	ctx.FormatNode(&node.Columns)
   283  	ctx.WriteByte(')')
   284  	if node.Sharded != nil {
   285  		ctx.FormatNode(node.Sharded)
   286  	}
   287  	if len(node.Storing) > 0 {
   288  		ctx.WriteString(" STORING (")
   289  		ctx.FormatNode(&node.Storing)
   290  		ctx.WriteByte(')')
   291  	}
   292  	if node.PartitionByIndex != nil {
   293  		ctx.FormatNode(node.PartitionByIndex)
   294  	}
   295  	if node.StorageParams != nil {
   296  		ctx.WriteString(" WITH (")
   297  		ctx.FormatNode(&node.StorageParams)
   298  		ctx.WriteString(")")
   299  	}
   300  	if node.Predicate != nil {
   301  		ctx.WriteString(" WHERE ")
   302  		ctx.FormatNode(node.Predicate)
   303  	}
   304  	switch {
   305  	case node.Invisibility.FloatProvided:
   306  		ctx.WriteString(" VISIBILITY " + fmt.Sprintf("%.2f", 1-node.Invisibility.Value))
   307  	case node.Invisibility.Value == 1.0:
   308  		ctx.WriteString(" NOT VISIBLE")
   309  	}
   310  }
   311  
   312  // CreateTypeVariety represents a particular variety of user defined types.
   313  type CreateTypeVariety int
   314  
   315  //go:generate stringer -type=CreateTypeVariety
   316  const (
   317  	_ CreateTypeVariety = iota
   318  	// Enum represents an ENUM user defined type.
   319  	Enum
   320  	// Composite represents a composite user defined type.
   321  	Composite
   322  	// Range represents a RANGE user defined type.
   323  	Range
   324  	// Base represents a base user defined type.
   325  	Base
   326  	// Shell represents a shell user defined type.
   327  	Shell
   328  	// Domain represents a DOMAIN user defined type.
   329  	Domain
   330  )
   331  
   332  // EnumValue represents a single enum value.
   333  type EnumValue string
   334  
   335  // Format implements the NodeFormatter interface.
   336  func (n *EnumValue) Format(ctx *FmtCtx) {
   337  	f := ctx.flags
   338  	if f.HasFlags(FmtAnonymize) {
   339  		ctx.WriteByte('_')
   340  	} else if f.HasFlags(FmtMarkRedactionNode) {
   341  		ctx.WriteString(string(redact.StartMarker()))
   342  		lexbase.EncodeSQLString(&ctx.Buffer, string(*n))
   343  		ctx.WriteString(string(redact.EndMarker()))
   344  	} else {
   345  		lexbase.EncodeSQLString(&ctx.Buffer, string(*n))
   346  	}
   347  }
   348  
   349  // EnumValueList represents a list of enum values.
   350  type EnumValueList []EnumValue
   351  
   352  // Format implements the NodeFormatter interface.
   353  func (l *EnumValueList) Format(ctx *FmtCtx) {
   354  	for i := range *l {
   355  		if i > 0 {
   356  			ctx.WriteString(", ")
   357  		}
   358  		ctx.FormatNode(&(*l)[i])
   359  	}
   360  }
   361  
   362  // CompositeTypeElem is a single element in a composite type definition.
   363  type CompositeTypeElem struct {
   364  	Label Name
   365  	Type  ResolvableTypeReference
   366  }
   367  
   368  // CreateType represents a CREATE TYPE statement.
   369  type CreateType struct {
   370  	TypeName *UnresolvedObjectName
   371  	Variety  CreateTypeVariety
   372  	// EnumLabels is set when this represents a CREATE TYPE ... AS ENUM statement.
   373  	EnumLabels EnumValueList
   374  	// CompositeTypeList is set when this repesnets a CREATE TYPE ... AS ( )
   375  	// statement.
   376  	CompositeTypeList []CompositeTypeElem
   377  	// IfNotExists is true if IF NOT EXISTS was requested.
   378  	IfNotExists bool
   379  }
   380  
   381  var _ Statement = &CreateType{}
   382  
   383  // Format implements the NodeFormatter interface.
   384  func (node *CreateType) Format(ctx *FmtCtx) {
   385  	ctx.WriteString("CREATE TYPE ")
   386  	if node.IfNotExists {
   387  		ctx.WriteString("IF NOT EXISTS ")
   388  	}
   389  	ctx.FormatNode(node.TypeName)
   390  	ctx.WriteString(" ")
   391  	switch node.Variety {
   392  	case Enum:
   393  		ctx.WriteString("AS ENUM (")
   394  		ctx.FormatNode(&node.EnumLabels)
   395  		ctx.WriteString(")")
   396  	case Composite:
   397  		ctx.WriteString("AS (")
   398  		for i := range node.CompositeTypeList {
   399  			elem := &node.CompositeTypeList[i]
   400  			if i != 0 {
   401  				ctx.WriteString(", ")
   402  			}
   403  			ctx.FormatNode(&elem.Label)
   404  			ctx.WriteString(" ")
   405  			ctx.FormatTypeReference(elem.Type)
   406  		}
   407  		ctx.WriteString(")")
   408  	}
   409  }
   410  
   411  func (node *CreateType) String() string {
   412  	return AsString(node)
   413  }
   414  
   415  // TableDef represents a column, index or constraint definition within a CREATE
   416  // TABLE statement.
   417  type TableDef interface {
   418  	NodeFormatter
   419  	// Placeholder function to ensure that only desired types (*TableDef) conform
   420  	// to the TableDef interface.
   421  	tableDef()
   422  }
   423  
   424  func (*ColumnTableDef) tableDef()               {}
   425  func (*IndexTableDef) tableDef()                {}
   426  func (*FamilyTableDef) tableDef()               {}
   427  func (*ForeignKeyConstraintTableDef) tableDef() {}
   428  func (*CheckConstraintTableDef) tableDef()      {}
   429  func (*LikeTableDef) tableDef()                 {}
   430  
   431  // TableDefs represents a list of table definitions.
   432  type TableDefs []TableDef
   433  
   434  // Format implements the NodeFormatter interface.
   435  func (node *TableDefs) Format(ctx *FmtCtx) {
   436  	for i, n := range *node {
   437  		if i > 0 {
   438  			ctx.WriteString(", ")
   439  		}
   440  		ctx.FormatNode(n)
   441  	}
   442  }
   443  
   444  // Nullability represents either NULL, NOT NULL or an unspecified value (silent
   445  // NULL).
   446  type Nullability int
   447  
   448  // The values for NullType.
   449  const (
   450  	NotNull Nullability = iota
   451  	Null
   452  	SilentNull
   453  )
   454  
   455  // RandomNullability returns a random valid Nullability, given a random number
   456  // generator, `rand`. If nullableOnly is true, the random Nullability will not
   457  // be `NotNull`.
   458  func RandomNullability(rand *rand.Rand, nullableOnly bool) Nullability {
   459  	if nullableOnly {
   460  		// Add 1 after getting the random number to exclude the zero-value NotNull.
   461  		return Nullability(rand.Intn(int(SilentNull)) + 1)
   462  	}
   463  	return Nullability(rand.Intn(int(SilentNull) + 1))
   464  }
   465  
   466  // GeneratedIdentityType represents either GENERATED ALWAYS AS IDENTITY
   467  // or GENERATED BY DEFAULT AS IDENTITY.
   468  type GeneratedIdentityType int
   469  
   470  // The values of GeneratedIdentity.GeneratedAsIdentityType.
   471  const (
   472  	GeneratedAlways GeneratedIdentityType = iota
   473  	GeneratedByDefault
   474  )
   475  
   476  // ColumnTableDef represents a column definition within a CREATE TABLE
   477  // statement.
   478  type ColumnTableDef struct {
   479  	Name     Name
   480  	Type     ResolvableTypeReference
   481  	IsSerial bool
   482  	// IsCreateAs is set to true if the Type is resolved after parsing.
   483  	// CREATE AS statements must not display column types during formatting.
   484  	IsCreateAs        bool
   485  	GeneratedIdentity struct {
   486  		IsGeneratedAsIdentity   bool
   487  		GeneratedAsIdentityType GeneratedIdentityType
   488  		SeqOptions              SequenceOptions
   489  	}
   490  	Hidden   bool
   491  	Nullable struct {
   492  		Nullability    Nullability
   493  		ConstraintName Name
   494  	}
   495  	PrimaryKey struct {
   496  		IsPrimaryKey  bool
   497  		Sharded       bool
   498  		ShardBuckets  Expr
   499  		StorageParams StorageParams
   500  	}
   501  	Unique struct {
   502  		IsUnique       bool
   503  		WithoutIndex   bool
   504  		ConstraintName Name
   505  	}
   506  	DefaultExpr struct {
   507  		Expr           Expr
   508  		ConstraintName Name
   509  	}
   510  	OnUpdateExpr struct {
   511  		Expr           Expr
   512  		ConstraintName Name
   513  	}
   514  	CheckExprs []ColumnTableDefCheckExpr
   515  	References struct {
   516  		Table          *TableName
   517  		Col            Name
   518  		ConstraintName Name
   519  		Actions        ReferenceActions
   520  		Match          CompositeKeyMatchMethod
   521  	}
   522  	Computed struct {
   523  		Computed bool
   524  		Expr     Expr
   525  		Virtual  bool
   526  	}
   527  	Family struct {
   528  		Name        Name
   529  		Create      bool
   530  		IfNotExists bool
   531  	}
   532  }
   533  
   534  // ColumnTableDefCheckExpr represents a check constraint on a column definition
   535  // within a CREATE TABLE statement.
   536  type ColumnTableDefCheckExpr struct {
   537  	Expr           Expr
   538  	ConstraintName Name
   539  }
   540  
   541  func processCollationOnType(
   542  	name Name, ref ResolvableTypeReference, c ColumnCollation,
   543  ) (*types.T, error) {
   544  	// At the moment, only string types can be collated. User defined types
   545  	//  like enums don't support collations, so check this at parse time.
   546  	typ, ok := GetStaticallyKnownType(ref)
   547  	if !ok {
   548  		return nil, pgerror.Newf(pgcode.DatatypeMismatch,
   549  			"COLLATE declaration for non-string-typed column %q", name)
   550  	}
   551  	switch typ.Family() {
   552  	case types.StringFamily:
   553  		return types.MakeCollatedString(typ, string(c)), nil
   554  	case types.CollatedStringFamily:
   555  		return nil, pgerror.Newf(pgcode.Syntax,
   556  			"multiple COLLATE declarations for column %q", name)
   557  	case types.ArrayFamily:
   558  		elemTyp, err := processCollationOnType(name, typ.ArrayContents(), c)
   559  		if err != nil {
   560  			return nil, err
   561  		}
   562  		return types.MakeArray(elemTyp), nil
   563  	default:
   564  		return nil, pgerror.Newf(pgcode.DatatypeMismatch,
   565  			"COLLATE declaration for non-string-typed column %q", name)
   566  	}
   567  }
   568  
   569  // NewColumnTableDef constructs a column definition for a CreateTable statement.
   570  func NewColumnTableDef(
   571  	name Name,
   572  	typRef ResolvableTypeReference,
   573  	isSerial bool,
   574  	qualifications []NamedColumnQualification,
   575  ) (*ColumnTableDef, error) {
   576  	d := &ColumnTableDef{
   577  		Name:     name,
   578  		Type:     typRef,
   579  		IsSerial: isSerial,
   580  	}
   581  	d.Nullable.Nullability = SilentNull
   582  	for _, c := range qualifications {
   583  		switch t := c.Qualification.(type) {
   584  		case ColumnCollation:
   585  			locale := string(t)
   586  			// In postgres, all strings have collations defaulting to "default".
   587  			// In CRDB, collated strings are treated separately to string family types.
   588  			// To most behave like postgres, set the CollatedString type if a non-"default"
   589  			// collation is used.
   590  			if locale != collatedstring.DefaultCollationTag {
   591  				_, err := language.Parse(locale)
   592  				if err != nil {
   593  					return nil, pgerror.Wrapf(err, pgcode.Syntax, "invalid locale %s", locale)
   594  				}
   595  				collatedTyp, err := processCollationOnType(name, d.Type, t)
   596  				if err != nil {
   597  					return nil, err
   598  				}
   599  				d.Type = collatedTyp
   600  			}
   601  		case *ColumnDefault:
   602  			if d.HasDefaultExpr() || d.GeneratedIdentity.IsGeneratedAsIdentity {
   603  				return nil, pgerror.Newf(pgcode.Syntax,
   604  					"multiple default values specified for column %q", name)
   605  			}
   606  			d.DefaultExpr.Expr = t.Expr
   607  			d.DefaultExpr.ConstraintName = c.Name
   608  		case *ColumnOnUpdate:
   609  			if d.HasOnUpdateExpr() {
   610  				return nil, pgerror.Newf(pgcode.Syntax,
   611  					"multiple ON UPDATE values specified for column %q", name)
   612  			}
   613  			if d.GeneratedIdentity.IsGeneratedAsIdentity {
   614  				return nil, pgerror.Newf(pgcode.Syntax,
   615  					"both generated identity and on update expression specified for column %q",
   616  					name)
   617  			}
   618  			d.OnUpdateExpr.Expr = t.Expr
   619  			d.OnUpdateExpr.ConstraintName = c.Name
   620  		case *GeneratedAlwaysAsIdentity, *GeneratedByDefAsIdentity:
   621  			if typ, ok := typRef.(*types.T); !ok || typ.InternalType.Family != types.IntFamily {
   622  				return nil, pgerror.Newf(
   623  					pgcode.InvalidParameterValue,
   624  					"identity column type must be an INT",
   625  				)
   626  			}
   627  			if d.GeneratedIdentity.IsGeneratedAsIdentity {
   628  				return nil, pgerror.Newf(pgcode.Syntax,
   629  					"multiple identity specifications for column %q", name)
   630  			}
   631  			if d.HasDefaultExpr() {
   632  				return nil, pgerror.Newf(pgcode.Syntax,
   633  					"multiple default values specified for column %q", name)
   634  			}
   635  			if d.Computed.Computed {
   636  				return nil, pgerror.Newf(pgcode.Syntax,
   637  					"both generated identity and computed expression specified for column %q", name)
   638  			}
   639  			if d.Nullable.Nullability == Null {
   640  				return nil, pgerror.Newf(pgcode.Syntax,
   641  					"conflicting NULL/NOT NULL declarations for column %q", name)
   642  			}
   643  			if d.HasOnUpdateExpr() {
   644  				return nil, pgerror.Newf(pgcode.Syntax,
   645  					"both generated identity and on update expression specified for column %q",
   646  					name)
   647  			}
   648  			d.GeneratedIdentity.IsGeneratedAsIdentity = true
   649  			d.Nullable.Nullability = NotNull
   650  			switch c.Qualification.(type) {
   651  			case *GeneratedAlwaysAsIdentity:
   652  				d.GeneratedIdentity.GeneratedAsIdentityType = GeneratedAlways
   653  				d.GeneratedIdentity.SeqOptions = t.(*GeneratedAlwaysAsIdentity).SeqOptions
   654  			case *GeneratedByDefAsIdentity:
   655  				d.GeneratedIdentity.GeneratedAsIdentityType = GeneratedByDefault
   656  				d.GeneratedIdentity.SeqOptions = t.(*GeneratedByDefAsIdentity).SeqOptions
   657  			}
   658  		case HiddenConstraint:
   659  			d.Hidden = true
   660  		case NotNullConstraint:
   661  			if d.Nullable.Nullability == Null {
   662  				return nil, pgerror.Newf(pgcode.Syntax,
   663  					"conflicting NULL/NOT NULL declarations for column %q", name)
   664  			}
   665  			d.Nullable.Nullability = NotNull
   666  			d.Nullable.ConstraintName = c.Name
   667  		case NullConstraint:
   668  			if d.Nullable.Nullability == NotNull {
   669  				return nil, pgerror.Newf(pgcode.Syntax,
   670  					"conflicting NULL/NOT NULL declarations for column %q", name)
   671  			}
   672  			d.Nullable.Nullability = Null
   673  			d.Nullable.ConstraintName = c.Name
   674  		case PrimaryKeyConstraint:
   675  			d.PrimaryKey.IsPrimaryKey = true
   676  			d.PrimaryKey.StorageParams = c.Qualification.(PrimaryKeyConstraint).StorageParams
   677  			d.Unique.ConstraintName = c.Name
   678  		case ShardedPrimaryKeyConstraint:
   679  			d.PrimaryKey.IsPrimaryKey = true
   680  			constraint := c.Qualification.(ShardedPrimaryKeyConstraint)
   681  			d.PrimaryKey.Sharded = true
   682  			d.PrimaryKey.ShardBuckets = constraint.ShardBuckets
   683  			d.PrimaryKey.StorageParams = constraint.StorageParams
   684  			d.Unique.ConstraintName = c.Name
   685  		case UniqueConstraint:
   686  			d.Unique.IsUnique = true
   687  			d.Unique.WithoutIndex = t.WithoutIndex
   688  			d.Unique.ConstraintName = c.Name
   689  		case *ColumnCheckConstraint:
   690  			d.CheckExprs = append(d.CheckExprs, ColumnTableDefCheckExpr{
   691  				Expr:           t.Expr,
   692  				ConstraintName: c.Name,
   693  			})
   694  		case *ColumnFKConstraint:
   695  			if d.HasFKConstraint() {
   696  				return nil, pgerror.Newf(pgcode.InvalidTableDefinition,
   697  					"multiple foreign key constraints specified for column %q", name)
   698  			}
   699  			d.References.Table = &t.Table
   700  			d.References.Col = t.Col
   701  			d.References.ConstraintName = c.Name
   702  			d.References.Actions = t.Actions
   703  			d.References.Match = t.Match
   704  		case *ColumnComputedDef:
   705  			if d.GeneratedIdentity.IsGeneratedAsIdentity {
   706  				return nil, pgerror.Newf(pgcode.Syntax,
   707  					"both generated identity and computed expression specified for column %q", name)
   708  			}
   709  			d.Computed.Computed = true
   710  			d.Computed.Expr = t.Expr
   711  			d.Computed.Virtual = t.Virtual
   712  		case *ColumnFamilyConstraint:
   713  			if d.HasColumnFamily() {
   714  				return nil, pgerror.Newf(pgcode.InvalidTableDefinition,
   715  					"multiple column families specified for column %q", name)
   716  			}
   717  			d.Family.Name = t.Family
   718  			d.Family.Create = t.Create
   719  			d.Family.IfNotExists = t.IfNotExists
   720  		default:
   721  			return nil, errors.AssertionFailedf("unexpected column qualification: %T", c)
   722  		}
   723  	}
   724  
   725  	return d, nil
   726  }
   727  
   728  // HasDefaultExpr returns if the ColumnTableDef has a default expression.
   729  func (node *ColumnTableDef) HasDefaultExpr() bool {
   730  	return node.DefaultExpr.Expr != nil
   731  }
   732  
   733  // HasOnUpdateExpr returns if the ColumnTableDef has an ON UPDATE expression.
   734  func (node *ColumnTableDef) HasOnUpdateExpr() bool {
   735  	return node.OnUpdateExpr.Expr != nil
   736  }
   737  
   738  // HasFKConstraint returns if the ColumnTableDef has a foreign key constraint.
   739  func (node *ColumnTableDef) HasFKConstraint() bool {
   740  	return node.References.Table != nil
   741  }
   742  
   743  // IsComputed returns if the ColumnTableDef is a computed column.
   744  func (node *ColumnTableDef) IsComputed() bool {
   745  	return node.Computed.Computed
   746  }
   747  
   748  // IsVirtual returns if the ColumnTableDef is a virtual column.
   749  func (node *ColumnTableDef) IsVirtual() bool {
   750  	return node.Computed.Virtual
   751  }
   752  
   753  // HasColumnFamily returns if the ColumnTableDef has a column family.
   754  func (node *ColumnTableDef) HasColumnFamily() bool {
   755  	return node.Family.Name != "" || node.Family.Create
   756  }
   757  
   758  // Format implements the NodeFormatter interface.
   759  func (node *ColumnTableDef) Format(ctx *FmtCtx) {
   760  	ctx.FormatNode(&node.Name)
   761  
   762  	// ColumnTableDef node type will not be specified if it represents a CREATE
   763  	// TABLE ... AS query.
   764  	if !node.IsCreateAs && node.Type != nil {
   765  		ctx.WriteByte(' ')
   766  		node.formatColumnType(ctx)
   767  	}
   768  
   769  	if node.Nullable.Nullability != SilentNull && node.Nullable.ConstraintName != "" {
   770  		ctx.WriteString(" CONSTRAINT ")
   771  		ctx.FormatNode(&node.Nullable.ConstraintName)
   772  	}
   773  	switch node.Nullable.Nullability {
   774  	case Null:
   775  		ctx.WriteString(" NULL")
   776  	case NotNull:
   777  		ctx.WriteString(" NOT NULL")
   778  	}
   779  	if node.Hidden {
   780  		ctx.WriteString(" NOT VISIBLE")
   781  	}
   782  	if node.PrimaryKey.IsPrimaryKey || node.Unique.IsUnique {
   783  		if node.Unique.ConstraintName != "" {
   784  			ctx.WriteString(" CONSTRAINT ")
   785  			ctx.FormatNode(&node.Unique.ConstraintName)
   786  		}
   787  		if node.PrimaryKey.IsPrimaryKey {
   788  			ctx.WriteString(" PRIMARY KEY")
   789  
   790  			// Always prefer to output hash sharding bucket count as a storage param.
   791  			pkStorageParams := node.PrimaryKey.StorageParams
   792  			if node.PrimaryKey.Sharded {
   793  				ctx.WriteString(" USING HASH")
   794  				bcStorageParam := node.PrimaryKey.StorageParams.GetVal(`bucket_count`)
   795  				if _, ok := node.PrimaryKey.ShardBuckets.(DefaultVal); !ok && bcStorageParam == nil {
   796  					pkStorageParams = append(
   797  						pkStorageParams,
   798  						StorageParam{
   799  							Key:   `bucket_count`,
   800  							Value: node.PrimaryKey.ShardBuckets,
   801  						},
   802  					)
   803  				}
   804  			}
   805  			if len(pkStorageParams) > 0 {
   806  				ctx.WriteString(" WITH (")
   807  				ctx.FormatNode(&pkStorageParams)
   808  				ctx.WriteString(")")
   809  			}
   810  		} else if node.Unique.IsUnique {
   811  			ctx.WriteString(" UNIQUE")
   812  			if node.Unique.WithoutIndex {
   813  				ctx.WriteString(" WITHOUT INDEX")
   814  			}
   815  		}
   816  	}
   817  	if node.HasDefaultExpr() {
   818  		if node.DefaultExpr.ConstraintName != "" {
   819  			ctx.WriteString(" CONSTRAINT ")
   820  			ctx.FormatNode(&node.DefaultExpr.ConstraintName)
   821  		}
   822  		ctx.WriteString(" DEFAULT ")
   823  		ctx.FormatNode(node.DefaultExpr.Expr)
   824  	}
   825  	if node.HasOnUpdateExpr() {
   826  		if node.OnUpdateExpr.ConstraintName != "" {
   827  			ctx.WriteString(" CONSTRAINT ")
   828  			ctx.FormatNode(&node.OnUpdateExpr.ConstraintName)
   829  		}
   830  		ctx.WriteString(" ON UPDATE ")
   831  		ctx.FormatNode(node.OnUpdateExpr.Expr)
   832  	}
   833  	if node.GeneratedIdentity.IsGeneratedAsIdentity {
   834  		switch node.GeneratedIdentity.GeneratedAsIdentityType {
   835  		case GeneratedAlways:
   836  			ctx.WriteString(" GENERATED ALWAYS AS IDENTITY")
   837  		case GeneratedByDefault:
   838  			ctx.WriteString(" GENERATED BY DEFAULT AS IDENTITY")
   839  		}
   840  		if genSeqOpt := node.GeneratedIdentity.SeqOptions; genSeqOpt != nil {
   841  			ctx.WriteString(" (")
   842  			// TODO(janexing): remove the leading and ending space of the
   843  			// sequence option expression.
   844  			genSeqOpt.Format(ctx)
   845  			ctx.WriteString(" ) ")
   846  		}
   847  	}
   848  	for _, checkExpr := range node.CheckExprs {
   849  		if checkExpr.ConstraintName != "" {
   850  			ctx.WriteString(" CONSTRAINT ")
   851  			ctx.FormatNode(&checkExpr.ConstraintName)
   852  		}
   853  		ctx.WriteString(" CHECK (")
   854  		ctx.FormatNode(checkExpr.Expr)
   855  		ctx.WriteByte(')')
   856  	}
   857  	if node.HasFKConstraint() {
   858  		if node.References.ConstraintName != "" {
   859  			ctx.WriteString(" CONSTRAINT ")
   860  			ctx.FormatNode(&node.References.ConstraintName)
   861  		}
   862  		ctx.WriteString(" REFERENCES ")
   863  		ctx.FormatNode(node.References.Table)
   864  		if node.References.Col != "" {
   865  			ctx.WriteString(" (")
   866  			ctx.FormatNode(&node.References.Col)
   867  			ctx.WriteByte(')')
   868  		}
   869  		if node.References.Match != MatchSimple {
   870  			ctx.WriteByte(' ')
   871  			ctx.WriteString(node.References.Match.String())
   872  		}
   873  		ctx.FormatNode(&node.References.Actions)
   874  	}
   875  	if node.IsComputed() {
   876  		ctx.WriteString(" AS (")
   877  		ctx.FormatNode(node.Computed.Expr)
   878  		if node.Computed.Virtual {
   879  			ctx.WriteString(") VIRTUAL")
   880  		} else {
   881  			ctx.WriteString(") STORED")
   882  		}
   883  	}
   884  	if node.HasColumnFamily() {
   885  		if node.Family.Create {
   886  			ctx.WriteString(" CREATE")
   887  			if node.Family.IfNotExists {
   888  				ctx.WriteString(" IF NOT EXISTS")
   889  			}
   890  		}
   891  		ctx.WriteString(" FAMILY")
   892  		if len(node.Family.Name) > 0 {
   893  			ctx.WriteByte(' ')
   894  			ctx.FormatNode(&node.Family.Name)
   895  		}
   896  	}
   897  }
   898  
   899  func (node *ColumnTableDef) formatColumnType(ctx *FmtCtx) {
   900  	if replaced, ok := node.replacedSerialTypeName(); ok {
   901  		ctx.WriteString(replaced)
   902  	} else {
   903  		ctx.FormatTypeReference(node.Type)
   904  	}
   905  }
   906  
   907  func (node *ColumnTableDef) replacedSerialTypeName() (string, bool) {
   908  	if node.IsSerial {
   909  		// Map INT types to SERIAL keyword.
   910  		// TODO (rohany): This should be pushed until type resolution occurs.
   911  		//  However, the argument is that we deal with serial at parse time only,
   912  		//  so we handle those cases here.
   913  		switch MustBeStaticallyKnownType(node.Type).Width() {
   914  		case 16:
   915  			return "SERIAL2", true
   916  		case 32:
   917  			return "SERIAL4", true
   918  		default:
   919  			return "SERIAL8", true
   920  		}
   921  	}
   922  	return "", false
   923  }
   924  
   925  // String implements the fmt.Stringer interface.
   926  func (node *ColumnTableDef) String() string { return AsString(node) }
   927  
   928  // NamedColumnQualification wraps a NamedColumnQualification with a name.
   929  type NamedColumnQualification struct {
   930  	Name          Name
   931  	Qualification ColumnQualification
   932  }
   933  
   934  // ColumnQualification represents a constraint on a column.
   935  type ColumnQualification interface {
   936  	columnQualification()
   937  }
   938  
   939  func (ColumnCollation) columnQualification()             {}
   940  func (*ColumnDefault) columnQualification()              {}
   941  func (*ColumnOnUpdate) columnQualification()             {}
   942  func (NotNullConstraint) columnQualification()           {}
   943  func (NullConstraint) columnQualification()              {}
   944  func (HiddenConstraint) columnQualification()            {}
   945  func (PrimaryKeyConstraint) columnQualification()        {}
   946  func (ShardedPrimaryKeyConstraint) columnQualification() {}
   947  func (UniqueConstraint) columnQualification()            {}
   948  func (*ColumnCheckConstraint) columnQualification()      {}
   949  func (*ColumnComputedDef) columnQualification()          {}
   950  func (*ColumnFKConstraint) columnQualification()         {}
   951  func (*ColumnFamilyConstraint) columnQualification()     {}
   952  func (*GeneratedAlwaysAsIdentity) columnQualification()  {}
   953  func (*GeneratedByDefAsIdentity) columnQualification()   {}
   954  
   955  // ColumnCollation represents a COLLATE clause for a column.
   956  type ColumnCollation string
   957  
   958  // ColumnDefault represents a DEFAULT clause for a column.
   959  type ColumnDefault struct {
   960  	Expr Expr
   961  }
   962  
   963  // ColumnOnUpdate represents a ON UPDATE clause for a column.
   964  type ColumnOnUpdate struct {
   965  	Expr Expr
   966  }
   967  
   968  // GeneratedAlwaysAsIdentity represents a column generated always as identity.
   969  type GeneratedAlwaysAsIdentity struct {
   970  	SeqOptions SequenceOptions
   971  }
   972  
   973  // GeneratedByDefAsIdentity represents a column generated by default as identity.
   974  type GeneratedByDefAsIdentity struct {
   975  	SeqOptions SequenceOptions
   976  }
   977  
   978  // NotNullConstraint represents NOT NULL on a column.
   979  type NotNullConstraint struct{}
   980  
   981  // NullConstraint represents NULL on a column.
   982  type NullConstraint struct{}
   983  
   984  // HiddenConstraint represents HIDDEN on a column.
   985  type HiddenConstraint struct{}
   986  
   987  // PrimaryKeyConstraint represents PRIMARY KEY on a column.
   988  type PrimaryKeyConstraint struct {
   989  	StorageParams StorageParams
   990  }
   991  
   992  // ShardedPrimaryKeyConstraint represents `PRIMARY KEY .. USING HASH..`
   993  // on a column.
   994  type ShardedPrimaryKeyConstraint struct {
   995  	Sharded       bool
   996  	ShardBuckets  Expr
   997  	StorageParams StorageParams
   998  }
   999  
  1000  // UniqueConstraint represents UNIQUE on a column.
  1001  type UniqueConstraint struct {
  1002  	WithoutIndex bool
  1003  }
  1004  
  1005  // ColumnCheckConstraint represents either a check on a column.
  1006  type ColumnCheckConstraint struct {
  1007  	Expr Expr
  1008  }
  1009  
  1010  // ColumnFKConstraint represents a FK-constaint on a column.
  1011  type ColumnFKConstraint struct {
  1012  	Table   TableName
  1013  	Col     Name // empty-string means use PK
  1014  	Actions ReferenceActions
  1015  	Match   CompositeKeyMatchMethod
  1016  }
  1017  
  1018  // ColumnComputedDef represents the description of a computed column.
  1019  type ColumnComputedDef struct {
  1020  	Expr    Expr
  1021  	Virtual bool
  1022  }
  1023  
  1024  // ColumnFamilyConstraint represents FAMILY on a column.
  1025  type ColumnFamilyConstraint struct {
  1026  	Family      Name
  1027  	Create      bool
  1028  	IfNotExists bool
  1029  }
  1030  
  1031  // IndexTableDef represents an index definition within a CREATE TABLE
  1032  // statement.
  1033  type IndexTableDef struct {
  1034  	Name             Name
  1035  	Columns          IndexElemList
  1036  	Sharded          *ShardedIndexDef
  1037  	Storing          NameList
  1038  	Inverted         bool
  1039  	PartitionByIndex *PartitionByIndex
  1040  	StorageParams    StorageParams
  1041  	Predicate        Expr
  1042  	Invisibility     IndexInvisibility
  1043  }
  1044  
  1045  // Format implements the NodeFormatter interface.
  1046  func (node *IndexTableDef) Format(ctx *FmtCtx) {
  1047  	if node.Inverted {
  1048  		ctx.WriteString("INVERTED ")
  1049  	}
  1050  	ctx.WriteString("INDEX ")
  1051  	if node.Name != "" {
  1052  		ctx.FormatNode(&node.Name)
  1053  		ctx.WriteByte(' ')
  1054  	}
  1055  	ctx.WriteByte('(')
  1056  	ctx.FormatNode(&node.Columns)
  1057  	ctx.WriteByte(')')
  1058  	if node.Sharded != nil {
  1059  		ctx.FormatNode(node.Sharded)
  1060  	}
  1061  	if node.Storing != nil {
  1062  		ctx.WriteString(" STORING (")
  1063  		ctx.FormatNode(&node.Storing)
  1064  		ctx.WriteByte(')')
  1065  	}
  1066  	if node.PartitionByIndex != nil {
  1067  		ctx.FormatNode(node.PartitionByIndex)
  1068  	}
  1069  	if node.StorageParams != nil {
  1070  		ctx.WriteString(" WITH (")
  1071  		ctx.FormatNode(&node.StorageParams)
  1072  		ctx.WriteString(")")
  1073  	}
  1074  	if node.Predicate != nil {
  1075  		ctx.WriteString(" WHERE ")
  1076  		ctx.FormatNode(node.Predicate)
  1077  	}
  1078  	switch {
  1079  	case node.Invisibility.FloatProvided:
  1080  		ctx.WriteString(" VISIBILITY " + fmt.Sprintf("%.2f", 1-node.Invisibility.Value))
  1081  	case node.Invisibility.Value == 1.0:
  1082  		ctx.WriteString(" NOT VISIBLE")
  1083  	}
  1084  }
  1085  
  1086  // ConstraintTableDef represents a constraint definition within a CREATE TABLE
  1087  // statement.
  1088  type ConstraintTableDef interface {
  1089  	TableDef
  1090  	// Placeholder function to ensure that only desired types
  1091  	// (*ConstraintTableDef) conform to the ConstraintTableDef interface.
  1092  	constraintTableDef()
  1093  
  1094  	// SetName replaces the name of the definition in-place. Used in the parser.
  1095  	SetName(name Name)
  1096  
  1097  	// SetIfNotExists sets this definition as coming from an
  1098  	// ADD CONSTRAINT IF NOT EXISTS statement. Used in the parser.
  1099  	SetIfNotExists()
  1100  }
  1101  
  1102  func (*UniqueConstraintTableDef) constraintTableDef()     {}
  1103  func (*ForeignKeyConstraintTableDef) constraintTableDef() {}
  1104  func (*CheckConstraintTableDef) constraintTableDef()      {}
  1105  
  1106  // UniqueConstraintTableDef represents a unique constraint within a CREATE
  1107  // TABLE statement.
  1108  type UniqueConstraintTableDef struct {
  1109  	IndexTableDef
  1110  	PrimaryKey   bool
  1111  	WithoutIndex bool
  1112  	IfNotExists  bool
  1113  }
  1114  
  1115  // SetName implements the TableDef interface.
  1116  func (node *UniqueConstraintTableDef) SetName(name Name) {
  1117  	node.Name = name
  1118  }
  1119  
  1120  // SetIfNotExists implements the ConstraintTableDef interface.
  1121  func (node *UniqueConstraintTableDef) SetIfNotExists() {
  1122  	node.IfNotExists = true
  1123  }
  1124  
  1125  // Format implements the NodeFormatter interface.
  1126  func (node *UniqueConstraintTableDef) Format(ctx *FmtCtx) {
  1127  	if node.Name != "" {
  1128  		ctx.WriteString("CONSTRAINT ")
  1129  		if node.IfNotExists {
  1130  			ctx.WriteString("IF NOT EXISTS ")
  1131  		}
  1132  		ctx.FormatNode(&node.Name)
  1133  		ctx.WriteByte(' ')
  1134  	}
  1135  	if node.PrimaryKey {
  1136  		ctx.WriteString("PRIMARY KEY ")
  1137  	} else {
  1138  		ctx.WriteString("UNIQUE ")
  1139  	}
  1140  	if node.WithoutIndex {
  1141  		ctx.WriteString("WITHOUT INDEX ")
  1142  	}
  1143  	ctx.WriteByte('(')
  1144  	ctx.FormatNode(&node.Columns)
  1145  	ctx.WriteByte(')')
  1146  	if node.Sharded != nil {
  1147  		ctx.FormatNode(node.Sharded)
  1148  	}
  1149  	if node.Storing != nil {
  1150  		ctx.WriteString(" STORING (")
  1151  		ctx.FormatNode(&node.Storing)
  1152  		ctx.WriteByte(')')
  1153  	}
  1154  	if node.PartitionByIndex != nil {
  1155  		ctx.FormatNode(node.PartitionByIndex)
  1156  	}
  1157  	if node.Predicate != nil {
  1158  		ctx.WriteString(" WHERE ")
  1159  		ctx.FormatNode(node.Predicate)
  1160  	}
  1161  	switch {
  1162  	case node.Invisibility.FloatProvided:
  1163  		ctx.WriteString(" VISIBILITY " + fmt.Sprintf("%.2f", 1-node.Invisibility.Value))
  1164  	case node.Invisibility.Value == 1.0:
  1165  		ctx.WriteString(" NOT VISIBLE")
  1166  	}
  1167  	if node.StorageParams != nil {
  1168  		ctx.WriteString(" WITH (")
  1169  		ctx.FormatNode(&node.StorageParams)
  1170  		ctx.WriteString(")")
  1171  	}
  1172  }
  1173  
  1174  // ForeignKeyConstraintTableDef represents a FOREIGN KEY constraint in the AST.
  1175  type ForeignKeyConstraintTableDef struct {
  1176  	Name        Name
  1177  	Table       TableName
  1178  	FromCols    NameList
  1179  	ToCols      NameList
  1180  	Actions     ReferenceActions
  1181  	Match       CompositeKeyMatchMethod
  1182  	IfNotExists bool
  1183  }
  1184  
  1185  // Format implements the NodeFormatter interface.
  1186  func (node *ForeignKeyConstraintTableDef) Format(ctx *FmtCtx) {
  1187  	if node.Name != "" {
  1188  		ctx.WriteString("CONSTRAINT ")
  1189  		if node.IfNotExists {
  1190  			ctx.WriteString("IF NOT EXISTS ")
  1191  		}
  1192  		ctx.FormatNode(&node.Name)
  1193  		ctx.WriteByte(' ')
  1194  	}
  1195  	ctx.WriteString("FOREIGN KEY (")
  1196  	ctx.FormatNode(&node.FromCols)
  1197  	ctx.WriteString(") REFERENCES ")
  1198  	ctx.FormatNode(&node.Table)
  1199  
  1200  	if len(node.ToCols) > 0 {
  1201  		ctx.WriteByte(' ')
  1202  		ctx.WriteByte('(')
  1203  		ctx.FormatNode(&node.ToCols)
  1204  		ctx.WriteByte(')')
  1205  	}
  1206  
  1207  	if node.Match != MatchSimple {
  1208  		ctx.WriteByte(' ')
  1209  		ctx.WriteString(node.Match.String())
  1210  	}
  1211  
  1212  	ctx.FormatNode(&node.Actions)
  1213  }
  1214  
  1215  // SetName implements the ConstraintTableDef interface.
  1216  func (node *ForeignKeyConstraintTableDef) SetName(name Name) {
  1217  	node.Name = name
  1218  }
  1219  
  1220  // SetIfNotExists implements the ConstraintTableDef interface.
  1221  func (node *ForeignKeyConstraintTableDef) SetIfNotExists() {
  1222  	node.IfNotExists = true
  1223  }
  1224  
  1225  // CheckConstraintTableDef represents a check constraint within a CREATE
  1226  // TABLE statement.
  1227  type CheckConstraintTableDef struct {
  1228  	Name                  Name
  1229  	Expr                  Expr
  1230  	FromHashShardedColumn bool
  1231  	IfNotExists           bool
  1232  }
  1233  
  1234  // SetName implements the ConstraintTableDef interface.
  1235  func (node *CheckConstraintTableDef) SetName(name Name) {
  1236  	node.Name = name
  1237  }
  1238  
  1239  // SetIfNotExists implements the ConstraintTableDef interface.
  1240  func (node *CheckConstraintTableDef) SetIfNotExists() {
  1241  	node.IfNotExists = true
  1242  }
  1243  
  1244  // Format implements the NodeFormatter interface.
  1245  func (node *CheckConstraintTableDef) Format(ctx *FmtCtx) {
  1246  	if node.Name != "" {
  1247  		ctx.WriteString("CONSTRAINT ")
  1248  		if node.IfNotExists {
  1249  			ctx.WriteString("IF NOT EXISTS ")
  1250  		}
  1251  		ctx.FormatNode(&node.Name)
  1252  		ctx.WriteByte(' ')
  1253  	}
  1254  	ctx.WriteString("CHECK (")
  1255  	ctx.FormatNode(node.Expr)
  1256  	ctx.WriteByte(')')
  1257  }
  1258  
  1259  // FamilyTableDef represents a family definition within a CREATE TABLE
  1260  // statement.
  1261  type FamilyTableDef struct {
  1262  	Name    Name
  1263  	Columns NameList
  1264  }
  1265  
  1266  // Format implements the NodeFormatter interface.
  1267  func (node *FamilyTableDef) Format(ctx *FmtCtx) {
  1268  	ctx.WriteString("FAMILY ")
  1269  	if node.Name != "" {
  1270  		ctx.FormatNode(&node.Name)
  1271  		ctx.WriteByte(' ')
  1272  	}
  1273  	ctx.WriteByte('(')
  1274  	ctx.FormatNode(&node.Columns)
  1275  	ctx.WriteByte(')')
  1276  }
  1277  
  1278  // ShardedIndexDef represents a hash sharded secondary index definition within a CREATE
  1279  // TABLE or CREATE INDEX statement.
  1280  type ShardedIndexDef struct {
  1281  	ShardBuckets Expr
  1282  }
  1283  
  1284  // Format implements the NodeFormatter interface.
  1285  func (node *ShardedIndexDef) Format(ctx *FmtCtx) {
  1286  	if _, ok := node.ShardBuckets.(DefaultVal); ok {
  1287  		ctx.WriteString(" USING HASH")
  1288  		return
  1289  	}
  1290  	ctx.WriteString(" USING HASH WITH BUCKET_COUNT = ")
  1291  	ctx.FormatNode(node.ShardBuckets)
  1292  }
  1293  
  1294  // PartitionByType is an enum of each type of partitioning (LIST/RANGE).
  1295  type PartitionByType string
  1296  
  1297  const (
  1298  	// PartitionByList indicates a PARTITION BY LIST clause.
  1299  	PartitionByList PartitionByType = "LIST"
  1300  	// PartitionByRange indicates a PARTITION BY LIST clause.
  1301  	PartitionByRange PartitionByType = "RANGE"
  1302  )
  1303  
  1304  // PartitionByIndex represents a PARTITION BY definition within
  1305  // a CREATE/ALTER INDEX statement.
  1306  type PartitionByIndex struct {
  1307  	*PartitionBy
  1308  }
  1309  
  1310  // ContainsPartitions determines if the partition by table contains
  1311  // a partition clause which is not PARTITION BY NOTHING.
  1312  func (node *PartitionByIndex) ContainsPartitions() bool {
  1313  	return node != nil && node.PartitionBy != nil
  1314  }
  1315  
  1316  // ContainsPartitioningClause determines if the partition by table contains
  1317  // a partitioning clause, including PARTITION BY NOTHING.
  1318  func (node *PartitionByIndex) ContainsPartitioningClause() bool {
  1319  	return node != nil
  1320  }
  1321  
  1322  // PartitionByTable represents a PARTITION [ALL] BY definition within
  1323  // a CREATE/ALTER TABLE statement.
  1324  type PartitionByTable struct {
  1325  	// All denotes PARTITION ALL BY.
  1326  	All bool
  1327  
  1328  	*PartitionBy
  1329  }
  1330  
  1331  // Format implements the NodeFormatter interface.
  1332  func (node *PartitionByTable) Format(ctx *FmtCtx) {
  1333  	if node == nil {
  1334  		ctx.WriteString(` PARTITION BY NOTHING`)
  1335  		return
  1336  	}
  1337  	ctx.WriteString(` PARTITION `)
  1338  	if node.All {
  1339  		ctx.WriteString(`ALL `)
  1340  	}
  1341  	ctx.WriteString(`BY `)
  1342  	node.PartitionBy.formatListOrRange(ctx)
  1343  }
  1344  
  1345  // ContainsPartitions determines if the partition by table contains
  1346  // a partition clause which is not PARTITION BY NOTHING.
  1347  func (node *PartitionByTable) ContainsPartitions() bool {
  1348  	return node != nil && node.PartitionBy != nil
  1349  }
  1350  
  1351  // ContainsPartitioningClause determines if the partition by table contains
  1352  // a partitioning clause, including PARTITION BY NOTHING.
  1353  func (node *PartitionByTable) ContainsPartitioningClause() bool {
  1354  	return node != nil
  1355  }
  1356  
  1357  // PartitionBy represents an PARTITION BY definition within a CREATE/ALTER
  1358  // TABLE/INDEX statement or within a subpartition statement.
  1359  // This is wrapped by top level PartitionByTable/PartitionByIndex
  1360  // structs for table and index definitions respectively.
  1361  type PartitionBy struct {
  1362  	Fields NameList
  1363  	// Exactly one of List or Range is required to be non-empty.
  1364  	List  []ListPartition
  1365  	Range []RangePartition
  1366  }
  1367  
  1368  // Format implements the NodeFormatter interface.
  1369  func (node *PartitionBy) Format(ctx *FmtCtx) {
  1370  	ctx.WriteString(` PARTITION BY `)
  1371  	node.formatListOrRange(ctx)
  1372  }
  1373  
  1374  func (node *PartitionBy) formatListOrRange(ctx *FmtCtx) {
  1375  	if node == nil {
  1376  		ctx.WriteString(`NOTHING`)
  1377  		return
  1378  	}
  1379  	if len(node.List) > 0 {
  1380  		ctx.WriteString(`LIST (`)
  1381  	} else if len(node.Range) > 0 {
  1382  		ctx.WriteString(`RANGE (`)
  1383  	}
  1384  	ctx.FormatNode(&node.Fields)
  1385  	ctx.WriteString(`) (`)
  1386  	for i := range node.List {
  1387  		if i > 0 {
  1388  			ctx.WriteString(", ")
  1389  		}
  1390  		ctx.FormatNode(&node.List[i])
  1391  	}
  1392  	for i := range node.Range {
  1393  		if i > 0 {
  1394  			ctx.WriteString(", ")
  1395  		}
  1396  		ctx.FormatNode(&node.Range[i])
  1397  	}
  1398  	ctx.WriteString(`)`)
  1399  }
  1400  
  1401  // ListPartition represents a PARTITION definition within a PARTITION BY LIST.
  1402  type ListPartition struct {
  1403  	Name         Name
  1404  	Exprs        Exprs
  1405  	Subpartition *PartitionBy
  1406  }
  1407  
  1408  // Format implements the NodeFormatter interface.
  1409  func (node *ListPartition) Format(ctx *FmtCtx) {
  1410  	ctx.WriteString(`PARTITION `)
  1411  	ctx.FormatNode(&node.Name)
  1412  	ctx.WriteString(` VALUES IN (`)
  1413  	ctx.FormatNode(&node.Exprs)
  1414  	ctx.WriteByte(')')
  1415  	if node.Subpartition != nil {
  1416  		ctx.FormatNode(node.Subpartition)
  1417  	}
  1418  }
  1419  
  1420  // RangePartition represents a PARTITION definition within a PARTITION BY RANGE.
  1421  type RangePartition struct {
  1422  	Name         Name
  1423  	From         Exprs
  1424  	To           Exprs
  1425  	Subpartition *PartitionBy
  1426  }
  1427  
  1428  // Format implements the NodeFormatter interface.
  1429  func (node *RangePartition) Format(ctx *FmtCtx) {
  1430  	ctx.WriteString(`PARTITION `)
  1431  	ctx.FormatNode(&node.Name)
  1432  	ctx.WriteString(` VALUES FROM (`)
  1433  	ctx.FormatNode(&node.From)
  1434  	ctx.WriteString(`) TO (`)
  1435  	ctx.FormatNode(&node.To)
  1436  	ctx.WriteByte(')')
  1437  	if node.Subpartition != nil {
  1438  		ctx.FormatNode(node.Subpartition)
  1439  	}
  1440  }
  1441  
  1442  // StorageParam is a key-value parameter for table storage.
  1443  type StorageParam struct {
  1444  	Key   Name
  1445  	Value Expr
  1446  }
  1447  
  1448  // StorageParams is a list of StorageParams.
  1449  type StorageParams []StorageParam
  1450  
  1451  // Format implements the NodeFormatter interface.
  1452  func (o *StorageParams) Format(ctx *FmtCtx) {
  1453  	for i := range *o {
  1454  		n := &(*o)[i]
  1455  		if i > 0 {
  1456  			ctx.WriteString(", ")
  1457  		}
  1458  		// TODO(knz): the key may need to be formatted differently
  1459  		// if we want to de-anonymize it.
  1460  		ctx.FormatNode(&n.Key)
  1461  		if n.Value != nil {
  1462  			ctx.WriteString(` = `)
  1463  			ctx.FormatNode(n.Value)
  1464  		}
  1465  	}
  1466  }
  1467  
  1468  // GetVal returns corresponding value if a key exists, otherwise nil is
  1469  // returned.
  1470  func (o *StorageParams) GetVal(key string) Expr {
  1471  	k := Name(key)
  1472  	for _, param := range *o {
  1473  		if param.Key == k {
  1474  			return param.Value
  1475  		}
  1476  	}
  1477  	return nil
  1478  }
  1479  
  1480  // CreateTableOnCommitSetting represents the CREATE TABLE ... ON COMMIT <action>
  1481  // parameters.
  1482  type CreateTableOnCommitSetting uint32
  1483  
  1484  const (
  1485  	// CreateTableOnCommitUnset indicates that ON COMMIT was unset.
  1486  	CreateTableOnCommitUnset CreateTableOnCommitSetting = iota
  1487  	// CreateTableOnCommitPreserveRows indicates that ON COMMIT PRESERVE ROWS was set.
  1488  	CreateTableOnCommitPreserveRows
  1489  )
  1490  
  1491  // CreateTable represents a CREATE TABLE statement.
  1492  type CreateTable struct {
  1493  	IfNotExists      bool
  1494  	Table            TableName
  1495  	PartitionByTable *PartitionByTable
  1496  	Persistence      Persistence
  1497  	StorageParams    StorageParams
  1498  	OnCommit         CreateTableOnCommitSetting
  1499  	// In CREATE...AS queries, Defs represents a list of ColumnTableDefs, one for
  1500  	// each column, and a ConstraintTableDef for each constraint on a subset of
  1501  	// these columns.
  1502  	Defs     TableDefs
  1503  	AsSource *Select
  1504  	Locality *Locality
  1505  }
  1506  
  1507  // As returns true if this table represents a CREATE TABLE ... AS statement,
  1508  // false otherwise.
  1509  func (node *CreateTable) As() bool {
  1510  	return node.AsSource != nil
  1511  }
  1512  
  1513  // AsHasUserSpecifiedPrimaryKey returns true if a CREATE TABLE ... AS statement
  1514  // has a PRIMARY KEY constraint specified.
  1515  func (node *CreateTable) AsHasUserSpecifiedPrimaryKey() bool {
  1516  	if node.As() {
  1517  		for _, def := range node.Defs {
  1518  			if d, ok := def.(*ColumnTableDef); !ok {
  1519  				return false
  1520  			} else if d.PrimaryKey.IsPrimaryKey {
  1521  				return true
  1522  			}
  1523  		}
  1524  	}
  1525  	return false
  1526  }
  1527  
  1528  // Format implements the NodeFormatter interface.
  1529  func (node *CreateTable) Format(ctx *FmtCtx) {
  1530  	ctx.WriteString("CREATE ")
  1531  	switch node.Persistence {
  1532  	case PersistenceTemporary:
  1533  		ctx.WriteString("TEMPORARY ")
  1534  	case PersistenceUnlogged:
  1535  		ctx.WriteString("UNLOGGED ")
  1536  	}
  1537  	ctx.WriteString("TABLE ")
  1538  	if node.IfNotExists {
  1539  		ctx.WriteString("IF NOT EXISTS ")
  1540  	}
  1541  	ctx.FormatNode(&node.Table)
  1542  	node.FormatBody(ctx)
  1543  }
  1544  
  1545  // FormatBody formats the "body" of the create table definition - everything
  1546  // but the CREATE TABLE tableName part.
  1547  func (node *CreateTable) FormatBody(ctx *FmtCtx) {
  1548  	if node.As() {
  1549  		if len(node.Defs) > 0 {
  1550  			ctx.WriteString(" (")
  1551  			ctx.FormatNode(&node.Defs)
  1552  			ctx.WriteByte(')')
  1553  		}
  1554  		if node.StorageParams != nil {
  1555  			ctx.WriteString(` WITH (`)
  1556  			ctx.FormatNode(&node.StorageParams)
  1557  			ctx.WriteByte(')')
  1558  		}
  1559  		ctx.WriteString(" AS ")
  1560  		ctx.FormatNode(node.AsSource)
  1561  	} else {
  1562  		ctx.WriteString(" (")
  1563  		ctx.FormatNode(&node.Defs)
  1564  		ctx.WriteByte(')')
  1565  		if node.PartitionByTable != nil {
  1566  			ctx.FormatNode(node.PartitionByTable)
  1567  		}
  1568  		if node.StorageParams != nil {
  1569  			ctx.WriteString(` WITH (`)
  1570  			ctx.FormatNode(&node.StorageParams)
  1571  			ctx.WriteByte(')')
  1572  		}
  1573  		if node.Locality != nil {
  1574  			ctx.WriteString(" ")
  1575  			ctx.FormatNode(node.Locality)
  1576  		}
  1577  	}
  1578  }
  1579  
  1580  // HoistConstraints finds column check and foreign key constraints defined
  1581  // inline with their columns and makes them table-level constraints, stored in
  1582  // n.Defs. For example, the foreign key constraint in
  1583  //
  1584  //	CREATE TABLE foo (a INT REFERENCES bar(a))
  1585  //
  1586  // gets pulled into a top-level constraint like:
  1587  //
  1588  //	CREATE TABLE foo (a INT, FOREIGN KEY (a) REFERENCES bar(a))
  1589  //
  1590  // Similarly, the CHECK constraint in
  1591  //
  1592  //	CREATE TABLE foo (a INT CHECK (a < 1), b INT)
  1593  //
  1594  // gets pulled into a top-level constraint like:
  1595  //
  1596  //	CREATE TABLE foo (a INT, b INT, CHECK (a < 1))
  1597  //
  1598  // Note that some SQL databases require that a constraint attached to a column
  1599  // to refer only to the column it is attached to. We follow Postgres' behavior,
  1600  // however, in omitting this restriction by blindly hoisting all column
  1601  // constraints. For example, the following table definition is accepted in
  1602  // CockroachDB and Postgres, but not necessarily other SQL databases:
  1603  //
  1604  //	CREATE TABLE foo (a INT CHECK (a < b), b INT)
  1605  //
  1606  // Unique constraints are not hoisted.
  1607  func (node *CreateTable) HoistConstraints() {
  1608  	for _, d := range node.Defs {
  1609  		if col, ok := d.(*ColumnTableDef); ok {
  1610  			for _, checkExpr := range col.CheckExprs {
  1611  				node.Defs = append(node.Defs,
  1612  					&CheckConstraintTableDef{
  1613  						Expr: checkExpr.Expr,
  1614  						Name: checkExpr.ConstraintName,
  1615  					},
  1616  				)
  1617  			}
  1618  			col.CheckExprs = nil
  1619  			if col.HasFKConstraint() {
  1620  				var targetCol NameList
  1621  				if col.References.Col != "" {
  1622  					targetCol = append(targetCol, col.References.Col)
  1623  				}
  1624  				node.Defs = append(node.Defs, &ForeignKeyConstraintTableDef{
  1625  					Table:    *col.References.Table,
  1626  					FromCols: NameList{col.Name},
  1627  					ToCols:   targetCol,
  1628  					Name:     col.References.ConstraintName,
  1629  					Actions:  col.References.Actions,
  1630  					Match:    col.References.Match,
  1631  				})
  1632  				col.References.Table = nil
  1633  			}
  1634  		}
  1635  	}
  1636  }
  1637  
  1638  // CreateSchema represents a CREATE SCHEMA statement.
  1639  type CreateSchema struct {
  1640  	IfNotExists bool
  1641  	AuthRole    RoleSpec
  1642  	Schema      ObjectNamePrefix
  1643  }
  1644  
  1645  // Format implements the NodeFormatter interface.
  1646  func (node *CreateSchema) Format(ctx *FmtCtx) {
  1647  	ctx.WriteString("CREATE SCHEMA")
  1648  
  1649  	if node.IfNotExists {
  1650  		ctx.WriteString(" IF NOT EXISTS")
  1651  	}
  1652  
  1653  	if node.Schema.ExplicitSchema {
  1654  		ctx.WriteString(" ")
  1655  		ctx.FormatNode(&node.Schema)
  1656  	}
  1657  
  1658  	if !node.AuthRole.Undefined() {
  1659  		ctx.WriteString(" AUTHORIZATION ")
  1660  		ctx.FormatNode(&node.AuthRole)
  1661  	}
  1662  }
  1663  
  1664  // CreateSequence represents a CREATE SEQUENCE statement.
  1665  type CreateSequence struct {
  1666  	IfNotExists bool
  1667  	Name        TableName
  1668  	Persistence Persistence
  1669  	Options     SequenceOptions
  1670  }
  1671  
  1672  // Format implements the NodeFormatter interface.
  1673  func (node *CreateSequence) Format(ctx *FmtCtx) {
  1674  	ctx.WriteString("CREATE ")
  1675  
  1676  	if node.Persistence == PersistenceTemporary {
  1677  		ctx.WriteString("TEMPORARY ")
  1678  	}
  1679  
  1680  	ctx.WriteString("SEQUENCE ")
  1681  
  1682  	if node.IfNotExists {
  1683  		ctx.WriteString("IF NOT EXISTS ")
  1684  	}
  1685  	ctx.FormatNode(&node.Name)
  1686  	ctx.FormatNode(&node.Options)
  1687  }
  1688  
  1689  // SequenceOptions represents a list of sequence options.
  1690  type SequenceOptions []SequenceOption
  1691  
  1692  // Format implements the NodeFormatter interface.
  1693  func (node *SequenceOptions) Format(ctx *FmtCtx) {
  1694  	for i := range *node {
  1695  		option := &(*node)[i]
  1696  		ctx.WriteByte(' ')
  1697  		switch option.Name {
  1698  		case SeqOptAs:
  1699  			ctx.WriteString(option.Name)
  1700  			ctx.WriteByte(' ')
  1701  			ctx.WriteString(option.AsIntegerType.SQLString())
  1702  		case SeqOptCycle, SeqOptNoCycle:
  1703  			ctx.WriteString(option.Name)
  1704  		case SeqOptCache:
  1705  			ctx.WriteString(option.Name)
  1706  			ctx.WriteByte(' ')
  1707  			// TODO(knz): replace all this with ctx.FormatNode if/when
  1708  			// the cache option supports expressions.
  1709  			if ctx.flags.HasFlags(FmtHideConstants) {
  1710  				ctx.WriteByte('0')
  1711  			} else {
  1712  				ctx.Printf("%d", *option.IntVal)
  1713  			}
  1714  		case SeqOptMaxValue, SeqOptMinValue:
  1715  			if option.IntVal == nil {
  1716  				ctx.WriteString("NO ")
  1717  				ctx.WriteString(option.Name)
  1718  			} else {
  1719  				ctx.WriteString(option.Name)
  1720  				ctx.WriteByte(' ')
  1721  				// TODO(knz): replace all this with ctx.FormatNode if/when
  1722  				// the min/max value options support expressions.
  1723  				if ctx.flags.HasFlags(FmtHideConstants) {
  1724  					ctx.WriteByte('0')
  1725  				} else {
  1726  					ctx.Printf("%d", *option.IntVal)
  1727  				}
  1728  			}
  1729  		case SeqOptStart:
  1730  			ctx.WriteString(option.Name)
  1731  			ctx.WriteByte(' ')
  1732  			if option.OptionalWord {
  1733  				ctx.WriteString("WITH ")
  1734  			}
  1735  			// TODO(knz): replace all this with ctx.FormatNode if/when
  1736  			// the start option supports expressions.
  1737  			if ctx.flags.HasFlags(FmtHideConstants) {
  1738  				ctx.WriteByte('0')
  1739  			} else {
  1740  				ctx.Printf("%d", *option.IntVal)
  1741  			}
  1742  		case SeqOptRestart:
  1743  			ctx.WriteString(option.Name)
  1744  			if option.IntVal != nil {
  1745  				ctx.WriteByte(' ')
  1746  				if option.OptionalWord {
  1747  					ctx.WriteString("WITH ")
  1748  				}
  1749  				if ctx.flags.HasFlags(FmtHideConstants) {
  1750  					ctx.WriteByte('0')
  1751  				} else {
  1752  					ctx.Printf("%d", *option.IntVal)
  1753  				}
  1754  			}
  1755  		case SeqOptIncrement:
  1756  			ctx.WriteString(option.Name)
  1757  			ctx.WriteByte(' ')
  1758  			if option.OptionalWord {
  1759  				ctx.WriteString("BY ")
  1760  			}
  1761  			// TODO(knz): replace all this with ctx.FormatNode if/when
  1762  			// the increment option supports expressions.
  1763  			if ctx.flags.HasFlags(FmtHideConstants) {
  1764  				ctx.WriteByte('0')
  1765  			} else {
  1766  				ctx.Printf("%d", *option.IntVal)
  1767  			}
  1768  		case SeqOptVirtual:
  1769  			ctx.WriteString(option.Name)
  1770  		case SeqOptOwnedBy:
  1771  			ctx.WriteString(option.Name)
  1772  			ctx.WriteByte(' ')
  1773  			switch option.ColumnItemVal {
  1774  			case nil:
  1775  				ctx.WriteString("NONE")
  1776  			default:
  1777  				ctx.FormatNode(option.ColumnItemVal)
  1778  			}
  1779  		default:
  1780  			panic(errors.AssertionFailedf("unexpected SequenceOption: %v", option))
  1781  		}
  1782  	}
  1783  }
  1784  
  1785  // SequenceOption represents an option on a CREATE SEQUENCE statement.
  1786  type SequenceOption struct {
  1787  	Name string
  1788  
  1789  	// AsIntegerType specifies default min and max values of a sequence.
  1790  	AsIntegerType *types.T
  1791  
  1792  	IntVal *int64
  1793  
  1794  	OptionalWord bool
  1795  
  1796  	ColumnItemVal *ColumnItem
  1797  }
  1798  
  1799  // Names of options on CREATE SEQUENCE.
  1800  const (
  1801  	SeqOptAs        = "AS"
  1802  	SeqOptCycle     = "CYCLE"
  1803  	SeqOptNoCycle   = "NO CYCLE"
  1804  	SeqOptOwnedBy   = "OWNED BY"
  1805  	SeqOptCache     = "CACHE"
  1806  	SeqOptIncrement = "INCREMENT"
  1807  	SeqOptMinValue  = "MINVALUE"
  1808  	SeqOptMaxValue  = "MAXVALUE"
  1809  	SeqOptStart     = "START"
  1810  	SeqOptRestart   = "RESTART"
  1811  	SeqOptVirtual   = "VIRTUAL"
  1812  
  1813  	// Avoid unused warning for constants.
  1814  	_ = SeqOptAs
  1815  )
  1816  
  1817  // LikeTableDef represents a LIKE table declaration on a CREATE TABLE statement.
  1818  type LikeTableDef struct {
  1819  	Name    TableName
  1820  	Options []LikeTableOption
  1821  }
  1822  
  1823  // LikeTableOption represents an individual INCLUDING / EXCLUDING statement
  1824  // on a LIKE table declaration.
  1825  type LikeTableOption struct {
  1826  	Excluded bool
  1827  	Opt      LikeTableOpt
  1828  }
  1829  
  1830  // Format implements the NodeFormatter interface.
  1831  func (def *LikeTableDef) Format(ctx *FmtCtx) {
  1832  	ctx.WriteString("LIKE ")
  1833  	ctx.FormatNode(&def.Name)
  1834  	for _, o := range def.Options {
  1835  		ctx.WriteString(" ")
  1836  		ctx.FormatNode(o)
  1837  	}
  1838  }
  1839  
  1840  // Format implements the NodeFormatter interface.
  1841  func (l LikeTableOption) Format(ctx *FmtCtx) {
  1842  	if l.Excluded {
  1843  		ctx.WriteString("EXCLUDING ")
  1844  	} else {
  1845  		ctx.WriteString("INCLUDING ")
  1846  	}
  1847  	ctx.WriteString(l.Opt.String())
  1848  }
  1849  
  1850  // LikeTableOpt represents one of the types of things that can be included or
  1851  // excluded in a LIKE table declaration. It's a bitmap, where each of the Opt
  1852  // values is a single enabled bit in the map.
  1853  type LikeTableOpt int
  1854  
  1855  // The values for LikeTableOpt.
  1856  const (
  1857  	LikeTableOptConstraints LikeTableOpt = 1 << iota
  1858  	LikeTableOptDefaults
  1859  	LikeTableOptGenerated
  1860  	LikeTableOptIndexes
  1861  
  1862  	// Make sure this field stays last!
  1863  	likeTableOptInvalid
  1864  )
  1865  
  1866  // LikeTableOptAll is the full LikeTableOpt bitmap.
  1867  const LikeTableOptAll = ^likeTableOptInvalid
  1868  
  1869  // Has returns true if the receiver has the other options bits set.
  1870  func (o LikeTableOpt) Has(other LikeTableOpt) bool {
  1871  	return int(o)&int(other) != 0
  1872  }
  1873  
  1874  func (o LikeTableOpt) String() string {
  1875  	switch o {
  1876  	case LikeTableOptConstraints:
  1877  		return "CONSTRAINTS"
  1878  	case LikeTableOptDefaults:
  1879  		return "DEFAULTS"
  1880  	case LikeTableOptGenerated:
  1881  		return "GENERATED"
  1882  	case LikeTableOptIndexes:
  1883  		return "INDEXES"
  1884  	case LikeTableOptAll:
  1885  		return "ALL"
  1886  	default:
  1887  		panic("unknown like table opt" + strconv.Itoa(int(o)))
  1888  	}
  1889  }
  1890  
  1891  func (o *KVOptions) formatAsRoleOptions(ctx *FmtCtx) {
  1892  	for _, option := range *o {
  1893  		ctx.WriteByte(' ')
  1894  		// Role option keys are always sequences of keywords separated
  1895  		// by spaces.
  1896  		ctx.WriteString(strings.ToUpper(string(option.Key)))
  1897  
  1898  		// Password is a special case.
  1899  		if strings.HasSuffix(string(option.Key), "password") {
  1900  			ctx.WriteByte(' ')
  1901  			if ctx.flags.HasFlags(FmtShowPasswords) {
  1902  				ctx.FormatNode(option.Value)
  1903  			} else {
  1904  				ctx.WriteString(PasswordSubstitution)
  1905  			}
  1906  		} else if option.Value != nil {
  1907  			ctx.WriteByte(' ')
  1908  			if ctx.HasFlags(FmtHideConstants) {
  1909  				ctx.WriteString("'_'")
  1910  			} else {
  1911  				ctx.FormatNode(option.Value)
  1912  			}
  1913  		}
  1914  	}
  1915  }
  1916  
  1917  // CreateRole represents a CREATE ROLE statement.
  1918  type CreateRole struct {
  1919  	Name        RoleSpec
  1920  	IfNotExists bool
  1921  	IsRole      bool
  1922  	KVOptions   KVOptions
  1923  }
  1924  
  1925  // Format implements the NodeFormatter interface.
  1926  func (node *CreateRole) Format(ctx *FmtCtx) {
  1927  	ctx.WriteString("CREATE")
  1928  	if node.IsRole {
  1929  		ctx.WriteString(" ROLE ")
  1930  	} else {
  1931  		ctx.WriteString(" USER ")
  1932  	}
  1933  	if node.IfNotExists {
  1934  		ctx.WriteString("IF NOT EXISTS ")
  1935  	}
  1936  	ctx.FormatNode(&node.Name)
  1937  
  1938  	if len(node.KVOptions) > 0 {
  1939  		ctx.WriteString(" WITH")
  1940  		node.KVOptions.formatAsRoleOptions(ctx)
  1941  	}
  1942  }
  1943  
  1944  // CreateView represents a CREATE VIEW statement.
  1945  type CreateView struct {
  1946  	Name         TableName
  1947  	ColumnNames  NameList
  1948  	AsSource     *Select
  1949  	IfNotExists  bool
  1950  	Persistence  Persistence
  1951  	Replace      bool
  1952  	Materialized bool
  1953  	WithData     bool
  1954  }
  1955  
  1956  // Format implements the NodeFormatter interface.
  1957  func (node *CreateView) Format(ctx *FmtCtx) {
  1958  	ctx.WriteString("CREATE ")
  1959  
  1960  	if node.Replace {
  1961  		ctx.WriteString("OR REPLACE ")
  1962  	}
  1963  
  1964  	if node.Persistence == PersistenceTemporary {
  1965  		ctx.WriteString("TEMPORARY ")
  1966  	}
  1967  
  1968  	if node.Materialized {
  1969  		ctx.WriteString("MATERIALIZED ")
  1970  	}
  1971  
  1972  	ctx.WriteString("VIEW ")
  1973  
  1974  	if node.IfNotExists {
  1975  		ctx.WriteString("IF NOT EXISTS ")
  1976  	}
  1977  	ctx.FormatNode(&node.Name)
  1978  
  1979  	if len(node.ColumnNames) > 0 {
  1980  		ctx.WriteByte(' ')
  1981  		ctx.WriteByte('(')
  1982  		ctx.FormatNode(&node.ColumnNames)
  1983  		ctx.WriteByte(')')
  1984  	}
  1985  
  1986  	ctx.WriteString(" AS ")
  1987  	ctx.FormatNode(node.AsSource)
  1988  	if node.Materialized && node.WithData {
  1989  		ctx.WriteString(" WITH DATA")
  1990  	} else if node.Materialized && !node.WithData {
  1991  		ctx.WriteString(" WITH NO DATA")
  1992  	}
  1993  }
  1994  
  1995  // RefreshMaterializedView represents a REFRESH MATERIALIZED VIEW statement.
  1996  type RefreshMaterializedView struct {
  1997  	Name              *UnresolvedObjectName
  1998  	Concurrently      bool
  1999  	RefreshDataOption RefreshDataOption
  2000  }
  2001  
  2002  // RefreshDataOption corresponds to arguments for the REFRESH MATERIALIZED VIEW
  2003  // statement.
  2004  type RefreshDataOption int
  2005  
  2006  const (
  2007  	// RefreshDataDefault refers to no option provided to the REFRESH MATERIALIZED
  2008  	// VIEW statement.
  2009  	RefreshDataDefault RefreshDataOption = iota
  2010  	// RefreshDataWithData refers to the WITH DATA option provided to the REFRESH
  2011  	// MATERIALIZED VIEW statement.
  2012  	RefreshDataWithData
  2013  	// RefreshDataClear refers to the WITH NO DATA option provided to the REFRESH
  2014  	// MATERIALIZED VIEW statement.
  2015  	RefreshDataClear
  2016  )
  2017  
  2018  // Format implements the NodeFormatter interface.
  2019  func (node *RefreshMaterializedView) Format(ctx *FmtCtx) {
  2020  	ctx.WriteString("REFRESH MATERIALIZED VIEW ")
  2021  	if node.Concurrently {
  2022  		ctx.WriteString("CONCURRENTLY ")
  2023  	}
  2024  	ctx.FormatNode(node.Name)
  2025  	switch node.RefreshDataOption {
  2026  	case RefreshDataWithData:
  2027  		ctx.WriteString(" WITH DATA")
  2028  	case RefreshDataClear:
  2029  		ctx.WriteString(" WITH NO DATA")
  2030  	}
  2031  }
  2032  
  2033  // CreateStats represents a CREATE STATISTICS statement.
  2034  type CreateStats struct {
  2035  	Name        Name
  2036  	ColumnNames NameList
  2037  	Table       TableExpr
  2038  	Options     CreateStatsOptions
  2039  }
  2040  
  2041  // Format implements the NodeFormatter interface.
  2042  func (node *CreateStats) Format(ctx *FmtCtx) {
  2043  	ctx.WriteString("CREATE STATISTICS ")
  2044  	ctx.FormatNode(&node.Name)
  2045  
  2046  	if len(node.ColumnNames) > 0 {
  2047  		ctx.WriteString(" ON ")
  2048  		ctx.FormatNode(&node.ColumnNames)
  2049  	}
  2050  
  2051  	ctx.WriteString(" FROM ")
  2052  	ctx.FormatNode(node.Table)
  2053  
  2054  	if !node.Options.Empty() {
  2055  		ctx.WriteString(" WITH OPTIONS")
  2056  		ctx.FormatNode(&node.Options)
  2057  	}
  2058  }
  2059  
  2060  // CreateStatsOptions contains options for CREATE STATISTICS.
  2061  type CreateStatsOptions struct {
  2062  	// Throttling enables throttling and indicates the fraction of time we are
  2063  	// idling (between 0 and 1).
  2064  	Throttling float64
  2065  
  2066  	// AsOf performs a historical read at the given timestamp.
  2067  	// Note that the timestamp will be moved up during the operation if it gets
  2068  	// too old (in order to avoid problems with TTL expiration).
  2069  	AsOf AsOfClause
  2070  
  2071  	// UsingExtremes is true when the statistics collection is at
  2072  	// extreme values of the table or the index specified.
  2073  	UsingExtremes bool
  2074  
  2075  	// Where will specify statistics collection in a set of rows of the table
  2076  	// or index specified.
  2077  	Where *Where
  2078  }
  2079  
  2080  // Empty returns true if no options were provided.
  2081  func (o *CreateStatsOptions) Empty() bool {
  2082  	return o.Throttling == 0 && o.AsOf.Expr == nil && o.Where == nil && !o.UsingExtremes
  2083  }
  2084  
  2085  // Format implements the NodeFormatter interface.
  2086  func (o *CreateStatsOptions) Format(ctx *FmtCtx) {
  2087  	if o.UsingExtremes {
  2088  		ctx.WriteString(" USING EXTREMES")
  2089  	}
  2090  	if o.Where != nil {
  2091  		ctx.WriteByte(' ')
  2092  		ctx.FormatNode(o.Where)
  2093  	}
  2094  	if o.Throttling != 0 {
  2095  		ctx.WriteString(" THROTTLING ")
  2096  		// TODO(knz): Remove all this with ctx.FormatNode()
  2097  		// if/when throttling supports full expressions.
  2098  		if ctx.flags.HasFlags(FmtHideConstants) {
  2099  			// Using the value '0.001' instead of '0.0', because
  2100  			// when using '0.0' the statement does not get
  2101  			// formatted with the THROTTLING option.
  2102  			ctx.WriteString("0.001")
  2103  		} else {
  2104  			fmt.Fprintf(ctx, "%g", o.Throttling)
  2105  		}
  2106  	}
  2107  	if o.AsOf.Expr != nil {
  2108  		ctx.WriteByte(' ')
  2109  		ctx.FormatNode(&o.AsOf)
  2110  	}
  2111  }
  2112  
  2113  // CombineWith combines two options, erroring out if the two options contain
  2114  // incompatible settings.
  2115  func (o *CreateStatsOptions) CombineWith(other *CreateStatsOptions) error {
  2116  	if other.Throttling != 0 {
  2117  		if o.Throttling != 0 {
  2118  			return errors.New("THROTTLING specified multiple times")
  2119  		}
  2120  		o.Throttling = other.Throttling
  2121  	}
  2122  	if other.AsOf.Expr != nil {
  2123  		if o.AsOf.Expr != nil {
  2124  			return errors.New("AS OF specified multiple times")
  2125  		}
  2126  		o.AsOf = other.AsOf
  2127  	}
  2128  	if other.UsingExtremes {
  2129  		if o.UsingExtremes {
  2130  			return errors.New("USING EXTREMES specified multiple times")
  2131  		}
  2132  		o.UsingExtremes = other.UsingExtremes
  2133  	}
  2134  	if other.Where != nil {
  2135  		if o.Where != nil {
  2136  			return errors.New("WHERE specified multiple times")
  2137  		}
  2138  		o.Where = other.Where
  2139  	}
  2140  	if other.Where != nil && o.UsingExtremes || o.Where != nil && other.UsingExtremes {
  2141  		return errors.New("USING EXTREMES and WHERE may not be specified together")
  2142  	}
  2143  	return nil
  2144  }
  2145  
  2146  // CreateExtension represents a CREATE EXTENSION statement.
  2147  type CreateExtension struct {
  2148  	Name        Name
  2149  	IfNotExists bool
  2150  }
  2151  
  2152  // Format implements the NodeFormatter interface.
  2153  func (node *CreateExtension) Format(ctx *FmtCtx) {
  2154  	ctx.WriteString("CREATE EXTENSION ")
  2155  	if node.IfNotExists {
  2156  		ctx.WriteString("IF NOT EXISTS ")
  2157  	}
  2158  	// NB: we do not anonymize the extension name
  2159  	// because 1) we assume that extension names
  2160  	// do not contain sensitive information and
  2161  	// 2) we want to get telemetry on which extensions
  2162  	// users attempt to load.
  2163  	ctx.WithFlags(ctx.flags&^FmtAnonymize, func() {
  2164  		ctx.FormatNode(&node.Name)
  2165  	})
  2166  }
  2167  
  2168  // CreateExternalConnection represents a CREATE EXTERNAL CONNECTION statement.
  2169  type CreateExternalConnection struct {
  2170  	ConnectionLabelSpec LabelSpec
  2171  	As                  Expr
  2172  }
  2173  
  2174  var _ Statement = &CreateExternalConnection{}
  2175  
  2176  // Format implements the Statement interface.
  2177  func (node *CreateExternalConnection) Format(ctx *FmtCtx) {
  2178  	ctx.WriteString("CREATE EXTERNAL CONNECTION")
  2179  	ctx.FormatNode(&node.ConnectionLabelSpec)
  2180  	ctx.WriteString(" AS ")
  2181  	ctx.FormatNode(node.As)
  2182  }
  2183  
  2184  // CreateTenant represents a CREATE VIRTUAL CLUSTER statement.
  2185  type CreateTenant struct {
  2186  	IfNotExists bool
  2187  	TenantSpec  *TenantSpec
  2188  	Like        *LikeTenantSpec
  2189  }
  2190  
  2191  // Format implements the NodeFormatter interface.
  2192  func (node *CreateTenant) Format(ctx *FmtCtx) {
  2193  	ctx.WriteString("CREATE VIRTUAL CLUSTER ")
  2194  	if node.IfNotExists {
  2195  		ctx.WriteString("IF NOT EXISTS ")
  2196  	}
  2197  	ctx.FormatNode(node.TenantSpec)
  2198  	ctx.FormatNode(node.Like)
  2199  }
  2200  
  2201  // LikeTenantSpec represents a LIKE clause in CREATE VIRTUAL CLUSTER.
  2202  type LikeTenantSpec struct {
  2203  	OtherTenant *TenantSpec
  2204  }
  2205  
  2206  func (node *LikeTenantSpec) Format(ctx *FmtCtx) {
  2207  	if node.OtherTenant == nil {
  2208  		return
  2209  	}
  2210  	ctx.WriteString(" LIKE ")
  2211  	ctx.FormatNode(node.OtherTenant)
  2212  }
  2213  
  2214  // CreateTenantFromReplication represents a CREATE VIRTUAL CLUSTER...FROM REPLICATION
  2215  // statement.
  2216  type CreateTenantFromReplication struct {
  2217  	IfNotExists bool
  2218  	TenantSpec  *TenantSpec
  2219  
  2220  	// ReplicationSourceTenantName is the name of the tenant that
  2221  	// we are replicating into the newly created tenant.
  2222  	// Note: even though this field can only be a name
  2223  	// (this is guaranteed during parsing), we still want
  2224  	// to use the TenantSpec type. This supports the auto-promotion
  2225  	// of simple identifiers to strings.
  2226  	ReplicationSourceTenantName *TenantSpec
  2227  	// ReplicationSourceAddress is the address of the source cluster that we are
  2228  	// replicating data from.
  2229  	ReplicationSourceAddress Expr
  2230  
  2231  	Options TenantReplicationOptions
  2232  
  2233  	Like *LikeTenantSpec
  2234  }
  2235  
  2236  // TenantReplicationOptions  options for the CREATE VIRTUAL CLUSTER FROM REPLICATION command.
  2237  type TenantReplicationOptions struct {
  2238  	Retention       Expr
  2239  	ResumeTimestamp Expr
  2240  }
  2241  
  2242  var _ NodeFormatter = &TenantReplicationOptions{}
  2243  
  2244  // Format implements the NodeFormatter interface.
  2245  func (node *CreateTenantFromReplication) Format(ctx *FmtCtx) {
  2246  	ctx.WriteString("CREATE VIRTUAL CLUSTER ")
  2247  	if node.IfNotExists {
  2248  		ctx.WriteString("IF NOT EXISTS ")
  2249  	}
  2250  	// NB: we do not anonymize the tenant name because we assume that tenant names
  2251  	// do not contain sensitive information.
  2252  	ctx.FormatNode(node.TenantSpec)
  2253  	ctx.FormatNode(node.Like)
  2254  
  2255  	if node.ReplicationSourceAddress != nil {
  2256  		ctx.WriteString(" FROM REPLICATION OF ")
  2257  		ctx.FormatNode(node.ReplicationSourceTenantName)
  2258  		ctx.WriteString(" ON ")
  2259  		_, canOmitParentheses := node.ReplicationSourceAddress.(alreadyDelimitedAsSyntacticDExpr)
  2260  		if !canOmitParentheses {
  2261  			ctx.WriteByte('(')
  2262  		}
  2263  		ctx.FormatNode(node.ReplicationSourceAddress)
  2264  		if !canOmitParentheses {
  2265  			ctx.WriteByte(')')
  2266  		}
  2267  
  2268  	}
  2269  	if !node.Options.IsDefault() {
  2270  		ctx.WriteString(" WITH ")
  2271  		ctx.FormatNode(&node.Options)
  2272  	}
  2273  }
  2274  
  2275  // Format implements the NodeFormatter interface
  2276  func (o *TenantReplicationOptions) Format(ctx *FmtCtx) {
  2277  	var addSep bool
  2278  	maybeAddSep := func() {
  2279  		if addSep {
  2280  			ctx.WriteString(", ")
  2281  		}
  2282  		addSep = true
  2283  	}
  2284  	if o.Retention != nil {
  2285  		maybeAddSep()
  2286  		ctx.WriteString("RETENTION = ")
  2287  		_, canOmitParentheses := o.Retention.(alreadyDelimitedAsSyntacticDExpr)
  2288  		if !canOmitParentheses {
  2289  			ctx.WriteByte('(')
  2290  		}
  2291  		ctx.FormatNode(o.Retention)
  2292  		if !canOmitParentheses {
  2293  			ctx.WriteByte(')')
  2294  		}
  2295  	}
  2296  	if o.ResumeTimestamp != nil {
  2297  		maybeAddSep()
  2298  		ctx.WriteString("RESUME TIMESTAMP = ")
  2299  		_, canOmitParentheses := o.ResumeTimestamp.(alreadyDelimitedAsSyntacticDExpr)
  2300  		if !canOmitParentheses {
  2301  			ctx.WriteByte('(')
  2302  		}
  2303  		ctx.FormatNode(o.ResumeTimestamp)
  2304  		if !canOmitParentheses {
  2305  			ctx.WriteByte(')')
  2306  		}
  2307  	}
  2308  }
  2309  
  2310  // CombineWith merges other TenantReplicationOptions into this struct.
  2311  // An error is returned if the same option merged multiple times.
  2312  func (o *TenantReplicationOptions) CombineWith(other *TenantReplicationOptions) error {
  2313  	if o.Retention != nil {
  2314  		if other.Retention != nil {
  2315  			return errors.New("RETENTION option specified multiple times")
  2316  		}
  2317  	} else {
  2318  		o.Retention = other.Retention
  2319  	}
  2320  
  2321  	if o.ResumeTimestamp != nil {
  2322  		if other.ResumeTimestamp != nil {
  2323  			return errors.New("RESUME TIMESTAMP option specified multiple times")
  2324  		}
  2325  	} else {
  2326  		o.ResumeTimestamp = other.ResumeTimestamp
  2327  	}
  2328  
  2329  	return nil
  2330  }
  2331  
  2332  // IsDefault returns true if this backup options struct has default value.
  2333  func (o TenantReplicationOptions) IsDefault() bool {
  2334  	options := TenantReplicationOptions{}
  2335  	return o.Retention == options.Retention &&
  2336  		o.ResumeTimestamp == options.ResumeTimestamp
  2337  }
  2338  
  2339  type SuperRegion struct {
  2340  	Name    Name
  2341  	Regions NameList
  2342  }
  2343  
  2344  func (node *SuperRegion) Format(ctx *FmtCtx) {
  2345  	ctx.WriteString(" SUPER REGION ")
  2346  	ctx.FormatNode(&node.Name)
  2347  	ctx.WriteString(" VALUES ")
  2348  	for i := range node.Regions {
  2349  		if i != 0 {
  2350  			ctx.WriteString(",")
  2351  		}
  2352  		ctx.FormatNode(&node.Regions[i])
  2353  	}
  2354  }