PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
var.c File Reference
#include "postgres.h"
#include "access/sysattr.h"
#include "nodes/nodeFuncs.h"
#include "optimizer/prep.h"
#include "optimizer/var.h"
#include "parser/parsetree.h"
#include "rewrite/rewriteManip.h"
Include dependency graph for var.c:

Go to the source code of this file.

Data Structures

struct  pull_varnos_context
 
struct  pull_varattnos_context
 
struct  pull_vars_context
 
struct  locate_var_of_level_context
 
struct  pull_var_clause_context
 
struct  flatten_join_alias_vars_context
 

Functions

static bool pull_varnos_walker (Node *node, pull_varnos_context *context)
 
static bool pull_varattnos_walker (Node *node, pull_varattnos_context *context)
 
static bool pull_vars_walker (Node *node, pull_vars_context *context)
 
static bool contain_var_clause_walker (Node *node, void *context)
 
static bool contain_vars_of_level_walker (Node *node, int *sublevels_up)
 
static bool locate_var_of_level_walker (Node *node, locate_var_of_level_context *context)
 
static bool pull_var_clause_walker (Node *node, pull_var_clause_context *context)
 
static Nodeflatten_join_alias_vars_mutator (Node *node, flatten_join_alias_vars_context *context)
 
static Relids alias_relid_set (PlannerInfo *root, Relids relids)
 
Relids pull_varnos (Node *node)
 
Relids pull_varnos_of_level (Node *node, int levelsup)
 
void pull_varattnos (Node *node, Index varno, Bitmapset **varattnos)
 
Listpull_vars_of_level (Node *node, int levelsup)
 
bool contain_var_clause (Node *node)
 
bool contain_vars_of_level (Node *node, int levelsup)
 
int locate_var_of_level (Node *node, int levelsup)
 
Listpull_var_clause (Node *node, int flags)
 
Nodeflatten_join_alias_vars (PlannerInfo *root, Node *node)
 

Function Documentation

static Relids alias_relid_set ( PlannerInfo root,
Relids  relids 
)
static

Definition at line 826 of file var.c.

References bms_add_member(), bms_join(), bms_next_member(), get_relids_for_join(), PlannerInfo::parse, rt_fetch, Query::rtable, RTE_JOIN, and RangeTblEntry::rtekind.

Referenced by flatten_join_alias_vars_mutator().

827 {
828  Relids result = NULL;
829  int rtindex;
830 
831  rtindex = -1;
832  while ((rtindex = bms_next_member(relids, rtindex)) >= 0)
833  {
834  RangeTblEntry *rte = rt_fetch(rtindex, root->parse->rtable);
835 
836  if (rte->rtekind == RTE_JOIN)
837  result = bms_join(result, get_relids_for_join(root, rtindex));
838  else
839  result = bms_add_member(result, rtindex);
840  }
841  return result;
842 }
Query * parse
Definition: relation.h:155
int bms_next_member(const Bitmapset *a, int prevbit)
Definition: bitmapset.c:937
List * rtable
Definition: parsenodes.h:135
Bitmapset * bms_join(Bitmapset *a, Bitmapset *b)
Definition: bitmapset.c:838
#define rt_fetch(rangetable_index, rangetable)
Definition: parsetree.h:31
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:698
RTEKind rtekind
Definition: parsenodes.h:945
Relids get_relids_for_join(PlannerInfo *root, int joinrelid)
bool contain_var_clause ( Node node)

Definition at line 331 of file var.c.

References contain_var_clause_walker().

Referenced by contain_leaked_vars_walker(), cookDefault(), domainAddConstraint(), interpret_function_parameter_list(), is_pseudo_constant_clause(), and match_clause_to_ordering_op().

332 {
333  return contain_var_clause_walker(node, NULL);
334 }
static bool contain_var_clause_walker(Node *node, void *context)
Definition: var.c:337
static bool contain_var_clause_walker ( Node node,
void *  context 
)
static

Definition at line 337 of file var.c.

References expression_tree_walker(), and IsA.

Referenced by contain_var_clause().

