PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
var.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * var.c
4  * Var node manipulation routines
5  *
6  * Note: for most purposes, PlaceHolderVar is considered a Var too,
7  * even if its contained expression is variable-free. Also, CurrentOfExpr
8  * is treated as a Var for purposes of determining whether an expression
9  * contains variables.
10  *
11  *
12  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
13  * Portions Copyright (c) 1994, Regents of the University of California
14  *
15  *
16  * IDENTIFICATION
17  * src/backend/optimizer/util/var.c
18  *
19  *-------------------------------------------------------------------------
20  */
21 #include "postgres.h"
22 
23 #include "access/sysattr.h"
24 #include "nodes/nodeFuncs.h"
25 #include "optimizer/prep.h"
26 #include "optimizer/var.h"
27 #include "parser/parsetree.h"
28 #include "rewrite/rewriteManip.h"
29 
30 
31 typedef struct
32 {
36 
37 typedef struct
38 {
42 
43 typedef struct
44 {
48 
49 typedef struct
50 {
54 
55 typedef struct
56 {
58  int flags;
60 
61 typedef struct
62 {
65  bool possible_sublink; /* could aliases include a SubLink? */
66  bool inserted_sublink; /* have we inserted a SubLink? */
68 
69 static bool pull_varnos_walker(Node *node,
70  pull_varnos_context *context);
71 static bool pull_varattnos_walker(Node *node, pull_varattnos_context *context);
72 static bool pull_vars_walker(Node *node, pull_vars_context *context);
73 static bool contain_var_clause_walker(Node *node, void *context);
74 static bool contain_vars_of_level_walker(Node *node, int *sublevels_up);
75 static bool locate_var_of_level_walker(Node *node,
77 static bool pull_var_clause_walker(Node *node,
78  pull_var_clause_context *context);
81 static Relids alias_relid_set(PlannerInfo *root, Relids relids);
82 
83 
84 /*
85  * pull_varnos
86  * Create a set of all the distinct varnos present in a parsetree.
87  * Only varnos that reference level-zero rtable entries are considered.
88  *
89  * NOTE: this is used on not-yet-planned expressions. It may therefore find
90  * bare SubLinks, and if so it needs to recurse into them to look for uplevel
91  * references to the desired rtable level! But when we find a completed
92  * SubPlan, we only need to look at the parameters passed to the subplan.
93  */
94 Relids
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 }
113 
114 /*
115  * pull_varnos_of_level
116  * Create a set of all the distinct varnos present in a parsetree.
117  * Only Vars of the specified level are considered.
118  */
119 Relids
120 pull_varnos_of_level(Node *node, int levelsup)
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 }
138 
139 static bool
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 }
202 
203 
204 /*
205  * pull_varattnos
206  * Find all the distinct attribute numbers present in an expression tree,
207  * and add them to the initial contents of *varattnos.
208  * Only Vars of the given varno and rtable level zero are considered.
209  *
210  * Attribute numbers are offset by FirstLowInvalidHeapAttributeNumber so that
211  * we can include system attributes (e.g., OID) in the bitmap representation.
212  *
213  * Currently, this does not support unplanned subqueries; that is not needed
214  * for current uses. It will handle already-planned SubPlan nodes, though,
215  * looking into only the "testexpr" and the "args" list. (The subplan cannot
216  * contain any other references to Vars of the current level.)
217  */
218 void
219 pull_varattnos(Node *node, Index varno, Bitmapset **varattnos)
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 }
230 
231 static bool
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 }
253 
254 
255 /*
256  * pull_vars_of_level
257  * Create a list of all Vars (and PlaceHolderVars) referencing the
258  * specified query level in the given parsetree.
259  *
260  * Caution: the Vars are not copied, only linked into the list.
261  */
262 List *
263 pull_vars_of_level(Node *node, int levelsup)
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 }
281 
282 static bool
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 }
318 
319 
320 /*
321  * contain_var_clause
322  * Recursively scan a clause to discover whether it contains any Var nodes
323  * (of the current query level).
324  *
325  * Returns true if any varnode found.
326  *
327  * Does not examine subqueries, therefore must only be used after reduction
328  * of sublinks to subplans!
329  */
330 bool
332 {
333  return contain_var_clause_walker(node, NULL);
334 }
335 
336 static bool
337 contain_var_clause_walker(Node *node, void *context)
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 }
357 
358 
359 /*
360  * contain_vars_of_level
361  * Recursively scan a clause to discover whether it contains any Var nodes
362  * of the specified query level.
363  *
364  * Returns true if any such Var found.
365  *
366  * Will recurse into sublinks. Also, may be invoked directly on a Query.
367  */
368 bool
369 contain_vars_of_level(Node *node, int levelsup)
370 {
371  int sublevels_up = levelsup;
372 
375  (void *) &sublevels_up,
376  0);
377 }
378 
379 static bool
380 contain_vars_of_level_walker(Node *node, int *sublevels_up)
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 }
419 
420 
421 /*
422  * locate_var_of_level
423  * Find the parse location of any Var of the specified query level.
424  *
425  * Returns -1 if no such Var is in the querytree, or if they all have
426  * unknown parse location. (The former case is probably caller error,
427  * but we don't bother to distinguish it from the latter case.)
428  *
429  * Will recurse into sublinks. Also, may be invoked directly on a Query.
430  *
431  * Note: it might seem appropriate to merge this functionality into
432  * contain_vars_of_level, but that would complicate that function's API.
433  * Currently, the only uses of this function are for error reporting,
434  * and so shaving cycles probably isn't very important.
435  */
436 int
437 locate_var_of_level(Node *node, int levelsup)
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 }
451 
452 static bool
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 }
493 
494 
495 /*
496  * pull_var_clause
497  * Recursively pulls all Var nodes from an expression clause.
498  *
499  * Aggrefs are handled according to these bits in 'flags':
500  * PVC_INCLUDE_AGGREGATES include Aggrefs in output list
501  * PVC_RECURSE_AGGREGATES recurse into Aggref arguments
502  * neither flag throw error if Aggref found
503  * Vars within an Aggref's expression are included in the result only
504  * when PVC_RECURSE_AGGREGATES is specified.
505  *
506  * WindowFuncs are handled according to these bits in 'flags':
507  * PVC_INCLUDE_WINDOWFUNCS include WindowFuncs in output list
508  * PVC_RECURSE_WINDOWFUNCS recurse into WindowFunc arguments
509  * neither flag throw error if WindowFunc found
510  * Vars within a WindowFunc's expression are included in the result only
511  * when PVC_RECURSE_WINDOWFUNCS is specified.
512  *
513  * PlaceHolderVars are handled according to these bits in 'flags':
514  * PVC_INCLUDE_PLACEHOLDERS include PlaceHolderVars in output list
515  * PVC_RECURSE_PLACEHOLDERS recurse into PlaceHolderVar arguments
516  * neither flag throw error if PlaceHolderVar found
517  * Vars within a PHV's expression are included in the result only
518  * when PVC_RECURSE_PLACEHOLDERS is specified.
519  *
520  * GroupingFuncs are treated mostly like Aggrefs, and so do not need
521  * their own flag bits.
522  *
523  * CurrentOfExpr nodes are ignored in all cases.
524  *
525  * Upper-level vars (with varlevelsup > 0) should not be seen here,
526  * likewise for upper-level Aggrefs and PlaceHolderVars.
527  *
528  * Returns list of nodes found. Note the nodes themselves are not
529  * copied, only referenced.
530  *
531  * Does not examine subqueries, therefore must only be used after reduction
532  * of sublinks to subplans!
533  */
534 List *
535 pull_var_clause(Node *node, int flags)
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 }
553 
554 static bool
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 }
642 
643 
644 /*
645  * flatten_join_alias_vars
646  * Replace Vars that reference JOIN outputs with references to the original
647  * relation variables instead. This allows quals involving such vars to be
648  * pushed down. Whole-row Vars that reference JOIN relations are expanded
649  * into RowExpr constructs that name the individual output Vars. This
650  * is necessary since we will not scan the JOIN as a base relation, which
651  * is the only way that the executor can directly handle whole-row Vars.
652  *
653  * This also adjusts relid sets found in some expression node types to
654  * substitute the contained base rels for any join relid.
655  *
656  * If a JOIN contains sub-selects that have been flattened, its join alias
657  * entries might now be arbitrary expressions, not just Vars. This affects
658  * this function in one important way: we might find ourselves inserting
659  * SubLink expressions into subqueries, and we must make sure that their
660  * Query.hasSubLinks fields get set to TRUE if so. If there are any
661  * SubLinks in the join alias lists, the outer Query should already have
662  * hasSubLinks = TRUE, so this is only relevant to un-flattened subqueries.
663  *
664  * NOTE: this is used on not-yet-planned expressions. We do not expect it
665  * to be applied directly to the whole Query, so if we see a Query to start
666  * with, we do want to increment sublevels_up (this occurs for LATERAL
667  * subqueries).
668  */
669 Node *
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 }
683 
684 static Node *
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 }
820 
821 /*
822  * alias_relid_set: in a set of RT indexes, replace joins by their
823  * underlying base relids
824  */
825 static Relids
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 }
List * pull_vars_of_level(Node *node, int levelsup)
Definition: var.c:263
int sublevels_up
Definition: var.c:46
#define NIL
Definition: pg_list.h:69
bool query_tree_walker(Query *query, bool(*walker)(), void *context, int flags)
Definition: nodeFuncs.c:2268
List * args
Definition: primnodes.h:985
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
Query * parse
Definition: relation.h:155
List * joinaliasvars
Definition: parsenodes.h:968
Index varlevelsup
Definition: primnodes.h:173
Node * expression_tree_mutator(Node *node, Node *(*mutator)(), void *context)
Definition: nodeFuncs.c:2432
#define forboth(cell1, list1, cell2, list2)
Definition: pg_list.h:180
#define PVC_RECURSE_AGGREGATES
Definition: var.h:21
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
Bitmapset * varattnos
Definition: var.c:39
static bool pull_vars_walker(Node *node, pull_vars_context *context)
Definition: var.c:283
int bms_next_member(const Bitmapset *a, int prevbit)
Definition: bitmapset.c:937
Definition: nodes.h:509
AttrNumber varattno
Definition: primnodes.h:168
static bool pull_varnos_walker(Node *node, pull_varnos_context *context)
Definition: var.c:140
int sublevels_up
Definition: var.c:34
return result
Definition: formatting.c:1632
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:28
List * pull_var_clause(Node *node, int flags)
Definition: var.c:535
bool contain_var_clause(Node *node)
Definition: var.c:331
Definition: primnodes.h:163
#define PVC_RECURSE_PLACEHOLDERS
Definition: var.h:26
List * vars
Definition: var.c:45
void pull_varattnos(Node *node, Index varno, Bitmapset **varattnos)
Definition: var.c:219
#define PVC_INCLUDE_AGGREGATES
Definition: var.h:20
#define PVC_INCLUDE_PLACEHOLDERS
Definition: var.h:24
int locate_var_of_level(Node *node, int levelsup)
Definition: var.c:437
List * rtable
Definition: parsenodes.h:135
Relids phrels
Definition: relation.h:1851
static bool pull_varattnos_walker(Node *node, pull_varattnos_context *context)
Definition: var.c:232
#define ERROR
Definition: elog.h:43
List * colnames
Definition: primnodes.h:998
Expr * phexpr
Definition: relation.h:1850
Oid vartype
Definition: primnodes.h:170
Bitmapset * bms_join(Bitmapset *a, Bitmapset *b)
Definition: bitmapset.c:838
int location
Definition: primnodes.h:178
int location
Definition: primnodes.h:999
void * list_nth(const List *list, int n)
Definition: list.c:410
Relids varnos
Definition: var.c:33
static Relids alias_relid_set(PlannerInfo *root, Relids relids)
Definition: var.c:826
#define PVC_RECURSE_WINDOWFUNCS
Definition: var.h:23
#define rt_fetch(rangetable_index, rangetable)
Definition: parsetree.h:31
Relids pull_varnos(Node *node)
Definition: var.c:95
List * lappend(List *list, void *datum)
Definition: list.c:128
bool bms_is_empty(const Bitmapset *a)
Definition: bitmapset.c:663
bool query_or_expression_tree_walker(Node *node, bool(*walker)(), void *context, int flags)
Definition: nodeFuncs.c:3200
Index varno
Definition: primnodes.h:166
static bool contain_var_clause_walker(Node *node, void *context)
Definition: var.c:337
Node * flatten_join_alias_vars(PlannerInfo *root, Node *node)
Definition: var.c:670
static bool locate_var_of_level_walker(Node *node, locate_var_of_level_context *context)
Definition: var.c:453
#define PVC_INCLUDE_WINDOWFUNCS
Definition: var.h:22
unsigned int Index
Definition: c.h:365
#define makeNode(_type_)
Definition: nodes.h:557
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
#define lfirst(lc)
Definition: pg_list.h:106
bool contain_vars_of_level(Node *node, int levelsup)
Definition: var.c:369
bool expression_tree_walker(Node *node, bool(*walker)(), void *context)
Definition: nodeFuncs.c:1865
Oid row_typeid
Definition: primnodes.h:986
static int list_length(const List *l)
Definition: pg_list.h:89
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:698
#define InvalidAttrNumber
Definition: attnum.h:23
static bool contain_vars_of_level_walker(Node *node, int *sublevels_up)
Definition: var.c:380
RTEKind rtekind
Definition: parsenodes.h:929
static bool pull_var_clause_walker(Node *node, pull_var_clause_context *context)
Definition: var.c:555
Index phlevelsup
Definition: relation.h:1853
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
#define elog
Definition: elog.h:219
Alias * eref
Definition: parsenodes.h:1016
#define copyObject(obj)
Definition: nodes.h:621
PlannerInfo * root
Definition: var.c:63
Bitmapset * bms_int_members(Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:791
CoercionForm row_format
Definition: primnodes.h:997
Definition: pg_list.h:45
Relids pull_varnos_of_level(Node *node, int levelsup)
Definition: var.c:120
int16 AttrNumber
Definition: attnum.h:21
Query * query_tree_mutator(Query *query, Node *(*mutator)(), void *context, int flags)
Definition: nodeFuncs.c:3090
Relids get_relids_for_join(PlannerInfo *root, int joinrelid)
Bitmapset * bms_add_members(Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:755
#define QTW_IGNORE_JOINALIASES
Definition: nodeFuncs.h:23