diff options
Diffstat (limited to 'src/backend/executor')
-rw-r--r-- | src/backend/executor/functions.c | 6 | ||||
-rw-r--r-- | src/backend/executor/nodeAgg.c | 10 | ||||
-rw-r--r-- | src/backend/executor/nodeHash.c | 50 | ||||
-rw-r--r-- | src/backend/executor/spi.c | 166 |
4 files changed, 86 insertions, 146 deletions
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c index ee5fabf1708..6d8d93a47f1 100644 --- a/src/backend/executor/functions.c +++ b/src/backend/executor/functions.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.34 2000/05/28 17:55:55 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.35 2000/06/28 03:31:33 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -87,8 +87,8 @@ init_execution_state(FunctionCachePtr fcache) nextes = newes; preves = (execution_state *) NULL; - queryTree_list = pg_parse_and_rewrite(fcache->src, fcache->argOidVect, - nargs, FALSE); + queryTree_list = pg_parse_and_rewrite(fcache->src, + fcache->argOidVect, nargs); foreach(qtl_item, queryTree_list) { diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c index c9d6299f493..0289cf45bd3 100644 --- a/src/backend/executor/nodeAgg.c +++ b/src/backend/executor/nodeAgg.c @@ -32,7 +32,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.67 2000/06/15 03:32:09 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.68 2000/06/28 03:31:33 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -265,7 +265,7 @@ advance_transition_functions(AggStatePerAgg peraggstate, else newVal = FunctionCallInvoke(&fcinfo); if (!peraggstate->transtype1ByVal && !peraggstate->value1IsNull) - pfree(peraggstate->value1); + pfree(DatumGetPointer(peraggstate->value1)); peraggstate->value1 = newVal; peraggstate->value1IsNull = fcinfo.isnull; } @@ -288,7 +288,7 @@ advance_transition_functions(AggStatePerAgg peraggstate, else newVal = FunctionCallInvoke(&fcinfo); if (!peraggstate->transtype2ByVal && !peraggstate->value2IsNull) - pfree(peraggstate->value2); + pfree(DatumGetPointer(peraggstate->value2)); peraggstate->value2 = newVal; peraggstate->value2IsNull = fcinfo.isnull; } @@ -424,12 +424,12 @@ finalize_aggregate(AggStatePerAgg peraggstate, if (OidIsValid(peraggstate->xfn1_oid) && !peraggstate->value1IsNull && !peraggstate->transtype1ByVal) - pfree(peraggstate->value1); + pfree(DatumGetPointer(peraggstate->value1)); if (OidIsValid(peraggstate->xfn2_oid) && !peraggstate->value2IsNull && !peraggstate->transtype2ByVal) - pfree(peraggstate->value2); + pfree(DatumGetPointer(peraggstate->value2)); } /* --------------------------------------- diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c index b662883803a..34b0a269a5b 100644 --- a/src/backend/executor/nodeHash.c +++ b/src/backend/executor/nodeHash.c @@ -7,14 +7,14 @@ * Portions Copyright (c) 1994, Regents of the University of California * * - * $Id: nodeHash.c,v 1.47 2000/06/15 04:09:52 momjian Exp $ + * $Id: nodeHash.c,v 1.48 2000/06/28 03:31:34 tgl Exp $ * *------------------------------------------------------------------------- */ /* * INTERFACE ROUTINES * ExecHash - generate an in-memory hash table of the relation - * ExecInitHash - initialize node and subnodes.. + * ExecInitHash - initialize node and subnodes * ExecEndHash - shutdown node and subnodes * */ @@ -23,11 +23,12 @@ #include <math.h> #include "postgres.h" + #include "executor/execdebug.h" #include "executor/nodeHash.h" #include "executor/nodeHashjoin.h" #include "miscadmin.h" -#include "utils/portal.h" + static int hashFunc(Datum key, int len, bool byVal); @@ -235,8 +236,6 @@ ExecHashTableCreate(Hash *node) int totalbuckets; int bucketsize; int i; - Portal myPortal; - char myPortalName[64]; MemoryContext oldcxt; /* ---------------- @@ -348,23 +347,21 @@ ExecHashTableCreate(Hash *node) hashtable->outerBatchSize = NULL; /* ---------------- - * Create a named portal in which to keep the hashtable working storage. - * Each hashjoin must have its own portal, so be wary of name conflicts. + * Create temporary memory contexts in which to keep the hashtable + * working storage. See notes in executor/hashjoin.h. * ---------------- */ - i = 0; - do - { - i++; - sprintf(myPortalName, "<hashtable %d>", i); - myPortal = GetPortalByName(myPortalName); - } while (PortalIsValid(myPortal)); - myPortal = CreatePortal(myPortalName); - Assert(PortalIsValid(myPortal)); - hashtable->myPortal = (void *) myPortal; /* kluge for circular - * includes */ - hashtable->hashCxt = (MemoryContext) PortalGetVariableMemory(myPortal); - hashtable->batchCxt = (MemoryContext) PortalGetHeapMemory(myPortal); + hashtable->hashCxt = AllocSetContextCreate(TransactionCommandContext, + "HashTableContext", + ALLOCSET_DEFAULT_MINSIZE, + ALLOCSET_DEFAULT_INITSIZE, + ALLOCSET_DEFAULT_MAXSIZE); + + hashtable->batchCxt = AllocSetContextCreate(hashtable->hashCxt, + "HashBatchContext", + ALLOCSET_DEFAULT_MINSIZE, + ALLOCSET_DEFAULT_INITSIZE, + ALLOCSET_DEFAULT_MAXSIZE); /* Allocate data that will live for the life of the hashjoin */ @@ -395,11 +392,10 @@ ExecHashTableCreate(Hash *node) } /* - * Prepare portal for the first-scan space allocations; allocate the + * Prepare context for the first-scan space allocations; allocate the * hashbucket array therein, and set each bucket "empty". */ MemoryContextSwitchTo(hashtable->batchCxt); - StartPortalAllocMode(DefaultAllocMode, 0); hashtable->buckets = (HashJoinTuple *) palloc(nbuckets * sizeof(HashJoinTuple)); @@ -435,9 +431,8 @@ ExecHashTableDestroy(HashJoinTable hashtable) BufFileClose(hashtable->outerBatchFile[i]); } - /* Destroy the portal to release all working memory */ - /* cast here is a kluge for circular includes... */ - PortalDrop((Portal *) &hashtable->myPortal); + /* Release working memory (batchCxt is a child, so it goes away too) */ + MemoryContextDelete(hashtable->hashCxt); /* And drop the control block */ pfree(hashtable); @@ -676,11 +671,10 @@ ExecHashTableReset(HashJoinTable hashtable, long ntuples) /* * Release all the hash buckets and tuples acquired in the prior pass, - * and reinitialize the portal for a new pass. + * and reinitialize the context for a new pass. */ + MemoryContextReset(hashtable->batchCxt); oldcxt = MemoryContextSwitchTo(hashtable->batchCxt); - EndPortalAllocMode(); - StartPortalAllocMode(DefaultAllocMode, 0); /* * We still use the same number of physical buckets as in the first diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index ac86695ee1b..1ab6ae67d50 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -3,21 +3,20 @@ * spi.c * Server Programming Interface * - * $Id: spi.c,v 1.46 2000/05/30 04:24:45 tgl Exp $ + * $Id: spi.c,v 1.47 2000/06/28 03:31:34 tgl Exp $ * *------------------------------------------------------------------------- */ #include "executor/spi_priv.h" #include "access/printtup.h" -static Portal _SPI_portal = (Portal) NULL; static _SPI_connection *_SPI_stack = NULL; static _SPI_connection *_SPI_current = NULL; static int _SPI_connected = -1; static int _SPI_curid = -1; DLLIMPORT uint32 SPI_processed = 0; -DLLIMPORT SPITupleTable *SPI_tuptable; +DLLIMPORT SPITupleTable *SPI_tuptable = NULL; DLLIMPORT int SPI_result; static int _SPI_execute(char *src, int tcount, _SPI_plan *plan); @@ -46,28 +45,6 @@ extern void ShowUsage(void); int SPI_connect() { - char pname[64]; - PortalVariableMemory pvmem; - - /* - * It's possible on startup and after commit/abort. In future we'll - * catch commit/abort in some way... - */ - strcpy(pname, "<SPI manager>"); - _SPI_portal = GetPortalByName(pname); - if (!PortalIsValid(_SPI_portal)) - { - if (_SPI_stack != NULL) /* there was abort */ - free(_SPI_stack); - _SPI_current = _SPI_stack = NULL; - _SPI_connected = _SPI_curid = -1; - SPI_processed = 0; - SPI_tuptable = NULL; - _SPI_portal = CreatePortal(pname); - if (!PortalIsValid(_SPI_portal)) - elog(FATAL, "SPI_connect: global initialization failed"); - } - /* * When procedure called by Executor _SPI_curid expected to be equal * to _SPI_connected @@ -99,15 +76,19 @@ SPI_connect() _SPI_current->processed = 0; _SPI_current->tuptable = NULL; - /* Create Portal for this procedure ... */ - snprintf(pname, 64, "<SPI %d>", _SPI_connected); - _SPI_current->portal = CreatePortal(pname); - if (!PortalIsValid(_SPI_current->portal)) - elog(FATAL, "SPI_connect: initialization failed"); - - /* ... and switch to Portal' Variable memory - procedure' context */ - pvmem = PortalGetVariableMemory(_SPI_current->portal); - _SPI_current->savedcxt = MemoryContextSwitchTo((MemoryContext) pvmem); + /* Create memory contexts for this procedure */ + _SPI_current->procCxt = AllocSetContextCreate(TopTransactionContext, + "SPI Proc", + ALLOCSET_DEFAULT_MINSIZE, + ALLOCSET_DEFAULT_INITSIZE, + ALLOCSET_DEFAULT_MAXSIZE); + _SPI_current->execCxt = AllocSetContextCreate(TopTransactionContext, + "SPI Exec", + ALLOCSET_DEFAULT_MINSIZE, + ALLOCSET_DEFAULT_INITSIZE, + ALLOCSET_DEFAULT_MAXSIZE); + /* ... and switch to procedure's context */ + _SPI_current->savedcxt = MemoryContextSwitchTo(_SPI_current->procCxt); _SPI_current->savedId = GetScanCommandId(); SetScanCommandId(GetCurrentCommandId()); @@ -127,7 +108,10 @@ SPI_finish() /* Restore memory context as it was before procedure call */ MemoryContextSwitchTo(_SPI_current->savedcxt); - PortalDrop(&(_SPI_current->portal)); + + /* Release memory used in procedure call */ + MemoryContextDelete(_SPI_current->execCxt); + MemoryContextDelete(_SPI_current->procCxt); SetScanCommandId(_SPI_current->savedId); @@ -142,6 +126,7 @@ SPI_finish() { free(_SPI_stack); _SPI_stack = NULL; + _SPI_current = NULL; } else { @@ -154,6 +139,25 @@ SPI_finish() } +/* + * Clean up SPI state at transaction commit or abort (we don't care which). + */ +void +AtEOXact_SPI(void) +{ + /* + * Note that memory contexts belonging to SPI stack entries will be + * freed automatically, so we can ignore them here. We just need to + * restore our static variables to initial state. + */ + if (_SPI_stack != NULL) /* there was abort */ + free(_SPI_stack); + _SPI_current = _SPI_stack = NULL; + _SPI_connected = _SPI_curid = -1; + SPI_processed = 0; + SPI_tuptable = NULL; +} + void SPI_push(void) { @@ -508,61 +512,22 @@ SPI_palloc(Size size) void * SPI_repalloc(void *pointer, Size size) { - MemoryContext oldcxt = NULL; - - if (_SPI_curid + 1 == _SPI_connected) /* connected */ - { - if (_SPI_current != &(_SPI_stack[_SPI_curid + 1])) - elog(FATAL, "SPI: stack corrupted"); - oldcxt = MemoryContextSwitchTo(_SPI_current->savedcxt); - } - - pointer = repalloc(pointer, size); - - if (oldcxt) - MemoryContextSwitchTo(oldcxt); - - return pointer; + /* No longer need to worry which context chunk was in... */ + return repalloc(pointer, size); } void SPI_pfree(void *pointer) { - MemoryContext oldcxt = NULL; - - if (_SPI_curid + 1 == _SPI_connected) /* connected */ - { - if (_SPI_current != &(_SPI_stack[_SPI_curid + 1])) - elog(FATAL, "SPI: stack corrupted"); - oldcxt = MemoryContextSwitchTo(_SPI_current->savedcxt); - } - + /* No longer need to worry which context chunk was in... */ pfree(pointer); - - if (oldcxt) - MemoryContextSwitchTo(oldcxt); - - return; } void SPI_freetuple(HeapTuple tuple) { - MemoryContext oldcxt = NULL; - - if (_SPI_curid + 1 == _SPI_connected) /* connected */ - { - if (_SPI_current != &(_SPI_stack[_SPI_curid + 1])) - elog(FATAL, "SPI: stack corrupted"); - oldcxt = MemoryContextSwitchTo(_SPI_current->savedcxt); - } - + /* No longer need to worry which context tuple was in... */ heap_freetuple(tuple); - - if (oldcxt) - MemoryContextSwitchTo(oldcxt); - - return; } /* =================== private functions =================== */ @@ -647,7 +612,7 @@ _SPI_execute(char *src, int tcount, _SPI_plan *plan) argtypes = plan->argtypes; } - queryTree_list = pg_parse_and_rewrite(src, argtypes, nargs, FALSE); + queryTree_list = pg_parse_and_rewrite(src, argtypes, nargs); _SPI_current->qtlist = queryTree_list; @@ -790,7 +755,6 @@ static int _SPI_pquery(QueryDesc *queryDesc, EState *state, int tcount) { Query *parseTree = queryDesc->parsetree; - Plan *plan = queryDesc->plantree; int operation = queryDesc->operation; CommandDest dest = queryDesc->dest; TupleDesc tupdesc; @@ -875,16 +839,13 @@ _SPI_pquery(QueryDesc *queryDesc, EState *state, int tcount) #endif tupdesc = ExecutorStart(queryDesc, state); - /* Don't work currently */ + /* Don't work currently --- need to rearrange callers so that + * we prepare the portal before doing CreateExecutorState() etc. + * See pquery.c for the correct order of operations. + */ if (isRetrieveIntoPortal) { - ProcessPortal(intoName, - parseTree, - plan, - state, - tupdesc, - None); - return SPI_OK_CURSOR; + elog(FATAL, "SPI_select: retrieve into portal not implemented"); } ExecutorRun(queryDesc, state, EXEC_FOR, parseTree->limitOffset, count); @@ -920,27 +881,13 @@ _SPI_pquery(QueryDesc *queryDesc, EState *state, int tcount) static MemoryContext _SPI_execmem() { - MemoryContext oldcxt; - PortalHeapMemory phmem; - - phmem = PortalGetHeapMemory(_SPI_current->portal); - oldcxt = MemoryContextSwitchTo((MemoryContext) phmem); - - return oldcxt; - + return MemoryContextSwitchTo(_SPI_current->execCxt); } static MemoryContext _SPI_procmem() { - MemoryContext oldcxt; - PortalVariableMemory pvmem; - - pvmem = PortalGetVariableMemory(_SPI_current->portal); - oldcxt = MemoryContextSwitchTo((MemoryContext) pvmem); - - return oldcxt; - + return MemoryContextSwitchTo(_SPI_current->procCxt); } /* @@ -959,7 +906,6 @@ _SPI_begin_call(bool execmem) if (execmem) /* switch to the Executor memory context */ { _SPI_execmem(); - StartPortalAllocMode(DefaultAllocMode, 0); } return 0; @@ -977,9 +923,10 @@ _SPI_end_call(bool procmem) _SPI_current->qtlist = NULL; if (procmem) /* switch to the procedure memory context */ - { /* but free Executor memory before */ - EndPortalAllocMode(); + { _SPI_procmem(); + /* and free Executor memory */ + MemoryContextResetAndDeleteChildren(_SPI_current->execCxt); } return 0; @@ -1016,8 +963,7 @@ _SPI_copy_plan(_SPI_plan *plan, int location) MemoryContext oldcxt = NULL; if (location == _SPI_CPLAN_PROCXT) - oldcxt = MemoryContextSwitchTo((MemoryContext) - PortalGetVariableMemory(_SPI_current->portal)); + oldcxt = MemoryContextSwitchTo(_SPI_current->procCxt); else if (location == _SPI_CPLAN_TOPCXT) oldcxt = MemoryContextSwitchTo(TopMemoryContext); @@ -1033,7 +979,7 @@ _SPI_copy_plan(_SPI_plan *plan, int location) else newplan->argtypes = NULL; - if (location != _SPI_CPLAN_CURCXT) + if (oldcxt != NULL) MemoryContextSwitchTo(oldcxt); return newplan; |