338 {
339  if (node == NULL)
340  return false;
341  if (IsA(node, Var))
342  {
343  if (((Var *) node)->varlevelsup == 0)
344  return true; /* abort the tree traversal and return true */
345  return false;
346  }
347  if (IsA(node, CurrentOfExpr))
348  return true;
349  if (IsA(node, PlaceHolderVar))
350  {
351  if (((PlaceHolderVar *) node)->phlevelsup == 0)
352  return true; /* abort the tree traversal and return true */
353  /* else fall through to check the contained expr */
354  }
355  return expression_tree_walker(node, contain_var_clause_walker, context);
356 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:561
Definition: primnodes.h:163
static bool contain_var_clause_walker(Node *node, void *context)
Definition: var.c:337
bool expression_tree_walker(Node *node, bool(*walker)(), void *context)
Definition: nodeFuncs.c:1834
bool contain_vars_of_level ( Node node,
int  levelsup 
)

Definition at line 369 of file var.c.

References contain_vars_of_level_walker(), and query_or_expression_tree_walker().

Referenced by checkExprIsVarFree(), convert_ANY_sublink_to_join(), convert_EXISTS_sublink_to_join(), convert_EXISTS_to_ANY(), pull_up_simple_values(), pullup_replace_vars_callback(), set_append_rel_size(), transformAExprIn(), transformRangeFunction(), transformRangeTableFunc(), transformSetOperationTree(), and transformValuesClause().

370 {
371  int sublevels_up = levelsup;
372 
375  (void *) &sublevels_up,
376  0);
377 }
bool query_or_expression_tree_walker(Node *node, bool(*walker)(), void *context, int flags)
Definition: nodeFuncs.c:3178
static bool contain_vars_of_level_walker(Node *node, int *sublevels_up)
Definition: var.c:380
static bool contain_vars_of_level_walker ( Node node,
int *  sublevels_up 
)
static

Definition at line 380 of file var.c.

References expression_tree_walker(), IsA, and query_tree_walker().

Referenced by contain_vars_of_level().

381 {
382  if (node == NULL)
383  return false;
384  if (IsA(node, Var))
385  {
386  if (((Var *) node)->varlevelsup == *sublevels_up)
387  return true; /* abort tree traversal and return true */
388  return false;
389  }
390  if (IsA(node, CurrentOfExpr))
391  {
392  if (*sublevels_up == 0)
393  return true;
394  return false;
395  }
396  if (IsA(node, PlaceHolderVar))
397  {
398  if (((PlaceHolderVar *) node)->phlevelsup == *sublevels_up)
399  return true; /* abort the tree traversal and return true */
400  /* else fall through to check the contained expr */
401  }
402  if (IsA(node, Query))
403  {
404  /* Recurse into subselects */
405  bool result;
406 
407  (*sublevels_up)++;
408  result = query_tree_walker((Query *) node,
410  (void *) sublevels_up,
411  0);
412  (*sublevels_up)--;
413  return result;
414  }
415  return expression_tree_walker(node,
417  (void *) sublevels_up);
418 }
bool query_tree_walker(Query *query, bool(*walker)(), void *context, int flags)
Definition: nodeFuncs.c:2245
#define IsA(nodeptr, _type_)
Definition: nodes.h:561
Definition: primnodes.h:163
bool expression_tree_walker(Node *node, bool(*walker)(), void *context)
Definition: nodeFuncs.c:1834
static bool contain_vars_of_level_walker(Node *node, int *sublevels_up)
Definition: var.c:380
Node* flatten_join_alias_vars ( PlannerInfo root,
Node node 
)

Definition at line 670 of file var.c.

References flatten_join_alias_vars_mutator(), Query::hasSubLinks, flatten_join_alias_vars_context::inserted_sublink, PlannerInfo::parse, flatten_join_alias_vars_context::possible_sublink, flatten_join_alias_vars_context::root, and flatten_join_alias_vars_context::sublevels_up.

Referenced by finalize_grouping_exprs_walker(), parseCheckAggregates(), preprocess_expression(), pull_up_simple_subquery(), and subquery_planner().

671 {
673 
674  context.root = root;
675  context.sublevels_up = 0;
676  /* flag whether join aliases could possibly contain SubLinks */
677  context.possible_sublink = root->parse->hasSubLinks;
678  /* if hasSubLinks is already true, no need to work hard */
679  context.inserted_sublink = root->parse->hasSubLinks;
680 
681  return flatten_join_alias_vars_mutator(node, &context);
682 }
Query * parse
Definition: relation.h:155
bool hasSubLinks
Definition: parsenodes.h:126
static Node * flatten_join_alias_vars_mutator(Node *node, flatten_join_alias_vars_context *context)
Definition: var.c:685
PlannerInfo * root
Definition: var.c:63
static Node * flatten_join_alias_vars_mutator ( Node node,
flatten_join_alias_vars_context context 
)
static

Definition at line 685 of file var.c.

References alias_relid_set(), RowExpr::args, Assert, checkExprHasSubLink(), COERCE_IMPLICIT_CAST, Alias::colnames, RowExpr::colnames, copyObject, RangeTblEntry::eref, expression_tree_mutator(), forboth, Query::hasSubLinks, IncrementVarSublevelsUp(), flatten_join_alias_vars_context::inserted_sublink, InvalidAttrNumber, IsA, RangeTblEntry::joinaliasvars, lappend(), lfirst, list_length(), list_nth(), Var::location, RowExpr::location, makeNode, NIL, PlannerInfo::parse, PlaceHolderVar::phlevelsup, PlaceHolderVar::phrels, flatten_join_alias_vars_context::possible_sublink, QTW_IGNORE_JOINALIASES, query_tree_mutator(), flatten_join_alias_vars_context::root, RowExpr::row_format, RowExpr::row_typeid, rt_fetch, Query::rtable, RTE_JOIN, RangeTblEntry::rtekind, flatten_join_alias_vars_context::sublevels_up, Var::varattno, Var::varlevelsup, Var::varno, and Var::vartype.

