1 /*-------------------------------------------------------------------------
4 * Routines to create the desired plan for processing a query.
5 * Planning is complete, we just need to convert the selected
8 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
13 * src/backend/optimizer/plan/createplan.c
15 *-------------------------------------------------------------------------
22 #include "access/sysattr.h"
23 #include "catalog/pg_class.h"
24 #include "foreign/fdwapi.h"
25 #include "miscadmin.h"
26 #include "nodes/extensible.h"
27 #include "nodes/makefuncs.h"
28 #include "nodes/nodeFuncs.h"
29 #include "optimizer/clauses.h"
30 #include "optimizer/cost.h"
31 #include "optimizer/optimizer.h"
32 #include "optimizer/paramassign.h"
33 #include "optimizer/paths.h"
34 #include "optimizer/placeholder.h"
35 #include "optimizer/plancat.h"
36 #include "optimizer/planmain.h"
37 #include "optimizer/prep.h"
38 #include "optimizer/restrictinfo.h"
39 #include "optimizer/subselect.h"
40 #include "optimizer/tlist.h"
41 #include "parser/parse_clause.h"
42 #include "parser/parsetree.h"
43 #include "partitioning/partprune.h"
44 #include "utils/lsyscache.h"
48 * Flag bits that can appear in the flags argument of create_plan_recurse().
49 * These can be OR-ed together.
51 * CP_EXACT_TLIST specifies that the generated plan node must return exactly
52 * the tlist specified by the path's pathtarget (this overrides both
53 * CP_SMALL_TLIST and CP_LABEL_TLIST, if those are set). Otherwise, the
54 * plan node is allowed to return just the Vars and PlaceHolderVars needed
55 * to evaluate the pathtarget.
57 * CP_SMALL_TLIST specifies that a narrower tlist is preferred. This is
58 * passed down by parent nodes such as Sort and Hash, which will have to
59 * store the returned tuples.
61 * CP_LABEL_TLIST specifies that the plan node must return columns matching
62 * any sortgrouprefs specified in its pathtarget, with appropriate
63 * ressortgroupref labels. This is passed down by parent nodes such as Sort
64 * and Group, which need these values to be available in their inputs.
66 * CP_IGNORE_TLIST specifies that the caller plans to replace the targetlist,
67 * and therefore it doesn't matter a bit what target list gets generated.
69 #define CP_EXACT_TLIST 0x0001 /* Plan must return specified tlist */
70 #define CP_SMALL_TLIST 0x0002 /* Prefer narrower tlists */
71 #define CP_LABEL_TLIST 0x0004 /* tlist must contain sortgrouprefs */
72 #define CP_IGNORE_TLIST 0x0008 /* caller will replace tlist */
75 static Plan
*create_plan_recurse(PlannerInfo
*root
, Path
*best_path
,
77 static Plan
*create_scan_plan(PlannerInfo
*root
, Path
*best_path
,
79 static List
*build_path_tlist(PlannerInfo
*root
, Path
*path
);
80 static bool use_physical_tlist(PlannerInfo
*root
, Path
*path
, int flags
);
81 static List
*get_gating_quals(PlannerInfo
*root
, List
*quals
);
82 static Plan
*create_gating_plan(PlannerInfo
*root
, Path
*path
, Plan
*plan
,
84 static Plan
*create_join_plan(PlannerInfo
*root
, JoinPath
*best_path
);
85 static bool is_async_capable_path(Path
*path
);
86 static Plan
*create_append_plan(PlannerInfo
*root
, AppendPath
*best_path
,
88 static Plan
*create_merge_append_plan(PlannerInfo
*root
, MergeAppendPath
*best_path
,
90 static Result
*create_group_result_plan(PlannerInfo
*root
,
91 GroupResultPath
*best_path
);
92 static ProjectSet
*create_project_set_plan(PlannerInfo
*root
, ProjectSetPath
*best_path
);
93 static Material
*create_material_plan(PlannerInfo
*root
, MaterialPath
*best_path
,
95 static Memoize
*create_memoize_plan(PlannerInfo
*root
, MemoizePath
*best_path
,
97 static Plan
*create_unique_plan(PlannerInfo
*root
, UniquePath
*best_path
,
99 static Gather
*create_gather_plan(PlannerInfo
*root
, GatherPath
*best_path
);
100 static Plan
*create_projection_plan(PlannerInfo
*root
,
101 ProjectionPath
*best_path
,
103 static Plan
*inject_projection_plan(Plan
*subplan
, List
*tlist
, bool parallel_safe
);
104 static Sort
*create_sort_plan(PlannerInfo
*root
, SortPath
*best_path
, int flags
);
105 static IncrementalSort
*create_incrementalsort_plan(PlannerInfo
*root
,
106 IncrementalSortPath
*best_path
, int flags
);
107 static Group
*create_group_plan(PlannerInfo
*root
, GroupPath
*best_path
);
108 static Unique
*create_upper_unique_plan(PlannerInfo
*root
, UpperUniquePath
*best_path
,
110 static Agg
*create_agg_plan(PlannerInfo
*root
, AggPath
*best_path
);
111 static Plan
*create_groupingsets_plan(PlannerInfo
*root
, GroupingSetsPath
*best_path
);
112 static Result
*create_minmaxagg_plan(PlannerInfo
*root
, MinMaxAggPath
*best_path
);
113 static WindowAgg
*create_windowagg_plan(PlannerInfo
*root
, WindowAggPath
*best_path
);
114 static SetOp
*create_setop_plan(PlannerInfo
*root
, SetOpPath
*best_path
,
116 static RecursiveUnion
*create_recursiveunion_plan(PlannerInfo
*root
, RecursiveUnionPath
*best_path
);
117 static LockRows
*create_lockrows_plan(PlannerInfo
*root
, LockRowsPath
*best_path
,
119 static ModifyTable
*create_modifytable_plan(PlannerInfo
*root
, ModifyTablePath
*best_path
);
120 static Limit
*create_limit_plan(PlannerInfo
*root
, LimitPath
*best_path
,
122 static SeqScan
*create_seqscan_plan(PlannerInfo
*root
, Path
*best_path
,
123 List
*tlist
, List
*scan_clauses
);
124 static SampleScan
*create_samplescan_plan(PlannerInfo
*root
, Path
*best_path
,
125 List
*tlist
, List
*scan_clauses
);
126 static Scan
*create_indexscan_plan(PlannerInfo
*root
, IndexPath
*best_path
,
127 List
*tlist
, List
*scan_clauses
, bool indexonly
);
128 static BitmapHeapScan
*create_bitmap_scan_plan(PlannerInfo
*root
,
129 BitmapHeapPath
*best_path
,
130 List
*tlist
, List
*scan_clauses
);
131 static Plan
*create_bitmap_subplan(PlannerInfo
*root
, Path
*bitmapqual
,
132 List
**qual
, List
**indexqual
, List
**indexECs
);
133 static void bitmap_subplan_mark_shared(Plan
*plan
);
134 static TidScan
*create_tidscan_plan(PlannerInfo
*root
, TidPath
*best_path
,
135 List
*tlist
, List
*scan_clauses
);
136 static TidRangeScan
*create_tidrangescan_plan(PlannerInfo
*root
,
137 TidRangePath
*best_path
,
140 static SubqueryScan
*create_subqueryscan_plan(PlannerInfo
*root
,
141 SubqueryScanPath
*best_path
,
142 List
*tlist
, List
*scan_clauses
);
143 static FunctionScan
*create_functionscan_plan(PlannerInfo
*root
, Path
*best_path
,
144 List
*tlist
, List
*scan_clauses
);
145 static ValuesScan
*create_valuesscan_plan(PlannerInfo
*root
, Path
*best_path
,
146 List
*tlist
, List
*scan_clauses
);
147 static TableFuncScan
*create_tablefuncscan_plan(PlannerInfo
*root
, Path
*best_path
,
148 List
*tlist
, List
*scan_clauses
);
149 static CteScan
*create_ctescan_plan(PlannerInfo
*root
, Path
*best_path
,
150 List
*tlist
, List
*scan_clauses
);
151 static NamedTuplestoreScan
*create_namedtuplestorescan_plan(PlannerInfo
*root
,
152 Path
*best_path
, List
*tlist
, List
*scan_clauses
);
153 static Result
*create_resultscan_plan(PlannerInfo
*root
, Path
*best_path
,
154 List
*tlist
, List
*scan_clauses
);
155 static WorkTableScan
*create_worktablescan_plan(PlannerInfo
*root
, Path
*best_path
,
156 List
*tlist
, List
*scan_clauses
);
157 static ForeignScan
*create_foreignscan_plan(PlannerInfo
*root
, ForeignPath
*best_path
,
158 List
*tlist
, List
*scan_clauses
);
159 static CustomScan
*create_customscan_plan(PlannerInfo
*root
,
160 CustomPath
*best_path
,
161 List
*tlist
, List
*scan_clauses
);
162 static NestLoop
*create_nestloop_plan(PlannerInfo
*root
, NestPath
*best_path
);
163 static MergeJoin
*create_mergejoin_plan(PlannerInfo
*root
, MergePath
*best_path
);
164 static HashJoin
*create_hashjoin_plan(PlannerInfo
*root
, HashPath
*best_path
);
165 static Node
*replace_nestloop_params(PlannerInfo
*root
, Node
*expr
);
166 static Node
*replace_nestloop_params_mutator(Node
*node
, PlannerInfo
*root
);
167 static void fix_indexqual_references(PlannerInfo
*root
, IndexPath
*index_path
,
168 List
**stripped_indexquals_p
,
169 List
**fixed_indexquals_p
);
170 static List
*fix_indexorderby_references(PlannerInfo
*root
, IndexPath
*index_path
);
171 static Node
*fix_indexqual_clause(PlannerInfo
*root
,
172 IndexOptInfo
*index
, int indexcol
,
173 Node
*clause
, List
*indexcolnos
);
174 static Node
*fix_indexqual_operand(Node
*node
, IndexOptInfo
*index
, int indexcol
);
175 static List
*get_switched_clauses(List
*clauses
, Relids outerrelids
);
176 static List
*order_qual_clauses(PlannerInfo
*root
, List
*clauses
);
177 static void copy_generic_path_info(Plan
*dest
, Path
*src
);
178 static void copy_plan_costsize(Plan
*dest
, Plan
*src
);
179 static void label_sort_with_costsize(PlannerInfo
*root
, Sort
*plan
,
180 double limit_tuples
);
181 static SeqScan
*make_seqscan(List
*qptlist
, List
*qpqual
, Index scanrelid
);
182 static SampleScan
*make_samplescan(List
*qptlist
, List
*qpqual
, Index scanrelid
,
183 TableSampleClause
*tsc
);
184 static IndexScan
*make_indexscan(List
*qptlist
, List
*qpqual
, Index scanrelid
,
185 Oid indexid
, List
*indexqual
, List
*indexqualorig
,
186 List
*indexorderby
, List
*indexorderbyorig
,
187 List
*indexorderbyops
,
188 ScanDirection indexscandir
);
189 static IndexOnlyScan
*make_indexonlyscan(List
*qptlist
, List
*qpqual
,
190 Index scanrelid
, Oid indexid
,
191 List
*indexqual
, List
*recheckqual
,
194 ScanDirection indexscandir
);
195 static BitmapIndexScan
*make_bitmap_indexscan(Index scanrelid
, Oid indexid
,
197 List
*indexqualorig
);
198 static BitmapHeapScan
*make_bitmap_heapscan(List
*qptlist
,
201 List
*bitmapqualorig
,
203 static TidScan
*make_tidscan(List
*qptlist
, List
*qpqual
, Index scanrelid
,
205 static TidRangeScan
*make_tidrangescan(List
*qptlist
, List
*qpqual
,
206 Index scanrelid
, List
*tidrangequals
);
207 static SubqueryScan
*make_subqueryscan(List
*qptlist
,
211 static FunctionScan
*make_functionscan(List
*qptlist
, List
*qpqual
,
212 Index scanrelid
, List
*functions
, bool funcordinality
);
213 static ValuesScan
*make_valuesscan(List
*qptlist
, List
*qpqual
,
214 Index scanrelid
, List
*values_lists
);
215 static TableFuncScan
*make_tablefuncscan(List
*qptlist
, List
*qpqual
,
216 Index scanrelid
, TableFunc
*tablefunc
);
217 static CteScan
*make_ctescan(List
*qptlist
, List
*qpqual
,
218 Index scanrelid
, int ctePlanId
, int cteParam
);
219 static NamedTuplestoreScan
*make_namedtuplestorescan(List
*qptlist
, List
*qpqual
,
220 Index scanrelid
, char *enrname
);
221 static WorkTableScan
*make_worktablescan(List
*qptlist
, List
*qpqual
,
222 Index scanrelid
, int wtParam
);
223 static RecursiveUnion
*make_recursive_union(List
*tlist
,
229 static BitmapAnd
*make_bitmap_and(List
*bitmapplans
);
230 static BitmapOr
*make_bitmap_or(List
*bitmapplans
);
231 static NestLoop
*make_nestloop(List
*tlist
,
232 List
*joinclauses
, List
*otherclauses
, List
*nestParams
,
233 Plan
*lefttree
, Plan
*righttree
,
234 JoinType jointype
, bool inner_unique
);
235 static HashJoin
*make_hashjoin(List
*tlist
,
236 List
*joinclauses
, List
*otherclauses
,
238 List
*hashoperators
, List
*hashcollations
,
240 Plan
*lefttree
, Plan
*righttree
,
241 JoinType jointype
, bool inner_unique
);
242 static Hash
*make_hash(Plan
*lefttree
,
245 AttrNumber skewColumn
,
247 static MergeJoin
*make_mergejoin(List
*tlist
,
248 List
*joinclauses
, List
*otherclauses
,
251 Oid
*mergecollations
,
252 int *mergestrategies
,
253 bool *mergenullsfirst
,
254 Plan
*lefttree
, Plan
*righttree
,
255 JoinType jointype
, bool inner_unique
,
256 bool skip_mark_restore
);
257 static Sort
*make_sort(Plan
*lefttree
, int numCols
,
258 AttrNumber
*sortColIdx
, Oid
*sortOperators
,
259 Oid
*collations
, bool *nullsFirst
);
260 static IncrementalSort
*make_incrementalsort(Plan
*lefttree
,
261 int numCols
, int nPresortedCols
,
262 AttrNumber
*sortColIdx
, Oid
*sortOperators
,
263 Oid
*collations
, bool *nullsFirst
);
264 static Plan
*prepare_sort_from_pathkeys(Plan
*lefttree
, List
*pathkeys
,
266 const AttrNumber
*reqColIdx
,
267 bool adjust_tlist_in_place
,
269 AttrNumber
**p_sortColIdx
,
270 Oid
**p_sortOperators
,
272 bool **p_nullsFirst
);
273 static Sort
*make_sort_from_pathkeys(Plan
*lefttree
, List
*pathkeys
,
275 static IncrementalSort
*make_incrementalsort_from_pathkeys(Plan
*lefttree
,
276 List
*pathkeys
, Relids relids
, int nPresortedCols
);
277 static Sort
*make_sort_from_groupcols(List
*groupcls
,
278 AttrNumber
*grpColIdx
,
280 static Material
*make_material(Plan
*lefttree
);
281 static Memoize
*make_memoize(Plan
*lefttree
, Oid
*hashoperators
,
282 Oid
*collations
, List
*param_exprs
,
283 bool singlerow
, bool binary_mode
,
284 uint32 est_entries
, Bitmapset
*keyparamids
);
285 static WindowAgg
*make_windowagg(List
*tlist
, Index winref
,
286 int partNumCols
, AttrNumber
*partColIdx
, Oid
*partOperators
, Oid
*partCollations
,
287 int ordNumCols
, AttrNumber
*ordColIdx
, Oid
*ordOperators
, Oid
*ordCollations
,
288 int frameOptions
, Node
*startOffset
, Node
*endOffset
,
289 Oid startInRangeFunc
, Oid endInRangeFunc
,
290 Oid inRangeColl
, bool inRangeAsc
, bool inRangeNullsFirst
,
292 static Group
*make_group(List
*tlist
, List
*qual
, int numGroupCols
,
293 AttrNumber
*grpColIdx
, Oid
*grpOperators
, Oid
*grpCollations
,
295 static Unique
*make_unique_from_sortclauses(Plan
*lefttree
, List
*distinctList
);
296 static Unique
*make_unique_from_pathkeys(Plan
*lefttree
,
297 List
*pathkeys
, int numCols
);
298 static Gather
*make_gather(List
*qptlist
, List
*qpqual
,
299 int nworkers
, int rescan_param
, bool single_copy
, Plan
*subplan
);
300 static SetOp
*make_setop(SetOpCmd cmd
, SetOpStrategy strategy
, Plan
*lefttree
,
301 List
*distinctList
, AttrNumber flagColIdx
, int firstFlag
,
303 static LockRows
*make_lockrows(Plan
*lefttree
, List
*rowMarks
, int epqParam
);
304 static Result
*make_result(List
*tlist
, Node
*resconstantqual
, Plan
*subplan
);
305 static ProjectSet
*make_project_set(List
*tlist
, Plan
*subplan
);
306 static ModifyTable
*make_modifytable(PlannerInfo
*root
, Plan
*subplan
,
307 CmdType operation
, bool canSetTag
,
308 Index nominalRelation
, Index rootRelation
,
309 bool partColsUpdated
,
310 List
*resultRelations
,
311 List
*updateColnosLists
,
312 List
*withCheckOptionLists
, List
*returningLists
,
313 List
*rowMarks
, OnConflictExpr
*onconflict
, int epqParam
);
314 static GatherMerge
*create_gather_merge_plan(PlannerInfo
*root
,
315 GatherMergePath
*best_path
);
320 * Creates the access plan for a query by recursively processing the
321 * desired tree of pathnodes, starting at the node 'best_path'. For
322 * every pathnode found, we create a corresponding plan node containing
323 * appropriate id, target list, and qualification information.
325 * The tlists and quals in the plan tree are still in planner format,
326 * ie, Vars still correspond to the parser's numbering. This will be
327 * fixed later by setrefs.c.
329 * best_path is the best access path
331 * Returns a Plan tree.
334 create_plan(PlannerInfo
*root
, Path
*best_path
)
338 /* plan_params should not be in use in current query level */
339 Assert(root
->plan_params
== NIL
);
341 /* Initialize this module's workspace in PlannerInfo */
342 root
->curOuterRels
= NULL
;
343 root
->curOuterParams
= NIL
;
345 /* Recursively process the path tree, demanding the correct tlist result */
346 plan
= create_plan_recurse(root
, best_path
, CP_EXACT_TLIST
);
349 * Make sure the topmost plan node's targetlist exposes the original
350 * column names and other decorative info. Targetlists generated within
351 * the planner don't bother with that stuff, but we must have it on the
352 * top-level tlist seen at execution time. However, ModifyTable plan
353 * nodes don't have a tlist matching the querytree targetlist.
355 if (!IsA(plan
, ModifyTable
))
356 apply_tlist_labeling(plan
->targetlist
, root
->processed_tlist
);
359 * Attach any initPlans created in this query level to the topmost plan
360 * node. (In principle the initplans could go in any plan node at or
361 * above where they're referenced, but there seems no reason to put them
362 * any lower than the topmost node for the query level. Also, see
363 * comments for SS_finalize_plan before you try to change this.)
365 SS_attach_initplans(root
, plan
);
367 /* Check we successfully assigned all NestLoopParams to plan nodes */
368 if (root
->curOuterParams
!= NIL
)
369 elog(ERROR
, "failed to assign all NestLoopParams to plan nodes");
372 * Reset plan_params to ensure param IDs used for nestloop params are not
375 root
->plan_params
= NIL
;
381 * create_plan_recurse
382 * Recursive guts of create_plan().
385 create_plan_recurse(PlannerInfo
*root
, Path
*best_path
, int flags
)
389 /* Guard against stack overflow due to overly complex plans */
392 switch (best_path
->pathtype
)
397 case T_IndexOnlyScan
:
398 case T_BitmapHeapScan
:
403 case T_TableFuncScan
:
406 case T_WorkTableScan
:
407 case T_NamedTuplestoreScan
:
410 plan
= create_scan_plan(root
, best_path
, flags
);
415 plan
= create_join_plan(root
,
416 (JoinPath
*) best_path
);
419 plan
= create_append_plan(root
,
420 (AppendPath
*) best_path
,
424 plan
= create_merge_append_plan(root
,
425 (MergeAppendPath
*) best_path
,
429 if (IsA(best_path
, ProjectionPath
))
431 plan
= create_projection_plan(root
,
432 (ProjectionPath
*) best_path
,
435 else if (IsA(best_path
, MinMaxAggPath
))
437 plan
= (Plan
*) create_minmaxagg_plan(root
,
438 (MinMaxAggPath
*) best_path
);
440 else if (IsA(best_path
, GroupResultPath
))
442 plan
= (Plan
*) create_group_result_plan(root
,
443 (GroupResultPath
*) best_path
);
447 /* Simple RTE_RESULT base relation */
448 Assert(IsA(best_path
, Path
));
449 plan
= create_scan_plan(root
, best_path
, flags
);
453 plan
= (Plan
*) create_project_set_plan(root
,
454 (ProjectSetPath
*) best_path
);
457 plan
= (Plan
*) create_material_plan(root
,
458 (MaterialPath
*) best_path
,
462 plan
= (Plan
*) create_memoize_plan(root
,
463 (MemoizePath
*) best_path
,
467 if (IsA(best_path
, UpperUniquePath
))
469 plan
= (Plan
*) create_upper_unique_plan(root
,
470 (UpperUniquePath
*) best_path
,
475 Assert(IsA(best_path
, UniquePath
));
476 plan
= create_unique_plan(root
,
477 (UniquePath
*) best_path
,
482 plan
= (Plan
*) create_gather_plan(root
,
483 (GatherPath
*) best_path
);
486 plan
= (Plan
*) create_sort_plan(root
,
487 (SortPath
*) best_path
,
490 case T_IncrementalSort
:
491 plan
= (Plan
*) create_incrementalsort_plan(root
,
492 (IncrementalSortPath
*) best_path
,
496 plan
= (Plan
*) create_group_plan(root
,
497 (GroupPath
*) best_path
);
500 if (IsA(best_path
, GroupingSetsPath
))
501 plan
= create_groupingsets_plan(root
,
502 (GroupingSetsPath
*) best_path
);
505 Assert(IsA(best_path
, AggPath
));
506 plan
= (Plan
*) create_agg_plan(root
,
507 (AggPath
*) best_path
);
511 plan
= (Plan
*) create_windowagg_plan(root
,
512 (WindowAggPath
*) best_path
);
515 plan
= (Plan
*) create_setop_plan(root
,
516 (SetOpPath
*) best_path
,
519 case T_RecursiveUnion
:
520 plan
= (Plan
*) create_recursiveunion_plan(root
,
521 (RecursiveUnionPath
*) best_path
);
524 plan
= (Plan
*) create_lockrows_plan(root
,
525 (LockRowsPath
*) best_path
,
529 plan
= (Plan
*) create_modifytable_plan(root
,
530 (ModifyTablePath
*) best_path
);
533 plan
= (Plan
*) create_limit_plan(root
,
534 (LimitPath
*) best_path
,
538 plan
= (Plan
*) create_gather_merge_plan(root
,
539 (GatherMergePath
*) best_path
);
542 elog(ERROR
, "unrecognized node type: %d",
543 (int) best_path
->pathtype
);
544 plan
= NULL
; /* keep compiler quiet */
553 * Create a scan plan for the parent relation of 'best_path'.
556 create_scan_plan(PlannerInfo
*root
, Path
*best_path
, int flags
)
558 RelOptInfo
*rel
= best_path
->parent
;
560 List
*gating_clauses
;
565 * Extract the relevant restriction clauses from the parent relation. The
566 * executor must apply all these restrictions during the scan, except for
567 * pseudoconstants which we'll take care of below.
569 * If this is a plain indexscan or index-only scan, we need not consider
570 * restriction clauses that are implied by the index's predicate, so use
571 * indrestrictinfo not baserestrictinfo. Note that we can't do that for
572 * bitmap indexscans, since there's not necessarily a single index
573 * involved; but it doesn't matter since create_bitmap_scan_plan() will be
574 * able to get rid of such clauses anyway via predicate proof.
576 switch (best_path
->pathtype
)
579 case T_IndexOnlyScan
:
580 scan_clauses
= castNode(IndexPath
, best_path
)->indexinfo
->indrestrictinfo
;
583 scan_clauses
= rel
->baserestrictinfo
;
588 * If this is a parameterized scan, we also need to enforce all the join
589 * clauses available from the outer relation(s).
591 * For paranoia's sake, don't modify the stored baserestrictinfo list.
593 if (best_path
->param_info
)
594 scan_clauses
= list_concat_copy(scan_clauses
,
595 best_path
->param_info
->ppi_clauses
);
598 * Detect whether we have any pseudoconstant quals to deal with. Then, if
599 * we'll need a gating Result node, it will be able to project, so there
600 * are no requirements on the child's tlist.
602 gating_clauses
= get_gating_quals(root
, scan_clauses
);
607 * For table scans, rather than using the relation targetlist (which is
608 * only those Vars actually needed by the query), we prefer to generate a
609 * tlist containing all Vars in order. This will allow the executor to
610 * optimize away projection of the table tuples, if possible.
612 * But if the caller is going to ignore our tlist anyway, then don't
613 * bother generating one at all. We use an exact equality test here, so
614 * that this only applies when CP_IGNORE_TLIST is the only flag set.
616 if (flags
== CP_IGNORE_TLIST
)
620 else if (use_physical_tlist(root
, best_path
, flags
))
622 if (best_path
->pathtype
== T_IndexOnlyScan
)
624 /* For index-only scan, the preferred tlist is the index's */
625 tlist
= copyObject(((IndexPath
*) best_path
)->indexinfo
->indextlist
);
628 * Transfer sortgroupref data to the replacement tlist, if
629 * requested (use_physical_tlist checked that this will work).
631 if (flags
& CP_LABEL_TLIST
)
632 apply_pathtarget_labeling_to_tlist(tlist
, best_path
->pathtarget
);
636 tlist
= build_physical_tlist(root
, rel
);
639 /* Failed because of dropped cols, so use regular method */
640 tlist
= build_path_tlist(root
, best_path
);
644 /* As above, transfer sortgroupref data to replacement tlist */
645 if (flags
& CP_LABEL_TLIST
)
646 apply_pathtarget_labeling_to_tlist(tlist
, best_path
->pathtarget
);
652 tlist
= build_path_tlist(root
, best_path
);
655 switch (best_path
->pathtype
)
658 plan
= (Plan
*) create_seqscan_plan(root
,
665 plan
= (Plan
*) create_samplescan_plan(root
,
672 plan
= (Plan
*) create_indexscan_plan(root
,
673 (IndexPath
*) best_path
,
679 case T_IndexOnlyScan
:
680 plan
= (Plan
*) create_indexscan_plan(root
,
681 (IndexPath
*) best_path
,
687 case T_BitmapHeapScan
:
688 plan
= (Plan
*) create_bitmap_scan_plan(root
,
689 (BitmapHeapPath
*) best_path
,
695 plan
= (Plan
*) create_tidscan_plan(root
,
696 (TidPath
*) best_path
,
702 plan
= (Plan
*) create_tidrangescan_plan(root
,
703 (TidRangePath
*) best_path
,
709 plan
= (Plan
*) create_subqueryscan_plan(root
,
710 (SubqueryScanPath
*) best_path
,
716 plan
= (Plan
*) create_functionscan_plan(root
,
722 case T_TableFuncScan
:
723 plan
= (Plan
*) create_tablefuncscan_plan(root
,
730 plan
= (Plan
*) create_valuesscan_plan(root
,
737 plan
= (Plan
*) create_ctescan_plan(root
,
743 case T_NamedTuplestoreScan
:
744 plan
= (Plan
*) create_namedtuplestorescan_plan(root
,
751 plan
= (Plan
*) create_resultscan_plan(root
,
757 case T_WorkTableScan
:
758 plan
= (Plan
*) create_worktablescan_plan(root
,
765 plan
= (Plan
*) create_foreignscan_plan(root
,
766 (ForeignPath
*) best_path
,
772 plan
= (Plan
*) create_customscan_plan(root
,
773 (CustomPath
*) best_path
,
779 elog(ERROR
, "unrecognized node type: %d",
780 (int) best_path
->pathtype
);
781 plan
= NULL
; /* keep compiler quiet */
786 * If there are any pseudoconstant clauses attached to this node, insert a
787 * gating Result node that evaluates the pseudoconstants as one-time
791 plan
= create_gating_plan(root
, best_path
, plan
, gating_clauses
);
797 * Build a target list (ie, a list of TargetEntry) for the Path's output.
799 * This is almost just make_tlist_from_pathtarget(), but we also have to
800 * deal with replacing nestloop params.
803 build_path_tlist(PlannerInfo
*root
, Path
*path
)
806 Index
*sortgrouprefs
= path
->pathtarget
->sortgrouprefs
;
810 foreach(v
, path
->pathtarget
->exprs
)
812 Node
*node
= (Node
*) lfirst(v
);
816 * If it's a parameterized path, there might be lateral references in
817 * the tlist, which need to be replaced with Params. There's no need
818 * to remake the TargetEntry nodes, so apply this to each list item
821 if (path
->param_info
)
822 node
= replace_nestloop_params(root
, node
);
824 tle
= makeTargetEntry((Expr
*) node
,
829 tle
->ressortgroupref
= sortgrouprefs
[resno
- 1];
831 tlist
= lappend(tlist
, tle
);
839 * Decide whether to use a tlist matching relation structure,
840 * rather than only those Vars actually referenced.
843 use_physical_tlist(PlannerInfo
*root
, Path
*path
, int flags
)
845 RelOptInfo
*rel
= path
->parent
;
850 * Forget it if either exact tlist or small tlist is demanded.
852 if (flags
& (CP_EXACT_TLIST
| CP_SMALL_TLIST
))
856 * We can do this for real relation scans, subquery scans, function scans,
857 * tablefunc scans, values scans, and CTE scans (but not for, eg, joins).
859 if (rel
->rtekind
!= RTE_RELATION
&&
860 rel
->rtekind
!= RTE_SUBQUERY
&&
861 rel
->rtekind
!= RTE_FUNCTION
&&
862 rel
->rtekind
!= RTE_TABLEFUNC
&&
863 rel
->rtekind
!= RTE_VALUES
&&
864 rel
->rtekind
!= RTE_CTE
)
868 * Can't do it with inheritance cases either (mainly because Append
869 * doesn't project; this test may be unnecessary now that
870 * create_append_plan instructs its children to return an exact tlist).
872 if (rel
->reloptkind
!= RELOPT_BASEREL
)
876 * Also, don't do it to a CustomPath; the premise that we're extracting
877 * columns from a simple physical tuple is unlikely to hold for those.
878 * (When it does make sense, the custom path creator can set up the path's
879 * pathtarget that way.)
881 if (IsA(path
, CustomPath
))
885 * If a bitmap scan's tlist is empty, keep it as-is. This may allow the
886 * executor to skip heap page fetches, and in any case, the benefit of
887 * using a physical tlist instead would be minimal.
889 if (IsA(path
, BitmapHeapPath
) &&
890 path
->pathtarget
->exprs
== NIL
)
894 * Can't do it if any system columns or whole-row Vars are requested.
895 * (This could possibly be fixed but would take some fragile assumptions
896 * in setrefs.c, I think.)
898 for (i
= rel
->min_attr
; i
<= 0; i
++)
900 if (!bms_is_empty(rel
->attr_needed
[i
- rel
->min_attr
]))
905 * Can't do it if the rel is required to emit any placeholder expressions,
908 foreach(lc
, root
->placeholder_list
)
910 PlaceHolderInfo
*phinfo
= (PlaceHolderInfo
*) lfirst(lc
);
912 if (bms_nonempty_difference(phinfo
->ph_needed
, rel
->relids
) &&
913 bms_is_subset(phinfo
->ph_eval_at
, rel
->relids
))
918 * Also, can't do it if CP_LABEL_TLIST is specified and path is requested
919 * to emit any sort/group columns that are not simple Vars. (If they are
920 * simple Vars, they should appear in the physical tlist, and
921 * apply_pathtarget_labeling_to_tlist will take care of getting them
922 * labeled again.) We also have to check that no two sort/group columns
923 * are the same Var, else that element of the physical tlist would need
924 * conflicting ressortgroupref labels.
926 if ((flags
& CP_LABEL_TLIST
) && path
->pathtarget
->sortgrouprefs
)
928 Bitmapset
*sortgroupatts
= NULL
;
931 foreach(lc
, path
->pathtarget
->exprs
)
933 Expr
*expr
= (Expr
*) lfirst(lc
);
935 if (path
->pathtarget
->sortgrouprefs
[i
])
937 if (expr
&& IsA(expr
, Var
))
939 int attno
= ((Var
*) expr
)->varattno
;
941 attno
-= FirstLowInvalidHeapAttributeNumber
;
942 if (bms_is_member(attno
, sortgroupatts
))
944 sortgroupatts
= bms_add_member(sortgroupatts
, attno
);
958 * See if there are pseudoconstant quals in a node's quals list
960 * If the node's quals list includes any pseudoconstant quals,
961 * return just those quals.
964 get_gating_quals(PlannerInfo
*root
, List
*quals
)
966 /* No need to look if we know there are no pseudoconstants */
967 if (!root
->hasPseudoConstantQuals
)
970 /* Sort into desirable execution order while still in RestrictInfo form */
971 quals
= order_qual_clauses(root
, quals
);
973 /* Pull out any pseudoconstant quals from the RestrictInfo list */
974 return extract_actual_clauses(quals
, true);
979 * Deal with pseudoconstant qual clauses
981 * Add a gating Result node atop the already-built plan.
984 create_gating_plan(PlannerInfo
*root
, Path
*path
, Plan
*plan
,
990 Assert(gating_quals
);
993 * We might have a trivial Result plan already. Stacking one Result atop
994 * another is silly, so if that applies, just discard the input plan.
995 * (We're assuming its targetlist is uninteresting; it should be either
996 * the same as the result of build_path_tlist, or a simplified version.)
999 if (IsA(plan
, Result
))
1001 Result
*rplan
= (Result
*) plan
;
1003 if (rplan
->plan
.lefttree
== NULL
&&
1004 rplan
->resconstantqual
== NULL
)
1009 * Since we need a Result node anyway, always return the path's requested
1010 * tlist; that's never a wrong choice, even if the parent node didn't ask
1011 * for CP_EXACT_TLIST.
1013 gplan
= (Plan
*) make_result(build_path_tlist(root
, path
),
1014 (Node
*) gating_quals
,
1018 * Notice that we don't change cost or size estimates when doing gating.
1019 * The costs of qual eval were already included in the subplan's cost.
1020 * Leaving the size alone amounts to assuming that the gating qual will
1021 * succeed, which is the conservative estimate for planning upper queries.
1022 * We certainly don't want to assume the output size is zero (unless the
1023 * gating qual is actually constant FALSE, and that case is dealt with in
1024 * clausesel.c). Interpolating between the two cases is silly, because it
1025 * doesn't reflect what will really happen at runtime, and besides which
1026 * in most cases we have only a very bad idea of the probability of the
1027 * gating qual being true.
1029 copy_plan_costsize(gplan
, plan
);
1031 /* Gating quals could be unsafe, so better use the Path's safety flag */
1032 gplan
->parallel_safe
= path
->parallel_safe
;
1039 * Create a join plan for 'best_path' and (recursively) plans for its
1040 * inner and outer paths.
1043 create_join_plan(PlannerInfo
*root
, JoinPath
*best_path
)
1046 List
*gating_clauses
;
1048 switch (best_path
->path
.pathtype
)
1051 plan
= (Plan
*) create_mergejoin_plan(root
,
1052 (MergePath
*) best_path
);
1055 plan
= (Plan
*) create_hashjoin_plan(root
,
1056 (HashPath
*) best_path
);
1059 plan
= (Plan
*) create_nestloop_plan(root
,
1060 (NestPath
*) best_path
);
1063 elog(ERROR
, "unrecognized node type: %d",
1064 (int) best_path
->path
.pathtype
);
1065 plan
= NULL
; /* keep compiler quiet */
1070 * If there are any pseudoconstant clauses attached to this node, insert a
1071 * gating Result node that evaluates the pseudoconstants as one-time
1074 gating_clauses
= get_gating_quals(root
, best_path
->joinrestrictinfo
);
1076 plan
= create_gating_plan(root
, (Path
*) best_path
, plan
,
1082 * * Expensive function pullups may have pulled local predicates * into
1083 * this path node. Put them in the qpqual of the plan node. * JMH,
1086 if (get_loc_restrictinfo(best_path
) != NIL
)
1087 set_qpqual((Plan
) plan
,
1088 list_concat(get_qpqual((Plan
) plan
),
1089 get_actual_clauses(get_loc_restrictinfo(best_path
))));
1096 * is_async_capable_path
1097 * Check whether a given Path node is async-capable.
1100 is_async_capable_path(Path
*path
)
1102 switch (nodeTag(path
))
1106 FdwRoutine
*fdwroutine
= path
->parent
->fdwroutine
;
1108 Assert(fdwroutine
!= NULL
);
1109 if (fdwroutine
->IsForeignPathAsyncCapable
!= NULL
&&
1110 fdwroutine
->IsForeignPathAsyncCapable((ForeignPath
*) path
))
1121 * create_append_plan
1122 * Create an Append plan for 'best_path' and (recursively) plans
1125 * Returns a Plan node.
1128 create_append_plan(PlannerInfo
*root
, AppendPath
*best_path
, int flags
)
1131 List
*tlist
= build_path_tlist(root
, &best_path
->path
);
1132 int orig_tlist_length
= list_length(tlist
);
1133 bool tlist_was_changed
= false;
1134 List
*pathkeys
= best_path
->path
.pathkeys
;
1135 List
*subplans
= NIL
;
1137 int nasyncplans
= 0;
1138 RelOptInfo
*rel
= best_path
->path
.parent
;
1139 PartitionPruneInfo
*partpruneinfo
= NULL
;
1140 int nodenumsortkeys
= 0;
1141 AttrNumber
*nodeSortColIdx
= NULL
;
1142 Oid
*nodeSortOperators
= NULL
;
1143 Oid
*nodeCollations
= NULL
;
1144 bool *nodeNullsFirst
= NULL
;
1145 bool consider_async
= false;
1148 * The subpaths list could be empty, if every child was proven empty by
1149 * constraint exclusion. In that case generate a dummy plan that returns
1152 * Note that an AppendPath with no members is also generated in certain
1153 * cases where there was no appending construct at all, but we know the
1154 * relation is empty (see set_dummy_rel_pathlist and mark_dummy_rel).
1156 if (best_path
->subpaths
== NIL
)
1158 /* Generate a Result plan with constant-FALSE gating qual */
1161 plan
= (Plan
*) make_result(tlist
,
1162 (Node
*) list_make1(makeBoolConst(false,
1166 copy_generic_path_info(plan
, (Path
*) best_path
);
1172 * Otherwise build an Append plan. Note that if there's just one child,
1173 * the Append is pretty useless; but we wait till setrefs.c to get rid of
1174 * it. Doing so here doesn't work because the varno of the child scan
1175 * plan won't match the parent-rel Vars it'll be asked to emit.
1177 * We don't have the actual creation of the Append node split out into a
1178 * separate make_xxx function. This is because we want to run
1179 * prepare_sort_from_pathkeys on it before we do so on the individual
1180 * child plans, to make cross-checking the sort info easier.
1182 plan
= makeNode(Append
);
1183 plan
->plan
.targetlist
= tlist
;
1184 plan
->plan
.qual
= NIL
;
1185 plan
->plan
.lefttree
= NULL
;
1186 plan
->plan
.righttree
= NULL
;
1187 plan
->apprelids
= rel
->relids
;
1189 if (pathkeys
!= NIL
)
1192 * Compute sort column info, and adjust the Append's tlist as needed.
1193 * Because we pass adjust_tlist_in_place = true, we may ignore the
1194 * function result; it must be the same plan node. However, we then
1195 * need to detect whether any tlist entries were added.
1197 (void) prepare_sort_from_pathkeys((Plan
*) plan
, pathkeys
,
1198 best_path
->path
.parent
->relids
,
1206 tlist_was_changed
= (orig_tlist_length
!= list_length(plan
->plan
.targetlist
));
1209 /* If appropriate, consider async append */
1210 consider_async
= (enable_async_append
&& pathkeys
== NIL
&&
1211 !best_path
->path
.parallel_safe
&&
1212 list_length(best_path
->subpaths
) > 1);
1214 /* Build the plan for each child */
1215 foreach(subpaths
, best_path
->subpaths
)
1217 Path
*subpath
= (Path
*) lfirst(subpaths
);
1220 /* Must insist that all children return the same tlist */
1221 subplan
= create_plan_recurse(root
, subpath
, CP_EXACT_TLIST
);
1224 * For ordered Appends, we must insert a Sort node if subplan isn't
1225 * sufficiently ordered.
1227 if (pathkeys
!= NIL
)
1230 AttrNumber
*sortColIdx
;
1236 * Compute sort column info, and adjust subplan's tlist as needed.
1237 * We must apply prepare_sort_from_pathkeys even to subplans that
1238 * don't need an explicit sort, to make sure they are returning
1239 * the same sort key columns the Append expects.
1241 subplan
= prepare_sort_from_pathkeys(subplan
, pathkeys
,
1242 subpath
->parent
->relids
,
1252 * Check that we got the same sort key information. We just
1253 * Assert that the sortops match, since those depend only on the
1254 * pathkeys; but it seems like a good idea to check the sort
1255 * column numbers explicitly, to ensure the tlists match up.
1257 Assert(numsortkeys
== nodenumsortkeys
);
1258 if (memcmp(sortColIdx
, nodeSortColIdx
,
1259 numsortkeys
* sizeof(AttrNumber
)) != 0)
1260 elog(ERROR
, "Append child's targetlist doesn't match Append");
1261 Assert(memcmp(sortOperators
, nodeSortOperators
,
1262 numsortkeys
* sizeof(Oid
)) == 0);
1263 Assert(memcmp(collations
, nodeCollations
,
1264 numsortkeys
* sizeof(Oid
)) == 0);
1265 Assert(memcmp(nullsFirst
, nodeNullsFirst
,
1266 numsortkeys
* sizeof(bool)) == 0);
1268 /* Now, insert a Sort node if subplan isn't sufficiently ordered */
1269 if (!pathkeys_contained_in(pathkeys
, subpath
->pathkeys
))
1271 Sort
*sort
= make_sort(subplan
, numsortkeys
,
1272 sortColIdx
, sortOperators
,
1273 collations
, nullsFirst
);
1275 label_sort_with_costsize(root
, sort
, best_path
->limit_tuples
);
1276 subplan
= (Plan
*) sort
;
1280 subplans
= lappend(subplans
, subplan
);
1282 /* Check to see if subplan can be executed asynchronously */
1283 if (consider_async
&& is_async_capable_path(subpath
))
1285 subplan
->async_capable
= true;
1291 * If any quals exist, they may be useful to perform further partition
1292 * pruning during execution. Gather information needed by the executor to
1293 * do partition pruning.
1295 if (enable_partition_pruning
)
1299 prunequal
= extract_actual_clauses(rel
->baserestrictinfo
, false);
1301 if (best_path
->path
.param_info
)
1303 List
*prmquals
= best_path
->path
.param_info
->ppi_clauses
;
1305 prmquals
= extract_actual_clauses(prmquals
, false);
1306 prmquals
= (List
*) replace_nestloop_params(root
,
1309 prunequal
= list_concat(prunequal
, prmquals
);
1312 if (prunequal
!= NIL
)
1314 make_partition_pruneinfo(root
, rel
,
1315 best_path
->subpaths
,
1319 plan
->appendplans
= subplans
;
1320 plan
->nasyncplans
= nasyncplans
;
1321 plan
->first_partial_plan
= best_path
->first_partial_path
;
1322 plan
->part_prune_info
= partpruneinfo
;
1324 copy_generic_path_info(&plan
->plan
, (Path
*) best_path
);
1327 * If prepare_sort_from_pathkeys added sort columns, but we were told to
1328 * produce either the exact tlist or a narrow tlist, we should get rid of
1329 * the sort columns again. We must inject a projection node to do so.
1331 if (tlist_was_changed
&& (flags
& (CP_EXACT_TLIST
| CP_SMALL_TLIST
)))
1333 tlist
= list_truncate(list_copy(plan
->plan
.targetlist
),
1335 return inject_projection_plan((Plan
*) plan
, tlist
,
1336 plan
->plan
.parallel_safe
);
1339 return (Plan
*) plan
;
1343 * create_merge_append_plan
1344 * Create a MergeAppend plan for 'best_path' and (recursively) plans
1347 * Returns a Plan node.
1350 create_merge_append_plan(PlannerInfo
*root
, MergeAppendPath
*best_path
,
1353 MergeAppend
*node
= makeNode(MergeAppend
);
1354 Plan
*plan
= &node
->plan
;
1355 List
*tlist
= build_path_tlist(root
, &best_path
->path
);
1356 int orig_tlist_length
= list_length(tlist
);
1357 bool tlist_was_changed
;
1358 List
*pathkeys
= best_path
->path
.pathkeys
;
1359 List
*subplans
= NIL
;
1361 RelOptInfo
*rel
= best_path
->path
.parent
;
1362 PartitionPruneInfo
*partpruneinfo
= NULL
;
1365 * We don't have the actual creation of the MergeAppend node split out
1366 * into a separate make_xxx function. This is because we want to run
1367 * prepare_sort_from_pathkeys on it before we do so on the individual
1368 * child plans, to make cross-checking the sort info easier.
1370 copy_generic_path_info(plan
, (Path
*) best_path
);
1371 plan
->targetlist
= tlist
;
1373 plan
->lefttree
= NULL
;
1374 plan
->righttree
= NULL
;
1375 node
->apprelids
= rel
->relids
;
1378 * Compute sort column info, and adjust MergeAppend's tlist as needed.
1379 * Because we pass adjust_tlist_in_place = true, we may ignore the
1380 * function result; it must be the same plan node. However, we then need
1381 * to detect whether any tlist entries were added.
1383 (void) prepare_sort_from_pathkeys(plan
, pathkeys
,
1384 best_path
->path
.parent
->relids
,
1389 &node
->sortOperators
,
1392 tlist_was_changed
= (orig_tlist_length
!= list_length(plan
->targetlist
));
1395 * Now prepare the child plans. We must apply prepare_sort_from_pathkeys
1396 * even to subplans that don't need an explicit sort, to make sure they
1397 * are returning the same sort key columns the MergeAppend expects.
1399 foreach(subpaths
, best_path
->subpaths
)
1401 Path
*subpath
= (Path
*) lfirst(subpaths
);
1404 AttrNumber
*sortColIdx
;
1409 /* Build the child plan */
1410 /* Must insist that all children return the same tlist */
1411 subplan
= create_plan_recurse(root
, subpath
, CP_EXACT_TLIST
);
1413 /* Compute sort column info, and adjust subplan's tlist as needed */
1414 subplan
= prepare_sort_from_pathkeys(subplan
, pathkeys
,
1415 subpath
->parent
->relids
,
1425 * Check that we got the same sort key information. We just Assert
1426 * that the sortops match, since those depend only on the pathkeys;
1427 * but it seems like a good idea to check the sort column numbers
1428 * explicitly, to ensure the tlists really do match up.
1430 Assert(numsortkeys
== node
->numCols
);
1431 if (memcmp(sortColIdx
, node
->sortColIdx
,
1432 numsortkeys
* sizeof(AttrNumber
)) != 0)
1433 elog(ERROR
, "MergeAppend child's targetlist doesn't match MergeAppend");
1434 Assert(memcmp(sortOperators
, node
->sortOperators
,
1435 numsortkeys
* sizeof(Oid
)) == 0);
1436 Assert(memcmp(collations
, node
->collations
,
1437 numsortkeys
* sizeof(Oid
)) == 0);
1438 Assert(memcmp(nullsFirst
, node
->nullsFirst
,
1439 numsortkeys
* sizeof(bool)) == 0);
1441 /* Now, insert a Sort node if subplan isn't sufficiently ordered */
1442 if (!pathkeys_contained_in(pathkeys
, subpath
->pathkeys
))
1444 Sort
*sort
= make_sort(subplan
, numsortkeys
,
1445 sortColIdx
, sortOperators
,
1446 collations
, nullsFirst
);
1448 label_sort_with_costsize(root
, sort
, best_path
->limit_tuples
);
1449 subplan
= (Plan
*) sort
;
1452 subplans
= lappend(subplans
, subplan
);
1456 * If any quals exist, they may be useful to perform further partition
1457 * pruning during execution. Gather information needed by the executor to
1458 * do partition pruning.
1460 if (enable_partition_pruning
)
1464 prunequal
= extract_actual_clauses(rel
->baserestrictinfo
, false);
1466 if (best_path
->path
.param_info
)
1468 List
*prmquals
= best_path
->path
.param_info
->ppi_clauses
;
1470 prmquals
= extract_actual_clauses(prmquals
, false);
1471 prmquals
= (List
*) replace_nestloop_params(root
,
1474 prunequal
= list_concat(prunequal
, prmquals
);
1477 if (prunequal
!= NIL
)
1478 partpruneinfo
= make_partition_pruneinfo(root
, rel
,
1479 best_path
->subpaths
,
1483 node
->mergeplans
= subplans
;
1484 node
->part_prune_info
= partpruneinfo
;
1487 * If prepare_sort_from_pathkeys added sort columns, but we were told to
1488 * produce either the exact tlist or a narrow tlist, we should get rid of
1489 * the sort columns again. We must inject a projection node to do so.
1491 if (tlist_was_changed
&& (flags
& (CP_EXACT_TLIST
| CP_SMALL_TLIST
)))
1493 tlist
= list_truncate(list_copy(plan
->targetlist
), orig_tlist_length
);
1494 return inject_projection_plan(plan
, tlist
, plan
->parallel_safe
);
1501 * create_group_result_plan
1502 * Create a Result plan for 'best_path'.
1503 * This is only used for degenerate grouping cases.
1505 * Returns a Plan node.
1508 create_group_result_plan(PlannerInfo
*root
, GroupResultPath
*best_path
)
1514 tlist
= build_path_tlist(root
, &best_path
->path
);
1516 /* best_path->quals is just bare clauses */
1517 quals
= order_qual_clauses(root
, best_path
->quals
);
1519 plan
= make_result(tlist
, (Node
*) quals
, NULL
);
1521 copy_generic_path_info(&plan
->plan
, (Path
*) best_path
);
1527 * create_project_set_plan
1528 * Create a ProjectSet plan for 'best_path'.
1530 * Returns a Plan node.
1533 create_project_set_plan(PlannerInfo
*root
, ProjectSetPath
*best_path
)
1539 /* Since we intend to project, we don't need to constrain child tlist */
1540 subplan
= create_plan_recurse(root
, best_path
->subpath
, 0);
1542 tlist
= build_path_tlist(root
, &best_path
->path
);
1544 plan
= make_project_set(tlist
, subplan
);
1546 copy_generic_path_info(&plan
->plan
, (Path
*) best_path
);
1552 * create_material_plan
1553 * Create a Material plan for 'best_path' and (recursively) plans
1556 * Returns a Plan node.
1559 create_material_plan(PlannerInfo
*root
, MaterialPath
*best_path
, int flags
)
1565 * We don't want any excess columns in the materialized tuples, so request
1566 * a smaller tlist. Otherwise, since Material doesn't project, tlist
1567 * requirements pass through.
1569 subplan
= create_plan_recurse(root
, best_path
->subpath
,
1570 flags
| CP_SMALL_TLIST
);
1572 plan
= make_material(subplan
);
1574 copy_generic_path_info(&plan
->plan
, (Path
*) best_path
);
1580 * create_memoize_plan
1581 * Create a Memoize plan for 'best_path' and (recursively) plans for its
1584 * Returns a Plan node.
1587 create_memoize_plan(PlannerInfo
*root
, MemoizePath
*best_path
, int flags
)
1590 Bitmapset
*keyparamids
;
1594 List
*param_exprs
= NIL
;
1600 subplan
= create_plan_recurse(root
, best_path
->subpath
,
1601 flags
| CP_SMALL_TLIST
);
1603 param_exprs
= (List
*) replace_nestloop_params(root
, (Node
*)
1604 best_path
->param_exprs
);
1606 nkeys
= list_length(param_exprs
);
1608 operators
= palloc(nkeys
* sizeof(Oid
));
1609 collations
= palloc(nkeys
* sizeof(Oid
));
1612 forboth(lc
, param_exprs
, lc2
, best_path
->hash_operators
)
1614 Expr
*param_expr
= (Expr
*) lfirst(lc
);
1615 Oid opno
= lfirst_oid(lc2
);
1617 operators
[i
] = opno
;
1618 collations
[i
] = exprCollation((Node
*) param_expr
);
1622 keyparamids
= pull_paramids((Expr
*) param_exprs
);
1624 plan
= make_memoize(subplan
, operators
, collations
, param_exprs
,
1625 best_path
->singlerow
, best_path
->binary_mode
,
1626 best_path
->est_entries
, keyparamids
);
1628 copy_generic_path_info(&plan
->plan
, (Path
*) best_path
);
1634 * create_unique_plan
1635 * Create a Unique plan for 'best_path' and (recursively) plans
1638 * Returns a Plan node.
1641 create_unique_plan(PlannerInfo
*root
, UniquePath
*best_path
, int flags
)
1651 AttrNumber
*groupColIdx
;
1652 Oid
*groupCollations
;
1656 /* Unique doesn't project, so tlist requirements pass through */
1657 subplan
= create_plan_recurse(root
, best_path
->subpath
, flags
);
1659 /* Done if we don't need to do any actual unique-ifying */
1660 if (best_path
->umethod
== UNIQUE_PATH_NOOP
)
1664 * As constructed, the subplan has a "flat" tlist containing just the Vars
1665 * needed here and at upper levels. The values we are supposed to
1666 * unique-ify may be expressions in these variables. We have to add any
1667 * such expressions to the subplan's tlist.
1669 * The subplan may have a "physical" tlist if it is a simple scan plan. If
1670 * we're going to sort, this should be reduced to the regular tlist, so
1671 * that we don't sort more data than we need to. For hashing, the tlist
1672 * should be left as-is if we don't need to add any expressions; but if we
1673 * do have to add expressions, then a projection step will be needed at
1674 * runtime anyway, so we may as well remove unneeded items. Therefore
1675 * newtlist starts from build_path_tlist() not just a copy of the
1676 * subplan's tlist; and we don't install it into the subplan unless we are
1677 * sorting or stuff has to be added.
1679 in_operators
= best_path
->in_operators
;
1680 uniq_exprs
= best_path
->uniq_exprs
;
1682 /* initialize modified subplan tlist as just the "required" vars */
1683 newtlist
= build_path_tlist(root
, &best_path
->path
);
1684 nextresno
= list_length(newtlist
) + 1;
1687 foreach(l
, uniq_exprs
)
1689 Expr
*uniqexpr
= lfirst(l
);
1692 tle
= tlist_member(uniqexpr
, newtlist
);
1695 tle
= makeTargetEntry((Expr
*) uniqexpr
,
1699 newtlist
= lappend(newtlist
, tle
);
1705 /* Use change_plan_targetlist in case we need to insert a Result node */
1706 if (newitems
|| best_path
->umethod
== UNIQUE_PATH_SORT
)
1707 subplan
= change_plan_targetlist(subplan
, newtlist
,
1708 best_path
->path
.parallel_safe
);
1711 * Build control information showing which subplan output columns are to
1712 * be examined by the grouping step. Unfortunately we can't merge this
1713 * with the previous loop, since we didn't then know which version of the
1714 * subplan tlist we'd end up using.
1716 newtlist
= subplan
->targetlist
;
1717 numGroupCols
= list_length(uniq_exprs
);
1718 groupColIdx
= (AttrNumber
*) palloc(numGroupCols
* sizeof(AttrNumber
));
1719 groupCollations
= (Oid
*) palloc(numGroupCols
* sizeof(Oid
));
1722 foreach(l
, uniq_exprs
)
1724 Expr
*uniqexpr
= lfirst(l
);
1727 tle
= tlist_member(uniqexpr
, newtlist
);
1728 if (!tle
) /* shouldn't happen */
1729 elog(ERROR
, "failed to find unique expression in subplan tlist");
1730 groupColIdx
[groupColPos
] = tle
->resno
;
1731 groupCollations
[groupColPos
] = exprCollation((Node
*) tle
->expr
);
1735 if (best_path
->umethod
== UNIQUE_PATH_HASH
)
1737 Oid
*groupOperators
;
1740 * Get the hashable equality operators for the Agg node to use.
1741 * Normally these are the same as the IN clause operators, but if
1742 * those are cross-type operators then the equality operators are the
1743 * ones for the IN clause operators' RHS datatype.
1745 groupOperators
= (Oid
*) palloc(numGroupCols
* sizeof(Oid
));
1747 foreach(l
, in_operators
)
1749 Oid in_oper
= lfirst_oid(l
);
1752 if (!get_compatible_hash_operators(in_oper
, NULL
, &eq_oper
))
1753 elog(ERROR
, "could not find compatible hash operator for operator %u",
1755 groupOperators
[groupColPos
++] = eq_oper
;
1759 * Since the Agg node is going to project anyway, we can give it the
1760 * minimum output tlist, without any stuff we might have added to the
1763 plan
= (Plan
*) make_agg(build_path_tlist(root
, &best_path
->path
),
1773 best_path
->path
.rows
,
1779 List
*sortList
= NIL
;
1782 /* Create an ORDER BY list to sort the input compatibly */
1784 foreach(l
, in_operators
)
1786 Oid in_oper
= lfirst_oid(l
);
1790 SortGroupClause
*sortcl
;
1792 sortop
= get_ordering_op_for_equality_op(in_oper
, false);
1793 if (!OidIsValid(sortop
)) /* shouldn't happen */
1794 elog(ERROR
, "could not find ordering operator for equality operator %u",
1798 * The Unique node will need equality operators. Normally these
1799 * are the same as the IN clause operators, but if those are
1800 * cross-type operators then the equality operators are the ones
1801 * for the IN clause operators' RHS datatype.
1803 eqop
= get_equality_op_for_ordering_op(sortop
, NULL
);
1804 if (!OidIsValid(eqop
)) /* shouldn't happen */
1805 elog(ERROR
, "could not find equality operator for ordering operator %u",
1808 tle
= get_tle_by_resno(subplan
->targetlist
,
1809 groupColIdx
[groupColPos
]);
1810 Assert(tle
!= NULL
);
1812 sortcl
= makeNode(SortGroupClause
);
1813 sortcl
->tleSortGroupRef
= assignSortGroupRef(tle
,
1814 subplan
->targetlist
);
1815 sortcl
->eqop
= eqop
;
1816 sortcl
->sortop
= sortop
;
1817 sortcl
->nulls_first
= false;
1818 sortcl
->hashable
= false; /* no need to make this accurate */
1819 sortList
= lappend(sortList
, sortcl
);
1822 sort
= make_sort_from_sortclauses(sortList
, subplan
);
1823 label_sort_with_costsize(root
, sort
, -1.0);
1824 plan
= (Plan
*) make_unique_from_sortclauses((Plan
*) sort
, sortList
);
1827 /* Copy cost data from Path to Plan */
1828 copy_generic_path_info(plan
, &best_path
->path
);
1834 * create_gather_plan
1836 * Create a Gather plan for 'best_path' and (recursively) plans
1840 create_gather_plan(PlannerInfo
*root
, GatherPath
*best_path
)
1842 Gather
*gather_plan
;
1847 * Push projection down to the child node. That way, the projection work
1848 * is parallelized, and there can be no system columns in the result (they
1849 * can't travel through a tuple queue because it uses MinimalTuple
1852 subplan
= create_plan_recurse(root
, best_path
->subpath
, CP_EXACT_TLIST
);
1854 tlist
= build_path_tlist(root
, &best_path
->path
);
1856 gather_plan
= make_gather(tlist
,
1858 best_path
->num_workers
,
1859 assign_special_exec_param(root
),
1860 best_path
->single_copy
,
1863 copy_generic_path_info(&gather_plan
->plan
, &best_path
->path
);
1865 /* use parallel mode for parallel plans. */
1866 root
->glob
->parallelModeNeeded
= true;
1872 * create_gather_merge_plan
1874 * Create a Gather Merge plan for 'best_path' and (recursively)
1875 * plans for its subpaths.
1877 static GatherMerge
*
1878 create_gather_merge_plan(PlannerInfo
*root
, GatherMergePath
*best_path
)
1880 GatherMerge
*gm_plan
;
1882 List
*pathkeys
= best_path
->path
.pathkeys
;
1883 List
*tlist
= build_path_tlist(root
, &best_path
->path
);
1885 /* As with Gather, project away columns in the workers. */
1886 subplan
= create_plan_recurse(root
, best_path
->subpath
, CP_EXACT_TLIST
);
1888 /* Create a shell for a GatherMerge plan. */
1889 gm_plan
= makeNode(GatherMerge
);
1890 gm_plan
->plan
.targetlist
= tlist
;
1891 gm_plan
->num_workers
= best_path
->num_workers
;
1892 copy_generic_path_info(&gm_plan
->plan
, &best_path
->path
);
1894 /* Assign the rescan Param. */
1895 gm_plan
->rescan_param
= assign_special_exec_param(root
);
1897 /* Gather Merge is pointless with no pathkeys; use Gather instead. */
1898 Assert(pathkeys
!= NIL
);
1900 /* Compute sort column info, and adjust subplan's tlist as needed */
1901 subplan
= prepare_sort_from_pathkeys(subplan
, pathkeys
,
1902 best_path
->subpath
->parent
->relids
,
1903 gm_plan
->sortColIdx
,
1906 &gm_plan
->sortColIdx
,
1907 &gm_plan
->sortOperators
,
1908 &gm_plan
->collations
,
1909 &gm_plan
->nullsFirst
);
1913 * All gather merge paths should have already guaranteed the necessary
1914 * sort order either by adding an explicit sort node or by using presorted
1915 * input. We can't simply add a sort here on additional pathkeys, because
1916 * we can't guarantee the sort would be safe. For example, expressions may
1917 * be volatile or otherwise parallel unsafe.
1919 if (!pathkeys_contained_in(pathkeys
, best_path
->subpath
->pathkeys
))
1920 elog(ERROR
, "gather merge input not sufficiently sorted");
1922 /* Now insert the subplan under GatherMerge. */
1923 gm_plan
->plan
.lefttree
= subplan
;
1925 /* use parallel mode for parallel plans. */
1926 root
->glob
->parallelModeNeeded
= true;
1932 * create_projection_plan
1934 * Create a plan tree to do a projection step and (recursively) plans
1935 * for its subpaths. We may need a Result node for the projection,
1936 * but sometimes we can just let the subplan do the work.
1939 create_projection_plan(PlannerInfo
*root
, ProjectionPath
*best_path
, int flags
)
1944 bool needs_result_node
= false;
1947 * Convert our subpath to a Plan and determine whether we need a Result
1950 * In most cases where we don't need to project, creation_projection_path
1951 * will have set dummypp, but not always. First, some createplan.c
1952 * routines change the tlists of their nodes. (An example is that
1953 * create_merge_append_plan might add resjunk sort columns to a
1954 * MergeAppend.) Second, create_projection_path has no way of knowing
1955 * what path node will be placed on top of the projection path and
1956 * therefore can't predict whether it will require an exact tlist. For
1957 * both of these reasons, we have to recheck here.
1959 if (use_physical_tlist(root
, &best_path
->path
, flags
))
1962 * Our caller doesn't really care what tlist we return, so we don't
1963 * actually need to project. However, we may still need to ensure
1964 * proper sortgroupref labels, if the caller cares about those.
1966 subplan
= create_plan_recurse(root
, best_path
->subpath
, 0);
1967 tlist
= subplan
->targetlist
;
1968 if (flags
& CP_LABEL_TLIST
)
1969 apply_pathtarget_labeling_to_tlist(tlist
,
1970 best_path
->path
.pathtarget
);
1972 else if (is_projection_capable_path(best_path
->subpath
))
1975 * Our caller requires that we return the exact tlist, but no separate
1976 * result node is needed because the subpath is projection-capable.
1977 * Tell create_plan_recurse that we're going to ignore the tlist it
1980 subplan
= create_plan_recurse(root
, best_path
->subpath
,
1982 Assert(is_projection_capable_plan(subplan
));
1983 tlist
= build_path_tlist(root
, &best_path
->path
);
1988 * It looks like we need a result node, unless by good fortune the
1989 * requested tlist is exactly the one the child wants to produce.
1991 subplan
= create_plan_recurse(root
, best_path
->subpath
, 0);
1992 tlist
= build_path_tlist(root
, &best_path
->path
);
1993 needs_result_node
= !tlist_same_exprs(tlist
, subplan
->targetlist
);
1997 * If we make a different decision about whether to include a Result node
1998 * than create_projection_path did, we'll have made slightly wrong cost
1999 * estimates; but label the plan with the cost estimates we actually used,
2000 * not "corrected" ones. (XXX this could be cleaned up if we moved more
2001 * of the sortcolumn setup logic into Path creation, but that would add
2002 * expense to creating Paths we might end up not using.)
2004 if (!needs_result_node
)
2006 /* Don't need a separate Result, just assign tlist to subplan */
2008 plan
->targetlist
= tlist
;
2010 /* Label plan with the estimated costs we actually used */
2011 plan
->startup_cost
= best_path
->path
.startup_cost
;
2012 plan
->total_cost
= best_path
->path
.total_cost
;
2013 plan
->plan_rows
= best_path
->path
.rows
;
2014 plan
->plan_width
= best_path
->path
.pathtarget
->width
;
2015 plan
->parallel_safe
= best_path
->path
.parallel_safe
;
2016 /* ... but don't change subplan's parallel_aware flag */
2020 /* We need a Result node */
2021 plan
= (Plan
*) make_result(tlist
, NULL
, subplan
);
2023 copy_generic_path_info(plan
, (Path
*) best_path
);
2030 * inject_projection_plan
2031 * Insert a Result node to do a projection step.
2033 * This is used in a few places where we decide on-the-fly that we need a
2034 * projection step as part of the tree generated for some Path node.
2035 * We should try to get rid of this in favor of doing it more honestly.
2037 * One reason it's ugly is we have to be told the right parallel_safe marking
2038 * to apply (since the tlist might be unsafe even if the child plan is safe).
2041 inject_projection_plan(Plan
*subplan
, List
*tlist
, bool parallel_safe
)
2045 plan
= (Plan
*) make_result(tlist
, NULL
, subplan
);
2048 * In principle, we should charge tlist eval cost plus cpu_per_tuple per
2049 * row for the Result node. But the former has probably been factored in
2050 * already and the latter was not accounted for during Path construction,
2051 * so being formally correct might just make the EXPLAIN output look less
2052 * consistent not more so. Hence, just copy the subplan's cost.
2054 copy_plan_costsize(plan
, subplan
);
2055 plan
->parallel_safe
= parallel_safe
;
2061 * change_plan_targetlist
2062 * Externally available wrapper for inject_projection_plan.
2064 * This is meant for use by FDW plan-generation functions, which might
2065 * want to adjust the tlist computed by some subplan tree. In general,
2066 * a Result node is needed to compute the new tlist, but we can optimize
2069 * In most cases, tlist_parallel_safe can just be passed as the parallel_safe
2070 * flag of the FDW's own Path node.
2073 change_plan_targetlist(Plan
*subplan
, List
*tlist
, bool tlist_parallel_safe
)
2076 * If the top plan node can't do projections and its existing target list
2077 * isn't already what we need, we need to add a Result node to help it
2080 if (!is_projection_capable_plan(subplan
) &&
2081 !tlist_same_exprs(tlist
, subplan
->targetlist
))
2082 subplan
= inject_projection_plan(subplan
, tlist
,
2083 subplan
->parallel_safe
&&
2084 tlist_parallel_safe
);
2087 /* Else we can just replace the plan node's tlist */
2088 subplan
->targetlist
= tlist
;
2089 subplan
->parallel_safe
&= tlist_parallel_safe
;
2097 * Create a Sort plan for 'best_path' and (recursively) plans
2101 create_sort_plan(PlannerInfo
*root
, SortPath
*best_path
, int flags
)
2107 * We don't want any excess columns in the sorted tuples, so request a
2108 * smaller tlist. Otherwise, since Sort doesn't project, tlist
2109 * requirements pass through.
2111 subplan
= create_plan_recurse(root
, best_path
->subpath
,
2112 flags
| CP_SMALL_TLIST
);
2115 * make_sort_from_pathkeys indirectly calls find_ec_member_matching_expr,
2116 * which will ignore any child EC members that don't belong to the given
2117 * relids. Thus, if this sort path is based on a child relation, we must
2120 plan
= make_sort_from_pathkeys(subplan
, best_path
->path
.pathkeys
,
2121 IS_OTHER_REL(best_path
->subpath
->parent
) ?
2122 best_path
->path
.parent
->relids
: NULL
);
2124 copy_generic_path_info(&plan
->plan
, (Path
*) best_path
);
2130 * create_incrementalsort_plan
2132 * Do the same as create_sort_plan, but create IncrementalSort plan.
2134 static IncrementalSort
*
2135 create_incrementalsort_plan(PlannerInfo
*root
, IncrementalSortPath
*best_path
,
2138 IncrementalSort
*plan
;
2141 /* See comments in create_sort_plan() above */
2142 subplan
= create_plan_recurse(root
, best_path
->spath
.subpath
,
2143 flags
| CP_SMALL_TLIST
);
2144 plan
= make_incrementalsort_from_pathkeys(subplan
,
2145 best_path
->spath
.path
.pathkeys
,
2146 IS_OTHER_REL(best_path
->spath
.subpath
->parent
) ?
2147 best_path
->spath
.path
.parent
->relids
: NULL
,
2148 best_path
->nPresortedCols
);
2150 copy_generic_path_info(&plan
->sort
.plan
, (Path
*) best_path
);
2158 * Create a Group plan for 'best_path' and (recursively) plans
2162 create_group_plan(PlannerInfo
*root
, GroupPath
*best_path
)
2170 * Group can project, so no need to be terribly picky about child tlist,
2171 * but we do need grouping columns to be available
2173 subplan
= create_plan_recurse(root
, best_path
->subpath
, CP_LABEL_TLIST
);
2175 tlist
= build_path_tlist(root
, &best_path
->path
);
2177 quals
= order_qual_clauses(root
, best_path
->qual
);
2179 plan
= make_group(tlist
,
2181 list_length(best_path
->groupClause
),
2182 extract_grouping_cols(best_path
->groupClause
,
2183 subplan
->targetlist
),
2184 extract_grouping_ops(best_path
->groupClause
),
2185 extract_grouping_collations(best_path
->groupClause
,
2186 subplan
->targetlist
),
2189 copy_generic_path_info(&plan
->plan
, (Path
*) best_path
);
2195 * create_upper_unique_plan
2197 * Create a Unique plan for 'best_path' and (recursively) plans
2201 create_upper_unique_plan(PlannerInfo
*root
, UpperUniquePath
*best_path
, int flags
)
2207 * Unique doesn't project, so tlist requirements pass through; moreover we
2208 * need grouping columns to be labeled.
2210 subplan
= create_plan_recurse(root
, best_path
->subpath
,
2211 flags
| CP_LABEL_TLIST
);
2213 plan
= make_unique_from_pathkeys(subplan
,
2214 best_path
->path
.pathkeys
,
2215 best_path
->numkeys
);
2217 copy_generic_path_info(&plan
->plan
, (Path
*) best_path
);
2225 * Create an Agg plan for 'best_path' and (recursively) plans
2229 create_agg_plan(PlannerInfo
*root
, AggPath
*best_path
)
2237 * Agg can project, so no need to be terribly picky about child tlist, but
2238 * we do need grouping columns to be available
2240 subplan
= create_plan_recurse(root
, best_path
->subpath
, CP_LABEL_TLIST
);
2242 tlist
= build_path_tlist(root
, &best_path
->path
);
2244 quals
= order_qual_clauses(root
, best_path
->qual
);
2246 plan
= make_agg(tlist
, quals
,
2247 best_path
->aggstrategy
,
2248 best_path
->aggsplit
,
2249 list_length(best_path
->groupClause
),
2250 extract_grouping_cols(best_path
->groupClause
,
2251 subplan
->targetlist
),
2252 extract_grouping_ops(best_path
->groupClause
),
2253 extract_grouping_collations(best_path
->groupClause
,
2254 subplan
->targetlist
),
2257 best_path
->numGroups
,
2258 best_path
->transitionSpace
,
2261 copy_generic_path_info(&plan
->plan
, (Path
*) best_path
);
2267 * Given a groupclause for a collection of grouping sets, produce the
2268 * corresponding groupColIdx.
2270 * root->grouping_map maps the tleSortGroupRef to the actual column position in
2271 * the input tuple. So we get the ref from the entries in the groupclause and
2272 * look them up there.
2275 remap_groupColIdx(PlannerInfo
*root
, List
*groupClause
)
2277 AttrNumber
*grouping_map
= root
->grouping_map
;
2278 AttrNumber
*new_grpColIdx
;
2282 Assert(grouping_map
);
2284 new_grpColIdx
= palloc0(sizeof(AttrNumber
) * list_length(groupClause
));
2287 foreach(lc
, groupClause
)
2289 SortGroupClause
*clause
= lfirst(lc
);
2291 new_grpColIdx
[i
++] = grouping_map
[clause
->tleSortGroupRef
];
2294 return new_grpColIdx
;
2298 * create_groupingsets_plan
2299 * Create a plan for 'best_path' and (recursively) plans
2302 * What we emit is an Agg plan with some vestigial Agg and Sort nodes
2303 * hanging off the side. The top Agg implements the last grouping set
2304 * specified in the GroupingSetsPath, and any additional grouping sets
2305 * each give rise to a subsidiary Agg and Sort node in the top Agg's
2306 * "chain" list. These nodes don't participate in the plan directly,
2307 * but they are a convenient way to represent the required data for
2310 * Returns a Plan node.
2313 create_groupingsets_plan(PlannerInfo
*root
, GroupingSetsPath
*best_path
)
2317 List
*rollups
= best_path
->rollups
;
2318 AttrNumber
*grouping_map
;
2323 /* Shouldn't get here without grouping sets */
2324 Assert(root
->parse
->groupingSets
);
2325 Assert(rollups
!= NIL
);
2328 * Agg can project, so no need to be terribly picky about child tlist, but
2329 * we do need grouping columns to be available
2331 subplan
= create_plan_recurse(root
, best_path
->subpath
, CP_LABEL_TLIST
);
2334 * Compute the mapping from tleSortGroupRef to column index in the child's
2335 * tlist. First, identify max SortGroupRef in groupClause, for array
2339 foreach(lc
, root
->parse
->groupClause
)
2341 SortGroupClause
*gc
= (SortGroupClause
*) lfirst(lc
);
2343 if (gc
->tleSortGroupRef
> maxref
)
2344 maxref
= gc
->tleSortGroupRef
;
2347 grouping_map
= (AttrNumber
*) palloc0((maxref
+ 1) * sizeof(AttrNumber
));
2349 /* Now look up the column numbers in the child's tlist */
2350 foreach(lc
, root
->parse
->groupClause
)
2352 SortGroupClause
*gc
= (SortGroupClause
*) lfirst(lc
);
2353 TargetEntry
*tle
= get_sortgroupclause_tle(gc
, subplan
->targetlist
);
2355 grouping_map
[gc
->tleSortGroupRef
] = tle
->resno
;
2359 * During setrefs.c, we'll need the grouping_map to fix up the cols lists
2360 * in GroupingFunc nodes. Save it for setrefs.c to use.
2362 Assert(root
->grouping_map
== NULL
);
2363 root
->grouping_map
= grouping_map
;
2366 * Generate the side nodes that describe the other sort and group
2367 * operations besides the top one. Note that we don't worry about putting
2368 * accurate cost estimates in the side nodes; only the topmost Agg node's
2369 * costs will be shown by EXPLAIN.
2372 if (list_length(rollups
) > 1)
2374 bool is_first_sort
= ((RollupData
*) linitial(rollups
))->is_hashed
;
2376 for_each_from(lc
, rollups
, 1)
2378 RollupData
*rollup
= lfirst(lc
);
2379 AttrNumber
*new_grpColIdx
;
2380 Plan
*sort_plan
= NULL
;
2384 new_grpColIdx
= remap_groupColIdx(root
, rollup
->groupClause
);
2386 if (!rollup
->is_hashed
&& !is_first_sort
)
2388 sort_plan
= (Plan
*)
2389 make_sort_from_groupcols(rollup
->groupClause
,
2394 if (!rollup
->is_hashed
)
2395 is_first_sort
= false;
2397 if (rollup
->is_hashed
)
2399 else if (list_length(linitial(rollup
->gsets
)) == 0)
2404 agg_plan
= (Plan
*) make_agg(NIL
,
2408 list_length((List
*) linitial(rollup
->gsets
)),
2410 extract_grouping_ops(rollup
->groupClause
),
2411 extract_grouping_collations(rollup
->groupClause
, subplan
->targetlist
),
2415 best_path
->transitionSpace
,
2419 * Remove stuff we don't need to avoid bloating debug output.
2423 sort_plan
->targetlist
= NIL
;
2424 sort_plan
->lefttree
= NULL
;
2427 chain
= lappend(chain
, agg_plan
);
2432 * Now make the real Agg node
2435 RollupData
*rollup
= linitial(rollups
);
2436 AttrNumber
*top_grpColIdx
;
2439 top_grpColIdx
= remap_groupColIdx(root
, rollup
->groupClause
);
2441 numGroupCols
= list_length((List
*) linitial(rollup
->gsets
));
2443 plan
= make_agg(build_path_tlist(root
, &best_path
->path
),
2445 best_path
->aggstrategy
,
2449 extract_grouping_ops(rollup
->groupClause
),
2450 extract_grouping_collations(rollup
->groupClause
, subplan
->targetlist
),
2454 best_path
->transitionSpace
,
2457 /* Copy cost data from Path to Plan */
2458 copy_generic_path_info(&plan
->plan
, &best_path
->path
);
2461 return (Plan
*) plan
;
2465 * create_minmaxagg_plan
2467 * Create a Result plan for 'best_path' and (recursively) plans
2471 create_minmaxagg_plan(PlannerInfo
*root
, MinMaxAggPath
*best_path
)
2477 /* Prepare an InitPlan for each aggregate's subquery. */
2478 foreach(lc
, best_path
->mmaggregates
)
2480 MinMaxAggInfo
*mminfo
= (MinMaxAggInfo
*) lfirst(lc
);
2481 PlannerInfo
*subroot
= mminfo
->subroot
;
2482 Query
*subparse
= subroot
->parse
;
2486 * Generate the plan for the subquery. We already have a Path, but we
2487 * have to convert it to a Plan and attach a LIMIT node above it.
2488 * Since we are entering a different planner context (subroot),
2489 * recurse to create_plan not create_plan_recurse.
2491 plan
= create_plan(subroot
, mminfo
->path
);
2493 plan
= (Plan
*) make_limit(plan
,
2494 subparse
->limitOffset
,
2495 subparse
->limitCount
,
2496 subparse
->limitOption
,
2497 0, NULL
, NULL
, NULL
);
2499 /* Must apply correct cost/width data to Limit node */
2500 plan
->startup_cost
= mminfo
->path
->startup_cost
;
2501 plan
->total_cost
= mminfo
->pathcost
;
2502 plan
->plan_rows
= 1;
2503 plan
->plan_width
= mminfo
->path
->pathtarget
->width
;
2504 plan
->parallel_aware
= false;
2505 plan
->parallel_safe
= mminfo
->path
->parallel_safe
;
2507 /* Convert the plan into an InitPlan in the outer query. */
2508 SS_make_initplan_from_plan(root
, subroot
, plan
, mminfo
->param
);
2511 /* Generate the output plan --- basically just a Result */
2512 tlist
= build_path_tlist(root
, &best_path
->path
);
2514 plan
= make_result(tlist
, (Node
*) best_path
->quals
, NULL
);
2516 copy_generic_path_info(&plan
->plan
, (Path
*) best_path
);
2519 * During setrefs.c, we'll need to replace references to the Agg nodes
2520 * with InitPlan output params. (We can't just do that locally in the
2521 * MinMaxAgg node, because path nodes above here may have Agg references
2522 * as well.) Save the mmaggregates list to tell setrefs.c to do that.
2524 Assert(root
->minmax_aggs
== NIL
);
2525 root
->minmax_aggs
= best_path
->mmaggregates
;
2531 * create_windowagg_plan
2533 * Create a WindowAgg plan for 'best_path' and (recursively) plans
2537 create_windowagg_plan(PlannerInfo
*root
, WindowAggPath
*best_path
)
2540 WindowClause
*wc
= best_path
->winclause
;
2541 int numPart
= list_length(wc
->partitionClause
);
2542 int numOrder
= list_length(wc
->orderClause
);
2546 AttrNumber
*partColIdx
;
2548 Oid
*partCollations
;
2550 AttrNumber
*ordColIdx
;
2556 * Choice of tlist here is motivated by the fact that WindowAgg will be
2557 * storing the input rows of window frames in a tuplestore; it therefore
2558 * behooves us to request a small tlist to avoid wasting space. We do of
2559 * course need grouping columns to be available.
2561 subplan
= create_plan_recurse(root
, best_path
->subpath
,
2562 CP_LABEL_TLIST
| CP_SMALL_TLIST
);
2564 tlist
= build_path_tlist(root
, &best_path
->path
);
2567 * Convert SortGroupClause lists into arrays of attr indexes and equality
2568 * operators, as wanted by executor. (Note: in principle, it's possible
2569 * to drop some of the sort columns, if they were proved redundant by
2570 * pathkey logic. However, it doesn't seem worth going out of our way to
2571 * optimize such cases. In any case, we must *not* remove the ordering
2572 * column for RANGE OFFSET cases, as the executor needs that for in_range
2573 * tests even if it's known to be equal to some partitioning column.)
2575 partColIdx
= (AttrNumber
*) palloc(sizeof(AttrNumber
) * numPart
);
2576 partOperators
= (Oid
*) palloc(sizeof(Oid
) * numPart
);
2577 partCollations
= (Oid
*) palloc(sizeof(Oid
) * numPart
);
2580 foreach(lc
, wc
->partitionClause
)
2582 SortGroupClause
*sgc
= (SortGroupClause
*) lfirst(lc
);
2583 TargetEntry
*tle
= get_sortgroupclause_tle(sgc
, subplan
->targetlist
);
2585 Assert(OidIsValid(sgc
->eqop
));
2586 partColIdx
[partNumCols
] = tle
->resno
;
2587 partOperators
[partNumCols
] = sgc
->eqop
;
2588 partCollations
[partNumCols
] = exprCollation((Node
*) tle
->expr
);
2592 ordColIdx
= (AttrNumber
*) palloc(sizeof(AttrNumber
) * numOrder
);
2593 ordOperators
= (Oid
*) palloc(sizeof(Oid
) * numOrder
);
2594 ordCollations
= (Oid
*) palloc(sizeof(Oid
) * numOrder
);
2597 foreach(lc
, wc
->orderClause
)
2599 SortGroupClause
*sgc
= (SortGroupClause
*) lfirst(lc
);
2600 TargetEntry
*tle
= get_sortgroupclause_tle(sgc
, subplan
->targetlist
);
2602 Assert(OidIsValid(sgc
->eqop
));
2603 ordColIdx
[ordNumCols
] = tle
->resno
;
2604 ordOperators
[ordNumCols
] = sgc
->eqop
;
2605 ordCollations
[ordNumCols
] = exprCollation((Node
*) tle
->expr
);
2609 /* And finally we can make the WindowAgg node */
2610 plan
= make_windowagg(tlist
,
2623 wc
->startInRangeFunc
,
2627 wc
->inRangeNullsFirst
,
2630 copy_generic_path_info(&plan
->plan
, (Path
*) best_path
);
2638 * Create a SetOp plan for 'best_path' and (recursively) plans
2642 create_setop_plan(PlannerInfo
*root
, SetOpPath
*best_path
, int flags
)
2649 * SetOp doesn't project, so tlist requirements pass through; moreover we
2650 * need grouping columns to be labeled.
2652 subplan
= create_plan_recurse(root
, best_path
->subpath
,
2653 flags
| CP_LABEL_TLIST
);
2655 /* Convert numGroups to long int --- but 'ware overflow! */
2656 numGroups
= (long) Min(best_path
->numGroups
, (double) LONG_MAX
);
2658 plan
= make_setop(best_path
->cmd
,
2659 best_path
->strategy
,
2661 best_path
->distinctList
,
2662 best_path
->flagColIdx
,
2663 best_path
->firstFlag
,
2666 copy_generic_path_info(&plan
->plan
, (Path
*) best_path
);
2672 * create_recursiveunion_plan
2674 * Create a RecursiveUnion plan for 'best_path' and (recursively) plans
2677 static RecursiveUnion
*
2678 create_recursiveunion_plan(PlannerInfo
*root
, RecursiveUnionPath
*best_path
)
2680 RecursiveUnion
*plan
;
2686 /* Need both children to produce same tlist, so force it */
2687 leftplan
= create_plan_recurse(root
, best_path
->leftpath
, CP_EXACT_TLIST
);
2688 rightplan
= create_plan_recurse(root
, best_path
->rightpath
, CP_EXACT_TLIST
);
2690 tlist
= build_path_tlist(root
, &best_path
->path
);
2692 /* Convert numGroups to long int --- but 'ware overflow! */
2693 numGroups
= (long) Min(best_path
->numGroups
, (double) LONG_MAX
);
2695 plan
= make_recursive_union(tlist
,
2699 best_path
->distinctList
,
2702 copy_generic_path_info(&plan
->plan
, (Path
*) best_path
);
2708 * create_lockrows_plan
2710 * Create a LockRows plan for 'best_path' and (recursively) plans
2714 create_lockrows_plan(PlannerInfo
*root
, LockRowsPath
*best_path
,
2720 /* LockRows doesn't project, so tlist requirements pass through */
2721 subplan
= create_plan_recurse(root
, best_path
->subpath
, flags
);
2723 plan
= make_lockrows(subplan
, best_path
->rowMarks
, best_path
->epqParam
);
2725 copy_generic_path_info(&plan
->plan
, (Path
*) best_path
);
2731 * create_modifytable_plan
2732 * Create a ModifyTable plan for 'best_path'.
2734 * Returns a Plan node.
2736 static ModifyTable
*
2737 create_modifytable_plan(PlannerInfo
*root
, ModifyTablePath
*best_path
)
2740 Path
*subpath
= best_path
->subpath
;
2743 /* Subplan must produce exactly the specified tlist */
2744 subplan
= create_plan_recurse(root
, subpath
, CP_EXACT_TLIST
);
2746 /* Transfer resname/resjunk labeling, too, to keep executor happy */
2747 apply_tlist_labeling(subplan
->targetlist
, root
->processed_tlist
);
2749 plan
= make_modifytable(root
,
2751 best_path
->operation
,
2752 best_path
->canSetTag
,
2753 best_path
->nominalRelation
,
2754 best_path
->rootRelation
,
2755 best_path
->partColsUpdated
,
2756 best_path
->resultRelations
,
2757 best_path
->updateColnosLists
,
2758 best_path
->withCheckOptionLists
,
2759 best_path
->returningLists
,
2760 best_path
->rowMarks
,
2761 best_path
->onconflict
,
2762 best_path
->epqParam
);
2764 copy_generic_path_info(&plan
->plan
, &best_path
->path
);
2772 * Create a Limit plan for 'best_path' and (recursively) plans
2776 create_limit_plan(PlannerInfo
*root
, LimitPath
*best_path
, int flags
)
2780 int numUniqkeys
= 0;
2781 AttrNumber
*uniqColIdx
= NULL
;
2782 Oid
*uniqOperators
= NULL
;
2783 Oid
*uniqCollations
= NULL
;
2785 /* Limit doesn't project, so tlist requirements pass through */
2786 subplan
= create_plan_recurse(root
, best_path
->subpath
, flags
);
2788 /* Extract information necessary for comparing rows for WITH TIES. */
2789 if (best_path
->limitOption
== LIMIT_OPTION_WITH_TIES
)
2791 Query
*parse
= root
->parse
;
2794 numUniqkeys
= list_length(parse
->sortClause
);
2795 uniqColIdx
= (AttrNumber
*) palloc(numUniqkeys
* sizeof(AttrNumber
));
2796 uniqOperators
= (Oid
*) palloc(numUniqkeys
* sizeof(Oid
));
2797 uniqCollations
= (Oid
*) palloc(numUniqkeys
* sizeof(Oid
));
2800 foreach(l
, parse
->sortClause
)
2802 SortGroupClause
*sortcl
= (SortGroupClause
*) lfirst(l
);
2803 TargetEntry
*tle
= get_sortgroupclause_tle(sortcl
, parse
->targetList
);
2805 uniqColIdx
[numUniqkeys
] = tle
->resno
;
2806 uniqOperators
[numUniqkeys
] = sortcl
->eqop
;
2807 uniqCollations
[numUniqkeys
] = exprCollation((Node
*) tle
->expr
);
2812 plan
= make_limit(subplan
,
2813 best_path
->limitOffset
,
2814 best_path
->limitCount
,
2815 best_path
->limitOption
,
2816 numUniqkeys
, uniqColIdx
, uniqOperators
, uniqCollations
);
2818 copy_generic_path_info(&plan
->plan
, (Path
*) best_path
);
2824 /*****************************************************************************
2826 * BASE-RELATION SCAN METHODS
2828 *****************************************************************************/
2832 * create_seqscan_plan
2833 * Returns a seqscan plan for the base relation scanned by 'best_path'
2834 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
2837 create_seqscan_plan(PlannerInfo
*root
, Path
*best_path
,
2838 List
*tlist
, List
*scan_clauses
)
2841 Index scan_relid
= best_path
->parent
->relid
;
2843 /* it should be a base rel... */
2844 Assert(scan_relid
> 0);
2845 Assert(best_path
->parent
->rtekind
== RTE_RELATION
);
2847 /* Sort clauses into best execution order */
2848 scan_clauses
= order_qual_clauses(root
, scan_clauses
);
2850 /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
2851 scan_clauses
= extract_actual_clauses(scan_clauses
, false);
2853 /* Replace any outer-relation variables with nestloop params */
2854 if (best_path
->param_info
)
2856 scan_clauses
= (List
*)
2857 replace_nestloop_params(root
, (Node
*) scan_clauses
);
2860 scan_plan
= make_seqscan(tlist
,
2864 copy_generic_path_info(&scan_plan
->scan
.plan
, best_path
);
2870 * create_samplescan_plan
2871 * Returns a samplescan plan for the base relation scanned by 'best_path'
2872 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
2875 create_samplescan_plan(PlannerInfo
*root
, Path
*best_path
,
2876 List
*tlist
, List
*scan_clauses
)
2878 SampleScan
*scan_plan
;
2879 Index scan_relid
= best_path
->parent
->relid
;
2881 TableSampleClause
*tsc
;
2883 /* it should be a base rel with a tablesample clause... */
2884 Assert(scan_relid
> 0);
2885 rte
= planner_rt_fetch(scan_relid
, root
);
2886 Assert(rte
->rtekind
== RTE_RELATION
);
2887 tsc
= rte
->tablesample
;
2888 Assert(tsc
!= NULL
);
2890 /* Sort clauses into best execution order */
2891 scan_clauses
= order_qual_clauses(root
, scan_clauses
);
2893 /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
2894 scan_clauses
= extract_actual_clauses(scan_clauses
, false);
2896 /* Replace any outer-relation variables with nestloop params */
2897 if (best_path
->param_info
)
2899 scan_clauses
= (List
*)
2900 replace_nestloop_params(root
, (Node
*) scan_clauses
);
2901 tsc
= (TableSampleClause
*)
2902 replace_nestloop_params(root
, (Node
*) tsc
);
2905 scan_plan
= make_samplescan(tlist
,
2910 copy_generic_path_info(&scan_plan
->scan
.plan
, best_path
);
2916 * create_indexscan_plan
2917 * Returns an indexscan plan for the base relation scanned by 'best_path'
2918 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
2920 * We use this for both plain IndexScans and IndexOnlyScans, because the
2921 * qual preprocessing work is the same for both. Note that the caller tells
2922 * us which to build --- we don't look at best_path->path.pathtype, because
2923 * create_bitmap_subplan needs to be able to override the prior decision.
2926 create_indexscan_plan(PlannerInfo
*root
,
2927 IndexPath
*best_path
,
2933 List
*indexclauses
= best_path
->indexclauses
;
2934 List
*indexorderbys
= best_path
->indexorderbys
;
2935 Index baserelid
= best_path
->path
.parent
->relid
;
2936 IndexOptInfo
*indexinfo
= best_path
->indexinfo
;
2937 Oid indexoid
= indexinfo
->indexoid
;
2939 List
*stripped_indexquals
;
2940 List
*fixed_indexquals
;
2941 List
*fixed_indexorderbys
;
2942 List
*indexorderbyops
= NIL
;
2945 /* it should be a base rel... */
2946 Assert(baserelid
> 0);
2947 Assert(best_path
->path
.parent
->rtekind
== RTE_RELATION
);
2950 * Extract the index qual expressions (stripped of RestrictInfos) from the
2951 * IndexClauses list, and prepare a copy with index Vars substituted for
2952 * table Vars. (This step also does replace_nestloop_params on the
2953 * fixed_indexquals.)
2955 fix_indexqual_references(root
, best_path
,
2956 &stripped_indexquals
,
2960 * Likewise fix up index attr references in the ORDER BY expressions.
2962 fixed_indexorderbys
= fix_indexorderby_references(root
, best_path
);
2965 * The qpqual list must contain all restrictions not automatically handled
2966 * by the index, other than pseudoconstant clauses which will be handled
2967 * by a separate gating plan node. All the predicates in the indexquals
2968 * will be checked (either by the index itself, or by nodeIndexscan.c),
2969 * but if there are any "special" operators involved then they must be
2970 * included in qpqual. The upshot is that qpqual must contain
2971 * scan_clauses minus whatever appears in indexquals.
2973 * is_redundant_with_indexclauses() detects cases where a scan clause is
2974 * present in the indexclauses list or is generated from the same
2975 * EquivalenceClass as some indexclause, and is therefore redundant with
2976 * it, though not equal. (The latter happens when indxpath.c prefers a
2977 * different derived equality than what generate_join_implied_equalities
2978 * picked for a parameterized scan's ppi_clauses.) Note that it will not
2979 * match to lossy index clauses, which is critical because we have to
2980 * include the original clause in qpqual in that case.
2982 * In some situations (particularly with OR'd index conditions) we may
2983 * have scan_clauses that are not equal to, but are logically implied by,
2984 * the index quals; so we also try a predicate_implied_by() check to see
2985 * if we can discard quals that way. (predicate_implied_by assumes its
2986 * first input contains only immutable functions, so we have to check
2989 * Note: if you change this bit of code you should also look at
2990 * extract_nonindex_conditions() in costsize.c.
2993 foreach(l
, scan_clauses
)
2995 RestrictInfo
*rinfo
= lfirst_node(RestrictInfo
, l
);
2997 if (rinfo
->pseudoconstant
)
2998 continue; /* we may drop pseudoconstants here */
2999 if (is_redundant_with_indexclauses(rinfo
, indexclauses
))
3000 continue; /* dup or derived from same EquivalenceClass */
3001 if (!contain_mutable_functions((Node
*) rinfo
->clause
) &&
3002 predicate_implied_by(list_make1(rinfo
->clause
), stripped_indexquals
,
3004 continue; /* provably implied by indexquals */
3005 qpqual
= lappend(qpqual
, rinfo
);
3008 /* Sort clauses into best execution order */
3009 qpqual
= order_qual_clauses(root
, qpqual
);
3011 /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
3012 qpqual
= extract_actual_clauses(qpqual
, false);
3015 * We have to replace any outer-relation variables with nestloop params in
3016 * the indexqualorig, qpqual, and indexorderbyorig expressions. A bit
3017 * annoying to have to do this separately from the processing in
3018 * fix_indexqual_references --- rethink this when generalizing the inner
3019 * indexscan support. But note we can't really do this earlier because
3020 * it'd break the comparisons to predicates above ... (or would it? Those
3021 * wouldn't have outer refs)
3023 if (best_path
->path
.param_info
)
3025 stripped_indexquals
= (List
*)
3026 replace_nestloop_params(root
, (Node
*) stripped_indexquals
);
3028 replace_nestloop_params(root
, (Node
*) qpqual
);
3029 indexorderbys
= (List
*)
3030 replace_nestloop_params(root
, (Node
*) indexorderbys
);
3034 * If there are ORDER BY expressions, look up the sort operators for their
3039 ListCell
*pathkeyCell
,
3043 * PathKey contains OID of the btree opfamily we're sorting by, but
3044 * that's not quite enough because we need the expression's datatype
3045 * to look up the sort operator in the operator family.
3047 Assert(list_length(best_path
->path
.pathkeys
) == list_length(indexorderbys
));
3048 forboth(pathkeyCell
, best_path
->path
.pathkeys
, exprCell
, indexorderbys
)
3050 PathKey
*pathkey
= (PathKey
*) lfirst(pathkeyCell
);
3051 Node
*expr
= (Node
*) lfirst(exprCell
);
3052 Oid exprtype
= exprType(expr
);
3055 /* Get sort operator from opfamily */
3056 sortop
= get_opfamily_member(pathkey
->pk_opfamily
,
3059 pathkey
->pk_strategy
);
3060 if (!OidIsValid(sortop
))
3061 elog(ERROR
, "missing operator %d(%u,%u) in opfamily %u",
3062 pathkey
->pk_strategy
, exprtype
, exprtype
, pathkey
->pk_opfamily
);
3063 indexorderbyops
= lappend_oid(indexorderbyops
, sortop
);
3068 * For an index-only scan, we must mark indextlist entries as resjunk if
3069 * they are columns that the index AM can't return; this cues setrefs.c to
3070 * not generate references to those columns.
3076 foreach(l
, indexinfo
->indextlist
)
3078 TargetEntry
*indextle
= (TargetEntry
*) lfirst(l
);
3080 indextle
->resjunk
= !indexinfo
->canreturn
[i
];
3085 /* Finally ready to build the plan node */
3087 scan_plan
= (Scan
*) make_indexonlyscan(tlist
,
3092 stripped_indexquals
,
3093 fixed_indexorderbys
,
3094 indexinfo
->indextlist
,
3095 best_path
->indexscandir
);
3097 scan_plan
= (Scan
*) make_indexscan(tlist
,
3102 stripped_indexquals
,
3103 fixed_indexorderbys
,
3106 best_path
->indexscandir
);
3108 copy_generic_path_info(&scan_plan
->plan
, &best_path
->path
);
3114 * create_bitmap_scan_plan
3115 * Returns a bitmap scan plan for the base relation scanned by 'best_path'
3116 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
3118 static BitmapHeapScan
*
3119 create_bitmap_scan_plan(PlannerInfo
*root
,
3120 BitmapHeapPath
*best_path
,
3124 Index baserelid
= best_path
->path
.parent
->relid
;
3125 Plan
*bitmapqualplan
;
3126 List
*bitmapqualorig
;
3131 BitmapHeapScan
*scan_plan
;
3133 /* it should be a base rel... */
3134 Assert(baserelid
> 0);
3135 Assert(best_path
->path
.parent
->rtekind
== RTE_RELATION
);
3137 /* Process the bitmapqual tree into a Plan tree and qual lists */
3138 bitmapqualplan
= create_bitmap_subplan(root
, best_path
->bitmapqual
,
3139 &bitmapqualorig
, &indexquals
,
3142 if (best_path
->path
.parallel_aware
)
3143 bitmap_subplan_mark_shared(bitmapqualplan
);
3146 * The qpqual list must contain all restrictions not automatically handled
3147 * by the index, other than pseudoconstant clauses which will be handled
3148 * by a separate gating plan node. All the predicates in the indexquals
3149 * will be checked (either by the index itself, or by
3150 * nodeBitmapHeapscan.c), but if there are any "special" operators
3151 * involved then they must be added to qpqual. The upshot is that qpqual
3152 * must contain scan_clauses minus whatever appears in indexquals.
3154 * This loop is similar to the comparable code in create_indexscan_plan(),
3155 * but with some differences because it has to compare the scan clauses to
3156 * stripped (no RestrictInfos) indexquals. See comments there for more
3159 * In normal cases simple equal() checks will be enough to spot duplicate
3160 * clauses, so we try that first. We next see if the scan clause is
3161 * redundant with any top-level indexqual by virtue of being generated
3162 * from the same EC. After that, try predicate_implied_by().
3164 * Unlike create_indexscan_plan(), the predicate_implied_by() test here is
3165 * useful for getting rid of qpquals that are implied by index predicates,
3166 * because the predicate conditions are included in the "indexquals"
3167 * returned by create_bitmap_subplan(). Bitmap scans have to do it that
3168 * way because predicate conditions need to be rechecked if the scan
3169 * becomes lossy, so they have to be included in bitmapqualorig.
3172 foreach(l
, scan_clauses
)
3174 RestrictInfo
*rinfo
= lfirst_node(RestrictInfo
, l
);
3175 Node
*clause
= (Node
*) rinfo
->clause
;
3177 if (rinfo
->pseudoconstant
)
3178 continue; /* we may drop pseudoconstants here */
3179 if (list_member(indexquals
, clause
))
3180 continue; /* simple duplicate */
3181 if (rinfo
->parent_ec
&& list_member_ptr(indexECs
, rinfo
->parent_ec
))
3182 continue; /* derived from same EquivalenceClass */
3183 if (!contain_mutable_functions(clause
) &&
3184 predicate_implied_by(list_make1(clause
), indexquals
, false))
3185 continue; /* provably implied by indexquals */
3186 qpqual
= lappend(qpqual
, rinfo
);
3189 /* Sort clauses into best execution order */
3190 qpqual
= order_qual_clauses(root
, qpqual
);
3192 /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
3193 qpqual
= extract_actual_clauses(qpqual
, false);
3196 * When dealing with special operators, we will at this point have
3197 * duplicate clauses in qpqual and bitmapqualorig. We may as well drop
3198 * 'em from bitmapqualorig, since there's no point in making the tests
3201 bitmapqualorig
= list_difference_ptr(bitmapqualorig
, qpqual
);
3204 * We have to replace any outer-relation variables with nestloop params in
3205 * the qpqual and bitmapqualorig expressions. (This was already done for
3206 * expressions attached to plan nodes in the bitmapqualplan tree.)
3208 if (best_path
->path
.param_info
)
3211 replace_nestloop_params(root
, (Node
*) qpqual
);
3212 bitmapqualorig
= (List
*)
3213 replace_nestloop_params(root
, (Node
*) bitmapqualorig
);
3216 /* Finally ready to build the plan node */
3217 scan_plan
= make_bitmap_heapscan(tlist
,
3223 copy_generic_path_info(&scan_plan
->scan
.plan
, &best_path
->path
);
3229 * Given a bitmapqual tree, generate the Plan tree that implements it
3231 * As byproducts, we also return in *qual and *indexqual the qual lists
3232 * (in implicit-AND form, without RestrictInfos) describing the original index
3233 * conditions and the generated indexqual conditions. (These are the same in
3234 * simple cases, but when special index operators are involved, the former
3235 * list includes the special conditions while the latter includes the actual
3236 * indexable conditions derived from them.) Both lists include partial-index
3237 * predicates, because we have to recheck predicates as well as index
3238 * conditions if the bitmap scan becomes lossy.
3240 * In addition, we return a list of EquivalenceClass pointers for all the
3241 * top-level indexquals that were possibly-redundantly derived from ECs.
3242 * This allows removal of scan_clauses that are redundant with such quals.
3243 * (We do not attempt to detect such redundancies for quals that are within
3244 * OR subtrees. This could be done in a less hacky way if we returned the
3245 * indexquals in RestrictInfo form, but that would be slower and still pretty
3246 * messy, since we'd have to build new RestrictInfos in many cases.)
3249 create_bitmap_subplan(PlannerInfo
*root
, Path
*bitmapqual
,
3250 List
**qual
, List
**indexqual
, List
**indexECs
)
3254 if (IsA(bitmapqual
, BitmapAndPath
))
3256 BitmapAndPath
*apath
= (BitmapAndPath
*) bitmapqual
;
3257 List
*subplans
= NIL
;
3258 List
*subquals
= NIL
;
3259 List
*subindexquals
= NIL
;
3260 List
*subindexECs
= NIL
;
3264 * There may well be redundant quals among the subplans, since a
3265 * top-level WHERE qual might have gotten used to form several
3266 * different index quals. We don't try exceedingly hard to eliminate
3267 * redundancies, but we do eliminate obvious duplicates by using
3268 * list_concat_unique.
3270 foreach(l
, apath
->bitmapquals
)
3277 subplan
= create_bitmap_subplan(root
, (Path
*) lfirst(l
),
3278 &subqual
, &subindexqual
,
3280 subplans
= lappend(subplans
, subplan
);
3281 subquals
= list_concat_unique(subquals
, subqual
);
3282 subindexquals
= list_concat_unique(subindexquals
, subindexqual
);
3283 /* Duplicates in indexECs aren't worth getting rid of */
3284 subindexECs
= list_concat(subindexECs
, subindexEC
);
3286 plan
= (Plan
*) make_bitmap_and(subplans
);
3287 plan
->startup_cost
= apath
->path
.startup_cost
;
3288 plan
->total_cost
= apath
->path
.total_cost
;
3290 clamp_row_est(apath
->bitmapselectivity
* apath
->path
.parent
->tuples
);
3291 plan
->plan_width
= 0; /* meaningless */
3292 plan
->parallel_aware
= false;
3293 plan
->parallel_safe
= apath
->path
.parallel_safe
;
3295 *indexqual
= subindexquals
;
3296 *indexECs
= subindexECs
;
3298 else if (IsA(bitmapqual
, BitmapOrPath
))
3300 BitmapOrPath
*opath
= (BitmapOrPath
*) bitmapqual
;
3301 List
*subplans
= NIL
;
3302 List
*subquals
= NIL
;
3303 List
*subindexquals
= NIL
;
3304 bool const_true_subqual
= false;
3305 bool const_true_subindexqual
= false;
3309 * Here, we only detect qual-free subplans. A qual-free subplan would
3310 * cause us to generate "... OR true ..." which we may as well reduce
3311 * to just "true". We do not try to eliminate redundant subclauses
3312 * because (a) it's not as likely as in the AND case, and (b) we might
3313 * well be working with hundreds or even thousands of OR conditions,
3314 * perhaps from a long IN list. The performance of list_append_unique
3315 * would be unacceptable.
3317 foreach(l
, opath
->bitmapquals
)
3324 subplan
= create_bitmap_subplan(root
, (Path
*) lfirst(l
),
3325 &subqual
, &subindexqual
,
3327 subplans
= lappend(subplans
, subplan
);
3329 const_true_subqual
= true;
3330 else if (!const_true_subqual
)
3331 subquals
= lappend(subquals
,
3332 make_ands_explicit(subqual
));
3333 if (subindexqual
== NIL
)
3334 const_true_subindexqual
= true;
3335 else if (!const_true_subindexqual
)
3336 subindexquals
= lappend(subindexquals
,
3337 make_ands_explicit(subindexqual
));
3341 * In the presence of ScalarArrayOpExpr quals, we might have built
3342 * BitmapOrPaths with just one subpath; don't add an OR step.
3344 if (list_length(subplans
) == 1)
3346 plan
= (Plan
*) linitial(subplans
);
3350 plan
= (Plan
*) make_bitmap_or(subplans
);
3351 plan
->startup_cost
= opath
->path
.startup_cost
;
3352 plan
->total_cost
= opath
->path
.total_cost
;
3354 clamp_row_est(opath
->bitmapselectivity
* opath
->path
.parent
->tuples
);
3355 plan
->plan_width
= 0; /* meaningless */
3356 plan
->parallel_aware
= false;
3357 plan
->parallel_safe
= opath
->path
.parallel_safe
;
3361 * If there were constant-TRUE subquals, the OR reduces to constant
3362 * TRUE. Also, avoid generating one-element ORs, which could happen
3363 * due to redundancy elimination or ScalarArrayOpExpr quals.
3365 if (const_true_subqual
)
3367 else if (list_length(subquals
) <= 1)
3370 *qual
= list_make1(make_orclause(subquals
));
3371 if (const_true_subindexqual
)
3373 else if (list_length(subindexquals
) <= 1)
3374 *indexqual
= subindexquals
;
3376 *indexqual
= list_make1(make_orclause(subindexquals
));
3379 else if (IsA(bitmapqual
, IndexPath
))
3381 IndexPath
*ipath
= (IndexPath
*) bitmapqual
;
3384 List
*subindexquals
;
3388 /* Use the regular indexscan plan build machinery... */
3389 iscan
= castNode(IndexScan
,
3390 create_indexscan_plan(root
, ipath
,
3392 /* then convert to a bitmap indexscan */
3393 plan
= (Plan
*) make_bitmap_indexscan(iscan
->scan
.scanrelid
,
3396 iscan
->indexqualorig
);
3397 /* and set its cost/width fields appropriately */
3398 plan
->startup_cost
= 0.0;
3399 plan
->total_cost
= ipath
->indextotalcost
;
3401 clamp_row_est(ipath
->indexselectivity
* ipath
->path
.parent
->tuples
);
3402 plan
->plan_width
= 0; /* meaningless */
3403 plan
->parallel_aware
= false;
3404 plan
->parallel_safe
= ipath
->path
.parallel_safe
;
3405 /* Extract original index clauses, actual index quals, relevant ECs */
3407 subindexquals
= NIL
;
3409 foreach(l
, ipath
->indexclauses
)
3411 IndexClause
*iclause
= (IndexClause
*) lfirst(l
);
3412 RestrictInfo
*rinfo
= iclause
->rinfo
;
3414 Assert(!rinfo
->pseudoconstant
);
3415 subquals
= lappend(subquals
, rinfo
->clause
);
3416 subindexquals
= list_concat(subindexquals
,
3417 get_actual_clauses(iclause
->indexquals
));
3418 if (rinfo
->parent_ec
)
3419 subindexECs
= lappend(subindexECs
, rinfo
->parent_ec
);
3421 /* We can add any index predicate conditions, too */
3422 foreach(l
, ipath
->indexinfo
->indpred
)
3424 Expr
*pred
= (Expr
*) lfirst(l
);
3427 * We know that the index predicate must have been implied by the
3428 * query condition as a whole, but it may or may not be implied by
3429 * the conditions that got pushed into the bitmapqual. Avoid
3430 * generating redundant conditions.
3432 if (!predicate_implied_by(list_make1(pred
), subquals
, false))
3434 subquals
= lappend(subquals
, pred
);
3435 subindexquals
= lappend(subindexquals
, pred
);
3439 *indexqual
= subindexquals
;
3440 *indexECs
= subindexECs
;
3444 elog(ERROR
, "unrecognized node type: %d", nodeTag(bitmapqual
));
3445 plan
= NULL
; /* keep compiler quiet */
3452 * create_tidscan_plan
3453 * Returns a tidscan plan for the base relation scanned by 'best_path'
3454 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
3457 create_tidscan_plan(PlannerInfo
*root
, TidPath
*best_path
,
3458 List
*tlist
, List
*scan_clauses
)
3461 Index scan_relid
= best_path
->path
.parent
->relid
;
3462 List
*tidquals
= best_path
->tidquals
;
3464 /* it should be a base rel... */
3465 Assert(scan_relid
> 0);
3466 Assert(best_path
->path
.parent
->rtekind
== RTE_RELATION
);
3469 * The qpqual list must contain all restrictions not enforced by the
3470 * tidquals list. Since tidquals has OR semantics, we have to be careful
3471 * about matching it up to scan_clauses. It's convenient to handle the
3472 * single-tidqual case separately from the multiple-tidqual case. In the
3473 * single-tidqual case, we look through the scan_clauses while they are
3474 * still in RestrictInfo form, and drop any that are redundant with the
3477 * In normal cases simple pointer equality checks will be enough to spot
3478 * duplicate RestrictInfos, so we try that first.
3480 * Another common case is that a scan_clauses entry is generated from the
3481 * same EquivalenceClass as some tidqual, and is therefore redundant with
3482 * it, though not equal.
3484 * Unlike indexpaths, we don't bother with predicate_implied_by(); the
3485 * number of cases where it could win are pretty small.
3487 if (list_length(tidquals
) == 1)
3492 foreach(l
, scan_clauses
)
3494 RestrictInfo
*rinfo
= lfirst_node(RestrictInfo
, l
);
3496 if (rinfo
->pseudoconstant
)
3497 continue; /* we may drop pseudoconstants here */
3498 if (list_member_ptr(tidquals
, rinfo
))
3499 continue; /* simple duplicate */
3500 if (is_redundant_derived_clause(rinfo
, tidquals
))
3501 continue; /* derived from same EquivalenceClass */
3502 qpqual
= lappend(qpqual
, rinfo
);
3504 scan_clauses
= qpqual
;
3507 /* Sort clauses into best execution order */
3508 scan_clauses
= order_qual_clauses(root
, scan_clauses
);
3510 /* Reduce RestrictInfo lists to bare expressions; ignore pseudoconstants */
3511 tidquals
= extract_actual_clauses(tidquals
, false);
3512 scan_clauses
= extract_actual_clauses(scan_clauses
, false);
3515 * If we have multiple tidquals, it's more convenient to remove duplicate
3516 * scan_clauses after stripping the RestrictInfos. In this situation,
3517 * because the tidquals represent OR sub-clauses, they could not have come
3518 * from EquivalenceClasses so we don't have to worry about matching up
3519 * non-identical clauses. On the other hand, because tidpath.c will have
3520 * extracted those sub-clauses from some OR clause and built its own list,
3521 * we will certainly not have pointer equality to any scan clause. So
3522 * convert the tidquals list to an explicit OR clause and see if we can
3523 * match it via equal() to any scan clause.
3525 if (list_length(tidquals
) > 1)
3526 scan_clauses
= list_difference(scan_clauses
,
3527 list_make1(make_orclause(tidquals
)));
3529 /* Replace any outer-relation variables with nestloop params */
3530 if (best_path
->path
.param_info
)
3533 replace_nestloop_params(root
, (Node
*) tidquals
);
3534 scan_clauses
= (List
*)
3535 replace_nestloop_params(root
, (Node
*) scan_clauses
);
3538 scan_plan
= make_tidscan(tlist
,
3543 copy_generic_path_info(&scan_plan
->scan
.plan
, &best_path
->path
);
3549 * create_tidrangescan_plan
3550 * Returns a tidrangescan plan for the base relation scanned by 'best_path'
3551 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
3553 static TidRangeScan
*
3554 create_tidrangescan_plan(PlannerInfo
*root
, TidRangePath
*best_path
,
3555 List
*tlist
, List
*scan_clauses
)
3557 TidRangeScan
*scan_plan
;
3558 Index scan_relid
= best_path
->path
.parent
->relid
;
3559 List
*tidrangequals
= best_path
->tidrangequals
;
3561 /* it should be a base rel... */
3562 Assert(scan_relid
> 0);
3563 Assert(best_path
->path
.parent
->rtekind
== RTE_RELATION
);
3566 * The qpqual list must contain all restrictions not enforced by the
3567 * tidrangequals list. tidrangequals has AND semantics, so we can simply
3568 * remove any qual that appears in it.
3574 foreach(l
, scan_clauses
)
3576 RestrictInfo
*rinfo
= lfirst_node(RestrictInfo
, l
);
3578 if (rinfo
->pseudoconstant
)
3579 continue; /* we may drop pseudoconstants here */
3580 if (list_member_ptr(tidrangequals
, rinfo
))
3581 continue; /* simple duplicate */
3582 qpqual
= lappend(qpqual
, rinfo
);
3584 scan_clauses
= qpqual
;
3587 /* Sort clauses into best execution order */
3588 scan_clauses
= order_qual_clauses(root
, scan_clauses
);
3590 /* Reduce RestrictInfo lists to bare expressions; ignore pseudoconstants */
3591 tidrangequals
= extract_actual_clauses(tidrangequals
, false);
3592 scan_clauses
= extract_actual_clauses(scan_clauses
, false);
3594 /* Replace any outer-relation variables with nestloop params */
3595 if (best_path
->path
.param_info
)
3597 tidrangequals
= (List
*)
3598 replace_nestloop_params(root
, (Node
*) tidrangequals
);
3599 scan_clauses
= (List
*)
3600 replace_nestloop_params(root
, (Node
*) scan_clauses
);
3603 scan_plan
= make_tidrangescan(tlist
,
3608 copy_generic_path_info(&scan_plan
->scan
.plan
, &best_path
->path
);
3614 * create_subqueryscan_plan
3615 * Returns a subqueryscan plan for the base relation scanned by 'best_path'
3616 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
3618 static SubqueryScan
*
3619 create_subqueryscan_plan(PlannerInfo
*root
, SubqueryScanPath
*best_path
,
3620 List
*tlist
, List
*scan_clauses
)
3622 SubqueryScan
*scan_plan
;
3623 RelOptInfo
*rel
= best_path
->path
.parent
;
3624 Index scan_relid
= rel
->relid
;
3627 /* it should be a subquery base rel... */
3628 Assert(scan_relid
> 0);
3629 Assert(rel
->rtekind
== RTE_SUBQUERY
);
3632 * Recursively create Plan from Path for subquery. Since we are entering
3633 * a different planner context (subroot), recurse to create_plan not
3634 * create_plan_recurse.
3636 subplan
= create_plan(rel
->subroot
, best_path
->subpath
);
3638 /* Sort clauses into best execution order */
3639 scan_clauses
= order_qual_clauses(root
, scan_clauses
);
3641 /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
3642 scan_clauses
= extract_actual_clauses(scan_clauses
, false);
3644 /* Replace any outer-relation variables with nestloop params */
3645 if (best_path
->path
.param_info
)
3647 scan_clauses
= (List
*)
3648 replace_nestloop_params(root
, (Node
*) scan_clauses
);
3649 process_subquery_nestloop_params(root
,
3650 rel
->subplan_params
);
3653 scan_plan
= make_subqueryscan(tlist
,
3658 copy_generic_path_info(&scan_plan
->scan
.plan
, &best_path
->path
);
3664 * create_functionscan_plan
3665 * Returns a functionscan plan for the base relation scanned by 'best_path'
3666 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
3668 static FunctionScan
*
3669 create_functionscan_plan(PlannerInfo
*root
, Path
*best_path
,
3670 List
*tlist
, List
*scan_clauses
)
3672 FunctionScan
*scan_plan
;
3673 Index scan_relid
= best_path
->parent
->relid
;
3677 /* it should be a function base rel... */
3678 Assert(scan_relid
> 0);
3679 rte
= planner_rt_fetch(scan_relid
, root
);
3680 Assert(rte
->rtekind
== RTE_FUNCTION
);
3681 functions
= rte
->functions
;
3683 /* Sort clauses into best execution order */
3684 scan_clauses
= order_qual_clauses(root
, scan_clauses
);
3686 /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
3687 scan_clauses
= extract_actual_clauses(scan_clauses
, false);
3689 /* Replace any outer-relation variables with nestloop params */
3690 if (best_path
->param_info
)
3692 scan_clauses
= (List
*)
3693 replace_nestloop_params(root
, (Node
*) scan_clauses
);
3694 /* The function expressions could contain nestloop params, too */
3695 functions
= (List
*) replace_nestloop_params(root
, (Node
*) functions
);
3698 scan_plan
= make_functionscan(tlist
, scan_clauses
, scan_relid
,
3699 functions
, rte
->funcordinality
);
3701 copy_generic_path_info(&scan_plan
->scan
.plan
, best_path
);
3707 * create_tablefuncscan_plan
3708 * Returns a tablefuncscan plan for the base relation scanned by 'best_path'
3709 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
3711 static TableFuncScan
*
3712 create_tablefuncscan_plan(PlannerInfo
*root
, Path
*best_path
,
3713 List
*tlist
, List
*scan_clauses
)
3715 TableFuncScan
*scan_plan
;
3716 Index scan_relid
= best_path
->parent
->relid
;
3718 TableFunc
*tablefunc
;
3720 /* it should be a function base rel... */
3721 Assert(scan_relid
> 0);
3722 rte
= planner_rt_fetch(scan_relid
, root
);
3723 Assert(rte
->rtekind
== RTE_TABLEFUNC
);
3724 tablefunc
= rte
->tablefunc
;
3726 /* Sort clauses into best execution order */
3727 scan_clauses
= order_qual_clauses(root
, scan_clauses
);
3729 /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
3730 scan_clauses
= extract_actual_clauses(scan_clauses
, false);
3732 /* Replace any outer-relation variables with nestloop params */
3733 if (best_path
->param_info
)
3735 scan_clauses
= (List
*)
3736 replace_nestloop_params(root
, (Node
*) scan_clauses
);
3737 /* The function expressions could contain nestloop params, too */
3738 tablefunc
= (TableFunc
*) replace_nestloop_params(root
, (Node
*) tablefunc
);
3741 scan_plan
= make_tablefuncscan(tlist
, scan_clauses
, scan_relid
,
3744 copy_generic_path_info(&scan_plan
->scan
.plan
, best_path
);
3750 * create_valuesscan_plan
3751 * Returns a valuesscan plan for the base relation scanned by 'best_path'
3752 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
3755 create_valuesscan_plan(PlannerInfo
*root
, Path
*best_path
,
3756 List
*tlist
, List
*scan_clauses
)
3758 ValuesScan
*scan_plan
;
3759 Index scan_relid
= best_path
->parent
->relid
;
3763 /* it should be a values base rel... */
3764 Assert(scan_relid
> 0);
3765 rte
= planner_rt_fetch(scan_relid
, root
);
3766 Assert(rte
->rtekind
== RTE_VALUES
);
3767 values_lists
= rte
->values_lists
;
3769 /* Sort clauses into best execution order */
3770 scan_clauses
= order_qual_clauses(root
, scan_clauses
);
3772 /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
3773 scan_clauses
= extract_actual_clauses(scan_clauses
, false);
3775 /* Replace any outer-relation variables with nestloop params */
3776 if (best_path
->param_info
)
3778 scan_clauses
= (List
*)
3779 replace_nestloop_params(root
, (Node
*) scan_clauses
);
3780 /* The values lists could contain nestloop params, too */
3781 values_lists
= (List
*)
3782 replace_nestloop_params(root
, (Node
*) values_lists
);
3785 scan_plan
= make_valuesscan(tlist
, scan_clauses
, scan_relid
,
3788 copy_generic_path_info(&scan_plan
->scan
.plan
, best_path
);
3794 * create_ctescan_plan
3795 * Returns a ctescan plan for the base relation scanned by 'best_path'
3796 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
3799 create_ctescan_plan(PlannerInfo
*root
, Path
*best_path
,
3800 List
*tlist
, List
*scan_clauses
)
3803 Index scan_relid
= best_path
->parent
->relid
;
3805 SubPlan
*ctesplan
= NULL
;
3808 PlannerInfo
*cteroot
;
3813 Assert(scan_relid
> 0);
3814 rte
= planner_rt_fetch(scan_relid
, root
);
3815 Assert(rte
->rtekind
== RTE_CTE
);
3816 Assert(!rte
->self_reference
);
3819 * Find the referenced CTE, and locate the SubPlan previously made for it.
3821 levelsup
= rte
->ctelevelsup
;
3823 while (levelsup
-- > 0)
3825 cteroot
= cteroot
->parent_root
;
3826 if (!cteroot
) /* shouldn't happen */
3827 elog(ERROR
, "bad levelsup for CTE \"%s\"", rte
->ctename
);
3831 * Note: cte_plan_ids can be shorter than cteList, if we are still working
3832 * on planning the CTEs (ie, this is a side-reference from another CTE).
3833 * So we mustn't use forboth here.
3836 foreach(lc
, cteroot
->parse
->cteList
)
3838 CommonTableExpr
*cte
= (CommonTableExpr
*) lfirst(lc
);
3840 if (strcmp(cte
->ctename
, rte
->ctename
) == 0)
3844 if (lc
== NULL
) /* shouldn't happen */
3845 elog(ERROR
, "could not find CTE \"%s\"", rte
->ctename
);
3846 if (ndx
>= list_length(cteroot
->cte_plan_ids
))
3847 elog(ERROR
, "could not find plan for CTE \"%s\"", rte
->ctename
);
3848 plan_id
= list_nth_int(cteroot
->cte_plan_ids
, ndx
);
3849 Assert(plan_id
> 0);
3850 foreach(lc
, cteroot
->init_plans
)
3852 ctesplan
= (SubPlan
*) lfirst(lc
);
3853 if (ctesplan
->plan_id
== plan_id
)
3856 if (lc
== NULL
) /* shouldn't happen */
3857 elog(ERROR
, "could not find plan for CTE \"%s\"", rte
->ctename
);
3860 * We need the CTE param ID, which is the sole member of the SubPlan's
3863 cte_param_id
= linitial_int(ctesplan
->setParam
);
3865 /* Sort clauses into best execution order */
3866 scan_clauses
= order_qual_clauses(root
, scan_clauses
);
3868 /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
3869 scan_clauses
= extract_actual_clauses(scan_clauses
, false);
3871 /* Replace any outer-relation variables with nestloop params */
3872 if (best_path
->param_info
)
3874 scan_clauses
= (List
*)
3875 replace_nestloop_params(root
, (Node
*) scan_clauses
);
3878 scan_plan
= make_ctescan(tlist
, scan_clauses
, scan_relid
,
3879 plan_id
, cte_param_id
);
3881 copy_generic_path_info(&scan_plan
->scan
.plan
, best_path
);
3887 * create_namedtuplestorescan_plan
3888 * Returns a tuplestorescan plan for the base relation scanned by
3889 * 'best_path' with restriction clauses 'scan_clauses' and targetlist
3892 static NamedTuplestoreScan
*
3893 create_namedtuplestorescan_plan(PlannerInfo
*root
, Path
*best_path
,
3894 List
*tlist
, List
*scan_clauses
)
3896 NamedTuplestoreScan
*scan_plan
;
3897 Index scan_relid
= best_path
->parent
->relid
;
3900 Assert(scan_relid
> 0);
3901 rte
= planner_rt_fetch(scan_relid
, root
);
3902 Assert(rte
->rtekind
== RTE_NAMEDTUPLESTORE
);
3904 /* Sort clauses into best execution order */
3905 scan_clauses
= order_qual_clauses(root
, scan_clauses
);
3907 /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
3908 scan_clauses
= extract_actual_clauses(scan_clauses
, false);
3910 /* Replace any outer-relation variables with nestloop params */
3911 if (best_path
->param_info
)
3913 scan_clauses
= (List
*)
3914 replace_nestloop_params(root
, (Node
*) scan_clauses
);
3917 scan_plan
= make_namedtuplestorescan(tlist
, scan_clauses
, scan_relid
,
3920 copy_generic_path_info(&scan_plan
->scan
.plan
, best_path
);
3926 * create_resultscan_plan
3927 * Returns a Result plan for the RTE_RESULT base relation scanned by
3928 * 'best_path' with restriction clauses 'scan_clauses' and targetlist
3932 create_resultscan_plan(PlannerInfo
*root
, Path
*best_path
,
3933 List
*tlist
, List
*scan_clauses
)
3936 Index scan_relid
= best_path
->parent
->relid
;
3937 RangeTblEntry
*rte PG_USED_FOR_ASSERTS_ONLY
;
3939 Assert(scan_relid
> 0);
3940 rte
= planner_rt_fetch(scan_relid
, root
);
3941 Assert(rte
->rtekind
== RTE_RESULT
);
3943 /* Sort clauses into best execution order */
3944 scan_clauses
= order_qual_clauses(root
, scan_clauses
);
3946 /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
3947 scan_clauses
= extract_actual_clauses(scan_clauses
, false);
3949 /* Replace any outer-relation variables with nestloop params */
3950 if (best_path
->param_info
)
3952 scan_clauses
= (List
*)
3953 replace_nestloop_params(root
, (Node
*) scan_clauses
);
3956 scan_plan
= make_result(tlist
, (Node
*) scan_clauses
, NULL
);
3958 copy_generic_path_info(&scan_plan
->plan
, best_path
);
3964 * create_worktablescan_plan
3965 * Returns a worktablescan plan for the base relation scanned by 'best_path'
3966 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
3968 static WorkTableScan
*
3969 create_worktablescan_plan(PlannerInfo
*root
, Path
*best_path
,
3970 List
*tlist
, List
*scan_clauses
)
3972 WorkTableScan
*scan_plan
;
3973 Index scan_relid
= best_path
->parent
->relid
;
3976 PlannerInfo
*cteroot
;
3978 Assert(scan_relid
> 0);
3979 rte
= planner_rt_fetch(scan_relid
, root
);
3980 Assert(rte
->rtekind
== RTE_CTE
);
3981 Assert(rte
->self_reference
);
3984 * We need to find the worktable param ID, which is in the plan level
3985 * that's processing the recursive UNION, which is one level *below* where
3986 * the CTE comes from.
3988 levelsup
= rte
->ctelevelsup
;
3989 if (levelsup
== 0) /* shouldn't happen */
3990 elog(ERROR
, "bad levelsup for CTE \"%s\"", rte
->ctename
);
3993 while (levelsup
-- > 0)
3995 cteroot
= cteroot
->parent_root
;
3996 if (!cteroot
) /* shouldn't happen */
3997 elog(ERROR
, "bad levelsup for CTE \"%s\"", rte
->ctename
);
3999 if (cteroot
->wt_param_id
< 0) /* shouldn't happen */
4000 elog(ERROR
, "could not find param ID for CTE \"%s\"", rte
->ctename
);
4002 /* Sort clauses into best execution order */
4003 scan_clauses
= order_qual_clauses(root
, scan_clauses
);
4005 /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
4006 scan_clauses
= extract_actual_clauses(scan_clauses
, false);
4008 /* Replace any outer-relation variables with nestloop params */
4009 if (best_path
->param_info
)
4011 scan_clauses
= (List
*)
4012 replace_nestloop_params(root
, (Node
*) scan_clauses
);
4015 scan_plan
= make_worktablescan(tlist
, scan_clauses
, scan_relid
,
4016 cteroot
->wt_param_id
);
4018 copy_generic_path_info(&scan_plan
->scan
.plan
, best_path
);
4024 * create_foreignscan_plan
4025 * Returns a foreignscan plan for the relation scanned by 'best_path'
4026 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
4028 static ForeignScan
*
4029 create_foreignscan_plan(PlannerInfo
*root
, ForeignPath
*best_path
,
4030 List
*tlist
, List
*scan_clauses
)
4032 ForeignScan
*scan_plan
;
4033 RelOptInfo
*rel
= best_path
->path
.parent
;
4034 Index scan_relid
= rel
->relid
;
4035 Oid rel_oid
= InvalidOid
;
4036 Plan
*outer_plan
= NULL
;
4038 Assert(rel
->fdwroutine
!= NULL
);
4040 /* transform the child path if any */
4041 if (best_path
->fdw_outerpath
)
4042 outer_plan
= create_plan_recurse(root
, best_path
->fdw_outerpath
,
4046 * If we're scanning a base relation, fetch its OID. (Irrelevant if
4047 * scanning a join relation.)
4053 Assert(rel
->rtekind
== RTE_RELATION
);
4054 rte
= planner_rt_fetch(scan_relid
, root
);
4055 Assert(rte
->rtekind
== RTE_RELATION
);
4056 rel_oid
= rte
->relid
;
4060 * Sort clauses into best execution order. We do this first since the FDW
4061 * might have more info than we do and wish to adjust the ordering.
4063 scan_clauses
= order_qual_clauses(root
, scan_clauses
);
4066 * Let the FDW perform its processing on the restriction clauses and
4067 * generate the plan node. Note that the FDW might remove restriction
4068 * clauses that it intends to execute remotely, or even add more (if it
4069 * has selected some join clauses for remote use but also wants them
4070 * rechecked locally).
4072 scan_plan
= rel
->fdwroutine
->GetForeignPlan(root
, rel
, rel_oid
,
4074 tlist
, scan_clauses
,
4077 /* Copy cost data from Path to Plan; no need to make FDW do this */
4078 copy_generic_path_info(&scan_plan
->scan
.plan
, &best_path
->path
);
4080 /* Copy foreign server OID; likewise, no need to make FDW do this */
4081 scan_plan
->fs_server
= rel
->serverid
;
4084 * Likewise, copy the relids that are represented by this foreign scan. An
4085 * upper rel doesn't have relids set, but it covers all the base relations
4086 * participating in the underlying scan, so use root's all_baserels.
4088 if (rel
->reloptkind
== RELOPT_UPPER_REL
)
4089 scan_plan
->fs_relids
= root
->all_baserels
;
4091 scan_plan
->fs_relids
= best_path
->path
.parent
->relids
;
4094 * If this is a foreign join, and to make it valid to push down we had to
4095 * assume that the current user is the same as some user explicitly named
4096 * in the query, mark the finished plan as depending on the current user.
4098 if (rel
->useridiscurrent
)
4099 root
->glob
->dependsOnRole
= true;
4102 * Replace any outer-relation variables with nestloop params in the qual,
4103 * fdw_exprs and fdw_recheck_quals expressions. We do this last so that
4104 * the FDW doesn't have to be involved. (Note that parts of fdw_exprs or
4105 * fdw_recheck_quals could have come from join clauses, so doing this
4106 * beforehand on the scan_clauses wouldn't work.) We assume
4107 * fdw_scan_tlist contains no such variables.
4109 if (best_path
->path
.param_info
)
4111 scan_plan
->scan
.plan
.qual
= (List
*)
4112 replace_nestloop_params(root
, (Node
*) scan_plan
->scan
.plan
.qual
);
4113 scan_plan
->fdw_exprs
= (List
*)
4114 replace_nestloop_params(root
, (Node
*) scan_plan
->fdw_exprs
);
4115 scan_plan
->fdw_recheck_quals
= (List
*)
4116 replace_nestloop_params(root
,
4117 (Node
*) scan_plan
->fdw_recheck_quals
);
4121 * If rel is a base relation, detect whether any system columns are
4122 * requested from the rel. (If rel is a join relation, rel->relid will be
4123 * 0, but there can be no Var with relid 0 in the rel's targetlist or the
4124 * restriction clauses, so we skip this in that case. Note that any such
4125 * columns in base relations that were joined are assumed to be contained
4126 * in fdw_scan_tlist.) This is a bit of a kluge and might go away
4127 * someday, so we intentionally leave it out of the API presented to FDWs.
4129 scan_plan
->fsSystemCol
= false;
4132 Bitmapset
*attrs_used
= NULL
;
4137 * First, examine all the attributes needed for joins or final output.
4138 * Note: we must look at rel's targetlist, not the attr_needed data,
4139 * because attr_needed isn't computed for inheritance child rels.
4141 pull_varattnos((Node
*) rel
->reltarget
->exprs
, scan_relid
, &attrs_used
);
4143 /* Add all the attributes used by restriction clauses. */
4144 foreach(lc
, rel
->baserestrictinfo
)
4146 RestrictInfo
*rinfo
= (RestrictInfo
*) lfirst(lc
);
4148 pull_varattnos((Node
*) rinfo
->clause
, scan_relid
, &attrs_used
);
4151 /* Now, are any system columns requested from rel? */
4152 for (i
= FirstLowInvalidHeapAttributeNumber
+ 1; i
< 0; i
++)
4154 if (bms_is_member(i
- FirstLowInvalidHeapAttributeNumber
, attrs_used
))
4156 scan_plan
->fsSystemCol
= true;
4161 bms_free(attrs_used
);
4168 * create_customscan_plan
4170 * Transform a CustomPath into a Plan.
4173 create_customscan_plan(PlannerInfo
*root
, CustomPath
*best_path
,
4174 List
*tlist
, List
*scan_clauses
)
4177 RelOptInfo
*rel
= best_path
->path
.parent
;
4178 List
*custom_plans
= NIL
;
4181 /* Recursively transform child paths. */
4182 foreach(lc
, best_path
->custom_paths
)
4184 Plan
*plan
= create_plan_recurse(root
, (Path
*) lfirst(lc
),
4187 custom_plans
= lappend(custom_plans
, plan
);
4191 * Sort clauses into the best execution order, although custom-scan
4192 * provider can reorder them again.
4194 scan_clauses
= order_qual_clauses(root
, scan_clauses
);
4197 * Invoke custom plan provider to create the Plan node represented by the
4200 cplan
= castNode(CustomScan
,
4201 best_path
->methods
->PlanCustomPath(root
,
4209 * Copy cost data from Path to Plan; no need to make custom-plan providers
4212 copy_generic_path_info(&cplan
->scan
.plan
, &best_path
->path
);
4214 /* Likewise, copy the relids that are represented by this custom scan */
4215 cplan
->custom_relids
= best_path
->path
.parent
->relids
;
4218 * Replace any outer-relation variables with nestloop params in the qual
4219 * and custom_exprs expressions. We do this last so that the custom-plan
4220 * provider doesn't have to be involved. (Note that parts of custom_exprs
4221 * could have come from join clauses, so doing this beforehand on the
4222 * scan_clauses wouldn't work.) We assume custom_scan_tlist contains no
4225 if (best_path
->path
.param_info
)
4227 cplan
->scan
.plan
.qual
= (List
*)
4228 replace_nestloop_params(root
, (Node
*) cplan
->scan
.plan
.qual
);
4229 cplan
->custom_exprs
= (List
*)
4230 replace_nestloop_params(root
, (Node
*) cplan
->custom_exprs
);
4237 /*****************************************************************************
4241 *****************************************************************************/
4244 create_nestloop_plan(PlannerInfo
*root
,
4245 NestPath
*best_path
)
4247 NestLoop
*join_plan
;
4250 List
*tlist
= build_path_tlist(root
, &best_path
->jpath
.path
);
4251 List
*joinrestrictclauses
= best_path
->jpath
.joinrestrictinfo
;
4256 Relids saveOuterRels
= root
->curOuterRels
;
4258 /* NestLoop can project, so no need to be picky about child tlists */
4259 outer_plan
= create_plan_recurse(root
, best_path
->jpath
.outerjoinpath
, 0);
4261 /* For a nestloop, include outer relids in curOuterRels for inner side */
4262 root
->curOuterRels
= bms_union(root
->curOuterRels
,
4263 best_path
->jpath
.outerjoinpath
->parent
->relids
);
4265 inner_plan
= create_plan_recurse(root
, best_path
->jpath
.innerjoinpath
, 0);
4267 /* Restore curOuterRels */
4268 bms_free(root
->curOuterRels
);
4269 root
->curOuterRels
= saveOuterRels
;
4271 /* Sort join qual clauses into best execution order */
4272 joinrestrictclauses
= order_qual_clauses(root
, joinrestrictclauses
);
4274 /* Get the join qual clauses (in plain expression form) */
4275 /* Any pseudoconstant clauses are ignored here */
4276 if (IS_OUTER_JOIN(best_path
->jpath
.jointype
))
4278 extract_actual_join_clauses(joinrestrictclauses
,
4279 best_path
->jpath
.path
.parent
->relids
,
4280 &joinclauses
, &otherclauses
);
4284 /* We can treat all clauses alike for an inner join */
4285 joinclauses
= extract_actual_clauses(joinrestrictclauses
, false);
4289 /* Replace any outer-relation variables with nestloop params */
4290 if (best_path
->jpath
.path
.param_info
)
4292 joinclauses
= (List
*)
4293 replace_nestloop_params(root
, (Node
*) joinclauses
);
4294 otherclauses
= (List
*)
4295 replace_nestloop_params(root
, (Node
*) otherclauses
);
4299 * Identify any nestloop parameters that should be supplied by this join
4300 * node, and remove them from root->curOuterParams.
4302 outerrelids
= best_path
->jpath
.outerjoinpath
->parent
->relids
;
4303 nestParams
= identify_current_nestloop_params(root
, outerrelids
);
4305 join_plan
= make_nestloop(tlist
,
4311 best_path
->jpath
.jointype
,
4312 best_path
->jpath
.inner_unique
);
4314 copy_generic_path_info(&join_plan
->join
.plan
, &best_path
->jpath
.path
);
4320 create_mergejoin_plan(PlannerInfo
*root
,
4321 MergePath
*best_path
)
4323 MergeJoin
*join_plan
;
4326 List
*tlist
= build_path_tlist(root
, &best_path
->jpath
.path
);
4330 List
*outerpathkeys
;
4331 List
*innerpathkeys
;
4334 Oid
*mergecollations
;
4335 int *mergestrategies
;
4336 bool *mergenullsfirst
;
4338 EquivalenceClass
*opeclass
;
4343 Path
*outer_path
= best_path
->jpath
.outerjoinpath
;
4344 Path
*inner_path
= best_path
->jpath
.innerjoinpath
;
4347 * MergeJoin can project, so we don't have to demand exact tlists from the
4348 * inputs. However, if we're intending to sort an input's result, it's
4349 * best to request a small tlist so we aren't sorting more data than
4352 outer_plan
= create_plan_recurse(root
, best_path
->jpath
.outerjoinpath
,
4353 (best_path
->outersortkeys
!= NIL
) ? CP_SMALL_TLIST
: 0);
4355 inner_plan
= create_plan_recurse(root
, best_path
->jpath
.innerjoinpath
,
4356 (best_path
->innersortkeys
!= NIL
) ? CP_SMALL_TLIST
: 0);
4358 /* Sort join qual clauses into best execution order */
4359 /* NB: do NOT reorder the mergeclauses */
4360 joinclauses
= order_qual_clauses(root
, best_path
->jpath
.joinrestrictinfo
);
4362 /* Get the join qual clauses (in plain expression form) */
4363 /* Any pseudoconstant clauses are ignored here */
4364 if (IS_OUTER_JOIN(best_path
->jpath
.jointype
))
4366 extract_actual_join_clauses(joinclauses
,
4367 best_path
->jpath
.path
.parent
->relids
,
4368 &joinclauses
, &otherclauses
);
4372 /* We can treat all clauses alike for an inner join */
4373 joinclauses
= extract_actual_clauses(joinclauses
, false);
4378 * Remove the mergeclauses from the list of join qual clauses, leaving the
4379 * list of quals that must be checked as qpquals.
4381 mergeclauses
= get_actual_clauses(best_path
->path_mergeclauses
);
4382 joinclauses
= list_difference(joinclauses
, mergeclauses
);
4385 * Replace any outer-relation variables with nestloop params. There
4386 * should not be any in the mergeclauses.
4388 if (best_path
->jpath
.path
.param_info
)
4390 joinclauses
= (List
*)
4391 replace_nestloop_params(root
, (Node
*) joinclauses
);
4392 otherclauses
= (List
*)
4393 replace_nestloop_params(root
, (Node
*) otherclauses
);
4397 * Rearrange mergeclauses, if needed, so that the outer variable is always
4398 * on the left; mark the mergeclause restrictinfos with correct
4399 * outer_is_left status.
4401 mergeclauses
= get_switched_clauses(best_path
->path_mergeclauses
,
4402 best_path
->jpath
.outerjoinpath
->parent
->relids
);
4405 * Create explicit sort nodes for the outer and inner paths if necessary.
4407 if (best_path
->outersortkeys
)
4409 Relids outer_relids
= outer_path
->parent
->relids
;
4410 Sort
*sort
= make_sort_from_pathkeys(outer_plan
,
4411 best_path
->outersortkeys
,
4414 label_sort_with_costsize(root
, sort
, -1.0);
4415 outer_plan
= (Plan
*) sort
;
4416 outerpathkeys
= best_path
->outersortkeys
;
4419 outerpathkeys
= best_path
->jpath
.outerjoinpath
->pathkeys
;
4421 if (best_path
->innersortkeys
)
4423 Relids inner_relids
= inner_path
->parent
->relids
;
4424 Sort
*sort
= make_sort_from_pathkeys(inner_plan
,
4425 best_path
->innersortkeys
,
4428 label_sort_with_costsize(root
, sort
, -1.0);
4429 inner_plan
= (Plan
*) sort
;
4430 innerpathkeys
= best_path
->innersortkeys
;
4433 innerpathkeys
= best_path
->jpath
.innerjoinpath
->pathkeys
;
4436 * If specified, add a materialize node to shield the inner plan from the
4437 * need to handle mark/restore.
4439 if (best_path
->materialize_inner
)
4441 Plan
*matplan
= (Plan
*) make_material(inner_plan
);
4444 * We assume the materialize will not spill to disk, and therefore
4445 * charge just cpu_operator_cost per tuple. (Keep this estimate in
4446 * sync with final_cost_mergejoin.)
4448 copy_plan_costsize(matplan
, inner_plan
);
4449 matplan
->total_cost
+= cpu_operator_cost
* matplan
->plan_rows
;
4451 inner_plan
= matplan
;
4455 * Compute the opfamily/collation/strategy/nullsfirst arrays needed by the
4456 * executor. The information is in the pathkeys for the two inputs, but
4457 * we need to be careful about the possibility of mergeclauses sharing a
4458 * pathkey, as well as the possibility that the inner pathkeys are not in
4459 * an order matching the mergeclauses.
4461 nClauses
= list_length(mergeclauses
);
4462 Assert(nClauses
== list_length(best_path
->path_mergeclauses
));
4463 mergefamilies
= (Oid
*) palloc(nClauses
* sizeof(Oid
));
4464 mergecollations
= (Oid
*) palloc(nClauses
* sizeof(Oid
));
4465 mergestrategies
= (int *) palloc(nClauses
* sizeof(int));
4466 mergenullsfirst
= (bool *) palloc(nClauses
* sizeof(bool));
4470 lop
= list_head(outerpathkeys
);
4471 lip
= list_head(innerpathkeys
);
4473 foreach(lc
, best_path
->path_mergeclauses
)
4475 RestrictInfo
*rinfo
= lfirst_node(RestrictInfo
, lc
);
4476 EquivalenceClass
*oeclass
;
4477 EquivalenceClass
*ieclass
;
4478 PathKey
*ipathkey
= NULL
;
4479 EquivalenceClass
*ipeclass
= NULL
;
4480 bool first_inner_match
= false;
4482 /* fetch outer/inner eclass from mergeclause */
4483 if (rinfo
->outer_is_left
)
4485 oeclass
= rinfo
->left_ec
;
4486 ieclass
= rinfo
->right_ec
;
4490 oeclass
= rinfo
->right_ec
;
4491 ieclass
= rinfo
->left_ec
;
4493 Assert(oeclass
!= NULL
);
4494 Assert(ieclass
!= NULL
);
4497 * We must identify the pathkey elements associated with this clause
4498 * by matching the eclasses (which should give a unique match, since
4499 * the pathkey lists should be canonical). In typical cases the merge
4500 * clauses are one-to-one with the pathkeys, but when dealing with
4501 * partially redundant query conditions, things are more complicated.
4503 * lop and lip reference the first as-yet-unmatched pathkey elements.
4504 * If they're NULL then all pathkey elements have been matched.
4506 * The ordering of the outer pathkeys should match the mergeclauses,
4507 * by construction (see find_mergeclauses_for_outer_pathkeys()). There
4508 * could be more than one mergeclause for the same outer pathkey, but
4509 * no pathkey may be entirely skipped over.
4511 if (oeclass
!= opeclass
) /* multiple matches are not interesting */
4513 /* doesn't match the current opathkey, so must match the next */
4515 elog(ERROR
, "outer pathkeys do not match mergeclauses");
4516 opathkey
= (PathKey
*) lfirst(lop
);
4517 opeclass
= opathkey
->pk_eclass
;
4518 lop
= lnext(outerpathkeys
, lop
);
4519 if (oeclass
!= opeclass
)
4520 elog(ERROR
, "outer pathkeys do not match mergeclauses");
4524 * The inner pathkeys likewise should not have skipped-over keys, but
4525 * it's possible for a mergeclause to reference some earlier inner
4526 * pathkey if we had redundant pathkeys. For example we might have
4527 * mergeclauses like "o.a = i.x AND o.b = i.y AND o.c = i.x". The
4528 * implied inner ordering is then "ORDER BY x, y, x", but the pathkey
4529 * mechanism drops the second sort by x as redundant, and this code
4532 * It's also possible for the implied inner-rel ordering to be like
4533 * "ORDER BY x, y, x DESC". We still drop the second instance of x as
4534 * redundant; but this means that the sort ordering of a redundant
4535 * inner pathkey should not be considered significant. So we must
4536 * detect whether this is the first clause matching an inner pathkey.
4540 ipathkey
= (PathKey
*) lfirst(lip
);
4541 ipeclass
= ipathkey
->pk_eclass
;
4542 if (ieclass
== ipeclass
)
4544 /* successful first match to this inner pathkey */
4545 lip
= lnext(innerpathkeys
, lip
);
4546 first_inner_match
= true;
4549 if (!first_inner_match
)
4551 /* redundant clause ... must match something before lip */
4554 foreach(l2
, innerpathkeys
)
4558 ipathkey
= (PathKey
*) lfirst(l2
);
4559 ipeclass
= ipathkey
->pk_eclass
;
4560 if (ieclass
== ipeclass
)
4563 if (ieclass
!= ipeclass
)
4564 elog(ERROR
, "inner pathkeys do not match mergeclauses");
4568 * The pathkeys should always match each other as to opfamily and
4569 * collation (which affect equality), but if we're considering a
4570 * redundant inner pathkey, its sort ordering might not match. In
4571 * such cases we may ignore the inner pathkey's sort ordering and use
4572 * the outer's. (In effect, we're lying to the executor about the
4573 * sort direction of this inner column, but it does not matter since
4574 * the run-time row comparisons would only reach this column when
4575 * there's equality for the earlier column containing the same eclass.
4576 * There could be only one value in this column for the range of inner
4577 * rows having a given value in the earlier column, so it does not
4578 * matter which way we imagine this column to be ordered.) But a
4579 * non-redundant inner pathkey had better match outer's ordering too.
4581 if (opathkey
->pk_opfamily
!= ipathkey
->pk_opfamily
||
4582 opathkey
->pk_eclass
->ec_collation
!= ipathkey
->pk_eclass
->ec_collation
)
4583 elog(ERROR
, "left and right pathkeys do not match in mergejoin");
4584 if (first_inner_match
&&
4585 (opathkey
->pk_strategy
!= ipathkey
->pk_strategy
||
4586 opathkey
->pk_nulls_first
!= ipathkey
->pk_nulls_first
))
4587 elog(ERROR
, "left and right pathkeys do not match in mergejoin");
4589 /* OK, save info for executor */
4590 mergefamilies
[i
] = opathkey
->pk_opfamily
;
4591 mergecollations
[i
] = opathkey
->pk_eclass
->ec_collation
;
4592 mergestrategies
[i
] = opathkey
->pk_strategy
;
4593 mergenullsfirst
[i
] = opathkey
->pk_nulls_first
;
4598 * Note: it is not an error if we have additional pathkey elements (i.e.,
4599 * lop or lip isn't NULL here). The input paths might be better-sorted
4600 * than we need for the current mergejoin.
4604 * Now we can build the mergejoin node.
4606 join_plan
= make_mergejoin(tlist
,
4616 best_path
->jpath
.jointype
,
4617 best_path
->jpath
.inner_unique
,
4618 best_path
->skip_mark_restore
);
4620 /* Costs of sort and material steps are included in path cost already */
4621 copy_generic_path_info(&join_plan
->join
.plan
, &best_path
->jpath
.path
);
4627 create_hashjoin_plan(PlannerInfo
*root
,
4628 HashPath
*best_path
)
4630 HashJoin
*join_plan
;
4634 List
*tlist
= build_path_tlist(root
, &best_path
->jpath
.path
);
4638 List
*hashoperators
= NIL
;
4639 List
*hashcollations
= NIL
;
4640 List
*inner_hashkeys
= NIL
;
4641 List
*outer_hashkeys
= NIL
;
4642 Oid skewTable
= InvalidOid
;
4643 AttrNumber skewColumn
= InvalidAttrNumber
;
4644 bool skewInherit
= false;
4648 * HashJoin can project, so we don't have to demand exact tlists from the
4649 * inputs. However, it's best to request a small tlist from the inner
4650 * side, so that we aren't storing more data than necessary. Likewise, if
4651 * we anticipate batching, request a small tlist from the outer side so
4652 * that we don't put extra data in the outer batch files.
4654 outer_plan
= create_plan_recurse(root
, best_path
->jpath
.outerjoinpath
,
4655 (best_path
->num_batches
> 1) ? CP_SMALL_TLIST
: 0);
4657 inner_plan
= create_plan_recurse(root
, best_path
->jpath
.innerjoinpath
,
4660 /* Sort join qual clauses into best execution order */
4661 joinclauses
= order_qual_clauses(root
, best_path
->jpath
.joinrestrictinfo
);
4662 /* There's no point in sorting the hash clauses ... */
4664 /* Get the join qual clauses (in plain expression form) */
4665 /* Any pseudoconstant clauses are ignored here */
4666 if (IS_OUTER_JOIN(best_path
->jpath
.jointype
))
4668 extract_actual_join_clauses(joinclauses
,
4669 best_path
->jpath
.path
.parent
->relids
,
4670 &joinclauses
, &otherclauses
);
4674 /* We can treat all clauses alike for an inner join */
4675 joinclauses
= extract_actual_clauses(joinclauses
, false);
4680 * Remove the hashclauses from the list of join qual clauses, leaving the
4681 * list of quals that must be checked as qpquals.
4683 hashclauses
= get_actual_clauses(best_path
->path_hashclauses
);
4684 joinclauses
= list_difference(joinclauses
, hashclauses
);
4687 * Replace any outer-relation variables with nestloop params. There
4688 * should not be any in the hashclauses.
4690 if (best_path
->jpath
.path
.param_info
)
4692 joinclauses
= (List
*)
4693 replace_nestloop_params(root
, (Node
*) joinclauses
);
4694 otherclauses
= (List
*)
4695 replace_nestloop_params(root
, (Node
*) otherclauses
);
4699 * Rearrange hashclauses, if needed, so that the outer variable is always
4702 hashclauses
= get_switched_clauses(best_path
->path_hashclauses
,
4703 best_path
->jpath
.outerjoinpath
->parent
->relids
);
4706 * If there is a single join clause and we can identify the outer variable
4707 * as a simple column reference, supply its identity for possible use in
4708 * skew optimization. (Note: in principle we could do skew optimization
4709 * with multiple join clauses, but we'd have to be able to determine the
4710 * most common combinations of outer values, which we don't currently have
4711 * enough stats for.)
4713 if (list_length(hashclauses
) == 1)
4715 OpExpr
*clause
= (OpExpr
*) linitial(hashclauses
);
4718 Assert(is_opclause(clause
));
4719 node
= (Node
*) linitial(clause
->args
);
4720 if (IsA(node
, RelabelType
))
4721 node
= (Node
*) ((RelabelType
*) node
)->arg
;
4724 Var
*var
= (Var
*) node
;
4727 rte
= root
->simple_rte_array
[var
->varno
];
4728 if (rte
->rtekind
== RTE_RELATION
)
4730 skewTable
= rte
->relid
;
4731 skewColumn
= var
->varattno
;
4732 skewInherit
= rte
->inh
;
4738 * Collect hash related information. The hashed expressions are
4739 * deconstructed into outer/inner expressions, so they can be computed
4740 * separately (inner expressions are used to build the hashtable via Hash,
4741 * outer expressions to perform lookups of tuples from HashJoin's outer
4742 * plan in the hashtable). Also collect operator information necessary to
4743 * build the hashtable.
4745 foreach(lc
, hashclauses
)
4747 OpExpr
*hclause
= lfirst_node(OpExpr
, lc
);
4749 hashoperators
= lappend_oid(hashoperators
, hclause
->opno
);
4750 hashcollations
= lappend_oid(hashcollations
, hclause
->inputcollid
);
4751 outer_hashkeys
= lappend(outer_hashkeys
, linitial(hclause
->args
));
4752 inner_hashkeys
= lappend(inner_hashkeys
, lsecond(hclause
->args
));
4756 * Build the hash node and hash join node.
4758 hash_plan
= make_hash(inner_plan
,
4765 * Set Hash node's startup & total costs equal to total cost of input
4766 * plan; this only affects EXPLAIN display not decisions.
4768 copy_plan_costsize(&hash_plan
->plan
, inner_plan
);
4769 hash_plan
->plan
.startup_cost
= hash_plan
->plan
.total_cost
;
4772 * If parallel-aware, the executor will also need an estimate of the total
4773 * number of rows expected from all participants so that it can size the
4774 * shared hash table.
4776 if (best_path
->jpath
.path
.parallel_aware
)
4778 hash_plan
->plan
.parallel_aware
= true;
4779 hash_plan
->rows_total
= best_path
->inner_rows_total
;
4782 join_plan
= make_hashjoin(tlist
,
4791 best_path
->jpath
.jointype
,
4792 best_path
->jpath
.inner_unique
);
4794 copy_generic_path_info(&join_plan
->join
.plan
, &best_path
->jpath
.path
);
4800 /*****************************************************************************
4802 * SUPPORTING ROUTINES
4804 *****************************************************************************/
4807 * replace_nestloop_params
4808 * Replace outer-relation Vars and PlaceHolderVars in the given expression
4809 * with nestloop Params
4811 * All Vars and PlaceHolderVars belonging to the relation(s) identified by
4812 * root->curOuterRels are replaced by Params, and entries are added to
4813 * root->curOuterParams if not already present.
4816 replace_nestloop_params(PlannerInfo
*root
, Node
*expr
)
4818 /* No setup needed for tree walk, so away we go */
4819 return replace_nestloop_params_mutator(expr
, root
);
4823 replace_nestloop_params_mutator(Node
*node
, PlannerInfo
*root
)
4829 Var
*var
= (Var
*) node
;
4831 /* Upper-level Vars should be long gone at this point */
4832 Assert(var
->varlevelsup
== 0);
4833 /* If not to be replaced, we can just return the Var unmodified */
4834 if (IS_SPECIAL_VARNO(var
->varno
) ||
4835 !bms_is_member(var
->varno
, root
->curOuterRels
))
4837 /* Replace the Var with a nestloop Param */
4838 return (Node
*) replace_nestloop_param_var(root
, var
);
4840 if (IsA(node
, PlaceHolderVar
))
4842 PlaceHolderVar
*phv
= (PlaceHolderVar
*) node
;
4844 /* Upper-level PlaceHolderVars should be long gone at this point */
4845 Assert(phv
->phlevelsup
== 0);
4848 * Check whether we need to replace the PHV. We use bms_overlap as a
4849 * cheap/quick test to see if the PHV might be evaluated in the outer
4850 * rels, and then grab its PlaceHolderInfo to tell for sure.
4852 if (!bms_overlap(phv
->phrels
, root
->curOuterRels
) ||
4853 !bms_is_subset(find_placeholder_info(root
, phv
, false)->ph_eval_at
,
4854 root
->curOuterRels
))
4857 * We can't replace the whole PHV, but we might still need to
4858 * replace Vars or PHVs within its expression, in case it ends up
4859 * actually getting evaluated here. (It might get evaluated in
4860 * this plan node, or some child node; in the latter case we don't
4861 * really need to process the expression here, but we haven't got
4862 * enough info to tell if that's the case.) Flat-copy the PHV
4863 * node and then recurse on its expression.
4865 * Note that after doing this, we might have different
4866 * representations of the contents of the same PHV in different
4867 * parts of the plan tree. This is OK because equal() will just
4868 * match on phid/phlevelsup, so setrefs.c will still recognize an
4869 * upper-level reference to a lower-level copy of the same PHV.
4871 PlaceHolderVar
*newphv
= makeNode(PlaceHolderVar
);
4873 memcpy(newphv
, phv
, sizeof(PlaceHolderVar
));
4874 newphv
->phexpr
= (Expr
*)
4875 replace_nestloop_params_mutator((Node
*) phv
->phexpr
,
4877 return (Node
*) newphv
;
4879 /* Replace the PlaceHolderVar with a nestloop Param */
4880 return (Node
*) replace_nestloop_param_placeholdervar(root
, phv
);
4882 return expression_tree_mutator(node
,
4883 replace_nestloop_params_mutator
,
4888 * fix_indexqual_references
4889 * Adjust indexqual clauses to the form the executor's indexqual
4892 * We have three tasks here:
4893 * * Select the actual qual clauses out of the input IndexClause list,
4894 * and remove RestrictInfo nodes from the qual clauses.
4895 * * Replace any outer-relation Var or PHV nodes with nestloop Params.
4896 * (XXX eventually, that responsibility should go elsewhere?)
4897 * * Index keys must be represented by Var nodes with varattno set to the
4898 * index's attribute number, not the attribute number in the original rel.
4900 * *stripped_indexquals_p receives a list of the actual qual clauses.
4902 * *fixed_indexquals_p receives a list of the adjusted quals. This is a copy
4903 * that shares no substructure with the original; this is needed in case there
4904 * are subplans in it (we need two separate copies of the subplan tree, or
4905 * things will go awry).
4908 fix_indexqual_references(PlannerInfo
*root
, IndexPath
*index_path
,
4909 List
**stripped_indexquals_p
, List
**fixed_indexquals_p
)
4911 IndexOptInfo
*index
= index_path
->indexinfo
;
4912 List
*stripped_indexquals
;
4913 List
*fixed_indexquals
;
4916 stripped_indexquals
= fixed_indexquals
= NIL
;
4918 foreach(lc
, index_path
->indexclauses
)
4920 IndexClause
*iclause
= lfirst_node(IndexClause
, lc
);
4921 int indexcol
= iclause
->indexcol
;
4924 foreach(lc2
, iclause
->indexquals
)
4926 RestrictInfo
*rinfo
= lfirst_node(RestrictInfo
, lc2
);
4927 Node
*clause
= (Node
*) rinfo
->clause
;
4929 stripped_indexquals
= lappend(stripped_indexquals
, clause
);
4930 clause
= fix_indexqual_clause(root
, index
, indexcol
,
4931 clause
, iclause
->indexcols
);
4932 fixed_indexquals
= lappend(fixed_indexquals
, clause
);
4936 *stripped_indexquals_p
= stripped_indexquals
;
4937 *fixed_indexquals_p
= fixed_indexquals
;
4941 * fix_indexorderby_references
4942 * Adjust indexorderby clauses to the form the executor's index
4945 * This is a simplified version of fix_indexqual_references. The input is
4946 * bare clauses and a separate indexcol list, instead of IndexClauses.
4949 fix_indexorderby_references(PlannerInfo
*root
, IndexPath
*index_path
)
4951 IndexOptInfo
*index
= index_path
->indexinfo
;
4952 List
*fixed_indexorderbys
;
4956 fixed_indexorderbys
= NIL
;
4958 forboth(lcc
, index_path
->indexorderbys
, lci
, index_path
->indexorderbycols
)
4960 Node
*clause
= (Node
*) lfirst(lcc
);
4961 int indexcol
= lfirst_int(lci
);
4963 clause
= fix_indexqual_clause(root
, index
, indexcol
, clause
, NIL
);
4964 fixed_indexorderbys
= lappend(fixed_indexorderbys
, clause
);
4967 return fixed_indexorderbys
;
4971 * fix_indexqual_clause
4972 * Convert a single indexqual clause to the form needed by the executor.
4974 * We replace nestloop params here, and replace the index key variables
4975 * or expressions by index Var nodes.
4978 fix_indexqual_clause(PlannerInfo
*root
, IndexOptInfo
*index
, int indexcol
,
4979 Node
*clause
, List
*indexcolnos
)
4982 * Replace any outer-relation variables with nestloop params.
4984 * This also makes a copy of the clause, so it's safe to modify it
4987 clause
= replace_nestloop_params(root
, clause
);
4989 if (IsA(clause
, OpExpr
))
4991 OpExpr
*op
= (OpExpr
*) clause
;
4993 /* Replace the indexkey expression with an index Var. */
4994 linitial(op
->args
) = fix_indexqual_operand(linitial(op
->args
),
4998 else if (IsA(clause
, RowCompareExpr
))
5000 RowCompareExpr
*rc
= (RowCompareExpr
*) clause
;
5004 /* Replace the indexkey expressions with index Vars. */
5005 Assert(list_length(rc
->largs
) == list_length(indexcolnos
));
5006 forboth(lca
, rc
->largs
, lcai
, indexcolnos
)
5008 lfirst(lca
) = fix_indexqual_operand(lfirst(lca
),
5013 else if (IsA(clause
, ScalarArrayOpExpr
))
5015 ScalarArrayOpExpr
*saop
= (ScalarArrayOpExpr
*) clause
;
5017 /* Replace the indexkey expression with an index Var. */
5018 linitial(saop
->args
) = fix_indexqual_operand(linitial(saop
->args
),
5022 else if (IsA(clause
, NullTest
))
5024 NullTest
*nt
= (NullTest
*) clause
;
5026 /* Replace the indexkey expression with an index Var. */
5027 nt
->arg
= (Expr
*) fix_indexqual_operand((Node
*) nt
->arg
,
5032 elog(ERROR
, "unsupported indexqual type: %d",
5033 (int) nodeTag(clause
));
5039 * fix_indexqual_operand
5040 * Convert an indexqual expression to a Var referencing the index column.
5042 * We represent index keys by Var nodes having varno == INDEX_VAR and varattno
5043 * equal to the index's attribute number (index column position).
5045 * Most of the code here is just for sanity cross-checking that the given
5046 * expression actually matches the index column it's claimed to.
5049 fix_indexqual_operand(Node
*node
, IndexOptInfo
*index
, int indexcol
)
5053 ListCell
*indexpr_item
;
5056 * Remove any binary-compatible relabeling of the indexkey
5058 if (IsA(node
, RelabelType
))
5059 node
= (Node
*) ((RelabelType
*) node
)->arg
;
5061 Assert(indexcol
>= 0 && indexcol
< index
->ncolumns
);
5063 if (index
->indexkeys
[indexcol
] != 0)
5065 /* It's a simple index column */
5066 if (IsA(node
, Var
) &&
5067 ((Var
*) node
)->varno
== index
->rel
->relid
&&
5068 ((Var
*) node
)->varattno
== index
->indexkeys
[indexcol
])
5070 result
= (Var
*) copyObject(node
);
5071 result
->varno
= INDEX_VAR
;
5072 result
->varattno
= indexcol
+ 1;
5073 return (Node
*) result
;
5076 elog(ERROR
, "index key does not match expected index column");
5079 /* It's an index expression, so find and cross-check the expression */
5080 indexpr_item
= list_head(index
->indexprs
);
5081 for (pos
= 0; pos
< index
->ncolumns
; pos
++)
5083 if (index
->indexkeys
[pos
] == 0)
5085 if (indexpr_item
== NULL
)
5086 elog(ERROR
, "too few entries in indexprs list");
5087 if (pos
== indexcol
)
5091 indexkey
= (Node
*) lfirst(indexpr_item
);
5092 if (indexkey
&& IsA(indexkey
, RelabelType
))
5093 indexkey
= (Node
*) ((RelabelType
*) indexkey
)->arg
;
5094 if (equal(node
, indexkey
))
5096 result
= makeVar(INDEX_VAR
, indexcol
+ 1,
5097 exprType(lfirst(indexpr_item
)), -1,
5098 exprCollation(lfirst(indexpr_item
)),
5100 return (Node
*) result
;
5103 elog(ERROR
, "index key does not match expected index column");
5105 indexpr_item
= lnext(index
->indexprs
, indexpr_item
);
5110 elog(ERROR
, "index key does not match expected index column");
5111 return NULL
; /* keep compiler quiet */
5115 * get_switched_clauses
5116 * Given a list of merge or hash joinclauses (as RestrictInfo nodes),
5117 * extract the bare clauses, and rearrange the elements within the
5118 * clauses, if needed, so the outer join variable is on the left and
5119 * the inner is on the right. The original clause data structure is not
5120 * touched; a modified list is returned. We do, however, set the transient
5121 * outer_is_left field in each RestrictInfo to show which side was which.
5124 get_switched_clauses(List
*clauses
, Relids outerrelids
)
5131 RestrictInfo
*restrictinfo
= (RestrictInfo
*) lfirst(l
);
5132 OpExpr
*clause
= (OpExpr
*) restrictinfo
->clause
;
5134 Assert(is_opclause(clause
));
5135 if (bms_is_subset(restrictinfo
->right_relids
, outerrelids
))
5138 * Duplicate just enough of the structure to allow commuting the
5139 * clause without changing the original list. Could use
5140 * copyObject, but a complete deep copy is overkill.
5142 OpExpr
*temp
= makeNode(OpExpr
);
5144 temp
->opno
= clause
->opno
;
5145 temp
->opfuncid
= InvalidOid
;
5146 temp
->opresulttype
= clause
->opresulttype
;
5147 temp
->opretset
= clause
->opretset
;
5148 temp
->opcollid
= clause
->opcollid
;
5149 temp
->inputcollid
= clause
->inputcollid
;
5150 temp
->args
= list_copy(clause
->args
);
5151 temp
->location
= clause
->location
;
5152 /* Commute it --- note this modifies the temp node in-place. */
5153 CommuteOpExpr(temp
);
5154 t_list
= lappend(t_list
, temp
);
5155 restrictinfo
->outer_is_left
= false;
5159 Assert(bms_is_subset(restrictinfo
->left_relids
, outerrelids
));
5160 t_list
= lappend(t_list
, clause
);
5161 restrictinfo
->outer_is_left
= true;
5168 * order_qual_clauses
5169 * Given a list of qual clauses that will all be evaluated at the same
5170 * plan node, sort the list into the order we want to check the quals
5173 * When security barrier quals are used in the query, we may have quals with
5174 * different security levels in the list. Quals of lower security_level
5175 * must go before quals of higher security_level, except that we can grant
5176 * exceptions to move up quals that are leakproof. When security level
5177 * doesn't force the decision, we prefer to order clauses by estimated
5178 * execution cost, cheapest first.
5180 * Ideally the order should be driven by a combination of execution cost and
5181 * selectivity, but it's not immediately clear how to account for both,
5182 * and given the uncertainty of the estimates the reliability of the decisions
5183 * would be doubtful anyway. So we just order by security level then
5184 * estimated per-tuple cost, being careful not to change the order when
5185 * (as is often the case) the estimates are identical.
5187 * Although this will work on either bare clauses or RestrictInfos, it's
5188 * much faster to apply it to RestrictInfos, since it can re-use cost
5189 * information that is cached in RestrictInfos. XXX in the bare-clause
5190 * case, we are also not able to apply security considerations. That is
5191 * all right for the moment, because the bare-clause case doesn't occur
5192 * anywhere that barrier quals could be present, but it would be better to
5195 * Note: some callers pass lists that contain entries that will later be
5196 * removed; this is the easiest way to let this routine see RestrictInfos
5197 * instead of bare clauses. This is another reason why trying to consider
5198 * selectivity in the ordering would likely do the wrong thing.
5201 order_qual_clauses(PlannerInfo
*root
, List
*clauses
)
5207 Index security_level
;
5209 int nitems
= list_length(clauses
);
5215 /* No need to work hard for 0 or 1 clause */
5220 * Collect the items and costs into an array. This is to avoid repeated
5221 * cost_qual_eval work if the inputs aren't RestrictInfos.
5223 items
= (QualItem
*) palloc(nitems
* sizeof(QualItem
));
5225 foreach(lc
, clauses
)
5227 Node
*clause
= (Node
*) lfirst(lc
);
5230 cost_qual_eval_node(&qcost
, clause
, root
);
5231 items
[i
].clause
= clause
;
5232 items
[i
].cost
= qcost
.per_tuple
;
5233 if (IsA(clause
, RestrictInfo
))
5235 RestrictInfo
*rinfo
= (RestrictInfo
*) clause
;
5238 * If a clause is leakproof, it doesn't have to be constrained by
5239 * its nominal security level. If it's also reasonably cheap
5240 * (here defined as 10X cpu_operator_cost), pretend it has
5241 * security_level 0, which will allow it to go in front of
5242 * more-expensive quals of lower security levels. Of course, that
5243 * will also force it to go in front of cheaper quals of its own
5244 * security level, which is not so great, but we can alleviate
5245 * that risk by applying the cost limit cutoff.
5247 if (rinfo
->leakproof
&& items
[i
].cost
< 10 * cpu_operator_cost
)
5248 items
[i
].security_level
= 0;
5250 items
[i
].security_level
= rinfo
->security_level
;
5253 items
[i
].security_level
= 0;
5258 * Sort. We don't use qsort() because it's not guaranteed stable for
5259 * equal keys. The expected number of entries is small enough that a
5260 * simple insertion sort should be good enough.
5262 for (i
= 1; i
< nitems
; i
++)
5264 QualItem newitem
= items
[i
];
5267 /* insert newitem into the already-sorted subarray */
5268 for (j
= i
; j
> 0; j
--)
5270 QualItem
*olditem
= &items
[j
- 1];
5272 if (newitem
.security_level
> olditem
->security_level
||
5273 (newitem
.security_level
== olditem
->security_level
&&
5274 newitem
.cost
>= olditem
->cost
))
5276 items
[j
] = *olditem
;
5281 /* Convert back to a list */
5283 for (i
= 0; i
< nitems
; i
++)
5284 result
= lappend(result
, items
[i
].clause
);
5290 * Copy cost and size info from a Path node to the Plan node created from it.
5291 * The executor usually won't use this info, but it's needed by EXPLAIN.
5292 * Also copy the parallel-related flags, which the executor *will* use.
5295 copy_generic_path_info(Plan
*dest
, Path
*src
)
5297 dest
->startup_cost
= src
->startup_cost
;
5298 dest
->total_cost
= src
->total_cost
;
5299 dest
->plan_rows
= src
->rows
;
5300 dest
->plan_width
= src
->pathtarget
->width
;
5301 dest
->parallel_aware
= src
->parallel_aware
;
5302 dest
->parallel_safe
= src
->parallel_safe
;
5306 * Copy cost and size info from a lower plan node to an inserted node.
5307 * (Most callers alter the info after copying it.)
5310 copy_plan_costsize(Plan
*dest
, Plan
*src
)
5312 dest
->startup_cost
= src
->startup_cost
;
5313 dest
->total_cost
= src
->total_cost
;
5314 dest
->plan_rows
= src
->plan_rows
;
5315 dest
->plan_width
= src
->plan_width
;
5316 /* Assume the inserted node is not parallel-aware. */
5317 dest
->parallel_aware
= false;
5318 /* Assume the inserted node is parallel-safe, if child plan is. */
5319 dest
->parallel_safe
= src
->parallel_safe
;
5323 * Some places in this file build Sort nodes that don't have a directly
5324 * corresponding Path node. The cost of the sort is, or should have been,
5325 * included in the cost of the Path node we're working from, but since it's
5326 * not split out, we have to re-figure it using cost_sort(). This is just
5327 * to label the Sort node nicely for EXPLAIN.
5329 * limit_tuples is as for cost_sort (in particular, pass -1 if no limit)
5332 label_sort_with_costsize(PlannerInfo
*root
, Sort
*plan
, double limit_tuples
)
5334 Plan
*lefttree
= plan
->plan
.lefttree
;
5335 Path sort_path
; /* dummy for result of cost_sort */
5338 * This function shouldn't have to deal with IncrementalSort plans because
5339 * they are only created from corresponding Path nodes.
5341 Assert(IsA(plan
, Sort
));
5343 cost_sort(&sort_path
, root
, NIL
,
5344 lefttree
->total_cost
,
5345 lefttree
->plan_rows
,
5346 lefttree
->plan_width
,
5350 plan
->plan
.startup_cost
= sort_path
.startup_cost
;
5351 plan
->plan
.total_cost
= sort_path
.total_cost
;
5352 plan
->plan
.plan_rows
= lefttree
->plan_rows
;
5353 plan
->plan
.plan_width
= lefttree
->plan_width
;
5354 plan
->plan
.parallel_aware
= false;
5355 plan
->plan
.parallel_safe
= lefttree
->parallel_safe
;
5359 * bitmap_subplan_mark_shared
5360 * Set isshared flag in bitmap subplan so that it will be created in
5364 bitmap_subplan_mark_shared(Plan
*plan
)
5366 if (IsA(plan
, BitmapAnd
))
5367 bitmap_subplan_mark_shared(linitial(((BitmapAnd
*) plan
)->bitmapplans
));
5368 else if (IsA(plan
, BitmapOr
))
5370 ((BitmapOr
*) plan
)->isshared
= true;
5371 bitmap_subplan_mark_shared(linitial(((BitmapOr
*) plan
)->bitmapplans
));
5373 else if (IsA(plan
, BitmapIndexScan
))
5374 ((BitmapIndexScan
*) plan
)->isshared
= true;
5376 elog(ERROR
, "unrecognized node type: %d", nodeTag(plan
));
5379 /*****************************************************************************
5381 * PLAN NODE BUILDING ROUTINES
5383 * In general, these functions are not passed the original Path and therefore
5384 * leave it to the caller to fill in the cost/width fields from the Path,
5385 * typically by calling copy_generic_path_info(). This convention is
5386 * somewhat historical, but it does support a few places above where we build
5387 * a plan node without having an exactly corresponding Path node. Under no
5388 * circumstances should one of these functions do its own cost calculations,
5389 * as that would be redundant with calculations done while building Paths.
5391 *****************************************************************************/
5394 make_seqscan(List
*qptlist
,
5398 SeqScan
*node
= makeNode(SeqScan
);
5399 Plan
*plan
= &node
->scan
.plan
;
5401 plan
->targetlist
= qptlist
;
5402 plan
->qual
= qpqual
;
5403 plan
->lefttree
= NULL
;
5404 plan
->righttree
= NULL
;
5405 node
->scan
.scanrelid
= scanrelid
;
5411 make_samplescan(List
*qptlist
,
5414 TableSampleClause
*tsc
)
5416 SampleScan
*node
= makeNode(SampleScan
);
5417 Plan
*plan
= &node
->scan
.plan
;
5419 plan
->targetlist
= qptlist
;
5420 plan
->qual
= qpqual
;
5421 plan
->lefttree
= NULL
;
5422 plan
->righttree
= NULL
;
5423 node
->scan
.scanrelid
= scanrelid
;
5424 node
->tablesample
= tsc
;
5430 make_indexscan(List
*qptlist
,
5435 List
*indexqualorig
,
5437 List
*indexorderbyorig
,
5438 List
*indexorderbyops
,
5439 ScanDirection indexscandir
)
5441 IndexScan
*node
= makeNode(IndexScan
);
5442 Plan
*plan
= &node
->scan
.plan
;
5444 plan
->targetlist
= qptlist
;
5445 plan
->qual
= qpqual
;
5446 plan
->lefttree
= NULL
;
5447 plan
->righttree
= NULL
;
5448 node
->scan
.scanrelid
= scanrelid
;
5449 node
->indexid
= indexid
;
5450 node
->indexqual
= indexqual
;
5451 node
->indexqualorig
= indexqualorig
;
5452 node
->indexorderby
= indexorderby
;
5453 node
->indexorderbyorig
= indexorderbyorig
;
5454 node
->indexorderbyops
= indexorderbyops
;
5455 node
->indexorderdir
= indexscandir
;
5460 static IndexOnlyScan
*
5461 make_indexonlyscan(List
*qptlist
,
5469 ScanDirection indexscandir
)
5471 IndexOnlyScan
*node
= makeNode(IndexOnlyScan
);
5472 Plan
*plan
= &node
->scan
.plan
;
5474 plan
->targetlist
= qptlist
;
5475 plan
->qual
= qpqual
;
5476 plan
->lefttree
= NULL
;
5477 plan
->righttree
= NULL
;
5478 node
->scan
.scanrelid
= scanrelid
;
5479 node
->indexid
= indexid
;
5480 node
->indexqual
= indexqual
;
5481 node
->recheckqual
= recheckqual
;
5482 node
->indexorderby
= indexorderby
;
5483 node
->indextlist
= indextlist
;
5484 node
->indexorderdir
= indexscandir
;
5489 static BitmapIndexScan
*
5490 make_bitmap_indexscan(Index scanrelid
,
5493 List
*indexqualorig
)
5495 BitmapIndexScan
*node
= makeNode(BitmapIndexScan
);
5496 Plan
*plan
= &node
->scan
.plan
;
5498 plan
->targetlist
= NIL
; /* not used */
5499 plan
->qual
= NIL
; /* not used */
5500 plan
->lefttree
= NULL
;
5501 plan
->righttree
= NULL
;
5502 node
->scan
.scanrelid
= scanrelid
;
5503 node
->indexid
= indexid
;
5504 node
->indexqual
= indexqual
;
5505 node
->indexqualorig
= indexqualorig
;
5510 static BitmapHeapScan
*
5511 make_bitmap_heapscan(List
*qptlist
,
5514 List
*bitmapqualorig
,
5517 BitmapHeapScan
*node
= makeNode(BitmapHeapScan
);
5518 Plan
*plan
= &node
->scan
.plan
;
5520 plan
->targetlist
= qptlist
;
5521 plan
->qual
= qpqual
;
5522 plan
->lefttree
= lefttree
;
5523 plan
->righttree
= NULL
;
5524 node
->scan
.scanrelid
= scanrelid
;
5525 node
->bitmapqualorig
= bitmapqualorig
;
5531 make_tidscan(List
*qptlist
,
5536 TidScan
*node
= makeNode(TidScan
);
5537 Plan
*plan
= &node
->scan
.plan
;
5539 plan
->targetlist
= qptlist
;
5540 plan
->qual
= qpqual
;
5541 plan
->lefttree
= NULL
;
5542 plan
->righttree
= NULL
;
5543 node
->scan
.scanrelid
= scanrelid
;
5544 node
->tidquals
= tidquals
;
5549 static TidRangeScan
*
5550 make_tidrangescan(List
*qptlist
,
5553 List
*tidrangequals
)
5555 TidRangeScan
*node
= makeNode(TidRangeScan
);
5556 Plan
*plan
= &node
->scan
.plan
;
5558 plan
->targetlist
= qptlist
;
5559 plan
->qual
= qpqual
;
5560 plan
->lefttree
= NULL
;
5561 plan
->righttree
= NULL
;
5562 node
->scan
.scanrelid
= scanrelid
;
5563 node
->tidrangequals
= tidrangequals
;
5568 static SubqueryScan
*
5569 make_subqueryscan(List
*qptlist
,
5574 SubqueryScan
*node
= makeNode(SubqueryScan
);
5575 Plan
*plan
= &node
->scan
.plan
;
5577 plan
->targetlist
= qptlist
;
5578 plan
->qual
= qpqual
;
5579 plan
->lefttree
= NULL
;
5580 plan
->righttree
= NULL
;
5581 node
->scan
.scanrelid
= scanrelid
;
5582 node
->subplan
= subplan
;
5587 static FunctionScan
*
5588 make_functionscan(List
*qptlist
,
5592 bool funcordinality
)
5594 FunctionScan
*node
= makeNode(FunctionScan
);
5595 Plan
*plan
= &node
->scan
.plan
;
5597 plan
->targetlist
= qptlist
;
5598 plan
->qual
= qpqual
;
5599 plan
->lefttree
= NULL
;
5600 plan
->righttree
= NULL
;
5601 node
->scan
.scanrelid
= scanrelid
;
5602 node
->functions
= functions
;
5603 node
->funcordinality
= funcordinality
;
5608 static TableFuncScan
*
5609 make_tablefuncscan(List
*qptlist
,
5612 TableFunc
*tablefunc
)
5614 TableFuncScan
*node
= makeNode(TableFuncScan
);
5615 Plan
*plan
= &node
->scan
.plan
;
5617 plan
->targetlist
= qptlist
;
5618 plan
->qual
= qpqual
;
5619 plan
->lefttree
= NULL
;
5620 plan
->righttree
= NULL
;
5621 node
->scan
.scanrelid
= scanrelid
;
5622 node
->tablefunc
= tablefunc
;
5628 make_valuesscan(List
*qptlist
,
5633 ValuesScan
*node
= makeNode(ValuesScan
);
5634 Plan
*plan
= &node
->scan
.plan
;
5636 plan
->targetlist
= qptlist
;
5637 plan
->qual
= qpqual
;
5638 plan
->lefttree
= NULL
;
5639 plan
->righttree
= NULL
;
5640 node
->scan
.scanrelid
= scanrelid
;
5641 node
->values_lists
= values_lists
;
5647 make_ctescan(List
*qptlist
,
5653 CteScan
*node
= makeNode(CteScan
);
5654 Plan
*plan
= &node
->scan
.plan
;
5656 plan
->targetlist
= qptlist
;
5657 plan
->qual
= qpqual
;
5658 plan
->lefttree
= NULL
;
5659 plan
->righttree
= NULL
;
5660 node
->scan
.scanrelid
= scanrelid
;
5661 node
->ctePlanId
= ctePlanId
;
5662 node
->cteParam
= cteParam
;
5667 static NamedTuplestoreScan
*
5668 make_namedtuplestorescan(List
*qptlist
,
5673 NamedTuplestoreScan
*node
= makeNode(NamedTuplestoreScan
);
5674 Plan
*plan
= &node
->scan
.plan
;
5676 /* cost should be inserted by caller */
5677 plan
->targetlist
= qptlist
;
5678 plan
->qual
= qpqual
;
5679 plan
->lefttree
= NULL
;
5680 plan
->righttree
= NULL
;
5681 node
->scan
.scanrelid
= scanrelid
;
5682 node
->enrname
= enrname
;
5687 static WorkTableScan
*
5688 make_worktablescan(List
*qptlist
,
5693 WorkTableScan
*node
= makeNode(WorkTableScan
);
5694 Plan
*plan
= &node
->scan
.plan
;
5696 plan
->targetlist
= qptlist
;
5697 plan
->qual
= qpqual
;
5698 plan
->lefttree
= NULL
;
5699 plan
->righttree
= NULL
;
5700 node
->scan
.scanrelid
= scanrelid
;
5701 node
->wtParam
= wtParam
;
5707 make_foreignscan(List
*qptlist
,
5712 List
*fdw_scan_tlist
,
5713 List
*fdw_recheck_quals
,
5716 ForeignScan
*node
= makeNode(ForeignScan
);
5717 Plan
*plan
= &node
->scan
.plan
;
5719 /* cost will be filled in by create_foreignscan_plan */
5720 plan
->targetlist
= qptlist
;
5721 plan
->qual
= qpqual
;
5722 plan
->lefttree
= outer_plan
;
5723 plan
->righttree
= NULL
;
5724 node
->scan
.scanrelid
= scanrelid
;
5726 /* these may be overridden by the FDW's PlanDirectModify callback. */
5727 node
->operation
= CMD_SELECT
;
5728 node
->resultRelation
= 0;
5730 /* fs_server will be filled in by create_foreignscan_plan */
5731 node
->fs_server
= InvalidOid
;
5732 node
->fdw_exprs
= fdw_exprs
;
5733 node
->fdw_private
= fdw_private
;
5734 node
->fdw_scan_tlist
= fdw_scan_tlist
;
5735 node
->fdw_recheck_quals
= fdw_recheck_quals
;
5736 /* fs_relids will be filled in by create_foreignscan_plan */
5737 node
->fs_relids
= NULL
;
5738 /* fsSystemCol will be filled in by create_foreignscan_plan */
5739 node
->fsSystemCol
= false;
5744 static RecursiveUnion
*
5745 make_recursive_union(List
*tlist
,
5752 RecursiveUnion
*node
= makeNode(RecursiveUnion
);
5753 Plan
*plan
= &node
->plan
;
5754 int numCols
= list_length(distinctList
);
5756 plan
->targetlist
= tlist
;
5758 plan
->lefttree
= lefttree
;
5759 plan
->righttree
= righttree
;
5760 node
->wtParam
= wtParam
;
5763 * convert SortGroupClause list into arrays of attr indexes and equality
5764 * operators, as wanted by executor
5766 node
->numCols
= numCols
;
5770 AttrNumber
*dupColIdx
;
5775 dupColIdx
= (AttrNumber
*) palloc(sizeof(AttrNumber
) * numCols
);
5776 dupOperators
= (Oid
*) palloc(sizeof(Oid
) * numCols
);
5777 dupCollations
= (Oid
*) palloc(sizeof(Oid
) * numCols
);
5779 foreach(slitem
, distinctList
)
5781 SortGroupClause
*sortcl
= (SortGroupClause
*) lfirst(slitem
);
5782 TargetEntry
*tle
= get_sortgroupclause_tle(sortcl
,
5785 dupColIdx
[keyno
] = tle
->resno
;
5786 dupOperators
[keyno
] = sortcl
->eqop
;
5787 dupCollations
[keyno
] = exprCollation((Node
*) tle
->expr
);
5788 Assert(OidIsValid(dupOperators
[keyno
]));
5791 node
->dupColIdx
= dupColIdx
;
5792 node
->dupOperators
= dupOperators
;
5793 node
->dupCollations
= dupCollations
;
5795 node
->numGroups
= numGroups
;
5801 make_bitmap_and(List
*bitmapplans
)
5803 BitmapAnd
*node
= makeNode(BitmapAnd
);
5804 Plan
*plan
= &node
->plan
;
5806 plan
->targetlist
= NIL
;
5808 plan
->lefttree
= NULL
;
5809 plan
->righttree
= NULL
;
5810 node
->bitmapplans
= bitmapplans
;
5816 make_bitmap_or(List
*bitmapplans
)
5818 BitmapOr
*node
= makeNode(BitmapOr
);
5819 Plan
*plan
= &node
->plan
;
5821 plan
->targetlist
= NIL
;
5823 plan
->lefttree
= NULL
;
5824 plan
->righttree
= NULL
;
5825 node
->bitmapplans
= bitmapplans
;
5831 make_nestloop(List
*tlist
,
5840 NestLoop
*node
= makeNode(NestLoop
);
5841 Plan
*plan
= &node
->join
.plan
;
5843 plan
->targetlist
= tlist
;
5844 plan
->qual
= otherclauses
;
5845 plan
->lefttree
= lefttree
;
5846 plan
->righttree
= righttree
;
5847 node
->join
.jointype
= jointype
;
5848 node
->join
.inner_unique
= inner_unique
;
5849 node
->join
.joinqual
= joinclauses
;
5850 node
->nestParams
= nestParams
;
5856 make_hashjoin(List
*tlist
,
5860 List
*hashoperators
,
5861 List
*hashcollations
,
5868 HashJoin
*node
= makeNode(HashJoin
);
5869 Plan
*plan
= &node
->join
.plan
;
5871 plan
->targetlist
= tlist
;
5872 plan
->qual
= otherclauses
;
5873 plan
->lefttree
= lefttree
;
5874 plan
->righttree
= righttree
;
5875 node
->hashclauses
= hashclauses
;
5876 node
->hashoperators
= hashoperators
;
5877 node
->hashcollations
= hashcollations
;
5878 node
->hashkeys
= hashkeys
;
5879 node
->join
.jointype
= jointype
;
5880 node
->join
.inner_unique
= inner_unique
;
5881 node
->join
.joinqual
= joinclauses
;
5887 make_hash(Plan
*lefttree
,
5890 AttrNumber skewColumn
,
5893 Hash
*node
= makeNode(Hash
);
5894 Plan
*plan
= &node
->plan
;
5896 plan
->targetlist
= lefttree
->targetlist
;
5898 plan
->lefttree
= lefttree
;
5899 plan
->righttree
= NULL
;
5901 node
->hashkeys
= hashkeys
;
5902 node
->skewTable
= skewTable
;
5903 node
->skewColumn
= skewColumn
;
5904 node
->skewInherit
= skewInherit
;
5910 make_mergejoin(List
*tlist
,
5915 Oid
*mergecollations
,
5916 int *mergestrategies
,
5917 bool *mergenullsfirst
,
5922 bool skip_mark_restore
)
5924 MergeJoin
*node
= makeNode(MergeJoin
);
5925 Plan
*plan
= &node
->join
.plan
;
5927 plan
->targetlist
= tlist
;
5928 plan
->qual
= otherclauses
;
5929 plan
->lefttree
= lefttree
;
5930 plan
->righttree
= righttree
;
5931 node
->skip_mark_restore
= skip_mark_restore
;
5932 node
->mergeclauses
= mergeclauses
;
5933 node
->mergeFamilies
= mergefamilies
;
5934 node
->mergeCollations
= mergecollations
;
5935 node
->mergeStrategies
= mergestrategies
;
5936 node
->mergeNullsFirst
= mergenullsfirst
;
5937 node
->join
.jointype
= jointype
;
5938 node
->join
.inner_unique
= inner_unique
;
5939 node
->join
.joinqual
= joinclauses
;
5945 * make_sort --- basic routine to build a Sort plan node
5947 * Caller must have built the sortColIdx, sortOperators, collations, and
5948 * nullsFirst arrays already.
5951 make_sort(Plan
*lefttree
, int numCols
,
5952 AttrNumber
*sortColIdx
, Oid
*sortOperators
,
5953 Oid
*collations
, bool *nullsFirst
)
5958 node
= makeNode(Sort
);
5961 plan
->targetlist
= lefttree
->targetlist
;
5963 plan
->lefttree
= lefttree
;
5964 plan
->righttree
= NULL
;
5965 node
->numCols
= numCols
;
5966 node
->sortColIdx
= sortColIdx
;
5967 node
->sortOperators
= sortOperators
;
5968 node
->collations
= collations
;
5969 node
->nullsFirst
= nullsFirst
;
5975 * make_incrementalsort --- basic routine to build an IncrementalSort plan node
5977 * Caller must have built the sortColIdx, sortOperators, collations, and
5978 * nullsFirst arrays already.
5980 static IncrementalSort
*
5981 make_incrementalsort(Plan
*lefttree
, int numCols
, int nPresortedCols
,
5982 AttrNumber
*sortColIdx
, Oid
*sortOperators
,
5983 Oid
*collations
, bool *nullsFirst
)
5985 IncrementalSort
*node
;
5988 node
= makeNode(IncrementalSort
);
5990 plan
= &node
->sort
.plan
;
5991 plan
->targetlist
= lefttree
->targetlist
;
5993 plan
->lefttree
= lefttree
;
5994 plan
->righttree
= NULL
;
5995 node
->nPresortedCols
= nPresortedCols
;
5996 node
->sort
.numCols
= numCols
;
5997 node
->sort
.sortColIdx
= sortColIdx
;
5998 node
->sort
.sortOperators
= sortOperators
;
5999 node
->sort
.collations
= collations
;
6000 node
->sort
.nullsFirst
= nullsFirst
;
6006 * prepare_sort_from_pathkeys
6007 * Prepare to sort according to given pathkeys
6009 * This is used to set up for Sort, MergeAppend, and Gather Merge nodes. It
6010 * calculates the executor's representation of the sort key information, and
6011 * adjusts the plan targetlist if needed to add resjunk sort columns.
6014 * 'lefttree' is the plan node which yields input tuples
6015 * 'pathkeys' is the list of pathkeys by which the result is to be sorted
6016 * 'relids' identifies the child relation being sorted, if any
6017 * 'reqColIdx' is NULL or an array of required sort key column numbers
6018 * 'adjust_tlist_in_place' is true if lefttree must be modified in-place
6020 * We must convert the pathkey information into arrays of sort key column
6021 * numbers, sort operator OIDs, collation OIDs, and nulls-first flags,
6022 * which is the representation the executor wants. These are returned into
6023 * the output parameters *p_numsortkeys etc.
6025 * When looking for matches to an EquivalenceClass's members, we will only
6026 * consider child EC members if they belong to given 'relids'. This protects
6027 * against possible incorrect matches to child expressions that contain no
6030 * If reqColIdx isn't NULL then it contains sort key column numbers that
6031 * we should match. This is used when making child plans for a MergeAppend;
6032 * it's an error if we can't match the columns.
6034 * If the pathkeys include expressions that aren't simple Vars, we will
6035 * usually need to add resjunk items to the input plan's targetlist to
6036 * compute these expressions, since a Sort or MergeAppend node itself won't
6037 * do any such calculations. If the input plan type isn't one that can do
6038 * projections, this means adding a Result node just to do the projection.
6039 * However, the caller can pass adjust_tlist_in_place = true to force the
6040 * lefttree tlist to be modified in-place regardless of whether the node type
6041 * can project --- we use this for fixing the tlist of MergeAppend itself.
6043 * Returns the node which is to be the input to the Sort (either lefttree,
6044 * or a Result stacked atop lefttree).
6047 prepare_sort_from_pathkeys(Plan
*lefttree
, List
*pathkeys
,
6049 const AttrNumber
*reqColIdx
,
6050 bool adjust_tlist_in_place
,
6052 AttrNumber
**p_sortColIdx
,
6053 Oid
**p_sortOperators
,
6055 bool **p_nullsFirst
)
6057 List
*tlist
= lefttree
->targetlist
;
6060 AttrNumber
*sortColIdx
;
6066 * We will need at most list_length(pathkeys) sort columns; possibly less
6068 numsortkeys
= list_length(pathkeys
);
6069 sortColIdx
= (AttrNumber
*) palloc(numsortkeys
* sizeof(AttrNumber
));
6070 sortOperators
= (Oid
*) palloc(numsortkeys
* sizeof(Oid
));
6071 collations
= (Oid
*) palloc(numsortkeys
* sizeof(Oid
));
6072 nullsFirst
= (bool *) palloc(numsortkeys
* sizeof(bool));
6076 foreach(i
, pathkeys
)
6078 PathKey
*pathkey
= (PathKey
*) lfirst(i
);
6079 EquivalenceClass
*ec
= pathkey
->pk_eclass
;
6080 EquivalenceMember
*em
;
6081 TargetEntry
*tle
= NULL
;
6082 Oid pk_datatype
= InvalidOid
;
6086 if (ec
->ec_has_volatile
)
6089 * If the pathkey's EquivalenceClass is volatile, then it must
6090 * have come from an ORDER BY clause, and we have to match it to
6091 * that same targetlist entry.
6093 if (ec
->ec_sortref
== 0) /* can't happen */
6094 elog(ERROR
, "volatile EquivalenceClass has no sortref");
6095 tle
= get_sortgroupref_tle(ec
->ec_sortref
, tlist
);
6097 Assert(list_length(ec
->ec_members
) == 1);
6098 pk_datatype
= ((EquivalenceMember
*) linitial(ec
->ec_members
))->em_datatype
;
6100 else if (reqColIdx
!= NULL
)
6103 * If we are given a sort column number to match, only consider
6104 * the single TLE at that position. It's possible that there is
6105 * no such TLE, in which case fall through and generate a resjunk
6106 * targetentry (we assume this must have happened in the parent
6107 * plan as well). If there is a TLE but it doesn't match the
6108 * pathkey's EC, we do the same, which is probably the wrong thing
6109 * but we'll leave it to caller to complain about the mismatch.
6111 tle
= get_tle_by_resno(tlist
, reqColIdx
[numsortkeys
]);
6114 em
= find_ec_member_matching_expr(ec
, tle
->expr
, relids
);
6117 /* found expr at right place in tlist */
6118 pk_datatype
= em
->em_datatype
;
6127 * Otherwise, we can sort by any non-constant expression listed in
6128 * the pathkey's EquivalenceClass. For now, we take the first
6129 * tlist item found in the EC. If there's no match, we'll generate
6130 * a resjunk entry using the first EC member that is an expression
6131 * in the input's vars. (The non-const restriction only matters
6132 * if the EC is below_outer_join; but if it isn't, it won't
6133 * contain consts anyway, else we'd have discarded the pathkey as
6136 * XXX if we have a choice, is there any way of figuring out which
6137 * might be cheapest to execute? (For example, int4lt is likely
6138 * much cheaper to execute than numericlt, but both might appear
6139 * in the same equivalence class...) Not clear that we ever will
6140 * have an interesting choice in practice, so it may not matter.
6144 tle
= (TargetEntry
*) lfirst(j
);
6145 em
= find_ec_member_matching_expr(ec
, tle
->expr
, relids
);
6148 /* found expr already in tlist */
6149 pk_datatype
= em
->em_datatype
;
6159 * No matching tlist item; look for a computable expression.
6161 em
= find_computable_ec_member(NULL
, ec
, tlist
, relids
, false);
6163 elog(ERROR
, "could not find pathkey item to sort");
6164 pk_datatype
= em
->em_datatype
;
6167 * Do we need to insert a Result node?
6169 if (!adjust_tlist_in_place
&&
6170 !is_projection_capable_plan(lefttree
))
6172 /* copy needed so we don't modify input's tlist below */
6173 tlist
= copyObject(tlist
);
6174 lefttree
= inject_projection_plan(lefttree
, tlist
,
6175 lefttree
->parallel_safe
);
6178 /* Don't bother testing is_projection_capable_plan again */
6179 adjust_tlist_in_place
= true;
6182 * Add resjunk entry to input's tlist
6184 tle
= makeTargetEntry(copyObject(em
->em_expr
),
6185 list_length(tlist
) + 1,
6188 tlist
= lappend(tlist
, tle
);
6189 lefttree
->targetlist
= tlist
; /* just in case NIL before */
6193 * Look up the correct sort operator from the PathKey's slightly
6194 * abstracted representation.
6196 sortop
= get_opfamily_member(pathkey
->pk_opfamily
,
6199 pathkey
->pk_strategy
);
6200 if (!OidIsValid(sortop
)) /* should not happen */
6201 elog(ERROR
, "missing operator %d(%u,%u) in opfamily %u",
6202 pathkey
->pk_strategy
, pk_datatype
, pk_datatype
,
6203 pathkey
->pk_opfamily
);
6205 /* Add the column to the sort arrays */
6206 sortColIdx
[numsortkeys
] = tle
->resno
;
6207 sortOperators
[numsortkeys
] = sortop
;
6208 collations
[numsortkeys
] = ec
->ec_collation
;
6209 nullsFirst
[numsortkeys
] = pathkey
->pk_nulls_first
;
6213 /* Return results */
6214 *p_numsortkeys
= numsortkeys
;
6215 *p_sortColIdx
= sortColIdx
;
6216 *p_sortOperators
= sortOperators
;
6217 *p_collations
= collations
;
6218 *p_nullsFirst
= nullsFirst
;
6224 * make_sort_from_pathkeys
6225 * Create sort plan to sort according to given pathkeys
6227 * 'lefttree' is the node which yields input tuples
6228 * 'pathkeys' is the list of pathkeys by which the result is to be sorted
6229 * 'relids' is the set of relations required by prepare_sort_from_pathkeys()
6232 make_sort_from_pathkeys(Plan
*lefttree
, List
*pathkeys
, Relids relids
)
6235 AttrNumber
*sortColIdx
;
6240 /* Compute sort column info, and adjust lefttree as needed */
6241 lefttree
= prepare_sort_from_pathkeys(lefttree
, pathkeys
,
6251 /* Now build the Sort node */
6252 return make_sort(lefttree
, numsortkeys
,
6253 sortColIdx
, sortOperators
,
6254 collations
, nullsFirst
);
6258 * make_incrementalsort_from_pathkeys
6259 * Create sort plan to sort according to given pathkeys
6261 * 'lefttree' is the node which yields input tuples
6262 * 'pathkeys' is the list of pathkeys by which the result is to be sorted
6263 * 'relids' is the set of relations required by prepare_sort_from_pathkeys()
6264 * 'nPresortedCols' is the number of presorted columns in input tuples
6266 static IncrementalSort
*
6267 make_incrementalsort_from_pathkeys(Plan
*lefttree
, List
*pathkeys
,
6268 Relids relids
, int nPresortedCols
)
6271 AttrNumber
*sortColIdx
;
6276 /* Compute sort column info, and adjust lefttree as needed */
6277 lefttree
= prepare_sort_from_pathkeys(lefttree
, pathkeys
,
6287 /* Now build the Sort node */
6288 return make_incrementalsort(lefttree
, numsortkeys
, nPresortedCols
,
6289 sortColIdx
, sortOperators
,
6290 collations
, nullsFirst
);
6294 * make_sort_from_sortclauses
6295 * Create sort plan to sort according to given sortclauses
6297 * 'sortcls' is a list of SortGroupClauses
6298 * 'lefttree' is the node which yields input tuples
6301 make_sort_from_sortclauses(List
*sortcls
, Plan
*lefttree
)
6303 List
*sub_tlist
= lefttree
->targetlist
;
6306 AttrNumber
*sortColIdx
;
6311 /* Convert list-ish representation to arrays wanted by executor */
6312 numsortkeys
= list_length(sortcls
);
6313 sortColIdx
= (AttrNumber
*) palloc(numsortkeys
* sizeof(AttrNumber
));
6314 sortOperators
= (Oid
*) palloc(numsortkeys
* sizeof(Oid
));
6315 collations
= (Oid
*) palloc(numsortkeys
* sizeof(Oid
));
6316 nullsFirst
= (bool *) palloc(numsortkeys
* sizeof(bool));
6321 SortGroupClause
*sortcl
= (SortGroupClause
*) lfirst(l
);
6322 TargetEntry
*tle
= get_sortgroupclause_tle(sortcl
, sub_tlist
);
6324 sortColIdx
[numsortkeys
] = tle
->resno
;
6325 sortOperators
[numsortkeys
] = sortcl
->sortop
;
6326 collations
[numsortkeys
] = exprCollation((Node
*) tle
->expr
);
6327 nullsFirst
[numsortkeys
] = sortcl
->nulls_first
;
6331 return make_sort(lefttree
, numsortkeys
,
6332 sortColIdx
, sortOperators
,
6333 collations
, nullsFirst
);
6337 * make_sort_from_groupcols
6338 * Create sort plan to sort based on grouping columns
6340 * 'groupcls' is the list of SortGroupClauses
6341 * 'grpColIdx' gives the column numbers to use
6343 * This might look like it could be merged with make_sort_from_sortclauses,
6344 * but presently we *must* use the grpColIdx[] array to locate sort columns,
6345 * because the child plan's tlist is not marked with ressortgroupref info
6346 * appropriate to the grouping node. So, only the sort ordering info
6347 * is used from the SortGroupClause entries.
6350 make_sort_from_groupcols(List
*groupcls
,
6351 AttrNumber
*grpColIdx
,
6354 List
*sub_tlist
= lefttree
->targetlist
;
6357 AttrNumber
*sortColIdx
;
6362 /* Convert list-ish representation to arrays wanted by executor */
6363 numsortkeys
= list_length(groupcls
);
6364 sortColIdx
= (AttrNumber
*) palloc(numsortkeys
* sizeof(AttrNumber
));
6365 sortOperators
= (Oid
*) palloc(numsortkeys
* sizeof(Oid
));
6366 collations
= (Oid
*) palloc(numsortkeys
* sizeof(Oid
));
6367 nullsFirst
= (bool *) palloc(numsortkeys
* sizeof(bool));
6370 foreach(l
, groupcls
)
6372 SortGroupClause
*grpcl
= (SortGroupClause
*) lfirst(l
);
6373 TargetEntry
*tle
= get_tle_by_resno(sub_tlist
, grpColIdx
[numsortkeys
]);
6376 elog(ERROR
, "could not retrieve tle for sort-from-groupcols");
6378 sortColIdx
[numsortkeys
] = tle
->resno
;
6379 sortOperators
[numsortkeys
] = grpcl
->sortop
;
6380 collations
[numsortkeys
] = exprCollation((Node
*) tle
->expr
);
6381 nullsFirst
[numsortkeys
] = grpcl
->nulls_first
;
6385 return make_sort(lefttree
, numsortkeys
,
6386 sortColIdx
, sortOperators
,
6387 collations
, nullsFirst
);
6391 make_material(Plan
*lefttree
)
6393 Material
*node
= makeNode(Material
);
6394 Plan
*plan
= &node
->plan
;
6396 plan
->targetlist
= lefttree
->targetlist
;
6398 plan
->lefttree
= lefttree
;
6399 plan
->righttree
= NULL
;
6405 * materialize_finished_plan: stick a Material node atop a completed plan
6407 * There are a couple of places where we want to attach a Material node
6408 * after completion of create_plan(), without any MaterialPath path.
6409 * Those places should probably be refactored someday to do this on the
6410 * Path representation, but it's not worth the trouble yet.
6413 materialize_finished_plan(Plan
*subplan
)
6416 Path matpath
; /* dummy for result of cost_material */
6418 matplan
= (Plan
*) make_material(subplan
);
6421 * XXX horrid kluge: if there are any initPlans attached to the subplan,
6422 * move them up to the Material node, which is now effectively the top
6423 * plan node in its query level. This prevents failure in
6424 * SS_finalize_plan(), which see for comments. We don't bother adjusting
6425 * the subplan's cost estimate for this.
6427 matplan
->initPlan
= subplan
->initPlan
;
6428 subplan
->initPlan
= NIL
;
6431 cost_material(&matpath
,
6432 subplan
->startup_cost
,
6433 subplan
->total_cost
,
6435 subplan
->plan_width
);
6436 matplan
->startup_cost
= matpath
.startup_cost
;
6437 matplan
->total_cost
= matpath
.total_cost
;
6438 matplan
->plan_rows
= subplan
->plan_rows
;
6439 matplan
->plan_width
= subplan
->plan_width
;
6440 matplan
->parallel_aware
= false;
6441 matplan
->parallel_safe
= subplan
->parallel_safe
;
6447 make_memoize(Plan
*lefttree
, Oid
*hashoperators
, Oid
*collations
,
6448 List
*param_exprs
, bool singlerow
, bool binary_mode
,
6449 uint32 est_entries
, Bitmapset
*keyparamids
)
6451 Memoize
*node
= makeNode(Memoize
);
6452 Plan
*plan
= &node
->plan
;
6454 plan
->targetlist
= lefttree
->targetlist
;
6456 plan
->lefttree
= lefttree
;
6457 plan
->righttree
= NULL
;
6459 node
->numKeys
= list_length(param_exprs
);
6460 node
->hashOperators
= hashoperators
;
6461 node
->collations
= collations
;
6462 node
->param_exprs
= param_exprs
;
6463 node
->singlerow
= singlerow
;
6464 node
->binary_mode
= binary_mode
;
6465 node
->est_entries
= est_entries
;
6466 node
->keyparamids
= keyparamids
;
6472 make_agg(List
*tlist
, List
*qual
,
6473 AggStrategy aggstrategy
, AggSplit aggsplit
,
6474 int numGroupCols
, AttrNumber
*grpColIdx
, Oid
*grpOperators
, Oid
*grpCollations
,
6475 List
*groupingSets
, List
*chain
, double dNumGroups
,
6476 Size transitionSpace
, Plan
*lefttree
)
6478 Agg
*node
= makeNode(Agg
);
6479 Plan
*plan
= &node
->plan
;
6482 /* Reduce to long, but 'ware overflow! */
6483 numGroups
= (long) Min(dNumGroups
, (double) LONG_MAX
);
6485 node
->aggstrategy
= aggstrategy
;
6486 node
->aggsplit
= aggsplit
;
6487 node
->numCols
= numGroupCols
;
6488 node
->grpColIdx
= grpColIdx
;
6489 node
->grpOperators
= grpOperators
;
6490 node
->grpCollations
= grpCollations
;
6491 node
->numGroups
= numGroups
;
6492 node
->transitionSpace
= transitionSpace
;
6493 node
->aggParams
= NULL
; /* SS_finalize_plan() will fill this */
6494 node
->groupingSets
= groupingSets
;
6495 node
->chain
= chain
;
6498 plan
->targetlist
= tlist
;
6499 plan
->lefttree
= lefttree
;
6500 plan
->righttree
= NULL
;
6506 make_windowagg(List
*tlist
, Index winref
,
6507 int partNumCols
, AttrNumber
*partColIdx
, Oid
*partOperators
, Oid
*partCollations
,
6508 int ordNumCols
, AttrNumber
*ordColIdx
, Oid
*ordOperators
, Oid
*ordCollations
,
6509 int frameOptions
, Node
*startOffset
, Node
*endOffset
,
6510 Oid startInRangeFunc
, Oid endInRangeFunc
,
6511 Oid inRangeColl
, bool inRangeAsc
, bool inRangeNullsFirst
,
6514 WindowAgg
*node
= makeNode(WindowAgg
);
6515 Plan
*plan
= &node
->plan
;
6517 node
->winref
= winref
;
6518 node
->partNumCols
= partNumCols
;
6519 node
->partColIdx
= partColIdx
;
6520 node
->partOperators
= partOperators
;
6521 node
->partCollations
= partCollations
;
6522 node
->ordNumCols
= ordNumCols
;
6523 node
->ordColIdx
= ordColIdx
;
6524 node
->ordOperators
= ordOperators
;
6525 node
->ordCollations
= ordCollations
;
6526 node
->frameOptions
= frameOptions
;
6527 node
->startOffset
= startOffset
;
6528 node
->endOffset
= endOffset
;
6529 node
->startInRangeFunc
= startInRangeFunc
;
6530 node
->endInRangeFunc
= endInRangeFunc
;
6531 node
->inRangeColl
= inRangeColl
;
6532 node
->inRangeAsc
= inRangeAsc
;
6533 node
->inRangeNullsFirst
= inRangeNullsFirst
;
6535 plan
->targetlist
= tlist
;
6536 plan
->lefttree
= lefttree
;
6537 plan
->righttree
= NULL
;
6538 /* WindowAgg nodes never have a qual clause */
6545 make_group(List
*tlist
,
6548 AttrNumber
*grpColIdx
,
6553 Group
*node
= makeNode(Group
);
6554 Plan
*plan
= &node
->plan
;
6556 node
->numCols
= numGroupCols
;
6557 node
->grpColIdx
= grpColIdx
;
6558 node
->grpOperators
= grpOperators
;
6559 node
->grpCollations
= grpCollations
;
6562 plan
->targetlist
= tlist
;
6563 plan
->lefttree
= lefttree
;
6564 plan
->righttree
= NULL
;
6570 * distinctList is a list of SortGroupClauses, identifying the targetlist items
6571 * that should be considered by the Unique filter. The input path must
6572 * already be sorted accordingly.
6575 make_unique_from_sortclauses(Plan
*lefttree
, List
*distinctList
)
6577 Unique
*node
= makeNode(Unique
);
6578 Plan
*plan
= &node
->plan
;
6579 int numCols
= list_length(distinctList
);
6581 AttrNumber
*uniqColIdx
;
6583 Oid
*uniqCollations
;
6586 plan
->targetlist
= lefttree
->targetlist
;
6588 plan
->lefttree
= lefttree
;
6589 plan
->righttree
= NULL
;
6592 * convert SortGroupClause list into arrays of attr indexes and equality
6593 * operators, as wanted by executor
6595 Assert(numCols
> 0);
6596 uniqColIdx
= (AttrNumber
*) palloc(sizeof(AttrNumber
) * numCols
);
6597 uniqOperators
= (Oid
*) palloc(sizeof(Oid
) * numCols
);
6598 uniqCollations
= (Oid
*) palloc(sizeof(Oid
) * numCols
);
6600 foreach(slitem
, distinctList
)
6602 SortGroupClause
*sortcl
= (SortGroupClause
*) lfirst(slitem
);
6603 TargetEntry
*tle
= get_sortgroupclause_tle(sortcl
, plan
->targetlist
);
6605 uniqColIdx
[keyno
] = tle
->resno
;
6606 uniqOperators
[keyno
] = sortcl
->eqop
;
6607 uniqCollations
[keyno
] = exprCollation((Node
*) tle
->expr
);
6608 Assert(OidIsValid(uniqOperators
[keyno
]));
6612 node
->numCols
= numCols
;
6613 node
->uniqColIdx
= uniqColIdx
;
6614 node
->uniqOperators
= uniqOperators
;
6615 node
->uniqCollations
= uniqCollations
;
6621 * as above, but use pathkeys to identify the sort columns and semantics
6624 make_unique_from_pathkeys(Plan
*lefttree
, List
*pathkeys
, int numCols
)
6626 Unique
*node
= makeNode(Unique
);
6627 Plan
*plan
= &node
->plan
;
6629 AttrNumber
*uniqColIdx
;
6631 Oid
*uniqCollations
;
6634 plan
->targetlist
= lefttree
->targetlist
;
6636 plan
->lefttree
= lefttree
;
6637 plan
->righttree
= NULL
;
6640 * Convert pathkeys list into arrays of attr indexes and equality
6641 * operators, as wanted by executor. This has a lot in common with
6642 * prepare_sort_from_pathkeys ... maybe unify sometime?
6644 Assert(numCols
>= 0 && numCols
<= list_length(pathkeys
));
6645 uniqColIdx
= (AttrNumber
*) palloc(sizeof(AttrNumber
) * numCols
);
6646 uniqOperators
= (Oid
*) palloc(sizeof(Oid
) * numCols
);
6647 uniqCollations
= (Oid
*) palloc(sizeof(Oid
) * numCols
);
6649 foreach(lc
, pathkeys
)
6651 PathKey
*pathkey
= (PathKey
*) lfirst(lc
);
6652 EquivalenceClass
*ec
= pathkey
->pk_eclass
;
6653 EquivalenceMember
*em
;
6654 TargetEntry
*tle
= NULL
;
6655 Oid pk_datatype
= InvalidOid
;
6659 /* Ignore pathkeys beyond the specified number of columns */
6660 if (keyno
>= numCols
)
6663 if (ec
->ec_has_volatile
)
6666 * If the pathkey's EquivalenceClass is volatile, then it must
6667 * have come from an ORDER BY clause, and we have to match it to
6668 * that same targetlist entry.
6670 if (ec
->ec_sortref
== 0) /* can't happen */
6671 elog(ERROR
, "volatile EquivalenceClass has no sortref");
6672 tle
= get_sortgroupref_tle(ec
->ec_sortref
, plan
->targetlist
);
6674 Assert(list_length(ec
->ec_members
) == 1);
6675 pk_datatype
= ((EquivalenceMember
*) linitial(ec
->ec_members
))->em_datatype
;
6680 * Otherwise, we can use any non-constant expression listed in the
6681 * pathkey's EquivalenceClass. For now, we take the first tlist
6682 * item found in the EC.
6684 foreach(j
, plan
->targetlist
)
6686 tle
= (TargetEntry
*) lfirst(j
);
6687 em
= find_ec_member_matching_expr(ec
, tle
->expr
, NULL
);
6690 /* found expr already in tlist */
6691 pk_datatype
= em
->em_datatype
;
6699 elog(ERROR
, "could not find pathkey item to sort");
6702 * Look up the correct equality operator from the PathKey's slightly
6703 * abstracted representation.
6705 eqop
= get_opfamily_member(pathkey
->pk_opfamily
,
6708 BTEqualStrategyNumber
);
6709 if (!OidIsValid(eqop
)) /* should not happen */
6710 elog(ERROR
, "missing operator %d(%u,%u) in opfamily %u",
6711 BTEqualStrategyNumber
, pk_datatype
, pk_datatype
,
6712 pathkey
->pk_opfamily
);
6714 uniqColIdx
[keyno
] = tle
->resno
;
6715 uniqOperators
[keyno
] = eqop
;
6716 uniqCollations
[keyno
] = ec
->ec_collation
;
6721 node
->numCols
= numCols
;
6722 node
->uniqColIdx
= uniqColIdx
;
6723 node
->uniqOperators
= uniqOperators
;
6724 node
->uniqCollations
= uniqCollations
;
6730 make_gather(List
*qptlist
,
6737 Gather
*node
= makeNode(Gather
);
6738 Plan
*plan
= &node
->plan
;
6740 plan
->targetlist
= qptlist
;
6741 plan
->qual
= qpqual
;
6742 plan
->lefttree
= subplan
;
6743 plan
->righttree
= NULL
;
6744 node
->num_workers
= nworkers
;
6745 node
->rescan_param
= rescan_param
;
6746 node
->single_copy
= single_copy
;
6747 node
->invisible
= false;
6748 node
->initParam
= NULL
;
6754 * distinctList is a list of SortGroupClauses, identifying the targetlist
6755 * items that should be considered by the SetOp filter. The input path must
6756 * already be sorted accordingly.
6759 make_setop(SetOpCmd cmd
, SetOpStrategy strategy
, Plan
*lefttree
,
6760 List
*distinctList
, AttrNumber flagColIdx
, int firstFlag
,
6763 SetOp
*node
= makeNode(SetOp
);
6764 Plan
*plan
= &node
->plan
;
6765 int numCols
= list_length(distinctList
);
6767 AttrNumber
*dupColIdx
;
6772 plan
->targetlist
= lefttree
->targetlist
;
6774 plan
->lefttree
= lefttree
;
6775 plan
->righttree
= NULL
;
6778 * convert SortGroupClause list into arrays of attr indexes and equality
6779 * operators, as wanted by executor
6781 dupColIdx
= (AttrNumber
*) palloc(sizeof(AttrNumber
) * numCols
);
6782 dupOperators
= (Oid
*) palloc(sizeof(Oid
) * numCols
);
6783 dupCollations
= (Oid
*) palloc(sizeof(Oid
) * numCols
);
6785 foreach(slitem
, distinctList
)
6787 SortGroupClause
*sortcl
= (SortGroupClause
*) lfirst(slitem
);
6788 TargetEntry
*tle
= get_sortgroupclause_tle(sortcl
, plan
->targetlist
);
6790 dupColIdx
[keyno
] = tle
->resno
;
6791 dupOperators
[keyno
] = sortcl
->eqop
;
6792 dupCollations
[keyno
] = exprCollation((Node
*) tle
->expr
);
6793 Assert(OidIsValid(dupOperators
[keyno
]));
6798 node
->strategy
= strategy
;
6799 node
->numCols
= numCols
;
6800 node
->dupColIdx
= dupColIdx
;
6801 node
->dupOperators
= dupOperators
;
6802 node
->dupCollations
= dupCollations
;
6803 node
->flagColIdx
= flagColIdx
;
6804 node
->firstFlag
= firstFlag
;
6805 node
->numGroups
= numGroups
;
6812 * Build a LockRows plan node
6815 make_lockrows(Plan
*lefttree
, List
*rowMarks
, int epqParam
)
6817 LockRows
*node
= makeNode(LockRows
);
6818 Plan
*plan
= &node
->plan
;
6820 plan
->targetlist
= lefttree
->targetlist
;
6822 plan
->lefttree
= lefttree
;
6823 plan
->righttree
= NULL
;
6825 node
->rowMarks
= rowMarks
;
6826 node
->epqParam
= epqParam
;
6833 * Build a Limit plan node
6836 make_limit(Plan
*lefttree
, Node
*limitOffset
, Node
*limitCount
,
6837 LimitOption limitOption
, int uniqNumCols
, AttrNumber
*uniqColIdx
,
6838 Oid
*uniqOperators
, Oid
*uniqCollations
)
6840 Limit
*node
= makeNode(Limit
);
6841 Plan
*plan
= &node
->plan
;
6843 plan
->targetlist
= lefttree
->targetlist
;
6845 plan
->lefttree
= lefttree
;
6846 plan
->righttree
= NULL
;
6848 node
->limitOffset
= limitOffset
;
6849 node
->limitCount
= limitCount
;
6850 node
->limitOption
= limitOption
;
6851 node
->uniqNumCols
= uniqNumCols
;
6852 node
->uniqColIdx
= uniqColIdx
;
6853 node
->uniqOperators
= uniqOperators
;
6854 node
->uniqCollations
= uniqCollations
;
6861 * Build a Result plan node
6864 make_result(List
*tlist
,
6865 Node
*resconstantqual
,
6868 Result
*node
= makeNode(Result
);
6869 Plan
*plan
= &node
->plan
;
6871 plan
->targetlist
= tlist
;
6873 plan
->lefttree
= subplan
;
6874 plan
->righttree
= NULL
;
6875 node
->resconstantqual
= resconstantqual
;
6882 * Build a ProjectSet plan node
6885 make_project_set(List
*tlist
,
6888 ProjectSet
*node
= makeNode(ProjectSet
);
6889 Plan
*plan
= &node
->plan
;
6891 plan
->targetlist
= tlist
;
6893 plan
->lefttree
= subplan
;
6894 plan
->righttree
= NULL
;
6901 * Build a ModifyTable plan node
6903 static ModifyTable
*
6904 make_modifytable(PlannerInfo
*root
, Plan
*subplan
,
6905 CmdType operation
, bool canSetTag
,
6906 Index nominalRelation
, Index rootRelation
,
6907 bool partColsUpdated
,
6908 List
*resultRelations
,
6909 List
*updateColnosLists
,
6910 List
*withCheckOptionLists
, List
*returningLists
,
6911 List
*rowMarks
, OnConflictExpr
*onconflict
, int epqParam
)
6913 ModifyTable
*node
= makeNode(ModifyTable
);
6914 List
*fdw_private_list
;
6915 Bitmapset
*direct_modify_plans
;
6919 Assert(operation
== CMD_UPDATE
?
6920 list_length(resultRelations
) == list_length(updateColnosLists
) :
6921 updateColnosLists
== NIL
);
6922 Assert(withCheckOptionLists
== NIL
||
6923 list_length(resultRelations
) == list_length(withCheckOptionLists
));
6924 Assert(returningLists
== NIL
||
6925 list_length(resultRelations
) == list_length(returningLists
));
6927 node
->plan
.lefttree
= subplan
;
6928 node
->plan
.righttree
= NULL
;
6929 node
->plan
.qual
= NIL
;
6930 /* setrefs.c will fill in the targetlist, if needed */
6931 node
->plan
.targetlist
= NIL
;
6933 node
->operation
= operation
;
6934 node
->canSetTag
= canSetTag
;
6935 node
->nominalRelation
= nominalRelation
;
6936 node
->rootRelation
= rootRelation
;
6937 node
->partColsUpdated
= partColsUpdated
;
6938 node
->resultRelations
= resultRelations
;
6941 node
->onConflictAction
= ONCONFLICT_NONE
;
6942 node
->onConflictSet
= NIL
;
6943 node
->onConflictCols
= NIL
;
6944 node
->onConflictWhere
= NULL
;
6945 node
->arbiterIndexes
= NIL
;
6946 node
->exclRelRTI
= 0;
6947 node
->exclRelTlist
= NIL
;
6951 node
->onConflictAction
= onconflict
->action
;
6954 * Here we convert the ON CONFLICT UPDATE tlist, if any, to the
6955 * executor's convention of having consecutive resno's. The actual
6956 * target column numbers are saved in node->onConflictCols. (This
6957 * could be done earlier, but there seems no need to.)
6959 node
->onConflictSet
= onconflict
->onConflictSet
;
6960 node
->onConflictCols
=
6961 extract_update_targetlist_colnos(node
->onConflictSet
);
6962 node
->onConflictWhere
= onconflict
->onConflictWhere
;
6965 * If a set of unique index inference elements was provided (an
6966 * INSERT...ON CONFLICT "inference specification"), then infer
6967 * appropriate unique indexes (or throw an error if none are
6970 node
->arbiterIndexes
= infer_arbiter_indexes(root
);
6972 node
->exclRelRTI
= onconflict
->exclRelIndex
;
6973 node
->exclRelTlist
= onconflict
->exclRelTlist
;
6975 node
->updateColnosLists
= updateColnosLists
;
6976 node
->withCheckOptionLists
= withCheckOptionLists
;
6977 node
->returningLists
= returningLists
;
6978 node
->rowMarks
= rowMarks
;
6979 node
->epqParam
= epqParam
;
6982 * For each result relation that is a foreign table, allow the FDW to
6983 * construct private plan data, and accumulate it all into a list.
6985 fdw_private_list
= NIL
;
6986 direct_modify_plans
= NULL
;
6988 foreach(lc
, resultRelations
)
6990 Index rti
= lfirst_int(lc
);
6991 FdwRoutine
*fdwroutine
;
6996 * If possible, we want to get the FdwRoutine from our RelOptInfo for
6997 * the table. But sometimes we don't have a RelOptInfo and must get
6998 * it the hard way. (In INSERT, the target relation is not scanned,
6999 * so it's not a baserel; and there are also corner cases for
7000 * updatable views where the target rel isn't a baserel.)
7002 if (rti
< root
->simple_rel_array_size
&&
7003 root
->simple_rel_array
[rti
] != NULL
)
7005 RelOptInfo
*resultRel
= root
->simple_rel_array
[rti
];
7007 fdwroutine
= resultRel
->fdwroutine
;
7011 RangeTblEntry
*rte
= planner_rt_fetch(rti
, root
);
7013 Assert(rte
->rtekind
== RTE_RELATION
);
7014 if (rte
->relkind
== RELKIND_FOREIGN_TABLE
)
7015 fdwroutine
= GetFdwRoutineByRelId(rte
->relid
);
7021 * Try to modify the foreign table directly if (1) the FDW provides
7022 * callback functions needed for that and (2) there are no local
7023 * structures that need to be run for each modified row: row-level
7024 * triggers on the foreign table, stored generated columns, WITH CHECK
7025 * OPTIONs from parent views.
7027 direct_modify
= false;
7028 if (fdwroutine
!= NULL
&&
7029 fdwroutine
->PlanDirectModify
!= NULL
&&
7030 fdwroutine
->BeginDirectModify
!= NULL
&&
7031 fdwroutine
->IterateDirectModify
!= NULL
&&
7032 fdwroutine
->EndDirectModify
!= NULL
&&
7033 withCheckOptionLists
== NIL
&&
7034 !has_row_triggers(root
, rti
, operation
) &&
7035 !has_stored_generated_columns(root
, rti
))
7036 direct_modify
= fdwroutine
->PlanDirectModify(root
, node
, rti
, i
);
7038 direct_modify_plans
= bms_add_member(direct_modify_plans
, i
);
7040 if (!direct_modify
&&
7041 fdwroutine
!= NULL
&&
7042 fdwroutine
->PlanForeignModify
!= NULL
)
7043 fdw_private
= fdwroutine
->PlanForeignModify(root
, node
, rti
, i
);
7046 fdw_private_list
= lappend(fdw_private_list
, fdw_private
);
7049 node
->fdwPrivLists
= fdw_private_list
;
7050 node
->fdwDirectModifyPlans
= direct_modify_plans
;
7056 * is_projection_capable_path
7057 * Check whether a given Path node is able to do projection.
7060 is_projection_capable_path(Path
*path
)
7062 /* Most plan types can project, so just list the ones that can't */
7063 switch (path
->pathtype
)
7069 case T_IncrementalSort
:
7076 case T_RecursiveUnion
:
7079 if (castNode(CustomPath
, path
)->flags
& CUSTOMPATH_SUPPORT_PROJECTION
)
7085 * Append can't project, but if an AppendPath is being used to
7086 * represent a dummy path, what will actually be generated is a
7087 * Result which can project.
7089 return IS_DUMMY_APPEND(path
);
7093 * Although ProjectSet certainly projects, say "no" because we
7094 * don't want the planner to randomly replace its tlist with
7095 * something else; the SRFs have to stay at top level. This might
7096 * get relaxed later.
7106 * is_projection_capable_plan
7107 * Check whether a given Plan node is able to do projection.
7110 is_projection_capable_plan(Plan
*plan
)
7112 /* Most plan types can project, so just list the ones that can't */
7113 switch (nodeTag(plan
))
7126 case T_RecursiveUnion
:
7129 if (((CustomScan
*) plan
)->flags
& CUSTOMPATH_SUPPORT_PROJECTION
)
7135 * Although ProjectSet certainly projects, say "no" because we
7136 * don't want the planner to randomly replace its tlist with
7137 * something else; the SRFs have to stay at top level. This might
7138 * get relaxed later.