rehash-partition.patch

application/octet-stream

Filename: rehash-partition.patch
Type: application/octet-stream
Part: 0
Message: Re: BUG #16104: Invalid DSA Memory Alloc Request in Parallel Hash

Patch

Format: unified
File+
src/backend/executor/nodeHash.c 9 27
diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index 224cbb32ba..a273beeaea 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -38,6 +38,7 @@
 #include "pgstat.h"
 #include "port/atomics.h"
 #include "utils/dynahash.h"
+#include "utils/hashutils.h"
 #include "utils/memutils.h"
 #include "utils/lsyscache.h"
 #include "utils/syscache.h"
@@ -1872,25 +1873,6 @@ ExecHashGetHashValue(HashJoinTable hashtable,
 /*
  * ExecHashGetBucketAndBatch
  *		Determine the bucket number and batch number for a hash value
- *
- * Note: on-the-fly increases of nbatch must not change the bucket number
- * for a given hash code (since we don't move tuples to different hash
- * chains), and must only cause the batch number to remain the same or
- * increase.  Our algorithm is
- *		bucketno = hashvalue MOD nbuckets
- *		batchno = (hashvalue DIV nbuckets) MOD nbatch
- * where nbuckets and nbatch are both expected to be powers of 2, so we can
- * do the computations by shifting and masking.  (This assumes that all hash
- * functions are good about randomizing all their output bits, else we are
- * likely to have very skewed bucket or batch occupancy.)
- *
- * nbuckets and log2_nbuckets may change while nbatch == 1 because of dynamic
- * bucket count growth.  Once we start batching, the value is fixed and does
- * not change over the course of the join (making it possible to compute batch
- * number the way we do here).
- *
- * nbatch is always a power of 2; we increase it only by doubling it.  This
- * effectively adds one more bit to the top of the batchno.
  */
 void
 ExecHashGetBucketAndBatch(HashJoinTable hashtable,
@@ -1901,17 +1883,17 @@ ExecHashGetBucketAndBatch(HashJoinTable hashtable,
 	uint32		nbuckets = (uint32) hashtable->nbuckets;
 	uint32		nbatch = (uint32) hashtable->nbatch;
 
+	/*
+	 * Previously we used some of the bits of hashvalue for the batch and some
+	 * for the bucket, but this caused us to run out of bits on larger
+	 * problems.  Mix the bits with an arbitrary constant to produce an
+	 * independent hash value.
+	 */
 	if (nbatch > 1)
-	{
-		/* we can do MOD by masking, DIV by shifting */
-		*bucketno = hashvalue & (nbuckets - 1);
-		*batchno = (hashvalue >> hashtable->log2_nbuckets) & (nbatch - 1);
-	}
+		*batchno = hash_combine(0x9e3779b9, hashvalue) & (nbatch - 1);
 	else
-	{
-		*bucketno = hashvalue & (nbuckets - 1);
 		*batchno = 0;
-	}
+	*bucketno = hashvalue & (nbuckets - 1);
 }
 
 /*