Referenced by flatten_join_alias_vars().

687 {
688  if (node == NULL)
689  return NULL;
690  if (IsA(node, Var))
691  {
692  Var *var = (Var *) node;
693  RangeTblEntry *rte;
694  Node *newvar;
695 
696  /* No change unless Var belongs to a JOIN of the target level */
697  if (var->varlevelsup != context->sublevels_up)
698  return node; /* no need to copy, really */
699  rte = rt_fetch(var->varno, context->root->parse->rtable);
700  if (rte->rtekind != RTE_JOIN)
701  return node;
702  if (var->varattno == InvalidAttrNumber)
703  {
704  /* Must expand whole-row reference */
705  RowExpr *rowexpr;
706  List *fields = NIL;
707  List *colnames = NIL;
708  AttrNumber attnum;
709  ListCell *lv;
710  ListCell *ln;
711 
712  attnum = 0;
714  forboth(lv, rte->joinaliasvars, ln, rte->eref->colnames)
715  {
716  newvar = (Node *) lfirst(lv);
717  attnum++;
718  /* Ignore dropped columns */
719  if (newvar == NULL)
720  continue;
721  newvar = copyObject(newvar);
722 
723  /*
724  * If we are expanding an alias carried down from an upper
725  * query, must adjust its varlevelsup fields.
726  */
727  if (context->sublevels_up != 0)
728  IncrementVarSublevelsUp(newvar, context->sublevels_up, 0);
729  /* Preserve original Var's location, if possible */
730  if (IsA(newvar, Var))
731  ((Var *) newvar)->location = var->location;
732  /* Recurse in case join input is itself a join */
733  /* (also takes care of setting inserted_sublink if needed) */
734  newvar = flatten_join_alias_vars_mutator(newvar, context);
735  fields = lappend(fields, newvar);
736  /* We need the names of non-dropped columns, too */
737  colnames = lappend(colnames, copyObject((Node *) lfirst(ln)));
738  }
739  rowexpr = makeNode(RowExpr);
740  rowexpr->args = fields;
741  rowexpr->row_typeid = var->vartype;
742  rowexpr->row_format = COERCE_IMPLICIT_CAST;
743  rowexpr->colnames = colnames;
744  rowexpr->location = var->location;
745 
746  return (Node *) rowexpr;
747  }
748 
749  /* Expand join alias reference */
750  Assert(var->varattno > 0);
751  newvar = (Node *) list_nth(rte->joinaliasvars, var->varattno - 1);
752  Assert(newvar != NULL);
753  newvar = copyObject(newvar);
754 
755  /*
756  * If we are expanding an alias carried down from an upper query, must
757  * adjust its varlevelsup fields.
758  */
759  if (context->sublevels_up != 0)
760  IncrementVarSublevelsUp(newvar, context->sublevels_up, 0);
761 
762  /* Preserve original Var's location, if possible */
763  if (IsA(newvar, Var))
764  ((Var *) newvar)->location = var->location;
765 
766  /* Recurse in case join input is itself a join */
767  newvar = flatten_join_alias_vars_mutator(newvar, context);
768 
769  /* Detect if we are adding a sublink to query */
770  if (context->possible_sublink && !context->inserted_sublink)
771  context->inserted_sublink = checkExprHasSubLink(newvar);
772 
773  return newvar;
774  }
775  if (IsA(node, PlaceHolderVar))
776  {
777  /* Copy the PlaceHolderVar node with correct mutation of subnodes */
778  PlaceHolderVar *phv;
779 
782  (void *) context);
783  /* now fix PlaceHolderVar's relid sets */
784  if (phv->phlevelsup == context->sublevels_up)
785  {
786  phv->phrels = alias_relid_set(context->root,
787  phv->phrels);
788  }
789  return (Node *) phv;
790  }
791 
792  if (IsA(node, Query))
793  {
794  /* Recurse into RTE subquery or not-yet-planned sublink subquery */
795  Query *newnode;
796  bool save_inserted_sublink;
797 
798  context->sublevels_up++;
799  save_inserted_sublink = context->inserted_sublink;
800  context->inserted_sublink = ((Query *) node)->hasSubLinks;
801  newnode = query_tree_mutator((Query *) node,
803  (void *) context,
805  newnode->hasSubLinks |= context->inserted_sublink;
806  context->inserted_sublink = save_inserted_sublink;
807  context->sublevels_up--;
808  return (Node *) newnode;
809  }
810  /* Already-planned tree not supported */
811  Assert(!IsA(node, SubPlan));
812  /* Shouldn't need to handle these planner auxiliary nodes here */
813  Assert(!IsA(node, SpecialJoinInfo));
814  Assert(!IsA(node, PlaceHolderInfo));
815  Assert(!IsA(node, MinMaxAggInfo));
816 
818  (void *) context);
819 }
#define NIL
Definition: pg_list.h:69
List * args
Definition: primnodes.h:986
#define IsA(nodeptr, _type_)
Definition: nodes.h:561
Query * parse
Definition: relation.h:155
List * joinaliasvars
Definition: parsenodes.h:989
Index varlevelsup
Definition: primnodes.h:173
Node * expression_tree_mutator(Node *node, Node *(*mutator)(), void *context)
Definition: nodeFuncs.c:2409
#define forboth(cell1, list1, cell2, list2)
Definition: pg_list.h:180
void IncrementVarSublevelsUp(Node *node, int delta_sublevels_up, int min_sublevels_up)
Definition: rewriteManip.c:773
List * colnames
Definition: primnodes.h:43
bool checkExprHasSubLink(Node *node)
Definition: rewriteManip.c:277
Definition: nodes.h:510
AttrNumber varattno
Definition: primnodes.h:168
Definition: primnodes.h:163
List * rtable
Definition: parsenodes.h:135
Relids phrels
Definition: relation.h:1941
List * colnames
Definition: primnodes.h:999
Oid vartype
Definition: primnodes.h:170
int location
Definition: primnodes.h:178
int location
Definition: primnodes.h:1000
void * list_nth(const List *list, int n)
Definition: list.c:410
static Relids alias_relid_set(PlannerInfo *root, Relids relids)
Definition: var.c:826
#define rt_fetch(rangetable_index, rangetable)
Definition: parsetree.h:31
List * lappend(List *list, void *datum)
Definition: list.c:128
Index varno
Definition: primnodes.h:166
#define makeNode(_type_)
Definition: nodes.h:558
#define Assert(condition)
Definition: c.h:681
#define lfirst(lc)
Definition: pg_list.h:106
Oid row_typeid
Definition: primnodes.h:987
static int list_length(const List *l)
Definition: pg_list.h:89
#define InvalidAttrNumber
Definition: attnum.h:23
RTEKind rtekind
Definition: parsenodes.h:945
Index phlevelsup
Definition: relation.h:1943
bool hasSubLinks
Definition: parsenodes.h:126
static Node * flatten_join_alias_vars_mutator(Node *node, flatten_join_alias_vars_context *context)
Definition: var.c:685
Alias * eref
Definition: parsenodes.h:1049
#define copyObject(obj)
Definition: nodes.h:623
PlannerInfo * root
Definition: var.c:63
CoercionForm row_format
Definition: primnodes.h:998
Definition: pg_list.h:45
int16 AttrNumber
Definition: attnum.h:21
Query * query_tree_mutator(Query *query, Node *(*mutator)(), void *context, int flags)
Definition: nodeFuncs.c:3068
#define QTW_IGNORE_JOINALIASES
Definition: nodeFuncs.h:23
int locate_var_of_level ( Node node,
int  levelsup 
)

