Re: BUG #17094: FailedAssertion at planner.c - Mailing list pgsql-bugs

From Tom Lane
Subject Re: BUG #17094: FailedAssertion at planner.c
Date
Msg-id 2032521.1625764926@sss.pgh.pa.us
Whole thread Raw
In response to Re: BUG #17094: FailedAssertion at planner.c  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: BUG #17094: FailedAssertion at planner.c  (Richard Guo <guofenglinux@gmail.com>)
List pgsql-bugs
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

diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.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_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.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 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.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

pgsql-bugs by date:

Previous
From: Etsuro Fujita
Date:
Subject: Re: The case when AsyncAppend exists also in the qual of Async ForeignScan
Next
From: Tom Lane
Date:
Subject: Re: BUG #17083: [PATCH] PostgreSQL fails to build with OpenLDAP 2.5.x