Propagates NOT VALID option for FK&CHECK constraints w/out a name (#6649)

Adds NOT VALID option to deparser. When we need to deparse:
  "ALTER TABLE ADD FOREIGN KEY ... NOT VALID"
  "ALTER TABLE ADD CHECK ... NOT VALID"
NOT VALID option should be propagated to workers.

Fixes issue #6646

This commit also uses AppendColumnNameList function
instead of repeated code blocks in two appropriate places
in the "ALTER TABLE" deparser.
pull/6647/head
Emel Şimşek 2023-01-25 20:41:04 +03:00 committed by GitHub
parent 94b63f35a5
commit 2169e0222b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 103 additions and 35 deletions

View File

@ -168,7 +168,7 @@ AppendAlterTableCmdAddConstraint(StringInfo buf, Constraint *constraint,
if (constraint->contype == CONSTR_PRIMARY) if (constraint->contype == CONSTR_PRIMARY)
{ {
appendStringInfoString(buf, appendStringInfoString(buf,
" PRIMARY KEY ("); " PRIMARY KEY ");
} }
else else
{ {
@ -180,44 +180,15 @@ AppendAlterTableCmdAddConstraint(StringInfo buf, Constraint *constraint,
appendStringInfoString(buf, " NULLS NOT DISTINCT"); appendStringInfoString(buf, " NULLS NOT DISTINCT");
} }
#endif #endif
appendStringInfoString(buf, " (");
} }
ListCell *lc; AppendColumnNameList(buf, constraint->keys);
bool firstkey = true;
foreach(lc, constraint->keys)
{
if (firstkey == false)
{
appendStringInfoString(buf, ", ");
}
appendStringInfo(buf, "%s", quote_identifier(strVal(lfirst(lc))));
firstkey = false;
}
appendStringInfoString(buf, ")");
if (constraint->including != NULL) if (constraint->including != NULL)
{ {
appendStringInfoString(buf, " INCLUDE ("); appendStringInfoString(buf, " INCLUDE ");
firstkey = true; AppendColumnNameList(buf, constraint->including);
foreach(lc, constraint->including)
{
if (firstkey == false)
{
appendStringInfoString(buf, ", ");
}
appendStringInfo(buf, "%s", quote_identifier(strVal(lfirst(
lc))));
firstkey = false;
}
appendStringInfoString(buf, " )");
} }
} }
else if (constraint->contype == CONSTR_EXCLUSION) else if (constraint->contype == CONSTR_EXCLUSION)
@ -404,6 +375,12 @@ AppendAlterTableCmdAddConstraint(StringInfo buf, Constraint *constraint,
} }
} }
/* FOREIGN KEY and CHECK constraints migth have NOT VALID option */
if (constraint->skip_validation)
{
appendStringInfoString(buf, " NOT VALID ");
}
if (constraint->deferrable) if (constraint->deferrable)
{ {
appendStringInfoString(buf, " DEFERRABLE"); appendStringInfoString(buf, " DEFERRABLE");

View File

@ -268,7 +268,7 @@ SELECT con.conname, con.connoinherit
(1 row) (1 row)
\c - - :public_worker_1_host :worker_1_port \c - - :public_worker_1_host :worker_1_port
SELECT con.conname, connoinherit SELECT con.conname, con.connoinherit
FROM pg_catalog.pg_constraint con FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
@ -278,6 +278,31 @@ SELECT con.conname, connoinherit
products_check_5410000 | t products_check_5410000 | t
(1 row) (1 row)
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_check;
-- Check "ADD CHECK ... NOT VALID"
ALTER TABLE AT_AddConstNoName.products ADD CHECK (product_no > 0 AND price > 0) NOT VALID;
SELECT con.conname, con.convalidated
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'products';
conname | convalidated
---------------------------------------------------------------------
products_check | f
(1 row)
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname, con.convalidated
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'products_5410000';
conname | convalidated
---------------------------------------------------------------------
products_check_5410000 | f
(1 row)
\c - - :master_host :master_port \c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_check; ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_check;
DROP TABLE AT_AddConstNoName.products; DROP TABLE AT_AddConstNoName.products;

View File

@ -248,6 +248,34 @@ SELECT con.conname, con.confupdtype, con.confdeltype, con.confmatchtype
referencing_table_ref_id_fkey_1770043 | a | c | s referencing_table_ref_id_fkey_1770043 | a | c | s
(3 rows) (3 rows)
\c - - :master_host :master_port
SET SEARCH_PATH = at_add_fk;
ALTER TABLE referencing_table DROP CONSTRAINT referencing_table_ref_id_fkey;
-- test NOT VALID
ALTER TABLE referencing_table ADD FOREIGN KEY(ref_id) REFERENCES referenced_table(id) NOT VALID;
SELECT con.conname, con.convalidated
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'referencing_table';
conname | convalidated
---------------------------------------------------------------------
referencing_table_ref_id_fkey | f
(1 row)
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname, con.convalidated
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'referencing_table%' ORDER BY con.conname ASC;
conname | convalidated
---------------------------------------------------------------------
referencing_table_ref_id_fkey | f
referencing_table_ref_id_fkey_1770041 | f
referencing_table_ref_id_fkey_1770043 | f
(3 rows)
\c - - :master_host :master_port \c - - :master_host :master_port
SET SEARCH_PATH = at_add_fk; SET SEARCH_PATH = at_add_fk;
ALTER TABLE referencing_table DROP CONSTRAINT referencing_table_ref_id_fkey; ALTER TABLE referencing_table DROP CONSTRAINT referencing_table_ref_id_fkey;

View File

@ -212,7 +212,26 @@ SELECT con.conname, con.connoinherit
WHERE rel.relname = 'products'; WHERE rel.relname = 'products';
\c - - :public_worker_1_host :worker_1_port \c - - :public_worker_1_host :worker_1_port
SELECT con.conname, connoinherit SELECT con.conname, con.connoinherit
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'products_5410000';
\c - - :master_host :master_port
ALTER TABLE AT_AddConstNoName.products DROP CONSTRAINT products_check;
-- Check "ADD CHECK ... NOT VALID"
ALTER TABLE AT_AddConstNoName.products ADD CHECK (product_no > 0 AND price > 0) NOT VALID;
SELECT con.conname, con.convalidated
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'products';
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname, con.convalidated
FROM pg_catalog.pg_constraint con FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace

View File

@ -154,6 +154,25 @@ SET SEARCH_PATH = at_add_fk;
ALTER TABLE referencing_table DROP CONSTRAINT referencing_table_ref_id_fkey; ALTER TABLE referencing_table DROP CONSTRAINT referencing_table_ref_id_fkey;
-- test NOT VALID
ALTER TABLE referencing_table ADD FOREIGN KEY(ref_id) REFERENCES referenced_table(id) NOT VALID;
SELECT con.conname, con.convalidated
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname = 'referencing_table';
\c - - :public_worker_1_host :worker_1_port
SELECT con.conname, con.convalidated
FROM pg_catalog.pg_constraint con
INNER JOIN pg_catalog.pg_class rel ON rel.oid = con.conrelid
INNER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = connamespace
WHERE rel.relname LIKE 'referencing_table%' ORDER BY con.conname ASC;
\c - - :master_host :master_port
SET SEARCH_PATH = at_add_fk;
ALTER TABLE referencing_table DROP CONSTRAINT referencing_table_ref_id_fkey;
-- test ON DELETE NO ACTION + DEFERABLE + INITIALLY DEFERRED -- test ON DELETE NO ACTION + DEFERABLE + INITIALLY DEFERRED
ALTER TABLE referencing_table ADD FOREIGN KEY(ref_id) REFERENCES referenced_table(id) ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED; ALTER TABLE referencing_table ADD FOREIGN KEY(ref_id) REFERENCES referenced_table(id) ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED;