PostgreSQL Source Code git master
tlist.h File Reference
#include "nodes/pathnodes.h"
Include dependency graph for tlist.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define create_pathtarget(root, tlist)    set_pathtarget_cost_width(root, make_pathtarget_from_tlist(tlist))
 

Functions

TargetEntrytlist_member (Expr *node, List *targetlist)
 
Listadd_to_flat_tlist (List *tlist, List *exprs)
 
Listget_tlist_exprs (List *tlist, bool includeJunk)
 
bool tlist_same_exprs (List *tlist1, List *tlist2)
 
bool tlist_same_datatypes (List *tlist, List *colTypes, bool junkOK)
 
bool tlist_same_collations (List *tlist, List *colCollations, bool junkOK)
 
void apply_tlist_labeling (List *dest_tlist, List *src_tlist)
 
Oidextract_grouping_ops (List *groupClause)
 
Oidextract_grouping_collations (List *groupClause, List *tlist)
 
AttrNumberextract_grouping_cols (List *groupClause, List *tlist)
 
bool grouping_is_sortable (List *groupClause)
 
bool grouping_is_hashable (List *groupClause)
 
PathTargetmake_pathtarget_from_tlist (List *tlist)
 
Listmake_tlist_from_pathtarget (PathTarget *target)
 
PathTargetcopy_pathtarget (PathTarget *src)
 
PathTargetcreate_empty_pathtarget (void)
 
void add_column_to_pathtarget (PathTarget *target, Expr *expr, Index sortgroupref)
 
void add_new_column_to_pathtarget (PathTarget *target, Expr *expr)
 
void add_new_columns_to_pathtarget (PathTarget *target, List *exprs)
 
void apply_pathtarget_labeling_to_tlist (List *tlist, PathTarget *target)
 
void split_pathtarget_at_srfs (PlannerInfo *root, PathTarget *target, PathTarget *input_target, List **targets, List **targets_contain_srfs)
 
void split_pathtarget_at_srfs_grouping (PlannerInfo *root, PathTarget *target, PathTarget *input_target, List **targets, List **targets_contain_srfs)
 

Macro Definition Documentation

◆ create_pathtarget

#define create_pathtarget (   root,
  tlist 
)     set_pathtarget_cost_width(root, make_pathtarget_from_tlist(tlist))

Definition at line 58 of file tlist.h.

Function Documentation

◆ add_column_to_pathtarget()

void add_column_to_pathtarget ( PathTarget target,
Expr expr,
Index  sortgroupref 
)

Definition at line 704 of file tlist.c.

705{
706 /* Updating the exprs list is easy ... */
707 target->exprs = lappend(target->exprs, expr);
708 /* ... the sortgroupref data, a bit less so */
709 if (target->sortgrouprefs)
710 {
711 int nexprs = list_length(target->exprs);
712
713 /* This might look inefficient, but actually it's usually cheap */
714 target->sortgrouprefs = (Index *)
715 repalloc(target->sortgrouprefs, nexprs * sizeof(Index));
716 target->sortgrouprefs[nexprs - 1] = sortgroupref;
717 }
718 else if (sortgroupref)
719 {
720 /* Adding sortgroupref labeling to a previously unlabeled target */
721 int nexprs = list_length(target->exprs);
722
723 target->sortgrouprefs = (Index *) palloc0(nexprs * sizeof(Index));
724 target->sortgrouprefs[nexprs - 1] = sortgroupref;
725 }
726
727 /*
728 * Reset has_volatile_expr to UNKNOWN. We just leave it up to
729 * contain_volatile_functions to set this properly again. Technically we
730 * could save some effort here and just check the new Expr, but it seems
731 * better to keep the logic for setting this flag in one location rather
732 * than duplicating the logic here.
733 */
736}
unsigned int Index
Definition: c.h:634
List * lappend(List *list, void *datum)
Definition: list.c:339
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1632
void * palloc0(Size size)
Definition: mcxt.c:1417
@ VOLATILITY_NOVOLATILE
Definition: pathnodes.h:1747
@ VOLATILITY_UNKNOWN
Definition: pathnodes.h:1745
static int list_length(const List *l)
Definition: pg_list.h:152
VolatileFunctionStatus has_volatile_expr
Definition: pathnodes.h:1792
List * exprs
Definition: pathnodes.h:1780

