1 /*-------------------------------------------------------------------------
4 * Target list manipulation routines
6 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * src/backend/optimizer/util/tlist.c
13 *-------------------------------------------------------------------------
17 #include "nodes/makefuncs.h"
18 #include "nodes/nodeFuncs.h"
19 #include "optimizer/cost.h"
20 #include "optimizer/optimizer.h"
21 #include "optimizer/tlist.h"
24 /* Test if an expression node represents a SRF call. Beware multiple eval! */
25 #define IS_SRF_CALL(node) \
26 ((IsA(node, FuncExpr) && ((FuncExpr *) (node))->funcretset) || \
27 (IsA(node, OpExpr) && ((OpExpr *) (node))->opretset))
30 * Data structures for split_pathtarget_at_srfs(). To preserve the identity
31 * of sortgroupref items even if they are textually equal(), what we track is
32 * not just bare expressions but expressions plus their sortgroupref indexes.
36 Node *expr; /* some subexpression of a PathTarget */
37 Index sortgroupref; /* its sortgroupref, or 0 if none */
38 } split_pathtarget_item;
42 /* This is a List of bare expressions: */
43 List *input_target_exprs; /* exprs available from input */
44 /* These are Lists of Lists of split_pathtarget_items: */
45 List *level_srfs; /* SRF exprs to evaluate at each level */
46 List *level_input_vars; /* input vars needed at each level */
47 List *level_input_srfs; /* input SRFs needed at each level */
48 /* These are Lists of split_pathtarget_items: */
49 List *current_input_vars; /* vars needed in current subexpr */
50 List *current_input_srfs; /* SRFs needed in current subexpr */
51 /* Auxiliary data for current split_pathtarget_walker traversal: */
52 int current_depth; /* max SRF depth in current subexpr */
53 Index current_sgref; /* current subexpr's sortgroupref, or 0 */
54 } split_pathtarget_context;
56 static bool split_pathtarget_walker(Node *node,
57 split_pathtarget_context *context);
58 static void add_sp_item_to_pathtarget(PathTarget *target,
59 split_pathtarget_item *item);
60 static void add_sp_items_to_pathtarget(PathTarget *target, List *items);
63 /*****************************************************************************
64 * Target list creation and searching utilities
65 *****************************************************************************/
69 * Finds the (first) member of the given tlist whose expression is
70 * equal() to the given expression. Result is NULL if no such member.
73 tlist_member(Expr *node, List *targetlist)
77 foreach(temp, targetlist)
79 TargetEntry *tlentry = (TargetEntry *) lfirst(temp);
81 if (equal(node, tlentry->expr))
88 * tlist_member_ignore_relabel
89 * Same as above, except that we ignore top-level RelabelType nodes
90 * while checking for a match. This is needed for some scenarios
91 * involving binary-compatible sort operations.
94 tlist_member_ignore_relabel(Expr *node, List *targetlist)
98 while (node && IsA(node, RelabelType))
99 node = ((RelabelType *) node)->arg;
101 foreach(temp, targetlist)
103 TargetEntry *tlentry = (TargetEntry *) lfirst(temp);
104 Expr *tlexpr = tlentry->expr;
106 while (tlexpr && IsA(tlexpr, RelabelType))
107 tlexpr = ((RelabelType *) tlexpr)->arg;
109 if (equal(node, tlexpr))
116 * tlist_member_match_var
117 * Same as above, except that we match the provided Var on the basis
118 * of varno/varattno/varlevelsup/vartype only, rather than full equal().
120 * This is needed in some cases where we can't be sure of an exact typmod
121 * match. For safety, though, we insist on vartype match.
124 tlist_member_match_var(Var *var, List *targetlist)
128 foreach(temp, targetlist)
130 TargetEntry *tlentry = (TargetEntry *) lfirst(temp);
131 Var *tlvar = (Var *) tlentry->expr;
133 if (!tlvar || !IsA(tlvar, Var))
135 if (var->varno == tlvar->varno &&
136 var->varattno == tlvar->varattno &&
137 var->varlevelsup == tlvar->varlevelsup &&
138 var->vartype == tlvar->vartype)
146 * Add more items to a flattened tlist (if they're not already in it)
148 * 'tlist' is the flattened tlist
149 * 'exprs' is a list of expressions (usually, but not necessarily, Vars)
151 * Returns the extended tlist.
154 add_to_flat_tlist(List *tlist, List *exprs)
156 int next_resno = list_length(tlist) + 1;
161 Expr *expr = (Expr *) lfirst(lc);
163 if (!tlist_member(expr, tlist))
167 tle = makeTargetEntry(copyObject(expr), /* copy needed?? */
171 tlist = lappend(tlist, tle);
180 * Get just the expression subtrees of a tlist
182 * Resjunk columns are ignored unless includeJunk is true
185 get_tlist_exprs(List *tlist, bool includeJunk)
192 TargetEntry *tle = (TargetEntry *) lfirst(l);
194 if (tle->resjunk && !includeJunk)
197 result = lappend(result, tle->expr);
204 * count_nonjunk_tlist_entries
208 count_nonjunk_tlist_entries(List *tlist)
215 TargetEntry *tle = (TargetEntry *) lfirst(l);
226 * Check whether two target lists contain the same expressions
228 * Note: this function is used to decide whether it's safe to jam a new tlist
229 * into a non-projection-capable plan node. Obviously we can't do that unless
230 * the node's tlist shows it already returns the column values we want.
231 * However, we can ignore the TargetEntry attributes resname, ressortgroupref,
232 * resorigtbl, resorigcol, and resjunk, because those are only labelings that
233 * don't affect the row values computed by the node. (Moreover, if we didn't
234 * ignore them, we'd frequently fail to make the desired optimization, since
235 * the planner tends to not bother to make resname etc. valid in intermediate
236 * plan nodes.) Note that on success, the caller must still jam the desired
237 * tlist into the plan node, else it won't have the desired labeling fields.
240 tlist_same_exprs(List *tlist1, List *tlist2)
245 if (list_length(tlist1) != list_length(tlist2))
246 return false; /* not same length, so can't match */
248 forboth(lc1, tlist1, lc2, tlist2)
250 TargetEntry *tle1 = (TargetEntry *) lfirst(lc1);
251 TargetEntry *tle2 = (TargetEntry *) lfirst(lc2);
253 if (!equal(tle1->expr, tle2->expr))
262 * Does tlist have same output datatypes as listed in colTypes?
264 * Resjunk columns are ignored if junkOK is true; otherwise presence of
265 * a resjunk column will always cause a 'false' result.
267 * Note: currently no callers care about comparing typmods.
270 tlist_same_datatypes(List *tlist, List *colTypes, bool junkOK)
273 ListCell *curColType = list_head(colTypes);
277 TargetEntry *tle = (TargetEntry *) lfirst(l);
286 if (curColType == NULL)
287 return false; /* tlist longer than colTypes */
288 if (exprType((Node *) tle->expr) != lfirst_oid(curColType))
290 curColType = lnext(curColType);
293 if (curColType != NULL)
294 return false; /* tlist shorter than colTypes */
299 * Does tlist have same exposed collations as listed in colCollations?
301 * Identical logic to the above, but for collations.
304 tlist_same_collations(List *tlist, List *colCollations, bool junkOK)
307 ListCell *curColColl = list_head(colCollations);
311 TargetEntry *tle = (TargetEntry *) lfirst(l);
320 if (curColColl == NULL)
321 return false; /* tlist longer than colCollations */
322 if (exprCollation((Node *) tle->expr) != lfirst_oid(curColColl))
324 curColColl = lnext(curColColl);
327 if (curColColl != NULL)
328 return false; /* tlist shorter than colCollations */
333 * apply_tlist_labeling
334 * Apply the TargetEntry labeling attributes of src_tlist to dest_tlist
336 * This is useful for reattaching column names etc to a plan's final output
340 apply_tlist_labeling(List *dest_tlist, List *src_tlist)
345 Assert(list_length(dest_tlist) == list_length(src_tlist));
346 forboth(ld, dest_tlist, ls, src_tlist)
348 TargetEntry *dest_tle = (TargetEntry *) lfirst(ld);
349 TargetEntry *src_tle = (TargetEntry *) lfirst(ls);
351 Assert(dest_tle->resno == src_tle->resno);
352 dest_tle->resname = src_tle->resname;
353 dest_tle->ressortgroupref = src_tle->ressortgroupref;
354 dest_tle->resorigtbl = src_tle->resorigtbl;
355 dest_tle->resorigcol = src_tle->resorigcol;
356 dest_tle->resjunk = src_tle->resjunk;
362 * get_sortgroupref_tle
363 * Find the targetlist entry matching the given SortGroupRef index,
367 get_sortgroupref_tle(Index sortref, List *targetList)
371 foreach(l, targetList)
373 TargetEntry *tle = (TargetEntry *) lfirst(l);
375 if (tle->ressortgroupref == sortref)
379 elog(ERROR, "ORDER/GROUP BY expression not found in targetlist");
380 return NULL; /* keep compiler quiet */
384 * get_sortgroupclause_tle
385 * Find the targetlist entry matching the given SortGroupClause
386 * by ressortgroupref, and return it.
389 get_sortgroupclause_tle(SortGroupClause *sgClause,
392 return get_sortgroupref_tle(sgClause->tleSortGroupRef, targetList);
396 * get_sortgroupclause_expr
397 * Find the targetlist entry matching the given SortGroupClause
398 * by ressortgroupref, and return its expression.
401 get_sortgroupclause_expr(SortGroupClause *sgClause, List *targetList)
403 TargetEntry *tle = get_sortgroupclause_tle(sgClause, targetList);
405 return (Node *) tle->expr;
409 * get_sortgrouplist_exprs
410 * Given a list of SortGroupClauses, build a list
411 * of the referenced targetlist expressions.
414 get_sortgrouplist_exprs(List *sgClauses, List *targetList)
419 foreach(l, sgClauses)
421 SortGroupClause *sortcl = (SortGroupClause *) lfirst(l);
424 sortexpr = get_sortgroupclause_expr(sortcl, targetList);
425 result = lappend(result, sortexpr);
431 /*****************************************************************************
432 * Functions to extract data from a list of SortGroupClauses
434 * These don't really belong in tlist.c, but they are sort of related to the
435 * functions just above, and they don't seem to deserve their own file.
436 *****************************************************************************/
439 * get_sortgroupref_clause
440 * Find the SortGroupClause matching the given SortGroupRef index,
444 get_sortgroupref_clause(Index sortref, List *clauses)
450 SortGroupClause *cl = (SortGroupClause *) lfirst(l);
452 if (cl->tleSortGroupRef == sortref)
456 elog(ERROR, "ORDER/GROUP BY expression not found in list");
457 return NULL; /* keep compiler quiet */
461 * get_sortgroupref_clause_noerr
462 * As above, but return NULL rather than throwing an error if not found.
465 get_sortgroupref_clause_noerr(Index sortref, List *clauses)
471 SortGroupClause *cl = (SortGroupClause *) lfirst(l);
473 if (cl->tleSortGroupRef == sortref)
481 * extract_grouping_ops - make an array of the equality operator OIDs
482 * for a SortGroupClause list
485 extract_grouping_ops(List *groupClause)
487 int numCols = list_length(groupClause);
492 groupOperators = (Oid *) palloc(sizeof(Oid) * numCols);
494 foreach(glitem, groupClause)
496 SortGroupClause *groupcl = (SortGroupClause *) lfirst(glitem);
498 groupOperators[colno] = groupcl->eqop;
499 Assert(OidIsValid(groupOperators[colno]));
503 return groupOperators;
507 * extract_grouping_cols - make an array of the grouping column resnos
508 * for a SortGroupClause list
511 extract_grouping_cols(List *groupClause, List *tlist)
513 AttrNumber *grpColIdx;
514 int numCols = list_length(groupClause);
518 grpColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numCols);
520 foreach(glitem, groupClause)
522 SortGroupClause *groupcl = (SortGroupClause *) lfirst(glitem);
523 TargetEntry *tle = get_sortgroupclause_tle(groupcl, tlist);
525 grpColIdx[colno++] = tle->resno;
532 * grouping_is_sortable - is it possible to implement grouping list by sorting?
534 * This is easy since the parser will have included a sortop if one exists.
537 grouping_is_sortable(List *groupClause)
541 foreach(glitem, groupClause)
543 SortGroupClause *groupcl = (SortGroupClause *) lfirst(glitem);
545 if (!OidIsValid(groupcl->sortop))
552 * grouping_is_hashable - is it possible to implement grouping list by hashing?
554 * We rely on the parser to have set the hashable flag correctly.
557 grouping_is_hashable(List *groupClause)
561 foreach(glitem, groupClause)
563 SortGroupClause *groupcl = (SortGroupClause *) lfirst(glitem);
565 if (!groupcl->hashable)
572 /*****************************************************************************
573 * PathTarget manipulation functions
575 * PathTarget is a somewhat stripped-down version of a full targetlist; it
576 * omits all the TargetEntry decoration except (optionally) sortgroupref data,
577 * and it adds evaluation cost and output data width info.
578 *****************************************************************************/
581 * make_pathtarget_from_tlist
582 * Construct a PathTarget equivalent to the given targetlist.
584 * This leaves the cost and width fields as zeroes. Most callers will want
585 * to use create_pathtarget(), so as to get those set.
588 make_pathtarget_from_tlist(List *tlist)
590 PathTarget *target = makeNode(PathTarget);
594 target->sortgrouprefs = (Index *) palloc(list_length(tlist) * sizeof(Index));
599 TargetEntry *tle = (TargetEntry *) lfirst(lc);
601 target->exprs = lappend(target->exprs, tle->expr);
602 target->sortgrouprefs[i] = tle->ressortgroupref;
610 * make_tlist_from_pathtarget
611 * Construct a targetlist from a PathTarget.
614 make_tlist_from_pathtarget(PathTarget *target)
621 foreach(lc, target->exprs)
623 Expr *expr = (Expr *) lfirst(lc);
626 tle = makeTargetEntry(expr,
630 if (target->sortgrouprefs)
631 tle->ressortgroupref = target->sortgrouprefs[i];
632 tlist = lappend(tlist, tle);
643 * The new PathTarget has its own List cells, but shares the underlying
644 * target expression trees with the old one. We duplicate the List cells
645 * so that items can be added to one target without damaging the other.
648 copy_pathtarget(PathTarget *src)
650 PathTarget *dst = makeNode(PathTarget);
652 /* Copy scalar fields */
653 memcpy(dst, src, sizeof(PathTarget));
654 /* Shallow-copy the expression list */
655 dst->exprs = list_copy(src->exprs);
656 /* Duplicate sortgrouprefs if any (if not, the memcpy handled this) */
657 if (src->sortgrouprefs)
659 Size nbytes = list_length(src->exprs) * sizeof(Index);
661 dst->sortgrouprefs = (Index *) palloc(nbytes);
662 memcpy(dst->sortgrouprefs, src->sortgrouprefs, nbytes);
668 * create_empty_pathtarget
669 * Create an empty (zero columns, zero cost) PathTarget.
672 create_empty_pathtarget(void)
674 /* This is easy, but we don't want callers to hard-wire this ... */
675 return makeNode(PathTarget);
679 * add_column_to_pathtarget
680 * Append a target column to the PathTarget.
682 * As with make_pathtarget_from_tlist, we leave it to the caller to update
683 * the cost and width fields.
686 add_column_to_pathtarget(PathTarget *target, Expr *expr, Index sortgroupref)
688 /* Updating the exprs list is easy ... */
689 target->exprs = lappend(target->exprs, expr);
690 /* ... the sortgroupref data, a bit less so */
691 if (target->sortgrouprefs)
693 int nexprs = list_length(target->exprs);
695 /* This might look inefficient, but actually it's usually cheap */
696 target->sortgrouprefs = (Index *)
697 repalloc(target->sortgrouprefs, nexprs * sizeof(Index));
698 target->sortgrouprefs[nexprs - 1] = sortgroupref;
700 else if (sortgroupref)
702 /* Adding sortgroupref labeling to a previously unlabeled target */
703 int nexprs = list_length(target->exprs);
705 target->sortgrouprefs = (Index *) palloc0(nexprs * sizeof(Index));
706 target->sortgrouprefs[nexprs - 1] = sortgroupref;
711 * add_new_column_to_pathtarget
712 * Append a target column to the PathTarget, but only if it's not
713 * equal() to any pre-existing target expression.
715 * The caller cannot specify a sortgroupref, since it would be unclear how
716 * to merge that with a pre-existing column.
718 * As with make_pathtarget_from_tlist, we leave it to the caller to update
719 * the cost and width fields.
722 add_new_column_to_pathtarget(PathTarget *target, Expr *expr)
724 if (!list_member(target->exprs, expr))
725 add_column_to_pathtarget(target, expr, 0);
729 * add_new_columns_to_pathtarget
730 * Apply add_new_column_to_pathtarget() for each element of the list.
733 add_new_columns_to_pathtarget(PathTarget *target, List *exprs)
739 Expr *expr = (Expr *) lfirst(lc);
741 add_new_column_to_pathtarget(target, expr);
746 * apply_pathtarget_labeling_to_tlist
747 * Apply any sortgrouprefs in the PathTarget to matching tlist entries
749 * Here, we do not assume that the tlist entries are one-for-one with the
750 * PathTarget. The intended use of this function is to deal with cases
751 * where createplan.c has decided to use some other tlist and we have
752 * to identify what matches exist.
755 apply_pathtarget_labeling_to_tlist(List *tlist, PathTarget *target)
760 /* Nothing to do if PathTarget has no sortgrouprefs data */
761 if (target->sortgrouprefs == NULL)
765 foreach(lc, target->exprs)
767 Expr *expr = (Expr *) lfirst(lc);
770 if (target->sortgrouprefs[i])
773 * For Vars, use tlist_member_match_var's weakened matching rule;
774 * this allows us to deal with some cases where a set-returning
775 * function has been inlined, so that we now have more knowledge
776 * about what it returns than we did when the original Var was
777 * created. Otherwise, use regular equal() to find the matching
778 * TLE. (In current usage, only the Var case is actually needed;
779 * but it seems best to have sane behavior here for non-Vars too.)
781 if (expr && IsA(expr, Var))
782 tle = tlist_member_match_var((Var *) expr, tlist);
784 tle = tlist_member(expr, tlist);
787 * Complain if noplace for the sortgrouprefs label, or if we'd
788 * have to label a column twice. (The case where it already has
789 * the desired label probably can't happen, but we may as well
793 elog(ERROR, "ORDER/GROUP BY expression not found in targetlist");
794 if (tle->ressortgroupref != 0 &&
795 tle->ressortgroupref != target->sortgrouprefs[i])
796 elog(ERROR, "targetlist item has multiple sortgroupref labels");
798 tle->ressortgroupref = target->sortgrouprefs[i];
805 * split_pathtarget_at_srfs
806 * Split given PathTarget into multiple levels to position SRFs safely
808 * The executor can only handle set-returning functions that appear at the
809 * top level of the targetlist of a ProjectSet plan node. If we have any SRFs
810 * that are not at top level, we need to split up the evaluation into multiple
811 * plan levels in which each level satisfies this constraint. This function
812 * creates appropriate PathTarget(s) for each level.
814 * As an example, consider the tlist expression
815 * x + srf1(srf2(y + z))
816 * This expression should appear as-is in the top PathTarget, but below that
817 * we must have a PathTarget containing
818 * x, srf1(srf2(y + z))
819 * and below that, another PathTarget containing
821 * and below that, another PathTarget containing
823 * When these tlists are processed by setrefs.c, subexpressions that match
824 * output expressions of the next lower tlist will be replaced by Vars,
825 * so that what the executor gets are tlists looking like
828 * Var1, srf2(Var2 + Var3)
830 * which satisfy the desired property.
833 * srf1(x), srf2(srf3(y))
834 * That must appear as-is in the top PathTarget, but below that we need
836 * That is, each SRF must be computed at a level corresponding to the nesting
837 * depth of SRFs within its arguments.
839 * In some cases, a SRF has already been evaluated in some previous plan level
840 * and we shouldn't expand it again (that is, what we see in the target is
841 * already meant as a reference to a lower subexpression). So, don't expand
842 * any tlist expressions that appear in input_target, if that's not NULL.
844 * It's also important that we preserve any sortgroupref annotation appearing
845 * in the given target, especially on expressions matching input_target items.
847 * The outputs of this function are two parallel lists, one a list of
848 * PathTargets and the other an integer list of bool flags indicating
849 * whether the corresponding PathTarget contains any evaluatable SRFs.
850 * The lists are given in the order they'd need to be evaluated in, with
851 * the "lowest" PathTarget first. So the last list entry is always the
852 * originally given PathTarget, and any entries before it indicate evaluation
853 * levels that must be inserted below it. The first list entry must not
854 * contain any SRFs (other than ones duplicating input_target entries), since
855 * it will typically be attached to a plan node that cannot evaluate SRFs.
857 * Note: using a list for the flags may seem like overkill, since there
858 * are only a few possible patterns for which levels contain SRFs.
859 * But this representation decouples callers from that knowledge.
862 split_pathtarget_at_srfs(PlannerInfo *root,
863 PathTarget *target, PathTarget *input_target,
864 List **targets, List **targets_contain_srfs)
866 split_pathtarget_context context;
868 bool need_extra_projection;
869 List *prev_level_tlist;
877 * It's not unusual for planner.c to pass us two physically identical
878 * targets, in which case we can conclude without further ado that all
879 * expressions are available from the input. (The logic below would
880 * arrive at the same conclusion, but much more tediously.)
882 if (target == input_target)
884 *targets = list_make1(target);
885 *targets_contain_srfs = list_make1_int(false);
889 /* Pass any input_target exprs down to split_pathtarget_walker() */
890 context.input_target_exprs = input_target ? input_target->exprs : NIL;
893 * Initialize with empty level-zero lists, and no levels after that.
894 * (Note: we could dispense with representing level zero explicitly, since
895 * it will never receive any SRFs, but then we'd have to special-case that
896 * level when we get to building result PathTargets. Level zero describes
897 * the SRF-free PathTarget that will be given to the input plan node.)
899 context.level_srfs = list_make1(NIL);
900 context.level_input_vars = list_make1(NIL);
901 context.level_input_srfs = list_make1(NIL);
903 /* Initialize data we'll accumulate across all the target expressions */
904 context.current_input_vars = NIL;
905 context.current_input_srfs = NIL;
907 need_extra_projection = false;
909 /* Scan each expression in the PathTarget looking for SRFs */
911 foreach(lc, target->exprs)
913 Node *node = (Node *) lfirst(lc);
915 /* Tell split_pathtarget_walker about this expr's sortgroupref */
916 context.current_sgref = get_pathtarget_sortgroupref(target, lci);
920 * Find all SRFs and Vars (and Var-like nodes) in this expression, and
921 * enter them into appropriate lists within the context struct.
923 context.current_depth = 0;
924 split_pathtarget_walker(node, &context);
926 /* An expression containing no SRFs is of no further interest */
927 if (context.current_depth == 0)
931 * Track max SRF nesting depth over the whole PathTarget. Also, if
932 * this expression establishes a new max depth, we no longer care
933 * whether previous expressions contained nested SRFs; we can handle
934 * any required projection for them in the final ProjectSet node.
936 if (max_depth < context.current_depth)
938 max_depth = context.current_depth;
939 need_extra_projection = false;
943 * If any maximum-depth SRF is not at the top level of its expression,
944 * we'll need an extra Result node to compute the top-level scalar
947 if (max_depth == context.current_depth && !IS_SRF_CALL(node))
948 need_extra_projection = true;
952 * If we found no SRFs needing evaluation (maybe they were all present in
953 * input_target, or maybe they were all removed by const-simplification),
954 * then no ProjectSet is needed; fall out.
958 *targets = list_make1(target);
959 *targets_contain_srfs = list_make1_int(false);
964 * The Vars and SRF outputs needed at top level can be added to the last
965 * level_input lists if we don't need an extra projection step. If we do
966 * need one, add a SRF-free level to the lists.
968 if (need_extra_projection)
970 context.level_srfs = lappend(context.level_srfs, NIL);
971 context.level_input_vars = lappend(context.level_input_vars,
972 context.current_input_vars);
973 context.level_input_srfs = lappend(context.level_input_srfs,
974 context.current_input_srfs);
978 lc = list_nth_cell(context.level_input_vars, max_depth);
979 lfirst(lc) = list_concat(lfirst(lc), context.current_input_vars);
980 lc = list_nth_cell(context.level_input_srfs, max_depth);
981 lfirst(lc) = list_concat(lfirst(lc), context.current_input_srfs);
985 * Now construct the output PathTargets. The original target can be used
986 * as-is for the last one, but we need to construct a new SRF-free target
987 * representing what the preceding plan node has to emit, as well as a
988 * target for each intermediate ProjectSet node.
990 *targets = *targets_contain_srfs = NIL;
991 prev_level_tlist = NIL;
993 forthree(lc1, context.level_srfs,
994 lc2, context.level_input_vars,
995 lc3, context.level_input_srfs)
997 List *level_srfs = (List *) lfirst(lc1);
1000 if (lnext(lc1) == NULL)
1006 ntarget = create_empty_pathtarget();
1009 * This target should actually evaluate any SRFs of the current
1010 * level, and it needs to propagate forward any Vars needed by
1011 * later levels, as well as SRFs computed earlier and needed by
1014 add_sp_items_to_pathtarget(ntarget, level_srfs);
1015 for_each_cell(lc, lnext(lc2))
1017 List *input_vars = (List *) lfirst(lc);
1019 add_sp_items_to_pathtarget(ntarget, input_vars);
1021 for_each_cell(lc, lnext(lc3))
1023 List *input_srfs = (List *) lfirst(lc);
1026 foreach(lcx, input_srfs)
1028 split_pathtarget_item *item = lfirst(lcx);
1030 if (list_member(prev_level_tlist, item->expr))
1031 add_sp_item_to_pathtarget(ntarget, item);
1034 set_pathtarget_cost_width(root, ntarget);
1038 * Add current target and does-it-compute-SRFs flag to output lists.
1040 *targets = lappend(*targets, ntarget);
1041 *targets_contain_srfs = lappend_int(*targets_contain_srfs,
1042 (level_srfs != NIL));
1044 /* Remember this level's output for next pass */
1045 prev_level_tlist = ntarget->exprs;
1050 * Recursively examine expressions for split_pathtarget_at_srfs.
1052 * Note we make no effort here to prevent duplicate entries in the output
1053 * lists. Duplicates will be gotten rid of later.
1056 split_pathtarget_walker(Node *node, split_pathtarget_context *context)
1062 * A subexpression that matches an expression already computed in
1063 * input_target can be treated like a Var (which indeed it will be after
1064 * setrefs.c gets done with it), even if it's actually a SRF. Record it
1065 * as being needed for the current expression, and ignore any
1066 * substructure. (Note in particular that this preserves the identity of
1067 * any expressions that appear as sortgrouprefs in input_target.)
1069 if (list_member(context->input_target_exprs, node))
1071 split_pathtarget_item *item = palloc(sizeof(split_pathtarget_item));
1074 item->sortgroupref = context->current_sgref;
1075 context->current_input_vars = lappend(context->current_input_vars,
1081 * Vars and Var-like constructs are expected to be gotten from the input,
1082 * too. We assume that these constructs cannot contain any SRFs (if one
1083 * does, there will be an executor failure from a misplaced SRF).
1085 if (IsA(node, Var) ||
1086 IsA(node, PlaceHolderVar) ||
1087 IsA(node, Aggref) ||
1088 IsA(node, GroupingFunc) ||
1089 IsA(node, WindowFunc))
1091 split_pathtarget_item *item = palloc(sizeof(split_pathtarget_item));
1094 item->sortgroupref = context->current_sgref;
1095 context->current_input_vars = lappend(context->current_input_vars,
1101 * If it's a SRF, recursively examine its inputs, determine its level, and
1102 * make appropriate entries in the output lists.
1104 if (IS_SRF_CALL(node))
1106 split_pathtarget_item *item = palloc(sizeof(split_pathtarget_item));
1107 List *save_input_vars = context->current_input_vars;
1108 List *save_input_srfs = context->current_input_srfs;
1109 int save_current_depth = context->current_depth;
1114 item->sortgroupref = context->current_sgref;
1116 context->current_input_vars = NIL;
1117 context->current_input_srfs = NIL;
1118 context->current_depth = 0;
1119 context->current_sgref = 0; /* subexpressions are not sortgroup items */
1121 (void) expression_tree_walker(node, split_pathtarget_walker,
1124 /* Depth is one more than any SRF below it */
1125 srf_depth = context->current_depth + 1;
1127 /* If new record depth, initialize another level of output lists */
1128 if (srf_depth >= list_length(context->level_srfs))
1130 context->level_srfs = lappend(context->level_srfs, NIL);
1131 context->level_input_vars = lappend(context->level_input_vars, NIL);
1132 context->level_input_srfs = lappend(context->level_input_srfs, NIL);
1135 /* Record this SRF as needing to be evaluated at appropriate level */
1136 lc = list_nth_cell(context->level_srfs, srf_depth);
1137 lfirst(lc) = lappend(lfirst(lc), item);
1139 /* Record its inputs as being needed at the same level */
1140 lc = list_nth_cell(context->level_input_vars, srf_depth);
1141 lfirst(lc) = list_concat(lfirst(lc), context->current_input_vars);
1142 lc = list_nth_cell(context->level_input_srfs, srf_depth);
1143 lfirst(lc) = list_concat(lfirst(lc), context->current_input_srfs);
1146 * Restore caller-level state and update it for presence of this SRF.
1147 * Notice we report the SRF itself as being needed for evaluation of
1148 * surrounding expression.
1150 context->current_input_vars = save_input_vars;
1151 context->current_input_srfs = lappend(save_input_srfs, item);
1152 context->current_depth = Max(save_current_depth, srf_depth);
1154 /* We're done here */
1159 * Otherwise, the node is a scalar (non-set) expression, so recurse to
1160 * examine its inputs.
1162 context->current_sgref = 0; /* subexpressions are not sortgroup items */
1163 return expression_tree_walker(node, split_pathtarget_walker,
1168 * Add a split_pathtarget_item to the PathTarget, unless a matching item is
1169 * already present. This is like add_new_column_to_pathtarget, but allows
1170 * for sortgrouprefs to be handled. An item having zero sortgroupref can
1171 * be merged with one that has a sortgroupref, acquiring the latter's
1174 * Note that we don't worry about possibly adding duplicate sortgrouprefs
1175 * to the PathTarget. That would be bad, but it should be impossible unless
1176 * the target passed to split_pathtarget_at_srfs already had duplicates.
1177 * As long as it didn't, we can have at most one split_pathtarget_item with
1178 * any particular nonzero sortgroupref.
1181 add_sp_item_to_pathtarget(PathTarget *target, split_pathtarget_item *item)
1187 * Look for a pre-existing entry that is equal() and does not have a
1188 * conflicting sortgroupref already.
1191 foreach(lc, target->exprs)
1193 Node *node = (Node *) lfirst(lc);
1194 Index sgref = get_pathtarget_sortgroupref(target, lci);
1196 if ((item->sortgroupref == sgref ||
1197 item->sortgroupref == 0 ||
1199 equal(item->expr, node))
1201 /* Found a match. Assign item's sortgroupref if it has one. */
1202 if (item->sortgroupref)
1204 if (target->sortgrouprefs == NULL)
1206 target->sortgrouprefs = (Index *)
1207 palloc0(list_length(target->exprs) * sizeof(Index));
1209 target->sortgrouprefs[lci] = item->sortgroupref;
1217 * No match, so add item to PathTarget. Copy the expr for safety.
1219 add_column_to_pathtarget(target, (Expr *) copyObject(item->expr),
1220 item->sortgroupref);
1224 * Apply add_sp_item_to_pathtarget to each element of list.
1227 add_sp_items_to_pathtarget(PathTarget *target, List *items)
1233 split_pathtarget_item *item = lfirst(lc);
1235 add_sp_item_to_pathtarget(target, item);