OSDN Git Service

580675a85b70b05c24e3496b81983c952a1da258
[pg-rex/syncrep.git] / src / backend / optimizer / path / pathkeys.c
1 /*-------------------------------------------------------------------------
2  *
3  * pathkeys.c
4  *        Utilities for matching and building path keys
5  *
6  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $Header: /cvsroot/pgsql/src/backend/optimizer/path/pathkeys.c,v 1.21 2000/04/12 17:15:20 momjian Exp $
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include "postgres.h"
16
17 #include "nodes/makefuncs.h"
18 #include "optimizer/clauses.h"
19 #include "optimizer/joininfo.h"
20 #include "optimizer/pathnode.h"
21 #include "optimizer/paths.h"
22 #include "optimizer/tlist.h"
23 #include "optimizer/var.h"
24 #include "parser/parsetree.h"
25 #include "parser/parse_func.h"
26 #include "utils/lsyscache.h"
27
28 static PathKeyItem *makePathKeyItem(Node *key, Oid sortop);
29 static List *make_canonical_pathkey(Query *root, PathKeyItem *item);
30 static Var *find_indexkey_var(Query *root, RelOptInfo *rel,
31                                   AttrNumber varattno);
32
33
34 /*--------------------
35  *      Explanation of Path.pathkeys
36  *
37  *      Path.pathkeys is a List of Lists of PathKeyItem nodes that represent
38  *      the sort order of the result generated by the Path.  The n'th sublist
39  *      represents the n'th sort key of the result.
40  *
41  *      In single/base relation RelOptInfo's, the Paths represent various ways
42  *      of scanning the relation and the resulting ordering of the tuples.
43  *      Sequential scan Paths have NIL pathkeys, indicating no known ordering.
44  *      Index scans have Path.pathkeys that represent the chosen index's ordering,
45  *      if any.  A single-key index would create a pathkey with a single sublist,
46  *      e.g. ( (tab1.indexkey1/sortop1) ).      A multi-key index generates a sublist
47  *      per key, e.g. ( (tab1.indexkey1/sortop1) (tab1.indexkey2/sortop2) ) which
48  *      shows major sort by indexkey1 (ordering by sortop1) and minor sort by
49  *      indexkey2 with sortop2.
50  *
51  *      Note that a multi-pass indexscan (OR clause scan) has NIL pathkeys since
52  *      we can say nothing about the overall order of its result.  Also, an
53  *      indexscan on an unordered type of index generates NIL pathkeys.  However,
54  *      we can always create a pathkey by doing an explicit sort.  The pathkeys
55  *      for a sort plan's output just represent the sort key fields and the
56  *      ordering operators used.
57  *
58  *      Things get more interesting when we consider joins.  Suppose we do a
59  *      mergejoin between A and B using the mergeclause A.X = B.Y.      The output
60  *      of the mergejoin is sorted by X --- but it is also sorted by Y.  We
61  *      represent this fact by listing both keys in a single pathkey sublist:
62  *      ( (A.X/xsortop B.Y/ysortop) ).  This pathkey asserts that the major
63  *      sort order of the Path can be taken to be *either* A.X or B.Y.
64  *      They are equal, so they are both primary sort keys.  By doing this,
65  *      we allow future joins to use either var as a pre-sorted key, so upper
66  *      Mergejoins may be able to avoid having to re-sort the Path.  This is
67  *      why pathkeys is a List of Lists.
68  *
69  *      We keep a sortop associated with each PathKeyItem because cross-data-type
70  *      mergejoins are possible; for example int4 = int8 is mergejoinable.
71  *      In this case we need to remember that the left var is ordered by int4lt
72  *      while the right var is ordered by int8lt.  So the different members of
73  *      each sublist could have different sortops.
74  *
75  *      Note that while the order of the top list is meaningful (primary vs.
76  *      secondary sort key), the order of each sublist is arbitrary.  Each sublist
77  *      should be regarded as a set of equivalent keys, with no significance
78  *      to the list order.
79  *
80  *      With a little further thought, it becomes apparent that pathkeys for
81  *      joins need not only come from mergejoins.  For example, if we do a
82  *      nestloop join between outer relation A and inner relation B, then any
83  *      pathkeys relevant to A are still valid for the join result: we have
84  *      not altered the order of the tuples from A.  Even more interesting,
85  *      if there was a mergeclause (more formally, an "equijoin clause") A.X=B.Y,
86  *      and A.X was a pathkey for the outer relation A, then we can assert that
87  *      B.Y is a pathkey for the join result; X was ordered before and still is,
88  *      and the joined values of Y are equal to the joined values of X, so Y
89  *      must now be ordered too.  This is true even though we used no mergejoin.
90  *
91  *      More generally, whenever we have an equijoin clause A.X = B.Y and a
92  *      pathkey A.X, we can add B.Y to that pathkey if B is part of the joined
93  *      relation the pathkey is for, *no matter how we formed the join*.
94  *
95  *      In short, then: when producing the pathkeys for a merge or nestloop join,
96  *      we can keep all of the keys of the outer path, since the ordering of the
97  *      outer path will be preserved in the result.  Furthermore, we can add to
98  *      each pathkey sublist any inner vars that are equijoined to any of the
99  *      outer vars in the sublist; this works regardless of whether we are
100  *      implementing the join using that equijoin clause as a mergeclause,
101  *      or merely enforcing the clause after-the-fact as a qpqual filter.
102  *
103  *      Although Hashjoins also work only with equijoin operators, it is *not*
104  *      safe to consider the output of a Hashjoin to be sorted in any particular
105  *      order --- not even the outer path's order.  This is true because the
106  *      executor might have to split the join into multiple batches.  Therefore
107  *      a Hashjoin is always given NIL pathkeys.  (Also, we need to use only
108  *      mergejoinable operators when deducing which inner vars are now sorted,
109  *      because a mergejoin operator tells us which left- and right-datatype
110  *      sortops can be considered equivalent, whereas a hashjoin operator
111  *      doesn't imply anything about sort order.)
112  *
113  *      Pathkeys are also useful to represent an ordering that we wish to achieve,
114  *      since they are easily compared to the pathkeys of a potential candidate
115  *      path.  So, SortClause lists are turned into pathkeys lists for use inside
116  *      the optimizer.
117  *
118  *      OK, now for how it *really* works:
119  *
120  *      We did implement pathkeys just as described above, and found that the
121  *      planner spent a huge amount of time comparing pathkeys, because the
122  *      representation of pathkeys as unordered lists made it expensive to decide
123  *      whether two were equal or not.  So, we've modified the representation
124  *      as described next.
125  *
126  *      If we scan the WHERE clause for equijoin clauses (mergejoinable clauses)
127  *      during planner startup, we can construct lists of equivalent pathkey items
128  *      for the query.  There could be more than two items per equivalence set;
129  *      for example, WHERE A.X = B.Y AND B.Y = C.Z AND D.R = E.S creates the
130  *      equivalence sets { A.X B.Y C.Z } and { D.R E.S } (plus associated sortops).
131  *      Any pathkey item that belongs to an equivalence set implies that all the
132  *      other items in its set apply to the relation too, or at least all the ones
133  *      that are for fields present in the relation.  (Some of the items in the
134  *      set might be for as-yet-unjoined relations.)  Furthermore, any multi-item
135  *      pathkey sublist that appears at any stage of planning the query *must* be
136  *      a subset of one or another of these equivalence sets; there's no way we'd
137  *      have put two items in the same pathkey sublist unless they were equijoined
138  *      in WHERE.
139  *
140  *      Now suppose that we allow a pathkey sublist to contain pathkey items for
141  *      vars that are not yet part of the pathkey's relation.  This introduces
142  *      no logical difficulty, because such items can easily be seen to be
143  *      irrelevant; we just mandate that they be ignored.  But having allowed
144  *      this, we can declare (by fiat) that any multiple-item pathkey sublist
145  *      must be equal() to the appropriate equivalence set.  In effect, whenever
146  *      we make a pathkey sublist that mentions any var appearing in an
147  *      equivalence set, we instantly add all the other vars equivalenced to it,
148  *      whether they appear yet in the pathkey's relation or not.  And we also
149  *      mandate that the pathkey sublist appear in the same order as the
150  *      equivalence set it comes from.  (In practice, we simply return a pointer
151  *      to the relevant equivalence set without building any new sublist at all.)
152  *      This makes comparing pathkeys very simple and fast, and saves a lot of
153  *      work and memory space for pathkey construction as well.
154  *
155  *      Note that pathkey sublists having just one item still exist, and are
156  *      not expected to be equal() to any equivalence set.      This occurs when
157  *      we describe a sort order that involves a var that's not mentioned in
158  *      any equijoin clause of the WHERE.  We could add singleton sets containing
159  *      such vars to the query's list of equivalence sets, but there's little
160  *      point in doing so.
161  *
162  *      By the way, it's OK and even useful for us to build equivalence sets
163  *      that mention multiple vars from the same relation.      For example, if
164  *      we have WHERE A.X = A.Y and we are scanning A using an index on X,
165  *      we can legitimately conclude that the path is sorted by Y as well;
166  *      and this could be handy if Y is the variable used in other join clauses
167  *      or ORDER BY.  So, any WHERE clause with a mergejoinable operator can
168  *      contribute to an equivalence set, even if it's not a join clause.
169  *
170  *      -- bjm & tgl
171  *--------------------
172  */
173
174
175 /*
176  * makePathKeyItem
177  *              create a PathKeyItem node
178  */
179 static PathKeyItem *
180 makePathKeyItem(Node *key, Oid sortop)
181 {
182         PathKeyItem *item = makeNode(PathKeyItem);
183
184         item->key = key;
185         item->sortop = sortop;
186         return item;
187 }
188
189 /*
190  * add_equijoined_keys
191  *        The given clause has a mergejoinable operator, so its two sides
192  *        can be considered equal after restriction clause application; in
193  *        particular, any pathkey mentioning one side (with the correct sortop)
194  *        can be expanded to include the other as well.  Record the vars and
195  *        associated sortops in the query's equi_key_list for future use.
196  *
197  * The query's equi_key_list field points to a list of sublists of PathKeyItem
198  * nodes, where each sublist is a set of two or more vars+sortops that have
199  * been identified as logically equivalent (and, therefore, we may consider
200  * any two in a set to be equal).  As described above, we will subsequently
201  * use direct pointers to one of these sublists to represent any pathkey
202  * that involves an equijoined variable.
203  *
204  * This code would actually work fine with expressions more complex than
205  * a single Var, but currently it won't see any because check_mergejoinable
206  * won't accept such clauses as mergejoinable.
207  */
208 void
209 add_equijoined_keys(Query *root, RestrictInfo *restrictinfo)
210 {
211         Expr       *clause = restrictinfo->clause;
212         PathKeyItem *item1 = makePathKeyItem((Node *) get_leftop(clause),
213                                                                                  restrictinfo->left_sortop);
214         PathKeyItem *item2 = makePathKeyItem((Node *) get_rightop(clause),
215                                                                                  restrictinfo->right_sortop);
216         List       *newset,
217                            *cursetlink;
218
219         /* We might see a clause X=X; don't make a single-element list from it */
220         if (equal(item1, item2))
221                 return;
222
223         /*
224          * Our plan is to make a two-element set, then sweep through the
225          * existing equijoin sets looking for matches to item1 or item2.  When
226          * we find one, we remove that set from equi_key_list and union it
227          * into our new set. When done, we add the new set to the front of
228          * equi_key_list.
229          *
230          * This is a standard UNION-FIND problem, for which there exist better
231          * data structures than simple lists.  If this code ever proves to be
232          * a bottleneck then it could be sped up --- but for now, simple is
233          * beautiful.
234          */
235         newset = lcons(item1, lcons(item2, NIL));
236
237         foreach(cursetlink, root->equi_key_list)
238         {
239                 List       *curset = lfirst(cursetlink);
240
241                 if (member(item1, curset) || member(item2, curset))
242                 {
243                         /* Found a set to merge into our new set */
244                         newset = LispUnion(newset, curset);
245
246                         /*
247                          * Remove old set from equi_key_list.  NOTE this does not
248                          * change lnext(cursetlink), so the outer foreach doesn't
249                          * break.
250                          */
251                         root->equi_key_list = lremove(curset, root->equi_key_list);
252                         freeList(curset);       /* might as well recycle old cons cells */
253                 }
254         }
255
256         root->equi_key_list = lcons(newset, root->equi_key_list);
257 }
258
259 /*
260  * make_canonical_pathkey
261  *        Given a PathKeyItem, find the equi_key_list subset it is a member of,
262  *        if any.  If so, return a pointer to that sublist, which is the
263  *        canonical representation (for this query) of that PathKeyItem's
264  *        equivalence set.      If it is not found, return a single-element list
265  *        containing the PathKeyItem (when the item has no equivalence peers,
266  *        we just allow it to be a standalone list).
267  *
268  * Note that this function must not be used until after we have completed
269  * scanning the WHERE clause for equijoin operators.
270  */
271 static List *
272 make_canonical_pathkey(Query *root, PathKeyItem *item)
273 {
274         List       *cursetlink;
275
276         foreach(cursetlink, root->equi_key_list)
277         {
278                 List       *curset = lfirst(cursetlink);
279
280                 if (member(item, curset))
281                         return curset;
282         }
283         return lcons(item, NIL);
284 }
285
286 /*
287  * canonicalize_pathkeys
288  *         Convert a not-necessarily-canonical pathkeys list to canonical form.
289  *
290  * Note that this function must not be used until after we have completed
291  * scanning the WHERE clause for equijoin operators.
292  */
293 List *
294 canonicalize_pathkeys(Query *root, List *pathkeys)
295 {
296         List       *new_pathkeys = NIL;
297         List       *i;
298
299         foreach(i, pathkeys)
300         {
301                 List       *pathkey = (List *) lfirst(i);
302                 PathKeyItem *item;
303
304                 /*
305                  * It's sufficient to look at the first entry in the sublist; if
306                  * there are more entries, they're already part of an equivalence
307                  * set by definition.
308                  */
309                 Assert(pathkey != NIL);
310                 item = (PathKeyItem *) lfirst(pathkey);
311                 new_pathkeys = lappend(new_pathkeys,
312                                                            make_canonical_pathkey(root, item));
313         }
314         return new_pathkeys;
315 }
316
317 /****************************************************************************
318  *              PATHKEY COMPARISONS
319  ****************************************************************************/
320
321 /*
322  * compare_pathkeys
323  *        Compare two pathkeys to see if they are equivalent, and if not whether
324  *        one is "better" than the other.
325  *
326  *        A pathkey can be considered better than another if it is a superset:
327  *        it contains all the keys of the other plus more.      For example, either
328  *        ((A) (B)) or ((A B)) is better than ((A)).
329  *
330  *        Because we actually only expect to see canonicalized pathkey sublists,
331  *        we don't have to do the full two-way-subset-inclusion test on each
332  *        pair of sublists that is implied by the above statement.      Instead we
333  *        just do an equal().  In the normal case where multi-element sublists
334  *        are pointers into the root's equi_key_list, equal() will be very fast:
335  *        it will recognize pointer equality when the sublists are the same,
336  *        and will fail at the first sublist element when they are not.
337  *
338  * Yes, this gets called enough to be worth coding it this tensely.
339  */
340 PathKeysComparison
341 compare_pathkeys(List *keys1, List *keys2)
342 {
343         List       *key1,
344                            *key2;
345
346         for (key1 = keys1, key2 = keys2;
347                  key1 != NIL && key2 != NIL;
348                  key1 = lnext(key1), key2 = lnext(key2))
349         {
350                 List       *subkey1 = lfirst(key1);
351                 List       *subkey2 = lfirst(key2);
352
353                 /*
354                  * We will never have two subkeys where one is a subset of the
355                  * other, because of the canonicalization explained above.      Either
356                  * they are equal or they ain't.
357                  */
358                 if (!equal(subkey1, subkey2))
359                         return PATHKEYS_DIFFERENT;      /* no need to keep looking */
360         }
361
362         /*
363          * If we reached the end of only one list, the other is longer and
364          * therefore not a subset.      (We assume the additional sublist(s) of
365          * the other list are not NIL --- no pathkey list should ever have a
366          * NIL sublist.)
367          */
368         if (key1 == NIL && key2 == NIL)
369                 return PATHKEYS_EQUAL;
370         if (key1 != NIL)
371                 return PATHKEYS_BETTER1;/* key1 is longer */
372         return PATHKEYS_BETTER2;        /* key2 is longer */
373 }
374
375 /*
376  * pathkeys_contained_in
377  *        Common special case of compare_pathkeys: we just want to know
378  *        if keys2 are at least as well sorted as keys1.
379  */
380 bool
381 pathkeys_contained_in(List *keys1, List *keys2)
382 {
383         switch (compare_pathkeys(keys1, keys2))
384         {
385                         case PATHKEYS_EQUAL:
386                         case PATHKEYS_BETTER2:
387                         return true;
388                 default:
389                         break;
390         }
391         return false;
392 }
393
394 /*
395  * get_cheapest_path_for_pathkeys
396  *        Find the cheapest path (according to the specified criterion) that
397  *        satisfies the given pathkeys.  Return NULL if no such path.
398  *
399  * 'paths' is a list of possible paths that all generate the same relation
400  * 'pathkeys' represents a required ordering (already canonicalized!)
401  * 'cost_criterion' is STARTUP_COST or TOTAL_COST
402  */
403 Path *
404 get_cheapest_path_for_pathkeys(List *paths, List *pathkeys,
405                                                            CostSelector cost_criterion)
406 {
407         Path       *matched_path = NULL;
408         List       *i;
409
410         foreach(i, paths)
411         {
412                 Path       *path = (Path *) lfirst(i);
413
414                 /*
415                  * Since cost comparison is a lot cheaper than pathkey comparison,
416                  * do that first.  (XXX is that still true?)
417                  */
418                 if (matched_path != NULL &&
419                         compare_path_costs(matched_path, path, cost_criterion) <= 0)
420                         continue;
421
422                 if (pathkeys_contained_in(pathkeys, path->pathkeys))
423                         matched_path = path;
424         }
425         return matched_path;
426 }
427
428 /*
429  * get_cheapest_fractional_path_for_pathkeys
430  *        Find the cheapest path (for retrieving a specified fraction of all
431  *        the tuples) that satisfies the given pathkeys.
432  *        Return NULL if no such path.
433  *
434  * See compare_fractional_path_costs() for the interpretation of the fraction
435  * parameter.
436  *
437  * 'paths' is a list of possible paths that all generate the same relation
438  * 'pathkeys' represents a required ordering (already canonicalized!)
439  * 'fraction' is the fraction of the total tuples expected to be retrieved
440  */
441 Path *
442 get_cheapest_fractional_path_for_pathkeys(List *paths,
443                                                                                   List *pathkeys,
444                                                                                   double fraction)
445 {
446         Path       *matched_path = NULL;
447         List       *i;
448
449         foreach(i, paths)
450         {
451                 Path       *path = (Path *) lfirst(i);
452
453                 /*
454                  * Since cost comparison is a lot cheaper than pathkey comparison,
455                  * do that first.
456                  */
457                 if (matched_path != NULL &&
458                 compare_fractional_path_costs(matched_path, path, fraction) <= 0)
459                         continue;
460
461                 if (pathkeys_contained_in(pathkeys, path->pathkeys))
462                         matched_path = path;
463         }
464         return matched_path;
465 }
466
467 /****************************************************************************
468  *              NEW PATHKEY FORMATION
469  ****************************************************************************/
470
471 /*
472  * build_index_pathkeys
473  *        Build a pathkeys list that describes the ordering induced by an index
474  *        scan using the given index.  (Note that an unordered index doesn't
475  *        induce any ordering; such an index will have no sortop OIDS in
476  *        its "ordering" field, and we will return NIL.)
477  *
478  * If 'scandir' is BackwardScanDirection, attempt to build pathkeys
479  * representing a backwards scan of the index.  Return NIL if can't do it.
480  */
481 List *
482 build_index_pathkeys(Query *root,
483                                          RelOptInfo *rel,
484                                          IndexOptInfo *index,
485                                          ScanDirection scandir)
486 {
487         List       *retval = NIL;
488         int                *indexkeys = index->indexkeys;
489         Oid                *ordering = index->ordering;
490         PathKeyItem *item;
491         Oid                     sortop;
492
493         if (!indexkeys || indexkeys[0] == 0 ||
494                 !ordering || ordering[0] == InvalidOid)
495                 return NIL;                             /* unordered index? */
496
497         if (index->indproc)
498         {
499                 /* Functional index: build a representation of the function call */
500                 Func       *funcnode = makeNode(Func);
501                 List       *funcargs = NIL;
502
503                 funcnode->funcid = index->indproc;
504                 funcnode->functype = get_func_rettype(index->indproc);
505                 funcnode->funcisindex = false;
506                 funcnode->funcsize = 0;
507                 funcnode->func_fcache = NULL;
508                 /* we assume here that the function returns a base type... */
509                 funcnode->func_tlist = setup_base_tlist(funcnode->functype);
510                 funcnode->func_planlist = NIL;
511
512                 while (*indexkeys != 0)
513                 {
514                         funcargs = lappend(funcargs,
515                                                            find_indexkey_var(root, rel, *indexkeys));
516                         indexkeys++;
517                 }
518
519                 sortop = *ordering;
520                 if (ScanDirectionIsBackward(scandir))
521                 {
522                         sortop = get_commutator(sortop);
523                         if (sortop == InvalidOid)
524                                 return NIL;             /* oops, no reverse sort operator? */
525                 }
526
527                 /* Make a one-sublist pathkeys list for the function expression */
528                 item = makePathKeyItem((Node *) make_funcclause(funcnode, funcargs),
529                                                            sortop);
530                 retval = lcons(make_canonical_pathkey(root, item), NIL);
531         }
532         else
533         {
534                 /* Normal non-functional index */
535                 while (*indexkeys != 0 && *ordering != InvalidOid)
536                 {
537                         Var                *relvar = find_indexkey_var(root, rel, *indexkeys);
538
539                         sortop = *ordering;
540                         if (ScanDirectionIsBackward(scandir))
541                         {
542                                 sortop = get_commutator(sortop);
543                                 if (sortop == InvalidOid)
544                                         break;          /* oops, no reverse sort operator? */
545                         }
546
547                         /* OK, make a sublist for this sort key */
548                         item = makePathKeyItem((Node *) relvar, sortop);
549                         retval = lappend(retval, make_canonical_pathkey(root, item));
550
551                         indexkeys++;
552                         ordering++;
553                 }
554         }
555
556         return retval;
557 }
558
559 /*
560  * Find or make a Var node for the specified attribute of the rel.
561  *
562  * We first look for the var in the rel's target list, because that's
563  * easy and fast.  But the var might not be there (this should normally
564  * only happen for vars that are used in WHERE restriction clauses,
565  * but not in join clauses or in the SELECT target list).  In that case,
566  * gin up a Var node the hard way.
567  */
568 static Var *
569 find_indexkey_var(Query *root, RelOptInfo *rel, AttrNumber varattno)
570 {
571         List       *temp;
572         int                     relid;
573         Oid                     reloid,
574                                 vartypeid;
575         int32           type_mod;
576
577         foreach(temp, rel->targetlist)
578         {
579                 Var                *tle_var = get_expr(lfirst(temp));
580
581                 if (IsA(tle_var, Var) &&tle_var->varattno == varattno)
582                         return tle_var;
583         }
584
585         relid = lfirsti(rel->relids);
586         reloid = getrelid(relid, root->rtable);
587         vartypeid = get_atttype(reloid, varattno);
588         type_mod = get_atttypmod(reloid, varattno);
589
590         return makeVar(relid, varattno, vartypeid, type_mod, 0);
591 }
592
593 /*
594  * build_join_pathkeys
595  *        Build the path keys for a join relation constructed by mergejoin or
596  *        nestloop join.  These keys should include all the path key vars of the
597  *        outer path (since the join will retain the ordering of the outer path)
598  *        plus any vars of the inner path that are equijoined to the outer vars.
599  *
600  *        Per the discussion at the top of this file, equijoined inner vars
601  *        can be considered path keys of the result, just the same as the outer
602  *        vars they were joined with; furthermore, it doesn't matter what kind
603  *        of join algorithm is actually used.
604  *
605  * 'outer_pathkeys' is the list of the outer path's path keys
606  * 'join_rel_tlist' is the target list of the join relation
607  * 'equi_key_list' is the query's list of pathkeyitem equivalence sets
608  *
609  * Returns the list of new path keys.
610  */
611 List *
612 build_join_pathkeys(List *outer_pathkeys,
613                                         List *join_rel_tlist,
614                                         List *equi_key_list)
615 {
616
617         /*
618          * This used to be quite a complex bit of code, but now that all
619          * pathkey sublists start out life canonicalized, we don't have to do
620          * a darn thing here!  The inner-rel vars we used to need to add are
621          * *already* part of the outer pathkey!
622          *
623          * I'd remove the routine entirely, but maybe someday we'll need it...
624          */
625         return outer_pathkeys;
626 }
627
628 /****************************************************************************
629  *              PATHKEYS AND SORT CLAUSES
630  ****************************************************************************/
631
632 /*
633  * make_pathkeys_for_sortclauses
634  *              Generate a pathkeys list that represents the sort order specified
635  *              by a list of SortClauses (GroupClauses will work too!)
636  *
637  * NB: the result is NOT in canonical form, but must be passed through
638  * canonicalize_pathkeys() before it can be used for comparisons or
639  * labeling relation sort orders.  (We do things this way because
640  * union_planner needs to be able to construct requested pathkeys before
641  * the pathkey equivalence sets have been created for the query.)
642  *
643  * 'sortclauses' is a list of SortClause or GroupClause nodes
644  * 'tlist' is the targetlist to find the referenced tlist entries in
645  */
646 List *
647 make_pathkeys_for_sortclauses(List *sortclauses,
648                                                           List *tlist)
649 {
650         List       *pathkeys = NIL;
651         List       *i;
652
653         foreach(i, sortclauses)
654         {
655                 SortClause *sortcl = (SortClause *) lfirst(i);
656                 Node       *sortkey;
657                 PathKeyItem *pathkey;
658
659                 sortkey = get_sortgroupclause_expr(sortcl, tlist);
660                 pathkey = makePathKeyItem(sortkey, sortcl->sortop);
661
662                 /*
663                  * The pathkey becomes a one-element sublist, for now;
664                  * canonicalize_pathkeys() might replace it with a longer sublist
665                  * later.
666                  */
667                 pathkeys = lappend(pathkeys, lcons(pathkey, NIL));
668         }
669         return pathkeys;
670 }
671
672 /****************************************************************************
673  *              PATHKEYS AND MERGECLAUSES
674  ****************************************************************************/
675
676 /*
677  * find_mergeclauses_for_pathkeys
678  *        This routine attempts to find a set of mergeclauses that can be
679  *        used with a specified ordering for one of the input relations.
680  *        If successful, it returns a list of mergeclauses.
681  *
682  * 'pathkeys' is a pathkeys list showing the ordering of an input path.
683  *                      It doesn't matter whether it is for the inner or outer path.
684  * 'restrictinfos' is a list of mergejoinable restriction clauses for the
685  *                      join relation being formed.
686  *
687  * The result is NIL if no merge can be done, else a maximal list of
688  * usable mergeclauses (represented as a list of their restrictinfo nodes).
689  *
690  * XXX Ideally we ought to be considering context, ie what path orderings
691  * are available on the other side of the join, rather than just making
692  * an arbitrary choice among the mergeclause orders that will work for
693  * this side of the join.
694  */
695 List *
696 find_mergeclauses_for_pathkeys(List *pathkeys, List *restrictinfos)
697 {
698         List       *mergeclauses = NIL;
699         List       *i;
700
701         foreach(i, pathkeys)
702         {
703                 List       *pathkey = lfirst(i);
704                 RestrictInfo *matched_restrictinfo = NULL;
705                 List       *j;
706
707                 /*
708                  * We can match any of the keys in this pathkey sublist, since
709                  * they're all equivalent.  And we can match against either left
710                  * or right side of any mergejoin clause we haven't used yet.  For
711                  * the moment we use a dumb "greedy" algorithm with no
712                  * backtracking.  Is it worth being any smarter to make a longer
713                  * list of usable mergeclauses?  Probably not.
714                  */
715                 foreach(j, pathkey)
716                 {
717                         PathKeyItem *keyitem = lfirst(j);
718                         Node       *key = keyitem->key;
719                         Oid                     keyop = keyitem->sortop;
720                         List       *k;
721
722                         foreach(k, restrictinfos)
723                         {
724                                 RestrictInfo *restrictinfo = lfirst(k);
725
726                                 Assert(restrictinfo->mergejoinoperator != InvalidOid);
727
728                                 if (((keyop == restrictinfo->left_sortop &&
729                                           equal(key, get_leftop(restrictinfo->clause))) ||
730                                          (keyop == restrictinfo->right_sortop &&
731                                           equal(key, get_rightop(restrictinfo->clause)))) &&
732                                         !member(restrictinfo, mergeclauses))
733                                 {
734                                         matched_restrictinfo = restrictinfo;
735                                         break;
736                                 }
737                         }
738                         if (matched_restrictinfo)
739                                 break;
740                 }
741
742                 /*
743                  * If we didn't find a mergeclause, we're done --- any additional
744                  * sort-key positions in the pathkeys are useless.      (But we can
745                  * still mergejoin if we found at least one mergeclause.)
746                  */
747                 if (!matched_restrictinfo)
748                         break;
749
750                 /*
751                  * If we did find a usable mergeclause for this sort-key position,
752                  * add it to result list.
753                  */
754                 mergeclauses = lappend(mergeclauses, matched_restrictinfo);
755         }
756
757         return mergeclauses;
758 }
759
760 /*
761  * make_pathkeys_for_mergeclauses
762  *        Builds a pathkey list representing the explicit sort order that
763  *        must be applied to a path in order to make it usable for the
764  *        given mergeclauses.
765  *
766  * 'mergeclauses' is a list of RestrictInfos for mergejoin clauses
767  *                      that will be used in a merge join.
768  * 'tlist' is a relation target list for either the inner or outer
769  *                      side of the proposed join rel.  (Not actually needed anymore)
770  *
771  * Returns a pathkeys list that can be applied to the indicated relation.
772  *
773  * Note that it is not this routine's job to decide whether sorting is
774  * actually needed for a particular input path.  Assume a sort is necessary;
775  * just make the keys, eh?
776  */
777 List *
778 make_pathkeys_for_mergeclauses(Query *root,
779                                                            List *mergeclauses,
780                                                            List *tlist)
781 {
782         List       *pathkeys = NIL;
783         List       *i;
784
785         foreach(i, mergeclauses)
786         {
787                 RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(i);
788                 Node       *key;
789                 Oid                     sortop;
790                 PathKeyItem *item;
791                 List       *pathkey;
792
793                 Assert(restrictinfo->mergejoinoperator != InvalidOid);
794
795                 /*
796                  * Find the key and sortop needed for this mergeclause.
797                  *
798                  * Both sides of the mergeclause should appear in one of the query's
799                  * pathkey equivalence classes, so it doesn't matter which one we
800                  * use here.
801                  */
802                 key = (Node *) get_leftop(restrictinfo->clause);
803                 sortop = restrictinfo->left_sortop;
804
805                 /*
806                  * Find pathkey sublist for this sort item.  We expect to find the
807                  * canonical set including the mergeclause's left and right sides;
808                  * if we get back just the one item, something is rotten.
809                  */
810                 item = makePathKeyItem(key, sortop);
811                 pathkey = make_canonical_pathkey(root, item);
812                 Assert(length(pathkey) > 1);
813
814                 /*
815                  * Since the item we just made is not in the returned canonical
816                  * set, we can free it --- this saves a useful amount of storage
817                  * in a big join tree.
818                  */
819                 pfree(item);
820
821                 pathkeys = lappend(pathkeys, pathkey);
822         }
823
824         return pathkeys;
825 }