References PathTarget::exprs, PathTarget::has_volatile_expr, lappend(), list_length(), palloc0(), repalloc(), VOLATILITY_NOVOLATILE, and VOLATILITY_UNKNOWN.

Referenced by add_new_column_to_pathtarget(), add_sp_item_to_pathtarget(), create_one_window_path(), create_rel_agg_info(), init_grouping_targets(), make_group_input_target(), make_partial_grouping_target(), make_sort_input_target(), and make_window_input_target().

◆ add_new_column_to_pathtarget()

void add_new_column_to_pathtarget ( PathTarget target,
Expr expr 
)

Definition at line 750 of file tlist.c.

751{
752 if (!list_member(target->exprs, expr))
753 add_column_to_pathtarget(target, expr, 0);
754}
bool list_member(const List *list, const void *datum)
Definition: list.c:661
void add_column_to_pathtarget(PathTarget *target, Expr *expr, Index sortgroupref)
Definition: tlist.c:704

References add_column_to_pathtarget(), PathTarget::exprs, and list_member().

Referenced by add_new_columns_to_pathtarget(), and init_grouping_targets().

◆ add_new_columns_to_pathtarget()

void add_new_columns_to_pathtarget ( PathTarget target,
List exprs 
)

Definition at line 761 of file tlist.c.

762{
763 ListCell *lc;
764
765 foreach(lc, exprs)
766 {
767 Expr *expr = (Expr *) lfirst(lc);
768
769 add_new_column_to_pathtarget(target, expr);
770 }
771}
#define lfirst(lc)
Definition: pg_list.h:172
void add_new_column_to_pathtarget(PathTarget *target, Expr *expr)
Definition: tlist.c:750

References add_new_column_to_pathtarget(), and lfirst.

Referenced by add_paths_with_pathkeys_for_rel(), make_group_input_target(), make_partial_grouping_target(), make_sort_input_target(), and make_window_input_target().

◆ add_to_flat_tlist()

List * add_to_flat_tlist ( List tlist,
List exprs 
)

Definition at line 141 of file tlist.c.

142{
143 int next_resno = list_length(tlist) + 1;
144 ListCell *lc;
145
146 foreach(lc, exprs)
147 {
148 Expr *expr = (Expr *) lfirst(lc);
149
150 if (!tlist_member(expr, tlist))
151 {
152 TargetEntry *tle;
153
154 tle = makeTargetEntry(copyObject(expr), /* copy needed?? */
155 next_resno++,
156 NULL,
157 false);
158 tlist = lappend(tlist, tle);
159 }
160 }
161 return tlist;
162}
TargetEntry * makeTargetEntry(Expr *expr, AttrNumber resno, char *resname, bool resjunk)
Definition: makefuncs.c:289
#define copyObject(obj)
Definition: nodes.h:232
TargetEntry * tlist_member(Expr *node, List *targetlist)
Definition: tlist.c:88

References copyObject, lappend(), lfirst, list_length(), makeTargetEntry(), and tlist_member().

Referenced by build_tlist_to_deparse(), and foreign_grouping_ok().

◆ apply_pathtarget_labeling_to_tlist()

void apply_pathtarget_labeling_to_tlist ( List tlist,
PathTarget target 
)

Definition at line 783 of file tlist.c.

