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-2005, PostgreSQL Global Development Group
9
* Portions Copyright (c) 1994, Regents of the University of California
13
* $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.175 2004-12-31 22:00:08 pgsql Exp $
15
*-------------------------------------------------------------------------
21
#include "nodes/makefuncs.h"
22
#include "nodes/nodeFuncs.h"
23
#include "optimizer/clauses.h"
24
#include "optimizer/cost.h"
25
#include "optimizer/paths.h"
26
#include "optimizer/plancat.h"
27
#include "optimizer/planmain.h"
28
#include "optimizer/restrictinfo.h"
29
#include "optimizer/tlist.h"
30
#include "optimizer/var.h"
31
#include "parser/parsetree.h"
32
#include "parser/parse_clause.h"
33
#include "parser/parse_expr.h"
34
#include "utils/lsyscache.h"
35
#include "utils/syscache.h"
38
static Scan *create_scan_plan(Query *root, Path *best_path);
39
static List *build_relation_tlist(RelOptInfo *rel);
40
static bool use_physical_tlist(RelOptInfo *rel);
41
static void disuse_physical_tlist(Plan *plan, Path *path);
42
static Join *create_join_plan(Query *root, JoinPath *best_path);
43
static Append *create_append_plan(Query *root, AppendPath *best_path);
44
static Result *create_result_plan(Query *root, ResultPath *best_path);
45
static Material *create_material_plan(Query *root, MaterialPath *best_path);
46
static Plan *create_unique_plan(Query *root, UniquePath *best_path);
47
static SeqScan *create_seqscan_plan(Query *root, Path *best_path,
48
List *tlist, List *scan_clauses);
49
static IndexScan *create_indexscan_plan(Query *root, IndexPath *best_path,
50
List *tlist, List *scan_clauses);
51
static TidScan *create_tidscan_plan(Query *root, TidPath *best_path,
52
List *tlist, List *scan_clauses);
53
static SubqueryScan *create_subqueryscan_plan(Query *root, Path *best_path,
54
List *tlist, List *scan_clauses);
55
static FunctionScan *create_functionscan_plan(Query *root, Path *best_path,
56
List *tlist, List *scan_clauses);
57
static NestLoop *create_nestloop_plan(Query *root, NestPath *best_path,
58
Plan *outer_plan, Plan *inner_plan);
59
static MergeJoin *create_mergejoin_plan(Query *root, MergePath *best_path,
60
Plan *outer_plan, Plan *inner_plan);
61
static HashJoin *create_hashjoin_plan(Query *root, HashPath *best_path,
62
Plan *outer_plan, Plan *inner_plan);
63
static void fix_indxqual_references(List *indexquals, IndexPath *index_path,
64
List **fixed_indexquals,
68
static void fix_indxqual_sublist(List *indexqual,
69
Relids baserelids, int baserelid,
75
static Node *fix_indxqual_operand(Node *node, int baserelid,
78
static List *get_switched_clauses(List *clauses, Relids outerrelids);
79
static List *order_qual_clauses(Query *root, List *clauses);
80
static void copy_path_costsize(Plan *dest, Path *src);
81
static void copy_plan_costsize(Plan *dest, Plan *src);
82
static SeqScan *make_seqscan(List *qptlist, List *qpqual, Index scanrelid);
83
static IndexScan *make_indexscan(List *qptlist, List *qpqual, Index scanrelid,
84
List *indxid, List *indxqual, List *indxqualorig,
85
List *indxstrategy, List *indxsubtype, List *indxlossy,
86
ScanDirection indexscandir);
87
static TidScan *make_tidscan(List *qptlist, List *qpqual, Index scanrelid,
89
static FunctionScan *make_functionscan(List *qptlist, List *qpqual,
91
static NestLoop *make_nestloop(List *tlist,
92
List *joinclauses, List *otherclauses,
93
Plan *lefttree, Plan *righttree,
95
static HashJoin *make_hashjoin(List *tlist,
96
List *joinclauses, List *otherclauses,
98
Plan *lefttree, Plan *righttree,
100
static Hash *make_hash(Plan *lefttree);
101
static MergeJoin *make_mergejoin(List *tlist,
102
List *joinclauses, List *otherclauses,
104
Plan *lefttree, Plan *righttree,
106
static Sort *make_sort(Query *root, Plan *lefttree, int numCols,
107
AttrNumber *sortColIdx, Oid *sortOperators);
108
static Sort *make_sort_from_pathkeys(Query *root, Plan *lefttree,
114
* Creates the access plan for a query by tracing backwards through the
115
* desired chain of pathnodes, starting at the node 'best_path'. For
116
* every pathnode found:
117
* (1) Create a corresponding plan node containing appropriate id,
118
* target list, and qualification information.
119
* (2) Modify qual clauses of join nodes so that subplan attributes are
120
* referenced using relative values.
121
* (3) Target lists are not modified, but will be in setrefs.c.
123
* best_path is the best access path
125
* Returns a Plan tree.
128
create_plan(Query *root, Path *best_path)
132
switch (best_path->pathtype)
139
plan = (Plan *) create_scan_plan(root, best_path);
144
plan = (Plan *) create_join_plan(root,
145
(JoinPath *) best_path);
148
plan = (Plan *) create_append_plan(root,
149
(AppendPath *) best_path);
152
plan = (Plan *) create_result_plan(root,
153
(ResultPath *) best_path);
156
plan = (Plan *) create_material_plan(root,
157
(MaterialPath *) best_path);
160
plan = (Plan *) create_unique_plan(root,
161
(UniquePath *) best_path);
164
elog(ERROR, "unrecognized node type: %d",
165
(int) best_path->pathtype);
166
plan = NULL; /* keep compiler quiet */
175
* Create a scan plan for the parent relation of 'best_path'.
177
* Returns a Plan node.
180
create_scan_plan(Query *root, Path *best_path)
182
RelOptInfo *rel = best_path->parent;
188
* For table scans, rather than using the relation targetlist (which
189
* is only those Vars actually needed by the query), we prefer to
190
* generate a tlist containing all Vars in order. This will allow the
191
* executor to optimize away projection of the table tuples, if
192
* possible. (Note that planner.c may replace the tlist we generate
193
* here, forcing projection to occur.)
195
if (use_physical_tlist(rel))
197
tlist = build_physical_tlist(root, rel);
198
/* if fail because of dropped cols, use regular method */
200
tlist = build_relation_tlist(rel);
203
tlist = build_relation_tlist(rel);
206
* Extract the relevant restriction clauses from the parent relation;
207
* the executor must apply all these restrictions during the scan.
209
scan_clauses = rel->baserestrictinfo;
211
switch (best_path->pathtype)
214
plan = (Scan *) create_seqscan_plan(root,
221
plan = (Scan *) create_indexscan_plan(root,
222
(IndexPath *) best_path,
228
plan = (Scan *) create_tidscan_plan(root,
229
(TidPath *) best_path,
235
plan = (Scan *) create_subqueryscan_plan(root,
242
plan = (Scan *) create_functionscan_plan(root,
249
elog(ERROR, "unrecognized node type: %d",
250
(int) best_path->pathtype);
251
plan = NULL; /* keep compiler quiet */
259
* Build a target list (ie, a list of TargetEntry) for a relation.
262
build_relation_tlist(RelOptInfo *rel)
268
foreach(v, rel->reltargetlist)
270
/* Do we really need to copy here? Not sure */
271
Var *var = (Var *) copyObject(lfirst(v));
273
tlist = lappend(tlist, create_tl_element(var, resdomno));
281
* Decide whether to use a tlist matching relation structure,
282
* rather than only those Vars actually referenced.
285
use_physical_tlist(RelOptInfo *rel)
290
* Currently, can't do this for subquery or function scans. (This is
291
* mainly because we don't have an equivalent of build_physical_tlist
292
* for them; worth adding?)
294
if (rel->rtekind != RTE_RELATION)
298
* Can't do it with inheritance cases either (mainly because Append
301
if (rel->reloptkind != RELOPT_BASEREL)
305
* Can't do it if any system columns are requested, either. (This
306
* could possibly be fixed but would take some fragile assumptions in
307
* setrefs.c, I think.)
309
for (i = rel->min_attr; i <= 0; i++)
311
if (!bms_is_empty(rel->attr_needed[i - rel->min_attr]))
318
* disuse_physical_tlist
319
* Switch a plan node back to emitting only Vars actually referenced.
321
* If the plan node immediately above a scan would prefer to get only
322
* needed Vars and not a physical tlist, it must call this routine to
323
* undo the decision made by use_physical_tlist(). Currently, Hash, Sort,
324
* and Material nodes want this, so they don't have to store useless columns.
327
disuse_physical_tlist(Plan *plan, Path *path)
329
/* Only need to undo it for path types handled by create_scan_plan() */
330
switch (path->pathtype)
337
plan->targetlist = build_relation_tlist(path->parent);
346
* Create a join plan for 'best_path' and (recursively) plans for its
347
* inner and outer paths.
349
* Returns a Plan node.
352
create_join_plan(Query *root, JoinPath *best_path)
358
outer_plan = create_plan(root, best_path->outerjoinpath);
359
inner_plan = create_plan(root, best_path->innerjoinpath);
361
switch (best_path->path.pathtype)
364
plan = (Join *) create_mergejoin_plan(root,
365
(MergePath *) best_path,
370
plan = (Join *) create_hashjoin_plan(root,
371
(HashPath *) best_path,
376
plan = (Join *) create_nestloop_plan(root,
377
(NestPath *) best_path,
382
elog(ERROR, "unrecognized node type: %d",
383
(int) best_path->path.pathtype);
384
plan = NULL; /* keep compiler quiet */
391
* * Expensive function pullups may have pulled local predicates *
392
* into this path node. Put them in the qpqual of the plan node. *
395
if (get_loc_restrictinfo(best_path) != NIL)
396
set_qpqual((Plan) plan,
397
list_concat(get_qpqual((Plan) plan),
398
get_actual_clauses(get_loc_restrictinfo(best_path))));
406
* Create an Append plan for 'best_path' and (recursively) plans
409
* Returns a Plan node.
412
create_append_plan(Query *root, AppendPath *best_path)
415
List *tlist = build_relation_tlist(best_path->path.parent);
416
List *subplans = NIL;
419
foreach(subpaths, best_path->subpaths)
421
Path *subpath = (Path *) lfirst(subpaths);
423
subplans = lappend(subplans, create_plan(root, subpath));
426
plan = make_append(subplans, false, tlist);
433
* Create a Result plan for 'best_path' and (recursively) plans
436
* Returns a Plan node.
439
create_result_plan(Query *root, ResultPath *best_path)
446
if (best_path->path.parent)
447
tlist = build_relation_tlist(best_path->path.parent);
449
tlist = NIL; /* will be filled in later */
451
if (best_path->subpath)
452
subplan = create_plan(root, best_path->subpath);
456
constclauses = order_qual_clauses(root, best_path->constantqual);
458
plan = make_result(tlist, (Node *) constclauses, subplan);
464
* create_material_plan
465
* Create a Material plan for 'best_path' and (recursively) plans
468
* Returns a Plan node.
471
create_material_plan(Query *root, MaterialPath *best_path)
476
subplan = create_plan(root, best_path->subpath);
478
/* We don't want any excess columns in the materialized tuples */
479
disuse_physical_tlist(subplan, best_path->subpath);
481
plan = make_material(subplan);
483
copy_path_costsize(&plan->plan, (Path *) best_path);
490
* Create a Unique plan for 'best_path' and (recursively) plans
493
* Returns a Plan node.
496
create_unique_plan(Query *root, UniquePath *best_path)
502
AttrNumber *groupColIdx;
509
subplan = create_plan(root, best_path->subpath);
512
* As constructed, the subplan has a "flat" tlist containing just the
513
* Vars needed here and at upper levels. The values we are supposed
514
* to unique-ify may be expressions in these variables. We have to
515
* add any such expressions to the subplan's tlist. We then build
516
* control information showing which subplan output columns are to be
517
* examined by the grouping step. (Since we do not remove any
518
* existing subplan outputs, not all the output columns may be used
521
* Note: the reason we don't remove any subplan outputs is that there are
522
* scenarios where a Var is needed at higher levels even though it is
523
* not one of the nominal outputs of an IN clause. Consider WHERE x
524
* IN (SELECT y FROM t1,t2 WHERE y = z) Implied equality deduction
525
* will generate an "x = z" clause, which may get used instead of "x =
526
* y" in the upper join step. Therefore the sub-select had better
527
* deliver both y and z in its targetlist. It is sufficient to
528
* unique-ify on y, however.
530
* To find the correct list of values to unique-ify, we look in the
531
* information saved for IN expressions. If this code is ever used in
532
* other scenarios, some other way of finding what to unique-ify will
535
uniq_exprs = NIL; /* just to keep compiler quiet */
536
foreach(l, root->in_info_list)
538
InClauseInfo *ininfo = (InClauseInfo *) lfirst(l);
540
if (bms_equal(ininfo->righthand, best_path->path.parent->relids))
542
uniq_exprs = ininfo->sub_targetlist;
546
if (l == NULL) /* fell out of loop? */
547
elog(ERROR, "could not find UniquePath in in_info_list");
549
/* set up to record positions of unique columns */
550
numGroupCols = list_length(uniq_exprs);
551
groupColIdx = (AttrNumber *) palloc(numGroupCols * sizeof(AttrNumber));
553
/* not sure if tlist might be shared with other nodes, so copy */
554
newtlist = copyObject(subplan->targetlist);
555
nextresno = list_length(newtlist) + 1;
558
foreach(l, uniq_exprs)
560
Node *uniqexpr = lfirst(l);
563
tle = tlistentry_member(uniqexpr, newtlist);
566
tle = makeTargetEntry(makeResdom(nextresno,
568
exprTypmod(uniqexpr),
572
newtlist = lappend(newtlist, tle);
576
groupColIdx[groupColPos++] = tle->resdom->resno;
582
* If the top plan node can't do projections, we need to add a
583
* Result node to help it along.
585
if (!is_projection_capable_plan(subplan))
586
subplan = (Plan *) make_result(newtlist, NULL, subplan);
588
subplan->targetlist = newtlist;
591
/* Done if we don't need to do any actual unique-ifying */
592
if (best_path->umethod == UNIQUE_PATH_NOOP)
595
if (best_path->umethod == UNIQUE_PATH_HASH)
599
numGroups = (long) Min(best_path->rows, (double) LONG_MAX);
601
plan = (Plan *) make_agg(root,
602
copyObject(subplan->targetlist),
613
List *sortList = NIL;
615
for (groupColPos = 0; groupColPos < numGroupCols; groupColPos++)
619
tle = get_tle_by_resno(subplan->targetlist,
620
groupColIdx[groupColPos]);
622
sortList = addTargetToSortList(NULL, tle,
623
sortList, subplan->targetlist,
624
SORTBY_ASC, NIL, false);
626
plan = (Plan *) make_sort_from_sortclauses(root, sortList, subplan);
627
plan = (Plan *) make_unique(plan, sortList);
630
/* Adjust output size estimate (other fields should be OK already) */
631
plan->plan_rows = best_path->rows;
637
/*****************************************************************************
639
* BASE-RELATION SCAN METHODS
641
*****************************************************************************/
645
* create_seqscan_plan
646
* Returns a seqscan plan for the base relation scanned by 'best_path'
647
* with restriction clauses 'scan_clauses' and targetlist 'tlist'.
650
create_seqscan_plan(Query *root, Path *best_path,
651
List *tlist, List *scan_clauses)
654
Index scan_relid = best_path->parent->relid;
656
/* it should be a base rel... */
657
Assert(scan_relid > 0);
658
Assert(best_path->parent->rtekind == RTE_RELATION);
660
/* Reduce RestrictInfo list to bare expressions */
661
scan_clauses = get_actual_clauses(scan_clauses);
663
/* Sort clauses into best execution order */
664
scan_clauses = order_qual_clauses(root, scan_clauses);
666
scan_plan = make_seqscan(tlist,
670
copy_path_costsize(&scan_plan->plan, best_path);
676
* create_indexscan_plan
677
* Returns a indexscan plan for the base relation scanned by 'best_path'
678
* with restriction clauses 'scan_clauses' and targetlist 'tlist'.
680
* The indexquals list of the path contains a sublist of implicitly-ANDed
681
* qual conditions for each scan of the index(es); if there is more than one
682
* scan then the retrieved tuple sets are ORed together. The indexquals
683
* and indexinfo lists must have the same length, ie, the number of scans
684
* that will occur. Note it is possible for a qual condition sublist
685
* to be empty --- then no index restrictions will be applied during that
689
create_indexscan_plan(Query *root,
690
IndexPath *best_path,
694
List *indxquals = best_path->indexquals;
695
Index baserelid = best_path->path.parent->relid;
697
Expr *indxqual_or_expr = NULL;
698
List *stripped_indxquals;
699
List *fixed_indxquals;
705
IndexScan *scan_plan;
707
/* it should be a base rel... */
708
Assert(baserelid > 0);
709
Assert(best_path->path.parent->rtekind == RTE_RELATION);
712
* If this is a innerjoin scan, the indexclauses will contain join
713
* clauses that are not present in scan_clauses (since the passed-in
714
* value is just the rel's baserestrictinfo list). We must add these
715
* clauses to scan_clauses to ensure they get checked. In most cases
716
* we will remove the join clauses again below, but if a join clause
717
* contains a special operator, we need to make sure it gets into the
720
if (best_path->isjoininner)
723
* We don't currently support OR indexscans in joins, so we only
724
* need to worry about the plain AND case. Also, pointer
725
* comparison should be enough to determine RestrictInfo matches.
727
Assert(list_length(best_path->indexclauses) == 1);
728
scan_clauses = list_union_ptr(scan_clauses,
729
(List *) linitial(best_path->indexclauses));
732
/* Reduce RestrictInfo list to bare expressions */
733
scan_clauses = get_actual_clauses(scan_clauses);
735
/* Sort clauses into best execution order */
736
scan_clauses = order_qual_clauses(root, scan_clauses);
738
/* Build list of index OIDs */
740
foreach(l, best_path->indexinfo)
742
IndexOptInfo *index = (IndexOptInfo *) lfirst(l);
744
indexids = lappend_oid(indexids, index->indexoid);
748
* Build "stripped" indexquals structure (no RestrictInfos) to pass to
749
* executor as indxqualorig
751
stripped_indxquals = NIL;
752
foreach(l, indxquals)
754
List *andlist = (List *) lfirst(l);
756
stripped_indxquals = lappend(stripped_indxquals,
757
get_actual_clauses(andlist));
761
* The qpqual list must contain all restrictions not automatically
762
* handled by the index. All the predicates in the indexquals will be
763
* checked (either by the index itself, or by nodeIndexscan.c), but if
764
* there are any "special" operators involved then they must be added
765
* to qpqual. The upshot is that qpquals must contain scan_clauses
766
* minus whatever appears in indxquals.
768
if (list_length(indxquals) > 1)
771
* Build an expression representation of the indexqual, expanding
772
* the implicit OR and AND semantics of the first- and
773
* second-level lists. (The odds that this will exactly match any
774
* scan_clause are not great; perhaps we need more smarts here.)
776
indxqual_or_expr = make_expr_from_indexclauses(indxquals);
777
qpqual = list_difference(scan_clauses, list_make1(indxqual_or_expr));
782
* Here, we can simply treat the first sublist as an independent
783
* set of qual expressions, since there is no top-level OR
786
Assert(stripped_indxquals != NIL);
787
qpqual = list_difference(scan_clauses, linitial(stripped_indxquals));
791
* The executor needs a copy with the indexkey on the left of each
792
* clause and with index attr numbers substituted for table ones. This
793
* pass also gets strategy info and looks for "lossy" operators.
795
fix_indxqual_references(indxquals, best_path,
797
&indxstrategy, &indxsubtype, &indxlossy);
799
/* Finally ready to build the plan node */
800
scan_plan = make_indexscan(tlist,
809
best_path->indexscandir);
811
copy_path_costsize(&scan_plan->scan.plan, &best_path->path);
812
/* use the indexscan-specific rows estimate, not the parent rel's */
813
scan_plan->scan.plan.plan_rows = best_path->rows;
819
* create_tidscan_plan
820
* Returns a tidscan plan for the base relation scanned by 'best_path'
821
* with restriction clauses 'scan_clauses' and targetlist 'tlist'.
824
create_tidscan_plan(Query *root, TidPath *best_path,
825
List *tlist, List *scan_clauses)
828
Index scan_relid = best_path->path.parent->relid;
830
/* it should be a base rel... */
831
Assert(scan_relid > 0);
832
Assert(best_path->path.parent->rtekind == RTE_RELATION);
834
/* Reduce RestrictInfo list to bare expressions */
835
scan_clauses = get_actual_clauses(scan_clauses);
837
/* Sort clauses into best execution order */
838
scan_clauses = order_qual_clauses(root, scan_clauses);
840
scan_plan = make_tidscan(tlist,
845
copy_path_costsize(&scan_plan->scan.plan, &best_path->path);
851
* create_subqueryscan_plan
852
* Returns a subqueryscan plan for the base relation scanned by 'best_path'
853
* with restriction clauses 'scan_clauses' and targetlist 'tlist'.
855
static SubqueryScan *
856
create_subqueryscan_plan(Query *root, Path *best_path,
857
List *tlist, List *scan_clauses)
859
SubqueryScan *scan_plan;
860
Index scan_relid = best_path->parent->relid;
862
/* it should be a subquery base rel... */
863
Assert(scan_relid > 0);
864
Assert(best_path->parent->rtekind == RTE_SUBQUERY);
866
/* Reduce RestrictInfo list to bare expressions */
867
scan_clauses = get_actual_clauses(scan_clauses);
869
/* Sort clauses into best execution order */
870
scan_clauses = order_qual_clauses(root, scan_clauses);
872
scan_plan = make_subqueryscan(tlist,
875
best_path->parent->subplan);
877
copy_path_costsize(&scan_plan->scan.plan, best_path);
883
* create_functionscan_plan
884
* Returns a functionscan plan for the base relation scanned by 'best_path'
885
* with restriction clauses 'scan_clauses' and targetlist 'tlist'.
887
static FunctionScan *
888
create_functionscan_plan(Query *root, Path *best_path,
889
List *tlist, List *scan_clauses)
891
FunctionScan *scan_plan;
892
Index scan_relid = best_path->parent->relid;
894
/* it should be a function base rel... */
895
Assert(scan_relid > 0);
896
Assert(best_path->parent->rtekind == RTE_FUNCTION);
898
/* Reduce RestrictInfo list to bare expressions */
899
scan_clauses = get_actual_clauses(scan_clauses);
901
/* Sort clauses into best execution order */
902
scan_clauses = order_qual_clauses(root, scan_clauses);
904
scan_plan = make_functionscan(tlist, scan_clauses, scan_relid);
906
copy_path_costsize(&scan_plan->scan.plan, best_path);
911
/*****************************************************************************
915
*****************************************************************************/
918
create_nestloop_plan(Query *root,
923
List *tlist = build_relation_tlist(best_path->path.parent);
924
List *joinrestrictclauses = best_path->joinrestrictinfo;
929
if (IsA(best_path->innerjoinpath, IndexPath))
932
* An index is being used to reduce the number of tuples scanned
933
* in the inner relation. If there are join clauses being used
934
* with the index, we may remove those join clauses from the list
935
* of clauses that have to be checked as qpquals at the join node
936
* --- but only if there's just one indexscan in the inner path
937
* (otherwise, several different sets of clauses are being ORed
940
* We can also remove any join clauses that are redundant with those
941
* being used in the index scan; prior redundancy checks will not
942
* have caught this case because the join clauses would never have
943
* been put in the same joininfo list.
945
* We can skip this if the index path is an ordinary indexpath and
946
* not a special innerjoin path.
948
IndexPath *innerpath = (IndexPath *) best_path->innerjoinpath;
949
List *indexclauses = innerpath->indexclauses;
951
if (innerpath->isjoininner &&
952
list_length(indexclauses) == 1) /* single indexscan? */
954
joinrestrictclauses =
955
select_nonredundant_join_clauses(root,
957
linitial(indexclauses),
958
best_path->jointype);
962
/* Get the join qual clauses (in plain expression form) */
963
if (IS_OUTER_JOIN(best_path->jointype))
965
get_actual_join_clauses(joinrestrictclauses,
966
&joinclauses, &otherclauses);
970
/* We can treat all clauses alike for an inner join */
971
joinclauses = get_actual_clauses(joinrestrictclauses);
975
/* Sort clauses into best execution order */
976
joinclauses = order_qual_clauses(root, joinclauses);
977
otherclauses = order_qual_clauses(root, otherclauses);
979
join_plan = make_nestloop(tlist,
984
best_path->jointype);
986
copy_path_costsize(&join_plan->join.plan, &best_path->path);
992
create_mergejoin_plan(Query *root,
993
MergePath *best_path,
997
List *tlist = build_relation_tlist(best_path->jpath.path.parent);
1001
MergeJoin *join_plan;
1003
/* Get the join qual clauses (in plain expression form) */
1004
if (IS_OUTER_JOIN(best_path->jpath.jointype))
1006
get_actual_join_clauses(best_path->jpath.joinrestrictinfo,
1007
&joinclauses, &otherclauses);
1011
/* We can treat all clauses alike for an inner join */
1012
joinclauses = get_actual_clauses(best_path->jpath.joinrestrictinfo);
1017
* Remove the mergeclauses from the list of join qual clauses, leaving
1018
* the list of quals that must be checked as qpquals.
1020
mergeclauses = get_actual_clauses(best_path->path_mergeclauses);
1021
joinclauses = list_difference(joinclauses, mergeclauses);
1024
* Rearrange mergeclauses, if needed, so that the outer variable is
1025
* always on the left.
1027
mergeclauses = get_switched_clauses(best_path->path_mergeclauses,
1028
best_path->jpath.outerjoinpath->parent->relids);
1030
/* Sort clauses into best execution order */
1031
/* NB: do NOT reorder the mergeclauses */
1032
joinclauses = order_qual_clauses(root, joinclauses);
1033
otherclauses = order_qual_clauses(root, otherclauses);
1036
* Create explicit sort nodes for the outer and inner join paths if
1037
* necessary. The sort cost was already accounted for in the path.
1038
* Make sure there are no excess columns in the inputs if sorting.
1040
if (best_path->outersortkeys)
1042
disuse_physical_tlist(outer_plan, best_path->jpath.outerjoinpath);
1043
outer_plan = (Plan *)
1044
make_sort_from_pathkeys(root,
1046
best_path->outersortkeys);
1049
if (best_path->innersortkeys)
1051
disuse_physical_tlist(inner_plan, best_path->jpath.innerjoinpath);
1052
inner_plan = (Plan *)
1053
make_sort_from_pathkeys(root,
1055
best_path->innersortkeys);
1059
* Now we can build the mergejoin node.
1061
join_plan = make_mergejoin(tlist,
1067
best_path->jpath.jointype);
1069
copy_path_costsize(&join_plan->join.plan, &best_path->jpath.path);
1075
create_hashjoin_plan(Query *root,
1076
HashPath *best_path,
1080
List *tlist = build_relation_tlist(best_path->jpath.path.parent);
1084
HashJoin *join_plan;
1087
/* Get the join qual clauses (in plain expression form) */
1088
if (IS_OUTER_JOIN(best_path->jpath.jointype))
1090
get_actual_join_clauses(best_path->jpath.joinrestrictinfo,
1091
&joinclauses, &otherclauses);
1095
/* We can treat all clauses alike for an inner join */
1096
joinclauses = get_actual_clauses(best_path->jpath.joinrestrictinfo);
1101
* Remove the hashclauses from the list of join qual clauses, leaving
1102
* the list of quals that must be checked as qpquals.
1104
hashclauses = get_actual_clauses(best_path->path_hashclauses);
1105
joinclauses = list_difference(joinclauses, hashclauses);
1108
* Rearrange hashclauses, if needed, so that the outer variable is
1109
* always on the left.
1111
hashclauses = get_switched_clauses(best_path->path_hashclauses,
1112
best_path->jpath.outerjoinpath->parent->relids);
1114
/* Sort clauses into best execution order */
1115
joinclauses = order_qual_clauses(root, joinclauses);
1116
otherclauses = order_qual_clauses(root, otherclauses);
1117
hashclauses = order_qual_clauses(root, hashclauses);
1119
/* We don't want any excess columns in the hashed tuples */
1120
disuse_physical_tlist(inner_plan, best_path->jpath.innerjoinpath);
1123
* Build the hash node and hash join node.
1125
hash_plan = make_hash(inner_plan);
1126
join_plan = make_hashjoin(tlist,
1132
best_path->jpath.jointype);
1134
copy_path_costsize(&join_plan->join.plan, &best_path->jpath.path);
1140
/*****************************************************************************
1142
* SUPPORTING ROUTINES
1144
*****************************************************************************/
1147
* fix_indxqual_references
1148
* Adjust indexqual clauses to the form the executor's indexqual
1149
* machinery needs, and check for recheckable (lossy) index conditions.
1151
* We have four tasks here:
1152
* * Remove RestrictInfo nodes from the input clauses.
1153
* * Index keys must be represented by Var nodes with varattno set to the
1154
* index's attribute number, not the attribute number in the original rel.
1155
* * If the index key is on the right, commute the clause to put it on the
1156
* left. (Someday the executor might not need this, but for now it does.)
1157
* * We must construct lists of operator strategy numbers, subtypes, and
1158
* recheck (lossy-operator) flags for the top-level operators of each
1161
* Both the input list and the "fixed" output list have the form of lists of
1162
* sublists of qual clauses --- the top-level list has one entry for each
1163
* indexscan to be performed. The semantics are OR-of-ANDs. Note however
1164
* that the input list contains RestrictInfos, while the output list doesn't.
1166
* fixed_indexquals receives a modified copy of the indexqual list --- the
1167
* original is not changed. Note also that the copy shares no substructure
1168
* with the original; this is needed in case there is a subplan in it (we need
1169
* two separate copies of the subplan tree, or things will go awry).
1171
* indxstrategy receives a list of integer sublists of strategy numbers.
1172
* indxsubtype receives a list of OID sublists of strategy subtypes.
1173
* indxlossy receives a list of integer sublists of lossy-operator booleans.
1176
fix_indxqual_references(List *indexquals, IndexPath *index_path,
1177
List **fixed_indexquals,
1178
List **indxstrategy,
1182
Relids baserelids = index_path->path.parent->relids;
1183
int baserelid = index_path->path.parent->relid;
1184
List *index_info = index_path->indexinfo;
1188
*fixed_indexquals = NIL;
1189
*indxstrategy = NIL;
1192
forboth(iq, indexquals, ii, index_info)
1194
List *indexqual = (List *) lfirst(iq);
1195
IndexOptInfo *index = (IndexOptInfo *) lfirst(ii);
1201
fix_indxqual_sublist(indexqual, baserelids, baserelid, index,
1202
&fixed_qual, &strategy, &subtype, &lossy);
1203
*fixed_indexquals = lappend(*fixed_indexquals, fixed_qual);
1204
*indxstrategy = lappend(*indxstrategy, strategy);
1205
*indxsubtype = lappend(*indxsubtype, subtype);
1206
*indxlossy = lappend(*indxlossy, lossy);
1211
* Fix the sublist of indexquals to be used in a particular scan.
1213
* For each qual clause, commute if needed to put the indexkey operand on the
1214
* left, and then fix its varattno. (We do not need to change the other side
1215
* of the clause.) Then determine the operator's strategy number and subtype
1216
* number, and check for lossy index behavior.
1218
* Returns four lists:
1219
* the list of fixed indexquals
1220
* the integer list of strategy numbers
1221
* the OID list of strategy subtypes
1222
* the integer list of lossiness flags (1/0)
1225
fix_indxqual_sublist(List *indexqual,
1226
Relids baserelids, int baserelid,
1227
IndexOptInfo *index,
1239
foreach(l, indexqual)
1241
RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
1249
Assert(IsA(rinfo, RestrictInfo));
1250
clause = (OpExpr *) rinfo->clause;
1251
if (!IsA(clause, OpExpr) ||list_length(clause->args) != 2)
1252
elog(ERROR, "indexqual clause is not binary opclause");
1255
* Make a copy that will become the fixed clause.
1257
* We used to try to do a shallow copy here, but that fails if there
1258
* is a subplan in the arguments of the opclause. So just do a
1261
newclause = (OpExpr *) copyObject((Node *) clause);
1264
* Check to see if the indexkey is on the right; if so, commute
1265
* the clause. The indexkey should be the side that refers to
1266
* (only) the base relation.
1268
if (!bms_equal(rinfo->left_relids, baserelids))
1269
CommuteClause(newclause);
1272
* Now, determine which index attribute this is, change the
1273
* indexkey operand as needed, and get the index opclass.
1275
linitial(newclause->args) = fix_indxqual_operand(linitial(newclause->args),
1280
*fixed_quals = lappend(*fixed_quals, newclause);
1283
* Look up the (possibly commuted) operator in the operator class
1284
* to get its strategy numbers and the recheck indicator. This
1285
* also double-checks that we found an operator matching the
1288
get_op_opclass_properties(newclause->opno, opclass,
1289
&stratno, &stratsubtype, &recheck);
1291
*strategy = lappend_int(*strategy, stratno);
1292
*subtype = lappend_oid(*subtype, stratsubtype);
1293
*lossy = lappend_int(*lossy, (int) recheck);
1298
fix_indxqual_operand(Node *node, int baserelid, IndexOptInfo *index,
1302
* We represent index keys by Var nodes having the varno of the base
1303
* table but varattno equal to the index's attribute number (index
1304
* column position). This is a bit hokey ... would be cleaner to use
1305
* a special-purpose node type that could not be mistaken for a
1306
* regular Var. But it will do for now.
1310
ListCell *indexpr_item;
1313
* Remove any binary-compatible relabeling of the indexkey
1315
if (IsA(node, RelabelType))
1316
node = (Node *) ((RelabelType *) node)->arg;
1318
if (IsA(node, Var) &&
1319
((Var *) node)->varno == baserelid)
1321
/* Try to match against simple index columns */
1322
int varatt = ((Var *) node)->varattno;
1326
for (pos = 0; pos < index->ncolumns; pos++)
1328
if (index->indexkeys[pos] == varatt)
1330
result = (Var *) copyObject(node);
1331
result->varattno = pos + 1;
1332
/* return the correct opclass, too */
1333
*opclass = index->classlist[pos];
1334
return (Node *) result;
1340
/* Try to match against index expressions */
1341
indexpr_item = list_head(index->indexprs);
1342
for (pos = 0; pos < index->ncolumns; pos++)
1344
if (index->indexkeys[pos] == 0)
1348
if (indexpr_item == NULL)
1349
elog(ERROR, "too few entries in indexprs list");
1350
indexkey = (Node *) lfirst(indexpr_item);
1351
if (indexkey && IsA(indexkey, RelabelType))
1352
indexkey = (Node *) ((RelabelType *) indexkey)->arg;
1353
if (equal(node, indexkey))
1356
result = makeVar(baserelid, pos + 1,
1357
exprType(lfirst(indexpr_item)), -1,
1359
/* return the correct opclass, too */
1360
*opclass = index->classlist[pos];
1361
return (Node *) result;
1363
indexpr_item = lnext(indexpr_item);
1368
elog(ERROR, "node is not an index attribute");
1369
return NULL; /* keep compiler quiet */
1373
* get_switched_clauses
1374
* Given a list of merge or hash joinclauses (as RestrictInfo nodes),
1375
* extract the bare clauses, and rearrange the elements within the
1376
* clauses, if needed, so the outer join variable is on the left and
1377
* the inner is on the right. The original data structure is not touched;
1378
* a modified list is returned.
1381
get_switched_clauses(List *clauses, Relids outerrelids)
1388
RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(l);
1389
OpExpr *clause = (OpExpr *) restrictinfo->clause;
1391
Assert(is_opclause(clause));
1392
if (bms_is_subset(restrictinfo->right_relids, outerrelids))
1395
* Duplicate just enough of the structure to allow commuting
1396
* the clause without changing the original list. Could use
1397
* copyObject, but a complete deep copy is overkill.
1399
OpExpr *temp = makeNode(OpExpr);
1401
temp->opno = clause->opno;
1402
temp->opfuncid = InvalidOid;
1403
temp->opresulttype = clause->opresulttype;
1404
temp->opretset = clause->opretset;
1405
temp->args = list_copy(clause->args);
1406
/* Commute it --- note this modifies the temp node in-place. */
1407
CommuteClause(temp);
1408
t_list = lappend(t_list, temp);
1411
t_list = lappend(t_list, clause);
1417
* order_qual_clauses
1418
* Given a list of qual clauses that will all be evaluated at the same
1419
* plan node, sort the list into the order we want to check the quals
1422
* Ideally the order should be driven by a combination of execution cost and
1423
* selectivity, but unfortunately we have so little information about
1424
* execution cost of operators that it's really hard to do anything smart.
1425
* For now, we just move any quals that contain SubPlan references (but not
1426
* InitPlan references) to the end of the list.
1429
order_qual_clauses(Query *root, List *clauses)
1435
/* No need to work hard if the query is subselect-free */
1436
if (!root->hasSubLinks)
1443
Node *clause = (Node *) lfirst(l);
1445
if (contain_subplans(clause))
1446
withsubplans = lappend(withsubplans, clause);
1448
nosubplans = lappend(nosubplans, clause);
1451
return list_concat(nosubplans, withsubplans);
1455
* Copy cost and size info from a Path node to the Plan node created from it.
1456
* The executor won't use this info, but it's needed by EXPLAIN.
1459
copy_path_costsize(Plan *dest, Path *src)
1463
dest->startup_cost = src->startup_cost;
1464
dest->total_cost = src->total_cost;
1465
dest->plan_rows = src->parent->rows;
1466
dest->plan_width = src->parent->width;
1470
dest->startup_cost = 0;
1471
dest->total_cost = 0;
1472
dest->plan_rows = 0;
1473
dest->plan_width = 0;
1478
* Copy cost and size info from a lower plan node to an inserted node.
1479
* This is not critical, since the decisions have already been made,
1480
* but it helps produce more reasonable-looking EXPLAIN output.
1481
* (Some callers alter the info after copying it.)
1484
copy_plan_costsize(Plan *dest, Plan *src)
1488
dest->startup_cost = src->startup_cost;
1489
dest->total_cost = src->total_cost;
1490
dest->plan_rows = src->plan_rows;
1491
dest->plan_width = src->plan_width;
1495
dest->startup_cost = 0;
1496
dest->total_cost = 0;
1497
dest->plan_rows = 0;
1498
dest->plan_width = 0;
1503
/*****************************************************************************
1505
* PLAN NODE BUILDING ROUTINES
1507
* Some of these are exported because they are called to build plan nodes
1508
* in contexts where we're not deriving the plan node from a path node.
1510
*****************************************************************************/
1513
make_seqscan(List *qptlist,
1517
SeqScan *node = makeNode(SeqScan);
1518
Plan *plan = &node->plan;
1520
/* cost should be inserted by caller */
1521
plan->targetlist = qptlist;
1522
plan->qual = qpqual;
1523
plan->lefttree = NULL;
1524
plan->righttree = NULL;
1525
node->scanrelid = scanrelid;
1531
make_indexscan(List *qptlist,
1540
ScanDirection indexscandir)
1542
IndexScan *node = makeNode(IndexScan);
1543
Plan *plan = &node->scan.plan;
1545
/* cost should be inserted by caller */
1546
plan->targetlist = qptlist;
1547
plan->qual = qpqual;
1548
plan->lefttree = NULL;
1549
plan->righttree = NULL;
1550
node->scan.scanrelid = scanrelid;
1551
node->indxid = indxid;
1552
node->indxqual = indxqual;
1553
node->indxqualorig = indxqualorig;
1554
node->indxstrategy = indxstrategy;
1555
node->indxsubtype = indxsubtype;
1556
node->indxlossy = indxlossy;
1557
node->indxorderdir = indexscandir;
1563
make_tidscan(List *qptlist,
1568
TidScan *node = makeNode(TidScan);
1569
Plan *plan = &node->scan.plan;
1571
/* cost should be inserted by caller */
1572
plan->targetlist = qptlist;
1573
plan->qual = qpqual;
1574
plan->lefttree = NULL;
1575
plan->righttree = NULL;
1576
node->scan.scanrelid = scanrelid;
1577
node->tideval = tideval;
1583
make_subqueryscan(List *qptlist,
1588
SubqueryScan *node = makeNode(SubqueryScan);
1589
Plan *plan = &node->scan.plan;
1592
* Cost is figured here for the convenience of prepunion.c. Note this
1593
* is only correct for the case where qpqual is empty; otherwise
1594
* caller should overwrite cost with a better estimate.
1596
copy_plan_costsize(plan, subplan);
1597
plan->total_cost += cpu_tuple_cost * subplan->plan_rows;
1599
plan->targetlist = qptlist;
1600
plan->qual = qpqual;
1601
plan->lefttree = NULL;
1602
plan->righttree = NULL;
1603
node->scan.scanrelid = scanrelid;
1604
node->subplan = subplan;
1609
static FunctionScan *
1610
make_functionscan(List *qptlist,
1614
FunctionScan *node = makeNode(FunctionScan);
1615
Plan *plan = &node->scan.plan;
1617
/* cost should be inserted by caller */
1618
plan->targetlist = qptlist;
1619
plan->qual = qpqual;
1620
plan->lefttree = NULL;
1621
plan->righttree = NULL;
1622
node->scan.scanrelid = scanrelid;
1628
make_append(List *appendplans, bool isTarget, List *tlist)
1630
Append *node = makeNode(Append);
1631
Plan *plan = &node->plan;
1635
* Compute cost as sum of subplan costs. We charge nothing extra for
1636
* the Append itself, which perhaps is too optimistic, but since it
1637
* doesn't do any selection or projection, it is a pretty cheap node.
1639
plan->startup_cost = 0;
1640
plan->total_cost = 0;
1641
plan->plan_rows = 0;
1642
plan->plan_width = 0;
1643
foreach(subnode, appendplans)
1645
Plan *subplan = (Plan *) lfirst(subnode);
1647
if (subnode == list_head(appendplans)) /* first node? */
1648
plan->startup_cost = subplan->startup_cost;
1649
plan->total_cost += subplan->total_cost;
1650
plan->plan_rows += subplan->plan_rows;
1651
if (plan->plan_width < subplan->plan_width)
1652
plan->plan_width = subplan->plan_width;
1655
plan->targetlist = tlist;
1657
plan->lefttree = NULL;
1658
plan->righttree = NULL;
1659
node->appendplans = appendplans;
1660
node->isTarget = isTarget;
1666
make_nestloop(List *tlist,
1673
NestLoop *node = makeNode(NestLoop);
1674
Plan *plan = &node->join.plan;
1676
/* cost should be inserted by caller */
1677
plan->targetlist = tlist;
1678
plan->qual = otherclauses;
1679
plan->lefttree = lefttree;
1680
plan->righttree = righttree;
1681
node->join.jointype = jointype;
1682
node->join.joinqual = joinclauses;
1688
make_hashjoin(List *tlist,
1696
HashJoin *node = makeNode(HashJoin);
1697
Plan *plan = &node->join.plan;
1699
/* cost should be inserted by caller */
1700
plan->targetlist = tlist;
1701
plan->qual = otherclauses;
1702
plan->lefttree = lefttree;
1703
plan->righttree = righttree;
1704
node->hashclauses = hashclauses;
1705
node->join.jointype = jointype;
1706
node->join.joinqual = joinclauses;
1712
make_hash(Plan *lefttree)
1714
Hash *node = makeNode(Hash);
1715
Plan *plan = &node->plan;
1717
copy_plan_costsize(plan, lefttree);
1720
* For plausibility, make startup & total costs equal total cost of
1721
* input plan; this only affects EXPLAIN display not decisions.
1723
plan->startup_cost = plan->total_cost;
1724
plan->targetlist = copyObject(lefttree->targetlist);
1726
plan->lefttree = lefttree;
1727
plan->righttree = NULL;
1733
make_mergejoin(List *tlist,
1741
MergeJoin *node = makeNode(MergeJoin);
1742
Plan *plan = &node->join.plan;
1744
/* cost should be inserted by caller */
1745
plan->targetlist = tlist;
1746
plan->qual = otherclauses;
1747
plan->lefttree = lefttree;
1748
plan->righttree = righttree;
1749
node->mergeclauses = mergeclauses;
1750
node->join.jointype = jointype;
1751
node->join.joinqual = joinclauses;
1757
* make_sort --- basic routine to build a Sort plan node
1759
* Caller must have built the sortColIdx and sortOperators arrays already.
1762
make_sort(Query *root, Plan *lefttree, int numCols,
1763
AttrNumber *sortColIdx, Oid *sortOperators)
1765
Sort *node = makeNode(Sort);
1766
Plan *plan = &node->plan;
1767
Path sort_path; /* dummy for result of cost_sort */
1769
copy_plan_costsize(plan, lefttree); /* only care about copying size */
1770
cost_sort(&sort_path, root, NIL,
1771
lefttree->total_cost,
1772
lefttree->plan_rows,
1773
lefttree->plan_width);
1774
plan->startup_cost = sort_path.startup_cost;
1775
plan->total_cost = sort_path.total_cost;
1776
plan->targetlist = copyObject(lefttree->targetlist);
1778
plan->lefttree = lefttree;
1779
plan->righttree = NULL;
1780
node->numCols = numCols;
1781
node->sortColIdx = sortColIdx;
1782
node->sortOperators = sortOperators;
1788
* add_sort_column --- utility subroutine for building sort info arrays
1790
* We need this routine because the same column might be selected more than
1791
* once as a sort key column; if so, the extra mentions are redundant.
1793
* Caller is assumed to have allocated the arrays large enough for the
1794
* max possible number of columns. Return value is the new column count.
1797
add_sort_column(AttrNumber colIdx, Oid sortOp,
1798
int numCols, AttrNumber *sortColIdx, Oid *sortOperators)
1802
for (i = 0; i < numCols; i++)
1804
if (sortColIdx[i] == colIdx)
1806
/* Already sorting by this col, so extra sort key is useless */
1811
/* Add the column */
1812
sortColIdx[numCols] = colIdx;
1813
sortOperators[numCols] = sortOp;
1818
* make_sort_from_pathkeys
1819
* Create sort plan to sort according to given pathkeys
1821
* 'lefttree' is the node which yields input tuples
1822
* 'pathkeys' is the list of pathkeys by which the result is to be sorted
1824
* We must convert the pathkey information into arrays of sort key column
1825
* numbers and sort operator OIDs.
1827
* If the pathkeys include expressions that aren't simple Vars, we will
1828
* usually need to add resjunk items to the input plan's targetlist to
1829
* compute these expressions (since the Sort node itself won't do it).
1830
* If the input plan type isn't one that can do projections, this means
1831
* adding a Result node just to do the projection.
1834
make_sort_from_pathkeys(Query *root, Plan *lefttree, List *pathkeys)
1836
List *tlist = lefttree->targetlist;
1839
AttrNumber *sortColIdx;
1843
* We will need at most list_length(pathkeys) sort columns; possibly
1846
numsortkeys = list_length(pathkeys);
1847
sortColIdx = (AttrNumber *) palloc(numsortkeys * sizeof(AttrNumber));
1848
sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));
1852
foreach(i, pathkeys)
1854
List *keysublist = (List *) lfirst(i);
1855
PathKeyItem *pathkey = NULL;
1856
Resdom *resdom = NULL;
1860
* We can sort by any one of the sort key items listed in this
1861
* sublist. For now, we take the first one that corresponds to an
1862
* available Var in the tlist. If there isn't any, use the first
1863
* one that is an expression in the input's vars.
1865
* XXX if we have a choice, is there any way of figuring out which
1866
* might be cheapest to execute? (For example, int4lt is likely
1867
* much cheaper to execute than numericlt, but both might appear
1868
* in the same pathkey sublist...) Not clear that we ever will
1869
* have a choice in practice, so it may not matter.
1871
foreach(j, keysublist)
1873
pathkey = (PathKeyItem *) lfirst(j);
1874
Assert(IsA(pathkey, PathKeyItem));
1875
resdom = tlist_member(pathkey->key, tlist);
1881
/* No matching Var; look for a computable expression */
1882
foreach(j, keysublist)
1887
pathkey = (PathKeyItem *) lfirst(j);
1888
exprvars = pull_var_clause(pathkey->key, false);
1889
foreach(k, exprvars)
1891
if (!tlist_member(lfirst(k), tlist))
1894
list_free(exprvars);
1896
break; /* found usable expression */
1899
elog(ERROR, "could not find pathkey item to sort");
1902
* Do we need to insert a Result node?
1904
if (!is_projection_capable_plan(lefttree))
1906
tlist = copyObject(tlist);
1907
lefttree = (Plan *) make_result(tlist, NULL, lefttree);
1911
* Add resjunk entry to input's tlist
1913
resdom = makeResdom(list_length(tlist) + 1,
1914
exprType(pathkey->key),
1915
exprTypmod(pathkey->key),
1918
tlist = lappend(tlist,
1919
makeTargetEntry(resdom,
1920
(Expr *) pathkey->key));
1921
lefttree->targetlist = tlist; /* just in case NIL before */
1925
* The column might already be selected as a sort key, if the
1926
* pathkeys contain duplicate entries. (This can happen in
1927
* scenarios where multiple mergejoinable clauses mention the same
1928
* var, for example.) So enter it only once in the sort arrays.
1930
numsortkeys = add_sort_column(resdom->resno, pathkey->sortop,
1931
numsortkeys, sortColIdx, sortOperators);
1934
Assert(numsortkeys > 0);
1936
return make_sort(root, lefttree, numsortkeys,
1937
sortColIdx, sortOperators);
1941
* make_sort_from_sortclauses
1942
* Create sort plan to sort according to given sortclauses
1944
* 'sortcls' is a list of SortClauses
1945
* 'lefttree' is the node which yields input tuples
1948
make_sort_from_sortclauses(Query *root, List *sortcls, Plan *lefttree)
1950
List *sub_tlist = lefttree->targetlist;
1953
AttrNumber *sortColIdx;
1957
* We will need at most list_length(sortcls) sort columns; possibly
1960
numsortkeys = list_length(sortcls);
1961
sortColIdx = (AttrNumber *) palloc(numsortkeys * sizeof(AttrNumber));
1962
sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));
1968
SortClause *sortcl = (SortClause *) lfirst(l);
1969
TargetEntry *tle = get_sortgroupclause_tle(sortcl, sub_tlist);
1972
* Check for the possibility of duplicate order-by clauses --- the
1973
* parser should have removed 'em, but no point in sorting
1976
numsortkeys = add_sort_column(tle->resdom->resno, sortcl->sortop,
1977
numsortkeys, sortColIdx, sortOperators);
1980
Assert(numsortkeys > 0);
1982
return make_sort(root, lefttree, numsortkeys,
1983
sortColIdx, sortOperators);
1987
* make_sort_from_groupcols
1988
* Create sort plan to sort based on grouping columns
1990
* 'groupcls' is the list of GroupClauses
1991
* 'grpColIdx' gives the column numbers to use
1993
* This might look like it could be merged with make_sort_from_sortclauses,
1994
* but presently we *must* use the grpColIdx[] array to locate sort columns,
1995
* because the child plan's tlist is not marked with ressortgroupref info
1996
* appropriate to the grouping node. So, only the sortop is used from the
1997
* GroupClause entries.
2000
make_sort_from_groupcols(Query *root,
2002
AttrNumber *grpColIdx,
2005
List *sub_tlist = lefttree->targetlist;
2009
AttrNumber *sortColIdx;
2013
* We will need at most list_length(groupcls) sort columns; possibly
2016
numsortkeys = list_length(groupcls);
2017
sortColIdx = (AttrNumber *) palloc(numsortkeys * sizeof(AttrNumber));
2018
sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));
2022
foreach(l, groupcls)
2024
GroupClause *grpcl = (GroupClause *) lfirst(l);
2025
TargetEntry *tle = get_tle_by_resno(sub_tlist, grpColIdx[grpno]);
2028
* Check for the possibility of duplicate group-by clauses --- the
2029
* parser should have removed 'em, but no point in sorting
2032
numsortkeys = add_sort_column(tle->resdom->resno, grpcl->sortop,
2033
numsortkeys, sortColIdx, sortOperators);
2037
Assert(numsortkeys > 0);
2039
return make_sort(root, lefttree, numsortkeys,
2040
sortColIdx, sortOperators);
2044
make_material(Plan *lefttree)
2046
Material *node = makeNode(Material);
2047
Plan *plan = &node->plan;
2049
/* cost should be inserted by caller */
2050
plan->targetlist = copyObject(lefttree->targetlist);
2052
plan->lefttree = lefttree;
2053
plan->righttree = NULL;
2059
* materialize_finished_plan: stick a Material node atop a completed plan
2061
* There are a couple of places where we want to attach a Material node
2062
* after completion of subquery_planner(). This currently requires hackery.
2063
* Since subquery_planner has already run SS_finalize_plan on the subplan
2064
* tree, we have to kluge up parameter lists for the Material node.
2065
* Possibly this could be fixed by postponing SS_finalize_plan processing
2066
* until setrefs.c is run?
2069
materialize_finished_plan(Plan *subplan)
2072
Path matpath; /* dummy for result of cost_material */
2074
matplan = (Plan *) make_material(subplan);
2077
cost_material(&matpath,
2078
subplan->total_cost,
2080
subplan->plan_width);
2081
matplan->startup_cost = matpath.startup_cost;
2082
matplan->total_cost = matpath.total_cost;
2083
matplan->plan_rows = subplan->plan_rows;
2084
matplan->plan_width = subplan->plan_width;
2086
/* parameter kluge --- see comments above */
2087
matplan->extParam = bms_copy(subplan->extParam);
2088
matplan->allParam = bms_copy(subplan->allParam);
2094
make_agg(Query *root, List *tlist, List *qual,
2095
AggStrategy aggstrategy,
2096
int numGroupCols, AttrNumber *grpColIdx,
2097
long numGroups, int numAggs,
2100
Agg *node = makeNode(Agg);
2101
Plan *plan = &node->plan;
2102
Path agg_path; /* dummy for result of cost_agg */
2105
node->aggstrategy = aggstrategy;
2106
node->numCols = numGroupCols;
2107
node->grpColIdx = grpColIdx;
2108
node->numGroups = numGroups;
2110
copy_plan_costsize(plan, lefttree); /* only care about copying size */
2111
cost_agg(&agg_path, root,
2112
aggstrategy, numAggs,
2113
numGroupCols, numGroups,
2114
lefttree->startup_cost,
2115
lefttree->total_cost,
2116
lefttree->plan_rows);
2117
plan->startup_cost = agg_path.startup_cost;
2118
plan->total_cost = agg_path.total_cost;
2121
* We will produce a single output tuple if not grouping, and a tuple
2122
* per group otherwise.
2124
if (aggstrategy == AGG_PLAIN)
2125
plan->plan_rows = 1;
2127
plan->plan_rows = numGroups;
2130
* We also need to account for the cost of evaluation of the qual (ie,
2131
* the HAVING clause) and the tlist. Note that cost_qual_eval doesn't
2132
* charge anything for Aggref nodes; this is okay since they are
2133
* really comparable to Vars.
2135
* See notes in grouping_planner about why this routine and make_group
2136
* are the only ones in this file that worry about tlist eval cost.
2140
cost_qual_eval(&qual_cost, qual);
2141
plan->startup_cost += qual_cost.startup;
2142
plan->total_cost += qual_cost.startup;
2143
plan->total_cost += qual_cost.per_tuple * plan->plan_rows;
2145
cost_qual_eval(&qual_cost, tlist);
2146
plan->startup_cost += qual_cost.startup;
2147
plan->total_cost += qual_cost.startup;
2148
plan->total_cost += qual_cost.per_tuple * plan->plan_rows;
2151
plan->targetlist = tlist;
2152
plan->lefttree = lefttree;
2153
plan->righttree = NULL;
2159
make_group(Query *root,
2162
AttrNumber *grpColIdx,
2166
Group *node = makeNode(Group);
2167
Plan *plan = &node->plan;
2168
Path group_path; /* dummy for result of cost_group */
2171
node->numCols = numGroupCols;
2172
node->grpColIdx = grpColIdx;
2174
copy_plan_costsize(plan, lefttree); /* only care about copying size */
2175
cost_group(&group_path, root,
2176
numGroupCols, numGroups,
2177
lefttree->startup_cost,
2178
lefttree->total_cost,
2179
lefttree->plan_rows);
2180
plan->startup_cost = group_path.startup_cost;
2181
plan->total_cost = group_path.total_cost;
2183
/* One output tuple per estimated result group */
2184
plan->plan_rows = numGroups;
2187
* We also need to account for the cost of evaluation of the tlist.
2189
* XXX this double-counts the cost of evaluation of any expressions used
2190
* for grouping, since in reality those will have been evaluated at a
2191
* lower plan level and will only be copied by the Group node. Worth
2194
* See notes in grouping_planner about why this routine and make_agg are
2195
* the only ones in this file that worry about tlist eval cost.
2197
cost_qual_eval(&qual_cost, tlist);
2198
plan->startup_cost += qual_cost.startup;
2199
plan->total_cost += qual_cost.startup;
2200
plan->total_cost += qual_cost.per_tuple * plan->plan_rows;
2203
plan->targetlist = tlist;
2204
plan->lefttree = lefttree;
2205
plan->righttree = NULL;
2211
* distinctList is a list of SortClauses, identifying the targetlist items
2212
* that should be considered by the Unique filter.
2215
make_unique(Plan *lefttree, List *distinctList)
2217
Unique *node = makeNode(Unique);
2218
Plan *plan = &node->plan;
2219
int numCols = list_length(distinctList);
2221
AttrNumber *uniqColIdx;
2224
copy_plan_costsize(plan, lefttree);
2227
* Charge one cpu_operator_cost per comparison per input tuple. We
2228
* assume all columns get compared at most of the tuples. (XXX
2229
* probably this is an overestimate.)
2231
plan->total_cost += cpu_operator_cost * plan->plan_rows * numCols;
2234
* plan->plan_rows is left as a copy of the input subplan's plan_rows;
2235
* ie, we assume the filter removes nothing. The caller must alter
2236
* this if he has a better idea.
2239
plan->targetlist = copyObject(lefttree->targetlist);
2241
plan->lefttree = lefttree;
2242
plan->righttree = NULL;
2245
* convert SortClause list into array of attr indexes, as wanted by
2248
Assert(numCols > 0);
2249
uniqColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numCols);
2251
foreach(slitem, distinctList)
2253
SortClause *sortcl = (SortClause *) lfirst(slitem);
2254
TargetEntry *tle = get_sortgroupclause_tle(sortcl, plan->targetlist);
2256
uniqColIdx[keyno++] = tle->resdom->resno;
2259
node->numCols = numCols;
2260
node->uniqColIdx = uniqColIdx;
2266
* distinctList is a list of SortClauses, identifying the targetlist items
2267
* that should be considered by the SetOp filter.
2271
make_setop(SetOpCmd cmd, Plan *lefttree,
2272
List *distinctList, AttrNumber flagColIdx)
2274
SetOp *node = makeNode(SetOp);
2275
Plan *plan = &node->plan;
2276
int numCols = list_length(distinctList);
2278
AttrNumber *dupColIdx;
2281
copy_plan_costsize(plan, lefttree);
2284
* Charge one cpu_operator_cost per comparison per input tuple. We
2285
* assume all columns get compared at most of the tuples.
2287
plan->total_cost += cpu_operator_cost * plan->plan_rows * numCols;
2290
* We make the unsupported assumption that there will be 10% as many
2291
* tuples out as in. Any way to do better?
2293
plan->plan_rows *= 0.1;
2294
if (plan->plan_rows < 1)
2295
plan->plan_rows = 1;
2297
plan->targetlist = copyObject(lefttree->targetlist);
2299
plan->lefttree = lefttree;
2300
plan->righttree = NULL;
2303
* convert SortClause list into array of attr indexes, as wanted by
2306
Assert(numCols > 0);
2307
dupColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numCols);
2309
foreach(slitem, distinctList)
2311
SortClause *sortcl = (SortClause *) lfirst(slitem);
2312
TargetEntry *tle = get_sortgroupclause_tle(sortcl, plan->targetlist);
2314
dupColIdx[keyno++] = tle->resdom->resno;
2318
node->numCols = numCols;
2319
node->dupColIdx = dupColIdx;
2320
node->flagColIdx = flagColIdx;
2326
make_limit(Plan *lefttree, Node *limitOffset, Node *limitCount)
2328
Limit *node = makeNode(Limit);
2329
Plan *plan = &node->plan;
2331
copy_plan_costsize(plan, lefttree);
2334
* If offset/count are constants, adjust the output rows count and
2335
* costs accordingly. This is only a cosmetic issue if we are at top
2336
* level, but if we are building a subquery then it's important to
2337
* report correct info to the outer planner.
2339
if (limitOffset && IsA(limitOffset, Const))
2341
Const *limito = (Const *) limitOffset;
2342
int32 offset = DatumGetInt32(limito->constvalue);
2344
if (!limito->constisnull && offset > 0)
2346
if (offset > plan->plan_rows)
2347
offset = (int32) plan->plan_rows;
2348
if (plan->plan_rows > 0)
2349
plan->startup_cost +=
2350
(plan->total_cost - plan->startup_cost)
2351
* ((double) offset) / plan->plan_rows;
2352
plan->plan_rows -= offset;
2353
if (plan->plan_rows < 1)
2354
plan->plan_rows = 1;
2357
if (limitCount && IsA(limitCount, Const))
2359
Const *limitc = (Const *) limitCount;
2360
int32 count = DatumGetInt32(limitc->constvalue);
2362
if (!limitc->constisnull && count >= 0)
2364
if (count > plan->plan_rows)
2365
count = (int32) plan->plan_rows;
2366
if (plan->plan_rows > 0)
2367
plan->total_cost = plan->startup_cost +
2368
(plan->total_cost - plan->startup_cost)
2369
* ((double) count) / plan->plan_rows;
2370
plan->plan_rows = count;
2371
if (plan->plan_rows < 1)
2372
plan->plan_rows = 1;
2376
plan->targetlist = copyObject(lefttree->targetlist);
2378
plan->lefttree = lefttree;
2379
plan->righttree = NULL;
2381
node->limitOffset = limitOffset;
2382
node->limitCount = limitCount;
2388
make_result(List *tlist,
2389
Node *resconstantqual,
2392
Result *node = makeNode(Result);
2393
Plan *plan = &node->plan;
2396
copy_plan_costsize(plan, subplan);
2399
plan->startup_cost = 0;
2400
plan->total_cost = cpu_tuple_cost;
2401
plan->plan_rows = 1; /* wrong if we have a set-valued function? */
2402
plan->plan_width = 0; /* XXX try to be smarter? */
2405
if (resconstantqual)
2409
cost_qual_eval(&qual_cost, (List *) resconstantqual);
2410
/* resconstantqual is evaluated once at startup */
2411
plan->startup_cost += qual_cost.startup + qual_cost.per_tuple;
2412
plan->total_cost += qual_cost.startup + qual_cost.per_tuple;
2415
plan->targetlist = tlist;
2417
plan->lefttree = subplan;
2418
plan->righttree = NULL;
2419
node->resconstantqual = resconstantqual;
2425
* is_projection_capable_plan
2426
* Check whether a given Plan node is able to do projection.
2429
is_projection_capable_plan(Plan *plan)
2431
/* Most plan types can project, so just list the ones that can't */
2432
switch (nodeTag(plan))