Definition at line 437 of file var.c.

References locate_var_of_level_walker(), query_or_expression_tree_walker(), locate_var_of_level_context::sublevels_up, and locate_var_of_level_context::var_location.

Referenced by check_agg_arguments(), checkExprIsVarFree(), and transformSetOperationTree().

438 {
440 
441  context.var_location = -1; /* in case we find nothing */
442  context.sublevels_up = levelsup;
443 
446  (void *) &context,
447  0);
448 
449  return context.var_location;
450 }
bool query_or_expression_tree_walker(Node *node, bool(*walker)(), void *context, int flags)
Definition: nodeFuncs.c:3178
static bool locate_var_of_level_walker(Node *node, locate_var_of_level_context *context)
Definition: var.c:453
static bool locate_var_of_level_walker ( Node node,
locate_var_of_level_context context 
)
static

Definition at line 453 of file var.c.

References expression_tree_walker(), IsA, Var::location, query_tree_walker(), locate_var_of_level_context::sublevels_up, locate_var_of_level_context::var_location, and Var::varlevelsup.

Referenced by locate_var_of_level().

455 {
456  if (node == NULL)
457  return false;
458  if (IsA(node, Var))
459  {
460  Var *var = (Var *) node;
461 
462  if (var->varlevelsup == context->sublevels_up &&
463  var->location >= 0)
464  {
465  context->var_location = var->location;
466  return true; /* abort tree traversal and return true */
467  }
468  return false;
469  }
470  if (IsA(node, CurrentOfExpr))
471  {
472  /* since CurrentOfExpr doesn't carry location, nothing we can do */
473  return false;
474  }
475  /* No extra code needed for PlaceHolderVar; just look in contained expr */
476  if (IsA(node, Query))
477  {
478  /* Recurse into subselects */
479  bool result;
480 
481  context->sublevels_up++;
482  result = query_tree_walker((Query *) node,
484  (void *) context,
485  0);
486  context->sublevels_up--;
487  return result;
488  }
489  return expression_tree_walker(node,
491  (void *) context);
492 }
bool query_tree_walker(Query *query, bool(*walker)(), void *context, int flags)
Definition: nodeFuncs.c:2245
#define IsA(nodeptr, _type_)
Definition: nodes.h:561
Index varlevelsup
Definition: primnodes.h:173
Definition: primnodes.h:163
int location
Definition: primnodes.h:178
static bool locate_var_of_level_walker(Node *node, locate_var_of_level_context *context)
Definition: var.c:453
bool expression_tree_walker(Node *node, bool(*walker)(), void *context)
Definition: nodeFuncs.c:1834
List* pull_var_clause ( Node node,
int  flags 
)

