In cost_mergejoin, the early-exit effect should not apply to the
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 4 Apr 2005 01:43:33 +0000 (01:43 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 4 Apr 2005 01:43:33 +0000 (01:43 +0000)
outer side of an outer join.  Per andrew@supernews.

src/backend/optimizer/path/costsize.c

index 87c76f1129d676d0bb20fc6395c8814cb79bb0d2..71bb21b1409a1e117d6ea778b5808bf22b80316b 100644 (file)
@@ -919,16 +919,17 @@ cost_mergejoin(MergePath *path, Query *root)
        rescanratio = 1.0 + (rescannedtuples / inner_path_rows);
 
        /*
-        * A merge join will stop as soon as it exhausts either input stream.
-        * Estimate fraction of the left and right inputs that will actually
-        * need to be scanned.  We use only the first (most significant) merge
-        * clause for this purpose.
+        * A merge join will stop as soon as it exhausts either input stream
+        * (unless it's an outer join, in which case the outer side has to be
+        * scanned all the way anyway).  Estimate fraction of the left and right
+        * inputs that will actually need to be scanned. We use only the first
+        * (most significant) merge clause for this purpose.
         *
         * Since this calculation is somewhat expensive, and will be the same for
         * all mergejoin paths associated with the merge clause, we cache the
         * results in the RestrictInfo node.
         */
-       if (mergeclauses)
+       if (mergeclauses && path->jpath.jointype != JOIN_FULL)
        {
                firstclause = (RestrictInfo *) lfirst(mergeclauses);
                if (firstclause->left_mergescansel < 0) /* not computed yet? */
@@ -948,10 +949,14 @@ cost_mergejoin(MergePath *path, Query *root)
                        outerscansel = firstclause->right_mergescansel;
                        innerscansel = firstclause->left_mergescansel;
                }
+               if (path->jpath.jointype == JOIN_LEFT)
+                       outerscansel = 1.0;
+               else if (path->jpath.jointype == JOIN_RIGHT)
+                       innerscansel = 1.0;
        }
        else
        {
-               /* cope with clauseless mergejoin */
+               /* cope with clauseless or full mergejoin */
                outerscansel = innerscansel = 1.0;
        }