aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/util')
-rw-r--r--src/backend/optimizer/util/placeholder.c4
-rw-r--r--src/backend/optimizer/util/tlist.c5
-rw-r--r--src/backend/optimizer/util/var.c38
3 files changed, 29 insertions, 18 deletions
diff --git a/src/backend/optimizer/util/placeholder.c b/src/backend/optimizer/util/placeholder.c
index c1834a12914..019352158d2 100644
--- a/src/backend/optimizer/util/placeholder.c
+++ b/src/backend/optimizer/util/placeholder.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/util/placeholder.c,v 1.3 2009/01/01 17:23:45 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/placeholder.c,v 1.4 2009/04/19 19:46:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -162,7 +162,7 @@ fix_placeholder_eval_levels(PlannerInfo *root)
if (bms_membership(eval_at) == BMS_MULTIPLE)
{
List *vars = pull_var_clause((Node *) phinfo->ph_var->phexpr,
- true);
+ PVC_INCLUDE_PLACEHOLDERS);
add_vars_to_targetlist(root, vars, eval_at);
list_free(vars);
diff --git a/src/backend/optimizer/util/tlist.c b/src/backend/optimizer/util/tlist.c
index 5cf2839b37e..9526aefd9ac 100644
--- a/src/backend/optimizer/util/tlist.c
+++ b/src/backend/optimizer/util/tlist.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/util/tlist.c,v 1.85 2009/01/01 17:23:45 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/tlist.c,v 1.86 2009/04/19 19:46:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -91,7 +91,8 @@ tlist_member_ignore_relabel(Node *node, List *targetlist)
List *
flatten_tlist(List *tlist)
{
- List *vlist = pull_var_clause((Node *) tlist, true);
+ List *vlist = pull_var_clause((Node *) tlist,
+ PVC_INCLUDE_PLACEHOLDERS);
List *new_tlist;
new_tlist = add_to_flat_tlist(NIL, vlist);
diff --git a/src/backend/optimizer/util/var.c b/src/backend/optimizer/util/var.c
index 7768712b569..cd88c337f1a 100644
--- a/src/backend/optimizer/util/var.c
+++ b/src/backend/optimizer/util/var.c
@@ -14,7 +14,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/util/var.c,v 1.84 2009/02/25 03:30:37 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/var.c,v 1.85 2009/04/19 19:46:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -56,7 +56,7 @@ typedef struct
typedef struct
{
List *varlist;
- bool includePlaceHolderVars;
+ PVCPlaceHolderBehavior behavior;
} pull_var_clause_context;
typedef struct
@@ -614,11 +614,13 @@ find_minimum_var_level_walker(Node *node,
* pull_var_clause
* Recursively pulls all Var nodes from an expression clause.
*
- * PlaceHolderVars are included too, if includePlaceHolderVars is true.
- * If it isn't true, an error is thrown if any are found.
- * Note that Vars within a PHV's expression are *not* included.
+ * PlaceHolderVars are handled according to 'behavior':
+ * PVC_REJECT_PLACEHOLDERS throw error if PlaceHolderVar found
+ * PVC_INCLUDE_PLACEHOLDERS include PlaceHolderVars in output list
+ * PVC_RECURSE_PLACEHOLDERS recurse into PlaceHolderVar argument
+ * Vars within a PHV's expression are included only in the last case.
*
- * CurrentOfExpr nodes are *not* included.
+ * CurrentOfExpr nodes are ignored in all cases.
*
* Upper-level vars (with varlevelsup > 0) are not included.
* (These probably represent errors too, but we don't complain.)
@@ -630,12 +632,12 @@ find_minimum_var_level_walker(Node *node,
* of sublinks to subplans!
*/
List *
-pull_var_clause(Node *node, bool includePlaceHolderVars)
+pull_var_clause(Node *node, PVCPlaceHolderBehavior behavior)
{
pull_var_clause_context context;
context.varlist = NIL;
- context.includePlaceHolderVars = includePlaceHolderVars;
+ context.behavior = behavior;
pull_var_clause_walker(node, &context);
return context.varlist;
@@ -654,12 +656,20 @@ pull_var_clause_walker(Node *node, pull_var_clause_context *context)
}
if (IsA(node, PlaceHolderVar))
{
- if (!context->includePlaceHolderVars)
- elog(ERROR, "PlaceHolderVar found where not expected");
- if (((PlaceHolderVar *) node)->phlevelsup == 0)
- context->varlist = lappend(context->varlist, node);
- /* we do NOT descend into the contained expression */
- return false;
+ switch (context->behavior)
+ {
+ case PVC_REJECT_PLACEHOLDERS:
+ elog(ERROR, "PlaceHolderVar found where not expected");
+ break;
+ case PVC_INCLUDE_PLACEHOLDERS:
+ if (((PlaceHolderVar *) node)->phlevelsup == 0)
+ context->varlist = lappend(context->varlist, node);
+ /* we do NOT descend into the contained expression */
+ return false;
+ case PVC_RECURSE_PLACEHOLDERS:
+ /* ignore the placeholder, look at its argument instead */
+ break;
+ }
}
return expression_tree_walker(node, pull_var_clause_walker,
(void *) context);