summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2008-09-24 16:53:07 +0000
committerTom Lane2008-09-24 16:53:07 +0000
commitce0774448b17e36b28cfd33267781b37ae20d253 (patch)
treec98bf4f59dffa42dcbd761dd46f9d0eb21b89a03
parent0d849e104982868aa25aabce95e5ffca729b788d (diff)
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.
-rw-r--r--src/backend/rewrite/rewriteHandler.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index cb8626dccb..6369932c70 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -347,6 +347,37 @@ rewriteRuleAction(Query *parsetree,
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
* that we're replacing (if present, which it won't be for INSERT). Note
@@ -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;