Commit 364a9f47 authored by Tom Lane's avatar Tom Lane

Refactor pull_var_clause's API to make it less tedious to extend.

In commit 1d97c19a and later c1d9579d, 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.
parent 37c54863
...@@ -734,7 +734,6 @@ build_tlist_to_deparse(RelOptInfo *foreignrel) ...@@ -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, foreignrel->reltarget.exprs);
tlist = add_to_flat_tlist(tlist, tlist = add_to_flat_tlist(tlist,
pull_var_clause((Node *) fpinfo->local_conds, pull_var_clause((Node *) fpinfo->local_conds,
PVC_REJECT_AGGREGATES,
PVC_RECURSE_PLACEHOLDERS)); PVC_RECURSE_PLACEHOLDERS));
return tlist; return tlist;
......
...@@ -2006,9 +2006,7 @@ StoreRelCheck(Relation rel, char *ccname, Node *expr, ...@@ -2006,9 +2006,7 @@ StoreRelCheck(Relation rel, char *ccname, Node *expr,
* in check constraints; it would fail to examine the contents of * in check constraints; it would fail to examine the contents of
* subselects. * subselects.
*/ */
varList = pull_var_clause(expr, varList = pull_var_clause(expr, 0);
PVC_REJECT_AGGREGATES,
PVC_REJECT_PLACEHOLDERS);
keycount = list_length(varList); keycount = list_length(varList);
if (keycount > 0) if (keycount > 0)
...@@ -2323,9 +2321,7 @@ AddRelationNewConstraints(Relation rel, ...@@ -2323,9 +2321,7 @@ AddRelationNewConstraints(Relation rel,
List *vars; List *vars;
char *colname; char *colname;
vars = pull_var_clause(expr, vars = pull_var_clause(expr, 0);
PVC_REJECT_AGGREGATES,
PVC_REJECT_PLACEHOLDERS);
/* eliminate duplicates */ /* eliminate duplicates */
vars = list_union(NIL, vars); vars = list_union(NIL, vars);
......
...@@ -352,9 +352,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, ...@@ -352,9 +352,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
* subselects in WHEN clauses; it would fail to examine the contents * subselects in WHEN clauses; it would fail to examine the contents
* of subselects. * of subselects.
*/ */
varList = pull_var_clause(whenClause, varList = pull_var_clause(whenClause, 0);
PVC_REJECT_AGGREGATES,
PVC_REJECT_PLACEHOLDERS);
foreach(lc, varList) foreach(lc, varList)
{ {
Var *var = (Var *) lfirst(lc); Var *var = (Var *) lfirst(lc);
......
...@@ -2509,9 +2509,7 @@ qual_is_pushdown_safe(Query *subquery, Index rti, Node *qual, ...@@ -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 * Examine all Vars used in clause; since it's a restriction clause, all
* such Vars must refer to subselect output columns. * such Vars must refer to subselect output columns.
*/ */
vars = pull_var_clause(qual, vars = pull_var_clause(qual, PVC_INCLUDE_PLACEHOLDERS);
PVC_REJECT_AGGREGATES,
PVC_INCLUDE_PLACEHOLDERS);
foreach(vl, vars) foreach(vl, vars)
{ {
Var *var = (Var *) lfirst(vl); Var *var = (Var *) lfirst(vl);
......
...@@ -910,7 +910,7 @@ generate_base_implied_equalities_no_const(PlannerInfo *root, ...@@ -910,7 +910,7 @@ generate_base_implied_equalities_no_const(PlannerInfo *root,
{ {
EquivalenceMember *cur_em = (EquivalenceMember *) lfirst(lc); EquivalenceMember *cur_em = (EquivalenceMember *) lfirst(lc);
List *vars = pull_var_clause((Node *) cur_em->em_expr, List *vars = pull_var_clause((Node *) cur_em->em_expr,
PVC_RECURSE_AGGREGATES, PVC_RECURSE_AGGREGATES |
PVC_INCLUDE_PLACEHOLDERS); PVC_INCLUDE_PLACEHOLDERS);
add_vars_to_targetlist(root, vars, ec->ec_relids, false); add_vars_to_targetlist(root, vars, ec->ec_relids, false);
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "optimizer/paths.h" #include "optimizer/paths.h"
#include "optimizer/planmain.h" #include "optimizer/planmain.h"
#include "optimizer/tlist.h" #include "optimizer/tlist.h"
#include "optimizer/var.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
/* local functions */ /* local functions */
......
...@@ -5335,7 +5335,7 @@ prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys, ...@@ -5335,7 +5335,7 @@ prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys,
sortexpr = em->em_expr; sortexpr = em->em_expr;
exprvars = pull_var_clause((Node *) sortexpr, exprvars = pull_var_clause((Node *) sortexpr,
PVC_INCLUDE_AGGREGATES, PVC_INCLUDE_AGGREGATES |
PVC_INCLUDE_PLACEHOLDERS); PVC_INCLUDE_PLACEHOLDERS);
foreach(k, exprvars) foreach(k, exprvars)
{ {
......
...@@ -146,7 +146,7 @@ void ...@@ -146,7 +146,7 @@ void
build_base_rel_tlists(PlannerInfo *root, List *final_tlist) build_base_rel_tlists(PlannerInfo *root, List *final_tlist)
{ {
List *tlist_vars = pull_var_clause((Node *) final_tlist, List *tlist_vars = pull_var_clause((Node *) final_tlist,
PVC_RECURSE_AGGREGATES, PVC_RECURSE_AGGREGATES |
PVC_INCLUDE_PLACEHOLDERS); PVC_INCLUDE_PLACEHOLDERS);
if (tlist_vars != NIL) if (tlist_vars != NIL)
...@@ -161,7 +161,7 @@ build_base_rel_tlists(PlannerInfo *root, List *final_tlist) ...@@ -161,7 +161,7 @@ build_base_rel_tlists(PlannerInfo *root, List *final_tlist)
if (root->parse->havingQual) if (root->parse->havingQual)
{ {
List *having_vars = pull_var_clause(root->parse->havingQual, List *having_vars = pull_var_clause(root->parse->havingQual,
PVC_RECURSE_AGGREGATES, PVC_RECURSE_AGGREGATES |
PVC_INCLUDE_PLACEHOLDERS); PVC_INCLUDE_PLACEHOLDERS);
if (having_vars != NIL) if (having_vars != NIL)
...@@ -1787,7 +1787,7 @@ distribute_qual_to_rels(PlannerInfo *root, Node *clause, ...@@ -1787,7 +1787,7 @@ distribute_qual_to_rels(PlannerInfo *root, Node *clause,
if (bms_membership(relids) == BMS_MULTIPLE) if (bms_membership(relids) == BMS_MULTIPLE)
{ {
List *vars = pull_var_clause(clause, List *vars = pull_var_clause(clause,
PVC_RECURSE_AGGREGATES, PVC_RECURSE_AGGREGATES |
PVC_INCLUDE_PLACEHOLDERS); PVC_INCLUDE_PLACEHOLDERS);
add_vars_to_targetlist(root, vars, relids, false); add_vars_to_targetlist(root, vars, relids, false);
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include "optimizer/prep.h" #include "optimizer/prep.h"
#include "optimizer/subselect.h" #include "optimizer/subselect.h"
#include "optimizer/tlist.h" #include "optimizer/tlist.h"
#include "optimizer/var.h"
#include "parser/analyze.h" #include "parser/analyze.h"
#include "parser/parsetree.h" #include "parser/parsetree.h"
#include "parser/parse_agg.h" #include "parser/parse_agg.h"
...@@ -3840,7 +3841,7 @@ make_group_input_target(PlannerInfo *root, List *tlist) ...@@ -3840,7 +3841,7 @@ make_group_input_target(PlannerInfo *root, List *tlist)
* pulled out here, too. * pulled out here, too.
*/ */
non_group_vars = pull_var_clause((Node *) non_group_cols, non_group_vars = pull_var_clause((Node *) non_group_cols,
PVC_RECURSE_AGGREGATES, PVC_RECURSE_AGGREGATES |
PVC_INCLUDE_PLACEHOLDERS); PVC_INCLUDE_PLACEHOLDERS);
sub_tlist = add_to_flat_tlist(sub_tlist, non_group_vars); sub_tlist = add_to_flat_tlist(sub_tlist, non_group_vars);
...@@ -4088,7 +4089,7 @@ make_window_input_target(PlannerInfo *root, ...@@ -4088,7 +4089,7 @@ make_window_input_target(PlannerInfo *root,
* at higher levels. * at higher levels.
*/ */
flattenable_vars = pull_var_clause((Node *) flattenable_cols, flattenable_vars = pull_var_clause((Node *) flattenable_cols,
PVC_INCLUDE_AGGREGATES, PVC_INCLUDE_AGGREGATES |
PVC_INCLUDE_PLACEHOLDERS); PVC_INCLUDE_PLACEHOLDERS);
new_tlist = add_to_flat_tlist(new_tlist, flattenable_vars); new_tlist = add_to_flat_tlist(new_tlist, flattenable_vars);
......
...@@ -1641,12 +1641,12 @@ set_join_references(PlannerInfo *root, Join *join, int rtoffset) ...@@ -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 * 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 * qual expressions with elements of the subplan's tlist (which was
* generated by flatten_tlist() from these selfsame expressions, so it * generated by flattening these selfsame expressions, so it should have all
* should have all the required variables). There is an important exception, * the required variables). There is an important exception, however:
* however: GROUP BY and ORDER BY expressions will have been pushed into the * depending on where we are in the plan tree, sort/group columns may have
* subplan tlist unflattened. If these values are also needed in the output * been pushed into the subplan tlist unflattened. If these values are also
* then we want to reference the subplan tlist element rather than recomputing * needed in the output then we want to reference the subplan tlist element
* the expression. * rather than recomputing the expression.
*/ */
static void static void
set_upper_references(PlannerInfo *root, Plan *plan, int rtoffset) set_upper_references(PlannerInfo *root, Plan *plan, int rtoffset)
...@@ -2129,7 +2129,8 @@ fix_join_expr_mutator(Node *node, fix_join_expr_context *context) ...@@ -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 * 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' * --- 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 * 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 * against elements of the subplan tlist, so that we can avoid recomputing
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "optimizer/prep.h" #include "optimizer/prep.h"
#include "optimizer/subselect.h" #include "optimizer/subselect.h"
#include "optimizer/tlist.h" #include "optimizer/tlist.h"
#include "optimizer/var.h"
#include "parser/parse_relation.h" #include "parser/parse_relation.h"
#include "parser/parsetree.h" #include "parser/parsetree.h"
#include "rewrite/rewriteManip.h" #include "rewrite/rewriteManip.h"
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include "nodes/makefuncs.h" #include "nodes/makefuncs.h"
#include "optimizer/prep.h" #include "optimizer/prep.h"
#include "optimizer/tlist.h" #include "optimizer/tlist.h"
#include "optimizer/var.h"
#include "parser/parsetree.h" #include "parser/parsetree.h"
#include "parser/parse_coerce.h" #include "parser/parse_coerce.h"
#include "utils/rel.h" #include "utils/rel.h"
...@@ -167,7 +168,7 @@ preprocess_targetlist(PlannerInfo *root, List *tlist) ...@@ -167,7 +168,7 @@ preprocess_targetlist(PlannerInfo *root, List *tlist)
ListCell *l; ListCell *l;
vars = pull_var_clause((Node *) parse->returningList, vars = pull_var_clause((Node *) parse->returningList,
PVC_RECURSE_AGGREGATES, PVC_RECURSE_AGGREGATES |
PVC_INCLUDE_PLACEHOLDERS); PVC_INCLUDE_PLACEHOLDERS);
foreach(l, vars) foreach(l, vars)
{ {
......
...@@ -220,7 +220,7 @@ find_placeholders_in_expr(PlannerInfo *root, Node *expr) ...@@ -220,7 +220,7 @@ find_placeholders_in_expr(PlannerInfo *root, Node *expr)
* convenient to use. * convenient to use.
*/ */
vars = pull_var_clause(expr, vars = pull_var_clause(expr,
PVC_RECURSE_AGGREGATES, PVC_RECURSE_AGGREGATES |
PVC_INCLUDE_PLACEHOLDERS); PVC_INCLUDE_PLACEHOLDERS);
foreach(vl, vars) foreach(vl, vars)
{ {
...@@ -354,7 +354,7 @@ fix_placeholder_input_needed_levels(PlannerInfo *root) ...@@ -354,7 +354,7 @@ fix_placeholder_input_needed_levels(PlannerInfo *root)
{ {
PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(lc); PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(lc);
List *vars = pull_var_clause((Node *) phinfo->ph_var->phexpr, List *vars = pull_var_clause((Node *) phinfo->ph_var->phexpr,
PVC_RECURSE_AGGREGATES, PVC_RECURSE_AGGREGATES |
PVC_INCLUDE_PLACEHOLDERS); PVC_INCLUDE_PLACEHOLDERS);
add_vars_to_targetlist(root, vars, phinfo->ph_eval_at, false); add_vars_to_targetlist(root, vars, phinfo->ph_eval_at, false);
......
...@@ -100,34 +100,6 @@ tlist_member_match_var(Var *var, List *targetlist) ...@@ -100,34 +100,6 @@ tlist_member_match_var(Var *var, List *targetlist)
return NULL; 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_to_flat_tlist
* Add more items to a flattened tlist (if they're not already in it) * Add more items to a flattened tlist (if they're not already in it)
......
...@@ -55,8 +55,7 @@ typedef struct ...@@ -55,8 +55,7 @@ typedef struct
typedef struct typedef struct
{ {
List *varlist; List *varlist;
PVCAggregateBehavior aggbehavior; int flags;
PVCPlaceHolderBehavior phbehavior;
} pull_var_clause_context; } pull_var_clause_context;
typedef struct typedef struct
...@@ -497,17 +496,22 @@ locate_var_of_level_walker(Node *node, ...@@ -497,17 +496,22 @@ locate_var_of_level_walker(Node *node,
* pull_var_clause * pull_var_clause
* Recursively pulls all Var nodes from an expression clause. * Recursively pulls all Var nodes from an expression clause.
* *
* Aggrefs are handled according to 'aggbehavior': * Aggrefs are handled according to these bits in 'flags':
* PVC_REJECT_AGGREGATES throw error if Aggref found
* PVC_INCLUDE_AGGREGATES include Aggrefs in output list * PVC_INCLUDE_AGGREGATES include Aggrefs in output list
* PVC_RECURSE_AGGREGATES recurse into Aggref arguments * 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': * PlaceHolderVars are handled according to these bits in 'flags':
* PVC_REJECT_PLACEHOLDERS throw error if PlaceHolderVar found
* PVC_INCLUDE_PLACEHOLDERS include PlaceHolderVars in output list * PVC_INCLUDE_PLACEHOLDERS include PlaceHolderVars in output list
* PVC_RECURSE_PLACEHOLDERS recurse into PlaceHolderVar arguments * 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. * CurrentOfExpr nodes are ignored in all cases.
* *
...@@ -521,14 +525,18 @@ locate_var_of_level_walker(Node *node, ...@@ -521,14 +525,18 @@ locate_var_of_level_walker(Node *node,
* of sublinks to subplans! * of sublinks to subplans!
*/ */
List * List *
pull_var_clause(Node *node, PVCAggregateBehavior aggbehavior, pull_var_clause(Node *node, int flags)
PVCPlaceHolderBehavior phbehavior)
{ {
pull_var_clause_context context; 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.varlist = NIL;
context.aggbehavior = aggbehavior; context.flags = flags;
context.phbehavior = phbehavior;
pull_var_clause_walker(node, &context); pull_var_clause_walker(node, &context);
return context.varlist; return context.varlist;
...@@ -550,62 +558,58 @@ pull_var_clause_walker(Node *node, pull_var_clause_context *context) ...@@ -550,62 +558,58 @@ pull_var_clause_walker(Node *node, pull_var_clause_context *context)
{ {
if (((Aggref *) node)->agglevelsup != 0) if (((Aggref *) node)->agglevelsup != 0)
elog(ERROR, "Upper-level Aggref found where not expected"); elog(ERROR, "Upper-level Aggref found where not expected");
switch (context->aggbehavior) if (context->flags & PVC_INCLUDE_AGGREGATES)
{ {
case PVC_REJECT_AGGREGATES:
elog(ERROR, "Aggref found where not expected");
break;
case PVC_INCLUDE_AGGREGATES:
context->varlist = lappend(context->varlist, node); context->varlist = lappend(context->varlist, node);
/* we do NOT descend into the contained expression */ /* we do NOT descend into the contained expression */
return false; return false;
case PVC_RECURSE_AGGREGATES:
/* ignore the aggregate, look at its argument instead */
break;
} }
else if (context->flags & PVC_RECURSE_AGGREGATES)
{
/* fall through to recurse into the aggregate's arguments */
}
else
elog(ERROR, "Aggref found where not expected");
} }
else if (IsA(node, GroupingFunc)) else if (IsA(node, GroupingFunc))
{ {
if (((GroupingFunc *) node)->agglevelsup != 0) if (((GroupingFunc *) node)->agglevelsup != 0)
elog(ERROR, "Upper-level GROUPING found where not expected"); 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); context->varlist = lappend(context->varlist, node);
/* we do NOT descend into the contained expression */ /* we do NOT descend into the contained expression */
return false; return false;
case PVC_RECURSE_AGGREGATES: }
else if (context->flags & PVC_RECURSE_AGGREGATES)
{
/* /*
* we do NOT descend into the contained expression, even if * We do NOT descend into the contained expression, even if the
* the caller asked for it, because we never actually evaluate * caller asked for it, because we never actually evaluate it -
* it - the result is driven entirely off the associated GROUP * the result is driven entirely off the associated GROUP BY
* BY clause, so we never need to extract the actual Vars * clause, so we never need to extract the actual Vars here.
* here.
*/ */
return false; return false;
} }
else
elog(ERROR, "GROUPING found where not expected");
} }
else if (IsA(node, PlaceHolderVar)) else if (IsA(node, PlaceHolderVar))
{ {
if (((PlaceHolderVar *) node)->phlevelsup != 0) if (((PlaceHolderVar *) node)->phlevelsup != 0)
elog(ERROR, "Upper-level PlaceHolderVar found where not expected"); 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); context->varlist = lappend(context->varlist, node);
/* we do NOT descend into the contained expression */ /* we do NOT descend into the contained expression */
return false; return false;
case PVC_RECURSE_PLACEHOLDERS:
/* ignore the placeholder, look at its argument instead */
break;
} }
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, return expression_tree_walker(node, pull_var_clause_walker,
(void *) context); (void *) context);
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "nodes/makefuncs.h" #include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h" #include "nodes/nodeFuncs.h"
#include "optimizer/tlist.h" #include "optimizer/tlist.h"
#include "optimizer/var.h"
#include "parser/parse_agg.h" #include "parser/parse_agg.h"
#include "parser/parse_clause.h" #include "parser/parse_clause.h"
#include "parser/parse_coerce.h" #include "parser/parse_coerce.h"
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "nodes/makefuncs.h" #include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h" #include "nodes/nodeFuncs.h"
#include "optimizer/tlist.h" #include "optimizer/tlist.h"
#include "optimizer/var.h"
#include "parser/analyze.h" #include "parser/analyze.h"
#include "parser/parsetree.h" #include "parser/parsetree.h"
#include "parser/parser.h" #include "parser/parser.h"
......
...@@ -3328,7 +3328,7 @@ estimate_num_groups(PlannerInfo *root, List *groupExprs, double input_rows, ...@@ -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). * down to ignoring the possible addition of nulls to the result set).
*/ */
varshere = pull_var_clause(groupexpr, varshere = pull_var_clause(groupexpr,
PVC_RECURSE_AGGREGATES, PVC_RECURSE_AGGREGATES |
PVC_RECURSE_PLACEHOLDERS); PVC_RECURSE_PLACEHOLDERS);
/* /*
......
...@@ -14,14 +14,12 @@ ...@@ -14,14 +14,12 @@
#ifndef TLIST_H #ifndef TLIST_H
#define 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(Node *node, List *targetlist);
extern TargetEntry *tlist_member_ignore_relabel(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 *add_to_flat_tlist(List *tlist, List *exprs);
extern List *get_tlist_exprs(List *tlist, bool includeJunk); extern List *get_tlist_exprs(List *tlist, bool includeJunk);
......
...@@ -16,19 +16,14 @@ ...@@ -16,19 +16,14 @@
#include "nodes/relation.h" #include "nodes/relation.h"
typedef enum /* Bits that can be OR'd into the flags argument of pull_var_clause() */
{ #define PVC_INCLUDE_AGGREGATES 0x0001 /* include Aggrefs in output list */
PVC_REJECT_AGGREGATES, /* throw error if Aggref found */ #define PVC_RECURSE_AGGREGATES 0x0002 /* recurse into Aggref arguments */
PVC_INCLUDE_AGGREGATES, /* include Aggrefs in output list */ #define PVC_INCLUDE_PLACEHOLDERS 0x0004 /* include PlaceHolderVars in
PVC_RECURSE_AGGREGATES /* recurse into Aggref arguments */ * output list */
} PVCAggregateBehavior; #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(Node *node);
extern Relids pull_varnos_of_level(Node *node, int levelsup); extern Relids pull_varnos_of_level(Node *node, int levelsup);
...@@ -37,8 +32,7 @@ extern List *pull_vars_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_var_clause(Node *node);
extern bool contain_vars_of_level(Node *node, int levelsup); extern bool contain_vars_of_level(Node *node, int levelsup);
extern int locate_var_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, extern List *pull_var_clause(Node *node, int flags);
PVCPlaceHolderBehavior phbehavior);
extern Node *flatten_join_alias_vars(PlannerInfo *root, Node *node); extern Node *flatten_join_alias_vars(PlannerInfo *root, Node *node);
#endif /* VAR_H */ #endif /* VAR_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment