The result of a FULL or RIGHT join can't be assumed to be sorted by the
authorTom Lane <[email protected]>
Sun, 23 Jan 2005 02:23:30 +0000 (02:23 +0000)
committerTom Lane <[email protected]>
Sun, 23 Jan 2005 02:23:30 +0000 (02:23 +0000)
left input's sorting, because null rows may be inserted at various points.
Per report from Ferenc Lutischážn.

src/backend/optimizer/path/joinpath.c
src/backend/optimizer/path/pathkeys.c
src/include/optimizer/paths.h

index 17b0e147ae87d72b861a21026959ab25bdd3ae25..a79d3e0e3e1f3a7e92fb2249e3f8dc1c081d0f12 100644 (file)
@@ -271,7 +271,8 @@ sort_inner_and_outer(Query *root,
                                                                                                   cur_mergeclauses,
                                                                                                   innerrel);
                /* Build pathkeys representing output sort order. */
-               merge_pathkeys = build_join_pathkeys(root, joinrel, outerkeys);
+               merge_pathkeys = build_join_pathkeys(root, joinrel, jointype,
+                                                                                        outerkeys);
 
                /*
                 * And now we can make the path.
@@ -431,7 +432,7 @@ match_unsorted_outer(Query *root,
                 * as a nestloop, and even if some of the mergeclauses are
                 * implemented by qpquals rather than as true mergeclauses):
                 */
-               merge_pathkeys = build_join_pathkeys(root, joinrel,
+               merge_pathkeys = build_join_pathkeys(root, joinrel, jointype,
                                                                                         outerpath->pathkeys);
 
                if (nestjoinOK)
index 49d7ff5dcaac9102ae903db8e0da2bb096935b61..b0f8bcca946e2adaec5c315c1d472e56c7727df2 100644 (file)
@@ -861,7 +861,12 @@ build_subquery_pathkeys(Query *root, RelOptInfo *rel, Query *subquery)
  *       vars they were joined with; furthermore, it doesn't matter what kind
  *       of join algorithm is actually used.
  *
+ *       EXCEPTION: in a FULL or RIGHT join, we cannot treat the result as
+ *       having the outer path's path keys, because null lefthand rows may be
+ *       inserted at random points.  It must be treated as unsorted.
+ *
  * 'joinrel' is the join relation that paths are being formed for
+ * 'jointype' is the join type (inner, left, full, etc)
  * 'outer_pathkeys' is the list of the current outer path's path keys
  *
  * Returns the list of new path keys.
@@ -869,8 +874,12 @@ build_subquery_pathkeys(Query *root, RelOptInfo *rel, Query *subquery)
 List *
 build_join_pathkeys(Query *root,
                                        RelOptInfo *joinrel,
+                                       JoinType jointype,
                                        List *outer_pathkeys)
 {
+       if (jointype == JOIN_FULL || jointype == JOIN_RIGHT)
+               return NIL;
+
        /*
         * This used to be quite a complex bit of code, but now that all
         * pathkey sublists start out life canonicalized, we don't have to do
index 223d7fabbe224cc1ff6039bc9829d2fc45c05bc9..cc2f33e730977ab060b25e50879d0ce1a98b15f2 100644 (file)
@@ -109,6 +109,7 @@ extern List *build_subquery_pathkeys(Query *root, RelOptInfo *rel,
                                                Query *subquery);
 extern List *build_join_pathkeys(Query *root,
                                        RelOptInfo *joinrel,
+                                       JoinType jointype,
                                        List *outer_pathkeys);
 extern List *make_pathkeys_for_sortclauses(List *sortclauses,
                                                          List *tlist);