aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access')
-rw-r--r--src/backend/access/gist/gist.c97
-rw-r--r--src/backend/access/index/istrat.c198
2 files changed, 108 insertions, 187 deletions
diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c
index 4d0cbb6d9c5..779a0aa8757 100644
--- a/src/backend/access/gist/gist.c
+++ b/src/backend/access/gist/gist.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.81 2001/08/10 14:34:28 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.82 2001/08/21 16:35:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,8 +20,10 @@
#include "access/heapam.h"
#include "catalog/index.h"
#include "catalog/pg_index.h"
+#include "catalog/pg_opclass.h"
#include "executor/executor.h"
#include "miscadmin.h"
+#include "utils/lsyscache.h"
#include "utils/syscache.h"
#include "access/xlogutils.h"
@@ -1377,10 +1379,9 @@ gistchoose(Relation r, Page p, IndexTuple it, /* it has compressed entry */
for (i = FirstOffsetNumber; i <= maxoff && sum_grow; i = OffsetNumberNext(i))
{
+ IndexTuple itup = (IndexTuple) PageGetItem(p, PageGetItemId(p, i));
sum_grow=0;
for (j=0; j<r->rd_att->natts; j++) {
- IndexTuple itup = (IndexTuple) PageGetItem(p, PageGetItemId(p, i));
-
datum = index_getattr(itup, j+1, r->rd_att, &IsNull);
gistdentryinit(giststate, j, &entry, datum, r, p, i, ATTSIZE( datum, r, j+1, IsNull ), FALSE, IsNull);
gistpenalty( giststate, j, &entry, IsNull, &identry[j], isnull[j], &usize);
@@ -1548,20 +1549,32 @@ initGISTstate(GISTSTATE *giststate, Relation index)
RegProcedure consistent_proc,
union_proc,
compress_proc,
- decompress_proc;
- RegProcedure penalty_proc,
+ decompress_proc,
+ penalty_proc,
picksplit_proc,
equal_proc;
- HeapTuple htup;
+ HeapTuple itup;
+ HeapTuple ctup;
Form_pg_index itupform;
- Oid indexrelid;
+ Form_pg_opclass opclassform;
+ Oid inputtype;
+ Oid keytype;
int i;
- if (index->rd_att->natts >= INDEX_MAX_KEYS)
- elog(ERROR, "initGISTstate: numberOfAttributes %d > %d",
- index->rd_att->natts, INDEX_MAX_KEYS);
+ if (index->rd_att->natts > INDEX_MAX_KEYS)
+ elog(ERROR, "initGISTstate: numberOfAttributes %d > %d",
+ index->rd_att->natts, INDEX_MAX_KEYS);
+
+ itup = SearchSysCache(INDEXRELID,
+ ObjectIdGetDatum(RelationGetRelid(index)),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(itup))
+ elog(ERROR, "initGISTstate: index %u not found",
+ RelationGetRelid(index));
+ itupform = (Form_pg_index) GETSTRUCT(itup);
- 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 );
union_proc = index_getprocid(index, i+1, GIST_UNION_PROC );
compress_proc = index_getprocid(index, i+1, GIST_COMPRESS_PROC );
@@ -1577,37 +1590,35 @@ initGISTstate(GISTSTATE *giststate, Relation index)
fmgr_info(picksplit_proc, &((giststate->picksplitFn)[i]) );
fmgr_info(equal_proc, &((giststate->equalFn)[i]) );
- giststate->attbyval[i] =
- index->rd_att->attrs[i]->attbyval;
+ /* Check opclass entry to see if there is a keytype */
+ ctup = SearchSysCache(CLAOID,
+ ObjectIdGetDatum(itupform->indclass[i]),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(ctup))
+ elog(ERROR, "cache lookup failed for opclass %u",
+ itupform->indclass[i]);
+ opclassform = (Form_pg_opclass) GETSTRUCT(ctup);
+ inputtype = opclassform->opcintype;
+ keytype = opclassform->opckeytype;
+ ReleaseSysCache(ctup);
+
+ if (OidIsValid(keytype))
+ {
+ /* index column type is (possibly) different from input data */
+ giststate->haskeytype[i] = true;
+ giststate->attbyval[i] = get_typbyval(inputtype);
+ giststate->keytypbyval[i] = index->rd_att->attrs[i]->attbyval;
+ }
+ else
+ {
+ /* Normal case where index column type is same as input data */
+ giststate->haskeytype[i] = false;
+ giststate->attbyval[i] = index->rd_att->attrs[i]->attbyval;
+ giststate->keytypbyval[i] = false; /* not actually used */
+ }
}
- /* see if key type is different from type of attribute being indexed */
- htup = SearchSysCache(INDEXRELID,
- ObjectIdGetDatum(RelationGetRelid(index)),
- 0, 0, 0);
- if (!HeapTupleIsValid(htup))
- elog(ERROR, "initGISTstate: index %u not found",
- RelationGetRelid(index));
- itupform = (Form_pg_index) GETSTRUCT(htup);
- giststate->haskeytype = itupform->indhaskeytype;
- indexrelid = itupform->indexrelid;
- ReleaseSysCache(htup);
-
- if (giststate->haskeytype)
- {
- /* key type is different -- is it byval? */
- htup = SearchSysCache(ATTNUM,
- ObjectIdGetDatum(indexrelid),
- UInt16GetDatum(FirstOffsetNumber),
- 0, 0);
- if (!HeapTupleIsValid(htup))
- elog(ERROR, "initGISTstate: no attribute tuple %u %d",
- indexrelid, FirstOffsetNumber);
- giststate->keytypbyval = (((Form_pg_attribute) htup)->attbyval);
- ReleaseSysCache(htup);
- }
- else
- giststate->keytypbyval = FALSE;
+ ReleaseSysCache(itup);
}
#ifdef GIST_PAGEADDITEM
@@ -1670,7 +1681,7 @@ gistdentryinit(GISTSTATE *giststate, int nkey, GISTENTRY *e,
GISTENTRY *dep;
gistentryinit(*e, k, r, pg, o, b, l);
- if (giststate->haskeytype)
+ if (giststate->haskeytype[nkey])
{
if ( b && ! isNull ) {
dep = (GISTENTRY *)
@@ -1698,7 +1709,7 @@ gistcentryinit(GISTSTATE *giststate, int nkey,
GISTENTRY *cep;
gistentryinit(*e, k, r, pg, o, b, l);
- if (giststate->haskeytype)
+ if (giststate->haskeytype[nkey])
{
if ( ! isNull ) {
cep = (GISTENTRY *)
@@ -1792,7 +1803,7 @@ gistpenalty( GISTSTATE *giststate, int attno,
FunctionCall3(&giststate->penaltyFn[attno],
PointerGetDatum(key1),
PointerGetDatum(key2),
- PointerGetDatum(&penalty));
+ PointerGetDatum(penalty));
}
#ifdef GISTDEBUG
diff --git a/src/backend/access/index/istrat.c b/src/backend/access/index/istrat.c
index 188f69b5719..35df06aeace 100644
--- a/src/backend/access/index/istrat.c
+++ b/src/backend/access/index/istrat.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.51 2001/06/01 02:41:35 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.52 2001/08/21 16:36:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -457,61 +457,32 @@ RelationInvokeStrategy(Relation relation,
#endif
/* ----------------
- * OperatorRelationFillScanKeyEntry
+ * FillScanKeyEntry
*
- * Initialize a ScanKey entry given already-opened pg_operator relation.
+ * Initialize a ScanKey entry for the given operator OID.
* ----------------
*/
static void
-OperatorRelationFillScanKeyEntry(Relation operatorRelation,
- Oid operatorObjectId,
- ScanKey entry)
+FillScanKeyEntry(Oid operatorObjectId, ScanKey entry)
{
HeapTuple tuple;
- HeapScanDesc scan = NULL;
- bool cachesearch = (!IsBootstrapProcessingMode()) && IsCacheInitialized();
- if (cachesearch)
- {
- tuple = SearchSysCache(OPEROID,
- ObjectIdGetDatum(operatorObjectId),
- 0, 0, 0);
- }
- else
- {
- ScanKeyData scanKeyData;
-
- ScanKeyEntryInitialize(&scanKeyData, 0,
- ObjectIdAttributeNumber,
- F_OIDEQ,
- ObjectIdGetDatum(operatorObjectId));
-
- scan = heap_beginscan(operatorRelation, false, SnapshotNow,
- 1, &scanKeyData);
-
- tuple = heap_getnext(scan, 0);
- }
+ tuple = SearchSysCache(OPEROID,
+ ObjectIdGetDatum(operatorObjectId),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
- {
- if (!cachesearch)
- heap_endscan(scan);
- elog(ERROR, "OperatorRelationFillScanKeyEntry: unknown operator %u",
+ elog(ERROR, "FillScanKeyEntry: unknown operator %u",
operatorObjectId);
- }
MemSet(entry, 0, sizeof(*entry));
entry->sk_flags = 0;
entry->sk_procedure = ((Form_pg_operator) GETSTRUCT(tuple))->oprcode;
- if (cachesearch)
- ReleaseSysCache(tuple);
- else
- heap_endscan(scan);
+ ReleaseSysCache(tuple);
if (!RegProcedureIsValid(entry->sk_procedure))
- elog(ERROR,
- "OperatorRelationFillScanKeyEntry: no procedure for operator %u",
+ elog(ERROR, "FillScanKeyEntry: no procedure for operator %u",
operatorObjectId);
/*
@@ -548,160 +519,99 @@ IndexSupportInitialize(IndexStrategy indexStrategy,
StrategyNumber maxSupportNumber,
AttrNumber maxAttributeNumber)
{
- Relation relation = NULL;
- HeapScanDesc scan = NULL;
- ScanKeyData entry[2];
- Relation operatorRelation;
HeapTuple tuple;
Form_pg_index iform;
- StrategyMap map;
- AttrNumber attNumber;
int attIndex;
Oid operatorClassObjectId[INDEX_MAX_KEYS];
- bool cachesearch = (!IsBootstrapProcessingMode()) && IsCacheInitialized();
-
- if (cachesearch)
- {
- tuple = SearchSysCache(INDEXRELID,
- ObjectIdGetDatum(indexObjectId),
- 0, 0, 0);
- }
- else
- {
- ScanKeyEntryInitialize(&entry[0], 0, Anum_pg_index_indexrelid,
- F_OIDEQ,
- ObjectIdGetDatum(indexObjectId));
- relation = heap_openr(IndexRelationName, AccessShareLock);
- scan = heap_beginscan(relation, false, SnapshotNow, 1, entry);
- tuple = heap_getnext(scan, 0);
- }
+ maxStrategyNumber = AMStrategies(maxStrategyNumber);
+ tuple = SearchSysCache(INDEXRELID,
+ ObjectIdGetDatum(indexObjectId),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "IndexSupportInitialize: no pg_index entry for index %u",
indexObjectId);
-
iform = (Form_pg_index) GETSTRUCT(tuple);
*isUnique = iform->indisunique;
- maxStrategyNumber = AMStrategies(maxStrategyNumber);
-
/*
* XXX note that the following assumes the INDEX tuple is well formed
* and that the *key and *class are 0 terminated.
*/
for (attIndex = 0; attIndex < maxAttributeNumber; attIndex++)
{
- if (!OidIsValid(iform->indkey[attIndex]))
- {
- if (attIndex == InvalidAttrNumber)
- elog(ERROR, "IndexSupportInitialize: bogus pg_index tuple");
- break;
- }
-
+ if (iform->indkey[attIndex] == InvalidAttrNumber ||
+ !OidIsValid(iform->indclass[attIndex]))
+ elog(ERROR, "IndexSupportInitialize: bogus pg_index tuple");
operatorClassObjectId[attIndex] = iform->indclass[attIndex];
}
- if (cachesearch)
- ReleaseSysCache(tuple);
- else
- {
- heap_endscan(scan);
- heap_close(relation, AccessShareLock);
- }
+ ReleaseSysCache(tuple);
/* if support routines exist for this access method, load them */
if (maxSupportNumber > 0)
{
- ScanKeyEntryInitialize(&entry[0], 0, Anum_pg_amproc_amid,
- F_OIDEQ,
- ObjectIdGetDatum(accessMethodObjectId));
-
- ScanKeyEntryInitialize(&entry[1], 0, Anum_pg_amproc_amopclaid,
- F_OIDEQ,
- InvalidOid); /* will set below */
-
- relation = heap_openr(AccessMethodProcedureRelationName,
- AccessShareLock);
-
- for (attNumber = 1; attNumber <= maxAttributeNumber; attNumber++)
+ for (attIndex = 0; attIndex < maxAttributeNumber; attIndex++)
{
+ Oid opclass = operatorClassObjectId[attIndex];
RegProcedure *loc;
StrategyNumber support;
- loc = &indexSupport[((attNumber - 1) * maxSupportNumber)];
+ loc = &indexSupport[attIndex * maxSupportNumber];
for (support = 0; support < maxSupportNumber; ++support)
- loc[support] = InvalidOid;
-
- entry[1].sk_argument =
- ObjectIdGetDatum(operatorClassObjectId[attNumber - 1]);
-
- scan = heap_beginscan(relation, false, SnapshotNow, 2, entry);
-
- while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
{
- Form_pg_amproc aform;
-
- aform = (Form_pg_amproc) GETSTRUCT(tuple);
- support = aform->amprocnum;
- Assert(support > 0 && support <= maxSupportNumber);
- loc[support - 1] = aform->amproc;
+ tuple = SearchSysCache(AMPROCNUM,
+ ObjectIdGetDatum(opclass),
+ Int16GetDatum(support+1),
+ 0, 0);
+ if (HeapTupleIsValid(tuple))
+ {
+ Form_pg_amproc amprocform;
+
+ amprocform = (Form_pg_amproc) GETSTRUCT(tuple);
+ loc[support] = amprocform->amproc;
+ ReleaseSysCache(tuple);
+ }
+ else
+ loc[support] = InvalidOid;
}
-
- heap_endscan(scan);
}
- heap_close(relation, AccessShareLock);
}
/* Now load the strategy information for the index operators */
- ScanKeyEntryInitialize(&entry[0], 0,
- Anum_pg_amop_amopid,
- F_OIDEQ,
- ObjectIdGetDatum(accessMethodObjectId));
-
- ScanKeyEntryInitialize(&entry[1], 0,
- Anum_pg_amop_amopclaid,
- F_OIDEQ,
- 0); /* will fill below */
-
- relation = heap_openr(AccessMethodOperatorRelationName, AccessShareLock);
- operatorRelation = heap_openr(OperatorRelationName, AccessShareLock);
-
- for (attNumber = maxAttributeNumber; attNumber > 0; attNumber--)
+ for (attIndex = 0; attIndex < maxAttributeNumber; attIndex++)
{
+ Oid opclass = operatorClassObjectId[attIndex];
+ StrategyMap map;
StrategyNumber strategy;
- entry[1].sk_argument =
- ObjectIdGetDatum(operatorClassObjectId[attNumber - 1]);
-
map = IndexStrategyGetStrategyMap(indexStrategy,
maxStrategyNumber,
- attNumber);
+ attIndex + 1);
for (strategy = 1; strategy <= maxStrategyNumber; strategy++)
- ScanKeyEntrySetIllegal(StrategyMapGetScanKeyEntry(map, strategy));
+ {
+ ScanKey mapentry = StrategyMapGetScanKeyEntry(map, strategy);
- scan = heap_beginscan(relation, false, SnapshotNow, 2, entry);
+ tuple = SearchSysCache(AMOPSTRATEGY,
+ ObjectIdGetDatum(opclass),
+ Int16GetDatum(strategy),
+ 0, 0);
+ if (HeapTupleIsValid(tuple))
+ {
+ Form_pg_amop amopform;
- while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
- {
- Form_pg_amop aform;
-
- aform = (Form_pg_amop) GETSTRUCT(tuple);
- strategy = aform->amopstrategy;
- Assert(strategy > 0 && strategy <= maxStrategyNumber);
- OperatorRelationFillScanKeyEntry(operatorRelation,
- aform->amopopr,
- StrategyMapGetScanKeyEntry(map, strategy));
+ amopform = (Form_pg_amop) GETSTRUCT(tuple);
+ FillScanKeyEntry(amopform->amopopr, mapentry);
+ ReleaseSysCache(tuple);
+ }
+ else
+ ScanKeyEntrySetIllegal(mapentry);
}
-
- heap_endscan(scan);
}
-
- heap_close(operatorRelation, AccessShareLock);
- heap_close(relation, AccessShareLock);
}
/* ----------------