aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/util/var.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/util/var.c')
-rw-r--r--src/backend/optimizer/util/var.c38
1 files changed, 24 insertions, 14 deletions
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);