From: Tom Lane Date: Wed, 24 Sep 2008 16:52:46 +0000 (+0000) Subject: Fix more problems with rewriter failing to set Query.hasSubLinks when inserting X-Git-Tag: REL8_4_BETA1~956 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=96a25d393cac5b0f9d36f32c8a874b6ea662ebc1;p=thirdparty%2Fpostgresql.git 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. --- diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c index a6e01a8b1c2..305b91202ad 100644 --- a/src/backend/rewrite/rewriteHandler.c +++ b/src/backend/rewrite/rewriteHandler.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.179 2008/08/28 23:09:48 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.180 2008/09/24 16:52:46 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -346,6 +346,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 @@ -455,6 +486,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;