From 882905cabe42d061aad6b895602710beb5d81297 Mon Sep 17 00:00:00 2001 From: Melanie Plageman 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