summaryrefslogtreecommitdiff
path: root/src/backend/executor/execGrouping.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor/execGrouping.c')
-rw-r--r--src/backend/executor/execGrouping.c36
1 files changed, 19 insertions, 17 deletions
diff --git a/src/backend/executor/execGrouping.c b/src/backend/executor/execGrouping.c
index e1a3a813dd9..8b64a625ca5 100644
--- a/src/backend/executor/execGrouping.c
+++ b/src/backend/executor/execGrouping.c
@@ -14,6 +14,8 @@
*/
#include "postgres.h"
+#include <math.h>
+
#include "access/htup_details.h"
#include "access/parallel.h"
#include "common/hashfn.h"
@@ -144,7 +146,7 @@ execTuplesHashPrepare(int numCols,
* eqfuncoids: OIDs of equality comparison functions to use
* hashfunctions: FmgrInfos of datatype-specific hashing functions to use
* collations: collations to use in comparisons
- * nbuckets: initial estimate of hashtable size
+ * nelements: initial estimate of hashtable size
* additionalsize: size of data that may be stored along with the hash entry
* metacxt: memory context for long-lived data and the simplehash table
* tuplescxt: memory context in which to store the hashed tuples themselves
@@ -187,7 +189,7 @@ BuildTupleHashTable(PlanState *parent,
const Oid *eqfuncoids,
FmgrInfo *hashfunctions,
Oid *collations,
- long nbuckets,
+ double nelements,
Size additionalsize,
MemoryContext metacxt,
MemoryContext tuplescxt,
@@ -195,12 +197,24 @@ BuildTupleHashTable(PlanState *parent,
bool use_variable_hash_iv)
{
TupleHashTable hashtable;
- Size entrysize;
- Size hash_mem_limit;
+ uint32 nbuckets;
MemoryContext oldcontext;
uint32 hash_iv = 0;
- Assert(nbuckets > 0);
+ /*
+ * tuplehash_create requires a uint32 element count, so we had better
+ * clamp the given nelements to fit in that. As long as we have to do
+ * that, we might as well protect against completely insane input like
+ * zero or NaN. But it is not our job here to enforce issues like staying
+ * within hash_mem: the caller should have done that, and we don't have
+ * enough info to second-guess.
+ */
+ if (isnan(nelements) || nelements <= 0)
+ nbuckets = 1;
+ else if (nelements >= PG_UINT32_MAX)
+ nbuckets = PG_UINT32_MAX;
+ else
+ nbuckets = (uint32) nelements;
/* tuplescxt must be separate, else ResetTupleHashTable breaks things */
Assert(metacxt != tuplescxt);
@@ -208,18 +222,6 @@ BuildTupleHashTable(PlanState *parent,
/* ensure additionalsize is maxalign'ed */
additionalsize = MAXALIGN(additionalsize);
- /*
- * Limit initial table size request to not more than hash_mem.
- *
- * XXX this calculation seems pretty misguided, as it counts only overhead
- * and not the tuples themselves. But we have no knowledge of the
- * expected tuple width here.
- */
- entrysize = sizeof(TupleHashEntryData) + additionalsize;
- hash_mem_limit = get_hash_memory_limit() / entrysize;
- if (nbuckets > hash_mem_limit)
- nbuckets = hash_mem_limit;
-
oldcontext = MemoryContextSwitchTo(metacxt);
hashtable = (TupleHashTable) palloc(sizeof(TupleHashTableData));