784{
785 int i;
786 ListCell *lc;
787
788 /* Nothing to do if PathTarget has no sortgrouprefs data */
789 if (target->sortgrouprefs == NULL)
790 return;
791
792 i = 0;
793 foreach(lc, target->exprs)
794 {
795 Expr *expr = (Expr *) lfirst(lc);
796 TargetEntry *tle;
797
798 if (target->sortgrouprefs[i])
799 {
800 /*
801 * For Vars, use tlist_member_match_var's weakened matching rule;
802 * this allows us to deal with some cases where a set-returning
803 * function has been inlined, so that we now have more knowledge
804 * about what it returns than we did when the original Var was
805 * created. Otherwise, use regular equal() to find the matching
806 * TLE. (In current usage, only the Var case is actually needed;
807 * but it seems best to have sane behavior here for non-Vars too.)
808 */
809 if (expr && IsA(expr, Var))
810 tle = tlist_member_match_var((Var *) expr, tlist);
811 else
812 tle = tlist_member(expr, tlist);
813
814 /*
815 * Complain if noplace for the sortgrouprefs label, or if we'd
816 * have to label a column twice. (The case where it already has
817 * the desired label probably can't happen, but we may as well
818 * allow for it.)
819 */
820 if (!tle)
821 elog(ERROR, "ORDER/GROUP BY expression not found in targetlist");
822 if (tle->ressortgroupref != 0 &&
823 tle->ressortgroupref != target->sortgrouprefs[i])
824 elog(ERROR, "targetlist item has multiple sortgroupref labels");
825
826 tle->ressortgroupref = target->sortgrouprefs[i];
827 }
828 i++;
829 }
830}
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:226
int i
Definition: isn.c:77
#define IsA(nodeptr, _type_)
Definition: nodes.h:164
Index ressortgroupref
Definition: primnodes.h:2245
Definition: primnodes.h:262
static TargetEntry * tlist_member_match_var(Var *var, List *targetlist)
Definition: tlist.c:111

References elog, ERROR, PathTarget::exprs, i, IsA, lfirst, TargetEntry::ressortgroupref, tlist_member(), and tlist_member_match_var().

Referenced by create_projection_plan(), and create_scan_plan().

◆ apply_tlist_labeling()

void apply_tlist_labeling ( List dest_tlist,
List src_tlist 
)

Definition at line 327 of file tlist.c.

328{
329 ListCell *ld,
330 *ls;
331
332 Assert(list_length(dest_tlist) == list_length(src_tlist));
333 forboth(ld, dest_tlist, ls, src_tlist)
334 {
335 TargetEntry *dest_tle = (TargetEntry *) lfirst(ld);
336 TargetEntry *src_tle = (TargetEntry *) lfirst(ls);
337
338 Assert(dest_tle->resno == src_tle->resno);
339 dest_tle->resname = src_tle->resname;
340 dest_tle->ressortgroupref = src_tle->ressortgroupref;
341 dest_tle->resorigtbl = src_tle->resorigtbl;
342 dest_tle->resorigcol = src_tle->resorigcol;
343 dest_tle->resjunk = src_tle->resjunk;
344 }
345}
Assert(PointerIsAligned(start, uint64))
#define forboth(cell1, list1, cell2, list2)
Definition: pg_list.h:518
AttrNumber resno
Definition: primnodes.h:2241

References Assert(), forboth, lfirst, list_length(), TargetEntry::resno, and TargetEntry::ressortgroupref.

Referenced by clean_up_removed_plan_level(), create_modifytable_plan(), and create_plan().

◆ copy_pathtarget()

PathTarget * copy_pathtarget ( PathTarget src)

Definition at line 666 of file tlist.c.

667{
669
670 /* Copy scalar fields */
671 memcpy(dst, src, sizeof(PathTarget));
672 /* Shallow-copy the expression list */
673 dst->exprs = list_copy(src->exprs);
674 /* Duplicate sortgrouprefs if any (if not, the memcpy handled this) */
675 if (src->sortgrouprefs)
676 {
677 Size nbytes = list_length(src->exprs) * sizeof(Index);
678
679 dst->sortgrouprefs = (Index *) palloc(nbytes);
680 memcpy(dst->sortgrouprefs, src->sortgrouprefs, nbytes);
681 }
682 return dst;
683}
size_t Size
Definition: c.h:625
List * list_copy(const List *oldlist)
Definition: list.c:1573
void * palloc(Size size)
Definition: mcxt.c:1387
#define makeNode(_type_)
Definition: nodes.h:161

References PathTarget::exprs, list_copy(), list_length(), makeNode, and palloc().

Referenced by add_paths_with_pathkeys_for_rel(), apply_scanjoin_target_to_paths(), create_one_window_path(), create_partitionwise_grouping_paths(), create_unique_paths(), and reparameterize_path_by_child().

◆ create_empty_pathtarget()

PathTarget * create_empty_pathtarget ( void  )

◆ extract_grouping_collations()

