1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-12 05:01:15 +03:00

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.
This commit is contained in:
Tom Lane
2000-08-22 04:06:22 +00:00
parent 94e90d9a86
commit 0147b1934f
7 changed files with 84 additions and 51 deletions

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/pquery.c,v 1.37 2000/07/17 03:05:15 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/tcop/pquery.c,v 1.38 2000/08/22 04:06:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -68,8 +68,8 @@ CreateExecutorState(void)
state->es_direction = ForwardScanDirection;
state->es_range_table = NIL;
state->es_into_relation_descriptor = NULL;
state->es_result_relation_info = NULL;
state->es_into_relation_descriptor = NULL;
state->es_param_list_info = NULL;
state->es_param_exec_vals = NULL;
@@ -78,6 +78,10 @@ CreateExecutorState(void)
state->es_junkFilter = NULL;
state->es_query_cxt = CurrentMemoryContext;
state->es_per_tuple_exprcontext = NULL;
/* ----------------
* return the executor state structure
* ----------------
@@ -144,13 +148,11 @@ PreparePortal(char *portalName)
}
/* ----------------
* Create the new portal and make its memory context active.
* Create the new portal.
* ----------------
*/
portal = CreatePortal(portalName);
MemoryContextSwitchTo(PortalGetHeapMemory(portal));
return portal;
}
@@ -170,8 +172,9 @@ ProcessQuery(Query *parsetree,
char *tag;
bool isRetrieveIntoPortal;
bool isRetrieveIntoRelation;
Portal portal = NULL;
char *intoName = NULL;
Portal portal = NULL;
MemoryContext oldContext = NULL;
QueryDesc *queryDesc;
EState *state;
TupleDesc attinfo;
@@ -217,14 +220,18 @@ ProcessQuery(Query *parsetree,
if (isRetrieveIntoPortal)
{
portal = PreparePortal(intoName);
/* CurrentMemoryContext is now pointing to portal's context */
oldContext = MemoryContextSwitchTo(PortalGetHeapMemory(portal));
parsetree = copyObject(parsetree);
plan = copyObject(plan);
/*
* We stay in portal's memory context for now, so that query desc,
* EState, and plan startup info are also allocated in the portal
* context.
*/
}
/* ----------------
* Now we can create the QueryDesc object (this is also in
* the portal context, if portal retrieve).
* Now we can create the QueryDesc object.
* ----------------
*/
queryDesc = CreateQueryDesc(parsetree, plan, dest);
@@ -241,7 +248,7 @@ ProcessQuery(Query *parsetree,
queryDesc->dest = (int) None;
/* ----------------
* create a default executor state..
* create a default executor state.
* ----------------
*/
state = CreateExecutorState();
@@ -279,9 +286,11 @@ ProcessQuery(Query *parsetree,
state,
PortalCleanup);
MemoryContextSwitchTo(TransactionCommandContext);
/* Now we can return to caller's memory context. */
MemoryContextSwitchTo(oldContext);
EndCommand(tag, dest);
return;
}