From cacef172237fd3426b578f81b7414c0de56cbaaf Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 10 Mar 2020 14:54:00 -0400 Subject: [PATCH] Ensure that CREATE TABLE LIKE copies any NO INHERIT constraint property. Since the documentation about LIKE doesn't say that a copied constraint has properties different from the original, it seems that ignoring a NO INHERIT property doesn't meet the principle of least surprise. So make it copy that. (Note, however, that we still don't copy a NOT VALID property; CREATE TABLE offers no way to do that, plus it seems pointless.) Arguably this is a bug fix; but no back-patch, as it seems barely possible somebody is depending on the current behavior. Ildar Musin and Chris Travers; reviewed by Amit Langote and myself Discussion: https://postgr.es/m/CAONYFtMC6C+3AWCVp7Yd8H87Zn0GxG1_iQG6_bQKbaqYZY0=-g@mail.gmail.com --- src/backend/parser/parse_utilcmd.c | 11 +++++++---- src/test/regress/expected/create_table_like.out | 16 ++++++++++++++++ src/test/regress/sql/create_table_like.sql | 11 +++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index af77f1890f9..c1911411d0b 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -1133,12 +1133,14 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla if ((table_like_clause->options & CREATE_TABLE_LIKE_CONSTRAINTS) && tupleDesc->constr) { + TupleConstr *constr = tupleDesc->constr; int ccnum; - for (ccnum = 0; ccnum < tupleDesc->constr->num_check; ccnum++) + for (ccnum = 0; ccnum < constr->num_check; ccnum++) { - char *ccname = tupleDesc->constr->check[ccnum].ccname; - char *ccbin = tupleDesc->constr->check[ccnum].ccbin; + char *ccname = constr->check[ccnum].ccname; + char *ccbin = constr->check[ccnum].ccbin; + bool ccnoinherit = constr->check[ccnum].ccnoinherit; Constraint *n = makeNode(Constraint); Node *ccbin_node; bool found_whole_row; @@ -1163,8 +1165,9 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla RelationGetRelationName(relation)))); n->contype = CONSTR_CHECK; - n->location = -1; n->conname = pstrdup(ccname); + n->location = -1; + n->is_no_inherit = ccnoinherit; n->raw_expr = NULL; n->cooked_expr = nodeToString(ccbin_node); cxt->ckconstraints = lappend(cxt->ckconstraints, n); diff --git a/src/test/regress/expected/create_table_like.out b/src/test/regress/expected/create_table_like.out index 94d48582dba..f686606e423 100644 --- a/src/test/regress/expected/create_table_like.out +++ b/src/test/regress/expected/create_table_like.out @@ -388,6 +388,22 @@ ERROR: column "a" has a storage parameter conflict DETAIL: MAIN versus EXTENDED DROP TABLE ctlt1, ctlt2, ctlt3, ctlt4, ctlt12_storage, ctlt12_comments, ctlt1_inh, ctlt13_inh, ctlt13_like, ctlt_all, ctla, ctlb CASCADE; NOTICE: drop cascades to table inhe +-- LIKE must respect NO INHERIT property of constraints +CREATE TABLE noinh_con_copy (a int CHECK (a > 0) NO INHERIT); +CREATE TABLE noinh_con_copy1 (LIKE noinh_con_copy INCLUDING CONSTRAINTS); +\d noinh_con_copy1 + Table "public.noinh_con_copy1" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | | +Check constraints: + "noinh_con_copy_a_check" CHECK (a > 0) NO INHERIT + +-- fail, as partitioned tables don't allow NO INHERIT constraints +CREATE TABLE noinh_con_copy1_parted (LIKE noinh_con_copy INCLUDING ALL) + PARTITION BY LIST (a); +ERROR: cannot add NO INHERIT constraint to partitioned table "noinh_con_copy1_parted" +DROP TABLE noinh_con_copy, noinh_con_copy1; /* LIKE with other relation kinds */ CREATE TABLE ctlt4 (a int, b text); CREATE SEQUENCE ctlseq1; diff --git a/src/test/regress/sql/create_table_like.sql b/src/test/regress/sql/create_table_like.sql index 589ee12ebcf..afcb59b8970 100644 --- a/src/test/regress/sql/create_table_like.sql +++ b/src/test/regress/sql/create_table_like.sql @@ -151,6 +151,17 @@ CREATE TABLE inh_error2 (LIKE ctlt4 INCLUDING STORAGE) INHERITS (ctlt1); DROP TABLE ctlt1, ctlt2, ctlt3, ctlt4, ctlt12_storage, ctlt12_comments, ctlt1_inh, ctlt13_inh, ctlt13_like, ctlt_all, ctla, ctlb CASCADE; +-- LIKE must respect NO INHERIT property of constraints +CREATE TABLE noinh_con_copy (a int CHECK (a > 0) NO INHERIT); +CREATE TABLE noinh_con_copy1 (LIKE noinh_con_copy INCLUDING CONSTRAINTS); +\d noinh_con_copy1 + +-- fail, as partitioned tables don't allow NO INHERIT constraints +CREATE TABLE noinh_con_copy1_parted (LIKE noinh_con_copy INCLUDING ALL) + PARTITION BY LIST (a); + +DROP TABLE noinh_con_copy, noinh_con_copy1; + /* LIKE with other relation kinds */