*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.352 2009/03/31 17:59:56 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.353 2009/04/19 19:46:32 tgl Exp $
*
*
* INTERFACE ROUTINES
* in check constraints; it would fail to examine the contents of
* subselects.
*/
- varList = pull_var_clause(expr, false);
+ varList = pull_var_clause(expr, PVC_REJECT_PLACEHOLDERS);
keycount = list_length(varList);
if (keycount > 0)
List *vars;
char *colname;
- vars = pull_var_clause(expr, false);
+ vars = pull_var_clause(expr, PVC_REJECT_PLACEHOLDERS);
/* eliminate duplicates */
vars = list_union(NIL, vars);
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.181 2009/03/10 20:58:26 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.182 2009/04/19 19:46:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* 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, true);
+ vars = pull_var_clause(qual, PVC_INCLUDE_PLACEHOLDERS);
foreach(vl, vars)
{
Var *var = (Var *) lfirst(vl);
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/path/equivclass.c,v 1.17 2009/02/06 23:43:23 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/path/equivclass.c,v 1.18 2009/04/19 19:46:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
foreach(lc, ec->ec_members)
{
EquivalenceMember *cur_em = (EquivalenceMember *) lfirst(lc);
- List *vars = pull_var_clause((Node *) cur_em->em_expr, true);
+ List *vars = pull_var_clause((Node *) cur_em->em_expr,
+ PVC_INCLUDE_PLACEHOLDERS);
add_vars_to_targetlist(root, vars, ec->ec_relids);
list_free(vars);
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.257 2009/03/26 17:15:35 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.258 2009/04/19 19:46:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
if (em->em_is_const || em->em_is_child)
continue;
sortexpr = em->em_expr;
- exprvars = pull_var_clause((Node *) sortexpr, true);
+ exprvars = pull_var_clause((Node *) sortexpr,
+ PVC_INCLUDE_PLACEHOLDERS);
foreach(k, exprvars)
{
if (!tlist_member_ignore_relabel(lfirst(k), tlist))
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.150 2009/04/16 20:42:16 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.151 2009/04/19 19:46:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
void
build_base_rel_tlists(PlannerInfo *root, List *final_tlist)
{
- List *tlist_vars = pull_var_clause((Node *) final_tlist, true);
+ List *tlist_vars = pull_var_clause((Node *) final_tlist,
+ PVC_INCLUDE_PLACEHOLDERS);
if (tlist_vars != NIL)
{
*/
if (bms_membership(relids) == BMS_MULTIPLE)
{
- List *vars = pull_var_clause(clause, true);
+ List *vars = pull_var_clause(clause, PVC_INCLUDE_PLACEHOLDERS);
add_vars_to_targetlist(root, vars, relids);
list_free(vars);
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.253 2009/03/30 17:30:44 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.254 2009/04/19 19:46:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* and window specifications.
*/
sub_tlist = flatten_tlist(tlist);
- extravars = pull_var_clause(parse->havingQual, true);
+ extravars = pull_var_clause(parse->havingQual, PVC_INCLUDE_PLACEHOLDERS);
sub_tlist = add_to_flat_tlist(sub_tlist, extravars);
list_free(extravars);
*need_tlist_eval = false; /* only eval if not flat tlist */
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/prep/preptlist.c,v 1.95 2009/01/01 17:23:44 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/prep/preptlist.c,v 1.96 2009/04/19 19:46:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
List *vars;
ListCell *l;
- vars = pull_var_clause((Node *) parse->returningList, true);
+ vars = pull_var_clause((Node *) parse->returningList,
+ PVC_INCLUDE_PLACEHOLDERS);
foreach(l, vars)
{
Var *var = (Var *) lfirst(l);
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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);
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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);
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
typedef struct
{
List *varlist;
- bool includePlaceHolderVars;
+ PVCPlaceHolderBehavior behavior;
} pull_var_clause_context;
typedef struct
* 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.)
* 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;
}
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);
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.259 2009/02/15 20:16:21 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.260 2009/04/19 19:46:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
ReleaseVariableStats(vardata);
/*
- * Else pull out the component Vars
+ * Else pull out the component Vars. Handle PlaceHolderVars by
+ * recursing into their arguments (effectively assuming that the
+ * PlaceHolderVar doesn't change the number of groups, which boils
+ * down to ignoring the possible addition of nulls to the result set).
*/
- varshere = pull_var_clause(groupexpr, true);
+ varshere = pull_var_clause(groupexpr, PVC_RECURSE_PLACEHOLDERS);
/*
* If we find any variable-free GROUP BY item, then either it is a
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/optimizer/var.h,v 1.40 2009/01/01 17:24:00 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/optimizer/var.h,v 1.41 2009/04/19 19:46:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "nodes/relation.h"
+typedef enum
+{
+ PVC_REJECT_PLACEHOLDERS, /* throw error if PlaceHolderVar found */
+ PVC_INCLUDE_PLACEHOLDERS, /* include PlaceHolderVars in output list */
+ PVC_RECURSE_PLACEHOLDERS /* recurse into PlaceHolderVar argument */
+} PVCPlaceHolderBehavior;
extern Relids pull_varnos(Node *node);
extern void pull_varattnos(Node *node, Bitmapset **varattnos);
extern int locate_var_of_level(Node *node, int levelsup);
extern int locate_var_of_relation(Node *node, int relid, int levelsup);
extern int find_minimum_var_level(Node *node);
-extern List *pull_var_clause(Node *node, bool includePlaceHolderVars);
+extern List *pull_var_clause(Node *node, PVCPlaceHolderBehavior behavior);
extern Node *flatten_join_alias_vars(PlannerInfo *root, Node *node);
#endif /* VAR_H */