Definition at line 535 of file var.c.

References Assert, pull_var_clause_context::flags, NIL, pull_var_clause_walker(), PVC_INCLUDE_AGGREGATES, PVC_INCLUDE_PLACEHOLDERS, PVC_INCLUDE_WINDOWFUNCS, PVC_RECURSE_AGGREGATES, PVC_RECURSE_PLACEHOLDERS, PVC_RECURSE_WINDOWFUNCS, and pull_var_clause_context::varlist.

Referenced by AddRelationNewConstraints(), build_base_rel_tlists(), build_tlist_to_deparse(), CreateTrigger(), distribute_qual_to_rels(), estimate_num_groups(), find_placeholders_in_expr(), fix_placeholder_input_needed_levels(), foreign_grouping_ok(), generate_base_implied_equalities_no_const(), make_group_input_target(), make_partial_grouping_target(), make_sort_input_target(), make_window_input_target(), prepare_sort_from_pathkeys(), preprocess_targetlist(), qual_is_pushdown_safe(), and StoreRelCheck().

536 {
537  pull_var_clause_context context;
538 
539  /* Assert that caller has not specified inconsistent flags */
546 
547  context.varlist = NIL;
548  context.flags = flags;
549 
550  pull_var_clause_walker(node, &context);
551  return context.varlist;
552 }
#define NIL
Definition: pg_list.h:69
#define PVC_RECURSE_AGGREGATES
Definition: var.h:21
#define PVC_RECURSE_PLACEHOLDERS
Definition: var.h:26
#define PVC_INCLUDE_AGGREGATES
Definition: var.h:20
#define PVC_INCLUDE_PLACEHOLDERS
Definition: var.h:24
#define PVC_RECURSE_WINDOWFUNCS
Definition: var.h:23
#define PVC_INCLUDE_WINDOWFUNCS
Definition: var.h:22
#define Assert(condition)
Definition: c.h:681
static bool pull_var_clause_walker(Node *node, pull_var_clause_context *context)
Definition: var.c:555
static bool pull_var_clause_walker ( Node node,
pull_var_clause_context context 
)
static

Definition at line 555 of file var.c.

References elog, ERROR, expression_tree_walker(), pull_var_clause_context::flags, IsA, lappend(), PVC_INCLUDE_AGGREGATES, PVC_INCLUDE_PLACEHOLDERS, PVC_INCLUDE_WINDOWFUNCS, PVC_RECURSE_AGGREGATES, PVC_RECURSE_PLACEHOLDERS, PVC_RECURSE_WINDOWFUNCS, and pull_var_clause_context::varlist.

Referenced by pull_var_clause().

