mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-27 08:39:28 +08:00
Fix more problems with rewriter failing to set Query.hasSubLinks when inserting
a SubLink expression into a rule query. We missed cases where the original query contained a sub-SELECT in a function in FROM, a multi-row VALUES list, or a RETURNING list. Per bug #4434 from Dean Rasheed and subsequent investigation. Back-patch to 8.1; older releases don't have the issue because they didn't try to be smart about setting hasSubLinks only when needed.
This commit is contained in:
parent
c4e5ec592f
commit
a36a20aa52
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.168.2.1 2007/03/01 18:50:36 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.168.2.2 2008/09/24 16:53:00 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -345,6 +345,37 @@ rewriteRuleAction(Query *parsetree,
|
||||
sub_action->rtable = list_concat((List *) copyObject(parsetree->rtable),
|
||||
sub_action->rtable);
|
||||
|
||||
/*
|
||||
* There could have been some SubLinks in parsetree's rtable, in which
|
||||
* case we'd better mark the sub_action correctly.
|
||||
*/
|
||||
if (parsetree->hasSubLinks && !sub_action->hasSubLinks)
|
||||
{
|
||||
ListCell *lc;
|
||||
|
||||
foreach(lc, parsetree->rtable)
|
||||
{
|
||||
RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);
|
||||
|
||||
switch (rte->rtekind)
|
||||
{
|
||||
case RTE_FUNCTION:
|
||||
sub_action->hasSubLinks =
|
||||
checkExprHasSubLink(rte->funcexpr);
|
||||
break;
|
||||
case RTE_VALUES:
|
||||
sub_action->hasSubLinks =
|
||||
checkExprHasSubLink((Node *) rte->values_lists);
|
||||
break;
|
||||
default:
|
||||
/* other RTE types don't contain bare expressions */
|
||||
break;
|
||||
}
|
||||
if (sub_action->hasSubLinks)
|
||||
break; /* no need to keep scanning rtable */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Each rule action's jointree should be the main parsetree's jointree
|
||||
* plus that rule's jointree, but usually *without* the original rtindex
|
||||
@ -454,6 +485,14 @@ rewriteRuleAction(Query *parsetree,
|
||||
rule_action->returningList,
|
||||
CMD_SELECT,
|
||||
0);
|
||||
|
||||
/*
|
||||
* There could have been some SubLinks in parsetree's returningList,
|
||||
* in which case we'd better mark the rule_action correctly.
|
||||
*/
|
||||
if (parsetree->hasSubLinks && !rule_action->hasSubLinks)
|
||||
rule_action->hasSubLinks =
|
||||
checkExprHasSubLink((Node *) rule_action->returningList);
|
||||
}
|
||||
|
||||
return rule_action;
|
||||
|
Loading…
Reference in New Issue
Block a user