diff options
Diffstat (limited to 'src/backend/optimizer/util')
-rw-r--r-- | src/backend/optimizer/util/placeholder.c | 4 | ||||
-rw-r--r-- | src/backend/optimizer/util/tlist.c | 5 | ||||
-rw-r--r-- | src/backend/optimizer/util/var.c | 38 |
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); |