556 {
557  if (node == NULL)
558  return false;
559  if (IsA(node, Var))
560  {
561  if (((Var *) node)->varlevelsup != 0)
562  elog(ERROR, "Upper-level Var found where not expected");
563  context->varlist = lappend(context->varlist, node);
564  return false;
565  }
566  else if (IsA(node, Aggref))
567  {
568  if (((Aggref *) node)->agglevelsup != 0)
569  elog(ERROR, "Upper-level Aggref found where not expected");
570  if (context->flags & PVC_INCLUDE_AGGREGATES)
571  {
572  context->varlist = lappend(context->varlist, node);
573  /* we do NOT descend into the contained expression */
574  return false;
575  }
576  else if (context->flags & PVC_RECURSE_AGGREGATES)
577  {
578  /* fall through to recurse into the aggregate's arguments */
579  }
580  else
581  elog(ERROR, "Aggref found where not expected");
582  }
583  else if (IsA(node, GroupingFunc))
584  {
585  if (((GroupingFunc *) node)->agglevelsup != 0)
586  elog(ERROR, "Upper-level GROUPING found where not expected");
587  if (context->flags & PVC_INCLUDE_AGGREGATES)
588  {
589  context->varlist = lappend(context->varlist, node);
590  /* we do NOT descend into the contained expression */
591  return false;
592  }
593  else if (context->flags & PVC_RECURSE_AGGREGATES)
594  {
595  /*
596  * We do NOT descend into the contained expression, even if the
597  * caller asked for it, because we never actually evaluate it -
598  * the result is driven entirely off the associated GROUP BY
599  * clause, so we never need to extract the actual Vars here.
600  */
601  return false;
602  }
603  else
604  elog(ERROR, "GROUPING found where not expected");
605  }
606  else if (IsA(node, WindowFunc))
607  {
608  /* WindowFuncs have no levelsup field to check ... */
609  if (context->flags & PVC_INCLUDE_WINDOWFUNCS)
610  {
611  context->varlist = lappend(context->varlist, node);
612  /* we do NOT descend into the contained expressions */
613  return false;
614  }
615  else if (context->flags & PVC_RECURSE_WINDOWFUNCS)
616  {
617  /* fall through to recurse into the windowfunc's arguments */
618  }
619  else
620  elog(ERROR, "WindowFunc found where not expected");
621  }
622  else if (IsA(node, PlaceHolderVar))
623  {
624  if (((PlaceHolderVar *) node)->phlevelsup != 0)
625  elog(ERROR, "Upper-level PlaceHolderVar found where not expected");
626  if (context->flags & PVC_INCLUDE_PLACEHOLDERS)
627  {
628  context->varlist = lappend(context->varlist, node);
629  /* we do NOT descend into the contained expression */
630  return false;
631  }
632  else if (context->flags & PVC_RECURSE_PLACEHOLDERS)
633  {
634  /* fall through to recurse into the placeholder's expression */
635  }
636  else
637  elog(ERROR, "PlaceHolderVar found where not expected");
638  }
640  (void *) context);
641 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:561
#define PVC_RECURSE_AGGREGATES
Definition: var.h:21
Definition: primnodes.h:163
#define PVC_RECURSE_PLACEHOLDERS
Definition: var.h:26
#define PVC_INCLUDE_AGGREGATES
Definition: var.h:20
#define PVC_INCLUDE_PLACEHOLDERS
Definition: var.h:24
#define ERROR
Definition: elog.h:43
#define PVC_RECURSE_WINDOWFUNCS
Definition: var.h:23
List * lappend(List *list, void *datum)
Definition: list.c:128
#define PVC_INCLUDE_WINDOWFUNCS
Definition: var.h:22
bool expression_tree_walker(Node *node, bool(*walker)(), void *context)
Definition: nodeFuncs.c:1834
static bool pull_var_clause_walker(Node *node, pull_var_clause_context *context)
Definition: var.c:555
#define elog
Definition: elog.h:219
void pull_varattnos ( Node node,
Index  varno,
Bitmapset **  varattnos 
)

Definition at line 219 of file var.c.

References pull_varattnos_walker(), pull_varattnos_context::varattnos, and pull_varattnos_context::varno.

Referenced by check_index_only(), check_selective_binary_conversion(), ComputePartitionAttrs(), create_foreignscan_plan(), DefineIndex(), deparseReturningList(), is_partition_attr(), postgresGetForeignRelSize(), RelationGetIndexAttrBitmap(), and remove_unused_subquery_outputs().

220 {
221  pull_varattnos_context context;
222 
223  context.varattnos = *varattnos;
224  context.varno = varno;
225 
226  (void) pull_varattnos_walker(node, &context);
227 
228  *varattnos = context.varattnos;
229 }
Bitmapset * varattnos
Definition: var.c:39
static bool pull_varattnos_walker(Node *node, pull_varattnos_context *context)
Definition: var.c:232
static bool pull_varattnos_walker ( Node node,
pull_varattnos_context context 
)
static

Definition at line 232 of file var.c.

References Assert, bms_add_member(), expression_tree_walker(), FirstLowInvalidHeapAttributeNumber, IsA, Var::varattno, pull_varattnos_context::varattnos, Var::varlevelsup, pull_varattnos_context::varno, and Var::varno.

Referenced by pull_varattnos().

