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

     1  // Copyright 2015 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package sql
    12  
    13  import (
    14  	"bytes"
    15  	"context"
    16  	gojson "encoding/json"
    17  	"fmt"
    18  
    19  	"github.com/cockroachdb/cockroach/pkg/keys"
    20  	"github.com/cockroachdb/cockroach/pkg/security"
    21  	"github.com/cockroachdb/cockroach/pkg/server/telemetry"
    22  	"github.com/cockroachdb/cockroach/pkg/sql/catalog/resolver"
    23  	"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode"
    24  	"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror"
    25  	"github.com/cockroachdb/cockroach/pkg/sql/privilege"
    26  	"github.com/cockroachdb/cockroach/pkg/sql/schemaexpr"
    27  	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
    28  	"github.com/cockroachdb/cockroach/pkg/sql/sqlbase"
    29  	"github.com/cockroachdb/cockroach/pkg/sql/sqltelemetry"
    30  	"github.com/cockroachdb/cockroach/pkg/sql/stats"
    31  	"github.com/cockroachdb/cockroach/pkg/sql/types"
    32  	"github.com/cockroachdb/cockroach/pkg/util/protoutil"
    33  	"github.com/cockroachdb/errors"
    34  	"github.com/gogo/protobuf/proto"
    35  )
    36  
    37  type alterTableNode struct {
    38  	n         *tree.AlterTable
    39  	tableDesc *MutableTableDescriptor
    40  	// statsData is populated with data for "alter table inject statistics"
    41  	// commands - the JSON stats expressions.
    42  	// It is parallel with n.Cmds (for the inject stats commands).
    43  	statsData map[int]tree.TypedExpr
    44  }
    45  
    46  // AlterTable applies a schema change on a table.
    47  // Privileges: CREATE on table.
    48  //   notes: postgres requires CREATE on the table.
    49  //          mysql requires ALTER, CREATE, INSERT on the table.
    50  func (p *planner) AlterTable(ctx context.Context, n *tree.AlterTable) (planNode, error) {
    51  	tableDesc, err := p.ResolveMutableTableDescriptorEx(
    52  		ctx, n.Table, !n.IfExists, resolver.ResolveRequireTableDesc,
    53  	)
    54  	if errors.Is(err, resolver.ErrNoPrimaryKey) {
    55  		if len(n.Cmds) > 0 && isAlterCmdValidWithoutPrimaryKey(n.Cmds[0]) {
    56  			tableDesc, err = p.ResolveMutableTableDescriptorExAllowNoPrimaryKey(
    57  				ctx, n.Table, !n.IfExists, resolver.ResolveRequireTableDesc,
    58  			)
    59  		}
    60  	}
    61  	if err != nil {
    62  		return nil, err
    63  	}
    64  
    65  	if tableDesc == nil {
    66  		return newZeroNode(nil /* columns */), nil
    67  	}
    68  
    69  	if err := p.CheckPrivilege(ctx, tableDesc, privilege.CREATE); err != nil {
    70  		return nil, err
    71  	}
    72  
    73  	n.HoistAddColumnConstraints()
    74  
    75  	// See if there's any "inject statistics" in the query and type check the
    76  	// expressions.
    77  	statsData := make(map[int]tree.TypedExpr)
    78  	for i, cmd := range n.Cmds {
    79  		injectStats, ok := cmd.(*tree.AlterTableInjectStats)
    80  		if !ok {
    81  			continue
    82  		}
    83  		typedExpr, err := p.analyzeExpr(
    84  			ctx, injectStats.Stats,
    85  			nil, /* sources - no name resolution */
    86  			tree.IndexedVarHelper{},
    87  			types.Jsonb, true, /* requireType */
    88  			"INJECT STATISTICS" /* typingContext */)
    89  		if err != nil {
    90  			return nil, err
    91  		}
    92  		statsData[i] = typedExpr
    93  	}
    94  
    95  	return &alterTableNode{
    96  		n:         n,
    97  		tableDesc: tableDesc,
    98  		statsData: statsData,
    99  	}, nil
   100  }
   101  
   102  func isAlterCmdValidWithoutPrimaryKey(cmd tree.AlterTableCmd) bool {
   103  	switch t := cmd.(type) {
   104  	case *tree.AlterTableAlterPrimaryKey:
   105  		return true
   106  	case *tree.AlterTableAddConstraint:
   107  		cs, ok := t.ConstraintDef.(*tree.UniqueConstraintTableDef)
   108  		if ok && cs.PrimaryKey {
   109  			return true
   110  		}
   111  	default:
   112  		return false
   113  	}
   114  	return false
   115  }
   116  
   117  // ReadingOwnWrites implements the planNodeReadingOwnWrites interface.
   118  // This is because ALTER TABLE performs multiple KV operations on descriptors
   119  // and expects to see its own writes.
   120  func (n *alterTableNode) ReadingOwnWrites() {}
   121  
   122  func (n *alterTableNode) startExec(params runParams) error {
   123  	telemetry.Inc(sqltelemetry.SchemaChangeAlterCounter("table"))
   124  
   125  	// Commands can either change the descriptor directly (for
   126  	// alterations that don't require a backfill) or add a mutation to
   127  	// the list.
   128  	descriptorChanged := false
   129  	origNumMutations := len(n.tableDesc.Mutations)
   130  	var droppedViews []string
   131  	resolved := params.p.ResolvedName(n.n.Table)
   132  	tn, ok := resolved.(*tree.TableName)
   133  	if !ok {
   134  		return errors.AssertionFailedf(
   135  			"%q was not resolved as a table but is %T", resolved, resolved)
   136  	}
   137  
   138  	for i, cmd := range n.n.Cmds {
   139  		telemetry.Inc(cmd.TelemetryCounter())
   140  
   141  		if !n.tableDesc.HasPrimaryKey() && !isAlterCmdValidWithoutPrimaryKey(cmd) {
   142  			return errors.Newf("table %q does not have a primary key, cannot perform%s", n.tableDesc.Name, tree.AsString(cmd))
   143  		}
   144  
   145  		switch t := cmd.(type) {
   146  		case *tree.AlterTableAddColumn:
   147  			d := t.ColumnDef
   148  			version := params.ExecCfg().Settings.Version.ActiveVersionOrEmpty(params.ctx)
   149  			toType, err := tree.ResolveType(params.ctx, d.Type, params.p.semaCtx.GetTypeResolver())
   150  			if err != nil {
   151  				return err
   152  			}
   153  			if supported, err := isTypeSupportedInVersion(version, toType); err != nil {
   154  				return err
   155  			} else if !supported {
   156  				return pgerror.Newf(
   157  					pgcode.FeatureNotSupported,
   158  					"type %s is not supported until version upgrade is finalized",
   159  					toType.SQLString(),
   160  				)
   161  			}
   162  
   163  			newDef, seqDbDesc, seqName, seqOpts, err := params.p.processSerialInColumnDef(params.ctx, d, tn)
   164  			if err != nil {
   165  				return err
   166  			}
   167  			if seqName != nil {
   168  				if err := doCreateSequence(
   169  					params,
   170  					n.n.String(),
   171  					seqDbDesc,
   172  					n.tableDesc.GetParentSchemaID(),
   173  					seqName,
   174  					n.tableDesc.Temporary,
   175  					seqOpts,
   176  					tree.AsStringWithFQNames(n.n, params.Ann()),
   177  				); err != nil {
   178  					return err
   179  				}
   180  			}
   181  			d = newDef
   182  			incTelemetryForNewColumn(d)
   183  
   184  			col, idx, expr, err := sqlbase.MakeColumnDefDescs(params.ctx, d, &params.p.semaCtx, params.EvalContext())
   185  			if err != nil {
   186  				return err
   187  			}
   188  			// If the new column has a DEFAULT expression that uses a sequence, add references between
   189  			// its descriptor and this column descriptor.
   190  			if d.HasDefaultExpr() {
   191  				changedSeqDescs, err := maybeAddSequenceDependencies(
   192  					params.ctx, params.p, n.tableDesc, col, expr, nil,
   193  				)
   194  				if err != nil {
   195  					return err
   196  				}
   197  				for _, changedSeqDesc := range changedSeqDescs {
   198  					if err := params.p.writeSchemaChange(
   199  						params.ctx, changedSeqDesc, sqlbase.InvalidMutationID, tree.AsStringWithFQNames(n.n, params.Ann()),
   200  					); err != nil {
   201  						return err
   202  					}
   203  				}
   204  			}
   205  
   206  			// We're checking to see if a user is trying add a non-nullable column without a default to a
   207  			// non empty table by scanning the primary index span with a limit of 1 to see if any key exists.
   208  			if !col.Nullable && (col.DefaultExpr == nil && !col.IsComputed()) {
   209  				span := n.tableDesc.PrimaryIndexSpan(params.ExecCfg().Codec)
   210  				kvs, err := params.p.txn.Scan(params.ctx, span.Key, span.EndKey, 1)
   211  				if err != nil {
   212  					return err
   213  				}
   214  				if len(kvs) > 0 {
   215  					return sqlbase.NewNonNullViolationError(col.Name)
   216  				}
   217  			}
   218  			_, err = n.tableDesc.FindActiveColumnByName(string(d.Name))
   219  			if m := n.tableDesc.FindColumnMutationByName(d.Name); m != nil {
   220  				switch m.Direction {
   221  				case sqlbase.DescriptorMutation_ADD:
   222  					return pgerror.Newf(pgcode.DuplicateColumn,
   223  						"duplicate: column %q in the middle of being added, not yet public",
   224  						col.Name)
   225  				case sqlbase.DescriptorMutation_DROP:
   226  					return pgerror.Newf(pgcode.ObjectNotInPrerequisiteState,
   227  						"column %q being dropped, try again later", col.Name)
   228  				default:
   229  					if err != nil {
   230  						return errors.AssertionFailedf(
   231  							"mutation in state %s, direction %s, and no column descriptor",
   232  							errors.Safe(m.State), errors.Safe(m.Direction))
   233  					}
   234  				}
   235  			}
   236  			if err == nil {
   237  				if t.IfNotExists {
   238  					continue
   239  				}
   240  				return sqlbase.NewColumnAlreadyExistsError(string(d.Name), n.tableDesc.Name)
   241  			}
   242  
   243  			n.tableDesc.AddColumnMutation(col, sqlbase.DescriptorMutation_ADD)
   244  			if idx != nil {
   245  				if err := n.tableDesc.AddIndexMutation(idx, sqlbase.DescriptorMutation_ADD); err != nil {
   246  					return err
   247  				}
   248  			}
   249  			if d.HasColumnFamily() {
   250  				err := n.tableDesc.AddColumnToFamilyMaybeCreate(
   251  					col.Name, string(d.Family.Name), d.Family.Create,
   252  					d.Family.IfNotExists)
   253  				if err != nil {
   254  					return err
   255  				}
   256  			}
   257  
   258  			if d.IsComputed() {
   259  				computedColValidator := schemaexpr.NewComputedColumnValidator(params.ctx, n.tableDesc, &params.p.semaCtx)
   260  				if err := computedColValidator.Validate(d); err != nil {
   261  					return err
   262  				}
   263  			}
   264  
   265  		case *tree.AlterTableAddConstraint:
   266  			switch d := t.ConstraintDef.(type) {
   267  			case *tree.UniqueConstraintTableDef:
   268  				if d.PrimaryKey {
   269  					// We only support "adding" a primary key when we are using the
   270  					// default rowid primary index or if a DROP PRIMARY KEY statement
   271  					// was processed before this statement. If a DROP PRIMARY KEY
   272  					// statement was processed, then n.tableDesc.HasPrimaryKey() = false.
   273  					if n.tableDesc.HasPrimaryKey() && !n.tableDesc.IsPrimaryIndexDefaultRowID() {
   274  						return pgerror.Newf(pgcode.InvalidTableDefinition,
   275  							"multiple primary keys for table %q are not allowed", n.tableDesc.Name)
   276  					}
   277  
   278  					// Translate this operation into an ALTER PRIMARY KEY command.
   279  					alterPK := &tree.AlterTableAlterPrimaryKey{
   280  						Columns:    d.Columns,
   281  						Sharded:    d.Sharded,
   282  						Interleave: d.Interleave,
   283  					}
   284  					if err := params.p.AlterPrimaryKey(params.ctx, n.tableDesc, alterPK); err != nil {
   285  						return err
   286  					}
   287  					continue
   288  				}
   289  				idx := sqlbase.IndexDescriptor{
   290  					Name:             string(d.Name),
   291  					Unique:           true,
   292  					StoreColumnNames: d.Storing.ToStrings(),
   293  				}
   294  				if err := idx.FillColumns(d.Columns); err != nil {
   295  					return err
   296  				}
   297  				if d.PartitionBy != nil {
   298  					partitioning, err := CreatePartitioning(
   299  						params.ctx, params.p.ExecCfg().Settings,
   300  						params.EvalContext(), n.tableDesc, &idx, d.PartitionBy)
   301  					if err != nil {
   302  						return err
   303  					}
   304  					idx.Partitioning = partitioning
   305  				}
   306  				_, dropped, err := n.tableDesc.FindIndexByName(string(d.Name))
   307  				if err == nil {
   308  					if dropped {
   309  						return pgerror.Newf(pgcode.ObjectNotInPrerequisiteState,
   310  							"index %q being dropped, try again later", d.Name)
   311  					}
   312  				}
   313  				if err := n.tableDesc.AddIndexMutation(&idx, sqlbase.DescriptorMutation_ADD); err != nil {
   314  					return err
   315  				}
   316  
   317  			case *tree.CheckConstraintTableDef:
   318  				info, err := n.tableDesc.GetConstraintInfo(params.ctx, nil, params.ExecCfg().Codec)
   319  				if err != nil {
   320  					return err
   321  				}
   322  				ckBuilder := schemaexpr.NewCheckConstraintBuilder(params.ctx, *tn, n.tableDesc, &params.p.semaCtx)
   323  				for k := range info {
   324  					ckBuilder.MarkNameInUse(k)
   325  				}
   326  				ck, err := ckBuilder.Build(d)
   327  				if err != nil {
   328  					return err
   329  				}
   330  				if t.ValidationBehavior == tree.ValidationDefault {
   331  					ck.Validity = sqlbase.ConstraintValidity_Validating
   332  				} else {
   333  					ck.Validity = sqlbase.ConstraintValidity_Unvalidated
   334  				}
   335  				n.tableDesc.AddCheckMutation(ck, sqlbase.DescriptorMutation_ADD)
   336  
   337  			case *tree.ForeignKeyConstraintTableDef:
   338  				for _, colName := range d.FromCols {
   339  					col, err := n.tableDesc.FindActiveOrNewColumnByName(colName)
   340  					if err != nil {
   341  						return err
   342  					}
   343  
   344  					if err := col.CheckCanBeFKRef(); err != nil {
   345  						return err
   346  					}
   347  				}
   348  				affected := make(map[sqlbase.ID]*sqlbase.MutableTableDescriptor)
   349  
   350  				// If there are any FKs, we will need to update the table descriptor of the
   351  				// depended-on table (to register this table against its DependedOnBy field).
   352  				// This descriptor must be looked up uncached, and we'll allow FK dependencies
   353  				// on tables that were just added. See the comment at the start of
   354  				// the global-scope resolveFK().
   355  				// TODO(vivek): check if the cache can be used.
   356  				var err error
   357  				params.p.runWithOptions(resolveFlags{skipCache: true}, func() {
   358  					// Check whether the table is empty, and pass the result to resolveFK(). If
   359  					// the table is empty, then resolveFK will automatically add the necessary
   360  					// index for a fk constraint if the index does not exist.
   361  					span := n.tableDesc.PrimaryIndexSpan(params.ExecCfg().Codec)
   362  					kvs, scanErr := params.p.txn.Scan(params.ctx, span.Key, span.EndKey, 1)
   363  					if scanErr != nil {
   364  						err = scanErr
   365  						return
   366  					}
   367  					var tableState FKTableState
   368  					if len(kvs) == 0 {
   369  						tableState = EmptyTable
   370  					} else {
   371  						tableState = NonEmptyTable
   372  					}
   373  					err = params.p.resolveFK(params.ctx, n.tableDesc, d, affected, tableState, t.ValidationBehavior)
   374  				})
   375  				if err != nil {
   376  					return err
   377  				}
   378  				descriptorChanged = true
   379  				for _, updated := range affected {
   380  					if err := params.p.writeSchemaChange(
   381  						params.ctx, updated, sqlbase.InvalidMutationID, tree.AsStringWithFQNames(n.n, params.Ann()),
   382  					); err != nil {
   383  						return err
   384  					}
   385  				}
   386  				// TODO(lucy): Validate() can't be called here because it reads the
   387  				// referenced table descs, which may have to be upgraded to the new FK
   388  				// representation. That requires reading the original table descriptor
   389  				// (which the backreference points to) from KV, but we haven't written
   390  				// the updated table desc yet. We can restore the call to Validate()
   391  				// after running a migration of all table descriptors, making it
   392  				// unnecessary to read the original table desc from KV.
   393  				// if err := n.tableDesc.Validate(params.ctx, params.p.txn); err != nil {
   394  				// 	return err
   395  				// }
   396  
   397  			default:
   398  				return errors.AssertionFailedf(
   399  					"unsupported constraint: %T", t.ConstraintDef)
   400  			}
   401  
   402  		case *tree.AlterTableAlterPrimaryKey:
   403  			if err := params.p.AlterPrimaryKey(params.ctx, n.tableDesc, t); err != nil {
   404  				return err
   405  			}
   406  			// Mark descriptorChanged so that a mutation job is scheduled at the end of startExec.
   407  			descriptorChanged = true
   408  
   409  		case *tree.AlterTableDropColumn:
   410  			if params.SessionData().SafeUpdates {
   411  				return pgerror.DangerousStatementf("ALTER TABLE DROP COLUMN will remove all data in that column")
   412  			}
   413  
   414  			colToDrop, dropped, err := n.tableDesc.FindColumnByName(t.Column)
   415  			if err != nil {
   416  				if t.IfExists {
   417  					// Noop.
   418  					continue
   419  				}
   420  				return err
   421  			}
   422  			if dropped {
   423  				continue
   424  			}
   425  
   426  			// If the dropped column uses a sequence, remove references to it from that sequence.
   427  			if len(colToDrop.UsesSequenceIds) > 0 {
   428  				if err := params.p.removeSequenceDependencies(params.ctx, n.tableDesc, colToDrop); err != nil {
   429  					return err
   430  				}
   431  			}
   432  
   433  			// You can't remove a column that owns a sequence that is depended on
   434  			// by another column
   435  			if err := params.p.canRemoveAllColumnOwnedSequences(params.ctx, n.tableDesc, colToDrop, t.DropBehavior); err != nil {
   436  				return err
   437  			}
   438  
   439  			if err := params.p.dropSequencesOwnedByCol(params.ctx, colToDrop); err != nil {
   440  				return err
   441  			}
   442  
   443  			// You can't drop a column depended on by a view unless CASCADE was
   444  			// specified.
   445  			for _, ref := range n.tableDesc.DependedOnBy {
   446  				found := false
   447  				for _, colID := range ref.ColumnIDs {
   448  					if colID == colToDrop.ID {
   449  						found = true
   450  						break
   451  					}
   452  				}
   453  				if !found {
   454  					continue
   455  				}
   456  				err := params.p.canRemoveDependentViewGeneric(
   457  					params.ctx, "column", string(t.Column), n.tableDesc.ParentID, ref, t.DropBehavior,
   458  				)
   459  				if err != nil {
   460  					return err
   461  				}
   462  				viewDesc, err := params.p.getViewDescForCascade(
   463  					params.ctx, "column", string(t.Column), n.tableDesc.ParentID, ref.ID, t.DropBehavior,
   464  				)
   465  				if err != nil {
   466  					return err
   467  				}
   468  				jobDesc := fmt.Sprintf("removing view %q dependent on column %q which is being dropped",
   469  					viewDesc.Name, colToDrop.ColName())
   470  				droppedViews, err = params.p.removeDependentView(params.ctx, n.tableDesc, viewDesc, jobDesc)
   471  				if err != nil {
   472  					return err
   473  				}
   474  			}
   475  
   476  			// We cannot remove this column if there are computed columns that use it.
   477  			computedColValidator := schemaexpr.NewComputedColumnValidator(params.ctx, n.tableDesc, &params.p.semaCtx)
   478  			if err := computedColValidator.ValidateNoDependents(colToDrop); err != nil {
   479  				return err
   480  			}
   481  
   482  			if n.tableDesc.PrimaryIndex.ContainsColumnID(colToDrop.ID) {
   483  				return pgerror.Newf(pgcode.InvalidColumnReference,
   484  					"column %q is referenced by the primary key", colToDrop.Name)
   485  			}
   486  			for _, idx := range n.tableDesc.AllNonDropIndexes() {
   487  				// We automatically drop indexes on that column that only
   488  				// index that column (and no other columns). If CASCADE is
   489  				// specified, we also drop other indices that refer to this
   490  				// column.  The criteria to determine whether an index "only
   491  				// indexes that column":
   492  				//
   493  				// Assume a table created with CREATE TABLE foo (a INT, b INT).
   494  				// Then assume the user issues ALTER TABLE foo DROP COLUMN a.
   495  				//
   496  				// INDEX i1 ON foo(a) -> i1 deleted
   497  				// INDEX i2 ON foo(a) STORING(b) -> i2 deleted
   498  				// INDEX i3 ON foo(a, b) -> i3 not deleted unless CASCADE is specified.
   499  				// INDEX i4 ON foo(b) STORING(a) -> i4 not deleted unless CASCADE is specified.
   500  
   501  				// containsThisColumn becomes true if the index is defined
   502  				// over the column being dropped.
   503  				containsThisColumn := false
   504  				// containsOnlyThisColumn becomes false if the index also
   505  				// includes non-PK columns other than the one being dropped.
   506  				containsOnlyThisColumn := true
   507  
   508  				// Analyze the index.
   509  				for _, id := range idx.ColumnIDs {
   510  					if id == colToDrop.ID {
   511  						containsThisColumn = true
   512  					} else {
   513  						containsOnlyThisColumn = false
   514  					}
   515  				}
   516  				for _, id := range idx.ExtraColumnIDs {
   517  					if n.tableDesc.PrimaryIndex.ContainsColumnID(id) {
   518  						// All secondary indices necessary contain the PK
   519  						// columns, too. (See the comments on the definition of
   520  						// IndexDescriptor). The presence of a PK column in the
   521  						// secondary index should thus not be seen as a
   522  						// sufficient reason to reject the DROP.
   523  						continue
   524  					}
   525  					if id == colToDrop.ID {
   526  						containsThisColumn = true
   527  					}
   528  				}
   529  				// The loop above this comment is for the old STORING encoding. The
   530  				// loop below is for the new encoding (where the STORING columns are
   531  				// always in the value part of a KV).
   532  				for _, id := range idx.StoreColumnIDs {
   533  					if id == colToDrop.ID {
   534  						containsThisColumn = true
   535  					}
   536  				}
   537  
   538  				// Perform the DROP.
   539  				if containsThisColumn {
   540  					if containsOnlyThisColumn || t.DropBehavior == tree.DropCascade {
   541  						jobDesc := fmt.Sprintf("removing index %q dependent on column %q which is being"+
   542  							" dropped; full details: %s", idx.Name, colToDrop.ColName(),
   543  							tree.AsStringWithFQNames(n.n, params.Ann()))
   544  						if err := params.p.dropIndexByName(
   545  							params.ctx, tn, tree.UnrestrictedName(idx.Name), n.tableDesc, false,
   546  							t.DropBehavior, ignoreIdxConstraint, jobDesc,
   547  						); err != nil {
   548  							return err
   549  						}
   550  					} else {
   551  						return pgerror.Newf(pgcode.InvalidColumnReference,
   552  							"column %q is referenced by existing index %q", colToDrop.Name, idx.Name)
   553  					}
   554  				}
   555  			}
   556  
   557  			// Drop check constraints which reference the column.
   558  			// Note that foreign key constraints are dropped as part of dropping
   559  			// indexes on the column. In the future, when FKs no longer depend on
   560  			// indexes in the same way, FKs will have to be dropped separately here.
   561  			validChecks := n.tableDesc.Checks[:0]
   562  			for _, check := range n.tableDesc.AllActiveAndInactiveChecks() {
   563  				if used, err := check.UsesColumn(n.tableDesc.TableDesc(), colToDrop.ID); err != nil {
   564  					return err
   565  				} else if used {
   566  					if check.Validity == sqlbase.ConstraintValidity_Validating {
   567  						return pgerror.Newf(pgcode.ObjectNotInPrerequisiteState,
   568  							"referencing constraint %q in the middle of being added, try again later", check.Name)
   569  					}
   570  				} else {
   571  					validChecks = append(validChecks, check)
   572  				}
   573  			}
   574  
   575  			if len(validChecks) != len(n.tableDesc.Checks) {
   576  				n.tableDesc.Checks = validChecks
   577  				descriptorChanged = true
   578  			}
   579  
   580  			if err != nil {
   581  				return err
   582  			}
   583  			if err := params.p.removeColumnComment(params.ctx, n.tableDesc.ID, colToDrop.ID); err != nil {
   584  				return err
   585  			}
   586  
   587  			found := false
   588  			for i := range n.tableDesc.Columns {
   589  				if n.tableDesc.Columns[i].ID == colToDrop.ID {
   590  					n.tableDesc.AddColumnMutation(colToDrop, sqlbase.DescriptorMutation_DROP)
   591  					// Use [:i:i] to prevent reuse of existing slice, or outstanding refs
   592  					// to ColumnDescriptors may unexpectedly change.
   593  					n.tableDesc.Columns = append(n.tableDesc.Columns[:i:i], n.tableDesc.Columns[i+1:]...)
   594  					found = true
   595  					break
   596  				}
   597  			}
   598  			if !found {
   599  				return pgerror.Newf(pgcode.ObjectNotInPrerequisiteState,
   600  					"column %q in the middle of being added, try again later", t.Column)
   601  			}
   602  			if err := n.tableDesc.Validate(params.ctx, params.p.txn, params.ExecCfg().Codec); err != nil {
   603  				return err
   604  			}
   605  
   606  		case *tree.AlterTableDropConstraint:
   607  			info, err := n.tableDesc.GetConstraintInfo(params.ctx, nil, params.ExecCfg().Codec)
   608  			if err != nil {
   609  				return err
   610  			}
   611  			name := string(t.Constraint)
   612  			details, ok := info[name]
   613  			if !ok {
   614  				if t.IfExists {
   615  					continue
   616  				}
   617  				return pgerror.Newf(pgcode.UndefinedObject,
   618  					"constraint %q does not exist", t.Constraint)
   619  			}
   620  			if err := n.tableDesc.DropConstraint(
   621  				params.ctx,
   622  				name, details,
   623  				func(desc *sqlbase.MutableTableDescriptor, ref *sqlbase.ForeignKeyConstraint) error {
   624  					return params.p.removeFKBackReference(params.ctx, desc, ref)
   625  				}, params.ExecCfg().Settings); err != nil {
   626  				return err
   627  			}
   628  			descriptorChanged = true
   629  			if err := n.tableDesc.Validate(params.ctx, params.p.txn, params.ExecCfg().Codec); err != nil {
   630  				return err
   631  			}
   632  
   633  		case *tree.AlterTableValidateConstraint:
   634  			info, err := n.tableDesc.GetConstraintInfo(params.ctx, nil, params.ExecCfg().Codec)
   635  			if err != nil {
   636  				return err
   637  			}
   638  			name := string(t.Constraint)
   639  			constraint, ok := info[name]
   640  			if !ok {
   641  				return pgerror.Newf(pgcode.UndefinedObject,
   642  					"constraint %q does not exist", t.Constraint)
   643  			}
   644  			if !constraint.Unvalidated {
   645  				continue
   646  			}
   647  			switch constraint.Kind {
   648  			case sqlbase.ConstraintTypeCheck:
   649  				found := false
   650  				var ck *sqlbase.TableDescriptor_CheckConstraint
   651  				for _, c := range n.tableDesc.Checks {
   652  					// If the constraint is still being validated, don't allow VALIDATE CONSTRAINT to run
   653  					if c.Name == name && c.Validity != sqlbase.ConstraintValidity_Validating {
   654  						found = true
   655  						ck = c
   656  						break
   657  					}
   658  				}
   659  				if !found {
   660  					return pgerror.Newf(pgcode.ObjectNotInPrerequisiteState,
   661  						"constraint %q in the middle of being added, try again later", t.Constraint)
   662  				}
   663  				if err := validateCheckInTxn(
   664  					params.ctx, params.p.LeaseMgr(), params.EvalContext(), n.tableDesc, params.EvalContext().Txn, name,
   665  				); err != nil {
   666  					return err
   667  				}
   668  				ck.Validity = sqlbase.ConstraintValidity_Validated
   669  
   670  			case sqlbase.ConstraintTypeFK:
   671  				var foundFk *sqlbase.ForeignKeyConstraint
   672  				for i := range n.tableDesc.OutboundFKs {
   673  					fk := &n.tableDesc.OutboundFKs[i]
   674  					// If the constraint is still being validated, don't allow VALIDATE CONSTRAINT to run
   675  					if fk.Name == name && fk.Validity != sqlbase.ConstraintValidity_Validating {
   676  						foundFk = fk
   677  						break
   678  					}
   679  				}
   680  				if foundFk == nil {
   681  					return pgerror.Newf(pgcode.ObjectNotInPrerequisiteState,
   682  						"constraint %q in the middle of being added, try again later", t.Constraint)
   683  				}
   684  				if err := validateFkInTxn(
   685  					params.ctx, params.p.LeaseMgr(), params.EvalContext(), n.tableDesc, params.EvalContext().Txn, name,
   686  				); err != nil {
   687  					return err
   688  				}
   689  				foundFk.Validity = sqlbase.ConstraintValidity_Validated
   690  
   691  			default:
   692  				return pgerror.Newf(pgcode.WrongObjectType,
   693  					"constraint %q of relation %q is not a foreign key or check constraint",
   694  					tree.ErrString(&t.Constraint), tree.ErrString(n.n.Table))
   695  			}
   696  			descriptorChanged = true
   697  
   698  		case tree.ColumnMutationCmd:
   699  			// Column mutations
   700  			col, dropped, err := n.tableDesc.FindColumnByName(t.GetColumn())
   701  			if err != nil {
   702  				return err
   703  			}
   704  			if dropped {
   705  				return pgerror.Newf(pgcode.ObjectNotInPrerequisiteState,
   706  					"column %q in the middle of being dropped", t.GetColumn())
   707  			}
   708  			// Apply mutations to copy of column descriptor.
   709  			if err := applyColumnMutation(params.ctx, n.tableDesc, col, t, params, n.n.Cmds); err != nil {
   710  				return err
   711  			}
   712  			descriptorChanged = true
   713  
   714  		case *tree.AlterTablePartitionBy:
   715  			partitioning, err := CreatePartitioning(
   716  				params.ctx, params.p.ExecCfg().Settings,
   717  				params.EvalContext(),
   718  				n.tableDesc, &n.tableDesc.PrimaryIndex, t.PartitionBy)
   719  			if err != nil {
   720  				return err
   721  			}
   722  			descriptorChanged = !proto.Equal(
   723  				&n.tableDesc.PrimaryIndex.Partitioning,
   724  				&partitioning,
   725  			)
   726  			err = deleteRemovedPartitionZoneConfigs(
   727  				params.ctx, params.p.txn,
   728  				n.tableDesc.TableDesc(), &n.tableDesc.PrimaryIndex, &n.tableDesc.PrimaryIndex.Partitioning,
   729  				&partitioning, params.extendedEvalCtx.ExecCfg,
   730  			)
   731  			if err != nil {
   732  				return err
   733  			}
   734  			n.tableDesc.PrimaryIndex.Partitioning = partitioning
   735  
   736  		case *tree.AlterTableSetAudit:
   737  			var err error
   738  			descriptorChanged, err = params.p.setAuditMode(params.ctx, n.tableDesc.TableDesc(), t.Mode)
   739  			if err != nil {
   740  				return err
   741  			}
   742  
   743  		case *tree.AlterTableInjectStats:
   744  			sd, ok := n.statsData[i]
   745  			if !ok {
   746  				return errors.AssertionFailedf("missing stats data")
   747  			}
   748  			if !params.p.EvalContext().TxnImplicit {
   749  				return errors.New("cannot inject statistics in an explicit transaction")
   750  			}
   751  			if err := injectTableStats(params, n.tableDesc.TableDesc(), sd); err != nil {
   752  				return err
   753  			}
   754  
   755  		case *tree.AlterTableRenameColumn:
   756  			const allowRenameOfShardColumn = false
   757  			descChanged, err := params.p.renameColumn(params.ctx, n.tableDesc,
   758  				&t.Column, &t.NewName, allowRenameOfShardColumn)
   759  			if err != nil {
   760  				return err
   761  			}
   762  			descriptorChanged = descChanged
   763  
   764  		case *tree.AlterTableRenameConstraint:
   765  			info, err := n.tableDesc.GetConstraintInfo(params.ctx, nil, params.ExecCfg().Codec)
   766  			if err != nil {
   767  				return err
   768  			}
   769  			details, ok := info[string(t.Constraint)]
   770  			if !ok {
   771  				return pgerror.Newf(pgcode.UndefinedObject,
   772  					"constraint %q does not exist", tree.ErrString(&t.Constraint))
   773  			}
   774  			if t.Constraint == t.NewName {
   775  				// Nothing to do.
   776  				break
   777  			}
   778  
   779  			if _, ok := info[string(t.NewName)]; ok {
   780  				return pgerror.Newf(pgcode.DuplicateObject,
   781  					"duplicate constraint name: %q", tree.ErrString(&t.NewName))
   782  			}
   783  
   784  			if err := params.p.CheckPrivilege(params.ctx, n.tableDesc, privilege.CREATE); err != nil {
   785  				return err
   786  			}
   787  
   788  			depViewRenameError := func(objType string, refTableID sqlbase.ID) error {
   789  				return params.p.dependentViewRenameError(params.ctx,
   790  					objType, tree.ErrString(&t.NewName), n.tableDesc.ParentID, refTableID)
   791  			}
   792  
   793  			if err := n.tableDesc.RenameConstraint(
   794  				details, string(t.Constraint), string(t.NewName), depViewRenameError, func(desc *MutableTableDescriptor, ref *sqlbase.ForeignKeyConstraint, newName string) error {
   795  					return params.p.updateFKBackReferenceName(params.ctx, desc, ref, newName)
   796  				}); err != nil {
   797  				return err
   798  			}
   799  			descriptorChanged = true
   800  
   801  		default:
   802  			return errors.AssertionFailedf("unsupported alter command: %T", cmd)
   803  		}
   804  
   805  		// Allocate IDs now, so new IDs are available to subsequent commands
   806  		if err := n.tableDesc.AllocateIDs(); err != nil {
   807  			return err
   808  		}
   809  	}
   810  	// Were some changes made?
   811  	//
   812  	// This is only really needed for the unittests that add dummy mutations
   813  	// before calling ALTER TABLE commands. We do not want to apply those
   814  	// dummy mutations. Most tests trigger errors above
   815  	// this line, but tests that run redundant operations like dropping
   816  	// a column when it's already dropped will hit this condition and exit.
   817  	addedMutations := len(n.tableDesc.Mutations) > origNumMutations
   818  	if !addedMutations && !descriptorChanged {
   819  		return nil
   820  	}
   821  
   822  	mutationID := sqlbase.InvalidMutationID
   823  	if addedMutations {
   824  		mutationID = n.tableDesc.ClusterVersion.NextMutationID
   825  	}
   826  	if err := params.p.writeSchemaChange(
   827  		params.ctx, n.tableDesc, mutationID, tree.AsStringWithFQNames(n.n, params.Ann()),
   828  	); err != nil {
   829  		return err
   830  	}
   831  
   832  	// Record this table alteration in the event log. This is an auditable log
   833  	// event and is recorded in the same transaction as the table descriptor
   834  	// update.
   835  	return MakeEventLogger(params.extendedEvalCtx.ExecCfg).InsertEventRecord(
   836  		params.ctx,
   837  		params.p.txn,
   838  		EventLogAlterTable,
   839  		int32(n.tableDesc.ID),
   840  		int32(params.extendedEvalCtx.NodeID.SQLInstanceID()),
   841  		struct {
   842  			TableName           string
   843  			Statement           string
   844  			User                string
   845  			MutationID          uint32
   846  			CascadeDroppedViews []string
   847  		}{params.p.ResolvedName(n.n.Table).FQString(), n.n.String(),
   848  			params.SessionData().User, uint32(mutationID), droppedViews},
   849  	)
   850  }
   851  
   852  func (p *planner) setAuditMode(
   853  	ctx context.Context, desc *sqlbase.TableDescriptor, auditMode tree.AuditMode,
   854  ) (bool, error) {
   855  	// An auditing config change is itself auditable!
   856  	// We record the event even if the permission check below fails:
   857  	// auditing wants to know who tried to change the settings.
   858  	p.curPlan.auditEvents = append(p.curPlan.auditEvents,
   859  		auditEvent{desc: desc, writing: true})
   860  
   861  	// We require root for now. Later maybe use a different permission?
   862  	if err := p.RequireAdminRole(ctx, "change auditing settings on a table"); err != nil {
   863  		return false, err
   864  	}
   865  
   866  	telemetry.Inc(sqltelemetry.SchemaSetAuditModeCounter(auditMode.TelemetryName()))
   867  
   868  	return desc.SetAuditMode(auditMode)
   869  }
   870  
   871  func (n *alterTableNode) Next(runParams) (bool, error) { return false, nil }
   872  func (n *alterTableNode) Values() tree.Datums          { return tree.Datums{} }
   873  func (n *alterTableNode) Close(context.Context)        {}
   874  
   875  // addIndexMutationWithSpecificPrimaryKey adds an index mutation into the given table descriptor, but sets up
   876  // the index with ExtraColumnIDs from the given index, rather than the table's primary key.
   877  func addIndexMutationWithSpecificPrimaryKey(
   878  	table *sqlbase.MutableTableDescriptor,
   879  	toAdd *sqlbase.IndexDescriptor,
   880  	primary *sqlbase.IndexDescriptor,
   881  ) error {
   882  	// Reset the ID so that a call to AllocateIDs will set up the index.
   883  	toAdd.ID = 0
   884  	if err := table.AddIndexMutation(toAdd, sqlbase.DescriptorMutation_ADD); err != nil {
   885  		return err
   886  	}
   887  	if err := table.AllocateIDs(); err != nil {
   888  		return err
   889  	}
   890  	// Use the columns in the given primary index to construct this indexes ExtraColumnIDs list.
   891  	toAdd.ExtraColumnIDs = nil
   892  	for _, colID := range primary.ColumnIDs {
   893  		if !toAdd.ContainsColumnID(colID) {
   894  			toAdd.ExtraColumnIDs = append(toAdd.ExtraColumnIDs, colID)
   895  		}
   896  	}
   897  	return nil
   898  }
   899  
   900  // applyColumnMutation applies the mutation specified in `mut` to the given
   901  // columnDescriptor, and saves the containing table descriptor. If the column's
   902  // dependencies on sequences change, it updates them as well.
   903  func applyColumnMutation(
   904  	ctx context.Context,
   905  	tableDesc *sqlbase.MutableTableDescriptor,
   906  	col *sqlbase.ColumnDescriptor,
   907  	mut tree.ColumnMutationCmd,
   908  	params runParams,
   909  	cmds tree.AlterTableCmds,
   910  ) error {
   911  	switch t := mut.(type) {
   912  	case *tree.AlterTableAlterColumnType:
   913  		return AlterColumnType(ctx, tableDesc, col, t, params, cmds)
   914  
   915  	case *tree.AlterTableSetDefault:
   916  		if len(col.UsesSequenceIds) > 0 {
   917  			if err := params.p.removeSequenceDependencies(params.ctx, tableDesc, col); err != nil {
   918  				return err
   919  			}
   920  		}
   921  		if t.Default == nil {
   922  			col.DefaultExpr = nil
   923  		} else {
   924  			colDatumType := col.Type
   925  			expr, err := sqlbase.SanitizeVarFreeExpr(
   926  				params.ctx, t.Default, colDatumType, "DEFAULT", &params.p.semaCtx, true, /* allowImpure */
   927  			)
   928  			if err != nil {
   929  				return err
   930  			}
   931  			s := tree.Serialize(t.Default)
   932  			col.DefaultExpr = &s
   933  
   934  			// Add references to the sequence descriptors this column is now using.
   935  			changedSeqDescs, err := maybeAddSequenceDependencies(
   936  				params.ctx, params.p, tableDesc, col, expr, nil, /* backrefs */
   937  			)
   938  			if err != nil {
   939  				return err
   940  			}
   941  			for _, changedSeqDesc := range changedSeqDescs {
   942  				// TODO (lucy): Have more consistent/informative names for dependent jobs.
   943  				if err := params.p.writeSchemaChange(
   944  					params.ctx, changedSeqDesc, sqlbase.InvalidMutationID, "updating dependent sequence",
   945  				); err != nil {
   946  					return err
   947  				}
   948  			}
   949  		}
   950  
   951  	case *tree.AlterTableSetNotNull:
   952  		if !col.Nullable {
   953  			return nil
   954  		}
   955  		// See if there's already a mutation to add a not null constraint
   956  		for i := range tableDesc.Mutations {
   957  			if constraint := tableDesc.Mutations[i].GetConstraint(); constraint != nil &&
   958  				constraint.ConstraintType == sqlbase.ConstraintToUpdate_NOT_NULL &&
   959  				constraint.NotNullColumn == col.ID {
   960  				if tableDesc.Mutations[i].Direction == sqlbase.DescriptorMutation_ADD {
   961  					return pgerror.Newf(pgcode.ObjectNotInPrerequisiteState,
   962  						"constraint in the middle of being added")
   963  				}
   964  				return pgerror.Newf(pgcode.ObjectNotInPrerequisiteState,
   965  					"constraint in the middle of being dropped, try again later")
   966  			}
   967  		}
   968  
   969  		info, err := tableDesc.GetConstraintInfo(params.ctx, nil, params.ExecCfg().Codec)
   970  		if err != nil {
   971  			return err
   972  		}
   973  		inuseNames := make(map[string]struct{}, len(info))
   974  		for k := range info {
   975  			inuseNames[k] = struct{}{}
   976  		}
   977  		check := sqlbase.MakeNotNullCheckConstraint(col.Name, col.ID, inuseNames, sqlbase.ConstraintValidity_Validating)
   978  		tableDesc.AddNotNullMutation(check, sqlbase.DescriptorMutation_ADD)
   979  
   980  	case *tree.AlterTableDropNotNull:
   981  		if col.Nullable {
   982  			return nil
   983  		}
   984  
   985  		// Prevent a column in a primary key from becoming non-null.
   986  		if tableDesc.PrimaryIndex.ContainsColumnID(col.ID) {
   987  			return pgerror.Newf(pgcode.InvalidTableDefinition,
   988  				`column "%s" is in a primary index`, col.Name)
   989  		}
   990  
   991  		// See if there's already a mutation to add/drop a not null constraint.
   992  		for i := range tableDesc.Mutations {
   993  			if constraint := tableDesc.Mutations[i].GetConstraint(); constraint != nil &&
   994  				constraint.ConstraintType == sqlbase.ConstraintToUpdate_NOT_NULL &&
   995  				constraint.NotNullColumn == col.ID {
   996  				if tableDesc.Mutations[i].Direction == sqlbase.DescriptorMutation_ADD {
   997  					return pgerror.Newf(pgcode.ObjectNotInPrerequisiteState,
   998  						"constraint in the middle of being added, try again later")
   999  				}
  1000  				return pgerror.Newf(pgcode.ObjectNotInPrerequisiteState,
  1001  					"constraint in the middle of being dropped")
  1002  			}
  1003  		}
  1004  		info, err := tableDesc.GetConstraintInfo(params.ctx, nil, params.ExecCfg().Codec)
  1005  		if err != nil {
  1006  			return err
  1007  		}
  1008  		inuseNames := make(map[string]struct{}, len(info))
  1009  		for k := range info {
  1010  			inuseNames[k] = struct{}{}
  1011  		}
  1012  		col.Nullable = true
  1013  
  1014  		// Add a check constraint equivalent to the non-null constraint and drop
  1015  		// it in the schema changer.
  1016  		check := sqlbase.MakeNotNullCheckConstraint(col.Name, col.ID, inuseNames, sqlbase.ConstraintValidity_Dropping)
  1017  		tableDesc.Checks = append(tableDesc.Checks, check)
  1018  		tableDesc.AddNotNullMutation(check, sqlbase.DescriptorMutation_DROP)
  1019  
  1020  	case *tree.AlterTableDropStored:
  1021  		if !col.IsComputed() {
  1022  			return pgerror.Newf(pgcode.InvalidColumnDefinition,
  1023  				"column %q is not a computed column", col.Name)
  1024  		}
  1025  		col.ComputeExpr = nil
  1026  	}
  1027  	return nil
  1028  }
  1029  
  1030  func labeledRowValues(cols []sqlbase.ColumnDescriptor, values tree.Datums) string {
  1031  	var s bytes.Buffer
  1032  	for i := range cols {
  1033  		if i != 0 {
  1034  			s.WriteString(`, `)
  1035  		}
  1036  		s.WriteString(cols[i].Name)
  1037  		s.WriteString(`=`)
  1038  		s.WriteString(values[i].String())
  1039  	}
  1040  	return s.String()
  1041  }
  1042  
  1043  // injectTableStats implements the INJECT STATISTICS command, which deletes any
  1044  // existing statistics on the table and replaces them with the statistics in the
  1045  // given json object (in the same format as the result of SHOW STATISTICS USING
  1046  // JSON). This is useful for reproducing planning issues without importing the
  1047  // data.
  1048  func injectTableStats(
  1049  	params runParams, desc *sqlbase.TableDescriptor, statsExpr tree.TypedExpr,
  1050  ) error {
  1051  	val, err := statsExpr.Eval(params.EvalContext())
  1052  	if err != nil {
  1053  		return err
  1054  	}
  1055  	if val == tree.DNull {
  1056  		return pgerror.New(pgcode.Syntax,
  1057  			"statistics cannot be NULL")
  1058  	}
  1059  	jsonStr := val.(*tree.DJSON).JSON.String()
  1060  	var jsonStats []stats.JSONStatistic
  1061  	if err := gojson.Unmarshal([]byte(jsonStr), &jsonStats); err != nil {
  1062  		return err
  1063  	}
  1064  
  1065  	// First, delete all statistics for the table.
  1066  	if _ /* rows */, err := params.extendedEvalCtx.ExecCfg.InternalExecutor.Exec(
  1067  		params.ctx,
  1068  		"delete-stats",
  1069  		params.EvalContext().Txn,
  1070  		`DELETE FROM system.table_statistics WHERE "tableID" = $1`, desc.ID,
  1071  	); err != nil {
  1072  		return errors.Wrapf(err, "failed to delete old stats")
  1073  	}
  1074  
  1075  	// Insert each statistic.
  1076  	for i := range jsonStats {
  1077  		s := &jsonStats[i]
  1078  		h, err := s.GetHistogram(&params.p.semaCtx, params.EvalContext())
  1079  		if err != nil {
  1080  			return err
  1081  		}
  1082  		// histogram will be passed to the INSERT statement; we want it to be a
  1083  		// nil interface{} if we don't generate a histogram.
  1084  		var histogram interface{}
  1085  		if h != nil {
  1086  			histogram, err = protoutil.Marshal(h)
  1087  			if err != nil {
  1088  				return err
  1089  			}
  1090  		}
  1091  
  1092  		columnIDs := tree.NewDArray(types.Int)
  1093  		for _, colName := range s.Columns {
  1094  			colDesc, _, err := desc.FindColumnByName(tree.Name(colName))
  1095  			if err != nil {
  1096  				return err
  1097  			}
  1098  			if err := columnIDs.Append(tree.NewDInt(tree.DInt(colDesc.ID))); err != nil {
  1099  				return err
  1100  			}
  1101  		}
  1102  		var name interface{}
  1103  		if s.Name != "" {
  1104  			name = s.Name
  1105  		}
  1106  		if _ /* rows */, err := params.extendedEvalCtx.ExecCfg.InternalExecutor.Exec(
  1107  			params.ctx,
  1108  			"insert-stats",
  1109  			params.EvalContext().Txn,
  1110  			`INSERT INTO system.table_statistics (
  1111  					"tableID",
  1112  					"name",
  1113  					"columnIDs",
  1114  					"createdAt",
  1115  					"rowCount",
  1116  					"distinctCount",
  1117  					"nullCount",
  1118  					histogram
  1119  				) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`,
  1120  			desc.ID,
  1121  			name,
  1122  			columnIDs,
  1123  			s.CreatedAt,
  1124  			s.RowCount,
  1125  			s.DistinctCount,
  1126  			s.NullCount,
  1127  			histogram,
  1128  		); err != nil {
  1129  			return errors.Wrapf(err, "failed to insert stats")
  1130  		}
  1131  	}
  1132  
  1133  	// Invalidate the local cache synchronously; this guarantees that the next
  1134  	// statement in the same session won't use a stale cache (whereas the gossip
  1135  	// update is handled asynchronously).
  1136  	params.extendedEvalCtx.ExecCfg.TableStatsCache.InvalidateTableStats(params.ctx, desc.ID)
  1137  
  1138  	if g, ok := params.extendedEvalCtx.ExecCfg.Gossip.Optional(47925); ok {
  1139  		return stats.GossipTableStatAdded(g, desc.ID)
  1140  	}
  1141  	return nil
  1142  }
  1143  
  1144  func (p *planner) removeColumnComment(
  1145  	ctx context.Context, tableID sqlbase.ID, columnID sqlbase.ColumnID,
  1146  ) error {
  1147  	_, err := p.ExtendedEvalContext().ExecCfg.InternalExecutor.ExecEx(
  1148  		ctx,
  1149  		"delete-column-comment",
  1150  		p.txn,
  1151  		sqlbase.InternalExecutorSessionDataOverride{User: security.RootUser},
  1152  		"DELETE FROM system.comments WHERE type=$1 AND object_id=$2 AND sub_id=$3",
  1153  		keys.ColumnCommentType,
  1154  		tableID,
  1155  		columnID)
  1156  
  1157  	return err
  1158  }
  1159  
  1160  // updateFKBackReferenceName updates the name of a foreign key reference on
  1161  // the referenced table descriptor.
  1162  // TODO (lucy): This method is meant to be analogous to removeFKBackReference,
  1163  // in that it only updates the backreference, but we should refactor/unify all
  1164  // the places where we update both FKs and their backreferences, so that callers
  1165  // don't have to manually take care of updating both table descriptors.
  1166  func (p *planner) updateFKBackReferenceName(
  1167  	ctx context.Context,
  1168  	tableDesc *sqlbase.MutableTableDescriptor,
  1169  	ref *sqlbase.ForeignKeyConstraint,
  1170  	newName string,
  1171  ) error {
  1172  	var referencedTableDesc *sqlbase.MutableTableDescriptor
  1173  	// We don't want to lookup/edit a second copy of the same table.
  1174  	if tableDesc.ID == ref.ReferencedTableID {
  1175  		referencedTableDesc = tableDesc
  1176  	} else {
  1177  		lookup, err := p.Tables().GetMutableTableVersionByID(ctx, ref.ReferencedTableID, p.txn)
  1178  		if err != nil {
  1179  			return errors.Errorf("error resolving referenced table ID %d: %v", ref.ReferencedTableID, err)
  1180  		}
  1181  		referencedTableDesc = lookup
  1182  	}
  1183  	if referencedTableDesc.Dropped() {
  1184  		// The referenced table is being dropped. No need to modify it further.
  1185  		return nil
  1186  	}
  1187  	for i := range referencedTableDesc.InboundFKs {
  1188  		backref := &referencedTableDesc.InboundFKs[i]
  1189  		if backref.Name == ref.Name && backref.OriginTableID == tableDesc.ID {
  1190  			backref.Name = newName
  1191  			// TODO (lucy): Have more consistent/informative names for dependent jobs.
  1192  			return p.writeSchemaChange(
  1193  				ctx, referencedTableDesc, sqlbase.InvalidMutationID, "updating referenced table",
  1194  			)
  1195  		}
  1196  	}
  1197  	return errors.Errorf("missing backreference for foreign key %s", ref.Name)
  1198  }