Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit6edccac

Browse files
committed
Reject cases where a query in WITH rewrites to just NOTIFY.
Since the executor can't cope with a utility statement appearingas a node of a plan tree, we can't support cases where a rewriterule inserts a NOTIFY into an INSERT/UPDATE/DELETE command appearingin a WITH clause of a larger query. (One can imagine ways aroundthat, but it'd be a new feature not a bug fix, and so far there'sbeen no demand for it.) RewriteQuery checked for this, but itmissed the case where the DML command rewrites to *only* a NOTIFY.That'd lead to crashes later on in planning. Add the missed check,and improve the level of testing of this area.Per bug #17094 from Yaoguang Chen. It's been busted since WITHwas introduced, so back-patch to all supported branches.Discussion:https://postgr.es/m/17094-bf15dff55eaf2e28@postgresql.org
1 parent7dd2379 commit6edccac

File tree

3 files changed

+63
-3
lines changed

3 files changed

+63
-3
lines changed

‎src/backend/rewrite/rewriteHandler.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3516,15 +3516,29 @@ RewriteQuery(Query *parsetree, List *rewrite_events)
35163516

35173517
/*
35183518
* Currently we can only handle unconditional, single-statement DO
3519-
* INSTEAD rules correctly; we have to get exactly oneQuery out of
3520-
* the rewrite operation to stuff back into the CTE node.
3519+
* INSTEAD rules correctly; we have to get exactly onenon-utility
3520+
*Query out ofthe rewrite operation to stuff back into the CTE node.
35213521
*/
35223522
if (list_length(newstuff)==1)
35233523
{
3524-
/*Push the single Query back into the CTE node */
3524+
/*Must check it's not a utility command */
35253525
ctequery=linitial_node(Query,newstuff);
3526+
if (!(ctequery->commandType==CMD_SELECT||
3527+
ctequery->commandType==CMD_UPDATE||
3528+
ctequery->commandType==CMD_INSERT||
3529+
ctequery->commandType==CMD_DELETE))
3530+
{
3531+
/*
3532+
* Currently it could only be NOTIFY; this error message will
3533+
* need work if we ever allow other utility commands in rules.
3534+
*/
3535+
ereport(ERROR,
3536+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3537+
errmsg("DO INSTEAD NOTIFY rules are not supported for data-modifying statements in WITH")));
3538+
}
35263539
/* WITH queries should never be canSetTag */
35273540
Assert(!ctequery->canSetTag);
3541+
/* Push the single Query back into the CTE node */
35283542
cte->ctequery= (Node*)ctequery;
35293543
}
35303544
elseif (newstuff==NIL)

‎src/test/regress/expected/with.out

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2315,6 +2315,31 @@ WITH t AS (
23152315
)
23162316
VALUES(FALSE);
23172317
ERROR: conditional DO INSTEAD rules are not supported for data-modifying statements in WITH
2318+
CREATE OR REPLACE RULE y_rule AS ON INSERT TO y DO INSTEAD NOTHING;
2319+
WITH t AS (
2320+
INSERT INTO y VALUES(0)
2321+
)
2322+
VALUES(FALSE);
2323+
ERROR: DO INSTEAD NOTHING rules are not supported for data-modifying statements in WITH
2324+
CREATE OR REPLACE RULE y_rule AS ON INSERT TO y DO INSTEAD NOTIFY foo;
2325+
WITH t AS (
2326+
INSERT INTO y VALUES(0)
2327+
)
2328+
VALUES(FALSE);
2329+
ERROR: DO INSTEAD NOTIFY rules are not supported for data-modifying statements in WITH
2330+
CREATE OR REPLACE RULE y_rule AS ON INSERT TO y DO ALSO NOTIFY foo;
2331+
WITH t AS (
2332+
INSERT INTO y VALUES(0)
2333+
)
2334+
VALUES(FALSE);
2335+
ERROR: DO ALSO rules are not supported for data-modifying statements in WITH
2336+
CREATE OR REPLACE RULE y_rule AS ON INSERT TO y
2337+
DO INSTEAD (NOTIFY foo; NOTIFY bar);
2338+
WITH t AS (
2339+
INSERT INTO y VALUES(0)
2340+
)
2341+
VALUES(FALSE);
2342+
ERROR: multi-statement DO INSTEAD rules are not supported for data-modifying statements in WITH
23182343
DROP RULE y_rule ON y;
23192344
-- check that parser lookahead for WITH doesn't cause any odd behavior
23202345
create table foo (with baz); -- fail, WITH is a reserved word

‎src/test/regress/sql/with.sql

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,6 +1066,27 @@ WITH t AS (
10661066
INSERT INTO yVALUES(0)
10671067
)
10681068
VALUES(FALSE);
1069+
CREATE OR REPLACERULEy_ruleASON INSERT TO y DO INSTEAD NOTHING;
1070+
WITH tAS (
1071+
INSERT INTO yVALUES(0)
1072+
)
1073+
VALUES(FALSE);
1074+
CREATE OR REPLACERULEy_ruleASON INSERT TO y DO INSTEAD NOTIFY foo;
1075+
WITH tAS (
1076+
INSERT INTO yVALUES(0)
1077+
)
1078+
VALUES(FALSE);
1079+
CREATE OR REPLACERULEy_ruleASON INSERT TO y DO ALSO NOTIFY foo;
1080+
WITH tAS (
1081+
INSERT INTO yVALUES(0)
1082+
)
1083+
VALUES(FALSE);
1084+
CREATE OR REPLACERULEy_ruleASON INSERT TO y
1085+
DO INSTEAD (NOTIFY foo; NOTIFY bar);
1086+
WITH tAS (
1087+
INSERT INTO yVALUES(0)
1088+
)
1089+
VALUES(FALSE);
10691090
DROPRULE y_ruleON y;
10701091

10711092
-- check that parser lookahead for WITH doesn't cause any odd behavior

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp