aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/execMain.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2000-08-22 04:06:22 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2000-08-22 04:06:22 +0000
commit0147b1934f251183d3614bca011bf21205890835 (patch)
treeed7df11ba0ecbdae22095a2eeacbd204dcdca1b8 /src/backend/executor/execMain.c
parent94e90d9a86a186c83891fe4ce3e343bcf1860053 (diff)
downloadpostgresql-0147b1934f251183d3614bca011bf21205890835.tar.gz
postgresql-0147b1934f251183d3614bca011bf21205890835.zip
Fix a many-legged critter reported by chifungfan@yahoo.com: under the
right circumstances a hash join executed as a DECLARE CURSOR/FETCH query would crash the backend. Problem as seen in current sources was that the hash tables were stored in a context that was a child of TransactionCommandContext, which got zapped at completion of the FETCH command --- but cursor cleanup executed at COMMIT expected the tables to still be valid. I haven't chased down the details as seen in 7.0.* but I'm sure it's the same general problem.
Diffstat (limited to 'src/backend/executor/execMain.c')
-rw-r--r--src/backend/executor/execMain.c42
1 files changed, 25 insertions, 17 deletions
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index e66107ce7d1..2db826144dc 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -27,7 +27,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.123 2000/08/06 04:26:26 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.124 2000/08/22 04:06:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1574,31 +1574,32 @@ ExecRelCheck(Relation rel, TupleTableSlot *slot, EState *estate)
{
int ncheck = rel->rd_att->constr->num_check;
ConstrCheck *check = rel->rd_att->constr->check;
- MemoryContext oldContext;
ExprContext *econtext;
+ MemoryContext oldContext;
List *qual;
int i;
/*
- * Make sure econtext, expressions, etc are placed in appropriate context.
+ * We will use the EState's per-tuple context for evaluating constraint
+ * expressions. Create it if it's not already there; if it is, reset it
+ * to free previously-used storage.
*/
- oldContext = MemoryContextSwitchTo(TransactionCommandContext);
-
- /*
- * Create or reset the exprcontext for evaluating constraint expressions.
- */
- econtext = estate->es_constraint_exprcontext;
+ econtext = estate->es_per_tuple_exprcontext;
if (econtext == NULL)
- estate->es_constraint_exprcontext = econtext =
- MakeExprContext(NULL, TransactionCommandContext);
+ {
+ oldContext = MemoryContextSwitchTo(estate->es_query_cxt);
+ estate->es_per_tuple_exprcontext = econtext =
+ MakeExprContext(NULL, estate->es_query_cxt);
+ MemoryContextSwitchTo(oldContext);
+ }
else
ResetExprContext(econtext);
/*
* If first time through for current result relation, set up econtext's
* range table to refer to result rel, and build expression nodetrees
- * for rel's constraint expressions. All this stuff is kept in
- * TransactionCommandContext so it will still be here next time through.
+ * for rel's constraint expressions. All this stuff is kept in the
+ * per-query memory context so it will still be here next time through.
*
* NOTE: if there are multiple result relations (eg, due to inheritance)
* then we leak storage for prior rel's expressions and rangetable.
@@ -1608,7 +1609,14 @@ ExecRelCheck(Relation rel, TupleTableSlot *slot, EState *estate)
if (econtext->ecxt_range_table == NIL ||
getrelid(1, econtext->ecxt_range_table) != RelationGetRelid(rel))
{
- RangeTblEntry *rte = makeNode(RangeTblEntry);
+ RangeTblEntry *rte;
+
+ /*
+ * Make sure expressions, etc are placed in appropriate context.
+ */
+ oldContext = MemoryContextSwitchTo(estate->es_query_cxt);
+
+ rte = makeNode(RangeTblEntry);
rte->relname = RelationGetRelationName(rel);
rte->ref = makeNode(Attr);
@@ -1627,10 +1635,10 @@ ExecRelCheck(Relation rel, TupleTableSlot *slot, EState *estate)
qual = (List *) stringToNode(check[i].ccbin);
estate->es_result_relation_constraints[i] = qual;
}
- }
- /* Done with building long-lived items */
- MemoryContextSwitchTo(oldContext);
+ /* Done with building long-lived items */
+ MemoryContextSwitchTo(oldContext);
+ }
/* Arrange for econtext's scan tuple to be the tuple under test */
econtext->ecxt_scantuple = slot;