Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1m1Xj2-0000wH-76 for pgsql-bugs@arkaria.postgresql.org; Thu, 08 Jul 2021 17:22:12 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1m1Xj0-00087Y-PO for pgsql-bugs@arkaria.postgresql.org; Thu, 08 Jul 2021 17:22:10 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1m1Xj0-00087F-IQ for pgsql-bugs@lists.postgresql.org; Thu, 08 Jul 2021 17:22:10 +0000 Received: from sss.pgh.pa.us ([66.207.139.130]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1m1Xiy-00086J-EZ for pgsql-bugs@lists.postgresql.org; Thu, 08 Jul 2021 17:22:09 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.15.2/8.15.2) with ESMTP id 168HM62I2032522; Thu, 8 Jul 2021 13:22:06 -0400 From: Tom Lane To: Richard Guo cc: cyg0810@gmail.com, PostgreSQL mailing lists Subject: Re: BUG #17094: FailedAssertion at planner.c In-reply-to: <1974959.1625761759@sss.pgh.pa.us> References: <17094-bf15dff55eaf2e28@postgresql.org> <1974959.1625761759@sss.pgh.pa.us> Comments: In-reply-to Tom Lane message dated "Thu, 08 Jul 2021 12:29:19 -0400" MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0" Content-ID: <2032511.1625764917.0@sss.pgh.pa.us> Date: Thu, 08 Jul 2021 13:22:06 -0400 Message-ID: <2032521.1625764926@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk ------- =_aaaaaaaaaa0 Content-Type: text/plain; charset="us-ascii" Content-ID: <2032511.1625764917.1@sss.pgh.pa.us> I wrote: > I'm inclined to think we have to reject cases like this. Concretely, about like this. I noticed that the adjacent error cases in RewriteQuery were mostly not covered either by the regression tests, so I added tests to hit them all. regards, tom lane ------- =_aaaaaaaaaa0 Content-Type: text/x-diff; name="tighten-rule-rewrite-in-WITH-restrictions.patch"; charset="us-ascii" Content-ID: <2032511.1625764917.2@sss.pgh.pa.us> Content-Description: tighten-rule-rewrite-in-WITH-restrictions.patch Content-Transfer-Encoding: quoted-printable diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/re= writeHandler.c index 88a9e95e33..54fd6d6fb2 100644 --- a/src/backend/rewrite/rewriteHandler.c +++ b/src/backend/rewrite/rewriteHandler.c @@ -3585,15 +3585,29 @@ RewriteQuery(Query *parsetree, List *rewrite_event= s) = /* * Currently we can only handle unconditional, single-statement DO - * INSTEAD rules correctly; we have to get exactly one Query out of - * the rewrite operation to stuff back into the CTE node. + * INSTEAD rules correctly; we have to get exactly one non-utility + * Query out of the rewrite operation to stuff back into the CTE node. */ if (list_length(newstuff) =3D=3D 1) { - /* Push the single Query back into the CTE node */ + /* Must check it's not a utility command */ ctequery =3D linitial_node(Query, newstuff); + if (!(ctequery->commandType =3D=3D CMD_SELECT || + ctequery->commandType =3D=3D CMD_UPDATE || + ctequery->commandType =3D=3D CMD_INSERT || + ctequery->commandType =3D=3D CMD_DELETE)) + { + /* + * Currently it could only be NOTIFY; this error message will + * need work if we ever allow other utility commands in rules. + */ + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("DO INSTEAD NOTIFY rules are not supported for data-modifyi= ng statements in WITH"))); + } /* WITH queries should never be canSetTag */ Assert(!ctequery->canSetTag); + /* Push the single Query back into the CTE node */ cte->ctequery =3D (Node *) ctequery; } else if (newstuff =3D=3D NIL) diff --git a/src/test/regress/expected/with.out b/src/test/regress/expecte= d/with.out index 584bdc6600..3523a7dcc1 100644 --- a/src/test/regress/expected/with.out +++ b/src/test/regress/expected/with.out @@ -2969,6 +2969,31 @@ WITH t AS ( ) VALUES(FALSE); ERROR: conditional DO INSTEAD rules are not supported for data-modifying= statements in WITH +CREATE OR REPLACE RULE y_rule AS ON INSERT TO y DO INSTEAD NOTHING; +WITH t AS ( + INSERT INTO y VALUES(0) +) +VALUES(FALSE); +ERROR: DO INSTEAD NOTHING rules are not supported for data-modifying sta= tements in WITH +CREATE OR REPLACE RULE y_rule AS ON INSERT TO y DO INSTEAD NOTIFY foo; +WITH t AS ( + INSERT INTO y VALUES(0) +) +VALUES(FALSE); +ERROR: DO INSTEAD NOTIFY rules are not supported for data-modifying stat= ements in WITH +CREATE OR REPLACE RULE y_rule AS ON INSERT TO y DO ALSO NOTIFY foo; +WITH t AS ( + INSERT INTO y VALUES(0) +) +VALUES(FALSE); +ERROR: DO ALSO rules are not supported for data-modifying statements in = WITH +CREATE OR REPLACE RULE y_rule AS ON INSERT TO y + DO INSTEAD (NOTIFY foo; NOTIFY bar); +WITH t AS ( + INSERT INTO y VALUES(0) +) +VALUES(FALSE); +ERROR: multi-statement DO INSTEAD rules are not supported for data-modif= ying statements in WITH DROP RULE y_rule ON y; -- check that parser lookahead for WITH doesn't cause any odd behavior create table foo (with baz); -- fail, WITH is a reserved word diff --git a/src/test/regress/sql/with.sql b/src/test/regress/sql/with.sql index 1a9bdc9f3e..8b213ee408 100644 --- a/src/test/regress/sql/with.sql +++ b/src/test/regress/sql/with.sql @@ -1375,6 +1375,27 @@ WITH t AS ( INSERT INTO y VALUES(0) ) VALUES(FALSE); +CREATE OR REPLACE RULE y_rule AS ON INSERT TO y DO INSTEAD NOTHING; +WITH t AS ( + INSERT INTO y VALUES(0) +) +VALUES(FALSE); +CREATE OR REPLACE RULE y_rule AS ON INSERT TO y DO INSTEAD NOTIFY foo; +WITH t AS ( + INSERT INTO y VALUES(0) +) +VALUES(FALSE); +CREATE OR REPLACE RULE y_rule AS ON INSERT TO y DO ALSO NOTIFY foo; +WITH t AS ( + INSERT INTO y VALUES(0) +) +VALUES(FALSE); +CREATE OR REPLACE RULE y_rule AS ON INSERT TO y + DO INSTEAD (NOTIFY foo; NOTIFY bar); +WITH t AS ( + INSERT INTO y VALUES(0) +) +VALUES(FALSE); DROP RULE y_rule ON y; = -- check that parser lookahead for WITH doesn't cause any odd behavior ------- =_aaaaaaaaaa0--