Commit 85801a4d authored by Tom Lane's avatar Tom Lane

Rearrange fmgr.c and relcache so that it's possible to keep FmgrInfo

lookup info in the relcache for index access method support functions.
This makes a huge difference for dynamically loaded support functions,
and should save a few cycles even for built-in ones.  Also tweak dfmgr.c
so that load_external_function is called only once, not twice, when
doing fmgr_info for a dynamically loaded function.  All per performance
gripe from Teodor Sigaev, 5-Oct-01.
parent a965750a
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/common/scankey.c,v 1.19 2001/06/01 02:41:35 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/common/scankey.c,v 1.20 2001/10/06 23:21:43 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -69,3 +69,31 @@ ScanKeyEntryInitialize(ScanKey entry, ...@@ -69,3 +69,31 @@ ScanKeyEntryInitialize(ScanKey entry,
Assert(ScanKeyEntryIsLegal(entry)); Assert(ScanKeyEntryIsLegal(entry));
} }
/*
* ScanKeyEntryInitializeWithInfo
* Initializes a scan key entry using an already-completed FmgrInfo
* function lookup record.
*
* mcxt is the memory context holding the scan key; it'll be used for
* any subsidiary info attached to the scankey's FmgrInfo record.
*/
void
ScanKeyEntryInitializeWithInfo(ScanKey entry,
bits16 flags,
AttrNumber attributeNumber,
FmgrInfo *finfo,
MemoryContext mcxt,
Datum argument)
{
Assert(PointerIsValid(entry));
Assert(RegProcedureIsValid(finfo->fn_oid));
entry->sk_flags = flags;
entry->sk_attno = attributeNumber;
entry->sk_procedure = finfo->fn_oid;
entry->sk_argument = argument;
fmgr_info_copy(&entry->sk_func, finfo, mcxt);
Assert(ScanKeyEntryIsLegal(entry));
}
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.83 2001/08/22 18:24:26 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.84 2001/10/06 23:21:43 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1542,13 +1542,6 @@ gistbulkdelete(PG_FUNCTION_ARGS) ...@@ -1542,13 +1542,6 @@ gistbulkdelete(PG_FUNCTION_ARGS)
void void
initGISTstate(GISTSTATE *giststate, Relation index) initGISTstate(GISTSTATE *giststate, Relation index)
{ {
RegProcedure consistent_proc,
union_proc,
compress_proc,
decompress_proc,
penalty_proc,
picksplit_proc,
equal_proc;
int i; int i;
if (index->rd_att->natts > INDEX_MAX_KEYS) if (index->rd_att->natts > INDEX_MAX_KEYS)
...@@ -1559,20 +1552,27 @@ initGISTstate(GISTSTATE *giststate, Relation index) ...@@ -1559,20 +1552,27 @@ initGISTstate(GISTSTATE *giststate, Relation index)
for (i = 0; i < index->rd_att->natts; i++) for (i = 0; i < index->rd_att->natts; i++)
{ {
consistent_proc = index_getprocid(index, i+1, GIST_CONSISTENT_PROC ); fmgr_info_copy(&(giststate->consistentFn[i]),
union_proc = index_getprocid(index, i+1, GIST_UNION_PROC ); index_getprocinfo(index, i+1, GIST_CONSISTENT_PROC),
compress_proc = index_getprocid(index, i+1, GIST_COMPRESS_PROC ); CurrentMemoryContext);
decompress_proc = index_getprocid(index, i+1, GIST_DECOMPRESS_PROC ); fmgr_info_copy(&(giststate->unionFn[i]),
penalty_proc = index_getprocid(index, i+1, GIST_PENALTY_PROC ); index_getprocinfo(index, i+1, GIST_UNION_PROC),
picksplit_proc = index_getprocid(index, i+1, GIST_PICKSPLIT_PROC ); CurrentMemoryContext);
equal_proc = index_getprocid(index, i+1, GIST_EQUAL_PROC ); fmgr_info_copy(&(giststate->compressFn[i]),
fmgr_info(consistent_proc, &((giststate->consistentFn)[i]) ); index_getprocinfo(index, i+1, GIST_COMPRESS_PROC),
fmgr_info(union_proc, &((giststate->unionFn)[i]) ); CurrentMemoryContext);
fmgr_info(compress_proc, &((giststate->compressFn)[i]) ); fmgr_info_copy(&(giststate->decompressFn[i]),
fmgr_info(decompress_proc, &((giststate->decompressFn)[i]) ); index_getprocinfo(index, i+1, GIST_DECOMPRESS_PROC),
fmgr_info(penalty_proc, &((giststate->penaltyFn)[i]) ); CurrentMemoryContext);
fmgr_info(picksplit_proc, &((giststate->picksplitFn)[i]) ); fmgr_info_copy(&(giststate->penaltyFn[i]),
fmgr_info(equal_proc, &((giststate->equalFn)[i]) ); index_getprocinfo(index, i+1, GIST_PENALTY_PROC),
CurrentMemoryContext);
fmgr_info_copy(&(giststate->picksplitFn[i]),
index_getprocinfo(index, i+1, GIST_PICKSPLIT_PROC),
CurrentMemoryContext);
fmgr_info_copy(&(giststate->equalFn[i]),
index_getprocinfo(index, i+1, GIST_EQUAL_PROC),
CurrentMemoryContext);
} }
} }
......
...@@ -8,13 +8,14 @@ ...@@ -8,13 +8,14 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashutil.c,v 1.26 2001/02/22 21:48:49 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/hash/hashutil.c,v 1.27 2001/10/06 23:21:43 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#include "postgres.h" #include "postgres.h"
#include "access/genam.h"
#include "access/hash.h" #include "access/hash.h"
#include "access/iqual.h" #include "access/iqual.h"
...@@ -27,8 +28,8 @@ _hash_mkscankey(Relation rel, IndexTuple itup, HashMetaPage metap) ...@@ -27,8 +28,8 @@ _hash_mkscankey(Relation rel, IndexTuple itup, HashMetaPage metap)
int natts; int natts;
AttrNumber i; AttrNumber i;
Datum arg; Datum arg;
RegProcedure proc; FmgrInfo *procinfo;
bool null; bool isnull;
natts = rel->rd_rel->relnatts; natts = rel->rd_rel->relnatts;
itupdesc = RelationGetDescr(rel); itupdesc = RelationGetDescr(rel);
...@@ -37,10 +38,14 @@ _hash_mkscankey(Relation rel, IndexTuple itup, HashMetaPage metap) ...@@ -37,10 +38,14 @@ _hash_mkscankey(Relation rel, IndexTuple itup, HashMetaPage metap)
for (i = 0; i < natts; i++) for (i = 0; i < natts; i++)
{ {
arg = index_getattr(itup, i + 1, itupdesc, &null); arg = index_getattr(itup, i + 1, itupdesc, &isnull);
proc = metap->hashm_procid; procinfo = index_getprocinfo(rel, i + 1, HASHPROC);
ScanKeyEntryInitialize(&skey[i], ScanKeyEntryInitializeWithInfo(&skey[i],
0x0, (AttrNumber) (i + 1), proc, arg); 0x0,
(AttrNumber) (i + 1),
procinfo,
CurrentMemoryContext,
arg);
} }
return skey; return skey;
...@@ -89,10 +94,13 @@ _hash_formitem(IndexTuple itup) ...@@ -89,10 +94,13 @@ _hash_formitem(IndexTuple itup)
Bucket Bucket
_hash_call(Relation rel, HashMetaPage metap, Datum key) _hash_call(Relation rel, HashMetaPage metap, Datum key)
{ {
FmgrInfo *procinfo;
uint32 n; uint32 n;
Bucket bucket; Bucket bucket;
n = DatumGetUInt32(OidFunctionCall1(metap->hashm_procid, key)); /* XXX assumes index has only one attribute */
procinfo = index_getprocinfo(rel, 1, HASHPROC);
n = DatumGetUInt32(FunctionCall1(procinfo, key));
bucket = n & metap->hashm_highmask; bucket = n & metap->hashm_highmask;
if (bucket > metap->hashm_maxbucket) if (bucket > metap->hashm_maxbucket)
bucket = bucket & metap->hashm_lowmask; bucket = bucket & metap->hashm_lowmask;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.52 2001/07/15 22:48:15 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.53 2001/10/06 23:21:43 tgl Exp $
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
* index_open - open an index relation by relationId * index_open - open an index relation by relationId
...@@ -428,12 +428,58 @@ index_getprocid(Relation irel, ...@@ -428,12 +428,58 @@ index_getprocid(Relation irel,
{ {
RegProcedure *loc; RegProcedure *loc;
int nproc; int nproc;
int procindex;
nproc = irel->rd_am->amsupport; nproc = irel->rd_am->amsupport;
Assert(procnum > 0 && procnum <= (uint16) nproc);
procindex = (nproc * (attnum - 1)) + (procnum - 1);
loc = irel->rd_support; loc = irel->rd_support;
Assert(loc != NULL); Assert(loc != NULL);
return loc[(nproc * (attnum - 1)) + (procnum - 1)]; return loc[procindex];
}
/* ----------------
* index_getprocinfo
*
* This routine allows index AMs to keep fmgr lookup info for
* support procs in the relcache.
* ----------------
*/
struct FmgrInfo *
index_getprocinfo(Relation irel,
AttrNumber attnum,
uint16 procnum)
{
FmgrInfo *locinfo;
int nproc;
int procindex;
nproc = irel->rd_am->amsupport;
Assert(procnum > 0 && procnum <= (uint16) nproc);
procindex = (nproc * (attnum - 1)) + (procnum - 1);
locinfo = irel->rd_supportinfo;
Assert(locinfo != NULL);
locinfo += procindex;
/* Initialize the lookup info if first time through */
if (locinfo->fn_oid == InvalidOid)
{
RegProcedure *loc = irel->rd_support;
Assert(loc != NULL);
fmgr_info_cxt(loc[procindex], locinfo, irel->rd_indexcxt);
}
return locinfo;
} }
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.52 2001/08/21 16:36:00 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.53 2001/10/06 23:21:43 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -486,12 +486,9 @@ FillScanKeyEntry(Oid operatorObjectId, ScanKey entry) ...@@ -486,12 +486,9 @@ FillScanKeyEntry(Oid operatorObjectId, ScanKey entry)
operatorObjectId); operatorObjectId);
/* /*
* Formerly we initialized entry->sk_func here, but that's a waste of * Mark entry->sk_func invalid, until and unless someone sets it up.
* time because ScanKey entries in strategy maps are never actually
* used to invoke the operator. Furthermore, to do that we'd have to
* worry about setting the proper memory context (the map is probably
* not allocated in the current memory context!)
*/ */
entry->sk_func.fn_oid = InvalidOid;
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.67 2001/07/15 22:48:16 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.68 2001/10/06 23:21:43 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -435,7 +435,6 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) ...@@ -435,7 +435,6 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
BlockNumber blkno; BlockNumber blkno;
StrategyNumber strat; StrategyNumber strat;
RetrieveIndexResult res; RetrieveIndexResult res;
RegProcedure proc;
int32 result; int32 result;
BTScanOpaque so; BTScanOpaque so;
bool continuescan; bool continuescan;
...@@ -532,6 +531,8 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) ...@@ -532,6 +531,8 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
scankeys = (ScanKey) palloc(keysCount * sizeof(ScanKeyData)); scankeys = (ScanKey) palloc(keysCount * sizeof(ScanKeyData));
for (i = 0; i < keysCount; i++) for (i = 0; i < keysCount; i++)
{ {
FmgrInfo *procinfo;
j = nKeyIs[i]; j = nKeyIs[i];
/* /*
...@@ -545,9 +546,13 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) ...@@ -545,9 +546,13 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
elog(ERROR, "_bt_first: btree doesn't support is(not)null, yet"); elog(ERROR, "_bt_first: btree doesn't support is(not)null, yet");
return ((RetrieveIndexResult) NULL); return ((RetrieveIndexResult) NULL);
} }
proc = index_getprocid(rel, i + 1, BTORDER_PROC); procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC);
ScanKeyEntryInitialize(scankeys + i, so->keyData[j].sk_flags, ScanKeyEntryInitializeWithInfo(scankeys + i,
i + 1, proc, so->keyData[j].sk_argument); so->keyData[j].sk_flags,
i + 1,
procinfo,
CurrentMemoryContext,
so->keyData[j].sk_argument);
} }
if (nKeyIs) if (nKeyIs)
pfree(nKeyIs); pfree(nKeyIs);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.45 2001/05/17 14:59:31 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.46 2001/10/06 23:21:43 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -36,7 +36,7 @@ _bt_mkscankey(Relation rel, IndexTuple itup) ...@@ -36,7 +36,7 @@ _bt_mkscankey(Relation rel, IndexTuple itup)
TupleDesc itupdesc; TupleDesc itupdesc;
int natts; int natts;
int i; int i;
RegProcedure proc; FmgrInfo *procinfo;
Datum arg; Datum arg;
bool null; bool null;
bits16 flag; bits16 flag;
...@@ -48,14 +48,15 @@ _bt_mkscankey(Relation rel, IndexTuple itup) ...@@ -48,14 +48,15 @@ _bt_mkscankey(Relation rel, IndexTuple itup)
for (i = 0; i < natts; i++) for (i = 0; i < natts; i++)
{ {
proc = index_getprocid(rel, i + 1, BTORDER_PROC); procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC);
arg = index_getattr(itup, i + 1, itupdesc, &null); arg = index_getattr(itup, i + 1, itupdesc, &null);
flag = null ? SK_ISNULL : 0x0; flag = null ? SK_ISNULL : 0x0;
ScanKeyEntryInitialize(&skey[i], ScanKeyEntryInitializeWithInfo(&skey[i],
flag, flag,
(AttrNumber) (i + 1), (AttrNumber) (i + 1),
proc, procinfo,
arg); CurrentMemoryContext,
arg);
} }
return skey; return skey;
...@@ -76,7 +77,7 @@ _bt_mkscankey_nodata(Relation rel) ...@@ -76,7 +77,7 @@ _bt_mkscankey_nodata(Relation rel)
ScanKey skey; ScanKey skey;
int natts; int natts;
int i; int i;
RegProcedure proc; FmgrInfo *procinfo;
natts = RelationGetNumberOfAttributes(rel); natts = RelationGetNumberOfAttributes(rel);
...@@ -84,12 +85,13 @@ _bt_mkscankey_nodata(Relation rel) ...@@ -84,12 +85,13 @@ _bt_mkscankey_nodata(Relation rel)
for (i = 0; i < natts; i++) for (i = 0; i < natts; i++)
{ {
proc = index_getprocid(rel, i + 1, BTORDER_PROC); procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC);
ScanKeyEntryInitialize(&skey[i], ScanKeyEntryInitializeWithInfo(&skey[i],
SK_ISNULL, SK_ISNULL,
(AttrNumber) (i + 1), (AttrNumber) (i + 1),
proc, procinfo,
(Datum) NULL); CurrentMemoryContext,
(Datum) 0);
} }
return skey; return skey;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.64 2001/09/29 03:46:12 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.65 2001/10/06 23:21:43 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1264,17 +1264,15 @@ rtbulkdelete(PG_FUNCTION_ARGS) ...@@ -1264,17 +1264,15 @@ rtbulkdelete(PG_FUNCTION_ARGS)
static void static void
initRtstate(RTSTATE *rtstate, Relation index) initRtstate(RTSTATE *rtstate, Relation index)
{ {
RegProcedure union_proc, fmgr_info_copy(&rtstate->unionFn,
size_proc, index_getprocinfo(index, 1, RT_UNION_PROC),
inter_proc; CurrentMemoryContext);
fmgr_info_copy(&rtstate->sizeFn,
union_proc = index_getprocid(index, 1, RT_UNION_PROC); index_getprocinfo(index, 1, RT_SIZE_PROC),
size_proc = index_getprocid(index, 1, RT_SIZE_PROC); CurrentMemoryContext);
inter_proc = index_getprocid(index, 1, RT_INTER_PROC); fmgr_info_copy(&rtstate->interFn,
fmgr_info(union_proc, &rtstate->unionFn); index_getprocinfo(index, 1, RT_INTER_PROC),
fmgr_info(size_proc, &rtstate->sizeFn); CurrentMemoryContext);
fmgr_info(inter_proc, &rtstate->interFn);
return;
} }
/* for sorting SPLITCOST records in descending order */ /* for sorting SPLITCOST records in descending order */
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.176 2001/09/06 02:07:42 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.177 2001/10/06 23:21:43 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
...@@ -973,10 +973,8 @@ RelationTruncateIndexes(Oid heapId) ...@@ -973,10 +973,8 @@ RelationTruncateIndexes(Oid heapId)
while (HeapTupleIsValid(indexTuple = heap_getnext(scan, 0))) while (HeapTupleIsValid(indexTuple = heap_getnext(scan, 0)))
{ {
Oid indexId, Oid indexId;
accessMethodId;
IndexInfo *indexInfo; IndexInfo *indexInfo;
HeapTuple classTuple;
Relation heapRelation, Relation heapRelation,
currentIndex; currentIndex;
...@@ -986,16 +984,6 @@ RelationTruncateIndexes(Oid heapId) ...@@ -986,16 +984,6 @@ RelationTruncateIndexes(Oid heapId)
indexId = ((Form_pg_index) GETSTRUCT(indexTuple))->indexrelid; indexId = ((Form_pg_index) GETSTRUCT(indexTuple))->indexrelid;
indexInfo = BuildIndexInfo(indexTuple); indexInfo = BuildIndexInfo(indexTuple);
/* Fetch access method from pg_class tuple for this index */
classTuple = SearchSysCache(RELOID,
ObjectIdGetDatum(indexId),
0, 0, 0);
if (!HeapTupleIsValid(classTuple))
elog(ERROR, "RelationTruncateIndexes: index %u not found in pg_class",
indexId);
accessMethodId = ((Form_pg_class) GETSTRUCT(classTuple))->relam;
ReleaseSysCache(classTuple);
/* /*
* We have to re-open the heap rel each time through this loop * We have to re-open the heap rel each time through this loop
* because index_build will close it again. We need grab no lock, * because index_build will close it again. We need grab no lock,
...@@ -1022,8 +1010,6 @@ RelationTruncateIndexes(Oid heapId) ...@@ -1022,8 +1010,6 @@ RelationTruncateIndexes(Oid heapId)
currentIndex->rd_targblock = InvalidBlockNumber; currentIndex->rd_targblock = InvalidBlockNumber;
/* Initialize the index and rebuild */ /* Initialize the index and rebuild */
InitIndexStrategy(indexInfo->ii_NumIndexAttrs,
currentIndex, accessMethodId);
index_build(heapRelation, currentIndex, indexInfo); index_build(heapRelation, currentIndex, indexInfo);
/* /*
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.164 2001/09/26 21:09:27 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.165 2001/10/06 23:21:43 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
...@@ -644,76 +644,6 @@ UpdateIndexRelation(Oid indexoid, ...@@ -644,76 +644,6 @@ UpdateIndexRelation(Oid indexoid,
heap_freetuple(tuple); heap_freetuple(tuple);
} }
/* ----------------------------------------------------------------
* InitIndexStrategy
*
* XXX this is essentially the same as relcache.c's
* IndexedAccessMethodInitialize(), and probably ought to be merged with it.
* ----------------------------------------------------------------
*/
void
InitIndexStrategy(int numatts,
Relation indexRelation,
Oid accessMethodObjectId)
{
IndexStrategy strategy;
RegProcedure *support;
uint16 amstrategies;
uint16 amsupport;
Size strsize;
/*
* get information from the index relation descriptor
*/
amstrategies = indexRelation->rd_am->amstrategies;
amsupport = indexRelation->rd_am->amsupport;
/*
* compute the size of the strategy array
*/
strsize = AttributeNumberGetIndexStrategySize(numatts, amstrategies);
/*
* allocate the new index strategy structure
*
* the index strategy has to be allocated in the same context as the
* relation descriptor cache or else it will be lost at the end of the
* transaction.
*/
if (!CacheMemoryContext)
CreateCacheMemoryContext();
strategy = (IndexStrategy) MemoryContextAlloc(CacheMemoryContext,
strsize);
if (amsupport > 0)
{
strsize = numatts * (amsupport * sizeof(RegProcedure));
support = (RegProcedure *) MemoryContextAlloc(CacheMemoryContext,
strsize);
}
else
support = (RegProcedure *) NULL;
/*
* fill in the index strategy structure with information from the
* catalogs. First we must advance the command counter so that we
* will see the newly-entered index catalog tuples.
*/
CommandCounterIncrement();
IndexSupportInitialize(strategy, support,
&indexRelation->rd_uniqueindex,
RelationGetRelid(indexRelation),
accessMethodObjectId,
amstrategies, amsupport, numatts);
/*
* store the strategy information in the index reldesc
*/
RelationSetIndexSupport(indexRelation, strategy, support);
}
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
* index_create * index_create
...@@ -839,11 +769,13 @@ index_create(char *heapRelationName, ...@@ -839,11 +769,13 @@ index_create(char *heapRelationName,
classObjectId, primary); classObjectId, primary);
/* /*
* initialize the index strategy * fill in the index strategy structure with information from the
* catalogs. First we must advance the command counter so that we
* will see the newly-entered index catalog tuples.
*/ */
InitIndexStrategy(indexInfo->ii_NumIndexAttrs, CommandCounterIncrement();
indexRelation,
accessMethodObjectId); RelationInitIndexAccessInfo(indexRelation);
/* /*
* If this is bootstrap (initdb) time, then we don't actually fill in * If this is bootstrap (initdb) time, then we don't actually fill in
...@@ -1935,11 +1867,9 @@ reindex_index(Oid indexId, bool force, bool inplace) ...@@ -1935,11 +1867,9 @@ reindex_index(Oid indexId, bool force, bool inplace)
heapRelation; heapRelation;
ScanKeyData entry; ScanKeyData entry;
HeapScanDesc scan; HeapScanDesc scan;
HeapTuple indexTuple, HeapTuple indexTuple;
classTuple;
IndexInfo *indexInfo; IndexInfo *indexInfo;
Oid heapId, Oid heapId;
accessMethodId;
bool old; bool old;
/* /*
...@@ -1970,15 +1900,6 @@ reindex_index(Oid indexId, bool force, bool inplace) ...@@ -1970,15 +1900,6 @@ reindex_index(Oid indexId, bool force, bool inplace)
heap_endscan(scan); heap_endscan(scan);
heap_close(indexRelation, AccessShareLock); heap_close(indexRelation, AccessShareLock);
/* Fetch the classTuple associated with this index */
classTuple = SearchSysCache(RELOID,
ObjectIdGetDatum(indexId),
0, 0, 0);
if (!HeapTupleIsValid(classTuple))
elog(ERROR, "reindex_index: index %u not found in pg_class", indexId);
accessMethodId = ((Form_pg_class) GETSTRUCT(classTuple))->relam;
ReleaseSysCache(classTuple);
/* Open our index relation */ /* Open our index relation */
heapRelation = heap_open(heapId, ExclusiveLock); heapRelation = heap_open(heapId, ExclusiveLock);
if (heapRelation == NULL) if (heapRelation == NULL)
...@@ -2012,7 +1933,6 @@ reindex_index(Oid indexId, bool force, bool inplace) ...@@ -2012,7 +1933,6 @@ reindex_index(Oid indexId, bool force, bool inplace)
} }
/* Initialize the index and rebuild */ /* Initialize the index and rebuild */
InitIndexStrategy(indexInfo->ii_NumIndexAttrs, iRel, accessMethodId);
index_build(heapRelation, iRel, indexInfo); index_build(heapRelation, iRel, indexInfo);
/* /*
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.60 2001/10/02 21:39:35 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.61 2001/10/06 23:21:43 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -246,11 +246,14 @@ ProcedureCreate(char *procedureName, ...@@ -246,11 +246,14 @@ ProcedureCreate(char *procedureName,
if (languageObjectId == ClanguageId) if (languageObjectId == ClanguageId)
{ {
void *libraryhandle;
/* If link symbol is specified as "-", substitute procedure name */ /* If link symbol is specified as "-", substitute procedure name */
if (strcmp(prosrc, "-") == 0) if (strcmp(prosrc, "-") == 0)
prosrc = procedureName; prosrc = procedureName;
(void) load_external_function(probin, prosrc, true); (void) load_external_function(probin, prosrc, true,
(void) fetch_finfo_record(probin, prosrc); &libraryhandle);
(void) fetch_finfo_record(libraryhandle, prosrc);
} }
/* /*
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
* Portions Copyright (c) 2000-2001, PostgreSQL Global Development Group * Portions Copyright (c) 2000-2001, PostgreSQL Global Development Group
* Copyright 1999 Jan Wieck * Copyright 1999 Jan Wieck
* *
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.27 2001/10/05 17:28:12 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.28 2001/10/06 23:21:44 tgl Exp $
* *
* ---------- * ----------
*/ */
...@@ -3243,7 +3243,6 @@ ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue) ...@@ -3243,7 +3243,6 @@ ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue)
{ {
HeapTuple opr_tup; HeapTuple opr_tup;
Oid opr_proc; Oid opr_proc;
MemoryContext oldcontext;
FmgrInfo finfo; FmgrInfo finfo;
opr_tup = SearchSysCache(OPERNAME, opr_tup = SearchSysCache(OPERNAME,
...@@ -3265,9 +3264,7 @@ ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue) ...@@ -3265,9 +3264,7 @@ ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue)
* table entry, we must make sure any subsidiary structures of the * table entry, we must make sure any subsidiary structures of the
* fmgr record are kept in TopMemoryContext. * fmgr record are kept in TopMemoryContext.
*/ */
oldcontext = MemoryContextSwitchTo(TopMemoryContext); fmgr_info_cxt(opr_proc, &finfo, TopMemoryContext);
fmgr_info(opr_proc, &finfo);
MemoryContextSwitchTo(oldcontext);
entry = (RI_OpreqHashEntry *) hash_search(ri_opreq_cache, entry = (RI_OpreqHashEntry *) hash_search(ri_opreq_cache,
(void *) &typeid, (void *) &typeid,
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varbit.c,v 1.18 2001/05/22 16:37:16 petere Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/varbit.c,v 1.19 2001/10/06 23:21:44 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "utils/array.h" #include "utils/array.h"
#include "utils/fmgroids.h" #include "utils/fmgroids.h"
#include "utils/memutils.h"
#include "utils/varbit.h" #include "utils/varbit.h"
#define HEXDIG(z) ((z)<10 ? ((z)+'0') : ((z)-10+'A')) #define HEXDIG(z) ((z)<10 ? ((z)+'0') : ((z)-10+'A'))
...@@ -238,7 +239,7 @@ _bit(PG_FUNCTION_ARGS) ...@@ -238,7 +239,7 @@ _bit(PG_FUNCTION_ARGS)
static FmgrInfo bit_finfo; static FmgrInfo bit_finfo;
if (bit_finfo.fn_oid == InvalidOid) if (bit_finfo.fn_oid == InvalidOid)
fmgr_info(F_BIT, &bit_finfo); fmgr_info_cxt(F_BIT, &bit_finfo, TopMemoryContext);
MemSet(&locfcinfo, 0, sizeof(locfcinfo)); MemSet(&locfcinfo, 0, sizeof(locfcinfo));
locfcinfo.flinfo = &bit_finfo; locfcinfo.flinfo = &bit_finfo;
...@@ -452,7 +453,7 @@ _varbit(PG_FUNCTION_ARGS) ...@@ -452,7 +453,7 @@ _varbit(PG_FUNCTION_ARGS)
static FmgrInfo varbit_finfo; static FmgrInfo varbit_finfo;
if (varbit_finfo.fn_oid == InvalidOid) if (varbit_finfo.fn_oid == InvalidOid)
fmgr_info(F_VARBIT, &varbit_finfo); fmgr_info_cxt(F_VARBIT, &varbit_finfo, TopMemoryContext);
MemSet(&locfcinfo, 0, sizeof(locfcinfo)); MemSet(&locfcinfo, 0, sizeof(locfcinfo));
locfcinfo.flinfo = &varbit_finfo; locfcinfo.flinfo = &varbit_finfo;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.83 2001/10/03 05:29:24 thomas Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.84 2001/10/06 23:21:44 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -285,7 +285,7 @@ _bpchar(PG_FUNCTION_ARGS) ...@@ -285,7 +285,7 @@ _bpchar(PG_FUNCTION_ARGS)
static FmgrInfo bpchar_finfo; static FmgrInfo bpchar_finfo;
if (bpchar_finfo.fn_oid == InvalidOid) if (bpchar_finfo.fn_oid == InvalidOid)
fmgr_info(F_BPCHAR, &bpchar_finfo); fmgr_info_cxt(F_BPCHAR, &bpchar_finfo, TopMemoryContext);
MemSet(&locfcinfo, 0, sizeof(locfcinfo)); MemSet(&locfcinfo, 0, sizeof(locfcinfo));
locfcinfo.flinfo = &bpchar_finfo; locfcinfo.flinfo = &bpchar_finfo;
...@@ -544,7 +544,7 @@ _varchar(PG_FUNCTION_ARGS) ...@@ -544,7 +544,7 @@ _varchar(PG_FUNCTION_ARGS)
static FmgrInfo varchar_finfo; static FmgrInfo varchar_finfo;
if (varchar_finfo.fn_oid == InvalidOid) if (varchar_finfo.fn_oid == InvalidOid)
fmgr_info(F_VARCHAR, &varchar_finfo); fmgr_info_cxt(F_VARCHAR, &varchar_finfo, TopMemoryContext);
MemSet(&locfcinfo, 0, sizeof(locfcinfo)); MemSet(&locfcinfo, 0, sizeof(locfcinfo));
locfcinfo.flinfo = &varchar_finfo; locfcinfo.flinfo = &varchar_finfo;
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# Makefile for utils/cache # Makefile for utils/cache
# #
# IDENTIFICATION # IDENTIFICATION
# $Header: /cvsroot/pgsql/src/backend/utils/cache/Makefile,v 1.14 2000/08/31 16:10:46 petere Exp $ # $Header: /cvsroot/pgsql/src/backend/utils/cache/Makefile,v 1.15 2001/10/06 23:21:44 tgl Exp $
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
...@@ -12,7 +12,7 @@ subdir = src/backend/utils/cache ...@@ -12,7 +12,7 @@ subdir = src/backend/utils/cache
top_builddir = ../../../.. top_builddir = ../../../..
include $(top_builddir)/src/Makefile.global include $(top_builddir)/src/Makefile.global
OBJS = catcache.o inval.o rel.o relcache.o syscache.o lsyscache.o \ OBJS = catcache.o inval.o relcache.o syscache.o lsyscache.o \
fcache.o temprel.o fcache.o temprel.o
all: SUBSYS.o all: SUBSYS.o
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.82 2001/08/21 16:36:04 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.83 2001/10/06 23:21:44 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -269,23 +269,10 @@ CatalogCacheInitializeCache(CatCache *cache) ...@@ -269,23 +269,10 @@ CatalogCacheInitializeCache(CatCache *cache)
*/ */
cache->cc_skey[i].sk_procedure = EQPROC(keytype); cache->cc_skey[i].sk_procedure = EQPROC(keytype);
/* /* Do function lookup */
* Note: to avoid any possible leakage of scan temporary data into fmgr_info_cxt(cache->cc_skey[i].sk_procedure,
* the cache context, we do not switch into CacheMemoryContext while &cache->cc_skey[i].sk_func,
* calling fmgr_info here. Instead set fn_mcxt on return. This CacheMemoryContext);
* would fail to work correctly if fmgr_info allocated any subsidiary
* data structures to attach to the FmgrInfo record; but it doesn't
* do so for built-in functions, and all the comparator functions
* for system caches should most assuredly be built-in functions.
* Currently there's no real need to fix fn_mcxt either, but let's do
* that anyway just to make sure it's not pointing to a dead context
* later on.
*/
fmgr_info(cache->cc_skey[i].sk_procedure,
&cache->cc_skey[i].sk_func);
cache->cc_skey[i].sk_func.fn_mcxt = CacheMemoryContext;
/* Initialize sk_attno suitably for HeapKeyTest() and heap scans */ /* Initialize sk_attno suitably for HeapKeyTest() and heap scans */
cache->cc_skey[i].sk_attno = cache->cc_key[i]; cache->cc_skey[i].sk_attno = cache->cc_key[i];
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/fcache.c,v 1.40 2001/09/21 00:11:31 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/fcache.c,v 1.41 2001/10/06 23:21:44 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -23,26 +23,22 @@ ...@@ -23,26 +23,22 @@
FunctionCachePtr FunctionCachePtr
init_fcache(Oid foid, int nargs, MemoryContext fcacheCxt) init_fcache(Oid foid, int nargs, MemoryContext fcacheCxt)
{ {
MemoryContext oldcontext;
FunctionCachePtr retval; FunctionCachePtr retval;
/* Safety check (should never fail, as parser should check sooner) */ /* Safety check (should never fail, as parser should check sooner) */
if (nargs > FUNC_MAX_ARGS) if (nargs > FUNC_MAX_ARGS)
elog(ERROR, "init_fcache: too many arguments"); elog(ERROR, "init_fcache: too many arguments");
/* Switch to a context long-lived enough for the fcache entry */ /* Create fcache entry in the desired context */
oldcontext = MemoryContextSwitchTo(fcacheCxt); retval = (FunctionCachePtr) MemoryContextAlloc(fcacheCxt,
sizeof(FunctionCache));
retval = (FunctionCachePtr) palloc(sizeof(FunctionCache));
MemSet(retval, 0, sizeof(FunctionCache)); MemSet(retval, 0, sizeof(FunctionCache));
/* Set up the primary fmgr lookup information */ /* Set up the primary fmgr lookup information */
fmgr_info(foid, &(retval->func)); fmgr_info_cxt(foid, &(retval->func), fcacheCxt);
/* Initialize additional info */ /* Initialize additional info */
retval->setArgsValid = false; retval->setArgsValid = false;
MemoryContextSwitchTo(oldcontext);
return retval; return retval;
} }
/*-------------------------------------------------------------------------
*
* rel.c
* POSTGRES relation descriptor code.
*
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/rel.c,v 1.9 2001/01/24 19:43:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "access/istrat.h"
/*
* RelationIsValid is now a macro in rel.h -cim 4/27/91
*
* All of the RelationGet...() functions are now macros in rel.h
* -mer 3/2/92
*/
/*
* RelationSetIndexSupport
* Sets index strategy and support info for a relation.
*
* This routine saves two pointers -- one to the IndexStrategy, and
* one to the RegProcs that support the indexed access method.
*
* Note:
* Assumes relation descriptor is valid.
* Assumes index strategy is valid. Assumes support is valid if non-
* NULL.
*/
void
RelationSetIndexSupport(Relation relation,
IndexStrategy strategy,
RegProcedure *support)
{
Assert(PointerIsValid(relation));
Assert(IndexStrategyIsValid(strategy));
relation->rd_istrat = strategy;
relation->rd_support = support;
}
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.145 2001/10/05 17:28:12 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.146 2001/10/06 23:21:44 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -249,7 +249,6 @@ static void build_tupdesc_ind(RelationBuildDescInfo buildinfo, ...@@ -249,7 +249,6 @@ static void build_tupdesc_ind(RelationBuildDescInfo buildinfo,
Relation relation); Relation relation);
static Relation RelationBuildDesc(RelationBuildDescInfo buildinfo, static Relation RelationBuildDesc(RelationBuildDescInfo buildinfo,
Relation oldrelation); Relation oldrelation);
static void IndexedAccessMethodInitialize(Relation relation);
static void AttrDefaultFetch(Relation relation); static void AttrDefaultFetch(Relation relation);
static void RelCheckFetch(Relation relation); static void RelCheckFetch(Relation relation);
static List *insert_ordered_oid(List *list, Oid datum); static List *insert_ordered_oid(List *list, Oid datum);
...@@ -1044,7 +1043,7 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo, ...@@ -1044,7 +1043,7 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo,
* initialize index strategy and support information for this relation * initialize index strategy and support information for this relation
*/ */
if (OidIsValid(relam)) if (OidIsValid(relam))
IndexedAccessMethodInitialize(relation); RelationInitIndexAccessInfo(relation);
/* /*
* initialize the relation lock manager information * initialize the relation lock manager information
...@@ -1087,41 +1086,75 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo, ...@@ -1087,41 +1086,75 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo,
return relation; return relation;
} }
static void /*
IndexedAccessMethodInitialize(Relation relation) * Initialize index-access-method support data for an index relation
*/
void
RelationInitIndexAccessInfo(Relation relation)
{ {
MemoryContext indexcxt;
IndexStrategy strategy; IndexStrategy strategy;
RegProcedure *support; RegProcedure *support;
FmgrInfo *supportinfo;
int natts; int natts;
Size stratSize;
Size supportSize;
uint16 amstrategies; uint16 amstrategies;
uint16 amsupport; uint16 amsupport;
Size stratSize;
natts = relation->rd_rel->relnatts; natts = relation->rd_rel->relnatts;
amstrategies = relation->rd_am->amstrategies; amstrategies = relation->rd_am->amstrategies;
amsupport = relation->rd_am->amsupport; amsupport = relation->rd_am->amsupport;
/*
* Make the private context to hold index access info. The reason
* we need a context, and not just a couple of pallocs, is so that
* we won't leak any subsidiary info attached to fmgr lookup records.
*
* Context parameters are set on the assumption that it'll probably not
* contain much data.
*/
indexcxt = AllocSetContextCreate(CacheMemoryContext,
RelationGetRelationName(relation),
0, /* minsize */
512, /* initsize */
1024); /* maxsize */
relation->rd_indexcxt = indexcxt;
/*
* Allocate arrays to hold data
*/
stratSize = AttributeNumberGetIndexStrategySize(natts, amstrategies); stratSize = AttributeNumberGetIndexStrategySize(natts, amstrategies);
strategy = (IndexStrategy) MemoryContextAlloc(CacheMemoryContext, strategy = (IndexStrategy) MemoryContextAlloc(indexcxt, stratSize);
stratSize);
if (amsupport > 0) if (amsupport > 0)
{ {
supportSize = natts * (amsupport * sizeof(RegProcedure)); int nsupport = natts * amsupport;
support = (RegProcedure *) MemoryContextAlloc(CacheMemoryContext,
supportSize); support = (RegProcedure *)
MemoryContextAlloc(indexcxt, nsupport * sizeof(RegProcedure));
supportinfo = (FmgrInfo *)
MemoryContextAlloc(indexcxt, nsupport * sizeof(FmgrInfo));
MemSet(supportinfo, 0, nsupport * sizeof(FmgrInfo));
} }
else else
support = (RegProcedure *) NULL; {
support = NULL;
supportinfo = NULL;
}
/*
* Fill the strategy map and the support RegProcedure arrays.
* (supportinfo is left as zeroes, and is filled on-the-fly when used)
*/
IndexSupportInitialize(strategy, support, IndexSupportInitialize(strategy, support,
&relation->rd_uniqueindex, &relation->rd_uniqueindex,
RelationGetRelid(relation), RelationGetRelid(relation),
relation->rd_rel->relam, relation->rd_rel->relam,
amstrategies, amsupport, natts); amstrategies, amsupport, natts);
RelationSetIndexSupport(relation, strategy, support); relation->rd_istrat = strategy;
relation->rd_support = support;
relation->rd_supportinfo = supportinfo;
} }
/* /*
...@@ -1595,11 +1628,9 @@ RelationClearRelation(Relation relation, bool rebuildIt) ...@@ -1595,11 +1628,9 @@ RelationClearRelation(Relation relation, bool rebuildIt)
pfree(relation->rd_am); pfree(relation->rd_am);
if (relation->rd_rel) if (relation->rd_rel)
pfree(relation->rd_rel); pfree(relation->rd_rel);
if (relation->rd_istrat)
pfree(relation->rd_istrat);
if (relation->rd_support)
pfree(relation->rd_support);
freeList(relation->rd_indexlist); freeList(relation->rd_indexlist);
if (relation->rd_indexcxt)
MemoryContextDelete(relation->rd_indexcxt);
/* /*
* If we're really done with the relcache entry, blow it away. But if * If we're really done with the relcache entry, blow it away. But if
...@@ -2624,8 +2655,11 @@ init_irels(void) ...@@ -2624,8 +2655,11 @@ init_irels(void)
Relation ird; Relation ird;
Form_pg_am am; Form_pg_am am;
Form_pg_class relform; Form_pg_class relform;
MemoryContext indexcxt;
IndexStrategy strat; IndexStrategy strat;
RegProcedure *support; RegProcedure *support;
int nstrategies,
nsupport;
int i; int i;
int relno; int relno;
...@@ -2646,6 +2680,13 @@ init_irels(void) ...@@ -2646,6 +2680,13 @@ init_irels(void)
return; return;
} }
/* safety check for incompatible relcache layout */
if (len != sizeof(RelationData))
{
write_irels();
return;
}
ird = irel[relno] = (Relation) palloc(len); ird = irel[relno] = (Relation) palloc(len);
MemSet(ird, 0, len); MemSet(ird, 0, len);
...@@ -2659,6 +2700,7 @@ init_irels(void) ...@@ -2659,6 +2700,7 @@ init_irels(void)
/* reset transient fields */ /* reset transient fields */
ird->rd_targblock = InvalidBlockNumber; ird->rd_targblock = InvalidBlockNumber;
ird->rd_fd = -1; ird->rd_fd = -1;
ird->rd_refcnt = 0;
ird->rd_node.tblNode = MyDatabaseId; ird->rd_node.tblNode = MyDatabaseId;
...@@ -2716,6 +2758,17 @@ init_irels(void) ...@@ -2716,6 +2758,17 @@ init_irels(void)
} }
} }
/*
* prepare index info context --- parameters should match
* RelationInitIndexAccessInfo
*/
indexcxt = AllocSetContextCreate(CacheMemoryContext,
RelationGetRelationName(ird),
0, /* minsize */
512, /* initsize */
1024); /* maxsize */
ird->rd_indexcxt = indexcxt;
/* next, read the index strategy map */ /* next, read the index strategy map */
if ((nread = FileRead(fd, (char *) &len, sizeof(len))) != sizeof(len)) if ((nread = FileRead(fd, (char *) &len, sizeof(len))) != sizeof(len))
{ {
...@@ -2723,27 +2776,18 @@ init_irels(void) ...@@ -2723,27 +2776,18 @@ init_irels(void)
return; return;
} }
strat = (IndexStrategy) palloc(len); strat = (IndexStrategy) MemoryContextAlloc(indexcxt, len);
if ((nread = FileRead(fd, (char *) strat, len)) != len) if ((nread = FileRead(fd, (char *) strat, len)) != len)
{ {
write_irels(); write_irels();
return; return;
} }
/* oh, for god's sake... */ /* have to invalidate any FmgrInfo data in the strategy maps */
#define SMD(i) strat->strategyMapData[i].entry[0] nstrategies = am->amstrategies * relform->relnatts;
for (i = 0; i < nstrategies; i++)
/* have to reinit the function pointers in the strategy maps */ strat->strategyMapData[i].entry[0].sk_func.fn_oid = InvalidOid;
for (i = 0; i < am->amstrategies * relform->relnatts; i++)
{
fmgr_info(SMD(i).sk_procedure,
&(SMD(i).sk_func));
}
/*
* use a real field called rd_istrat instead of the bogosity of
* hanging invisible fields off the end of a structure - jolly
*/
ird->rd_istrat = strat; ird->rd_istrat = strat;
/* finally, read the vector of support procedures */ /* finally, read the vector of support procedures */
...@@ -2753,7 +2797,7 @@ init_irels(void) ...@@ -2753,7 +2797,7 @@ init_irels(void)
return; return;
} }
support = (RegProcedure *) palloc(len); support = (RegProcedure *) MemoryContextAlloc(indexcxt, len);
if ((nread = FileRead(fd, (char *) support, len)) != len) if ((nread = FileRead(fd, (char *) support, len)) != len)
{ {
write_irels(); write_irels();
...@@ -2761,6 +2805,11 @@ init_irels(void) ...@@ -2761,6 +2805,11 @@ init_irels(void)
} }
ird->rd_support = support; ird->rd_support = support;
nsupport = relform->relnatts * am->amsupport;
ird->rd_supportinfo = (FmgrInfo *)
MemoryContextAlloc(indexcxt, nsupport * sizeof(FmgrInfo));
MemSet(ird->rd_supportinfo, 0, nsupport * sizeof(FmgrInfo));
RelationInitLockInfo(ird); RelationInitLockInfo(ird);
RelationCacheInsert(ird); RelationCacheInsert(ird);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.52 2001/10/04 19:13:55 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.53 2001/10/06 23:21:44 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -55,14 +55,20 @@ static char * substitute_libpath_macro(const char * name); ...@@ -55,14 +55,20 @@ static char * substitute_libpath_macro(const char * name);
/* /*
* Load the specified dynamic-link library file, and look for a function * Load the specified dynamic-link library file, and look for a function
* named funcname in it. If the function is not found, we raise an error * named funcname in it. (funcname can be NULL to just load the file.)
* if signalNotFound is true, else return (PGFunction) NULL. Note that *
* errors in loading the library will provoke elog regardless of * If the function is not found, we raise an error if signalNotFound is true,
* signalNotFound. * else return (PGFunction) NULL. Note that errors in loading the library
*/ * will provoke elog regardless of signalNotFound.
*
* If filehandle is not NULL, then *filehandle will be set to a handle
* identifying the library file. The filehandle can be used with
* lookup_external_function to lookup additional functions in the same file
* at less cost than repeating load_external_function.
*/
PGFunction PGFunction
load_external_function(char *filename, char *funcname, load_external_function(char *filename, char *funcname,
bool signalNotFound) bool signalNotFound, void **filehandle)
{ {
DynamicFileList *file_scanner; DynamicFileList *file_scanner;
PGFunction retval; PGFunction retval;
...@@ -130,6 +136,10 @@ load_external_function(char *filename, char *funcname, ...@@ -130,6 +136,10 @@ load_external_function(char *filename, char *funcname,
file_tail = file_scanner; file_tail = file_scanner;
} }
/* Return handle if caller wants it. */
if (filehandle)
*filehandle = file_scanner->handle;
/* /*
* If funcname is NULL, we only wanted to load the file. * If funcname is NULL, we only wanted to load the file.
*/ */
...@@ -201,11 +211,20 @@ load_file(char *filename) ...@@ -201,11 +211,20 @@ load_file(char *filename)
} }
} }
load_external_function(fullname, (char *) NULL, false); load_external_function(fullname, (char *) NULL, false, (void *) NULL);
pfree(fullname); pfree(fullname);
} }
/*
* Lookup a function whose library file is already loaded.
* Return (PGFunction) NULL if not found.
*/
PGFunction
lookup_external_function(void *filehandle, char *funcname)
{
return pg_dlsym(filehandle, funcname);
}
static bool static bool
...@@ -305,7 +324,7 @@ substitute_libpath_macro(const char * name) ...@@ -305,7 +324,7 @@ substitute_libpath_macro(const char * name)
AssertArg(name != NULL); AssertArg(name != NULL);
if (strlen(name) == 0 || name[0] != '$') if (name[0] != '$')
return pstrdup(name); return pstrdup(name);
macroname_len = strcspn(name + 1, "/") + 1; macroname_len = strcspn(name + 1, "/") + 1;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.54 2001/08/14 22:21:58 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.55 2001/10/06 23:21:44 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -121,11 +121,21 @@ fmgr_lookupByName(const char *name) ...@@ -121,11 +121,21 @@ fmgr_lookupByName(const char *name)
* will be allocated in that context. The caller must ensure that this * will be allocated in that context. The caller must ensure that this
* context is at least as long-lived as the info struct itself. This is * context is at least as long-lived as the info struct itself. This is
* not a problem in typical cases where the info struct is on the stack or * not a problem in typical cases where the info struct is on the stack or
* in freshly-palloc'd space, but one must take extra care when the info * in freshly-palloc'd space. However, if one intends to store an info
* struct is in a long-lived table. * struct in a long-lived table, it's better to use fmgr_info_cxt.
*/ */
void void
fmgr_info(Oid functionId, FmgrInfo *finfo) fmgr_info(Oid functionId, FmgrInfo *finfo)
{
fmgr_info_cxt(functionId, finfo, CurrentMemoryContext);
}
/*
* Fill a FmgrInfo struct, specifying a memory context in which its
* subsidiary data should go.
*/
void
fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
{ {
const FmgrBuiltin *fbp; const FmgrBuiltin *fbp;
HeapTuple procedureTuple; HeapTuple procedureTuple;
...@@ -139,7 +149,7 @@ fmgr_info(Oid functionId, FmgrInfo *finfo) ...@@ -139,7 +149,7 @@ fmgr_info(Oid functionId, FmgrInfo *finfo)
*/ */
finfo->fn_oid = InvalidOid; finfo->fn_oid = InvalidOid;
finfo->fn_extra = NULL; finfo->fn_extra = NULL;
finfo->fn_mcxt = CurrentMemoryContext; finfo->fn_mcxt = mcxt;
if ((fbp = fmgr_isbuiltin(functionId)) != NULL) if ((fbp = fmgr_isbuiltin(functionId)) != NULL)
{ {
...@@ -228,6 +238,7 @@ fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple) ...@@ -228,6 +238,7 @@ fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
probinattr; probinattr;
char *prosrcstring, char *prosrcstring,
*probinstring; *probinstring;
void *libraryhandle;
PGFunction user_fn; PGFunction user_fn;
Pg_finfo_record *inforec; Pg_finfo_record *inforec;
Oldstyle_fnextra *fnextra; Oldstyle_fnextra *fnextra;
...@@ -250,22 +261,19 @@ fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple) ...@@ -250,22 +261,19 @@ fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
probinstring = DatumGetCString(DirectFunctionCall1(textout, probinattr)); probinstring = DatumGetCString(DirectFunctionCall1(textout, probinattr));
/* Look up the function itself */ /* Look up the function itself */
user_fn = load_external_function(probinstring, prosrcstring, true); user_fn = load_external_function(probinstring, prosrcstring, true,
&libraryhandle);
/* Get the function information record (real or default) */ /* Get the function information record (real or default) */
inforec = fetch_finfo_record(probinstring, prosrcstring); inforec = fetch_finfo_record(libraryhandle, prosrcstring);
switch (inforec->api_version) switch (inforec->api_version)
{ {
case 0: case 0:
/* Old style: need to use a handler */ /* Old style: need to use a handler */
finfo->fn_addr = fmgr_oldstyle; finfo->fn_addr = fmgr_oldstyle;
fnextra = (Oldstyle_fnextra *)
/* MemoryContextAlloc(finfo->fn_mcxt, sizeof(Oldstyle_fnextra));
* OK to use palloc here because fn_mcxt is
* CurrentMemoryContext
*/
fnextra = (Oldstyle_fnextra *) palloc(sizeof(Oldstyle_fnextra));
finfo->fn_extra = (void *) fnextra; finfo->fn_extra = (void *) fnextra;
MemSet(fnextra, 0, sizeof(Oldstyle_fnextra)); MemSet(fnextra, 0, sizeof(Oldstyle_fnextra));
fnextra->func = (func_ptr) user_fn; fnextra->func = (func_ptr) user_fn;
...@@ -335,6 +343,8 @@ fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple) ...@@ -335,6 +343,8 @@ fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
/* /*
* Fetch and validate the information record for the given external function. * Fetch and validate the information record for the given external function.
* The function is specified by a handle for the containing library
* (obtained from load_external_function) as well as the function name.
* *
* If no info function exists for the given name, it is not an error. * If no info function exists for the given name, it is not an error.
* Instead we return a default info record for a version-0 function. * Instead we return a default info record for a version-0 function.
...@@ -346,7 +356,7 @@ fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple) ...@@ -346,7 +356,7 @@ fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple)
* pg_proc. * pg_proc.
*/ */
Pg_finfo_record * Pg_finfo_record *
fetch_finfo_record(char *filename, char *funcname) fetch_finfo_record(void *filehandle, char *funcname)
{ {
char *infofuncname; char *infofuncname;
PGFInfoFunction infofunc; PGFInfoFunction infofunc;
...@@ -355,12 +365,12 @@ fetch_finfo_record(char *filename, char *funcname) ...@@ -355,12 +365,12 @@ fetch_finfo_record(char *filename, char *funcname)
/* Compute name of info func */ /* Compute name of info func */
infofuncname = (char *) palloc(strlen(funcname) + 10); infofuncname = (char *) palloc(strlen(funcname) + 10);
sprintf(infofuncname, "pg_finfo_%s", funcname); strcpy(infofuncname, "pg_finfo_");
strcat(infofuncname, funcname);
/* Try to look up the info function */ /* Try to look up the info function */
infofunc = (PGFInfoFunction) load_external_function(filename, infofunc = (PGFInfoFunction) lookup_external_function(filehandle,
infofuncname, infofuncname);
false);
if (infofunc == (PGFInfoFunction) NULL) if (infofunc == (PGFInfoFunction) NULL)
{ {
/* Not found --- assume version 0 */ /* Not found --- assume version 0 */
...@@ -391,6 +401,34 @@ fetch_finfo_record(char *filename, char *funcname) ...@@ -391,6 +401,34 @@ fetch_finfo_record(char *filename, char *funcname)
} }
/*
* Copy an FmgrInfo struct
*
* This is inherently somewhat bogus since we can't reliably duplicate
* language-dependent subsidiary info. We cheat by zeroing fn_extra,
* instead, meaning that subsidiary info will have to be recomputed.
*/
void
fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo,
MemoryContext destcxt)
{
memcpy(dstinfo, srcinfo, sizeof(FmgrInfo));
dstinfo->fn_mcxt = destcxt;
if (dstinfo->fn_addr == fmgr_oldstyle)
{
/* For oldstyle functions we must copy fn_extra */
Oldstyle_fnextra *fnextra;
fnextra = (Oldstyle_fnextra *)
MemoryContextAlloc(destcxt, sizeof(Oldstyle_fnextra));
memcpy(fnextra, srcinfo->fn_extra, sizeof(Oldstyle_fnextra));
dstinfo->fn_extra = (void *) fnextra;
}
else
dstinfo->fn_extra = NULL;
}
/* /*
* Specialized lookup routine for ProcedureCreate(): given the alleged name * Specialized lookup routine for ProcedureCreate(): given the alleged name
* of an internal function, return the OID of the function. * of an internal function, return the OID of the function.
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: genam.h,v 1.26 2001/07/15 22:48:18 tgl Exp $ * $Id: genam.h,v 1.27 2001/10/06 23:21:44 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -56,6 +56,8 @@ extern IndexBulkDeleteResult *index_bulk_delete(Relation relation, ...@@ -56,6 +56,8 @@ extern IndexBulkDeleteResult *index_bulk_delete(Relation relation,
extern RegProcedure index_cost_estimator(Relation relation); extern RegProcedure index_cost_estimator(Relation relation);
extern RegProcedure index_getprocid(Relation irel, AttrNumber attnum, extern RegProcedure index_getprocid(Relation irel, AttrNumber attnum,
uint16 procnum); uint16 procnum);
extern struct FmgrInfo *index_getprocinfo(Relation irel, AttrNumber attnum,
uint16 procnum);
/* in genam.c */ /* in genam.c */
extern IndexScanDesc RelationGetIndexScan(Relation relation, bool scanFromEnd, extern IndexScanDesc RelationGetIndexScan(Relation relation, bool scanFromEnd,
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: skey.h,v 1.16 2001/06/09 18:16:59 tgl Exp $ * $Id: skey.h,v 1.17 2001/10/06 23:21:44 tgl Exp $
* *
* Note: * Note:
* Needs more accessor/assignment routines. * Needs more accessor/assignment routines.
...@@ -44,5 +44,8 @@ typedef ScanKeyData *ScanKey; ...@@ -44,5 +44,8 @@ typedef ScanKeyData *ScanKey;
extern void ScanKeyEntrySetIllegal(ScanKey entry); extern void ScanKeyEntrySetIllegal(ScanKey entry);
extern void ScanKeyEntryInitialize(ScanKey entry, bits16 flags, extern void ScanKeyEntryInitialize(ScanKey entry, bits16 flags,
AttrNumber attributeNumber, RegProcedure procedure, Datum argument); AttrNumber attributeNumber, RegProcedure procedure, Datum argument);
extern void ScanKeyEntryInitializeWithInfo(ScanKey entry, bits16 flags,
AttrNumber attributeNumber, FmgrInfo *finfo,
MemoryContext mcxt, Datum argument);
#endif /* SKEY_H */ #endif /* SKEY_H */
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: index.h,v 1.39 2001/08/21 16:36:05 tgl Exp $ * $Id: index.h,v 1.40 2001/10/06 23:21:44 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -30,10 +30,6 @@ typedef void (*IndexBuildCallback) (Relation index, ...@@ -30,10 +30,6 @@ typedef void (*IndexBuildCallback) (Relation index,
extern Form_pg_am AccessMethodObjectIdGetForm(Oid accessMethodObjectId, extern Form_pg_am AccessMethodObjectIdGetForm(Oid accessMethodObjectId,
MemoryContext resultCxt); MemoryContext resultCxt);
extern void InitIndexStrategy(int numatts,
Relation indexRelation,
Oid accessMethodObjectId);
extern Oid index_create(char *heapRelationName, extern Oid index_create(char *heapRelationName,
char *indexRelationName, char *indexRelationName,
IndexInfo *indexInfo, IndexInfo *indexInfo,
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: fmgr.h,v 1.14 2001/05/17 17:44:18 petere Exp $ * $Id: fmgr.h,v 1.15 2001/10/06 23:21:44 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -35,7 +35,7 @@ typedef Datum (*PGFunction) (FunctionCallInfo fcinfo); ...@@ -35,7 +35,7 @@ typedef Datum (*PGFunction) (FunctionCallInfo fcinfo);
* to be called multiple times, the lookup need be done only once and the * to be called multiple times, the lookup need be done only once and the
* info struct saved for re-use. * info struct saved for re-use.
*/ */
typedef struct typedef struct FmgrInfo
{ {
PGFunction fn_addr; /* pointer to function or handler to be PGFunction fn_addr; /* pointer to function or handler to be
* called */ * called */
...@@ -72,6 +72,20 @@ typedef struct FunctionCallInfoData ...@@ -72,6 +72,20 @@ typedef struct FunctionCallInfoData
*/ */
extern void fmgr_info(Oid functionId, FmgrInfo *finfo); extern void fmgr_info(Oid functionId, FmgrInfo *finfo);
/*
* Same, when the FmgrInfo struct is in a memory context longer-lived than
* CurrentMemoryContext. The specified context will be set as fn_mcxt
* and used to hold all subsidiary data of finfo.
*/
extern void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo,
MemoryContext mcxt);
/*
* Copy an FmgrInfo struct
*/
extern void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo,
MemoryContext destcxt);
/* /*
* This macro invokes a function given a filled-in FunctionCallInfoData * This macro invokes a function given a filled-in FunctionCallInfoData
* struct. The macro result is the returned Datum --- but note that * struct. The macro result is the returned Datum --- but note that
...@@ -341,16 +355,18 @@ extern Datum OidFunctionCall9(Oid functionId, Datum arg1, Datum arg2, ...@@ -341,16 +355,18 @@ extern Datum OidFunctionCall9(Oid functionId, Datum arg1, Datum arg2,
/* /*
* Routines in fmgr.c * Routines in fmgr.c
*/ */
extern Pg_finfo_record *fetch_finfo_record(char *filename, char *funcname); extern Pg_finfo_record *fetch_finfo_record(void *filehandle, char *funcname);
extern Oid fmgr_internal_function(const char *proname); extern Oid fmgr_internal_function(const char *proname);
/* /*
* Routines in dfmgr.c * Routines in dfmgr.c
*/ */
extern char * Dynamic_library_path;
extern PGFunction load_external_function(char *filename, char *funcname, extern PGFunction load_external_function(char *filename, char *funcname,
bool signalNotFound); bool signalNotFound, void **filehandle);
extern PGFunction lookup_external_function(void *filehandle, char *funcname);
extern void load_file(char *filename); extern void load_file(char *filename);
extern char * Dynamic_library_path;
/* /*
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: rel.h,v 1.51 2001/06/27 23:31:40 tgl Exp $ * $Id: rel.h,v 1.52 2001/10/06 23:21:44 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -23,8 +23,6 @@ ...@@ -23,8 +23,6 @@
#include "storage/fd.h" #include "storage/fd.h"
#include "storage/relfilenode.h" #include "storage/relfilenode.h"
/* added to prevent circular dependency. bjm 1999/11/15 */
extern char *get_temp_rel_by_physicalname(const char *relname);
/* /*
* LockRelId and LockInfo really belong to lmgr.h, but it's more convenient * LockRelId and LockInfo really belong to lmgr.h, but it's more convenient
...@@ -115,7 +113,7 @@ typedef struct RelationData ...@@ -115,7 +113,7 @@ typedef struct RelationData
bool rd_isnailed; /* rel is nailed in cache */ bool rd_isnailed; /* rel is nailed in cache */
bool rd_indexfound; /* true if rd_indexlist is valid */ bool rd_indexfound; /* true if rd_indexlist is valid */
bool rd_uniqueindex; /* true if rel is a UNIQUE index */ bool rd_uniqueindex; /* true if rel is a UNIQUE index */
Form_pg_am rd_am; /* AM tuple */ Form_pg_am rd_am; /* AM tuple (if an index) */
Form_pg_class rd_rel; /* RELATION tuple */ Form_pg_class rd_rel; /* RELATION tuple */
Oid rd_id; /* relation's object id */ Oid rd_id; /* relation's object id */
List *rd_indexlist; /* list of OIDs of indexes on relation */ List *rd_indexlist; /* list of OIDs of indexes on relation */
...@@ -123,10 +121,16 @@ typedef struct RelationData ...@@ -123,10 +121,16 @@ typedef struct RelationData
TupleDesc rd_att; /* tuple descriptor */ TupleDesc rd_att; /* tuple descriptor */
RuleLock *rd_rules; /* rewrite rules */ RuleLock *rd_rules; /* rewrite rules */
MemoryContext rd_rulescxt; /* private memory cxt for rd_rules, if any */ MemoryContext rd_rulescxt; /* private memory cxt for rd_rules, if any */
IndexStrategy rd_istrat; /* info needed if rel is an index */
RegProcedure *rd_support;
TriggerDesc *trigdesc; /* Trigger info, or NULL if rel has none */ TriggerDesc *trigdesc; /* Trigger info, or NULL if rel has none */
/* index access support info (used only for an index relation) */
MemoryContext rd_indexcxt; /* private memory cxt for this stuff */
IndexStrategy rd_istrat; /* operator strategy map */
RegProcedure *rd_support; /* OIDs of support procedures */
struct FmgrInfo *rd_supportinfo; /* lookup info for support procedures */
/* "struct FmgrInfo" avoids need to include fmgr.h here */
/* statistics collection area */
PgStat_Info pgstat_info; PgStat_Info pgstat_info;
} RelationData; } RelationData;
...@@ -228,13 +232,6 @@ typedef Relation *RelationPtr; ...@@ -228,13 +232,6 @@ typedef Relation *RelationPtr;
*/ */
#define RelationGetIndexStrategy(relation) ((relation)->rd_istrat) #define RelationGetIndexStrategy(relation) ((relation)->rd_istrat)
/*
* Routines in utils/cache/rel.c
*/
extern void RelationSetIndexSupport(Relation relation,
IndexStrategy strategy,
RegProcedure *support);
/* /*
* Handle temp relations * Handle temp relations
*/ */
...@@ -279,5 +276,7 @@ extern void RelationSetIndexSupport(Relation relation, ...@@ -279,5 +276,7 @@ extern void RelationSetIndexSupport(Relation relation,
RelationGetPhysicalRelationName(relation) \ RelationGetPhysicalRelationName(relation) \
) )
/* added to prevent circular dependency. bjm 1999/11/15 */
extern char *get_temp_rel_by_physicalname(const char *relname);
#endif /* REL_H */ #endif /* REL_H */
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: relcache.h,v 1.25 2001/06/29 21:08:25 tgl Exp $ * $Id: relcache.h,v 1.26 2001/10/06 23:21:44 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -33,6 +33,8 @@ extern void RelationClose(Relation relation); ...@@ -33,6 +33,8 @@ extern void RelationClose(Relation relation);
*/ */
extern List *RelationGetIndexList(Relation relation); extern List *RelationGetIndexList(Relation relation);
extern void RelationInitIndexAccessInfo(Relation relation);
/* /*
* Routines for backend startup * Routines for backend startup
*/ */
...@@ -61,6 +63,7 @@ extern void RelationPurgeLocalRelation(bool xactComitted); ...@@ -61,6 +63,7 @@ extern void RelationPurgeLocalRelation(bool xactComitted);
extern void RelationCacheAbort(void); extern void RelationCacheAbort(void);
/* XLOG support */
extern void CreateDummyCaches(void); extern void CreateDummyCaches(void);
extern void DestroyDummyCaches(void); extern void DestroyDummyCaches(void);
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
* ENHANCEMENTS, OR MODIFICATIONS. * ENHANCEMENTS, OR MODIFICATIONS.
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/pl/plperl/plperl.c,v 1.22 2001/06/18 21:40:06 momjian Exp $ * $Header: /cvsroot/pgsql/src/pl/plperl/plperl.c,v 1.23 2001/10/06 23:21:44 tgl Exp $
* *
**********************************************************************/ **********************************************************************/
...@@ -171,18 +171,14 @@ static void plperl_set_tuple_values(Tcl_Interp *interp, char *arrayname, ...@@ -171,18 +171,14 @@ static void plperl_set_tuple_values(Tcl_Interp *interp, char *arrayname,
* data structures such as fmgr info records therefore must live forever * data structures such as fmgr info records therefore must live forever
* as well. A better implementation would store all this stuff in a per- * as well. A better implementation would store all this stuff in a per-
* function memory context that could be reclaimed at need. In the meantime, * function memory context that could be reclaimed at need. In the meantime,
* fmgr_info must be called in TopMemoryContext so that whatever it might * fmgr_info_cxt must be called specifying TopMemoryContext so that whatever
* allocate, and whatever the eventual function might allocate using fn_mcxt, * it might allocate, and whatever the eventual function might allocate using
* will live forever too. * fn_mcxt, will live forever too.
*/ */
static void static void
perm_fmgr_info(Oid functionId, FmgrInfo *finfo) perm_fmgr_info(Oid functionId, FmgrInfo *finfo)
{ {
MemoryContext oldcontext; fmgr_info_cxt(functionId, finfo, TopMemoryContext);
oldcontext = MemoryContextSwitchTo(TopMemoryContext);
fmgr_info(functionId, finfo);
MemoryContextSwitchTo(oldcontext);
} }
/********************************************************************** /**********************************************************************
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* procedural language * procedural language
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.33 2001/07/12 17:42:07 momjian Exp $ * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.34 2001/10/06 23:21:44 tgl Exp $
* *
* This software is copyrighted by Jan Wieck - Hamburg. * This software is copyrighted by Jan Wieck - Hamburg.
* *
...@@ -92,18 +92,14 @@ PLpgSQL_function *plpgsql_curr_compile; ...@@ -92,18 +92,14 @@ PLpgSQL_function *plpgsql_curr_compile;
* data structures such as fmgr info records therefore must live forever * data structures such as fmgr info records therefore must live forever
* as well. A better implementation would store all this stuff in a per- * as well. A better implementation would store all this stuff in a per-
* function memory context that could be reclaimed at need. In the meantime, * function memory context that could be reclaimed at need. In the meantime,
* fmgr_info must be called in TopMemoryContext so that whatever it might * fmgr_info_cxt must be called specifying TopMemoryContext so that whatever
* allocate, and whatever the eventual function might allocate using fn_mcxt, * it might allocate, and whatever the eventual function might allocate using
* will live forever too. * fn_mcxt, will live forever too.
*/ */
static void static void
perm_fmgr_info(Oid functionId, FmgrInfo *finfo) perm_fmgr_info(Oid functionId, FmgrInfo *finfo)
{ {
MemoryContext oldcontext; fmgr_info_cxt(functionId, finfo, TopMemoryContext);
oldcontext = MemoryContextSwitchTo(TopMemoryContext);
fmgr_info(functionId, finfo);
MemoryContextSwitchTo(oldcontext);
} }
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/pl/plpython/plpython.c,v 1.7 2001/10/04 15:45:49 momjian Exp $ * $Header: /cvsroot/pgsql/src/pl/plpython/plpython.c,v 1.8 2001/10/06 23:21:45 tgl Exp $
* *
********************************************************************* *********************************************************************
*/ */
...@@ -308,18 +308,14 @@ volatile int func_leave_calls = 0; ...@@ -308,18 +308,14 @@ volatile int func_leave_calls = 0;
* data structures such as fmgr info records therefore must live forever * data structures such as fmgr info records therefore must live forever
* as well. A better implementation would store all this stuff in a per- * as well. A better implementation would store all this stuff in a per-
* function memory context that could be reclaimed at need. In the meantime, * function memory context that could be reclaimed at need. In the meantime,
* fmgr_info must be called in TopMemoryContext so that whatever it might * fmgr_info_cxt must be called specifying TopMemoryContext so that whatever
* allocate, and whatever the eventual function might allocate using fn_mcxt, * it might allocate, and whatever the eventual function might allocate using
* will live forever too. * fn_mcxt, will live forever too.
*/ */
static void static void
perm_fmgr_info(Oid functionId, FmgrInfo *finfo) perm_fmgr_info(Oid functionId, FmgrInfo *finfo)
{ {
MemoryContext oldcontext; fmgr_info_cxt(functionId, finfo, TopMemoryContext);
oldcontext = MemoryContextSwitchTo(TopMemoryContext);
fmgr_info(functionId, finfo);
MemoryContextSwitchTo(oldcontext);
} }
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
* ENHANCEMENTS, OR MODIFICATIONS. * ENHANCEMENTS, OR MODIFICATIONS.
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.42 2001/10/04 15:48:37 momjian Exp $ * $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.43 2001/10/06 23:21:45 tgl Exp $
* *
**********************************************************************/ **********************************************************************/
...@@ -187,18 +187,14 @@ static int pltcl_SPI_lastoid(ClientData cdata, Tcl_Interp *interp, ...@@ -187,18 +187,14 @@ static int pltcl_SPI_lastoid(ClientData cdata, Tcl_Interp *interp,
* data structures such as fmgr info records therefore must live forever * data structures such as fmgr info records therefore must live forever
* as well. A better implementation would store all this stuff in a per- * as well. A better implementation would store all this stuff in a per-
* function memory context that could be reclaimed at need. In the meantime, * function memory context that could be reclaimed at need. In the meantime,
* fmgr_info must be called in TopMemoryContext so that whatever it might * fmgr_info_cxt must be called specifying TopMemoryContext so that whatever
* allocate, and whatever the eventual function might allocate using fn_mcxt, * it might allocate, and whatever the eventual function might allocate using
* will live forever too. * fn_mcxt, will live forever too.
*/ */
static void static void
perm_fmgr_info(Oid functionId, FmgrInfo *finfo) perm_fmgr_info(Oid functionId, FmgrInfo *finfo)
{ {
MemoryContext oldcontext; fmgr_info_cxt(functionId, finfo, TopMemoryContext);
oldcontext = MemoryContextSwitchTo(TopMemoryContext);
fmgr_info(functionId, finfo);
MemoryContextSwitchTo(oldcontext);
} }
/********************************************************************** /**********************************************************************
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment