Refactor hash_agg_entry_size().
authorJeff Davis
Thu, 6 Feb 2020 19:49:56 +0000 (11:49 -0800)
committerJeff Davis
Thu, 6 Feb 2020 19:49:56 +0000 (11:49 -0800)
Consolidate the calculations for hash table size estimation. This will
help with upcoming Hash Aggregation work that will add additional call
sites.

src/backend/executor/nodeAgg.c
src/backend/optimizer/plan/planner.c
src/backend/utils/adt/selfuncs.c
src/include/executor/nodeAgg.h

index 9073395eacfd363c8a8f57c1b01baf953362a88d..b7f49ceddf8c7258305ac144a10d831bc745c8a5 100644 (file)
@@ -1422,24 +1422,17 @@ find_hash_columns(AggState *aggstate)
 }
 
 /*
- * Estimate per-hash-table-entry overhead for the planner.
- *
- * Note that the estimate does not include space for pass-by-reference
- * transition data values, nor for the representative tuple of each group.
- * Nor does this account of the target fill-factor and growth policy of the
- * hash table.
+ * Estimate per-hash-table-entry overhead.
  */
 Size
-hash_agg_entry_size(int numAggs)
+hash_agg_entry_size(int numAggs, Size tupleWidth, Size transitionSpace)
 {
-   Size        entrysize;
-
-   /* This must match build_hash_table */
-   entrysize = sizeof(TupleHashEntryData) +
-       numAggs * sizeof(AggStatePerGroupData);
-   entrysize = MAXALIGN(entrysize);
-
-   return entrysize;
+   return
+       MAXALIGN(SizeofMinimalTupleHeader) +
+       MAXALIGN(tupleWidth) +
+       MAXALIGN(sizeof(TupleHashEntryData) +
+                numAggs * sizeof(AggStatePerGroupData)) +
+       transitionSpace;
 }
 
 /*
index d6f21535937ba4937aa25d5143eb63070ef8d7b4..b44efd6314c5edd3a21dbc681ebf0747516910cc 100644 (file)
@@ -4867,13 +4867,8 @@ create_distinct_paths(PlannerInfo *root,
        allow_hash = false;     /* policy-based decision not to hash */
    else
    {
-       Size        hashentrysize;
-
-       /* Estimate per-hash-entry space at tuple width... */
-       hashentrysize = MAXALIGN(cheapest_input_path->pathtarget->width) +
-           MAXALIGN(SizeofMinimalTupleHeader);
-       /* plus the per-hash-entry overhead */
-       hashentrysize += hash_agg_entry_size(0);
+       Size        hashentrysize = hash_agg_entry_size(
+           0, cheapest_input_path->pathtarget->width, 0);
 
        /* Allow hashing only if hashtable is predicted to fit in work_mem */
        allow_hash = (hashentrysize * numDistinctRows <= work_mem * 1024L);
index 7c6f0574b3720d632270ab213c80d8f9effc3dfa..0be26fe03780c89f15642dd98ecea2eaa0db42a3 100644 (file)
@@ -3526,16 +3526,8 @@ double
 estimate_hashagg_tablesize(Path *path, const AggClauseCosts *agg_costs,
                           double dNumGroups)
 {
-   Size        hashentrysize;
-
-   /* Estimate per-hash-entry space at tuple width... */
-   hashentrysize = MAXALIGN(path->pathtarget->width) +
-       MAXALIGN(SizeofMinimalTupleHeader);
-
-   /* plus space for pass-by-ref transition values... */
-   hashentrysize += agg_costs->transitionSpace;
-   /* plus the per-hash-entry overhead */
-   hashentrysize += hash_agg_entry_size(agg_costs->numAggs);
+   Size        hashentrysize = hash_agg_entry_size(
+       agg_costs->numAggs, path->pathtarget->width, agg_costs->transitionSpace);
 
    /*
     * Note that this disregards the effect of fill-factor and growth policy
index 2fe82da6ff734e7654102c7f36c16f0033dc584a..264916f9a921c33abcbd5cfaf96a45b4e53db22e 100644 (file)
@@ -309,6 +309,7 @@ extern AggState *ExecInitAgg(Agg *node, EState *estate, int eflags);
 extern void ExecEndAgg(AggState *node);
 extern void ExecReScanAgg(AggState *node);
 
-extern Size hash_agg_entry_size(int numAggs);
+extern Size hash_agg_entry_size(int numAggs, Size tupleWidth,
+                               Size transitionSpace);
 
 #endif                         /* NODEAGG_H */