summaryrefslogtreecommitdiff
path: root/src/backend/utils/cache/relcache.c
diff options
context:
space:
mode:
authorTom Lane2003-11-09 21:30:38 +0000
committerTom Lane2003-11-09 21:30:38 +0000
commitc1d62bfd00f4d1ea0647e12947ca1de9fea39b33 (patch)
tree1afdccb5267627182cab94b347730657107ad6eb /src/backend/utils/cache/relcache.c
parent723825afebb6de7212fa18882bcc78212d5c1743 (diff)
Add operator strategy and comparison-value datatype fields to ScanKey.
Remove the 'strategy map' code, which was a large amount of mechanism that no longer had any use except reverse-mapping from procedure OID to strategy number. Passing the strategy number to the index AM in the first place is simpler and faster. This is a preliminary step in planned support for cross-datatype index operations. I'm committing it now since the ScanKeyEntryInitialize() API change touches quite a lot of files, and I want to commit those changes before the tree drifts under me.
Diffstat (limited to 'src/backend/utils/cache/relcache.c')
-rw-r--r--src/backend/utils/cache/relcache.c251
1 files changed, 87 insertions, 164 deletions
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index d28875b1da9..88c8cbb1418 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.190 2003/09/25 06:58:05 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.191 2003/11/09 21:30:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -34,7 +34,6 @@
#include "access/genam.h"
#include "access/heapam.h"
-#include "access/istrat.h"
#include "catalog/catalog.h"
#include "catalog/catname.h"
#include "catalog/indexing.h"
@@ -69,6 +68,8 @@
*/
#define RELCACHE_INIT_FILENAME "pg_internal.init"
+#define RELCACHE_INIT_FILEMAGIC 0x573261 /* version ID value */
+
/*
* hardcoded tuple descriptors. see include/catalog/pg_attribute.h
*/
@@ -260,6 +261,8 @@ do { \
/*
* Special cache for opclass-related information
+ *
+ * Note: only non-cross-type operators and support procs get cached
*/
typedef struct opclasscacheent
{
@@ -268,7 +271,6 @@ typedef struct opclasscacheent
StrategyNumber numStrats; /* max # of strategies (from pg_am) */
StrategyNumber numSupport; /* max # of support procs (from pg_am) */
Oid *operatorOids; /* strategy operators' OIDs */
- RegProcedure *operatorProcs; /* strategy operators' procs */
RegProcedure *supportProcs; /* support procs */
} OpClassCacheEnt;
@@ -298,7 +300,6 @@ static void AttrDefaultFetch(Relation relation);
static void CheckConstraintFetch(Relation relation);
static List *insert_ordered_oid(List *list, Oid datum);
static void IndexSupportInitialize(Form_pg_index iform,
- IndexStrategy indexStrategy,
Oid *indexOperator,
RegProcedure *indexSupport,
StrategyNumber maxStrategyNumber,
@@ -337,8 +338,9 @@ ScanPgRelation(RelationBuildDescInfo buildinfo, bool indexOK)
case INFO_RELID:
ScanKeyEntryInitialize(&key[0], 0,
ObjectIdAttributeNumber,
- F_OIDEQ,
- ObjectIdGetDatum(buildinfo.i.info_id));
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(buildinfo.i.info_id),
+ OIDOID);
nkeys = 1;
indexRelname = ClassOidIndex;
break;
@@ -346,12 +348,14 @@ ScanPgRelation(RelationBuildDescInfo buildinfo, bool indexOK)
case INFO_RELNAME:
ScanKeyEntryInitialize(&key[0], 0,
Anum_pg_class_relname,
- F_NAMEEQ,
- NameGetDatum(buildinfo.i.info_name));
+ BTEqualStrategyNumber, F_NAMEEQ,
+ NameGetDatum(buildinfo.i.info_name),
+ NAMEOID);
ScanKeyEntryInitialize(&key[1], 0,
Anum_pg_class_relnamespace,
- F_OIDEQ,
- ObjectIdGetDatum(PG_CATALOG_NAMESPACE));
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
+ OIDOID);
nkeys = 2;
indexRelname = ClassNameNspIndex;
break;
@@ -481,12 +485,13 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
*/
ScanKeyEntryInitialize(&skey[0], 0,
Anum_pg_attribute_attrelid,
- F_OIDEQ,
- ObjectIdGetDatum(RelationGetRelid(relation)));
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(RelationGetRelid(relation)),
+ OIDOID);
ScanKeyEntryInitialize(&skey[1], 0,
Anum_pg_attribute_attnum,
- F_INT2GT,
- Int16GetDatum(0));
+ BTGreaterStrategyNumber, F_INT2GT,
+ Int16GetDatum(0), INT2OID);
/*
* Open pg_attribute and begin a scan. Force heap scan if we haven't
@@ -531,14 +536,10 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
if (attp->atthasdef)
{
if (attrdef == NULL)
- {
attrdef = (AttrDefault *)
- MemoryContextAlloc(CacheMemoryContext,
- relation->rd_rel->relnatts *
- sizeof(AttrDefault));
- MemSet(attrdef, 0,
- relation->rd_rel->relnatts * sizeof(AttrDefault));
- }
+ MemoryContextAllocZero(CacheMemoryContext,
+ relation->rd_rel->relnatts *
+ sizeof(AttrDefault));
attrdef[ndef].adnum = attp->attnum;
attrdef[ndef].adbin = NULL;
ndef++;
@@ -605,9 +606,8 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
{
constr->num_check = relation->rd_rel->relchecks;
constr->check = (ConstrCheck *)
- MemoryContextAlloc(CacheMemoryContext,
- constr->num_check * sizeof(ConstrCheck));
- MemSet(constr->check, 0, constr->num_check * sizeof(ConstrCheck));
+ MemoryContextAllocZero(CacheMemoryContext,
+ constr->num_check * sizeof(ConstrCheck));
CheckConstraintFetch(relation);
}
else
@@ -675,8 +675,9 @@ RelationBuildRuleLock(Relation relation)
*/
ScanKeyEntryInitialize(&key, 0,
Anum_pg_rewrite_ev_class,
- F_OIDEQ,
- ObjectIdGetDatum(RelationGetRelid(relation)));
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(RelationGetRelid(relation)),
+ OIDOID);
/*
* open pg_rewrite and begin a scan
@@ -950,7 +951,6 @@ RelationInitIndexAccessInfo(Relation relation)
Form_pg_am aform;
MemoryContext indexcxt;
MemoryContext oldcontext;
- IndexStrategy strategy;
Oid *operator;
RegProcedure *support;
FmgrInfo *supportinfo;
@@ -1016,33 +1016,20 @@ RelationInitIndexAccessInfo(Relation relation)
* Allocate arrays to hold data
*/
if (amstrategies > 0)
- {
- int noperators = natts * amstrategies;
- Size stratSize;
-
- stratSize = AttributeNumberGetIndexStrategySize(natts, amstrategies);
- strategy = (IndexStrategy) MemoryContextAlloc(indexcxt, stratSize);
- MemSet(strategy, 0, stratSize);
operator = (Oid *)
- MemoryContextAlloc(indexcxt, noperators * sizeof(Oid));
- MemSet(operator, 0, noperators * sizeof(Oid));
- }
+ MemoryContextAllocZero(indexcxt,
+ natts * amstrategies * sizeof(Oid));
else
- {
- strategy = NULL;
operator = NULL;
- }
if (amsupport > 0)
{
int nsupport = natts * amsupport;
support = (RegProcedure *)
- MemoryContextAlloc(indexcxt, nsupport * sizeof(RegProcedure));
- MemSet(support, 0, nsupport * sizeof(RegProcedure));
+ MemoryContextAllocZero(indexcxt, nsupport * sizeof(RegProcedure));
supportinfo = (FmgrInfo *)
- MemoryContextAlloc(indexcxt, nsupport * sizeof(FmgrInfo));
- MemSet(supportinfo, 0, nsupport * sizeof(FmgrInfo));
+ MemoryContextAllocZero(indexcxt, nsupport * sizeof(FmgrInfo));
}
else
{
@@ -1050,17 +1037,16 @@ RelationInitIndexAccessInfo(Relation relation)
supportinfo = NULL;
}
- relation->rd_istrat = strategy;
relation->rd_operator = operator;
relation->rd_support = support;
relation->rd_supportinfo = supportinfo;
/*
- * Fill the strategy map and the support RegProcedure arrays.
+ * Fill the operator and support procedure OID arrays.
* (supportinfo is left as zeroes, and is filled on-the-fly when used)
*/
IndexSupportInitialize(relation->rd_index,
- strategy, operator, support,
+ operator, support,
amstrategies, amsupport, natts);
/*
@@ -1072,11 +1058,11 @@ RelationInitIndexAccessInfo(Relation relation)
/*
* IndexSupportInitialize
- * Initializes an index strategy and associated support procedures,
+ * Initializes an index's cached lists of operators and support procs,
* given the index's pg_index tuple.
*
- * Data is returned into *indexStrategy, *indexOperator, and *indexSupport,
- * all of which are objects allocated by the caller.
+ * Data is returned into *indexOperator and *indexSupport, which are arrays
+ * allocated by the caller.
*
* The caller also passes maxStrategyNumber, maxSupportNumber, and
* maxAttributeNumber, since these indicate the size of the arrays
@@ -1086,7 +1072,6 @@ RelationInitIndexAccessInfo(Relation relation)
*/
static void
IndexSupportInitialize(Form_pg_index iform,
- IndexStrategy indexStrategy,
Oid *indexOperator,
RegProcedure *indexSupport,
StrategyNumber maxStrategyNumber,
@@ -1095,8 +1080,6 @@ IndexSupportInitialize(Form_pg_index iform,
{
int attIndex;
- maxStrategyNumber = AMStrategies(maxStrategyNumber);
-
/*
* XXX note that the following assumes the INDEX tuple is well formed
* and that the *key and *class are 0 terminated.
@@ -1113,52 +1096,15 @@ IndexSupportInitialize(Form_pg_index iform,
maxStrategyNumber,
maxSupportNumber);
- /* load the strategy information for the index operators */
+ /* copy cached data into relcache entry */
if (maxStrategyNumber > 0)
- {
- StrategyMap map;
- Oid *opers;
- StrategyNumber strategy;
-
- map = IndexStrategyGetStrategyMap(indexStrategy,
- maxStrategyNumber,
- attIndex + 1);
- opers = &indexOperator[attIndex * maxStrategyNumber];
-
- for (strategy = 0; strategy < maxStrategyNumber; strategy++)
- {
- ScanKey mapentry;
-
- mapentry = StrategyMapGetScanKeyEntry(map, strategy + 1);
- if (RegProcedureIsValid(opcentry->operatorProcs[strategy]))
- {
- MemSet(mapentry, 0, sizeof(*mapentry));
- mapentry->sk_flags = 0;
- mapentry->sk_procedure = opcentry->operatorProcs[strategy];
-
- /*
- * Mark mapentry->sk_func invalid, until and unless
- * someone sets it up.
- */
- mapentry->sk_func.fn_oid = InvalidOid;
- }
- else
- ScanKeyEntrySetIllegal(mapentry);
- opers[strategy] = opcentry->operatorOids[strategy];
- }
- }
-
- /* if support routines exist for this access method, load them */
+ memcpy(&indexOperator[attIndex * maxStrategyNumber],
+ opcentry->operatorOids,
+ maxStrategyNumber * sizeof(Oid));
if (maxSupportNumber > 0)
- {
- RegProcedure *procs;
- StrategyNumber support;
-
- procs = &indexSupport[attIndex * maxSupportNumber];
-
- for (support = 0; support < maxSupportNumber; ++support)
- procs[support] = opcentry->supportProcs[support];
- }
+ memcpy(&indexSupport[attIndex * maxSupportNumber],
+ opcentry->supportProcs,
+ maxSupportNumber * sizeof(RegProcedure));
}
}
@@ -1231,29 +1177,16 @@ LookupOpclassInfo(Oid operatorClassOid,
opcentry->numSupport = numSupport;
if (numStrats > 0)
- {
opcentry->operatorOids = (Oid *)
- MemoryContextAlloc(CacheMemoryContext,
- numStrats * sizeof(Oid));
- MemSet(opcentry->operatorOids, 0, numStrats * sizeof(Oid));
- opcentry->operatorProcs = (RegProcedure *)
- MemoryContextAlloc(CacheMemoryContext,
- numStrats * sizeof(RegProcedure));
- MemSet(opcentry->operatorProcs, 0, numStrats * sizeof(RegProcedure));
- }
+ MemoryContextAllocZero(CacheMemoryContext,
+ numStrats * sizeof(Oid));
else
- {
opcentry->operatorOids = NULL;
- opcentry->operatorProcs = NULL;
- }
if (numSupport > 0)
- {
opcentry->supportProcs = (RegProcedure *)
- MemoryContextAlloc(CacheMemoryContext,
- numSupport * sizeof(RegProcedure));
- MemSet(opcentry->supportProcs, 0, numSupport * sizeof(RegProcedure));
- }
+ MemoryContextAllocZero(CacheMemoryContext,
+ numSupport * sizeof(RegProcedure));
else
opcentry->supportProcs = NULL;
@@ -1273,8 +1206,9 @@ LookupOpclassInfo(Oid operatorClassOid,
{
ScanKeyEntryInitialize(&key, 0,
Anum_pg_amop_amopclaid,
- F_OIDEQ,
- ObjectIdGetDatum(operatorClassOid));
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(operatorClassOid),
+ OIDOID);
pg_amop_desc = heap_openr(AccessMethodOperatorRelationName,
AccessShareLock);
pg_amop_scan = systable_beginscan(pg_amop_desc,
@@ -1293,8 +1227,6 @@ LookupOpclassInfo(Oid operatorClassOid,
amopform->amopstrategy, operatorClassOid);
opcentry->operatorOids[amopform->amopstrategy - 1] =
amopform->amopopr;
- opcentry->operatorProcs[amopform->amopstrategy - 1] =
- get_opcode(amopform->amopopr);
}
systable_endscan(pg_amop_scan);
@@ -1308,8 +1240,9 @@ LookupOpclassInfo(Oid operatorClassOid,
{
ScanKeyEntryInitialize(&key, 0,
Anum_pg_amproc_amopclaid,
- F_OIDEQ,
- ObjectIdGetDatum(operatorClassOid));
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(operatorClassOid),
+ OIDOID);
pg_amproc_desc = heap_openr(AccessMethodProcedureRelationName,
AccessShareLock);
pg_amproc_scan = systable_beginscan(pg_amproc_desc,
@@ -2550,11 +2483,11 @@ AttrDefaultFetch(Relation relation)
int found;
int i;
- ScanKeyEntryInitialize(&skey,
- (bits16) 0x0,
- (AttrNumber) Anum_pg_attrdef_adrelid,
- (RegProcedure) F_OIDEQ,
- ObjectIdGetDatum(RelationGetRelid(relation)));
+ ScanKeyEntryInitialize(&skey, 0,
+ Anum_pg_attrdef_adrelid,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(RelationGetRelid(relation)),
+ OIDOID);
adrel = heap_openr(AttrDefaultRelationName, AccessShareLock);
adscan = systable_beginscan(adrel, AttrDefaultIndex, true,
@@ -2617,9 +2550,11 @@ CheckConstraintFetch(Relation relation)
bool isnull;
int found = 0;
- ScanKeyEntryInitialize(&skey[0], 0x0,
- Anum_pg_constraint_conrelid, F_OIDEQ,
- ObjectIdGetDatum(RelationGetRelid(relation)));
+ ScanKeyEntryInitialize(&skey[0], 0,
+ Anum_pg_constraint_conrelid,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(RelationGetRelid(relation)),
+ OIDOID);
conrel = heap_openr(ConstraintRelationName, AccessShareLock);
conscan = systable_beginscan(conrel, ConstraintRelidIndex, true,
@@ -2707,11 +2642,11 @@ RelationGetIndexList(Relation relation)
result = NIL;
/* Prepare to scan pg_index for entries having indrelid = this rel. */
- ScanKeyEntryInitialize(&skey,
- (bits16) 0x0,
- (AttrNumber) Anum_pg_index_indrelid,
- (RegProcedure) F_OIDEQ,
- ObjectIdGetDatum(RelationGetRelid(relation)));
+ ScanKeyEntryInitialize(&skey, 0,
+ Anum_pg_index_indrelid,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(RelationGetRelid(relation)),
+ OIDOID);
indrel = heap_openr(IndexRelationName, AccessShareLock);
indscan = systable_beginscan(indrel, IndexIndrelidIndex, true,
@@ -2988,7 +2923,8 @@ load_relcache_init_file(void)
num_rels,
max_rels,
nailed_rels,
- nailed_indexes;
+ nailed_indexes,
+ magic;
int i;
snprintf(initfilename, sizeof(initfilename), "%s/%s",
@@ -3012,6 +2948,12 @@ load_relcache_init_file(void)
nailed_rels = nailed_indexes = 0;
initFileRelationIds = NIL;
+ /* check for correct magic number (compatible version) */
+ if (fread(&magic, 1, sizeof(magic), fp) != sizeof(magic))
+ goto read_failed;
+ if (magic != RELCACHE_INIT_FILEMAGIC)
+ goto read_failed;
+
for (relno = 0;; relno++)
{
Size len;
@@ -3088,11 +3030,9 @@ load_relcache_init_file(void)
{
Form_pg_am am;
MemoryContext indexcxt;
- IndexStrategy strat;
Oid *operator;
RegProcedure *support;
- int nstrategies,
- nsupport;
+ int nsupport;
/* Count nailed indexes to ensure we have 'em all */
if (rel->rd_isnailed)
@@ -3131,21 +3071,6 @@ load_relcache_init_file(void)
ALLOCSET_SMALL_MAXSIZE);
rel->rd_indexcxt = indexcxt;
- /* next, read the index strategy map */
- if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
- goto read_failed;
-
- strat = (IndexStrategy) MemoryContextAlloc(indexcxt, len);
- if ((nread = fread(strat, 1, len, fp)) != len)
- goto read_failed;
-
- /* 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;
-
- rel->rd_istrat = strat;
-
/* next, read the vector of operator OIDs */
if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
goto read_failed;
@@ -3168,8 +3093,7 @@ load_relcache_init_file(void)
/* add a zeroed support-fmgr-info vector */
nsupport = relform->relnatts * am->amsupport;
rel->rd_supportinfo = (FmgrInfo *)
- MemoryContextAlloc(indexcxt, nsupport * sizeof(FmgrInfo));
- MemSet(rel->rd_supportinfo, 0, nsupport * sizeof(FmgrInfo));
+ MemoryContextAllocZero(indexcxt, nsupport * sizeof(FmgrInfo));
}
else
{
@@ -3181,7 +3105,6 @@ load_relcache_init_file(void)
Assert(rel->rd_indextuple == NULL);
Assert(rel->rd_am == NULL);
Assert(rel->rd_indexcxt == NULL);
- Assert(rel->rd_istrat == NULL);
Assert(rel->rd_operator == NULL);
Assert(rel->rd_support == NULL);
Assert(rel->rd_supportinfo == NULL);
@@ -3277,6 +3200,7 @@ write_relcache_init_file(void)
FILE *fp;
char tempfilename[MAXPGPATH];
char finalfilename[MAXPGPATH];
+ int magic;
HASH_SEQ_STATUS status;
RelIdCacheEnt *idhentry;
MemoryContext oldcxt;
@@ -3310,6 +3234,14 @@ write_relcache_init_file(void)
}
/*
+ * Write a magic number to serve as a file version identifier. We can
+ * change the magic number whenever the relcache layout changes.
+ */
+ magic = RELCACHE_INIT_FILEMAGIC;
+ if (fwrite(&magic, 1, sizeof(magic), fp) != sizeof(magic))
+ elog(FATAL, "could not write init file");
+
+ /*
* Write all the reldescs (in no particular order).
*/
hash_seq_init(&status, RelationIdCache);
@@ -3375,15 +3307,6 @@ write_relcache_init_file(void)
if (fwrite(am, 1, len, fp) != len)
elog(FATAL, "could not write init file");
- /* next, write the index strategy map */
- len = AttributeNumberGetIndexStrategySize(relform->relnatts,
- am->amstrategies);
- if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len))
- elog(FATAL, "could not write init file");
-
- if (fwrite(rel->rd_istrat, 1, len, fp) != len)
- elog(FATAL, "could not write init file");
-
/* next, write the vector of operator OIDs */
len = relform->relnatts * (am->amstrategies * sizeof(Oid));
if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len))