233 {
234  if (node == NULL)
235  return false;
236  if (IsA(node, Var))
237  {
238  Var *var = (Var *) node;
239 
240  if (var->varno == context->varno && var->varlevelsup == 0)
241  context->varattnos =
242  bms_add_member(context->varattnos,
244  return false;
245  }
246 
247  /* Should not find an unplanned subquery */
248  Assert(!IsA(node, Query));
249 
251  (void *) context);
252 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:561
Index varlevelsup
Definition: primnodes.h:173
Bitmapset * varattnos
Definition: var.c:39
AttrNumber varattno
Definition: primnodes.h:168
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:28
Definition: primnodes.h:163
static bool pull_varattnos_walker(Node *node, pull_varattnos_context *context)
Definition: var.c:232
Index varno
Definition: primnodes.h:166
#define Assert(condition)
Definition: c.h:681
bool expression_tree_walker(Node *node, bool(*walker)(), void *context)
Definition: nodeFuncs.c:1834
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:698
Relids pull_varnos ( Node node)

Definition at line 95 of file var.c.

References pull_varnos_walker(), query_or_expression_tree_walker(), pull_varnos_context::sublevels_up, and pull_varnos_context::varnos.

Referenced by adjust_rowcompare_for_index(), compute_semijoin_info(), convert_ANY_sublink_to_join(), convert_EXISTS_sublink_to_join(), distribute_qual_to_rels(), examine_variable(), find_placeholder_info(), get_eclass_for_sort_expr(), inheritance_planner(), join_is_removable(), make_outerjoininfo(), make_restrictinfo_internal(), match_clause_to_indexcol(), match_rowcompare_to_indexcol(), NumRelids(), pullup_replace_vars_callback(), and reduce_outer_joins_pass2().

96 {
97  pull_varnos_context context;
98 
99  context.varnos = NULL;
100  context.sublevels_up = 0;
101 
102  /*
103  * Must be prepared to start with a Query or a bare expression tree; if
104  * it's a Query, we don't want to increment sublevels_up.
105  */
108  (void *) &context,
109  0);
110 
111  return context.varnos;
112 }
static bool pull_varnos_walker(Node *node, pull_varnos_context *context)
Definition: var.c:140
int sublevels_up
Definition: var.c:34
Relids varnos
Definition: var.c:33
bool query_or_expression_tree_walker(Node *node, bool(*walker)(), void *context, int flags)
Definition: nodeFuncs.c:3178
Relids pull_varnos_of_level ( Node node,
int  levelsup 
)

Definition at line 120 of file var.c.

References pull_varnos_walker(), query_or_expression_tree_walker(), pull_varnos_context::sublevels_up, and pull_varnos_context::varnos.

Referenced by is_simple_subquery(), and jointree_contains_lateral_outer_refs().

121 {
122  pull_varnos_context context;
123 
124  context.varnos = NULL;
125  context.sublevels_up = levelsup;
126 
127  /*
128  * Must be prepared to start with a Query or a bare expression tree; if
129  * it's a Query, we don't want to increment sublevels_up.
130  */
133  (void *) &context,
134  0);
135 
136  return context.varnos;
137 }
static bool pull_varnos_walker(Node *node, pull_varnos_context *context)
Definition: var.c:140
int sublevels_up
Definition: var.c:34
Relids varnos
Definition: var.c:33
bool query_or_expression_tree_walker(Node *node, bool(*walker)(), void *context, int flags)
Definition: nodeFuncs.c:3178
static bool pull_varnos_walker ( Node node,
pull_varnos_context context 
)
static

Definition at line 140 of file var.c.

References bms_add_member(), bms_add_members(), bms_int_members(), bms_is_empty(), bms_join(), CurrentOfExpr::cvarno, expression_tree_walker(), IsA, PlaceHolderVar::phexpr, PlaceHolderVar::phlevelsup, PlaceHolderVar::phrels, query_tree_walker(), pull_varnos_context::sublevels_up, Var::varlevelsup, Var::varno, and pull_varnos_context::varnos.

Referenced by pull_varnos(), and pull_varnos_of_level().

