From: Álvaro Herrera Date: Thu, 27 Mar 2025 08:24:52 +0000 (+0100) Subject: Simplify syntax for ALTER TABLE ALTER CONSTRAINT NO INHERIT X-Git-Tag: REL_18_BETA1~415 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4a02af8b1a5f3f8221c7381bc4de08a3d830f682;p=thirdparty%2Fpostgresql.git Simplify syntax for ALTER TABLE ALTER CONSTRAINT NO INHERIT Commit d45597f72fe5 introduced the ability to change a not-null constraint from NO INHERIT to INHERIT and vice versa, but we included the SET noise word in the syntax for it. The SET turns out not to be necessary and goes against what the SQL standard says for other ALTER TABLE subcommands, so remove it. This changes the way this command is processed for constraint types other than not-null, so there are some error message changes. Reviewed-by: Peter Eisentraut Reviewed-by: Suraj Kharage Discussion: https://postgr.es/m/202503251602.vsxaehsyaoac@alvherre.pgsql --- diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml index 4f15b89a98f..11d1bc7dbe1 100644 --- a/doc/src/sgml/ref/alter_table.sgml +++ b/doc/src/sgml/ref/alter_table.sgml @@ -59,7 +59,7 @@ ALTER TABLE [ IF EXISTS ] name ADD table_constraint [ NOT VALID ] ADD table_constraint_using_index ALTER CONSTRAINT constraint_name [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] - ALTER CONSTRAINT constraint_name SET [ INHERIT | NO INHERIT ] + ALTER CONSTRAINT constraint_name [ INHERIT | NO INHERIT ] VALIDATE CONSTRAINT constraint_name DROP CONSTRAINT [ IF EXISTS ] constraint_name [ RESTRICT | CASCADE ] DISABLE TRIGGER [ trigger_name | ALL | USER ] @@ -564,8 +564,8 @@ WITH ( MODULUS numeric_literal, REM - ALTER CONSTRAINT ... SET INHERIT - ALTER CONSTRAINT ... SET NO INHERIT + ALTER CONSTRAINT ... INHERIT + ALTER CONSTRAINT ... NO INHERIT These forms modify a inheritable constraint so that it becomes not diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 29ca7c9369c..afb25007613 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -12199,7 +12199,7 @@ ATExecAlterConstrInheritability(List **wqueue, ATAlterConstraint *cmdcon, colName = get_attname(currcon->conrelid, colNum, false); /* - * Propagate the change to children. For SET NO INHERIT, we don't + * Propagate the change to children. For this subcommand type we don't * recursively affect children, just the immediate level. */ children = find_inheritance_children(RelationGetRelid(rel), diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 271ae26cbaf..0fc502a3a40 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -2662,15 +2662,19 @@ alter_table_cmd: n->subtype = AT_AlterConstraint; n->def = (Node *) c; c->conname = $3; - c->alterDeferrability = true; + if ($4 & (CAS_DEFERRABLE | CAS_NOT_DEFERRABLE | + CAS_INITIALLY_DEFERRED | CAS_INITIALLY_IMMEDIATE)) + c->alterDeferrability = true; + if ($4 & CAS_NO_INHERIT) + c->alterInheritability = true; processCASbits($4, @4, "FOREIGN KEY", &c->deferrable, &c->initdeferred, - NULL, NULL, NULL, yyscanner); + NULL, NULL, &c->noinherit, yyscanner); $$ = (Node *) n; } - /* ALTER TABLE ALTER CONSTRAINT SET INHERIT */ - | ALTER CONSTRAINT name SET INHERIT + /* ALTER TABLE ALTER CONSTRAINT INHERIT */ + | ALTER CONSTRAINT name INHERIT { AlterTableCmd *n = makeNode(AlterTableCmd); ATAlterConstraint *c = makeNode(ATAlterConstraint); @@ -2681,20 +2685,6 @@ alter_table_cmd: c->alterInheritability = true; c->noinherit = false; - $$ = (Node *) n; - } - /* ALTER TABLE ALTER CONSTRAINT SET NO INHERIT */ - | ALTER CONSTRAINT name SET NO INHERIT - { - AlterTableCmd *n = makeNode(AlterTableCmd); - ATAlterConstraint *c = makeNode(ATAlterConstraint); - - n->subtype = AT_AlterConstraint; - n->def = (Node *) c; - c->conname = $3; - c->alterInheritability = true; - c->noinherit = true; - $$ = (Node *) n; } /* ALTER TABLE VALIDATE CONSTRAINT ... */ diff --git a/src/test/regress/expected/foreign_key.out b/src/test/regress/expected/foreign_key.out index 6a3374d5152..7f678349a8e 100644 --- a/src/test/regress/expected/foreign_key.out +++ b/src/test/regress/expected/foreign_key.out @@ -1284,9 +1284,7 @@ ERROR: constraint declared INITIALLY DEFERRED must be DEFERRABLE LINE 1: ...e ALTER CONSTRAINT fktable_fk_fkey NOT DEFERRABLE INITIALLY ... ^ ALTER TABLE fktable ALTER CONSTRAINT fktable_fk_fkey NO INHERIT; -ERROR: FOREIGN KEY constraints cannot be marked NO INHERIT -LINE 1: ...ER TABLE fktable ALTER CONSTRAINT fktable_fk_fkey NO INHERIT... - ^ +ERROR: constraint "fktable_fk_fkey" of relation "fktable" is not a not-null constraint ALTER TABLE fktable ALTER CONSTRAINT fktable_fk_fkey NOT VALID; ERROR: FOREIGN KEY constraints cannot be marked NOT VALID LINE 1: ...ER TABLE fktable ALTER CONSTRAINT fktable_fk_fkey NOT VALID; diff --git a/src/test/regress/expected/inherit.out b/src/test/regress/expected/inherit.out index e671975a281..58461e7f53f 100644 --- a/src/test/regress/expected/inherit.out +++ b/src/test/regress/expected/inherit.out @@ -2754,7 +2754,7 @@ alter table inh_nn2 inherit inh_nn1; create table inh_nn3 (f4 float) inherits (inh_nn2); create table inh_nn4 (f5 int, f4 float, f2 text, f3 int, f1 int); alter table inh_nn4 inherit inh_nn2, inherit inh_nn1, inherit inh_nn3; -alter table inh_nn1 alter constraint inh_nn1_f1_not_null set inherit; +alter table inh_nn1 alter constraint inh_nn1_f1_not_null inherit; select conrelid::regclass, conname, conkey, coninhcount, conislocal, connoinherit from pg_constraint where contype = 'n' and conrelid::regclass::text in ('inh_nn1', 'inh_nn2', 'inh_nn3', 'inh_nn4') @@ -2767,8 +2767,8 @@ select conrelid::regclass, conname, conkey, coninhcount, conislocal, connoinheri inh_nn4 | inh_nn1_f1_not_null | {5} | 3 | f | f (4 rows) --- ALTER CONSTRAINT SET NO INHERIT should work on top-level constraints -alter table inh_nn1 alter constraint inh_nn1_f1_not_null set no inherit; +-- ALTER CONSTRAINT NO INHERIT should work on top-level constraints +alter table inh_nn1 alter constraint inh_nn1_f1_not_null no inherit; select conrelid::regclass, conname, conkey, coninhcount, conislocal, connoinherit from pg_constraint where contype = 'n' and conrelid::regclass::text in ('inh_nn1', 'inh_nn2', 'inh_nn3', 'inh_nn4') @@ -2799,15 +2799,15 @@ drop table inh_nn1, inh_nn2, inh_nn3, inh_nn4; create table inh_nn1 (f1 int not null no inherit); create table inh_nn2 (f2 text, f3 int) inherits (inh_nn1); insert into inh_nn2 values(NULL, 'sample', 1); -alter table inh_nn1 alter constraint inh_nn1_f1_not_null set inherit; +alter table inh_nn1 alter constraint inh_nn1_f1_not_null inherit; ERROR: column "f1" of relation "inh_nn2" contains null values delete from inh_nn2; create table inh_nn3 () inherits (inh_nn2); create table inh_nn4 () inherits (inh_nn1, inh_nn2); NOTICE: merging multiple inherited definitions of column "f1" alter table inh_nn1 -- test multicommand alter table while at it - alter constraint inh_nn1_f1_not_null set inherit, - alter constraint inh_nn1_f1_not_null set no inherit; + alter constraint inh_nn1_f1_not_null inherit, + alter constraint inh_nn1_f1_not_null no inherit; select conrelid::regclass, conname, coninhcount, conislocal, connoinherit from pg_constraint where contype = 'n' and conrelid::regclass::text in ('inh_nn1', 'inh_nn2', 'inh_nn3', 'inh_nn4') @@ -2837,10 +2837,10 @@ select conrelid::regclass, conname, conkey, coninhcount, conislocal, connoinheri (2 rows) -- error: inh_nn3 has an incompatible NO INHERIT constraint -alter table inh_nn1 alter constraint inh_nn1_f1_not_null set inherit; +alter table inh_nn1 alter constraint inh_nn1_f1_not_null inherit; ERROR: cannot change NO INHERIT status of NOT NULL constraint "nn3_f1" on relation "inh_nn3" -alter table inh_nn3 alter constraint nn3_f1 set inherit; -alter table inh_nn1 alter constraint inh_nn1_f1_not_null set inherit; -- now it works +alter table inh_nn3 alter constraint nn3_f1 inherit; +alter table inh_nn1 alter constraint inh_nn1_f1_not_null inherit; -- now it works select conrelid::regclass, conname, conkey, coninhcount, conislocal, connoinherit from pg_constraint where contype = 'n' and conrelid::regclass::text in ('inh_nn1', 'inh_nn2', 'inh_nn3') @@ -2853,21 +2853,21 @@ select conrelid::regclass, conname, conkey, coninhcount, conislocal, connoinheri (3 rows) drop table inh_nn1, inh_nn2, inh_nn3; --- Negative scenarios for alter constraint .. set inherit. +-- Negative scenarios for alter constraint .. inherit. create table inh_nn1 (f1 int check(f1 > 5) primary key references inh_nn1, f2 int not null); -- constraints other than not-null are not supported -alter table inh_nn1 alter constraint inh_nn1_f1_check set inherit; +alter table inh_nn1 alter constraint inh_nn1_f1_check inherit; ERROR: constraint "inh_nn1_f1_check" of relation "inh_nn1" is not a not-null constraint -alter table inh_nn1 alter constraint inh_nn1_pkey set inherit; +alter table inh_nn1 alter constraint inh_nn1_pkey inherit; ERROR: constraint "inh_nn1_pkey" of relation "inh_nn1" is not a not-null constraint -alter table inh_nn1 alter constraint inh_nn1_f1_fkey set inherit; +alter table inh_nn1 alter constraint inh_nn1_f1_fkey inherit; ERROR: constraint "inh_nn1_f1_fkey" of relation "inh_nn1" is not a not-null constraint -- try to drop a nonexistant constraint -alter table inh_nn1 alter constraint foo set inherit; +alter table inh_nn1 alter constraint foo inherit; ERROR: constraint "foo" of relation "inh_nn1" does not exist -- Can't modify inheritability of inherited constraints create table inh_nn2 () inherits (inh_nn1); -alter table inh_nn2 alter constraint inh_nn1_f2_not_null set no inherit; +alter table inh_nn2 alter constraint inh_nn1_f2_not_null no inherit; ERROR: cannot alter inherited constraint "inh_nn1_f2_not_null" on relation "inh_nn2" drop table inh_nn1, inh_nn2; -- diff --git a/src/test/regress/sql/inherit.sql b/src/test/regress/sql/inherit.sql index 4e73c70495c..8df0f8af08a 100644 --- a/src/test/regress/sql/inherit.sql +++ b/src/test/regress/sql/inherit.sql @@ -1099,13 +1099,13 @@ alter table inh_nn2 inherit inh_nn1; create table inh_nn3 (f4 float) inherits (inh_nn2); create table inh_nn4 (f5 int, f4 float, f2 text, f3 int, f1 int); alter table inh_nn4 inherit inh_nn2, inherit inh_nn1, inherit inh_nn3; -alter table inh_nn1 alter constraint inh_nn1_f1_not_null set inherit; +alter table inh_nn1 alter constraint inh_nn1_f1_not_null inherit; select conrelid::regclass, conname, conkey, coninhcount, conislocal, connoinherit from pg_constraint where contype = 'n' and conrelid::regclass::text in ('inh_nn1', 'inh_nn2', 'inh_nn3', 'inh_nn4') order by 2, 1; --- ALTER CONSTRAINT SET NO INHERIT should work on top-level constraints -alter table inh_nn1 alter constraint inh_nn1_f1_not_null set no inherit; +-- ALTER CONSTRAINT NO INHERIT should work on top-level constraints +alter table inh_nn1 alter constraint inh_nn1_f1_not_null no inherit; select conrelid::regclass, conname, conkey, coninhcount, conislocal, connoinherit from pg_constraint where contype = 'n' and conrelid::regclass::text in ('inh_nn1', 'inh_nn2', 'inh_nn3', 'inh_nn4') @@ -1122,13 +1122,13 @@ drop table inh_nn1, inh_nn2, inh_nn3, inh_nn4; create table inh_nn1 (f1 int not null no inherit); create table inh_nn2 (f2 text, f3 int) inherits (inh_nn1); insert into inh_nn2 values(NULL, 'sample', 1); -alter table inh_nn1 alter constraint inh_nn1_f1_not_null set inherit; +alter table inh_nn1 alter constraint inh_nn1_f1_not_null inherit; delete from inh_nn2; create table inh_nn3 () inherits (inh_nn2); create table inh_nn4 () inherits (inh_nn1, inh_nn2); alter table inh_nn1 -- test multicommand alter table while at it - alter constraint inh_nn1_f1_not_null set inherit, - alter constraint inh_nn1_f1_not_null set no inherit; + alter constraint inh_nn1_f1_not_null inherit, + alter constraint inh_nn1_f1_not_null no inherit; select conrelid::regclass, conname, coninhcount, conislocal, connoinherit from pg_constraint where contype = 'n' and conrelid::regclass::text in ('inh_nn1', 'inh_nn2', 'inh_nn3', 'inh_nn4') @@ -1144,26 +1144,26 @@ select conrelid::regclass, conname, conkey, coninhcount, conislocal, connoinheri conrelid::regclass::text in ('inh_nn1', 'inh_nn2', 'inh_nn3') order by 2, 1; -- error: inh_nn3 has an incompatible NO INHERIT constraint -alter table inh_nn1 alter constraint inh_nn1_f1_not_null set inherit; -alter table inh_nn3 alter constraint nn3_f1 set inherit; -alter table inh_nn1 alter constraint inh_nn1_f1_not_null set inherit; -- now it works +alter table inh_nn1 alter constraint inh_nn1_f1_not_null inherit; +alter table inh_nn3 alter constraint nn3_f1 inherit; +alter table inh_nn1 alter constraint inh_nn1_f1_not_null inherit; -- now it works select conrelid::regclass, conname, conkey, coninhcount, conislocal, connoinherit from pg_constraint where contype = 'n' and conrelid::regclass::text in ('inh_nn1', 'inh_nn2', 'inh_nn3') order by 2, 1; drop table inh_nn1, inh_nn2, inh_nn3; --- Negative scenarios for alter constraint .. set inherit. +-- Negative scenarios for alter constraint .. inherit. create table inh_nn1 (f1 int check(f1 > 5) primary key references inh_nn1, f2 int not null); -- constraints other than not-null are not supported -alter table inh_nn1 alter constraint inh_nn1_f1_check set inherit; -alter table inh_nn1 alter constraint inh_nn1_pkey set inherit; -alter table inh_nn1 alter constraint inh_nn1_f1_fkey set inherit; +alter table inh_nn1 alter constraint inh_nn1_f1_check inherit; +alter table inh_nn1 alter constraint inh_nn1_pkey inherit; +alter table inh_nn1 alter constraint inh_nn1_f1_fkey inherit; -- try to drop a nonexistant constraint -alter table inh_nn1 alter constraint foo set inherit; +alter table inh_nn1 alter constraint foo inherit; -- Can't modify inheritability of inherited constraints create table inh_nn2 () inherits (inh_nn1); -alter table inh_nn2 alter constraint inh_nn1_f2_not_null set no inherit; +alter table inh_nn2 alter constraint inh_nn1_f2_not_null no inherit; drop table inh_nn1, inh_nn2;