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.
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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));
+}
* Portions Copyright (c) 1994, Regents of the University of California
*
* 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 $
*
*-------------------------------------------------------------------------
*/
void
initGISTstate(GISTSTATE *giststate, Relation index)
{
- RegProcedure consistent_proc,
- union_proc,
- compress_proc,
- decompress_proc,
- penalty_proc,
- picksplit_proc,
- equal_proc;
int i;
if (index->rd_att->natts > INDEX_MAX_KEYS)
for (i = 0; i < index->rd_att->natts; i++)
{
- consistent_proc = index_getprocid(index, i+1, GIST_CONSISTENT_PROC );
- union_proc = index_getprocid(index, i+1, GIST_UNION_PROC );
- compress_proc = index_getprocid(index, i+1, GIST_COMPRESS_PROC );
- decompress_proc = index_getprocid(index, i+1, GIST_DECOMPRESS_PROC );
- penalty_proc = index_getprocid(index, i+1, GIST_PENALTY_PROC );
- picksplit_proc = index_getprocid(index, i+1, GIST_PICKSPLIT_PROC );
- equal_proc = index_getprocid(index, i+1, GIST_EQUAL_PROC );
- fmgr_info(consistent_proc, &((giststate->consistentFn)[i]) );
- fmgr_info(union_proc, &((giststate->unionFn)[i]) );
- fmgr_info(compress_proc, &((giststate->compressFn)[i]) );
- fmgr_info(decompress_proc, &((giststate->decompressFn)[i]) );
- fmgr_info(penalty_proc, &((giststate->penaltyFn)[i]) );
- fmgr_info(picksplit_proc, &((giststate->picksplitFn)[i]) );
- fmgr_info(equal_proc, &((giststate->equalFn)[i]) );
+ fmgr_info_copy(&(giststate->consistentFn[i]),
+ index_getprocinfo(index, i+1, GIST_CONSISTENT_PROC),
+ CurrentMemoryContext);
+ fmgr_info_copy(&(giststate->unionFn[i]),
+ index_getprocinfo(index, i+1, GIST_UNION_PROC),
+ CurrentMemoryContext);
+ fmgr_info_copy(&(giststate->compressFn[i]),
+ index_getprocinfo(index, i+1, GIST_COMPRESS_PROC),
+ CurrentMemoryContext);
+ fmgr_info_copy(&(giststate->decompressFn[i]),
+ index_getprocinfo(index, i+1, GIST_DECOMPRESS_PROC),
+ CurrentMemoryContext);
+ fmgr_info_copy(&(giststate->penaltyFn[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);
}
}
*
*
* 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 "access/genam.h"
#include "access/hash.h"
#include "access/iqual.h"
int natts;
AttrNumber i;
Datum arg;
- RegProcedure proc;
- bool null;
+ FmgrInfo *procinfo;
+ bool isnull;
natts = rel->rd_rel->relnatts;
itupdesc = RelationGetDescr(rel);
for (i = 0; i < natts; i++)
{
- arg = index_getattr(itup, i + 1, itupdesc, &null);
- proc = metap->hashm_procid;
- ScanKeyEntryInitialize(&skey[i],
- 0x0, (AttrNumber) (i + 1), proc, arg);
+ arg = index_getattr(itup, i + 1, itupdesc, &isnull);
+ procinfo = index_getprocinfo(rel, i + 1, HASHPROC);
+ ScanKeyEntryInitializeWithInfo(&skey[i],
+ 0x0,
+ (AttrNumber) (i + 1),
+ procinfo,
+ CurrentMemoryContext,
+ arg);
}
return skey;
Bucket
_hash_call(Relation rel, HashMetaPage metap, Datum key)
{
+ FmgrInfo *procinfo;
uint32 n;
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;
if (bucket > metap->hashm_maxbucket)
bucket = bucket & metap->hashm_lowmask;
*
*
* 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
* index_open - open an index relation by relationId
{
RegProcedure *loc;
int nproc;
+ int procindex;
nproc = irel->rd_am->amsupport;
+ Assert(procnum > 0 && procnum <= (uint16) nproc);
+
+ procindex = (nproc * (attnum - 1)) + (procnum - 1);
+
loc = irel->rd_support;
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;
}
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
operatorObjectId);
/*
- * Formerly we initialized entry->sk_func here, but that's a waste of
- * 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!)
+ * Mark entry->sk_func invalid, until and unless someone sets it up.
*/
+ entry->sk_func.fn_oid = InvalidOid;
}
* Portions Copyright (c) 1994, Regents of the University of California
*
* 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 $
*
*-------------------------------------------------------------------------
*/
BlockNumber blkno;
StrategyNumber strat;
RetrieveIndexResult res;
- RegProcedure proc;
int32 result;
BTScanOpaque so;
bool continuescan;
scankeys = (ScanKey) palloc(keysCount * sizeof(ScanKeyData));
for (i = 0; i < keysCount; i++)
{
+ FmgrInfo *procinfo;
+
j = nKeyIs[i];
/*
elog(ERROR, "_bt_first: btree doesn't support is(not)null, yet");
return ((RetrieveIndexResult) NULL);
}
- proc = index_getprocid(rel, i + 1, BTORDER_PROC);
- ScanKeyEntryInitialize(scankeys + i, so->keyData[j].sk_flags,
- i + 1, proc, so->keyData[j].sk_argument);
+ procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC);
+ ScanKeyEntryInitializeWithInfo(scankeys + i,
+ so->keyData[j].sk_flags,
+ i + 1,
+ procinfo,
+ CurrentMemoryContext,
+ so->keyData[j].sk_argument);
}
if (nKeyIs)
pfree(nKeyIs);
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
TupleDesc itupdesc;
int natts;
int i;
- RegProcedure proc;
+ FmgrInfo *procinfo;
Datum arg;
bool null;
bits16 flag;
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);
flag = null ? SK_ISNULL : 0x0;
- ScanKeyEntryInitialize(&skey[i],
- flag,
- (AttrNumber) (i + 1),
- proc,
- arg);
+ ScanKeyEntryInitializeWithInfo(&skey[i],
+ flag,
+ (AttrNumber) (i + 1),
+ procinfo,
+ CurrentMemoryContext,
+ arg);
}
return skey;
ScanKey skey;
int natts;
int i;
- RegProcedure proc;
+ FmgrInfo *procinfo;
natts = RelationGetNumberOfAttributes(rel);
for (i = 0; i < natts; i++)
{
- proc = index_getprocid(rel, i + 1, BTORDER_PROC);
- ScanKeyEntryInitialize(&skey[i],
- SK_ISNULL,
- (AttrNumber) (i + 1),
- proc,
- (Datum) NULL);
+ procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC);
+ ScanKeyEntryInitializeWithInfo(&skey[i],
+ SK_ISNULL,
+ (AttrNumber) (i + 1),
+ procinfo,
+ CurrentMemoryContext,
+ (Datum) 0);
}
return skey;
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
static void
initRtstate(RTSTATE *rtstate, Relation index)
{
- RegProcedure union_proc,
- size_proc,
- inter_proc;
-
- union_proc = index_getprocid(index, 1, RT_UNION_PROC);
- size_proc = index_getprocid(index, 1, RT_SIZE_PROC);
- inter_proc = index_getprocid(index, 1, RT_INTER_PROC);
- fmgr_info(union_proc, &rtstate->unionFn);
- fmgr_info(size_proc, &rtstate->sizeFn);
- fmgr_info(inter_proc, &rtstate->interFn);
- return;
+ fmgr_info_copy(&rtstate->unionFn,
+ index_getprocinfo(index, 1, RT_UNION_PROC),
+ CurrentMemoryContext);
+ fmgr_info_copy(&rtstate->sizeFn,
+ index_getprocinfo(index, 1, RT_SIZE_PROC),
+ CurrentMemoryContext);
+ fmgr_info_copy(&rtstate->interFn,
+ index_getprocinfo(index, 1, RT_INTER_PROC),
+ CurrentMemoryContext);
}
/* for sorting SPLITCOST records in descending order */
*
*
* 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
while (HeapTupleIsValid(indexTuple = heap_getnext(scan, 0)))
{
- Oid indexId,
- accessMethodId;
+ Oid indexId;
IndexInfo *indexInfo;
- HeapTuple classTuple;
Relation heapRelation,
currentIndex;
indexId = ((Form_pg_index) GETSTRUCT(indexTuple))->indexrelid;
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
* because index_build will close it again. We need grab no lock,
currentIndex->rd_targblock = InvalidBlockNumber;
/* Initialize the index and rebuild */
- InitIndexStrategy(indexInfo->ii_NumIndexAttrs,
- currentIndex, accessMethodId);
index_build(heapRelation, currentIndex, indexInfo);
/*
*
*
* 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
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
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,
- indexRelation,
- accessMethodObjectId);
+ CommandCounterIncrement();
+
+ RelationInitIndexAccessInfo(indexRelation);
/*
* If this is bootstrap (initdb) time, then we don't actually fill in
heapRelation;
ScanKeyData entry;
HeapScanDesc scan;
- HeapTuple indexTuple,
- classTuple;
+ HeapTuple indexTuple;
IndexInfo *indexInfo;
- Oid heapId,
- accessMethodId;
+ Oid heapId;
bool old;
/*
heap_endscan(scan);
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 */
heapRelation = heap_open(heapId, ExclusiveLock);
if (heapRelation == NULL)
}
/* Initialize the index and rebuild */
- InitIndexStrategy(indexInfo->ii_NumIndexAttrs, iRel, accessMethodId);
index_build(heapRelation, iRel, indexInfo);
/*
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
if (languageObjectId == ClanguageId)
{
+ void *libraryhandle;
+
/* If link symbol is specified as "-", substitute procedure name */
if (strcmp(prosrc, "-") == 0)
prosrc = procedureName;
- (void) load_external_function(probin, prosrc, true);
- (void) fetch_finfo_record(probin, prosrc);
+ (void) load_external_function(probin, prosrc, true,
+ &libraryhandle);
+ (void) fetch_finfo_record(libraryhandle, prosrc);
}
/*
* Portions Copyright (c) 2000-2001, PostgreSQL Global Development Group
* 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 $
*
* ----------
*/
{
HeapTuple opr_tup;
Oid opr_proc;
- MemoryContext oldcontext;
FmgrInfo finfo;
opr_tup = SearchSysCache(OPERNAME,
* table entry, we must make sure any subsidiary structures of the
* fmgr record are kept in TopMemoryContext.
*/
- oldcontext = MemoryContextSwitchTo(TopMemoryContext);
- fmgr_info(opr_proc, &finfo);
- MemoryContextSwitchTo(oldcontext);
+ fmgr_info_cxt(opr_proc, &finfo, TopMemoryContext);
entry = (RI_OpreqHashEntry *) hash_search(ri_opreq_cache,
(void *) &typeid,
* Portions Copyright (c) 1994, Regents of the University of California
*
* 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 $
*
*-------------------------------------------------------------------------
*/
#include "catalog/pg_type.h"
#include "utils/array.h"
#include "utils/fmgroids.h"
+#include "utils/memutils.h"
#include "utils/varbit.h"
#define HEXDIG(z) ((z)<10 ? ((z)+'0') : ((z)-10+'A'))
static FmgrInfo bit_finfo;
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));
locfcinfo.flinfo = &bit_finfo;
static FmgrInfo varbit_finfo;
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));
locfcinfo.flinfo = &varbit_finfo;
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
static FmgrInfo bpchar_finfo;
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));
locfcinfo.flinfo = &bpchar_finfo;
static FmgrInfo varchar_finfo;
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));
locfcinfo.flinfo = &varchar_finfo;
# Makefile for utils/cache
#
# 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 $
#
#-------------------------------------------------------------------------
top_builddir = ../../../..
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
all: SUBSYS.o
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
*/
cache->cc_skey[i].sk_procedure = EQPROC(keytype);
- /*
- * Note: to avoid any possible leakage of scan temporary data into
- * the cache context, we do not switch into CacheMemoryContext while
- * calling fmgr_info here. Instead set fn_mcxt on return. This
- * 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;
+ /* Do function lookup */
+ fmgr_info_cxt(cache->cc_skey[i].sk_procedure,
+ &cache->cc_skey[i].sk_func,
+ CacheMemoryContext);
/* Initialize sk_attno suitably for HeapKeyTest() and heap scans */
cache->cc_skey[i].sk_attno = cache->cc_key[i];
* Portions Copyright (c) 1994, Regents of the University of California
*
* 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 $
*
*-------------------------------------------------------------------------
*/
FunctionCachePtr
init_fcache(Oid foid, int nargs, MemoryContext fcacheCxt)
{
- MemoryContext oldcontext;
FunctionCachePtr retval;
/* Safety check (should never fail, as parser should check sooner) */
if (nargs > FUNC_MAX_ARGS)
elog(ERROR, "init_fcache: too many arguments");
- /* Switch to a context long-lived enough for the fcache entry */
- oldcontext = MemoryContextSwitchTo(fcacheCxt);
-
- retval = (FunctionCachePtr) palloc(sizeof(FunctionCache));
+ /* Create fcache entry in the desired context */
+ retval = (FunctionCachePtr) MemoryContextAlloc(fcacheCxt,
+ sizeof(FunctionCache));
MemSet(retval, 0, sizeof(FunctionCache));
/* Set up the primary fmgr lookup information */
- fmgr_info(foid, &(retval->func));
+ fmgr_info_cxt(foid, &(retval->func), fcacheCxt);
/* Initialize additional info */
retval->setArgsValid = false;
- MemoryContextSwitchTo(oldcontext);
-
return retval;
}
+++ /dev/null
-/*-------------------------------------------------------------------------
- *
- * 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;
-}
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
Relation relation);
static Relation RelationBuildDesc(RelationBuildDescInfo buildinfo,
Relation oldrelation);
-static void IndexedAccessMethodInitialize(Relation relation);
static void AttrDefaultFetch(Relation relation);
static void RelCheckFetch(Relation relation);
static List *insert_ordered_oid(List *list, Oid datum);
* initialize index strategy and support information for this relation
*/
if (OidIsValid(relam))
- IndexedAccessMethodInitialize(relation);
+ RelationInitIndexAccessInfo(relation);
/*
* initialize the relation lock manager information
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;
RegProcedure *support;
+ FmgrInfo *supportinfo;
int natts;
- Size stratSize;
- Size supportSize;
uint16 amstrategies;
uint16 amsupport;
+ Size stratSize;
natts = relation->rd_rel->relnatts;
amstrategies = relation->rd_am->amstrategies;
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);
- strategy = (IndexStrategy) MemoryContextAlloc(CacheMemoryContext,
- stratSize);
+ strategy = (IndexStrategy) MemoryContextAlloc(indexcxt, stratSize);
if (amsupport > 0)
{
- supportSize = natts * (amsupport * sizeof(RegProcedure));
- support = (RegProcedure *) MemoryContextAlloc(CacheMemoryContext,
- supportSize);
+ int nsupport = natts * amsupport;
+
+ support = (RegProcedure *)
+ MemoryContextAlloc(indexcxt, nsupport * sizeof(RegProcedure));
+ supportinfo = (FmgrInfo *)
+ MemoryContextAlloc(indexcxt, nsupport * sizeof(FmgrInfo));
+ MemSet(supportinfo, 0, nsupport * sizeof(FmgrInfo));
}
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,
&relation->rd_uniqueindex,
RelationGetRelid(relation),
relation->rd_rel->relam,
amstrategies, amsupport, natts);
- RelationSetIndexSupport(relation, strategy, support);
+ relation->rd_istrat = strategy;
+ relation->rd_support = support;
+ relation->rd_supportinfo = supportinfo;
}
/*
pfree(relation->rd_am);
if (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);
+ if (relation->rd_indexcxt)
+ MemoryContextDelete(relation->rd_indexcxt);
/*
* If we're really done with the relcache entry, blow it away. But if
Relation ird;
Form_pg_am am;
Form_pg_class relform;
+ MemoryContext indexcxt;
IndexStrategy strat;
RegProcedure *support;
+ int nstrategies,
+ nsupport;
int i;
int relno;
return;
}
+ /* safety check for incompatible relcache layout */
+ if (len != sizeof(RelationData))
+ {
+ write_irels();
+ return;
+ }
+
ird = irel[relno] = (Relation) palloc(len);
MemSet(ird, 0, len);
/* reset transient fields */
ird->rd_targblock = InvalidBlockNumber;
ird->rd_fd = -1;
+ ird->rd_refcnt = 0;
ird->rd_node.tblNode = MyDatabaseId;
}
}
+ /*
+ * 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 */
if ((nread = FileRead(fd, (char *) &len, sizeof(len))) != sizeof(len))
{
return;
}
- strat = (IndexStrategy) palloc(len);
+ strat = (IndexStrategy) MemoryContextAlloc(indexcxt, len);
if ((nread = FileRead(fd, (char *) strat, len)) != len)
{
write_irels();
return;
}
- /* oh, for god's sake... */
-#define SMD(i) strat->strategyMapData[i].entry[0]
-
- /* have to reinit the function pointers in the strategy maps */
- for (i = 0; i < am->amstrategies * relform->relnatts; i++)
- {
- fmgr_info(SMD(i).sk_procedure,
- &(SMD(i).sk_func));
- }
+ /* have to invalidate any FmgrInfo data in the strategy maps */
+ nstrategies = am->amstrategies * relform->relnatts;
+ for (i = 0; i < nstrategies; i++)
+ strat->strategyMapData[i].entry[0].sk_func.fn_oid = InvalidOid;
- /*
- * 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;
/* finally, read the vector of support procedures */
return;
}
- support = (RegProcedure *) palloc(len);
+ support = (RegProcedure *) MemoryContextAlloc(indexcxt, len);
if ((nread = FileRead(fd, (char *) support, len)) != len)
{
write_irels();
}
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);
RelationCacheInsert(ird);
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
/*
* 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
- * if signalNotFound is true, else return (PGFunction) NULL. Note that
- * errors in loading the library will provoke elog regardless of
- * signalNotFound.
- */
+ * named funcname in it. (funcname can be NULL to just load the file.)
+ *
+ * If the function is not found, we raise an error if signalNotFound is true,
+ * 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
load_external_function(char *filename, char *funcname,
- bool signalNotFound)
+ bool signalNotFound, void **filehandle)
{
DynamicFileList *file_scanner;
PGFunction retval;
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.
*/
}
}
- load_external_function(fullname, (char *) NULL, false);
+ load_external_function(fullname, (char *) NULL, false, (void *) NULL);
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
AssertArg(name != NULL);
- if (strlen(name) == 0 || name[0] != '$')
+ if (name[0] != '$')
return pstrdup(name);
macroname_len = strcspn(name + 1, "/") + 1;
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
* 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
* 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
- * struct is in a long-lived table.
+ * in freshly-palloc'd space. However, if one intends to store an info
+ * struct in a long-lived table, it's better to use fmgr_info_cxt.
*/
void
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;
HeapTuple procedureTuple;
*/
finfo->fn_oid = InvalidOid;
finfo->fn_extra = NULL;
- finfo->fn_mcxt = CurrentMemoryContext;
+ finfo->fn_mcxt = mcxt;
if ((fbp = fmgr_isbuiltin(functionId)) != NULL)
{
probinattr;
char *prosrcstring,
*probinstring;
+ void *libraryhandle;
PGFunction user_fn;
Pg_finfo_record *inforec;
Oldstyle_fnextra *fnextra;
probinstring = DatumGetCString(DirectFunctionCall1(textout, probinattr));
/* 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) */
- inforec = fetch_finfo_record(probinstring, prosrcstring);
+ inforec = fetch_finfo_record(libraryhandle, prosrcstring);
switch (inforec->api_version)
{
case 0:
/* Old style: need to use a handler */
finfo->fn_addr = fmgr_oldstyle;
-
- /*
- * OK to use palloc here because fn_mcxt is
- * CurrentMemoryContext
- */
- fnextra = (Oldstyle_fnextra *) palloc(sizeof(Oldstyle_fnextra));
+ fnextra = (Oldstyle_fnextra *)
+ MemoryContextAlloc(finfo->fn_mcxt, sizeof(Oldstyle_fnextra));
finfo->fn_extra = (void *) fnextra;
MemSet(fnextra, 0, sizeof(Oldstyle_fnextra));
fnextra->func = (func_ptr) user_fn;
/*
* 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.
* Instead we return a default info record for a version-0 function.
* pg_proc.
*/
Pg_finfo_record *
-fetch_finfo_record(char *filename, char *funcname)
+fetch_finfo_record(void *filehandle, char *funcname)
{
char *infofuncname;
PGFInfoFunction infofunc;
/* Compute name of info func */
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 */
- infofunc = (PGFInfoFunction) load_external_function(filename,
- infofuncname,
- false);
+ infofunc = (PGFInfoFunction) lookup_external_function(filehandle,
+ infofuncname);
if (infofunc == (PGFInfoFunction) NULL)
{
/* Not found --- assume version 0 */
}
+/*
+ * 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
* of an internal function, return the OID of the function.
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* 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 $
*
*-------------------------------------------------------------------------
*/
extern RegProcedure index_cost_estimator(Relation relation);
extern RegProcedure index_getprocid(Relation irel, AttrNumber attnum,
uint16 procnum);
+extern struct FmgrInfo *index_getprocinfo(Relation irel, AttrNumber attnum,
+ uint16 procnum);
/* in genam.c */
extern IndexScanDesc RelationGetIndexScan(Relation relation, bool scanFromEnd,
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* 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:
* Needs more accessor/assignment routines.
extern void ScanKeyEntrySetIllegal(ScanKey entry);
extern void ScanKeyEntryInitialize(ScanKey entry, bits16 flags,
AttrNumber attributeNumber, RegProcedure procedure, Datum argument);
+extern void ScanKeyEntryInitializeWithInfo(ScanKey entry, bits16 flags,
+ AttrNumber attributeNumber, FmgrInfo *finfo,
+ MemoryContext mcxt, Datum argument);
#endif /* SKEY_H */
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* 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 $
*
*-------------------------------------------------------------------------
*/
extern Form_pg_am AccessMethodObjectIdGetForm(Oid accessMethodObjectId,
MemoryContext resultCxt);
-extern void InitIndexStrategy(int numatts,
- Relation indexRelation,
- Oid accessMethodObjectId);
-
extern Oid index_create(char *heapRelationName,
char *indexRelationName,
IndexInfo *indexInfo,
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* 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 $
*
*-------------------------------------------------------------------------
*/
* to be called multiple times, the lookup need be done only once and the
* info struct saved for re-use.
*/
-typedef struct
+typedef struct FmgrInfo
{
PGFunction fn_addr; /* pointer to function or handler to be
* called */
*/
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
* struct. The macro result is the returned Datum --- but note that
/*
* 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);
/*
* Routines in dfmgr.c
*/
+extern char * Dynamic_library_path;
+
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 char * Dynamic_library_path;
/*
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* 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 $
*
*-------------------------------------------------------------------------
*/
#include "storage/fd.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
bool rd_isnailed; /* rel is nailed in cache */
bool rd_indexfound; /* true if rd_indexlist is valid */
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 */
Oid rd_id; /* relation's object id */
List *rd_indexlist; /* list of OIDs of indexes on relation */
TupleDesc rd_att; /* tuple descriptor */
RuleLock *rd_rules; /* rewrite rules */
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 */
+ /* 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;
} RelationData;
*/
#define RelationGetIndexStrategy(relation) ((relation)->rd_istrat)
-/*
- * Routines in utils/cache/rel.c
- */
-extern void RelationSetIndexSupport(Relation relation,
- IndexStrategy strategy,
- RegProcedure *support);
-
/*
* Handle temp relations
*/
RelationGetPhysicalRelationName(relation) \
)
+/* added to prevent circular dependency. bjm 1999/11/15 */
+extern char *get_temp_rel_by_physicalname(const char *relname);
#endif /* REL_H */
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* 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 $
*
*-------------------------------------------------------------------------
*/
*/
extern List *RelationGetIndexList(Relation relation);
+extern void RelationInitIndexAccessInfo(Relation relation);
+
/*
* Routines for backend startup
*/
extern void RelationCacheAbort(void);
+/* XLOG support */
extern void CreateDummyCaches(void);
extern void DestroyDummyCaches(void);
* ENHANCEMENTS, OR MODIFICATIONS.
*
* 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 $
*
**********************************************************************/
* data structures such as fmgr info records therefore must live forever
* 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,
- * fmgr_info must be called in TopMemoryContext so that whatever it might
- * allocate, and whatever the eventual function might allocate using fn_mcxt,
- * will live forever too.
+ * fmgr_info_cxt must be called specifying TopMemoryContext so that whatever
+ * it might allocate, and whatever the eventual function might allocate using
+ * fn_mcxt, will live forever too.
*/
static void
perm_fmgr_info(Oid functionId, FmgrInfo *finfo)
{
- MemoryContext oldcontext;
-
- oldcontext = MemoryContextSwitchTo(TopMemoryContext);
- fmgr_info(functionId, finfo);
- MemoryContextSwitchTo(oldcontext);
+ fmgr_info_cxt(functionId, finfo, TopMemoryContext);
}
/**********************************************************************
* procedural language
*
* 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.
*
* data structures such as fmgr info records therefore must live forever
* 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,
- * fmgr_info must be called in TopMemoryContext so that whatever it might
- * allocate, and whatever the eventual function might allocate using fn_mcxt,
- * will live forever too.
+ * fmgr_info_cxt must be called specifying TopMemoryContext so that whatever
+ * it might allocate, and whatever the eventual function might allocate using
+ * fn_mcxt, will live forever too.
*/
static void
perm_fmgr_info(Oid functionId, FmgrInfo *finfo)
{
- MemoryContext oldcontext;
-
- oldcontext = MemoryContextSwitchTo(TopMemoryContext);
- fmgr_info(functionId, finfo);
- MemoryContextSwitchTo(oldcontext);
+ fmgr_info_cxt(functionId, finfo, TopMemoryContext);
}
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* 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 $
*
*********************************************************************
*/
* data structures such as fmgr info records therefore must live forever
* 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,
- * fmgr_info must be called in TopMemoryContext so that whatever it might
- * allocate, and whatever the eventual function might allocate using fn_mcxt,
- * will live forever too.
+ * fmgr_info_cxt must be called specifying TopMemoryContext so that whatever
+ * it might allocate, and whatever the eventual function might allocate using
+ * fn_mcxt, will live forever too.
*/
static void
perm_fmgr_info(Oid functionId, FmgrInfo *finfo)
{
- MemoryContext oldcontext;
-
- oldcontext = MemoryContextSwitchTo(TopMemoryContext);
- fmgr_info(functionId, finfo);
- MemoryContextSwitchTo(oldcontext);
+ fmgr_info_cxt(functionId, finfo, TopMemoryContext);
}
* ENHANCEMENTS, OR MODIFICATIONS.
*
* 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 $
*
**********************************************************************/
* data structures such as fmgr info records therefore must live forever
* 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,
- * fmgr_info must be called in TopMemoryContext so that whatever it might
- * allocate, and whatever the eventual function might allocate using fn_mcxt,
- * will live forever too.
+ * fmgr_info_cxt must be called specifying TopMemoryContext so that whatever
+ * it might allocate, and whatever the eventual function might allocate using
+ * fn_mcxt, will live forever too.
*/
static void
perm_fmgr_info(Oid functionId, FmgrInfo *finfo)
{
- MemoryContext oldcontext;
-
- oldcontext = MemoryContextSwitchTo(TopMemoryContext);
- fmgr_info(functionId, finfo);
- MemoryContextSwitchTo(oldcontext);
+ fmgr_info_cxt(functionId, finfo, TopMemoryContext);
}
/**********************************************************************