sort_inner_and_outer needs a check to ensure that it's consumed all the
authorTom Lane
Sun, 11 Nov 2001 19:18:54 +0000 (19:18 +0000)
committerTom Lane
Sun, 11 Nov 2001 19:18:54 +0000 (19:18 +0000)
mergeclauses in RIGHT/FULL join cases, just like the other routines have.
I'm not quite sure why I thought it didn't need one --- but Nick
Fankhauser's recent bug report proves that it does.

src/backend/optimizer/path/joinpath.c

index 15bb56757d1e76fa09f1aa95a471c64a3c64915d..4d60569e7ef6fc01ab9e5fb283c56dc5df7c35a8 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.66 2001/10/25 05:49:32 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.67 2001/11/11 19:18:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -150,9 +150,31 @@ sort_inner_and_outer(Query *root,
                     List *mergeclause_list,
                     JoinType jointype)
 {
+   bool        useallclauses;
    List       *all_pathkeys;
    List       *i;
 
+   /*
+    * If we are doing a right or full join, we must use *all* the
+    * mergeclauses as join clauses, else we will not have a valid plan.
+    */
+   switch (jointype)
+   {
+       case JOIN_INNER:
+       case JOIN_LEFT:
+           useallclauses = false;
+           break;
+       case JOIN_RIGHT:
+       case JOIN_FULL:
+           useallclauses = true;
+           break;
+       default:
+           elog(ERROR, "sort_inner_and_outer: unexpected join type %d",
+                (int) jointype);
+           useallclauses = false;  /* keep compiler quiet */
+           break;
+   }
+
    /*
     * Each possible ordering of the available mergejoin clauses will
     * generate a differently-sorted result path at essentially the same
@@ -212,6 +234,11 @@ sort_inner_and_outer(Query *root,
                                                       mergeclause_list);
        Assert(cur_mergeclauses != NIL);
 
+       /* Forget it if can't use all the clauses in right/full join */
+       if (useallclauses &&
+           length(cur_mergeclauses) != length(mergeclause_list))
+           continue;
+
        /*
         * Build sort pathkeys for both sides.
         *