diff --git a/pkg/ccl/backupccl/testdata/backup-restore/user-defined-functions-in-checks b/pkg/ccl/backupccl/testdata/backup-restore/user-defined-functions-in-checks index fbffe9f85d7c..a4b8e91acbcd 100644 --- a/pkg/ccl/backupccl/testdata/backup-restore/user-defined-functions-in-checks +++ b/pkg/ccl/backupccl/testdata/backup-restore/user-defined-functions-in-checks @@ -111,9 +111,14 @@ USE db1 # Make sure function ids in CHECK constraint are rewritten. query-sql -SELECT create_statement FROM [SHOW CREATE TABLE sc1.f1] +SELECT create_statement FROM [SHOW CREATE TABLE sc1.t1] ---- -pq: relation "sc1.f1" does not exist +CREATE TABLE sc1.t1 ( + a INT8 NOT NULL, + b INT8 NULL, + CONSTRAINT t1_pkey PRIMARY KEY (a ASC), + CONSTRAINT check_b CHECK (sc1.f1(b) > 1:::INT8) +) # Make sure that CHECK constraint still applies correctly query-sql diff --git a/pkg/ccl/backupccl/testdata/backup-restore/user-defined-functions-in-defaults b/pkg/ccl/backupccl/testdata/backup-restore/user-defined-functions-in-defaults new file mode 100644 index 000000000000..b5a61b86e18e --- /dev/null +++ b/pkg/ccl/backupccl/testdata/backup-restore/user-defined-functions-in-defaults @@ -0,0 +1,235 @@ +# Test backing up and restoring a database with user defined functions. +new-cluster name=s +---- + +exec-sql +CREATE DATABASE db1; +USE db1; +CREATE SCHEMA sc1; +CREATE FUNCTION sc1.f1() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +CREATE TABLE sc1.t1(a INT PRIMARY KEY, b INT DEFAULT sc1.f1()); +---- + +exec-sql +BACKUP DATABASE db1 INTO 'nodelocal://0/test/' +---- + +query-sql +WITH descs AS ( + SHOW BACKUP LATEST IN 'nodelocal://0/test/' +) +SELECT database_name, parent_schema_name, object_name, object_type, is_full_cluster FROM descs +---- + db1 database false +db1 public schema false +db1 sc1 schema false +db1 sc1 f1 function false +db1 sc1 t1 table false + +exec-sql +RESTORE DATABASE db1 FROM LATEST IN 'nodelocal://0/test/' WITH new_db_name = db1_new +---- + +exec-sql +USE db1_new +---- + +# Make sure function ids in DEFAULT are rewritten. +query-sql +SELECT create_statement FROM [SHOW CREATE TABLE sc1.t1] +---- +CREATE TABLE sc1.t1 ( + a INT8 NOT NULL, + b INT8 NULL DEFAULT sc1.f1(), + CONSTRAINT t1_pkey PRIMARY KEY (a ASC) +) + +# Make sure that the DEFAULT expression still works. +query-sql +INSERT INTO sc1.t1 VALUES (1), (2); +---- + +query-sql +SELECT * FROM sc1.t1 ORDER BY a; +---- +1 1 +2 1 + +# Make sure that depenency IDs are rewritten by checking DROP FUNCTION errors. +# Note that technically this only tests forward-reference IDs in depended-on +# objects are rewritten. But since we have cross-references validation, so this +# also means back-references in UDF descriptor are good. +query-sql +DROP FUNCTION sc1.f1; +---- +pq: cannot drop function "f1" because other objects ([db1_new.sc1.t1]) still depend on it + +# Test backing up and restoring a full cluster with user defined function. +new-cluster name=s1 +---- + +exec-sql cluster=s1 +CREATE DATABASE db1; +USE db1; +CREATE SCHEMA sc1; +CREATE FUNCTION sc1.f1() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +CREATE TABLE sc1.t1(a INT PRIMARY KEY, b INT DEFAULT sc1.f1()); +---- + +exec-sql +BACKUP INTO 'nodelocal://0/test/' +---- + +query-sql +WITH descs AS ( + SHOW BACKUP LATEST IN 'nodelocal://0/test/' +) +SELECT + database_name, parent_schema_name, object_name, object_type, is_full_cluster +FROM + descs +WHERE + database_name = 'db1' +---- +db1 public schema true +db1 sc1 schema true +db1 sc1 f1 function true +db1 sc1 t1 table true + +# Start a new cluster with the same IO dir. +new-cluster name=s2 share-io-dir=s1 +---- + +# Restore into the new cluster. +exec-sql cluster=s2 +RESTORE FROM LATEST IN 'nodelocal://0/test/' +---- + +exec-sql +USE db1 +---- + +# Make sure function ids in DEFAULT are rewritten. +query-sql +SELECT create_statement FROM [SHOW CREATE TABLE sc1.t1] +---- +CREATE TABLE sc1.t1 ( + a INT8 NOT NULL, + b INT8 NULL DEFAULT sc1.f1(), + CONSTRAINT t1_pkey PRIMARY KEY (a ASC) +) + +# Make sure that the DEFAULT expression still works. +query-sql +INSERT INTO sc1.t1 VALUES (1), (2); +---- + +query-sql +SELECT * FROM sc1.t1 ORDER BY a; +---- +1 1 +2 1 + +# Make sure that depenency IDs are rewritten by checking DROP FUNCTION errors. +# Note that technically this only tests forward-reference IDs in depended-on +# objects are rewritten. But since we have cross-references validation, so this +# also means back-references in UDF descriptor are good. +query-sql +DROP FUNCTION sc1.f1; +---- +pq: cannot drop function "f1" because other objects ([db1.sc1.t1]) still depend on it + +# Make sure that backup and restore individual tables referencing UDFs able to +# drop DEFAULT. +new-cluster name=s3 +---- + +exec-sql cluster=s3 +CREATE DATABASE db1; +CREATE DATABASE db2; +CREATE DATABASE db3; +USE db1; +CREATE SCHEMA sc1; +CREATE FUNCTION sc1.f1() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +CREATE TABLE sc1.t1(a INT PRIMARY KEY, b INT DEFAULT sc1.f1()); +---- + +exec-sql +BACKUP DATABASE db1 INTO 'nodelocal://0/test/' +---- + +query-sql +WITH descs AS ( + SHOW BACKUP LATEST IN 'nodelocal://0/test/' +) +SELECT database_name, parent_schema_name, object_name, object_type, is_full_cluster FROM descs +---- + db1 database false +db1 public schema false +db1 sc1 schema false +db1 sc1 f1 function false +db1 sc1 t1 table false + +exec-sql +RESTORE TABLE sc1.t1 FROM LATEST IN 'nodelocal://0/test/' WITH into_db = 'db2'; +---- +pq: cannot restore table "t1" without referenced function 114 (or "skip_missing_udfs" option) + +exec-sql +RESTORE TABLE sc1.t1 FROM LATEST IN 'nodelocal://0/test/' WITH into_db = 'db2', skip_missing_udfs; +---- + +exec-sql +USE db2 +---- + +# Make sure DEFAULT is dropped. +query-sql +SELECT create_statement FROM [SHOW CREATE TABLE sc1.t1] +---- +CREATE TABLE sc1.t1 ( + a INT8 NOT NULL, + b INT8 NULL, + CONSTRAINT t1_pkey PRIMARY KEY (a ASC) +) + +exec-sql +USE db1 +---- + +exec-sql +BACKUP TABLE sc1.t1 INTO 'nodelocal://0/test/' +---- + +query-sql +WITH descs AS ( + SHOW BACKUP LATEST IN 'nodelocal://0/test/' +) +SELECT database_name, parent_schema_name, object_name, object_type, is_full_cluster FROM descs +---- + db1 database false +db1 sc1 schema false +db1 sc1 t1 table false + +exec-sql +RESTORE TABLE sc1.t1 FROM LATEST IN 'nodelocal://0/test/' WITH into_db = 'db3'; +---- +pq: cannot restore table "t1" without referenced function 114 (or "skip_missing_udfs" option) + +exec-sql +RESTORE TABLE sc1.t1 FROM LATEST IN 'nodelocal://0/test/' WITH into_db = 'db3', skip_missing_udfs; +---- + +exec-sql +USE db3 +---- + +# Make sure DEFAULT is dropped. +query-sql +SELECT create_statement FROM [SHOW CREATE TABLE sc1.t1] +---- +CREATE TABLE sc1.t1 ( + a INT8 NOT NULL, + b INT8 NULL, + CONSTRAINT t1_pkey PRIMARY KEY (a ASC) +) diff --git a/pkg/ccl/changefeedccl/avro_test.go b/pkg/ccl/changefeedccl/avro_test.go index 34b52eb7b3e1..4ae6d9ea1df8 100644 --- a/pkg/ccl/changefeedccl/avro_test.go +++ b/pkg/ccl/changefeedccl/avro_test.go @@ -177,7 +177,7 @@ func avroFieldMetadataToColDesc( def := parsed.AST.(*tree.AlterTable).Cmds[0].(*tree.AlterTableAddColumn).ColumnDef ctx := context.Background() semaCtx := makeTestSemaCtx() - cdd, err := tabledesc.MakeColumnDefDescs(ctx, def, &semaCtx, evalCtx) + cdd, err := tabledesc.MakeColumnDefDescs(ctx, def, &semaCtx, evalCtx, tree.ColumnDefaultExprInAddColumn) if err != nil { return nil, err } diff --git a/pkg/ccl/changefeedccl/cdceval/cdc_prev.go b/pkg/ccl/changefeedccl/cdceval/cdc_prev.go index ef7391114478..15b223622927 100644 --- a/pkg/ccl/changefeedccl/cdceval/cdc_prev.go +++ b/pkg/ccl/changefeedccl/cdceval/cdc_prev.go @@ -232,6 +232,14 @@ func (c *prevCol) NumOwnsSequences() int { return 0 } +func (c *prevCol) NumUsesFunctions() int { + return 0 +} + +func (c *prevCol) GetUsesFunctionID(ordinal int) descpb.ID { + return 0 +} + func (c *prevCol) GetOwnsSequenceID(ownsSequenceOrdinal int) descpb.ID { return 0 } diff --git a/pkg/ccl/logictestccl/tests/3node-tenant/generated_test.go b/pkg/ccl/logictestccl/tests/3node-tenant/generated_test.go index 140d03ef4d73..e6b03acb43c0 100644 --- a/pkg/ccl/logictestccl/tests/3node-tenant/generated_test.go +++ b/pkg/ccl/logictestccl/tests/3node-tenant/generated_test.go @@ -2026,6 +2026,13 @@ func TestTenantLogic_udf( runLogicTest(t, "udf") } +func TestTenantLogic_udf_in_column_defaults( + t *testing.T, +) { + defer leaktest.AfterTest(t)() + runLogicTest(t, "udf_in_column_defaults") +} + func TestTenantLogic_udf_in_constraints( t *testing.T, ) { diff --git a/pkg/ccl/schemachangerccl/backup_base_generated_test.go b/pkg/ccl/schemachangerccl/backup_base_generated_test.go index f743de428bbf..b39a909593bb 100644 --- a/pkg/ccl/schemachangerccl/backup_base_generated_test.go +++ b/pkg/ccl/schemachangerccl/backup_base_generated_test.go @@ -153,6 +153,11 @@ func TestBackup_base_drop_column_with_partial_index(t *testing.T) { defer log.Scope(t).Close(t) sctest.Backup(t, "pkg/sql/schemachanger/testdata/end_to_end/drop_column_with_partial_index", newCluster) } +func TestBackup_base_drop_column_with_udf_default(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + sctest.Backup(t, "pkg/sql/schemachanger/testdata/end_to_end/drop_column_with_udf_default", newCluster) +} func TestBackup_base_drop_function(t *testing.T) { defer leaktest.AfterTest(t)() defer log.Scope(t).Close(t) @@ -193,3 +198,8 @@ func TestBackup_base_drop_table(t *testing.T) { defer log.Scope(t).Close(t) sctest.Backup(t, "pkg/sql/schemachanger/testdata/end_to_end/drop_table", newCluster) } +func TestBackup_base_drop_table_udf_default(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + sctest.Backup(t, "pkg/sql/schemachanger/testdata/end_to_end/drop_table_udf_default", newCluster) +} diff --git a/pkg/ccl/schemachangerccl/backup_base_mixed_generated_test.go b/pkg/ccl/schemachangerccl/backup_base_mixed_generated_test.go index c3c72947d64b..04e6ca5171df 100644 --- a/pkg/ccl/schemachangerccl/backup_base_mixed_generated_test.go +++ b/pkg/ccl/schemachangerccl/backup_base_mixed_generated_test.go @@ -153,6 +153,11 @@ func TestBackupMixedVersionElements_base_drop_column_with_partial_index(t *testi defer log.Scope(t).Close(t) sctest.BackupMixedVersionElements(t, "pkg/sql/schemachanger/testdata/end_to_end/drop_column_with_partial_index", newClusterMixed) } +func TestBackupMixedVersionElements_base_drop_column_with_udf_default(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + sctest.BackupMixedVersionElements(t, "pkg/sql/schemachanger/testdata/end_to_end/drop_column_with_udf_default", newClusterMixed) +} func TestBackupMixedVersionElements_base_drop_function(t *testing.T) { defer leaktest.AfterTest(t)() defer log.Scope(t).Close(t) @@ -193,3 +198,8 @@ func TestBackupMixedVersionElements_base_drop_table(t *testing.T) { defer log.Scope(t).Close(t) sctest.BackupMixedVersionElements(t, "pkg/sql/schemachanger/testdata/end_to_end/drop_table", newClusterMixed) } +func TestBackupMixedVersionElements_base_drop_table_udf_default(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + sctest.BackupMixedVersionElements(t, "pkg/sql/schemachanger/testdata/end_to_end/drop_table_udf_default", newClusterMixed) +} diff --git a/pkg/sql/add_column.go b/pkg/sql/add_column.go index 4888d9125966..e978581aefcb 100644 --- a/pkg/sql/add_column.go +++ b/pkg/sql/add_column.go @@ -72,7 +72,7 @@ func (p *planner) addColumnImpl( } d = newDef - cdd, err := tabledesc.MakeColumnDefDescs(params.ctx, d, ¶ms.p.semaCtx, params.EvalContext()) + cdd, err := tabledesc.MakeColumnDefDescs(params.ctx, d, ¶ms.p.semaCtx, params.EvalContext(), tree.ColumnDefaultExprInAddColumn) if err != nil { return err } diff --git a/pkg/sql/alter_table.go b/pkg/sql/alter_table.go index 0aa11a377e0c..ec2072d5a4f2 100644 --- a/pkg/sql/alter_table.go +++ b/pkg/sql/alter_table.go @@ -910,7 +910,7 @@ func applyColumnMutation( col, t.Default, &col.ColumnDesc().DefaultExpr, - tree.ColumnDefaultExpr, + tree.ColumnDefaultExprInSetDefault, ); err != nil { return err } @@ -1086,7 +1086,11 @@ func updateNonComputedColExpr( *exprField = &s } - if err := updateSequenceDependencies(params, tab, col); err != nil { + if err := updateSequenceDependencies(params, tab, col, op); err != nil { + return err + } + + if err := params.p.maybeUpdateFunctionReferencesForColumn(params.ctx, tab, col.ColumnDesc()); err != nil { return err } @@ -1107,6 +1111,12 @@ func sanitizeColumnExpression( if err := funcdesc.MaybeFailOnUDFUsage(typedExpr, context, p.EvalContext().Settings.Version.ActiveVersionOrEmpty(p.ctx)); err != nil { return nil, "", err } + + typedExpr, err = schemaexpr.MaybeReplaceUDFNameWithOIDReferenceInTypedExpr(typedExpr) + if err != nil { + return nil, "", err + } + s := tree.Serialize(typedExpr) return typedExpr, s, nil } @@ -1114,7 +1124,10 @@ func sanitizeColumnExpression( // updateSequenceDependencies checks for sequence dependencies on the provided // DEFAULT and ON UPDATE expressions and adds any dependencies to the tableDesc. func updateSequenceDependencies( - params runParams, tableDesc *tabledesc.Mutable, colDesc catalog.Column, + params runParams, + tableDesc *tabledesc.Mutable, + colDesc catalog.Column, + defaultExprCtx tree.SchemaExprContext, ) error { var seqDescsToUpdate []*tabledesc.Mutable mergeNewSeqDescs := func(toAdd []*tabledesc.Mutable) { @@ -1139,7 +1152,7 @@ func updateSequenceDependencies( }{ { colExprKind: tabledesc.DefaultExpr, - colExprContext: tree.ColumnDefaultExpr, + colExprContext: defaultExprCtx, exists: colDesc.HasDefault, get: colDesc.GetDefaultExpr, }, @@ -1577,6 +1590,12 @@ func dropColumnImpl( } } + if colToDrop.NumUsesFunctions() > 0 { + if err := params.p.removeColumnBackReferenceInFunctions(params.ctx, tableDesc, colToDrop.ColumnDesc()); err != nil { + return nil, err + } + } + // You can't remove a column that owns a sequence that is depended on // by another column if err := params.p.canRemoveAllColumnOwnedSequences(params.ctx, tableDesc, colToDrop, t.DropBehavior); err != nil { diff --git a/pkg/sql/catalog/descpb/structured.proto b/pkg/sql/catalog/descpb/structured.proto index 8a1e0d376344..20acfc7a5465 100644 --- a/pkg/sql/catalog/descpb/structured.proto +++ b/pkg/sql/catalog/descpb/structured.proto @@ -176,6 +176,8 @@ message ColumnDescriptor { repeated uint32 uses_sequence_ids = 10 [(gogoproto.casttype) = "ID"]; // Ids of sequences that the column owns. repeated uint32 owns_sequence_ids = 12 [(gogoproto.casttype) = "ID"]; + // Ids of functions used in the column's DEFAULT and ON UPDATE expressions. + repeated uint32 uses_function_ids = 21 [(gogoproto.casttype) = "ID"]; // Expression to use to compute the value of this column if this is a // computed column. Note that it is not correct to use ComputeExpr // as output to display to a user. User defined types within ComputeExpr @@ -202,6 +204,8 @@ message ColumnDescriptor { // SystemColumnKind represents what kind of system column this column // descriptor represents, if any. optional cockroach.sql.catalog.catpb.SystemColumnKind system_column_kind = 15 [(gogoproto.nullable) = false]; + + // Next id: 22 } // ColumnFamilyDescriptor is set of columns stored together in one kv entry. diff --git a/pkg/sql/catalog/descriptor.go b/pkg/sql/catalog/descriptor.go index d2d20eb71030..30ad9c392f1b 100644 --- a/pkg/sql/catalog/descriptor.go +++ b/pkg/sql/catalog/descriptor.go @@ -588,6 +588,14 @@ type TableDescriptor interface { cstID descpb.ConstraintID, ) (DescriptorIDSet, error) + // GetAllReferencedFunctionIDsInColumnExprs returns descriptor IDs of all user + // defined functions referenced by expressions in this column. + // Note: it extracts ids from expression strings, not from the UsesFunctionIDs + // field of column descriptors. + GetAllReferencedFunctionIDsInColumnExprs( + colID descpb.ColumnID, + ) (DescriptorIDSet, error) + // ForeachDependedOnBy runs a function on all indexes, including those being // added in the mutations. ForeachDependedOnBy(f func(dep *descpb.TableDescriptor_Reference) error) error diff --git a/pkg/sql/catalog/funcdesc/func_desc.go b/pkg/sql/catalog/funcdesc/func_desc.go index 5062a81b5787..b5ba0938309f 100644 --- a/pkg/sql/catalog/funcdesc/func_desc.go +++ b/pkg/sql/catalog/funcdesc/func_desc.go @@ -326,12 +326,20 @@ func (desc *immutable) validateInboundTableRef( var foundInTable bool for _, colID := range by.ColumnIDs { - if catalog.FindColumnByID(backRefTbl, colID) == nil { + col := catalog.FindColumnByID(backRefTbl, colID) + if col == nil { return errors.AssertionFailedf("depended-on-by relation %q (%d) does not have a column with ID %d", backRefTbl.GetName(), by.ID, colID) } - // TODO(chengxiong): add logic to validate reference in column expressions - // when UDF usage is allowed in columns. + fnIDs := catalog.MakeDescriptorIDSet(col.ColumnDesc().UsesFunctionIds...) + if fnIDs.Contains(desc.GetID()) { + foundInTable = true + continue + } + return errors.AssertionFailedf( + "column %d in depended-on-by relation %q (%d) does not have reference to function %q (%d)", + col.GetID(), backRefTbl.GetName(), backRefTbl.GetID(), desc.GetName(), desc.GetID(), + ) } for _, idxID := range by.IndexIDs { @@ -529,11 +537,12 @@ func (desc *Mutable) SetParentSchemaID(id descpb.ID) { desc.ParentSchemaID = id } +// AddConstraintReference adds back reference to a constraint to the function. func (desc *Mutable) AddConstraintReference(id descpb.ID, constraintID descpb.ConstraintID) error { for _, dep := range desc.DependsOn { if dep == id { - return errors.AssertionFailedf( - "Cannot add dependency from descriptor %d to function %s (%d) because there will be a dependency cycle", id, desc.GetName(), desc.GetID(), + return errors.Errorf( + "cannot add dependency from descriptor %d to function %s (%d) because there will be a dependency cycle", id, desc.GetName(), desc.GetID(), ) } } @@ -558,6 +567,8 @@ func (desc *Mutable) AddConstraintReference(id descpb.ID, constraintID descpb.Co return nil } +// RemoveConstraintReference removes back reference to a constraint from the +// function. func (desc *Mutable) RemoveConstraintReference(id descpb.ID, constraintID descpb.ConstraintID) { for i := range desc.DependedOnBy { if desc.DependedOnBy[i].ID == id { @@ -570,6 +581,49 @@ func (desc *Mutable) RemoveConstraintReference(id descpb.ID, constraintID descpb } } +// AddColumnReference adds back reference to a column to the function. +func (desc *Mutable) AddColumnReference(id descpb.ID, colID descpb.ColumnID) error { + for _, dep := range desc.DependsOn { + if dep == id { + return errors.Errorf( + "cannot add dependency from descriptor %d to function %s (%d) because there will be a dependency cycle", id, desc.GetName(), desc.GetID(), + ) + } + } + for i := range desc.DependedOnBy { + if desc.DependedOnBy[i].ID == id { + ids := catalog.MakeTableColSet(desc.DependedOnBy[i].ColumnIDs...) + ids.Add(colID) + desc.DependedOnBy[i].ColumnIDs = ids.Ordered() + return nil + } + } + desc.DependedOnBy = append( + desc.DependedOnBy, + descpb.FunctionDescriptor_Reference{ + ID: id, + ColumnIDs: []descpb.ColumnID{colID}, + }, + ) + sort.Slice(desc.DependedOnBy, func(i, j int) bool { + return desc.DependedOnBy[i].ID < desc.DependedOnBy[j].ID + }) + return nil +} + +// RemoveColumnReference removes back reference to a column from the function. +func (desc *Mutable) RemoveColumnReference(id descpb.ID, colID descpb.ColumnID) { + for i := range desc.DependedOnBy { + if desc.DependedOnBy[i].ID == id { + ids := catalog.MakeTableColSet(desc.DependedOnBy[i].ColumnIDs...) + ids.Remove(colID) + desc.DependedOnBy[i].ColumnIDs = ids.Ordered() + desc.maybeRemoveTableReference(id) + return + } + } +} + // maybeRemoveTableReference removes a table's references from the function if // the column, index and constraint references are all empty. This function is // only used internally when removing an individual column, index or constraint diff --git a/pkg/sql/catalog/funcdesc/func_desc_test.go b/pkg/sql/catalog/funcdesc/func_desc_test.go index c41642ad051b..1f3eae511033 100644 --- a/pkg/sql/catalog/funcdesc/func_desc_test.go +++ b/pkg/sql/catalog/funcdesc/func_desc_test.go @@ -52,8 +52,10 @@ func TestValidateFuncDesc(t *testing.T) { tableWithFuncForwardRefID = dbID + 6 typeWithFuncRefID = dbID + 7 viewID = dbID + 8 - tableWithBadConstraintID = dbID + 9 - tableWithGoodConstraintID = dbID + 10 + tableWithBadConstraint = dbID + 9 + tableWithGoodConstraint = dbID + 10 + tableWithBadColumn = dbID + 11 + tableWIthGoodColumn = dbID + 12 ) funcDescID := descpb.ID(bootstrap.TestingUserDescID(0)) @@ -104,8 +106,8 @@ func TestValidateFuncDesc(t *testing.T) { ViewQuery: "some query", }).BuildImmutable()) cb.UpsertDescriptor(tabledesc.NewBuilder(&descpb.TableDescriptor{ - ID: tableWithBadConstraintID, - Name: "tbl", + ID: tableWithBadConstraint, + Name: "tbl_bad_constraint", Checks: []*descpb.TableDescriptor_CheckConstraint{ { Expr: "[FUNCTION 100101] ()", @@ -114,8 +116,8 @@ func TestValidateFuncDesc(t *testing.T) { }, }).BuildImmutable()) cb.UpsertDescriptor(tabledesc.NewBuilder(&descpb.TableDescriptor{ - ID: tableWithGoodConstraintID, - Name: "v", + ID: tableWithGoodConstraint, + Name: "tbl_good_constraint", Checks: []*descpb.TableDescriptor_CheckConstraint{ { Expr: "[FUNCTION 100100] ()", @@ -123,6 +125,26 @@ func TestValidateFuncDesc(t *testing.T) { }, }, }).BuildImmutable()) + cb.UpsertDescriptor(tabledesc.NewBuilder(&descpb.TableDescriptor{ + ID: tableWithBadColumn, + Name: "tbl_bad_col", + Columns: []descpb.ColumnDescriptor{ + { + ID: 1, + UsesFunctionIds: []descpb.ID{101}, + }, + }, + }).BuildImmutable()) + cb.UpsertDescriptor(tabledesc.NewBuilder(&descpb.TableDescriptor{ + ID: tableWIthGoodColumn, + Name: "tbl_good_col", + Columns: []descpb.ColumnDescriptor{ + { + ID: 1, + UsesFunctionIds: []descpb.ID{100}, + }, + }, + }).BuildImmutable()) defaultPrivileges := catpb.NewBasePrivilegeDescriptor(username.RootUserName()) invalidPrivileges := catpb.NewBasePrivilegeDescriptor(username.RootUserName()) @@ -508,7 +530,7 @@ func TestValidateFuncDesc(t *testing.T) { }, }, { - `constraint 1 in depended-on-by relation "tbl" (1009) does not have reference to function "f" (100)`, + `constraint 1 in depended-on-by relation "tbl_bad_constraint" (1009) does not have reference to function "f" (100)`, descpb.FunctionDescriptor{ Name: "f", ID: funcDescID, @@ -527,7 +549,7 @@ func TestValidateFuncDesc(t *testing.T) { LeakProof: true, Volatility: catpb.Function_IMMUTABLE, DependedOnBy: []descpb.FunctionDescriptor_Reference{ - {ID: tableWithBadConstraintID, ConstraintIDs: []descpb.ConstraintID{1}}, + {ID: tableWithBadConstraint, ConstraintIDs: []descpb.ConstraintID{1}}, }, DependsOn: []descpb.ID{tableWithFuncBackRefID}, DependsOnTypes: []descpb.ID{typeWithFuncRefID}, @@ -553,7 +575,45 @@ func TestValidateFuncDesc(t *testing.T) { LeakProof: true, Volatility: catpb.Function_IMMUTABLE, DependedOnBy: []descpb.FunctionDescriptor_Reference{ - {ID: tableWithGoodConstraintID, ConstraintIDs: []descpb.ConstraintID{1}}, + {ID: tableWithGoodConstraint, ConstraintIDs: []descpb.ConstraintID{1}}, + }, + DependsOn: []descpb.ID{tableWithFuncBackRefID}, + DependsOnTypes: []descpb.ID{typeWithFuncRefID}, + }, + }, + { + `column 1 in depended-on-by relation "tbl_bad_col" (1011) does not have reference to function "f" (100)`, + descpb.FunctionDescriptor{ + Name: "f", + ID: funcDescID, + ParentID: dbID, + ParentSchemaID: schemaWithFuncRefID, + Privileges: defaultPrivileges, + ReturnType: descpb.FunctionDescriptor_ReturnType{ + Type: types.Int, + }, + Volatility: catpb.Function_IMMUTABLE, + DependedOnBy: []descpb.FunctionDescriptor_Reference{ + {ID: tableWithBadColumn, ColumnIDs: []descpb.ColumnID{1}}, + }, + DependsOn: []descpb.ID{tableWithFuncBackRefID}, + DependsOnTypes: []descpb.ID{typeWithFuncRefID}, + }, + }, + { + ``, + descpb.FunctionDescriptor{ + Name: "f", + ID: funcDescID, + ParentID: dbID, + ParentSchemaID: schemaWithFuncRefID, + Privileges: defaultPrivileges, + ReturnType: descpb.FunctionDescriptor_ReturnType{ + Type: types.Int, + }, + Volatility: catpb.Function_IMMUTABLE, + DependedOnBy: []descpb.FunctionDescriptor_Reference{ + {ID: tableWIthGoodColumn, ColumnIDs: []descpb.ColumnID{1}}, }, DependsOn: []descpb.ID{tableWithFuncBackRefID}, DependsOnTypes: []descpb.ID{typeWithFuncRefID}, diff --git a/pkg/sql/catalog/funcdesc/helpers.go b/pkg/sql/catalog/funcdesc/helpers.go index 56ea6037ed8c..d86a04eca412 100644 --- a/pkg/sql/catalog/funcdesc/helpers.go +++ b/pkg/sql/catalog/funcdesc/helpers.go @@ -81,7 +81,9 @@ func ParamClassToProto(v tree.FuncParamClass) (catpb.Function_Param_Class, error } var schemaExprContextAllowingUDF = map[tree.SchemaExprContext]clusterversion.Key{ - tree.CheckConstraintExpr: clusterversion.V23_1, + tree.CheckConstraintExpr: clusterversion.V23_1, + tree.ColumnDefaultExprInNewTable: clusterversion.V23_1, + tree.ColumnDefaultExprInSetDefault: clusterversion.V23_1, } // MaybeFailOnUDFUsage returns an error if the given expression or any diff --git a/pkg/sql/catalog/rewrite/rewrite.go b/pkg/sql/catalog/rewrite/rewrite.go index 9aaf2783b671..e3e26a5998c7 100644 --- a/pkg/sql/catalog/rewrite/rewrite.go +++ b/pkg/sql/catalog/rewrite/rewrite.go @@ -74,44 +74,14 @@ func TableDescs( // Rewrite CHECK constraints before function IDs in expressions are // rewritten. Check constraint mutations are also dropped if any function // referenced are missing. - var newChecks []*descpb.TableDescriptor_CheckConstraint - for i := range table.Checks { - fnIDs, err := table.GetAllReferencedFunctionIDsInConstraint(table.Checks[i].ConstraintID) - if err != nil { - return err - } - allFnFound := true - for _, fnID := range fnIDs.Ordered() { - if _, ok := descriptorRewrites[fnID]; !ok { - allFnFound = false - break - } - } - if allFnFound { - newChecks = append(newChecks, table.Checks[i]) - } + if err := dropCheckConstraintMissingDeps(table, descriptorRewrites); err != nil { + return err } - table.Checks = newChecks - var newMutations []descpb.DescriptorMutation - for i := range table.Mutations { - keepMutation := true - if c := table.Mutations[i].GetConstraint(); c != nil && c.ConstraintType == descpb.ConstraintToUpdate_CHECK { - fnIDs, err := table.GetAllReferencedFunctionIDsInConstraint(c.Check.ConstraintID) - if err != nil { - return err - } - for _, fnID := range fnIDs.Ordered() { - if _, ok := descriptorRewrites[fnID]; !ok { - keepMutation = false - break - } - } - } - if keepMutation { - newMutations = append(newMutations, table.Mutations[i]) - } + + // Drop column expressions if referenced UDFs not found. + if err := dropColumnExpressionsMissingDeps(table, descriptorRewrites); err != nil { + return err } - table.Mutations = newMutations // Remap type IDs and sequence IDs in all serialized expressions within the TableDescriptor. // TODO (rohany): This needs tests once partial indexes are ready. @@ -296,6 +266,12 @@ func TableDescs( } col.OwnsSequenceIds = newOwnedSeqRefs + for i, fnID := range col.UsesFunctionIds { + // We have dropped expressions missing UDF references. so it's safe to + // just rewrite ids. + col.UsesFunctionIds[i] = descriptorRewrites[fnID].ID + } + return nil } @@ -708,6 +684,14 @@ func rewriteSchemaChangerState( i-- droppedConstraints.Add(el.ConstraintID) continue + case *scpb.ColumnDefaultExpression: + // IF there is any dependency missing for column default expression, we + // just drop the target. + state.Targets = append(state.Targets[:i], state.Targets[i+1:]...) + state.CurrentStatuses = append(state.CurrentStatuses[:i], state.CurrentStatuses[i+1:]...) + state.TargetRanks = append(state.TargetRanks[:i], state.TargetRanks[i+1:]...) + i-- + continue } return errors.Wrap(err, "rewriting descriptor ids") } @@ -742,6 +726,7 @@ func rewriteSchemaChangerState( // views are not handled by the declarative schema changer. } + // Drop all children targets of dropped CHECK constraint. for i := 0; i < len(state.Targets); i++ { t := &state.Targets[i] if err := screl.WalkConstraintIDs(t.Element(), func(id *catid.ConstraintID) error { @@ -761,6 +746,92 @@ func rewriteSchemaChangerState( return nil } +func dropCheckConstraintMissingDeps( + table *tabledesc.Mutable, descriptorRewrites jobspb.DescRewriteMap, +) error { + var newChecks []*descpb.TableDescriptor_CheckConstraint + for i := range table.Checks { + fnIDs, err := table.GetAllReferencedFunctionIDsInConstraint(table.Checks[i].ConstraintID) + if err != nil { + return err + } + allFnFound := true + for _, fnID := range fnIDs.Ordered() { + if _, ok := descriptorRewrites[fnID]; !ok { + allFnFound = false + break + } + } + if allFnFound { + newChecks = append(newChecks, table.Checks[i]) + } + } + table.Checks = newChecks + var newMutations []descpb.DescriptorMutation + for i := range table.Mutations { + keepMutation := true + if c := table.Mutations[i].GetConstraint(); c != nil && c.ConstraintType == descpb.ConstraintToUpdate_CHECK { + fnIDs, err := table.GetAllReferencedFunctionIDsInConstraint(c.Check.ConstraintID) + if err != nil { + return err + } + for _, fnID := range fnIDs.Ordered() { + if _, ok := descriptorRewrites[fnID]; !ok { + keepMutation = false + break + } + } + } + if keepMutation { + newMutations = append(newMutations, table.Mutations[i]) + } + } + table.Mutations = newMutations + return nil +} + +func dropColumnExpressionsMissingDeps( + table *tabledesc.Mutable, descriptorRewrites jobspb.DescRewriteMap, +) error { + maybeDropExpressions := func(col *descpb.ColumnDescriptor) error { + allFnFound := true + fnIDs, err := table.GetAllReferencedFunctionIDsInColumnExprs(col.ID) + if err != nil { + return err + } + for _, fnID := range fnIDs.Ordered() { + if _, ok := descriptorRewrites[fnID]; !ok { + allFnFound = false + break + } + } + if !allFnFound { + // TODO(chengxiong): right now, we only allow UDFs in DEFAULT expression, + // so it's ok to just clear default expression and referenced function + // ids. Need to refactor to support ON UPDATE and computed column + // expression once supported. + col.DefaultExpr = nil + col.UsesFunctionIds = nil + } + return nil + } + + for i := range table.Columns { + col := &table.Columns[i] + if err := maybeDropExpressions(col); err != nil { + return err + } + } + for i := range table.Mutations { + if col := table.Mutations[i].GetColumn(); col != nil { + if err := maybeDropExpressions(col); err != nil { + return err + } + } + } + return nil +} + // DatabaseDescs rewrites all ID's in the input slice of DatabaseDescriptors // using the input ID rewrite mapping. The function elides remapping offline schemas, // since they will not get restored into the cluster. diff --git a/pkg/sql/catalog/schemaexpr/expr.go b/pkg/sql/catalog/schemaexpr/expr.go index cc0bc60daa8a..23263c6faa5c 100644 --- a/pkg/sql/catalog/schemaexpr/expr.go +++ b/pkg/sql/catalog/schemaexpr/expr.go @@ -124,7 +124,7 @@ func DequalifyAndValidateExprImpl( // We need to do the rewrite here before the expression is serialized because // the serialization would drop the prefixes to functions. // - typedExpr, err = maybeReplaceUDFNameWithOIDReferenceInTypedExpr(typedExpr) + typedExpr, err = MaybeReplaceUDFNameWithOIDReferenceInTypedExpr(typedExpr) if err != nil { return "", nil, colIDs, err } @@ -577,7 +577,7 @@ func ValidateTTLExpirationExpression( return nil } -func maybeReplaceUDFNameWithOIDReferenceInTypedExpr( +func MaybeReplaceUDFNameWithOIDReferenceInTypedExpr( typedExpr tree.TypedExpr, ) (tree.TypedExpr, error) { replaceFunc := func(ex tree.Expr) (recurse bool, newExpr tree.Expr, err error) { @@ -623,3 +623,14 @@ func GetUDFIDs(e tree.Expr) (catalog.DescriptorIDSet, error) { } return fnIDs, nil } + +// GetUDFIDsFromExprStr extracts all UDF descriptor ids from the given +// expression string, assuming that the UDF names has been replaced with OID +// references. It's a convenient wrapper of GetUDFIDs. +func GetUDFIDsFromExprStr(exprStr string) (catalog.DescriptorIDSet, error) { + expr, err := parser.ParseExpr(exprStr) + if err != nil { + return catalog.DescriptorIDSet{}, err + } + return GetUDFIDs(expr) +} diff --git a/pkg/sql/catalog/table_col_set.go b/pkg/sql/catalog/table_col_set.go index 827334c4e524..ea6cc0f08b81 100644 --- a/pkg/sql/catalog/table_col_set.go +++ b/pkg/sql/catalog/table_col_set.go @@ -32,6 +32,9 @@ func MakeTableColSet(vals ...descpb.ColumnID) TableColSet { // Add adds a column to the set. No-op if the column is already in the set. func (s *TableColSet) Add(col descpb.ColumnID) { s.set.Add(int(col)) } +// Remove removes a column from the set. No-op if the column is not in the set. +func (s *TableColSet) Remove(col descpb.ColumnID) { s.set.Remove(int(col)) } + // Contains returns true if the set contains the column. func (s TableColSet) Contains(col descpb.ColumnID) bool { return s.set.Contains(int(col)) } diff --git a/pkg/sql/catalog/table_elements.go b/pkg/sql/catalog/table_elements.go index d77f7402d6eb..cd72ea178600 100644 --- a/pkg/sql/catalog/table_elements.go +++ b/pkg/sql/catalog/table_elements.go @@ -364,6 +364,13 @@ type Column interface { // GetUsesSequenceID returns the ID of a sequence used by this column. GetUsesSequenceID(usesSequenceOrdinal int) descpb.ID + // NumUsesFunctions returns the number of functions used by this column. + NumUsesFunctions() int + + // GetUsesFunctionID returns the ID of a function used by this column at the + // given ordinal. + GetUsesFunctionID(ordinal int) descpb.ID + // NumOwnsSequences returns the number of sequences owned by this column. NumOwnsSequences() int diff --git a/pkg/sql/catalog/tabledesc/column.go b/pkg/sql/catalog/tabledesc/column.go index e415298d6e37..5a2db0ca066d 100644 --- a/pkg/sql/catalog/tabledesc/column.go +++ b/pkg/sql/catalog/tabledesc/column.go @@ -182,6 +182,17 @@ func (w column) GetUsesSequenceID(usesSequenceOrdinal int) descpb.ID { return w.desc.UsesSequenceIds[usesSequenceOrdinal] } +// NumUsesFunctions returns the number of functions used by this column. +func (w column) NumUsesFunctions() int { + return len(w.desc.UsesFunctionIds) +} + +// GetUsesFunctionID returns the ID of a function used by this column at the +// given ordinal. +func (w column) GetUsesFunctionID(ordinal int) descpb.ID { + return w.desc.UsesSequenceIds[ordinal] +} + // NumOwnsSequences returns the number of sequences owned by this column. func (w column) NumOwnsSequences() int { return len(w.desc.OwnsSequenceIds) diff --git a/pkg/sql/catalog/tabledesc/structured.go b/pkg/sql/catalog/tabledesc/structured.go index fa6ab1be89b4..466cf26912f2 100644 --- a/pkg/sql/catalog/tabledesc/structured.go +++ b/pkg/sql/catalog/tabledesc/structured.go @@ -376,8 +376,13 @@ func (desc *wrapper) GetAllReferencedFunctionIDs() (catalog.DescriptorIDSet, err } ret = ret.Union(ids) } - // TODO(chengxiong): add logic to extract references from columns and indexes - // when UDFs are allowed in them. + for _, c := range desc.AllColumns() { + for _, id := range c.ColumnDesc().UsesFunctionIds { + ret.Add(id) + } + } + // TODO(chengxiong): add logic to extract references from indexes when UDFs + // are allowed in them. return ret.Union(catalog.MakeDescriptorIDSet(desc.DependsOnFunctions...)), nil } @@ -391,14 +396,38 @@ func (desc *wrapper) GetAllReferencedFunctionIDsInConstraint( if ck == nil { return catalog.DescriptorIDSet{}, nil } - ckExpr, err := parser.ParseExpr(ck.GetExpr()) + ret, err := schemaexpr.GetUDFIDsFromExprStr(ck.GetExpr()) if err != nil { return catalog.DescriptorIDSet{}, err } - ret, err := schemaexpr.GetUDFIDs(ckExpr) - if err != nil { - return catalog.DescriptorIDSet{}, err + return ret, nil +} + +// GetAllReferencedFunctionIDsInColumnExprs implements the TableDescriptor +// interface. +func (desc *wrapper) GetAllReferencedFunctionIDsInColumnExprs( + colID descpb.ColumnID, +) (fnIDs catalog.DescriptorIDSet, err error) { + col := catalog.FindColumnByID(desc, colID) + if col == nil { + return catalog.DescriptorIDSet{}, nil } + + var ret catalog.DescriptorIDSet + // TODO(chengxiong): add support for computed columns when UDFs are allowed in + // them. + if !col.IsComputed() { + if col.HasDefault() { + ids, err := schemaexpr.GetUDFIDsFromExprStr(col.GetDefaultExpr()) + if err != nil { + return catalog.DescriptorIDSet{}, err + } + ret = ret.Union(ids) + } + // TODO(chengxiong): add support for ON UPDATE expressions when UDFs are + // allowed in them. + } + return ret, nil } diff --git a/pkg/sql/catalog/tabledesc/table.go b/pkg/sql/catalog/tabledesc/table.go index 7d12a80a0a12..2f48311f5372 100644 --- a/pkg/sql/catalog/tabledesc/table.go +++ b/pkg/sql/catalog/tabledesc/table.go @@ -100,7 +100,11 @@ func (cdd *ColumnDefDescs) ForEachTypedExpr( // // See the ColumnDefDescs definition for a description of the return values. func MakeColumnDefDescs( - ctx context.Context, d *tree.ColumnTableDef, semaCtx *tree.SemaContext, evalCtx *eval.Context, + ctx context.Context, + d *tree.ColumnTableDef, + semaCtx *tree.SemaContext, + evalCtx *eval.Context, + defaultExprCtx tree.SchemaExprContext, ) (*ColumnDefDescs, error) { if d.IsSerial { // To the reader of this code: if control arrives here, this means @@ -162,12 +166,17 @@ func MakeColumnDefDescs( // Verify the default expression type is compatible with the column type // and does not contain invalid functions. ret.DefaultExpr, err = schemaexpr.SanitizeVarFreeExpr( - ctx, d.DefaultExpr.Expr, resType, "DEFAULT", semaCtx, volatility.Volatile, true, /*allowAssignmentCast*/ + ctx, d.DefaultExpr.Expr, resType, defaultExprCtx, semaCtx, volatility.Volatile, true, /*allowAssignmentCast*/ ) if err != nil { return nil, err } - if err := funcdesc.MaybeFailOnUDFUsage(ret.DefaultExpr, tree.ColumnDefaultExpr, evalCtx.Settings.Version.ActiveVersion(ctx)); err != nil { + if err := funcdesc.MaybeFailOnUDFUsage(ret.DefaultExpr, defaultExprCtx, evalCtx.Settings.Version.ActiveVersion(ctx)); err != nil { + return nil, err + } + + ret.DefaultExpr, err = schemaexpr.MaybeReplaceUDFNameWithOIDReferenceInTypedExpr(ret.DefaultExpr) + if err != nil { return nil, err } @@ -185,7 +194,7 @@ func MakeColumnDefDescs( // Verify the on update expression type is compatible with the column type // and does not contain invalid functions. ret.OnUpdateExpr, err = schemaexpr.SanitizeVarFreeExpr( - ctx, d.OnUpdateExpr.Expr, resType, "ON UPDATE", semaCtx, volatility.Volatile, true, /*allowAssignmentCast*/ + ctx, d.OnUpdateExpr.Expr, resType, tree.ColumnOnUpdateExpr, semaCtx, volatility.Volatile, true, /*allowAssignmentCast*/ ) if err != nil { return nil, err diff --git a/pkg/sql/catalog/tabledesc/validate.go b/pkg/sql/catalog/tabledesc/validate.go index d88296629de9..c4cbe90f9b8d 100644 --- a/pkg/sql/catalog/tabledesc/validate.go +++ b/pkg/sql/catalog/tabledesc/validate.go @@ -81,13 +81,11 @@ func (desc *wrapper) GetReferencedDescIDs() (catalog.DescriptorIDSet, error) { ids.Add(col.GetUsesSequenceID(i)) } } - for _, cst := range desc.Checks { - fnIDs, err := desc.GetAllReferencedFunctionIDsInConstraint(cst.ConstraintID) - if err != nil { - return catalog.DescriptorIDSet{}, err - } - fnIDs.ForEach(ids.Add) + fnIDs, err := desc.GetAllReferencedFunctionIDs() + if err != nil { + return catalog.DescriptorIDSet{}, err } + fnIDs.ForEach(ids.Add) // Collect user defined type IDs in expressions. // All serialized expressions within a table descriptor are serialized // with type annotations as IDs, so this visitor will collect them all. @@ -193,6 +191,13 @@ func (desc *wrapper) ValidateForwardReferences( } } + // check all functions referenced by columns exists. + for _, col := range desc.Columns { + for _, fnID := range col.UsesFunctionIds { + vea.Report(desc.validateOutboundFuncRef(fnID, vdg)) + } + } + // Row-level TTL is not compatible with foreign keys. // This check should be in ValidateSelf but interferes with AllocateIDs. if desc.HasRowLevelTTL() { @@ -264,6 +269,18 @@ func (desc *wrapper) ValidateBackReferences( } } + // Check back-references in functions referenced by columns. + for _, col := range desc.Columns { + for _, fnID := range col.UsesFunctionIds { + fn, err := vdg.GetFunctionDescriptor(fnID) + if err != nil { + vea.Report(err) + continue + } + vea.Report(desc.validateOutboundFuncRefBackReferenceForColumn(fn, col.ID)) + } + } + // For views, check dependent relations. if desc.IsView() { for _, id := range desc.DependsOnTypes { @@ -360,6 +377,23 @@ func (desc *wrapper) validateOutboundFuncRefBackReferenceForConstraint( ref.GetName(), ref.GetID()) } +func (desc *wrapper) validateOutboundFuncRefBackReferenceForColumn( + ref catalog.FunctionDescriptor, colID descpb.ColumnID, +) error { + for _, dep := range ref.GetDependedOnBy() { + if dep.ID != desc.GetID() { + continue + } + for _, id := range dep.ColumnIDs { + if id == colID { + return nil + } + } + } + return errors.AssertionFailedf("depends-on function %q (%d) has no corresponding depended-on-by back reference", + ref.GetName(), ref.GetID()) +} + func (desc *wrapper) validateInboundFunctionRef( by descpb.TableDescriptor_Reference, vdg catalog.ValidationDescGetter, ) error { diff --git a/pkg/sql/catalog/tabledesc/validate_test.go b/pkg/sql/catalog/tabledesc/validate_test.go index f2b41c94da49..28a8e33caa41 100644 --- a/pkg/sql/catalog/tabledesc/validate_test.go +++ b/pkg/sql/catalog/tabledesc/validate_test.go @@ -208,6 +208,7 @@ var validationMap = []struct { "AlterColumnTypeInProgress": {status: thisFieldReferencesNoObjects}, "SystemColumnKind": {status: thisFieldReferencesNoObjects}, "OnUpdateExpr": {status: iSolemnlySwearThisFieldIsValidated}, + "UsesFunctionIds": {status: iSolemnlySwearThisFieldIsValidated}, }, }, { @@ -2966,6 +2967,69 @@ func TestValidateCrossTableReferences(t *testing.T) { }, }, }, + { // 23 + err: `invalid depends-on function back reference: referenced function ID 100: referenced descriptor not found`, + desc: descpb.TableDescriptor{ + Name: "foo", + ID: 51, + ParentID: 1, + UnexposedParentSchemaID: keys.PublicSchemaID, + Columns: []descpb.ColumnDescriptor{ + { + ID: 1, + Type: types.Int, + UsesFunctionIds: []descpb.ID{100}, + }, + }, + }, + }, + { // 24 + err: `depends-on function "f" (100) has no corresponding depended-on-by back reference`, + desc: descpb.TableDescriptor{ + Name: "foo", + ID: 51, + ParentID: 1, + UnexposedParentSchemaID: keys.PublicSchemaID, + Columns: []descpb.ColumnDescriptor{ + { + ID: 1, + Type: types.Int, + UsesFunctionIds: []descpb.ID{100}, + }, + }, + }, + fnDescs: []descpb.FunctionDescriptor{ + { + ID: 100, + Name: "f", + }, + }, + }, + { // 25 + err: `depends-on function "f" (100) has no corresponding depended-on-by back reference`, + desc: descpb.TableDescriptor{ + Name: "foo", + ID: 51, + ParentID: 1, + UnexposedParentSchemaID: keys.PublicSchemaID, + Columns: []descpb.ColumnDescriptor{ + { + ID: 1, + Type: types.Int, + UsesFunctionIds: []descpb.ID{100}, + }, + }, + }, + fnDescs: []descpb.FunctionDescriptor{ + { + ID: 100, + Name: "f", + DependedOnBy: []descpb.FunctionDescriptor_Reference{ + {ID: 51}, + }, + }, + }, + }, } for i, test := range tests { diff --git a/pkg/sql/crdb_internal_test.go b/pkg/sql/crdb_internal_test.go index ce0fd2b4c888..93807e1c49d8 100644 --- a/pkg/sql/crdb_internal_test.go +++ b/pkg/sql/crdb_internal_test.go @@ -240,7 +240,7 @@ CREATE TABLE t.test (k INT); } colDef := alterCmd.AST.(*tree.AlterTable).Cmds[0].(*tree.AlterTableAddColumn).ColumnDef evalCtx := eval.NewTestingEvalContext(cluster.MakeTestingClusterSettings()) - cdd, err := tabledesc.MakeColumnDefDescs(ctx, colDef, nil, evalCtx) + cdd, err := tabledesc.MakeColumnDefDescs(ctx, colDef, nil, evalCtx, tree.ColumnDefaultExprInAddColumn) if err != nil { t.Fatal(err) } diff --git a/pkg/sql/create_function_test.go b/pkg/sql/create_function_test.go index 47bec7bd19ce..cc0741cf64f4 100644 --- a/pkg/sql/create_function_test.go +++ b/pkg/sql/create_function_test.go @@ -232,6 +232,54 @@ func TestVersionGatingUDFInCheckConstraints(t *testing.T) { }) } +func TestVersionGatingUDFInColumnDefault(t *testing.T) { + defer leaktest.AfterTest(t)() + + t.Run("new_schema_changer_version_enabled", func(t *testing.T) { + params, _ := tests.CreateTestServerParams() + // Override binary version to be older. + params.Knobs.Server = &server.TestingKnobs{ + DisableAutomaticVersionUpgrade: make(chan struct{}), + BinaryVersionOverride: clusterversion.ByKey(clusterversion.V23_1), + } + + s, sqlDB, _ := serverutils.StartServer(t, params) + defer s.Stopper().Stop(context.Background()) + + _, err := sqlDB.Exec(`CREATE FUNCTION f() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$`) + require.NoError(t, err) + _, err = sqlDB.Exec(`CREATE TABLE t(a INT DEFAULT f());`) + require.NoError(t, err) + _, err = sqlDB.Exec(`ALTER TABLE t ALTER COLUMN a SET DEFAULT (f() + 1)`) + require.NoError(t, err) + }) + + t.Run("new_schema_changer_version_disabled", func(t *testing.T) { + params, _ := tests.CreateTestServerParams() + // Override binary version to be older. + params.Knobs.Server = &server.TestingKnobs{ + DisableAutomaticVersionUpgrade: make(chan struct{}), + BinaryVersionOverride: clusterversion.ByKey(clusterversion.V23_1 - 1), + } + + s, sqlDB, _ := serverutils.StartServer(t, params) + defer s.Stopper().Stop(context.Background()) + + // Need to turn new schema changer off, because function related rules are + // only valid in 23.1. + _, err := sqlDB.Exec(`SET use_declarative_schema_changer = 'off'`) + require.NoError(t, err) + _, err = sqlDB.Exec(`CREATE FUNCTION f() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$`) + require.NoError(t, err) + _, err = sqlDB.Exec(`CREATE TABLE t(a INT DEFAULT f());`) + require.Equal(t, "pq: unimplemented: usage of user-defined function from relations not supported", err.Error()) + _, err = sqlDB.Exec(`CREATE TABLE t(a INT);`) + require.NoError(t, err) + _, err = sqlDB.Exec(`ALTER TABLE t ALTER COLUMN a SET DEFAULT (f() + 1)`) + require.Equal(t, "pq: unimplemented: usage of user-defined function from relations not supported", err.Error()) + }) +} + func TestCreateOrReplaceFunctionUpdateReferences(t *testing.T) { defer leaktest.AfterTest(t)() defer log.Scope(t).Close(t) diff --git a/pkg/sql/create_table.go b/pkg/sql/create_table.go index 643005cb0239..87195c7bd861 100644 --- a/pkg/sql/create_table.go +++ b/pkg/sql/create_table.go @@ -394,6 +394,7 @@ func (n *createTableNode) startExec(params runParams) error { if desc.Adding() { // if this table and all its references are created in the same // transaction it can be made PUBLIC. + // TODO(chengxiong): do we need to do something here? Like. add logic to find all references. refs, err := desc.FindAllReferences() if err != nil { return err @@ -421,6 +422,13 @@ func (n *createTableNode) startExec(params runParams) error { } } + // Update cross-references between functions and columns. + for i := range desc.Columns { + if err := params.p.maybeUpdateFunctionReferencesForColumn(params.ctx, desc, &desc.Columns[i]); err != nil { + return err + } + } + // Descriptor written to store here. if err := params.p.createDescriptor( params.ctx, @@ -1579,7 +1587,7 @@ func NewTableDesc( return nil, pgerror.Newf(pgcode.Syntax, "virtual columns cannot have family specifications") } - cdd[i], err = tabledesc.MakeColumnDefDescs(ctx, d, semaCtx, evalCtx) + cdd[i], err = tabledesc.MakeColumnDefDescs(ctx, d, semaCtx, evalCtx, tree.ColumnDefaultExprInNewTable) if err != nil { return nil, err } diff --git a/pkg/sql/create_view.go b/pkg/sql/create_view.go index 6e8f66348702..5d05bb17af59 100644 --- a/pkg/sql/create_view.go +++ b/pkg/sql/create_view.go @@ -696,7 +696,7 @@ func addResultColumns( columnTableDef.Nullable.Nullability = tree.SilentNull // The new types in the CREATE VIEW column specs never use // SERIAL so we need not process SERIAL types here. - cdd, err := tabledesc.MakeColumnDefDescs(ctx, &columnTableDef, semaCtx, evalCtx) + cdd, err := tabledesc.MakeColumnDefDescs(ctx, &columnTableDef, semaCtx, evalCtx, tree.ColumnDefaultExprInNewView) if err != nil { return err } diff --git a/pkg/sql/drop_table.go b/pkg/sql/drop_table.go index 3f93a31d6000..59c1464134d8 100644 --- a/pkg/sql/drop_table.go +++ b/pkg/sql/drop_table.go @@ -592,6 +592,22 @@ func (p *planner) removeCheckBackReferenceInFunctions( return nil } +func (p *planner) removeColumnBackReferenceInFunctions( + ctx context.Context, tableDesc *tabledesc.Mutable, col *descpb.ColumnDescriptor, +) error { + for _, id := range col.UsesFunctionIds { + fnDesc, err := p.Descriptors().MutableByID(p.Txn()).Function(ctx, id) + if err != nil { + return err + } + fnDesc.RemoveColumnReference(tableDesc.GetID(), col.ID) + if err := p.writeFuncSchemaChange(ctx, fnDesc); err != nil { + return err + } + } + return nil +} + func removeCheckBackReferenceInFunctions( ctx context.Context, tableDesc *tabledesc.Mutable, diff --git a/pkg/sql/function_references.go b/pkg/sql/function_references.go index e418fee2c4af..dfaeafccfe32 100644 --- a/pkg/sql/function_references.go +++ b/pkg/sql/function_references.go @@ -38,3 +38,40 @@ func (p *planner) updateFunctionReferencesForCheck( } return nil } + +func (p *planner) maybeUpdateFunctionReferencesForColumn( + ctx context.Context, tblDesc catalog.TableDescriptor, col *descpb.ColumnDescriptor, +) error { + // Remove back references in old referenced functions. + for _, id := range col.UsesFunctionIds { + fnDesc, err := p.descCollection.MutableByID(p.txn).Function(ctx, id) + if err != nil { + return err + } + fnDesc.RemoveColumnReference(tblDesc.GetID(), col.ID) + if err := p.writeFuncSchemaChange(ctx, fnDesc); err != nil { + return err + } + } + + udfIDs, err := tblDesc.GetAllReferencedFunctionIDsInColumnExprs(col.ID) + if err != nil { + return err + } + col.UsesFunctionIds = udfIDs.Ordered() + + // Add new back references. + for _, id := range col.UsesFunctionIds { + fnDesc, err := p.descCollection.MutableByID(p.txn).Function(ctx, id) + if err != nil { + return err + } + if err := fnDesc.AddColumnReference(tblDesc.GetID(), col.ID); err != nil { + return err + } + if err := p.writeFuncSchemaChange(ctx, fnDesc); err != nil { + return err + } + } + return nil +} diff --git a/pkg/sql/logictest/testdata/logic_test/alter_table b/pkg/sql/logictest/testdata/logic_test/alter_table index 154ba08557c7..6c87228e43ae 100644 --- a/pkg/sql/logictest/testdata/logic_test/alter_table +++ b/pkg/sql/logictest/testdata/logic_test/alter_table @@ -543,7 +543,7 @@ INSERT INTO add_default (a) VALUES (2) statement ok ALTER TABLE add_default ALTER COLUMN b SET DEFAULT 10 -statement error pgcode 42804 expected DEFAULT expression to have type int, but ''i'::STRING' has type string +statement error pgcode 42804 expected DEFAULT \(in SET DEFAULT\) expression to have type int, but ''i'::STRING' has type string ALTER TABLE add_default ALTER COLUMN b SET DEFAULT 'i'::string statement ok diff --git a/pkg/sql/logictest/testdata/logic_test/cast b/pkg/sql/logictest/testdata/logic_test/cast index c18ba18dd9db..2f7869b20838 100644 --- a/pkg/sql/logictest/testdata/logic_test/cast +++ b/pkg/sql/logictest/testdata/logic_test/cast @@ -1466,12 +1466,12 @@ CREATE TABLE fail_assn_cast ( a BOOL DEFAULT 'foo' ) -statement error pq: expected DEFAULT expression to have type .*, but .* has type .* +statement error pq: expected DEFAULT \(in CREATE TABLE\) expression to have type .*, but .* has type .* CREATE TABLE fail_assn_cast ( a DATE DEFAULT 1.0::FLOAT4 ) -statement error pq: expected DEFAULT expression to have type .*, but .* has type .* +statement error pq: expected DEFAULT \(in CREATE TABLE\) expression to have type .*, but .* has type .* CREATE TABLE fail_assn_cast ( b JSONB DEFAULT 'null'::CHAR ) diff --git a/pkg/sql/logictest/testdata/logic_test/default b/pkg/sql/logictest/testdata/logic_test/default index 2cd9933c57e8..b82fcb656491 100644 --- a/pkg/sql/logictest/testdata/logic_test/default +++ b/pkg/sql/logictest/testdata/logic_test/default @@ -1,4 +1,4 @@ -statement error expected DEFAULT expression to have type int, but 'false' has type bool +statement error expected DEFAULT \(in CREATE TABLE\) expression to have type int, but 'false' has type bool CREATE TABLE t (a INT PRIMARY KEY DEFAULT false) statement error variable sub-expressions are not allowed in DEFAULT diff --git a/pkg/sql/logictest/testdata/logic_test/udf b/pkg/sql/logictest/testdata/logic_test/udf index 5a52ec242b00..2103fc8cb5bf 100644 --- a/pkg/sql/logictest/testdata/logic_test/udf +++ b/pkg/sql/logictest/testdata/logic_test/udf @@ -553,9 +553,6 @@ subtest disallow_udf_in_table statement ok CREATE FUNCTION test_tbl_f() RETURNS INT IMMUTABLE LANGUAGE SQL AS $$ SELECT 1 $$; -statement error pq: unimplemented: usage of user-defined function from relations not supported -CREATE TABLE test_tbl_t (a INT PRIMARY KEY, b INT DEFAULT (test_tbl_f() + 1)); - statement error pq: unimplemented: usage of user-defined function from relations not supported CREATE TABLE test_tbl_t (a INT PRIMARY KEY, b INT ON UPDATE (test_tbl_f() + 1)); @@ -583,9 +580,6 @@ ALTER TABLE test_tbl_t ADD COLUMN c int DEFAULT (test_tbl_f()); statement error pq: unimplemented: usage of user-defined function from relations not supported ALTER TABLE test_tbl_t ADD COLUMN c int ON UPDATE (test_tbl_f()); -statement error pq: unimplemented: usage of user-defined function from relations not supported -ALTER TABLE test_tbl_t ALTER COLUMN b SET DEFAULT (test_tbl_f()); - statement error pq: unimplemented: usage of user-defined function from relations not supported ALTER TABLE test_tbl_t ALTER COLUMN b SET ON UPDATE (test_tbl_f()); diff --git a/pkg/sql/logictest/testdata/logic_test/udf_in_column_defaults b/pkg/sql/logictest/testdata/logic_test/udf_in_column_defaults new file mode 100644 index 000000000000..2e720c7e91b3 --- /dev/null +++ b/pkg/sql/logictest/testdata/logic_test/udf_in_column_defaults @@ -0,0 +1,503 @@ +statement ok +CREATE FUNCTION f1() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; + +statement ok +CREATE VIEW v_col_fn_ids AS +SELECT +id, +json_array_elements( + crdb_internal.pb_to_json( + 'cockroach.sql.sqlbase.Descriptor', + descriptor, + false + )->'table'->'columns' +)->'id' as col_id, +json_array_elements( + crdb_internal.pb_to_json( + 'cockroach.sql.sqlbase.Descriptor', + descriptor, + false + )->'table'->'columns' +)->'defaultExpr' as default_expr, +json_array_elements( + crdb_internal.pb_to_json( + 'cockroach.sql.sqlbase.Descriptor', + descriptor, + false + )->'table'->'columns' +)->'usesFunctionIds' as uses_fn_ids +FROM system.descriptor + +statement ok +CREATE FUNCTION get_col_fn_ids(table_id INT) RETURNS SETOF v_col_fn_ids +LANGUAGE SQL +AS $$ + SELECT * + FROM v_col_fn_ids + WHERE id = table_id +$$; + +statement ok +CREATE VIEW v_fn_depended_on_by AS +SELECT + id, + jsonb_pretty( + crdb_internal.pb_to_json( + 'cockroach.sql.sqlbase.Descriptor', + descriptor, + false + )->'function'->'dependedOnBy' + ) as depended_on_by +FROM system.descriptor + +statement ok +CREATE FUNCTION get_fn_depended_on_by(function_id INT) RETURNS STRING +LANGUAGE SQL +AS $$ + SELECT depended_on_by + FROM v_fn_depended_on_by + WHERE id = function_id +$$; + +# Make sure that column DEFAULT expression is properly serialized and +# deserialized. +statement ok +CREATE TABLE t1( + a INT PRIMARY KEY, + b INT DEFAULT f1(), + c INT, + FAMILY fam_0 (a, b, c) +); + +let $tbl_id +SELECT id FROM system.namespace WHERE name = 't1'; + +query T +SELECT get_col_fn_ids($tbl_id); +---- +(111,1,,) +(111,2,"""[FUNCTION 100106]()""",[106]) +(111,3,,) + +query T +SELECT create_statement FROM [SHOW CREATE TABLE t1]; +---- +CREATE TABLE public.t1 ( + a INT8 NOT NULL, + b INT8 NULL DEFAULT public.f1(), + c INT8 NULL, + CONSTRAINT t1_pkey PRIMARY KEY (a ASC), + FAMILY fam_0 (a, b, c) +) + +# Make sure that back references are tracked properly. +let $fn_id +SELECT oid::int - 100000 FROM pg_catalog.pg_proc WHERE proname = 'f1'; + +query T +SELECT get_fn_depended_on_by($fn_id) +---- +[ + { + "columnIds": [ + 2 + ], + "id": 111 + } +] + +# Make sure SET DEFAULT sets cross references properly. +statement ok +ALTER TABLE t1 ALTER COLUMN c SET DEFAULT f1(); + +query T +SELECT get_col_fn_ids($tbl_id); +---- +(111,1,,) +(111,2,"""[FUNCTION 100106]()""",[106]) +(111,3,"""[FUNCTION 100106]()""",[106]) + +query T +SELECT create_statement FROM [SHOW CREATE TABLE t1]; +---- +CREATE TABLE public.t1 ( + a INT8 NOT NULL, + b INT8 NULL DEFAULT public.f1(), + c INT8 NULL DEFAULT public.f1(), + CONSTRAINT t1_pkey PRIMARY KEY (a ASC), + FAMILY fam_0 (a, b, c) +) + +query T +SELECT get_fn_depended_on_by($fn_id) +---- +[ + { + "columnIds": [ + 2, + 3 + ], + "id": 111 + } +] + +# Make sure cross references are properly removed with SET DEFAULT. +statement ok +ALTER TABLE t1 ALTER COLUMN c SET DEFAULT NULL; + +query T +SELECT get_col_fn_ids($tbl_id); +---- +(111,1,,) +(111,2,"""[FUNCTION 100106]()""",[106]) +(111,3,,) + +query T +SELECT get_fn_depended_on_by($fn_id) +---- +[ + { + "columnIds": [ + 2 + ], + "id": 111 + } +] + +statement ok +ALTER TABLE t1 ALTER COLUMN b SET DEFAULT NULL; + +query T +SELECT get_col_fn_ids($tbl_id); +---- +(111,1,,) +(111,2,,) +(111,3,,) + +query T +SELECT get_fn_depended_on_by($fn_id) +---- +NULL + +# Make sure cross references are properly removed with DROP COLUMN +statement ok +ALTER TABLE t1 ALTER COLUMN c SET DEFAULT f1(); + +query T +SELECT get_col_fn_ids($tbl_id); +---- +(111,1,,) +(111,2,,) +(111,3,"""[FUNCTION 100106]()""",[106]) + +query T +SELECT get_fn_depended_on_by($fn_id) +---- +[ + { + "columnIds": [ + 3 + ], + "id": 111 + } +] + +statement ok +ALTER TABLE t1 DROP COLUMN c; + +query T +SELECT get_col_fn_ids($tbl_id); +---- +(111,1,,) +(111,2,,) + +query T +SELECT get_fn_depended_on_by($fn_id) +---- +NULL + +# Make sure that cross references are properly remove with DROP TABLE. +statement ok +ALTER TABLE t1 ALTER COLUMN b SET DEFAULT f1(); + +query T +SELECT get_col_fn_ids($tbl_id); +---- +(111,1,,) +(111,2,"""[FUNCTION 100106]()""",[106]) + +query T +SELECT get_fn_depended_on_by($fn_id) +---- +[ + { + "columnIds": [ + 2 + ], + "id": 111 + } +] + +statement ok +DROP TABLE t1; + +query T +SELECT get_fn_depended_on_by($fn_id) +---- +NULL + +# Make sure function used by multiple tables can handle cross-references +# properly. + +statement ok +CREATE TABLE t1( + a INT PRIMARY KEY, + b INT DEFAULT f1(), + FAMILY fam_0 (a, b) +); +CREATE TABLE t2( + a INT PRIMARY KEY, + b INT DEFAULT f1(), + FAMILY fam_0 (a, b) +); + +query T +SELECT get_fn_depended_on_by($fn_id) +---- +[ + { + "columnIds": [ + 2 + ], + "id": 112 + }, + { + "columnIds": [ + 2 + ], + "id": 113 + } +] + +statement ok +DROP TABLE t1; +DROp TABLE t2; + +query T +SELECT get_fn_depended_on_by($fn_id) +---- +NULL + +# Make sure table uses multiple functions can handle cross-references properly. +statement ok +CREATE FUNCTION f2() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; + +let $fn_id_2 +SELECT oid::int - 100000 FROM pg_catalog.pg_proc WHERE proname = 'f2'; + +statement ok +CREATE TABLE t1( + a INT PRIMARY KEY, + b INT DEFAULT f1(), + c INT DEFAULT f2(), + FAMILY fam_0 (a, b, c) +); + +query T +SELECT get_fn_depended_on_by($fn_id) +---- +[ + { + "columnIds": [ + 2 + ], + "id": 115 + } +] + +query T +SELECT get_fn_depended_on_by($fn_id_2) +---- +[ + { + "columnIds": [ + 3 + ], + "id": 115 + } +] + +statement ok +DROP TABLE t1; + +query T +SELECT get_fn_depended_on_by($fn_id) +---- +NULL + +query T +SELECT get_fn_depended_on_by($fn_id_2) +---- +NULL + +# Make sure function cannot be dropped if used in constraints +statement ok +CREATE TABLE t1( + a INT PRIMARY KEY, + b INT DEFAULT f1(), + FAMILY fam_0 (a, b) +); + +statement error cannot drop function "f1" because other objects \(\[test.public.t1\]\) still depend on it +DROP FUNCTION f1; + +statement ok +ALTER TABLE t1 ALTER COLUMN b SET DEFAULT NULL; + +statement ok +DROP FUNCTION f1; +DROP TABLE t1; + +# Make sure that CREATE FUNCTION and CREATE TABLE works in one txn. +statement ok +BEGIN; +CREATE FUNCTION f1() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +CREATE TABLE t1( + a INT PRIMARY KEY, + b INT DEFAULT f1(), + FAMILY fam_0 (a, b) +); +END; + +let $tbl_id +SELECT id FROM system.namespace WHERE name = 't1'; + +let $fn_id +SELECT oid::int - 100000 FROM pg_catalog.pg_proc WHERE proname = 'f1'; + +query T +SELECT get_col_fn_ids($tbl_id); +---- +(118,1,,) +(118,2,"""[FUNCTION 100117]()""",[117]) + +query T +SELECT get_fn_depended_on_by($fn_id); +---- +[ + { + "columnIds": [ + 2 + ], + "id": 118 + } +] + +statement ok +BEGIN; +DROP TABLE t1; +DROP FUNCTION f1; +END; + +# Make sure that CREATE FUNCTION and SET DEFAULT works in one txn. +statement ok +CREATE TABLE t1 ( + a INT PRIMARY KEY, + b INT, + FAMILY fam_0 (a, b) +); + +statement ok +CREATE FUNCTION f1() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +ALTER TABLE t1 ALTER COLUMN b SET DEFAULT f1(); + +let $tbl_id +SELECT id FROM system.namespace WHERE name = 't1'; + +let $fn_id +SELECT oid::int - 100000 FROM pg_catalog.pg_proc WHERE proname = 'f1'; + +query T +SELECT get_col_fn_ids($tbl_id); +---- +(119,1,,) +(119,2,"""[FUNCTION 100120]()""",[120]) + +query T +SELECT get_fn_depended_on_by($fn_id); +---- +[ + { + "columnIds": [ + 2 + ], + "id": 119 + } +] + +skipif config local-legacy-schema-changer +statement ok +SET use_declarative_schema_changer = 'unsafe_always'; + +statement ok +BEGIN; +ALTER TABLE t1 DROP COLUMN b; +DROP FUNCTION f1; +END; + +skipif config local-legacy-schema-changer +statement ok +SET use_declarative_schema_changer = 'on'; + +# Make sure column DEFAULT works properly with insert. +statement ok +DROP TABLE t1; + +statement ok +CREATE FUNCTION f1() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +CREATE TABLE t1 ( + a INT PRIMARY KEY, + b INT DEFAULT f1(), + FAMILY fam_0 (a, b) +); + +statement ok +INSERT INTO t1 VALUES (1), (2) + +query II +SELECT * FROM t1 ORDER BY a; +---- +1 1 +2 1 + +# Make sure that renaming a function is fine. +statement ok +ALTER FUNCTION f1() RENAME TO f1_new; + +query T +SELECT create_statement FROM [SHOW CREATE TABLE t1] +---- +CREATE TABLE public.t1 ( + a INT8 NOT NULL, + b INT8 NULL DEFAULT public.f1_new(), + CONSTRAINT t1_pkey PRIMARY KEY (a ASC), + FAMILY fam_0 (a, b) +) + +statement ok +INSERT INTO t1 VALUES (3) + +query II +SELECT * FROM t1 ORDER BY a; +---- +1 1 +2 1 +3 1 + +# Make sure dependency circle is not allowed. +statement ok +CREATE TABLE t_circle(a INT PRIMARY KEY, b INT); +CREATE FUNCTION f_circle() RETURNS INT LANGUAGE SQL AS $$ SELECT a FROM t_circle $$; + +statement error pq: cannot add dependency from descriptor \d+ to function f_circle \(\d+\) because there will be a dependency cycle +ALTER TABLE t_circle ALTER COLUMN b SET DEFAULT f_circle(); diff --git a/pkg/sql/logictest/testdata/logic_test/udf_in_constraints b/pkg/sql/logictest/testdata/logic_test/udf_in_constraints index b14ee0934a1e..278a0a2047fd 100644 --- a/pkg/sql/logictest/testdata/logic_test/udf_in_constraints +++ b/pkg/sql/logictest/testdata/logic_test/udf_in_constraints @@ -367,6 +367,31 @@ INSERT INTO t1 VALUES (1,1); statement error validation of CHECK "public\.f1\(a\) > 10:::INT8" failed on row: a=1, b=1 ALTER TABLE t1 ADD CONSTRAINT cka CHECK (f1(a) > 10); +# Make sure that constraint still works after a function is renamed. +statement ok +ALTER TABLE t1 ADD CONSTRAINT cka CHECK (f1(a) > 1); + +statement error pq: failed to satisfy CHECK constraint \(public\.f1\(b\) > 1:::INT8\) +INSERT INTO t1 VALUES (2, -1); + +statement ok +ALTER FUNCTION f1 RENAME to f2; + +statement error pq: failed to satisfy CHECK constraint \(public\.f2\(b\) > 1:::INT8\) +INSERT INTO t1 VALUES (2, -1); + +query T +SELECT create_statement FROM [SHOW CREATE TABLE t1] +---- +CREATE TABLE public.t1 ( + a INT8 NOT NULL, + b INT8 NULL, + CONSTRAINT t1_pkey PRIMARY KEY (a ASC), + FAMILY fam_0 (a, b), + CONSTRAINT check_b CHECK (public.f2(b) > 1:::INT8), + CONSTRAINT cka CHECK (public.f2(a) > 1:::INT8) +) + # Make sure that schema prefix is preserved through serialization and # deserialization. @@ -392,3 +417,11 @@ CREATE TABLE public.t ( FAMILY fam_0_b_a (b, a), CONSTRAINT check_b CHECK (sc1.f1(b) > 1:::INT8) ) + +# Make sure dependency circle is not allowed. +statement ok +CREATE TABLE t_circle(a INT PRIMARY KEY, b INT); +CREATE FUNCTION f_circle() RETURNS INT LANGUAGE SQL AS $$ SELECT a FROM t_circle $$; + +statement error .*cannot add dependency from descriptor \d+ to function f_circle \(\d+\) because there will be a dependency cycle +ALTER TABLE t_circle ADD CONSTRAINT ckb CHECK (b + f_circle() > 1); diff --git a/pkg/sql/logictest/tests/fakedist-disk/generated_test.go b/pkg/sql/logictest/tests/fakedist-disk/generated_test.go index ad7ebd4b7c09..27613dcffc7b 100644 --- a/pkg/sql/logictest/tests/fakedist-disk/generated_test.go +++ b/pkg/sql/logictest/tests/fakedist-disk/generated_test.go @@ -1997,6 +1997,13 @@ func TestLogic_udf( runLogicTest(t, "udf") } +func TestLogic_udf_in_column_defaults( + t *testing.T, +) { + defer leaktest.AfterTest(t)() + runLogicTest(t, "udf_in_column_defaults") +} + func TestLogic_udf_in_constraints( t *testing.T, ) { diff --git a/pkg/sql/logictest/tests/fakedist-vec-off/generated_test.go b/pkg/sql/logictest/tests/fakedist-vec-off/generated_test.go index f82c3233c603..341528b8fa2a 100644 --- a/pkg/sql/logictest/tests/fakedist-vec-off/generated_test.go +++ b/pkg/sql/logictest/tests/fakedist-vec-off/generated_test.go @@ -2004,6 +2004,13 @@ func TestLogic_udf( runLogicTest(t, "udf") } +func TestLogic_udf_in_column_defaults( + t *testing.T, +) { + defer leaktest.AfterTest(t)() + runLogicTest(t, "udf_in_column_defaults") +} + func TestLogic_udf_in_constraints( t *testing.T, ) { diff --git a/pkg/sql/logictest/tests/fakedist/generated_test.go b/pkg/sql/logictest/tests/fakedist/generated_test.go index 0ed12b9a0272..aa89194c3d6a 100644 --- a/pkg/sql/logictest/tests/fakedist/generated_test.go +++ b/pkg/sql/logictest/tests/fakedist/generated_test.go @@ -2018,6 +2018,13 @@ func TestLogic_udf( runLogicTest(t, "udf") } +func TestLogic_udf_in_column_defaults( + t *testing.T, +) { + defer leaktest.AfterTest(t)() + runLogicTest(t, "udf_in_column_defaults") +} + func TestLogic_udf_in_constraints( t *testing.T, ) { diff --git a/pkg/sql/logictest/tests/local-legacy-schema-changer/generated_test.go b/pkg/sql/logictest/tests/local-legacy-schema-changer/generated_test.go index 534dc0137514..76c808898c0d 100644 --- a/pkg/sql/logictest/tests/local-legacy-schema-changer/generated_test.go +++ b/pkg/sql/logictest/tests/local-legacy-schema-changer/generated_test.go @@ -1983,6 +1983,13 @@ func TestLogic_udf( runLogicTest(t, "udf") } +func TestLogic_udf_in_column_defaults( + t *testing.T, +) { + defer leaktest.AfterTest(t)() + runLogicTest(t, "udf_in_column_defaults") +} + func TestLogic_udf_in_constraints( t *testing.T, ) { diff --git a/pkg/sql/logictest/tests/local-vec-off/generated_test.go b/pkg/sql/logictest/tests/local-vec-off/generated_test.go index e31ff774878b..cfae275038f5 100644 --- a/pkg/sql/logictest/tests/local-vec-off/generated_test.go +++ b/pkg/sql/logictest/tests/local-vec-off/generated_test.go @@ -2018,6 +2018,13 @@ func TestLogic_udf( runLogicTest(t, "udf") } +func TestLogic_udf_in_column_defaults( + t *testing.T, +) { + defer leaktest.AfterTest(t)() + runLogicTest(t, "udf_in_column_defaults") +} + func TestLogic_udf_in_constraints( t *testing.T, ) { diff --git a/pkg/sql/logictest/tests/local/generated_test.go b/pkg/sql/logictest/tests/local/generated_test.go index 28d588e70f40..fd894d9176a3 100644 --- a/pkg/sql/logictest/tests/local/generated_test.go +++ b/pkg/sql/logictest/tests/local/generated_test.go @@ -2207,6 +2207,13 @@ func TestLogic_udf( runLogicTest(t, "udf") } +func TestLogic_udf_in_column_defaults( + t *testing.T, +) { + defer leaktest.AfterTest(t)() + runLogicTest(t, "udf_in_column_defaults") +} + func TestLogic_udf_in_constraints( t *testing.T, ) { diff --git a/pkg/sql/schemachanger/scbuild/internal/scbuildstmt/alter_table_add_column.go b/pkg/sql/schemachanger/scbuild/internal/scbuildstmt/alter_table_add_column.go index c6b0db5eada2..b09998f1a202 100644 --- a/pkg/sql/schemachanger/scbuild/internal/scbuildstmt/alter_table_add_column.go +++ b/pkg/sql/schemachanger/scbuild/internal/scbuildstmt/alter_table_add_column.go @@ -108,7 +108,7 @@ func alterTableAddColumn( "regional by row partitioning is not supported")) } } - cdd, err := tabledesc.MakeColumnDefDescs(b, d, b.SemaCtx(), b.EvalCtx()) + cdd, err := tabledesc.MakeColumnDefDescs(b, d, b.SemaCtx(), b.EvalCtx(), tree.ColumnDefaultExprInAddColumn) if err != nil { panic(err) } diff --git a/pkg/sql/schemachanger/scexec/scmutationexec/BUILD.bazel b/pkg/sql/schemachanger/scexec/scmutationexec/BUILD.bazel index 5d5a346a31ef..96db5d550952 100644 --- a/pkg/sql/schemachanger/scexec/scmutationexec/BUILD.bazel +++ b/pkg/sql/schemachanger/scexec/scmutationexec/BUILD.bazel @@ -32,6 +32,7 @@ go_library( "//pkg/sql/catalog/descpb", "//pkg/sql/catalog/funcdesc", "//pkg/sql/catalog/schemadesc", + "//pkg/sql/catalog/schemaexpr", "//pkg/sql/catalog/seqexpr", "//pkg/sql/catalog/tabledesc", "//pkg/sql/catalog/typedesc", diff --git a/pkg/sql/schemachanger/scexec/scmutationexec/column.go b/pkg/sql/schemachanger/scexec/scmutationexec/column.go index 2e6e3dd4f991..d38d7b27a35c 100644 --- a/pkg/sql/schemachanger/scexec/scmutationexec/column.go +++ b/pkg/sql/schemachanger/scexec/scmutationexec/column.go @@ -285,7 +285,10 @@ func (i *immediateVisitor) RemoveColumnDefaultExpression( } d := col.ColumnDesc() d.DefaultExpr = nil - return updateColumnExprSequenceUsage(d) + if err := updateColumnExprSequenceUsage(d); err != nil { + return err + } + return updateColumnExprFunctionsUsage(d) } func (i *immediateVisitor) AddColumnOnUpdateExpression( diff --git a/pkg/sql/schemachanger/scexec/scmutationexec/helpers.go b/pkg/sql/schemachanger/scexec/scmutationexec/helpers.go index 4663bc7c6cd0..d33140458da7 100644 --- a/pkg/sql/schemachanger/scexec/scmutationexec/helpers.go +++ b/pkg/sql/schemachanger/scexec/scmutationexec/helpers.go @@ -18,6 +18,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb" "github.com/cockroachdb/cockroach/pkg/sql/catalog/funcdesc" "github.com/cockroachdb/cockroach/pkg/sql/catalog/schemadesc" + "github.com/cockroachdb/cockroach/pkg/sql/catalog/schemaexpr" "github.com/cockroachdb/cockroach/pkg/sql/catalog/seqexpr" "github.com/cockroachdb/cockroach/pkg/sql/catalog/tabledesc" "github.com/cockroachdb/cockroach/pkg/sql/catalog/typedesc" @@ -264,6 +265,22 @@ func updateColumnExprSequenceUsage(d *descpb.ColumnDescriptor) error { return nil } +func updateColumnExprFunctionsUsage(d *descpb.ColumnDescriptor) error { + var all catalog.DescriptorIDSet + for _, expr := range [3]*string{d.ComputeExpr, d.DefaultExpr, d.OnUpdateExpr} { + if expr == nil { + continue + } + ids, err := schemaexpr.GetUDFIDsFromExprStr(*expr) + if err != nil { + return err + } + ids.ForEach(all.Add) + } + d.UsesSequenceIds = all.Ordered() + return nil +} + func sequenceIDsInExpr(expr string) (ids catalog.DescriptorIDSet, _ error) { e, err := parser.ParseExpr(expr) if err != nil { diff --git a/pkg/sql/schemachanger/scexec/scmutationexec/references.go b/pkg/sql/schemachanger/scexec/scmutationexec/references.go index 5b85c61e1ac3..6735898a6725 100644 --- a/pkg/sql/schemachanger/scexec/scmutationexec/references.go +++ b/pkg/sql/schemachanger/scexec/scmutationexec/references.go @@ -281,6 +281,34 @@ func (i *immediateVisitor) RemoveTableConstraintBackReferencesFromFunctions( return nil } +func (i *immediateVisitor) RemoveTableColumnBackReferencesInFunctions( + ctx context.Context, op scop.RemoveTableColumnBackReferencesInFunctions, +) error { + tblDesc, err := i.checkOutTable(ctx, op.BackReferencedTableID) + if err != nil { + return err + } + var fnIDsInUse catalog.DescriptorIDSet + if !tblDesc.Dropped() { + // If table is dropped then there is no functions in use. + fnIDsInUse, err = tblDesc.GetAllReferencedFunctionIDsInColumnExprs(op.BackReferencedColumnID) + if err != nil { + return err + } + } + for _, id := range op.FunctionIDs { + if fnIDsInUse.Contains(id) { + continue + } + fnDesc, err := i.checkOutFunction(ctx, id) + if err != nil { + return err + } + fnDesc.RemoveColumnReference(op.BackReferencedTableID, op.BackReferencedColumnID) + } + return nil +} + // Look through `seqID`'s dependedOnBy slice, find the back-reference to `tblID`, // and update it to either // - upsert `colID` to ColumnIDs field of that back-reference, if `forwardRefs` contains `seqID`; or diff --git a/pkg/sql/schemachanger/scop/immediate_mutation.go b/pkg/sql/schemachanger/scop/immediate_mutation.go index 9d1ffc661e3f..7452a97b4917 100644 --- a/pkg/sql/schemachanger/scop/immediate_mutation.go +++ b/pkg/sql/schemachanger/scop/immediate_mutation.go @@ -516,6 +516,15 @@ type RemoveTableConstraintBackReferencesFromFunctions struct { FunctionIDs []descpb.ID } +// RemoveTableColumnBackReferencesInFunctions removes back-references to columns +// from referenced functions. +type RemoveTableColumnBackReferencesInFunctions struct { + immediateMutationOp + BackReferencedTableID descpb.ID + BackReferencedColumnID descpb.ColumnID + FunctionIDs []descpb.ID +} + // SetColumnName renames a column. type SetColumnName struct { immediateMutationOp diff --git a/pkg/sql/schemachanger/scop/immediate_mutation_visitor_generated.go b/pkg/sql/schemachanger/scop/immediate_mutation_visitor_generated.go index 30774b8eefc7..a27f9b71e11e 100644 --- a/pkg/sql/schemachanger/scop/immediate_mutation_visitor_generated.go +++ b/pkg/sql/schemachanger/scop/immediate_mutation_visitor_generated.go @@ -83,6 +83,7 @@ type ImmediateMutationVisitor interface { RemoveBackReferencesInRelations(context.Context, RemoveBackReferencesInRelations) error AddTableConstraintBackReferencesInFunctions(context.Context, AddTableConstraintBackReferencesInFunctions) error RemoveTableConstraintBackReferencesFromFunctions(context.Context, RemoveTableConstraintBackReferencesFromFunctions) error + RemoveTableColumnBackReferencesInFunctions(context.Context, RemoveTableColumnBackReferencesInFunctions) error SetColumnName(context.Context, SetColumnName) error SetIndexName(context.Context, SetIndexName) error SetConstraintName(context.Context, SetConstraintName) error @@ -424,6 +425,11 @@ func (op RemoveTableConstraintBackReferencesFromFunctions) Visit(ctx context.Con return v.RemoveTableConstraintBackReferencesFromFunctions(ctx, op) } +// Visit is part of the ImmediateMutationOp interface. +func (op RemoveTableColumnBackReferencesInFunctions) Visit(ctx context.Context, v ImmediateMutationVisitor) error { + return v.RemoveTableColumnBackReferencesInFunctions(ctx, op) +} + // Visit is part of the ImmediateMutationOp interface. func (op SetColumnName) Visit(ctx context.Context, v ImmediateMutationVisitor) error { return v.SetColumnName(ctx, op) diff --git a/pkg/sql/schemachanger/scplan/internal/opgen/opgen_column_default_expression.go b/pkg/sql/schemachanger/scplan/internal/opgen/opgen_column_default_expression.go index ba9328399c4d..f7eaaef08543 100644 --- a/pkg/sql/schemachanger/scplan/internal/opgen/opgen_column_default_expression.go +++ b/pkg/sql/schemachanger/scplan/internal/opgen/opgen_column_default_expression.go @@ -75,6 +75,16 @@ func init() { BackReferencedColumnID: this.ColumnID, } }), + emit(func(this *scpb.ColumnDefaultExpression) *scop.RemoveTableColumnBackReferencesInFunctions { + if len(this.UsesFunctionIDs) == 0 { + return nil + } + return &scop.RemoveTableColumnBackReferencesInFunctions{ + FunctionIDs: this.UsesFunctionIDs, + BackReferencedTableID: this.TableID, + BackReferencedColumnID: this.ColumnID, + } + }), ), ), ) diff --git a/pkg/sql/schemachanger/scplan/internal/rules/current/dep_drop_object.go b/pkg/sql/schemachanger/scplan/internal/rules/current/dep_drop_object.go index 91cb9e97e1b7..9531cf369a10 100644 --- a/pkg/sql/schemachanger/scplan/internal/rules/current/dep_drop_object.go +++ b/pkg/sql/schemachanger/scplan/internal/rules/current/dep_drop_object.go @@ -171,6 +171,23 @@ func init() { } }, ) + + registerDepRule( + "descriptor drop right before removing dependent with function refs in columns", + scgraph.SameStagePrecedence, + "referenced-descriptor", "referencing-via-function", + func(from, to NodeVars) rel.Clauses { + fromDescID := rel.Var("fromDescID") + return rel.Clauses{ + from.Type((*scpb.Function)(nil)), + from.DescIDEq(fromDescID), + to.ReferencedFunctionIDsContains(fromDescID), + to.TypeFilter(rulesVersionKey, isSimpleDependent, isWithExpression), + StatusesToAbsent(from, scpb.Status_DROPPED, to, scpb.Status_ABSENT), + } + }, + ) + } // These rules ensure that descriptor, back-reference in parent descriptor, diff --git a/pkg/sql/schemachanger/scplan/internal/rules/current/testdata/deprules b/pkg/sql/schemachanger/scplan/internal/rules/current/testdata/deprules index 06efdd4331f6..0e0c016ea81d 100644 --- a/pkg/sql/schemachanger/scplan/internal/rules/current/testdata/deprules +++ b/pkg/sql/schemachanger/scplan/internal/rules/current/testdata/deprules @@ -2242,6 +2242,20 @@ deprules - $referencing-via-expr-Node[CurrentStatus] = ABSENT - joinTargetNode($referenced-descriptor, $referenced-descriptor-Target, $referenced-descriptor-Node) - joinTargetNode($referencing-via-expr, $referencing-via-expr-Target, $referencing-via-expr-Node) +- name: descriptor drop right before removing dependent with function refs in columns + from: referenced-descriptor-Node + kind: SameStagePrecedence + to: referencing-via-function-Node + query: + - $referenced-descriptor[Type] = '*scpb.Function' + - $referenced-descriptor[DescID] = $fromDescID + - $referencing-via-function[ReferencedFunctionIDs] CONTAINS $fromDescID + - $referencing-via-function[Type] IN ['*scpb.CheckConstraintUnvalidated', '*scpb.ColumnType', '*scpb.ColumnDefaultExpression', '*scpb.ColumnOnUpdateExpression', '*scpb.SecondaryIndexPartial', '*scpb.FunctionParamDefaultExpression'] + - toAbsent($referenced-descriptor-Target, $referencing-via-function-Target) + - $referenced-descriptor-Node[CurrentStatus] = DROPPED + - $referencing-via-function-Node[CurrentStatus] = ABSENT + - joinTargetNode($referenced-descriptor, $referenced-descriptor-Target, $referenced-descriptor-Node) + - joinTargetNode($referencing-via-function, $referencing-via-function-Target, $referencing-via-function-Node) - name: descriptor drop right before removing dependent with type refs in expressions from: referenced-descriptor-Node kind: SameStagePrecedence @@ -5576,6 +5590,20 @@ deprules - $referencing-via-expr-Node[CurrentStatus] = ABSENT - joinTargetNode($referenced-descriptor, $referenced-descriptor-Target, $referenced-descriptor-Node) - joinTargetNode($referencing-via-expr, $referencing-via-expr-Target, $referencing-via-expr-Node) +- name: descriptor drop right before removing dependent with function refs in columns + from: referenced-descriptor-Node + kind: SameStagePrecedence + to: referencing-via-function-Node + query: + - $referenced-descriptor[Type] = '*scpb.Function' + - $referenced-descriptor[DescID] = $fromDescID + - $referencing-via-function[ReferencedFunctionIDs] CONTAINS $fromDescID + - $referencing-via-function[Type] IN ['*scpb.CheckConstraintUnvalidated', '*scpb.ColumnType', '*scpb.ColumnDefaultExpression', '*scpb.ColumnOnUpdateExpression', '*scpb.SecondaryIndexPartial', '*scpb.FunctionParamDefaultExpression'] + - toAbsent($referenced-descriptor-Target, $referencing-via-function-Target) + - $referenced-descriptor-Node[CurrentStatus] = DROPPED + - $referencing-via-function-Node[CurrentStatus] = ABSENT + - joinTargetNode($referenced-descriptor, $referenced-descriptor-Target, $referenced-descriptor-Node) + - joinTargetNode($referencing-via-function, $referencing-via-function-Target, $referencing-via-function-Node) - name: descriptor drop right before removing dependent with type refs in expressions from: referenced-descriptor-Node kind: SameStagePrecedence diff --git a/pkg/sql/schemachanger/scplan/internal/rules/registry.go b/pkg/sql/schemachanger/scplan/internal/rules/registry.go index 6368472d650f..32a835380573 100644 --- a/pkg/sql/schemachanger/scplan/internal/rules/registry.go +++ b/pkg/sql/schemachanger/scplan/internal/rules/registry.go @@ -265,6 +265,13 @@ func (v NodeVars) ReferencedSequenceIDsContains(containedIDVar rel.Var) rel.Clau return v.El.AttrContainsVar(screl.ReferencedSequenceIDs, containedIDVar) } +// ReferencedFunctionIDsContains defines a clause which will bind +// containedIDVar to a descriptor ID contained in v's element's referenced +// function IDs. +func (v NodeVars) ReferencedFunctionIDsContains(containedIDVar rel.Var) rel.Clause { + return v.El.AttrContainsVar(screl.ReferencedFunctionIDs, containedIDVar) +} + func MkNodeVars(elStr string) NodeVars { el := rel.Var(elStr) return NodeVars{ diff --git a/pkg/sql/schemachanger/scplan/internal/scgraph/graph.go b/pkg/sql/schemachanger/scplan/internal/scgraph/graph.go index 857fe512937e..a3db189eb3ac 100644 --- a/pkg/sql/schemachanger/scplan/internal/scgraph/graph.go +++ b/pkg/sql/schemachanger/scplan/internal/scgraph/graph.go @@ -109,6 +109,10 @@ func New(cs scpb.CurrentState) (*Graph, error) { Attrs: []rel.Attr{screl.ReferencedSequenceIDs}, Inverted: true, }, + { + Attrs: []rel.Attr{screl.ReferencedFunctionIDs}, + Inverted: true, + }, }...) if err != nil { return nil, err diff --git a/pkg/sql/schemachanger/scplan/testdata/alter_table_drop_column b/pkg/sql/schemachanger/scplan/testdata/alter_table_drop_column index a435377bd5e6..dcd4348e3646 100644 --- a/pkg/sql/schemachanger/scplan/testdata/alter_table_drop_column +++ b/pkg/sql/schemachanger/scplan/testdata/alter_table_drop_column @@ -8,13 +8,16 @@ CREATE TABLE defaultdb.foo ( UNIQUE INDEX (v2) STORING (v1) ); CREATE VIEW defaultdb.fooview AS SELECT k, v1, v2 FROM defaultdb.foo; +CREATE FUNCTION f1() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +ALTER TABLE foo ADD COLUMN udfcol INT; +ALTER TABLE foo ALTER COLUMN udfcol SET DEFAULT f1(); SET sql_safe_updates = false; ---- ops ALTER TABLE defaultdb.foo DROP COLUMN v1 CASCADE; ---- -StatementPhase stage 1 of 1 with 29 MutationType ops +StatementPhase stage 1 of 1 with 31 MutationType ops transitions: [[Column:{DescID: 107, ColumnID: 2}, ABSENT], PUBLIC] -> WRITE_ONLY [[ColumnName:{DescID: 107, Name: v1, ColumnID: 2}, ABSENT], PUBLIC] -> ABSENT @@ -43,10 +46,12 @@ StatementPhase stage 1 of 1 with 29 MutationType ops [[PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, PUBLIC], ABSENT] -> BACKFILL_ONLY [[IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 3}, PUBLIC], ABSENT] -> PUBLIC [[IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 3}, PUBLIC], ABSENT] -> PUBLIC + [[IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 3}, PUBLIC], ABSENT] -> PUBLIC [[IndexData:{DescID: 107, IndexID: 3}, PUBLIC], ABSENT] -> PUBLIC [[TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_ABSENT], ABSENT] -> DELETE_ONLY [[IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 4}, TRANSIENT_ABSENT], ABSENT] -> PUBLIC [[IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 4}, TRANSIENT_ABSENT], ABSENT] -> PUBLIC + [[IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 4}, TRANSIENT_ABSENT], ABSENT] -> PUBLIC ops: *scop.MakePublicColumnWriteOnly ColumnID: 2 @@ -131,6 +136,12 @@ StatementPhase stage 1 of 1 with 29 MutationType ops IndexID: 3 Kind: 2 TableID: 107 + *scop.AddColumnToIndex + ColumnID: 4 + IndexID: 3 + Kind: 2 + Ordinal: 1 + TableID: 107 *scop.MakeAbsentTempIndexDeleteOnly Index: ConstraintID: 4 @@ -147,6 +158,12 @@ StatementPhase stage 1 of 1 with 29 MutationType ops IndexID: 4 Kind: 2 TableID: 107 + *scop.AddColumnToIndex + ColumnID: 4 + IndexID: 4 + Kind: 2 + Ordinal: 1 + TableID: 107 *scop.DrainDescriptorName Namespace: DatabaseID: 100 @@ -191,14 +208,16 @@ PreCommitPhase stage 1 of 2 with 1 MutationType op [[PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, PUBLIC], BACKFILL_ONLY] -> ABSENT [[IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 3}, PUBLIC], PUBLIC] -> ABSENT [[IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 3}, PUBLIC], PUBLIC] -> ABSENT + [[IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 3}, PUBLIC], PUBLIC] -> ABSENT [[IndexData:{DescID: 107, IndexID: 3}, PUBLIC], PUBLIC] -> ABSENT [[TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_ABSENT], DELETE_ONLY] -> ABSENT [[IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 4}, TRANSIENT_ABSENT], PUBLIC] -> ABSENT [[IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 4}, TRANSIENT_ABSENT], PUBLIC] -> ABSENT + [[IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 4}, TRANSIENT_ABSENT], PUBLIC] -> ABSENT ops: *scop.UndoAllInTxnImmediateMutationOpSideEffects {} -PreCommitPhase stage 2 of 2 with 16 MutationType ops +PreCommitPhase stage 2 of 2 with 18 MutationType ops transitions: [[Column:{DescID: 107, ColumnID: 2}, ABSENT], PUBLIC] -> WRITE_ONLY [[ColumnName:{DescID: 107, Name: v1, ColumnID: 2}, ABSENT], PUBLIC] -> ABSENT @@ -206,10 +225,12 @@ PreCommitPhase stage 2 of 2 with 16 MutationType ops [[PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, PUBLIC], ABSENT] -> BACKFILL_ONLY [[IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 3}, PUBLIC], ABSENT] -> PUBLIC [[IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 3}, PUBLIC], ABSENT] -> PUBLIC + [[IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 3}, PUBLIC], ABSENT] -> PUBLIC [[IndexData:{DescID: 107, IndexID: 3}, PUBLIC], ABSENT] -> PUBLIC [[TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_ABSENT], ABSENT] -> DELETE_ONLY [[IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 4}, TRANSIENT_ABSENT], ABSENT] -> PUBLIC [[IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 4}, TRANSIENT_ABSENT], ABSENT] -> PUBLIC + [[IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 4}, TRANSIENT_ABSENT], ABSENT] -> PUBLIC ops: *scop.MakePublicColumnWriteOnly ColumnID: 2 @@ -241,6 +262,12 @@ PreCommitPhase stage 2 of 2 with 16 MutationType ops IndexID: 3 Kind: 2 TableID: 107 + *scop.AddColumnToIndex + ColumnID: 4 + IndexID: 3 + Kind: 2 + Ordinal: 1 + TableID: 107 *scop.MakeAbsentTempIndexDeleteOnly Index: ConstraintID: 4 @@ -260,6 +287,12 @@ PreCommitPhase stage 2 of 2 with 16 MutationType ops IndexID: 4 Kind: 2 TableID: 107 + *scop.AddColumnToIndex + ColumnID: 4 + IndexID: 4 + Kind: 2 + Ordinal: 1 + TableID: 107 *scop.SetJobStateOnDescriptor DescriptorID: 104 Initialize: true @@ -378,7 +411,7 @@ PostCommitPhase stage 7 of 7 with 1 ValidationType op *scop.ValidateIndex IndexID: 3 TableID: 107 -PostCommitNonRevertiblePhase stage 1 of 3 with 48 MutationType ops +PostCommitNonRevertiblePhase stage 1 of 3 with 49 MutationType ops transitions: [[Column:{DescID: 107, ColumnID: 2}, ABSENT], WRITE_ONLY] -> DELETE_ONLY [[PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, ABSENT], PUBLIC] -> VALIDATED @@ -414,6 +447,7 @@ PostCommitNonRevertiblePhase stage 1 of 3 with 48 MutationType ops [[TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_ABSENT], WRITE_ONLY] -> TRANSIENT_DELETE_ONLY [[IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 4}, TRANSIENT_ABSENT], PUBLIC] -> TRANSIENT_ABSENT [[IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 4}, TRANSIENT_ABSENT], PUBLIC] -> TRANSIENT_ABSENT + [[IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 4}, TRANSIENT_ABSENT], PUBLIC] -> TRANSIENT_ABSENT ops: *scop.MakeWriteOnlyColumnDeleteOnly ColumnID: 2 @@ -497,6 +531,12 @@ PostCommitNonRevertiblePhase stage 1 of 3 with 48 MutationType ops IndexID: 4 Kind: 2 TableID: 107 + *scop.RemoveColumnFromIndex + ColumnID: 4 + IndexID: 4 + Kind: 2 + Ordinal: 1 + TableID: 107 *scop.MakeWriteOnlyIndexDeleteOnly IndexID: 2 TableID: 107 @@ -577,11 +617,12 @@ PostCommitNonRevertiblePhase stage 1 of 3 with 48 MutationType ops *scop.UpdateSchemaChangerJob IsNonCancelable: true JobID: 1 -PostCommitNonRevertiblePhase stage 2 of 3 with 11 MutationType ops +PostCommitNonRevertiblePhase stage 2 of 3 with 12 MutationType ops transitions: [[IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT [[IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT [[IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT + [[IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT [[PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, ABSENT], VALIDATED] -> DELETE_ONLY [[SecondaryIndex:{DescID: 107, IndexID: 2, ConstraintID: 1}, ABSENT], DELETE_ONLY] -> ABSENT [[View:{DescID: 108}, ABSENT], DROPPED] -> ABSENT @@ -613,6 +654,12 @@ PostCommitNonRevertiblePhase stage 2 of 3 with 11 MutationType ops Kind: 2 Ordinal: 1 TableID: 107 + *scop.RemoveColumnFromIndex + ColumnID: 4 + IndexID: 1 + Kind: 2 + Ordinal: 2 + TableID: 107 *scop.SetJobStateOnDescriptor DescriptorID: 104 *scop.SetJobStateOnDescriptor @@ -922,6 +969,26 @@ ALTER TABLE defaultdb.foo DROP COLUMN v1 CASCADE; to: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_ABSENT] kind: Precedence rule: dependents removed before index +- from: [IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 1}, ABSENT] + to: [PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, ABSENT] + kind: Precedence + rule: dependents removed before index +- from: [IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 3}, PUBLIC] + to: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, BACKFILLED] + kind: Precedence + rule: index-column added to index before index is backfilled +- from: [IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 3}, PUBLIC] + to: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, PUBLIC] + kind: Precedence + rule: index dependents exist before index becomes public +- from: [IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 4}, PUBLIC] + to: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, WRITE_ONLY] + kind: Precedence + rule: index-column added to index before temp index receives writes +- from: [IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 4}, TRANSIENT_ABSENT] + to: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_ABSENT] + kind: Precedence + rule: dependents removed before index - from: [IndexData:{DescID: 107, IndexID: 1}, DROPPED] to: [IndexData:{DescID: 107, IndexID: 2}, DROPPED] kind: SameStagePrecedence @@ -978,6 +1045,10 @@ ALTER TABLE defaultdb.foo DROP COLUMN v1 CASCADE; to: [IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 1}, ABSENT] kind: Precedence rule: index drop mutation visible before cleaning up index columns +- from: [PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, DELETE_ONLY] + to: [IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 1}, ABSENT] + kind: Precedence + rule: index drop mutation visible before cleaning up index columns - from: [PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, DELETE_ONLY] to: [PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, ABSENT] kind: PreviousStagePrecedence @@ -1014,6 +1085,10 @@ ALTER TABLE defaultdb.foo DROP COLUMN v1 CASCADE; to: [IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 3}, PUBLIC] kind: Precedence rule: index existence precedes index dependents +- from: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, BACKFILL_ONLY] + to: [IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 3}, PUBLIC] + kind: Precedence + rule: index existence precedes index dependents - from: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, BACKFILL_ONLY] to: [IndexData:{DescID: 107, IndexID: 3}, PUBLIC] kind: SameStagePrecedence @@ -1098,6 +1173,10 @@ ALTER TABLE defaultdb.foo DROP COLUMN v1 CASCADE; to: [IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 4}, PUBLIC] kind: Precedence rule: temp index existence precedes index dependents +- from: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, DELETE_ONLY] + to: [IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 4}, PUBLIC] + kind: Precedence + rule: temp index existence precedes index dependents - from: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, DELETE_ONLY] to: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, WRITE_ONLY] kind: PreviousStagePrecedence @@ -1114,6 +1193,10 @@ ALTER TABLE defaultdb.foo DROP COLUMN v1 CASCADE; to: [IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 4}, TRANSIENT_ABSENT] kind: Precedence rule: index drop mutation visible before cleaning up index columns +- from: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_DELETE_ONLY] + to: [IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 4}, TRANSIENT_ABSENT] + kind: Precedence + rule: index drop mutation visible before cleaning up index columns - from: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_DELETE_ONLY] to: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_ABSENT] kind: PreviousStagePrecedence @@ -1226,7 +1309,7 @@ ALTER TABLE defaultdb.foo DROP COLUMN v1 CASCADE; ops ALTER TABLE defaultdb.foo DROP COLUMN v2 CASCADE; ---- -StatementPhase stage 1 of 1 with 30 MutationType ops +StatementPhase stage 1 of 1 with 32 MutationType ops transitions: [[Column:{DescID: 107, ColumnID: 3}, ABSENT], PUBLIC] -> WRITE_ONLY [[ColumnName:{DescID: 107, Name: v2, ColumnID: 3}, ABSENT], PUBLIC] -> ABSENT @@ -1256,10 +1339,12 @@ StatementPhase stage 1 of 1 with 30 MutationType ops [[PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, PUBLIC], ABSENT] -> BACKFILL_ONLY [[IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 3}, PUBLIC], ABSENT] -> PUBLIC [[IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 3}, PUBLIC], ABSENT] -> PUBLIC + [[IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 3}, PUBLIC], ABSENT] -> PUBLIC [[IndexData:{DescID: 107, IndexID: 3}, PUBLIC], ABSENT] -> PUBLIC [[TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_ABSENT], ABSENT] -> DELETE_ONLY [[IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 4}, TRANSIENT_ABSENT], ABSENT] -> PUBLIC [[IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 4}, TRANSIENT_ABSENT], ABSENT] -> PUBLIC + [[IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 4}, TRANSIENT_ABSENT], ABSENT] -> PUBLIC ops: *scop.MakePublicColumnNotNullValidated ColumnID: 3 @@ -1340,6 +1425,12 @@ StatementPhase stage 1 of 1 with 30 MutationType ops IndexID: 3 Kind: 2 TableID: 107 + *scop.AddColumnToIndex + ColumnID: 4 + IndexID: 3 + Kind: 2 + Ordinal: 1 + TableID: 107 *scop.MakeAbsentTempIndexDeleteOnly Index: ConstraintID: 4 @@ -1356,6 +1447,12 @@ StatementPhase stage 1 of 1 with 30 MutationType ops IndexID: 4 Kind: 2 TableID: 107 + *scop.AddColumnToIndex + ColumnID: 4 + IndexID: 4 + Kind: 2 + Ordinal: 1 + TableID: 107 *scop.MakePublicColumnWriteOnly ColumnID: 3 TableID: 107 @@ -1408,14 +1505,16 @@ PreCommitPhase stage 1 of 2 with 1 MutationType op [[PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, PUBLIC], BACKFILL_ONLY] -> ABSENT [[IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 3}, PUBLIC], PUBLIC] -> ABSENT [[IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 3}, PUBLIC], PUBLIC] -> ABSENT + [[IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 3}, PUBLIC], PUBLIC] -> ABSENT [[IndexData:{DescID: 107, IndexID: 3}, PUBLIC], PUBLIC] -> ABSENT [[TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_ABSENT], DELETE_ONLY] -> ABSENT [[IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 4}, TRANSIENT_ABSENT], PUBLIC] -> ABSENT [[IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 4}, TRANSIENT_ABSENT], PUBLIC] -> ABSENT + [[IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 4}, TRANSIENT_ABSENT], PUBLIC] -> ABSENT ops: *scop.UndoAllInTxnImmediateMutationOpSideEffects {} -PreCommitPhase stage 2 of 2 with 18 MutationType ops +PreCommitPhase stage 2 of 2 with 20 MutationType ops transitions: [[Column:{DescID: 107, ColumnID: 3}, ABSENT], PUBLIC] -> WRITE_ONLY [[ColumnName:{DescID: 107, Name: v2, ColumnID: 3}, ABSENT], PUBLIC] -> ABSENT @@ -1424,10 +1523,12 @@ PreCommitPhase stage 2 of 2 with 18 MutationType ops [[PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, PUBLIC], ABSENT] -> BACKFILL_ONLY [[IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 3}, PUBLIC], ABSENT] -> PUBLIC [[IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 3}, PUBLIC], ABSENT] -> PUBLIC + [[IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 3}, PUBLIC], ABSENT] -> PUBLIC [[IndexData:{DescID: 107, IndexID: 3}, PUBLIC], ABSENT] -> PUBLIC [[TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_ABSENT], ABSENT] -> DELETE_ONLY [[IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 4}, TRANSIENT_ABSENT], ABSENT] -> PUBLIC [[IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 4}, TRANSIENT_ABSENT], ABSENT] -> PUBLIC + [[IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 4}, TRANSIENT_ABSENT], ABSENT] -> PUBLIC ops: *scop.MakePublicColumnNotNullValidated ColumnID: 3 @@ -1455,6 +1556,12 @@ PreCommitPhase stage 2 of 2 with 18 MutationType ops IndexID: 3 Kind: 2 TableID: 107 + *scop.AddColumnToIndex + ColumnID: 4 + IndexID: 3 + Kind: 2 + Ordinal: 1 + TableID: 107 *scop.MakeAbsentTempIndexDeleteOnly Index: ConstraintID: 4 @@ -1474,6 +1581,12 @@ PreCommitPhase stage 2 of 2 with 18 MutationType ops IndexID: 4 Kind: 2 TableID: 107 + *scop.AddColumnToIndex + ColumnID: 4 + IndexID: 4 + Kind: 2 + Ordinal: 1 + TableID: 107 *scop.MakePublicColumnWriteOnly ColumnID: 3 TableID: 107 @@ -1611,7 +1724,7 @@ PostCommitPhase stage 7 of 7 with 1 ValidationType op *scop.ValidateIndex IndexID: 3 TableID: 107 -PostCommitNonRevertiblePhase stage 1 of 3 with 50 MutationType ops +PostCommitNonRevertiblePhase stage 1 of 3 with 51 MutationType ops transitions: [[Column:{DescID: 107, ColumnID: 3}, ABSENT], WRITE_ONLY] -> DELETE_ONLY [[ColumnNotNull:{DescID: 107, ColumnID: 3, IndexID: 0}, ABSENT], VALIDATED] -> ABSENT @@ -1648,6 +1761,7 @@ PostCommitNonRevertiblePhase stage 1 of 3 with 50 MutationType ops [[TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_ABSENT], WRITE_ONLY] -> TRANSIENT_DELETE_ONLY [[IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 4}, TRANSIENT_ABSENT], PUBLIC] -> TRANSIENT_ABSENT [[IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 4}, TRANSIENT_ABSENT], PUBLIC] -> TRANSIENT_ABSENT + [[IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 4}, TRANSIENT_ABSENT], PUBLIC] -> TRANSIENT_ABSENT ops: *scop.RemoveColumnNotNull ColumnID: 3 @@ -1731,6 +1845,12 @@ PostCommitNonRevertiblePhase stage 1 of 3 with 50 MutationType ops IndexID: 4 Kind: 2 TableID: 107 + *scop.RemoveColumnFromIndex + ColumnID: 4 + IndexID: 4 + Kind: 2 + Ordinal: 1 + TableID: 107 *scop.MakeWriteOnlyColumnDeleteOnly ColumnID: 3 TableID: 107 @@ -1816,11 +1936,12 @@ PostCommitNonRevertiblePhase stage 1 of 3 with 50 MutationType ops *scop.UpdateSchemaChangerJob IsNonCancelable: true JobID: 1 -PostCommitNonRevertiblePhase stage 2 of 3 with 12 MutationType ops +PostCommitNonRevertiblePhase stage 2 of 3 with 13 MutationType ops transitions: [[IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT [[IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT [[IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT + [[IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT [[PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, ABSENT], VALIDATED] -> DELETE_ONLY [[SecondaryIndex:{DescID: 107, IndexID: 2, ConstraintID: 1}, ABSENT], DELETE_ONLY] -> ABSENT [[View:{DescID: 108}, ABSENT], DROPPED] -> ABSENT @@ -1852,6 +1973,12 @@ PostCommitNonRevertiblePhase stage 2 of 3 with 12 MutationType ops Kind: 2 Ordinal: 1 TableID: 107 + *scop.RemoveColumnFromIndex + ColumnID: 4 + IndexID: 1 + Kind: 2 + Ordinal: 2 + TableID: 107 *scop.SetJobStateOnDescriptor DescriptorID: 104 *scop.SetJobStateOnDescriptor @@ -2200,6 +2327,26 @@ ALTER TABLE defaultdb.foo DROP COLUMN v2 CASCADE; to: [SecondaryIndex:{DescID: 107, IndexID: 2, ConstraintID: 1}, ABSENT] kind: Precedence rule: dependents removed before index +- from: [IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 1}, ABSENT] + to: [PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, ABSENT] + kind: Precedence + rule: dependents removed before index +- from: [IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 3}, PUBLIC] + to: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, BACKFILLED] + kind: Precedence + rule: index-column added to index before index is backfilled +- from: [IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 3}, PUBLIC] + to: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, PUBLIC] + kind: Precedence + rule: index dependents exist before index becomes public +- from: [IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 4}, PUBLIC] + to: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, WRITE_ONLY] + kind: Precedence + rule: index-column added to index before temp index receives writes +- from: [IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 4}, TRANSIENT_ABSENT] + to: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_ABSENT] + kind: Precedence + rule: dependents removed before index - from: [IndexData:{DescID: 107, IndexID: 1}, DROPPED] to: [IndexData:{DescID: 107, IndexID: 2}, DROPPED] kind: SameStagePrecedence @@ -2256,6 +2403,10 @@ ALTER TABLE defaultdb.foo DROP COLUMN v2 CASCADE; to: [IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 1}, ABSENT] kind: Precedence rule: index drop mutation visible before cleaning up index columns +- from: [PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, DELETE_ONLY] + to: [IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 1}, ABSENT] + kind: Precedence + rule: index drop mutation visible before cleaning up index columns - from: [PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, DELETE_ONLY] to: [PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, ABSENT] kind: PreviousStagePrecedence @@ -2292,6 +2443,10 @@ ALTER TABLE defaultdb.foo DROP COLUMN v2 CASCADE; to: [IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 3}, PUBLIC] kind: Precedence rule: index existence precedes index dependents +- from: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, BACKFILL_ONLY] + to: [IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 3}, PUBLIC] + kind: Precedence + rule: index existence precedes index dependents - from: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, BACKFILL_ONLY] to: [IndexData:{DescID: 107, IndexID: 3}, PUBLIC] kind: SameStagePrecedence @@ -2380,6 +2535,10 @@ ALTER TABLE defaultdb.foo DROP COLUMN v2 CASCADE; to: [IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 4}, PUBLIC] kind: Precedence rule: temp index existence precedes index dependents +- from: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, DELETE_ONLY] + to: [IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 4}, PUBLIC] + kind: Precedence + rule: temp index existence precedes index dependents - from: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, DELETE_ONLY] to: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, WRITE_ONLY] kind: PreviousStagePrecedence @@ -2396,6 +2555,10 @@ ALTER TABLE defaultdb.foo DROP COLUMN v2 CASCADE; to: [IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 4}, TRANSIENT_ABSENT] kind: Precedence rule: index drop mutation visible before cleaning up index columns +- from: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_DELETE_ONLY] + to: [IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 4}, TRANSIENT_ABSENT] + kind: Precedence + rule: index drop mutation visible before cleaning up index columns - from: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_DELETE_ONLY] to: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_ABSENT] kind: PreviousStagePrecedence @@ -2504,3 +2667,673 @@ ALTER TABLE defaultdb.foo DROP COLUMN v2 CASCADE; to: [View:{DescID: 108}, ABSENT] kind: PreviousStagePrecedence rule: descriptor dropped in transaction before removal + +ops +ALTER TABLE defaultdb.foo DROP COLUMN udfcol; +---- +StatementPhase stage 1 of 1 with 10 MutationType ops + transitions: + [[Column:{DescID: 107, ColumnID: 4}, ABSENT], PUBLIC] -> WRITE_ONLY + [[ColumnName:{DescID: 107, Name: udfcol, ColumnID: 4}, ABSENT], PUBLIC] -> ABSENT + [[PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, PUBLIC], ABSENT] -> BACKFILL_ONLY + [[IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 3}, PUBLIC], ABSENT] -> PUBLIC + [[IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 3}, PUBLIC], ABSENT] -> PUBLIC + [[IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 3}, PUBLIC], ABSENT] -> PUBLIC + [[IndexData:{DescID: 107, IndexID: 3}, PUBLIC], ABSENT] -> PUBLIC + [[TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_ABSENT], ABSENT] -> DELETE_ONLY + [[IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 4}, TRANSIENT_ABSENT], ABSENT] -> PUBLIC + [[IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 4}, TRANSIENT_ABSENT], ABSENT] -> PUBLIC + [[IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 4}, TRANSIENT_ABSENT], ABSENT] -> PUBLIC + ops: + *scop.MakePublicColumnWriteOnly + ColumnID: 4 + TableID: 107 + *scop.SetColumnName + ColumnID: 4 + Name: crdb_internal_column_4_name_placeholder + TableID: 107 + *scop.MakeAbsentIndexBackfilling + Index: + ConstraintID: 3 + IndexID: 3 + IsUnique: true + SourceIndexID: 1 + TableID: 107 + TemporaryIndexID: 4 + *scop.AddColumnToIndex + ColumnID: 1 + IndexID: 3 + TableID: 107 + *scop.AddColumnToIndex + ColumnID: 2 + IndexID: 3 + Kind: 2 + TableID: 107 + *scop.AddColumnToIndex + ColumnID: 3 + IndexID: 3 + Kind: 2 + Ordinal: 1 + TableID: 107 + *scop.MakeAbsentTempIndexDeleteOnly + Index: + ConstraintID: 4 + IndexID: 4 + IsUnique: true + SourceIndexID: 1 + TableID: 107 + *scop.AddColumnToIndex + ColumnID: 1 + IndexID: 4 + TableID: 107 + *scop.AddColumnToIndex + ColumnID: 2 + IndexID: 4 + Kind: 2 + TableID: 107 + *scop.AddColumnToIndex + ColumnID: 3 + IndexID: 4 + Kind: 2 + Ordinal: 1 + TableID: 107 +PreCommitPhase stage 1 of 2 with 1 MutationType op + transitions: + [[Column:{DescID: 107, ColumnID: 4}, ABSENT], WRITE_ONLY] -> PUBLIC + [[ColumnName:{DescID: 107, Name: udfcol, ColumnID: 4}, ABSENT], ABSENT] -> PUBLIC + [[PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, PUBLIC], BACKFILL_ONLY] -> ABSENT + [[IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 3}, PUBLIC], PUBLIC] -> ABSENT + [[IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 3}, PUBLIC], PUBLIC] -> ABSENT + [[IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 3}, PUBLIC], PUBLIC] -> ABSENT + [[IndexData:{DescID: 107, IndexID: 3}, PUBLIC], PUBLIC] -> ABSENT + [[TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_ABSENT], DELETE_ONLY] -> ABSENT + [[IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 4}, TRANSIENT_ABSENT], PUBLIC] -> ABSENT + [[IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 4}, TRANSIENT_ABSENT], PUBLIC] -> ABSENT + [[IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 4}, TRANSIENT_ABSENT], PUBLIC] -> ABSENT + ops: + *scop.UndoAllInTxnImmediateMutationOpSideEffects + {} +PreCommitPhase stage 2 of 2 with 15 MutationType ops + transitions: + [[Column:{DescID: 107, ColumnID: 4}, ABSENT], PUBLIC] -> WRITE_ONLY + [[ColumnName:{DescID: 107, Name: udfcol, ColumnID: 4}, ABSENT], PUBLIC] -> ABSENT + [[PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, PUBLIC], ABSENT] -> BACKFILL_ONLY + [[IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 3}, PUBLIC], ABSENT] -> PUBLIC + [[IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 3}, PUBLIC], ABSENT] -> PUBLIC + [[IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 3}, PUBLIC], ABSENT] -> PUBLIC + [[IndexData:{DescID: 107, IndexID: 3}, PUBLIC], ABSENT] -> PUBLIC + [[TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_ABSENT], ABSENT] -> DELETE_ONLY + [[IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 4}, TRANSIENT_ABSENT], ABSENT] -> PUBLIC + [[IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 4}, TRANSIENT_ABSENT], ABSENT] -> PUBLIC + [[IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 4}, TRANSIENT_ABSENT], ABSENT] -> PUBLIC + ops: + *scop.MakePublicColumnWriteOnly + ColumnID: 4 + TableID: 107 + *scop.SetColumnName + ColumnID: 4 + Name: crdb_internal_column_4_name_placeholder + TableID: 107 + *scop.MakeAbsentIndexBackfilling + Index: + ConstraintID: 3 + IndexID: 3 + IsUnique: true + SourceIndexID: 1 + TableID: 107 + TemporaryIndexID: 4 + *scop.MaybeAddSplitForIndex + IndexID: 3 + TableID: 107 + *scop.AddColumnToIndex + ColumnID: 1 + IndexID: 3 + TableID: 107 + *scop.AddColumnToIndex + ColumnID: 2 + IndexID: 3 + Kind: 2 + TableID: 107 + *scop.AddColumnToIndex + ColumnID: 3 + IndexID: 3 + Kind: 2 + Ordinal: 1 + TableID: 107 + *scop.MakeAbsentTempIndexDeleteOnly + Index: + ConstraintID: 4 + IndexID: 4 + IsUnique: true + SourceIndexID: 1 + TableID: 107 + *scop.MaybeAddSplitForIndex + IndexID: 4 + TableID: 107 + *scop.AddColumnToIndex + ColumnID: 1 + IndexID: 4 + TableID: 107 + *scop.AddColumnToIndex + ColumnID: 2 + IndexID: 4 + Kind: 2 + TableID: 107 + *scop.AddColumnToIndex + ColumnID: 3 + IndexID: 4 + Kind: 2 + Ordinal: 1 + TableID: 107 + *scop.SetJobStateOnDescriptor + DescriptorID: 107 + Initialize: true + *scop.SetJobStateOnDescriptor + DescriptorID: 109 + Initialize: true + *scop.CreateSchemaChangerJob + Authorization: + UserName: root + DescriptorIDs: + - 107 + - 109 + JobID: 1 + RunningStatus: PostCommitPhase stage 1 of 7 with 1 MutationType op pending + Statements: + - statement: ALTER TABLE defaultdb.foo DROP COLUMN udfcol + redactedstatement: ALTER TABLE ‹defaultdb›.public.‹foo› DROP COLUMN ‹udfcol› + statementtag: ALTER TABLE +PostCommitPhase stage 1 of 7 with 4 MutationType ops + transitions: + [[TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_ABSENT], DELETE_ONLY] -> WRITE_ONLY + [[IndexData:{DescID: 107, IndexID: 4}, TRANSIENT_ABSENT], ABSENT] -> PUBLIC + ops: + *scop.MakeDeleteOnlyIndexWriteOnly + IndexID: 4 + TableID: 107 + *scop.SetJobStateOnDescriptor + DescriptorID: 107 + *scop.SetJobStateOnDescriptor + DescriptorID: 109 + *scop.UpdateSchemaChangerJob + JobID: 1 +PostCommitPhase stage 2 of 7 with 1 BackfillType op + transitions: + [[PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, PUBLIC], BACKFILL_ONLY] -> BACKFILLED + ops: + *scop.BackfillIndex + IndexID: 3 + SourceIndexID: 1 + TableID: 107 +PostCommitPhase stage 3 of 7 with 4 MutationType ops + transitions: + [[PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, PUBLIC], BACKFILLED] -> DELETE_ONLY + ops: + *scop.MakeBackfillingIndexDeleteOnly + IndexID: 3 + TableID: 107 + *scop.SetJobStateOnDescriptor + DescriptorID: 107 + *scop.SetJobStateOnDescriptor + DescriptorID: 109 + *scop.UpdateSchemaChangerJob + JobID: 1 +PostCommitPhase stage 4 of 7 with 4 MutationType ops + transitions: + [[PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, PUBLIC], DELETE_ONLY] -> MERGE_ONLY + ops: + *scop.MakeBackfilledIndexMerging + IndexID: 3 + TableID: 107 + *scop.SetJobStateOnDescriptor + DescriptorID: 107 + *scop.SetJobStateOnDescriptor + DescriptorID: 109 + *scop.UpdateSchemaChangerJob + JobID: 1 +PostCommitPhase stage 5 of 7 with 1 BackfillType op + transitions: + [[PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, PUBLIC], MERGE_ONLY] -> MERGED + ops: + *scop.MergeIndex + BackfilledIndexID: 3 + TableID: 107 + TemporaryIndexID: 4 +PostCommitPhase stage 6 of 7 with 4 MutationType ops + transitions: + [[PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, PUBLIC], MERGED] -> WRITE_ONLY + ops: + *scop.MakeMergedIndexWriteOnly + IndexID: 3 + TableID: 107 + *scop.SetJobStateOnDescriptor + DescriptorID: 107 + *scop.SetJobStateOnDescriptor + DescriptorID: 109 + *scop.UpdateSchemaChangerJob + JobID: 1 +PostCommitPhase stage 7 of 7 with 1 ValidationType op + transitions: + [[PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, PUBLIC], WRITE_ONLY] -> VALIDATED + ops: + *scop.ValidateIndex + IndexID: 3 + TableID: 107 +PostCommitNonRevertiblePhase stage 1 of 3 with 12 MutationType ops + transitions: + [[Column:{DescID: 107, ColumnID: 4}, ABSENT], WRITE_ONLY] -> DELETE_ONLY + [[PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, ABSENT], PUBLIC] -> VALIDATED + [[IndexName:{DescID: 107, Name: foo_pkey, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT + [[PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, PUBLIC], VALIDATED] -> PUBLIC + [[IndexName:{DescID: 107, Name: foo_pkey, IndexID: 3}, PUBLIC], ABSENT] -> PUBLIC + [[TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_ABSENT], WRITE_ONLY] -> TRANSIENT_DELETE_ONLY + [[IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 4}, TRANSIENT_ABSENT], PUBLIC] -> TRANSIENT_ABSENT + [[IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 4}, TRANSIENT_ABSENT], PUBLIC] -> TRANSIENT_ABSENT + [[IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 4}, TRANSIENT_ABSENT], PUBLIC] -> TRANSIENT_ABSENT + ops: + *scop.MakeWriteOnlyColumnDeleteOnly + ColumnID: 4 + TableID: 107 + *scop.MakePublicPrimaryIndexWriteOnly + IndexID: 1 + TableID: 107 + *scop.SetIndexName + IndexID: 1 + Name: crdb_internal_index_1_name_placeholder + TableID: 107 + *scop.SetIndexName + IndexID: 3 + Name: foo_pkey + TableID: 107 + *scop.MakeWriteOnlyIndexDeleteOnly + IndexID: 4 + TableID: 107 + *scop.RemoveColumnFromIndex + ColumnID: 1 + IndexID: 4 + TableID: 107 + *scop.RemoveColumnFromIndex + ColumnID: 2 + IndexID: 4 + Kind: 2 + TableID: 107 + *scop.RemoveColumnFromIndex + ColumnID: 3 + IndexID: 4 + Kind: 2 + Ordinal: 1 + TableID: 107 + *scop.MakeValidatedPrimaryIndexPublic + IndexID: 3 + TableID: 107 + *scop.SetJobStateOnDescriptor + DescriptorID: 107 + *scop.SetJobStateOnDescriptor + DescriptorID: 109 + *scop.UpdateSchemaChangerJob + IsNonCancelable: true + JobID: 1 +PostCommitNonRevertiblePhase stage 2 of 3 with 9 MutationType ops + transitions: + [[IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT + [[IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT + [[IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT + [[IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT + [[PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, ABSENT], VALIDATED] -> DELETE_ONLY + [[TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_ABSENT], TRANSIENT_DELETE_ONLY] -> TRANSIENT_ABSENT + ops: + *scop.MakeIndexAbsent + IndexID: 4 + TableID: 107 + *scop.MakeWriteOnlyIndexDeleteOnly + IndexID: 1 + TableID: 107 + *scop.RemoveColumnFromIndex + ColumnID: 1 + IndexID: 1 + TableID: 107 + *scop.RemoveColumnFromIndex + ColumnID: 2 + IndexID: 1 + Kind: 2 + TableID: 107 + *scop.RemoveColumnFromIndex + ColumnID: 3 + IndexID: 1 + Kind: 2 + Ordinal: 1 + TableID: 107 + *scop.RemoveColumnFromIndex + ColumnID: 4 + IndexID: 1 + Kind: 2 + Ordinal: 2 + TableID: 107 + *scop.SetJobStateOnDescriptor + DescriptorID: 107 + *scop.SetJobStateOnDescriptor + DescriptorID: 109 + *scop.UpdateSchemaChangerJob + IsNonCancelable: true + JobID: 1 +PostCommitNonRevertiblePhase stage 3 of 3 with 9 MutationType ops + transitions: + [[Column:{DescID: 107, ColumnID: 4}, ABSENT], DELETE_ONLY] -> ABSENT + [[ColumnType:{DescID: 107, ColumnFamilyID: 0, ColumnID: 4}, ABSENT], PUBLIC] -> ABSENT + [[ColumnDefaultExpression:{DescID: 107, ColumnID: 4, ReferencedFunctionIDs: [109]}, ABSENT], PUBLIC] -> ABSENT + [[PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, ABSENT], DELETE_ONLY] -> ABSENT + [[IndexData:{DescID: 107, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT + [[IndexData:{DescID: 107, IndexID: 4}, TRANSIENT_ABSENT], PUBLIC] -> TRANSIENT_ABSENT + ops: + *scop.RemoveColumnDefaultExpression + ColumnID: 4 + TableID: 107 + *scop.RemoveTableColumnBackReferencesInFunctions + BackReferencedColumnID: 4 + BackReferencedTableID: 107 + FunctionIDs: + - 109 + *scop.MakeIndexAbsent + IndexID: 1 + TableID: 107 + *scop.CreateGCJobForIndex + IndexID: 1 + StatementForDropJob: + Statement: ALTER TABLE defaultdb.public.foo DROP COLUMN udfcol + TableID: 107 + *scop.CreateGCJobForIndex + IndexID: 4 + StatementForDropJob: + Statement: ALTER TABLE defaultdb.public.foo DROP COLUMN udfcol + TableID: 107 + *scop.MakeDeleteOnlyColumnAbsent + ColumnID: 4 + TableID: 107 + *scop.RemoveJobStateFromDescriptor + DescriptorID: 107 + JobID: 1 + *scop.RemoveJobStateFromDescriptor + DescriptorID: 109 + JobID: 1 + *scop.UpdateSchemaChangerJob + DescriptorIDsToRemove: + - 107 + - 109 + IsNonCancelable: true + JobID: 1 + +deps +ALTER TABLE defaultdb.foo DROP COLUMN udfcol; +---- +- from: [Column:{DescID: 107, ColumnID: 4}, DELETE_ONLY] + to: [Column:{DescID: 107, ColumnID: 4}, ABSENT] + kind: PreviousStagePrecedence + rule: Column transitions to ABSENT uphold 2-version invariant: DELETE_ONLY->ABSENT +- from: [Column:{DescID: 107, ColumnID: 4}, PUBLIC] + to: [Column:{DescID: 107, ColumnID: 4}, WRITE_ONLY] + kind: PreviousStagePrecedence + rule: Column transitions to ABSENT uphold 2-version invariant: PUBLIC->WRITE_ONLY +- from: [Column:{DescID: 107, ColumnID: 4}, WRITE_ONLY] + to: [Column:{DescID: 107, ColumnID: 4}, DELETE_ONLY] + kind: PreviousStagePrecedence + rule: Column transitions to ABSENT uphold 2-version invariant: WRITE_ONLY->DELETE_ONLY +- from: [Column:{DescID: 107, ColumnID: 4}, WRITE_ONLY] + to: [ColumnDefaultExpression:{DescID: 107, ColumnID: 4, ReferencedFunctionIDs: [109]}, ABSENT] + kind: Precedence + rule: column no longer public before dependents +- from: [Column:{DescID: 107, ColumnID: 4}, WRITE_ONLY] + to: [ColumnName:{DescID: 107, Name: udfcol, ColumnID: 4}, ABSENT] + kind: Precedence + rule: column no longer public before dependents +- from: [Column:{DescID: 107, ColumnID: 4}, WRITE_ONLY] + to: [ColumnType:{DescID: 107, ColumnFamilyID: 0, ColumnID: 4}, ABSENT] + kind: Precedence + rule: column no longer public before dependents +- from: [Column:{DescID: 107, ColumnID: 4}, WRITE_ONLY] + to: [IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 1}, ABSENT] + kind: Precedence + rule: column no longer public before dependents +- from: [ColumnDefaultExpression:{DescID: 107, ColumnID: 4, ReferencedFunctionIDs: [109]}, ABSENT] + to: [Column:{DescID: 107, ColumnID: 4}, ABSENT] + kind: Precedence + rule: dependents removed before column +- from: [ColumnDefaultExpression:{DescID: 107, ColumnID: 4, ReferencedFunctionIDs: [109]}, ABSENT] + to: [ColumnType:{DescID: 107, ColumnFamilyID: 0, ColumnID: 4}, ABSENT] + kind: SameStagePrecedence + rule: column type dependents removed right before column type +- from: [ColumnName:{DescID: 107, Name: udfcol, ColumnID: 4}, ABSENT] + to: [Column:{DescID: 107, ColumnID: 4}, ABSENT] + kind: Precedence + rule: dependents removed before column +- from: [ColumnType:{DescID: 107, ColumnFamilyID: 0, ColumnID: 4}, ABSENT] + to: [Column:{DescID: 107, ColumnID: 4}, ABSENT] + kind: SameStagePrecedence + rules: [dependents removed before column; column type removed right before column when not dropping relation] +- from: [IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 1}, ABSENT] + to: [PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, ABSENT] + kind: Precedence + rule: dependents removed before index +- from: [IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 3}, PUBLIC] + to: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, BACKFILLED] + kind: Precedence + rule: index-column added to index before index is backfilled +- from: [IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 3}, PUBLIC] + to: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, PUBLIC] + kind: Precedence + rule: index dependents exist before index becomes public +- from: [IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 4}, PUBLIC] + to: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, WRITE_ONLY] + kind: Precedence + rule: index-column added to index before temp index receives writes +- from: [IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 4}, TRANSIENT_ABSENT] + to: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_ABSENT] + kind: Precedence + rule: dependents removed before index +- from: [IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 1}, ABSENT] + to: [PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, ABSENT] + kind: Precedence + rule: dependents removed before index +- from: [IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 3}, PUBLIC] + to: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, BACKFILLED] + kind: Precedence + rule: index-column added to index before index is backfilled +- from: [IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 3}, PUBLIC] + to: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, PUBLIC] + kind: Precedence + rule: index dependents exist before index becomes public +- from: [IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 4}, PUBLIC] + to: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, WRITE_ONLY] + kind: Precedence + rule: index-column added to index before temp index receives writes +- from: [IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 4}, TRANSIENT_ABSENT] + to: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_ABSENT] + kind: Precedence + rule: dependents removed before index +- from: [IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 1}, ABSENT] + to: [PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, ABSENT] + kind: Precedence + rule: dependents removed before index +- from: [IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 3}, PUBLIC] + to: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, BACKFILLED] + kind: Precedence + rule: index-column added to index before index is backfilled +- from: [IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 3}, PUBLIC] + to: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, PUBLIC] + kind: Precedence + rule: index dependents exist before index becomes public +- from: [IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 4}, PUBLIC] + to: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, WRITE_ONLY] + kind: Precedence + rule: index-column added to index before temp index receives writes +- from: [IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 4}, TRANSIENT_ABSENT] + to: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_ABSENT] + kind: Precedence + rule: dependents removed before index +- from: [IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 1}, ABSENT] + to: [Column:{DescID: 107, ColumnID: 4}, ABSENT] + kind: Precedence + rule: dependents removed before column +- from: [IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 1}, ABSENT] + to: [PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, ABSENT] + kind: Precedence + rule: dependents removed before index +- from: [IndexData:{DescID: 107, IndexID: 1}, DROPPED] + to: [IndexData:{DescID: 107, IndexID: 4}, TRANSIENT_DROPPED] + kind: SameStagePrecedence + rule: schedule all GC jobs for a descriptor in the same stage +- from: [IndexName:{DescID: 107, Name: foo_pkey, IndexID: 1}, ABSENT] + to: [PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, ABSENT] + kind: Precedence + rule: dependents removed before index +- from: [IndexName:{DescID: 107, Name: foo_pkey, IndexID: 3}, PUBLIC] + to: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, PUBLIC] + kind: SameStagePrecedence + rules: [index dependents exist before index becomes public; primary index named right before index becomes public] +- from: [PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, ABSENT] + to: [Column:{DescID: 107, ColumnID: 4}, ABSENT] + kind: Precedence + rule: indexes containing column reach absent before column +- from: [PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, ABSENT] + to: [IndexData:{DescID: 107, IndexID: 1}, DROPPED] + kind: Precedence + rule: index removed before garbage collection +- from: [PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, DELETE_ONLY] + to: [IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 1}, ABSENT] + kind: Precedence + rule: index drop mutation visible before cleaning up index columns +- from: [PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, DELETE_ONLY] + to: [IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 1}, ABSENT] + kind: Precedence + rule: index drop mutation visible before cleaning up index columns +- from: [PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, DELETE_ONLY] + to: [IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 1}, ABSENT] + kind: Precedence + rule: index drop mutation visible before cleaning up index columns +- from: [PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, DELETE_ONLY] + to: [IndexColumn:{DescID: 107, ColumnID: 4, IndexID: 1}, ABSENT] + kind: Precedence + rule: index drop mutation visible before cleaning up index columns +- from: [PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, DELETE_ONLY] + to: [PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, ABSENT] + kind: PreviousStagePrecedence + rule: PrimaryIndex transitions to ABSENT uphold 2-version invariant: DELETE_ONLY->ABSENT +- from: [PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, PUBLIC] + to: [PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, VALIDATED] + kind: PreviousStagePrecedence + rule: PrimaryIndex transitions to ABSENT uphold 2-version invariant: PUBLIC->VALIDATED +- from: [PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, VALIDATED] + to: [IndexName:{DescID: 107, Name: foo_pkey, IndexID: 1}, ABSENT] + kind: Precedence + rule: index no longer public before dependents, excluding columns +- from: [PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, VALIDATED] + to: [PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, WRITE_ONLY] + kind: PreviousStagePrecedence + rule: PrimaryIndex transitions to ABSENT uphold 2-version invariant: VALIDATED->WRITE_ONLY +- from: [PrimaryIndex:{DescID: 107, IndexID: 1, ConstraintID: 2}, VALIDATED] + to: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, PUBLIC] + kind: SameStagePrecedence + rule: primary index swap +- from: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, ABSENT] + to: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, BACKFILL_ONLY] + kind: PreviousStagePrecedence + rule: PrimaryIndex transitions to PUBLIC uphold 2-version invariant: ABSENT->BACKFILL_ONLY +- from: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, BACKFILLED] + to: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, DELETE_ONLY] + kind: PreviousStagePrecedence + rule: PrimaryIndex transitions to PUBLIC uphold 2-version invariant: BACKFILLED->DELETE_ONLY +- from: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, BACKFILL_ONLY] + to: [IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 3}, PUBLIC] + kind: Precedence + rule: index existence precedes index dependents +- from: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, BACKFILL_ONLY] + to: [IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 3}, PUBLIC] + kind: Precedence + rule: index existence precedes index dependents +- from: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, BACKFILL_ONLY] + to: [IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 3}, PUBLIC] + kind: Precedence + rule: index existence precedes index dependents +- from: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, BACKFILL_ONLY] + to: [IndexData:{DescID: 107, IndexID: 3}, PUBLIC] + kind: SameStagePrecedence + rule: index data exists as soon as index accepts backfills +- from: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, BACKFILL_ONLY] + to: [IndexName:{DescID: 107, Name: foo_pkey, IndexID: 3}, PUBLIC] + kind: Precedence + rule: index existence precedes index dependents +- from: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, BACKFILL_ONLY] + to: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, BACKFILLED] + kind: PreviousStagePrecedence + rule: PrimaryIndex transitions to PUBLIC uphold 2-version invariant: BACKFILL_ONLY->BACKFILLED +- from: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, DELETE_ONLY] + to: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, MERGE_ONLY] + kind: PreviousStagePrecedence + rule: PrimaryIndex transitions to PUBLIC uphold 2-version invariant: DELETE_ONLY->MERGE_ONLY +- from: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, MERGED] + to: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, WRITE_ONLY] + kind: PreviousStagePrecedence + rule: PrimaryIndex transitions to PUBLIC uphold 2-version invariant: MERGED->WRITE_ONLY +- from: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, MERGE_ONLY] + to: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, MERGED] + kind: PreviousStagePrecedence + rule: PrimaryIndex transitions to PUBLIC uphold 2-version invariant: MERGE_ONLY->MERGED +- from: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, VALIDATED] + to: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, PUBLIC] + kind: PreviousStagePrecedence + rule: PrimaryIndex transitions to PUBLIC uphold 2-version invariant: VALIDATED->PUBLIC +- from: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, WRITE_ONLY] + to: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, VALIDATED] + kind: PreviousStagePrecedence + rule: PrimaryIndex transitions to PUBLIC uphold 2-version invariant: WRITE_ONLY->VALIDATED +- from: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, ABSENT] + to: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, DELETE_ONLY] + kind: PreviousStagePrecedence + rule: TemporaryIndex transitions to TRANSIENT_ABSENT uphold 2-version invariant: ABSENT->DELETE_ONLY +- from: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, DELETE_ONLY] + to: [IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 4}, PUBLIC] + kind: Precedence + rule: temp index existence precedes index dependents +- from: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, DELETE_ONLY] + to: [IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 4}, PUBLIC] + kind: Precedence + rule: temp index existence precedes index dependents +- from: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, DELETE_ONLY] + to: [IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 4}, PUBLIC] + kind: Precedence + rule: temp index existence precedes index dependents +- from: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, DELETE_ONLY] + to: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, WRITE_ONLY] + kind: PreviousStagePrecedence + rule: TemporaryIndex transitions to TRANSIENT_ABSENT uphold 2-version invariant: DELETE_ONLY->WRITE_ONLY +- from: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_ABSENT] + to: [IndexData:{DescID: 107, IndexID: 4}, TRANSIENT_DROPPED] + kind: Precedence + rule: index removed before garbage collection +- from: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_DELETE_ONLY] + to: [IndexColumn:{DescID: 107, ColumnID: 1, IndexID: 4}, TRANSIENT_ABSENT] + kind: Precedence + rule: index drop mutation visible before cleaning up index columns +- from: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_DELETE_ONLY] + to: [IndexColumn:{DescID: 107, ColumnID: 2, IndexID: 4}, TRANSIENT_ABSENT] + kind: Precedence + rule: index drop mutation visible before cleaning up index columns +- from: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_DELETE_ONLY] + to: [IndexColumn:{DescID: 107, ColumnID: 3, IndexID: 4}, TRANSIENT_ABSENT] + kind: Precedence + rule: index drop mutation visible before cleaning up index columns +- from: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_DELETE_ONLY] + to: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_ABSENT] + kind: PreviousStagePrecedence + rule: TemporaryIndex transitions to TRANSIENT_ABSENT uphold 2-version invariant: TRANSIENT_DELETE_ONLY->TRANSIENT_ABSENT +- from: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, WRITE_ONLY] + to: [IndexData:{DescID: 107, IndexID: 4}, PUBLIC] + kind: SameStagePrecedence + rule: temp index data exists as soon as temp index accepts writes +- from: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, WRITE_ONLY] + to: [PrimaryIndex:{DescID: 107, IndexID: 3, ConstraintID: 3, TemporaryIndexID: 4, SourceIndexID: 1}, BACKFILLED] + kind: Precedence + rule: temp index is WRITE_ONLY before backfill +- from: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, WRITE_ONLY] + to: [TemporaryIndex:{DescID: 107, IndexID: 4, ConstraintID: 4, SourceIndexID: 1}, TRANSIENT_DELETE_ONLY] + kind: PreviousStagePrecedence + rule: TemporaryIndex transitions to TRANSIENT_ABSENT uphold 2-version invariant: WRITE_ONLY->TRANSIENT_DELETE_ONLY diff --git a/pkg/sql/schemachanger/scplan/testdata/drop_table b/pkg/sql/schemachanger/scplan/testdata/drop_table index 42ebb3874fbe..0e1e7376648a 100644 --- a/pkg/sql/schemachanger/scplan/testdata/drop_table +++ b/pkg/sql/schemachanger/scplan/testdata/drop_table @@ -24,6 +24,9 @@ COMMENT ON TABLE defaultdb.shipments IS 'shipment is important'; COMMENT ON COLUMN defaultdb.shipments.tracking_number IS 'tracking_number is a must'; COMMENT ON INDEX defaultdb.shipments@shipments_pkey IS 'pkey is good'; COMMENT ON CONSTRAINT fk_customers ON defaultdb.shipments IS 'customer is not god'; +CREATE FUNCTION defaultdb.f1() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +ALTER TABLE shipments ADD COLUMN udfcol INT; +ALTER TABLE shipments ALTER COLUMN udfcol SET DEFAULT f1(); ---- ops @@ -152,7 +155,7 @@ PreCommitPhase stage 1 of 2 with 1 MutationType op ops: *scop.UndoAllInTxnImmediateMutationOpSideEffects {} -PreCommitPhase stage 2 of 2 with 111 MutationType ops +PreCommitPhase stage 2 of 2 with 119 MutationType ops transitions: [[Namespace:{DescID: 109, Name: shipments, ReferencedDescID: 100}, ABSENT], PUBLIC] -> ABSENT [[Owner:{DescID: 109}, ABSENT], PUBLIC] -> ABSENT @@ -182,6 +185,10 @@ PreCommitPhase stage 2 of 2 with 111 MutationType ops [[ColumnName:{DescID: 109, Name: randcol, ColumnID: 5}, ABSENT], PUBLIC] -> ABSENT [[ColumnType:{DescID: 109, ColumnFamilyID: 0, ColumnID: 5}, ABSENT], PUBLIC] -> ABSENT [[ColumnDefaultExpression:{DescID: 109, ColumnID: 5, ReferencedSequenceIDs: [106]}, ABSENT], PUBLIC] -> ABSENT + [[Column:{DescID: 109, ColumnID: 6}, ABSENT], PUBLIC] -> ABSENT + [[ColumnName:{DescID: 109, Name: udfcol, ColumnID: 6}, ABSENT], PUBLIC] -> ABSENT + [[ColumnType:{DescID: 109, ColumnFamilyID: 0, ColumnID: 6}, ABSENT], PUBLIC] -> ABSENT + [[ColumnDefaultExpression:{DescID: 109, ColumnID: 6, ReferencedFunctionIDs: [112]}, ABSENT], PUBLIC] -> ABSENT [[Column:{DescID: 109, ColumnID: 4294967295}, ABSENT], PUBLIC] -> ABSENT [[ColumnName:{DescID: 109, Name: crdb_internal_mvcc_timestamp, ColumnID: 4294967295}, ABSENT], PUBLIC] -> ABSENT [[ColumnType:{DescID: 109, ColumnFamilyID: 0, ColumnID: 4294967295}, ABSENT], PUBLIC] -> ABSENT @@ -193,6 +200,7 @@ PreCommitPhase stage 2 of 2 with 111 MutationType ops [[IndexColumn:{DescID: 109, ColumnID: 3, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT [[IndexColumn:{DescID: 109, ColumnID: 4, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT [[IndexColumn:{DescID: 109, ColumnID: 5, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT + [[IndexColumn:{DescID: 109, ColumnID: 6, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT [[PrimaryIndex:{DescID: 109, IndexID: 1, ConstraintID: 1}, ABSENT], PUBLIC] -> ABSENT [[IndexName:{DescID: 109, Name: shipments_pkey, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT [[IndexComment:{DescID: 109, IndexID: 1, Comment: pkey is good}, ABSENT], PUBLIC] -> ABSENT @@ -423,6 +431,21 @@ PreCommitPhase stage 2 of 2 with 111 MutationType ops BackReferencedTableID: 109 SequenceIDs: - 106 + *scop.MakePublicColumnWriteOnly + ColumnID: 6 + TableID: 109 + *scop.SetColumnName + ColumnID: 6 + Name: crdb_internal_column_6_name_placeholder + TableID: 109 + *scop.RemoveColumnDefaultExpression + ColumnID: 6 + TableID: 109 + *scop.RemoveTableColumnBackReferencesInFunctions + BackReferencedColumnID: 6 + BackReferencedTableID: 109 + FunctionIDs: + - 112 *scop.MakePublicColumnWriteOnly ColumnID: 4294967295 TableID: 109 @@ -492,6 +515,9 @@ PreCommitPhase stage 2 of 2 with 111 MutationType ops *scop.MakeWriteOnlyColumnDeleteOnly ColumnID: 5 TableID: 109 + *scop.MakeWriteOnlyColumnDeleteOnly + ColumnID: 6 + TableID: 109 *scop.MakeWriteOnlyColumnDeleteOnly ColumnID: 4294967295 TableID: 109 @@ -547,6 +573,12 @@ PreCommitPhase stage 2 of 2 with 111 MutationType ops Kind: 2 Ordinal: 3 TableID: 109 + *scop.RemoveColumnFromIndex + ColumnID: 6 + IndexID: 1 + Kind: 2 + Ordinal: 4 + TableID: 109 *scop.MakeIndexAbsent IndexID: 1 TableID: 109 @@ -582,6 +614,9 @@ PreCommitPhase stage 2 of 2 with 111 MutationType ops *scop.MakeDeleteOnlyColumnAbsent ColumnID: 5 TableID: 109 + *scop.MakeDeleteOnlyColumnAbsent + ColumnID: 6 + TableID: 109 *scop.SetJobStateOnDescriptor DescriptorID: 104 Initialize: true @@ -606,6 +641,9 @@ PreCommitPhase stage 2 of 2 with 111 MutationType ops *scop.SetJobStateOnDescriptor DescriptorID: 111 Initialize: true + *scop.SetJobStateOnDescriptor + DescriptorID: 112 + Initialize: true *scop.CreateSchemaChangerJob Authorization: UserName: root @@ -618,6 +656,7 @@ PreCommitPhase stage 2 of 2 with 111 MutationType ops - 109 - 110 - 111 + - 112 JobID: 1 NonCancelable: true RunningStatus: PostCommitNonRevertiblePhase stage 1 of 1 with 5 MutationType ops pending @@ -625,7 +664,7 @@ PreCommitPhase stage 2 of 2 with 111 MutationType ops - statement: DROP TABLE defaultdb.shipments CASCADE redactedstatement: DROP TABLE ‹defaultdb›.public.‹shipments› CASCADE statementtag: DROP TABLE -PostCommitNonRevertiblePhase stage 1 of 1 with 14 MutationType ops +PostCommitNonRevertiblePhase stage 1 of 1 with 15 MutationType ops transitions: [[Table:{DescID: 109}, ABSENT], DROPPED] -> ABSENT [[IndexData:{DescID: 109, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT @@ -681,6 +720,9 @@ PostCommitNonRevertiblePhase stage 1 of 1 with 14 MutationType ops *scop.RemoveJobStateFromDescriptor DescriptorID: 111 JobID: 1 + *scop.RemoveJobStateFromDescriptor + DescriptorID: 112 + JobID: 1 *scop.UpdateSchemaChangerJob DescriptorIDsToRemove: - 104 @@ -691,6 +733,7 @@ PostCommitNonRevertiblePhase stage 1 of 1 with 14 MutationType ops - 109 - 110 - 111 + - 112 IsNonCancelable: true JobID: 1 @@ -833,6 +876,26 @@ DROP TABLE defaultdb.shipments CASCADE; to: [IndexColumn:{DescID: 109, ColumnID: 5, IndexID: 1}, ABSENT] kind: Precedence rule: column no longer public before dependents +- from: [Column:{DescID: 109, ColumnID: 6}, ABSENT] + to: [Table:{DescID: 109}, ABSENT] + kind: Precedence + rule: non-data dependents removed before descriptor +- from: [Column:{DescID: 109, ColumnID: 6}, WRITE_ONLY] + to: [ColumnDefaultExpression:{DescID: 109, ColumnID: 6, ReferencedFunctionIDs: [112]}, ABSENT] + kind: Precedence + rule: column no longer public before dependents +- from: [Column:{DescID: 109, ColumnID: 6}, WRITE_ONLY] + to: [ColumnName:{DescID: 109, Name: udfcol, ColumnID: 6}, ABSENT] + kind: Precedence + rule: column no longer public before dependents +- from: [Column:{DescID: 109, ColumnID: 6}, WRITE_ONLY] + to: [ColumnType:{DescID: 109, ColumnFamilyID: 0, ColumnID: 6}, ABSENT] + kind: Precedence + rule: column no longer public before dependents +- from: [Column:{DescID: 109, ColumnID: 6}, WRITE_ONLY] + to: [IndexColumn:{DescID: 109, ColumnID: 6, IndexID: 1}, ABSENT] + kind: Precedence + rule: column no longer public before dependents - from: [Column:{DescID: 111, ColumnID: 1}, ABSENT] to: [View:{DescID: 111}, ABSENT] kind: Precedence @@ -913,6 +976,18 @@ DROP TABLE defaultdb.shipments CASCADE; to: [Table:{DescID: 109}, ABSENT] kind: Precedence rule: non-data dependents removed before descriptor +- from: [ColumnDefaultExpression:{DescID: 109, ColumnID: 6, ReferencedFunctionIDs: [112]}, ABSENT] + to: [Column:{DescID: 109, ColumnID: 6}, ABSENT] + kind: Precedence + rule: dependents removed before column +- from: [ColumnDefaultExpression:{DescID: 109, ColumnID: 6, ReferencedFunctionIDs: [112]}, ABSENT] + to: [ColumnType:{DescID: 109, ColumnFamilyID: 0, ColumnID: 6}, ABSENT] + kind: SameStagePrecedence + rule: column type dependents removed right before column type +- from: [ColumnDefaultExpression:{DescID: 109, ColumnID: 6, ReferencedFunctionIDs: [112]}, ABSENT] + to: [Table:{DescID: 109}, ABSENT] + kind: Precedence + rule: non-data dependents removed before descriptor - from: [ColumnFamily:{DescID: 109, Name: primary, ColumnFamilyID: 0}, ABSENT] to: [Table:{DescID: 109}, ABSENT] kind: Precedence @@ -973,6 +1048,14 @@ DROP TABLE defaultdb.shipments CASCADE; to: [Table:{DescID: 109}, ABSENT] kind: Precedence rule: non-data dependents removed before descriptor +- from: [ColumnName:{DescID: 109, Name: udfcol, ColumnID: 6}, ABSENT] + to: [Column:{DescID: 109, ColumnID: 6}, ABSENT] + kind: Precedence + rule: dependents removed before column +- from: [ColumnName:{DescID: 109, Name: udfcol, ColumnID: 6}, ABSENT] + to: [Table:{DescID: 109}, ABSENT] + kind: Precedence + rule: non-data dependents removed before descriptor - from: [ColumnName:{DescID: 111, Name: carrier, ColumnID: 2}, ABSENT] to: [Column:{DescID: 111, ColumnID: 2}, ABSENT] kind: Precedence @@ -1065,6 +1148,14 @@ DROP TABLE defaultdb.shipments CASCADE; to: [Table:{DescID: 109}, ABSENT] kind: Precedence rule: non-data dependents removed before descriptor +- from: [ColumnType:{DescID: 109, ColumnFamilyID: 0, ColumnID: 6}, ABSENT] + to: [Column:{DescID: 109, ColumnID: 6}, ABSENT] + kind: Precedence + rule: dependents removed before column +- from: [ColumnType:{DescID: 109, ColumnFamilyID: 0, ColumnID: 6}, ABSENT] + to: [Table:{DescID: 109}, ABSENT] + kind: Precedence + rule: non-data dependents removed before descriptor - from: [ColumnType:{DescID: 109, ReferencedTypeIDs: [107 108], ColumnFamilyID: 0, ColumnID: 3}, ABSENT] to: [Column:{DescID: 109, ColumnID: 3}, ABSENT] kind: Precedence @@ -1253,6 +1344,18 @@ DROP TABLE defaultdb.shipments CASCADE; to: [Table:{DescID: 109}, ABSENT] kind: Precedence rule: non-data dependents removed before descriptor +- from: [IndexColumn:{DescID: 109, ColumnID: 6, IndexID: 1}, ABSENT] + to: [Column:{DescID: 109, ColumnID: 6}, ABSENT] + kind: Precedence + rule: dependents removed before column +- from: [IndexColumn:{DescID: 109, ColumnID: 6, IndexID: 1}, ABSENT] + to: [PrimaryIndex:{DescID: 109, IndexID: 1, ConstraintID: 1}, ABSENT] + kind: Precedence + rule: dependents removed before index +- from: [IndexColumn:{DescID: 109, ColumnID: 6, IndexID: 1}, ABSENT] + to: [Table:{DescID: 109}, ABSENT] + kind: Precedence + rule: non-data dependents removed before descriptor - from: [IndexComment:{DescID: 109, IndexID: 1, Comment: pkey is good}, ABSENT] to: [PrimaryIndex:{DescID: 109, IndexID: 1, ConstraintID: 1}, ABSENT] kind: Precedence @@ -1345,6 +1448,10 @@ DROP TABLE defaultdb.shipments CASCADE; to: [IndexColumn:{DescID: 109, ColumnID: 5, IndexID: 1}, ABSENT] kind: Precedence rule: index drop mutation visible before cleaning up index columns +- from: [PrimaryIndex:{DescID: 109, IndexID: 1, ConstraintID: 1}, DELETE_ONLY] + to: [IndexColumn:{DescID: 109, ColumnID: 6, IndexID: 1}, ABSENT] + kind: Precedence + rule: index drop mutation visible before cleaning up index columns - from: [PrimaryIndex:{DescID: 109, IndexID: 1, ConstraintID: 1}, VALIDATED] to: [IndexComment:{DescID: 109, IndexID: 1, Comment: pkey is good}, ABSENT] kind: Precedence @@ -1457,6 +1564,10 @@ DROP TABLE defaultdb.shipments CASCADE; to: [Column:{DescID: 109, ColumnID: 5}, WRITE_ONLY] kind: Precedence rule: relation dropped before dependent column +- from: [Table:{DescID: 109}, DROPPED] + to: [Column:{DescID: 109, ColumnID: 6}, WRITE_ONLY] + kind: Precedence + rule: relation dropped before dependent column - from: [Table:{DescID: 109}, DROPPED] to: [ColumnComment:{DescID: 109, ColumnID: 1, Comment: tracking_number is a must}, ABSENT] kind: Precedence @@ -1469,6 +1580,10 @@ DROP TABLE defaultdb.shipments CASCADE; to: [ColumnDefaultExpression:{DescID: 109, ColumnID: 5, ReferencedSequenceIDs: [106]}, ABSENT] kind: Precedence rule: descriptor dropped before dependent element removal +- from: [Table:{DescID: 109}, DROPPED] + to: [ColumnDefaultExpression:{DescID: 109, ColumnID: 6, ReferencedFunctionIDs: [112]}, ABSENT] + kind: Precedence + rule: descriptor dropped before dependent element removal - from: [Table:{DescID: 109}, DROPPED] to: [ColumnFamily:{DescID: 109, Name: primary, ColumnFamilyID: 0}, ABSENT] kind: Precedence @@ -1501,6 +1616,10 @@ DROP TABLE defaultdb.shipments CASCADE; to: [ColumnName:{DescID: 109, Name: tracking_number, ColumnID: 1}, ABSENT] kind: Precedence rule: descriptor dropped before dependent element removal +- from: [Table:{DescID: 109}, DROPPED] + to: [ColumnName:{DescID: 109, Name: udfcol, ColumnID: 6}, ABSENT] + kind: Precedence + rule: descriptor dropped before dependent element removal - from: [Table:{DescID: 109}, DROPPED] to: [ColumnNotNull:{DescID: 109, ColumnID: 1, IndexID: 0}, VALIDATED] kind: Precedence @@ -1529,6 +1648,10 @@ DROP TABLE defaultdb.shipments CASCADE; to: [ColumnType:{DescID: 109, ColumnFamilyID: 0, ColumnID: 5}, ABSENT] kind: Precedence rule: descriptor dropped before dependent element removal +- from: [Table:{DescID: 109}, DROPPED] + to: [ColumnType:{DescID: 109, ColumnFamilyID: 0, ColumnID: 6}, ABSENT] + kind: Precedence + rule: descriptor dropped before dependent element removal - from: [Table:{DescID: 109}, DROPPED] to: [ColumnType:{DescID: 109, ReferencedTypeIDs: [107 108], ColumnFamilyID: 0, ColumnID: 3}, ABSENT] kind: Precedence @@ -1565,6 +1688,10 @@ DROP TABLE defaultdb.shipments CASCADE; to: [IndexColumn:{DescID: 109, ColumnID: 5, IndexID: 1}, ABSENT] kind: Precedence rule: descriptor dropped before dependent element removal +- from: [Table:{DescID: 109}, DROPPED] + to: [IndexColumn:{DescID: 109, ColumnID: 6, IndexID: 1}, ABSENT] + kind: Precedence + rule: descriptor dropped before dependent element removal - from: [Table:{DescID: 109}, DROPPED] to: [IndexComment:{DescID: 109, IndexID: 1, Comment: pkey is good}, ABSENT] kind: Precedence @@ -1741,271 +1868,271 @@ DROP TABLE defaultdb.greeter ---- StatementPhase stage 1 of 1 with 2 MutationType ops transitions: - [[CheckConstraint:{DescID: 114, ReferencedTypeIDs: [112 113], IndexID: 0, ConstraintID: 2}, ABSENT], PUBLIC] -> VALIDATED - [[ConstraintWithoutIndexName:{DescID: 114, Name: check, ConstraintID: 2}, ABSENT], PUBLIC] -> ABSENT + [[CheckConstraint:{DescID: 115, ReferencedTypeIDs: [113 114], IndexID: 0, ConstraintID: 2}, ABSENT], PUBLIC] -> VALIDATED + [[ConstraintWithoutIndexName:{DescID: 115, Name: check, ConstraintID: 2}, ABSENT], PUBLIC] -> ABSENT ops: *scop.MakePublicCheckConstraintValidated ConstraintID: 2 - TableID: 114 + TableID: 115 *scop.SetConstraintName ConstraintID: 2 Name: crdb_internal_constraint_2_name_placeholder - TableID: 114 + TableID: 115 PreCommitPhase stage 1 of 2 with 1 MutationType op transitions: - [[CheckConstraint:{DescID: 114, ReferencedTypeIDs: [112 113], IndexID: 0, ConstraintID: 2}, ABSENT], VALIDATED] -> PUBLIC - [[ConstraintWithoutIndexName:{DescID: 114, Name: check, ConstraintID: 2}, ABSENT], ABSENT] -> PUBLIC + [[CheckConstraint:{DescID: 115, ReferencedTypeIDs: [113 114], IndexID: 0, ConstraintID: 2}, ABSENT], VALIDATED] -> PUBLIC + [[ConstraintWithoutIndexName:{DescID: 115, Name: check, ConstraintID: 2}, ABSENT], ABSENT] -> PUBLIC ops: *scop.UndoAllInTxnImmediateMutationOpSideEffects {} PreCommitPhase stage 2 of 2 with 59 MutationType ops transitions: - [[Namespace:{DescID: 114, Name: greeter, ReferencedDescID: 100}, ABSENT], PUBLIC] -> ABSENT - [[Owner:{DescID: 114}, ABSENT], PUBLIC] -> ABSENT - [[UserPrivileges:{DescID: 114, Name: admin}, ABSENT], PUBLIC] -> ABSENT - [[UserPrivileges:{DescID: 114, Name: root}, ABSENT], PUBLIC] -> ABSENT - [[Table:{DescID: 114}, ABSENT], PUBLIC] -> DROPPED - [[ObjectParent:{DescID: 114, ReferencedDescID: 101}, ABSENT], PUBLIC] -> ABSENT - [[ColumnFamily:{DescID: 114, Name: primary, ColumnFamilyID: 0}, ABSENT], PUBLIC] -> ABSENT - [[Column:{DescID: 114, ColumnID: 1}, ABSENT], PUBLIC] -> ABSENT - [[ColumnName:{DescID: 114, Name: x, ColumnID: 1}, ABSENT], PUBLIC] -> ABSENT - [[ColumnType:{DescID: 114, ColumnFamilyID: 0, ColumnID: 1}, ABSENT], PUBLIC] -> ABSENT - [[ColumnDefaultExpression:{DescID: 114, ReferencedTypeIDs: [112 113], ColumnID: 1}, ABSENT], PUBLIC] -> ABSENT - [[Column:{DescID: 114, ColumnID: 2}, ABSENT], PUBLIC] -> ABSENT - [[ColumnName:{DescID: 114, Name: y, ColumnID: 2}, ABSENT], PUBLIC] -> ABSENT - [[ColumnType:{DescID: 114, ReferencedTypeIDs: [112 113], ColumnFamilyID: 0, ColumnID: 2}, ABSENT], PUBLIC] -> ABSENT - [[ColumnNotNull:{DescID: 114, ColumnID: 2, IndexID: 0}, ABSENT], PUBLIC] -> ABSENT - [[Column:{DescID: 114, ColumnID: 3}, ABSENT], PUBLIC] -> ABSENT - [[ColumnName:{DescID: 114, Name: rowid, ColumnID: 3}, ABSENT], PUBLIC] -> ABSENT - [[ColumnType:{DescID: 114, ColumnFamilyID: 0, ColumnID: 3}, ABSENT], PUBLIC] -> ABSENT - [[ColumnNotNull:{DescID: 114, ColumnID: 3, IndexID: 0}, ABSENT], PUBLIC] -> ABSENT - [[ColumnDefaultExpression:{DescID: 114, ColumnID: 3}, ABSENT], PUBLIC] -> ABSENT - [[Column:{DescID: 114, ColumnID: 4294967295}, ABSENT], PUBLIC] -> ABSENT - [[ColumnName:{DescID: 114, Name: crdb_internal_mvcc_timestamp, ColumnID: 4294967295}, ABSENT], PUBLIC] -> ABSENT - [[ColumnType:{DescID: 114, ColumnFamilyID: 0, ColumnID: 4294967295}, ABSENT], PUBLIC] -> ABSENT - [[Column:{DescID: 114, ColumnID: 4294967294}, ABSENT], PUBLIC] -> ABSENT - [[ColumnName:{DescID: 114, Name: tableoid, ColumnID: 4294967294}, ABSENT], PUBLIC] -> ABSENT - [[ColumnType:{DescID: 114, ColumnFamilyID: 0, ColumnID: 4294967294}, ABSENT], PUBLIC] -> ABSENT - [[IndexColumn:{DescID: 114, ColumnID: 3, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT - [[IndexColumn:{DescID: 114, ColumnID: 1, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT - [[IndexColumn:{DescID: 114, ColumnID: 2, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT - [[PrimaryIndex:{DescID: 114, IndexID: 1, ConstraintID: 1}, ABSENT], PUBLIC] -> ABSENT - [[IndexName:{DescID: 114, Name: greeter_pkey, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT - [[IndexColumn:{DescID: 114, ColumnID: 2, IndexID: 2}, ABSENT], PUBLIC] -> ABSENT - [[IndexColumn:{DescID: 114, ColumnID: 3, IndexID: 2}, ABSENT], PUBLIC] -> ABSENT - [[SecondaryIndex:{DescID: 114, IndexID: 2, ConstraintID: 0}, ABSENT], PUBLIC] -> ABSENT - [[IndexName:{DescID: 114, Name: i, IndexID: 2}, ABSENT], PUBLIC] -> ABSENT - [[CheckConstraint:{DescID: 114, ReferencedTypeIDs: [112 113], IndexID: 0, ConstraintID: 2}, ABSENT], PUBLIC] -> ABSENT - [[ConstraintWithoutIndexName:{DescID: 114, Name: check, ConstraintID: 2}, ABSENT], PUBLIC] -> ABSENT + [[Namespace:{DescID: 115, Name: greeter, ReferencedDescID: 100}, ABSENT], PUBLIC] -> ABSENT + [[Owner:{DescID: 115}, ABSENT], PUBLIC] -> ABSENT + [[UserPrivileges:{DescID: 115, Name: admin}, ABSENT], PUBLIC] -> ABSENT + [[UserPrivileges:{DescID: 115, Name: root}, ABSENT], PUBLIC] -> ABSENT + [[Table:{DescID: 115}, ABSENT], PUBLIC] -> DROPPED + [[ObjectParent:{DescID: 115, ReferencedDescID: 101}, ABSENT], PUBLIC] -> ABSENT + [[ColumnFamily:{DescID: 115, Name: primary, ColumnFamilyID: 0}, ABSENT], PUBLIC] -> ABSENT + [[Column:{DescID: 115, ColumnID: 1}, ABSENT], PUBLIC] -> ABSENT + [[ColumnName:{DescID: 115, Name: x, ColumnID: 1}, ABSENT], PUBLIC] -> ABSENT + [[ColumnType:{DescID: 115, ColumnFamilyID: 0, ColumnID: 1}, ABSENT], PUBLIC] -> ABSENT + [[ColumnDefaultExpression:{DescID: 115, ReferencedTypeIDs: [113 114], ColumnID: 1}, ABSENT], PUBLIC] -> ABSENT + [[Column:{DescID: 115, ColumnID: 2}, ABSENT], PUBLIC] -> ABSENT + [[ColumnName:{DescID: 115, Name: y, ColumnID: 2}, ABSENT], PUBLIC] -> ABSENT + [[ColumnType:{DescID: 115, ReferencedTypeIDs: [113 114], ColumnFamilyID: 0, ColumnID: 2}, ABSENT], PUBLIC] -> ABSENT + [[ColumnNotNull:{DescID: 115, ColumnID: 2, IndexID: 0}, ABSENT], PUBLIC] -> ABSENT + [[Column:{DescID: 115, ColumnID: 3}, ABSENT], PUBLIC] -> ABSENT + [[ColumnName:{DescID: 115, Name: rowid, ColumnID: 3}, ABSENT], PUBLIC] -> ABSENT + [[ColumnType:{DescID: 115, ColumnFamilyID: 0, ColumnID: 3}, ABSENT], PUBLIC] -> ABSENT + [[ColumnNotNull:{DescID: 115, ColumnID: 3, IndexID: 0}, ABSENT], PUBLIC] -> ABSENT + [[ColumnDefaultExpression:{DescID: 115, ColumnID: 3}, ABSENT], PUBLIC] -> ABSENT + [[Column:{DescID: 115, ColumnID: 4294967295}, ABSENT], PUBLIC] -> ABSENT + [[ColumnName:{DescID: 115, Name: crdb_internal_mvcc_timestamp, ColumnID: 4294967295}, ABSENT], PUBLIC] -> ABSENT + [[ColumnType:{DescID: 115, ColumnFamilyID: 0, ColumnID: 4294967295}, ABSENT], PUBLIC] -> ABSENT + [[Column:{DescID: 115, ColumnID: 4294967294}, ABSENT], PUBLIC] -> ABSENT + [[ColumnName:{DescID: 115, Name: tableoid, ColumnID: 4294967294}, ABSENT], PUBLIC] -> ABSENT + [[ColumnType:{DescID: 115, ColumnFamilyID: 0, ColumnID: 4294967294}, ABSENT], PUBLIC] -> ABSENT + [[IndexColumn:{DescID: 115, ColumnID: 3, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT + [[IndexColumn:{DescID: 115, ColumnID: 1, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT + [[IndexColumn:{DescID: 115, ColumnID: 2, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT + [[PrimaryIndex:{DescID: 115, IndexID: 1, ConstraintID: 1}, ABSENT], PUBLIC] -> ABSENT + [[IndexName:{DescID: 115, Name: greeter_pkey, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT + [[IndexColumn:{DescID: 115, ColumnID: 2, IndexID: 2}, ABSENT], PUBLIC] -> ABSENT + [[IndexColumn:{DescID: 115, ColumnID: 3, IndexID: 2}, ABSENT], PUBLIC] -> ABSENT + [[SecondaryIndex:{DescID: 115, IndexID: 2, ConstraintID: 0}, ABSENT], PUBLIC] -> ABSENT + [[IndexName:{DescID: 115, Name: i, IndexID: 2}, ABSENT], PUBLIC] -> ABSENT + [[CheckConstraint:{DescID: 115, ReferencedTypeIDs: [113 114], IndexID: 0, ConstraintID: 2}, ABSENT], PUBLIC] -> ABSENT + [[ConstraintWithoutIndexName:{DescID: 115, Name: check, ConstraintID: 2}, ABSENT], PUBLIC] -> ABSENT ops: *scop.MakePublicCheckConstraintValidated ConstraintID: 2 - TableID: 114 + TableID: 115 *scop.SetConstraintName ConstraintID: 2 Name: crdb_internal_constraint_2_name_placeholder - TableID: 114 + TableID: 115 *scop.RemoveCheckConstraint ConstraintID: 2 - TableID: 114 + TableID: 115 *scop.UpdateTableBackReferencesInTypes - BackReferencedTableID: 114 + BackReferencedTableID: 115 TypeIDs: - - 112 - 113 + - 114 *scop.MarkDescriptorAsDropped - DescriptorID: 114 + DescriptorID: 115 *scop.RemoveObjectParent - ObjectID: 114 + ObjectID: 115 ParentSchemaID: 101 *scop.NotImplementedForPublicObjects - DescID: 114 + DescID: 115 ElementType: scpb.ColumnFamily *scop.MakePublicColumnWriteOnly ColumnID: 1 - TableID: 114 + TableID: 115 *scop.SetColumnName ColumnID: 1 Name: crdb_internal_column_1_name_placeholder - TableID: 114 + TableID: 115 *scop.RemoveColumnDefaultExpression ColumnID: 1 - TableID: 114 + TableID: 115 *scop.UpdateTableBackReferencesInTypes - BackReferencedTableID: 114 + BackReferencedTableID: 115 TypeIDs: - - 112 - 113 + - 114 *scop.MakePublicColumnWriteOnly ColumnID: 2 - TableID: 114 + TableID: 115 *scop.SetColumnName ColumnID: 2 Name: crdb_internal_column_2_name_placeholder - TableID: 114 + TableID: 115 *scop.RemoveDroppedColumnType ColumnID: 2 - TableID: 114 + TableID: 115 *scop.UpdateTableBackReferencesInTypes - BackReferencedTableID: 114 + BackReferencedTableID: 115 TypeIDs: - - 112 - 113 + - 114 *scop.MakePublicColumnNotNullValidated ColumnID: 2 - TableID: 114 + TableID: 115 *scop.MakePublicColumnWriteOnly ColumnID: 3 - TableID: 114 + TableID: 115 *scop.SetColumnName ColumnID: 3 Name: crdb_internal_column_3_name_placeholder - TableID: 114 + TableID: 115 *scop.MakePublicColumnNotNullValidated ColumnID: 3 - TableID: 114 + TableID: 115 *scop.RemoveColumnDefaultExpression ColumnID: 3 - TableID: 114 + TableID: 115 *scop.MakePublicColumnWriteOnly ColumnID: 4294967295 - TableID: 114 + TableID: 115 *scop.SetColumnName ColumnID: 4294967295 Name: crdb_internal_column_4294967295_name_placeholder - TableID: 114 + TableID: 115 *scop.MakePublicColumnWriteOnly ColumnID: 4294967294 - TableID: 114 + TableID: 115 *scop.SetColumnName ColumnID: 4294967294 Name: crdb_internal_column_4294967294_name_placeholder - TableID: 114 + TableID: 115 *scop.MakePublicPrimaryIndexWriteOnly IndexID: 1 - TableID: 114 + TableID: 115 *scop.SetIndexName IndexID: 1 Name: crdb_internal_index_1_name_placeholder - TableID: 114 + TableID: 115 *scop.MakePublicSecondaryIndexWriteOnly IndexID: 2 - TableID: 114 + TableID: 115 *scop.DrainDescriptorName Namespace: DatabaseID: 100 - DescriptorID: 114 + DescriptorID: 115 Name: greeter SchemaID: 101 *scop.NotImplementedForPublicObjects - DescID: 114 + DescID: 115 ElementType: scpb.Owner *scop.RemoveUserPrivileges - DescriptorID: 114 + DescriptorID: 115 User: admin *scop.RemoveUserPrivileges - DescriptorID: 114 + DescriptorID: 115 User: root *scop.MakeWriteOnlyColumnDeleteOnly ColumnID: 1 - TableID: 114 + TableID: 115 *scop.RemoveColumnNotNull ColumnID: 2 - TableID: 114 + TableID: 115 *scop.RemoveColumnNotNull ColumnID: 3 - TableID: 114 + TableID: 115 *scop.MakeWriteOnlyColumnDeleteOnly ColumnID: 4294967295 - TableID: 114 + TableID: 115 *scop.MakeWriteOnlyColumnDeleteOnly ColumnID: 4294967294 - TableID: 114 + TableID: 115 *scop.MakeWriteOnlyColumnDeleteOnly ColumnID: 2 - TableID: 114 + TableID: 115 *scop.MakeWriteOnlyColumnDeleteOnly ColumnID: 3 - TableID: 114 + TableID: 115 *scop.MakeDeleteOnlyColumnAbsent ColumnID: 4294967295 - TableID: 114 + TableID: 115 *scop.MakeDeleteOnlyColumnAbsent ColumnID: 4294967294 - TableID: 114 + TableID: 115 *scop.MakeWriteOnlyIndexDeleteOnly IndexID: 1 - TableID: 114 + TableID: 115 *scop.MakeWriteOnlyIndexDeleteOnly IndexID: 2 - TableID: 114 + TableID: 115 *scop.RemoveDroppedIndexPartialPredicate IndexID: 2 - TableID: 114 + TableID: 115 *scop.UpdateTableBackReferencesInTypes - BackReferencedTableID: 114 + BackReferencedTableID: 115 TypeIDs: - - 112 - 113 + - 114 *scop.SetIndexName IndexID: 2 Name: crdb_internal_index_2_name_placeholder - TableID: 114 + TableID: 115 *scop.RemoveColumnFromIndex ColumnID: 3 IndexID: 1 - TableID: 114 + TableID: 115 *scop.RemoveColumnFromIndex ColumnID: 1 IndexID: 1 Kind: 2 - TableID: 114 + TableID: 115 *scop.RemoveColumnFromIndex ColumnID: 2 IndexID: 1 Kind: 2 Ordinal: 1 - TableID: 114 + TableID: 115 *scop.MakeIndexAbsent IndexID: 1 - TableID: 114 + TableID: 115 *scop.RemoveColumnFromIndex ColumnID: 2 IndexID: 2 - TableID: 114 + TableID: 115 *scop.RemoveColumnFromIndex ColumnID: 3 IndexID: 2 Kind: 1 - TableID: 114 + TableID: 115 *scop.MakeIndexAbsent IndexID: 2 - TableID: 114 + TableID: 115 *scop.MakeDeleteOnlyColumnAbsent ColumnID: 1 - TableID: 114 + TableID: 115 *scop.MakeDeleteOnlyColumnAbsent ColumnID: 2 - TableID: 114 + TableID: 115 *scop.MakeDeleteOnlyColumnAbsent ColumnID: 3 - TableID: 114 - *scop.SetJobStateOnDescriptor - DescriptorID: 112 - Initialize: true + TableID: 115 *scop.SetJobStateOnDescriptor DescriptorID: 113 Initialize: true *scop.SetJobStateOnDescriptor DescriptorID: 114 Initialize: true + *scop.SetJobStateOnDescriptor + DescriptorID: 115 + Initialize: true *scop.CreateSchemaChangerJob Authorization: UserName: root DescriptorIDs: - - 112 - 113 - 114 + - 115 JobID: 1 NonCancelable: true RunningStatus: PostCommitNonRevertiblePhase stage 1 of 1 with 3 MutationType ops pending @@ -2015,39 +2142,39 @@ PreCommitPhase stage 2 of 2 with 59 MutationType ops statementtag: DROP TABLE PostCommitNonRevertiblePhase stage 1 of 1 with 7 MutationType ops transitions: - [[Table:{DescID: 114}, ABSENT], DROPPED] -> ABSENT - [[IndexData:{DescID: 114, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT - [[IndexData:{DescID: 114, IndexID: 2}, ABSENT], PUBLIC] -> ABSENT - [[TableData:{DescID: 114, ReferencedDescID: 100}, ABSENT], PUBLIC] -> ABSENT + [[Table:{DescID: 115}, ABSENT], DROPPED] -> ABSENT + [[IndexData:{DescID: 115, IndexID: 1}, ABSENT], PUBLIC] -> ABSENT + [[IndexData:{DescID: 115, IndexID: 2}, ABSENT], PUBLIC] -> ABSENT + [[TableData:{DescID: 115, ReferencedDescID: 100}, ABSENT], PUBLIC] -> ABSENT ops: *scop.CreateGCJobForTable DatabaseID: 100 StatementForDropJob: Statement: DROP TABLE defaultdb.public.greeter - TableID: 114 + TableID: 115 *scop.CreateGCJobForIndex IndexID: 1 StatementForDropJob: Statement: DROP TABLE defaultdb.public.greeter - TableID: 114 + TableID: 115 *scop.CreateGCJobForIndex IndexID: 2 StatementForDropJob: Statement: DROP TABLE defaultdb.public.greeter - TableID: 114 - *scop.RemoveJobStateFromDescriptor - DescriptorID: 112 - JobID: 1 + TableID: 115 *scop.RemoveJobStateFromDescriptor DescriptorID: 113 JobID: 1 *scop.RemoveJobStateFromDescriptor DescriptorID: 114 JobID: 1 + *scop.RemoveJobStateFromDescriptor + DescriptorID: 115 + JobID: 1 *scop.UpdateSchemaChangerJob DescriptorIDsToRemove: - - 112 - 113 - 114 + - 115 IsNonCancelable: true JobID: 1 diff --git a/pkg/sql/schemachanger/screl/attr.go b/pkg/sql/schemachanger/screl/attr.go index 4d9bb152e8c6..d47072838ac8 100644 --- a/pkg/sql/schemachanger/screl/attr.go +++ b/pkg/sql/schemachanger/screl/attr.go @@ -84,6 +84,9 @@ const ( // ReferencedSequenceIDs corresponds to a slice of sequence descriptor IDs // referenced by an element. ReferencedSequenceIDs + // ReferencedFunctionIDs corresponds to a slice of function descriptor IDs + // referenced by an element. + ReferencedFunctionIDs // AttrMax is the largest possible Attr value. // Note: add any new enum values before TargetStatus, leave these at the end. @@ -245,6 +248,7 @@ var elementSchemaOptions = []rel.SchemaOption{ rel.EntityAttr(ColumnID, "ColumnID"), rel.EntityAttr(ReferencedSequenceIDs, "UsesSequenceIDs"), rel.EntityAttr(ReferencedTypeIDs, "UsesTypeIDs"), + rel.EntityAttr(ReferencedFunctionIDs, "UsesFunctionIDs"), ), rel.EntityMapping(t((*scpb.ColumnOnUpdateExpression)(nil)), rel.EntityAttr(DescID, "TableID"), diff --git a/pkg/sql/schemachanger/screl/attr_string.go b/pkg/sql/schemachanger/screl/attr_string.go index 464a5908945f..a9d69f679fb9 100644 --- a/pkg/sql/schemachanger/screl/attr_string.go +++ b/pkg/sql/schemachanger/screl/attr_string.go @@ -24,11 +24,12 @@ func _() { _ = x[Target-14] _ = x[ReferencedTypeIDs-15] _ = x[ReferencedSequenceIDs-16] + _ = x[ReferencedFunctionIDs-17] } -const _Attr_name = "DescIDIndexIDColumnFamilyIDColumnIDConstraintIDNameReferencedDescIDCommentTemporaryIndexIDSourceIndexIDTargetStatusCurrentStatusElementTargetReferencedTypeIDsReferencedSequenceIDs" +const _Attr_name = "DescIDIndexIDColumnFamilyIDColumnIDConstraintIDNameReferencedDescIDCommentTemporaryIndexIDSourceIndexIDTargetStatusCurrentStatusElementTargetReferencedTypeIDsReferencedSequenceIDsReferencedFunctionIDs" -var _Attr_index = [...]uint8{0, 6, 13, 27, 35, 47, 51, 67, 74, 90, 103, 115, 128, 135, 141, 158, 179} +var _Attr_index = [...]uint8{0, 6, 13, 27, 35, 47, 51, 67, 74, 90, 103, 115, 128, 135, 141, 158, 179, 200} func (i Attr) String() string { i -= 1 diff --git a/pkg/sql/schemachanger/sctest/cumulative.go b/pkg/sql/schemachanger/sctest/cumulative.go index 5c0b715eb629..77b8c6c1a43c 100644 --- a/pkg/sql/schemachanger/sctest/cumulative.go +++ b/pkg/sql/schemachanger/sctest/cumulative.go @@ -1212,29 +1212,49 @@ func Backup(t *testing.T, path string, newCluster NewClusterFunc) { // in this case, since it will no longer be simply `before` // and `after`. - removeChecksDependOnUDFs := func(n *tree.CreateTable) { - usesUDF := func(ck *tree.CheckConstraintTableDef) bool { - var foundUDF bool - _, err := tree.SimpleVisit(ck.Expr, func(expr tree.Expr) (recurse bool, newExpr tree.Expr, err error) { - if fe, ok := expr.(*tree.FuncExpr); ok { - ref := fe.Func.FunctionReference.(*tree.UnresolvedName) - fn, err := ref.ToFunctionName() - require.NoError(t, err) - fd, err := tree.GetBuiltinFuncDefinition(fn, &sessiondata.DefaultSearchPath) - require.NoError(t, err) - if fd == nil { - foundUDF = true - } + containsUDF := func(expr tree.Expr) (bool, error) { + var foundUDF bool + _, err := tree.SimpleVisit(expr, func(expr tree.Expr) (recurse bool, newExpr tree.Expr, err error) { + if fe, ok := expr.(*tree.FuncExpr); ok { + ref := fe.Func.FunctionReference.(*tree.UnresolvedName) + fn, err := ref.ToFunctionName() + require.NoError(t, err) + fd, err := tree.GetBuiltinFuncDefinition(fn, &sessiondata.DefaultSearchPath) + require.NoError(t, err) + if fd == nil { + foundUDF = true } - return true, expr, nil - }) - require.NoError(t, err) - return foundUDF + } + return true, expr, nil + }) + if err != nil { + return false, err } + return foundUDF, nil + } + + removeDefsDependOnUDFs := func(n *tree.CreateTable) { var newDefs tree.TableDefs for _, def := range n.Defs { - if ck, ok := def.(*tree.CheckConstraintTableDef); ok && usesUDF(ck) { - continue + var usesUDF bool + switch d := def.(type) { + case *tree.CheckConstraintTableDef: + usesUDF, err = containsUDF(d.Expr) + require.NoError(t, err) + if usesUDF { + continue + } + case *tree.ColumnTableDef: + if d.DefaultExpr.Expr != nil { + usesUDF, err = containsUDF(d.DefaultExpr.Expr) + require.NoError(t, err) + if usesUDF { + d.DefaultExpr = struct { + Expr tree.Expr + ConstraintName tree.Name + }{} + } + } } newDefs = append(newDefs, def) } @@ -1250,30 +1270,37 @@ func Backup(t *testing.T, path string, newCluster NewClusterFunc) { tdb.Exec(t, fmt.Sprintf("USE %q", dbName)) waitForSchemaChangesToFinish(t, tdb) afterRestore := tdb.QueryStr(t, fetchDescriptorStateQuery) - if b.isRollback { - require.Equal(t, before, afterRestore) - } else { - if flavor.name != "restore all tables in database" { + + if flavor.name != "restore all tables in database" { + if b.isRollback { + require.Equal(t, before, afterRestore) + } else { require.Equal(t, after, afterRestore) + } + } else { + // If the flavor restore only tables, there can be missing UDF + // dependencies which cause check constraints or expressions + // dropped through RESTORE due to missing UDFs. We need to remove + // those kind of table elements from original AST. + var expected [][]string + if b.isRollback { + expected = before } else { - // If the flavor restore only tables, there can be missing UDF - // dependencies which cause check constraints dropped through - // RESTORE due to missing UDFs. We need to remove those kind of - // check constraint using UDFs from original AST. - require.Equal(t, len(after), len(afterRestore)) - for i := range after { - require.Equal(t, 1, len(after[i])) - require.Equal(t, 1, len(afterRestore[i])) - afterNode, _ := parser.ParseOne(after[i][0]) - afterRestoreNode, _ := parser.ParseOne(afterRestore[i][0]) - if _, ok := afterNode.AST.(*tree.CreateTable); !ok { - require.Equal(t, after[i][0], afterRestore[i][0]) - } else { - createTbl := afterNode.AST.(*tree.CreateTable) - removeChecksDependOnUDFs(createTbl) - createTblRestored := afterRestoreNode.AST.(*tree.CreateTable) - require.Equal(t, tree.AsString(createTbl), tree.AsString(createTblRestored)) - } + expected = after + } + require.Equal(t, len(expected), len(afterRestore)) + for i := range expected { + require.Equal(t, 1, len(expected[i])) + require.Equal(t, 1, len(afterRestore[i])) + afterNode, _ := parser.ParseOne(expected[i][0]) + afterRestoreNode, _ := parser.ParseOne(afterRestore[i][0]) + if _, ok := afterNode.AST.(*tree.CreateTable); !ok { + require.Equal(t, expected[i][0], afterRestore[i][0]) + } else { + createTbl := afterNode.AST.(*tree.CreateTable) + removeDefsDependOnUDFs(createTbl) + createTblRestored := afterRestoreNode.AST.(*tree.CreateTable) + require.Equal(t, tree.AsString(createTbl), tree.AsString(createTblRestored)) } } } diff --git a/pkg/sql/schemachanger/sctest_generated_test.go b/pkg/sql/schemachanger/sctest_generated_test.go index 4fe5640dd85a..fcd5336bfed0 100644 --- a/pkg/sql/schemachanger/sctest_generated_test.go +++ b/pkg/sql/schemachanger/sctest_generated_test.go @@ -695,6 +695,31 @@ func TestRollback_drop_column_with_partial_index(t *testing.T) { defer log.Scope(t).Close(t) sctest.Rollback(t, "pkg/sql/schemachanger/testdata/end_to_end/drop_column_with_partial_index", sctest.SingleNodeCluster) } +func TestEndToEndSideEffects_drop_column_with_udf_default(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + sctest.EndToEndSideEffects(t, "pkg/sql/schemachanger/testdata/end_to_end/drop_column_with_udf_default", sctest.SingleNodeCluster) +} +func TestExecuteWithDMLInjection_drop_column_with_udf_default(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + sctest.ExecuteWithDMLInjection(t, "pkg/sql/schemachanger/testdata/end_to_end/drop_column_with_udf_default", sctest.SingleNodeCluster) +} +func TestGenerateSchemaChangeCorpus_drop_column_with_udf_default(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + sctest.GenerateSchemaChangeCorpus(t, "pkg/sql/schemachanger/testdata/end_to_end/drop_column_with_udf_default", sctest.SingleNodeCluster) +} +func TestPause_drop_column_with_udf_default(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + sctest.Pause(t, "pkg/sql/schemachanger/testdata/end_to_end/drop_column_with_udf_default", sctest.SingleNodeCluster) +} +func TestRollback_drop_column_with_udf_default(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + sctest.Rollback(t, "pkg/sql/schemachanger/testdata/end_to_end/drop_column_with_udf_default", sctest.SingleNodeCluster) +} func TestEndToEndSideEffects_drop_function(t *testing.T) { defer leaktest.AfterTest(t)() defer log.Scope(t).Close(t) @@ -895,3 +920,28 @@ func TestRollback_drop_table(t *testing.T) { defer log.Scope(t).Close(t) sctest.Rollback(t, "pkg/sql/schemachanger/testdata/end_to_end/drop_table", sctest.SingleNodeCluster) } +func TestEndToEndSideEffects_drop_table_udf_default(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + sctest.EndToEndSideEffects(t, "pkg/sql/schemachanger/testdata/end_to_end/drop_table_udf_default", sctest.SingleNodeCluster) +} +func TestExecuteWithDMLInjection_drop_table_udf_default(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + sctest.ExecuteWithDMLInjection(t, "pkg/sql/schemachanger/testdata/end_to_end/drop_table_udf_default", sctest.SingleNodeCluster) +} +func TestGenerateSchemaChangeCorpus_drop_table_udf_default(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + sctest.GenerateSchemaChangeCorpus(t, "pkg/sql/schemachanger/testdata/end_to_end/drop_table_udf_default", sctest.SingleNodeCluster) +} +func TestPause_drop_table_udf_default(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + sctest.Pause(t, "pkg/sql/schemachanger/testdata/end_to_end/drop_table_udf_default", sctest.SingleNodeCluster) +} +func TestRollback_drop_table_udf_default(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + sctest.Rollback(t, "pkg/sql/schemachanger/testdata/end_to_end/drop_table_udf_default", sctest.SingleNodeCluster) +} diff --git a/pkg/sql/schemachanger/sctest_mixed_generated_test.go b/pkg/sql/schemachanger/sctest_mixed_generated_test.go index bad2afd56d78..a0d87d8da5bb 100644 --- a/pkg/sql/schemachanger/sctest_mixed_generated_test.go +++ b/pkg/sql/schemachanger/sctest_mixed_generated_test.go @@ -155,6 +155,11 @@ func TestValidateMixedVersionElements_drop_column_with_partial_index(t *testing. defer log.Scope(t).Close(t) sctest.ValidateMixedVersionElements(t, "pkg/sql/schemachanger/testdata/end_to_end/drop_column_with_partial_index", sctest.SingleNodeMixedCluster) } +func TestValidateMixedVersionElements_drop_column_with_udf_default(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + sctest.ValidateMixedVersionElements(t, "pkg/sql/schemachanger/testdata/end_to_end/drop_column_with_udf_default", sctest.SingleNodeMixedCluster) +} func TestValidateMixedVersionElements_drop_function(t *testing.T) { defer leaktest.AfterTest(t)() defer log.Scope(t).Close(t) @@ -195,3 +200,8 @@ func TestValidateMixedVersionElements_drop_table(t *testing.T) { defer log.Scope(t).Close(t) sctest.ValidateMixedVersionElements(t, "pkg/sql/schemachanger/testdata/end_to_end/drop_table", sctest.SingleNodeMixedCluster) } +func TestValidateMixedVersionElements_drop_table_udf_default(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + sctest.ValidateMixedVersionElements(t, "pkg/sql/schemachanger/testdata/end_to_end/drop_table_udf_default", sctest.SingleNodeMixedCluster) +} diff --git a/pkg/sql/schemachanger/testdata/end_to_end/drop_column_with_udf_default b/pkg/sql/schemachanger/testdata/end_to_end/drop_column_with_udf_default new file mode 100644 index 000000000000..4150193387aa --- /dev/null +++ b/pkg/sql/schemachanger/testdata/end_to_end/drop_column_with_udf_default @@ -0,0 +1,679 @@ +setup +CREATE FUNCTION f() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +CREATE TABLE t (i INT PRIMARY KEY, b INT DEFAULT f()); +---- +... ++object {100 101 t} -> 105 + +test +ALTER TABLE t DROP COLUMN b; +---- +begin transaction #1 +# begin StatementPhase +checking for feature: ALTER TABLE +increment telemetry for sql.schema.alter_table +increment telemetry for sql.schema.alter_table.drop_column +write *eventpb.AlterTable to event log: + mutationId: 1 + sql: + descriptorId: 105 + statement: ALTER TABLE ‹defaultdb›.‹public›.‹t› DROP COLUMN ‹b› + tag: ALTER TABLE + user: root + tableName: defaultdb.public.t +## StatementPhase stage 1 of 1 with 6 MutationType ops +upsert descriptor #105 + ... + oid: 20 + width: 64 + - - defaultExpr: '[FUNCTION 100104]()' + - id: 2 + - name: b + - nullable: true + - type: + - family: IntFamily + - oid: 20 + - width: 64 + - usesFunctionIds: + - - 104 + createAsOfTime: + wallTime: "1640995200000000000" + ... + columnNames: + - i + - - b + + - crdb_internal_column_2_name_placeholder + defaultColumnId: 2 + name: primary + ... + id: 105 + modificationTime: {} + + mutations: + + - column: + + defaultExpr: '[FUNCTION 100104]()' + + id: 2 + + name: crdb_internal_column_2_name_placeholder + + nullable: true + + type: + + family: IntFamily + + oid: 20 + + width: 64 + + usesFunctionIds: + + - 104 + + direction: DROP + + mutationId: 1 + + state: WRITE_ONLY + + - direction: ADD + + index: + + constraintId: 2 + + createdExplicitly: true + + encodingType: 1 + + foreignKey: {} + + geoConfig: {} + + id: 2 + + interleave: {} + + keyColumnDirections: + + - ASC + + keyColumnIds: + + - 1 + + keyColumnNames: + + - i + + name: crdb_internal_index_2_name_placeholder + + partitioning: {} + + sharded: {} + + storeColumnNames: [] + + unique: true + + version: 4 + + mutationId: 1 + + state: BACKFILLING + + - direction: ADD + + index: + + constraintId: 3 + + createdExplicitly: true + + encodingType: 1 + + foreignKey: {} + + geoConfig: {} + + id: 3 + + interleave: {} + + keyColumnDirections: + + - ASC + + keyColumnIds: + + - 1 + + keyColumnNames: + + - i + + name: crdb_internal_index_3_name_placeholder + + partitioning: {} + + sharded: {} + + storeColumnNames: [] + + unique: true + + useDeletePreservingEncoding: true + + version: 4 + + mutationId: 1 + + state: DELETE_ONLY + name: t + nextColumnId: 3 + - nextConstraintId: 2 + + nextConstraintId: 4 + nextFamilyId: 1 + - nextIndexId: 2 + + nextIndexId: 4 + nextMutationId: 1 + parentId: 100 + ... + - 2 + storeColumnNames: + - - b + + - crdb_internal_column_2_name_placeholder + unique: true + version: 4 + ... + time: {} + unexposedParentSchemaId: 101 + - version: "1" + + version: "2" +# end StatementPhase +# begin PreCommitPhase +## PreCommitPhase stage 1 of 2 with 1 MutationType op +undo all catalog changes within txn #1 +persist all catalog changes to storage +## PreCommitPhase stage 2 of 2 with 11 MutationType ops +upsert descriptor #104 + function: + + declarativeSchemaChangerState: + + authorization: + + userName: root + + jobId: "1" + + revertible: true + dependedOnBy: + - columnIds: + ... + oid: 20 + width: 64 + - version: "2" + + version: "3" + volatility: VOLATILE +upsert descriptor #105 + ... + oid: 20 + width: 64 + - - defaultExpr: '[FUNCTION 100104]()' + - id: 2 + - name: b + - nullable: true + - type: + - family: IntFamily + - oid: 20 + - width: 64 + - usesFunctionIds: + - - 104 + createAsOfTime: + wallTime: "1640995200000000000" + + declarativeSchemaChangerState: + + authorization: + + userName: root + + currentStatuses: + + jobId: "1" + + relevantStatements: + + - statement: + + redactedStatement: ALTER TABLE ‹defaultdb›.‹public›.‹t› DROP COLUMN ‹b› + + statement: ALTER TABLE t DROP COLUMN b + + statementTag: ALTER TABLE + + revertible: true + + targetRanks: + + targets: + families: + - columnIds: + ... + columnNames: + - i + - - b + + - crdb_internal_column_2_name_placeholder + defaultColumnId: 2 + name: primary + ... + id: 105 + modificationTime: {} + + mutations: + + - column: + + defaultExpr: '[FUNCTION 100104]()' + + id: 2 + + name: crdb_internal_column_2_name_placeholder + + nullable: true + + type: + + family: IntFamily + + oid: 20 + + width: 64 + + usesFunctionIds: + + - 104 + + direction: DROP + + mutationId: 1 + + state: WRITE_ONLY + + - direction: ADD + + index: + + constraintId: 2 + + createdExplicitly: true + + encodingType: 1 + + foreignKey: {} + + geoConfig: {} + + id: 2 + + interleave: {} + + keyColumnDirections: + + - ASC + + keyColumnIds: + + - 1 + + keyColumnNames: + + - i + + name: crdb_internal_index_2_name_placeholder + + partitioning: {} + + sharded: {} + + storeColumnNames: [] + + unique: true + + version: 4 + + mutationId: 1 + + state: BACKFILLING + + - direction: ADD + + index: + + constraintId: 3 + + createdExplicitly: true + + encodingType: 1 + + foreignKey: {} + + geoConfig: {} + + id: 3 + + interleave: {} + + keyColumnDirections: + + - ASC + + keyColumnIds: + + - 1 + + keyColumnNames: + + - i + + name: crdb_internal_index_3_name_placeholder + + partitioning: {} + + sharded: {} + + storeColumnNames: [] + + unique: true + + useDeletePreservingEncoding: true + + version: 4 + + mutationId: 1 + + state: DELETE_ONLY + name: t + nextColumnId: 3 + - nextConstraintId: 2 + + nextConstraintId: 4 + nextFamilyId: 1 + - nextIndexId: 2 + + nextIndexId: 4 + nextMutationId: 1 + parentId: 100 + ... + - 2 + storeColumnNames: + - - b + + - crdb_internal_column_2_name_placeholder + unique: true + version: 4 + ... + time: {} + unexposedParentSchemaId: 101 + - version: "1" + + version: "2" +persist all catalog changes to storage +create job #1 (non-cancelable: false): "ALTER TABLE defaultdb.public.t DROP COLUMN b" + descriptor IDs: [104 105] +# end PreCommitPhase +commit transaction #1 +notified job registry to adopt jobs: [1] +# begin PostCommitPhase +begin transaction #2 +commit transaction #2 +begin transaction #3 +## PostCommitPhase stage 1 of 7 with 4 MutationType ops +upsert descriptor #104 + ... + oid: 20 + width: 64 + - version: "3" + + version: "4" + volatility: VOLATILE +upsert descriptor #105 + ... + version: 4 + mutationId: 1 + - state: DELETE_ONLY + + state: WRITE_ONLY + name: t + nextColumnId: 3 + ... + time: {} + unexposedParentSchemaId: 101 + - version: "2" + + version: "3" +persist all catalog changes to storage +update progress of schema change job #1: "PostCommitPhase stage 2 of 7 with 1 BackfillType op pending" +commit transaction #3 +begin transaction #4 +## PostCommitPhase stage 2 of 7 with 1 BackfillType op +backfill indexes [2] from index #1 in table #105 +commit transaction #4 +begin transaction #5 +## PostCommitPhase stage 3 of 7 with 4 MutationType ops +upsert descriptor #104 + ... + oid: 20 + width: 64 + - version: "4" + + version: "5" + volatility: VOLATILE +upsert descriptor #105 + ... + version: 4 + mutationId: 1 + - state: BACKFILLING + + state: DELETE_ONLY + - direction: ADD + index: + ... + time: {} + unexposedParentSchemaId: 101 + - version: "3" + + version: "4" +persist all catalog changes to storage +update progress of schema change job #1: "PostCommitPhase stage 4 of 7 with 1 MutationType op pending" +commit transaction #5 +begin transaction #6 +## PostCommitPhase stage 4 of 7 with 4 MutationType ops +upsert descriptor #104 + ... + oid: 20 + width: 64 + - version: "5" + + version: "6" + volatility: VOLATILE +upsert descriptor #105 + ... + version: 4 + mutationId: 1 + - state: DELETE_ONLY + + state: MERGING + - direction: ADD + index: + ... + time: {} + unexposedParentSchemaId: 101 + - version: "4" + + version: "5" +persist all catalog changes to storage +update progress of schema change job #1: "PostCommitPhase stage 5 of 7 with 1 BackfillType op pending" +commit transaction #6 +begin transaction #7 +## PostCommitPhase stage 5 of 7 with 1 BackfillType op +merge temporary indexes [3] into backfilled indexes [2] in table #105 +commit transaction #7 +begin transaction #8 +## PostCommitPhase stage 6 of 7 with 4 MutationType ops +upsert descriptor #104 + ... + oid: 20 + width: 64 + - version: "6" + + version: "7" + volatility: VOLATILE +upsert descriptor #105 + ... + version: 4 + mutationId: 1 + - state: MERGING + + state: WRITE_ONLY + - direction: ADD + index: + ... + time: {} + unexposedParentSchemaId: 101 + - version: "5" + + version: "6" +persist all catalog changes to storage +update progress of schema change job #1: "PostCommitPhase stage 7 of 7 with 1 ValidationType op pending" +commit transaction #8 +begin transaction #9 +## PostCommitPhase stage 7 of 7 with 1 ValidationType op +validate forward indexes [2] in table #105 +commit transaction #9 +begin transaction #10 +## PostCommitNonRevertiblePhase stage 1 of 3 with 10 MutationType ops +upsert descriptor #104 + ... + userName: root + jobId: "1" + - revertible: true + dependedOnBy: + - columnIds: + ... + oid: 20 + width: 64 + - version: "7" + + version: "8" + volatility: VOLATILE +upsert descriptor #105 + ... + statement: ALTER TABLE t DROP COLUMN b + statementTag: ALTER TABLE + - revertible: true + targetRanks: + targets: + ... + direction: DROP + mutationId: 1 + - state: WRITE_ONLY + - - direction: ADD + + state: DELETE_ONLY + + - direction: DROP + index: + - constraintId: 2 + + constraintId: 3 + createdExplicitly: true + encodingType: 1 + foreignKey: {} + geoConfig: {} + - id: 2 + + id: 3 + interleave: {} + keyColumnDirections: + ... + keyColumnNames: + - i + - name: crdb_internal_index_2_name_placeholder + + name: crdb_internal_index_3_name_placeholder + partitioning: {} + sharded: {} + storeColumnNames: [] + unique: true + + useDeletePreservingEncoding: true + version: 4 + mutationId: 1 + - state: WRITE_ONLY + - - direction: ADD + + state: DELETE_ONLY + + - direction: DROP + index: + - constraintId: 3 + - createdExplicitly: true + + constraintId: 1 + + createdAtNanos: "1640995200000000000" + encodingType: 1 + foreignKey: {} + geoConfig: {} + - id: 3 + + id: 1 + interleave: {} + keyColumnDirections: + ... + keyColumnNames: + - i + - name: crdb_internal_index_3_name_placeholder + + name: crdb_internal_index_1_name_placeholder + partitioning: {} + sharded: {} + - storeColumnNames: [] + + storeColumnIds: + + - 2 + + storeColumnNames: + + - crdb_internal_column_2_name_placeholder + unique: true + - useDeletePreservingEncoding: true + version: 4 + mutationId: 1 + ... + parentId: 100 + primaryIndex: + - constraintId: 1 + - createdAtNanos: "1640995200000000000" + + constraintId: 2 + + createdExplicitly: true + encodingType: 1 + foreignKey: {} + geoConfig: {} + - id: 1 + + id: 2 + interleave: {} + keyColumnDirections: + ... + partitioning: {} + sharded: {} + - storeColumnIds: + - - 2 + - storeColumnNames: + - - crdb_internal_column_2_name_placeholder + + storeColumnNames: [] + unique: true + version: 4 + ... + time: {} + unexposedParentSchemaId: 101 + - version: "6" + + version: "7" +persist all catalog changes to storage +update progress of schema change job #1: "PostCommitNonRevertiblePhase stage 2 of 3 with 4 MutationType ops pending" +set schema change job #1 to non-cancellable +commit transaction #10 +begin transaction #11 +## PostCommitNonRevertiblePhase stage 2 of 3 with 7 MutationType ops +upsert descriptor #104 + ... + oid: 20 + width: 64 + - version: "8" + + version: "9" + volatility: VOLATILE +upsert descriptor #105 + ... + - direction: DROP + index: + - constraintId: 3 + - createdExplicitly: true + - encodingType: 1 + - foreignKey: {} + - geoConfig: {} + - id: 3 + - interleave: {} + - keyColumnDirections: + - - ASC + - keyColumnIds: + - - 1 + - keyColumnNames: + - - i + - name: crdb_internal_index_3_name_placeholder + - partitioning: {} + - sharded: {} + - storeColumnNames: [] + - unique: true + - useDeletePreservingEncoding: true + - version: 4 + - mutationId: 1 + - state: DELETE_ONLY + - - direction: DROP + - index: + constraintId: 1 + createdAtNanos: "1640995200000000000" + ... + version: 4 + mutationId: 1 + - state: WRITE_ONLY + + state: DELETE_ONLY + name: t + nextColumnId: 3 + ... + time: {} + unexposedParentSchemaId: 101 + - version: "7" + + version: "8" +persist all catalog changes to storage +update progress of schema change job #1: "PostCommitNonRevertiblePhase stage 3 of 3 with 6 MutationType ops pending" +commit transaction #11 +begin transaction #12 +## PostCommitNonRevertiblePhase stage 3 of 3 with 9 MutationType ops +upsert descriptor #104 + function: + - declarativeSchemaChangerState: + - authorization: + - userName: root + - jobId: "1" + - dependedOnBy: + - - columnIds: + - - 2 + - id: 105 + functionBody: SELECT 1; + id: 104 + ... + oid: 20 + width: 64 + - version: "9" + + version: "10" + volatility: VOLATILE +upsert descriptor #105 + ... + createAsOfTime: + wallTime: "1640995200000000000" + - declarativeSchemaChangerState: + - authorization: + - userName: root + - currentStatuses: + - jobId: "1" + - relevantStatements: + - - statement: + - redactedStatement: ALTER TABLE ‹defaultdb›.‹public›.‹t› DROP COLUMN ‹b› + - statement: ALTER TABLE t DROP COLUMN b + - statementTag: ALTER TABLE + - targetRanks: + - targets: + families: + - columnIds: + - 1 + - - 2 + columnNames: + - i + - - crdb_internal_column_2_name_placeholder + defaultColumnId: 2 + name: primary + ... + id: 105 + modificationTime: {} + - mutations: + - - column: + - defaultExpr: '[FUNCTION 100104]()' + - id: 2 + - name: crdb_internal_column_2_name_placeholder + - nullable: true + - type: + - family: IntFamily + - oid: 20 + - width: 64 + - usesFunctionIds: + - - 104 + - direction: DROP + - mutationId: 1 + - state: DELETE_ONLY + - - direction: DROP + - index: + - constraintId: 1 + - createdAtNanos: "1640995200000000000" + - encodingType: 1 + - foreignKey: {} + - geoConfig: {} + - id: 1 + - interleave: {} + - keyColumnDirections: + - - ASC + - keyColumnIds: + - - 1 + - keyColumnNames: + - - i + - name: crdb_internal_index_1_name_placeholder + - partitioning: {} + - sharded: {} + - storeColumnIds: + - - 2 + - storeColumnNames: + - - crdb_internal_column_2_name_placeholder + - unique: true + - version: 4 + - mutationId: 1 + - state: DELETE_ONLY + + mutations: [] + name: t + nextColumnId: 3 + ... + time: {} + unexposedParentSchemaId: 101 + - version: "8" + + version: "9" +persist all catalog changes to storage +create job #2 (non-cancelable: true): "GC for ALTER TABLE defaultdb.public.t DROP COLUMN b" + descriptor IDs: [105] +update progress of schema change job #1: "all stages completed" +set schema change job #1 to non-cancellable +updated schema change job #1 descriptor IDs to [] +write *eventpb.FinishSchemaChange to event log: + sc: + descriptorId: 105 +commit transaction #12 +notified job registry to adopt jobs: [2] +# end PostCommitPhase diff --git a/pkg/sql/schemachanger/testdata/end_to_end/drop_table_udf_default b/pkg/sql/schemachanger/testdata/end_to_end/drop_table_udf_default new file mode 100644 index 000000000000..02222849aff8 --- /dev/null +++ b/pkg/sql/schemachanger/testdata/end_to_end/drop_table_udf_default @@ -0,0 +1,162 @@ +setup +CREATE FUNCTION f() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +CREATE TABLE t (i INT PRIMARY KEY, b INT DEFAULT f()); +---- +... ++object {100 101 t} -> 105 + +test +DROP TABLE t; +---- +begin transaction #1 +# begin StatementPhase +checking for feature: DROP TABLE +increment telemetry for sql.schema.drop_table +write *eventpb.DropTable to event log: + sql: + descriptorId: 105 + statement: DROP TABLE ‹defaultdb›.‹public›.‹t› + tag: DROP TABLE + user: root + tableName: defaultdb.public.t +## StatementPhase stage 1 of 1 with 20 MutationType ops +delete object namespace entry {100 101 t} -> 105 +upsert descriptor #104 + function: + - dependedOnBy: + - - columnIds: + - - 2 + - id: 105 + functionBody: SELECT 1; + id: 104 + ... + oid: 20 + width: 64 + - version: "2" + + version: "3" + volatility: VOLATILE +upsert descriptor #105 + ... + createAsOfTime: + wallTime: "1640995200000000000" + + dropTime: " + families: + - columnIds: + ... + replacementOf: + time: {} + + state: DROP + unexposedParentSchemaId: 101 + - version: "1" + + version: "2" +# end StatementPhase +# begin PreCommitPhase +## PreCommitPhase stage 1 of 2 with 1 MutationType op +undo all catalog changes within txn #1 +persist all catalog changes to storage +## PreCommitPhase stage 2 of 2 with 36 MutationType ops +delete object namespace entry {100 101 t} -> 105 +upsert descriptor #104 + function: + - dependedOnBy: + - - columnIds: + - - 2 + - id: 105 + + declarativeSchemaChangerState: + + authorization: + + userName: root + + jobId: "1" + functionBody: SELECT 1; + id: 104 + ... + oid: 20 + width: 64 + - version: "2" + + version: "3" + volatility: VOLATILE +upsert descriptor #105 + ... + createAsOfTime: + wallTime: "1640995200000000000" + + declarativeSchemaChangerState: + + authorization: + + userName: root + + currentStatuses: + + jobId: "1" + + relevantStatements: + + - statement: + + redactedStatement: DROP TABLE ‹defaultdb›.‹public›.‹t› + + statement: DROP TABLE t + + statementTag: DROP TABLE + + targetRanks: + + targets: + + dropTime: " + families: + - columnIds: + ... + replacementOf: + time: {} + + state: DROP + unexposedParentSchemaId: 101 + - version: "1" + + version: "2" +persist all catalog changes to storage +create job #1 (non-cancelable: true): "DROP TABLE defaultdb.public.t" + descriptor IDs: [104 105] +# end PreCommitPhase +commit transaction #1 +notified job registry to adopt jobs: [1] +# begin PostCommitPhase +begin transaction #2 +commit transaction #2 +begin transaction #3 +## PostCommitNonRevertiblePhase stage 1 of 1 with 5 MutationType ops +upsert descriptor #104 + function: + - declarativeSchemaChangerState: + - authorization: + - userName: root + - jobId: "1" + functionBody: SELECT 1; + id: 104 + ... + oid: 20 + width: 64 + - version: "3" + + version: "4" + volatility: VOLATILE +upsert descriptor #105 + ... + createAsOfTime: + wallTime: "1640995200000000000" + - declarativeSchemaChangerState: + - authorization: + - userName: root + - currentStatuses: + - jobId: "1" + - relevantStatements: + - - statement: + - redactedStatement: DROP TABLE ‹defaultdb›.‹public›.‹t› + - statement: DROP TABLE t + - statementTag: DROP TABLE + - targetRanks: + - targets: + dropTime: " + families: + ... + state: DROP + unexposedParentSchemaId: 101 + - version: "2" + + version: "3" +persist all catalog changes to storage +create job #2 (non-cancelable: true): "GC for DROP TABLE defaultdb.public.t" + descriptor IDs: [105] +update progress of schema change job #1: "all stages completed" +set schema change job #1 to non-cancellable +updated schema change job #1 descriptor IDs to [] +write *eventpb.FinishSchemaChange to event log: + sc: + descriptorId: 105 +commit transaction #3 +notified job registry to adopt jobs: [2] +# end PostCommitPhase diff --git a/pkg/sql/schemachanger/testdata/explain/drop_column_with_udf_default b/pkg/sql/schemachanger/testdata/explain/drop_column_with_udf_default new file mode 100644 index 000000000000..dbbb88da2d71 --- /dev/null +++ b/pkg/sql/schemachanger/testdata/explain/drop_column_with_udf_default @@ -0,0 +1,170 @@ +/* setup */ +CREATE FUNCTION f() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +CREATE TABLE t (i INT PRIMARY KEY, b INT DEFAULT f()); + +/* test */ +EXPLAIN (ddl) ALTER TABLE t DROP COLUMN b; +---- +Schema change plan for ALTER TABLE ‹defaultdb›.‹public›.‹t› DROP COLUMN ‹b›; + ├── StatementPhase + │ └── Stage 1 of 1 in StatementPhase + │ ├── 3 elements transitioning toward PUBLIC + │ │ ├── ABSENT → BACKFILL_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ ├── ABSENT → PUBLIC IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} + │ │ └── ABSENT → PUBLIC IndexData:{DescID: 105, IndexID: 2} + │ ├── 2 elements transitioning toward TRANSIENT_ABSENT + │ │ ├── ABSENT → DELETE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ └── ABSENT → PUBLIC IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} + │ ├── 2 elements transitioning toward ABSENT + │ │ ├── PUBLIC → WRITE_ONLY Column:{DescID: 105, ColumnID: 2} + │ │ └── PUBLIC → ABSENT ColumnName:{DescID: 105, Name: b, ColumnID: 2} + │ └── 6 Mutation operations + │ ├── MakePublicColumnWriteOnly {"ColumnID":2,"TableID":105} + │ ├── SetColumnName {"ColumnID":2,"Name":"crdb_internal_co...","TableID":105} + │ ├── MakeAbsentIndexBackfilling {"Index":{"ConstraintID":2,"IndexID":2,"IsUnique":true,"SourceIndexID":1,"TableID":105,"TemporaryIndexID":3}} + │ ├── AddColumnToIndex {"ColumnID":1,"IndexID":2,"TableID":105} + │ ├── MakeAbsentTempIndexDeleteOnly {"Index":{"ConstraintID":3,"IndexID":3,"IsUnique":true,"SourceIndexID":1,"TableID":105}} + │ └── AddColumnToIndex {"ColumnID":1,"IndexID":3,"TableID":105} + ├── PreCommitPhase + │ ├── Stage 1 of 2 in PreCommitPhase + │ │ ├── 3 elements transitioning toward PUBLIC + │ │ │ ├── BACKFILL_ONLY → ABSENT PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} + │ │ │ └── PUBLIC → ABSENT IndexData:{DescID: 105, IndexID: 2} + │ │ ├── 2 elements transitioning toward TRANSIENT_ABSENT + │ │ │ ├── DELETE_ONLY → ABSENT TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ └── PUBLIC → ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} + │ │ ├── 2 elements transitioning toward ABSENT + │ │ │ ├── WRITE_ONLY → PUBLIC Column:{DescID: 105, ColumnID: 2} + │ │ │ └── ABSENT → PUBLIC ColumnName:{DescID: 105, Name: b, ColumnID: 2} + │ │ └── 1 Mutation operation + │ │ └── UndoAllInTxnImmediateMutationOpSideEffects + │ └── Stage 2 of 2 in PreCommitPhase + │ ├── 3 elements transitioning toward PUBLIC + │ │ ├── ABSENT → BACKFILL_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ ├── ABSENT → PUBLIC IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} + │ │ └── ABSENT → PUBLIC IndexData:{DescID: 105, IndexID: 2} + │ ├── 2 elements transitioning toward TRANSIENT_ABSENT + │ │ ├── ABSENT → DELETE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ └── ABSENT → PUBLIC IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} + │ ├── 2 elements transitioning toward ABSENT + │ │ ├── PUBLIC → WRITE_ONLY Column:{DescID: 105, ColumnID: 2} + │ │ └── PUBLIC → ABSENT ColumnName:{DescID: 105, Name: b, ColumnID: 2} + │ └── 11 Mutation operations + │ ├── MakePublicColumnWriteOnly {"ColumnID":2,"TableID":105} + │ ├── SetColumnName {"ColumnID":2,"Name":"crdb_internal_co...","TableID":105} + │ ├── MakeAbsentIndexBackfilling {"Index":{"ConstraintID":2,"IndexID":2,"IsUnique":true,"SourceIndexID":1,"TableID":105,"TemporaryIndexID":3}} + │ ├── MaybeAddSplitForIndex {"IndexID":2,"TableID":105} + │ ├── AddColumnToIndex {"ColumnID":1,"IndexID":2,"TableID":105} + │ ├── MakeAbsentTempIndexDeleteOnly {"Index":{"ConstraintID":3,"IndexID":3,"IsUnique":true,"SourceIndexID":1,"TableID":105}} + │ ├── MaybeAddSplitForIndex {"IndexID":3,"TableID":105} + │ ├── AddColumnToIndex {"ColumnID":1,"IndexID":3,"TableID":105} + │ ├── SetJobStateOnDescriptor {"DescriptorID":104,"Initialize":true} + │ ├── SetJobStateOnDescriptor {"DescriptorID":105,"Initialize":true} + │ └── CreateSchemaChangerJob {"RunningStatus":"PostCommitPhase ..."} + ├── PostCommitPhase + │ ├── Stage 1 of 7 in PostCommitPhase + │ │ ├── 2 elements transitioning toward TRANSIENT_ABSENT + │ │ │ ├── DELETE_ONLY → WRITE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ └── ABSENT → PUBLIC IndexData:{DescID: 105, IndexID: 3} + │ │ └── 4 Mutation operations + │ │ ├── MakeDeleteOnlyIndexWriteOnly {"IndexID":3,"TableID":105} + │ │ ├── SetJobStateOnDescriptor {"DescriptorID":104} + │ │ ├── SetJobStateOnDescriptor {"DescriptorID":105} + │ │ └── UpdateSchemaChangerJob {"RunningStatus":"PostCommitPhase ..."} + │ ├── Stage 2 of 7 in PostCommitPhase + │ │ ├── 1 element transitioning toward PUBLIC + │ │ │ └── BACKFILL_ONLY → BACKFILLED PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ └── 1 Backfill operation + │ │ └── BackfillIndex {"IndexID":2,"SourceIndexID":1,"TableID":105} + │ ├── Stage 3 of 7 in PostCommitPhase + │ │ ├── 1 element transitioning toward PUBLIC + │ │ │ └── BACKFILLED → DELETE_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ └── 4 Mutation operations + │ │ ├── MakeBackfillingIndexDeleteOnly {"IndexID":2,"TableID":105} + │ │ ├── SetJobStateOnDescriptor {"DescriptorID":104} + │ │ ├── SetJobStateOnDescriptor {"DescriptorID":105} + │ │ └── UpdateSchemaChangerJob {"RunningStatus":"PostCommitPhase ..."} + │ ├── Stage 4 of 7 in PostCommitPhase + │ │ ├── 1 element transitioning toward PUBLIC + │ │ │ └── DELETE_ONLY → MERGE_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ └── 4 Mutation operations + │ │ ├── MakeBackfilledIndexMerging {"IndexID":2,"TableID":105} + │ │ ├── SetJobStateOnDescriptor {"DescriptorID":104} + │ │ ├── SetJobStateOnDescriptor {"DescriptorID":105} + │ │ └── UpdateSchemaChangerJob {"RunningStatus":"PostCommitPhase ..."} + │ ├── Stage 5 of 7 in PostCommitPhase + │ │ ├── 1 element transitioning toward PUBLIC + │ │ │ └── MERGE_ONLY → MERGED PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ └── 1 Backfill operation + │ │ └── MergeIndex {"BackfilledIndexID":2,"TableID":105,"TemporaryIndexID":3} + │ ├── Stage 6 of 7 in PostCommitPhase + │ │ ├── 1 element transitioning toward PUBLIC + │ │ │ └── MERGED → WRITE_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ └── 4 Mutation operations + │ │ ├── MakeMergedIndexWriteOnly {"IndexID":2,"TableID":105} + │ │ ├── SetJobStateOnDescriptor {"DescriptorID":104} + │ │ ├── SetJobStateOnDescriptor {"DescriptorID":105} + │ │ └── UpdateSchemaChangerJob {"RunningStatus":"PostCommitPhase ..."} + │ └── Stage 7 of 7 in PostCommitPhase + │ ├── 1 element transitioning toward PUBLIC + │ │ └── WRITE_ONLY → VALIDATED PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ └── 1 Validation operation + │ └── ValidateIndex {"IndexID":2,"TableID":105} + └── PostCommitNonRevertiblePhase + ├── Stage 1 of 3 in PostCommitNonRevertiblePhase + │ ├── 2 elements transitioning toward PUBLIC + │ │ ├── VALIDATED → PUBLIC PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ └── ABSENT → PUBLIC IndexName:{DescID: 105, Name: t_pkey, IndexID: 2} + │ ├── 2 elements transitioning toward TRANSIENT_ABSENT + │ │ ├── WRITE_ONLY → TRANSIENT_DELETE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ └── PUBLIC → TRANSIENT_ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} + │ ├── 3 elements transitioning toward ABSENT + │ │ ├── WRITE_ONLY → DELETE_ONLY Column:{DescID: 105, ColumnID: 2} + │ │ ├── PUBLIC → VALIDATED PrimaryIndex:{DescID: 105, IndexID: 1, ConstraintID: 1} + │ │ └── PUBLIC → ABSENT IndexName:{DescID: 105, Name: t_pkey, IndexID: 1} + │ └── 10 Mutation operations + │ ├── MakeWriteOnlyColumnDeleteOnly {"ColumnID":2,"TableID":105} + │ ├── MakePublicPrimaryIndexWriteOnly {"IndexID":1,"TableID":105} + │ ├── SetIndexName {"IndexID":1,"Name":"crdb_internal_in...","TableID":105} + │ ├── SetIndexName {"IndexID":2,"Name":"t_pkey","TableID":105} + │ ├── MakeWriteOnlyIndexDeleteOnly {"IndexID":3,"TableID":105} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":3,"TableID":105} + │ ├── MakeValidatedPrimaryIndexPublic {"IndexID":2,"TableID":105} + │ ├── SetJobStateOnDescriptor {"DescriptorID":104} + │ ├── SetJobStateOnDescriptor {"DescriptorID":105} + │ └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"PostCommitNonRev..."} + ├── Stage 2 of 3 in PostCommitNonRevertiblePhase + │ ├── 1 element transitioning toward TRANSIENT_ABSENT + │ │ └── TRANSIENT_DELETE_ONLY → TRANSIENT_ABSENT TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ ├── 3 elements transitioning toward ABSENT + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 1} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 105, ColumnID: 2, IndexID: 1} + │ │ └── VALIDATED → DELETE_ONLY PrimaryIndex:{DescID: 105, IndexID: 1, ConstraintID: 1} + │ └── 7 Mutation operations + │ ├── MakeIndexAbsent {"IndexID":3,"TableID":105} + │ ├── MakeWriteOnlyIndexDeleteOnly {"IndexID":1,"TableID":105} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":1,"TableID":105} + │ ├── RemoveColumnFromIndex {"ColumnID":2,"IndexID":1,"Kind":2,"TableID":105} + │ ├── SetJobStateOnDescriptor {"DescriptorID":104} + │ ├── SetJobStateOnDescriptor {"DescriptorID":105} + │ └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"PostCommitNonRev..."} + └── Stage 3 of 3 in PostCommitNonRevertiblePhase + ├── 1 element transitioning toward TRANSIENT_ABSENT + │ └── PUBLIC → TRANSIENT_ABSENT IndexData:{DescID: 105, IndexID: 3} + ├── 5 elements transitioning toward ABSENT + │ ├── DELETE_ONLY → ABSENT Column:{DescID: 105, ColumnID: 2} + │ ├── PUBLIC → ABSENT ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 2} + │ ├── PUBLIC → ABSENT ColumnDefaultExpression:{DescID: 105, ColumnID: 2, ReferencedFunctionIDs: [104]} + │ ├── DELETE_ONLY → ABSENT PrimaryIndex:{DescID: 105, IndexID: 1, ConstraintID: 1} + │ └── PUBLIC → ABSENT IndexData:{DescID: 105, IndexID: 1} + └── 9 Mutation operations + ├── RemoveColumnDefaultExpression {"ColumnID":2,"TableID":105} + ├── RemoveTableColumnBackReferencesInFunctions {"BackReferencedColumnID":2,"BackReferencedTableID":105} + ├── MakeIndexAbsent {"IndexID":1,"TableID":105} + ├── CreateGCJobForIndex {"IndexID":1,"TableID":105} + ├── CreateGCJobForIndex {"IndexID":3,"TableID":105} + ├── MakeDeleteOnlyColumnAbsent {"ColumnID":2,"TableID":105} + ├── RemoveJobStateFromDescriptor {"DescriptorID":104} + ├── RemoveJobStateFromDescriptor {"DescriptorID":105} + └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"all stages compl..."} diff --git a/pkg/sql/schemachanger/testdata/explain/drop_column_with_udf_default.rollback_1_of_7 b/pkg/sql/schemachanger/testdata/explain/drop_column_with_udf_default.rollback_1_of_7 new file mode 100644 index 000000000000..2320c51da366 --- /dev/null +++ b/pkg/sql/schemachanger/testdata/explain/drop_column_with_udf_default.rollback_1_of_7 @@ -0,0 +1,32 @@ +/* setup */ +CREATE FUNCTION f() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +CREATE TABLE t (i INT PRIMARY KEY, b INT DEFAULT f()); + +/* test */ +ALTER TABLE t DROP COLUMN b; +EXPLAIN (ddl) rollback at post-commit stage 1 of 7; +---- +Schema change plan for rolling back ALTER TABLE ‹defaultdb›.public.‹t› DROP COLUMN ‹b›; + └── PostCommitNonRevertiblePhase + └── Stage 1 of 1 in PostCommitNonRevertiblePhase + ├── 2 elements transitioning toward PUBLIC + │ ├── WRITE_ONLY → PUBLIC Column:{DescID: 105, ColumnID: 2} + │ └── ABSENT → PUBLIC ColumnName:{DescID: 105, Name: b, ColumnID: 2} + ├── 5 elements transitioning toward ABSENT + │ ├── BACKFILL_ONLY → ABSENT PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} + │ ├── PUBLIC → ABSENT IndexData:{DescID: 105, IndexID: 2} + │ ├── DELETE_ONLY → ABSENT TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ └── PUBLIC → ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} + └── 11 Mutation operations + ├── SetColumnName {"ColumnID":2,"Name":"b","TableID":105} + ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":2,"TableID":105} + ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":3,"TableID":105} + ├── MakeWriteOnlyColumnPublic {"ColumnID":2,"TableID":105} + ├── RefreshStats {"TableID":105} + ├── MakeIndexAbsent {"IndexID":2,"TableID":105} + ├── CreateGCJobForIndex {"IndexID":2,"TableID":105} + ├── MakeIndexAbsent {"IndexID":3,"TableID":105} + ├── RemoveJobStateFromDescriptor {"DescriptorID":104} + ├── RemoveJobStateFromDescriptor {"DescriptorID":105} + └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"all stages compl..."} diff --git a/pkg/sql/schemachanger/testdata/explain/drop_column_with_udf_default.rollback_2_of_7 b/pkg/sql/schemachanger/testdata/explain/drop_column_with_udf_default.rollback_2_of_7 new file mode 100644 index 000000000000..d46bba335fbb --- /dev/null +++ b/pkg/sql/schemachanger/testdata/explain/drop_column_with_udf_default.rollback_2_of_7 @@ -0,0 +1,42 @@ +/* setup */ +CREATE FUNCTION f() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +CREATE TABLE t (i INT PRIMARY KEY, b INT DEFAULT f()); + +/* test */ +ALTER TABLE t DROP COLUMN b; +EXPLAIN (ddl) rollback at post-commit stage 2 of 7; +---- +Schema change plan for rolling back ALTER TABLE ‹defaultdb›.public.‹t› DROP COLUMN ‹b›; + └── PostCommitNonRevertiblePhase + ├── Stage 1 of 2 in PostCommitNonRevertiblePhase + │ ├── 2 elements transitioning toward PUBLIC + │ │ ├── WRITE_ONLY → PUBLIC Column:{DescID: 105, ColumnID: 2} + │ │ └── ABSENT → PUBLIC ColumnName:{DescID: 105, Name: b, ColumnID: 2} + │ ├── 4 elements transitioning toward ABSENT + │ │ ├── BACKFILL_ONLY → ABSENT PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} + │ │ ├── WRITE_ONLY → DELETE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ └── PUBLIC → ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} + │ └── 10 Mutation operations + │ ├── SetColumnName {"ColumnID":2,"Name":"b","TableID":105} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":2,"TableID":105} + │ ├── MakeWriteOnlyIndexDeleteOnly {"IndexID":3,"TableID":105} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":3,"TableID":105} + │ ├── MakeWriteOnlyColumnPublic {"ColumnID":2,"TableID":105} + │ ├── RefreshStats {"TableID":105} + │ ├── MakeIndexAbsent {"IndexID":2,"TableID":105} + │ ├── SetJobStateOnDescriptor {"DescriptorID":104} + │ ├── SetJobStateOnDescriptor {"DescriptorID":105} + │ └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"PostCommitNonRev..."} + └── Stage 2 of 2 in PostCommitNonRevertiblePhase + ├── 3 elements transitioning toward ABSENT + │ ├── PUBLIC → ABSENT IndexData:{DescID: 105, IndexID: 2} + │ ├── DELETE_ONLY → ABSENT TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ └── PUBLIC → ABSENT IndexData:{DescID: 105, IndexID: 3} + └── 6 Mutation operations + ├── CreateGCJobForIndex {"IndexID":2,"TableID":105} + ├── MakeIndexAbsent {"IndexID":3,"TableID":105} + ├── CreateGCJobForIndex {"IndexID":3,"TableID":105} + ├── RemoveJobStateFromDescriptor {"DescriptorID":104} + ├── RemoveJobStateFromDescriptor {"DescriptorID":105} + └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"all stages compl..."} diff --git a/pkg/sql/schemachanger/testdata/explain/drop_column_with_udf_default.rollback_3_of_7 b/pkg/sql/schemachanger/testdata/explain/drop_column_with_udf_default.rollback_3_of_7 new file mode 100644 index 000000000000..fd531b30bcd7 --- /dev/null +++ b/pkg/sql/schemachanger/testdata/explain/drop_column_with_udf_default.rollback_3_of_7 @@ -0,0 +1,42 @@ +/* setup */ +CREATE FUNCTION f() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +CREATE TABLE t (i INT PRIMARY KEY, b INT DEFAULT f()); + +/* test */ +ALTER TABLE t DROP COLUMN b; +EXPLAIN (ddl) rollback at post-commit stage 3 of 7; +---- +Schema change plan for rolling back ALTER TABLE ‹defaultdb›.public.‹t› DROP COLUMN ‹b›; + └── PostCommitNonRevertiblePhase + ├── Stage 1 of 2 in PostCommitNonRevertiblePhase + │ ├── 2 elements transitioning toward PUBLIC + │ │ ├── WRITE_ONLY → PUBLIC Column:{DescID: 105, ColumnID: 2} + │ │ └── ABSENT → PUBLIC ColumnName:{DescID: 105, Name: b, ColumnID: 2} + │ ├── 4 elements transitioning toward ABSENT + │ │ ├── BACKFILL_ONLY → ABSENT PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} + │ │ ├── WRITE_ONLY → DELETE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ └── PUBLIC → ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} + │ └── 10 Mutation operations + │ ├── SetColumnName {"ColumnID":2,"Name":"b","TableID":105} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":2,"TableID":105} + │ ├── MakeWriteOnlyIndexDeleteOnly {"IndexID":3,"TableID":105} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":3,"TableID":105} + │ ├── MakeWriteOnlyColumnPublic {"ColumnID":2,"TableID":105} + │ ├── RefreshStats {"TableID":105} + │ ├── MakeIndexAbsent {"IndexID":2,"TableID":105} + │ ├── SetJobStateOnDescriptor {"DescriptorID":104} + │ ├── SetJobStateOnDescriptor {"DescriptorID":105} + │ └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"PostCommitNonRev..."} + └── Stage 2 of 2 in PostCommitNonRevertiblePhase + ├── 3 elements transitioning toward ABSENT + │ ├── PUBLIC → ABSENT IndexData:{DescID: 105, IndexID: 2} + │ ├── DELETE_ONLY → ABSENT TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ └── PUBLIC → ABSENT IndexData:{DescID: 105, IndexID: 3} + └── 6 Mutation operations + ├── CreateGCJobForIndex {"IndexID":2,"TableID":105} + ├── MakeIndexAbsent {"IndexID":3,"TableID":105} + ├── CreateGCJobForIndex {"IndexID":3,"TableID":105} + ├── RemoveJobStateFromDescriptor {"DescriptorID":104} + ├── RemoveJobStateFromDescriptor {"DescriptorID":105} + └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"all stages compl..."} diff --git a/pkg/sql/schemachanger/testdata/explain/drop_column_with_udf_default.rollback_4_of_7 b/pkg/sql/schemachanger/testdata/explain/drop_column_with_udf_default.rollback_4_of_7 new file mode 100644 index 000000000000..0be6fa2c0a50 --- /dev/null +++ b/pkg/sql/schemachanger/testdata/explain/drop_column_with_udf_default.rollback_4_of_7 @@ -0,0 +1,42 @@ +/* setup */ +CREATE FUNCTION f() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +CREATE TABLE t (i INT PRIMARY KEY, b INT DEFAULT f()); + +/* test */ +ALTER TABLE t DROP COLUMN b; +EXPLAIN (ddl) rollback at post-commit stage 4 of 7; +---- +Schema change plan for rolling back ALTER TABLE ‹defaultdb›.public.‹t› DROP COLUMN ‹b›; + └── PostCommitNonRevertiblePhase + ├── Stage 1 of 2 in PostCommitNonRevertiblePhase + │ ├── 2 elements transitioning toward PUBLIC + │ │ ├── WRITE_ONLY → PUBLIC Column:{DescID: 105, ColumnID: 2} + │ │ └── ABSENT → PUBLIC ColumnName:{DescID: 105, Name: b, ColumnID: 2} + │ ├── 4 elements transitioning toward ABSENT + │ │ ├── DELETE_ONLY → ABSENT PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} + │ │ ├── WRITE_ONLY → DELETE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ └── PUBLIC → ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} + │ └── 10 Mutation operations + │ ├── SetColumnName {"ColumnID":2,"Name":"b","TableID":105} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":2,"TableID":105} + │ ├── MakeWriteOnlyIndexDeleteOnly {"IndexID":3,"TableID":105} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":3,"TableID":105} + │ ├── MakeWriteOnlyColumnPublic {"ColumnID":2,"TableID":105} + │ ├── RefreshStats {"TableID":105} + │ ├── MakeIndexAbsent {"IndexID":2,"TableID":105} + │ ├── SetJobStateOnDescriptor {"DescriptorID":104} + │ ├── SetJobStateOnDescriptor {"DescriptorID":105} + │ └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"PostCommitNonRev..."} + └── Stage 2 of 2 in PostCommitNonRevertiblePhase + ├── 3 elements transitioning toward ABSENT + │ ├── PUBLIC → ABSENT IndexData:{DescID: 105, IndexID: 2} + │ ├── DELETE_ONLY → ABSENT TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ └── PUBLIC → ABSENT IndexData:{DescID: 105, IndexID: 3} + └── 6 Mutation operations + ├── CreateGCJobForIndex {"IndexID":2,"TableID":105} + ├── MakeIndexAbsent {"IndexID":3,"TableID":105} + ├── CreateGCJobForIndex {"IndexID":3,"TableID":105} + ├── RemoveJobStateFromDescriptor {"DescriptorID":104} + ├── RemoveJobStateFromDescriptor {"DescriptorID":105} + └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"all stages compl..."} diff --git a/pkg/sql/schemachanger/testdata/explain/drop_column_with_udf_default.rollback_5_of_7 b/pkg/sql/schemachanger/testdata/explain/drop_column_with_udf_default.rollback_5_of_7 new file mode 100644 index 000000000000..71d7ddfa325c --- /dev/null +++ b/pkg/sql/schemachanger/testdata/explain/drop_column_with_udf_default.rollback_5_of_7 @@ -0,0 +1,44 @@ +/* setup */ +CREATE FUNCTION f() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +CREATE TABLE t (i INT PRIMARY KEY, b INT DEFAULT f()); + +/* test */ +ALTER TABLE t DROP COLUMN b; +EXPLAIN (ddl) rollback at post-commit stage 5 of 7; +---- +Schema change plan for rolling back ALTER TABLE ‹defaultdb›.public.‹t› DROP COLUMN ‹b›; + └── PostCommitNonRevertiblePhase + ├── Stage 1 of 2 in PostCommitNonRevertiblePhase + │ ├── 2 elements transitioning toward PUBLIC + │ │ ├── WRITE_ONLY → PUBLIC Column:{DescID: 105, ColumnID: 2} + │ │ └── ABSENT → PUBLIC ColumnName:{DescID: 105, Name: b, ColumnID: 2} + │ ├── 4 elements transitioning toward ABSENT + │ │ ├── MERGE_ONLY → DELETE_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} + │ │ ├── WRITE_ONLY → DELETE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ └── PUBLIC → ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} + │ └── 10 Mutation operations + │ ├── SetColumnName {"ColumnID":2,"Name":"b","TableID":105} + │ ├── MakeWriteOnlyIndexDeleteOnly {"IndexID":3,"TableID":105} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":3,"TableID":105} + │ ├── MakeWriteOnlyColumnPublic {"ColumnID":2,"TableID":105} + │ ├── RefreshStats {"TableID":105} + │ ├── MakeWriteOnlyIndexDeleteOnly {"IndexID":2,"TableID":105} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":2,"TableID":105} + │ ├── SetJobStateOnDescriptor {"DescriptorID":104} + │ ├── SetJobStateOnDescriptor {"DescriptorID":105} + │ └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"PostCommitNonRev..."} + └── Stage 2 of 2 in PostCommitNonRevertiblePhase + ├── 4 elements transitioning toward ABSENT + │ ├── DELETE_ONLY → ABSENT PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ ├── PUBLIC → ABSENT IndexData:{DescID: 105, IndexID: 2} + │ ├── DELETE_ONLY → ABSENT TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ └── PUBLIC → ABSENT IndexData:{DescID: 105, IndexID: 3} + └── 7 Mutation operations + ├── MakeIndexAbsent {"IndexID":2,"TableID":105} + ├── CreateGCJobForIndex {"IndexID":2,"TableID":105} + ├── MakeIndexAbsent {"IndexID":3,"TableID":105} + ├── CreateGCJobForIndex {"IndexID":3,"TableID":105} + ├── RemoveJobStateFromDescriptor {"DescriptorID":104} + ├── RemoveJobStateFromDescriptor {"DescriptorID":105} + └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"all stages compl..."} diff --git a/pkg/sql/schemachanger/testdata/explain/drop_column_with_udf_default.rollback_6_of_7 b/pkg/sql/schemachanger/testdata/explain/drop_column_with_udf_default.rollback_6_of_7 new file mode 100644 index 000000000000..9c48e5acbdf1 --- /dev/null +++ b/pkg/sql/schemachanger/testdata/explain/drop_column_with_udf_default.rollback_6_of_7 @@ -0,0 +1,44 @@ +/* setup */ +CREATE FUNCTION f() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +CREATE TABLE t (i INT PRIMARY KEY, b INT DEFAULT f()); + +/* test */ +ALTER TABLE t DROP COLUMN b; +EXPLAIN (ddl) rollback at post-commit stage 6 of 7; +---- +Schema change plan for rolling back ALTER TABLE ‹defaultdb›.public.‹t› DROP COLUMN ‹b›; + └── PostCommitNonRevertiblePhase + ├── Stage 1 of 2 in PostCommitNonRevertiblePhase + │ ├── 2 elements transitioning toward PUBLIC + │ │ ├── WRITE_ONLY → PUBLIC Column:{DescID: 105, ColumnID: 2} + │ │ └── ABSENT → PUBLIC ColumnName:{DescID: 105, Name: b, ColumnID: 2} + │ ├── 4 elements transitioning toward ABSENT + │ │ ├── MERGE_ONLY → DELETE_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} + │ │ ├── WRITE_ONLY → DELETE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ └── PUBLIC → ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} + │ └── 10 Mutation operations + │ ├── SetColumnName {"ColumnID":2,"Name":"b","TableID":105} + │ ├── MakeWriteOnlyIndexDeleteOnly {"IndexID":3,"TableID":105} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":3,"TableID":105} + │ ├── MakeWriteOnlyColumnPublic {"ColumnID":2,"TableID":105} + │ ├── RefreshStats {"TableID":105} + │ ├── MakeWriteOnlyIndexDeleteOnly {"IndexID":2,"TableID":105} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":2,"TableID":105} + │ ├── SetJobStateOnDescriptor {"DescriptorID":104} + │ ├── SetJobStateOnDescriptor {"DescriptorID":105} + │ └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"PostCommitNonRev..."} + └── Stage 2 of 2 in PostCommitNonRevertiblePhase + ├── 4 elements transitioning toward ABSENT + │ ├── DELETE_ONLY → ABSENT PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ ├── PUBLIC → ABSENT IndexData:{DescID: 105, IndexID: 2} + │ ├── DELETE_ONLY → ABSENT TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ └── PUBLIC → ABSENT IndexData:{DescID: 105, IndexID: 3} + └── 7 Mutation operations + ├── MakeIndexAbsent {"IndexID":2,"TableID":105} + ├── CreateGCJobForIndex {"IndexID":2,"TableID":105} + ├── MakeIndexAbsent {"IndexID":3,"TableID":105} + ├── CreateGCJobForIndex {"IndexID":3,"TableID":105} + ├── RemoveJobStateFromDescriptor {"DescriptorID":104} + ├── RemoveJobStateFromDescriptor {"DescriptorID":105} + └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"all stages compl..."} diff --git a/pkg/sql/schemachanger/testdata/explain/drop_column_with_udf_default.rollback_7_of_7 b/pkg/sql/schemachanger/testdata/explain/drop_column_with_udf_default.rollback_7_of_7 new file mode 100644 index 000000000000..9ebdbc99e915 --- /dev/null +++ b/pkg/sql/schemachanger/testdata/explain/drop_column_with_udf_default.rollback_7_of_7 @@ -0,0 +1,44 @@ +/* setup */ +CREATE FUNCTION f() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +CREATE TABLE t (i INT PRIMARY KEY, b INT DEFAULT f()); + +/* test */ +ALTER TABLE t DROP COLUMN b; +EXPLAIN (ddl) rollback at post-commit stage 7 of 7; +---- +Schema change plan for rolling back ALTER TABLE ‹defaultdb›.public.‹t› DROP COLUMN ‹b›; + └── PostCommitNonRevertiblePhase + ├── Stage 1 of 2 in PostCommitNonRevertiblePhase + │ ├── 2 elements transitioning toward PUBLIC + │ │ ├── WRITE_ONLY → PUBLIC Column:{DescID: 105, ColumnID: 2} + │ │ └── ABSENT → PUBLIC ColumnName:{DescID: 105, Name: b, ColumnID: 2} + │ ├── 4 elements transitioning toward ABSENT + │ │ ├── WRITE_ONLY → DELETE_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} + │ │ ├── WRITE_ONLY → DELETE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ └── PUBLIC → ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} + │ └── 10 Mutation operations + │ ├── SetColumnName {"ColumnID":2,"Name":"b","TableID":105} + │ ├── MakeWriteOnlyIndexDeleteOnly {"IndexID":2,"TableID":105} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":2,"TableID":105} + │ ├── MakeWriteOnlyIndexDeleteOnly {"IndexID":3,"TableID":105} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":3,"TableID":105} + │ ├── MakeWriteOnlyColumnPublic {"ColumnID":2,"TableID":105} + │ ├── RefreshStats {"TableID":105} + │ ├── SetJobStateOnDescriptor {"DescriptorID":104} + │ ├── SetJobStateOnDescriptor {"DescriptorID":105} + │ └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"PostCommitNonRev..."} + └── Stage 2 of 2 in PostCommitNonRevertiblePhase + ├── 4 elements transitioning toward ABSENT + │ ├── DELETE_ONLY → ABSENT PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ ├── PUBLIC → ABSENT IndexData:{DescID: 105, IndexID: 2} + │ ├── DELETE_ONLY → ABSENT TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ └── PUBLIC → ABSENT IndexData:{DescID: 105, IndexID: 3} + └── 7 Mutation operations + ├── MakeIndexAbsent {"IndexID":2,"TableID":105} + ├── CreateGCJobForIndex {"IndexID":2,"TableID":105} + ├── MakeIndexAbsent {"IndexID":3,"TableID":105} + ├── CreateGCJobForIndex {"IndexID":3,"TableID":105} + ├── RemoveJobStateFromDescriptor {"DescriptorID":104} + ├── RemoveJobStateFromDescriptor {"DescriptorID":105} + └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"all stages compl..."} diff --git a/pkg/sql/schemachanger/testdata/explain/drop_table_udf_default b/pkg/sql/schemachanger/testdata/explain/drop_table_udf_default new file mode 100644 index 000000000000..5c198c7a0072 --- /dev/null +++ b/pkg/sql/schemachanger/testdata/explain/drop_table_udf_default @@ -0,0 +1,159 @@ +/* setup */ +CREATE FUNCTION f() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +CREATE TABLE t (i INT PRIMARY KEY, b INT DEFAULT f()); + +/* test */ +EXPLAIN (ddl) DROP TABLE t; +---- +Schema change plan for DROP TABLE ‹defaultdb›.‹public›.‹t›; + ├── StatementPhase + │ └── Stage 1 of 1 in StatementPhase + │ ├── 23 elements transitioning toward ABSENT + │ │ ├── PUBLIC → ABSENT Namespace:{DescID: 105, Name: t, ReferencedDescID: 100} + │ │ ├── PUBLIC → ABSENT Owner:{DescID: 105} + │ │ ├── PUBLIC → ABSENT UserPrivileges:{DescID: 105, Name: admin} + │ │ ├── PUBLIC → ABSENT UserPrivileges:{DescID: 105, Name: root} + │ │ ├── PUBLIC → DROPPED Table:{DescID: 105} + │ │ ├── PUBLIC → ABSENT ObjectParent:{DescID: 105, ReferencedDescID: 101} + │ │ ├── PUBLIC → ABSENT ColumnFamily:{DescID: 105, Name: primary, ColumnFamilyID: 0} + │ │ ├── PUBLIC → WRITE_ONLY Column:{DescID: 105, ColumnID: 1} + │ │ ├── PUBLIC → ABSENT ColumnName:{DescID: 105, Name: i, ColumnID: 1} + │ │ ├── PUBLIC → ABSENT ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 1} + │ │ ├── PUBLIC → VALIDATED ColumnNotNull:{DescID: 105, ColumnID: 1, IndexID: 0} + │ │ ├── PUBLIC → WRITE_ONLY Column:{DescID: 105, ColumnID: 2} + │ │ ├── PUBLIC → ABSENT ColumnName:{DescID: 105, Name: b, ColumnID: 2} + │ │ ├── PUBLIC → ABSENT ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 2} + │ │ ├── PUBLIC → ABSENT ColumnDefaultExpression:{DescID: 105, ColumnID: 2, ReferencedFunctionIDs: [104]} + │ │ ├── PUBLIC → WRITE_ONLY Column:{DescID: 105, ColumnID: 4294967295} + │ │ ├── PUBLIC → ABSENT ColumnName:{DescID: 105, Name: crdb_internal_mvcc_timestamp, ColumnID: 4294967295} + │ │ ├── PUBLIC → ABSENT ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 4294967295} + │ │ ├── PUBLIC → WRITE_ONLY Column:{DescID: 105, ColumnID: 4294967294} + │ │ ├── PUBLIC → ABSENT ColumnName:{DescID: 105, Name: tableoid, ColumnID: 4294967294} + │ │ ├── PUBLIC → ABSENT ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 4294967294} + │ │ ├── PUBLIC → VALIDATED PrimaryIndex:{DescID: 105, IndexID: 1, ConstraintID: 1} + │ │ └── PUBLIC → ABSENT IndexName:{DescID: 105, Name: t_pkey, IndexID: 1} + │ └── 20 Mutation operations + │ ├── MarkDescriptorAsDropped {"DescriptorID":105} + │ ├── RemoveObjectParent {"ObjectID":105,"ParentSchemaID":101} + │ ├── NotImplementedForPublicObjects {"DescID":105,"ElementType":"scpb.ColumnFamil..."} + │ ├── MakePublicColumnWriteOnly {"ColumnID":1,"TableID":105} + │ ├── SetColumnName {"ColumnID":1,"Name":"crdb_internal_co...","TableID":105} + │ ├── MakePublicColumnNotNullValidated {"ColumnID":1,"TableID":105} + │ ├── MakePublicColumnWriteOnly {"ColumnID":2,"TableID":105} + │ ├── SetColumnName {"ColumnID":2,"Name":"crdb_internal_co...","TableID":105} + │ ├── RemoveColumnDefaultExpression {"ColumnID":2,"TableID":105} + │ ├── RemoveTableColumnBackReferencesInFunctions {"BackReferencedColumnID":2,"BackReferencedTableID":105} + │ ├── MakePublicColumnWriteOnly {"ColumnID":4294967295,"TableID":105} + │ ├── SetColumnName {"ColumnID":4294967295,"Name":"crdb_internal_co...","TableID":105} + │ ├── MakePublicColumnWriteOnly {"ColumnID":4294967294,"TableID":105} + │ ├── SetColumnName {"ColumnID":4294967294,"Name":"crdb_internal_co...","TableID":105} + │ ├── MakePublicPrimaryIndexWriteOnly {"IndexID":1,"TableID":105} + │ ├── SetIndexName {"IndexID":1,"Name":"crdb_internal_in...","TableID":105} + │ ├── DrainDescriptorName {"Namespace":{"DatabaseID":100,"DescriptorID":105,"Name":"t","SchemaID":101}} + │ ├── NotImplementedForPublicObjects {"DescID":105,"ElementType":"scpb.Owner"} + │ ├── RemoveUserPrivileges {"DescriptorID":105,"User":"admin"} + │ └── RemoveUserPrivileges {"DescriptorID":105,"User":"root"} + ├── PreCommitPhase + │ ├── Stage 1 of 2 in PreCommitPhase + │ │ ├── 23 elements transitioning toward ABSENT + │ │ │ ├── ABSENT → PUBLIC Namespace:{DescID: 105, Name: t, ReferencedDescID: 100} + │ │ │ ├── ABSENT → PUBLIC Owner:{DescID: 105} + │ │ │ ├── ABSENT → PUBLIC UserPrivileges:{DescID: 105, Name: admin} + │ │ │ ├── ABSENT → PUBLIC UserPrivileges:{DescID: 105, Name: root} + │ │ │ ├── DROPPED → PUBLIC Table:{DescID: 105} + │ │ │ ├── ABSENT → PUBLIC ObjectParent:{DescID: 105, ReferencedDescID: 101} + │ │ │ ├── ABSENT → PUBLIC ColumnFamily:{DescID: 105, Name: primary, ColumnFamilyID: 0} + │ │ │ ├── WRITE_ONLY → PUBLIC Column:{DescID: 105, ColumnID: 1} + │ │ │ ├── ABSENT → PUBLIC ColumnName:{DescID: 105, Name: i, ColumnID: 1} + │ │ │ ├── ABSENT → PUBLIC ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 1} + │ │ │ ├── VALIDATED → PUBLIC ColumnNotNull:{DescID: 105, ColumnID: 1, IndexID: 0} + │ │ │ ├── WRITE_ONLY → PUBLIC Column:{DescID: 105, ColumnID: 2} + │ │ │ ├── ABSENT → PUBLIC ColumnName:{DescID: 105, Name: b, ColumnID: 2} + │ │ │ ├── ABSENT → PUBLIC ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 2} + │ │ │ ├── ABSENT → PUBLIC ColumnDefaultExpression:{DescID: 105, ColumnID: 2, ReferencedFunctionIDs: [104]} + │ │ │ ├── WRITE_ONLY → PUBLIC Column:{DescID: 105, ColumnID: 4294967295} + │ │ │ ├── ABSENT → PUBLIC ColumnName:{DescID: 105, Name: crdb_internal_mvcc_timestamp, ColumnID: 4294967295} + │ │ │ ├── ABSENT → PUBLIC ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 4294967295} + │ │ │ ├── WRITE_ONLY → PUBLIC Column:{DescID: 105, ColumnID: 4294967294} + │ │ │ ├── ABSENT → PUBLIC ColumnName:{DescID: 105, Name: tableoid, ColumnID: 4294967294} + │ │ │ ├── ABSENT → PUBLIC ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 4294967294} + │ │ │ ├── VALIDATED → PUBLIC PrimaryIndex:{DescID: 105, IndexID: 1, ConstraintID: 1} + │ │ │ └── ABSENT → PUBLIC IndexName:{DescID: 105, Name: t_pkey, IndexID: 1} + │ │ └── 1 Mutation operation + │ │ └── UndoAllInTxnImmediateMutationOpSideEffects + │ └── Stage 2 of 2 in PreCommitPhase + │ ├── 25 elements transitioning toward ABSENT + │ │ ├── PUBLIC → ABSENT Namespace:{DescID: 105, Name: t, ReferencedDescID: 100} + │ │ ├── PUBLIC → ABSENT Owner:{DescID: 105} + │ │ ├── PUBLIC → ABSENT UserPrivileges:{DescID: 105, Name: admin} + │ │ ├── PUBLIC → ABSENT UserPrivileges:{DescID: 105, Name: root} + │ │ ├── PUBLIC → DROPPED Table:{DescID: 105} + │ │ ├── PUBLIC → ABSENT ObjectParent:{DescID: 105, ReferencedDescID: 101} + │ │ ├── PUBLIC → ABSENT ColumnFamily:{DescID: 105, Name: primary, ColumnFamilyID: 0} + │ │ ├── PUBLIC → ABSENT Column:{DescID: 105, ColumnID: 1} + │ │ ├── PUBLIC → ABSENT ColumnName:{DescID: 105, Name: i, ColumnID: 1} + │ │ ├── PUBLIC → ABSENT ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 1} + │ │ ├── PUBLIC → ABSENT ColumnNotNull:{DescID: 105, ColumnID: 1, IndexID: 0} + │ │ ├── PUBLIC → ABSENT Column:{DescID: 105, ColumnID: 2} + │ │ ├── PUBLIC → ABSENT ColumnName:{DescID: 105, Name: b, ColumnID: 2} + │ │ ├── PUBLIC → ABSENT ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 2} + │ │ ├── PUBLIC → ABSENT ColumnDefaultExpression:{DescID: 105, ColumnID: 2, ReferencedFunctionIDs: [104]} + │ │ ├── PUBLIC → ABSENT Column:{DescID: 105, ColumnID: 4294967295} + │ │ ├── PUBLIC → ABSENT ColumnName:{DescID: 105, Name: crdb_internal_mvcc_timestamp, ColumnID: 4294967295} + │ │ ├── PUBLIC → ABSENT ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 4294967295} + │ │ ├── PUBLIC → ABSENT Column:{DescID: 105, ColumnID: 4294967294} + │ │ ├── PUBLIC → ABSENT ColumnName:{DescID: 105, Name: tableoid, ColumnID: 4294967294} + │ │ ├── PUBLIC → ABSENT ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 4294967294} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 1} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 105, ColumnID: 2, IndexID: 1} + │ │ ├── PUBLIC → ABSENT PrimaryIndex:{DescID: 105, IndexID: 1, ConstraintID: 1} + │ │ └── PUBLIC → ABSENT IndexName:{DescID: 105, Name: t_pkey, IndexID: 1} + │ └── 36 Mutation operations + │ ├── MarkDescriptorAsDropped {"DescriptorID":105} + │ ├── RemoveObjectParent {"ObjectID":105,"ParentSchemaID":101} + │ ├── NotImplementedForPublicObjects {"DescID":105,"ElementType":"scpb.ColumnFamil..."} + │ ├── MakePublicColumnWriteOnly {"ColumnID":1,"TableID":105} + │ ├── SetColumnName {"ColumnID":1,"Name":"crdb_internal_co...","TableID":105} + │ ├── MakePublicColumnNotNullValidated {"ColumnID":1,"TableID":105} + │ ├── MakePublicColumnWriteOnly {"ColumnID":2,"TableID":105} + │ ├── SetColumnName {"ColumnID":2,"Name":"crdb_internal_co...","TableID":105} + │ ├── RemoveColumnDefaultExpression {"ColumnID":2,"TableID":105} + │ ├── RemoveTableColumnBackReferencesInFunctions {"BackReferencedColumnID":2,"BackReferencedTableID":105} + │ ├── MakePublicColumnWriteOnly {"ColumnID":4294967295,"TableID":105} + │ ├── SetColumnName {"ColumnID":4294967295,"Name":"crdb_internal_co...","TableID":105} + │ ├── MakePublicColumnWriteOnly {"ColumnID":4294967294,"TableID":105} + │ ├── SetColumnName {"ColumnID":4294967294,"Name":"crdb_internal_co...","TableID":105} + │ ├── MakePublicPrimaryIndexWriteOnly {"IndexID":1,"TableID":105} + │ ├── SetIndexName {"IndexID":1,"Name":"crdb_internal_in...","TableID":105} + │ ├── DrainDescriptorName {"Namespace":{"DatabaseID":100,"DescriptorID":105,"Name":"t","SchemaID":101}} + │ ├── NotImplementedForPublicObjects {"DescID":105,"ElementType":"scpb.Owner"} + │ ├── RemoveUserPrivileges {"DescriptorID":105,"User":"admin"} + │ ├── RemoveUserPrivileges {"DescriptorID":105,"User":"root"} + │ ├── RemoveColumnNotNull {"ColumnID":1,"TableID":105} + │ ├── MakeWriteOnlyColumnDeleteOnly {"ColumnID":2,"TableID":105} + │ ├── MakeWriteOnlyColumnDeleteOnly {"ColumnID":4294967295,"TableID":105} + │ ├── MakeWriteOnlyColumnDeleteOnly {"ColumnID":4294967294,"TableID":105} + │ ├── MakeWriteOnlyColumnDeleteOnly {"ColumnID":1,"TableID":105} + │ ├── MakeDeleteOnlyColumnAbsent {"ColumnID":4294967295,"TableID":105} + │ ├── MakeDeleteOnlyColumnAbsent {"ColumnID":4294967294,"TableID":105} + │ ├── MakeWriteOnlyIndexDeleteOnly {"IndexID":1,"TableID":105} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":1,"TableID":105} + │ ├── RemoveColumnFromIndex {"ColumnID":2,"IndexID":1,"Kind":2,"TableID":105} + │ ├── MakeIndexAbsent {"IndexID":1,"TableID":105} + │ ├── MakeDeleteOnlyColumnAbsent {"ColumnID":1,"TableID":105} + │ ├── MakeDeleteOnlyColumnAbsent {"ColumnID":2,"TableID":105} + │ ├── SetJobStateOnDescriptor {"DescriptorID":104,"Initialize":true} + │ ├── SetJobStateOnDescriptor {"DescriptorID":105,"Initialize":true} + │ └── CreateSchemaChangerJob {"NonCancelable":true,"RunningStatus":"PostCommitNonRev..."} + └── PostCommitNonRevertiblePhase + └── Stage 1 of 1 in PostCommitNonRevertiblePhase + ├── 3 elements transitioning toward ABSENT + │ ├── DROPPED → ABSENT Table:{DescID: 105} + │ ├── PUBLIC → ABSENT IndexData:{DescID: 105, IndexID: 1} + │ └── PUBLIC → ABSENT TableData:{DescID: 105, ReferencedDescID: 100} + └── 5 Mutation operations + ├── CreateGCJobForTable {"DatabaseID":100,"TableID":105} + ├── CreateGCJobForIndex {"IndexID":1,"TableID":105} + ├── RemoveJobStateFromDescriptor {"DescriptorID":104} + ├── RemoveJobStateFromDescriptor {"DescriptorID":105} + └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"all stages compl..."} diff --git a/pkg/sql/schemachanger/testdata/explain_verbose/drop_column_with_udf_default b/pkg/sql/schemachanger/testdata/explain_verbose/drop_column_with_udf_default new file mode 100644 index 000000000000..b378798e6157 --- /dev/null +++ b/pkg/sql/schemachanger/testdata/explain_verbose/drop_column_with_udf_default @@ -0,0 +1,717 @@ +/* setup */ +CREATE FUNCTION f() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +CREATE TABLE t (i INT PRIMARY KEY, b INT DEFAULT f()); + +/* test */ +EXPLAIN (ddl, verbose) ALTER TABLE t DROP COLUMN b; +---- +• Schema change plan for ALTER TABLE ‹defaultdb›.‹public›.‹t› DROP COLUMN ‹b›; +│ +├── • StatementPhase +│ │ +│ └── • Stage 1 of 1 in StatementPhase +│ │ +│ ├── • 3 elements transitioning toward PUBLIC +│ │ │ +│ │ ├── • PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} +│ │ │ │ ABSENT → BACKFILL_ONLY +│ │ │ │ +│ │ │ └── • PreviousStagePrecedence dependency from ABSENT PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} +│ │ │ rule: "PrimaryIndex transitions to PUBLIC uphold 2-version invariant: ABSENT->BACKFILL_ONLY" +│ │ │ +│ │ ├── • IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} +│ │ │ │ ABSENT → PUBLIC +│ │ │ │ +│ │ │ └── • Precedence dependency from BACKFILL_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} +│ │ │ rule: "index existence precedes index dependents" +│ │ │ +│ │ └── • IndexData:{DescID: 105, IndexID: 2} +│ │ │ ABSENT → PUBLIC +│ │ │ +│ │ └── • SameStagePrecedence dependency from BACKFILL_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} +│ │ rule: "index data exists as soon as index accepts backfills" +│ │ +│ ├── • 2 elements transitioning toward TRANSIENT_ABSENT +│ │ │ +│ │ ├── • TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} +│ │ │ │ ABSENT → DELETE_ONLY +│ │ │ │ +│ │ │ └── • PreviousStagePrecedence dependency from ABSENT TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} +│ │ │ rule: "TemporaryIndex transitions to TRANSIENT_ABSENT uphold 2-version invariant: ABSENT->DELETE_ONLY" +│ │ │ +│ │ └── • IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} +│ │ │ ABSENT → PUBLIC +│ │ │ +│ │ └── • Precedence dependency from DELETE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} +│ │ rule: "temp index existence precedes index dependents" +│ │ +│ ├── • 2 elements transitioning toward ABSENT +│ │ │ +│ │ ├── • Column:{DescID: 105, ColumnID: 2} +│ │ │ │ PUBLIC → WRITE_ONLY +│ │ │ │ +│ │ │ └── • PreviousStagePrecedence dependency from PUBLIC Column:{DescID: 105, ColumnID: 2} +│ │ │ rule: "Column transitions to ABSENT uphold 2-version invariant: PUBLIC->WRITE_ONLY" +│ │ │ +│ │ └── • ColumnName:{DescID: 105, Name: b, ColumnID: 2} +│ │ │ PUBLIC → ABSENT +│ │ │ +│ │ └── • Precedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 2} +│ │ rule: "column no longer public before dependents" +│ │ +│ └── • 6 Mutation operations +│ │ +│ ├── • MakePublicColumnWriteOnly +│ │ ColumnID: 2 +│ │ TableID: 105 +│ │ +│ ├── • SetColumnName +│ │ ColumnID: 2 +│ │ Name: crdb_internal_column_2_name_placeholder +│ │ TableID: 105 +│ │ +│ ├── • MakeAbsentIndexBackfilling +│ │ Index: +│ │ ConstraintID: 2 +│ │ IndexID: 2 +│ │ IsUnique: true +│ │ SourceIndexID: 1 +│ │ TableID: 105 +│ │ TemporaryIndexID: 3 +│ │ +│ ├── • AddColumnToIndex +│ │ ColumnID: 1 +│ │ IndexID: 2 +│ │ TableID: 105 +│ │ +│ ├── • MakeAbsentTempIndexDeleteOnly +│ │ Index: +│ │ ConstraintID: 3 +│ │ IndexID: 3 +│ │ IsUnique: true +│ │ SourceIndexID: 1 +│ │ TableID: 105 +│ │ +│ └── • AddColumnToIndex +│ ColumnID: 1 +│ IndexID: 3 +│ TableID: 105 +│ +├── • PreCommitPhase +│ │ +│ ├── • Stage 1 of 2 in PreCommitPhase +│ │ │ +│ │ ├── • 3 elements transitioning toward PUBLIC +│ │ │ │ +│ │ │ ├── • PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} +│ │ │ │ BACKFILL_ONLY → ABSENT +│ │ │ │ +│ │ │ ├── • IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ └── • IndexData:{DescID: 105, IndexID: 2} +│ │ │ PUBLIC → ABSENT +│ │ │ +│ │ ├── • 2 elements transitioning toward TRANSIENT_ABSENT +│ │ │ │ +│ │ │ ├── • TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} +│ │ │ │ DELETE_ONLY → ABSENT +│ │ │ │ +│ │ │ └── • IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} +│ │ │ PUBLIC → ABSENT +│ │ │ +│ │ ├── • 2 elements transitioning toward ABSENT +│ │ │ │ +│ │ │ ├── • Column:{DescID: 105, ColumnID: 2} +│ │ │ │ WRITE_ONLY → PUBLIC +│ │ │ │ +│ │ │ └── • ColumnName:{DescID: 105, Name: b, ColumnID: 2} +│ │ │ ABSENT → PUBLIC +│ │ │ +│ │ └── • 1 Mutation operation +│ │ │ +│ │ └── • UndoAllInTxnImmediateMutationOpSideEffects +│ │ {} +│ │ +│ └── • Stage 2 of 2 in PreCommitPhase +│ │ +│ ├── • 3 elements transitioning toward PUBLIC +│ │ │ +│ │ ├── • PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} +│ │ │ │ ABSENT → BACKFILL_ONLY +│ │ │ │ +│ │ │ └── • PreviousStagePrecedence dependency from ABSENT PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} +│ │ │ rule: "PrimaryIndex transitions to PUBLIC uphold 2-version invariant: ABSENT->BACKFILL_ONLY" +│ │ │ +│ │ ├── • IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} +│ │ │ │ ABSENT → PUBLIC +│ │ │ │ +│ │ │ └── • Precedence dependency from BACKFILL_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} +│ │ │ rule: "index existence precedes index dependents" +│ │ │ +│ │ └── • IndexData:{DescID: 105, IndexID: 2} +│ │ │ ABSENT → PUBLIC +│ │ │ +│ │ └── • SameStagePrecedence dependency from BACKFILL_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} +│ │ rule: "index data exists as soon as index accepts backfills" +│ │ +│ ├── • 2 elements transitioning toward TRANSIENT_ABSENT +│ │ │ +│ │ ├── • TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} +│ │ │ │ ABSENT → DELETE_ONLY +│ │ │ │ +│ │ │ └── • PreviousStagePrecedence dependency from ABSENT TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} +│ │ │ rule: "TemporaryIndex transitions to TRANSIENT_ABSENT uphold 2-version invariant: ABSENT->DELETE_ONLY" +│ │ │ +│ │ └── • IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} +│ │ │ ABSENT → PUBLIC +│ │ │ +│ │ └── • Precedence dependency from DELETE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} +│ │ rule: "temp index existence precedes index dependents" +│ │ +│ ├── • 2 elements transitioning toward ABSENT +│ │ │ +│ │ ├── • Column:{DescID: 105, ColumnID: 2} +│ │ │ │ PUBLIC → WRITE_ONLY +│ │ │ │ +│ │ │ └── • PreviousStagePrecedence dependency from PUBLIC Column:{DescID: 105, ColumnID: 2} +│ │ │ rule: "Column transitions to ABSENT uphold 2-version invariant: PUBLIC->WRITE_ONLY" +│ │ │ +│ │ └── • ColumnName:{DescID: 105, Name: b, ColumnID: 2} +│ │ │ PUBLIC → ABSENT +│ │ │ +│ │ └── • Precedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 2} +│ │ rule: "column no longer public before dependents" +│ │ +│ └── • 11 Mutation operations +│ │ +│ ├── • MakePublicColumnWriteOnly +│ │ ColumnID: 2 +│ │ TableID: 105 +│ │ +│ ├── • SetColumnName +│ │ ColumnID: 2 +│ │ Name: crdb_internal_column_2_name_placeholder +│ │ TableID: 105 +│ │ +│ ├── • MakeAbsentIndexBackfilling +│ │ Index: +│ │ ConstraintID: 2 +│ │ IndexID: 2 +│ │ IsUnique: true +│ │ SourceIndexID: 1 +│ │ TableID: 105 +│ │ TemporaryIndexID: 3 +│ │ +│ ├── • MaybeAddSplitForIndex +│ │ IndexID: 2 +│ │ TableID: 105 +│ │ +│ ├── • AddColumnToIndex +│ │ ColumnID: 1 +│ │ IndexID: 2 +│ │ TableID: 105 +│ │ +│ ├── • MakeAbsentTempIndexDeleteOnly +│ │ Index: +│ │ ConstraintID: 3 +│ │ IndexID: 3 +│ │ IsUnique: true +│ │ SourceIndexID: 1 +│ │ TableID: 105 +│ │ +│ ├── • MaybeAddSplitForIndex +│ │ IndexID: 3 +│ │ TableID: 105 +│ │ +│ ├── • AddColumnToIndex +│ │ ColumnID: 1 +│ │ IndexID: 3 +│ │ TableID: 105 +│ │ +│ ├── • SetJobStateOnDescriptor +│ │ DescriptorID: 104 +│ │ Initialize: true +│ │ +│ ├── • SetJobStateOnDescriptor +│ │ DescriptorID: 105 +│ │ Initialize: true +│ │ +│ └── • CreateSchemaChangerJob +│ Authorization: +│ UserName: root +│ DescriptorIDs: +│ - 104 +│ - 105 +│ JobID: 1 +│ RunningStatus: PostCommitPhase stage 1 of 7 with 1 MutationType op pending +│ Statements: +│ - statement: ALTER TABLE t DROP COLUMN b +│ redactedstatement: ALTER TABLE ‹defaultdb›.‹public›.‹t› DROP COLUMN ‹b› +│ statementtag: ALTER TABLE +│ +├── • PostCommitPhase +│ │ +│ ├── • Stage 1 of 7 in PostCommitPhase +│ │ │ +│ │ ├── • 2 elements transitioning toward TRANSIENT_ABSENT +│ │ │ │ +│ │ │ ├── • TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} +│ │ │ │ │ DELETE_ONLY → WRITE_ONLY +│ │ │ │ │ +│ │ │ │ ├── • PreviousStagePrecedence dependency from DELETE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} +│ │ │ │ │ rule: "TemporaryIndex transitions to TRANSIENT_ABSENT uphold 2-version invariant: DELETE_ONLY->WRITE_ONLY" +│ │ │ │ │ +│ │ │ │ └── • Precedence dependency from PUBLIC IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} +│ │ │ │ rule: "index-column added to index before temp index receives writes" +│ │ │ │ +│ │ │ └── • IndexData:{DescID: 105, IndexID: 3} +│ │ │ │ ABSENT → PUBLIC +│ │ │ │ +│ │ │ └── • SameStagePrecedence dependency from WRITE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} +│ │ │ rule: "temp index data exists as soon as temp index accepts writes" +│ │ │ +│ │ └── • 4 Mutation operations +│ │ │ +│ │ ├── • MakeDeleteOnlyIndexWriteOnly +│ │ │ IndexID: 3 +│ │ │ TableID: 105 +│ │ │ +│ │ ├── • SetJobStateOnDescriptor +│ │ │ DescriptorID: 104 +│ │ │ +│ │ ├── • SetJobStateOnDescriptor +│ │ │ DescriptorID: 105 +│ │ │ +│ │ └── • UpdateSchemaChangerJob +│ │ JobID: 1 +│ │ RunningStatus: PostCommitPhase stage 2 of 7 with 1 BackfillType op pending +│ │ +│ ├── • Stage 2 of 7 in PostCommitPhase +│ │ │ +│ │ ├── • 1 element transitioning toward PUBLIC +│ │ │ │ +│ │ │ └── • PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} +│ │ │ │ BACKFILL_ONLY → BACKFILLED +│ │ │ │ +│ │ │ ├── • PreviousStagePrecedence dependency from BACKFILL_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} +│ │ │ │ rule: "PrimaryIndex transitions to PUBLIC uphold 2-version invariant: BACKFILL_ONLY->BACKFILLED" +│ │ │ │ +│ │ │ ├── • Precedence dependency from PUBLIC IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} +│ │ │ │ rule: "index-column added to index before index is backfilled" +│ │ │ │ +│ │ │ └── • Precedence dependency from WRITE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} +│ │ │ rule: "temp index is WRITE_ONLY before backfill" +│ │ │ +│ │ └── • 1 Backfill operation +│ │ │ +│ │ └── • BackfillIndex +│ │ IndexID: 2 +│ │ SourceIndexID: 1 +│ │ TableID: 105 +│ │ +│ ├── • Stage 3 of 7 in PostCommitPhase +│ │ │ +│ │ ├── • 1 element transitioning toward PUBLIC +│ │ │ │ +│ │ │ └── • PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} +│ │ │ │ BACKFILLED → DELETE_ONLY +│ │ │ │ +│ │ │ └── • PreviousStagePrecedence dependency from BACKFILLED PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} +│ │ │ rule: "PrimaryIndex transitions to PUBLIC uphold 2-version invariant: BACKFILLED->DELETE_ONLY" +│ │ │ +│ │ └── • 4 Mutation operations +│ │ │ +│ │ ├── • MakeBackfillingIndexDeleteOnly +│ │ │ IndexID: 2 +│ │ │ TableID: 105 +│ │ │ +│ │ ├── • SetJobStateOnDescriptor +│ │ │ DescriptorID: 104 +│ │ │ +│ │ ├── • SetJobStateOnDescriptor +│ │ │ DescriptorID: 105 +│ │ │ +│ │ └── • UpdateSchemaChangerJob +│ │ JobID: 1 +│ │ RunningStatus: PostCommitPhase stage 4 of 7 with 1 MutationType op pending +│ │ +│ ├── • Stage 4 of 7 in PostCommitPhase +│ │ │ +│ │ ├── • 1 element transitioning toward PUBLIC +│ │ │ │ +│ │ │ └── • PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} +│ │ │ │ DELETE_ONLY → MERGE_ONLY +│ │ │ │ +│ │ │ └── • PreviousStagePrecedence dependency from DELETE_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} +│ │ │ rule: "PrimaryIndex transitions to PUBLIC uphold 2-version invariant: DELETE_ONLY->MERGE_ONLY" +│ │ │ +│ │ └── • 4 Mutation operations +│ │ │ +│ │ ├── • MakeBackfilledIndexMerging +│ │ │ IndexID: 2 +│ │ │ TableID: 105 +│ │ │ +│ │ ├── • SetJobStateOnDescriptor +│ │ │ DescriptorID: 104 +│ │ │ +│ │ ├── • SetJobStateOnDescriptor +│ │ │ DescriptorID: 105 +│ │ │ +│ │ └── • UpdateSchemaChangerJob +│ │ JobID: 1 +│ │ RunningStatus: PostCommitPhase stage 5 of 7 with 1 BackfillType op pending +│ │ +│ ├── • Stage 5 of 7 in PostCommitPhase +│ │ │ +│ │ ├── • 1 element transitioning toward PUBLIC +│ │ │ │ +│ │ │ └── • PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} +│ │ │ │ MERGE_ONLY → MERGED +│ │ │ │ +│ │ │ └── • PreviousStagePrecedence dependency from MERGE_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} +│ │ │ rule: "PrimaryIndex transitions to PUBLIC uphold 2-version invariant: MERGE_ONLY->MERGED" +│ │ │ +│ │ └── • 1 Backfill operation +│ │ │ +│ │ └── • MergeIndex +│ │ BackfilledIndexID: 2 +│ │ TableID: 105 +│ │ TemporaryIndexID: 3 +│ │ +│ ├── • Stage 6 of 7 in PostCommitPhase +│ │ │ +│ │ ├── • 1 element transitioning toward PUBLIC +│ │ │ │ +│ │ │ └── • PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} +│ │ │ │ MERGED → WRITE_ONLY +│ │ │ │ +│ │ │ └── • PreviousStagePrecedence dependency from MERGED PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} +│ │ │ rule: "PrimaryIndex transitions to PUBLIC uphold 2-version invariant: MERGED->WRITE_ONLY" +│ │ │ +│ │ └── • 4 Mutation operations +│ │ │ +│ │ ├── • MakeMergedIndexWriteOnly +│ │ │ IndexID: 2 +│ │ │ TableID: 105 +│ │ │ +│ │ ├── • SetJobStateOnDescriptor +│ │ │ DescriptorID: 104 +│ │ │ +│ │ ├── • SetJobStateOnDescriptor +│ │ │ DescriptorID: 105 +│ │ │ +│ │ └── • UpdateSchemaChangerJob +│ │ JobID: 1 +│ │ RunningStatus: PostCommitPhase stage 7 of 7 with 1 ValidationType op pending +│ │ +│ └── • Stage 7 of 7 in PostCommitPhase +│ │ +│ ├── • 1 element transitioning toward PUBLIC +│ │ │ +│ │ └── • PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} +│ │ │ WRITE_ONLY → VALIDATED +│ │ │ +│ │ └── • PreviousStagePrecedence dependency from WRITE_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} +│ │ rule: "PrimaryIndex transitions to PUBLIC uphold 2-version invariant: WRITE_ONLY->VALIDATED" +│ │ +│ └── • 1 Validation operation +│ │ +│ └── • ValidateIndex +│ IndexID: 2 +│ TableID: 105 +│ +└── • PostCommitNonRevertiblePhase + │ + ├── • Stage 1 of 3 in PostCommitNonRevertiblePhase + │ │ + │ ├── • 2 elements transitioning toward PUBLIC + │ │ │ + │ │ ├── • PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ │ VALIDATED → PUBLIC + │ │ │ │ + │ │ │ ├── • SameStagePrecedence dependency from VALIDATED PrimaryIndex:{DescID: 105, IndexID: 1, ConstraintID: 1} + │ │ │ │ rule: "primary index swap" + │ │ │ │ + │ │ │ ├── • PreviousStagePrecedence dependency from VALIDATED PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ │ rule: "PrimaryIndex transitions to PUBLIC uphold 2-version invariant: VALIDATED->PUBLIC" + │ │ │ │ + │ │ │ ├── • SameStagePrecedence dependency from PUBLIC IndexName:{DescID: 105, Name: t_pkey, IndexID: 2} + │ │ │ │ rule: "index dependents exist before index becomes public" + │ │ │ │ rule: "primary index named right before index becomes public" + │ │ │ │ + │ │ │ └── • Precedence dependency from PUBLIC IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} + │ │ │ rule: "index dependents exist before index becomes public" + │ │ │ + │ │ └── • IndexName:{DescID: 105, Name: t_pkey, IndexID: 2} + │ │ │ ABSENT → PUBLIC + │ │ │ + │ │ └── • Precedence dependency from BACKFILL_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ rule: "index existence precedes index dependents" + │ │ + │ ├── • 2 elements transitioning toward TRANSIENT_ABSENT + │ │ │ + │ │ ├── • TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ │ WRITE_ONLY → TRANSIENT_DELETE_ONLY + │ │ │ │ + │ │ │ └── • PreviousStagePrecedence dependency from WRITE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ rule: "TemporaryIndex transitions to TRANSIENT_ABSENT uphold 2-version invariant: WRITE_ONLY->TRANSIENT_DELETE_ONLY" + │ │ │ + │ │ └── • IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} + │ │ │ PUBLIC → TRANSIENT_ABSENT + │ │ │ + │ │ └── • Precedence dependency from TRANSIENT_DELETE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ rule: "index drop mutation visible before cleaning up index columns" + │ │ + │ ├── • 3 elements transitioning toward ABSENT + │ │ │ + │ │ ├── • Column:{DescID: 105, ColumnID: 2} + │ │ │ │ WRITE_ONLY → DELETE_ONLY + │ │ │ │ + │ │ │ └── • PreviousStagePrecedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 2} + │ │ │ rule: "Column transitions to ABSENT uphold 2-version invariant: WRITE_ONLY->DELETE_ONLY" + │ │ │ + │ │ ├── • PrimaryIndex:{DescID: 105, IndexID: 1, ConstraintID: 1} + │ │ │ │ PUBLIC → VALIDATED + │ │ │ │ + │ │ │ └── • PreviousStagePrecedence dependency from PUBLIC PrimaryIndex:{DescID: 105, IndexID: 1, ConstraintID: 1} + │ │ │ rule: "PrimaryIndex transitions to ABSENT uphold 2-version invariant: PUBLIC->VALIDATED" + │ │ │ + │ │ └── • IndexName:{DescID: 105, Name: t_pkey, IndexID: 1} + │ │ │ PUBLIC → ABSENT + │ │ │ + │ │ └── • Precedence dependency from VALIDATED PrimaryIndex:{DescID: 105, IndexID: 1, ConstraintID: 1} + │ │ rule: "index no longer public before dependents, excluding columns" + │ │ + │ └── • 10 Mutation operations + │ │ + │ ├── • MakeWriteOnlyColumnDeleteOnly + │ │ ColumnID: 2 + │ │ TableID: 105 + │ │ + │ ├── • MakePublicPrimaryIndexWriteOnly + │ │ IndexID: 1 + │ │ TableID: 105 + │ │ + │ ├── • SetIndexName + │ │ IndexID: 1 + │ │ Name: crdb_internal_index_1_name_placeholder + │ │ TableID: 105 + │ │ + │ ├── • SetIndexName + │ │ IndexID: 2 + │ │ Name: t_pkey + │ │ TableID: 105 + │ │ + │ ├── • MakeWriteOnlyIndexDeleteOnly + │ │ IndexID: 3 + │ │ TableID: 105 + │ │ + │ ├── • RemoveColumnFromIndex + │ │ ColumnID: 1 + │ │ IndexID: 3 + │ │ TableID: 105 + │ │ + │ ├── • MakeValidatedPrimaryIndexPublic + │ │ IndexID: 2 + │ │ TableID: 105 + │ │ + │ ├── • SetJobStateOnDescriptor + │ │ DescriptorID: 104 + │ │ + │ ├── • SetJobStateOnDescriptor + │ │ DescriptorID: 105 + │ │ + │ └── • UpdateSchemaChangerJob + │ IsNonCancelable: true + │ JobID: 1 + │ RunningStatus: PostCommitNonRevertiblePhase stage 2 of 3 with 4 MutationType ops pending + │ + ├── • Stage 2 of 3 in PostCommitNonRevertiblePhase + │ │ + │ ├── • 1 element transitioning toward TRANSIENT_ABSENT + │ │ │ + │ │ └── • TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ TRANSIENT_DELETE_ONLY → TRANSIENT_ABSENT + │ │ │ + │ │ ├── • PreviousStagePrecedence dependency from TRANSIENT_DELETE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ rule: "TemporaryIndex transitions to TRANSIENT_ABSENT uphold 2-version invariant: TRANSIENT_DELETE_ONLY->TRANSIENT_ABSENT" + │ │ │ + │ │ └── • Precedence dependency from TRANSIENT_ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} + │ │ rule: "dependents removed before index" + │ │ + │ ├── • 3 elements transitioning toward ABSENT + │ │ │ + │ │ ├── • IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 1} + │ │ │ │ PUBLIC → ABSENT + │ │ │ │ + │ │ │ └── • Precedence dependency from DELETE_ONLY PrimaryIndex:{DescID: 105, IndexID: 1, ConstraintID: 1} + │ │ │ rule: "index drop mutation visible before cleaning up index columns" + │ │ │ + │ │ ├── • IndexColumn:{DescID: 105, ColumnID: 2, IndexID: 1} + │ │ │ │ PUBLIC → ABSENT + │ │ │ │ + │ │ │ ├── • Precedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 2} + │ │ │ │ rule: "column no longer public before dependents" + │ │ │ │ + │ │ │ └── • Precedence dependency from DELETE_ONLY PrimaryIndex:{DescID: 105, IndexID: 1, ConstraintID: 1} + │ │ │ rule: "index drop mutation visible before cleaning up index columns" + │ │ │ + │ │ └── • PrimaryIndex:{DescID: 105, IndexID: 1, ConstraintID: 1} + │ │ │ VALIDATED → DELETE_ONLY + │ │ │ + │ │ └── • PreviousStagePrecedence dependency from VALIDATED PrimaryIndex:{DescID: 105, IndexID: 1, ConstraintID: 1} + │ │ rule: "PrimaryIndex transitions to ABSENT uphold 2-version invariant: VALIDATED->WRITE_ONLY" + │ │ + │ └── • 7 Mutation operations + │ │ + │ ├── • MakeIndexAbsent + │ │ IndexID: 3 + │ │ TableID: 105 + │ │ + │ ├── • MakeWriteOnlyIndexDeleteOnly + │ │ IndexID: 1 + │ │ TableID: 105 + │ │ + │ ├── • RemoveColumnFromIndex + │ │ ColumnID: 1 + │ │ IndexID: 1 + │ │ TableID: 105 + │ │ + │ ├── • RemoveColumnFromIndex + │ │ ColumnID: 2 + │ │ IndexID: 1 + │ │ Kind: 2 + │ │ TableID: 105 + │ │ + │ ├── • SetJobStateOnDescriptor + │ │ DescriptorID: 104 + │ │ + │ ├── • SetJobStateOnDescriptor + │ │ DescriptorID: 105 + │ │ + │ └── • UpdateSchemaChangerJob + │ IsNonCancelable: true + │ JobID: 1 + │ RunningStatus: PostCommitNonRevertiblePhase stage 3 of 3 with 6 MutationType ops pending + │ + └── • Stage 3 of 3 in PostCommitNonRevertiblePhase + │ + ├── • 1 element transitioning toward TRANSIENT_ABSENT + │ │ + │ └── • IndexData:{DescID: 105, IndexID: 3} + │ │ PUBLIC → TRANSIENT_ABSENT + │ │ + │ ├── • SameStagePrecedence dependency from DROPPED IndexData:{DescID: 105, IndexID: 1} + │ │ rule: "schedule all GC jobs for a descriptor in the same stage" + │ │ + │ └── • Precedence dependency from TRANSIENT_ABSENT TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ rule: "index removed before garbage collection" + │ + ├── • 5 elements transitioning toward ABSENT + │ │ + │ ├── • Column:{DescID: 105, ColumnID: 2} + │ │ │ DELETE_ONLY → ABSENT + │ │ │ + │ │ ├── • PreviousStagePrecedence dependency from DELETE_ONLY Column:{DescID: 105, ColumnID: 2} + │ │ │ rule: "Column transitions to ABSENT uphold 2-version invariant: DELETE_ONLY->ABSENT" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT ColumnName:{DescID: 105, Name: b, ColumnID: 2} + │ │ │ rule: "dependents removed before column" + │ │ │ + │ │ ├── • SameStagePrecedence dependency from ABSENT ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 2} + │ │ │ rule: "dependents removed before column" + │ │ │ rule: "column type removed right before column when not dropping relation" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT ColumnDefaultExpression:{DescID: 105, ColumnID: 2, ReferencedFunctionIDs: [104]} + │ │ │ rule: "dependents removed before column" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT IndexColumn:{DescID: 105, ColumnID: 2, IndexID: 1} + │ │ │ rule: "dependents removed before column" + │ │ │ + │ │ └── • Precedence dependency from ABSENT PrimaryIndex:{DescID: 105, IndexID: 1, ConstraintID: 1} + │ │ rule: "indexes containing column reach absent before column" + │ │ + │ ├── • ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 2} + │ │ │ PUBLIC → ABSENT + │ │ │ + │ │ ├── • Precedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 2} + │ │ │ rule: "column no longer public before dependents" + │ │ │ + │ │ └── • SameStagePrecedence dependency from ABSENT ColumnDefaultExpression:{DescID: 105, ColumnID: 2, ReferencedFunctionIDs: [104]} + │ │ rule: "column type dependents removed right before column type" + │ │ + │ ├── • ColumnDefaultExpression:{DescID: 105, ColumnID: 2, ReferencedFunctionIDs: [104]} + │ │ │ PUBLIC → ABSENT + │ │ │ + │ │ └── • Precedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 2} + │ │ rule: "column no longer public before dependents" + │ │ + │ ├── • PrimaryIndex:{DescID: 105, IndexID: 1, ConstraintID: 1} + │ │ │ DELETE_ONLY → ABSENT + │ │ │ + │ │ ├── • Precedence dependency from ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 1} + │ │ │ rule: "dependents removed before index" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT IndexColumn:{DescID: 105, ColumnID: 2, IndexID: 1} + │ │ │ rule: "dependents removed before index" + │ │ │ + │ │ ├── • PreviousStagePrecedence dependency from DELETE_ONLY PrimaryIndex:{DescID: 105, IndexID: 1, ConstraintID: 1} + │ │ │ rule: "PrimaryIndex transitions to ABSENT uphold 2-version invariant: DELETE_ONLY->ABSENT" + │ │ │ + │ │ └── • Precedence dependency from ABSENT IndexName:{DescID: 105, Name: t_pkey, IndexID: 1} + │ │ rule: "dependents removed before index" + │ │ + │ └── • IndexData:{DescID: 105, IndexID: 1} + │ │ PUBLIC → ABSENT + │ │ + │ └── • Precedence dependency from ABSENT PrimaryIndex:{DescID: 105, IndexID: 1, ConstraintID: 1} + │ rule: "index removed before garbage collection" + │ + └── • 9 Mutation operations + │ + ├── • RemoveColumnDefaultExpression + │ ColumnID: 2 + │ TableID: 105 + │ + ├── • RemoveTableColumnBackReferencesInFunctions + │ BackReferencedColumnID: 2 + │ BackReferencedTableID: 105 + │ FunctionIDs: + │ - 104 + │ + ├── • MakeIndexAbsent + │ IndexID: 1 + │ TableID: 105 + │ + ├── • CreateGCJobForIndex + │ IndexID: 1 + │ StatementForDropJob: + │ Statement: ALTER TABLE defaultdb.public.t DROP COLUMN b + │ TableID: 105 + │ + ├── • CreateGCJobForIndex + │ IndexID: 3 + │ StatementForDropJob: + │ Statement: ALTER TABLE defaultdb.public.t DROP COLUMN b + │ TableID: 105 + │ + ├── • MakeDeleteOnlyColumnAbsent + │ ColumnID: 2 + │ TableID: 105 + │ + ├── • RemoveJobStateFromDescriptor + │ DescriptorID: 104 + │ JobID: 1 + │ + ├── • RemoveJobStateFromDescriptor + │ DescriptorID: 105 + │ JobID: 1 + │ + └── • UpdateSchemaChangerJob + DescriptorIDsToRemove: + - 104 + - 105 + IsNonCancelable: true + JobID: 1 + RunningStatus: all stages completed diff --git a/pkg/sql/schemachanger/testdata/explain_verbose/drop_column_with_udf_default.rollback_1_of_7 b/pkg/sql/schemachanger/testdata/explain_verbose/drop_column_with_udf_default.rollback_1_of_7 new file mode 100644 index 000000000000..825dbd2d8631 --- /dev/null +++ b/pkg/sql/schemachanger/testdata/explain_verbose/drop_column_with_udf_default.rollback_1_of_7 @@ -0,0 +1,132 @@ +/* setup */ +CREATE FUNCTION f() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +CREATE TABLE t (i INT PRIMARY KEY, b INT DEFAULT f()); + +/* test */ +ALTER TABLE t DROP COLUMN b; +EXPLAIN (ddl, verbose) rollback at post-commit stage 1 of 7; +---- +• Schema change plan for rolling back ALTER TABLE ‹defaultdb›.public.‹t› DROP COLUMN ‹b›; +│ +└── • PostCommitNonRevertiblePhase + │ + └── • Stage 1 of 1 in PostCommitNonRevertiblePhase + │ + ├── • 2 elements transitioning toward PUBLIC + │ │ + │ ├── • Column:{DescID: 105, ColumnID: 2} + │ │ │ WRITE_ONLY → PUBLIC + │ │ │ + │ │ ├── • PreviousStagePrecedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 2} + │ │ │ rule: "Column transitions to PUBLIC uphold 2-version invariant: WRITE_ONLY->PUBLIC" + │ │ │ + │ │ ├── • Precedence dependency from PUBLIC ColumnName:{DescID: 105, Name: b, ColumnID: 2} + │ │ │ rule: "column dependents exist before column becomes public" + │ │ │ + │ │ ├── • Precedence dependency from PUBLIC ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 2} + │ │ │ rule: "column dependents exist before column becomes public" + │ │ │ + │ │ ├── • Precedence dependency from PUBLIC ColumnDefaultExpression:{DescID: 105, ColumnID: 2, ReferencedFunctionIDs: [104]} + │ │ │ rule: "column dependents exist before column becomes public" + │ │ │ + │ │ └── • Precedence dependency from PUBLIC IndexColumn:{DescID: 105, ColumnID: 2, IndexID: 1} + │ │ rule: "column dependents exist before column becomes public" + │ │ + │ └── • ColumnName:{DescID: 105, Name: b, ColumnID: 2} + │ ABSENT → PUBLIC + │ + ├── • 5 elements transitioning toward ABSENT + │ │ + │ ├── • PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ BACKFILL_ONLY → ABSENT + │ │ │ + │ │ ├── • PreviousStagePrecedence dependency from BACKFILL_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ rule: "PrimaryIndex transitions to ABSENT uphold 2-version invariant: BACKFILL_ONLY->DELETE_ONLY" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT IndexName:{DescID: 105, Name: t_pkey, IndexID: 2} + │ │ │ rule: "dependents removed before index" + │ │ │ + │ │ └── • Precedence dependency from ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} + │ │ rule: "dependents removed before index" + │ │ + │ ├── • IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} + │ │ │ PUBLIC → ABSENT + │ │ │ + │ │ └── • Precedence dependency from DELETE_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ rule: "index drop mutation visible before cleaning up index columns" + │ │ + │ ├── • IndexData:{DescID: 105, IndexID: 2} + │ │ │ PUBLIC → ABSENT + │ │ │ + │ │ └── • Precedence dependency from ABSENT PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ rule: "index removed before garbage collection" + │ │ + │ ├── • TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ DELETE_ONLY → ABSENT + │ │ │ + │ │ ├── • PreviousStagePrecedence dependency from DELETE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ rule: "TemporaryIndex transitions to ABSENT uphold 2-version invariant: DELETE_ONLY->ABSENT" + │ │ │ + │ │ └── • Precedence dependency from ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} + │ │ rule: "dependents removed before index" + │ │ + │ └── • IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} + │ │ PUBLIC → ABSENT + │ │ + │ └── • Precedence dependency from DELETE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ rule: "index drop mutation visible before cleaning up index columns" + │ + └── • 11 Mutation operations + │ + ├── • SetColumnName + │ ColumnID: 2 + │ Name: b + │ TableID: 105 + │ + ├── • RemoveColumnFromIndex + │ ColumnID: 1 + │ IndexID: 2 + │ TableID: 105 + │ + ├── • RemoveColumnFromIndex + │ ColumnID: 1 + │ IndexID: 3 + │ TableID: 105 + │ + ├── • MakeWriteOnlyColumnPublic + │ ColumnID: 2 + │ TableID: 105 + │ + ├── • RefreshStats + │ TableID: 105 + │ + ├── • MakeIndexAbsent + │ IndexID: 2 + │ TableID: 105 + │ + ├── • CreateGCJobForIndex + │ IndexID: 2 + │ StatementForDropJob: + │ Rollback: true + │ Statement: ALTER TABLE defaultdb.public.t DROP COLUMN b + │ TableID: 105 + │ + ├── • MakeIndexAbsent + │ IndexID: 3 + │ TableID: 105 + │ + ├── • RemoveJobStateFromDescriptor + │ DescriptorID: 104 + │ JobID: 1 + │ + ├── • RemoveJobStateFromDescriptor + │ DescriptorID: 105 + │ JobID: 1 + │ + └── • UpdateSchemaChangerJob + DescriptorIDsToRemove: + - 104 + - 105 + IsNonCancelable: true + JobID: 1 + RunningStatus: all stages completed diff --git a/pkg/sql/schemachanger/testdata/explain_verbose/drop_column_with_udf_default.rollback_2_of_7 b/pkg/sql/schemachanger/testdata/explain_verbose/drop_column_with_udf_default.rollback_2_of_7 new file mode 100644 index 000000000000..e7c96e5623bb --- /dev/null +++ b/pkg/sql/schemachanger/testdata/explain_verbose/drop_column_with_udf_default.rollback_2_of_7 @@ -0,0 +1,175 @@ +/* setup */ +CREATE FUNCTION f() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +CREATE TABLE t (i INT PRIMARY KEY, b INT DEFAULT f()); + +/* test */ +ALTER TABLE t DROP COLUMN b; +EXPLAIN (ddl, verbose) rollback at post-commit stage 2 of 7; +---- +• Schema change plan for rolling back ALTER TABLE ‹defaultdb›.public.‹t› DROP COLUMN ‹b›; +│ +└── • PostCommitNonRevertiblePhase + │ + ├── • Stage 1 of 2 in PostCommitNonRevertiblePhase + │ │ + │ ├── • 2 elements transitioning toward PUBLIC + │ │ │ + │ │ ├── • Column:{DescID: 105, ColumnID: 2} + │ │ │ │ WRITE_ONLY → PUBLIC + │ │ │ │ + │ │ │ ├── • PreviousStagePrecedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 2} + │ │ │ │ rule: "Column transitions to PUBLIC uphold 2-version invariant: WRITE_ONLY->PUBLIC" + │ │ │ │ + │ │ │ ├── • Precedence dependency from PUBLIC ColumnName:{DescID: 105, Name: b, ColumnID: 2} + │ │ │ │ rule: "column dependents exist before column becomes public" + │ │ │ │ + │ │ │ ├── • Precedence dependency from PUBLIC ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 2} + │ │ │ │ rule: "column dependents exist before column becomes public" + │ │ │ │ + │ │ │ ├── • Precedence dependency from PUBLIC ColumnDefaultExpression:{DescID: 105, ColumnID: 2, ReferencedFunctionIDs: [104]} + │ │ │ │ rule: "column dependents exist before column becomes public" + │ │ │ │ + │ │ │ └── • Precedence dependency from PUBLIC IndexColumn:{DescID: 105, ColumnID: 2, IndexID: 1} + │ │ │ rule: "column dependents exist before column becomes public" + │ │ │ + │ │ └── • ColumnName:{DescID: 105, Name: b, ColumnID: 2} + │ │ ABSENT → PUBLIC + │ │ + │ ├── • 4 elements transitioning toward ABSENT + │ │ │ + │ │ ├── • PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ │ BACKFILL_ONLY → ABSENT + │ │ │ │ + │ │ │ ├── • PreviousStagePrecedence dependency from BACKFILL_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ │ rule: "PrimaryIndex transitions to ABSENT uphold 2-version invariant: BACKFILL_ONLY->DELETE_ONLY" + │ │ │ │ + │ │ │ ├── • Precedence dependency from ABSENT IndexName:{DescID: 105, Name: t_pkey, IndexID: 2} + │ │ │ │ rule: "dependents removed before index" + │ │ │ │ + │ │ │ └── • Precedence dependency from ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} + │ │ │ rule: "dependents removed before index" + │ │ │ + │ │ ├── • IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} + │ │ │ │ PUBLIC → ABSENT + │ │ │ │ + │ │ │ └── • Precedence dependency from DELETE_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ rule: "index drop mutation visible before cleaning up index columns" + │ │ │ + │ │ ├── • TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ │ WRITE_ONLY → DELETE_ONLY + │ │ │ │ + │ │ │ └── • PreviousStagePrecedence dependency from WRITE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ rule: "TemporaryIndex transitions to ABSENT uphold 2-version invariant: WRITE_ONLY->DELETE_ONLY" + │ │ │ + │ │ └── • IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} + │ │ │ PUBLIC → ABSENT + │ │ │ + │ │ └── • Precedence dependency from DELETE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ rule: "index drop mutation visible before cleaning up index columns" + │ │ + │ └── • 10 Mutation operations + │ │ + │ ├── • SetColumnName + │ │ ColumnID: 2 + │ │ Name: b + │ │ TableID: 105 + │ │ + │ ├── • RemoveColumnFromIndex + │ │ ColumnID: 1 + │ │ IndexID: 2 + │ │ TableID: 105 + │ │ + │ ├── • MakeWriteOnlyIndexDeleteOnly + │ │ IndexID: 3 + │ │ TableID: 105 + │ │ + │ ├── • RemoveColumnFromIndex + │ │ ColumnID: 1 + │ │ IndexID: 3 + │ │ TableID: 105 + │ │ + │ ├── • MakeWriteOnlyColumnPublic + │ │ ColumnID: 2 + │ │ TableID: 105 + │ │ + │ ├── • RefreshStats + │ │ TableID: 105 + │ │ + │ ├── • MakeIndexAbsent + │ │ IndexID: 2 + │ │ TableID: 105 + │ │ + │ ├── • SetJobStateOnDescriptor + │ │ DescriptorID: 104 + │ │ + │ ├── • SetJobStateOnDescriptor + │ │ DescriptorID: 105 + │ │ + │ └── • UpdateSchemaChangerJob + │ IsNonCancelable: true + │ JobID: 1 + │ RunningStatus: PostCommitNonRevertiblePhase stage 2 of 2 with 3 MutationType ops pending + │ + └── • Stage 2 of 2 in PostCommitNonRevertiblePhase + │ + ├── • 3 elements transitioning toward ABSENT + │ │ + │ ├── • IndexData:{DescID: 105, IndexID: 2} + │ │ │ PUBLIC → ABSENT + │ │ │ + │ │ └── • Precedence dependency from ABSENT PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ rule: "index removed before garbage collection" + │ │ + │ ├── • TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ DELETE_ONLY → ABSENT + │ │ │ + │ │ ├── • PreviousStagePrecedence dependency from DELETE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ rule: "TemporaryIndex transitions to ABSENT uphold 2-version invariant: DELETE_ONLY->ABSENT" + │ │ │ + │ │ └── • Precedence dependency from ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} + │ │ rule: "dependents removed before index" + │ │ + │ └── • IndexData:{DescID: 105, IndexID: 3} + │ │ PUBLIC → ABSENT + │ │ + │ ├── • SameStagePrecedence dependency from DROPPED IndexData:{DescID: 105, IndexID: 2} + │ │ rule: "schedule all GC jobs for a descriptor in the same stage" + │ │ + │ └── • Precedence dependency from ABSENT TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ rule: "index removed before garbage collection" + │ + └── • 6 Mutation operations + │ + ├── • CreateGCJobForIndex + │ IndexID: 2 + │ StatementForDropJob: + │ Rollback: true + │ Statement: ALTER TABLE defaultdb.public.t DROP COLUMN b + │ TableID: 105 + │ + ├── • MakeIndexAbsent + │ IndexID: 3 + │ TableID: 105 + │ + ├── • CreateGCJobForIndex + │ IndexID: 3 + │ StatementForDropJob: + │ Rollback: true + │ Statement: ALTER TABLE defaultdb.public.t DROP COLUMN b + │ TableID: 105 + │ + ├── • RemoveJobStateFromDescriptor + │ DescriptorID: 104 + │ JobID: 1 + │ + ├── • RemoveJobStateFromDescriptor + │ DescriptorID: 105 + │ JobID: 1 + │ + └── • UpdateSchemaChangerJob + DescriptorIDsToRemove: + - 104 + - 105 + IsNonCancelable: true + JobID: 1 + RunningStatus: all stages completed diff --git a/pkg/sql/schemachanger/testdata/explain_verbose/drop_column_with_udf_default.rollback_3_of_7 b/pkg/sql/schemachanger/testdata/explain_verbose/drop_column_with_udf_default.rollback_3_of_7 new file mode 100644 index 000000000000..1789afc782fa --- /dev/null +++ b/pkg/sql/schemachanger/testdata/explain_verbose/drop_column_with_udf_default.rollback_3_of_7 @@ -0,0 +1,175 @@ +/* setup */ +CREATE FUNCTION f() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +CREATE TABLE t (i INT PRIMARY KEY, b INT DEFAULT f()); + +/* test */ +ALTER TABLE t DROP COLUMN b; +EXPLAIN (ddl, verbose) rollback at post-commit stage 3 of 7; +---- +• Schema change plan for rolling back ALTER TABLE ‹defaultdb›.public.‹t› DROP COLUMN ‹b›; +│ +└── • PostCommitNonRevertiblePhase + │ + ├── • Stage 1 of 2 in PostCommitNonRevertiblePhase + │ │ + │ ├── • 2 elements transitioning toward PUBLIC + │ │ │ + │ │ ├── • Column:{DescID: 105, ColumnID: 2} + │ │ │ │ WRITE_ONLY → PUBLIC + │ │ │ │ + │ │ │ ├── • PreviousStagePrecedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 2} + │ │ │ │ rule: "Column transitions to PUBLIC uphold 2-version invariant: WRITE_ONLY->PUBLIC" + │ │ │ │ + │ │ │ ├── • Precedence dependency from PUBLIC ColumnName:{DescID: 105, Name: b, ColumnID: 2} + │ │ │ │ rule: "column dependents exist before column becomes public" + │ │ │ │ + │ │ │ ├── • Precedence dependency from PUBLIC ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 2} + │ │ │ │ rule: "column dependents exist before column becomes public" + │ │ │ │ + │ │ │ ├── • Precedence dependency from PUBLIC ColumnDefaultExpression:{DescID: 105, ColumnID: 2, ReferencedFunctionIDs: [104]} + │ │ │ │ rule: "column dependents exist before column becomes public" + │ │ │ │ + │ │ │ └── • Precedence dependency from PUBLIC IndexColumn:{DescID: 105, ColumnID: 2, IndexID: 1} + │ │ │ rule: "column dependents exist before column becomes public" + │ │ │ + │ │ └── • ColumnName:{DescID: 105, Name: b, ColumnID: 2} + │ │ ABSENT → PUBLIC + │ │ + │ ├── • 4 elements transitioning toward ABSENT + │ │ │ + │ │ ├── • PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ │ BACKFILL_ONLY → ABSENT + │ │ │ │ + │ │ │ ├── • PreviousStagePrecedence dependency from BACKFILL_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ │ rule: "PrimaryIndex transitions to ABSENT uphold 2-version invariant: BACKFILL_ONLY->DELETE_ONLY" + │ │ │ │ + │ │ │ ├── • Precedence dependency from ABSENT IndexName:{DescID: 105, Name: t_pkey, IndexID: 2} + │ │ │ │ rule: "dependents removed before index" + │ │ │ │ + │ │ │ └── • Precedence dependency from ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} + │ │ │ rule: "dependents removed before index" + │ │ │ + │ │ ├── • IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} + │ │ │ │ PUBLIC → ABSENT + │ │ │ │ + │ │ │ └── • Precedence dependency from DELETE_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ rule: "index drop mutation visible before cleaning up index columns" + │ │ │ + │ │ ├── • TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ │ WRITE_ONLY → DELETE_ONLY + │ │ │ │ + │ │ │ └── • PreviousStagePrecedence dependency from WRITE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ rule: "TemporaryIndex transitions to ABSENT uphold 2-version invariant: WRITE_ONLY->DELETE_ONLY" + │ │ │ + │ │ └── • IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} + │ │ │ PUBLIC → ABSENT + │ │ │ + │ │ └── • Precedence dependency from DELETE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ rule: "index drop mutation visible before cleaning up index columns" + │ │ + │ └── • 10 Mutation operations + │ │ + │ ├── • SetColumnName + │ │ ColumnID: 2 + │ │ Name: b + │ │ TableID: 105 + │ │ + │ ├── • RemoveColumnFromIndex + │ │ ColumnID: 1 + │ │ IndexID: 2 + │ │ TableID: 105 + │ │ + │ ├── • MakeWriteOnlyIndexDeleteOnly + │ │ IndexID: 3 + │ │ TableID: 105 + │ │ + │ ├── • RemoveColumnFromIndex + │ │ ColumnID: 1 + │ │ IndexID: 3 + │ │ TableID: 105 + │ │ + │ ├── • MakeWriteOnlyColumnPublic + │ │ ColumnID: 2 + │ │ TableID: 105 + │ │ + │ ├── • RefreshStats + │ │ TableID: 105 + │ │ + │ ├── • MakeIndexAbsent + │ │ IndexID: 2 + │ │ TableID: 105 + │ │ + │ ├── • SetJobStateOnDescriptor + │ │ DescriptorID: 104 + │ │ + │ ├── • SetJobStateOnDescriptor + │ │ DescriptorID: 105 + │ │ + │ └── • UpdateSchemaChangerJob + │ IsNonCancelable: true + │ JobID: 1 + │ RunningStatus: PostCommitNonRevertiblePhase stage 2 of 2 with 3 MutationType ops pending + │ + └── • Stage 2 of 2 in PostCommitNonRevertiblePhase + │ + ├── • 3 elements transitioning toward ABSENT + │ │ + │ ├── • IndexData:{DescID: 105, IndexID: 2} + │ │ │ PUBLIC → ABSENT + │ │ │ + │ │ └── • Precedence dependency from ABSENT PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ rule: "index removed before garbage collection" + │ │ + │ ├── • TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ DELETE_ONLY → ABSENT + │ │ │ + │ │ ├── • PreviousStagePrecedence dependency from DELETE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ rule: "TemporaryIndex transitions to ABSENT uphold 2-version invariant: DELETE_ONLY->ABSENT" + │ │ │ + │ │ └── • Precedence dependency from ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} + │ │ rule: "dependents removed before index" + │ │ + │ └── • IndexData:{DescID: 105, IndexID: 3} + │ │ PUBLIC → ABSENT + │ │ + │ ├── • SameStagePrecedence dependency from DROPPED IndexData:{DescID: 105, IndexID: 2} + │ │ rule: "schedule all GC jobs for a descriptor in the same stage" + │ │ + │ └── • Precedence dependency from ABSENT TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ rule: "index removed before garbage collection" + │ + └── • 6 Mutation operations + │ + ├── • CreateGCJobForIndex + │ IndexID: 2 + │ StatementForDropJob: + │ Rollback: true + │ Statement: ALTER TABLE defaultdb.public.t DROP COLUMN b + │ TableID: 105 + │ + ├── • MakeIndexAbsent + │ IndexID: 3 + │ TableID: 105 + │ + ├── • CreateGCJobForIndex + │ IndexID: 3 + │ StatementForDropJob: + │ Rollback: true + │ Statement: ALTER TABLE defaultdb.public.t DROP COLUMN b + │ TableID: 105 + │ + ├── • RemoveJobStateFromDescriptor + │ DescriptorID: 104 + │ JobID: 1 + │ + ├── • RemoveJobStateFromDescriptor + │ DescriptorID: 105 + │ JobID: 1 + │ + └── • UpdateSchemaChangerJob + DescriptorIDsToRemove: + - 104 + - 105 + IsNonCancelable: true + JobID: 1 + RunningStatus: all stages completed diff --git a/pkg/sql/schemachanger/testdata/explain_verbose/drop_column_with_udf_default.rollback_4_of_7 b/pkg/sql/schemachanger/testdata/explain_verbose/drop_column_with_udf_default.rollback_4_of_7 new file mode 100644 index 000000000000..cdab2ccbec4d --- /dev/null +++ b/pkg/sql/schemachanger/testdata/explain_verbose/drop_column_with_udf_default.rollback_4_of_7 @@ -0,0 +1,175 @@ +/* setup */ +CREATE FUNCTION f() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +CREATE TABLE t (i INT PRIMARY KEY, b INT DEFAULT f()); + +/* test */ +ALTER TABLE t DROP COLUMN b; +EXPLAIN (ddl, verbose) rollback at post-commit stage 4 of 7; +---- +• Schema change plan for rolling back ALTER TABLE ‹defaultdb›.public.‹t› DROP COLUMN ‹b›; +│ +└── • PostCommitNonRevertiblePhase + │ + ├── • Stage 1 of 2 in PostCommitNonRevertiblePhase + │ │ + │ ├── • 2 elements transitioning toward PUBLIC + │ │ │ + │ │ ├── • Column:{DescID: 105, ColumnID: 2} + │ │ │ │ WRITE_ONLY → PUBLIC + │ │ │ │ + │ │ │ ├── • PreviousStagePrecedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 2} + │ │ │ │ rule: "Column transitions to PUBLIC uphold 2-version invariant: WRITE_ONLY->PUBLIC" + │ │ │ │ + │ │ │ ├── • Precedence dependency from PUBLIC ColumnName:{DescID: 105, Name: b, ColumnID: 2} + │ │ │ │ rule: "column dependents exist before column becomes public" + │ │ │ │ + │ │ │ ├── • Precedence dependency from PUBLIC ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 2} + │ │ │ │ rule: "column dependents exist before column becomes public" + │ │ │ │ + │ │ │ ├── • Precedence dependency from PUBLIC ColumnDefaultExpression:{DescID: 105, ColumnID: 2, ReferencedFunctionIDs: [104]} + │ │ │ │ rule: "column dependents exist before column becomes public" + │ │ │ │ + │ │ │ └── • Precedence dependency from PUBLIC IndexColumn:{DescID: 105, ColumnID: 2, IndexID: 1} + │ │ │ rule: "column dependents exist before column becomes public" + │ │ │ + │ │ └── • ColumnName:{DescID: 105, Name: b, ColumnID: 2} + │ │ ABSENT → PUBLIC + │ │ + │ ├── • 4 elements transitioning toward ABSENT + │ │ │ + │ │ ├── • PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ │ DELETE_ONLY → ABSENT + │ │ │ │ + │ │ │ ├── • PreviousStagePrecedence dependency from DELETE_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ │ rule: "PrimaryIndex transitions to ABSENT uphold 2-version invariant: DELETE_ONLY->ABSENT" + │ │ │ │ + │ │ │ ├── • Precedence dependency from ABSENT IndexName:{DescID: 105, Name: t_pkey, IndexID: 2} + │ │ │ │ rule: "dependents removed before index" + │ │ │ │ + │ │ │ └── • Precedence dependency from ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} + │ │ │ rule: "dependents removed before index" + │ │ │ + │ │ ├── • IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} + │ │ │ │ PUBLIC → ABSENT + │ │ │ │ + │ │ │ └── • Precedence dependency from DELETE_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ rule: "index drop mutation visible before cleaning up index columns" + │ │ │ + │ │ ├── • TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ │ WRITE_ONLY → DELETE_ONLY + │ │ │ │ + │ │ │ └── • PreviousStagePrecedence dependency from WRITE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ rule: "TemporaryIndex transitions to ABSENT uphold 2-version invariant: WRITE_ONLY->DELETE_ONLY" + │ │ │ + │ │ └── • IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} + │ │ │ PUBLIC → ABSENT + │ │ │ + │ │ └── • Precedence dependency from DELETE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ rule: "index drop mutation visible before cleaning up index columns" + │ │ + │ └── • 10 Mutation operations + │ │ + │ ├── • SetColumnName + │ │ ColumnID: 2 + │ │ Name: b + │ │ TableID: 105 + │ │ + │ ├── • RemoveColumnFromIndex + │ │ ColumnID: 1 + │ │ IndexID: 2 + │ │ TableID: 105 + │ │ + │ ├── • MakeWriteOnlyIndexDeleteOnly + │ │ IndexID: 3 + │ │ TableID: 105 + │ │ + │ ├── • RemoveColumnFromIndex + │ │ ColumnID: 1 + │ │ IndexID: 3 + │ │ TableID: 105 + │ │ + │ ├── • MakeWriteOnlyColumnPublic + │ │ ColumnID: 2 + │ │ TableID: 105 + │ │ + │ ├── • RefreshStats + │ │ TableID: 105 + │ │ + │ ├── • MakeIndexAbsent + │ │ IndexID: 2 + │ │ TableID: 105 + │ │ + │ ├── • SetJobStateOnDescriptor + │ │ DescriptorID: 104 + │ │ + │ ├── • SetJobStateOnDescriptor + │ │ DescriptorID: 105 + │ │ + │ └── • UpdateSchemaChangerJob + │ IsNonCancelable: true + │ JobID: 1 + │ RunningStatus: PostCommitNonRevertiblePhase stage 2 of 2 with 3 MutationType ops pending + │ + └── • Stage 2 of 2 in PostCommitNonRevertiblePhase + │ + ├── • 3 elements transitioning toward ABSENT + │ │ + │ ├── • IndexData:{DescID: 105, IndexID: 2} + │ │ │ PUBLIC → ABSENT + │ │ │ + │ │ └── • Precedence dependency from ABSENT PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ rule: "index removed before garbage collection" + │ │ + │ ├── • TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ DELETE_ONLY → ABSENT + │ │ │ + │ │ ├── • PreviousStagePrecedence dependency from DELETE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ rule: "TemporaryIndex transitions to ABSENT uphold 2-version invariant: DELETE_ONLY->ABSENT" + │ │ │ + │ │ └── • Precedence dependency from ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} + │ │ rule: "dependents removed before index" + │ │ + │ └── • IndexData:{DescID: 105, IndexID: 3} + │ │ PUBLIC → ABSENT + │ │ + │ ├── • SameStagePrecedence dependency from DROPPED IndexData:{DescID: 105, IndexID: 2} + │ │ rule: "schedule all GC jobs for a descriptor in the same stage" + │ │ + │ └── • Precedence dependency from ABSENT TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ rule: "index removed before garbage collection" + │ + └── • 6 Mutation operations + │ + ├── • CreateGCJobForIndex + │ IndexID: 2 + │ StatementForDropJob: + │ Rollback: true + │ Statement: ALTER TABLE defaultdb.public.t DROP COLUMN b + │ TableID: 105 + │ + ├── • MakeIndexAbsent + │ IndexID: 3 + │ TableID: 105 + │ + ├── • CreateGCJobForIndex + │ IndexID: 3 + │ StatementForDropJob: + │ Rollback: true + │ Statement: ALTER TABLE defaultdb.public.t DROP COLUMN b + │ TableID: 105 + │ + ├── • RemoveJobStateFromDescriptor + │ DescriptorID: 104 + │ JobID: 1 + │ + ├── • RemoveJobStateFromDescriptor + │ DescriptorID: 105 + │ JobID: 1 + │ + └── • UpdateSchemaChangerJob + DescriptorIDsToRemove: + - 104 + - 105 + IsNonCancelable: true + JobID: 1 + RunningStatus: all stages completed diff --git a/pkg/sql/schemachanger/testdata/explain_verbose/drop_column_with_udf_default.rollback_5_of_7 b/pkg/sql/schemachanger/testdata/explain_verbose/drop_column_with_udf_default.rollback_5_of_7 new file mode 100644 index 000000000000..865949cfbe48 --- /dev/null +++ b/pkg/sql/schemachanger/testdata/explain_verbose/drop_column_with_udf_default.rollback_5_of_7 @@ -0,0 +1,185 @@ +/* setup */ +CREATE FUNCTION f() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +CREATE TABLE t (i INT PRIMARY KEY, b INT DEFAULT f()); + +/* test */ +ALTER TABLE t DROP COLUMN b; +EXPLAIN (ddl, verbose) rollback at post-commit stage 5 of 7; +---- +• Schema change plan for rolling back ALTER TABLE ‹defaultdb›.public.‹t› DROP COLUMN ‹b›; +│ +└── • PostCommitNonRevertiblePhase + │ + ├── • Stage 1 of 2 in PostCommitNonRevertiblePhase + │ │ + │ ├── • 2 elements transitioning toward PUBLIC + │ │ │ + │ │ ├── • Column:{DescID: 105, ColumnID: 2} + │ │ │ │ WRITE_ONLY → PUBLIC + │ │ │ │ + │ │ │ ├── • PreviousStagePrecedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 2} + │ │ │ │ rule: "Column transitions to PUBLIC uphold 2-version invariant: WRITE_ONLY->PUBLIC" + │ │ │ │ + │ │ │ ├── • Precedence dependency from PUBLIC ColumnName:{DescID: 105, Name: b, ColumnID: 2} + │ │ │ │ rule: "column dependents exist before column becomes public" + │ │ │ │ + │ │ │ ├── • Precedence dependency from PUBLIC ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 2} + │ │ │ │ rule: "column dependents exist before column becomes public" + │ │ │ │ + │ │ │ ├── • Precedence dependency from PUBLIC ColumnDefaultExpression:{DescID: 105, ColumnID: 2, ReferencedFunctionIDs: [104]} + │ │ │ │ rule: "column dependents exist before column becomes public" + │ │ │ │ + │ │ │ └── • Precedence dependency from PUBLIC IndexColumn:{DescID: 105, ColumnID: 2, IndexID: 1} + │ │ │ rule: "column dependents exist before column becomes public" + │ │ │ + │ │ └── • ColumnName:{DescID: 105, Name: b, ColumnID: 2} + │ │ ABSENT → PUBLIC + │ │ + │ ├── • 4 elements transitioning toward ABSENT + │ │ │ + │ │ ├── • PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ │ MERGE_ONLY → DELETE_ONLY + │ │ │ │ + │ │ │ └── • PreviousStagePrecedence dependency from MERGE_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ rule: "PrimaryIndex transitions to ABSENT uphold 2-version invariant: MERGE_ONLY->WRITE_ONLY" + │ │ │ + │ │ ├── • IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} + │ │ │ │ PUBLIC → ABSENT + │ │ │ │ + │ │ │ └── • Precedence dependency from DELETE_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ rule: "index drop mutation visible before cleaning up index columns" + │ │ │ + │ │ ├── • TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ │ WRITE_ONLY → DELETE_ONLY + │ │ │ │ + │ │ │ └── • PreviousStagePrecedence dependency from WRITE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ rule: "TemporaryIndex transitions to ABSENT uphold 2-version invariant: WRITE_ONLY->DELETE_ONLY" + │ │ │ + │ │ └── • IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} + │ │ │ PUBLIC → ABSENT + │ │ │ + │ │ └── • Precedence dependency from DELETE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ rule: "index drop mutation visible before cleaning up index columns" + │ │ + │ └── • 10 Mutation operations + │ │ + │ ├── • SetColumnName + │ │ ColumnID: 2 + │ │ Name: b + │ │ TableID: 105 + │ │ + │ ├── • MakeWriteOnlyIndexDeleteOnly + │ │ IndexID: 3 + │ │ TableID: 105 + │ │ + │ ├── • RemoveColumnFromIndex + │ │ ColumnID: 1 + │ │ IndexID: 3 + │ │ TableID: 105 + │ │ + │ ├── • MakeWriteOnlyColumnPublic + │ │ ColumnID: 2 + │ │ TableID: 105 + │ │ + │ ├── • RefreshStats + │ │ TableID: 105 + │ │ + │ ├── • MakeWriteOnlyIndexDeleteOnly + │ │ IndexID: 2 + │ │ TableID: 105 + │ │ + │ ├── • RemoveColumnFromIndex + │ │ ColumnID: 1 + │ │ IndexID: 2 + │ │ TableID: 105 + │ │ + │ ├── • SetJobStateOnDescriptor + │ │ DescriptorID: 104 + │ │ + │ ├── • SetJobStateOnDescriptor + │ │ DescriptorID: 105 + │ │ + │ └── • UpdateSchemaChangerJob + │ IsNonCancelable: true + │ JobID: 1 + │ RunningStatus: PostCommitNonRevertiblePhase stage 2 of 2 with 4 MutationType ops pending + │ + └── • Stage 2 of 2 in PostCommitNonRevertiblePhase + │ + ├── • 4 elements transitioning toward ABSENT + │ │ + │ ├── • PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ DELETE_ONLY → ABSENT + │ │ │ + │ │ ├── • PreviousStagePrecedence dependency from DELETE_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ rule: "PrimaryIndex transitions to ABSENT uphold 2-version invariant: DELETE_ONLY->ABSENT" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT IndexName:{DescID: 105, Name: t_pkey, IndexID: 2} + │ │ │ rule: "dependents removed before index" + │ │ │ + │ │ └── • Precedence dependency from ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} + │ │ rule: "dependents removed before index" + │ │ + │ ├── • IndexData:{DescID: 105, IndexID: 2} + │ │ │ PUBLIC → ABSENT + │ │ │ + │ │ └── • Precedence dependency from ABSENT PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ rule: "index removed before garbage collection" + │ │ + │ ├── • TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ DELETE_ONLY → ABSENT + │ │ │ + │ │ ├── • PreviousStagePrecedence dependency from DELETE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ rule: "TemporaryIndex transitions to ABSENT uphold 2-version invariant: DELETE_ONLY->ABSENT" + │ │ │ + │ │ └── • Precedence dependency from ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} + │ │ rule: "dependents removed before index" + │ │ + │ └── • IndexData:{DescID: 105, IndexID: 3} + │ │ PUBLIC → ABSENT + │ │ + │ ├── • SameStagePrecedence dependency from DROPPED IndexData:{DescID: 105, IndexID: 2} + │ │ rule: "schedule all GC jobs for a descriptor in the same stage" + │ │ + │ └── • Precedence dependency from ABSENT TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ rule: "index removed before garbage collection" + │ + └── • 7 Mutation operations + │ + ├── • MakeIndexAbsent + │ IndexID: 2 + │ TableID: 105 + │ + ├── • CreateGCJobForIndex + │ IndexID: 2 + │ StatementForDropJob: + │ Rollback: true + │ Statement: ALTER TABLE defaultdb.public.t DROP COLUMN b + │ TableID: 105 + │ + ├── • MakeIndexAbsent + │ IndexID: 3 + │ TableID: 105 + │ + ├── • CreateGCJobForIndex + │ IndexID: 3 + │ StatementForDropJob: + │ Rollback: true + │ Statement: ALTER TABLE defaultdb.public.t DROP COLUMN b + │ TableID: 105 + │ + ├── • RemoveJobStateFromDescriptor + │ DescriptorID: 104 + │ JobID: 1 + │ + ├── • RemoveJobStateFromDescriptor + │ DescriptorID: 105 + │ JobID: 1 + │ + └── • UpdateSchemaChangerJob + DescriptorIDsToRemove: + - 104 + - 105 + IsNonCancelable: true + JobID: 1 + RunningStatus: all stages completed diff --git a/pkg/sql/schemachanger/testdata/explain_verbose/drop_column_with_udf_default.rollback_6_of_7 b/pkg/sql/schemachanger/testdata/explain_verbose/drop_column_with_udf_default.rollback_6_of_7 new file mode 100644 index 000000000000..6840ddd88ae3 --- /dev/null +++ b/pkg/sql/schemachanger/testdata/explain_verbose/drop_column_with_udf_default.rollback_6_of_7 @@ -0,0 +1,185 @@ +/* setup */ +CREATE FUNCTION f() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +CREATE TABLE t (i INT PRIMARY KEY, b INT DEFAULT f()); + +/* test */ +ALTER TABLE t DROP COLUMN b; +EXPLAIN (ddl, verbose) rollback at post-commit stage 6 of 7; +---- +• Schema change plan for rolling back ALTER TABLE ‹defaultdb›.public.‹t› DROP COLUMN ‹b›; +│ +└── • PostCommitNonRevertiblePhase + │ + ├── • Stage 1 of 2 in PostCommitNonRevertiblePhase + │ │ + │ ├── • 2 elements transitioning toward PUBLIC + │ │ │ + │ │ ├── • Column:{DescID: 105, ColumnID: 2} + │ │ │ │ WRITE_ONLY → PUBLIC + │ │ │ │ + │ │ │ ├── • PreviousStagePrecedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 2} + │ │ │ │ rule: "Column transitions to PUBLIC uphold 2-version invariant: WRITE_ONLY->PUBLIC" + │ │ │ │ + │ │ │ ├── • Precedence dependency from PUBLIC ColumnName:{DescID: 105, Name: b, ColumnID: 2} + │ │ │ │ rule: "column dependents exist before column becomes public" + │ │ │ │ + │ │ │ ├── • Precedence dependency from PUBLIC ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 2} + │ │ │ │ rule: "column dependents exist before column becomes public" + │ │ │ │ + │ │ │ ├── • Precedence dependency from PUBLIC ColumnDefaultExpression:{DescID: 105, ColumnID: 2, ReferencedFunctionIDs: [104]} + │ │ │ │ rule: "column dependents exist before column becomes public" + │ │ │ │ + │ │ │ └── • Precedence dependency from PUBLIC IndexColumn:{DescID: 105, ColumnID: 2, IndexID: 1} + │ │ │ rule: "column dependents exist before column becomes public" + │ │ │ + │ │ └── • ColumnName:{DescID: 105, Name: b, ColumnID: 2} + │ │ ABSENT → PUBLIC + │ │ + │ ├── • 4 elements transitioning toward ABSENT + │ │ │ + │ │ ├── • PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ │ MERGE_ONLY → DELETE_ONLY + │ │ │ │ + │ │ │ └── • PreviousStagePrecedence dependency from MERGE_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ rule: "PrimaryIndex transitions to ABSENT uphold 2-version invariant: MERGE_ONLY->WRITE_ONLY" + │ │ │ + │ │ ├── • IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} + │ │ │ │ PUBLIC → ABSENT + │ │ │ │ + │ │ │ └── • Precedence dependency from DELETE_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ rule: "index drop mutation visible before cleaning up index columns" + │ │ │ + │ │ ├── • TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ │ WRITE_ONLY → DELETE_ONLY + │ │ │ │ + │ │ │ └── • PreviousStagePrecedence dependency from WRITE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ rule: "TemporaryIndex transitions to ABSENT uphold 2-version invariant: WRITE_ONLY->DELETE_ONLY" + │ │ │ + │ │ └── • IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} + │ │ │ PUBLIC → ABSENT + │ │ │ + │ │ └── • Precedence dependency from DELETE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ rule: "index drop mutation visible before cleaning up index columns" + │ │ + │ └── • 10 Mutation operations + │ │ + │ ├── • SetColumnName + │ │ ColumnID: 2 + │ │ Name: b + │ │ TableID: 105 + │ │ + │ ├── • MakeWriteOnlyIndexDeleteOnly + │ │ IndexID: 3 + │ │ TableID: 105 + │ │ + │ ├── • RemoveColumnFromIndex + │ │ ColumnID: 1 + │ │ IndexID: 3 + │ │ TableID: 105 + │ │ + │ ├── • MakeWriteOnlyColumnPublic + │ │ ColumnID: 2 + │ │ TableID: 105 + │ │ + │ ├── • RefreshStats + │ │ TableID: 105 + │ │ + │ ├── • MakeWriteOnlyIndexDeleteOnly + │ │ IndexID: 2 + │ │ TableID: 105 + │ │ + │ ├── • RemoveColumnFromIndex + │ │ ColumnID: 1 + │ │ IndexID: 2 + │ │ TableID: 105 + │ │ + │ ├── • SetJobStateOnDescriptor + │ │ DescriptorID: 104 + │ │ + │ ├── • SetJobStateOnDescriptor + │ │ DescriptorID: 105 + │ │ + │ └── • UpdateSchemaChangerJob + │ IsNonCancelable: true + │ JobID: 1 + │ RunningStatus: PostCommitNonRevertiblePhase stage 2 of 2 with 4 MutationType ops pending + │ + └── • Stage 2 of 2 in PostCommitNonRevertiblePhase + │ + ├── • 4 elements transitioning toward ABSENT + │ │ + │ ├── • PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ DELETE_ONLY → ABSENT + │ │ │ + │ │ ├── • PreviousStagePrecedence dependency from DELETE_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ rule: "PrimaryIndex transitions to ABSENT uphold 2-version invariant: DELETE_ONLY->ABSENT" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT IndexName:{DescID: 105, Name: t_pkey, IndexID: 2} + │ │ │ rule: "dependents removed before index" + │ │ │ + │ │ └── • Precedence dependency from ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} + │ │ rule: "dependents removed before index" + │ │ + │ ├── • IndexData:{DescID: 105, IndexID: 2} + │ │ │ PUBLIC → ABSENT + │ │ │ + │ │ └── • Precedence dependency from ABSENT PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ rule: "index removed before garbage collection" + │ │ + │ ├── • TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ DELETE_ONLY → ABSENT + │ │ │ + │ │ ├── • PreviousStagePrecedence dependency from DELETE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ rule: "TemporaryIndex transitions to ABSENT uphold 2-version invariant: DELETE_ONLY->ABSENT" + │ │ │ + │ │ └── • Precedence dependency from ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} + │ │ rule: "dependents removed before index" + │ │ + │ └── • IndexData:{DescID: 105, IndexID: 3} + │ │ PUBLIC → ABSENT + │ │ + │ ├── • SameStagePrecedence dependency from DROPPED IndexData:{DescID: 105, IndexID: 2} + │ │ rule: "schedule all GC jobs for a descriptor in the same stage" + │ │ + │ └── • Precedence dependency from ABSENT TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ rule: "index removed before garbage collection" + │ + └── • 7 Mutation operations + │ + ├── • MakeIndexAbsent + │ IndexID: 2 + │ TableID: 105 + │ + ├── • CreateGCJobForIndex + │ IndexID: 2 + │ StatementForDropJob: + │ Rollback: true + │ Statement: ALTER TABLE defaultdb.public.t DROP COLUMN b + │ TableID: 105 + │ + ├── • MakeIndexAbsent + │ IndexID: 3 + │ TableID: 105 + │ + ├── • CreateGCJobForIndex + │ IndexID: 3 + │ StatementForDropJob: + │ Rollback: true + │ Statement: ALTER TABLE defaultdb.public.t DROP COLUMN b + │ TableID: 105 + │ + ├── • RemoveJobStateFromDescriptor + │ DescriptorID: 104 + │ JobID: 1 + │ + ├── • RemoveJobStateFromDescriptor + │ DescriptorID: 105 + │ JobID: 1 + │ + └── • UpdateSchemaChangerJob + DescriptorIDsToRemove: + - 104 + - 105 + IsNonCancelable: true + JobID: 1 + RunningStatus: all stages completed diff --git a/pkg/sql/schemachanger/testdata/explain_verbose/drop_column_with_udf_default.rollback_7_of_7 b/pkg/sql/schemachanger/testdata/explain_verbose/drop_column_with_udf_default.rollback_7_of_7 new file mode 100644 index 000000000000..4c753fd5318d --- /dev/null +++ b/pkg/sql/schemachanger/testdata/explain_verbose/drop_column_with_udf_default.rollback_7_of_7 @@ -0,0 +1,185 @@ +/* setup */ +CREATE FUNCTION f() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +CREATE TABLE t (i INT PRIMARY KEY, b INT DEFAULT f()); + +/* test */ +ALTER TABLE t DROP COLUMN b; +EXPLAIN (ddl, verbose) rollback at post-commit stage 7 of 7; +---- +• Schema change plan for rolling back ALTER TABLE ‹defaultdb›.public.‹t› DROP COLUMN ‹b›; +│ +└── • PostCommitNonRevertiblePhase + │ + ├── • Stage 1 of 2 in PostCommitNonRevertiblePhase + │ │ + │ ├── • 2 elements transitioning toward PUBLIC + │ │ │ + │ │ ├── • Column:{DescID: 105, ColumnID: 2} + │ │ │ │ WRITE_ONLY → PUBLIC + │ │ │ │ + │ │ │ ├── • PreviousStagePrecedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 2} + │ │ │ │ rule: "Column transitions to PUBLIC uphold 2-version invariant: WRITE_ONLY->PUBLIC" + │ │ │ │ + │ │ │ ├── • Precedence dependency from PUBLIC ColumnName:{DescID: 105, Name: b, ColumnID: 2} + │ │ │ │ rule: "column dependents exist before column becomes public" + │ │ │ │ + │ │ │ ├── • Precedence dependency from PUBLIC ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 2} + │ │ │ │ rule: "column dependents exist before column becomes public" + │ │ │ │ + │ │ │ ├── • Precedence dependency from PUBLIC ColumnDefaultExpression:{DescID: 105, ColumnID: 2, ReferencedFunctionIDs: [104]} + │ │ │ │ rule: "column dependents exist before column becomes public" + │ │ │ │ + │ │ │ └── • Precedence dependency from PUBLIC IndexColumn:{DescID: 105, ColumnID: 2, IndexID: 1} + │ │ │ rule: "column dependents exist before column becomes public" + │ │ │ + │ │ └── • ColumnName:{DescID: 105, Name: b, ColumnID: 2} + │ │ ABSENT → PUBLIC + │ │ + │ ├── • 4 elements transitioning toward ABSENT + │ │ │ + │ │ ├── • PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ │ WRITE_ONLY → DELETE_ONLY + │ │ │ │ + │ │ │ └── • PreviousStagePrecedence dependency from WRITE_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ rule: "PrimaryIndex transitions to ABSENT uphold 2-version invariant: WRITE_ONLY->DELETE_ONLY" + │ │ │ + │ │ ├── • IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} + │ │ │ │ PUBLIC → ABSENT + │ │ │ │ + │ │ │ └── • Precedence dependency from DELETE_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ rule: "index drop mutation visible before cleaning up index columns" + │ │ │ + │ │ ├── • TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ │ WRITE_ONLY → DELETE_ONLY + │ │ │ │ + │ │ │ └── • PreviousStagePrecedence dependency from WRITE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ rule: "TemporaryIndex transitions to ABSENT uphold 2-version invariant: WRITE_ONLY->DELETE_ONLY" + │ │ │ + │ │ └── • IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} + │ │ │ PUBLIC → ABSENT + │ │ │ + │ │ └── • Precedence dependency from DELETE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ rule: "index drop mutation visible before cleaning up index columns" + │ │ + │ └── • 10 Mutation operations + │ │ + │ ├── • SetColumnName + │ │ ColumnID: 2 + │ │ Name: b + │ │ TableID: 105 + │ │ + │ ├── • MakeWriteOnlyIndexDeleteOnly + │ │ IndexID: 2 + │ │ TableID: 105 + │ │ + │ ├── • RemoveColumnFromIndex + │ │ ColumnID: 1 + │ │ IndexID: 2 + │ │ TableID: 105 + │ │ + │ ├── • MakeWriteOnlyIndexDeleteOnly + │ │ IndexID: 3 + │ │ TableID: 105 + │ │ + │ ├── • RemoveColumnFromIndex + │ │ ColumnID: 1 + │ │ IndexID: 3 + │ │ TableID: 105 + │ │ + │ ├── • MakeWriteOnlyColumnPublic + │ │ ColumnID: 2 + │ │ TableID: 105 + │ │ + │ ├── • RefreshStats + │ │ TableID: 105 + │ │ + │ ├── • SetJobStateOnDescriptor + │ │ DescriptorID: 104 + │ │ + │ ├── • SetJobStateOnDescriptor + │ │ DescriptorID: 105 + │ │ + │ └── • UpdateSchemaChangerJob + │ IsNonCancelable: true + │ JobID: 1 + │ RunningStatus: PostCommitNonRevertiblePhase stage 2 of 2 with 4 MutationType ops pending + │ + └── • Stage 2 of 2 in PostCommitNonRevertiblePhase + │ + ├── • 4 elements transitioning toward ABSENT + │ │ + │ ├── • PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ DELETE_ONLY → ABSENT + │ │ │ + │ │ ├── • PreviousStagePrecedence dependency from DELETE_ONLY PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ │ rule: "PrimaryIndex transitions to ABSENT uphold 2-version invariant: DELETE_ONLY->ABSENT" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT IndexName:{DescID: 105, Name: t_pkey, IndexID: 2} + │ │ │ rule: "dependents removed before index" + │ │ │ + │ │ └── • Precedence dependency from ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 2} + │ │ rule: "dependents removed before index" + │ │ + │ ├── • IndexData:{DescID: 105, IndexID: 2} + │ │ │ PUBLIC → ABSENT + │ │ │ + │ │ └── • Precedence dependency from ABSENT PrimaryIndex:{DescID: 105, IndexID: 2, ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1} + │ │ rule: "index removed before garbage collection" + │ │ + │ ├── • TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ DELETE_ONLY → ABSENT + │ │ │ + │ │ ├── • PreviousStagePrecedence dependency from DELETE_ONLY TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ │ │ rule: "TemporaryIndex transitions to ABSENT uphold 2-version invariant: DELETE_ONLY->ABSENT" + │ │ │ + │ │ └── • Precedence dependency from ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 3} + │ │ rule: "dependents removed before index" + │ │ + │ └── • IndexData:{DescID: 105, IndexID: 3} + │ │ PUBLIC → ABSENT + │ │ + │ ├── • SameStagePrecedence dependency from DROPPED IndexData:{DescID: 105, IndexID: 2} + │ │ rule: "schedule all GC jobs for a descriptor in the same stage" + │ │ + │ └── • Precedence dependency from ABSENT TemporaryIndex:{DescID: 105, IndexID: 3, ConstraintID: 3, SourceIndexID: 1} + │ rule: "index removed before garbage collection" + │ + └── • 7 Mutation operations + │ + ├── • MakeIndexAbsent + │ IndexID: 2 + │ TableID: 105 + │ + ├── • CreateGCJobForIndex + │ IndexID: 2 + │ StatementForDropJob: + │ Rollback: true + │ Statement: ALTER TABLE defaultdb.public.t DROP COLUMN b + │ TableID: 105 + │ + ├── • MakeIndexAbsent + │ IndexID: 3 + │ TableID: 105 + │ + ├── • CreateGCJobForIndex + │ IndexID: 3 + │ StatementForDropJob: + │ Rollback: true + │ Statement: ALTER TABLE defaultdb.public.t DROP COLUMN b + │ TableID: 105 + │ + ├── • RemoveJobStateFromDescriptor + │ DescriptorID: 104 + │ JobID: 1 + │ + ├── • RemoveJobStateFromDescriptor + │ DescriptorID: 105 + │ JobID: 1 + │ + └── • UpdateSchemaChangerJob + DescriptorIDsToRemove: + - 104 + - 105 + IsNonCancelable: true + JobID: 1 + RunningStatus: all stages completed diff --git a/pkg/sql/schemachanger/testdata/explain_verbose/drop_table_udf_default b/pkg/sql/schemachanger/testdata/explain_verbose/drop_table_udf_default new file mode 100644 index 000000000000..5727f7992b27 --- /dev/null +++ b/pkg/sql/schemachanger/testdata/explain_verbose/drop_table_udf_default @@ -0,0 +1,899 @@ +/* setup */ +CREATE FUNCTION f() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +CREATE TABLE t (i INT PRIMARY KEY, b INT DEFAULT f()); + +/* test */ +EXPLAIN (ddl, verbose) DROP TABLE t; +---- +• Schema change plan for DROP TABLE ‹defaultdb›.‹public›.‹t›; +│ +├── • StatementPhase +│ │ +│ └── • Stage 1 of 1 in StatementPhase +│ │ +│ ├── • 23 elements transitioning toward ABSENT +│ │ │ +│ │ ├── • Namespace:{DescID: 105, Name: t, ReferencedDescID: 100} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ └── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ +│ │ ├── • Owner:{DescID: 105} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ └── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ +│ │ ├── • UserPrivileges:{DescID: 105, Name: admin} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ └── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ +│ │ ├── • UserPrivileges:{DescID: 105, Name: root} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ └── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ +│ │ ├── • Table:{DescID: 105} +│ │ │ PUBLIC → DROPPED +│ │ │ +│ │ ├── • ObjectParent:{DescID: 105, ReferencedDescID: 101} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ └── • SameStagePrecedence dependency from DROPPED Table:{DescID: 105} +│ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ rule: "descriptor dropped right before removing back-reference in its parent descriptor" +│ │ │ +│ │ ├── • ColumnFamily:{DescID: 105, Name: primary, ColumnFamilyID: 0} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ └── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ +│ │ ├── • Column:{DescID: 105, ColumnID: 1} +│ │ │ │ PUBLIC → WRITE_ONLY +│ │ │ │ +│ │ │ └── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ rule: "relation dropped before dependent column" +│ │ │ +│ │ ├── • ColumnName:{DescID: 105, Name: i, ColumnID: 1} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ ├── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ │ +│ │ │ └── • Precedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 1} +│ │ │ rule: "column no longer public before dependents" +│ │ │ +│ │ ├── • ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 1} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ ├── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ │ +│ │ │ └── • Precedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 1} +│ │ │ rule: "column no longer public before dependents" +│ │ │ +│ │ ├── • ColumnNotNull:{DescID: 105, ColumnID: 1, IndexID: 0} +│ │ │ │ PUBLIC → VALIDATED +│ │ │ │ +│ │ │ └── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ rule: "relation dropped before dependent constraint" +│ │ │ +│ │ ├── • Column:{DescID: 105, ColumnID: 2} +│ │ │ │ PUBLIC → WRITE_ONLY +│ │ │ │ +│ │ │ └── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ rule: "relation dropped before dependent column" +│ │ │ +│ │ ├── • ColumnName:{DescID: 105, Name: b, ColumnID: 2} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ ├── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ │ +│ │ │ └── • Precedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 2} +│ │ │ rule: "column no longer public before dependents" +│ │ │ +│ │ ├── • ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 2} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ ├── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ │ +│ │ │ ├── • Precedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 2} +│ │ │ │ rule: "column no longer public before dependents" +│ │ │ │ +│ │ │ └── • SameStagePrecedence dependency from ABSENT ColumnDefaultExpression:{DescID: 105, ColumnID: 2, ReferencedFunctionIDs: [104]} +│ │ │ rule: "column type dependents removed right before column type" +│ │ │ +│ │ ├── • ColumnDefaultExpression:{DescID: 105, ColumnID: 2, ReferencedFunctionIDs: [104]} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ ├── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ │ +│ │ │ └── • Precedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 2} +│ │ │ rule: "column no longer public before dependents" +│ │ │ +│ │ ├── • Column:{DescID: 105, ColumnID: 4294967295} +│ │ │ │ PUBLIC → WRITE_ONLY +│ │ │ │ +│ │ │ └── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ rule: "relation dropped before dependent column" +│ │ │ +│ │ ├── • ColumnName:{DescID: 105, Name: crdb_internal_mvcc_timestamp, ColumnID: 4294967295} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ ├── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ │ +│ │ │ └── • Precedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 4294967295} +│ │ │ rule: "column no longer public before dependents" +│ │ │ +│ │ ├── • ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 4294967295} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ ├── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ │ +│ │ │ └── • Precedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 4294967295} +│ │ │ rule: "column no longer public before dependents" +│ │ │ +│ │ ├── • Column:{DescID: 105, ColumnID: 4294967294} +│ │ │ │ PUBLIC → WRITE_ONLY +│ │ │ │ +│ │ │ └── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ rule: "relation dropped before dependent column" +│ │ │ +│ │ ├── • ColumnName:{DescID: 105, Name: tableoid, ColumnID: 4294967294} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ ├── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ │ +│ │ │ └── • Precedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 4294967294} +│ │ │ rule: "column no longer public before dependents" +│ │ │ +│ │ ├── • ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 4294967294} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ ├── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ │ +│ │ │ └── • Precedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 4294967294} +│ │ │ rule: "column no longer public before dependents" +│ │ │ +│ │ ├── • PrimaryIndex:{DescID: 105, IndexID: 1, ConstraintID: 1} +│ │ │ │ PUBLIC → VALIDATED +│ │ │ │ +│ │ │ └── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ rule: "relation dropped before dependent index" +│ │ │ +│ │ └── • IndexName:{DescID: 105, Name: t_pkey, IndexID: 1} +│ │ │ PUBLIC → ABSENT +│ │ │ +│ │ ├── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ +│ │ └── • Precedence dependency from VALIDATED PrimaryIndex:{DescID: 105, IndexID: 1, ConstraintID: 1} +│ │ rule: "index no longer public before dependents, excluding columns" +│ │ +│ └── • 20 Mutation operations +│ │ +│ ├── • MarkDescriptorAsDropped +│ │ DescriptorID: 105 +│ │ +│ ├── • RemoveObjectParent +│ │ ObjectID: 105 +│ │ ParentSchemaID: 101 +│ │ +│ ├── • NotImplementedForPublicObjects +│ │ DescID: 105 +│ │ ElementType: scpb.ColumnFamily +│ │ +│ ├── • MakePublicColumnWriteOnly +│ │ ColumnID: 1 +│ │ TableID: 105 +│ │ +│ ├── • SetColumnName +│ │ ColumnID: 1 +│ │ Name: crdb_internal_column_1_name_placeholder +│ │ TableID: 105 +│ │ +│ ├── • MakePublicColumnNotNullValidated +│ │ ColumnID: 1 +│ │ TableID: 105 +│ │ +│ ├── • MakePublicColumnWriteOnly +│ │ ColumnID: 2 +│ │ TableID: 105 +│ │ +│ ├── • SetColumnName +│ │ ColumnID: 2 +│ │ Name: crdb_internal_column_2_name_placeholder +│ │ TableID: 105 +│ │ +│ ├── • RemoveColumnDefaultExpression +│ │ ColumnID: 2 +│ │ TableID: 105 +│ │ +│ ├── • RemoveTableColumnBackReferencesInFunctions +│ │ BackReferencedColumnID: 2 +│ │ BackReferencedTableID: 105 +│ │ FunctionIDs: +│ │ - 104 +│ │ +│ ├── • MakePublicColumnWriteOnly +│ │ ColumnID: 4294967295 +│ │ TableID: 105 +│ │ +│ ├── • SetColumnName +│ │ ColumnID: 4294967295 +│ │ Name: crdb_internal_column_4294967295_name_placeholder +│ │ TableID: 105 +│ │ +│ ├── • MakePublicColumnWriteOnly +│ │ ColumnID: 4294967294 +│ │ TableID: 105 +│ │ +│ ├── • SetColumnName +│ │ ColumnID: 4294967294 +│ │ Name: crdb_internal_column_4294967294_name_placeholder +│ │ TableID: 105 +│ │ +│ ├── • MakePublicPrimaryIndexWriteOnly +│ │ IndexID: 1 +│ │ TableID: 105 +│ │ +│ ├── • SetIndexName +│ │ IndexID: 1 +│ │ Name: crdb_internal_index_1_name_placeholder +│ │ TableID: 105 +│ │ +│ ├── • DrainDescriptorName +│ │ Namespace: +│ │ DatabaseID: 100 +│ │ DescriptorID: 105 +│ │ Name: t +│ │ SchemaID: 101 +│ │ +│ ├── • NotImplementedForPublicObjects +│ │ DescID: 105 +│ │ ElementType: scpb.Owner +│ │ +│ ├── • RemoveUserPrivileges +│ │ DescriptorID: 105 +│ │ User: admin +│ │ +│ └── • RemoveUserPrivileges +│ DescriptorID: 105 +│ User: root +│ +├── • PreCommitPhase +│ │ +│ ├── • Stage 1 of 2 in PreCommitPhase +│ │ │ +│ │ ├── • 23 elements transitioning toward ABSENT +│ │ │ │ +│ │ │ ├── • Namespace:{DescID: 105, Name: t, ReferencedDescID: 100} +│ │ │ │ ABSENT → PUBLIC +│ │ │ │ +│ │ │ ├── • Owner:{DescID: 105} +│ │ │ │ ABSENT → PUBLIC +│ │ │ │ +│ │ │ ├── • UserPrivileges:{DescID: 105, Name: admin} +│ │ │ │ ABSENT → PUBLIC +│ │ │ │ +│ │ │ ├── • UserPrivileges:{DescID: 105, Name: root} +│ │ │ │ ABSENT → PUBLIC +│ │ │ │ +│ │ │ ├── • Table:{DescID: 105} +│ │ │ │ DROPPED → PUBLIC +│ │ │ │ +│ │ │ ├── • ObjectParent:{DescID: 105, ReferencedDescID: 101} +│ │ │ │ ABSENT → PUBLIC +│ │ │ │ +│ │ │ ├── • ColumnFamily:{DescID: 105, Name: primary, ColumnFamilyID: 0} +│ │ │ │ ABSENT → PUBLIC +│ │ │ │ +│ │ │ ├── • Column:{DescID: 105, ColumnID: 1} +│ │ │ │ WRITE_ONLY → PUBLIC +│ │ │ │ +│ │ │ ├── • ColumnName:{DescID: 105, Name: i, ColumnID: 1} +│ │ │ │ ABSENT → PUBLIC +│ │ │ │ +│ │ │ ├── • ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 1} +│ │ │ │ ABSENT → PUBLIC +│ │ │ │ +│ │ │ ├── • ColumnNotNull:{DescID: 105, ColumnID: 1, IndexID: 0} +│ │ │ │ VALIDATED → PUBLIC +│ │ │ │ +│ │ │ ├── • Column:{DescID: 105, ColumnID: 2} +│ │ │ │ WRITE_ONLY → PUBLIC +│ │ │ │ +│ │ │ ├── • ColumnName:{DescID: 105, Name: b, ColumnID: 2} +│ │ │ │ ABSENT → PUBLIC +│ │ │ │ +│ │ │ ├── • ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 2} +│ │ │ │ ABSENT → PUBLIC +│ │ │ │ +│ │ │ ├── • ColumnDefaultExpression:{DescID: 105, ColumnID: 2, ReferencedFunctionIDs: [104]} +│ │ │ │ ABSENT → PUBLIC +│ │ │ │ +│ │ │ ├── • Column:{DescID: 105, ColumnID: 4294967295} +│ │ │ │ WRITE_ONLY → PUBLIC +│ │ │ │ +│ │ │ ├── • ColumnName:{DescID: 105, Name: crdb_internal_mvcc_timestamp, ColumnID: 4294967295} +│ │ │ │ ABSENT → PUBLIC +│ │ │ │ +│ │ │ ├── • ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 4294967295} +│ │ │ │ ABSENT → PUBLIC +│ │ │ │ +│ │ │ ├── • Column:{DescID: 105, ColumnID: 4294967294} +│ │ │ │ WRITE_ONLY → PUBLIC +│ │ │ │ +│ │ │ ├── • ColumnName:{DescID: 105, Name: tableoid, ColumnID: 4294967294} +│ │ │ │ ABSENT → PUBLIC +│ │ │ │ +│ │ │ ├── • ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 4294967294} +│ │ │ │ ABSENT → PUBLIC +│ │ │ │ +│ │ │ ├── • PrimaryIndex:{DescID: 105, IndexID: 1, ConstraintID: 1} +│ │ │ │ VALIDATED → PUBLIC +│ │ │ │ +│ │ │ └── • IndexName:{DescID: 105, Name: t_pkey, IndexID: 1} +│ │ │ ABSENT → PUBLIC +│ │ │ +│ │ └── • 1 Mutation operation +│ │ │ +│ │ └── • UndoAllInTxnImmediateMutationOpSideEffects +│ │ {} +│ │ +│ └── • Stage 2 of 2 in PreCommitPhase +│ │ +│ ├── • 25 elements transitioning toward ABSENT +│ │ │ +│ │ ├── • Namespace:{DescID: 105, Name: t, ReferencedDescID: 100} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ └── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ +│ │ ├── • Owner:{DescID: 105} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ └── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ +│ │ ├── • UserPrivileges:{DescID: 105, Name: admin} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ └── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ +│ │ ├── • UserPrivileges:{DescID: 105, Name: root} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ └── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ +│ │ ├── • Table:{DescID: 105} +│ │ │ PUBLIC → DROPPED +│ │ │ +│ │ ├── • ObjectParent:{DescID: 105, ReferencedDescID: 101} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ └── • SameStagePrecedence dependency from DROPPED Table:{DescID: 105} +│ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ rule: "descriptor dropped right before removing back-reference in its parent descriptor" +│ │ │ +│ │ ├── • ColumnFamily:{DescID: 105, Name: primary, ColumnFamilyID: 0} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ └── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ +│ │ ├── • Column:{DescID: 105, ColumnID: 1} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ ├── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ │ rule: "relation dropped before dependent column" +│ │ │ │ +│ │ │ ├── • SameStagePrecedence dependency from ABSENT ColumnNotNull:{DescID: 105, ColumnID: 1, IndexID: 0} +│ │ │ │ rule: "column constraint removed right before column reaches delete only" +│ │ │ │ +│ │ │ ├── • Precedence dependency from ABSENT ColumnName:{DescID: 105, Name: i, ColumnID: 1} +│ │ │ │ rule: "dependents removed before column" +│ │ │ │ +│ │ │ ├── • Precedence dependency from ABSENT ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 1} +│ │ │ │ rule: "dependents removed before column" +│ │ │ │ +│ │ │ ├── • Precedence dependency from ABSENT ColumnNotNull:{DescID: 105, ColumnID: 1, IndexID: 0} +│ │ │ │ rule: "dependents removed before column" +│ │ │ │ +│ │ │ └── • Precedence dependency from ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 1} +│ │ │ rule: "dependents removed before column" +│ │ │ +│ │ ├── • ColumnName:{DescID: 105, Name: i, ColumnID: 1} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ ├── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ │ +│ │ │ └── • Precedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 1} +│ │ │ rule: "column no longer public before dependents" +│ │ │ +│ │ ├── • ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 1} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ ├── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ │ +│ │ │ └── • Precedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 1} +│ │ │ rule: "column no longer public before dependents" +│ │ │ +│ │ ├── • ColumnNotNull:{DescID: 105, ColumnID: 1, IndexID: 0} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ ├── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ │ rule: "relation dropped before dependent constraint" +│ │ │ │ +│ │ │ └── • Precedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 1} +│ │ │ rule: "column no longer public before dependents" +│ │ │ +│ │ ├── • Column:{DescID: 105, ColumnID: 2} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ ├── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ │ rule: "relation dropped before dependent column" +│ │ │ │ +│ │ │ ├── • Precedence dependency from ABSENT ColumnName:{DescID: 105, Name: b, ColumnID: 2} +│ │ │ │ rule: "dependents removed before column" +│ │ │ │ +│ │ │ ├── • Precedence dependency from ABSENT ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 2} +│ │ │ │ rule: "dependents removed before column" +│ │ │ │ +│ │ │ ├── • Precedence dependency from ABSENT ColumnDefaultExpression:{DescID: 105, ColumnID: 2, ReferencedFunctionIDs: [104]} +│ │ │ │ rule: "dependents removed before column" +│ │ │ │ +│ │ │ └── • Precedence dependency from ABSENT IndexColumn:{DescID: 105, ColumnID: 2, IndexID: 1} +│ │ │ rule: "dependents removed before column" +│ │ │ +│ │ ├── • ColumnName:{DescID: 105, Name: b, ColumnID: 2} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ ├── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ │ +│ │ │ └── • Precedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 2} +│ │ │ rule: "column no longer public before dependents" +│ │ │ +│ │ ├── • ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 2} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ ├── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ │ +│ │ │ ├── • Precedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 2} +│ │ │ │ rule: "column no longer public before dependents" +│ │ │ │ +│ │ │ └── • SameStagePrecedence dependency from ABSENT ColumnDefaultExpression:{DescID: 105, ColumnID: 2, ReferencedFunctionIDs: [104]} +│ │ │ rule: "column type dependents removed right before column type" +│ │ │ +│ │ ├── • ColumnDefaultExpression:{DescID: 105, ColumnID: 2, ReferencedFunctionIDs: [104]} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ ├── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ │ +│ │ │ └── • Precedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 2} +│ │ │ rule: "column no longer public before dependents" +│ │ │ +│ │ ├── • Column:{DescID: 105, ColumnID: 4294967295} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ ├── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ │ rule: "relation dropped before dependent column" +│ │ │ │ +│ │ │ ├── • Precedence dependency from ABSENT ColumnName:{DescID: 105, Name: crdb_internal_mvcc_timestamp, ColumnID: 4294967295} +│ │ │ │ rule: "dependents removed before column" +│ │ │ │ +│ │ │ └── • Precedence dependency from ABSENT ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 4294967295} +│ │ │ rule: "dependents removed before column" +│ │ │ +│ │ ├── • ColumnName:{DescID: 105, Name: crdb_internal_mvcc_timestamp, ColumnID: 4294967295} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ ├── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ │ +│ │ │ └── • Precedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 4294967295} +│ │ │ rule: "column no longer public before dependents" +│ │ │ +│ │ ├── • ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 4294967295} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ ├── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ │ +│ │ │ └── • Precedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 4294967295} +│ │ │ rule: "column no longer public before dependents" +│ │ │ +│ │ ├── • Column:{DescID: 105, ColumnID: 4294967294} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ ├── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ │ rule: "relation dropped before dependent column" +│ │ │ │ +│ │ │ ├── • Precedence dependency from ABSENT ColumnName:{DescID: 105, Name: tableoid, ColumnID: 4294967294} +│ │ │ │ rule: "dependents removed before column" +│ │ │ │ +│ │ │ └── • Precedence dependency from ABSENT ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 4294967294} +│ │ │ rule: "dependents removed before column" +│ │ │ +│ │ ├── • ColumnName:{DescID: 105, Name: tableoid, ColumnID: 4294967294} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ ├── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ │ +│ │ │ └── • Precedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 4294967294} +│ │ │ rule: "column no longer public before dependents" +│ │ │ +│ │ ├── • ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 4294967294} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ ├── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ │ +│ │ │ └── • Precedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 4294967294} +│ │ │ rule: "column no longer public before dependents" +│ │ │ +│ │ ├── • IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 1} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ ├── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ │ +│ │ │ ├── • Precedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 1} +│ │ │ │ rule: "column no longer public before dependents" +│ │ │ │ +│ │ │ └── • Precedence dependency from DELETE_ONLY PrimaryIndex:{DescID: 105, IndexID: 1, ConstraintID: 1} +│ │ │ rule: "index drop mutation visible before cleaning up index columns" +│ │ │ +│ │ ├── • IndexColumn:{DescID: 105, ColumnID: 2, IndexID: 1} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ ├── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ │ +│ │ │ ├── • Precedence dependency from WRITE_ONLY Column:{DescID: 105, ColumnID: 2} +│ │ │ │ rule: "column no longer public before dependents" +│ │ │ │ +│ │ │ └── • Precedence dependency from DELETE_ONLY PrimaryIndex:{DescID: 105, IndexID: 1, ConstraintID: 1} +│ │ │ rule: "index drop mutation visible before cleaning up index columns" +│ │ │ +│ │ ├── • PrimaryIndex:{DescID: 105, IndexID: 1, ConstraintID: 1} +│ │ │ │ PUBLIC → ABSENT +│ │ │ │ +│ │ │ ├── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ │ rule: "relation dropped before dependent index" +│ │ │ │ +│ │ │ ├── • Precedence dependency from ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 1} +│ │ │ │ rule: "dependents removed before index" +│ │ │ │ +│ │ │ ├── • Precedence dependency from ABSENT IndexColumn:{DescID: 105, ColumnID: 2, IndexID: 1} +│ │ │ │ rule: "dependents removed before index" +│ │ │ │ +│ │ │ └── • Precedence dependency from ABSENT IndexName:{DescID: 105, Name: t_pkey, IndexID: 1} +│ │ │ rule: "dependents removed before index" +│ │ │ +│ │ └── • IndexName:{DescID: 105, Name: t_pkey, IndexID: 1} +│ │ │ PUBLIC → ABSENT +│ │ │ +│ │ ├── • Precedence dependency from DROPPED Table:{DescID: 105} +│ │ │ rule: "descriptor dropped before dependent element removal" +│ │ │ +│ │ └── • Precedence dependency from VALIDATED PrimaryIndex:{DescID: 105, IndexID: 1, ConstraintID: 1} +│ │ rule: "index no longer public before dependents, excluding columns" +│ │ +│ └── • 36 Mutation operations +│ │ +│ ├── • MarkDescriptorAsDropped +│ │ DescriptorID: 105 +│ │ +│ ├── • RemoveObjectParent +│ │ ObjectID: 105 +│ │ ParentSchemaID: 101 +│ │ +│ ├── • NotImplementedForPublicObjects +│ │ DescID: 105 +│ │ ElementType: scpb.ColumnFamily +│ │ +│ ├── • MakePublicColumnWriteOnly +│ │ ColumnID: 1 +│ │ TableID: 105 +│ │ +│ ├── • SetColumnName +│ │ ColumnID: 1 +│ │ Name: crdb_internal_column_1_name_placeholder +│ │ TableID: 105 +│ │ +│ ├── • MakePublicColumnNotNullValidated +│ │ ColumnID: 1 +│ │ TableID: 105 +│ │ +│ ├── • MakePublicColumnWriteOnly +│ │ ColumnID: 2 +│ │ TableID: 105 +│ │ +│ ├── • SetColumnName +│ │ ColumnID: 2 +│ │ Name: crdb_internal_column_2_name_placeholder +│ │ TableID: 105 +│ │ +│ ├── • RemoveColumnDefaultExpression +│ │ ColumnID: 2 +│ │ TableID: 105 +│ │ +│ ├── • RemoveTableColumnBackReferencesInFunctions +│ │ BackReferencedColumnID: 2 +│ │ BackReferencedTableID: 105 +│ │ FunctionIDs: +│ │ - 104 +│ │ +│ ├── • MakePublicColumnWriteOnly +│ │ ColumnID: 4294967295 +│ │ TableID: 105 +│ │ +│ ├── • SetColumnName +│ │ ColumnID: 4294967295 +│ │ Name: crdb_internal_column_4294967295_name_placeholder +│ │ TableID: 105 +│ │ +│ ├── • MakePublicColumnWriteOnly +│ │ ColumnID: 4294967294 +│ │ TableID: 105 +│ │ +│ ├── • SetColumnName +│ │ ColumnID: 4294967294 +│ │ Name: crdb_internal_column_4294967294_name_placeholder +│ │ TableID: 105 +│ │ +│ ├── • MakePublicPrimaryIndexWriteOnly +│ │ IndexID: 1 +│ │ TableID: 105 +│ │ +│ ├── • SetIndexName +│ │ IndexID: 1 +│ │ Name: crdb_internal_index_1_name_placeholder +│ │ TableID: 105 +│ │ +│ ├── • DrainDescriptorName +│ │ Namespace: +│ │ DatabaseID: 100 +│ │ DescriptorID: 105 +│ │ Name: t +│ │ SchemaID: 101 +│ │ +│ ├── • NotImplementedForPublicObjects +│ │ DescID: 105 +│ │ ElementType: scpb.Owner +│ │ +│ ├── • RemoveUserPrivileges +│ │ DescriptorID: 105 +│ │ User: admin +│ │ +│ ├── • RemoveUserPrivileges +│ │ DescriptorID: 105 +│ │ User: root +│ │ +│ ├── • RemoveColumnNotNull +│ │ ColumnID: 1 +│ │ TableID: 105 +│ │ +│ ├── • MakeWriteOnlyColumnDeleteOnly +│ │ ColumnID: 2 +│ │ TableID: 105 +│ │ +│ ├── • MakeWriteOnlyColumnDeleteOnly +│ │ ColumnID: 4294967295 +│ │ TableID: 105 +│ │ +│ ├── • MakeWriteOnlyColumnDeleteOnly +│ │ ColumnID: 4294967294 +│ │ TableID: 105 +│ │ +│ ├── • MakeWriteOnlyColumnDeleteOnly +│ │ ColumnID: 1 +│ │ TableID: 105 +│ │ +│ ├── • MakeDeleteOnlyColumnAbsent +│ │ ColumnID: 4294967295 +│ │ TableID: 105 +│ │ +│ ├── • MakeDeleteOnlyColumnAbsent +│ │ ColumnID: 4294967294 +│ │ TableID: 105 +│ │ +│ ├── • MakeWriteOnlyIndexDeleteOnly +│ │ IndexID: 1 +│ │ TableID: 105 +│ │ +│ ├── • RemoveColumnFromIndex +│ │ ColumnID: 1 +│ │ IndexID: 1 +│ │ TableID: 105 +│ │ +│ ├── • RemoveColumnFromIndex +│ │ ColumnID: 2 +│ │ IndexID: 1 +│ │ Kind: 2 +│ │ TableID: 105 +│ │ +│ ├── • MakeIndexAbsent +│ │ IndexID: 1 +│ │ TableID: 105 +│ │ +│ ├── • MakeDeleteOnlyColumnAbsent +│ │ ColumnID: 1 +│ │ TableID: 105 +│ │ +│ ├── • MakeDeleteOnlyColumnAbsent +│ │ ColumnID: 2 +│ │ TableID: 105 +│ │ +│ ├── • SetJobStateOnDescriptor +│ │ DescriptorID: 104 +│ │ Initialize: true +│ │ +│ ├── • SetJobStateOnDescriptor +│ │ DescriptorID: 105 +│ │ Initialize: true +│ │ +│ └── • CreateSchemaChangerJob +│ Authorization: +│ UserName: root +│ DescriptorIDs: +│ - 104 +│ - 105 +│ JobID: 1 +│ NonCancelable: true +│ RunningStatus: PostCommitNonRevertiblePhase stage 1 of 1 with 2 MutationType ops pending +│ Statements: +│ - statement: DROP TABLE t +│ redactedstatement: DROP TABLE ‹defaultdb›.‹public›.‹t› +│ statementtag: DROP TABLE +│ +└── • PostCommitNonRevertiblePhase + │ + └── • Stage 1 of 1 in PostCommitNonRevertiblePhase + │ + ├── • 3 elements transitioning toward ABSENT + │ │ + │ ├── • Table:{DescID: 105} + │ │ │ DROPPED → ABSENT + │ │ │ + │ │ ├── • Precedence dependency from ABSENT Namespace:{DescID: 105, Name: t, ReferencedDescID: 100} + │ │ │ rule: "non-data dependents removed before descriptor" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT Owner:{DescID: 105} + │ │ │ rule: "non-data dependents removed before descriptor" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT UserPrivileges:{DescID: 105, Name: admin} + │ │ │ rule: "non-data dependents removed before descriptor" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT UserPrivileges:{DescID: 105, Name: root} + │ │ │ rule: "non-data dependents removed before descriptor" + │ │ │ + │ │ ├── • PreviousStagePrecedence dependency from DROPPED Table:{DescID: 105} + │ │ │ rule: "descriptor dropped in transaction before removal" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT ObjectParent:{DescID: 105, ReferencedDescID: 101} + │ │ │ rule: "non-data dependents removed before descriptor" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT ColumnFamily:{DescID: 105, Name: primary, ColumnFamilyID: 0} + │ │ │ rule: "non-data dependents removed before descriptor" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT Column:{DescID: 105, ColumnID: 1} + │ │ │ rule: "non-data dependents removed before descriptor" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT ColumnName:{DescID: 105, Name: i, ColumnID: 1} + │ │ │ rule: "non-data dependents removed before descriptor" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 1} + │ │ │ rule: "non-data dependents removed before descriptor" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT ColumnNotNull:{DescID: 105, ColumnID: 1, IndexID: 0} + │ │ │ rule: "non-data dependents removed before descriptor" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT Column:{DescID: 105, ColumnID: 2} + │ │ │ rule: "non-data dependents removed before descriptor" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT ColumnName:{DescID: 105, Name: b, ColumnID: 2} + │ │ │ rule: "non-data dependents removed before descriptor" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 2} + │ │ │ rule: "non-data dependents removed before descriptor" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT ColumnDefaultExpression:{DescID: 105, ColumnID: 2, ReferencedFunctionIDs: [104]} + │ │ │ rule: "non-data dependents removed before descriptor" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT Column:{DescID: 105, ColumnID: 4294967295} + │ │ │ rule: "non-data dependents removed before descriptor" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT ColumnName:{DescID: 105, Name: crdb_internal_mvcc_timestamp, ColumnID: 4294967295} + │ │ │ rule: "non-data dependents removed before descriptor" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 4294967295} + │ │ │ rule: "non-data dependents removed before descriptor" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT Column:{DescID: 105, ColumnID: 4294967294} + │ │ │ rule: "non-data dependents removed before descriptor" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT ColumnName:{DescID: 105, Name: tableoid, ColumnID: 4294967294} + │ │ │ rule: "non-data dependents removed before descriptor" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT ColumnType:{DescID: 105, ColumnFamilyID: 0, ColumnID: 4294967294} + │ │ │ rule: "non-data dependents removed before descriptor" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT IndexColumn:{DescID: 105, ColumnID: 1, IndexID: 1} + │ │ │ rule: "non-data dependents removed before descriptor" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT IndexColumn:{DescID: 105, ColumnID: 2, IndexID: 1} + │ │ │ rule: "non-data dependents removed before descriptor" + │ │ │ + │ │ ├── • Precedence dependency from ABSENT PrimaryIndex:{DescID: 105, IndexID: 1, ConstraintID: 1} + │ │ │ rule: "non-data dependents removed before descriptor" + │ │ │ + │ │ └── • Precedence dependency from ABSENT IndexName:{DescID: 105, Name: t_pkey, IndexID: 1} + │ │ rule: "non-data dependents removed before descriptor" + │ │ + │ ├── • IndexData:{DescID: 105, IndexID: 1} + │ │ │ PUBLIC → ABSENT + │ │ │ + │ │ ├── • Precedence dependency from ABSENT PrimaryIndex:{DescID: 105, IndexID: 1, ConstraintID: 1} + │ │ │ rule: "index removed before garbage collection" + │ │ │ + │ │ └── • SameStagePrecedence dependency from DROPPED TableData:{DescID: 105, ReferencedDescID: 100} + │ │ rule: "schedule all GC jobs for a descriptor in the same stage" + │ │ + │ └── • TableData:{DescID: 105, ReferencedDescID: 100} + │ │ PUBLIC → ABSENT + │ │ + │ └── • SameStagePrecedence dependency from ABSENT Table:{DescID: 105} + │ rule: "table removed right before garbage collection" + │ + └── • 5 Mutation operations + │ + ├── • CreateGCJobForTable + │ DatabaseID: 100 + │ StatementForDropJob: + │ Statement: DROP TABLE defaultdb.public.t + │ TableID: 105 + │ + ├── • CreateGCJobForIndex + │ IndexID: 1 + │ StatementForDropJob: + │ Statement: DROP TABLE defaultdb.public.t + │ TableID: 105 + │ + ├── • RemoveJobStateFromDescriptor + │ DescriptorID: 104 + │ JobID: 1 + │ + ├── • RemoveJobStateFromDescriptor + │ DescriptorID: 105 + │ JobID: 1 + │ + └── • UpdateSchemaChangerJob + DescriptorIDsToRemove: + - 104 + - 105 + IsNonCancelable: true + JobID: 1 + RunningStatus: all stages completed diff --git a/pkg/sql/sem/tree/udf.go b/pkg/sql/sem/tree/udf.go index e37723348404..1d53bffadc53 100644 --- a/pkg/sql/sem/tree/udf.go +++ b/pkg/sql/sem/tree/udf.go @@ -538,7 +538,10 @@ const ( StoredComputedColumnExpr SchemaExprContext = "STORED COMPUTED COLUMN" VirtualComputedColumnExpr SchemaExprContext = "VIRTUAL COMPUTED COLUMN" ColumnOnUpdateExpr SchemaExprContext = "ON UPDATE" - ColumnDefaultExpr SchemaExprContext = "DEFAULT" + ColumnDefaultExprInAddColumn SchemaExprContext = "DEFAULT (in ADD COLUMN)" + ColumnDefaultExprInNewTable SchemaExprContext = "DEFAULT (in CREATE TABLE)" + ColumnDefaultExprInNewView SchemaExprContext = "DEFAULT (in CREATE VIEW)" + ColumnDefaultExprInSetDefault SchemaExprContext = "DEFAULT (in SET DEFAULT)" CheckConstraintExpr SchemaExprContext = "CHECK" UniqueWithoutIndexPredicateExpr SchemaExprContext = "UNIQUE WITHOUT INDEX PREDICATE" IndexPredicateExpr SchemaExprContext = "INDEX PREDICATE"