Hashed LEFT JOIN would miss outer tuples with no inner match if the join
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 17 Sep 2004 18:29:40 +0000 (18:29 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 17 Sep 2004 18:29:40 +0000 (18:29 +0000)
was large enough to be batched and the tuples fell into a batch where
there were no inner tuples at all.  Thanks to Xiaoyu Wang for finding a
test case that exposed this long-standing bug.

src/backend/executor/nodeHashjoin.c

index 58e97b8adb1a56ef43932f08d7445fdec57b4999..64ab1cc23383bd069136c057bd0d85a302862883 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/executor/nodeHashjoin.c,v 1.39 2001/10/25 05:49:28 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/executor/nodeHashjoin.c,v 1.39.2.1 2004/09/17 18:29:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -569,12 +569,14 @@ ExecHashJoinNewBatch(HashJoinState *hjstate)
    }
 
    /*
-    * We can skip over any batches that are empty on either side. Release
-    * associated temp files right away.
+    * Normally we can skip over any batches that are empty on either side
+    * --- but for JOIN_LEFT, can only skip when left side is empty.
+    * Release associated temp files right away.
     */
    while (newbatch <= nbatch &&
-          (innerBatchSize[newbatch - 1] == 0L ||
-           outerBatchSize[newbatch - 1] == 0L))
+          (outerBatchSize[newbatch - 1] == 0L ||
+           (innerBatchSize[newbatch - 1] == 0L &&
+            hjstate->js.jointype != JOIN_LEFT)))
    {
        BufFileClose(hashtable->innerBatchFile[newbatch - 1]);
        hashtable->innerBatchFile[newbatch - 1] = NULL;