Refactor pull_var_clause's API to make it less tedious to extend.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 10 Mar 2016 20:52:58 +0000 (15:52 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 10 Mar 2016 20:53:07 +0000 (15:53 -0500)
In commit 1d97c19a0f748e94 and later c1d9579dd8bf3c92, we extended
pull_var_clause's API by adding enum-type arguments.  That's sort of a pain
to maintain, though, because it means every time we add a new behavior we
must touch every last one of the call sites, even if there's a reasonable
default behavior that most of them could use.  Let's switch over to using a
bitmask of flags, instead; that seems more maintainable and might save a
nanosecond or two as well.  This commit changes no behavior in itself,
though I'm going to follow it up with one that does add a new behavior.

In passing, remove flatten_tlist(), which has not been used since 9.1
and would otherwise need the same API changes.

Removing these enums means that optimizer/tlist.h no longer needs to
depend on optimizer/var.h.  Changing that caused a number of C files to
need addition of #include "optimizer/var.h" (probably we can thank old
runs of pgrminclude for that); but on balance it seems like a good change
anyway.

20 files changed:
contrib/postgres_fdw/deparse.c
src/backend/catalog/heap.c
src/backend/commands/trigger.c
src/backend/optimizer/path/allpaths.c
src/backend/optimizer/path/equivclass.c
src/backend/optimizer/plan/analyzejoins.c
src/backend/optimizer/plan/createplan.c
src/backend/optimizer/plan/initsplan.c
src/backend/optimizer/plan/planner.c
src/backend/optimizer/plan/setrefs.c
src/backend/optimizer/prep/prepjointree.c
src/backend/optimizer/prep/preptlist.c
src/backend/optimizer/util/placeholder.c
src/backend/optimizer/util/tlist.c
src/backend/optimizer/util/var.c
src/backend/parser/parse_agg.c
src/backend/parser/parse_clause.c
src/backend/utils/adt/selfuncs.c
src/include/optimizer/tlist.h
src/include/optimizer/var.h

index 021b764ee98d235e2b02a0a2091a12db42d02ee1..e6d4cdbe5babe61b1d5f16932a214e6427977eb0 100644 (file)
@@ -734,7 +734,6 @@ build_tlist_to_deparse(RelOptInfo *foreignrel)
        tlist = add_to_flat_tlist(tlist, foreignrel->reltarget.exprs);
        tlist = add_to_flat_tlist(tlist,
                                                          pull_var_clause((Node *) fpinfo->local_conds,
-                                                                                         PVC_REJECT_AGGREGATES,
                                                                                          PVC_RECURSE_PLACEHOLDERS));
 
        return tlist;
