Skip to content

Commit f797fe4

Browse files
committed
sql: block ALTER TABLE of identity columns not backed by a sequence
Previously, identity columns not backed by sequences (e.g. SERIAL columns with serial_normalization=rowid) were not protected from ALTER operations that modified identity attributes. This could lead to assertion failures. This change adds checks to block such ALTER TABLE statements. Fixes #147488 Fixes #146989 Epic: none Release note (bug fix): Prevented ALTER TABLE from modifying identity attributes on columns not backed by a sequence.
1 parent 838bcb1 commit f797fe4

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

pkg/sql/alter_table.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,8 +1226,14 @@ func applyColumnMutation(
12261226
col.GetName(), tableDesc.GetName())
12271227
}
12281228

1229-
// It is assumed that an identify column owns only one sequence.
1230-
if col.NumUsesSequences() != 1 {
1229+
numSeqs := col.NumUsesSequences()
1230+
if numSeqs == 0 {
1231+
// This can happen when a SERIAL column is created with IDENTITY and
1232+
// serial_normalization=rowid, meaning it doesn't use a real sequence.
1233+
return pgerror.Newf(pgcode.ObjectNotInPrerequisiteState,
1234+
"identity column %q of relation %q is not backed by a sequence",
1235+
col.GetName(), tableDesc.GetName())
1236+
} else if numSeqs > 1 {
12311237
return errors.AssertionFailedf(
12321238
"identity column %q of relation %q has %d sequences instead of 1",
12331239
col.GetName(), tableDesc.GetName(), col.NumUsesSequences())
@@ -1273,8 +1279,14 @@ func applyColumnMutation(
12731279
col.GetName(), tableDesc.GetName())
12741280
}
12751281

1276-
// It is assumed that an identify column owns only one sequence.
1277-
if col.NumUsesSequences() != 1 {
1282+
numSeqs := col.NumUsesSequences()
1283+
if numSeqs == 0 {
1284+
// This can happen when a SERIAL column is created with IDENTITY and
1285+
// serial_normalization=rowid, meaning it doesn't use a real sequence.
1286+
return pgerror.Newf(pgcode.ObjectNotInPrerequisiteState,
1287+
"identity column %q of relation %q is not backed by a sequence",
1288+
col.GetName(), tableDesc.GetName())
1289+
} else if numSeqs > 1 {
12781290
return errors.AssertionFailedf(
12791291
"identity column %q of relation %q has %d sequences instead of 1",
12801292
col.GetName(), tableDesc.GetName(), col.NumUsesSequences())

pkg/sql/logictest/testdata/logic_test/alter_table

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2313,6 +2313,14 @@ WHERE id = 't'::regclass::oid
23132313
----
23142314
GENERATED_ALWAYS
23152315

2316+
skipif config local-schema-locked
2317+
statement error pq: identity column "b" of relation "t" is not backed by a sequence
2318+
ALTER TABLE t ALTER COLUMN b DROP IDENTITY;
2319+
2320+
skipif config local-schema-locked
2321+
statement error pq: identity column "b" of relation "t" is not backed by a sequence
2322+
ALTER TABLE t ALTER COLUMN b SET CYCLE;
2323+
23162324
statement ok
23172325
DROP TABLE t;
23182326

0 commit comments

Comments
 (0)