Oid * extract_grouping_collations ( List groupClause,
List tlist 
)

Definition at line 498 of file tlist.c.

499{
500 int numCols = list_length(groupClause);
501 int colno = 0;
502 Oid *grpCollations;
503 ListCell *glitem;
504
505 grpCollations = palloc_array(Oid, numCols);
506
507 foreach(glitem, groupClause)
508 {
509 SortGroupClause *groupcl = (SortGroupClause *) lfirst(glitem);
510 TargetEntry *tle = get_sortgroupclause_tle(groupcl, tlist);
511
512 grpCollations[colno++] = exprCollation((Node *) tle->expr);
513 }
514
515 return grpCollations;
516}
#define palloc_array(type, count)
Definition: fe_memutils.h:76
Oid exprCollation(const Node *expr)
Definition: nodeFuncs.c:821
unsigned int Oid
Definition: postgres_ext.h:32
Definition: nodes.h:135
Expr * expr
Definition: primnodes.h:2239
TargetEntry * get_sortgroupclause_tle(SortGroupClause *sgClause, List *targetList)
Definition: tlist.c:376

References TargetEntry::expr, exprCollation(), get_sortgroupclause_tle(), lfirst, list_length(), and palloc_array.

Referenced by create_agg_plan(), create_group_plan(), and create_groupingsets_plan().

◆ extract_grouping_cols()

AttrNumber * extract_grouping_cols ( List groupClause,
List tlist 
)

Definition at line 523 of file tlist.c.

524{
525 AttrNumber *grpColIdx;
526 int numCols = list_length(groupClause);
527 int colno = 0;
528 ListCell *glitem;
529
530 grpColIdx = palloc_array(AttrNumber, numCols);
531
532 foreach(glitem, groupClause)
533 {
534 SortGroupClause *groupcl = (SortGroupClause *) lfirst(glitem);
535 TargetEntry *tle = get_sortgroupclause_tle(groupcl, tlist);
536
537 grpColIdx[colno++] = tle->resno;
538 }
539
540 return grpColIdx;
541}
int16 AttrNumber
Definition: attnum.h:21

References get_sortgroupclause_tle(), lfirst, list_length(), palloc_array, and TargetEntry::resno.

Referenced by create_agg_plan(), and create_group_plan().

◆ extract_grouping_ops()

Oid * extract_grouping_ops ( List groupClause)

Definition at line 472 of file tlist.c.

473{
474 int numCols = list_length(groupClause);
475 int colno = 0;
476 Oid *groupOperators;
477 ListCell *glitem;
478
479 groupOperators = palloc_array(Oid, numCols);
480
481 foreach(glitem, groupClause)
482 {
483 SortGroupClause *groupcl = (SortGroupClause *) lfirst(glitem);
484
485 groupOperators[colno] = groupcl->eqop;
486 Assert(OidIsValid(groupOperators[colno]));
487 colno++;
488 }
489
490 return groupOperators;
491}
#define OidIsValid(objectId)
Definition: c.h:794

References Assert(), SortGroupClause::eqop, lfirst, list_length(), OidIsValid, and palloc_array.

Referenced by create_agg_plan(), create_group_plan(), and create_groupingsets_plan().

◆ get_tlist_exprs()

List * get_tlist_exprs ( List tlist,
bool  includeJunk 
)

Definition at line 172 of file tlist.c.

173{
174 List *result = NIL;
175 ListCell *l;
176
177 foreach(l, tlist)
178 {
179 TargetEntry *tle = (TargetEntry *) lfirst(l);
180
181 if (tle->resjunk && !includeJunk)
182 continue;
183
184 result = lappend(result, tle->expr);
185 }
186 return result;
187}
#define NIL
Definition: pg_list.h:68
Definition: pg_list.h:54

References TargetEntry::expr, lappend(), lfirst, and NIL.

Referenced by build_setop_child_paths().

◆ grouping_is_hashable()

bool grouping_is_hashable ( List groupClause)

Definition at line 569 of file tlist.c.

570{
571 ListCell *glitem;
572
573 foreach(glitem, groupClause)
574 {
575 SortGroupClause *groupcl = (SortGroupClause *) lfirst(glitem);
576
577 if (!groupcl->hashable)
578 return false;
579 }
580 return true;
581}

