v5-0003-more-tweaks.patch

text/x-patch

Filename: v5-0003-more-tweaks.patch
Type: text/x-patch
Part: 2
Message: Re: Fix overflow of nbatch

Patch

Format: format-patch
Series: patch v5-0003
Subject: more tweaks
File+
src/backend/executor/nodeHash.c 17 22
From 882905cabe42d061aad6b895602710beb5d81297 Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplageman@gmail.com>
Date: Mon, 13 Oct 2025 12:03:54 -0400
Subject: [PATCH v5 3/3] more tweaks

---
 src/backend/executor/nodeHash.c | 39 ++++++++++++++-------------------
 1 file changed, 17 insertions(+), 22 deletions(-)

diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index 264c5b7ed40..f562077df5e 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -884,37 +884,27 @@ ExecChooseHashTableSize(double ntuples, int tupwidth, bool useskew,
 	 * Note that we can only change nbuckets during initial hashtable sizing.
 	 * Once we start building the hash, nbuckets is fixed.
 	 *
-	 * We will double a number of parameters (space_allowed, nbuckets and
-	 * num_skew_mcvs), which brings the overflow risk. We simply stop the loop
-	 * if that happens. We could do something smarter (e.g. cap nbuckets and
-	 * continue), but the complexity is not worth it. It's extremely rare and
-	 * this is best-effort attempt to reduce memory usage.
+	 * We double several parameters (space_allowed, nbuckets, and
+	 * num_skew_mcvs), which introduces a risk of overflow. We avoid this by
+	 * exiting the loop. We could do something smarter (e.g. capping nbuckets
+	 * and continue), but the complexity is not worth it. Such cases are
+	 * extremely rare, and this is a best-effort attempt to reduce memory
+	 * usage.
 	 */
 	while (nbatch > 1)
 	{
-		/*
-		 * Check that nbuckets wont't overflow MaxAllocSize.
-		 *
-		 * With extremely low work_mem values, nbuckets may have been set
-		 * higher than hash_table_size / sizeof(HashJoinTuple). We don't try
-		 * to correct that here, we accept nbuckets to be oversized.
-		 */
+		/* Check that nbuckets wont't overflow MaxAllocSize */
 		if (nbuckets > MaxAllocSize / sizeof(HashJoinTuple) / 2)
 			break;
 
-		/*
-		 * Check that space_allowed won't overflow.
-		 *
-		 * We don't check hash_table_bytes, because we subtracted space for
-		 * skew hashtable from it (so it may not be equal to space_allowed).
-		 */
-		if ((*space_allowed) > SIZE_MAX / 2)
-			break;
+		/* num_skew_mcvs should be less than nbuckets */
+		Assert((*num_skew_mcvs) < INT_MAX / 2);
 
 		/*
-		 * Check that num_skew_mcvs won't overflow.
+		 * space_allowed will exceed hash_table_bytes when there is a
+		 * skew_hashtable. Just exit if doubling it will overflow.
 		 */
-		if ((*num_skew_mcvs) > INT_MAX / 2)
+		if ((*space_allowed) > SIZE_MAX / 2)
 			break;
 
 		/*
@@ -933,6 +923,10 @@ ExecChooseHashTableSize(double ntuples, int tupwidth, bool useskew,
 		/*
 		 * MaxAllocSize is sufficiently small that we are not worried about
 		 * overflowing nbuckets.
+		 *
+		 * With extremely low work_mem values, nbuckets may have been set
+		 * higher than hash_table_bytes / sizeof(HashJoinTuple). We don't try
+		 * to correct that here.
 		 */
 		nbuckets *= 2;
 
@@ -944,6 +938,7 @@ ExecChooseHashTableSize(double ntuples, int tupwidth, bool useskew,
 
 	Assert(nbuckets > 0);
 	Assert(nbatch > 0);
+
 	*numbuckets = nbuckets;
 	*numbatches = nbatch;
 }
-- 
2.43.0