]> granicus.if.org Git - postgresql/blob - src/backend/optimizer/plan/createplan.c
79855b00c0f97594b78cd91e540d5021b8ae5151
[postgresql] / src / backend / optimizer / plan / createplan.c
1 /*-------------------------------------------------------------------------
2  *
3  * createplan.c
4  *        Routines to create the desired plan for processing a query.
5  *        Planning is complete, we just need to convert the selected
6  *        Path into a Plan.
7  *
8  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
9  * Portions Copyright (c) 1994, Regents of the University of California
10  *
11  *
12  * IDENTIFICATION
13  *        $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.148 2003/07/14 22:35:54 tgl Exp $
14  *
15  *-------------------------------------------------------------------------
16  */
17 #include "postgres.h"
18
19 #include <limits.h>
20
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/parse_clause.h"
32 #include "parser/parse_expr.h"
33 #include "utils/lsyscache.h"
34 #include "utils/syscache.h"
35
36
37 static Scan *create_scan_plan(Query *root, Path *best_path);
38 static List *build_relation_tlist(RelOptInfo *rel);
39 static bool use_physical_tlist(RelOptInfo *rel);
40 static void disuse_physical_tlist(Plan *plan, Path *path);
41 static Join *create_join_plan(Query *root, JoinPath *best_path);
42 static Append *create_append_plan(Query *root, AppendPath *best_path);
43 static Result *create_result_plan(Query *root, ResultPath *best_path);
44 static Material *create_material_plan(Query *root, MaterialPath *best_path);
45 static Plan *create_unique_plan(Query *root, UniquePath *best_path);
46 static SeqScan *create_seqscan_plan(Path *best_path, List *tlist,
47                                         List *scan_clauses);
48 static IndexScan *create_indexscan_plan(Query *root, IndexPath *best_path,
49                                           List *tlist, List *scan_clauses);
50 static TidScan *create_tidscan_plan(TidPath *best_path, List *tlist,
51                                         List *scan_clauses);
52 static SubqueryScan *create_subqueryscan_plan(Path *best_path,
53                                                  List *tlist, List *scan_clauses);
54 static FunctionScan *create_functionscan_plan(Path *best_path,
55                                                  List *tlist, List *scan_clauses);
56 static NestLoop *create_nestloop_plan(Query *root, NestPath *best_path,
57                                          Plan *outer_plan, Plan *inner_plan);
58 static MergeJoin *create_mergejoin_plan(Query *root, MergePath *best_path,
59                                           Plan *outer_plan, Plan *inner_plan);
60 static HashJoin *create_hashjoin_plan(Query *root, HashPath *best_path,
61                                          Plan *outer_plan, Plan *inner_plan);
62 static void fix_indxqual_references(List *indexquals, IndexPath *index_path,
63                                                 List **fixed_indexquals,
64                                                 List **recheck_indexquals);
65 static void fix_indxqual_sublist(List *indexqual,
66                                                                  Relids baserelids, int baserelid,
67                                                                  IndexOptInfo *index,
68                                                                  List **fixed_quals, List **recheck_quals);
69 static Node *fix_indxqual_operand(Node *node, int baserelid,
70                                          IndexOptInfo *index,
71                                          Oid *opclass);
72 static List *get_switched_clauses(List *clauses, Relids outerrelids);
73 static List *order_qual_clauses(Query *root, List *clauses);
74 static void copy_path_costsize(Plan *dest, Path *src);
75 static void copy_plan_costsize(Plan *dest, Plan *src);
76 static SeqScan *make_seqscan(List *qptlist, List *qpqual, Index scanrelid);
77 static IndexScan *make_indexscan(List *qptlist, List *qpqual, Index scanrelid,
78                            List *indxid, List *indxqual,
79                            List *indxqualorig,
80                            ScanDirection indexscandir);
81 static TidScan *make_tidscan(List *qptlist, List *qpqual, Index scanrelid,
82                          List *tideval);
83 static FunctionScan *make_functionscan(List *qptlist, List *qpqual,
84                                   Index scanrelid);
85 static NestLoop *make_nestloop(List *tlist,
86                           List *joinclauses, List *otherclauses,
87                           Plan *lefttree, Plan *righttree,
88                           JoinType jointype);
89 static HashJoin *make_hashjoin(List *tlist,
90                           List *joinclauses, List *otherclauses,
91                           List *hashclauses,
92                           Plan *lefttree, Plan *righttree,
93                           JoinType jointype);
94 static Hash *make_hash(List *tlist, List *hashkeys, Plan *lefttree);
95 static MergeJoin *make_mergejoin(List *tlist,
96                            List *joinclauses, List *otherclauses,
97                            List *mergeclauses,
98                            Plan *lefttree, Plan *righttree,
99                            JoinType jointype);
100 static Sort *make_sort(Query *root, List *tlist, Plan *lefttree, int numCols,
101                                            AttrNumber *sortColIdx, Oid *sortOperators);
102 static Sort *make_sort_from_pathkeys(Query *root, Plan *lefttree,
103                                                                          Relids relids, List *pathkeys);
104
105
106 /*
107  * create_plan
108  *        Creates the access plan for a query by tracing backwards through the
109  *        desired chain of pathnodes, starting at the node 'best_path'.  For
110  *        every pathnode found:
111  *        (1) Create a corresponding plan node containing appropriate id,
112  *                target list, and qualification information.
113  *        (2) Modify qual clauses of join nodes so that subplan attributes are
114  *                referenced using relative values.
115  *        (3) Target lists are not modified, but will be in setrefs.c.
116  *
117  *        best_path is the best access path
118  *
119  *        Returns a Plan tree.
120  */
121 Plan *
122 create_plan(Query *root, Path *best_path)
123 {
124         Plan       *plan;
125
126         switch (best_path->pathtype)
127         {
128                 case T_IndexScan:
129                 case T_SeqScan:
130                 case T_TidScan:
131                 case T_SubqueryScan:
132                 case T_FunctionScan:
133                         plan = (Plan *) create_scan_plan(root, best_path);
134                         break;
135                 case T_HashJoin:
136                 case T_MergeJoin:
137                 case T_NestLoop:
138                         plan = (Plan *) create_join_plan(root,
139                                                                                          (JoinPath *) best_path);
140                         break;
141                 case T_Append:
142                         plan = (Plan *) create_append_plan(root,
143                                                                                            (AppendPath *) best_path);
144                         break;
145                 case T_Result:
146                         plan = (Plan *) create_result_plan(root,
147                                                                                            (ResultPath *) best_path);
148                         break;
149                 case T_Material:
150                         plan = (Plan *) create_material_plan(root,
151                                                                                                  (MaterialPath *) best_path);
152                         break;
153                 case T_Unique:
154                         plan = (Plan *) create_unique_plan(root,
155                                                                                            (UniquePath *) best_path);
156                         break;
157                 default:
158                         elog(ERROR, "create_plan: unknown pathtype %d",
159                                  best_path->pathtype);
160                         plan = NULL;            /* keep compiler quiet */
161                         break;
162         }
163
164 #ifdef NOT_USED                                 /* fix xfunc */
165         /* sort clauses by cost/(1-selectivity) -- JMH 2/26/92 */
166         if (XfuncMode != XFUNC_OFF)
167         {
168                 set_qpqual((Plan) plan,
169                                    lisp_qsort(get_qpqual((Plan) plan),
170                                                           xfunc_clause_compare));
171                 if (XfuncMode != XFUNC_NOR)
172                         /* sort the disjuncts within each clause by cost -- JMH 3/4/92 */
173                         xfunc_disjunct_sort(plan->qpqual);
174         }
175 #endif
176
177         return plan;
178 }
179
180 /*
181  * create_scan_plan
182  *       Create a scan plan for the parent relation of 'best_path'.
183  *
184  *       Returns a Plan node.
185  */
186 static Scan *
187 create_scan_plan(Query *root, Path *best_path)
188 {
189         RelOptInfo *rel = best_path->parent;
190         List       *tlist;
191         List       *scan_clauses;
192         Scan       *plan;
193
194         /*
195          * For table scans, rather than using the relation targetlist (which is
196          * only those Vars actually needed by the query), we prefer to generate a
197          * tlist containing all Vars in order.  This will allow the executor to
198          * optimize away projection of the table tuples, if possible.  (Note that
199          * planner.c may replace the tlist we generate here, forcing projection to
200          * occur.)
201          */
202         if (use_physical_tlist(rel))
203         {
204                 tlist = build_physical_tlist(root, rel);
205                 /* if fail because of dropped cols, use regular method */
206                 if (tlist == NIL)
207                         tlist = build_relation_tlist(rel);
208         }
209         else
210                 tlist = build_relation_tlist(rel);
211
212         /*
213          * Extract the relevant restriction clauses from the parent relation;
214          * the executor must apply all these restrictions during the scan.
215          */
216         scan_clauses = get_actual_clauses(rel->baserestrictinfo);
217
218         /* Sort clauses into best execution order */
219         scan_clauses = order_qual_clauses(root, scan_clauses);
220
221         switch (best_path->pathtype)
222         {
223                 case T_SeqScan:
224                         plan = (Scan *) create_seqscan_plan(best_path,
225                                                                                                 tlist,
226                                                                                                 scan_clauses);
227                         break;
228
229                 case T_IndexScan:
230                         plan = (Scan *) create_indexscan_plan(root,
231                                                                                                   (IndexPath *) best_path,
232                                                                                                   tlist,
233                                                                                                   scan_clauses);
234                         break;
235
236                 case T_TidScan:
237                         plan = (Scan *) create_tidscan_plan((TidPath *) best_path,
238                                                                                                 tlist,
239                                                                                                 scan_clauses);
240                         break;
241
242                 case T_SubqueryScan:
243                         plan = (Scan *) create_subqueryscan_plan(best_path,
244                                                                                                          tlist,
245                                                                                                          scan_clauses);
246                         break;
247
248                 case T_FunctionScan:
249                         plan = (Scan *) create_functionscan_plan(best_path,
250                                                                                                          tlist,
251                                                                                                          scan_clauses);
252                         break;
253
254                 default:
255                         elog(ERROR, "create_scan_plan: unknown node type: %d",
256                                  best_path->pathtype);
257                         plan = NULL;            /* keep compiler quiet */
258                         break;
259         }
260
261         return plan;
262 }
263
264 /*
265  * Build a target list (ie, a list of TargetEntry) for a relation.
266  */
267 static List *
268 build_relation_tlist(RelOptInfo *rel)
269 {
270         FastList        tlist;
271         int                     resdomno = 1;
272         List       *v;
273
274         FastListInit(&tlist);
275         foreach(v, FastListValue(&rel->reltargetlist))
276         {
277                 /* Do we really need to copy here?  Not sure */
278                 Var        *var = (Var *) copyObject(lfirst(v));
279
280                 FastAppend(&tlist, create_tl_element(var, resdomno));
281                 resdomno++;
282         }
283         return FastListValue(&tlist);
284 }
285
286 /*
287  * use_physical_tlist
288  *              Decide whether to use a tlist matching relation structure,
289  *              rather than only those Vars actually referenced.
290  */
291 static bool
292 use_physical_tlist(RelOptInfo *rel)
293 {
294         int                     i;
295
296         /*
297          * Currently, can't do this for subquery or function scans.  (This
298          * is mainly because we don't have an equivalent of build_physical_tlist
299          * for them; worth adding?)
300          */
301         if (rel->rtekind != RTE_RELATION)
302                 return false;
303         /*
304          * Can't do it with inheritance cases either (mainly because Append
305          * doesn't project).
306          */
307         if (rel->reloptkind != RELOPT_BASEREL)
308                 return false;
309         /*
310          * Can't do it if any system columns are requested, either.  (This could
311          * possibly be fixed but would take some fragile assumptions in setrefs.c,
312          * I think.)
313          */
314         for (i = rel->min_attr; i <= 0; i++)
315         {
316                 if (!bms_is_empty(rel->attr_needed[i - rel->min_attr]))
317                         return false;
318         }
319         return true;
320 }
321
322 /*
323  * disuse_physical_tlist
324  *              Switch a plan node back to emitting only Vars actually referenced.
325  *
326  * If the plan node immediately above a scan would prefer to get only
327  * needed Vars and not a physical tlist, it must call this routine to
328  * undo the decision made by use_physical_tlist().  Currently, Hash, Sort,
329  * and Material nodes want this, so they don't have to store useless columns.
330  */
331 static void
332 disuse_physical_tlist(Plan *plan, Path *path)
333 {
334         /* Only need to undo it for path types handled by create_scan_plan() */
335         switch (path->pathtype)
336         {
337                 case T_IndexScan:
338                 case T_SeqScan:
339                 case T_TidScan:
340                 case T_SubqueryScan:
341                 case T_FunctionScan:
342                         plan->targetlist = build_relation_tlist(path->parent);
343                         break;
344                 default:
345                         break;
346         }
347 }
348
349 /*
350  * create_join_plan
351  *        Create a join plan for 'best_path' and (recursively) plans for its
352  *        inner and outer paths.
353  *
354  *        Returns a Plan node.
355  */
356 static Join *
357 create_join_plan(Query *root, JoinPath *best_path)
358 {
359         Plan       *outer_plan;
360         Plan       *inner_plan;
361         Join       *plan;
362
363         outer_plan = create_plan(root, best_path->outerjoinpath);
364         inner_plan = create_plan(root, best_path->innerjoinpath);
365
366         switch (best_path->path.pathtype)
367         {
368                 case T_MergeJoin:
369                         plan = (Join *) create_mergejoin_plan(root,
370                                                                                                   (MergePath *) best_path,
371                                                                                                   outer_plan,
372                                                                                                   inner_plan);
373                         break;
374                 case T_HashJoin:
375                         plan = (Join *) create_hashjoin_plan(root,
376                                                                                                  (HashPath *) best_path,
377                                                                                                  outer_plan,
378                                                                                                  inner_plan);
379                         break;
380                 case T_NestLoop:
381                         plan = (Join *) create_nestloop_plan(root,
382                                                                                                  (NestPath *) best_path,
383                                                                                                  outer_plan,
384                                                                                                  inner_plan);
385                         break;
386                 default:
387                         elog(ERROR, "unsupported node type %d",
388                                  best_path->path.pathtype);
389                         plan = NULL;            /* keep compiler quiet */
390                         break;
391         }
392
393 #ifdef NOT_USED
394
395         /*
396          * * Expensive function pullups may have pulled local predicates *
397          * into this path node.  Put them in the qpqual of the plan node. *
398          * JMH, 6/15/92
399          */
400         if (get_loc_restrictinfo(best_path) != NIL)
401                 set_qpqual((Plan) plan,
402                                    nconc(get_qpqual((Plan) plan),
403                                    get_actual_clauses(get_loc_restrictinfo(best_path))));
404 #endif
405
406         return plan;
407 }
408
409 /*
410  * create_append_plan
411  *        Create an Append plan for 'best_path' and (recursively) plans
412  *        for its subpaths.
413  *
414  *        Returns a Plan node.
415  */
416 static Append *
417 create_append_plan(Query *root, AppendPath *best_path)
418 {
419         Append     *plan;
420         List       *tlist = build_relation_tlist(best_path->path.parent);
421         List       *subplans = NIL;
422         List       *subpaths;
423
424         foreach(subpaths, best_path->subpaths)
425         {
426                 Path       *subpath = (Path *) lfirst(subpaths);
427
428                 subplans = lappend(subplans, create_plan(root, subpath));
429         }
430
431         plan = make_append(subplans, false, tlist);
432
433         return plan;
434 }
435
436 /*
437  * create_result_plan
438  *        Create a Result plan for 'best_path' and (recursively) plans
439  *        for its subpaths.
440  *
441  *        Returns a Plan node.
442  */
443 static Result *
444 create_result_plan(Query *root, ResultPath *best_path)
445 {
446         Result     *plan;
447         List       *tlist;
448         List       *constclauses;
449         Plan       *subplan;
450
451         if (best_path->path.parent)
452                 tlist = build_relation_tlist(best_path->path.parent);
453         else
454                 tlist = NIL;                    /* will be filled in later */
455
456         if (best_path->subpath)
457                 subplan = create_plan(root, best_path->subpath);
458         else
459                 subplan = NULL;
460
461         constclauses = order_qual_clauses(root, best_path->constantqual);
462
463         plan = make_result(tlist, (Node *) constclauses, subplan);
464
465         return plan;
466 }
467
468 /*
469  * create_material_plan
470  *        Create a Material plan for 'best_path' and (recursively) plans
471  *        for its subpaths.
472  *
473  *        Returns a Plan node.
474  */
475 static Material *
476 create_material_plan(Query *root, MaterialPath *best_path)
477 {
478         Material   *plan;
479         Plan       *subplan;
480
481         subplan = create_plan(root, best_path->subpath);
482
483         /* We don't want any excess columns in the materialized tuples */
484         disuse_physical_tlist(subplan, best_path->subpath);
485
486         plan = make_material(subplan->targetlist, subplan);
487
488         copy_path_costsize(&plan->plan, (Path *) best_path);
489
490         return plan;
491 }
492
493 /*
494  * create_unique_plan
495  *        Create a Unique plan for 'best_path' and (recursively) plans
496  *        for its subpaths.
497  *
498  *        Returns a Plan node.
499  */
500 static Plan *
501 create_unique_plan(Query *root, UniquePath *best_path)
502 {
503         Plan       *plan;
504         Plan       *subplan;
505         List       *sub_targetlist;
506         List       *my_tlist;
507         List       *l;
508
509         subplan = create_plan(root, best_path->subpath);
510
511         /*
512          * If the subplan came from an IN subselect (currently always the case),
513          * we need to instantiate the correct output targetlist for the subselect,
514          * rather than using the flattened tlist.
515          */
516         sub_targetlist = NIL;
517         foreach(l, root->in_info_list)
518         {
519                 InClauseInfo *ininfo = (InClauseInfo *) lfirst(l);
520
521                 if (bms_equal(ininfo->righthand, best_path->path.parent->relids))
522                 {
523                         sub_targetlist = ininfo->sub_targetlist;
524                         break;
525                 }
526         }
527
528         if (sub_targetlist)
529         {
530                 /*
531                  * Transform list of plain Vars into targetlist
532                  */
533                 List   *newtlist = NIL;
534                 int             resno = 1;
535
536                 foreach(l, sub_targetlist)
537                 {
538                         Node       *tlexpr = lfirst(l);
539                         TargetEntry *tle;
540
541                         tle = makeTargetEntry(makeResdom(resno,
542                                                                                          exprType(tlexpr),
543                                                                                          exprTypmod(tlexpr),
544                                                                                          NULL,
545                                                                                          false),
546                                                                   (Expr *) tlexpr);
547                         newtlist = lappend(newtlist, tle);
548                         resno++;
549                 }
550                 /*
551                  * If the top plan node can't do projections, we need to add a
552                  * Result node to help it along.
553                  *
554                  * Currently, the only non-projection-capable plan type
555                  * we can see here is Append.
556                  */
557                 if (IsA(subplan, Append))
558                         subplan = (Plan *) make_result(newtlist, NULL, subplan);
559                 else
560                         subplan->targetlist = newtlist;
561         }
562
563         my_tlist = copyObject(subplan->targetlist);
564
565         if (best_path->use_hash)
566         {
567                 int             numGroupCols = length(my_tlist);
568                 long    numGroups;
569                 AttrNumber *groupColIdx;
570                 int             i;
571
572                 numGroups = (long) Min(best_path->rows, (double) LONG_MAX);
573
574                 groupColIdx = (AttrNumber *) palloc(numGroupCols * sizeof(AttrNumber));
575                 for (i = 0; i < numGroupCols; i++)
576                         groupColIdx[i] = i+1;
577
578                 plan = (Plan *) make_agg(root,
579                                                                  my_tlist,
580                                                                  NIL,
581                                                                  AGG_HASHED,
582                                                                  numGroupCols,
583                                                                  groupColIdx,
584                                                                  numGroups,
585                                                                  0,
586                                                                  subplan);
587         }
588         else
589         {
590                 List       *sortList;
591
592                 sortList = addAllTargetsToSortList(NULL, NIL, my_tlist, false);
593                 plan = (Plan *) make_sort_from_sortclauses(root, my_tlist,
594                                                                                                    subplan, sortList);
595                 plan = (Plan *) make_unique(my_tlist, plan, sortList);
596         }
597
598         plan->plan_rows = best_path->rows;
599
600         return plan;
601 }
602
603
604 /*****************************************************************************
605  *
606  *      BASE-RELATION SCAN METHODS
607  *
608  *****************************************************************************/
609
610
611 /*
612  * create_seqscan_plan
613  *       Returns a seqscan plan for the base relation scanned by 'best_path'
614  *       with restriction clauses 'scan_clauses' and targetlist 'tlist'.
615  */
616 static SeqScan *
617 create_seqscan_plan(Path *best_path, List *tlist, List *scan_clauses)
618 {
619         SeqScan    *scan_plan;
620         Index           scan_relid = best_path->parent->relid;
621
622         /* it should be a base rel... */
623         Assert(scan_relid > 0);
624         Assert(best_path->parent->rtekind == RTE_RELATION);
625
626         scan_plan = make_seqscan(tlist,
627                                                          scan_clauses,
628                                                          scan_relid);
629
630         copy_path_costsize(&scan_plan->plan, best_path);
631
632         return scan_plan;
633 }
634
635 /*
636  * create_indexscan_plan
637  *        Returns a indexscan plan for the base relation scanned by 'best_path'
638  *        with restriction clauses 'scan_clauses' and targetlist 'tlist'.
639  *
640  * The indexqual of the path contains a sublist of implicitly-ANDed qual
641  * conditions for each scan of the index(es); if there is more than one
642  * scan then the retrieved tuple sets are ORed together.  The indexqual
643  * and indexinfo lists must have the same length, ie, the number of scans
644  * that will occur.  Note it is possible for a qual condition sublist
645  * to be empty --- then no index restrictions will be applied during that
646  * scan.
647  */
648 static IndexScan *
649 create_indexscan_plan(Query *root,
650                                           IndexPath *best_path,
651                                           List *tlist,
652                                           List *scan_clauses)
653 {
654         List       *indxqual = best_path->indexqual;
655         Index           baserelid = best_path->path.parent->relid;
656         List       *qpqual;
657         Expr       *indxqual_or_expr = NULL;
658         List       *fixed_indxqual;
659         List       *recheck_indxqual;
660         FastList        indexids;
661         List       *ixinfo;
662         IndexScan  *scan_plan;
663
664         /* it should be a base rel... */
665         Assert(baserelid > 0);
666         Assert(best_path->path.parent->rtekind == RTE_RELATION);
667
668         /*
669          * Build list of index OIDs.
670          */
671         FastListInit(&indexids);
672         foreach(ixinfo, best_path->indexinfo)
673         {
674                 IndexOptInfo *index = (IndexOptInfo *) lfirst(ixinfo);
675
676                 FastAppendo(&indexids, index->indexoid);
677         }
678
679         /*
680          * The qpqual list must contain all restrictions not automatically
681          * handled by the index.  Normally the predicates in the indxqual are
682          * checked fully by the index, but if the index is "lossy" for a
683          * particular operator (as signaled by the amopreqcheck flag in
684          * pg_amop), then we need to double-check that predicate in qpqual,
685          * because the index may return more tuples than match the predicate.
686          *
687          * Since the indexquals were generated from the restriction clauses given
688          * by scan_clauses, there will normally be some duplications between
689          * the lists.  We get rid of the duplicates, then add back if lossy.
690          */
691         if (length(indxqual) > 1)
692         {
693                 /*
694                  * Build an expression representation of the indexqual, expanding
695                  * the implicit OR and AND semantics of the first- and
696                  * second-level lists.
697                  */
698                 FastList        orclauses;
699                 List       *orclause;
700
701                 FastListInit(&orclauses);
702                 foreach(orclause, indxqual)
703                 {
704                         FastAppend(&orclauses, make_ands_explicit(lfirst(orclause)));
705                 }
706                 indxqual_or_expr = make_orclause(FastListValue(&orclauses));
707
708                 qpqual = set_difference(scan_clauses, makeList1(indxqual_or_expr));
709         }
710         else if (indxqual != NIL)
711         {
712                 /*
713                  * Here, we can simply treat the first sublist as an independent
714                  * set of qual expressions, since there is no top-level OR
715                  * behavior.
716                  */
717                 qpqual = set_difference(scan_clauses, lfirst(indxqual));
718         }
719         else
720                 qpqual = scan_clauses;
721
722         /*
723          * The executor needs a copy with the indexkey on the left of each
724          * clause and with index attr numbers substituted for table ones. This
725          * pass also looks for "lossy" operators.
726          */
727         fix_indxqual_references(indxqual, best_path,
728                                                         &fixed_indxqual, &recheck_indxqual);
729
730         /*
731          * If there were any "lossy" operators, need to add back the
732          * appropriate qual clauses to the qpqual.      When there is just one
733          * indexscan being performed (ie, we have simple AND semantics), we
734          * can just add the lossy clauses themselves to qpqual.  If we have
735          * OR-of-ANDs, we'd better add the entire original indexqual to make
736          * sure that the semantics are correct.
737          */
738         if (recheck_indxqual != NIL)
739         {
740                 if (indxqual_or_expr)
741                 {
742                         /* Better do a deep copy of the original scanclauses */
743                         qpqual = lappend(qpqual, copyObject(indxqual_or_expr));
744                 }
745                 else
746                 {
747                         /* Subroutine already copied quals, so just append to list */
748                         Assert(length(recheck_indxqual) == 1);
749                         qpqual = nconc(qpqual, (List *) lfirst(recheck_indxqual));
750                 }
751         }
752
753         /* Finally ready to build the plan node */
754         scan_plan = make_indexscan(tlist,
755                                                            qpqual,
756                                                            baserelid,
757                                                            FastListValue(&indexids),
758                                                            fixed_indxqual,
759                                                            indxqual,
760                                                            best_path->indexscandir);
761
762         copy_path_costsize(&scan_plan->scan.plan, &best_path->path);
763         /* use the indexscan-specific rows estimate, not the parent rel's */
764         scan_plan->scan.plan.plan_rows = best_path->rows;
765
766         return scan_plan;
767 }
768
769 /*
770  * create_tidscan_plan
771  *       Returns a tidscan plan for the base relation scanned by 'best_path'
772  *       with restriction clauses 'scan_clauses' and targetlist 'tlist'.
773  */
774 static TidScan *
775 create_tidscan_plan(TidPath *best_path, List *tlist, List *scan_clauses)
776 {
777         TidScan    *scan_plan;
778         Index           scan_relid = best_path->path.parent->relid;
779
780         /* it should be a base rel... */
781         Assert(scan_relid > 0);
782         Assert(best_path->path.parent->rtekind == RTE_RELATION);
783
784         scan_plan = make_tidscan(tlist,
785                                                          scan_clauses,
786                                                          scan_relid,
787                                                          best_path->tideval);
788
789         copy_path_costsize(&scan_plan->scan.plan, &best_path->path);
790
791         return scan_plan;
792 }
793
794 /*
795  * create_subqueryscan_plan
796  *       Returns a subqueryscan plan for the base relation scanned by 'best_path'
797  *       with restriction clauses 'scan_clauses' and targetlist 'tlist'.
798  */
799 static SubqueryScan *
800 create_subqueryscan_plan(Path *best_path, List *tlist, List *scan_clauses)
801 {
802         SubqueryScan *scan_plan;
803         Index           scan_relid = best_path->parent->relid;
804
805         /* it should be a subquery base rel... */
806         Assert(scan_relid > 0);
807         Assert(best_path->parent->rtekind == RTE_SUBQUERY);
808
809         scan_plan = make_subqueryscan(tlist,
810                                                                   scan_clauses,
811                                                                   scan_relid,
812                                                                   best_path->parent->subplan);
813
814         copy_path_costsize(&scan_plan->scan.plan, best_path);
815
816         return scan_plan;
817 }
818
819 /*
820  * create_functionscan_plan
821  *       Returns a functionscan plan for the base relation scanned by 'best_path'
822  *       with restriction clauses 'scan_clauses' and targetlist 'tlist'.
823  */
824 static FunctionScan *
825 create_functionscan_plan(Path *best_path, List *tlist, List *scan_clauses)
826 {
827         FunctionScan *scan_plan;
828         Index           scan_relid = best_path->parent->relid;
829
830         /* it should be a function base rel... */
831         Assert(scan_relid > 0);
832         Assert(best_path->parent->rtekind == RTE_FUNCTION);
833
834         scan_plan = make_functionscan(tlist, scan_clauses, scan_relid);
835
836         copy_path_costsize(&scan_plan->scan.plan, best_path);
837
838         return scan_plan;
839 }
840
841 /*****************************************************************************
842  *
843  *      JOIN METHODS
844  *
845  *****************************************************************************/
846
847 static NestLoop *
848 create_nestloop_plan(Query *root,
849                                          NestPath *best_path,
850                                          Plan *outer_plan,
851                                          Plan *inner_plan)
852 {
853         List       *tlist = build_relation_tlist(best_path->path.parent);
854         List       *joinrestrictclauses = best_path->joinrestrictinfo;
855         List       *joinclauses;
856         List       *otherclauses;
857         NestLoop   *join_plan;
858
859         if (IsA(best_path->innerjoinpath, IndexPath))
860         {
861                 /*
862                  * An index is being used to reduce the number of tuples scanned
863                  * in the inner relation.  If there are join clauses being used
864                  * with the index, we may remove those join clauses from the list of
865                  * clauses that have to be checked as qpquals at the join node ---
866                  * but only if there's just one indexscan in the inner path
867                  * (otherwise, several different sets of clauses are being ORed
868                  * together).
869                  *
870                  * We can also remove any join clauses that are redundant with those
871                  * being used in the index scan; prior redundancy checks will not
872                  * have caught this case because the join clauses would never have
873                  * been put in the same joininfo list.
874                  *
875                  * This would be a waste of time if the indexpath was an ordinary
876                  * indexpath and not a special innerjoin path.  We will skip it in
877                  * that case since indexjoinclauses is NIL in an ordinary indexpath.
878                  */
879                 IndexPath  *innerpath = (IndexPath *) best_path->innerjoinpath;
880                 List       *indexjoinclauses = innerpath->indexjoinclauses;
881
882                 if (length(indexjoinclauses) == 1) /* single indexscan? */
883                 {
884                         joinrestrictclauses =
885                                 select_nonredundant_join_clauses(root,
886                                                                                                  joinrestrictclauses,
887                                                                                                  lfirst(indexjoinclauses),
888                                                                                                  best_path->jointype);
889                 }
890         }
891
892         /* Get the join qual clauses (in plain expression form) */
893         if (IS_OUTER_JOIN(best_path->jointype))
894         {
895                 get_actual_join_clauses(joinrestrictclauses,
896                                                                 &joinclauses, &otherclauses);
897         }
898         else
899         {
900                 /* We can treat all clauses alike for an inner join */
901                 joinclauses = get_actual_clauses(joinrestrictclauses);
902                 otherclauses = NIL;
903         }
904
905         join_plan = make_nestloop(tlist,
906                                                           joinclauses,
907                                                           otherclauses,
908                                                           outer_plan,
909                                                           inner_plan,
910                                                           best_path->jointype);
911
912         copy_path_costsize(&join_plan->join.plan, &best_path->path);
913
914         return join_plan;
915 }
916
917 static MergeJoin *
918 create_mergejoin_plan(Query *root,
919                                           MergePath *best_path,
920                                           Plan *outer_plan,
921                                           Plan *inner_plan)
922 {
923         List       *tlist = build_relation_tlist(best_path->jpath.path.parent);
924         List       *joinclauses;
925         List       *otherclauses;
926         List       *mergeclauses;
927         MergeJoin  *join_plan;
928
929         /* Get the join qual clauses (in plain expression form) */
930         if (IS_OUTER_JOIN(best_path->jpath.jointype))
931         {
932                 get_actual_join_clauses(best_path->jpath.joinrestrictinfo,
933                                                                 &joinclauses, &otherclauses);
934         }
935         else
936         {
937                 /* We can treat all clauses alike for an inner join */
938                 joinclauses = get_actual_clauses(best_path->jpath.joinrestrictinfo);
939                 otherclauses = NIL;
940         }
941
942         /*
943          * Remove the mergeclauses from the list of join qual clauses, leaving
944          * the list of quals that must be checked as qpquals.
945          */
946         mergeclauses = get_actual_clauses(best_path->path_mergeclauses);
947         joinclauses = set_difference(joinclauses, mergeclauses);
948
949         /*
950          * Rearrange mergeclauses, if needed, so that the outer variable
951          * is always on the left.
952          */
953         mergeclauses = get_switched_clauses(best_path->path_mergeclauses,
954                                                                                 best_path->jpath.outerjoinpath->parent->relids);
955
956         /*
957          * Create explicit sort nodes for the outer and inner join paths if
958          * necessary.  The sort cost was already accounted for in the path.
959          * Make sure there are no excess columns in the inputs if sorting.
960          */
961         if (best_path->outersortkeys)
962         {
963                 disuse_physical_tlist(outer_plan, best_path->jpath.outerjoinpath);
964                 outer_plan = (Plan *)
965                         make_sort_from_pathkeys(root,
966                                                                         outer_plan,
967                                                                         best_path->jpath.outerjoinpath->parent->relids,
968                                                                         best_path->outersortkeys);
969         }
970
971         if (best_path->innersortkeys)
972         {
973                 disuse_physical_tlist(inner_plan, best_path->jpath.innerjoinpath);
974                 inner_plan = (Plan *)
975                         make_sort_from_pathkeys(root,
976                                                                         inner_plan,
977                                                                         best_path->jpath.innerjoinpath->parent->relids,
978                                                                         best_path->innersortkeys);
979         }
980
981         /*
982          * Now we can build the mergejoin node.
983          */
984         join_plan = make_mergejoin(tlist,
985                                                            joinclauses,
986                                                            otherclauses,
987                                                            mergeclauses,
988                                                            outer_plan,
989                                                            inner_plan,
990                                                            best_path->jpath.jointype);
991
992         copy_path_costsize(&join_plan->join.plan, &best_path->jpath.path);
993
994         return join_plan;
995 }
996
997 static HashJoin *
998 create_hashjoin_plan(Query *root,
999                                          HashPath *best_path,
1000                                          Plan *outer_plan,
1001                                          Plan *inner_plan)
1002 {
1003         List       *tlist = build_relation_tlist(best_path->jpath.path.parent);
1004         List       *joinclauses;
1005         List       *otherclauses;
1006         List       *hashclauses;
1007         HashJoin   *join_plan;
1008         Hash       *hash_plan;
1009         List       *innerhashkeys;
1010         List       *hcl;
1011
1012         /* Get the join qual clauses (in plain expression form) */
1013         if (IS_OUTER_JOIN(best_path->jpath.jointype))
1014         {
1015                 get_actual_join_clauses(best_path->jpath.joinrestrictinfo,
1016                                                                 &joinclauses, &otherclauses);
1017         }
1018         else
1019         {
1020                 /* We can treat all clauses alike for an inner join */
1021                 joinclauses = get_actual_clauses(best_path->jpath.joinrestrictinfo);
1022                 otherclauses = NIL;
1023         }
1024
1025         /*
1026          * Remove the hashclauses from the list of join qual clauses, leaving
1027          * the list of quals that must be checked as qpquals.
1028          */
1029         hashclauses = get_actual_clauses(best_path->path_hashclauses);
1030         joinclauses = set_difference(joinclauses, hashclauses);
1031
1032         /*
1033          * Rearrange hashclauses, if needed, so that the outer variable
1034          * is always on the left.
1035          */
1036         hashclauses = get_switched_clauses(best_path->path_hashclauses,
1037                                                                            best_path->jpath.outerjoinpath->parent->relids);
1038
1039         /*
1040          * Extract the inner hash keys (right-hand operands of the hashclauses)
1041          * to put in the Hash node.
1042          */
1043         innerhashkeys = NIL;
1044         foreach(hcl, hashclauses)
1045         {
1046                 innerhashkeys = lappend(innerhashkeys, get_rightop(lfirst(hcl)));
1047         }
1048
1049         /* We don't want any excess columns in the hashed tuples */
1050         disuse_physical_tlist(inner_plan, best_path->jpath.innerjoinpath);
1051
1052         /*
1053          * Build the hash node and hash join node.
1054          */
1055         hash_plan = make_hash(inner_plan->targetlist,
1056                                                   innerhashkeys,
1057                                                   inner_plan);
1058         join_plan = make_hashjoin(tlist,
1059                                                           joinclauses,
1060                                                           otherclauses,
1061                                                           hashclauses,
1062                                                           outer_plan,
1063                                                           (Plan *) hash_plan,
1064                                                           best_path->jpath.jointype);
1065
1066         copy_path_costsize(&join_plan->join.plan, &best_path->jpath.path);
1067
1068         return join_plan;
1069 }
1070
1071
1072 /*****************************************************************************
1073  *
1074  *      SUPPORTING ROUTINES
1075  *
1076  *****************************************************************************/
1077
1078 /*
1079  * fix_indxqual_references
1080  *        Adjust indexqual clauses to the form the executor's indexqual
1081  *        machinery needs, and check for recheckable (lossy) index conditions.
1082  *
1083  * We have three tasks here:
1084  *      * Index keys must be represented by Var nodes with varattno set to the
1085  *        index's attribute number, not the attribute number in the original rel.
1086  *      * If the index key is on the right, commute the clause to put it on the
1087  *        left.  (Someday the executor might not need this, but for now it does.)
1088  *      * If the indexable operator is marked 'amopreqcheck' in pg_amop, then
1089  *        the index is "lossy" for this operator: it may return more tuples than
1090  *        actually satisfy the operator condition.      For each such operator, we
1091  *        must add (the original form of) the indexqual clause to the "qpquals"
1092  *        of the indexscan node, where the operator will be re-evaluated to
1093  *        ensure it passes.
1094  *
1095  * This code used to be entirely bogus for multi-index scans.  Now it keeps
1096  * track of which index applies to each subgroup of index qual clauses...
1097  *
1098  * Both the input list and the output lists have the form of lists of sublists
1099  * of qual clauses --- the top-level list has one entry for each indexscan
1100  * to be performed.  The semantics are OR-of-ANDs.
1101  *
1102  * fixed_indexquals receives a modified copy of the indexqual list --- the
1103  * original is not changed.  Note also that the copy shares no substructure
1104  * with the original; this is needed in case there is a subplan in it (we need
1105  * two separate copies of the subplan tree, or things will go awry).
1106  *
1107  * recheck_indexquals similarly receives a full copy of whichever clauses
1108  * need rechecking.
1109  */
1110 static void
1111 fix_indxqual_references(List *indexquals, IndexPath *index_path,
1112                                           List **fixed_indexquals, List **recheck_indexquals)
1113 {
1114         FastList        fixed_quals;
1115         FastList        recheck_quals;
1116         Relids          baserelids = index_path->path.parent->relids;
1117         int                     baserelid = index_path->path.parent->relid;
1118         List       *ixinfo = index_path->indexinfo;
1119         List       *i;
1120
1121         FastListInit(&fixed_quals);
1122         FastListInit(&recheck_quals);
1123         foreach(i, indexquals)
1124         {
1125                 List       *indexqual = lfirst(i);
1126                 IndexOptInfo *index = (IndexOptInfo *) lfirst(ixinfo);
1127                 List       *fixed_qual;
1128                 List       *recheck_qual;
1129
1130                 fix_indxqual_sublist(indexqual, baserelids, baserelid, index,
1131                                                          &fixed_qual, &recheck_qual);
1132                 FastAppend(&fixed_quals, fixed_qual);
1133                 if (recheck_qual != NIL)
1134                         FastAppend(&recheck_quals, recheck_qual);
1135
1136                 ixinfo = lnext(ixinfo);
1137         }
1138
1139         *fixed_indexquals = FastListValue(&fixed_quals);
1140         *recheck_indexquals = FastListValue(&recheck_quals);
1141 }
1142
1143 /*
1144  * Fix the sublist of indexquals to be used in a particular scan.
1145  *
1146  * For each qual clause, commute if needed to put the indexkey operand on the
1147  * left, and then fix its varattno.  (We do not need to change the other side
1148  * of the clause.)      Also change the operator if necessary, and check for
1149  * lossy index behavior.
1150  *
1151  * Returns two lists: the list of fixed indexquals, and the list (usually
1152  * empty) of original clauses that must be rechecked as qpquals because
1153  * the index is lossy for this operator type.
1154  */
1155 static void
1156 fix_indxqual_sublist(List *indexqual,
1157                                          Relids baserelids, int baserelid,
1158                                          IndexOptInfo *index,
1159                                          List **fixed_quals, List **recheck_quals)
1160 {
1161         FastList        fixed_qual;
1162         FastList        recheck_qual;
1163         List       *i;
1164
1165         FastListInit(&fixed_qual);
1166         FastListInit(&recheck_qual);
1167         foreach(i, indexqual)
1168         {
1169                 OpExpr     *clause = (OpExpr *) lfirst(i);
1170                 OpExpr     *newclause;
1171                 Relids          leftvarnos;
1172                 Oid                     opclass;
1173
1174                 if (!IsA(clause, OpExpr) || length(clause->args) != 2)
1175                         elog(ERROR, "fix_indxqual_sublist: indexqual clause is not binary opclause");
1176
1177                 /*
1178                  * Make a copy that will become the fixed clause.
1179                  *
1180                  * We used to try to do a shallow copy here, but that fails if there
1181                  * is a subplan in the arguments of the opclause.  So just do a
1182                  * full copy.
1183                  */
1184                 newclause = (OpExpr *) copyObject((Node *) clause);
1185
1186                 /*
1187                  * Check to see if the indexkey is on the right; if so, commute
1188                  * the clause.  The indexkey should be the side that refers to
1189                  * (only) the base relation.
1190                  */
1191                 leftvarnos = pull_varnos((Node *) lfirst(newclause->args));
1192                 if (!bms_equal(leftvarnos, baserelids))
1193                         CommuteClause(newclause);
1194                 bms_free(leftvarnos);
1195
1196                 /*
1197                  * Now, determine which index attribute this is, change the
1198                  * indexkey operand as needed, and get the index opclass.
1199                  */
1200                 lfirst(newclause->args) = fix_indxqual_operand(lfirst(newclause->args),
1201                                                                                                            baserelid,
1202                                                                                                            index,
1203                                                                                                            &opclass);
1204
1205                 FastAppend(&fixed_qual, newclause);
1206
1207                 /*
1208                  * Finally, check to see if index is lossy for this operator. If
1209                  * so, add (a copy of) original form of clause to recheck list.
1210                  */
1211                 if (op_requires_recheck(newclause->opno, opclass))
1212                         FastAppend(&recheck_qual, copyObject((Node *) clause));
1213         }
1214
1215         *fixed_quals = FastListValue(&fixed_qual);
1216         *recheck_quals = FastListValue(&recheck_qual);
1217 }
1218
1219 static Node *
1220 fix_indxqual_operand(Node *node, int baserelid, IndexOptInfo *index,
1221                                          Oid *opclass)
1222 {
1223         /*
1224          * We represent index keys by Var nodes having the varno of the base
1225          * table but varattno equal to the index's attribute number (index
1226          * column position).  This is a bit hokey ... would be cleaner to use
1227          * a special-purpose node type that could not be mistaken for a
1228          * regular Var.  But it will do for now.
1229          */
1230         Var                *result;
1231         int                     pos;
1232         List       *indexprs;
1233
1234         /*
1235          * Remove any binary-compatible relabeling of the indexkey
1236          */
1237         if (IsA(node, RelabelType))
1238                 node = (Node *) ((RelabelType *) node)->arg;
1239
1240         if (IsA(node, Var) &&
1241                 ((Var *) node)->varno == baserelid)
1242         {
1243                 /* Try to match against simple index columns */
1244                 int                     varatt = ((Var *) node)->varattno;
1245
1246                 if (varatt != 0)
1247                 {
1248                         for (pos = 0; pos < index->ncolumns; pos++)
1249                         {
1250                                 if (index->indexkeys[pos] == varatt)
1251                                 {
1252                                         result = (Var *) copyObject(node);
1253                                         result->varattno = pos + 1;
1254                                         /* return the correct opclass, too */
1255                                         *opclass = index->classlist[pos];
1256                                         return (Node *) result;
1257                                 }
1258                         }
1259                 }
1260         }
1261
1262         /* Try to match against index expressions */
1263         indexprs = index->indexprs;
1264         for (pos = 0; pos < index->ncolumns; pos++)
1265         {
1266                 if (index->indexkeys[pos] == 0)
1267                 {
1268                         Node       *indexkey;
1269
1270                         if (indexprs == NIL)
1271                                 elog(ERROR, "too few entries in indexprs list");
1272                         indexkey = (Node *) lfirst(indexprs);
1273                         if (indexkey && IsA(indexkey, RelabelType))
1274                                 indexkey = (Node *) ((RelabelType *) indexkey)->arg;
1275                         if (equal(node, indexkey))
1276                         {
1277                                 /* Found a match */
1278                                 result = makeVar(baserelid, pos + 1,
1279                                                                  exprType(lfirst(indexprs)), -1,
1280                                                                  0);
1281                                 /* return the correct opclass, too */
1282                                 *opclass = index->classlist[pos];
1283                                 return (Node *) result;
1284                         }
1285                         indexprs = lnext(indexprs);
1286                 }
1287         }
1288
1289         /* Ooops... */
1290         elog(ERROR, "fix_indxqual_operand: node is not index attribute");
1291         return NULL;                            /* keep compiler quiet */
1292 }
1293
1294 /*
1295  * get_switched_clauses
1296  *        Given a list of merge or hash joinclauses (as RestrictInfo nodes),
1297  *        extract the bare clauses, and rearrange the elements within the
1298  *        clauses, if needed, so the outer join variable is on the left and
1299  *        the inner is on the right.  The original data structure is not touched;
1300  *        a modified list is returned.
1301  */
1302 static List *
1303 get_switched_clauses(List *clauses, Relids outerrelids)
1304 {
1305         List       *t_list = NIL;
1306         List       *i;
1307
1308         foreach(i, clauses)
1309         {
1310                 RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(i);
1311                 OpExpr     *clause = (OpExpr *) restrictinfo->clause;
1312
1313                 Assert(is_opclause(clause));
1314                 if (bms_is_subset(restrictinfo->right_relids, outerrelids))
1315                 {
1316                         /*
1317                          * Duplicate just enough of the structure to allow commuting
1318                          * the clause without changing the original list.  Could use
1319                          * copyObject, but a complete deep copy is overkill.
1320                          */
1321                         OpExpr     *temp = makeNode(OpExpr);
1322
1323                         temp->opno = clause->opno;
1324                         temp->opfuncid = InvalidOid;
1325                         temp->opresulttype = clause->opresulttype;
1326                         temp->opretset = clause->opretset;
1327                         temp->args = listCopy(clause->args);
1328                         /* Commute it --- note this modifies the temp node in-place. */
1329                         CommuteClause(temp);
1330                         t_list = lappend(t_list, temp);
1331                 }
1332                 else
1333                         t_list = lappend(t_list, clause);
1334         }
1335         return t_list;
1336 }
1337
1338 /*
1339  * order_qual_clauses
1340  *              Given a list of qual clauses that will all be evaluated at the same
1341  *              plan node, sort the list into the order we want to check the quals
1342  *              in at runtime.
1343  *
1344  * Ideally the order should be driven by a combination of execution cost and
1345  * selectivity, but unfortunately we have so little information about
1346  * execution cost of operators that it's really hard to do anything smart.
1347  * For now, we just move any quals that contain SubPlan references (but not
1348  * InitPlan references) to the end of the list.
1349  */
1350 static List *
1351 order_qual_clauses(Query *root, List *clauses)
1352 {
1353         FastList        nosubplans;
1354         FastList        withsubplans;
1355         List       *l;
1356
1357         /* No need to work hard if the query is subselect-free */
1358         if (!root->hasSubLinks)
1359                 return clauses;
1360
1361         FastListInit(&nosubplans);
1362         FastListInit(&withsubplans);
1363         foreach(l, clauses)
1364         {
1365                 Node   *clause = lfirst(l);
1366
1367                 if (contain_subplans(clause))
1368                         FastAppend(&withsubplans, clause);
1369                 else
1370                         FastAppend(&nosubplans, clause);
1371         }
1372
1373         FastConcFast(&nosubplans, &withsubplans);
1374         return FastListValue(&nosubplans);
1375 }
1376
1377 /*
1378  * Copy cost and size info from a Path node to the Plan node created from it.
1379  * The executor won't use this info, but it's needed by EXPLAIN.
1380  */
1381 static void
1382 copy_path_costsize(Plan *dest, Path *src)
1383 {
1384         if (src)
1385         {
1386                 dest->startup_cost = src->startup_cost;
1387                 dest->total_cost = src->total_cost;
1388                 dest->plan_rows = src->parent->rows;
1389                 dest->plan_width = src->parent->width;
1390         }
1391         else
1392         {
1393                 dest->startup_cost = 0;
1394                 dest->total_cost = 0;
1395                 dest->plan_rows = 0;
1396                 dest->plan_width = 0;
1397         }
1398 }
1399
1400 /*
1401  * Copy cost and size info from a lower plan node to an inserted node.
1402  * This is not critical, since the decisions have already been made,
1403  * but it helps produce more reasonable-looking EXPLAIN output.
1404  * (Some callers alter the info after copying it.)
1405  */
1406 static void
1407 copy_plan_costsize(Plan *dest, Plan *src)
1408 {
1409         if (src)
1410         {
1411                 dest->startup_cost = src->startup_cost;
1412                 dest->total_cost = src->total_cost;
1413                 dest->plan_rows = src->plan_rows;
1414                 dest->plan_width = src->plan_width;
1415         }
1416         else
1417         {
1418                 dest->startup_cost = 0;
1419                 dest->total_cost = 0;
1420                 dest->plan_rows = 0;
1421                 dest->plan_width = 0;
1422         }
1423 }
1424
1425
1426 /*****************************************************************************
1427  *
1428  *      PLAN NODE BUILDING ROUTINES
1429  *
1430  * Some of these are exported because they are called to build plan nodes
1431  * in contexts where we're not deriving the plan node from a path node.
1432  *
1433  *****************************************************************************/
1434
1435 static SeqScan *
1436 make_seqscan(List *qptlist,
1437                          List *qpqual,
1438                          Index scanrelid)
1439 {
1440         SeqScan    *node = makeNode(SeqScan);
1441         Plan       *plan = &node->plan;
1442
1443         /* cost should be inserted by caller */
1444         plan->targetlist = qptlist;
1445         plan->qual = qpqual;
1446         plan->lefttree = NULL;
1447         plan->righttree = NULL;
1448         node->scanrelid = scanrelid;
1449
1450         return node;
1451 }
1452
1453 static IndexScan *
1454 make_indexscan(List *qptlist,
1455                            List *qpqual,
1456                            Index scanrelid,
1457                            List *indxid,
1458                            List *indxqual,
1459                            List *indxqualorig,
1460                            ScanDirection indexscandir)
1461 {
1462         IndexScan  *node = makeNode(IndexScan);
1463         Plan       *plan = &node->scan.plan;
1464
1465         /* cost should be inserted by caller */
1466         plan->targetlist = qptlist;
1467         plan->qual = qpqual;
1468         plan->lefttree = NULL;
1469         plan->righttree = NULL;
1470         node->scan.scanrelid = scanrelid;
1471         node->indxid = indxid;
1472         node->indxqual = indxqual;
1473         node->indxqualorig = indxqualorig;
1474         node->indxorderdir = indexscandir;
1475
1476         return node;
1477 }
1478
1479 static TidScan *
1480 make_tidscan(List *qptlist,
1481                          List *qpqual,
1482                          Index scanrelid,
1483                          List *tideval)
1484 {
1485         TidScan    *node = makeNode(TidScan);
1486         Plan       *plan = &node->scan.plan;
1487
1488         /* cost should be inserted by caller */
1489         plan->targetlist = qptlist;
1490         plan->qual = qpqual;
1491         plan->lefttree = NULL;
1492         plan->righttree = NULL;
1493         node->scan.scanrelid = scanrelid;
1494         node->tideval = tideval;
1495
1496         return node;
1497 }
1498
1499 SubqueryScan *
1500 make_subqueryscan(List *qptlist,
1501                                   List *qpqual,
1502                                   Index scanrelid,
1503                                   Plan *subplan)
1504 {
1505         SubqueryScan *node = makeNode(SubqueryScan);
1506         Plan       *plan = &node->scan.plan;
1507
1508         /*
1509          * Cost is figured here for the convenience of prepunion.c.  Note this
1510          * is only correct for the case where qpqual is empty; otherwise caller
1511          * should overwrite cost with a better estimate.
1512          */
1513         copy_plan_costsize(plan, subplan);
1514         plan->total_cost += cpu_tuple_cost * subplan->plan_rows;
1515
1516         plan->targetlist = qptlist;
1517         plan->qual = qpqual;
1518         plan->lefttree = NULL;
1519         plan->righttree = NULL;
1520         node->scan.scanrelid = scanrelid;
1521         node->subplan = subplan;
1522
1523         return node;
1524 }
1525
1526 static FunctionScan *
1527 make_functionscan(List *qptlist,
1528                                   List *qpqual,
1529                                   Index scanrelid)
1530 {
1531         FunctionScan *node = makeNode(FunctionScan);
1532         Plan       *plan = &node->scan.plan;
1533
1534         /* cost should be inserted by caller */
1535         plan->targetlist = qptlist;
1536         plan->qual = qpqual;
1537         plan->lefttree = NULL;
1538         plan->righttree = NULL;
1539         node->scan.scanrelid = scanrelid;
1540
1541         return node;
1542 }
1543
1544 Append *
1545 make_append(List *appendplans, bool isTarget, List *tlist)
1546 {
1547         Append     *node = makeNode(Append);
1548         Plan       *plan = &node->plan;
1549         List       *subnode;
1550
1551         /*
1552          * Compute cost as sum of subplan costs.  We charge nothing extra for
1553          * the Append itself, which perhaps is too optimistic, but since it
1554          * doesn't do any selection or projection, it is a pretty cheap node.
1555          */
1556         plan->startup_cost = 0;
1557         plan->total_cost = 0;
1558         plan->plan_rows = 0;
1559         plan->plan_width = 0;
1560         foreach(subnode, appendplans)
1561         {
1562                 Plan       *subplan = (Plan *) lfirst(subnode);
1563
1564                 if (subnode == appendplans)             /* first node? */
1565                         plan->startup_cost = subplan->startup_cost;
1566                 plan->total_cost += subplan->total_cost;
1567                 plan->plan_rows += subplan->plan_rows;
1568                 if (plan->plan_width < subplan->plan_width)
1569                         plan->plan_width = subplan->plan_width;
1570         }
1571
1572         plan->targetlist = tlist;
1573         plan->qual = NIL;
1574         plan->lefttree = NULL;
1575         plan->righttree = NULL;
1576         node->appendplans = appendplans;
1577         node->isTarget = isTarget;
1578
1579         return node;
1580 }
1581
1582 static NestLoop *
1583 make_nestloop(List *tlist,
1584                           List *joinclauses,
1585                           List *otherclauses,
1586                           Plan *lefttree,
1587                           Plan *righttree,
1588                           JoinType jointype)
1589 {
1590         NestLoop   *node = makeNode(NestLoop);
1591         Plan       *plan = &node->join.plan;
1592
1593         /* cost should be inserted by caller */
1594         plan->targetlist = tlist;
1595         plan->qual = otherclauses;
1596         plan->lefttree = lefttree;
1597         plan->righttree = righttree;
1598         node->join.jointype = jointype;
1599         node->join.joinqual = joinclauses;
1600
1601         return node;
1602 }
1603
1604 static HashJoin *
1605 make_hashjoin(List *tlist,
1606                           List *joinclauses,
1607                           List *otherclauses,
1608                           List *hashclauses,
1609                           Plan *lefttree,
1610                           Plan *righttree,
1611                           JoinType jointype)
1612 {
1613         HashJoin   *node = makeNode(HashJoin);
1614         Plan       *plan = &node->join.plan;
1615
1616         /* cost should be inserted by caller */
1617         plan->targetlist = tlist;
1618         plan->qual = otherclauses;
1619         plan->lefttree = lefttree;
1620         plan->righttree = righttree;
1621         node->hashclauses = hashclauses;
1622         node->join.jointype = jointype;
1623         node->join.joinqual = joinclauses;
1624
1625         return node;
1626 }
1627
1628 static Hash *
1629 make_hash(List *tlist, List *hashkeys, Plan *lefttree)
1630 {
1631         Hash       *node = makeNode(Hash);
1632         Plan       *plan = &node->plan;
1633
1634         copy_plan_costsize(plan, lefttree);
1635
1636         /*
1637          * For plausibility, make startup & total costs equal total cost of
1638          * input plan; this only affects EXPLAIN display not decisions.
1639          */
1640         plan->startup_cost = plan->total_cost;
1641         plan->targetlist = tlist;
1642         plan->qual = NIL;
1643         plan->lefttree = lefttree;
1644         plan->righttree = NULL;
1645         node->hashkeys = hashkeys;
1646
1647         return node;
1648 }
1649
1650 static MergeJoin *
1651 make_mergejoin(List *tlist,
1652                            List *joinclauses,
1653                            List *otherclauses,
1654                            List *mergeclauses,
1655                            Plan *lefttree,
1656                            Plan *righttree,
1657                            JoinType jointype)
1658 {
1659         MergeJoin  *node = makeNode(MergeJoin);
1660         Plan       *plan = &node->join.plan;
1661
1662         /* cost should be inserted by caller */
1663         plan->targetlist = tlist;
1664         plan->qual = otherclauses;
1665         plan->lefttree = lefttree;
1666         plan->righttree = righttree;
1667         node->mergeclauses = mergeclauses;
1668         node->join.jointype = jointype;
1669         node->join.joinqual = joinclauses;
1670
1671         return node;
1672 }
1673
1674 /*
1675  * make_sort --- basic routine to build a Sort plan node
1676  *
1677  * Caller must have built the sortColIdx and sortOperators arrays already.
1678  */
1679 static Sort *
1680 make_sort(Query *root, List *tlist, Plan *lefttree, int numCols,
1681                   AttrNumber *sortColIdx, Oid *sortOperators)
1682 {
1683         Sort       *node = makeNode(Sort);
1684         Plan       *plan = &node->plan;
1685         Path            sort_path;              /* dummy for result of cost_sort */
1686
1687         copy_plan_costsize(plan, lefttree); /* only care about copying size */
1688         cost_sort(&sort_path, root, NIL,
1689                           lefttree->total_cost,
1690                           lefttree->plan_rows,
1691                           lefttree->plan_width);
1692         plan->startup_cost = sort_path.startup_cost;
1693         plan->total_cost = sort_path.total_cost;
1694         plan->targetlist = tlist;
1695         plan->qual = NIL;
1696         plan->lefttree = lefttree;
1697         plan->righttree = NULL;
1698         node->numCols = numCols;
1699         node->sortColIdx = sortColIdx;
1700         node->sortOperators = sortOperators;
1701
1702         return node;
1703 }
1704
1705 /*
1706  * add_sort_column --- utility subroutine for building sort info arrays
1707  *
1708  * We need this routine because the same column might be selected more than
1709  * once as a sort key column; if so, the extra mentions are redundant.
1710  *
1711  * Caller is assumed to have allocated the arrays large enough for the
1712  * max possible number of columns.  Return value is the new column count.
1713  */
1714 static int
1715 add_sort_column(AttrNumber colIdx, Oid sortOp,
1716                                 int numCols, AttrNumber *sortColIdx, Oid *sortOperators)
1717 {
1718         int                     i;
1719
1720         for (i = 0; i < numCols; i++)
1721         {
1722                 if (sortColIdx[i] == colIdx)
1723                 {
1724                         /* Already sorting by this col, so extra sort key is useless */
1725                         return numCols;
1726                 }
1727         }
1728
1729         /* Add the column */
1730         sortColIdx[numCols] = colIdx;
1731         sortOperators[numCols] = sortOp;
1732         return numCols + 1;
1733 }
1734
1735 /*
1736  * make_sort_from_pathkeys
1737  *        Create sort plan to sort according to given pathkeys
1738  *
1739  *        'lefttree' is the node which yields input tuples
1740  *        'relids' is the set of relids represented by the input node
1741  *        'pathkeys' is the list of pathkeys by which the result is to be sorted
1742  *
1743  * We must convert the pathkey information into arrays of sort key column
1744  * numbers and sort operator OIDs.
1745  *
1746  * If the pathkeys include expressions that aren't simple Vars, we will
1747  * usually need to add resjunk items to the input plan's targetlist to
1748  * compute these expressions (since the Sort node itself won't do it).
1749  * If the input plan type isn't one that can do projections, this means
1750  * adding a Result node just to do the projection.
1751  */
1752 static Sort *
1753 make_sort_from_pathkeys(Query *root, Plan *lefttree,
1754                                                 Relids relids, List *pathkeys)
1755 {
1756         List       *tlist = lefttree->targetlist;
1757         List       *sort_tlist;
1758         List       *i;
1759         int                     numsortkeys;
1760         AttrNumber *sortColIdx;
1761         Oid                *sortOperators;
1762
1763         /* We will need at most length(pathkeys) sort columns; possibly less */
1764         numsortkeys = length(pathkeys);
1765         sortColIdx = (AttrNumber *) palloc(numsortkeys * sizeof(AttrNumber));
1766         sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));
1767
1768         numsortkeys = 0;
1769
1770         foreach(i, pathkeys)
1771         {
1772                 List       *keysublist = (List *) lfirst(i);
1773                 PathKeyItem *pathkey = NULL;
1774                 Resdom     *resdom = NULL;
1775                 List       *j;
1776
1777                 /*
1778                  * We can sort by any one of the sort key items listed in this
1779                  * sublist.  For now, we take the first one that corresponds to an
1780                  * available Var in the tlist.  If there isn't any, use the
1781                  * first one that is an expression in the input's vars.
1782                  *
1783                  * XXX if we have a choice, is there any way of figuring out which
1784                  * might be cheapest to execute?  (For example, int4lt is likely
1785                  * much cheaper to execute than numericlt, but both might appear
1786                  * in the same pathkey sublist...)      Not clear that we ever will
1787                  * have a choice in practice, so it may not matter.
1788                  */
1789                 foreach(j, keysublist)
1790                 {
1791                         pathkey = lfirst(j);
1792                         Assert(IsA(pathkey, PathKeyItem));
1793                         resdom = tlist_member(pathkey->key, tlist);
1794                         if (resdom)
1795                                 break;
1796                 }
1797                 if (!resdom)
1798                 {
1799                         /* No matching Var; look for an expression */
1800                         foreach(j, keysublist)
1801                         {
1802                                 pathkey = lfirst(j);
1803                                 if (bms_is_subset(pull_varnos(pathkey->key), relids))
1804                                         break;
1805                         }
1806                         if (!j)
1807                                 elog(ERROR, "make_sort_from_pathkeys: cannot find pathkey item to sort");
1808                         /*
1809                          * Do we need to insert a Result node?
1810                          *
1811                          * Currently, the only non-projection-capable plan type
1812                          * we can see here is Append.
1813                          */
1814                         if (IsA(lefttree, Append))
1815                         {
1816                                 tlist = copyObject(tlist);
1817                                 lefttree = (Plan *) make_result(tlist, NULL, lefttree);
1818                         }
1819                         /*
1820                          * Add resjunk entry to input's tlist
1821                          */
1822                         resdom = makeResdom(length(tlist) + 1,
1823                                                                 exprType(pathkey->key),
1824                                                                 exprTypmod(pathkey->key),
1825                                                                 NULL,
1826                                                                 true);
1827                         tlist = lappend(tlist,
1828                                                         makeTargetEntry(resdom,
1829                                                                                         (Expr *) pathkey->key));
1830                         lefttree->targetlist = tlist; /* just in case NIL before */
1831                 }
1832                 /*
1833                  * The column might already be selected as a sort key, if the
1834                  * pathkeys contain duplicate entries.  (This can happen in
1835                  * scenarios where multiple mergejoinable clauses mention the same
1836                  * var, for example.)  So enter it only once in the sort arrays.
1837                  */
1838                 numsortkeys = add_sort_column(resdom->resno, pathkey->sortop,
1839                                                                           numsortkeys, sortColIdx, sortOperators);
1840         }
1841
1842         Assert(numsortkeys > 0);
1843
1844         /* Give Sort node its own copy of the tlist (still necessary?) */
1845         sort_tlist = copyObject(tlist);
1846
1847         return make_sort(root, sort_tlist, lefttree, numsortkeys,
1848                                          sortColIdx, sortOperators);
1849 }
1850
1851 /*
1852  * make_sort_from_sortclauses
1853  *        Create sort plan to sort according to given sortclauses
1854  *
1855  *        'tlist' is the targetlist
1856  *        'lefttree' is the node which yields input tuples
1857  *        'sortcls' is a list of SortClauses
1858  */
1859 Sort *
1860 make_sort_from_sortclauses(Query *root, List *tlist,
1861                                                    Plan *lefttree, List *sortcls)
1862 {
1863         List       *sort_tlist;
1864         List       *i;
1865         int                     numsortkeys;
1866         AttrNumber *sortColIdx;
1867         Oid                *sortOperators;
1868
1869         /* We will need at most length(sortcls) sort columns; possibly less */
1870         numsortkeys = length(sortcls);
1871         sortColIdx = (AttrNumber *) palloc(numsortkeys * sizeof(AttrNumber));
1872         sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));
1873
1874         numsortkeys = 0;
1875
1876         foreach(i, sortcls)
1877         {
1878                 SortClause *sortcl = (SortClause *) lfirst(i);
1879                 TargetEntry *tle = get_sortgroupclause_tle(sortcl, tlist);
1880                 Resdom     *resdom = tle->resdom;
1881
1882                 /*
1883                  * Check for the possibility of duplicate order-by clauses --- the
1884                  * parser should have removed 'em, but no point in sorting redundantly.
1885                  */
1886                 numsortkeys = add_sort_column(resdom->resno, sortcl->sortop,
1887                                                                           numsortkeys, sortColIdx, sortOperators);
1888         }
1889
1890         Assert(numsortkeys > 0);
1891
1892         /* Give Sort node its own copy of the tlist (still necessary?) */
1893         sort_tlist = copyObject(tlist);
1894
1895         return make_sort(root, sort_tlist, lefttree, numsortkeys,
1896                                          sortColIdx, sortOperators);
1897 }
1898
1899 /*
1900  * make_sort_from_groupcols
1901  *        Create sort plan to sort based on grouping columns
1902  *
1903  * 'groupcls' is the list of GroupClauses
1904  * 'grpColIdx' gives the column numbers to use
1905  *
1906  * This might look like it could be merged with make_sort_from_sortclauses,
1907  * but presently we *must* use the grpColIdx[] array to locate sort columns,
1908  * because the child plan's tlist is not marked with ressortgroupref info
1909  * appropriate to the grouping node.  So, only the sortop is used from the
1910  * GroupClause entries.
1911  */
1912 Sort *
1913 make_sort_from_groupcols(Query *root,
1914                                                  List *groupcls,
1915                                                  AttrNumber *grpColIdx,
1916                                                  Plan *lefttree)
1917 {
1918         List       *sub_tlist = lefttree->targetlist;
1919         List       *sort_tlist;
1920         int                     grpno = 0;
1921         List       *i;
1922         int                     numsortkeys;
1923         AttrNumber *sortColIdx;
1924         Oid                *sortOperators;
1925
1926         /* We will need at most length(groupcls) sort columns; possibly less */
1927         numsortkeys = length(groupcls);
1928         sortColIdx = (AttrNumber *) palloc(numsortkeys * sizeof(AttrNumber));
1929         sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));
1930
1931         numsortkeys = 0;
1932
1933         foreach(i, groupcls)
1934         {
1935                 GroupClause *grpcl = (GroupClause *) lfirst(i);
1936                 TargetEntry *tle = nth(grpColIdx[grpno] - 1, sub_tlist);
1937                 Resdom     *resdom = tle->resdom;
1938
1939                 /*
1940                  * Check for the possibility of duplicate group-by clauses --- the
1941                  * parser should have removed 'em, but no point in sorting redundantly.
1942                  */
1943                 numsortkeys = add_sort_column(resdom->resno, grpcl->sortop,
1944                                                                           numsortkeys, sortColIdx, sortOperators);
1945                 grpno++;
1946         }
1947
1948         Assert(numsortkeys > 0);
1949
1950         /* Give Sort node its own copy of the tlist (still necessary?) */
1951         sort_tlist = copyObject(sub_tlist);
1952
1953         return make_sort(root, sort_tlist, lefttree, numsortkeys,
1954                                          sortColIdx, sortOperators);
1955 }
1956
1957 Material *
1958 make_material(List *tlist, Plan *lefttree)
1959 {
1960         Material   *node = makeNode(Material);
1961         Plan       *plan = &node->plan;
1962
1963         /* cost should be inserted by caller */
1964         plan->targetlist = tlist;
1965         plan->qual = NIL;
1966         plan->lefttree = lefttree;
1967         plan->righttree = NULL;
1968
1969         return node;
1970 }
1971
1972 /*
1973  * materialize_finished_plan: stick a Material node atop a completed plan
1974  *
1975  * There are a couple of places where we want to attach a Material node
1976  * after completion of subquery_planner().  This currently requires hackery.
1977  * Since subquery_planner has already run SS_finalize_plan on the subplan
1978  * tree, we have to kluge up parameter lists for the Material node.
1979  * Possibly this could be fixed by postponing SS_finalize_plan processing
1980  * until setrefs.c is run?
1981  */
1982 Plan *
1983 materialize_finished_plan(Plan *subplan)
1984 {
1985         Plan       *matplan;
1986         Path            matpath;                /* dummy for result of cost_material */
1987
1988         matplan = (Plan *) make_material(subplan->targetlist, subplan);
1989
1990         /* Set cost data */
1991         cost_material(&matpath,
1992                                   subplan->total_cost,
1993                                   subplan->plan_rows,
1994                                   subplan->plan_width);
1995         matplan->startup_cost = matpath.startup_cost;
1996         matplan->total_cost = matpath.total_cost;
1997         matplan->plan_rows = subplan->plan_rows;
1998         matplan->plan_width = subplan->plan_width;
1999
2000         /* parameter kluge --- see comments above */
2001         matplan->extParam = bms_copy(subplan->extParam);
2002         matplan->allParam = bms_copy(subplan->allParam);
2003
2004         return matplan;
2005 }
2006
2007 Agg *
2008 make_agg(Query *root, List *tlist, List *qual,
2009                  AggStrategy aggstrategy,
2010                  int numGroupCols, AttrNumber *grpColIdx,
2011                  long numGroups, int numAggs,
2012                  Plan *lefttree)
2013 {
2014         Agg                *node = makeNode(Agg);
2015         Plan       *plan = &node->plan;
2016         Path            agg_path;               /* dummy for result of cost_agg */
2017         QualCost        qual_cost;
2018
2019         node->aggstrategy = aggstrategy;
2020         node->numCols = numGroupCols;
2021         node->grpColIdx = grpColIdx;
2022         node->numGroups = numGroups;
2023
2024         copy_plan_costsize(plan, lefttree); /* only care about copying size */
2025         cost_agg(&agg_path, root,
2026                          aggstrategy, numAggs,
2027                          numGroupCols, numGroups,
2028                          lefttree->startup_cost,
2029                          lefttree->total_cost,
2030                          lefttree->plan_rows);
2031         plan->startup_cost = agg_path.startup_cost;
2032         plan->total_cost = agg_path.total_cost;
2033
2034         /*
2035          * We will produce a single output tuple if not grouping,
2036          * and a tuple per group otherwise.
2037          */
2038         if (aggstrategy == AGG_PLAIN)
2039                 plan->plan_rows = 1;
2040         else
2041                 plan->plan_rows = numGroups;
2042
2043         /*
2044          * We also need to account for the cost of evaluation of the qual
2045          * (ie, the HAVING clause) and the tlist.  Note that cost_qual_eval
2046          * doesn't charge anything for Aggref nodes; this is okay since
2047          * they are really comparable to Vars.
2048          *
2049          * See notes in grouping_planner about why this routine and make_group
2050          * are the only ones in this file that worry about tlist eval cost.
2051          */
2052         if (qual)
2053         {
2054                 cost_qual_eval(&qual_cost, qual);
2055                 plan->startup_cost += qual_cost.startup;
2056                 plan->total_cost += qual_cost.startup;
2057                 plan->total_cost += qual_cost.per_tuple * plan->plan_rows;
2058         }
2059         cost_qual_eval(&qual_cost, tlist);
2060         plan->startup_cost += qual_cost.startup;
2061         plan->total_cost += qual_cost.startup;
2062         plan->total_cost += qual_cost.per_tuple * plan->plan_rows;
2063
2064         plan->qual = qual;
2065         plan->targetlist = tlist;
2066         plan->lefttree = lefttree;
2067         plan->righttree = (Plan *) NULL;
2068
2069         return node;
2070 }
2071
2072 Group *
2073 make_group(Query *root,
2074                    List *tlist,
2075                    int numGroupCols,
2076                    AttrNumber *grpColIdx,
2077                    double numGroups,
2078                    Plan *lefttree)
2079 {
2080         Group      *node = makeNode(Group);
2081         Plan       *plan = &node->plan;
2082         Path            group_path;             /* dummy for result of cost_group */
2083         QualCost        qual_cost;
2084
2085         node->numCols = numGroupCols;
2086         node->grpColIdx = grpColIdx;
2087
2088         copy_plan_costsize(plan, lefttree); /* only care about copying size */
2089         cost_group(&group_path, root,
2090                            numGroupCols, numGroups,
2091                            lefttree->startup_cost,
2092                            lefttree->total_cost,
2093                            lefttree->plan_rows);
2094         plan->startup_cost = group_path.startup_cost;
2095         plan->total_cost = group_path.total_cost;
2096
2097         /* One output tuple per estimated result group */
2098         plan->plan_rows = numGroups;
2099
2100         /*
2101          * We also need to account for the cost of evaluation of the tlist.
2102          *
2103          * XXX this double-counts the cost of evaluation of any expressions
2104          * used for grouping, since in reality those will have been evaluated
2105          * at a lower plan level and will only be copied by the Group node.
2106          * Worth fixing?
2107          *
2108          * See notes in grouping_planner about why this routine and make_agg
2109          * are the only ones in this file that worry about tlist eval cost.
2110          */
2111         cost_qual_eval(&qual_cost, tlist);
2112         plan->startup_cost += qual_cost.startup;
2113         plan->total_cost += qual_cost.startup;
2114         plan->total_cost += qual_cost.per_tuple * plan->plan_rows;
2115
2116         plan->qual = NIL;
2117         plan->targetlist = tlist;
2118         plan->lefttree = lefttree;
2119         plan->righttree = (Plan *) NULL;
2120
2121         return node;
2122 }
2123
2124 /*
2125  * distinctList is a list of SortClauses, identifying the targetlist items
2126  * that should be considered by the Unique filter.
2127  */
2128 Unique *
2129 make_unique(List *tlist, Plan *lefttree, List *distinctList)
2130 {
2131         Unique     *node = makeNode(Unique);
2132         Plan       *plan = &node->plan;
2133         int                     numCols = length(distinctList);
2134         int                     keyno = 0;
2135         AttrNumber *uniqColIdx;
2136         List       *slitem;
2137
2138         copy_plan_costsize(plan, lefttree);
2139
2140         /*
2141          * Charge one cpu_operator_cost per comparison per input tuple. We
2142          * assume all columns get compared at most of the tuples.  (XXX probably
2143          * this is an overestimate.)
2144          */
2145         plan->total_cost += cpu_operator_cost * plan->plan_rows * numCols;
2146
2147         /*
2148          * plan->plan_rows is left as a copy of the input subplan's plan_rows;
2149          * ie, we assume the filter removes nothing.  The caller must alter this
2150          * if he has a better idea.
2151          */
2152
2153         plan->targetlist = tlist;
2154         plan->qual = NIL;
2155         plan->lefttree = lefttree;
2156         plan->righttree = NULL;
2157
2158         /*
2159          * convert SortClause list into array of attr indexes, as wanted by
2160          * exec
2161          */
2162         Assert(numCols > 0);
2163         uniqColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numCols);
2164
2165         foreach(slitem, distinctList)
2166         {
2167                 SortClause *sortcl = (SortClause *) lfirst(slitem);
2168                 TargetEntry *tle = get_sortgroupclause_tle(sortcl, tlist);
2169
2170                 uniqColIdx[keyno++] = tle->resdom->resno;
2171         }
2172
2173         node->numCols = numCols;
2174         node->uniqColIdx = uniqColIdx;
2175
2176         return node;
2177 }
2178
2179 /*
2180  * distinctList is a list of SortClauses, identifying the targetlist items
2181  * that should be considered by the SetOp filter.
2182  */
2183
2184 SetOp *
2185 make_setop(SetOpCmd cmd, List *tlist, Plan *lefttree,
2186                    List *distinctList, AttrNumber flagColIdx)
2187 {
2188         SetOp      *node = makeNode(SetOp);
2189         Plan       *plan = &node->plan;
2190         int                     numCols = length(distinctList);
2191         int                     keyno = 0;
2192         AttrNumber *dupColIdx;
2193         List       *slitem;
2194
2195         copy_plan_costsize(plan, lefttree);
2196
2197         /*
2198          * Charge one cpu_operator_cost per comparison per input tuple. We
2199          * assume all columns get compared at most of the tuples.
2200          */
2201         plan->total_cost += cpu_operator_cost * plan->plan_rows * numCols;
2202
2203         /*
2204          * We make the unsupported assumption that there will be 10% as many
2205          * tuples out as in.  Any way to do better?
2206          */
2207         plan->plan_rows *= 0.1;
2208         if (plan->plan_rows < 1)
2209                 plan->plan_rows = 1;
2210
2211         plan->targetlist = tlist;
2212         plan->qual = NIL;
2213         plan->lefttree = lefttree;
2214         plan->righttree = NULL;
2215
2216         /*
2217          * convert SortClause list into array of attr indexes, as wanted by
2218          * exec
2219          */
2220         Assert(numCols > 0);
2221         dupColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numCols);
2222
2223         foreach(slitem, distinctList)
2224         {
2225                 SortClause *sortcl = (SortClause *) lfirst(slitem);
2226                 TargetEntry *tle = get_sortgroupclause_tle(sortcl, tlist);
2227
2228                 dupColIdx[keyno++] = tle->resdom->resno;
2229         }
2230
2231         node->cmd = cmd;
2232         node->numCols = numCols;
2233         node->dupColIdx = dupColIdx;
2234         node->flagColIdx = flagColIdx;
2235
2236         return node;
2237 }
2238
2239 Limit *
2240 make_limit(List *tlist, Plan *lefttree,
2241                    Node *limitOffset, Node *limitCount)
2242 {
2243         Limit      *node = makeNode(Limit);
2244         Plan       *plan = &node->plan;
2245
2246         copy_plan_costsize(plan, lefttree);
2247
2248         /*
2249          * If offset/count are constants, adjust the output rows count and
2250          * costs accordingly.  This is only a cosmetic issue if we are at top
2251          * level, but if we are building a subquery then it's important to
2252          * report correct info to the outer planner.
2253          */
2254         if (limitOffset && IsA(limitOffset, Const))
2255         {
2256                 Const      *limito = (Const *) limitOffset;
2257                 int32           offset = DatumGetInt32(limito->constvalue);
2258
2259                 if (!limito->constisnull && offset > 0)
2260                 {
2261                         if (offset > plan->plan_rows)
2262                                 offset = (int32) plan->plan_rows;
2263                         if (plan->plan_rows > 0)
2264                                 plan->startup_cost +=
2265                                         (plan->total_cost - plan->startup_cost)
2266                                         * ((double) offset) / plan->plan_rows;
2267                         plan->plan_rows -= offset;
2268                         if (plan->plan_rows < 1)
2269                                 plan->plan_rows = 1;
2270                 }
2271         }
2272         if (limitCount && IsA(limitCount, Const))
2273         {
2274                 Const      *limitc = (Const *) limitCount;
2275                 int32           count = DatumGetInt32(limitc->constvalue);
2276
2277                 if (!limitc->constisnull && count >= 0)
2278                 {
2279                         if (count > plan->plan_rows)
2280                                 count = (int32) plan->plan_rows;
2281                         if (plan->plan_rows > 0)
2282                                 plan->total_cost = plan->startup_cost +
2283                                         (plan->total_cost - plan->startup_cost)
2284                                         * ((double) count) / plan->plan_rows;
2285                         plan->plan_rows = count;
2286                         if (plan->plan_rows < 1)
2287                                 plan->plan_rows = 1;
2288                 }
2289         }
2290
2291         plan->targetlist = tlist;
2292         plan->qual = NIL;
2293         plan->lefttree = lefttree;
2294         plan->righttree = NULL;
2295
2296         node->limitOffset = limitOffset;
2297         node->limitCount = limitCount;
2298
2299         return node;
2300 }
2301
2302 Result *
2303 make_result(List *tlist,
2304                         Node *resconstantqual,
2305                         Plan *subplan)
2306 {
2307         Result     *node = makeNode(Result);
2308         Plan       *plan = &node->plan;
2309
2310         if (subplan)
2311                 copy_plan_costsize(plan, subplan);
2312         else
2313         {
2314                 plan->startup_cost = 0;
2315                 plan->total_cost = cpu_tuple_cost;
2316                 plan->plan_rows = 1;    /* wrong if we have a set-valued function? */
2317                 plan->plan_width = 0;   /* XXX try to be smarter? */
2318         }
2319
2320         if (resconstantqual)
2321         {
2322                 QualCost        qual_cost;
2323
2324                 cost_qual_eval(&qual_cost, (List *) resconstantqual);
2325                 /* resconstantqual is evaluated once at startup */
2326                 plan->startup_cost += qual_cost.startup + qual_cost.per_tuple;
2327                 plan->total_cost += qual_cost.startup + qual_cost.per_tuple;
2328         }
2329
2330         plan->targetlist = tlist;
2331         plan->qual = NIL;
2332         plan->lefttree = subplan;
2333         plan->righttree = NULL;
2334         node->resconstantqual = resconstantqual;
2335
2336         return node;
2337 }