Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1tXl0Q-00DksE-0Q for pgsql-hackers@arkaria.postgresql.org; Tue, 14 Jan 2025 17:47:10 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1tXl0O-002avr-N1 for pgsql-hackers@arkaria.postgresql.org; Tue, 14 Jan 2025 17:47:09 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1tXl0O-002avj-0f for pgsql-hackers@lists.postgresql.org; Tue, 14 Jan 2025 17:47:08 +0000 Received: from fhigh-a4-smtp.messagingengine.com ([103.168.172.155]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tXl0L-000Ofz-0c for pgsql-hackers@postgresql.org; Tue, 14 Jan 2025 17:47:08 +0000 Received: from phl-compute-01.internal (phl-compute-01.phl.internal [10.202.2.41]) by mailfhigh.phl.internal (Postfix) with ESMTP id 0B08011400F6; Tue, 14 Jan 2025 12:47:03 -0500 (EST) Received: from phl-mailfrontend-01 ([10.202.2.162]) by phl-compute-01.internal (MEProxy); Tue, 14 Jan 2025 12:47:03 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:content-type:date:date:feedback-id:feedback-id :from:from:in-reply-to:in-reply-to:message-id:mime-version :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm2; t=1736876823; x=1736963223; bh=x gZxqDAXXR3u5Pe/OrJaNbnYEdQqibh4bChm3QgmaWI=; b=Hyzb9tNVYFVDqI2gQ NP/zIFNiGY3QnpdblEMaPc1OGHlLFpjAIHrwFVTegifPBNg3eq0vRC0N2g94JEJG AdTKIK3dU/MwQQt9KKufgZmUsemYvLcmSm90/tZUORBZlDf+JflubTugkxhZ2/7O he+DQ79YSJf3hAE4sQI+LM4UDajE4Mo22980yZ+Z0XWyVe5E8ohc1anJc/BwRr7d 6hbQgBZAOnNYkH3uPYv6NQKsj53u3FjSocYJuq8P0L1WsCD56Iwnsd3BOtJykcDN Pqm5/pvQo5K3Pdh0/VFKGR+b+Ynza+mgWOxPHXpCt2VDqiVUrVk6L63aKa39oZ7L 1aIjA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefuddrudehiedguddtgecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpggftfghnshhusghstghrihgsvgdp uffrtefokffrpgfnqfghnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivg hnthhsucdlqddutddtmdenucfjughrpeffhffvvefukfggtggugfgjsehmkeerredttdej necuhfhrohhmpeetlhhvrghrohcujfgvrhhrvghrrgcuoegrlhhvhhgvrhhrvgesrghlvh hhrdhnohdqihhprdhorhhgqeenucggtffrrghtthgvrhhnpeegueehtdeiveffgfefvedu feefieelleekheefueeiieffkedtheeuudeijeetueenucffohhmrghinhepghhithhhuh gsrdgtohhmpdgvnhhtvghrphhrihhsvggusgdrtghomhenucevlhhushhtvghrufhiiigv pedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpegrlhhvhhgvrhhrvgesrghlvhhhrdhnoh dqihhprdhorhhgpdhnsggprhgtphhtthhopeefpdhmohguvgepshhmthhpohhuthdprhgt phhtthhopehjihgrnhdruhhnihhvvghrshgrlhhithihsehgmhgrihhlrdgtohhmpdhrtg hpthhtohephigrshhuohdrhhhonhgurgesghhmrghilhdrtghomhdprhgtphhtthhopehp ghhsqhhlqdhhrggtkhgvrhhssehpohhsthhgrhgvshhqlhdrohhrgh X-ME-Proxy: Feedback-ID: ia2694551:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 14 Jan 2025 12:47:02 -0500 (EST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alvh.no-ip.org; s=schmee; t=1736876819; bh=J/khIsqg00LUaPQR36O+9LR9ybp62OuPeU3oMrPZbOw=; h=Date:From:To:Cc:Subject:In-Reply-To:From; b=bpWxgKae67qizKN0Ic7JJpb1wvdqRedJkyQpUqxTiY6F3pZSmrMr3gssVNSUsKHZ/ MTvgKYErHbW/8NwG3XVu+OdnTwapto+8xC/1lIHLBDljU5+Csav8vv4Xykeuy/bD6J d359FrLrRpKma+DWF/wXph0Wx4z6W6ZiPTotCItkmj+nvXYWXVhMAjT9SB0xzxU9Rs 3KwSa1XP7txtoUdhVcs++tPuZCNDgYW9dnymP4HGrep6U1RNjcEgRi9hCx+iJUboTI fC8LwFkX8w2HKMvXk+qLGX64U4ujxsa9OnIKiwK+fJYv2e+dTb6KAnQPSSRLNSMCdq 4Ezhviixdkmmg== Received: by schmee.alvh.no-ip.org (Postfix, from userid 1000) id AF13A329; Tue, 14 Jan 2025 18:46:59 +0100 (CET) Date: Tue, 14 Jan 2025 18:46:59 +0100 From: Alvaro Herrera To: Yasuo Honda Cc: jian he , PostgreSQL-development Subject: Re: CREATE TABLE NOT VALID for check and foreign key Message-ID: <202501141746.ztgtjtjcehr3@alvherre.pgsql> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="wantdbmfjkbtd4yv" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <202501081336.5ntcq5oar24r@alvherre.pgsql> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --wantdbmfjkbtd4yv Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit On 2025-Jan-08, Alvaro Herrera wrote: > On 2025-Jan-07, Yasuo Honda wrote: > > > I'd like PostgreSQL to raise errors and/or warnings for the NOT VALID > > check constraint for CREATE TABLE. > > Ruby on Rails supports creating check constraints with the NOT VALID > > option and I was not aware that it is just ignored until > > https://github.com/rails/rails/issues/53732 issue is reported. > > Thanks. I left a comment there. I think raising a WARNING might work. I think it'd be something like the rough POC here. I didn't add warnings to all the CreateConstraintEntry() because some of them aren't reachable via a path that allows NOT VALID. However, I may have missed some cases. I was really surprised to find that we have no test coverage for the case where CREATE TABLE specifies a NOT VALID constraint. -- Álvaro Herrera 48°01'N 7°57'E — https://www.EnterpriseDB.com/ --wantdbmfjkbtd4yv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="0001-Throw-warning-if-NOT-VALID-is-given-during-CREATE-TA.patch" From 08dd8b9a65223dfb3662a509b9da54fcb8adb520 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Tue, 14 Jan 2025 18:43:47 +0100 Subject: [PATCH] Throw warning if NOT VALID is given during CREATE TABLE Discussion: https://postgr.es/m/CACJufxEQcHNhN6M18JY1mQcgQq9Gn9ofMeop47SdFDE5B8wbug@mail.gmail.com --- src/backend/catalog/heap.c | 8 ++++++++ src/backend/commands/tablecmds.c | 7 +++++++ src/backend/parser/gram.y | 2 ++ src/include/nodes/parsenodes.h | 1 + src/test/regress/expected/alter_table.out | 1 + src/test/regress/expected/foreign_key.out | 3 ++- src/test/regress/sql/foreign_key.sql | 2 +- 7 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 57ef466acce..8a39dc1c2da 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -2510,6 +2510,12 @@ AddRelationNewConstraints(Relation rel, checknames = lappend(checknames, ccname); } + /* XXX improve error report */ + if (cdef->was_not_valid && cdef->initially_valid && cdef->is_enforced) + ereport(WARNING, + errcode(ERRCODE_WARNING), + errmsg("NOT VALID flag for constraint \"%s\" ignored", ccname)); + /* * OK, store it. */ @@ -2967,6 +2973,8 @@ AddRelationNotNullConstraints(Relation rel, List *constraints, nnnames); nnnames = lappend(nnnames, conname); + /* XXX if NOT VALID is given during CREATE TABLE, throw warning */ + StoreRelNotNull(rel, conname, attnum, true, true, inhcount, constr->is_no_inherit); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index f070ffc960e..8e498344e7a 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -10446,6 +10446,13 @@ addFkConstraint(addFkConstraintSides fkside, connoinherit = rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE; } + /* XXX improve error report */ + if (fkconstraint->was_not_valid && fkconstraint->initially_valid) + ereport(WARNING, + errcode(ERRCODE_WARNING), + errmsg("NOT VALID flag for constraint \"%s\" ignored", + fkconstraint->conname)); + /* * Record the FK constraint in pg_constraint. */ diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 6079de70e09..c008a445bd4 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -4172,6 +4172,7 @@ ConstraintElem: NULL, NULL, &n->is_enforced, &n->skip_validation, &n->is_no_inherit, yyscanner); n->initially_valid = !n->skip_validation; + n->was_not_valid = n->skip_validation; $$ = (Node *) n; } | NOT NULL_P ColId ConstraintAttributeSpec @@ -4306,6 +4307,7 @@ ConstraintElem: NULL, &n->skip_validation, NULL, yyscanner); n->initially_valid = !n->skip_validation; + n->was_not_valid = n->skip_validation; $$ = (Node *) n; } ; diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index b191eaaecab..2f103238d8f 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -2762,6 +2762,7 @@ typedef struct Constraint bool is_enforced; /* enforced constraint? */ bool skip_validation; /* skip validation of existing rows? */ bool initially_valid; /* mark the new constraint as valid? */ + bool was_not_valid; /* did the user request NOT VALID? */ bool is_no_inherit; /* is constraint non-inheritable? */ Node *raw_expr; /* CHECK or DEFAULT expression, as * untransformed parse tree */ diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index dd8cdec2905..8b5918b9eb6 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -574,6 +574,7 @@ DROP TABLE attmp2; -- exclusion until validated set constraint_exclusion TO 'partition'; create table nv_parent (d date, check (false) no inherit not valid); +WARNING: NOT VALID flag for constraint "nv_parent_check" ignored -- not valid constraint added at creation time should automatically become valid \d nv_parent Table "public.nv_parent" diff --git a/src/test/regress/expected/foreign_key.out b/src/test/regress/expected/foreign_key.out index 3f459f70ac1..3b528738302 100644 --- a/src/test/regress/expected/foreign_key.out +++ b/src/test/regress/expected/foreign_key.out @@ -61,7 +61,8 @@ DROP TABLE PKTABLE; -- CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 text, PRIMARY KEY(ptest1, ptest2) ); CREATE TABLE FKTABLE ( ftest1 int, ftest2 int, ftest3 int, CONSTRAINT constrname FOREIGN KEY(ftest1, ftest2) - REFERENCES PKTABLE MATCH FULL ON DELETE SET NULL ON UPDATE SET NULL); + REFERENCES PKTABLE MATCH FULL ON DELETE SET NULL ON UPDATE SET NULL NOT VALID); +WARNING: NOT VALID flag for constraint "constrname" ignored -- Test comments COMMENT ON CONSTRAINT constrname_wrong ON FKTABLE IS 'fk constraint comment'; ERROR: constraint "constrname_wrong" for table "fktable" does not exist diff --git a/src/test/regress/sql/foreign_key.sql b/src/test/regress/sql/foreign_key.sql index 2e710e419c2..46a043e18e1 100644 --- a/src/test/regress/sql/foreign_key.sql +++ b/src/test/regress/sql/foreign_key.sql @@ -48,7 +48,7 @@ DROP TABLE PKTABLE; -- CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 text, PRIMARY KEY(ptest1, ptest2) ); CREATE TABLE FKTABLE ( ftest1 int, ftest2 int, ftest3 int, CONSTRAINT constrname FOREIGN KEY(ftest1, ftest2) - REFERENCES PKTABLE MATCH FULL ON DELETE SET NULL ON UPDATE SET NULL); + REFERENCES PKTABLE MATCH FULL ON DELETE SET NULL ON UPDATE SET NULL NOT VALID); -- Test comments COMMENT ON CONSTRAINT constrname_wrong ON FKTABLE IS 'fk constraint comment'; -- 2.39.5 --wantdbmfjkbtd4yv--