aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/executor/nodeSubplan.c34
-rw-r--r--src/include/nodes/execnodes.h7
-rw-r--r--src/test/regress/expected/subselect.out9
-rw-r--r--src/test/regress/sql/subselect.sql6
4 files changed, 36 insertions, 20 deletions
diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c
index 02a00b15a7b..e456fdb6198 100644
--- a/src/backend/executor/nodeSubplan.c
+++ b/src/backend/executor/nodeSubplan.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/nodeSubplan.c,v 1.80.2.3 2007/04/26 23:24:56 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/nodeSubplan.c,v 1.80.2.4 2010/07/28 04:51:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -79,7 +79,6 @@ ExecHashSubPlan(SubPlanState *node,
{
SubPlan *subplan = (SubPlan *) node->xprstate.expr;
PlanState *planstate = node->planstate;
- ExprContext *innerecontext = node->innerecontext;
TupleTableSlot *slot;
/* Shouldn't have any direct correlation Vars */
@@ -117,12 +116,6 @@ ExecHashSubPlan(SubPlanState *node,
*/
/*
- * Since the hashtable routines will use innerecontext's per-tuple memory
- * as working memory, be sure to reset it for each tuple.
- */
- ResetExprContext(innerecontext);
-
- /*
* If the LHS is all non-null, probe for an exact match in the main hash
* table. If we find one, the result is TRUE. Otherwise, scan the
* partly-null table to see if there are any rows that aren't provably
@@ -419,7 +412,6 @@ buildSubPlanHash(SubPlanState *node)
PlanState *planstate = node->planstate;
int ncols = list_length(subplan->paramIds);
ExprContext *innerecontext = node->innerecontext;
- MemoryContext tempcxt = innerecontext->ecxt_per_tuple_memory;
MemoryContext oldcontext;
int nbuckets;
TupleTableSlot *slot;
@@ -441,7 +433,7 @@ buildSubPlanHash(SubPlanState *node)
* If it's not necessary to distinguish FALSE and UNKNOWN, then we don't
* need to store subplan output rows that contain NULL.
*/
- MemoryContextReset(node->tablecxt);
+ MemoryContextReset(node->hashtablecxt);
node->hashtable = NULL;
node->hashnulls = NULL;
node->havehashrows = false;
@@ -457,8 +449,8 @@ buildSubPlanHash(SubPlanState *node)
node->hashfunctions,
nbuckets,
sizeof(TupleHashEntryData),
- node->tablecxt,
- tempcxt);
+ node->hashtablecxt,
+ node->hashtempcxt);
if (!subplan->unknownEqFalse)
{
@@ -476,8 +468,8 @@ buildSubPlanHash(SubPlanState *node)
node->hashfunctions,
nbuckets,
sizeof(TupleHashEntryData),
- node->tablecxt,
- tempcxt);
+ node->hashtablecxt,
+ node->hashtempcxt);
}
/*
@@ -536,7 +528,7 @@ buildSubPlanHash(SubPlanState *node)
/*
* Reset innerecontext after each inner tuple to free any memory used
- * in hash computation or comparison routines.
+ * during ExecProject.
*/
ResetExprContext(innerecontext);
}
@@ -654,7 +646,8 @@ ExecInitSubPlan(SubPlanState *node, EState *estate, int eflags)
node->projRight = NULL;
node->hashtable = NULL;
node->hashnulls = NULL;
- node->tablecxt = NULL;
+ node->hashtablecxt = NULL;
+ node->hashtempcxt = NULL;
node->innerecontext = NULL;
node->keyColIdx = NULL;
node->eqfunctions = NULL;
@@ -735,12 +728,19 @@ ExecInitSubPlan(SubPlanState *node, EState *estate, int eflags)
ListCell *l;
/* We need a memory context to hold the hash table(s) */
- node->tablecxt =
+ node->hashtablecxt =
AllocSetContextCreate(CurrentMemoryContext,
"Subplan HashTable Context",
ALLOCSET_DEFAULT_MINSIZE,
ALLOCSET_DEFAULT_INITSIZE,
ALLOCSET_DEFAULT_MAXSIZE);
+ /* and a small one for the hash tables to use as temp storage */
+ node->hashtempcxt =
+ AllocSetContextCreate(CurrentMemoryContext,
+ "Subplan HashTable Temp Context",
+ ALLOCSET_SMALL_MINSIZE,
+ ALLOCSET_SMALL_INITSIZE,
+ ALLOCSET_SMALL_MAXSIZE);
/* and a short-lived exprcontext for function evaluation */
node->innerecontext = CreateExprContext(estate);
/* Silly little array of column numbers 1..n */
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index e981a6a933b..84bf53f956e 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.161.2.2 2007/04/26 23:24:57 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.161.2.3 2010/07/28 04:51:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -589,8 +589,9 @@ typedef struct SubPlanState
TupleHashTable hashnulls; /* hash table for rows with null(s) */
bool havehashrows; /* TRUE if hashtable is not empty */
bool havenullrows; /* TRUE if hashnulls is not empty */
- MemoryContext tablecxt; /* memory context containing tables */
- ExprContext *innerecontext; /* working context for comparisons */
+ MemoryContext hashtablecxt; /* memory context containing hash tables */
+ MemoryContext hashtempcxt; /* temp memory context for hash tables */
+ ExprContext *innerecontext; /* econtext for computing inner tuples */
AttrNumber *keyColIdx; /* control data for hash tables */
FmgrInfo *eqfunctions; /* comparison functions for hash tables */
FmgrInfo *hashfunctions; /* lookup data for hash functions */
diff --git a/src/test/regress/expected/subselect.out b/src/test/regress/expected/subselect.out
index 339b46f2972..7dd2db728bd 100644
--- a/src/test/regress/expected/subselect.out
+++ b/src/test/regress/expected/subselect.out
@@ -449,3 +449,12 @@ from
-----
(0 rows)
+--
+-- Test case for premature memory release during hashing of subplan output
+--
+select '1'::text in (select '1'::name union all select '1'::name);
+ ?column?
+----------
+ t
+(1 row)
+
diff --git a/src/test/regress/sql/subselect.sql b/src/test/regress/sql/subselect.sql
index 46b46b4c45e..257ff9a6a59 100644
--- a/src/test/regress/sql/subselect.sql
+++ b/src/test/regress/sql/subselect.sql
@@ -289,3 +289,9 @@ from
from int8_tbl) sq0
join
int4_tbl i4 on dummy = i4.f1;
+
+--
+-- Test case for premature memory release during hashing of subplan output
+--
+
+select '1'::text in (select '1'::name union all select '1'::name);