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

Commita9da193

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 parentca2e447 commita9da193

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
@@ -3585,15 +3585,29 @@ RewriteQuery(Query *parsetree, List *rewrite_events)
35853585

35863586
/*
35873587
* Currently we can only handle unconditional, single-statement DO
3588-
* INSTEAD rules correctly; we have to get exactly oneQuery out of
3589-
* the rewrite operation to stuff back into the CTE node.
3588+
* INSTEAD rules correctly; we have to get exactly onenon-utility
3589+
*Query out ofthe rewrite operation to stuff back into the CTE node.
35903590
*/
35913591
if (list_length(newstuff)==1)
35923592
{
3593-
/*Push the single Query back into the CTE node */
3593+
/*Must check it's not a utility command */
35943594
ctequery=linitial_node(Query,newstuff);
3595+
if (!(ctequery->commandType==CMD_SELECT||
3596+
ctequery->commandType==CMD_UPDATE||
3597+
ctequery->commandType==CMD_INSERT||
3598+
ctequery->commandType==CMD_DELETE))
3599+
{
3600+
/*
3601+
* Currently it could only be NOTIFY; this error message will
3602+
* need work if we ever allow other utility commands in rules.
3603+
*/
3604+
ereport(ERROR,
3605+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3606+
errmsg("DO INSTEAD NOTIFY rules are not supported for data-modifying statements in WITH")));
3607+
}
35953608
/* WITH queries should never be canSetTag */
35963609
Assert(!ctequery->canSetTag);
3610+
/* Push the single Query back into the CTE node */
35973611
cte->ctequery= (Node*)ctequery;
35983612
}
35993613
elseif (newstuff==NIL)

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2969,6 +2969,31 @@ WITH t AS (
29692969
)
29702970
VALUES(FALSE);
29712971
ERROR: conditional DO INSTEAD rules are not supported for data-modifying statements in WITH
2972+
CREATE OR REPLACE RULE y_rule AS ON INSERT TO y DO INSTEAD NOTHING;
2973+
WITH t AS (
2974+
INSERT INTO y VALUES(0)
2975+
)
2976+
VALUES(FALSE);
2977+
ERROR: DO INSTEAD NOTHING rules are not supported for data-modifying statements in WITH
2978+
CREATE OR REPLACE RULE y_rule AS ON INSERT TO y DO INSTEAD NOTIFY foo;
2979+
WITH t AS (
2980+
INSERT INTO y VALUES(0)
2981+
)
2982+
VALUES(FALSE);
2983+
ERROR: DO INSTEAD NOTIFY rules are not supported for data-modifying statements in WITH
2984+
CREATE OR REPLACE RULE y_rule AS ON INSERT TO y DO ALSO NOTIFY foo;
2985+
WITH t AS (
2986+
INSERT INTO y VALUES(0)
2987+
)
2988+
VALUES(FALSE);
2989+
ERROR: DO ALSO rules are not supported for data-modifying statements in WITH
2990+
CREATE OR REPLACE RULE y_rule AS ON INSERT TO y
2991+
DO INSTEAD (NOTIFY foo; NOTIFY bar);
2992+
WITH t AS (
2993+
INSERT INTO y VALUES(0)
2994+
)
2995+
VALUES(FALSE);
2996+
ERROR: multi-statement DO INSTEAD rules are not supported for data-modifying statements in WITH
29722997
DROP RULE y_rule ON y;
29732998
-- check that parser lookahead for WITH doesn't cause any odd behavior
29742999
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
@@ -1375,6 +1375,27 @@ WITH t AS (
13751375
INSERT INTO yVALUES(0)
13761376
)
13771377
VALUES(FALSE);
1378+
CREATE OR REPLACERULEy_ruleASON INSERT TO y DO INSTEAD NOTHING;
1379+
WITH tAS (
1380+
INSERT INTO yVALUES(0)
1381+
)
1382+
VALUES(FALSE);
1383+
CREATE OR REPLACERULEy_ruleASON INSERT TO y DO INSTEAD NOTIFY foo;
1384+
WITH tAS (
1385+
INSERT INTO yVALUES(0)
1386+
)
1387+
VALUES(FALSE);
1388+
CREATE OR REPLACERULEy_ruleASON INSERT TO y DO ALSO NOTIFY foo;
1389+
WITH tAS (
1390+
INSERT INTO yVALUES(0)
1391+
)
1392+
VALUES(FALSE);
1393+
CREATE OR REPLACERULEy_ruleASON INSERT TO y
1394+
DO INSTEAD (NOTIFY foo; NOTIFY bar);
1395+
WITH tAS (
1396+
INSERT INTO yVALUES(0)
1397+
)
1398+
VALUES(FALSE);
13781399
DROPRULE y_ruleON y;
13791400

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

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp