diff --git a/pkg/sql/alter_table.go b/pkg/sql/alter_table.go index 632d33259018..3bc72b455e99 100644 --- a/pkg/sql/alter_table.go +++ b/pkg/sql/alter_table.go @@ -201,6 +201,12 @@ func (n *alterTableNode) startExec(params runParams) error { continue } + if d.Predicate != nil { + return pgerror.New(pgcode.InvalidTableDefinition, + "partial unique constraints cannot be added in ALTER TABLE, "+ + "use CREATE UNIQUE INDEX instead") + } + if d.PrimaryKey { // We only support "adding" a primary key when we are using the // default rowid primary index or if a DROP PRIMARY KEY statement diff --git a/pkg/sql/logictest/testdata/logic_test/alter_table b/pkg/sql/logictest/testdata/logic_test/alter_table index 8767e3b74e50..01eb0dc99033 100644 --- a/pkg/sql/logictest/testdata/logic_test/alter_table +++ b/pkg/sql/logictest/testdata/logic_test/alter_table @@ -1481,7 +1481,12 @@ ALTER TABLE unique_without_index ADD COLUMN f INT UNIQUE WITHOUT INDEX # constraint. statement ok ALTER TABLE unique_without_index ADD COLUMN f INT; -ALTER TABLE unique_without_index ADD CONSTRAINT my_unique_f UNIQUE WITHOUT INDEX (f); +ALTER TABLE unique_without_index ADD CONSTRAINT my_unique_f UNIQUE WITHOUT INDEX (f) + +# Partial predicates are allowed for UNIQUE WITHOUT INDEX, but not UNIQUE. +# TODO(mgartner): This is confusing, and something we should think more about +# if we ever make UNIQUE WITHOUT INDEX available by default. +statement ok ALTER TABLE unique_without_index ADD CONSTRAINT my_partial_unique_f UNIQUE WITHOUT INDEX (f) WHERE f > 0 # The unique constraint predicate must be valid. It cannot reference diff --git a/pkg/sql/logictest/testdata/logic_test/partial_index b/pkg/sql/logictest/testdata/logic_test/partial_index index a5a6c4260cf3..f904c7df3ad1 100644 --- a/pkg/sql/logictest/testdata/logic_test/partial_index +++ b/pkg/sql/logictest/testdata/logic_test/partial_index @@ -76,6 +76,14 @@ CREATE TABLE t4 (a INT, UNIQUE INDEX (a) WHERE a = 0) statement error expected index predicate expression to have type bool, but '1' has type int CREATE TABLE error (a INT, UNIQUE INDEX (a) WHERE 1) +# Disallow partial unique constraints in ALTER TABLE. + +statement ok +CREATE TABLE up (a INT) + +statement error partial unique constraints cannot be added in ALTER TABLE, use CREATE UNIQUE INDEX instead +ALTER TABLE up ADD CONSTRAINT partial_unique UNIQUE (a) WHERE a > 0 + # Validate CREATE INDEX predicate. statement ok diff --git a/pkg/sql/parser/sql.y b/pkg/sql/parser/sql.y index 98a360ae121e..b8f7f969e15b 100644 --- a/pkg/sql/parser/sql.y +++ b/pkg/sql/parser/sql.y @@ -6801,6 +6801,9 @@ constraint_elem: Expr: $3.expr(), } } +// TODO(mgartner): Postgres does not allow partial unique constraints. It only +// allows partial unique indexes. The opt_where_clause should be removed so that +// it is a syntax error. See discussion in #65825. | UNIQUE opt_without_index '(' index_params ')' opt_storing opt_interleave opt_partition_by_index opt_deferrable opt_where_clause {