summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/executor/nodeHash.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index eca5f1b34d0..b50cb231d19 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/nodeHash.c,v 1.116 2008/01/01 19:45:49 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/nodeHash.c,v 1.116.2.1 2009/10/30 20:58:57 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -363,6 +363,7 @@ ExecChooseHashTableSize(double ntuples, int tupwidth,
int tupsize;
double inner_rel_bytes;
long hash_table_bytes;
+ long max_pointers;
int nbatch;
int nbuckets;
int i;
@@ -389,8 +390,13 @@ ExecChooseHashTableSize(double ntuples, int tupwidth,
/*
* Set nbuckets to achieve an average bucket load of NTUP_PER_BUCKET when
* memory is filled. Set nbatch to the smallest power of 2 that appears
- * sufficient.
+ * sufficient. The Min() steps limit the results so that the pointer
+ * arrays we'll try to allocate do not exceed work_mem.
*/
+ max_pointers = (work_mem * 1024L) / sizeof(void *);
+ /* also ensure we avoid integer overflow in nbatch and nbuckets */
+ max_pointers = Min(max_pointers, INT_MAX / 2);
+
if (inner_rel_bytes > hash_table_bytes)
{
/* We'll need multiple batches */
@@ -399,11 +405,11 @@ ExecChooseHashTableSize(double ntuples, int tupwidth,
int minbatch;
lbuckets = (hash_table_bytes / tupsize) / NTUP_PER_BUCKET;
- lbuckets = Min(lbuckets, INT_MAX / 2);
+ lbuckets = Min(lbuckets, max_pointers);
nbuckets = (int) lbuckets;
dbatch = ceil(inner_rel_bytes / hash_table_bytes);
- dbatch = Min(dbatch, INT_MAX / 2);
+ dbatch = Min(dbatch, max_pointers);
minbatch = (int) dbatch;
nbatch = 2;
while (nbatch < minbatch)
@@ -415,7 +421,7 @@ ExecChooseHashTableSize(double ntuples, int tupwidth,
double dbuckets;
dbuckets = ceil(ntuples / NTUP_PER_BUCKET);
- dbuckets = Min(dbuckets, INT_MAX / 2);
+ dbuckets = Min(dbuckets, max_pointers);
nbuckets = (int) dbuckets;
nbatch = 1;
@@ -489,7 +495,7 @@ ExecHashIncreaseNumBatches(HashJoinTable hashtable)
return;
/* safety check to avoid overflow */
- if (oldnbatch > INT_MAX / 2)
+ if (oldnbatch > Min(INT_MAX / 2, MaxAllocSize / (sizeof(void *) * 2)))
return;
nbatch = oldnbatch * 2;