summaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeSubplan.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor/nodeSubplan.c')
-rw-r--r--src/backend/executor/nodeSubplan.c89
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);