From 00c8c6ae53625b8e9937c7b78243ab922ef828aa Mon Sep 17 00:00:00 2001 From: Faizan Qazi Date: Tue, 8 Oct 2024 21:16:47 +0000 Subject: [PATCH] sql/schemachanger: clean up SequenceOwner elements during restore Previously, when restoring a backup taken in middle of a DROP COLUMN, where a column had a sequence owner assigned, it was possible for the backup to be unrestorable. This would happen because the sequence reference would have been dropped in the plan, but the seqeunce owner element was still within the state. To address this, this test updates the rewrite logic to clean up any SequenceOwner elements which have the referenced sequence already removed. Fixes: #130778 Release note (bug fix): Addressed a rare bug that could prevent backups taken during a DROP COLUMN operation with a sequence owner from restoring with the error: "rewriting descriptor ids: missing rewrite for in SequenceOwner..." --- .../backup_base_generated_test.go | 28 + pkg/sql/catalog/rewrite/rewrite.go | 33 +- .../schemachanger/sctest_generated_test.go | 42 + .../drop_column_sequence_owner.definition | 49 ++ .../drop_column_sequence_owner.explain | 215 +++++ .../drop_column_sequence_owner.explain_shape | 22 + .../drop_column_sequence_owner.side_effects | 748 ++++++++++++++++++ ...mn_sequence_owner__rollback_1_of_7.explain | 43 + ...mn_sequence_owner__rollback_2_of_7.explain | 53 ++ ...mn_sequence_owner__rollback_3_of_7.explain | 53 ++ ...mn_sequence_owner__rollback_4_of_7.explain | 53 ++ ...mn_sequence_owner__rollback_5_of_7.explain | 55 ++ ...mn_sequence_owner__rollback_6_of_7.explain | 55 ++ ...mn_sequence_owner__rollback_7_of_7.explain | 53 ++ 14 files changed, 1490 insertions(+), 12 deletions(-) create mode 100644 pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner.definition create mode 100644 pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner.explain create mode 100644 pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner.explain_shape create mode 100644 pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner.side_effects create mode 100644 pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner__rollback_1_of_7.explain create mode 100644 pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner__rollback_2_of_7.explain create mode 100644 pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner__rollback_3_of_7.explain create mode 100644 pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner__rollback_4_of_7.explain create mode 100644 pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner__rollback_5_of_7.explain create mode 100644 pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner__rollback_6_of_7.explain create mode 100644 pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner__rollback_7_of_7.explain diff --git a/pkg/ccl/schemachangerccl/backup_base_generated_test.go b/pkg/ccl/schemachangerccl/backup_base_generated_test.go index ccd3affb4617..2ad0efe202c9 100644 --- a/pkg/ccl/schemachangerccl/backup_base_generated_test.go +++ b/pkg/ccl/schemachangerccl/backup_base_generated_test.go @@ -407,6 +407,13 @@ func TestBackupRollbacks_base_drop_column_create_index_separate_statements(t *te sctest.BackupRollbacks(t, path, sctest.SingleNodeTestClusterFactory{}) } +func TestBackupRollbacks_base_drop_column_sequence_owner(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + const path = "pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner" + sctest.BackupRollbacks(t, path, sctest.SingleNodeTestClusterFactory{}) +} + func TestBackupRollbacks_base_drop_column_unique_index(t *testing.T) { defer leaktest.AfterTest(t)() defer log.Scope(t).Close(t) @@ -918,6 +925,13 @@ func TestBackupRollbacksMixedVersion_base_drop_column_create_index_separate_stat sctest.BackupRollbacksMixedVersion(t, path, sctest.SingleNodeTestClusterFactory{}) } +func TestBackupRollbacksMixedVersion_base_drop_column_sequence_owner(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + const path = "pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner" + sctest.BackupRollbacksMixedVersion(t, path, sctest.SingleNodeTestClusterFactory{}) +} + func TestBackupRollbacksMixedVersion_base_drop_column_unique_index(t *testing.T) { defer leaktest.AfterTest(t)() defer log.Scope(t).Close(t) @@ -1429,6 +1443,13 @@ func TestBackupSuccess_base_drop_column_create_index_separate_statements(t *test sctest.BackupSuccess(t, path, sctest.SingleNodeTestClusterFactory{}) } +func TestBackupSuccess_base_drop_column_sequence_owner(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + const path = "pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner" + sctest.BackupSuccess(t, path, sctest.SingleNodeTestClusterFactory{}) +} + func TestBackupSuccess_base_drop_column_unique_index(t *testing.T) { defer leaktest.AfterTest(t)() defer log.Scope(t).Close(t) @@ -1940,6 +1961,13 @@ func TestBackupSuccessMixedVersion_base_drop_column_create_index_separate_statem sctest.BackupSuccessMixedVersion(t, path, sctest.SingleNodeTestClusterFactory{}) } +func TestBackupSuccessMixedVersion_base_drop_column_sequence_owner(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + const path = "pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner" + sctest.BackupSuccessMixedVersion(t, path, sctest.SingleNodeTestClusterFactory{}) +} + func TestBackupSuccessMixedVersion_base_drop_column_unique_index(t *testing.T) { defer leaktest.AfterTest(t)() defer log.Scope(t).Close(t) diff --git a/pkg/sql/catalog/rewrite/rewrite.go b/pkg/sql/catalog/rewrite/rewrite.go index d3272097d23e..41c0f5ec10a5 100644 --- a/pkg/sql/catalog/rewrite/rewrite.go +++ b/pkg/sql/catalog/rewrite/rewrite.go @@ -767,6 +767,16 @@ func rewriteSchemaChangerState( data.SchemaID = rewrite.ParentSchemaID continue } + + // removeElementAtCurrentIdx deletes the element at the current index. + removeElementAtCurrentIdx := func() { + 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-- + } + + missingID := descpb.InvalidID if err := screl.WalkDescIDs(t.Element(), func(id *descpb.ID) error { if *id == descpb.InvalidID { // Some descriptor ID fields in elements may be deliberately unset. @@ -775,6 +785,7 @@ func rewriteSchemaChangerState( } rewrite, ok := descriptorRewrites[*id] if !ok { + missingID = *id return errors.Errorf("missing rewrite for id %d in %s", *id, screl.ElementString(t.Element())) } *id = rewrite.ID @@ -785,29 +796,27 @@ func rewriteSchemaChangerState( // We'll permit this in the special case of a schema parent element. _, scExists := descriptorRewrites[el.SchemaID] if !scExists && state.CurrentStatuses[i] == scpb.Status_ABSENT { - 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-- + removeElementAtCurrentIdx() continue } case *scpb.CheckConstraint: // IF there is any dependency missing for check constraint, 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-- + removeElementAtCurrentIdx() 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-- + removeElementAtCurrentIdx() continue + case *scpb.SequenceOwner: + // If a sequence owner is missing the sequence, then the sequences + // was already dropped and this element can be removed. + if el.SequenceID == missingID { + removeElementAtCurrentIdx() + continue + } } return errors.Wrap(err, "rewriting descriptor ids") } diff --git a/pkg/sql/schemachanger/sctest_generated_test.go b/pkg/sql/schemachanger/sctest_generated_test.go index 8b57dd510ef9..c44936da49dd 100644 --- a/pkg/sql/schemachanger/sctest_generated_test.go +++ b/pkg/sql/schemachanger/sctest_generated_test.go @@ -407,6 +407,13 @@ func TestEndToEndSideEffects_drop_column_create_index_separate_statements(t *tes sctest.EndToEndSideEffects(t, path, sctest.SingleNodeTestClusterFactory{}) } +func TestEndToEndSideEffects_drop_column_sequence_owner(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + const path = "pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner" + sctest.EndToEndSideEffects(t, path, sctest.SingleNodeTestClusterFactory{}) +} + func TestEndToEndSideEffects_drop_column_unique_index(t *testing.T) { defer leaktest.AfterTest(t)() defer log.Scope(t).Close(t) @@ -918,6 +925,13 @@ func TestExecuteWithDMLInjection_drop_column_create_index_separate_statements(t sctest.ExecuteWithDMLInjection(t, path, sctest.SingleNodeTestClusterFactory{}) } +func TestExecuteWithDMLInjection_drop_column_sequence_owner(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + const path = "pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner" + sctest.ExecuteWithDMLInjection(t, path, sctest.SingleNodeTestClusterFactory{}) +} + func TestExecuteWithDMLInjection_drop_column_unique_index(t *testing.T) { defer leaktest.AfterTest(t)() defer log.Scope(t).Close(t) @@ -1429,6 +1443,13 @@ func TestGenerateSchemaChangeCorpus_drop_column_create_index_separate_statements sctest.GenerateSchemaChangeCorpus(t, path, sctest.SingleNodeTestClusterFactory{}) } +func TestGenerateSchemaChangeCorpus_drop_column_sequence_owner(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + const path = "pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner" + sctest.GenerateSchemaChangeCorpus(t, path, sctest.SingleNodeTestClusterFactory{}) +} + func TestGenerateSchemaChangeCorpus_drop_column_unique_index(t *testing.T) { defer leaktest.AfterTest(t)() defer log.Scope(t).Close(t) @@ -1940,6 +1961,13 @@ func TestPause_drop_column_create_index_separate_statements(t *testing.T) { sctest.Pause(t, path, sctest.SingleNodeTestClusterFactory{}) } +func TestPause_drop_column_sequence_owner(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + const path = "pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner" + sctest.Pause(t, path, sctest.SingleNodeTestClusterFactory{}) +} + func TestPause_drop_column_unique_index(t *testing.T) { defer leaktest.AfterTest(t)() defer log.Scope(t).Close(t) @@ -2451,6 +2479,13 @@ func TestPauseMixedVersion_drop_column_create_index_separate_statements(t *testi sctest.PauseMixedVersion(t, path, sctest.SingleNodeTestClusterFactory{}) } +func TestPauseMixedVersion_drop_column_sequence_owner(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + const path = "pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner" + sctest.PauseMixedVersion(t, path, sctest.SingleNodeTestClusterFactory{}) +} + func TestPauseMixedVersion_drop_column_unique_index(t *testing.T) { defer leaktest.AfterTest(t)() defer log.Scope(t).Close(t) @@ -2962,6 +2997,13 @@ func TestRollback_drop_column_create_index_separate_statements(t *testing.T) { sctest.Rollback(t, path, sctest.SingleNodeTestClusterFactory{}) } +func TestRollback_drop_column_sequence_owner(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + const path = "pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner" + sctest.Rollback(t, path, sctest.SingleNodeTestClusterFactory{}) +} + func TestRollback_drop_column_unique_index(t *testing.T) { defer leaktest.AfterTest(t)() defer log.Scope(t).Close(t) diff --git a/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner.definition b/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner.definition new file mode 100644 index 000000000000..ba996c2cafcc --- /dev/null +++ b/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner.definition @@ -0,0 +1,49 @@ +setup +CREATE TABLE t (i INT PRIMARY KEY, j INT, k int); +CREATE SEQUENCE sq1 OWNED BY t.j; +COMMENT ON TABLE t IS 't has a comment'; +COMMENT ON COLUMN t.j IS 'j has a comment'; +INSERT INTO t VALUES(-1); +INSERT INTO t VALUES(-2); +INSERT INTO t VALUES(-3); +---- + +stage-exec phase=PostCommitPhase stage=: +INSERT INTO t VALUES($stageKey); +INSERT INTO t VALUES($stageKey + 1); +UPDATE t SET k=$stageKey; +UPDATE t SET k=i; +DELETE FROM t WHERE i=-1; +DELETE FROM t WHERE i=$stageKey; +INSERT INTO t VALUES($stageKey); +INSERT INTO t VALUES(-1); +---- + +# Each insert will be injected twice per stage, plus 3 injected +# at the start. +stage-query phase=PostCommitPhase stage=: +SELECT count(*)=($successfulStageCount*2)+3 FROM t; +---- +true + +stage-exec phase=PostCommitNonRevertiblePhase stage=: +INSERT INTO t VALUES($stageKey); +INSERT INTO t VALUES($stageKey + 1); +UPDATE t SET k=$stageKey; +UPDATE t SET k=i; +DELETE FROM t WHERE i=-1; +DELETE FROM t WHERE i=$stageKey; +INSERT INTO t VALUES($stageKey); +INSERT INTO t VALUES(-1); +---- + +# Each insert will be injected twice per stage, plus 3 injected +# at the start. +stage-query phase=PostCommitNonRevertiblePhase stage=: +SELECT count(*)=($successfulStageCount*2)+3 FROM t; +---- +true + +test +ALTER TABLE t DROP COLUMN j +---- diff --git a/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner.explain b/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner.explain new file mode 100644 index 000000000000..fc1027aa910f --- /dev/null +++ b/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner.explain @@ -0,0 +1,215 @@ +/* setup */ +CREATE TABLE t (i INT PRIMARY KEY, j INT, k int); +CREATE SEQUENCE sq1 OWNED BY t.j; +COMMENT ON TABLE t IS 't has a comment'; +COMMENT ON COLUMN t.j IS 'j has a comment'; +INSERT INTO t VALUES(-1); +INSERT INTO t VALUES(-2); +INSERT INTO t VALUES(-3); + +/* test */ +EXPLAIN (DDL) ALTER TABLE t DROP COLUMN j; +---- +Schema change plan for ALTER TABLE ‹defaultdb›.‹public›.‹t› DROP COLUMN ‹j›; + ├── StatementPhase + │ └── Stage 1 of 1 in StatementPhase + │ ├── 4 elements transitioning toward PUBLIC + │ │ ├── ABSENT → BACKFILL_ONLY PrimaryIndex:{DescID: 104 (t), IndexID: 2 (t_pkey+), ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1 (t_pkey-)} + │ │ ├── ABSENT → PUBLIC IndexColumn:{DescID: 104 (t), ColumnID: 1 (i), IndexID: 2 (t_pkey+)} + │ │ ├── ABSENT → PUBLIC IndexColumn:{DescID: 104 (t), ColumnID: 3 (k), IndexID: 2 (t_pkey+)} + │ │ └── ABSENT → PUBLIC IndexData:{DescID: 104 (t), IndexID: 2 (t_pkey+)} + │ ├── 3 elements transitioning toward TRANSIENT_ABSENT + │ │ ├── ABSENT → DELETE_ONLY TemporaryIndex:{DescID: 104 (t), IndexID: 3, ConstraintID: 3, SourceIndexID: 1 (t_pkey-)} + │ │ ├── ABSENT → PUBLIC IndexColumn:{DescID: 104 (t), ColumnID: 1 (i), IndexID: 3} + │ │ └── ABSENT → PUBLIC IndexColumn:{DescID: 104 (t), ColumnID: 3 (k), IndexID: 3} + │ ├── 3 elements transitioning toward ABSENT + │ │ ├── PUBLIC → WRITE_ONLY Column:{DescID: 104 (t), ColumnID: 2 (j-)} + │ │ ├── PUBLIC → ABSENT ColumnName:{DescID: 104 (t), Name: "j", ColumnID: 2 (j-)} + │ │ └── PUBLIC → ABSENT ColumnComment:{DescID: 104 (t), ColumnID: 2 (j-), Comment: "j has a comment"} + │ └── 9 Mutation operations + │ ├── MakePublicColumnWriteOnly {"ColumnID":2,"TableID":104} + │ ├── SetColumnName {"ColumnID":2,"Name":"crdb_internal_co...","TableID":104} + │ ├── RemoveColumnComment {"ColumnID":2,"PgAttributeNum":2,"TableID":104} + │ ├── MakeAbsentIndexBackfilling {"Index":{"ConstraintID":2,"IndexID":2,"IsUnique":true,"SourceIndexID":1,"TableID":104,"TemporaryIndexID":3}} + │ ├── AddColumnToIndex {"ColumnID":1,"IndexID":2,"TableID":104} + │ ├── AddColumnToIndex {"ColumnID":3,"IndexID":2,"Kind":2,"TableID":104} + │ ├── MakeAbsentTempIndexDeleteOnly {"Index":{"ConstraintID":3,"IndexID":3,"IsUnique":true,"SourceIndexID":1,"TableID":104}} + │ ├── AddColumnToIndex {"ColumnID":1,"IndexID":3,"TableID":104} + │ └── AddColumnToIndex {"ColumnID":3,"IndexID":3,"Kind":2,"TableID":104} + ├── PreCommitPhase + │ ├── Stage 1 of 2 in PreCommitPhase + │ │ ├── 4 elements transitioning toward PUBLIC + │ │ │ ├── BACKFILL_ONLY → ABSENT PrimaryIndex:{DescID: 104 (t), IndexID: 2 (t_pkey+), ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1 (t_pkey-)} + │ │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 1 (i), IndexID: 2 (t_pkey+)} + │ │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 3 (k), IndexID: 2 (t_pkey+)} + │ │ │ └── PUBLIC → ABSENT IndexData:{DescID: 104 (t), IndexID: 2 (t_pkey+)} + │ │ ├── 3 elements transitioning toward TRANSIENT_ABSENT + │ │ │ ├── DELETE_ONLY → ABSENT TemporaryIndex:{DescID: 104 (t), IndexID: 3, ConstraintID: 3, SourceIndexID: 1 (t_pkey-)} + │ │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 1 (i), IndexID: 3} + │ │ │ └── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 3 (k), IndexID: 3} + │ │ ├── 3 elements transitioning toward ABSENT + │ │ │ ├── WRITE_ONLY → PUBLIC Column:{DescID: 104 (t), ColumnID: 2 (j-)} + │ │ │ ├── ABSENT → PUBLIC ColumnName:{DescID: 104 (t), Name: "j", ColumnID: 2 (j-)} + │ │ │ └── ABSENT → PUBLIC ColumnComment:{DescID: 104 (t), ColumnID: 2 (j-), Comment: "j has a comment"} + │ │ └── 1 Mutation operation + │ │ └── UndoAllInTxnImmediateMutationOpSideEffects + │ └── Stage 2 of 2 in PreCommitPhase + │ ├── 4 elements transitioning toward PUBLIC + │ │ ├── ABSENT → BACKFILL_ONLY PrimaryIndex:{DescID: 104 (t), IndexID: 2 (t_pkey+), ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1 (t_pkey-)} + │ │ ├── ABSENT → PUBLIC IndexColumn:{DescID: 104 (t), ColumnID: 1 (i), IndexID: 2 (t_pkey+)} + │ │ ├── ABSENT → PUBLIC IndexColumn:{DescID: 104 (t), ColumnID: 3 (k), IndexID: 2 (t_pkey+)} + │ │ └── ABSENT → PUBLIC IndexData:{DescID: 104 (t), IndexID: 2 (t_pkey+)} + │ ├── 3 elements transitioning toward TRANSIENT_ABSENT + │ │ ├── ABSENT → DELETE_ONLY TemporaryIndex:{DescID: 104 (t), IndexID: 3, ConstraintID: 3, SourceIndexID: 1 (t_pkey-)} + │ │ ├── ABSENT → PUBLIC IndexColumn:{DescID: 104 (t), ColumnID: 1 (i), IndexID: 3} + │ │ └── ABSENT → PUBLIC IndexColumn:{DescID: 104 (t), ColumnID: 3 (k), IndexID: 3} + │ ├── 3 elements transitioning toward ABSENT + │ │ ├── PUBLIC → WRITE_ONLY Column:{DescID: 104 (t), ColumnID: 2 (j-)} + │ │ ├── PUBLIC → ABSENT ColumnName:{DescID: 104 (t), Name: "j", ColumnID: 2 (j-)} + │ │ └── PUBLIC → ABSENT ColumnComment:{DescID: 104 (t), ColumnID: 2 (j-), Comment: "j has a comment"} + │ └── 14 Mutation operations + │ ├── MakePublicColumnWriteOnly {"ColumnID":2,"TableID":104} + │ ├── SetColumnName {"ColumnID":2,"Name":"crdb_internal_co...","TableID":104} + │ ├── RemoveColumnComment {"ColumnID":2,"PgAttributeNum":2,"TableID":104} + │ ├── MakeAbsentIndexBackfilling {"Index":{"ConstraintID":2,"IndexID":2,"IsUnique":true,"SourceIndexID":1,"TableID":104,"TemporaryIndexID":3}} + │ ├── MaybeAddSplitForIndex {"IndexID":2,"TableID":104} + │ ├── AddColumnToIndex {"ColumnID":1,"IndexID":2,"TableID":104} + │ ├── AddColumnToIndex {"ColumnID":3,"IndexID":2,"Kind":2,"TableID":104} + │ ├── MakeAbsentTempIndexDeleteOnly {"Index":{"ConstraintID":3,"IndexID":3,"IsUnique":true,"SourceIndexID":1,"TableID":104}} + │ ├── MaybeAddSplitForIndex {"IndexID":3,"TableID":104} + │ ├── AddColumnToIndex {"ColumnID":1,"IndexID":3,"TableID":104} + │ ├── AddColumnToIndex {"ColumnID":3,"IndexID":3,"Kind":2,"TableID":104} + │ ├── 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: 104 (t), IndexID: 3, ConstraintID: 3, SourceIndexID: 1 (t_pkey-)} + │ │ │ └── ABSENT → PUBLIC IndexData:{DescID: 104 (t), IndexID: 3} + │ │ └── 4 Mutation operations + │ │ ├── MakeDeleteOnlyIndexWriteOnly {"IndexID":3,"TableID":104} + │ │ ├── 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: 104 (t), IndexID: 2 (t_pkey+), ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1 (t_pkey-)} + │ │ └── 1 Backfill operation + │ │ └── BackfillIndex {"IndexID":2,"SourceIndexID":1,"TableID":104} + │ ├── Stage 3 of 7 in PostCommitPhase + │ │ ├── 1 element transitioning toward PUBLIC + │ │ │ └── BACKFILLED → DELETE_ONLY PrimaryIndex:{DescID: 104 (t), IndexID: 2 (t_pkey+), ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1 (t_pkey-)} + │ │ └── 4 Mutation operations + │ │ ├── MakeBackfillingIndexDeleteOnly {"IndexID":2,"TableID":104} + │ │ ├── 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: 104 (t), IndexID: 2 (t_pkey+), ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1 (t_pkey-)} + │ │ └── 4 Mutation operations + │ │ ├── MakeBackfilledIndexMerging {"IndexID":2,"TableID":104} + │ │ ├── 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: 104 (t), IndexID: 2 (t_pkey+), ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1 (t_pkey-)} + │ │ └── 1 Backfill operation + │ │ └── MergeIndex {"BackfilledIndexID":2,"TableID":104,"TemporaryIndexID":3} + │ ├── Stage 6 of 7 in PostCommitPhase + │ │ ├── 1 element transitioning toward PUBLIC + │ │ │ └── MERGED → WRITE_ONLY PrimaryIndex:{DescID: 104 (t), IndexID: 2 (t_pkey+), ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1 (t_pkey-)} + │ │ ├── 1 element transitioning toward TRANSIENT_ABSENT + │ │ │ └── WRITE_ONLY → TRANSIENT_DELETE_ONLY TemporaryIndex:{DescID: 104 (t), IndexID: 3, ConstraintID: 3, SourceIndexID: 1 (t_pkey-)} + │ │ └── 5 Mutation operations + │ │ ├── MakeWriteOnlyIndexDeleteOnly {"IndexID":3,"TableID":104} + │ │ ├── MakeMergedIndexWriteOnly {"IndexID":2,"TableID":104} + │ │ ├── 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: 104 (t), IndexID: 2 (t_pkey+), ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1 (t_pkey-)} + │ └── 1 Validation operation + │ └── ValidateIndex {"IndexID":2,"TableID":104} + └── PostCommitNonRevertiblePhase + ├── Stage 1 of 4 in PostCommitNonRevertiblePhase + │ ├── 2 elements transitioning toward PUBLIC + │ │ ├── VALIDATED → PUBLIC PrimaryIndex:{DescID: 104 (t), IndexID: 2 (t_pkey+), ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1 (t_pkey-)} + │ │ └── ABSENT → PUBLIC IndexName:{DescID: 104 (t), Name: "t_pkey", IndexID: 2 (t_pkey+)} + │ ├── 3 elements transitioning toward TRANSIENT_ABSENT + │ │ ├── TRANSIENT_DELETE_ONLY → TRANSIENT_ABSENT TemporaryIndex:{DescID: 104 (t), IndexID: 3, ConstraintID: 3, SourceIndexID: 1 (t_pkey-)} + │ │ ├── PUBLIC → TRANSIENT_ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 1 (i), IndexID: 3} + │ │ └── PUBLIC → TRANSIENT_ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 3 (k), IndexID: 3} + │ ├── 3 elements transitioning toward ABSENT + │ │ ├── WRITE_ONLY → DELETE_ONLY Column:{DescID: 104 (t), ColumnID: 2 (j-)} + │ │ ├── PUBLIC → VALIDATED PrimaryIndex:{DescID: 104 (t), IndexID: 1 (t_pkey-), ConstraintID: 1} + │ │ └── PUBLIC → ABSENT IndexName:{DescID: 104 (t), Name: "t_pkey", IndexID: 1 (t_pkey-)} + │ └── 11 Mutation operations + │ ├── MakeWriteOnlyColumnDeleteOnly {"ColumnID":2,"TableID":104} + │ ├── MakePublicPrimaryIndexWriteOnly {"IndexID":1,"TableID":104} + │ ├── SetIndexName {"IndexID":1,"Name":"crdb_internal_in...","TableID":104} + │ ├── SetIndexName {"IndexID":2,"Name":"t_pkey","TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":3,"TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":3,"IndexID":3,"Kind":2,"TableID":104} + │ ├── MakeValidatedPrimaryIndexPublic {"IndexID":2,"TableID":104} + │ ├── MakeIndexAbsent {"IndexID":3,"TableID":104} + │ ├── SetJobStateOnDescriptor {"DescriptorID":104} + │ ├── SetJobStateOnDescriptor {"DescriptorID":105} + │ └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"PostCommitNonRev..."} + ├── Stage 2 of 4 in PostCommitNonRevertiblePhase + │ ├── 4 elements transitioning toward ABSENT + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 1 (i), IndexID: 1 (t_pkey-)} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 2 (j-), IndexID: 1 (t_pkey-)} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 3 (k), IndexID: 1 (t_pkey-)} + │ │ └── VALIDATED → DELETE_ONLY PrimaryIndex:{DescID: 104 (t), IndexID: 1 (t_pkey-), ConstraintID: 1} + │ └── 7 Mutation operations + │ ├── MakeWriteOnlyIndexDeleteOnly {"IndexID":1,"TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":1,"TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":2,"IndexID":1,"Kind":2,"TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":3,"IndexID":1,"Kind":2,"Ordinal":1,"TableID":104} + │ ├── SetJobStateOnDescriptor {"DescriptorID":104} + │ ├── SetJobStateOnDescriptor {"DescriptorID":105} + │ └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"PostCommitNonRev..."} + ├── Stage 3 of 4 in PostCommitNonRevertiblePhase + │ ├── 1 element transitioning toward TRANSIENT_ABSENT + │ │ └── PUBLIC → TRANSIENT_ABSENT IndexData:{DescID: 104 (t), IndexID: 3} + │ ├── 11 elements transitioning toward ABSENT + │ │ ├── DELETE_ONLY → ABSENT Column:{DescID: 104 (t), ColumnID: 2 (j-)} + │ │ ├── PUBLIC → ABSENT ColumnType:{DescID: 104 (t), ColumnFamilyID: 0 (primary), ColumnID: 2 (j-), TypeName: "INT8"} + │ │ ├── PUBLIC → ABSENT SequenceOwner:{DescID: 104 (t), ColumnID: 2 (j-), ReferencedDescID: 105 (sq1-)} + │ │ ├── DELETE_ONLY → ABSENT PrimaryIndex:{DescID: 104 (t), IndexID: 1 (t_pkey-), ConstraintID: 1} + │ │ ├── PUBLIC → ABSENT IndexData:{DescID: 104 (t), IndexID: 1 (t_pkey-)} + │ │ ├── PUBLIC → ABSENT Namespace:{DescID: 105 (sq1-), Name: "sq1", ReferencedDescID: 100 (defaultdb)} + │ │ ├── PUBLIC → ABSENT Owner:{DescID: 105 (sq1-)} + │ │ ├── PUBLIC → ABSENT UserPrivileges:{DescID: 105 (sq1-), Name: "admin"} + │ │ ├── PUBLIC → ABSENT UserPrivileges:{DescID: 105 (sq1-), Name: "root"} + │ │ ├── PUBLIC → DROPPED Sequence:{DescID: 105 (sq1-)} + │ │ └── PUBLIC → ABSENT SchemaChild:{DescID: 105 (sq1-), ReferencedDescID: 101 (public)} + │ └── 15 Mutation operations + │ ├── MakeIndexAbsent {"IndexID":1,"TableID":104} + │ ├── CreateGCJobForIndex {"IndexID":1,"TableID":104} + │ ├── MarkDescriptorAsDropped {"DescriptorID":105} + │ ├── RemoveObjectParent {"ObjectID":105,"ParentSchemaID":101} + │ ├── CreateGCJobForIndex {"IndexID":3,"TableID":104} + │ ├── RemoveSequenceOwner {"ColumnID":2,"OwnedSequenceID":105,"TableID":104} + │ ├── RemoveOwnerBackReferenceInSequence {"SequenceID":105} + │ ├── DrainDescriptorName {"Namespace":{"DatabaseID":100,"DescriptorID":105,"Name":"sq1","SchemaID":101}} + │ ├── NotImplementedForPublicObjects {"DescID":105,"ElementType":"scpb.Owner"} + │ ├── RemoveUserPrivileges {"DescriptorID":105,"User":"admin"} + │ ├── RemoveUserPrivileges {"DescriptorID":105,"User":"root"} + │ ├── MakeDeleteOnlyColumnAbsent {"ColumnID":2,"TableID":104} + │ ├── SetJobStateOnDescriptor {"DescriptorID":104} + │ ├── SetJobStateOnDescriptor {"DescriptorID":105} + │ └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"PostCommitNonRev..."} + └── Stage 4 of 4 in PostCommitNonRevertiblePhase + ├── 2 elements transitioning toward ABSENT + │ ├── DROPPED → ABSENT Sequence:{DescID: 105 (sq1-)} + │ └── PUBLIC → ABSENT TableData:{DescID: 105 (sq1-), ReferencedDescID: 100 (defaultdb)} + └── 4 Mutation operations + ├── CreateGCJobForTable {"DatabaseID":100,"TableID":105} + ├── RemoveJobStateFromDescriptor {"DescriptorID":104} + ├── RemoveJobStateFromDescriptor {"DescriptorID":105} + └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"all stages compl..."} diff --git a/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner.explain_shape b/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner.explain_shape new file mode 100644 index 000000000000..1810a75900c9 --- /dev/null +++ b/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner.explain_shape @@ -0,0 +1,22 @@ +/* setup */ +CREATE TABLE t (i INT PRIMARY KEY, j INT, k int); +CREATE SEQUENCE sq1 OWNED BY t.j; +COMMENT ON TABLE t IS 't has a comment'; +COMMENT ON COLUMN t.j IS 'j has a comment'; +INSERT INTO t VALUES(-1); +INSERT INTO t VALUES(-2); +INSERT INTO t VALUES(-3); + +/* test */ +EXPLAIN (DDL, SHAPE) ALTER TABLE t DROP COLUMN j; +---- +Schema change plan for ALTER TABLE ‹defaultdb›.‹public›.‹t› DROP COLUMN ‹j›; + ├── execute 2 system table mutations transactions + ├── backfill using primary index t_pkey- in relation t + │ └── into t_pkey+ (i; k) + ├── execute 2 system table mutations transactions + ├── merge temporary indexes into backfilled indexes in relation t + │ └── from t@[3] into t_pkey+ + ├── execute 1 system table mutations transaction + ├── validate UNIQUE constraint backed by index t_pkey+ in relation t + └── execute 4 system table mutations transactions diff --git a/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner.side_effects b/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner.side_effects new file mode 100644 index 000000000000..ae24299708a9 --- /dev/null +++ b/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner.side_effects @@ -0,0 +1,748 @@ +/* setup */ +CREATE TABLE t (i INT PRIMARY KEY, j INT, k int); +CREATE SEQUENCE sq1 OWNED BY t.j; +COMMENT ON TABLE t IS 't has a comment'; +COMMENT ON COLUMN t.j IS 'j has a comment'; +INSERT INTO t VALUES(-1); +INSERT INTO t VALUES(-2); +INSERT INTO t VALUES(-3); +---- +... ++object {100 101 t} -> 104 ++object {100 101 sq1} -> 105 + +/* test */ +ALTER TABLE t DROP COLUMN j; +---- +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: 104 + statement: ALTER TABLE ‹defaultdb›.‹public›.‹t› DROP COLUMN ‹j› + tag: ALTER TABLE + user: root + tableName: defaultdb.public.t +## StatementPhase stage 1 of 1 with 9 MutationType ops +upsert descriptor #104 + ... + oid: 20 + width: 64 + - - id: 2 + - name: j + - nullable: true + - ownsSequenceIds: + - - 105 + - type: + - family: IntFamily + - oid: 20 + - width: 64 + - id: 3 + name: k + ... + columnNames: + - i + - - j + + - crdb_internal_column_2_name_placeholder + - k + name: primary + ... + id: 104 + modificationTime: {} + + mutations: + + - column: + + id: 2 + + name: crdb_internal_column_2_name_placeholder + + nullable: true + + ownsSequenceIds: + + - 105 + + type: + + family: IntFamily + + oid: 20 + + width: 64 + + 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: {} + + storeColumnIds: + + - 3 + + storeColumnNames: + + - k + + 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: {} + + storeColumnIds: + + - 3 + + storeColumnNames: + + - k + + unique: true + + useDeletePreservingEncoding: true + + version: 4 + + mutationId: 1 + + state: DELETE_ONLY + name: t + nextColumnId: 4 + - nextConstraintId: 2 + + nextConstraintId: 4 + nextFamilyId: 1 + - nextIndexId: 2 + + nextIndexId: 4 + nextMutationId: 1 + parentId: 100 + ... + - 3 + storeColumnNames: + - - j + + - crdb_internal_column_2_name_placeholder + - k + unique: true + ... + time: {} + unexposedParentSchemaId: 101 + - version: "2" + + version: "3" +delete comment ColumnCommentType(objID: 104, subID: 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 14 MutationType ops +upsert descriptor #104 + ... + oid: 20 + width: 64 + - - id: 2 + - name: j + - nullable: true + - ownsSequenceIds: + - - 105 + - type: + - family: IntFamily + - oid: 20 + - width: 64 + - id: 3 + name: k + ... + createAsOfTime: + wallTime: "1640995200000000000" + + declarativeSchemaChangerState: + + authorization: + + userName: root + + currentStatuses: + + jobId: "1" + + nameMapping: + + columns: + + "1": i + + "3": k + + "4294967294": tableoid + + "4294967295": crdb_internal_mvcc_timestamp + + families: + + "0": primary + + id: 104 + + indexes: + + "2": t_pkey + + name: t + + relevantStatements: + + - statement: + + redactedStatement: ALTER TABLE ‹defaultdb›.‹public›.‹t› DROP COLUMN ‹j› + + statement: ALTER TABLE t DROP COLUMN j + + statementTag: ALTER TABLE + + revertible: true + + targetRanks: + + targets: + families: + - columnIds: + ... + columnNames: + - i + - - j + + - crdb_internal_column_2_name_placeholder + - k + name: primary + ... + id: 104 + modificationTime: {} + + mutations: + + - column: + + id: 2 + + name: crdb_internal_column_2_name_placeholder + + nullable: true + + ownsSequenceIds: + + - 105 + + type: + + family: IntFamily + + oid: 20 + + width: 64 + + 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: {} + + storeColumnIds: + + - 3 + + storeColumnNames: + + - k + + 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: {} + + storeColumnIds: + + - 3 + + storeColumnNames: + + - k + + unique: true + + useDeletePreservingEncoding: true + + version: 4 + + mutationId: 1 + + state: DELETE_ONLY + name: t + nextColumnId: 4 + - nextConstraintId: 2 + + nextConstraintId: 4 + nextFamilyId: 1 + - nextIndexId: 2 + + nextIndexId: 4 + nextMutationId: 1 + parentId: 100 + ... + - 3 + storeColumnNames: + - - j + + - crdb_internal_column_2_name_placeholder + - k + unique: true + ... + time: {} + unexposedParentSchemaId: 101 + - version: "2" + + version: "3" +upsert descriptor #105 + ... + createAsOfTime: + wallTime: "1640995200000000000" + + declarativeSchemaChangerState: + + authorization: + + userName: root + + currentStatuses: + + jobId: "1" + + nameMapping: + + id: 105 + + name: sq1 + + relevantStatements: + + - statement: + + redactedStatement: ALTER TABLE ‹defaultdb›.‹public›.‹t› DROP COLUMN ‹j› + + statement: ALTER TABLE t DROP COLUMN j + + statementTag: ALTER TABLE + + revertible: true + + targetRanks: + + targets: + formatVersion: 3 + id: 105 + ... + start: "1" + unexposedParentSchemaId: 101 + - version: "1" + + version: "2" +delete comment ColumnCommentType(objID: 104, subID: 2) +persist all catalog changes to storage +create job #1 (non-cancelable: false): "ALTER TABLE defaultdb.public.t DROP COLUMN j" + 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 + ... + version: 4 + mutationId: 1 + - state: DELETE_ONLY + + state: WRITE_ONLY + name: t + nextColumnId: 4 + ... + time: {} + unexposedParentSchemaId: 101 + - version: "3" + + version: "4" +upsert descriptor #105 + ... + start: "1" + 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 #104 +commit transaction #4 +begin transaction #5 +## PostCommitPhase stage 3 of 7 with 4 MutationType ops +upsert descriptor #104 + ... + version: 4 + mutationId: 1 + - state: BACKFILLING + + state: DELETE_ONLY + - direction: ADD + index: + ... + time: {} + unexposedParentSchemaId: 101 + - version: "4" + + version: "5" +upsert descriptor #105 + ... + start: "1" + 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 + ... + version: 4 + mutationId: 1 + - state: DELETE_ONLY + + state: MERGING + - direction: ADD + index: + ... + time: {} + unexposedParentSchemaId: 101 + - version: "5" + + version: "6" +upsert descriptor #105 + ... + start: "1" + 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 #104 +commit transaction #7 +begin transaction #8 +## PostCommitPhase stage 6 of 7 with 5 MutationType ops +upsert descriptor #104 + ... + version: 4 + mutationId: 1 + - state: MERGING + - - direction: ADD + + state: WRITE_ONLY + + - direction: DROP + index: + constraintId: 3 + ... + version: 4 + mutationId: 1 + - state: WRITE_ONLY + + state: DELETE_ONLY + name: t + nextColumnId: 4 + ... + time: {} + unexposedParentSchemaId: 101 + - version: "6" + + version: "7" +upsert descriptor #105 + ... + start: "1" + 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 #104 +commit transaction #9 +begin transaction #10 +## PostCommitNonRevertiblePhase stage 1 of 4 with 11 MutationType ops +upsert descriptor #104 + ... + statement: ALTER TABLE t DROP COLUMN j + statementTag: ALTER TABLE + - revertible: true + targetRanks: + targets: + ... + 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: {} + - storeColumnIds: + - - 3 + - storeColumnNames: + - - k + - unique: true + - version: 4 + - mutationId: 1 + - state: WRITE_ONLY + + 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: {} + storeColumnIds: + + - 2 + - 3 + storeColumnNames: + + - crdb_internal_column_2_name_placeholder + - k + unique: true + - useDeletePreservingEncoding: true + version: 4 + mutationId: 1 + - state: DELETE_ONLY + + state: WRITE_ONLY + name: t + nextColumnId: 4 + ... + parentId: 100 + primaryIndex: + - constraintId: 1 + - createdAtNanos: "1640995200000000000" + + constraintId: 2 + + createdExplicitly: true + encodingType: 1 + foreignKey: {} + geoConfig: {} + - id: 1 + + id: 2 + interleave: {} + keyColumnDirections: + ... + sharded: {} + storeColumnIds: + - - 2 + - 3 + storeColumnNames: + - - crdb_internal_column_2_name_placeholder + - k + unique: true + ... + time: {} + unexposedParentSchemaId: 101 + - version: "7" + + version: "8" +upsert descriptor #105 + ... + statement: ALTER TABLE t DROP COLUMN j + statementTag: ALTER TABLE + - revertible: true + targetRanks: + targets: + ... + start: "1" + unexposedParentSchemaId: 101 + - version: "6" + + version: "7" +persist all catalog changes to storage +update progress of schema change job #1: "PostCommitNonRevertiblePhase stage 2 of 4 with 4 MutationType ops pending" +set schema change job #1 to non-cancellable +commit transaction #10 +begin transaction #11 +## PostCommitNonRevertiblePhase stage 2 of 4 with 7 MutationType ops +upsert descriptor #104 + ... + version: 4 + mutationId: 1 + - state: WRITE_ONLY + + state: DELETE_ONLY + name: t + nextColumnId: 4 + ... + time: {} + unexposedParentSchemaId: 101 + - version: "8" + + version: "9" +upsert descriptor #105 + ... + start: "1" + unexposedParentSchemaId: 101 + - version: "7" + + version: "8" +persist all catalog changes to storage +update progress of schema change job #1: "PostCommitNonRevertiblePhase stage 3 of 4 with 12 MutationType ops pending" +commit transaction #11 +begin transaction #12 +## PostCommitNonRevertiblePhase stage 3 of 4 with 15 MutationType ops +delete object namespace entry {100 101 sq1} -> 105 +upsert descriptor #104 + ... + - columnIds: + - 1 + - - 2 + - 3 + columnNames: + - i + - - crdb_internal_column_2_name_placeholder + - k + name: primary + ... + id: 104 + modificationTime: {} + - mutations: + - - column: + - id: 2 + - name: crdb_internal_column_2_name_placeholder + - nullable: true + - ownsSequenceIds: + - - 105 + - type: + - family: IntFamily + - oid: 20 + - width: 64 + - 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 + - - 3 + - storeColumnNames: + - - crdb_internal_column_2_name_placeholder + - - k + - unique: true + - version: 4 + - mutationId: 1 + - state: DELETE_ONLY + + mutations: [] + name: t + nextColumnId: 4 + ... + time: {} + unexposedParentSchemaId: 101 + - version: "9" + + version: "10" +upsert descriptor #105 + ... + ownerTableId: 104 + start: "1" + + state: DROP + 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 j" + descriptor IDs: [104] +update progress of schema change job #1: "PostCommitNonRevertiblePhase stage 4 of 4 with 1 MutationType op pending" +commit transaction #12 +notified job registry to adopt jobs: [2] +begin transaction #13 +## PostCommitNonRevertiblePhase stage 4 of 4 with 4 MutationType ops +upsert descriptor #104 + ... + createAsOfTime: + wallTime: "1640995200000000000" + - declarativeSchemaChangerState: + - authorization: + - userName: root + - currentStatuses: + - jobId: "1" + - nameMapping: + - columns: + - "1": i + - "3": k + - "4294967294": tableoid + - "4294967295": crdb_internal_mvcc_timestamp + - families: + - "0": primary + - id: 104 + - indexes: + - "2": t_pkey + - name: t + - relevantStatements: + - - statement: + - redactedStatement: ALTER TABLE ‹defaultdb›.‹public›.‹t› DROP COLUMN ‹j› + - statement: ALTER TABLE t DROP COLUMN j + - statementTag: ALTER TABLE + - targetRanks: + - targets: + families: + - columnIds: + ... + time: {} + unexposedParentSchemaId: 101 + - version: "10" + + version: "11" +upsert descriptor #105 + ... + createAsOfTime: + wallTime: "1640995200000000000" + - declarativeSchemaChangerState: + - authorization: + - userName: root + - currentStatuses: + - jobId: "1" + - nameMapping: + - id: 105 + - name: sq1 + - relevantStatements: + - - statement: + - redactedStatement: ALTER TABLE ‹defaultdb›.‹public›.‹t› DROP COLUMN ‹j› + - statement: ALTER TABLE t DROP COLUMN j + - statementTag: ALTER TABLE + - targetRanks: + - targets: + formatVersion: 3 + id: 105 + ... + state: DROP + unexposedParentSchemaId: 101 + - version: "9" + + version: "10" +persist all catalog changes to storage +create job #3 (non-cancelable: true): "GC for ALTER TABLE defaultdb.public.t DROP COLUMN j" + 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: 104 +write *eventpb.FinishSchemaChange to event log: + sc: + descriptorId: 105 +commit transaction #13 +notified job registry to adopt jobs: [3] +# end PostCommitPhase diff --git a/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner__rollback_1_of_7.explain b/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner__rollback_1_of_7.explain new file mode 100644 index 000000000000..b492518725fe --- /dev/null +++ b/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner__rollback_1_of_7.explain @@ -0,0 +1,43 @@ +/* setup */ +CREATE TABLE t (i INT PRIMARY KEY, j INT, k int); +CREATE SEQUENCE sq1 OWNED BY t.j; +COMMENT ON TABLE t IS 't has a comment'; +COMMENT ON COLUMN t.j IS 'j has a comment'; +INSERT INTO t VALUES(-1); +INSERT INTO t VALUES(-2); +INSERT INTO t VALUES(-3); + +/* test */ +ALTER TABLE t DROP COLUMN j; +EXPLAIN (DDL) rollback at post-commit stage 1 of 7; +---- +Schema change plan for rolling back ALTER TABLE ‹defaultdb›.public.‹t› DROP COLUMN ‹j›; + └── PostCommitNonRevertiblePhase + └── Stage 1 of 1 in PostCommitNonRevertiblePhase + ├── 3 elements transitioning toward PUBLIC + │ ├── WRITE_ONLY → PUBLIC Column:{DescID: 104 (t), ColumnID: 2 (j+)} + │ ├── ABSENT → PUBLIC ColumnName:{DescID: 104 (t), Name: "j", ColumnID: 2 (j+)} + │ └── ABSENT → PUBLIC ColumnComment:{DescID: 104 (t), ColumnID: 2 (j+), Comment: "j has a comment"} + ├── 7 elements transitioning toward ABSENT + │ ├── BACKFILL_ONLY → ABSENT PrimaryIndex:{DescID: 104 (t), IndexID: 2 (t_pkey-), ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1 (t_pkey+)} + │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 1 (i), IndexID: 2 (t_pkey-)} + │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 3 (k), IndexID: 2 (t_pkey-)} + │ ├── PUBLIC → ABSENT IndexData:{DescID: 104 (t), IndexID: 2 (t_pkey-)} + │ ├── DELETE_ONLY → ABSENT TemporaryIndex:{DescID: 104 (t), IndexID: 3, ConstraintID: 3, SourceIndexID: 1 (t_pkey+)} + │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 1 (i), IndexID: 3} + │ └── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 3 (k), IndexID: 3} + └── 14 Mutation operations + ├── SetColumnName {"ColumnID":2,"Name":"j","TableID":104} + ├── UpsertColumnComment {"ColumnID":2,"Comment":"j has a comment","PGAttributeNum":2,"TableID":104} + ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":2,"TableID":104} + ├── RemoveColumnFromIndex {"ColumnID":3,"IndexID":2,"Kind":2,"TableID":104} + ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":3,"TableID":104} + ├── RemoveColumnFromIndex {"ColumnID":3,"IndexID":3,"Kind":2,"TableID":104} + ├── MakeWriteOnlyColumnPublic {"ColumnID":2,"TableID":104} + ├── RefreshStats {"TableID":104} + ├── MakeIndexAbsent {"IndexID":2,"TableID":104} + ├── CreateGCJobForIndex {"IndexID":2,"TableID":104} + ├── MakeIndexAbsent {"IndexID":3,"TableID":104} + ├── RemoveJobStateFromDescriptor {"DescriptorID":104} + ├── RemoveJobStateFromDescriptor {"DescriptorID":105} + └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"all stages compl..."} diff --git a/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner__rollback_2_of_7.explain b/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner__rollback_2_of_7.explain new file mode 100644 index 000000000000..d413c60c2da2 --- /dev/null +++ b/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner__rollback_2_of_7.explain @@ -0,0 +1,53 @@ +/* setup */ +CREATE TABLE t (i INT PRIMARY KEY, j INT, k int); +CREATE SEQUENCE sq1 OWNED BY t.j; +COMMENT ON TABLE t IS 't has a comment'; +COMMENT ON COLUMN t.j IS 'j has a comment'; +INSERT INTO t VALUES(-1); +INSERT INTO t VALUES(-2); +INSERT INTO t VALUES(-3); + +/* test */ +ALTER TABLE t DROP COLUMN j; +EXPLAIN (DDL) rollback at post-commit stage 2 of 7; +---- +Schema change plan for rolling back ALTER TABLE ‹defaultdb›.public.‹t› DROP COLUMN ‹j›; + └── PostCommitNonRevertiblePhase + ├── Stage 1 of 2 in PostCommitNonRevertiblePhase + │ ├── 3 elements transitioning toward PUBLIC + │ │ ├── WRITE_ONLY → PUBLIC Column:{DescID: 104 (t), ColumnID: 2 (j+)} + │ │ ├── ABSENT → PUBLIC ColumnName:{DescID: 104 (t), Name: "j", ColumnID: 2 (j+)} + │ │ └── ABSENT → PUBLIC ColumnComment:{DescID: 104 (t), ColumnID: 2 (j+), Comment: "j has a comment"} + │ ├── 6 elements transitioning toward ABSENT + │ │ ├── BACKFILL_ONLY → ABSENT PrimaryIndex:{DescID: 104 (t), IndexID: 2 (t_pkey-), ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1 (t_pkey+)} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 1 (i), IndexID: 2 (t_pkey-)} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 3 (k), IndexID: 2 (t_pkey-)} + │ │ ├── WRITE_ONLY → DELETE_ONLY TemporaryIndex:{DescID: 104 (t), IndexID: 3, ConstraintID: 3, SourceIndexID: 1 (t_pkey+)} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 1 (i), IndexID: 3} + │ │ └── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 3 (k), IndexID: 3} + │ └── 13 Mutation operations + │ ├── SetColumnName {"ColumnID":2,"Name":"j","TableID":104} + │ ├── UpsertColumnComment {"ColumnID":2,"Comment":"j has a comment","PGAttributeNum":2,"TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":2,"TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":3,"IndexID":2,"Kind":2,"TableID":104} + │ ├── MakeWriteOnlyIndexDeleteOnly {"IndexID":3,"TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":3,"TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":3,"IndexID":3,"Kind":2,"TableID":104} + │ ├── MakeWriteOnlyColumnPublic {"ColumnID":2,"TableID":104} + │ ├── RefreshStats {"TableID":104} + │ ├── MakeIndexAbsent {"IndexID":2,"TableID":104} + │ ├── 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: 104 (t), IndexID: 2 (t_pkey-)} + │ ├── DELETE_ONLY → ABSENT TemporaryIndex:{DescID: 104 (t), IndexID: 3, ConstraintID: 3, SourceIndexID: 1 (t_pkey+)} + │ └── PUBLIC → ABSENT IndexData:{DescID: 104 (t), IndexID: 3} + └── 6 Mutation operations + ├── CreateGCJobForIndex {"IndexID":2,"TableID":104} + ├── MakeIndexAbsent {"IndexID":3,"TableID":104} + ├── CreateGCJobForIndex {"IndexID":3,"TableID":104} + ├── RemoveJobStateFromDescriptor {"DescriptorID":104} + ├── RemoveJobStateFromDescriptor {"DescriptorID":105} + └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"all stages compl..."} diff --git a/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner__rollback_3_of_7.explain b/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner__rollback_3_of_7.explain new file mode 100644 index 000000000000..3599f40b4adf --- /dev/null +++ b/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner__rollback_3_of_7.explain @@ -0,0 +1,53 @@ +/* setup */ +CREATE TABLE t (i INT PRIMARY KEY, j INT, k int); +CREATE SEQUENCE sq1 OWNED BY t.j; +COMMENT ON TABLE t IS 't has a comment'; +COMMENT ON COLUMN t.j IS 'j has a comment'; +INSERT INTO t VALUES(-1); +INSERT INTO t VALUES(-2); +INSERT INTO t VALUES(-3); + +/* test */ +ALTER TABLE t DROP COLUMN j; +EXPLAIN (DDL) rollback at post-commit stage 3 of 7; +---- +Schema change plan for rolling back ALTER TABLE ‹defaultdb›.public.‹t› DROP COLUMN ‹j›; + └── PostCommitNonRevertiblePhase + ├── Stage 1 of 2 in PostCommitNonRevertiblePhase + │ ├── 3 elements transitioning toward PUBLIC + │ │ ├── WRITE_ONLY → PUBLIC Column:{DescID: 104 (t), ColumnID: 2 (j+)} + │ │ ├── ABSENT → PUBLIC ColumnName:{DescID: 104 (t), Name: "j", ColumnID: 2 (j+)} + │ │ └── ABSENT → PUBLIC ColumnComment:{DescID: 104 (t), ColumnID: 2 (j+), Comment: "j has a comment"} + │ ├── 6 elements transitioning toward ABSENT + │ │ ├── BACKFILL_ONLY → ABSENT PrimaryIndex:{DescID: 104 (t), IndexID: 2 (t_pkey-), ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1 (t_pkey+)} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 1 (i), IndexID: 2 (t_pkey-)} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 3 (k), IndexID: 2 (t_pkey-)} + │ │ ├── WRITE_ONLY → DELETE_ONLY TemporaryIndex:{DescID: 104 (t), IndexID: 3, ConstraintID: 3, SourceIndexID: 1 (t_pkey+)} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 1 (i), IndexID: 3} + │ │ └── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 3 (k), IndexID: 3} + │ └── 13 Mutation operations + │ ├── SetColumnName {"ColumnID":2,"Name":"j","TableID":104} + │ ├── UpsertColumnComment {"ColumnID":2,"Comment":"j has a comment","PGAttributeNum":2,"TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":2,"TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":3,"IndexID":2,"Kind":2,"TableID":104} + │ ├── MakeWriteOnlyIndexDeleteOnly {"IndexID":3,"TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":3,"TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":3,"IndexID":3,"Kind":2,"TableID":104} + │ ├── MakeWriteOnlyColumnPublic {"ColumnID":2,"TableID":104} + │ ├── RefreshStats {"TableID":104} + │ ├── MakeIndexAbsent {"IndexID":2,"TableID":104} + │ ├── 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: 104 (t), IndexID: 2 (t_pkey-)} + │ ├── DELETE_ONLY → ABSENT TemporaryIndex:{DescID: 104 (t), IndexID: 3, ConstraintID: 3, SourceIndexID: 1 (t_pkey+)} + │ └── PUBLIC → ABSENT IndexData:{DescID: 104 (t), IndexID: 3} + └── 6 Mutation operations + ├── CreateGCJobForIndex {"IndexID":2,"TableID":104} + ├── MakeIndexAbsent {"IndexID":3,"TableID":104} + ├── CreateGCJobForIndex {"IndexID":3,"TableID":104} + ├── RemoveJobStateFromDescriptor {"DescriptorID":104} + ├── RemoveJobStateFromDescriptor {"DescriptorID":105} + └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"all stages compl..."} diff --git a/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner__rollback_4_of_7.explain b/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner__rollback_4_of_7.explain new file mode 100644 index 000000000000..fc5064f94394 --- /dev/null +++ b/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner__rollback_4_of_7.explain @@ -0,0 +1,53 @@ +/* setup */ +CREATE TABLE t (i INT PRIMARY KEY, j INT, k int); +CREATE SEQUENCE sq1 OWNED BY t.j; +COMMENT ON TABLE t IS 't has a comment'; +COMMENT ON COLUMN t.j IS 'j has a comment'; +INSERT INTO t VALUES(-1); +INSERT INTO t VALUES(-2); +INSERT INTO t VALUES(-3); + +/* test */ +ALTER TABLE t DROP COLUMN j; +EXPLAIN (DDL) rollback at post-commit stage 4 of 7; +---- +Schema change plan for rolling back ALTER TABLE ‹defaultdb›.public.‹t› DROP COLUMN ‹j›; + └── PostCommitNonRevertiblePhase + ├── Stage 1 of 2 in PostCommitNonRevertiblePhase + │ ├── 3 elements transitioning toward PUBLIC + │ │ ├── WRITE_ONLY → PUBLIC Column:{DescID: 104 (t), ColumnID: 2 (j+)} + │ │ ├── ABSENT → PUBLIC ColumnName:{DescID: 104 (t), Name: "j", ColumnID: 2 (j+)} + │ │ └── ABSENT → PUBLIC ColumnComment:{DescID: 104 (t), ColumnID: 2 (j+), Comment: "j has a comment"} + │ ├── 6 elements transitioning toward ABSENT + │ │ ├── DELETE_ONLY → ABSENT PrimaryIndex:{DescID: 104 (t), IndexID: 2 (t_pkey-), ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1 (t_pkey+)} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 1 (i), IndexID: 2 (t_pkey-)} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 3 (k), IndexID: 2 (t_pkey-)} + │ │ ├── WRITE_ONLY → DELETE_ONLY TemporaryIndex:{DescID: 104 (t), IndexID: 3, ConstraintID: 3, SourceIndexID: 1 (t_pkey+)} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 1 (i), IndexID: 3} + │ │ └── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 3 (k), IndexID: 3} + │ └── 13 Mutation operations + │ ├── SetColumnName {"ColumnID":2,"Name":"j","TableID":104} + │ ├── UpsertColumnComment {"ColumnID":2,"Comment":"j has a comment","PGAttributeNum":2,"TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":2,"TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":3,"IndexID":2,"Kind":2,"TableID":104} + │ ├── MakeWriteOnlyIndexDeleteOnly {"IndexID":3,"TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":3,"TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":3,"IndexID":3,"Kind":2,"TableID":104} + │ ├── MakeWriteOnlyColumnPublic {"ColumnID":2,"TableID":104} + │ ├── RefreshStats {"TableID":104} + │ ├── MakeIndexAbsent {"IndexID":2,"TableID":104} + │ ├── 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: 104 (t), IndexID: 2 (t_pkey-)} + │ ├── DELETE_ONLY → ABSENT TemporaryIndex:{DescID: 104 (t), IndexID: 3, ConstraintID: 3, SourceIndexID: 1 (t_pkey+)} + │ └── PUBLIC → ABSENT IndexData:{DescID: 104 (t), IndexID: 3} + └── 6 Mutation operations + ├── CreateGCJobForIndex {"IndexID":2,"TableID":104} + ├── MakeIndexAbsent {"IndexID":3,"TableID":104} + ├── CreateGCJobForIndex {"IndexID":3,"TableID":104} + ├── RemoveJobStateFromDescriptor {"DescriptorID":104} + ├── RemoveJobStateFromDescriptor {"DescriptorID":105} + └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"all stages compl..."} diff --git a/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner__rollback_5_of_7.explain b/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner__rollback_5_of_7.explain new file mode 100644 index 000000000000..a5fa30c05a65 --- /dev/null +++ b/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner__rollback_5_of_7.explain @@ -0,0 +1,55 @@ +/* setup */ +CREATE TABLE t (i INT PRIMARY KEY, j INT, k int); +CREATE SEQUENCE sq1 OWNED BY t.j; +COMMENT ON TABLE t IS 't has a comment'; +COMMENT ON COLUMN t.j IS 'j has a comment'; +INSERT INTO t VALUES(-1); +INSERT INTO t VALUES(-2); +INSERT INTO t VALUES(-3); + +/* test */ +ALTER TABLE t DROP COLUMN j; +EXPLAIN (DDL) rollback at post-commit stage 5 of 7; +---- +Schema change plan for rolling back ALTER TABLE ‹defaultdb›.public.‹t› DROP COLUMN ‹j›; + └── PostCommitNonRevertiblePhase + ├── Stage 1 of 2 in PostCommitNonRevertiblePhase + │ ├── 3 elements transitioning toward PUBLIC + │ │ ├── WRITE_ONLY → PUBLIC Column:{DescID: 104 (t), ColumnID: 2 (j+)} + │ │ ├── ABSENT → PUBLIC ColumnName:{DescID: 104 (t), Name: "j", ColumnID: 2 (j+)} + │ │ └── ABSENT → PUBLIC ColumnComment:{DescID: 104 (t), ColumnID: 2 (j+), Comment: "j has a comment"} + │ ├── 6 elements transitioning toward ABSENT + │ │ ├── MERGE_ONLY → DELETE_ONLY PrimaryIndex:{DescID: 104 (t), IndexID: 2 (t_pkey-), ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1 (t_pkey+)} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 1 (i), IndexID: 2 (t_pkey-)} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 3 (k), IndexID: 2 (t_pkey-)} + │ │ ├── WRITE_ONLY → DELETE_ONLY TemporaryIndex:{DescID: 104 (t), IndexID: 3, ConstraintID: 3, SourceIndexID: 1 (t_pkey+)} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 1 (i), IndexID: 3} + │ │ └── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 3 (k), IndexID: 3} + │ └── 13 Mutation operations + │ ├── SetColumnName {"ColumnID":2,"Name":"j","TableID":104} + │ ├── UpsertColumnComment {"ColumnID":2,"Comment":"j has a comment","PGAttributeNum":2,"TableID":104} + │ ├── MakeWriteOnlyIndexDeleteOnly {"IndexID":3,"TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":3,"TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":3,"IndexID":3,"Kind":2,"TableID":104} + │ ├── MakeWriteOnlyColumnPublic {"ColumnID":2,"TableID":104} + │ ├── RefreshStats {"TableID":104} + │ ├── MakeWriteOnlyIndexDeleteOnly {"IndexID":2,"TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":2,"TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":3,"IndexID":2,"Kind":2,"TableID":104} + │ ├── 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: 104 (t), IndexID: 2 (t_pkey-), ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1 (t_pkey+)} + │ ├── PUBLIC → ABSENT IndexData:{DescID: 104 (t), IndexID: 2 (t_pkey-)} + │ ├── DELETE_ONLY → ABSENT TemporaryIndex:{DescID: 104 (t), IndexID: 3, ConstraintID: 3, SourceIndexID: 1 (t_pkey+)} + │ └── PUBLIC → ABSENT IndexData:{DescID: 104 (t), IndexID: 3} + └── 7 Mutation operations + ├── MakeIndexAbsent {"IndexID":2,"TableID":104} + ├── CreateGCJobForIndex {"IndexID":2,"TableID":104} + ├── MakeIndexAbsent {"IndexID":3,"TableID":104} + ├── CreateGCJobForIndex {"IndexID":3,"TableID":104} + ├── RemoveJobStateFromDescriptor {"DescriptorID":104} + ├── RemoveJobStateFromDescriptor {"DescriptorID":105} + └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"all stages compl..."} diff --git a/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner__rollback_6_of_7.explain b/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner__rollback_6_of_7.explain new file mode 100644 index 000000000000..d1b51055cf20 --- /dev/null +++ b/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner__rollback_6_of_7.explain @@ -0,0 +1,55 @@ +/* setup */ +CREATE TABLE t (i INT PRIMARY KEY, j INT, k int); +CREATE SEQUENCE sq1 OWNED BY t.j; +COMMENT ON TABLE t IS 't has a comment'; +COMMENT ON COLUMN t.j IS 'j has a comment'; +INSERT INTO t VALUES(-1); +INSERT INTO t VALUES(-2); +INSERT INTO t VALUES(-3); + +/* test */ +ALTER TABLE t DROP COLUMN j; +EXPLAIN (DDL) rollback at post-commit stage 6 of 7; +---- +Schema change plan for rolling back ALTER TABLE ‹defaultdb›.public.‹t› DROP COLUMN ‹j›; + └── PostCommitNonRevertiblePhase + ├── Stage 1 of 2 in PostCommitNonRevertiblePhase + │ ├── 3 elements transitioning toward PUBLIC + │ │ ├── WRITE_ONLY → PUBLIC Column:{DescID: 104 (t), ColumnID: 2 (j+)} + │ │ ├── ABSENT → PUBLIC ColumnName:{DescID: 104 (t), Name: "j", ColumnID: 2 (j+)} + │ │ └── ABSENT → PUBLIC ColumnComment:{DescID: 104 (t), ColumnID: 2 (j+), Comment: "j has a comment"} + │ ├── 6 elements transitioning toward ABSENT + │ │ ├── MERGE_ONLY → DELETE_ONLY PrimaryIndex:{DescID: 104 (t), IndexID: 2 (t_pkey-), ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1 (t_pkey+)} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 1 (i), IndexID: 2 (t_pkey-)} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 3 (k), IndexID: 2 (t_pkey-)} + │ │ ├── WRITE_ONLY → DELETE_ONLY TemporaryIndex:{DescID: 104 (t), IndexID: 3, ConstraintID: 3, SourceIndexID: 1 (t_pkey+)} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 1 (i), IndexID: 3} + │ │ └── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 3 (k), IndexID: 3} + │ └── 13 Mutation operations + │ ├── SetColumnName {"ColumnID":2,"Name":"j","TableID":104} + │ ├── UpsertColumnComment {"ColumnID":2,"Comment":"j has a comment","PGAttributeNum":2,"TableID":104} + │ ├── MakeWriteOnlyIndexDeleteOnly {"IndexID":3,"TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":3,"TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":3,"IndexID":3,"Kind":2,"TableID":104} + │ ├── MakeWriteOnlyColumnPublic {"ColumnID":2,"TableID":104} + │ ├── RefreshStats {"TableID":104} + │ ├── MakeWriteOnlyIndexDeleteOnly {"IndexID":2,"TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":2,"TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":3,"IndexID":2,"Kind":2,"TableID":104} + │ ├── 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: 104 (t), IndexID: 2 (t_pkey-), ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1 (t_pkey+)} + │ ├── PUBLIC → ABSENT IndexData:{DescID: 104 (t), IndexID: 2 (t_pkey-)} + │ ├── DELETE_ONLY → ABSENT TemporaryIndex:{DescID: 104 (t), IndexID: 3, ConstraintID: 3, SourceIndexID: 1 (t_pkey+)} + │ └── PUBLIC → ABSENT IndexData:{DescID: 104 (t), IndexID: 3} + └── 7 Mutation operations + ├── MakeIndexAbsent {"IndexID":2,"TableID":104} + ├── CreateGCJobForIndex {"IndexID":2,"TableID":104} + ├── MakeIndexAbsent {"IndexID":3,"TableID":104} + ├── CreateGCJobForIndex {"IndexID":3,"TableID":104} + ├── RemoveJobStateFromDescriptor {"DescriptorID":104} + ├── RemoveJobStateFromDescriptor {"DescriptorID":105} + └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"all stages compl..."} diff --git a/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner__rollback_7_of_7.explain b/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner__rollback_7_of_7.explain new file mode 100644 index 000000000000..36246851cdda --- /dev/null +++ b/pkg/sql/schemachanger/testdata/end_to_end/drop_column_sequence_owner/drop_column_sequence_owner__rollback_7_of_7.explain @@ -0,0 +1,53 @@ +/* setup */ +CREATE TABLE t (i INT PRIMARY KEY, j INT, k int); +CREATE SEQUENCE sq1 OWNED BY t.j; +COMMENT ON TABLE t IS 't has a comment'; +COMMENT ON COLUMN t.j IS 'j has a comment'; +INSERT INTO t VALUES(-1); +INSERT INTO t VALUES(-2); +INSERT INTO t VALUES(-3); + +/* test */ +ALTER TABLE t DROP COLUMN j; +EXPLAIN (DDL) rollback at post-commit stage 7 of 7; +---- +Schema change plan for rolling back ALTER TABLE ‹defaultdb›.public.‹t› DROP COLUMN ‹j›; + └── PostCommitNonRevertiblePhase + ├── Stage 1 of 2 in PostCommitNonRevertiblePhase + │ ├── 3 elements transitioning toward PUBLIC + │ │ ├── WRITE_ONLY → PUBLIC Column:{DescID: 104 (t), ColumnID: 2 (j+)} + │ │ ├── ABSENT → PUBLIC ColumnName:{DescID: 104 (t), Name: "j", ColumnID: 2 (j+)} + │ │ └── ABSENT → PUBLIC ColumnComment:{DescID: 104 (t), ColumnID: 2 (j+), Comment: "j has a comment"} + │ ├── 6 elements transitioning toward ABSENT + │ │ ├── WRITE_ONLY → DELETE_ONLY PrimaryIndex:{DescID: 104 (t), IndexID: 2 (t_pkey-), ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1 (t_pkey+)} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 1 (i), IndexID: 2 (t_pkey-)} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 3 (k), IndexID: 2 (t_pkey-)} + │ │ ├── TRANSIENT_DELETE_ONLY → ABSENT TemporaryIndex:{DescID: 104 (t), IndexID: 3, ConstraintID: 3, SourceIndexID: 1 (t_pkey+)} + │ │ ├── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 1 (i), IndexID: 3} + │ │ └── PUBLIC → ABSENT IndexColumn:{DescID: 104 (t), ColumnID: 3 (k), IndexID: 3} + │ └── 13 Mutation operations + │ ├── SetColumnName {"ColumnID":2,"Name":"j","TableID":104} + │ ├── UpsertColumnComment {"ColumnID":2,"Comment":"j has a comment","PGAttributeNum":2,"TableID":104} + │ ├── MakeWriteOnlyIndexDeleteOnly {"IndexID":2,"TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":2,"TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":3,"IndexID":2,"Kind":2,"TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":1,"IndexID":3,"TableID":104} + │ ├── RemoveColumnFromIndex {"ColumnID":3,"IndexID":3,"Kind":2,"TableID":104} + │ ├── MakeWriteOnlyColumnPublic {"ColumnID":2,"TableID":104} + │ ├── RefreshStats {"TableID":104} + │ ├── MakeIndexAbsent {"IndexID":3,"TableID":104} + │ ├── SetJobStateOnDescriptor {"DescriptorID":104} + │ ├── SetJobStateOnDescriptor {"DescriptorID":105} + │ └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"PostCommitNonRev..."} + └── Stage 2 of 2 in PostCommitNonRevertiblePhase + ├── 3 elements transitioning toward ABSENT + │ ├── DELETE_ONLY → ABSENT PrimaryIndex:{DescID: 104 (t), IndexID: 2 (t_pkey-), ConstraintID: 2, TemporaryIndexID: 3, SourceIndexID: 1 (t_pkey+)} + │ ├── PUBLIC → ABSENT IndexData:{DescID: 104 (t), IndexID: 2 (t_pkey-)} + │ └── PUBLIC → ABSENT IndexData:{DescID: 104 (t), IndexID: 3} + └── 6 Mutation operations + ├── MakeIndexAbsent {"IndexID":2,"TableID":104} + ├── CreateGCJobForIndex {"IndexID":2,"TableID":104} + ├── CreateGCJobForIndex {"IndexID":3,"TableID":104} + ├── RemoveJobStateFromDescriptor {"DescriptorID":104} + ├── RemoveJobStateFromDescriptor {"DescriptorID":105} + └── UpdateSchemaChangerJob {"IsNonCancelable":true,"RunningStatus":"all stages compl..."}