index 6a4a9d9302b4937f7feb50d50b1baaad5faab522..e997b574ca9eaf93514817464b3a77467d1a5371 100644 (file)
@@ -2006,9 +2006,7 @@ StoreRelCheck(Relation rel, char *ccname, Node *expr,
         * in check constraints; it would fail to examine the contents of
         * subselects.
         */
-       varList = pull_var_clause(expr,
-                                                         PVC_REJECT_AGGREGATES,
-                                                         PVC_REJECT_PLACEHOLDERS);
+       varList = pull_var_clause(expr, 0);
        keycount = list_length(varList);
 
        if (keycount > 0)
@@ -2323,9 +2321,7 @@ AddRelationNewConstraints(Relation rel,
                        List       *vars;
                        char       *colname;
 
-                       vars = pull_var_clause(expr,
-                                                                  PVC_REJECT_AGGREGATES,
-                                                                  PVC_REJECT_PLACEHOLDERS);
+                       vars = pull_var_clause(expr, 0);
 
                        /* eliminate duplicates */
                        vars = list_union(NIL, vars);
index cca2e43b100b3833312b9eac596e9e334f5431bc..5fa2063c935ad7c24967a97a5078aba608751502 100644 (file)
@@ -352,9 +352,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
                 * subselects in WHEN clauses; it would fail to examine the contents
                 * of subselects.
                 */
-               varList = pull_var_clause(whenClause,
-                                                                 PVC_REJECT_AGGREGATES,
-                                                                 PVC_REJECT_PLACEHOLDERS);
+               varList = pull_var_clause(whenClause, 0);
                foreach(lc, varList)
                {
                        Var                *var = (Var *) lfirst(lc);
index a08c248e1407eccd73f84dfe11006d548dfa7341..05c51ff07e0225a63e18bddf58309b617356de4e 100644 (file)
@@ -2509,9 +2509,7 @@ qual_is_pushdown_safe(Query *subquery, Index rti, Node *qual,
         * Examine all Vars used in clause; since it's a restriction clause, all
         * such Vars must refer to subselect output columns.
         */
-       vars = pull_var_clause(qual,
-                                                  PVC_REJECT_AGGREGATES,
-                                                  PVC_INCLUDE_PLACEHOLDERS);
+       vars = pull_var_clause(qual, PVC_INCLUDE_PLACEHOLDERS);
        foreach(vl, vars)
        {
                Var                *var = (Var *) lfirst(vl);
index d9a65eba35deee7808361bbc988a7a1ab08ec274..e1c0ac996d58bd9258337f1e1a8c6f54fbdd70fd 100644 (file)
@@ -910,7 +910,7 @@ generate_base_implied_equalities_no_const(PlannerInfo *root,
        {
                EquivalenceMember *cur_em = (EquivalenceMember *) lfirst(lc);
                List       *vars = pull_var_clause((Node *) cur_em->em_expr,
-                                                                                  PVC_RECURSE_AGGREGATES,
+                                                                                  PVC_RECURSE_AGGREGATES |
                                                                                   PVC_INCLUDE_PLACEHOLDERS);
 
                add_vars_to_targetlist(root, vars, ec->ec_relids, false);
index d682db4e7274328a02638e4131e190201b3437e4..f7f5714e621f12cf0f57d82cc69d758a75c626ed 100644 (file)
@@ -29,6 +29,7 @@
 #include "optimizer/paths.h"
 #include "optimizer/planmain.h"
 #include "optimizer/tlist.h"
+#include "optimizer/var.h"
 #include "utils/lsyscache.h"
 
 /* local functions */
index 5c06547931b26a15e0e4832adaccdd7e7ac8395e..243e41d0cdea15f10e4ecc96510c19653ca11bca 100644 (file)
@@ -5335,7 +5335,7 @@ prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys,
 
                                sortexpr = em->em_expr;
                                exprvars = pull_var_clause((Node *) sortexpr,
-                                                                                  PVC_INCLUDE_AGGREGATES,
+                                                                                  PVC_INCLUDE_AGGREGATES |
                                                                                   PVC_INCLUDE_PLACEHOLDERS);
                                foreach(k, exprvars)
                                {
index 37fb58620977943da0a4c2d724a04a076a2fe008..4cbaa5a88160a58e6d55b3eff20d4563cbd17b7d 100644 (file)
@@ -146,7 +146,7 @@ void
 build_base_rel_tlists(PlannerInfo *root, List *final_tlist)
 {
        List       *tlist_vars = pull_var_clause((Node *) final_tlist,
-                                                                                        PVC_RECURSE_AGGREGATES,
+                                                                                        PVC_RECURSE_AGGREGATES |
                                                                                         PVC_INCLUDE_PLACEHOLDERS);
 
        if (tlist_vars != NIL)
@@ -161,7 +161,7 @@ build_base_rel_tlists(PlannerInfo *root, List *final_tlist)
        if (root->parse->havingQual)
        {
                List       *having_vars = pull_var_clause(root->parse->havingQual,
-                                                                                                 PVC_RECURSE_AGGREGATES,
+                                                                                                 PVC_RECURSE_AGGREGATES |
                                                                                                  PVC_INCLUDE_PLACEHOLDERS);
 
                if (having_vars != NIL)
@@ -1787,7 +1787,7 @@ distribute_qual_to_rels(PlannerInfo *root, Node *clause,
        if (bms_membership(relids) == BMS_MULTIPLE)
        {
                List       *vars = pull_var_clause(clause,
-                                                                                  PVC_RECURSE_AGGREGATES,
+                                                                                  PVC_RECURSE_AGGREGATES |
                                                                                   PVC_INCLUDE_PLACEHOLDERS);
 
                add_vars_to_targetlist(root, vars, relids, false);
index 8937e717d0611edc8ed8b9ae672748e415dad2e9..0161acf5223ec8ef2da6bd38ecc5287d9fb6f820 100644 (file)
@@ -43,6 +43,7 @@
 #include "optimizer/prep.h"
 #include "optimizer/subselect.h"
 #include "optimizer/tlist.h"
+#include "optimizer/var.h"
 #include "parser/analyze.h"
 #include "parser/parsetree.h"
 #include "parser/parse_agg.h"
@@ -3840,7 +3841,7 @@ make_group_input_target(PlannerInfo *root, List *tlist)
         * pulled out here, too.
         */
        non_group_vars = pull_var_clause((Node *) non_group_cols,
-                                                                        PVC_RECURSE_AGGREGATES,
+                                                                        PVC_RECURSE_AGGREGATES |
                                                                         PVC_INCLUDE_PLACEHOLDERS);
        sub_tlist = add_to_flat_tlist(sub_tlist, non_group_vars);
 
@@ -4088,7 +4089,7 @@ make_window_input_target(PlannerInfo *root,
         * at higher levels.
         */
        flattenable_vars = pull_var_clause((Node *) flattenable_cols,
-                                                                          PVC_INCLUDE_AGGREGATES,
+                                                                          PVC_INCLUDE_AGGREGATES |
                                                                           PVC_INCLUDE_PLACEHOLDERS);
        new_tlist = add_to_flat_tlist(new_tlist, flattenable_vars);
 
index 5e949850646119a17c6e1574a74972e4b0f12a4e..aa2c3084fc8d268637ec2769b81b5ad8b17c2c7d 100644 (file)
@@ -1641,12 +1641,12 @@ set_join_references(PlannerInfo *root, Join *join, int rtoffset)
  *
  * In most cases, we have to match up individual Vars in the tlist and
  * qual expressions with elements of the subplan's tlist (which was
- * generated by flatten_tlist() from these selfsame expressions, so it
- * should have all the required variables).  There is an important exception,
- * however: GROUP BY and ORDER BY expressions will have been pushed into the
- * subplan tlist unflattened.  If these values are also needed in the output
- * then we want to reference the subplan tlist element rather than recomputing
- * the expression.
+ * generated by flattening these selfsame expressions, so it should have all
+ * the required variables).  There is an important exception, however:
+ * depending on where we are in the plan tree, sort/group columns may have
+ * been pushed into the subplan tlist unflattened.  If these values are also
+ * needed in the output then we want to reference the subplan tlist element
+ * rather than recomputing the expression.
  */
 static void
 set_upper_references(PlannerInfo *root, Plan *plan, int rtoffset)
@@ -2129,7 +2129,8 @@ fix_join_expr_mutator(Node *node, fix_join_expr_context *context)
  *
  * An error is raised if no matching var can be found in the subplan tlist
  * --- so this routine should only be applied to nodes whose subplans'
- * targetlists were generated via flatten_tlist() or some such method.
+ * targetlists were generated by flattening the expressions used in the
+ * parent node.
  *
  * If itlist->has_non_vars is true, then we try to match whole subexpressions
  * against elements of the subplan tlist, so that we can avoid recomputing
index ba6770b4d551fb3469cdcfa5a809e935988ff3aa..c8d5c66b396cdde4d144d8539c858bdfdf60061d 100644 (file)
@@ -31,6 +31,7 @@
 #include "optimizer/prep.h"
 #include "optimizer/subselect.h"
 #include "optimizer/tlist.h"
+#include "optimizer/var.h"
 #include "parser/parse_relation.h"
 #include "parser/parsetree.h"
 #include "rewrite/rewriteManip.h"
index dd59a02c9591ba60a2b5be92081f1fced82eb182..777b273ac1701c42af1e4efbc230163f2962a58d 100644 (file)
@@ -44,6 +44,7 @@
 #include "nodes/makefuncs.h"
 #include "optimizer/prep.h"
 #include "optimizer/tlist.h"
+#include "optimizer/var.h"
 #include "parser/parsetree.h"
 #include "parser/parse_coerce.h"
 #include "utils/rel.h"
@@ -167,7 +168,7 @@ preprocess_targetlist(PlannerInfo *root, List *tlist)
                ListCell   *l;
 
                vars = pull_var_clause((Node *) parse->returningList,
-                                                          PVC_RECURSE_AGGREGATES,
+                                                          PVC_RECURSE_AGGREGATES |
                                                           PVC_INCLUDE_PLACEHOLDERS);
                foreach(l, vars)
                {
index 4af06ab73e5a43af0d91e6b979b82c68a86029cc..5e11286ac7a4ef7c317eed7a350a7908256ff578 100644 (file)
@@ -220,7 +220,7 @@ find_placeholders_in_expr(PlannerInfo *root, Node *expr)
         * convenient to use.
         */
        vars = pull_var_clause(expr,
-                                                  PVC_RECURSE_AGGREGATES,
+                                                  PVC_RECURSE_AGGREGATES |
                                                   PVC_INCLUDE_PLACEHOLDERS);
        foreach(vl, vars)
        {
@@ -354,7 +354,7 @@ fix_placeholder_input_needed_levels(PlannerInfo *root)
        {
                PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(lc);
                List       *vars = pull_var_clause((Node *) phinfo->ph_var->phexpr,
-                                                                                  PVC_RECURSE_AGGREGATES,
+                                                                                  PVC_RECURSE_AGGREGATES |
                                                                                   PVC_INCLUDE_PLACEHOLDERS);
 
                add_vars_to_targetlist(root, vars, phinfo->ph_eval_at, false);
index ccea3bf9d2727dffcc8f78b29de556c2d79ff56b..cbc8c2b9fef164f6a3f1aa141b94a2225d3d9bde 100644 (file)
@@ -100,34 +100,6 @@ tlist_member_match_var(Var *var, List *targetlist)
        return NULL;
 }
 
-/*
- * flatten_tlist
- *       Create a target list that only contains unique variables.
- *
- * Aggrefs and PlaceHolderVars in the input are treated according to
- * aggbehavior and phbehavior, for which see pull_var_clause().
- *
- * 'tlist' is the current target list
- *
- * Returns the "flattened" new target list.
- *
- * The result is entirely new structure sharing no nodes with the original.
- * Copying the Var nodes is probably overkill, but be safe for now.
- */
-List *
-flatten_tlist(List *tlist, PVCAggregateBehavior aggbehavior,
-                         PVCPlaceHolderBehavior phbehavior)
-{
-       List       *vlist = pull_var_clause((Node *) tlist,
-                                                                               aggbehavior,
-                                                                               phbehavior);
-       List       *new_tlist;
-
-       new_tlist = add_to_flat_tlist(NIL, vlist);
-       list_free(vlist);
-       return new_tlist;
-}
-
 /*
  * add_to_flat_tlist
  *             Add more items to a flattened tlist (if they're not already in it)
index dff52c439ab0ef555d6b45c3168e43ed7482bd16..a389f42a22447077fea654300e3f2d1b78161c60 100644 (file)
@@ -55,8 +55,7 @@ typedef struct
 typedef struct
 {
        List       *varlist;
-       PVCAggregateBehavior aggbehavior;
-       PVCPlaceHolderBehavior phbehavior;
+       int                     flags;
 } pull_var_clause_context;
 
 typedef struct
@@ -497,17 +496,22 @@ locate_var_of_level_walker(Node *node,
  * pull_var_clause
  *       Recursively pulls all Var nodes from an expression clause.
  *
- *       Aggrefs are handled according to 'aggbehavior':
- *             PVC_REJECT_AGGREGATES           throw error if Aggref found
+ *       Aggrefs are handled according to these bits in 'flags':
  *             PVC_INCLUDE_AGGREGATES          include Aggrefs in output list
  *             PVC_RECURSE_AGGREGATES          recurse into Aggref arguments
- *       Vars within an Aggref's expression are included only in the last case.
+ *             neither flag                            throw error if Aggref found
+ *       Vars within an Aggref's expression are included in the result only
+ *       when PVC_RECURSE_AGGREGATES is specified.
  *
- *       PlaceHolderVars are handled according to 'phbehavior':
- *             PVC_REJECT_PLACEHOLDERS         throw error if PlaceHolderVar found
+ *       PlaceHolderVars are handled according to these bits in 'flags':
  *             PVC_INCLUDE_PLACEHOLDERS        include PlaceHolderVars in output list
  *             PVC_RECURSE_PLACEHOLDERS        recurse into PlaceHolderVar arguments
- *       Vars within a PHV's expression are included only in the last case.
+ *             neither flag                            throw error if PlaceHolderVar found
+ *       Vars within a PHV's expression are included in the result only
+ *       when PVC_RECURSE_PLACEHOLDERS is specified.
+ *
+ *       GroupingFuncs are treated mostly like Aggrefs, and so do not need
+ *       their own flag bits.
  *
  *       CurrentOfExpr nodes are ignored in all cases.
  *
@@ -521,14 +525,18 @@ locate_var_of_level_walker(Node *node,
  * of sublinks to subplans!
  */
 List *
-pull_var_clause(Node *node, PVCAggregateBehavior aggbehavior,
-                               PVCPlaceHolderBehavior phbehavior)
+pull_var_clause(Node *node, int flags)
 {
        pull_var_clause_context context;
 
+       /* Assert that caller has not specified inconsistent flags */
+       Assert((flags & (PVC_INCLUDE_AGGREGATES | PVC_RECURSE_AGGREGATES))
+                  != (PVC_INCLUDE_AGGREGATES | PVC_RECURSE_AGGREGATES));
+       Assert((flags & (PVC_INCLUDE_PLACEHOLDERS | PVC_RECURSE_PLACEHOLDERS))
+                  != (PVC_INCLUDE_PLACEHOLDERS | PVC_RECURSE_PLACEHOLDERS));
+
        context.varlist = NIL;
-       context.aggbehavior = aggbehavior;
-       context.phbehavior = phbehavior;
+       context.flags = flags;
 
        pull_var_clause_walker(node, &context);
        return context.varlist;
@@ -550,62 +558,58 @@ pull_var_clause_walker(Node *node, pull_var_clause_context *context)
        {
                if (((Aggref *) node)->agglevelsup != 0)
                        elog(ERROR, "Upper-level Aggref found where not expected");
-               switch (context->aggbehavior)
+               if (context->flags & PVC_INCLUDE_AGGREGATES)
+               {
+                       context->varlist = lappend(context->varlist, node);
+                       /* we do NOT descend into the contained expression */
+                       return false;
+               }
+               else if (context->flags & PVC_RECURSE_AGGREGATES)
                {
-                       case PVC_REJECT_AGGREGATES:
-                               elog(ERROR, "Aggref found where not expected");
-                               break;
-                       case PVC_INCLUDE_AGGREGATES:
-                               context->varlist = lappend(context->varlist, node);
-                               /* we do NOT descend into the contained expression */
-                               return false;
-                       case PVC_RECURSE_AGGREGATES:
-                               /* ignore the aggregate, look at its argument instead */
-                               break;
+                       /* fall through to recurse into the aggregate's arguments */
                }
+               else
+                       elog(ERROR, "Aggref found where not expected");
        }
        else if (IsA(node, GroupingFunc))
        {
                if (((GroupingFunc *) node)->agglevelsup != 0)
                        elog(ERROR, "Upper-level GROUPING found where not expected");
-               switch (context->aggbehavior)
+               if (context->flags & PVC_INCLUDE_AGGREGATES)
                {
-                       case PVC_REJECT_AGGREGATES:
-                               elog(ERROR, "GROUPING found where not expected");
-                               break;
-                       case PVC_INCLUDE_AGGREGATES:
-                               context->varlist = lappend(context->varlist, node);
-                               /* we do NOT descend into the contained expression */
-                               return false;
-                       case PVC_RECURSE_AGGREGATES:
-
-                               /*
-                                * we do NOT descend into the contained expression, even if
-                                * the caller asked for it, because we never actually evaluate
-                                * it - the result is driven entirely off the associated GROUP
-                                * BY clause, so we never need to extract the actual Vars
-                                * here.
-                                */
-                               return false;
+                       context->varlist = lappend(context->varlist, node);
+                       /* we do NOT descend into the contained expression */
+                       return false;
+               }
+               else if (context->flags & PVC_RECURSE_AGGREGATES)
+               {
+                       /*
+                        * We do NOT descend into the contained expression, even if the
+                        * caller asked for it, because we never actually evaluate it -
+                        * the result is driven entirely off the associated GROUP BY
+                        * clause, so we never need to extract the actual Vars here.
+                        */
+                       return false;
                }
+               else
+                       elog(ERROR, "GROUPING found where not expected");
        }
        else if (IsA(node, PlaceHolderVar))
        {
                if (((PlaceHolderVar *) node)->phlevelsup != 0)
                        elog(ERROR, "Upper-level PlaceHolderVar found where not expected");
-               switch (context->phbehavior)
+               if (context->flags & PVC_INCLUDE_PLACEHOLDERS)
                {
-                       case PVC_REJECT_PLACEHOLDERS:
-                               elog(ERROR, "PlaceHolderVar found where not expected");
-                               break;
-                       case PVC_INCLUDE_PLACEHOLDERS:
-                               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;
+                       context->varlist = lappend(context->varlist, node);
+                       /* we do NOT descend into the contained expression */
+                       return false;
                }
+               else if (context->flags & PVC_RECURSE_PLACEHOLDERS)
+               {
+                       /* fall through to recurse into the placeholder's expression */
+               }
+               else
+                       elog(ERROR, "PlaceHolderVar found where not expected");
        }
        return expression_tree_walker(node, pull_var_clause_walker,
                                                                  (void *) context);
index b109ea5ba69841f0e0174e24dfa133882cf6042e..583462a91810a0ba7596d1037ac6f3d9736dde3e 100644 (file)
@@ -20,6 +20,7 @@
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
 #include "optimizer/tlist.h"
+#include "optimizer/var.h"
 #include "parser/parse_agg.h"
 #include "parser/parse_clause.h"
 #include "parser/parse_coerce.h"
index 04fa1271c806cb68608444043f44c16500f7fa75..4d9febee642a6db3905a121d06cbb7ffb7bba16e 100644 (file)
@@ -28,6 +28,7 @@
 #include "nodes/makefuncs.h"
 #include "nodes/nodeFuncs.h"
 #include "optimizer/tlist.h"
+#include "optimizer/var.h"
 #include "parser/analyze.h"
 #include "parser/parsetree.h"
 #include "parser/parser.h"
index 46c95b089edfa64b09802d23514a0e0d21424e1a..6e75a39bf3f086b4c171d59544f337155f7de01c 100644 (file)
@@ -3328,7 +3328,7 @@ estimate_num_groups(PlannerInfo *root, List *groupExprs, double input_rows,
                 * down to ignoring the possible addition of nulls to the result set).
                 */
                varshere = pull_var_clause(groupexpr,
-                                                                  PVC_RECURSE_AGGREGATES,
+                                                                  PVC_RECURSE_AGGREGATES |
                                                                   PVC_RECURSE_PLACEHOLDERS);
 
                /*
index a60e10278c7032a86606f109019d0b33281a2a9b..2c79a80391ec48533f1505ce7f26f72ecebda596 100644 (file)
 #ifndef TLIST_H
 #define TLIST_H
 
-#include "optimizer/var.h"
+#include "nodes/relation.h"
 
 
 extern TargetEntry *tlist_member(Node *node, List *targetlist);
 extern TargetEntry *tlist_member_ignore_relabel(Node *node, List *targetlist);
 
-extern List *flatten_tlist(List *tlist, PVCAggregateBehavior aggbehavior,
-                         PVCPlaceHolderBehavior phbehavior);
 extern List *add_to_flat_tlist(List *tlist, List *exprs);
 
 extern List *get_tlist_exprs(List *tlist, bool includeJunk);
index aded1fe4df9af6b42d1e32a1f046b7f89fd4c575..d1b0978b97ea83299b7edd68e3f759cf1f430728 100644 (file)
 
 #include "nodes/relation.h"
 
-typedef enum
-{
-       PVC_REJECT_AGGREGATES,          /* throw error if Aggref found */
-       PVC_INCLUDE_AGGREGATES,         /* include Aggrefs in output list */
-       PVC_RECURSE_AGGREGATES          /* recurse into Aggref arguments */
-} PVCAggregateBehavior;
+/* Bits that can be OR'd into the flags argument of pull_var_clause() */
+#define PVC_INCLUDE_AGGREGATES 0x0001  /* include Aggrefs in output list */
+#define PVC_RECURSE_AGGREGATES 0x0002  /* recurse into Aggref arguments */
+#define PVC_INCLUDE_PLACEHOLDERS       0x0004          /* include PlaceHolderVars in
+                                                                                                * output list */
+#define PVC_RECURSE_PLACEHOLDERS       0x0008          /* recurse into PlaceHolderVar
+                                                                                                * arguments */
 
-typedef enum
-{
-       PVC_REJECT_PLACEHOLDERS,        /* throw error if PlaceHolderVar found */
-       PVC_INCLUDE_PLACEHOLDERS,       /* include PlaceHolderVars in output list */
-       PVC_RECURSE_PLACEHOLDERS        /* recurse into PlaceHolderVar arguments */
-} PVCPlaceHolderBehavior;
 
 extern Relids pull_varnos(Node *node);
 extern Relids pull_varnos_of_level(Node *node, int levelsup);
@@ -37,8 +32,7 @@ extern List *pull_vars_of_level(Node *node, int levelsup);
 extern bool contain_var_clause(Node *node);
 extern bool contain_vars_of_level(Node *node, int levelsup);
 extern int     locate_var_of_level(Node *node, int levelsup);
-extern List *pull_var_clause(Node *node, PVCAggregateBehavior aggbehavior,
-                               PVCPlaceHolderBehavior phbehavior);
+extern List *pull_var_clause(Node *node, int flags);
 extern Node *flatten_join_alias_vars(PlannerInfo *root, Node *node);
 
 #endif   /* VAR_H */