Skip to content

Commit

Permalink
sql: disallow adding column as primary key
Browse files Browse the repository at this point in the history
Previously, the behavior of ALTER TABLE ... ADD COLUMN ... PRIMARY KEY
was undefined. With the legacy schema changer, this statement would
appear to succeed, but it would break the new schema changer. This
commit changes this by returning an explicit error.

In the future, we should support this statement if the table's primary
key was originally the default rowid primary key (see #82735).

Fixes #81449

Release note: None
  • Loading branch information
Jason Chan committed Jun 13, 2022
1 parent d82ac30 commit 149137b
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 0 deletions.
4 changes: 4 additions & 0 deletions pkg/sql/alter_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,10 @@ func (n *alterTableNode) startExec(params runParams) error {
"UNIQUE WITHOUT INDEX constraint on the column",
)
}
if t.ColumnDef.PrimaryKey.IsPrimaryKey {
return pgerror.Newf(pgcode.InvalidColumnDefinition,
"multiple primary keys for table %q are not allowed", tn.Object())
}
var err error
params.p.runWithOptions(resolveFlags{contextDatabaseID: n.tableDesc.ParentID}, func() {
err = params.p.addColumnImpl(params, n, tn, n.tableDesc, t)
Expand Down
11 changes: 11 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/alter_table
Original file line number Diff line number Diff line change
Expand Up @@ -2593,3 +2593,14 @@ CREATE INDEX idx_j ON t_add_column_not_null (j);

statement ok
DROP TABLE t_add_column_not_null

subtest regression_81448

statement ok
CREATE TABLE t81448 (a INT PRIMARY KEY)

statement error pq: multiple primary keys for table "t81448" are not allowed
ALTER TABLE t81448 ADD COLUMN b INT PRIMARY KEY

statement ok
DROP TABLE t81448
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,19 @@ func alterTableAddColumn(
"UNIQUE WITHOUT INDEX constraint on the column",
))
}
if d.PrimaryKey.IsPrimaryKey {
publicTargets := b.QueryByID(tbl.TableID).Filter(
func(_ scpb.Status, target scpb.TargetStatus, _ scpb.Element) bool {
return target == scpb.ToPublic
},
)
_, _, primaryIdx := scpb.FindPrimaryIndex(publicTargets)
// TODO(#82735): support when primary key is implicit
if primaryIdx != nil {
panic(pgerror.Newf(pgcode.InvalidColumnDefinition,
"multiple primary keys for table %q are not allowed", tn.Object()))
}
}
if d.IsComputed() {
d.Computed.Expr = schemaexpr.MaybeRewriteComputedColumn(d.Computed.Expr, b.SessionData())
}
Expand Down

0 comments on commit 149137b

Please sign in to comment.