References lfirst.

Referenced by create_final_distinct_paths(), create_grouping_paths(), create_partial_distinct_paths(), generate_grouped_paths(), generate_nonunion_paths(), generate_recursion_path(), and generate_union_paths().

◆ grouping_is_sortable()

bool grouping_is_sortable ( List groupClause)

Definition at line 549 of file tlist.c.

550{
551 ListCell *glitem;
552
553 foreach(glitem, groupClause)
554 {
555 SortGroupClause *groupcl = (SortGroupClause *) lfirst(glitem);
556
557 if (!OidIsValid(groupcl->sortop))
558 return false;
559 }
560 return true;
561}

References lfirst, OidIsValid, and SortGroupClause::sortop.

Referenced by adjust_foreign_grouping_path_cost(), create_final_distinct_paths(), create_grouping_paths(), create_partial_distinct_paths(), generate_grouped_paths(), generate_nonunion_paths(), generate_union_paths(), make_pathkeys_for_window(), and standard_qp_callback().

◆ make_pathtarget_from_tlist()

PathTarget * make_pathtarget_from_tlist ( List tlist)

Definition at line 600 of file tlist.c.

601{
602 PathTarget *target = makeNode(PathTarget);
603 int i;
604 ListCell *lc;
605
606 target->sortgrouprefs = (Index *) palloc(list_length(tlist) * sizeof(Index));
607
608 i = 0;
609 foreach(lc, tlist)
610 {
611 TargetEntry *tle = (TargetEntry *) lfirst(lc);
612
613 target->exprs = lappend(target->exprs, tle->expr);
614 target->sortgrouprefs[i] = tle->ressortgroupref;
615 i++;
616 }
617
618 /*
619 * Mark volatility as unknown. The contain_volatile_functions function
620 * will determine if there are any volatile functions when called for the
621 * first time with this PathTarget.
622 */
624
625 return target;
626}

References TargetEntry::expr, PathTarget::exprs, PathTarget::has_volatile_expr, i, lappend(), lfirst, list_length(), makeNode, palloc(), TargetEntry::ressortgroupref, and VOLATILITY_UNKNOWN.

◆ make_tlist_from_pathtarget()

List * make_tlist_from_pathtarget ( PathTarget target)

Definition at line 633 of file tlist.c.

634{
635 List *tlist = NIL;
636 int i;
637 ListCell *lc;
638
639 i = 0;
640 foreach(lc, target->exprs)
641 {
642 Expr *expr = (Expr *) lfirst(lc);
643 TargetEntry *tle;
644
645 tle = makeTargetEntry(expr,
646 i + 1,
647 NULL,
648 false);
649 if (target->sortgrouprefs)
650 tle->ressortgroupref = target->sortgrouprefs[i];
651 tlist = lappend(tlist, tle);
652 i++;
653 }
654
655 return tlist;
656}

References PathTarget::exprs, i, lappend(), lfirst, makeTargetEntry(), NIL, and TargetEntry::ressortgroupref.

Referenced by build_setop_child_paths(), create_unique_paths(), generate_grouped_paths(), and set_subquery_pathlist().

◆ split_pathtarget_at_srfs()

void split_pathtarget_at_srfs ( PlannerInfo root,
PathTarget target,
PathTarget input_target,
List **  targets,
List **  targets_contain_srfs 
)

Definition at line 845 of file tlist.c.

848{
849 split_pathtarget_at_srfs_extended(root, target, input_target,
850 targets, targets_contain_srfs,
851 false);
852}
tree ctl root
Definition: radixtree.h:1857
static void split_pathtarget_at_srfs_extended(PlannerInfo *root, PathTarget *target, PathTarget *input_target, List **targets, List **targets_contain_srfs, bool is_grouping_target)
Definition: tlist.c:942

References root, and split_pathtarget_at_srfs_extended().

Referenced by grouping_planner().

◆ split_pathtarget_at_srfs_grouping()

void split_pathtarget_at_srfs_grouping ( PlannerInfo root,
PathTarget target,
PathTarget input_target,
List **  targets,
List **  targets_contain_srfs 
)

