From d322f9e38241731a33dcfc9c9ebb2eb871f0c8e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emel=20=C5=9Eim=C5=9Fek?= Date: Thu, 12 Jan 2023 12:32:38 +0300 Subject: [PATCH] Handle DEFERRABLE option for the relevant constraints at deparser. (#6613) Table Constraints UNIQUE, PRIMARY KEY and EXCLUDE may have option DEFERRABLE in their command syntax. This PR handles the option when deparsing the relevant constraint statements. NOT DEFERRABLE and INITIALLY IMMEDIATE (if DEFERRABLE} are the default values for the option so we only append the non-default values to the alter table statement. --- .../deparser/deparse_table_stmts.c | 10 +++ ...ter_table_add_constraints_without_name.out | 75 +++++++++++++++++++ ...ter_table_add_constraints_without_name.sql | 58 ++++++++++++++ 3 files changed, 143 insertions(+) diff --git a/src/backend/distributed/deparser/deparse_table_stmts.c b/src/backend/distributed/deparser/deparse_table_stmts.c index c4cb7d4c2..5cd810f52 100644 --- a/src/backend/distributed/deparser/deparse_table_stmts.c +++ b/src/backend/distributed/deparser/deparse_table_stmts.c @@ -229,6 +229,16 @@ AppendAlterTableCmdAddConstraint(StringInfo buf, Constraint *constraint) appendStringInfoString(buf, " )"); } + + if (constraint->deferrable) + { + appendStringInfoString(buf, " DEFERRABLE"); + + if (constraint->initdeferred) + { + appendStringInfoString(buf, " INITIALLY DEFERRED"); + } + } } diff --git a/src/test/regress/expected/multi_alter_table_add_constraints_without_name.out b/src/test/regress/expected/multi_alter_table_add_constraints_without_name.out index d0602b5a7..3c1cd64c7 100644 --- a/src/test/regress/expected/multi_alter_table_add_constraints_without_name.out +++ b/src/test/regress/expected/multi_alter_table_add_constraints_without_name.out @@ -42,6 +42,31 @@ SELECT con.conname products_pkey_5410000 (1 row) +\c - - :master_host :master_port +ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_pkey; +-- Check "ADD PRIMARY KEY DEFERRABLE" +ALTER TABLE AT_AddConstNoName.products ADD PRIMARY KEY(product_no) DEFERRABLE; +\c - - :public_worker_1_host :worker_1_port +SELECT conname, tgfoid::regproc, tgtype, tgdeferrable, tginitdeferred + FROM pg_trigger JOIN pg_constraint con ON con.oid = tgconstraint + WHERE tgrelid = 'AT_AddConstNoName.products_5410000'::regclass; + conname | tgfoid | tgtype | tgdeferrable | tginitdeferred +--------------------------------------------------------------------- + products_pkey_5410000 | unique_key_recheck | 21 | t | f +(1 row) + +\c - - :master_host :master_port +ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_pkey; +ALTER TABLE AT_AddConstNoName.products ADD PRIMARY KEY(product_no) DEFERRABLE INITIALLY DEFERRED; +\c - - :public_worker_1_host :worker_1_port +SELECT conname, tgfoid::regproc, tgtype, tgdeferrable, tginitdeferred + FROM pg_trigger JOIN pg_constraint con ON con.oid = tgconstraint + WHERE tgrelid = 'AT_AddConstNoName.products_5410000'::regclass; + conname | tgfoid | tgtype | tgdeferrable | tginitdeferred +--------------------------------------------------------------------- + products_pkey_5410000 | unique_key_recheck | 21 | t | t +(1 row) + \c - - :master_host :master_port ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_pkey; -- Check "ADD UNIQUE" @@ -129,6 +154,31 @@ SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15 ALTER TABLE AT_AddConstNoName.products ADD UNIQUE NULLS NOT DISTINCT (product_no, price); ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_product_no_price_key; \endif +-- Check "ADD UNIQUE ... DEFERRABLE" +ALTER TABLE AT_AddConstNoName.products ADD UNIQUE(product_no) INCLUDE(price) DEFERRABLE; +\c - - :public_worker_1_host :worker_1_port +SELECT conname, tgfoid::regproc, tgtype, tgdeferrable, tginitdeferred + FROM pg_trigger JOIN pg_constraint con ON con.oid = tgconstraint + WHERE tgrelid = 'AT_AddConstNoName.products_5410000'::regclass; + conname | tgfoid | tgtype | tgdeferrable | tginitdeferred +--------------------------------------------------------------------- + products_product_no_key_5410000 | unique_key_recheck | 21 | t | f +(1 row) + +\c - - :master_host :master_port +ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_product_no_key; +ALTER TABLE AT_AddConstNoName.products ADD UNIQUE(product_no) INCLUDE(price) DEFERRABLE INITIALLY DEFERRED; +\c - - :public_worker_1_host :worker_1_port +SELECT conname, tgfoid::regproc, tgtype, tgdeferrable, tginitdeferred + FROM pg_trigger JOIN pg_constraint con ON con.oid = tgconstraint + WHERE tgrelid = 'AT_AddConstNoName.products_5410000'::regclass; + conname | tgfoid | tgtype | tgdeferrable | tginitdeferred +--------------------------------------------------------------------- + products_product_no_key_5410000 | unique_key_recheck | 21 | t | t +(1 row) + +\c - - :master_host :master_port +ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_product_no_key; -- Check "ADD EXCLUDE" CREATE EXTENSION btree_gist; ALTER TABLE AT_AddConstNoName.products ADD EXCLUDE USING gist (name WITH <> , product_no WITH =); @@ -153,6 +203,31 @@ SELECT con.conname products_name_product_no_excl_5410000 (1 row) +\c - - :master_host :master_port +ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_name_product_no_excl; +-- Check "ADD EXCLUDE ... DEFERRABLE" +ALTER TABLE AT_AddConstNoName.products ADD EXCLUDE USING gist (name WITH <> , product_no WITH =) DEFERRABLE; +\c - - :public_worker_1_host :worker_1_port +SELECT conname, tgfoid::regproc, tgtype, tgdeferrable, tginitdeferred + FROM pg_trigger JOIN pg_constraint con ON con.oid = tgconstraint + WHERE tgrelid = 'AT_AddConstNoName.products_5410000'::regclass; + conname | tgfoid | tgtype | tgdeferrable | tginitdeferred +--------------------------------------------------------------------- + products_name_product_no_excl_5410000 | unique_key_recheck | 21 | t | f +(1 row) + +\c - - :master_host :master_port +ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_name_product_no_excl; +ALTER TABLE AT_AddConstNoName.products ADD EXCLUDE USING gist (name WITH <> , product_no WITH =) DEFERRABLE INITIALLY DEFERRED; +\c - - :public_worker_1_host :worker_1_port +SELECT conname, tgfoid::regproc, tgtype, tgdeferrable, tginitdeferred + FROM pg_trigger JOIN pg_constraint con ON con.oid = tgconstraint + WHERE tgrelid = 'AT_AddConstNoName.products_5410000'::regclass; + conname | tgfoid | tgtype | tgdeferrable | tginitdeferred +--------------------------------------------------------------------- + products_name_product_no_excl_5410000 | unique_key_recheck | 21 | t | t +(1 row) + \c - - :master_host :master_port ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_name_product_no_excl; DROP TABLE AT_AddConstNoName.products; diff --git a/src/test/regress/sql/multi_alter_table_add_constraints_without_name.sql b/src/test/regress/sql/multi_alter_table_add_constraints_without_name.sql index eb38fad8c..0f8263f7a 100644 --- a/src/test/regress/sql/multi_alter_table_add_constraints_without_name.sql +++ b/src/test/regress/sql/multi_alter_table_add_constraints_without_name.sql @@ -37,6 +37,25 @@ SELECT con.conname \c - - :master_host :master_port ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_pkey; +-- Check "ADD PRIMARY KEY DEFERRABLE" +ALTER TABLE AT_AddConstNoName.products ADD PRIMARY KEY(product_no) DEFERRABLE; +\c - - :public_worker_1_host :worker_1_port +SELECT conname, tgfoid::regproc, tgtype, tgdeferrable, tginitdeferred + FROM pg_trigger JOIN pg_constraint con ON con.oid = tgconstraint + WHERE tgrelid = 'AT_AddConstNoName.products_5410000'::regclass; + +\c - - :master_host :master_port +ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_pkey; + +ALTER TABLE AT_AddConstNoName.products ADD PRIMARY KEY(product_no) DEFERRABLE INITIALLY DEFERRED; +\c - - :public_worker_1_host :worker_1_port +SELECT conname, tgfoid::regproc, tgtype, tgdeferrable, tginitdeferred + FROM pg_trigger JOIN pg_constraint con ON con.oid = tgconstraint + WHERE tgrelid = 'AT_AddConstNoName.products_5410000'::regclass; + +\c - - :master_host :master_port +ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_pkey; + -- Check "ADD UNIQUE" ALTER TABLE AT_AddConstNoName.products ADD UNIQUE(product_no); @@ -106,6 +125,26 @@ ALTER TABLE AT_AddConstNoName.products ADD UNIQUE NULLS NOT DISTINCT (product_no ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_product_no_price_key; \endif +-- Check "ADD UNIQUE ... DEFERRABLE" +ALTER TABLE AT_AddConstNoName.products ADD UNIQUE(product_no) INCLUDE(price) DEFERRABLE; +\c - - :public_worker_1_host :worker_1_port +SELECT conname, tgfoid::regproc, tgtype, tgdeferrable, tginitdeferred + FROM pg_trigger JOIN pg_constraint con ON con.oid = tgconstraint + WHERE tgrelid = 'AT_AddConstNoName.products_5410000'::regclass; + +\c - - :master_host :master_port +ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_product_no_key; + +ALTER TABLE AT_AddConstNoName.products ADD UNIQUE(product_no) INCLUDE(price) DEFERRABLE INITIALLY DEFERRED; +\c - - :public_worker_1_host :worker_1_port +SELECT conname, tgfoid::regproc, tgtype, tgdeferrable, tginitdeferred + FROM pg_trigger JOIN pg_constraint con ON con.oid = tgconstraint + WHERE tgrelid = 'AT_AddConstNoName.products_5410000'::regclass; + +\c - - :master_host :master_port + +ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_product_no_key; + -- Check "ADD EXCLUDE" CREATE EXTENSION btree_gist; ALTER TABLE AT_AddConstNoName.products ADD EXCLUDE USING gist (name WITH <> , product_no WITH =); @@ -126,6 +165,25 @@ SELECT con.conname \c - - :master_host :master_port ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_name_product_no_excl; +-- Check "ADD EXCLUDE ... DEFERRABLE" +ALTER TABLE AT_AddConstNoName.products ADD EXCLUDE USING gist (name WITH <> , product_no WITH =) DEFERRABLE; +\c - - :public_worker_1_host :worker_1_port +SELECT conname, tgfoid::regproc, tgtype, tgdeferrable, tginitdeferred + FROM pg_trigger JOIN pg_constraint con ON con.oid = tgconstraint + WHERE tgrelid = 'AT_AddConstNoName.products_5410000'::regclass; + +\c - - :master_host :master_port +ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_name_product_no_excl; + +ALTER TABLE AT_AddConstNoName.products ADD EXCLUDE USING gist (name WITH <> , product_no WITH =) DEFERRABLE INITIALLY DEFERRED; +\c - - :public_worker_1_host :worker_1_port +SELECT conname, tgfoid::regproc, tgtype, tgdeferrable, tginitdeferred + FROM pg_trigger JOIN pg_constraint con ON con.oid = tgconstraint + WHERE tgrelid = 'AT_AddConstNoName.products_5410000'::regclass; + +\c - - :master_host :master_port +ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_name_product_no_excl; + DROP TABLE AT_AddConstNoName.products; -- Check "ADD PRIMARY KEY" with reference table