diff options
Diffstat (limited to 'src/backend/executor/nodeSubplan.c')
| -rw-r--r-- | src/backend/executor/nodeSubplan.c | 89 |
1 files changed, 67 insertions, 22 deletions
diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c index 53fb56f7388..c8b7bd9eb66 100644 --- a/src/backend/executor/nodeSubplan.c +++ b/src/backend/executor/nodeSubplan.c @@ -34,7 +34,6 @@ #include "miscadmin.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" -#include "optimizer/optimizer.h" #include "utils/array.h" #include "utils/lsyscache.h" #include "utils/memutils.h" @@ -481,7 +480,7 @@ buildSubPlanHash(SubPlanState *node, ExprContext *econtext) int ncols = node->numCols; ExprContext *innerecontext = node->innerecontext; MemoryContext oldcontext; - long nbuckets; + double nentries; TupleTableSlot *slot; Assert(subplan->subLinkType == ANY_SUBLINK); @@ -506,13 +505,10 @@ buildSubPlanHash(SubPlanState *node, ExprContext *econtext) * saves a needless fetch inner op step for the hashing ExprState created * in BuildTupleHashTable(). */ - MemoryContextReset(node->hashtablecxt); node->havehashrows = false; node->havenullrows = false; - nbuckets = clamp_cardinality_to_long(planstate->plan->plan_rows); - if (nbuckets < 1) - nbuckets = 1; + nentries = planstate->plan->plan_rows; if (node->hashtable) ResetTupleHashTable(node->hashtable); @@ -525,22 +521,22 @@ buildSubPlanHash(SubPlanState *node, ExprContext *econtext) node->tab_eq_funcoids, node->tab_hash_funcs, node->tab_collations, - nbuckets, - 0, + nentries, + 0, /* no additional data */ node->planstate->state->es_query_cxt, - node->hashtablecxt, + node->tuplesContext, innerecontext->ecxt_per_tuple_memory, false); if (!subplan->unknownEqFalse) { if (ncols == 1) - nbuckets = 1; /* there can only be one entry */ + nentries = 1; /* there can only be one entry */ else { - nbuckets /= 16; - if (nbuckets < 1) - nbuckets = 1; + nentries /= 16; + if (nentries < 1) + nentries = 1; } if (node->hashnulls) @@ -554,10 +550,10 @@ buildSubPlanHash(SubPlanState *node, ExprContext *econtext) node->tab_eq_funcoids, node->tab_hash_funcs, node->tab_collations, - nbuckets, - 0, + nentries, + 0, /* no additional data */ node->planstate->state->es_query_cxt, - node->hashtablecxt, + node->tuplesContext, innerecontext->ecxt_per_tuple_memory, false); } @@ -637,6 +633,55 @@ buildSubPlanHash(SubPlanState *node, ExprContext *econtext) MemoryContextSwitchTo(oldcontext); } +/* Planner support routine to estimate space needed for hash table(s) */ +Size +EstimateSubplanHashTableSpace(double nentries, + Size tupleWidth, + bool unknownEqFalse) +{ + Size tab1space, + tab2space; + + /* Estimate size of main hashtable */ + tab1space = EstimateTupleHashTableSpace(nentries, + tupleWidth, + 0 /* no additional data */ ); + + /* Give up if that's already too big */ + if (tab1space >= SIZE_MAX) + return tab1space; + + /* Done if we don't need a hashnulls table */ + if (unknownEqFalse) + return tab1space; + + /* + * Adjust the rowcount estimate in the same way that buildSubPlanHash + * will, except that we don't bother with the special case for a single + * hash column. (We skip that detail because it'd be notationally painful + * for our caller to provide the column count, and this table has + * relatively little impact on the total estimate anyway.) + */ + nentries /= 16; + if (nentries < 1) + nentries = 1; + + /* + * It might be sane to also reduce the tupleWidth, but on the other hand + * we are not accounting for the space taken by the tuples' null bitmaps. + * Leave it alone for now. + */ + tab2space = EstimateTupleHashTableSpace(nentries, + tupleWidth, + 0 /* no additional data */ ); + + /* Guard against overflow */ + if (tab2space >= SIZE_MAX - tab1space) + return SIZE_MAX; + + return tab1space + tab2space; +} + /* * execTuplesUnequal * Return true if two tuples are definitely unequal in the indicated @@ -838,7 +883,7 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent) sstate->projRight = NULL; sstate->hashtable = NULL; sstate->hashnulls = NULL; - sstate->hashtablecxt = NULL; + sstate->tuplesContext = NULL; sstate->innerecontext = NULL; sstate->keyColIdx = NULL; sstate->tab_eq_funcoids = NULL; @@ -889,11 +934,11 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent) *righttlist; ListCell *l; - /* We need a memory context to hold the hash table(s) */ - sstate->hashtablecxt = - AllocSetContextCreate(CurrentMemoryContext, - "Subplan HashTable Context", - ALLOCSET_DEFAULT_SIZES); + /* We need a memory context to hold the hash table(s)' tuples */ + sstate->tuplesContext = + BumpContextCreate(CurrentMemoryContext, + "SubPlan hashed tuples", + ALLOCSET_DEFAULT_SIZES); /* and a short-lived exprcontext for function evaluation */ sstate->innerecontext = CreateExprContext(estate); |