Definition at line 868 of file tlist.c.

871{
872 split_pathtarget_at_srfs_extended(root, target, input_target,
873 targets, targets_contain_srfs,
874 true);
875}

References root, and split_pathtarget_at_srfs_extended().

Referenced by grouping_planner().

◆ tlist_member()

TargetEntry * tlist_member ( Expr node,
List targetlist 
)

Definition at line 88 of file tlist.c.

89{
90 ListCell *temp;
91
92 foreach(temp, targetlist)
93 {
94 TargetEntry *tlentry = (TargetEntry *) lfirst(temp);
95
96 if (equal(node, tlentry->expr))
97 return tlentry;
98 }
99 return NULL;
100}
bool equal(const void *a, const void *b)
Definition: equalfuncs.c:223

References equal(), TargetEntry::expr, and lfirst.

Referenced by add_to_flat_tlist(), apply_pathtarget_labeling_to_tlist(), build_remote_returning(), create_nestloop_plan(), create_unique_paths(), preprocess_targetlist(), rebuild_fdw_scan_tlist(), and search_indexed_tlist_for_non_var().

◆ tlist_same_collations()

bool tlist_same_collations ( List tlist,
List colCollations,
bool  junkOK 
)

Definition at line 291 of file tlist.c.

292{
293 ListCell *l;
294 ListCell *curColColl = list_head(colCollations);
295
296 foreach(l, tlist)
297 {
298 TargetEntry *tle = (TargetEntry *) lfirst(l);
299
300 if (tle->resjunk)
301 {
302 if (!junkOK)
303 return false;
304 }
305 else
306 {
307 if (curColColl == NULL)
308 return false; /* tlist longer than colCollations */
309 if (exprCollation((Node *) tle->expr) != lfirst_oid(curColColl))
310 return false;
311 curColColl = lnext(colCollations, curColColl);
312 }
313 }
314 if (curColColl != NULL)
315 return false; /* tlist shorter than colCollations */
316 return true;
317}
static ListCell * list_head(const List *l)
Definition: pg_list.h:128
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:343
#define lfirst_oid(lc)
Definition: pg_list.h:174

References TargetEntry::expr, exprCollation(), lfirst, lfirst_oid, list_head(), and lnext().

Referenced by recurse_set_operations().

◆ tlist_same_datatypes()

bool tlist_same_datatypes ( List tlist,
List colTypes,
bool  junkOK 
)

Definition at line 257 of file tlist.c.

258{
259 ListCell *l;
260 ListCell *curColType = list_head(colTypes);
261
262 foreach(l, tlist)
263 {
264 TargetEntry *tle = (TargetEntry *) lfirst(l);
265
266 if (tle->resjunk)
267 {
268 if (!junkOK)
269 return false;
270 }
271 else
272 {
273 if (curColType == NULL)
274 return false; /* tlist longer than colTypes */
275 if (exprType((Node *) tle->expr) != lfirst_oid(curColType))
276 return false;
277 curColType = lnext(colTypes, curColType);
278 }
279 }
280 if (curColType != NULL)
281 return false; /* tlist shorter than colTypes */
282 return true;
283}
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42

References TargetEntry::expr, exprType(), lfirst, lfirst_oid, list_head(), and lnext().

Referenced by is_simple_union_all_recurse(), and recurse_set_operations().

◆ tlist_same_exprs()

bool tlist_same_exprs ( List tlist1,
List tlist2 
)

Definition at line 227 of file tlist.c.

228{
229 ListCell *lc1,
230 *lc2;
231
232 if (list_length(tlist1) != list_length(tlist2))
233 return false; /* not same length, so can't match */
234
235 forboth(lc1, tlist1, lc2, tlist2)
236 {
237 TargetEntry *tle1 = (TargetEntry *) lfirst(lc1);
238 TargetEntry *tle2 = (TargetEntry *) lfirst(lc2);
239
240 if (!equal(tle1->expr, tle2->expr))
241 return false;
242 }
243
244 return true;
245}

References equal(), TargetEntry::expr, forboth, lfirst, and list_length().

Referenced by apply_scanjoin_target_to_paths(), change_plan_targetlist(), and create_projection_plan().