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-2003, 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.171 2004/05/30 23:40:28 neilc 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 FastListInit(&tlist);
269 foreach(v, FastListValue(&rel->reltargetlist))
271 /* Do we really need to copy here? Not sure */
272 Var *var = (Var *) copyObject(lfirst(v));
274 FastAppend(&tlist, create_tl_element(var, resdomno));
277 return FastListValue(&tlist);
282 * Decide whether to use a tlist matching relation structure,
283 * rather than only those Vars actually referenced.
286 use_physical_tlist(RelOptInfo *rel)
291 * Currently, can't do this for subquery or function scans. (This is
292 * mainly because we don't have an equivalent of build_physical_tlist
293 * for them; worth adding?)
295 if (rel->rtekind != RTE_RELATION)
299 * Can't do it with inheritance cases either (mainly because Append
302 if (rel->reloptkind != RELOPT_BASEREL)
306 * Can't do it if any system columns are requested, either. (This
307 * could possibly be fixed but would take some fragile assumptions in
308 * setrefs.c, I think.)
310 for (i = rel->min_attr; i <= 0; i++)
312 if (!bms_is_empty(rel->attr_needed[i - rel->min_attr]))
319 * disuse_physical_tlist
320 * Switch a plan node back to emitting only Vars actually referenced.
322 * If the plan node immediately above a scan would prefer to get only
323 * needed Vars and not a physical tlist, it must call this routine to
324 * undo the decision made by use_physical_tlist(). Currently, Hash, Sort,
325 * and Material nodes want this, so they don't have to store useless columns.
328 disuse_physical_tlist(Plan *plan, Path *path)
330 /* Only need to undo it for path types handled by create_scan_plan() */
331 switch (path->pathtype)
338 plan->targetlist = build_relation_tlist(path->parent);
347 * Create a join plan for 'best_path' and (recursively) plans for its
348 * inner and outer paths.
350 * Returns a Plan node.
353 create_join_plan(Query *root, JoinPath *best_path)
359 outer_plan = create_plan(root, best_path->outerjoinpath);
360 inner_plan = create_plan(root, best_path->innerjoinpath);
362 switch (best_path->path.pathtype)
365 plan = (Join *) create_mergejoin_plan(root,
366 (MergePath *) best_path,
371 plan = (Join *) create_hashjoin_plan(root,
372 (HashPath *) best_path,
377 plan = (Join *) create_nestloop_plan(root,
378 (NestPath *) best_path,
383 elog(ERROR, "unrecognized node type: %d",
384 (int) best_path->path.pathtype);
385 plan = NULL; /* keep compiler quiet */
392 * * Expensive function pullups may have pulled local predicates *
393 * into this path node. Put them in the qpqual of the plan node. *
396 if (get_loc_restrictinfo(best_path) != NIL)
397 set_qpqual((Plan) plan,
398 list_concat(get_qpqual((Plan) plan),
399 get_actual_clauses(get_loc_restrictinfo(best_path))));
407 * Create an Append plan for 'best_path' and (recursively) plans
410 * Returns a Plan node.
413 create_append_plan(Query *root, AppendPath *best_path)
416 List *tlist = build_relation_tlist(best_path->path.parent);
417 List *subplans = NIL;
420 foreach(subpaths, best_path->subpaths)
422 Path *subpath = (Path *) lfirst(subpaths);
424 subplans = lappend(subplans, create_plan(root, subpath));
427 plan = make_append(subplans, false, tlist);
434 * Create a Result plan for 'best_path' and (recursively) plans
437 * Returns a Plan node.
440 create_result_plan(Query *root, ResultPath *best_path)
447 if (best_path->path.parent)
448 tlist = build_relation_tlist(best_path->path.parent);
450 tlist = NIL; /* will be filled in later */
452 if (best_path->subpath)
453 subplan = create_plan(root, best_path->subpath);
457 constclauses = order_qual_clauses(root, best_path->constantqual);
459 plan = make_result(tlist, (Node *) constclauses, subplan);
465 * create_material_plan
466 * Create a Material plan for 'best_path' and (recursively) plans
469 * Returns a Plan node.
472 create_material_plan(Query *root, MaterialPath *best_path)
477 subplan = create_plan(root, best_path->subpath);
479 /* We don't want any excess columns in the materialized tuples */
480 disuse_physical_tlist(subplan, best_path->subpath);
482 plan = make_material(subplan);
484 copy_path_costsize(&plan->plan, (Path *) best_path);
491 * Create a Unique plan for 'best_path' and (recursively) plans
494 * Returns a Plan node.
497 create_unique_plan(Query *root, UniquePath *best_path)
503 AttrNumber *groupColIdx;
510 subplan = create_plan(root, best_path->subpath);
513 * As constructed, the subplan has a "flat" tlist containing just the
514 * Vars needed here and at upper levels. The values we are supposed
515 * to unique-ify may be expressions in these variables. We have to
516 * add any such expressions to the subplan's tlist. We then build
517 * control information showing which subplan output columns are to be
518 * examined by the grouping step. (Since we do not remove any
519 * existing subplan outputs, not all the output columns may be used
522 * Note: the reason we don't remove any subplan outputs is that there are
523 * scenarios where a Var is needed at higher levels even though it is
524 * not one of the nominal outputs of an IN clause. Consider WHERE x
525 * IN (SELECT y FROM t1,t2 WHERE y = z) Implied equality deduction
526 * will generate an "x = z" clause, which may get used instead of "x =
527 * y" in the upper join step. Therefore the sub-select had better
528 * deliver both y and z in its targetlist. It is sufficient to
529 * unique-ify on y, however.
531 * To find the correct list of values to unique-ify, we look in the
532 * information saved for IN expressions. If this code is ever used in
533 * other scenarios, some other way of finding what to unique-ify will
536 uniq_exprs = NIL; /* just to keep compiler quiet */
537 foreach(l, root->in_info_list)
539 InClauseInfo *ininfo = (InClauseInfo *) lfirst(l);
541 if (bms_equal(ininfo->righthand, best_path->path.parent->relids))
543 uniq_exprs = ininfo->sub_targetlist;
547 if (l == NULL) /* fell out of loop? */
548 elog(ERROR, "could not find UniquePath in in_info_list");
550 /* set up to record positions of unique columns */
551 numGroupCols = list_length(uniq_exprs);
552 groupColIdx = (AttrNumber *) palloc(numGroupCols * sizeof(AttrNumber));
554 /* not sure if tlist might be shared with other nodes, so copy */
555 newtlist = copyObject(subplan->targetlist);
556 nextresno = list_length(newtlist) + 1;
559 foreach(l, uniq_exprs)
561 Node *uniqexpr = lfirst(l);
564 tle = tlistentry_member(uniqexpr, newtlist);
567 tle = makeTargetEntry(makeResdom(nextresno,
569 exprTypmod(uniqexpr),
573 newtlist = lappend(newtlist, tle);
577 groupColIdx[groupColPos++] = tle->resdom->resno;
583 * If the top plan node can't do projections, we need to add a
584 * Result node to help it along.
586 if (!is_projection_capable_plan(subplan))
587 subplan = (Plan *) make_result(newtlist, NULL, subplan);
589 subplan->targetlist = newtlist;
592 /* Done if we don't need to do any actual unique-ifying */
593 if (best_path->umethod == UNIQUE_PATH_NOOP)
596 if (best_path->umethod == UNIQUE_PATH_HASH)
600 numGroups = (long) Min(best_path->rows, (double) LONG_MAX);
602 plan = (Plan *) make_agg(root,
603 copyObject(subplan->targetlist),
614 List *sortList = NIL;
616 for (groupColPos = 0; groupColPos < numGroupCols; groupColPos++)
620 tle = get_tle_by_resno(subplan->targetlist,
621 groupColIdx[groupColPos]);
623 sortList = addTargetToSortList(NULL, tle,
624 sortList, subplan->targetlist,
625 SORTBY_ASC, NIL, false);
627 plan = (Plan *) make_sort_from_sortclauses(root, sortList, subplan);
628 plan = (Plan *) make_unique(plan, sortList);
631 /* Adjust output size estimate (other fields should be OK already) */
632 plan->plan_rows = best_path->rows;
638 /*****************************************************************************
640 * BASE-RELATION SCAN METHODS
642 *****************************************************************************/
646 * create_seqscan_plan
647 * Returns a seqscan plan for the base relation scanned by 'best_path'
648 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
651 create_seqscan_plan(Query *root, Path *best_path,
652 List *tlist, List *scan_clauses)
655 Index scan_relid = best_path->parent->relid;
657 /* it should be a base rel... */
658 Assert(scan_relid > 0);
659 Assert(best_path->parent->rtekind == RTE_RELATION);
661 /* Reduce RestrictInfo list to bare expressions */
662 scan_clauses = get_actual_clauses(scan_clauses);
664 /* Sort clauses into best execution order */
665 scan_clauses = order_qual_clauses(root, scan_clauses);
667 scan_plan = make_seqscan(tlist,
671 copy_path_costsize(&scan_plan->plan, best_path);
677 * create_indexscan_plan
678 * Returns a indexscan plan for the base relation scanned by 'best_path'
679 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
681 * The indexquals list of the path contains a sublist of implicitly-ANDed
682 * qual conditions for each scan of the index(es); if there is more than one
683 * scan then the retrieved tuple sets are ORed together. The indexquals
684 * and indexinfo lists must have the same length, ie, the number of scans
685 * that will occur. Note it is possible for a qual condition sublist
686 * to be empty --- then no index restrictions will be applied during that
690 create_indexscan_plan(Query *root,
691 IndexPath *best_path,
695 List *indxquals = best_path->indexquals;
696 Index baserelid = best_path->path.parent->relid;
698 Expr *indxqual_or_expr = NULL;
699 List *stripped_indxquals;
700 List *fixed_indxquals;
706 IndexScan *scan_plan;
708 /* it should be a base rel... */
709 Assert(baserelid > 0);
710 Assert(best_path->path.parent->rtekind == RTE_RELATION);
713 * If this is a innerjoin scan, the indexclauses will contain join
714 * clauses that are not present in scan_clauses (since the passed-in
715 * value is just the rel's baserestrictinfo list). We must add these
716 * clauses to scan_clauses to ensure they get checked. In most cases
717 * we will remove the join clauses again below, but if a join clause
718 * contains a special operator, we need to make sure it gets into the
721 if (best_path->isjoininner)
724 * We don't currently support OR indexscans in joins, so we only
725 * need to worry about the plain AND case. Also, pointer comparison
726 * should be enough to determine RestrictInfo matches.
728 Assert(list_length(best_path->indexclauses) == 1);
729 scan_clauses = list_union_ptr(scan_clauses,
730 (List *) linitial(best_path->indexclauses));
733 /* Reduce RestrictInfo list to bare expressions */
734 scan_clauses = get_actual_clauses(scan_clauses);
736 /* Sort clauses into best execution order */
737 scan_clauses = order_qual_clauses(root, scan_clauses);
739 /* Build list of index OIDs */
740 FastListInit(&indexids);
741 foreach(l, best_path->indexinfo)
743 IndexOptInfo *index = (IndexOptInfo *) lfirst(l);
745 FastAppendo(&indexids, index->indexoid);
749 * Build "stripped" indexquals structure (no RestrictInfos) to pass to
750 * executor as indxqualorig
752 stripped_indxquals = NIL;
753 foreach(l, indxquals)
755 List *andlist = (List *) lfirst(l);
757 stripped_indxquals = lappend(stripped_indxquals,
758 get_actual_clauses(andlist));
762 * The qpqual list must contain all restrictions not automatically
763 * handled by the index. All the predicates in the indexquals will
764 * be checked (either by the index itself, or by nodeIndexscan.c), but
765 * if there are any "special" operators involved then they must be
766 * added to qpqual. The upshot is that qpquals must contain scan_clauses
767 * minus whatever appears in indxquals.
769 if (list_length(indxquals) > 1)
772 * Build an expression representation of the indexqual, expanding
773 * the implicit OR and AND semantics of the first- and
774 * second-level lists. (The odds that this will exactly match any
775 * scan_clause are not great; perhaps we need more smarts here.)
777 indxqual_or_expr = make_expr_from_indexclauses(indxquals);
778 qpqual = list_difference(scan_clauses, list_make1(indxqual_or_expr));
783 * Here, we can simply treat the first sublist as an independent
784 * set of qual expressions, since there is no top-level OR
787 Assert(stripped_indxquals != NIL);
788 qpqual = list_difference(scan_clauses, linitial(stripped_indxquals));
792 * The executor needs a copy with the indexkey on the left of each
793 * clause and with index attr numbers substituted for table ones. This
794 * pass also gets strategy info and looks for "lossy" operators.
796 fix_indxqual_references(indxquals, best_path,
798 &indxstrategy, &indxsubtype, &indxlossy);
800 /* Finally ready to build the plan node */
801 scan_plan = make_indexscan(tlist,
804 FastListValue(&indexids),
810 best_path->indexscandir);
812 copy_path_costsize(&scan_plan->scan.plan, &best_path->path);
813 /* use the indexscan-specific rows estimate, not the parent rel's */
814 scan_plan->scan.plan.plan_rows = best_path->rows;
820 * create_tidscan_plan
821 * Returns a tidscan plan for the base relation scanned by 'best_path'
822 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
825 create_tidscan_plan(Query *root, TidPath *best_path,
826 List *tlist, List *scan_clauses)
829 Index scan_relid = best_path->path.parent->relid;
831 /* it should be a base rel... */
832 Assert(scan_relid > 0);
833 Assert(best_path->path.parent->rtekind == RTE_RELATION);
835 /* Reduce RestrictInfo list to bare expressions */
836 scan_clauses = get_actual_clauses(scan_clauses);
838 /* Sort clauses into best execution order */
839 scan_clauses = order_qual_clauses(root, scan_clauses);
841 scan_plan = make_tidscan(tlist,
846 copy_path_costsize(&scan_plan->scan.plan, &best_path->path);
852 * create_subqueryscan_plan
853 * Returns a subqueryscan plan for the base relation scanned by 'best_path'
854 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
856 static SubqueryScan *
857 create_subqueryscan_plan(Query *root, Path *best_path,
858 List *tlist, List *scan_clauses)
860 SubqueryScan *scan_plan;
861 Index scan_relid = best_path->parent->relid;
863 /* it should be a subquery base rel... */
864 Assert(scan_relid > 0);
865 Assert(best_path->parent->rtekind == RTE_SUBQUERY);
867 /* Reduce RestrictInfo list to bare expressions */
868 scan_clauses = get_actual_clauses(scan_clauses);
870 /* Sort clauses into best execution order */
871 scan_clauses = order_qual_clauses(root, scan_clauses);
873 scan_plan = make_subqueryscan(tlist,
876 best_path->parent->subplan);
878 copy_path_costsize(&scan_plan->scan.plan, best_path);
884 * create_functionscan_plan
885 * Returns a functionscan plan for the base relation scanned by 'best_path'
886 * with restriction clauses 'scan_clauses' and targetlist 'tlist'.
888 static FunctionScan *
889 create_functionscan_plan(Query *root, Path *best_path,
890 List *tlist, List *scan_clauses)
892 FunctionScan *scan_plan;
893 Index scan_relid = best_path->parent->relid;
895 /* it should be a function base rel... */
896 Assert(scan_relid > 0);
897 Assert(best_path->parent->rtekind == RTE_FUNCTION);
899 /* Reduce RestrictInfo list to bare expressions */
900 scan_clauses = get_actual_clauses(scan_clauses);
902 /* Sort clauses into best execution order */
903 scan_clauses = order_qual_clauses(root, scan_clauses);
905 scan_plan = make_functionscan(tlist, scan_clauses, scan_relid);
907 copy_path_costsize(&scan_plan->scan.plan, best_path);
912 /*****************************************************************************
916 *****************************************************************************/
919 create_nestloop_plan(Query *root,
924 List *tlist = build_relation_tlist(best_path->path.parent);
925 List *joinrestrictclauses = best_path->joinrestrictinfo;
930 if (IsA(best_path->innerjoinpath, IndexPath))
933 * An index is being used to reduce the number of tuples scanned
934 * in the inner relation. If there are join clauses being used
935 * with the index, we may remove those join clauses from the list
936 * of clauses that have to be checked as qpquals at the join node
937 * --- but only if there's just one indexscan in the inner path
938 * (otherwise, several different sets of clauses are being ORed
941 * We can also remove any join clauses that are redundant with those
942 * being used in the index scan; prior redundancy checks will not
943 * have caught this case because the join clauses would never have
944 * been put in the same joininfo list.
946 * We can skip this if the index path is an ordinary indexpath and
947 * not a special innerjoin path.
949 IndexPath *innerpath = (IndexPath *) best_path->innerjoinpath;
950 List *indexclauses = innerpath->indexclauses;
952 if (innerpath->isjoininner &&
953 list_length(indexclauses) == 1) /* single indexscan? */
955 joinrestrictclauses =
956 select_nonredundant_join_clauses(root,
958 linitial(indexclauses),
959 best_path->jointype);
963 /* Get the join qual clauses (in plain expression form) */
964 if (IS_OUTER_JOIN(best_path->jointype))
966 get_actual_join_clauses(joinrestrictclauses,
967 &joinclauses, &otherclauses);
971 /* We can treat all clauses alike for an inner join */
972 joinclauses = get_actual_clauses(joinrestrictclauses);
976 /* Sort clauses into best execution order */
977 joinclauses = order_qual_clauses(root, joinclauses);
978 otherclauses = order_qual_clauses(root, otherclauses);
980 join_plan = make_nestloop(tlist,
985 best_path->jointype);
987 copy_path_costsize(&join_plan->join.plan, &best_path->path);
993 create_mergejoin_plan(Query *root,
994 MergePath *best_path,
998 List *tlist = build_relation_tlist(best_path->jpath.path.parent);
1002 MergeJoin *join_plan;
1004 /* Get the join qual clauses (in plain expression form) */
1005 if (IS_OUTER_JOIN(best_path->jpath.jointype))
1007 get_actual_join_clauses(best_path->jpath.joinrestrictinfo,
1008 &joinclauses, &otherclauses);
1012 /* We can treat all clauses alike for an inner join */
1013 joinclauses = get_actual_clauses(best_path->jpath.joinrestrictinfo);
1018 * Remove the mergeclauses from the list of join qual clauses, leaving
1019 * the list of quals that must be checked as qpquals.
1021 mergeclauses = get_actual_clauses(best_path->path_mergeclauses);
1022 joinclauses = list_difference(joinclauses, mergeclauses);
1025 * Rearrange mergeclauses, if needed, so that the outer variable is
1026 * always on the left.
1028 mergeclauses = get_switched_clauses(best_path->path_mergeclauses,
1029 best_path->jpath.outerjoinpath->parent->relids);
1031 /* Sort clauses into best execution order */
1032 /* NB: do NOT reorder the mergeclauses */
1033 joinclauses = order_qual_clauses(root, joinclauses);
1034 otherclauses = order_qual_clauses(root, otherclauses);
1037 * Create explicit sort nodes for the outer and inner join paths if
1038 * necessary. The sort cost was already accounted for in the path.
1039 * Make sure there are no excess columns in the inputs if sorting.
1041 if (best_path->outersortkeys)
1043 disuse_physical_tlist(outer_plan, best_path->jpath.outerjoinpath);
1044 outer_plan = (Plan *)
1045 make_sort_from_pathkeys(root,
1047 best_path->outersortkeys);
1050 if (best_path->innersortkeys)
1052 disuse_physical_tlist(inner_plan, best_path->jpath.innerjoinpath);
1053 inner_plan = (Plan *)
1054 make_sort_from_pathkeys(root,
1056 best_path->innersortkeys);
1060 * Now we can build the mergejoin node.
1062 join_plan = make_mergejoin(tlist,
1068 best_path->jpath.jointype);
1070 copy_path_costsize(&join_plan->join.plan, &best_path->jpath.path);
1076 create_hashjoin_plan(Query *root,
1077 HashPath *best_path,
1081 List *tlist = build_relation_tlist(best_path->jpath.path.parent);
1085 HashJoin *join_plan;
1088 /* Get the join qual clauses (in plain expression form) */
1089 if (IS_OUTER_JOIN(best_path->jpath.jointype))
1091 get_actual_join_clauses(best_path->jpath.joinrestrictinfo,
1092 &joinclauses, &otherclauses);
1096 /* We can treat all clauses alike for an inner join */
1097 joinclauses = get_actual_clauses(best_path->jpath.joinrestrictinfo);
1102 * Remove the hashclauses from the list of join qual clauses, leaving
1103 * the list of quals that must be checked as qpquals.
1105 hashclauses = get_actual_clauses(best_path->path_hashclauses);
1106 joinclauses = list_difference(joinclauses, hashclauses);
1109 * Rearrange hashclauses, if needed, so that the outer variable is
1110 * always on the left.
1112 hashclauses = get_switched_clauses(best_path->path_hashclauses,
1113 best_path->jpath.outerjoinpath->parent->relids);
1115 /* Sort clauses into best execution order */
1116 joinclauses = order_qual_clauses(root, joinclauses);
1117 otherclauses = order_qual_clauses(root, otherclauses);
1118 hashclauses = order_qual_clauses(root, hashclauses);
1120 /* We don't want any excess columns in the hashed tuples */
1121 disuse_physical_tlist(inner_plan, best_path->jpath.innerjoinpath);
1124 * Build the hash node and hash join node.
1126 hash_plan = make_hash(inner_plan);
1127 join_plan = make_hashjoin(tlist,
1133 best_path->jpath.jointype);
1135 copy_path_costsize(&join_plan->join.plan, &best_path->jpath.path);
1141 /*****************************************************************************
1143 * SUPPORTING ROUTINES
1145 *****************************************************************************/
1148 * fix_indxqual_references
1149 * Adjust indexqual clauses to the form the executor's indexqual
1150 * machinery needs, and check for recheckable (lossy) index conditions.
1152 * We have four tasks here:
1153 * * Remove RestrictInfo nodes from the input clauses.
1154 * * Index keys must be represented by Var nodes with varattno set to the
1155 * index's attribute number, not the attribute number in the original rel.
1156 * * If the index key is on the right, commute the clause to put it on the
1157 * left. (Someday the executor might not need this, but for now it does.)
1158 * * We must construct lists of operator strategy numbers, subtypes, and
1159 * recheck (lossy-operator) flags for the top-level operators of each
1162 * Both the input list and the "fixed" output list have the form of lists of
1163 * sublists of qual clauses --- the top-level list has one entry for each
1164 * indexscan to be performed. The semantics are OR-of-ANDs. Note however
1165 * that the input list contains RestrictInfos, while the output list doesn't.
1167 * fixed_indexquals receives a modified copy of the indexqual list --- the
1168 * original is not changed. Note also that the copy shares no substructure
1169 * with the original; this is needed in case there is a subplan in it (we need
1170 * two separate copies of the subplan tree, or things will go awry).
1172 * indxstrategy receives a list of integer sublists of strategy numbers.
1173 * indxsubtype receives a list of OID sublists of strategy subtypes.
1174 * indxlossy receives a list of integer sublists of lossy-operator booleans.
1177 fix_indxqual_references(List *indexquals, IndexPath *index_path,
1178 List **fixed_indexquals,
1179 List **indxstrategy,
1183 Relids baserelids = index_path->path.parent->relids;
1184 int baserelid = index_path->path.parent->relid;
1185 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 to
1284 * get its strategy numbers and the recheck indicator. This also
1285 * double-checks that we found an operator matching the index.
1287 get_op_opclass_properties(newclause->opno, opclass,
1288 &stratno, &stratsubtype, &recheck);
1290 *strategy = lappend_int(*strategy, stratno);
1291 *subtype = lappend_oid(*subtype, stratsubtype);
1292 *lossy = lappend_int(*lossy, (int) recheck);
1297 fix_indxqual_operand(Node *node, int baserelid, IndexOptInfo *index,
1301 * We represent index keys by Var nodes having the varno of the base
1302 * table but varattno equal to the index's attribute number (index
1303 * column position). This is a bit hokey ... would be cleaner to use
1304 * a special-purpose node type that could not be mistaken for a
1305 * regular Var. But it will do for now.
1309 ListCell *indexpr_item;
1312 * Remove any binary-compatible relabeling of the indexkey
1314 if (IsA(node, RelabelType))
1315 node = (Node *) ((RelabelType *) node)->arg;
1317 if (IsA(node, Var) &&
1318 ((Var *) node)->varno == baserelid)
1320 /* Try to match against simple index columns */
1321 int varatt = ((Var *) node)->varattno;
1325 for (pos = 0; pos < index->ncolumns; pos++)
1327 if (index->indexkeys[pos] == varatt)
1329 result = (Var *) copyObject(node);
1330 result->varattno = pos + 1;
1331 /* return the correct opclass, too */
1332 *opclass = index->classlist[pos];
1333 return (Node *) result;
1339 /* Try to match against index expressions */
1340 indexpr_item = list_head(index->indexprs);
1341 for (pos = 0; pos < index->ncolumns; pos++)
1343 if (index->indexkeys[pos] == 0)
1347 if (indexpr_item == NULL)
1348 elog(ERROR, "too few entries in indexprs list");
1349 indexkey = (Node *) lfirst(indexpr_item);
1350 if (indexkey && IsA(indexkey, RelabelType))
1351 indexkey = (Node *) ((RelabelType *) indexkey)->arg;
1352 if (equal(node, indexkey))
1355 result = makeVar(baserelid, pos + 1,
1356 exprType(lfirst(indexpr_item)), -1,
1358 /* return the correct opclass, too */
1359 *opclass = index->classlist[pos];
1360 return (Node *) result;
1362 indexpr_item = lnext(indexpr_item);
1367 elog(ERROR, "node is not an index attribute");
1368 return NULL; /* keep compiler quiet */
1372 * get_switched_clauses
1373 * Given a list of merge or hash joinclauses (as RestrictInfo nodes),
1374 * extract the bare clauses, and rearrange the elements within the
1375 * clauses, if needed, so the outer join variable is on the left and
1376 * the inner is on the right. The original data structure is not touched;
1377 * a modified list is returned.
1380 get_switched_clauses(List *clauses, Relids outerrelids)
1387 RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(l);
1388 OpExpr *clause = (OpExpr *) restrictinfo->clause;
1390 Assert(is_opclause(clause));
1391 if (bms_is_subset(restrictinfo->right_relids, outerrelids))
1394 * Duplicate just enough of the structure to allow commuting
1395 * the clause without changing the original list. Could use
1396 * copyObject, but a complete deep copy is overkill.
1398 OpExpr *temp = makeNode(OpExpr);
1400 temp->opno = clause->opno;
1401 temp->opfuncid = InvalidOid;
1402 temp->opresulttype = clause->opresulttype;
1403 temp->opretset = clause->opretset;
1404 temp->args = list_copy(clause->args);
1405 /* Commute it --- note this modifies the temp node in-place. */
1406 CommuteClause(temp);
1407 t_list = lappend(t_list, temp);
1410 t_list = lappend(t_list, clause);
1416 * order_qual_clauses
1417 * Given a list of qual clauses that will all be evaluated at the same
1418 * plan node, sort the list into the order we want to check the quals
1421 * Ideally the order should be driven by a combination of execution cost and
1422 * selectivity, but unfortunately we have so little information about
1423 * execution cost of operators that it's really hard to do anything smart.
1424 * For now, we just move any quals that contain SubPlan references (but not
1425 * InitPlan references) to the end of the list.
1428 order_qual_clauses(Query *root, List *clauses)
1430 FastList nosubplans;
1431 FastList withsubplans;
1434 /* No need to work hard if the query is subselect-free */
1435 if (!root->hasSubLinks)
1438 FastListInit(&nosubplans);
1439 FastListInit(&withsubplans);
1442 Node *clause = (Node *) lfirst(l);
1444 if (contain_subplans(clause))
1445 FastAppend(&withsubplans, clause);
1447 FastAppend(&nosubplans, clause);
1450 FastConcFast(&nosubplans, &withsubplans);
1451 return FastListValue(&nosubplans);
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;
1842 /* We will need at most list_length(pathkeys) sort columns; possibly less */
1843 numsortkeys = list_length(pathkeys);
1844 sortColIdx = (AttrNumber *) palloc(numsortkeys * sizeof(AttrNumber));
1845 sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));
1849 foreach(i, pathkeys)
1851 List *keysublist = (List *) lfirst(i);
1852 PathKeyItem *pathkey = NULL;
1853 Resdom *resdom = NULL;
1857 * We can sort by any one of the sort key items listed in this
1858 * sublist. For now, we take the first one that corresponds to an
1859 * available Var in the tlist. If there isn't any, use the first
1860 * one that is an expression in the input's vars.
1862 * XXX if we have a choice, is there any way of figuring out which
1863 * might be cheapest to execute? (For example, int4lt is likely
1864 * much cheaper to execute than numericlt, but both might appear
1865 * in the same pathkey sublist...) Not clear that we ever will
1866 * have a choice in practice, so it may not matter.
1868 foreach(j, keysublist)
1870 pathkey = (PathKeyItem *) lfirst(j);
1871 Assert(IsA(pathkey, PathKeyItem));
1872 resdom = tlist_member(pathkey->key, tlist);
1878 /* No matching Var; look for a computable expression */
1879 foreach(j, keysublist)
1884 pathkey = (PathKeyItem *) lfirst(j);
1885 exprvars = pull_var_clause(pathkey->key, false);
1886 foreach(k, exprvars)
1888 if (!tlist_member(lfirst(k), tlist))
1891 list_free(exprvars);
1893 break; /* found usable expression */
1896 elog(ERROR, "could not find pathkey item to sort");
1899 * Do we need to insert a Result node?
1901 if (!is_projection_capable_plan(lefttree))
1903 tlist = copyObject(tlist);
1904 lefttree = (Plan *) make_result(tlist, NULL, lefttree);
1908 * Add resjunk entry to input's tlist
1910 resdom = makeResdom(list_length(tlist) + 1,
1911 exprType(pathkey->key),
1912 exprTypmod(pathkey->key),
1915 tlist = lappend(tlist,
1916 makeTargetEntry(resdom,
1917 (Expr *) pathkey->key));
1918 lefttree->targetlist = tlist; /* just in case NIL before */
1922 * The column might already be selected as a sort key, if the
1923 * pathkeys contain duplicate entries. (This can happen in
1924 * scenarios where multiple mergejoinable clauses mention the same
1925 * var, for example.) So enter it only once in the sort arrays.
1927 numsortkeys = add_sort_column(resdom->resno, pathkey->sortop,
1928 numsortkeys, sortColIdx, sortOperators);
1931 Assert(numsortkeys > 0);
1933 return make_sort(root, lefttree, numsortkeys,
1934 sortColIdx, sortOperators);
1938 * make_sort_from_sortclauses
1939 * Create sort plan to sort according to given sortclauses
1941 * 'sortcls' is a list of SortClauses
1942 * 'lefttree' is the node which yields input tuples
1945 make_sort_from_sortclauses(Query *root, List *sortcls, Plan *lefttree)
1947 List *sub_tlist = lefttree->targetlist;
1950 AttrNumber *sortColIdx;
1953 /* We will need at most list_length(sortcls) sort columns; possibly less */
1954 numsortkeys = list_length(sortcls);
1955 sortColIdx = (AttrNumber *) palloc(numsortkeys * sizeof(AttrNumber));
1956 sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));
1962 SortClause *sortcl = (SortClause *) lfirst(l);
1963 TargetEntry *tle = get_sortgroupclause_tle(sortcl, sub_tlist);
1966 * Check for the possibility of duplicate order-by clauses --- the
1967 * parser should have removed 'em, but no point in sorting
1970 numsortkeys = add_sort_column(tle->resdom->resno, sortcl->sortop,
1971 numsortkeys, sortColIdx, sortOperators);
1974 Assert(numsortkeys > 0);
1976 return make_sort(root, lefttree, numsortkeys,
1977 sortColIdx, sortOperators);
1981 * make_sort_from_groupcols
1982 * Create sort plan to sort based on grouping columns
1984 * 'groupcls' is the list of GroupClauses
1985 * 'grpColIdx' gives the column numbers to use
1987 * This might look like it could be merged with make_sort_from_sortclauses,
1988 * but presently we *must* use the grpColIdx[] array to locate sort columns,
1989 * because the child plan's tlist is not marked with ressortgroupref info
1990 * appropriate to the grouping node. So, only the sortop is used from the
1991 * GroupClause entries.
1994 make_sort_from_groupcols(Query *root,
1996 AttrNumber *grpColIdx,
1999 List *sub_tlist = lefttree->targetlist;
2003 AttrNumber *sortColIdx;
2006 /* We will need at most list_length(groupcls) sort columns; possibly less */
2007 numsortkeys = list_length(groupcls);
2008 sortColIdx = (AttrNumber *) palloc(numsortkeys * sizeof(AttrNumber));
2009 sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));
2013 foreach(l, groupcls)
2015 GroupClause *grpcl = (GroupClause *) lfirst(l);
2016 TargetEntry *tle = get_tle_by_resno(sub_tlist, grpColIdx[grpno]);
2019 * Check for the possibility of duplicate group-by clauses --- the
2020 * parser should have removed 'em, but no point in sorting
2023 numsortkeys = add_sort_column(tle->resdom->resno, grpcl->sortop,
2024 numsortkeys, sortColIdx, sortOperators);
2028 Assert(numsortkeys > 0);
2030 return make_sort(root, lefttree, numsortkeys,
2031 sortColIdx, sortOperators);
2035 make_material(Plan *lefttree)
2037 Material *node = makeNode(Material);
2038 Plan *plan = &node->plan;
2040 /* cost should be inserted by caller */
2041 plan->targetlist = copyObject(lefttree->targetlist);
2043 plan->lefttree = lefttree;
2044 plan->righttree = NULL;
2050 * materialize_finished_plan: stick a Material node atop a completed plan
2052 * There are a couple of places where we want to attach a Material node
2053 * after completion of subquery_planner(). This currently requires hackery.
2054 * Since subquery_planner has already run SS_finalize_plan on the subplan
2055 * tree, we have to kluge up parameter lists for the Material node.
2056 * Possibly this could be fixed by postponing SS_finalize_plan processing
2057 * until setrefs.c is run?
2060 materialize_finished_plan(Plan *subplan)
2063 Path matpath; /* dummy for result of cost_material */
2065 matplan = (Plan *) make_material(subplan);
2068 cost_material(&matpath,
2069 subplan->total_cost,
2071 subplan->plan_width);
2072 matplan->startup_cost = matpath.startup_cost;
2073 matplan->total_cost = matpath.total_cost;
2074 matplan->plan_rows = subplan->plan_rows;
2075 matplan->plan_width = subplan->plan_width;
2077 /* parameter kluge --- see comments above */
2078 matplan->extParam = bms_copy(subplan->extParam);
2079 matplan->allParam = bms_copy(subplan->allParam);
2085 make_agg(Query *root, List *tlist, List *qual,
2086 AggStrategy aggstrategy,
2087 int numGroupCols, AttrNumber *grpColIdx,
2088 long numGroups, int numAggs,
2091 Agg *node = makeNode(Agg);
2092 Plan *plan = &node->plan;
2093 Path agg_path; /* dummy for result of cost_agg */
2096 node->aggstrategy = aggstrategy;
2097 node->numCols = numGroupCols;
2098 node->grpColIdx = grpColIdx;
2099 node->numGroups = numGroups;
2101 copy_plan_costsize(plan, lefttree); /* only care about copying size */
2102 cost_agg(&agg_path, root,
2103 aggstrategy, numAggs,
2104 numGroupCols, numGroups,
2105 lefttree->startup_cost,
2106 lefttree->total_cost,
2107 lefttree->plan_rows);
2108 plan->startup_cost = agg_path.startup_cost;
2109 plan->total_cost = agg_path.total_cost;
2112 * We will produce a single output tuple if not grouping, and a tuple
2113 * per group otherwise.
2115 if (aggstrategy == AGG_PLAIN)
2116 plan->plan_rows = 1;
2118 plan->plan_rows = numGroups;
2121 * We also need to account for the cost of evaluation of the qual (ie,
2122 * the HAVING clause) and the tlist. Note that cost_qual_eval doesn't
2123 * charge anything for Aggref nodes; this is okay since they are
2124 * really comparable to Vars.
2126 * See notes in grouping_planner about why this routine and make_group
2127 * are the only ones in this file that worry about tlist eval cost.
2131 cost_qual_eval(&qual_cost, qual);
2132 plan->startup_cost += qual_cost.startup;
2133 plan->total_cost += qual_cost.startup;
2134 plan->total_cost += qual_cost.per_tuple * plan->plan_rows;
2136 cost_qual_eval(&qual_cost, tlist);
2137 plan->startup_cost += qual_cost.startup;
2138 plan->total_cost += qual_cost.startup;
2139 plan->total_cost += qual_cost.per_tuple * plan->plan_rows;
2142 plan->targetlist = tlist;
2143 plan->lefttree = lefttree;
2144 plan->righttree = NULL;
2150 make_group(Query *root,
2153 AttrNumber *grpColIdx,
2157 Group *node = makeNode(Group);
2158 Plan *plan = &node->plan;
2159 Path group_path; /* dummy for result of cost_group */
2162 node->numCols = numGroupCols;
2163 node->grpColIdx = grpColIdx;
2165 copy_plan_costsize(plan, lefttree); /* only care about copying size */
2166 cost_group(&group_path, root,
2167 numGroupCols, numGroups,
2168 lefttree->startup_cost,
2169 lefttree->total_cost,
2170 lefttree->plan_rows);
2171 plan->startup_cost = group_path.startup_cost;
2172 plan->total_cost = group_path.total_cost;
2174 /* One output tuple per estimated result group */
2175 plan->plan_rows = numGroups;
2178 * We also need to account for the cost of evaluation of the tlist.
2180 * XXX this double-counts the cost of evaluation of any expressions used
2181 * for grouping, since in reality those will have been evaluated at a
2182 * lower plan level and will only be copied by the Group node. Worth
2185 * See notes in grouping_planner about why this routine and make_agg are
2186 * the only ones in this file that worry about tlist eval cost.
2188 cost_qual_eval(&qual_cost, tlist);
2189 plan->startup_cost += qual_cost.startup;
2190 plan->total_cost += qual_cost.startup;
2191 plan->total_cost += qual_cost.per_tuple * plan->plan_rows;
2194 plan->targetlist = tlist;
2195 plan->lefttree = lefttree;
2196 plan->righttree = NULL;
2202 * distinctList is a list of SortClauses, identifying the targetlist items
2203 * that should be considered by the Unique filter.
2206 make_unique(Plan *lefttree, List *distinctList)
2208 Unique *node = makeNode(Unique);
2209 Plan *plan = &node->plan;
2210 int numCols = list_length(distinctList);
2212 AttrNumber *uniqColIdx;
2215 copy_plan_costsize(plan, lefttree);
2218 * Charge one cpu_operator_cost per comparison per input tuple. We
2219 * assume all columns get compared at most of the tuples. (XXX
2220 * probably this is an overestimate.)
2222 plan->total_cost += cpu_operator_cost * plan->plan_rows * numCols;
2225 * plan->plan_rows is left as a copy of the input subplan's plan_rows;
2226 * ie, we assume the filter removes nothing. The caller must alter
2227 * this if he has a better idea.
2230 plan->targetlist = copyObject(lefttree->targetlist);
2232 plan->lefttree = lefttree;
2233 plan->righttree = NULL;
2236 * convert SortClause list into array of attr indexes, as wanted by
2239 Assert(numCols > 0);
2240 uniqColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numCols);
2242 foreach(slitem, distinctList)
2244 SortClause *sortcl = (SortClause *) lfirst(slitem);
2245 TargetEntry *tle = get_sortgroupclause_tle(sortcl, plan->targetlist);
2247 uniqColIdx[keyno++] = tle->resdom->resno;
2250 node->numCols = numCols;
2251 node->uniqColIdx = uniqColIdx;
2257 * distinctList is a list of SortClauses, identifying the targetlist items
2258 * that should be considered by the SetOp filter.
2262 make_setop(SetOpCmd cmd, Plan *lefttree,
2263 List *distinctList, AttrNumber flagColIdx)
2265 SetOp *node = makeNode(SetOp);
2266 Plan *plan = &node->plan;
2267 int numCols = list_length(distinctList);
2269 AttrNumber *dupColIdx;
2272 copy_plan_costsize(plan, lefttree);
2275 * Charge one cpu_operator_cost per comparison per input tuple. We
2276 * assume all columns get compared at most of the tuples.
2278 plan->total_cost += cpu_operator_cost * plan->plan_rows * numCols;
2281 * We make the unsupported assumption that there will be 10% as many
2282 * tuples out as in. Any way to do better?
2284 plan->plan_rows *= 0.1;
2285 if (plan->plan_rows < 1)
2286 plan->plan_rows = 1;
2288 plan->targetlist = copyObject(lefttree->targetlist);
2290 plan->lefttree = lefttree;
2291 plan->righttree = NULL;
2294 * convert SortClause list into array of attr indexes, as wanted by
2297 Assert(numCols > 0);
2298 dupColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numCols);
2300 foreach(slitem, distinctList)
2302 SortClause *sortcl = (SortClause *) lfirst(slitem);
2303 TargetEntry *tle = get_sortgroupclause_tle(sortcl, plan->targetlist);
2305 dupColIdx[keyno++] = tle->resdom->resno;
2309 node->numCols = numCols;
2310 node->dupColIdx = dupColIdx;
2311 node->flagColIdx = flagColIdx;
2317 make_limit(Plan *lefttree, Node *limitOffset, Node *limitCount)
2319 Limit *node = makeNode(Limit);
2320 Plan *plan = &node->plan;
2322 copy_plan_costsize(plan, lefttree);
2325 * If offset/count are constants, adjust the output rows count and
2326 * costs accordingly. This is only a cosmetic issue if we are at top
2327 * level, but if we are building a subquery then it's important to
2328 * report correct info to the outer planner.
2330 if (limitOffset && IsA(limitOffset, Const))
2332 Const *limito = (Const *) limitOffset;
2333 int32 offset = DatumGetInt32(limito->constvalue);
2335 if (!limito->constisnull && offset > 0)
2337 if (offset > plan->plan_rows)
2338 offset = (int32) plan->plan_rows;
2339 if (plan->plan_rows > 0)
2340 plan->startup_cost +=
2341 (plan->total_cost - plan->startup_cost)
2342 * ((double) offset) / plan->plan_rows;
2343 plan->plan_rows -= offset;
2344 if (plan->plan_rows < 1)
2345 plan->plan_rows = 1;
2348 if (limitCount && IsA(limitCount, Const))
2350 Const *limitc = (Const *) limitCount;
2351 int32 count = DatumGetInt32(limitc->constvalue);
2353 if (!limitc->constisnull && count >= 0)
2355 if (count > plan->plan_rows)
2356 count = (int32) plan->plan_rows;
2357 if (plan->plan_rows > 0)
2358 plan->total_cost = plan->startup_cost +
2359 (plan->total_cost - plan->startup_cost)
2360 * ((double) count) / plan->plan_rows;
2361 plan->plan_rows = count;
2362 if (plan->plan_rows < 1)
2363 plan->plan_rows = 1;
2367 plan->targetlist = copyObject(lefttree->targetlist);
2369 plan->lefttree = lefttree;
2370 plan->righttree = NULL;
2372 node->limitOffset = limitOffset;
2373 node->limitCount = limitCount;
2379 make_result(List *tlist,
2380 Node *resconstantqual,
2383 Result *node = makeNode(Result);
2384 Plan *plan = &node->plan;
2387 copy_plan_costsize(plan, subplan);
2390 plan->startup_cost = 0;
2391 plan->total_cost = cpu_tuple_cost;
2392 plan->plan_rows = 1; /* wrong if we have a set-valued function? */
2393 plan->plan_width = 0; /* XXX try to be smarter? */
2396 if (resconstantqual)
2400 cost_qual_eval(&qual_cost, (List *) resconstantqual);
2401 /* resconstantqual is evaluated once at startup */
2402 plan->startup_cost += qual_cost.startup + qual_cost.per_tuple;
2403 plan->total_cost += qual_cost.startup + qual_cost.per_tuple;
2406 plan->targetlist = tlist;
2408 plan->lefttree = subplan;
2409 plan->righttree = NULL;
2410 node->resconstantqual = resconstantqual;
2416 * is_projection_capable_plan
2417 * Check whether a given Plan node is able to do projection.
2420 is_projection_capable_plan(Plan *plan)
2422 /* Most plan types can project, so just list the ones that can't */
2423 switch (nodeTag(plan))