]> granicus.if.org Git - postgresql/commitdiff
Fix possible "invalid memory alloc request size" failure in nodeHash.c.
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 4 Oct 2015 18:16:59 +0000 (14:16 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 4 Oct 2015 18:17:28 +0000 (14:17 -0400)
Limit the size of the hashtable pointer array to not more than
MaxAllocSize.  We've seen reports of failures due to this in HEAD/9.5,
and it seems possible in older branches as well.  The change in
NTUP_PER_BUCKET in 9.5 may have made the problem more likely, but
surely it didn't introduce it.

Tomas Vondra, slightly modified by me

src/backend/executor/nodeHash.c

index 1597211ad8988a2c9724fe8f45266db2c96f6f5c..492e6e0d3324d390af34bb597dfe5dda6d87a4fa 100644 (file)
@@ -459,10 +459,12 @@ ExecChooseHashTableSize(double ntuples, int tupwidth, bool useskew,
         * 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.  The Min() steps limit the results so that the pointer
-        * arrays we'll try to allocate do not exceed work_mem.
+        * arrays we'll try to allocate do not exceed work_mem nor MaxAllocSize.
         */
-       max_pointers = (work_mem * 1024L) / sizeof(void *);
+       max_pointers = (work_mem * 1024L) / sizeof(HashJoinTuple);
+       max_pointers = Min(max_pointers, MaxAllocSize / sizeof(HashJoinTuple));
        /* also ensure we avoid integer overflow in nbatch and nbuckets */
+       /* (this step is redundant given the current value of MaxAllocSize) */
        max_pointers = Min(max_pointers, INT_MAX / 2);
 
        if (inner_rel_bytes > hash_table_bytes)