From e8b76c375d7fe5ec739e3eee0382dcec2051e504 Mon Sep 17 00:00:00 2001 From: Amul Sul Date: Wed, 16 Dec 2015 13:58:40 +0530 Subject: [PATCH] Make check constraint(s) valid at table creation even if NOT VALID option provided --- src/backend/catalog/heap.c | 2 +- src/backend/parser/gram.y | 2 ++ src/backend/parser/parse_utilcmd.c | 35 ++++++++++++++++++++++++++++++ src/test/regress/expected/create_table.out | 18 +++++++++++++++ src/test/regress/sql/create_table.sql | 11 ++++++++++ 5 files changed, 67 insertions(+), 1 deletion(-) diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 7d7d062..04c4f8f 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -2349,7 +2349,7 @@ AddRelationNewConstraints(Relation rel, * OK, store it. */ constrOid = - StoreRelCheck(rel, ccname, expr, !cdef->skip_validation, is_local, + StoreRelCheck(rel, ccname, expr, cdef->initially_valid, is_local, is_local ? 0 : 1, cdef->is_no_inherit, is_internal); numchecks++; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 7916df8..c4bed8a 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -3080,6 +3080,8 @@ ColConstraintElem: n->is_no_inherit = $5; n->raw_expr = $3; n->cooked_expr = NULL; + n->skip_validation = false; + n->initially_valid = true; $$ = (Node *)n; } | DEFAULT b_expr diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index 344a40c..566597b 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -120,6 +120,8 @@ static IndexStmt *transformIndexConstraint(Constraint *constraint, static void transformFKConstraints(CreateStmtContext *cxt, bool skipValidation, bool isAddConstraint); +static void transformCheckConstraints(CreateStmtContext *cxt, + bool skipValidation); static void transformConstraintAttrs(CreateStmtContext *cxt, List *constraintList); static void transformColumnType(CreateStmtContext *cxt, ColumnDef *column); @@ -320,6 +322,11 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString) transformFKConstraints(&cxt, true, false); /* + * Postprocess check constraints. + */ + transformCheckConstraints(&cxt, true); + + /* * Output results. */ stmt->tableElts = cxt.columns; @@ -1915,6 +1922,34 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt) } /* + * transformCheckConstraints + * handle CHECK constraints + */ +static void +transformCheckConstraints(CreateStmtContext *cxt, bool skipValidation) +{ + ListCell *ckclist; + + if (cxt->ckconstraints == NIL) + return; + /* + * If CREATE TABLE we can safely skip validation of check + * constraints, and nonetheless mark them valid. + * (This will override any user-supplied NOT VALID flag.) + */ + if (skipValidation) + { + foreach(ckclist, cxt->ckconstraints) + { + Constraint *constraint = (Constraint *) lfirst(ckclist); + + constraint->skip_validation = true; + constraint->initially_valid = true; + } + } +} + +/* * transformFKConstraints * handle FOREIGN KEY constraints */ diff --git a/src/test/regress/expected/create_table.out b/src/test/regress/expected/create_table.out index 41ceb87..8a73970 100644 --- a/src/test/regress/expected/create_table.out +++ b/src/test/regress/expected/create_table.out @@ -253,3 +253,21 @@ DROP TABLE as_select1; -- check that the oid column is added before the primary key is checked CREATE TABLE oid_pk (f1 INT, PRIMARY KEY(oid)) WITH OIDS; DROP TABLE oid_pk; +-- at table creation, override NOT VALID flag +CREATE TABLE foo (a SERIAL PRIMARY KEY); +CREATE TABLE bar (a INT, + FOREIGN KEY(a) REFERENCES foo NOT VALID, + CHECK(a != 0) NOT VALID); +\d bar + Table "public.bar" + Column | Type | Modifiers +--------+---------+----------- + a | integer | +Check constraints: + "bar_a_check" CHECK (a <> 0) +Foreign-key constraints: + "bar_a_fkey" FOREIGN KEY (a) REFERENCES foo(a) + +--cleanup +DROP TABLE bar; +DROP TABLE foo; diff --git a/src/test/regress/sql/create_table.sql b/src/test/regress/sql/create_table.sql index 78bdc8b..3fb1675 100644 --- a/src/test/regress/sql/create_table.sql +++ b/src/test/regress/sql/create_table.sql @@ -269,3 +269,14 @@ DROP TABLE as_select1; -- check that the oid column is added before the primary key is checked CREATE TABLE oid_pk (f1 INT, PRIMARY KEY(oid)) WITH OIDS; DROP TABLE oid_pk; + +-- at table creation, override NOT VALID flag +CREATE TABLE foo (a SERIAL PRIMARY KEY); + +CREATE TABLE bar (a INT, + FOREIGN KEY(a) REFERENCES foo NOT VALID, + CHECK(a != 0) NOT VALID); +\d bar +--cleanup +DROP TABLE bar; +DROP TABLE foo; -- 2.6.2