From: Tom Lane <tgl@sss.pgh.pa.us>
To: Richard Guo <guofenglinux@gmail.com>
Cc: cyg0810@gmail.com, PostgreSQL mailing lists <pgsql-bugs@lists.postgresql.org>
Subject: Re: BUG #17094: FailedAssertion at planner.c
Date: Thu, 08 Jul 2021 13:22:06 -0400
Message-ID: <2032521.1625764926@sss.pgh.pa.us> (raw)
In-Reply-To: <1974959.1625761759@sss.pgh.pa.us>
References: <17094-bf15dff55eaf2e28@postgresql.org>
<CAMbWs48ypEC6i6eZ77rbBbpmYa5ehuQ_M3TkDTWdieqBWAg=XQ@mail.gmail.com>
<1974959.1625761759@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
Attachments:tighten-rule-rewrite-in-WITH-restrictions.patch (text/x-diff, 3.8K) downloaddiff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.cindex 88a9e95e33..54fd6d6fb2 100644--- a/src/backend/rewrite/rewriteHandler.c+++ b/src/backend/rewrite/rewriteHandler.c@@ -3585,15 +3585,29 @@ RewriteQuery(Query *parsetree, List *rewrite_events)
/*
* 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) == 1)
{
- /* Push the single Query back into the CTE node */+ /* Must check it's not a utility command */
ctequery = linitial_node(Query, newstuff);
+ if (!(ctequery->commandType == CMD_SELECT ||+ ctequery->commandType == CMD_UPDATE ||+ ctequery->commandType == CMD_INSERT ||+ ctequery->commandType == 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-modifying statements in WITH")));+ }
/* WITH queries should never be canSetTag */
Assert(!ctequery->canSetTag);
+ /* Push the single Query back into the CTE node */
cte->ctequery = (Node *) ctequery;
}
else if (newstuff == NIL)
diff --git a/src/test/regress/expected/with.out b/src/test/regress/expected/with.outindex 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 statements 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 statements 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-modifying 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.sqlindex 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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-bugs@postgresql.org
Cc: tgl@sss.pgh.pa.us, guofenglinux@gmail.com, pgsql-bugs@lists.postgresql.org
Subject: Re: BUG #17094: FailedAssertion at planner.c
In-Reply-To: <2032521.1625764926@sss.pgh.pa.us>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox