From a5713ec427f15f2c63eaed14f2a16a952b7ddf06 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Fri, 17 Sep 2004 18:28:53 +0000
Subject: [PATCH] Hashed LEFT JOIN would miss outer tuples with no inner match
 if the join 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 | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index fbc55655714..53215be6e91 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/executor/nodeHashjoin.c,v 1.64 2004/08/29 05:06:42 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/executor/nodeHashjoin.c,v 1.65 2004/09/17 18:28:53 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -603,12 +603,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;
-- 
GitLab