141 {
142  if (node == NULL)
143  return false;
144  if (IsA(node, Var))
145  {
146  Var *var = (Var *) node;
147 
148  if (var->varlevelsup == context->sublevels_up)
149  context->varnos = bms_add_member(context->varnos, var->varno);
150  return false;
151  }
152  if (IsA(node, CurrentOfExpr))
153  {
154  CurrentOfExpr *cexpr = (CurrentOfExpr *) node;
155 
156  if (context->sublevels_up == 0)
157  context->varnos = bms_add_member(context->varnos, cexpr->cvarno);
158  return false;
159  }
160  if (IsA(node, PlaceHolderVar))
161  {
162  /*
163  * A PlaceHolderVar acts as a variable of its syntactic scope, or
164  * lower than that if it references only a subset of the rels in its
165  * syntactic scope. It might also contain lateral references, but we
166  * should ignore such references when computing the set of varnos in
167  * an expression tree. Also, if the PHV contains no variables within
168  * its syntactic scope, it will be forced to be evaluated exactly at
169  * the syntactic scope, so take that as the relid set.
170  */
171  PlaceHolderVar *phv = (PlaceHolderVar *) node;
172  pull_varnos_context subcontext;
173 
174  subcontext.varnos = NULL;
175  subcontext.sublevels_up = context->sublevels_up;
176  (void) pull_varnos_walker((Node *) phv->phexpr, &subcontext);
177  if (phv->phlevelsup == context->sublevels_up)
178  {
179  subcontext.varnos = bms_int_members(subcontext.varnos,
180  phv->phrels);
181  if (bms_is_empty(subcontext.varnos))
182  context->varnos = bms_add_members(context->varnos,
183  phv->phrels);
184  }
185  context->varnos = bms_join(context->varnos, subcontext.varnos);
186  return false;
187  }
188  if (IsA(node, Query))
189  {
190  /* Recurse into RTE subquery or not-yet-planned sublink subquery */
191  bool result;
192 
193  context->sublevels_up++;
194  result = query_tree_walker((Query *) node, pull_varnos_walker,
195  (void *) context, 0);
196  context->sublevels_up--;
197  return result;
198  }
200  (void *) context);
201 }
bool query_tree_walker(Query *query, bool(*walker)(), void *context, int flags)
Definition: nodeFuncs.c:2245
#define IsA(nodeptr, _type_)
Definition: nodes.h:561
Index varlevelsup
Definition: primnodes.h:173
Definition: nodes.h:510
static bool pull_varnos_walker(Node *node, pull_varnos_context *context)
Definition: var.c:140
int sublevels_up
Definition: var.c:34
Definition: primnodes.h:163
Relids phrels
Definition: relation.h:1941
Expr * phexpr
Definition: relation.h:1940
Bitmapset * bms_join(Bitmapset *a, Bitmapset *b)
Definition: bitmapset.c:838
Relids varnos
Definition: var.c:33
bool bms_is_empty(const Bitmapset *a)
Definition: bitmapset.c:663
Index varno
Definition: primnodes.h:166
bool expression_tree_walker(Node *node, bool(*walker)(), void *context)
Definition: nodeFuncs.c:1834
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:698
Index phlevelsup
Definition: relation.h:1943
Bitmapset * bms_int_members(Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:791
Bitmapset * bms_add_members(Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:755
List* pull_vars_of_level ( Node node,
int  levelsup 
)

Definition at line 263 of file var.c.

References NIL, pull_vars_walker(), query_or_expression_tree_walker(), pull_vars_context::sublevels_up, and pull_vars_context::vars.

Referenced by extract_lateral_references().

264 {
265  pull_vars_context context;
266 
267  context.vars = NIL;
268  context.sublevels_up = levelsup;
269 
270  /*
271  * Must be prepared to start with a Query or a bare expression tree; if
272  * it's a Query, we don't want to increment sublevels_up.
273  */
276  (void *) &context,
277  0);
278 
279  return context.vars;
280 }
int sublevels_up
Definition: var.c:46
#define NIL
Definition: pg_list.h:69
static bool pull_vars_walker(Node *node, pull_vars_context *context)
Definition: var.c:283
List * vars
Definition: var.c:45
bool query_or_expression_tree_walker(Node *node, bool(*walker)(), void *context, int flags)
Definition: nodeFuncs.c:3178
static bool pull_vars_walker ( Node node,
pull_vars_context context 
)
static

Definition at line 283 of file var.c.

References expression_tree_walker(), IsA, lappend(), PlaceHolderVar::phlevelsup, query_tree_walker(), pull_vars_context::sublevels_up, Var::varlevelsup, and pull_vars_context::vars.

Referenced by pull_vars_of_level().

284 {
285  if (node == NULL)
286  return false;
287  if (IsA(node, Var))
288  {
289  Var *var = (Var *) node;
290 
291  if (var->varlevelsup == context->sublevels_up)
292  context->vars = lappend(context->vars, var);
293  return false;
294  }
295  if (IsA(node, PlaceHolderVar))
296  {
297  PlaceHolderVar *phv = (PlaceHolderVar *) node;
298 
299  if (phv->phlevelsup == context->sublevels_up)
300  context->vars = lappend(context->vars, phv);
301  /* we don't want to look into the contained expression */
302  return false;
303  }
304  if (IsA(node, Query))
305  {
306  /* Recurse into RTE subquery or not-yet-planned sublink subquery */
307  bool result;
308 
309  context->sublevels_up++;
310  result = query_tree_walker((Query *) node, pull_vars_walker,
311  (void *) context, 0);
312  context->sublevels_up--;
313  return result;
314  }
316  (void *) context);
317 }
int sublevels_up
Definition: var.c:46
bool query_tree_walker(Query *query, bool(*walker)(), void *context, int flags)
Definition: nodeFuncs.c:2245
#define IsA(nodeptr, _type_)
Definition: nodes.h:561
Index varlevelsup
Definition: primnodes.h:173
static bool pull_vars_walker(Node *node, pull_vars_context *context)
Definition: var.c:283
Definition: primnodes.h:163
List * vars
Definition: var.c:45
List * lappend(List *list, void *datum)
Definition: list.c:128
bool expression_tree_walker(Node *node, bool(*walker)(), void *context)
Definition: nodeFuncs.c:1834
Index phlevelsup
Definition: relation.h:1943