aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/gist/gist.c154
-rw-r--r--src/backend/access/hash/hash.c90
-rw-r--r--src/backend/access/index/indexam.c55
-rw-r--r--src/backend/access/index/istrat.c15
-rw-r--r--src/backend/access/nbtree/nbtree.c105
-rw-r--r--src/backend/access/rtree/rtree.c129
-rw-r--r--src/backend/bootstrap/bootparse.y3
-rw-r--r--src/backend/bootstrap/bootscanner.l3
-rw-r--r--src/backend/bootstrap/bootstrap.c67
-rw-r--r--src/backend/catalog/heap.c82
-rw-r--r--src/backend/catalog/index.c666
-rw-r--r--src/backend/catalog/indexing.c80
-rw-r--r--src/backend/commands/cluster.c66
-rw-r--r--src/backend/commands/command.c21
-rw-r--r--src/backend/commands/copy.c241
-rw-r--r--src/backend/commands/indexcmds.c312
-rw-r--r--src/backend/commands/vacuum.c110
-rw-r--r--src/backend/executor/execUtils.c209
-rw-r--r--src/backend/storage/large_object/inv_api.c32
-rw-r--r--src/backend/utils/cache/relcache.c3
-rw-r--r--src/include/access/funcindex.h43
-rw-r--r--src/include/access/genam.h6
-rw-r--r--src/include/access/gist.h1
-rw-r--r--src/include/access/hash.h3
-rw-r--r--src/include/access/istrat.h13
-rw-r--r--src/include/access/itup.h14
-rw-r--r--src/include/bootstrap/bootstrap.h14
-rw-r--r--src/include/catalog/index.h39
-rw-r--r--src/include/catalog/pg_proc.h10
-rw-r--r--src/include/commands/vacuum.h15
-rw-r--r--src/include/nodes/execnodes.h32
-rw-r--r--src/include/utils/rel.h3
32 files changed, 900 insertions, 1736 deletions
diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c
index 28c547ffe69..640c1898860 100644
--- a/src/backend/access/gist/gist.c
+++ b/src/backend/access/gist/gist.c
@@ -6,7 +6,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.61 2000/07/12 02:36:46 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.62 2000/07/14 22:17:28 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -65,53 +65,42 @@ gistbuild(PG_FUNCTION_ARGS)
{
Relation heap = (Relation) PG_GETARG_POINTER(0);
Relation index = (Relation) PG_GETARG_POINTER(1);
- int32 natts = PG_GETARG_INT32(2);
- AttrNumber *attnum = (AttrNumber *) PG_GETARG_POINTER(3);
- FuncIndexInfo *finfo = (FuncIndexInfo *) PG_GETARG_POINTER(4);
- PredInfo *predInfo = (PredInfo *) PG_GETARG_POINTER(5);
+ IndexInfo *indexInfo = (IndexInfo *) PG_GETARG_POINTER(2);
+ Node *oldPred = (Node *) PG_GETARG_POINTER(3);
#ifdef NOT_USED
- bool unique = PG_GETARG_BOOL(6);
- IndexStrategy istrat = (IndexStrategy) PG_GETARG_POINTER(7);
+ IndexStrategy istrat = (IndexStrategy) PG_GETARG_POINTER(4);
#endif
- HeapScanDesc scan;
- AttrNumber i;
+ HeapScanDesc hscan;
HeapTuple htup;
IndexTuple itup;
- TupleDesc hd,
- id;
- InsertIndexResult res;
- Datum *d;
- bool *nulls;
- int nb,
- nh,
- ni;
+ TupleDesc htupdesc,
+ itupdesc;
+ Datum attdata[INDEX_MAX_KEYS];
+ char nulls[INDEX_MAX_KEYS];
+ int nhtups,
+ nitups;
+ Node *pred = indexInfo->ii_Predicate;
#ifndef OMIT_PARTIAL_INDEX
- ExprContext *econtext;
TupleTable tupleTable;
TupleTableSlot *slot;
#endif
- Node *pred,
- *oldPred;
+ ExprContext *econtext;
+ InsertIndexResult res = NULL;
GISTSTATE giststate;
GISTENTRY tmpcentry;
Buffer buffer = InvalidBuffer;
bool *compvec;
+ int i;
/* no locking is needed */
- CommandCounterIncrement(); /* so we can see the new pg_index tuple */
-
initGISTstate(&giststate, index);
- pred = predInfo->pred;
- oldPred = predInfo->oldPred;
-
/*
* We expect to be called exactly once for any index relation. If
* that's not the case, big trouble's what we have.
*/
-
- if (oldPred == NULL && (nb = RelationGetNumberOfBlocks(index)) != 0)
+ if (oldPred == NULL && RelationGetNumberOfBlocks(index) != 0)
elog(ERROR, "%s already contains data", RelationGetRelationName(index));
/* initialize the root page (if this is a new index) */
@@ -122,43 +111,50 @@ gistbuild(PG_FUNCTION_ARGS)
WriteBuffer(buffer);
}
- /* init the tuple descriptors and get set for a heap scan */
- hd = RelationGetDescr(heap);
- id = RelationGetDescr(index);
- d = (Datum *) palloc(natts * sizeof(*d));
- nulls = (bool *) palloc(natts * sizeof(*nulls));
+ /* get tuple descriptors for heap and index relations */
+ htupdesc = RelationGetDescr(heap);
+ itupdesc = RelationGetDescr(index);
/*
* If this is a predicate (partial) index, we will need to evaluate
* the predicate using ExecQual, which requires the current tuple to
* be in a slot of a TupleTable. In addition, ExecQual must have an
* ExprContext referring to that slot. Here, we initialize dummy
- * TupleTable and ExprContext objects for this purpose. --Nels, Feb
- * '92
+ * TupleTable and ExprContext objects for this purpose. --Nels, Feb 92
+ *
+ * We construct the ExprContext anyway since we need a per-tuple
+ * temporary memory context for function evaluation -- tgl July 00
*/
#ifndef OMIT_PARTIAL_INDEX
if (pred != NULL || oldPred != NULL)
{
tupleTable = ExecCreateTupleTable(1);
slot = ExecAllocTableSlot(tupleTable);
- ExecSetSlotDescriptor(slot, hd);
- econtext = MakeExprContext(slot, TransactionCommandContext);
+ ExecSetSlotDescriptor(slot, htupdesc);
}
else
{
tupleTable = NULL;
slot = NULL;
- econtext = NULL;
}
+ econtext = MakeExprContext(slot, TransactionCommandContext);
+#else
+ econtext = MakeExprContext(NULL, TransactionCommandContext);
#endif /* OMIT_PARTIAL_INDEX */
- /* int the tuples as we insert them */
- nh = ni = 0;
- scan = heap_beginscan(heap, 0, SnapshotNow, 0, (ScanKey) NULL);
+ /* build the index */
+ nhtups = nitups = 0;
+
+ compvec = (bool *) palloc(sizeof(bool) * indexInfo->ii_NumIndexAttrs);
- while (HeapTupleIsValid(htup = heap_getnext(scan, 0)))
+ /* start a heap scan */
+ hscan = heap_beginscan(heap, 0, SnapshotNow, 0, (ScanKey) NULL);
+
+ while (HeapTupleIsValid(htup = heap_getnext(hscan, 0)))
{
- nh++;
+ MemoryContextReset(econtext->ecxt_per_tuple_memory);
+
+ nhtups++;
#ifndef OMIT_PARTIAL_INDEX
/*
@@ -167,11 +163,10 @@ gistbuild(PG_FUNCTION_ARGS)
*/
if (oldPred != NULL)
{
- /* SetSlotContents(slot, htup); */
slot->val = htup;
if (ExecQual((List *) oldPred, econtext, false))
{
- ni++;
+ nitups++;
continue;
}
}
@@ -182,61 +177,41 @@ gistbuild(PG_FUNCTION_ARGS)
*/
if (pred != NULL)
{
- /* SetSlotContents(slot, htup); */
slot->val = htup;
if (!ExecQual((List *) pred, econtext, false))
continue;
}
#endif /* OMIT_PARTIAL_INDEX */
- ni++;
+ nitups++;
/*
* For the current heap tuple, extract all the attributes we use
* in this index, and note which are null.
*/
-
- for (i = 1; i <= natts; i++)
- {
- int attoff;
- bool attnull;
-
- /*
- * Offsets are from the start of the tuple, and are
- * zero-based; indices are one-based. The next call returns i
- * - 1. That's data hiding for you.
- */
-
- attoff = AttrNumberGetAttrOffset(i);
-
- /*
- * d[attoff] = HeapTupleGetAttributeValue(htup, buffer,
- */
- d[attoff] = GetIndexValue(htup,
- hd,
- attoff,
- attnum,
- finfo,
- &attnull);
- nulls[attoff] = (attnull ? 'n' : ' ');
- }
+ FormIndexDatum(indexInfo,
+ htup,
+ htupdesc,
+ econtext->ecxt_per_tuple_memory,
+ attdata,
+ nulls);
/* immediately compress keys to normalize */
- compvec = (bool *) palloc(sizeof(bool) * natts);
- for (i = 0; i < natts; i++)
+ for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
{
- gistcentryinit(&giststate, &tmpcentry, (char *) d[i],
+ gistcentryinit(&giststate, &tmpcentry, (char *) attdata[i],
(Relation) NULL, (Page) NULL, (OffsetNumber) 0,
-1 /* size is currently bogus */ , TRUE);
- if (d[i] != (Datum) tmpcentry.pred && !(giststate.keytypbyval))
+ if (attdata[i] != (Datum) tmpcentry.pred &&
+ !(giststate.keytypbyval))
compvec[i] = TRUE;
else
compvec[i] = FALSE;
- d[i] = (Datum) tmpcentry.pred;
+ attdata[i] = (Datum) tmpcentry.pred;
}
/* form an index tuple and point it at the heap tuple */
- itup = index_formtuple(id, &d[0], nulls);
+ itup = index_formtuple(itupdesc, attdata, nulls);
itup->t_tid = htup->t_self;
/*
@@ -248,24 +223,27 @@ gistbuild(PG_FUNCTION_ARGS)
*/
res = gistdoinsert(index, itup, &giststate);
- for (i = 0; i < natts; i++)
- if (compvec[i] == TRUE)
- pfree((char *) d[i]);
+
+ for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
+ if (compvec[i])
+ pfree(DatumGetPointer(attdata[i]));
+
pfree(itup);
pfree(res);
- pfree(compvec);
}
/* okay, all heap tuples are indexed */
- heap_endscan(scan);
+ heap_endscan(hscan);
+
+ pfree(compvec);
#ifndef OMIT_PARTIAL_INDEX
if (pred != NULL || oldPred != NULL)
{
ExecDropTupleTable(tupleTable, true);
- FreeExprContext(econtext);
}
#endif /* OMIT_PARTIAL_INDEX */
+ FreeExprContext(econtext);
/*
* Since we just counted the tuples in the heap, we update its stats
@@ -286,20 +264,16 @@ gistbuild(PG_FUNCTION_ARGS)
heap_close(heap, NoLock);
index_close(index);
- UpdateStats(hrelid, nh, inplace);
- UpdateStats(irelid, ni, inplace);
+ UpdateStats(hrelid, nhtups, inplace);
+ UpdateStats(irelid, nitups, inplace);
if (oldPred != NULL && !inplace)
{
- if (ni == nh)
+ if (nitups == nhtups)
pred = NULL;
UpdateIndexPredicate(irelid, oldPred, pred);
}
}
- /* be tidy */
- pfree(nulls);
- pfree(d);
-
PG_RETURN_VOID();
}
diff --git a/src/backend/access/hash/hash.c b/src/backend/access/hash/hash.c
index 354d4985723..cb740bbde9e 100644
--- a/src/backend/access/hash/hash.c
+++ b/src/backend/access/hash/hash.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/hash/hash.c,v 1.41 2000/07/12 02:36:46 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/hash/hash.c,v 1.42 2000/07/14 22:17:28 tgl Exp $
*
* NOTES
* This file contains only the public interface routines.
@@ -41,42 +41,32 @@ hashbuild(PG_FUNCTION_ARGS)
{
Relation heap = (Relation) PG_GETARG_POINTER(0);
Relation index = (Relation) PG_GETARG_POINTER(1);
- int32 natts = PG_GETARG_INT32(2);
- AttrNumber *attnum = (AttrNumber *) PG_GETARG_POINTER(3);
- FuncIndexInfo *finfo = (FuncIndexInfo *) PG_GETARG_POINTER(4);
- PredInfo *predInfo = (PredInfo *) PG_GETARG_POINTER(5);
+ IndexInfo *indexInfo = (IndexInfo *) PG_GETARG_POINTER(2);
+ Node *oldPred = (Node *) PG_GETARG_POINTER(3);
#ifdef NOT_USED
- bool unique = PG_GETARG_BOOL(6);
- IndexStrategy istrat = (IndexStrategy) PG_GETARG_POINTER(7);
+ IndexStrategy istrat = (IndexStrategy) PG_GETARG_POINTER(4);
#endif
HeapScanDesc hscan;
HeapTuple htup;
IndexTuple itup;
TupleDesc htupdesc,
itupdesc;
- Datum *attdata;
- bool *nulls;
- InsertIndexResult res;
+ Datum attdata[INDEX_MAX_KEYS];
+ char nulls[INDEX_MAX_KEYS];
int nhtups,
nitups;
- int i;
HashItem hitem;
-
+ Node *pred = indexInfo->ii_Predicate;
#ifndef OMIT_PARTIAL_INDEX
- ExprContext *econtext;
TupleTable tupleTable;
TupleTableSlot *slot;
-
#endif
- Node *pred,
- *oldPred;
+ ExprContext *econtext;
+ InsertIndexResult res = NULL;
- /* note that this is a new btree */
+ /* note that this is a new hash */
BuildingHash = true;
- pred = predInfo->pred;
- oldPred = predInfo->oldPred;
-
/* initialize the hash index metadata page (if this is a new index) */
if (oldPred == NULL)
_hash_metapinit(index);
@@ -85,17 +75,15 @@ hashbuild(PG_FUNCTION_ARGS)
htupdesc = RelationGetDescr(heap);
itupdesc = RelationGetDescr(index);
- /* get space for data items that'll appear in the index tuple */
- attdata = (Datum *) palloc(natts * sizeof(Datum));
- nulls = (bool *) palloc(natts * sizeof(bool));
-
/*
* If this is a predicate (partial) index, we will need to evaluate
* the predicate using ExecQual, which requires the current tuple to
* be in a slot of a TupleTable. In addition, ExecQual must have an
* ExprContext referring to that slot. Here, we initialize dummy
- * TupleTable and ExprContext objects for this purpose. --Nels, Feb
- * '92
+ * TupleTable and ExprContext objects for this purpose. --Nels, Feb 92
+ *
+ * We construct the ExprContext anyway since we need a per-tuple
+ * temporary memory context for function evaluation -- tgl July 00
*/
#ifndef OMIT_PARTIAL_INDEX
if (pred != NULL || oldPred != NULL)
@@ -103,14 +91,15 @@ hashbuild(PG_FUNCTION_ARGS)
tupleTable = ExecCreateTupleTable(1);
slot = ExecAllocTableSlot(tupleTable);
ExecSetSlotDescriptor(slot, htupdesc);
- econtext = MakeExprContext(slot, TransactionCommandContext);
}
else
{
tupleTable = NULL;
slot = NULL;
- econtext = NULL;
}
+ econtext = MakeExprContext(slot, TransactionCommandContext);
+#else
+ econtext = MakeExprContext(NULL, TransactionCommandContext);
#endif /* OMIT_PARTIAL_INDEX */
/* build the index */
@@ -121,6 +110,8 @@ hashbuild(PG_FUNCTION_ARGS)
while (HeapTupleIsValid(htup = heap_getnext(hscan, 0)))
{
+ MemoryContextReset(econtext->ecxt_per_tuple_memory);
+
nhtups++;
#ifndef OMIT_PARTIAL_INDEX
@@ -130,7 +121,6 @@ hashbuild(PG_FUNCTION_ARGS)
*/
if (oldPred != NULL)
{
- /* SetSlotContents(slot, htup); */
slot->val = htup;
if (ExecQual((List *) oldPred, econtext, false))
{
@@ -145,7 +135,6 @@ hashbuild(PG_FUNCTION_ARGS)
*/
if (pred != NULL)
{
- /* SetSlotContents(slot, htup); */
slot->val = htup;
if (!ExecQual((List *) pred, econtext, false))
continue;
@@ -158,33 +147,12 @@ hashbuild(PG_FUNCTION_ARGS)
* For the current heap tuple, extract all the attributes we use
* in this index, and note which are null.
*/
- for (i = 1; i <= natts; i++)
- {
- int attoff;
- bool attnull;
-
- /*
- * Offsets are from the start of the tuple, and are
- * zero-based; indices are one-based. The next call returns i
- * - 1. That's data hiding for you.
- */
-
- /* attoff = i - 1 */
- attoff = AttrNumberGetAttrOffset(i);
-
- /*
- * below, attdata[attoff] set to equal some datum & attnull is
- * changed to indicate whether or not the attribute is null
- * for this tuple
- */
- attdata[attoff] = GetIndexValue(htup,
- htupdesc,
- attoff,
- attnum,
- finfo,
- &attnull);
- nulls[attoff] = (attnull ? 'n' : ' ');
- }
+ FormIndexDatum(indexInfo,
+ htup,
+ htupdesc,
+ econtext->ecxt_per_tuple_memory,
+ attdata,
+ nulls);
/* form an index tuple and point it at the heap tuple */
itup = index_formtuple(itupdesc, attdata, nulls);
@@ -208,7 +176,9 @@ hashbuild(PG_FUNCTION_ARGS)
itup->t_tid = htup->t_self;
hitem = _hash_formitem(itup);
+
res = _hash_doinsert(index, hitem);
+
pfree(hitem);
pfree(itup);
pfree(res);
@@ -221,9 +191,9 @@ hashbuild(PG_FUNCTION_ARGS)
if (pred != NULL || oldPred != NULL)
{
ExecDropTupleTable(tupleTable, true);
- FreeExprContext(econtext);
}
#endif /* OMIT_PARTIAL_INDEX */
+ FreeExprContext(econtext);
/*
* Since we just counted the tuples in the heap, we update its stats
@@ -254,10 +224,6 @@ hashbuild(PG_FUNCTION_ARGS)
}
}
- /* be tidy */
- pfree(nulls);
- pfree(attdata);
-
/* all done */
BuildingHash = false;
diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c
index 2d1504238de..dc18b0d3b77 100644
--- a/src/backend/access/index/indexam.c
+++ b/src/backend/access/index/indexam.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.45 2000/06/13 07:34:35 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.46 2000/07/14 22:17:30 tgl Exp $
*
* INTERFACE ROUTINES
* index_open - open an index relation by relationId
@@ -424,56 +424,3 @@ index_getprocid(Relation irel,
return loc[(natts * (procnum - 1)) + (attnum - 1)];
}
-
-Datum
-GetIndexValue(HeapTuple tuple,
- TupleDesc hTupDesc,
- int attOff,
- AttrNumber *attrNums,
- FuncIndexInfo *fInfo,
- bool *attNull)
-{
- Datum returnVal;
-
- if (PointerIsValid(fInfo) && FIgetProcOid(fInfo) != InvalidOid)
- {
- FmgrInfo flinfo;
- FunctionCallInfoData fcinfo;
- int i;
- bool anynull = false;
-
- /*
- * XXX ought to store lookup info in FuncIndexInfo so it need not
- * be repeated on each call?
- */
- fmgr_info(FIgetProcOid(fInfo), &flinfo);
-
- MemSet(&fcinfo, 0, sizeof(fcinfo));
- fcinfo.flinfo = &flinfo;
- fcinfo.nargs = FIgetnArgs(fInfo);
-
- for (i = 0; i < FIgetnArgs(fInfo); i++)
- {
- fcinfo.arg[i] = heap_getattr(tuple,
- attrNums[i],
- hTupDesc,
- &fcinfo.argnull[i]);
- anynull |= fcinfo.argnull[i];
- }
- if (flinfo.fn_strict && anynull)
- {
- /* force a null result for strict function */
- returnVal = (Datum) 0;
- *attNull = true;
- }
- else
- {
- returnVal = FunctionCallInvoke(&fcinfo);
- *attNull = fcinfo.isnull;
- }
- }
- else
- returnVal = heap_getattr(tuple, attrNums[attOff], hTupDesc, attNull);
-
- return returnVal;
-}
diff --git a/src/backend/access/index/istrat.c b/src/backend/access/index/istrat.c
index fc7ac6dcb14..d6a966bcd44 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.45 2000/06/08 22:36:51 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.46 2000/07/14 22:17:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -533,6 +533,7 @@ OperatorRelationFillScanKeyEntry(Relation operatorRelation,
void
IndexSupportInitialize(IndexStrategy indexStrategy,
RegProcedure *indexSupport,
+ bool *isUnique,
Oid indexObjectId,
Oid accessMethodObjectId,
StrategyNumber maxStrategyNumber,
@@ -544,6 +545,7 @@ IndexSupportInitialize(IndexStrategy indexStrategy,
ScanKeyData entry[2];
Relation operatorRelation;
HeapTuple tuple;
+ Form_pg_index iform;
StrategyMap map;
AttrNumber attributeNumber;
int attributeIndex;
@@ -568,7 +570,12 @@ IndexSupportInitialize(IndexStrategy indexStrategy,
}
if (!HeapTupleIsValid(tuple))
- elog(ERROR, "IndexSupportInitialize: corrupted catalogs");
+ elog(ERROR, "IndexSupportInitialize: no pg_index entry for index %u",
+ indexObjectId);
+
+ iform = (Form_pg_index) GETSTRUCT(tuple);
+
+ *isUnique = iform->indisunique;
maxStrategyNumber = AMStrategies(maxStrategyNumber);
@@ -578,10 +585,6 @@ IndexSupportInitialize(IndexStrategy indexStrategy,
*/
for (attributeIndex = 0; attributeIndex < maxAttributeNumber; attributeIndex++)
{
- Form_pg_index iform;
-
- iform = (Form_pg_index) GETSTRUCT(tuple);
-
if (!OidIsValid(iform->indkey[attributeIndex]))
{
if (attributeIndex == InvalidAttrNumber)
diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c
index 3d8ea1a70a8..b174d303176 100644
--- a/src/backend/access/nbtree/nbtree.c
+++ b/src/backend/access/nbtree/nbtree.c
@@ -12,7 +12,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.60 2000/07/12 02:36:48 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.61 2000/07/14 22:17:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -45,44 +45,34 @@ btbuild(PG_FUNCTION_ARGS)
{
Relation heap = (Relation) PG_GETARG_POINTER(0);
Relation index = (Relation) PG_GETARG_POINTER(1);
- int32 natts = PG_GETARG_INT32(2);
- AttrNumber *attnum = (AttrNumber *) PG_GETARG_POINTER(3);
- FuncIndexInfo *finfo = (FuncIndexInfo *) PG_GETARG_POINTER(4);
- PredInfo *predInfo = (PredInfo *) PG_GETARG_POINTER(5);
- bool unique = PG_GETARG_BOOL(6);
+ IndexInfo *indexInfo = (IndexInfo *) PG_GETARG_POINTER(2);
+ Node *oldPred = (Node *) PG_GETARG_POINTER(3);
#ifdef NOT_USED
- IndexStrategy istrat = (IndexStrategy) PG_GETARG_POINTER(7);
+ IndexStrategy istrat = (IndexStrategy) PG_GETARG_POINTER(4);
#endif
HeapScanDesc hscan;
HeapTuple htup;
IndexTuple itup;
TupleDesc htupdesc,
itupdesc;
- Datum *attdata;
- bool *nulls;
- InsertIndexResult res = 0;
+ Datum attdata[INDEX_MAX_KEYS];
+ char nulls[INDEX_MAX_KEYS];
int nhtups,
nitups;
- int i;
- BTItem btitem;
-
+ Node *pred = indexInfo->ii_Predicate;
#ifndef OMIT_PARTIAL_INDEX
- ExprContext *econtext = (ExprContext *) NULL;
- TupleTable tupleTable = (TupleTable) NULL;
- TupleTableSlot *slot = (TupleTableSlot *) NULL;
-
+ TupleTable tupleTable;
+ TupleTableSlot *slot;
#endif
- Node *pred,
- *oldPred;
+ ExprContext *econtext;
+ InsertIndexResult res = NULL;
BTSpool *spool = NULL;
+ BTItem btitem;
bool usefast;
/* note that this is a new btree */
BuildingBtree = true;
- pred = predInfo->pred;
- oldPred = predInfo->oldPred;
-
/*
* bootstrap processing does something strange, so don't use
* sort/build for initial catalog indices. at some point i need to
@@ -104,17 +94,15 @@ btbuild(PG_FUNCTION_ARGS)
htupdesc = RelationGetDescr(heap);
itupdesc = RelationGetDescr(index);
- /* get space for data items that'll appear in the index tuple */
- attdata = (Datum *) palloc(natts * sizeof(Datum));
- nulls = (bool *) palloc(natts * sizeof(bool));
-
/*
* If this is a predicate (partial) index, we will need to evaluate
* the predicate using ExecQual, which requires the current tuple to
* be in a slot of a TupleTable. In addition, ExecQual must have an
* ExprContext referring to that slot. Here, we initialize dummy
- * TupleTable and ExprContext objects for this purpose. --Nels, Feb
- * '92
+ * TupleTable and ExprContext objects for this purpose. --Nels, Feb 92
+ *
+ * We construct the ExprContext anyway since we need a per-tuple
+ * temporary memory context for function evaluation -- tgl July 00
*/
#ifndef OMIT_PARTIAL_INDEX
if (pred != NULL || oldPred != NULL)
@@ -122,7 +110,6 @@ btbuild(PG_FUNCTION_ARGS)
tupleTable = ExecCreateTupleTable(1);
slot = ExecAllocTableSlot(tupleTable);
ExecSetSlotDescriptor(slot, htupdesc);
- econtext = MakeExprContext(slot, TransactionCommandContext);
/*
* we never want to use sort/build if we are extending an existing
@@ -133,22 +120,29 @@ btbuild(PG_FUNCTION_ARGS)
*/
usefast = false;
}
+ else
+ {
+ tupleTable = NULL;
+ slot = NULL;
+ }
+ econtext = MakeExprContext(slot, TransactionCommandContext);
+#else
+ econtext = MakeExprContext(NULL, TransactionCommandContext);
#endif /* OMIT_PARTIAL_INDEX */
- /* start a heap scan */
/* build the index */
nhtups = nitups = 0;
if (usefast)
- {
- spool = _bt_spoolinit(index, unique);
- res = (InsertIndexResult) NULL;
- }
+ spool = _bt_spoolinit(index, indexInfo->ii_Unique);
+ /* start a heap scan */
hscan = heap_beginscan(heap, 0, SnapshotNow, 0, (ScanKey) NULL);
while (HeapTupleIsValid(htup = heap_getnext(hscan, 0)))
{
+ MemoryContextReset(econtext->ecxt_per_tuple_memory);
+
nhtups++;
#ifndef OMIT_PARTIAL_INDEX
@@ -158,7 +152,6 @@ btbuild(PG_FUNCTION_ARGS)
*/
if (oldPred != NULL)
{
- /* SetSlotContents(slot, htup); */
slot->val = htup;
if (ExecQual((List *) oldPred, econtext, false))
{
@@ -173,7 +166,6 @@ btbuild(PG_FUNCTION_ARGS)
*/
if (pred != NULL)
{
- /* SetSlotContents(slot, htup); */
slot->val = htup;
if (!ExecQual((List *) pred, econtext, false))
continue;
@@ -186,27 +178,12 @@ btbuild(PG_FUNCTION_ARGS)
* For the current heap tuple, extract all the attributes we use
* in this index, and note which are null.
*/
-
- for (i = 1; i <= natts; i++)
- {
- int attoff;
- bool attnull;
-
- /*
- * Offsets are from the start of the tuple, and are
- * zero-based; indices are one-based. The next call returns i
- * - 1. That's data hiding for you.
- */
-
- attoff = AttrNumberGetAttrOffset(i);
- attdata[attoff] = GetIndexValue(htup,
- htupdesc,
- attoff,
- attnum,
- finfo,
- &attnull);
- nulls[attoff] = (attnull ? 'n' : ' ');
- }
+ FormIndexDatum(indexInfo,
+ htup,
+ htupdesc,
+ econtext->ecxt_per_tuple_memory,
+ attdata,
+ nulls);
/* form an index tuple and point it at the heap tuple */
itup = index_formtuple(itupdesc, attdata, nulls);
@@ -246,7 +223,7 @@ btbuild(PG_FUNCTION_ARGS)
if (usefast)
_bt_spool(btitem, spool);
else
- res = _bt_doinsert(index, btitem, unique, heap);
+ res = _bt_doinsert(index, btitem, indexInfo->ii_Unique, heap);
pfree(btitem);
pfree(itup);
@@ -261,9 +238,9 @@ btbuild(PG_FUNCTION_ARGS)
if (pred != NULL || oldPred != NULL)
{
ExecDropTupleTable(tupleTable, true);
- FreeExprContext(econtext);
}
#endif /* OMIT_PARTIAL_INDEX */
+ FreeExprContext(econtext);
/*
* if we are doing bottom-up btree build, finish the build by (1)
@@ -305,10 +282,6 @@ btbuild(PG_FUNCTION_ARGS)
heap_close(heap, NoLock);
index_close(index);
- /*
- * UpdateStats(hrelid, nhtups, true); UpdateStats(irelid, nitups,
- * false);
- */
UpdateStats(hrelid, nhtups, inplace);
UpdateStats(irelid, nitups, inplace);
if (oldPred != NULL)
@@ -320,9 +293,6 @@ btbuild(PG_FUNCTION_ARGS)
}
}
- pfree(nulls);
- pfree(attdata);
-
/* all done */
BuildingBtree = false;
@@ -361,8 +331,7 @@ btinsert(PG_FUNCTION_ARGS)
btitem = _bt_formitem(itup);
- res = _bt_doinsert(rel, btitem,
- IndexIsUnique(RelationGetRelid(rel)), heapRel);
+ res = _bt_doinsert(rel, btitem, rel->rd_uniqueindex, heapRel);
pfree(btitem);
pfree(itup);
diff --git a/src/backend/access/rtree/rtree.c b/src/backend/access/rtree/rtree.c
index badff1ee21b..583baa534a3 100644
--- a/src/backend/access/rtree/rtree.c
+++ b/src/backend/access/rtree/rtree.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.51 2000/07/12 02:36:52 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.52 2000/07/14 22:17:36 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -64,49 +64,37 @@ rtbuild(PG_FUNCTION_ARGS)
{
Relation heap = (Relation) PG_GETARG_POINTER(0);
Relation index = (Relation) PG_GETARG_POINTER(1);
- int32 natts = PG_GETARG_INT32(2);
- AttrNumber *attnum = (AttrNumber *) PG_GETARG_POINTER(3);
- FuncIndexInfo *finfo = (FuncIndexInfo *) PG_GETARG_POINTER(4);
- PredInfo *predInfo = (PredInfo *) PG_GETARG_POINTER(5);
+ IndexInfo *indexInfo = (IndexInfo *) PG_GETARG_POINTER(2);
+ Node *oldPred = (Node *) PG_GETARG_POINTER(3);
#ifdef NOT_USED
- bool unique = PG_GETARG_BOOL(6);
- IndexStrategy istrat = (IndexStrategy) PG_GETARG_POINTER(7);
+ IndexStrategy istrat = (IndexStrategy) PG_GETARG_POINTER(4);
#endif
- HeapScanDesc scan;
- AttrNumber i;
+ HeapScanDesc hscan;
HeapTuple htup;
IndexTuple itup;
- TupleDesc hd,
- id;
- InsertIndexResult res;
- Datum *d;
- bool *nulls;
- Buffer buffer = InvalidBuffer;
- int nb,
- nh,
- ni;
-
+ TupleDesc htupdesc,
+ itupdesc;
+ Datum attdata[INDEX_MAX_KEYS];
+ char nulls[INDEX_MAX_KEYS];
+ int nhtups,
+ nitups;
+ Node *pred = indexInfo->ii_Predicate;
#ifndef OMIT_PARTIAL_INDEX
- ExprContext *econtext;
TupleTable tupleTable;
TupleTableSlot *slot;
-
#endif
- Node *pred,
- *oldPred;
+ ExprContext *econtext;
+ InsertIndexResult res = NULL;
+ Buffer buffer = InvalidBuffer;
RTSTATE rtState;
initRtstate(&rtState, index);
- pred = predInfo->pred;
- oldPred = predInfo->oldPred;
-
/*
* We expect to be called exactly once for any index relation. If
* that's not the case, big trouble's what we have.
*/
-
- if (oldPred == NULL && (nb = RelationGetNumberOfBlocks(index)) != 0)
+ if (oldPred == NULL && RelationGetNumberOfBlocks(index) != 0)
elog(ERROR, "%s already contains data", RelationGetRelationName(index));
/* initialize the root page (if this is a new index) */
@@ -117,44 +105,48 @@ rtbuild(PG_FUNCTION_ARGS)
WriteBuffer(buffer);
}
- /* init the tuple descriptors and get set for a heap scan */
- hd = RelationGetDescr(heap);
- id = RelationGetDescr(index);
- d = (Datum *) palloc(natts * sizeof(*d));
- nulls = (bool *) palloc(natts * sizeof(*nulls));
+ /* get tuple descriptors for heap and index relations */
+ htupdesc = RelationGetDescr(heap);
+ itupdesc = RelationGetDescr(index);
/*
* If this is a predicate (partial) index, we will need to evaluate
* the predicate using ExecQual, which requires the current tuple to
* be in a slot of a TupleTable. In addition, ExecQual must have an
* ExprContext referring to that slot. Here, we initialize dummy
- * TupleTable and ExprContext objects for this purpose. --Nels, Feb
- * '92
+ * TupleTable and ExprContext objects for this purpose. --Nels, Feb 92
+ *
+ * We construct the ExprContext anyway since we need a per-tuple
+ * temporary memory context for function evaluation -- tgl July 00
*/
#ifndef OMIT_PARTIAL_INDEX
if (pred != NULL || oldPred != NULL)
{
tupleTable = ExecCreateTupleTable(1);
slot = ExecAllocTableSlot(tupleTable);
- ExecSetSlotDescriptor(slot, hd);
- econtext = MakeExprContext(slot, TransactionCommandContext);
+ ExecSetSlotDescriptor(slot, htupdesc);
}
else
{
tupleTable = NULL;
slot = NULL;
- econtext = NULL;
}
+ econtext = MakeExprContext(slot, TransactionCommandContext);
+#else
+ econtext = MakeExprContext(NULL, TransactionCommandContext);
#endif /* OMIT_PARTIAL_INDEX */
/* count the tuples as we insert them */
- nh = ni = 0;
+ nhtups = nitups = 0;
- scan = heap_beginscan(heap, 0, SnapshotNow, 0, (ScanKey) NULL);
+ /* start a heap scan */
+ hscan = heap_beginscan(heap, 0, SnapshotNow, 0, (ScanKey) NULL);
- while (HeapTupleIsValid(htup = heap_getnext(scan, 0)))
+ while (HeapTupleIsValid(htup = heap_getnext(hscan, 0)))
{
- nh++;
+ MemoryContextReset(econtext->ecxt_per_tuple_memory);
+
+ nhtups++;
#ifndef OMIT_PARTIAL_INDEX
/*
@@ -163,11 +155,10 @@ rtbuild(PG_FUNCTION_ARGS)
*/
if (oldPred != NULL)
{
- /* SetSlotContents(slot, htup); */
slot->val = htup;
if (ExecQual((List *) oldPred, econtext, false))
{
- ni++;
+ nitups++;
continue;
}
}
@@ -178,47 +169,27 @@ rtbuild(PG_FUNCTION_ARGS)
*/
if (pred != NULL)
{
- /* SetSlotContents(slot, htup); */
slot->val = htup;
if (!ExecQual((List *) pred, econtext, false))
continue;
}
#endif /* OMIT_PARTIAL_INDEX */
- ni++;
+ nitups++;
/*
* For the current heap tuple, extract all the attributes we use
* in this index, and note which are null.
*/
-
- for (i = 1; i <= natts; i++)
- {
- int attoff;
- bool attnull;
-
- /*
- * Offsets are from the start of the tuple, and are
- * zero-based; indices are one-based. The next call returns i
- * - 1. That's data hiding for you.
- */
-
- attoff = AttrNumberGetAttrOffset(i);
-
- /*
- * d[attoff] = HeapTupleGetAttributeValue(htup, buffer,
- */
- d[attoff] = GetIndexValue(htup,
- hd,
- attoff,
- attnum,
- finfo,
- &attnull);
- nulls[attoff] = (attnull ? 'n' : ' ');
- }
+ FormIndexDatum(indexInfo,
+ htup,
+ htupdesc,
+ econtext->ecxt_per_tuple_memory,
+ attdata,
+ nulls);
/* form an index tuple and point it at the heap tuple */
- itup = index_formtuple(id, &d[0], nulls);
+ itup = index_formtuple(itupdesc, attdata, nulls);
itup->t_tid = htup->t_self;
/*
@@ -235,15 +206,15 @@ rtbuild(PG_FUNCTION_ARGS)
}
/* okay, all heap tuples are indexed */
- heap_endscan(scan);
+ heap_endscan(hscan);
#ifndef OMIT_PARTIAL_INDEX
if (pred != NULL || oldPred != NULL)
{
ExecDropTupleTable(tupleTable, true);
- FreeExprContext(econtext);
}
#endif /* OMIT_PARTIAL_INDEX */
+ FreeExprContext(econtext);
/*
* Since we just counted the tuples in the heap, we update its stats
@@ -264,20 +235,16 @@ rtbuild(PG_FUNCTION_ARGS)
heap_close(heap, NoLock);
index_close(index);
- UpdateStats(hrelid, nh, inplace);
- UpdateStats(irelid, ni, inplace);
+ UpdateStats(hrelid, nhtups, inplace);
+ UpdateStats(irelid, nitups, inplace);
if (oldPred != NULL && !inplace)
{
- if (ni == nh)
+ if (nitups == nhtups)
pred = NULL;
UpdateIndexPredicate(irelid, oldPred, pred);
}
}
- /* be tidy */
- pfree(nulls);
- pfree(d);
-
PG_RETURN_VOID();
}
diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y
index 4c13aafc0eb..cf3cd1b280b 100644
--- a/src/backend/bootstrap/bootparse.y
+++ b/src/backend/bootstrap/bootparse.y
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.31 2000/07/04 06:11:22 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.32 2000/07/14 22:17:38 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,7 +20,6 @@
#include "access/attnum.h"
-#include "access/funcindex.h"
#include "access/htup.h"
#include "access/itup.h"
#include "access/skey.h"
diff --git a/src/backend/bootstrap/bootscanner.l b/src/backend/bootstrap/bootscanner.l
index 125ea516f17..ed68c92ac28 100644
--- a/src/backend/bootstrap/bootscanner.l
+++ b/src/backend/bootstrap/bootscanner.l
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootscanner.l,v 1.17 2000/01/26 05:56:07 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootscanner.l,v 1.18 2000/07/14 22:17:38 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -18,7 +18,6 @@
#include "postgres.h"
#include "access/attnum.h"
-#include "access/funcindex.h"
#include "access/htup.h"
#include "access/itup.h"
#include "access/skey.h"
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index 1c52d098a1a..c3cf9371724 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.90 2000/07/03 23:09:23 wieck Exp $
+ * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.91 2000/07/14 22:17:38 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -160,20 +160,12 @@ typedef struct _IndexList
{
char *il_heap;
char *il_ind;
- int il_natts;
- AttrNumber *il_attnos;
- FuncIndexInfo *il_finfo;
- PredInfo *il_predInfo;
- bool il_unique;
+ IndexInfo *il_info;
struct _IndexList *il_next;
} IndexList;
static IndexList *ILHead = (IndexList *) NULL;
-typedef void (*sig_func) ();
-
-
-
/* ----------------------------------------------------------------
* misc functions
@@ -334,9 +326,9 @@ BootstrapMain(int argc, char *argv[])
if (!IsUnderPostmaster)
{
- pqsignal(SIGINT, (sig_func) die);
- pqsignal(SIGHUP, (sig_func) die);
- pqsignal(SIGTERM, (sig_func) die);
+ pqsignal(SIGINT, (pqsigfunc) die);
+ pqsignal(SIGHUP, (pqsigfunc) die);
+ pqsignal(SIGTERM, (pqsigfunc) die);
}
/*
@@ -1080,14 +1072,9 @@ AddStr(char *str, int strlength, int mderef)
void
index_register(char *heap,
char *ind,
- int natts,
- AttrNumber *attnos,
- FuncIndexInfo *finfo,
- PredInfo *predInfo,
- bool unique)
+ IndexInfo *indexInfo)
{
IndexList *newind;
- int len;
MemoryContext oldcxt;
/*
@@ -1108,37 +1095,13 @@ index_register(char *heap,
newind = (IndexList *) palloc(sizeof(IndexList));
newind->il_heap = pstrdup(heap);
newind->il_ind = pstrdup(ind);
- newind->il_natts = natts;
-
- if (PointerIsValid(finfo))
- len = FIgetnArgs(finfo) * sizeof(AttrNumber);
- else
- len = natts * sizeof(AttrNumber);
-
- newind->il_attnos = (AttrNumber *) palloc(len);
- memcpy(newind->il_attnos, attnos, len);
-
- if (PointerIsValid(finfo))
- {
- newind->il_finfo = (FuncIndexInfo *) palloc(sizeof(FuncIndexInfo));
- memcpy(newind->il_finfo, finfo, sizeof(FuncIndexInfo));
- }
- else
- newind->il_finfo = (FuncIndexInfo *) NULL;
+ newind->il_info = (IndexInfo *) palloc(sizeof(IndexInfo));
- if (predInfo != NULL)
- {
- newind->il_predInfo = (PredInfo *) palloc(sizeof(PredInfo));
- newind->il_predInfo->pred = predInfo->pred;
- newind->il_predInfo->oldPred = predInfo->oldPred;
- }
- else
- newind->il_predInfo = NULL;
-
- newind->il_unique = unique;
+ memcpy(newind->il_info, indexInfo, sizeof(IndexInfo));
+ /* predicate will likely be null anyway, but may as well copy it */
+ newind->il_info->ii_Predicate = copyObject(indexInfo->ii_Predicate);
newind->il_next = ILHead;
-
ILHead = newind;
MemoryContextSwitchTo(oldcxt);
@@ -1147,18 +1110,16 @@ index_register(char *heap,
void
build_indices()
{
- Relation heap;
- Relation ind;
-
for (; ILHead != (IndexList *) NULL; ILHead = ILHead->il_next)
{
+ Relation heap;
+ Relation ind;
+
heap = heap_openr(ILHead->il_heap, NoLock);
Assert(heap);
ind = index_openr(ILHead->il_ind);
Assert(ind);
- index_build(heap, ind, ILHead->il_natts, ILHead->il_attnos,
- ILHead->il_finfo, ILHead->il_predInfo,
- ILHead->il_unique);
+ index_build(heap, ind, ILHead->il_info, NULL);
/*
* In normal processing mode, index_build would close the heap and
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 08b5e64c53d..b5334de15ed 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.139 2000/07/05 23:11:06 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.140 2000/07/14 22:17:40 tgl Exp $
*
*
* INTERFACE ROUTINES
@@ -1073,91 +1073,37 @@ RelationTruncateIndexes(Relation heapRelation)
ScanKeyData entry;
HeapScanDesc scan;
HeapTuple indexTuple,
- procTuple,
classTuple;
- Form_pg_index index;
+ IndexInfo *indexInfo;
Oid heapId,
indexId,
- procId,
accessMethodId;
- Node *oldPred = NULL;
- PredInfo *predInfo;
- List *cnfPred = NULL;
- AttrNumber *attributeNumberA;
- FuncIndexInfo fInfo,
- *funcInfo = NULL;
- bool unique;
- int i,
- numberOfAttributes;
- char *predString;
heapId = RelationGetRelid(heapRelation);
/* Scan pg_index to find indexes on heapRelation */
-
indexRelation = heap_openr(IndexRelationName, AccessShareLock);
ScanKeyEntryInitialize(&entry, 0, Anum_pg_index_indrelid, F_OIDEQ,
ObjectIdGetDatum(heapId));
scan = heap_beginscan(indexRelation, false, SnapshotNow, 1, &entry);
while (HeapTupleIsValid(indexTuple = heap_getnext(scan, 0)))
{
-
/*
- * For each index, fetch index attributes so we can apply
- * index_build
+ * For each index, fetch info needed for index_build
*/
- index = (Form_pg_index) GETSTRUCT(indexTuple);
- indexId = index->indexrelid;
- procId = index->indproc;
- unique = index->indisunique;
-
- for (i = 0; i < INDEX_MAX_KEYS; i++)
- {
- if (index->indkey[i] == InvalidAttrNumber)
- break;
- }
- numberOfAttributes = i;
-
- /* If a valid where predicate, compute predicate Node */
- if (VARSIZE(&index->indpred) != 0)
- {
- predString = DatumGetCString(DirectFunctionCall1(textout,
- PointerGetDatum(&index->indpred)));
- oldPred = stringToNode(predString);
- pfree(predString);
- }
- predInfo = (PredInfo *) palloc(sizeof(PredInfo));
- predInfo->pred = (Node *) cnfPred;
- predInfo->oldPred = oldPred;
-
- /* Assign Index keys to attributes array */
- attributeNumberA = (AttrNumber *) palloc(numberOfAttributes *
- sizeof(AttrNumber));
- for (i = 0; i < numberOfAttributes; i++)
- attributeNumberA[i] = index->indkey[i];
-
- /* If this is a procedural index, initialize our FuncIndexInfo */
- if (procId != InvalidOid)
- {
- funcInfo = &fInfo;
- FIsetnArgs(funcInfo, numberOfAttributes);
- procTuple = SearchSysCacheTuple(PROCOID, ObjectIdGetDatum(procId),
- 0, 0, 0);
- if (!HeapTupleIsValid(procTuple))
- elog(ERROR, "RelationTruncateIndexes: index procedure not found");
- namecpy(&(funcInfo->funcName),
- &(((Form_pg_proc) GETSTRUCT(procTuple))->proname));
- FIsetProcOid(funcInfo, procTuple->t_data->t_oid);
- }
+ indexId = ((Form_pg_index) GETSTRUCT(indexTuple))->indexrelid;
+ indexInfo = BuildIndexInfo(indexTuple);
- /* Fetch the classTuple associated with this index */
- classTuple = SearchSysCacheTupleCopy(RELOID, ObjectIdGetDatum(indexId),
+ /* Fetch the pg_class tuple associated with this index */
+ classTuple = SearchSysCacheTupleCopy(RELOID,
+ ObjectIdGetDatum(indexId),
0, 0, 0);
if (!HeapTupleIsValid(classTuple))
- elog(ERROR, "RelationTruncateIndexes: index access method not found");
+ elog(ERROR, "RelationTruncateIndexes: index %u not found in pg_class",
+ indexId);
accessMethodId = ((Form_pg_class) GETSTRUCT(classTuple))->relam;
- /* Open our index relation */
+ /* Open the index relation */
currentIndex = index_open(indexId);
if (currentIndex == NULL)
elog(ERROR, "RelationTruncateIndexes: can't open index relation");
@@ -1176,9 +1122,9 @@ RelationTruncateIndexes(Relation heapRelation)
currentIndex->rd_nblocks = 0;
/* Initialize the index and rebuild */
- InitIndexStrategy(numberOfAttributes, currentIndex, accessMethodId);
- index_build(heapRelation, currentIndex, numberOfAttributes,
- attributeNumberA, funcInfo, predInfo, unique);
+ InitIndexStrategy(indexInfo->ii_NumIndexAttrs,
+ currentIndex, accessMethodId);
+ index_build(heapRelation, currentIndex, indexInfo, NULL);
/*
* index_build will close both the heap and index relations (but
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 41d747b0dbf..2cbcb91ac06 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -8,13 +8,14 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.125 2000/07/12 02:36:55 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.126 2000/07/14 22:17:41 tgl Exp $
*
*
* INTERFACE ROUTINES
* index_create() - Create a cataloged index relation
* index_drop() - Removes index relation from catalogs
- *
+ * BuildIndexInfo() - Prepare to insert index tuples
+ * FormIndexDatum() - Construct datum vector for one index tuple
*
*-------------------------------------------------------------------------
*/
@@ -58,28 +59,29 @@
/* non-export function prototypes */
static Oid GetHeapRelationOid(char *heapRelationName, char *indexRelationName,
bool istemp);
-static TupleDesc BuildFuncTupleDesc(FuncIndexInfo *funcInfo);
+static TupleDesc BuildFuncTupleDesc(Oid funcOid);
static TupleDesc ConstructTupleDescriptor(Oid heapoid, Relation heapRelation,
- List *attributeList, int numatts, AttrNumber *attNums);
-
+ int numatts, AttrNumber *attNums);
static void ConstructIndexReldesc(Relation indexRelation, Oid amoid);
static Oid UpdateRelationRelation(Relation indexRelation, char *temp_relname);
static void InitializeAttributeOids(Relation indexRelation,
int numatts, Oid indexoid);
static void AppendAttributeTuples(Relation indexRelation, int numatts);
static void UpdateIndexRelation(Oid indexoid, Oid heapoid,
- FuncIndexInfo *funcInfo, int natts,
- AttrNumber *attNums, Oid *classOids, Node *predicate,
- List *attributeList, bool islossy, bool unique, bool primary);
+ IndexInfo *indexInfo,
+ Oid *classOids,
+ bool islossy, bool primary);
static void DefaultBuild(Relation heapRelation, Relation indexRelation,
- int numberOfAttributes, AttrNumber *attributeNumber,
- FuncIndexInfoPtr funcInfo, PredInfo *predInfo,
- bool unique, IndexStrategy indexStrategy);
+ IndexInfo *indexInfo, Node *oldPred,
+ IndexStrategy indexStrategy);
static Oid IndexGetRelation(Oid indexId);
static bool activate_index(Oid indexId, bool activate);
+
static bool reindexing = false;
-extern bool
+
+
+bool
SetReindexProcessing(bool reindexmode)
{
bool old = reindexing;
@@ -87,7 +89,8 @@ SetReindexProcessing(bool reindexmode)
reindexing = reindexmode;
return old;
}
-extern bool
+
+bool
IsReindexProcessing(void)
{
return reindexing;
@@ -154,14 +157,11 @@ GetHeapRelationOid(char *heapRelationName, char *indexRelationName, bool istemp)
}
static TupleDesc
-BuildFuncTupleDesc(FuncIndexInfo *funcInfo)
+BuildFuncTupleDesc(Oid funcOid)
{
- HeapTuple tuple;
TupleDesc funcTupDesc;
+ HeapTuple tuple;
Oid retType;
- char *funcname;
- int4 nargs;
- Oid *argtypes;
/*
* Allocate and zero a tuple descriptor.
@@ -171,30 +171,29 @@ BuildFuncTupleDesc(FuncIndexInfo *funcInfo)
MemSet(funcTupDesc->attrs[0], 0, ATTRIBUTE_TUPLE_SIZE);
/*
- * Lookup the function for the return type.
+ * Lookup the function to get its name and return type.
*/
- funcname = FIgetname(funcInfo);
- nargs = FIgetnArgs(funcInfo);
- argtypes = FIgetArglist(funcInfo);
- tuple = SearchSysCacheTuple(PROCNAME,
- PointerGetDatum(funcname),
- Int32GetDatum(nargs),
- PointerGetDatum(argtypes),
- 0);
-
+ tuple = SearchSysCacheTuple(PROCOID,
+ ObjectIdGetDatum(funcOid),
+ 0, 0, 0);
if (!HeapTupleIsValid(tuple))
- func_error("BuildFuncTupleDesc", funcname, nargs, argtypes, NULL);
-
+ elog(ERROR, "Function %u does not exist", funcOid);
retType = ((Form_pg_proc) GETSTRUCT(tuple))->prorettype;
/*
- * Look up the return type in pg_type for the type length.
+ * make the attributes name the same as the functions
+ */
+ namestrcpy(&funcTupDesc->attrs[0]->attname,
+ NameStr(((Form_pg_proc) GETSTRUCT(tuple))->proname));
+
+ /*
+ * Lookup the return type in pg_type for the type length etc.
*/
tuple = SearchSysCacheTuple(TYPEOID,
ObjectIdGetDatum(retType),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
- elog(ERROR, "Function %s return type does not exist", FIgetname(funcInfo));
+ elog(ERROR, "Type %u does not exist", retType);
/*
* Assign some of the attributes values. Leave the rest as 0.
@@ -208,57 +207,48 @@ BuildFuncTupleDesc(FuncIndexInfo *funcInfo)
funcTupDesc->attrs[0]->attstorage = 'p';
funcTupDesc->attrs[0]->attalign = ((Form_pg_type) GETSTRUCT(tuple))->typalign;
- /*
- * make the attributes name the same as the functions
- */
- namestrcpy(&funcTupDesc->attrs[0]->attname, funcname);
-
return funcTupDesc;
}
/* ----------------------------------------------------------------
* ConstructTupleDescriptor
+ *
+ * Build an index tuple descriptor for a new index (plain not functional)
* ----------------------------------------------------------------
*/
static TupleDesc
ConstructTupleDescriptor(Oid heapoid,
Relation heapRelation,
- List *attributeList,
int numatts,
AttrNumber *attNums)
{
TupleDesc heapTupDesc;
TupleDesc indexTupDesc;
- IndexElem *IndexKey;
- TypeName *IndexKeyType;
- AttrNumber atnum; /* attributeNumber[attributeOffset] */
- AttrNumber atind;
- int natts; /* Form_pg_class->relnatts */
- char *from; /* used to simplify memcpy below */
- char *to; /* used to simplify memcpy below */
+ int natts; /* #atts in heap rel --- for error checks */
int i;
+ heapTupDesc = RelationGetDescr(heapRelation);
+ natts = RelationGetForm(heapRelation)->relnatts;
+
/* ----------------
* allocate the new tuple descriptor
* ----------------
*/
- natts = RelationGetForm(heapRelation)->relnatts;
indexTupDesc = CreateTemplateTupleDesc(numatts);
/* ----------------
- *
- * ----------------
- */
-
- /* ----------------
* for each attribute we are indexing, obtain its attribute
* tuple form from either the static table of system attribute
* tuple forms or the relation tuple descriptor
* ----------------
*/
- for (i = 0; i < numatts; i += 1)
+ for (i = 0; i < numatts; i++)
{
+ AttrNumber atnum; /* attributeNumber[attributeOffset] */
+ AttrNumber atind;
+ char *from; /* used to simplify memcpy below */
+ char *to; /* used to simplify memcpy below */
/* ----------------
* get the attribute number and make sure it's valid
@@ -268,16 +258,9 @@ ConstructTupleDescriptor(Oid heapoid,
if (atnum > natts)
elog(ERROR, "Cannot create index: attribute %d does not exist",
atnum);
- if (attributeList)
- {
- IndexKey = (IndexElem *) lfirst(attributeList);
- IndexKeyType = IndexKey->typename;
- attributeList = lnext(attributeList);
- }
- else
- IndexKeyType = NULL;
- indexTupDesc->attrs[i] = (Form_pg_attribute) palloc(ATTRIBUTE_TUPLE_SIZE);
+ indexTupDesc->attrs[i] =
+ (Form_pg_attribute) palloc(ATTRIBUTE_TUPLE_SIZE);
/* ----------------
* determine which tuple descriptor to copy
@@ -285,10 +268,9 @@ ConstructTupleDescriptor(Oid heapoid,
*/
if (!AttrNumberIsForUserDefinedAttr(atnum))
{
-
/* ----------------
- * here we are indexing on a system attribute (-1...-12)
- * so we convert atnum into a usable index 0...11 so we can
+ * here we are indexing on a system attribute (-1...-n)
+ * so we convert atnum into a usable index 0...n-1 so we can
* use it to dereference the array sysatts[] which stores
* tuple descriptor information for system attributes.
* ----------------
@@ -298,7 +280,6 @@ ConstructTupleDescriptor(Oid heapoid,
atind = (-atnum) - 1;
from = (char *) (&sysatts[atind]);
-
}
else
{
@@ -306,7 +287,6 @@ ConstructTupleDescriptor(Oid heapoid,
* here we are indexing on a normal attribute (1...n)
* ----------------
*/
- heapTupDesc = RelationGetDescr(heapRelation);
atind = AttrNumberGetAttrOffset(atnum);
from = (char *) (heapTupDesc->attrs[atind]);
@@ -317,43 +297,18 @@ ConstructTupleDescriptor(Oid heapoid,
* the tuple desc data...
* ----------------
*/
-
to = (char *) (indexTupDesc->attrs[i]);
memcpy(to, from, ATTRIBUTE_TUPLE_SIZE);
+ /*
+ * Fix the stuff that should not be the same as the underlying attr
+ */
((Form_pg_attribute) to)->attnum = i + 1;
+ ((Form_pg_attribute) to)->attdisbursion = 0.0;
((Form_pg_attribute) to)->attnotnull = false;
((Form_pg_attribute) to)->atthasdef = false;
((Form_pg_attribute) to)->attcacheoff = -1;
- ((Form_pg_attribute) to)->atttypmod = -1;
- ((Form_pg_attribute) to)->attalign = 'i';
-
- /*
- * if the keytype is defined, we need to change the tuple form's
- * atttypid & attlen field to match that of the key's type
- */
- if (IndexKeyType != NULL)
- {
- HeapTuple tup;
-
- tup = SearchSysCacheTuple(TYPENAME,
- PointerGetDatum(IndexKeyType->name),
- 0, 0, 0);
- if (!HeapTupleIsValid(tup))
- elog(ERROR, "create index: type '%s' undefined",
- IndexKeyType->name);
- ((Form_pg_attribute) to)->atttypid = tup->t_data->t_oid;
- ((Form_pg_attribute) to)->attbyval =
- ((Form_pg_type) GETSTRUCT(tup))->typbyval;
- ((Form_pg_attribute) to)->attlen =
- ((Form_pg_type) GETSTRUCT(tup))->typlen;
- ((Form_pg_attribute) to)->attstorage = 'p';
- ((Form_pg_attribute) to)->attalign =
- ((Form_pg_type) GETSTRUCT(tup))->typalign;
- ((Form_pg_attribute) to)->atttypmod = IndexKeyType->typmod;
- }
-
/* ----------------
* now we have to drop in the proper relation descriptor
@@ -539,17 +494,14 @@ AppendAttributeTuples(Relation indexRelation, int numatts)
new_tuple;
bool hasind;
Relation idescs[Num_pg_attr_indices];
-
Datum value[Natts_pg_attribute];
char nullv[Natts_pg_attribute];
char replace[Natts_pg_attribute];
-
TupleDesc indexTupDesc;
int i;
/* ----------------
* open the attribute relation
- * XXX ADD INDEXING
* ----------------
*/
pg_attribute = heap_openr(AttributeRelationName, RowExclusiveLock);
@@ -641,7 +593,6 @@ AppendAttributeTuples(Relation indexRelation, int numatts)
heap_close(pg_attribute, RowExclusiveLock);
if (hasind)
CatalogCloseIndices(Num_pg_attr_indices, idescs);
-
}
/* ----------------------------------------------------------------
@@ -651,18 +602,12 @@ AppendAttributeTuples(Relation indexRelation, int numatts)
static void
UpdateIndexRelation(Oid indexoid,
Oid heapoid,
- FuncIndexInfo *funcInfo,
- int natts,
- AttrNumber *attNums,
+ IndexInfo *indexInfo,
Oid *classOids,
- Node *predicate,
- List *attributeList,
bool islossy,
- bool unique,
bool primary)
{
Form_pg_index indexForm;
- IndexElem *IndexKey;
char *predString;
text *predText;
int predLen,
@@ -673,13 +618,13 @@ UpdateIndexRelation(Oid indexoid,
Relation idescs[Num_pg_index_indices];
/* ----------------
- * allocate an Form_pg_index big enough to hold the
+ * allocate a Form_pg_index big enough to hold the
* index-predicate (if any) in string form
* ----------------
*/
- if (predicate != NULL)
+ if (indexInfo->ii_Predicate != NULL)
{
- predString = nodeToString(predicate);
+ predString = nodeToString(indexInfo->ii_Predicate);
predText = DatumGetTextP(DirectFunctionCall1(textin,
CStringGetDatum(predString)));
pfree(predString);
@@ -691,57 +636,33 @@ UpdateIndexRelation(Oid indexoid,
predLen = VARSIZE(predText);
itupLen = predLen + sizeof(FormData_pg_index);
indexForm = (Form_pg_index) palloc(itupLen);
- memset(indexForm, 0, sizeof(FormData_pg_index));
-
- memmove((char *) &indexForm->indpred, (char *) predText, predLen);
+ MemSet(indexForm, 0, sizeof(FormData_pg_index));
/* ----------------
- * store the oid information into the index tuple form
+ * store information into the index tuple form
* ----------------
*/
- indexForm->indrelid = heapoid;
indexForm->indexrelid = indexoid;
- indexForm->indproc = (PointerIsValid(funcInfo)) ?
- FIgetProcOid(funcInfo) : InvalidOid;
+ indexForm->indrelid = heapoid;
+ indexForm->indproc = indexInfo->ii_FuncOid;
+ indexForm->indisclustered = false;
indexForm->indislossy = islossy;
+ indexForm->indhaskeytype = true; /* not actually used anymore */
+ indexForm->indisunique = indexInfo->ii_Unique;
indexForm->indisprimary = primary;
- indexForm->indisunique = unique;
-
- indexForm->indhaskeytype = 0;
- while (attributeList != NIL)
- {
- IndexKey = (IndexElem *) lfirst(attributeList);
- if (IndexKey->typename != NULL)
- {
- indexForm->indhaskeytype = 1;
- break;
- }
- attributeList = lnext(attributeList);
- }
-
- MemSet((char *) &indexForm->indkey[0], 0, sizeof indexForm->indkey);
- MemSet((char *) &indexForm->indclass[0], 0, sizeof indexForm->indclass);
+ memcpy((char *) &indexForm->indpred, (char *) predText, predLen);
/* ----------------
* copy index key and op class information
+ *
+ * We zeroed the extra slots (if any) above --- that's essential.
* ----------------
*/
- for (i = 0; i < natts; i += 1)
- {
- indexForm->indkey[i] = attNums[i];
- indexForm->indclass[i] = classOids[i];
- }
-
- /*
- * If we have a functional index, add all attribute arguments
- */
- if (PointerIsValid(funcInfo))
- {
- for (i = 1; i < FIgetnArgs(funcInfo); i++)
- indexForm->indkey[i] = attNums[i];
- }
+ for (i = 0; i < indexInfo->ii_NumKeyAttrs; i++)
+ indexForm->indkey[i] = indexInfo->ii_KeyAttrNumbers[i];
- indexForm->indisclustered = '\0'; /* XXX constant */
+ for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
+ indexForm->indclass[i] = classOids[i];
/* ----------------
* open the system catalog index relation
@@ -759,13 +680,12 @@ UpdateIndexRelation(Oid indexoid,
/* ----------------
* insert the tuple into the pg_index
- * XXX ADD INDEX TUPLES TOO
* ----------------
*/
heap_insert(pg_index, tuple);
/* ----------------
- * insert the index tuple into the pg_index
+ * add index tuples for it
* ----------------
*/
if (!IsIgnoringSystemIndexes())
@@ -774,6 +694,7 @@ UpdateIndexRelation(Oid indexoid,
CatalogIndexInsert(idescs, Num_pg_index_indices, pg_index, tuple);
CatalogCloseIndices(Num_pg_index_indices, idescs);
}
+
/* ----------------
* close the relation and free the tuple
* ----------------
@@ -923,6 +844,7 @@ InitIndexStrategy(int numatts,
CommandCounterIncrement();
IndexSupportInitialize(strategy, support,
+ &indexRelation->rd_uniqueindex,
attrelid, accessMethodObjectId,
amstrategies, amsupport, numatts);
@@ -941,15 +863,10 @@ InitIndexStrategy(int numatts,
void
index_create(char *heapRelationName,
char *indexRelationName,
- FuncIndexInfo *funcInfo,
- List *attributeList,
+ IndexInfo *indexInfo,
Oid accessMethodObjectId,
- int numatts,
- AttrNumber *attNums,
Oid *classObjectId,
- Node *predicate,
bool islossy,
- bool unique,
bool primary,
bool allow_system_table_mods)
{
@@ -958,16 +875,17 @@ index_create(char *heapRelationName,
TupleDesc indexTupDesc;
Oid heapoid;
Oid indexoid;
- PredInfo *predInfo;
bool istemp = (get_temp_rel_by_username(heapRelationName) != NULL);
char *temp_relname = NULL;
+ SetReindexProcessing(false);
+
/* ----------------
* check parameters
* ----------------
*/
- SetReindexProcessing(false);
- if (numatts < 1)
+ if (indexInfo->ii_NumIndexAttrs < 1 ||
+ indexInfo->ii_NumKeyAttrs < 1)
elog(ERROR, "must index at least one attribute");
/* ----------------
@@ -985,14 +903,13 @@ index_create(char *heapRelationName,
* construct new tuple descriptor
* ----------------
*/
- if (PointerIsValid(funcInfo))
- indexTupDesc = BuildFuncTupleDesc(funcInfo);
+ if (OidIsValid(indexInfo->ii_FuncOid))
+ indexTupDesc = BuildFuncTupleDesc(indexInfo->ii_FuncOid);
else
indexTupDesc = ConstructTupleDescriptor(heapoid,
heapRelation,
- attributeList,
- numatts,
- attNums);
+ indexInfo->ii_NumKeyAttrs,
+ indexInfo->ii_KeyAttrNumbers);
if (istemp)
{
@@ -1035,13 +952,15 @@ index_create(char *heapRelationName,
* tuple forms in the index relation's tuple descriptor
* ----------------
*/
- InitializeAttributeOids(indexRelation, numatts, indexoid);
+ InitializeAttributeOids(indexRelation,
+ indexInfo->ii_NumIndexAttrs,
+ indexoid);
/* ----------------
- * append ATTRIBUTE tuples
+ * append ATTRIBUTE tuples for the index
* ----------------
*/
- AppendAttributeTuples(indexRelation, numatts);
+ AppendAttributeTuples(indexRelation, indexInfo->ii_NumIndexAttrs);
/* ----------------
* update pg_index
@@ -1051,19 +970,16 @@ index_create(char *heapRelationName,
* (Or, could define a rule to maintain the predicate) --Nels, Feb '92
* ----------------
*/
- UpdateIndexRelation(indexoid, heapoid, funcInfo,
- numatts, attNums, classObjectId, predicate,
- attributeList, islossy, unique, primary);
-
- predInfo = (PredInfo *) palloc(sizeof(PredInfo));
- predInfo->pred = predicate;
- predInfo->oldPred = NULL;
+ UpdateIndexRelation(indexoid, heapoid, indexInfo,
+ classObjectId, islossy, primary);
/* ----------------
* initialize the index strategy
* ----------------
*/
- InitIndexStrategy(numatts, indexRelation, accessMethodObjectId);
+ InitIndexStrategy(indexInfo->ii_NumIndexAttrs,
+ indexRelation,
+ accessMethodObjectId);
/*
* If this is bootstrap (initdb) time, then we don't actually fill in
@@ -1078,14 +994,12 @@ index_create(char *heapRelationName,
*/
if (IsBootstrapProcessingMode())
{
- index_register(heapRelationName, indexRelationName, numatts, attNums,
- funcInfo, predInfo, unique);
+ index_register(heapRelationName, indexRelationName, indexInfo);
/* XXX shouldn't we close the heap and index rels here? */
}
else
{
- index_build(heapRelation, indexRelation, numatts, attNums,
- funcInfo, predInfo, unique);
+ index_build(heapRelation, indexRelation, indexInfo, NULL);
}
}
@@ -1238,43 +1152,163 @@ index_drop(Oid indexId)
* index_build support
* ----------------------------------------------------------------
*/
+
+/* ----------------
+ * BuildIndexInfo
+ * Construct an IndexInfo record given the index's pg_index tuple
+ *
+ * IndexInfo stores the information about the index that's needed by
+ * FormIndexDatum, which is used for both index_build() and later insertion
+ * of individual index tuples. Normally we build an IndexInfo for an index
+ * just once per command, and then use it for (potentially) many tuples.
+ * ----------------
+ */
+IndexInfo *
+BuildIndexInfo(HeapTuple indexTuple)
+{
+ Form_pg_index indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
+ IndexInfo *ii = makeNode(IndexInfo);
+ int i;
+ int numKeys;
+
+ /* ----------------
+ * count the number of keys, and copy them into the IndexInfo
+ * ----------------
+ */
+ numKeys = 0;
+ for (i = 0; i < INDEX_MAX_KEYS &&
+ indexStruct->indkey[i] != InvalidAttrNumber; i++)
+ {
+ ii->ii_KeyAttrNumbers[i] = indexStruct->indkey[i];
+ numKeys++;
+ }
+ ii->ii_NumKeyAttrs = numKeys;
+
+ /* ----------------
+ * Handle functional index.
+ *
+ * If we have a functional index then the number of
+ * attributes defined in the index must be 1 (the function's
+ * single return value). Otherwise it's same as number of keys.
+ * ----------------
+ */
+ ii->ii_FuncOid = indexStruct->indproc;
+
+ if (OidIsValid(indexStruct->indproc))
+ {
+ ii->ii_NumIndexAttrs = 1;
+ /* Do a lookup on the function, too */
+ fmgr_info(indexStruct->indproc, & ii->ii_FuncInfo);
+ }
+ else
+ ii->ii_NumIndexAttrs = numKeys;
+
+ /* ----------------
+ * If partial index, convert predicate into expression nodetree
+ * ----------------
+ */
+ if (VARSIZE(&indexStruct->indpred) != 0)
+ {
+ char *predString;
+
+ predString = DatumGetCString(DirectFunctionCall1(textout,
+ PointerGetDatum(&indexStruct->indpred)));
+ ii->ii_Predicate = stringToNode(predString);
+ pfree(predString);
+ }
+ else
+ ii->ii_Predicate = NULL;
+
+ /* Other info */
+ ii->ii_Unique = indexStruct->indisunique;
+
+ return ii;
+}
+
/* ----------------
* FormIndexDatum
+ * Construct Datum[] and nullv[] arrays for a new index tuple.
+ *
+ * indexInfo Info about the index
+ * heapTuple Heap tuple for which we must prepare an index entry
+ * heapDescriptor tupledesc for heap tuple
+ * resultCxt Temporary memory context for any palloc'd datums created
+ * datum Array of index Datums (output area)
+ * nullv Array of is-null indicators (output area)
+ *
+ * For largely historical reasons, we don't actually call index_formtuple()
+ * here, we just prepare its input arrays datum[] and nullv[].
* ----------------
*/
void
-FormIndexDatum(int numberOfAttributes,
- AttrNumber *attributeNumber,
+FormIndexDatum(IndexInfo *indexInfo,
HeapTuple heapTuple,
TupleDesc heapDescriptor,
+ MemoryContext resultCxt,
Datum *datum,
- char *nullv,
- FuncIndexInfoPtr fInfo)
+ char *nullv)
{
- AttrNumber i;
- int offset;
+ MemoryContext oldContext;
+ int i;
+ Datum iDatum;
bool isNull;
- /* ----------------
- * for each attribute we need from the heap tuple,
- * get the attribute and stick it into the datum and
- * null arrays.
- * ----------------
- */
+ oldContext = MemoryContextSwitchTo(resultCxt);
- for (i = 1; i <= numberOfAttributes; i++)
+ if (OidIsValid(indexInfo->ii_FuncOid))
{
- offset = AttrNumberGetAttrOffset(i);
+ /* ----------------
+ * Functional index --- compute the single index attribute
+ * ----------------
+ */
+ FunctionCallInfoData fcinfo;
+ bool anynull = false;
- datum[offset] = PointerGetDatum(GetIndexValue(heapTuple,
- heapDescriptor,
- offset,
- attributeNumber,
- fInfo,
- &isNull));
+ MemSet(&fcinfo, 0, sizeof(fcinfo));
+ fcinfo.flinfo = &indexInfo->ii_FuncInfo;
+ fcinfo.nargs = indexInfo->ii_NumKeyAttrs;
- nullv[offset] = (isNull) ? 'n' : ' ';
+ for (i = 0; i < indexInfo->ii_NumKeyAttrs; i++)
+ {
+ fcinfo.arg[i] = heap_getattr(heapTuple,
+ indexInfo->ii_KeyAttrNumbers[i],
+ heapDescriptor,
+ &fcinfo.argnull[i]);
+ anynull |= fcinfo.argnull[i];
+ }
+ if (indexInfo->ii_FuncInfo.fn_strict && anynull)
+ {
+ /* force a null result for strict function */
+ iDatum = (Datum) 0;
+ isNull = true;
+ }
+ else
+ {
+ iDatum = FunctionCallInvoke(&fcinfo);
+ isNull = fcinfo.isnull;
+ }
+ datum[0] = iDatum;
+ nullv[0] = (isNull) ? 'n' : ' ';
+ }
+ else
+ {
+ /* ----------------
+ * Plain index --- for each attribute we need from the heap tuple,
+ * get the attribute and stick it into the datum and nullv arrays.
+ * ----------------
+ */
+ for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
+ {
+ iDatum = heap_getattr(heapTuple,
+ indexInfo->ii_KeyAttrNumbers[i],
+ heapDescriptor,
+ &isNull);
+ datum[i] = iDatum;
+ nullv[i] = (isNull) ? 'n' : ' ';
+ }
}
+
+ MemoryContextSwitchTo(oldContext);
}
@@ -1282,9 +1316,9 @@ FormIndexDatum(int numberOfAttributes,
* Lock class info for update
* --------------------------------------------
*/
-static
-bool
-LockClassinfoForUpdate(Oid relid, HeapTuple rtup, Buffer *buffer, bool confirmCommitted)
+static bool
+LockClassinfoForUpdate(Oid relid, HeapTuple rtup,
+ Buffer *buffer, bool confirmCommitted)
{
HeapTuple classTuple;
Form_pg_class pgcform;
@@ -1429,7 +1463,7 @@ setRelhasindexInplace(Oid relid, bool hasindex, bool immediate)
/*
* Confirm that target tuple is locked by this transaction in case of
- * immedaite updation.
+ * immediate updation.
*/
if (immediate)
{
@@ -1682,32 +1716,23 @@ UpdateStats(Oid relid, long reltuples, bool inplace)
static void
DefaultBuild(Relation heapRelation,
Relation indexRelation,
- int numberOfAttributes,
- AttrNumber *attributeNumber,
- FuncIndexInfoPtr funcInfo,
- PredInfo *predInfo,
- bool unique, /* not used */
+ IndexInfo *indexInfo,
+ Node *oldPred,
IndexStrategy indexStrategy) /* not used */
{
HeapScanDesc scan;
HeapTuple heapTuple;
- IndexTuple indexTuple;
TupleDesc heapDescriptor;
- TupleDesc indexDescriptor;
- Datum *datum;
- char *nullv;
+ Datum datum[INDEX_MAX_KEYS];
+ char nullv[INDEX_MAX_KEYS];
long reltuples,
indtuples;
-
+ Node *predicate = indexInfo->ii_Predicate;
#ifndef OMIT_PARTIAL_INDEX
- ExprContext *econtext;
TupleTable tupleTable;
TupleTableSlot *slot;
-
#endif
- Node *predicate;
- Node *oldPred;
-
+ ExprContext *econtext;
InsertIndexResult insertResult;
/* ----------------
@@ -1716,48 +1741,33 @@ DefaultBuild(Relation heapRelation,
*/
Assert(OidIsValid(indexRelation->rd_rel->relam)); /* XXX */
- /* ----------------
- * get the tuple descriptors from the relations so we know
- * how to form the index tuples..
- * ----------------
- */
heapDescriptor = RelationGetDescr(heapRelation);
- indexDescriptor = RelationGetDescr(indexRelation);
-
- /* ----------------
- * datum and null are arrays in which we collect the index attributes
- * when forming a new index tuple.
- * ----------------
- */
- datum = (Datum *) palloc(numberOfAttributes * sizeof *datum);
- nullv = (char *) palloc(numberOfAttributes * sizeof *nullv);
/*
* If this is a predicate (partial) index, we will need to evaluate
* the predicate using ExecQual, which requires the current tuple to
* be in a slot of a TupleTable. In addition, ExecQual must have an
* ExprContext referring to that slot. Here, we initialize dummy
- * TupleTable and ExprContext objects for this purpose. --Nels, Feb
- * '92
+ * TupleTable and ExprContext objects for this purpose. --Nels, Feb 92
+ *
+ * We construct the ExprContext anyway since we need a per-tuple
+ * temporary memory context for function evaluation -- tgl July 00
*/
-
- predicate = predInfo->pred;
- oldPred = predInfo->oldPred;
-
#ifndef OMIT_PARTIAL_INDEX
if (predicate != NULL || oldPred != NULL)
{
tupleTable = ExecCreateTupleTable(1);
slot = ExecAllocTableSlot(tupleTable);
ExecSetSlotDescriptor(slot, heapDescriptor);
- econtext = MakeExprContext(slot, TransactionCommandContext);
}
else
{
tupleTable = NULL;
slot = NULL;
- econtext = NULL;
}
+ econtext = MakeExprContext(slot, TransactionCommandContext);
+#else
+ econtext = MakeExprContext(NULL, TransactionCommandContext);
#endif /* OMIT_PARTIAL_INDEX */
/* ----------------
@@ -1781,6 +1791,8 @@ DefaultBuild(Relation heapRelation,
*/
while (HeapTupleIsValid(heapTuple = heap_getnext(scan, 0)))
{
+ MemoryContextReset(econtext->ecxt_per_tuple_memory);
+
reltuples++;
#ifndef OMIT_PARTIAL_INDEX
@@ -1790,7 +1802,6 @@ DefaultBuild(Relation heapRelation,
*/
if (oldPred != NULL)
{
- /* SetSlotContents(slot, heapTuple); */
slot->val = heapTuple;
if (ExecQual((List *) oldPred, econtext, false))
{
@@ -1805,7 +1816,6 @@ DefaultBuild(Relation heapRelation,
*/
if (predicate != NULL)
{
- /* SetSlotContents(slot, heapTuple); */
slot->val = heapTuple;
if (!ExecQual((List *) predicate, econtext, false))
continue;
@@ -1819,26 +1829,18 @@ DefaultBuild(Relation heapRelation,
* with attribute information taken from the given heap tuple.
* ----------------
*/
- FormIndexDatum(numberOfAttributes, /* num attributes */
- attributeNumber, /* array of att nums to extract */
- heapTuple, /* tuple from base relation */
- heapDescriptor, /* heap tuple's descriptor */
- datum, /* return: array of attributes */
- nullv, /* return: array of char's */
- funcInfo);
-
- indexTuple = index_formtuple(indexDescriptor,
- datum,
- nullv);
-
- indexTuple->t_tid = heapTuple->t_self;
+ FormIndexDatum(indexInfo,
+ heapTuple,
+ heapDescriptor,
+ econtext->ecxt_per_tuple_memory,
+ datum,
+ nullv);
insertResult = index_insert(indexRelation, datum, nullv,
&(heapTuple->t_self), heapRelation);
if (insertResult)
pfree(insertResult);
- pfree(indexTuple);
}
heap_endscan(scan);
@@ -1846,14 +1848,10 @@ DefaultBuild(Relation heapRelation,
#ifndef OMIT_PARTIAL_INDEX
if (predicate != NULL || oldPred != NULL)
{
- /* parameter was 'false', almost certainly wrong --- tgl 9/21/99 */
ExecDropTupleTable(tupleTable, true);
- FreeExprContext(econtext);
}
#endif /* OMIT_PARTIAL_INDEX */
-
- pfree(nullv);
- pfree(datum);
+ FreeExprContext(econtext);
/*
* Since we just counted the tuples in the heap, we update its stats
@@ -1893,11 +1891,8 @@ DefaultBuild(Relation heapRelation,
void
index_build(Relation heapRelation,
Relation indexRelation,
- int numberOfAttributes,
- AttrNumber *attributeNumber,
- FuncIndexInfo *funcInfo,
- PredInfo *predInfo,
- bool unique)
+ IndexInfo *indexInfo,
+ Node *oldPred)
{
RegProcedure procedure;
@@ -1915,23 +1910,17 @@ index_build(Relation heapRelation,
* ----------------
*/
if (RegProcedureIsValid(procedure))
- OidFunctionCall8(procedure,
+ OidFunctionCall5(procedure,
PointerGetDatum(heapRelation),
PointerGetDatum(indexRelation),
- Int32GetDatum(numberOfAttributes),
- PointerGetDatum(attributeNumber),
- PointerGetDatum(funcInfo),
- PointerGetDatum(predInfo),
- BoolGetDatum(unique),
+ PointerGetDatum(indexInfo),
+ PointerGetDatum(oldPred),
PointerGetDatum(RelationGetIndexStrategy(indexRelation)));
else
DefaultBuild(heapRelation,
indexRelation,
- numberOfAttributes,
- attributeNumber,
- funcInfo,
- predInfo,
- unique,
+ indexInfo,
+ oldPred,
RelationGetIndexStrategy(indexRelation));
}
@@ -1959,34 +1948,9 @@ IndexGetRelation(Oid indexId)
return index->indrelid;
}
-/*
- * IndexIsUnique: given an index's relation OID, see if it
- * is unique using the system cache.
- */
-bool
-IndexIsUnique(Oid indexId)
-{
- HeapTuple tuple;
- Form_pg_index index;
-
- tuple = SearchSysCacheTuple(INDEXRELID,
- ObjectIdGetDatum(indexId),
- 0, 0, 0);
- if (!HeapTupleIsValid(tuple))
- {
- elog(ERROR, "IndexIsUnique: can't find index id %u",
- indexId);
- }
- index = (Form_pg_index) GETSTRUCT(tuple);
- Assert(index->indexrelid == indexId);
-
- return index->indisunique;
-}
-
-
/* ---------------------------------
* activate_index -- activate/deactivate the specified index.
- * Note that currelntly PostgreSQL doesn't hold the
+ * Note that currently PostgreSQL doesn't hold the
* status per index
* ---------------------------------
*/
@@ -2011,92 +1975,47 @@ reindex_index(Oid indexId, bool force)
ScanKeyData entry;
HeapScanDesc scan;
HeapTuple indexTuple,
- procTuple,
classTuple;
- Form_pg_index index;
+ IndexInfo *indexInfo;
Oid heapId,
- procId,
accessMethodId;
- Node *oldPred = NULL;
- PredInfo *predInfo;
- AttrNumber *attributeNumberA;
- FuncIndexInfo fInfo,
- *funcInfo = NULL;
- int i,
- numberOfAttributes;
- bool unique;
- char *predString;
bool old;
old = SetReindexProcessing(true);
- /* Scan pg_index to find indexes on heapRelation */
+
+ /* Scan pg_index to find the index's pg_index entry */
indexRelation = heap_openr(IndexRelationName, AccessShareLock);
ScanKeyEntryInitialize(&entry, 0, Anum_pg_index_indexrelid, F_OIDEQ,
ObjectIdGetDatum(indexId));
scan = heap_beginscan(indexRelation, false, SnapshotNow, 1, &entry);
indexTuple = heap_getnext(scan, 0);
if (!HeapTupleIsValid(indexTuple))
- elog(ERROR, "reindex_index index %d tuple is invalid", indexId);
-
- /*
- * For the index, fetch index attributes so we can apply index_build
- */
- index = (Form_pg_index) GETSTRUCT(indexTuple);
- heapId = index->indrelid;
- procId = index->indproc;
- unique = index->indisunique;
-
- for (i = 0; i < INDEX_MAX_KEYS; i++)
- {
- if (index->indkey[i] == InvalidAttrNumber)
- break;
- }
- numberOfAttributes = i;
+ elog(ERROR, "reindex_index: index %u not found in pg_index", indexId);
- /* If a valid where predicate, compute predicate Node */
- if (VARSIZE(&index->indpred) != 0)
- {
- predString = DatumGetCString(DirectFunctionCall1(textout,
- PointerGetDatum(&index->indpred)));
- oldPred = stringToNode(predString);
- pfree(predString);
- }
- predInfo = (PredInfo *) palloc(sizeof(PredInfo));
- predInfo->pred = (Node *) oldPred;
- predInfo->oldPred = NULL;
+ /* Get OID of index's parent table */
+ heapId = ((Form_pg_index) GETSTRUCT(indexTuple))->indrelid;
+ /* Fetch info needed for index_build */
+ indexInfo = BuildIndexInfo(indexTuple);
- /* Assign Index keys to attributes array */
- attributeNumberA = (AttrNumber *) palloc(numberOfAttributes * sizeof(AttrNumber));
- for (i = 0; i < numberOfAttributes; i++)
- attributeNumberA[i] = index->indkey[i];
-
- /* If this is a procedural index, initialize our FuncIndexInfo */
- if (procId != InvalidOid)
- {
- funcInfo = &fInfo;
- FIsetnArgs(funcInfo, numberOfAttributes);
- procTuple = SearchSysCacheTuple(PROCOID, ObjectIdGetDatum(procId),
- 0, 0, 0);
- if (!HeapTupleIsValid(procTuple))
- elog(ERROR, "RelationTruncateIndexes: index procedure not found");
- namecpy(&(funcInfo->funcName),
- &(((Form_pg_proc) GETSTRUCT(procTuple))->proname));
- FIsetProcOid(funcInfo, procTuple->t_data->t_oid);
- }
+ /* Complete the scan and close pg_index */
+ heap_endscan(scan);
+ heap_close(indexRelation, AccessShareLock);
/* Fetch the classTuple associated with this index */
- classTuple = SearchSysCacheTupleCopy(RELOID, ObjectIdGetDatum(indexId), 0, 0, 0);
+ classTuple = SearchSysCacheTuple(RELOID,
+ ObjectIdGetDatum(indexId),
+ 0, 0, 0);
if (!HeapTupleIsValid(classTuple))
- elog(ERROR, "RelationTruncateIndexes: index access method not found");
+ elog(ERROR, "reindex_index: index %u not found in pg_class", indexId);
accessMethodId = ((Form_pg_class) GETSTRUCT(classTuple))->relam;
/* Open our index relation */
- iRel = index_open(indexId);
- if (iRel == NULL)
- elog(ERROR, "reindex_index: can't open index relation");
heapRelation = heap_open(heapId, ExclusiveLock);
if (heapRelation == NULL)
elog(ERROR, "reindex_index: can't open heap relation");
+ iRel = index_open(indexId);
+ if (iRel == NULL)
+ elog(ERROR, "reindex_index: can't open index relation");
/* Obtain exclusive lock on it, just to be sure */
LockRelation(iRel, AccessExclusiveLock);
@@ -2112,23 +2031,16 @@ reindex_index(Oid indexId, bool force)
iRel->rd_nblocks = 0;
/* Initialize the index and rebuild */
- InitIndexStrategy(numberOfAttributes, iRel, accessMethodId);
- index_build(heapRelation, iRel, numberOfAttributes,
- attributeNumberA, funcInfo, predInfo, unique);
+ InitIndexStrategy(indexInfo->ii_NumIndexAttrs, iRel, accessMethodId);
+ index_build(heapRelation, iRel, indexInfo, NULL);
/*
* index_build will close both the heap and index relations (but not
- * give up the locks we hold on them). That's fine for the index, but
- * we need to open the heap again. We need no new lock, since this
- * backend still has the exclusive lock grabbed by heap_truncate.
+ * give up the locks we hold on them). So we're done.
*/
- iRel = index_open(indexId);
- Assert(iRel != NULL);
- /* Complete the scan and close pg_index */
- heap_endscan(scan);
- heap_close(indexRelation, AccessShareLock);
SetReindexProcessing(old);
+
return true;
}
diff --git a/src/backend/catalog/indexing.c b/src/backend/catalog/indexing.c
index deb016e4a04..c2980f6fefc 100644
--- a/src/backend/catalog/indexing.c
+++ b/src/backend/catalog/indexing.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.66 2000/06/17 04:56:39 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.67 2000/07/14 22:17:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -83,9 +83,9 @@ static HeapTuple CatalogIndexFetchTuple(Relation heapRelation,
/*
- * Changes (appends) to catalogs can (and does) happen at various places
+ * Changes (appends) to catalogs can and do happen at various places
* throughout the code. We need a generic routine that will open all of
- * the indices defined on a given catalog a return the relation descriptors
+ * the indices defined on a given catalog and return the relation descriptors
* associated with them.
*/
void
@@ -115,9 +115,20 @@ CatalogCloseIndices(int nIndices, Relation *idescs)
/*
- * For the same reasons outlined above CatalogOpenIndices() we need a routine
- * that takes a new catalog tuple and inserts an associated index tuple into
- * each catalog index.
+ * For the same reasons outlined above for CatalogOpenIndices(), we need a
+ * routine that takes a new catalog tuple and inserts an associated index
+ * tuple into each catalog index.
+ *
+ * NOTE: since this routine looks up all the pg_index data on each call,
+ * it's relatively inefficient for inserting a large number of tuples into
+ * the same catalog. We use it only for inserting one or a few tuples
+ * in a given command. See ExecOpenIndices() and related routines if you
+ * are inserting tuples in bulk.
+ *
+ * NOTE: we do not bother to handle partial indices. Nor do we try to
+ * be efficient for functional indices (the code should work for them,
+ * but may leak memory intraquery). This should be OK for system catalogs,
+ * but don't use this routine for user tables!
*/
void
CatalogIndexInsert(Relation *idescs,
@@ -125,15 +136,9 @@ CatalogIndexInsert(Relation *idescs,
Relation heapRelation,
HeapTuple heapTuple)
{
- HeapTuple index_tup;
TupleDesc heapDescriptor;
- Form_pg_index index_form;
Datum datum[INDEX_MAX_KEYS];
- char nulls[INDEX_MAX_KEYS];
- int natts;
- AttrNumber *attnumP;
- FuncIndexInfo finfo,
- *finfoP;
+ char nullv[INDEX_MAX_KEYS];
int i;
if (IsIgnoringSystemIndexes())
@@ -142,51 +147,30 @@ CatalogIndexInsert(Relation *idescs,
for (i = 0; i < nIndices; i++)
{
+ HeapTuple index_tup;
+ IndexInfo *indexInfo;
InsertIndexResult indexRes;
- index_tup = SearchSysCacheTupleCopy(INDEXRELID,
- ObjectIdGetDatum(idescs[i]->rd_id),
- 0, 0, 0);
- Assert(index_tup);
- index_form = (Form_pg_index) GETSTRUCT(index_tup);
-
- if (index_form->indproc != InvalidOid)
- {
- int fatts;
-
- /*
- * Compute the number of attributes we are indexing upon.
- */
- for (attnumP = index_form->indkey, fatts = 0;
- fatts < INDEX_MAX_KEYS && *attnumP != InvalidAttrNumber;
- attnumP++, fatts++)
- ;
- FIgetnArgs(&finfo) = fatts;
- natts = 1;
- FIgetProcOid(&finfo) = index_form->indproc;
- *(FIgetname(&finfo)) = '\0';
- finfoP = &finfo;
- }
- else
- {
- natts = RelationGetDescr(idescs[i])->natts;
- finfoP = (FuncIndexInfo *) NULL;
- }
+ index_tup = SearchSysCacheTuple(INDEXRELID,
+ ObjectIdGetDatum(idescs[i]->rd_id),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(index_tup))
+ elog(ERROR, "CatalogIndexInsert: index %u not found",
+ idescs[i]->rd_id);
+ indexInfo = BuildIndexInfo(index_tup);
- FormIndexDatum(natts,
- (AttrNumber *) index_form->indkey,
+ FormIndexDatum(indexInfo,
heapTuple,
heapDescriptor,
+ CurrentMemoryContext,
datum,
- nulls,
- finfoP);
+ nullv);
- indexRes = index_insert(idescs[i], datum, nulls,
+ indexRes = index_insert(idescs[i], datum, nullv,
&heapTuple->t_self, heapRelation);
if (indexRes)
pfree(indexRes);
-
- heap_freetuple(index_tup);
+ pfree(indexInfo);
}
}
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index 38539707cd8..5c176254d66 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -15,7 +15,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.57 2000/07/04 06:11:27 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.58 2000/07/14 22:17:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -198,35 +198,31 @@ copy_index(Oid OIDOldIndex, Oid OIDNewHeap)
Relation OldIndex,
NewHeap;
HeapTuple Old_pg_index_Tuple,
- Old_pg_index_relation_Tuple,
- pg_proc_Tuple;
+ Old_pg_index_relation_Tuple;
Form_pg_index Old_pg_index_Form;
Form_pg_class Old_pg_index_relation_Form;
- Form_pg_proc pg_proc_Form;
+ IndexInfo *indexInfo;
char *NewIndexName;
- AttrNumber *attnumP;
- int natts;
- FuncIndexInfo *finfo;
NewHeap = heap_open(OIDNewHeap, AccessExclusiveLock);
OldIndex = index_open(OIDOldIndex);
/*
* OK. Create a new (temporary) index for the one that's already here.
- * To do this I get the info from pg_index, re-build the FunctInfo if
- * I have to, and add a new index with a temporary name.
+ * To do this I get the info from pg_index, and add a new index with
+ * a temporary name.
*/
- Old_pg_index_Tuple = SearchSysCacheTuple(INDEXRELID,
+ Old_pg_index_Tuple = SearchSysCacheTupleCopy(INDEXRELID,
ObjectIdGetDatum(RelationGetRelid(OldIndex)),
- 0, 0, 0);
-
+ 0, 0, 0);
Assert(Old_pg_index_Tuple);
Old_pg_index_Form = (Form_pg_index) GETSTRUCT(Old_pg_index_Tuple);
- Old_pg_index_relation_Tuple = SearchSysCacheTuple(RELOID,
- ObjectIdGetDatum(RelationGetRelid(OldIndex)),
- 0, 0, 0);
+ indexInfo = BuildIndexInfo(Old_pg_index_Tuple);
+ Old_pg_index_relation_Tuple = SearchSysCacheTupleCopy(RELOID,
+ ObjectIdGetDatum(RelationGetRelid(OldIndex)),
+ 0, 0, 0);
Assert(Old_pg_index_relation_Tuple);
Old_pg_index_relation_Form = (Form_pg_class) GETSTRUCT(Old_pg_index_relation_Tuple);
@@ -234,50 +230,12 @@ copy_index(Oid OIDOldIndex, Oid OIDNewHeap)
NewIndexName = palloc(NAMEDATALEN); /* XXX */
snprintf(NewIndexName, NAMEDATALEN, "temp_%x", OIDOldIndex);
- /*
- * Ugly as it is, the only way I have of working out the number of
- * attribues is to count them. Mostly there'll be just one but I've
- * got to be sure.
- */
- for (attnumP = &(Old_pg_index_Form->indkey[0]), natts = 0;
- natts < INDEX_MAX_KEYS && *attnumP != InvalidAttrNumber;
- attnumP++, natts++);
-
- /*
- * If this is a functional index, I need to rebuild the functional
- * component to pass it to the defining procedure.
- */
- if (Old_pg_index_Form->indproc != InvalidOid)
- {
- finfo = (FuncIndexInfo *) palloc(sizeof(FuncIndexInfo));
- FIgetnArgs(finfo) = natts;
- FIgetProcOid(finfo) = Old_pg_index_Form->indproc;
-
- pg_proc_Tuple = SearchSysCacheTuple(PROCOID,
- ObjectIdGetDatum(Old_pg_index_Form->indproc),
- 0, 0, 0);
-
- Assert(pg_proc_Tuple);
- pg_proc_Form = (Form_pg_proc) GETSTRUCT(pg_proc_Tuple);
- namecpy(&(finfo->funcName), &(pg_proc_Form->proname));
- natts = 1; /* function result is a single column */
- }
- else
- {
- finfo = (FuncIndexInfo *) NULL;
- }
-
index_create(RelationGetRelationName(NewHeap),
NewIndexName,
- finfo,
- NULL, /* type info is in the old index */
+ indexInfo,
Old_pg_index_relation_Form->relam,
- natts,
- Old_pg_index_Form->indkey,
Old_pg_index_Form->indclass,
- (Node *) NULL, /* XXX where's the predicate? */
Old_pg_index_Form->indislossy,
- Old_pg_index_Form->indisunique,
Old_pg_index_Form->indisprimary,
allowSystemTableMods);
diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c
index 6648e66f4e3..be24c696a7c 100644
--- a/src/backend/commands/command.c
+++ b/src/backend/commands/command.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.88 2000/07/05 23:11:09 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.89 2000/07/14 22:17:42 tgl Exp $
*
* NOTES
* The PerformAddAttribute() code, like most of the relation
@@ -1205,7 +1205,7 @@ AlterTableCreateToastTable(const char *relationName, bool silent)
char toast_relname[NAMEDATALEN + 1];
char toast_idxname[NAMEDATALEN + 1];
Relation toast_rel;
- AttrNumber attNums[1];
+ IndexInfo *indexInfo;
Oid classObjectId[1];
/*
@@ -1334,11 +1334,20 @@ AlterTableCreateToastTable(const char *relationName, bool silent)
CommandCounterIncrement();
/* create index on chunk_id */
- attNums[0] = 1;
+
+ indexInfo = makeNode(IndexInfo);
+ indexInfo->ii_NumIndexAttrs = 1;
+ indexInfo->ii_NumKeyAttrs = 1;
+ indexInfo->ii_KeyAttrNumbers[0] = 1;
+ indexInfo->ii_Predicate = NULL;
+ indexInfo->ii_FuncOid = InvalidOid;
+ indexInfo->ii_Unique = false;
+
classObjectId[0] = OID_OPS_OID;
- index_create(toast_relname, toast_idxname, NULL, NULL, BTREE_AM_OID,
- 1, attNums, classObjectId,
- (Node *) NULL, false, false, false, true);
+
+ index_create(toast_relname, toast_idxname, indexInfo,
+ BTREE_AM_OID, classObjectId,
+ false, false, true);
/* make the index visible in this transaction */
CommandCounterIncrement();
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index 355b218e640..52100e92dd9 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.118 2000/07/12 02:36:58 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.119 2000/07/14 22:17:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -50,10 +50,6 @@ static Oid GetOutputFunction(Oid type);
static Oid GetTypeElement(Oid type);
static Oid GetInputFunction(Oid type);
static Oid IsTypeByVal(Oid type);
-static void GetIndexRelations(Oid main_relation_oid,
- int *n_indices,
- Relation **index_rels);
-
static void CopyReadNewline(FILE *fp, int *newline);
static char *CopyReadAttribute(FILE *fp, bool *isnull, char *delim, int *newline, char *null_print);
@@ -576,53 +572,35 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p
}
static void
-CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_print)
+CopyFrom(Relation rel, bool binary, bool oids, FILE *fp,
+ char *delim, char *null_print)
{
HeapTuple tuple;
- AttrNumber attr_count;
+ TupleDesc tupDesc;
Form_pg_attribute *attr;
+ AttrNumber attr_count;
FmgrInfo *in_functions;
+ Oid *elements;
+ int32 *typmod;
int i;
Oid in_func_oid;
Datum *values;
- char *nulls,
- *index_nulls;
+ char *nulls;
bool *byval;
bool isnull;
- bool has_index;
int done = 0;
char *string = NULL,
*ptr;
- Relation *index_rels;
int32 len,
null_ct,
null_id;
int32 ntuples,
tuples_read = 0;
bool reading_to_eof = true;
- Oid *elements;
- int32 *typmod;
- FuncIndexInfo *finfo,
- **finfoP = NULL;
- TupleDesc *itupdescArr;
- HeapTuple pgIndexTup;
- Form_pg_index *pgIndexP = NULL;
- int *indexNatts = NULL;
- char *predString;
- Node **indexPred = NULL;
- TupleDesc rtupdesc;
+ RelationInfo *relationInfo;
EState *estate = makeNode(EState); /* for ExecConstraints() */
-#ifndef OMIT_PARTIAL_INDEX
- ExprContext *econtext = NULL;
TupleTable tupleTable;
- TupleTableSlot *slot = NULL;
-#endif
- int natts;
- AttrNumber *attnumP;
- Datum *idatum;
- int n_indices;
- InsertIndexResult indexRes;
- TupleDesc tupDesc;
+ TupleTableSlot *slot;
Oid loaded_oid = InvalidOid;
bool skip_tuple = false;
@@ -630,71 +608,26 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null
attr = tupDesc->attrs;
attr_count = tupDesc->natts;
- has_index = false;
-
/*
- * This may be a scalar or a functional index. We initialize all
- * kinds of arrays here to avoid doing extra work at every tuple copy.
+ * We need a RelationInfo so we can use the regular executor's
+ * index-entry-making machinery. (There used to be a huge amount
+ * of code here that basically duplicated execUtils.c ...)
*/
+ relationInfo = makeNode(RelationInfo);
+ relationInfo->ri_RangeTableIndex = 1; /* dummy */
+ relationInfo->ri_RelationDesc = rel;
+ relationInfo->ri_NumIndices = 0;
+ relationInfo->ri_IndexRelationDescs = NULL;
+ relationInfo->ri_IndexRelationInfo = NULL;
- if (rel->rd_rel->relhasindex)
- {
- GetIndexRelations(RelationGetRelid(rel), &n_indices, &index_rels);
- if (n_indices > 0)
- {
- has_index = true;
- itupdescArr = (TupleDesc *) palloc(n_indices * sizeof(TupleDesc));
- pgIndexP = (Form_pg_index *) palloc(n_indices * sizeof(Form_pg_index));
- indexNatts = (int *) palloc(n_indices * sizeof(int));
- finfo = (FuncIndexInfo *) palloc(n_indices * sizeof(FuncIndexInfo));
- finfoP = (FuncIndexInfo **) palloc(n_indices * sizeof(FuncIndexInfo *));
- indexPred = (Node **) palloc(n_indices * sizeof(Node *));
- for (i = 0; i < n_indices; i++)
- {
- itupdescArr[i] = RelationGetDescr(index_rels[i]);
- pgIndexTup = SearchSysCacheTuple(INDEXRELID,
- ObjectIdGetDatum(RelationGetRelid(index_rels[i])),
- 0, 0, 0);
- Assert(pgIndexTup);
- pgIndexP[i] = (Form_pg_index) GETSTRUCT(pgIndexTup);
- for (attnumP = &(pgIndexP[i]->indkey[0]), natts = 0;
- natts < INDEX_MAX_KEYS && *attnumP != InvalidAttrNumber;
- attnumP++, natts++);
- if (pgIndexP[i]->indproc != InvalidOid)
- {
- FIgetnArgs(&finfo[i]) = natts;
- natts = 1;
- FIgetProcOid(&finfo[i]) = pgIndexP[i]->indproc;
- *(FIgetname(&finfo[i])) = '\0';
- finfoP[i] = &finfo[i];
- }
- else
- finfoP[i] = (FuncIndexInfo *) NULL;
- indexNatts[i] = natts;
- if (VARSIZE(&pgIndexP[i]->indpred) != 0)
- {
- predString = DatumGetCString(DirectFunctionCall1(textout,
- PointerGetDatum(&pgIndexP[i]->indpred)));
- indexPred[i] = stringToNode(predString);
- pfree(predString);
-#ifndef OMIT_PARTIAL_INDEX
- /* make dummy ExprContext for use by ExecQual */
- if (econtext == NULL)
- {
- tupleTable = ExecCreateTupleTable(1);
- slot = ExecAllocTableSlot(tupleTable);
- rtupdesc = RelationGetDescr(rel);
- ExecSetSlotDescriptor(slot, rtupdesc);
- econtext = MakeExprContext(slot,
- TransactionCommandContext);
- }
-#endif /* OMIT_PARTIAL_INDEX */
- }
- else
- indexPred[i] = NULL;
- }
- }
- }
+ ExecOpenIndices(relationInfo);
+
+ estate->es_result_relation_info = relationInfo;
+
+ /* Set up a dummy tuple table too */
+ tupleTable = ExecCreateTupleTable(1);
+ slot = ExecAllocTableSlot(tupleTable);
+ ExecSetSlotDescriptor(slot, tupDesc);
if (!binary)
{
@@ -723,16 +656,13 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null
reading_to_eof = false;
}
- values = (Datum *) palloc(sizeof(Datum) * attr_count);
- nulls = (char *) palloc(attr_count);
- index_nulls = (char *) palloc(attr_count);
- idatum = (Datum *) palloc(sizeof(Datum) * attr_count);
+ values = (Datum *) palloc(attr_count * sizeof(Datum));
+ nulls = (char *) palloc(attr_count * sizeof(char));
byval = (bool *) palloc(attr_count * sizeof(bool));
for (i = 0; i < attr_count; i++)
{
nulls[i] = ' ';
- index_nulls[i] = ' ';
#ifdef _DROP_COLUMN_HACK__
if (COLUMN_IS_DROPPED(attr[i]))
{
@@ -873,6 +803,7 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null
tuple->t_data->t_oid = loaded_oid;
skip_tuple = false;
+
/* BEFORE ROW INSERT Triggers */
if (rel->trigdesc &&
rel->trigdesc->n_before_row[TRIGGER_EVENT_INSERT] > 0)
@@ -893,45 +824,25 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null
if (!skip_tuple)
{
/* ----------------
- * Check the constraints of a tuple
+ * Check the constraints of the tuple
* ----------------
*/
if (rel->rd_att->constr)
ExecConstraints("CopyFrom", rel, tuple, estate);
+ /* ----------------
+ * OK, store the tuple and create index entries for it
+ * ----------------
+ */
heap_insert(rel, tuple);
- if (has_index)
+ if (relationInfo->ri_NumIndices > 0)
{
- for (i = 0; i < n_indices; i++)
- {
-#ifndef OMIT_PARTIAL_INDEX
- if (indexPred[i] != NULL)
- {
- /*
- * if tuple doesn't satisfy predicate, don't
- * update index
- */
- slot->val = tuple;
- /* SetSlotContents(slot, tuple); */
- if (!ExecQual((List *) indexPred[i], econtext, false))
- continue;
- }
-#endif /* OMIT_PARTIAL_INDEX */
- FormIndexDatum(indexNatts[i],
- (AttrNumber *) &(pgIndexP[i]->indkey[0]),
- tuple,
- tupDesc,
- idatum,
- index_nulls,
- finfoP[i]);
- indexRes = index_insert(index_rels[i], idatum, index_nulls,
- &(tuple->t_self), rel);
- if (indexRes)
- pfree(indexRes);
- }
+ ExecStoreTuple(tuple, slot, InvalidBuffer, false);
+ ExecInsertIndexTuples(slot, &(tuple->t_self), estate, false);
}
+
/* AFTER ROW INSERT Triggers */
if (rel->trigdesc &&
rel->trigdesc->n_after_row[TRIGGER_EVENT_INSERT] > 0)
@@ -948,8 +859,8 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null
if (!binary)
pfree((void *) values[i]);
}
- else if (nulls[i] == 'n')
- nulls[i] = ' ';
+ /* reset nulls[] array for next time */
+ nulls[i] = ' ';
}
heap_freetuple(tuple);
@@ -958,11 +869,14 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null
if (!reading_to_eof && ntuples == tuples_read)
done = true;
}
+
+ /*
+ * Done, clean up
+ */
lineno = 0;
+
pfree(values);
pfree(nulls);
- pfree(index_nulls);
- pfree(idatum);
pfree(byval);
if (!binary)
@@ -972,21 +886,10 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null
pfree(typmod);
}
- if (has_index)
- {
- for (i = 0; i < n_indices; i++)
- {
- if (index_rels[i] == NULL)
- continue;
- /* see comments in ExecOpenIndices() in execUtils.c */
- if ((index_rels[i])->rd_rel->relam != BTREE_AM_OID &&
- (index_rels[i])->rd_rel->relam != HASH_AM_OID)
- UnlockRelation(index_rels[i], AccessExclusiveLock);
- index_close(index_rels[i]);
- }
- }
-}
+ ExecDropTupleTable(tupleTable, true);
+ ExecCloseIndices(relationInfo);
+}
static Oid
@@ -1054,52 +957,6 @@ IsTypeByVal(Oid type)
return InvalidOid;
}
-/*
- * Given the OID of a relation, return an array of index relation descriptors
- * and the number of index relations. These relation descriptors are open
- * using index_open().
- *
- * Space for the array itself is palloc'ed.
- */
-
-static void
-GetIndexRelations(Oid main_relation_oid,
- int *n_indices,
- Relation **index_rels)
-{
- Relation relation;
- List *indexoidlist,
- *indexoidscan;
- int i;
-
- relation = heap_open(main_relation_oid, AccessShareLock);
- indexoidlist = RelationGetIndexList(relation);
-
- *n_indices = length(indexoidlist);
-
- if (*n_indices > 0)
- *index_rels = (Relation *) palloc(*n_indices * sizeof(Relation));
- else
- *index_rels = NULL;
-
- i = 0;
- foreach(indexoidscan, indexoidlist)
- {
- Oid indexoid = lfirsti(indexoidscan);
- Relation index = index_open(indexoid);
-
- /* see comments in ExecOpenIndices() in execUtils.c */
- if (index != NULL &&
- index->rd_rel->relam != BTREE_AM_OID &&
- index->rd_rel->relam != HASH_AM_OID)
- LockRelation(index, AccessExclusiveLock);
- (*index_rels)[i] = index;
- i++;
- }
-
- freeList(indexoidlist);
- heap_close(relation, AccessShareLock);
-}
/*
* Reads input from fp until an end of line is seen.
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index efe8a44180a..6ede4f51c12 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.34 2000/07/05 23:11:11 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.35 2000/07/14 22:17:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,6 +21,7 @@
#include "catalog/catname.h"
#include "catalog/heap.h"
#include "catalog/index.h"
+#include "catalog/pg_am.h"
#include "catalog/pg_amop.h"
#include "catalog/pg_database.h"
#include "catalog/pg_index.h"
@@ -47,14 +48,14 @@
static void CheckPredicate(List *predList, List *rangeTable, Oid baseRelOid);
static void CheckPredExpr(Node *predicate, List *rangeTable, Oid baseRelOid);
static void CheckPredClause(Expr *predicate, List *rangeTable, Oid baseRelOid);
-static void FuncIndexArgs(IndexElem *funcIndex, FuncIndexInfo *funcInfo,
- AttrNumber *attNumP, Oid *opOidP, Oid relId,
+static void FuncIndexArgs(IndexInfo *indexInfo, Oid *classOidP,
+ IndexElem *funcIndex,
+ Oid relId,
char *accessMethodName, Oid accessMethodId);
-static void NormIndexAttrs(List *attList, AttrNumber *attNumP,
- Oid *opOidP, Oid relId,
+static void NormIndexAttrs(IndexInfo *indexInfo, Oid *classOidP,
+ List *attList,
+ Oid relId,
char *accessMethodName, Oid accessMethodId);
-static void ProcessAttrTypename(IndexElem *attribute,
- Oid defType, int32 defTypmod);
static Oid GetAttrOpClass(IndexElem *attribute, Oid attrType,
char *accessMethodName, Oid accessMethodId);
static char *GetDefaultOpClass(Oid atttypid);
@@ -67,10 +68,7 @@ static char *GetDefaultOpClass(Oid atttypid);
* index or a list of attributes to index on.
* 'parameterList' is a list of DefElem specified in the with clause.
* 'predicate' is the qual specified in the where clause.
- * 'rangetable' is for the predicate
- *
- * Exceptions:
- * XXX
+ * 'rangetable' is needed to interpret the predicate
*/
void
DefineIndex(char *heapRelationName,
@@ -86,16 +84,15 @@ DefineIndex(char *heapRelationName,
Oid *classObjectId;
Oid accessMethodId;
Oid relationId;
+ IndexInfo *indexInfo;
int numberOfAttributes;
- AttrNumber *attributeNumberA;
HeapTuple tuple;
- FuncIndexInfo fInfo;
- List *cnfPred = NULL;
+ List *cnfPred = NIL;
bool lossy = false;
List *pl;
/*
- * count attributes
+ * count attributes in index
*/
numberOfAttributes = length(attributeList);
if (numberOfAttributes <= 0)
@@ -108,21 +105,8 @@ DefineIndex(char *heapRelationName,
* compute heap relation id
*/
if ((relationId = RelnameFindRelid(heapRelationName)) == InvalidOid)
- {
elog(ERROR, "DefineIndex: relation \"%s\" not found",
heapRelationName);
- }
-
- /*
- * XXX Hardwired hacks to check for limitations on supported index types.
- * We really ought to be learning this info from entries in the pg_am
- * table, instead of having it wired in here!
- */
- if (unique && strcmp(accessMethodName, "btree") != 0)
- elog(ERROR, "DefineIndex: unique indices are only available with the btree access method");
-
- if (numberOfAttributes > 1 && strcmp(accessMethodName, "btree") != 0)
- elog(ERROR, "DefineIndex: multi-column indices are only available with the btree access method");
/*
* compute access method id
@@ -131,13 +115,22 @@ DefineIndex(char *heapRelationName,
PointerGetDatum(accessMethodName),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
- {
elog(ERROR, "DefineIndex: access method \"%s\" not found",
accessMethodName);
- }
accessMethodId = tuple->t_data->t_oid;
/*
+ * XXX Hardwired hacks to check for limitations on supported index types.
+ * We really ought to be learning this info from entries in the pg_am
+ * table, instead of having it wired in here!
+ */
+ if (unique && accessMethodId != BTREE_AM_OID)
+ elog(ERROR, "DefineIndex: unique indices are only available with the btree access method");
+
+ if (numberOfAttributes > 1 && accessMethodId != BTREE_AM_OID)
+ elog(ERROR, "DefineIndex: multi-column indices are only available with the btree access method");
+
+ /*
* WITH clause reinstated to handle lossy indices. -- JMH, 7/22/96
*/
foreach(pl, parameterList)
@@ -145,7 +138,7 @@ DefineIndex(char *heapRelationName,
DefElem *param = (DefElem *) lfirst(pl);
if (!strcasecmp(param->defname, "islossy"))
- lossy = TRUE;
+ lossy = true;
else
elog(NOTICE, "Unrecognized index attribute \"%s\" ignored",
param->defname);
@@ -169,55 +162,51 @@ DefineIndex(char *heapRelationName,
if (!IsBootstrapProcessingMode() && !IndexesAreActive(relationId, false))
elog(ERROR, "Existing indexes are inactive. REINDEX first");
+ /*
+ * Prepare arguments for index_create, primarily an IndexInfo structure
+ */
+ indexInfo = makeNode(IndexInfo);
+ indexInfo->ii_Predicate = (Node *) cnfPred;
+ indexInfo->ii_FuncOid = InvalidOid;
+ indexInfo->ii_Unique = unique;
+
if (IsFuncIndex(attributeList))
{
- IndexElem *funcIndex = lfirst(attributeList);
+ IndexElem *funcIndex = (IndexElem *) lfirst(attributeList);
int nargs;
+ /* Parser should have given us only one list item, but check */
+ if (numberOfAttributes != 1)
+ elog(ERROR, "Functional index can only have one attribute");
+
nargs = length(funcIndex->args);
if (nargs > INDEX_MAX_KEYS)
elog(ERROR, "Index function can take at most %d arguments",
INDEX_MAX_KEYS);
- FIsetnArgs(&fInfo, nargs);
-
- namestrcpy(&fInfo.funcName, funcIndex->name);
-
- attributeNumberA = (AttrNumber *) palloc(nargs *
- sizeof attributeNumberA[0]);
+ indexInfo->ii_NumIndexAttrs = 1;
+ indexInfo->ii_NumKeyAttrs = nargs;
classObjectId = (Oid *) palloc(sizeof(Oid));
- FuncIndexArgs(funcIndex, &fInfo, attributeNumberA,
- classObjectId, relationId,
- accessMethodName, accessMethodId);
-
- index_create(heapRelationName, indexRelationName,
- &fInfo, NULL,
- accessMethodId, numberOfAttributes, attributeNumberA,
- classObjectId,
- (Node *) cnfPred,
- lossy, unique, primary, allowSystemTableMods);
+ FuncIndexArgs(indexInfo, classObjectId, funcIndex,
+ relationId, accessMethodName, accessMethodId);
}
else
{
- attributeNumberA = (AttrNumber *) palloc(numberOfAttributes *
- sizeof attributeNumberA[0]);
+ indexInfo->ii_NumIndexAttrs = numberOfAttributes;
+ indexInfo->ii_NumKeyAttrs = numberOfAttributes;
classObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid));
- NormIndexAttrs(attributeList, attributeNumberA,
- classObjectId, relationId,
- accessMethodName, accessMethodId);
-
- index_create(heapRelationName, indexRelationName,
- NULL, attributeList,
- accessMethodId, numberOfAttributes, attributeNumberA,
- classObjectId,
- (Node *) cnfPred,
- lossy, unique, primary, allowSystemTableMods);
+ NormIndexAttrs(indexInfo, classObjectId, attributeList,
+ relationId, accessMethodName, accessMethodId);
}
+ index_create(heapRelationName, indexRelationName,
+ indexInfo, accessMethodId, classObjectId,
+ lossy, primary, allowSystemTableMods);
+
/*
* We update the relation's pg_class tuple even if it already has
* relhasindex = true. This is needed to cause a shared-cache-inval
@@ -232,83 +221,48 @@ DefineIndex(char *heapRelationName,
/*
* ExtendIndex
* Extends a partial index.
- *
- * Exceptions:
- * XXX
*/
void
ExtendIndex(char *indexRelationName, Expr *predicate, List *rangetable)
{
- Oid *classObjectId;
- Oid accessMethodId;
- Oid indexId,
+ Relation heapRelation;
+ Relation indexRelation;
+ Oid accessMethodId,
+ indexId,
relationId;
- Oid indproc;
- int numberOfAttributes;
- AttrNumber *attributeNumberA;
HeapTuple tuple;
- FuncIndexInfo fInfo;
- FuncIndexInfo *funcInfo = NULL;
- bool unique;
Form_pg_index index;
- Node *oldPred = NULL;
- List *cnfPred = NULL;
- PredInfo *predInfo;
- Relation heapRelation;
- Relation indexRelation;
- int i;
+ List *cnfPred = NIL;
+ IndexInfo *indexInfo;
+ Node *oldPred;
/*
- * compute index relation id and access method id
+ * Get index's relation id and access method id from pg_class
*/
tuple = SearchSysCacheTuple(RELNAME,
PointerGetDatum(indexRelationName),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
- {
elog(ERROR, "ExtendIndex: index \"%s\" not found",
indexRelationName);
- }
indexId = tuple->t_data->t_oid;
accessMethodId = ((Form_pg_class) GETSTRUCT(tuple))->relam;
/*
- * find pg_index tuple
+ * Extract info from the pg_index tuple for the index
*/
tuple = SearchSysCacheTuple(INDEXRELID,
ObjectIdGetDatum(indexId),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
- {
elog(ERROR, "ExtendIndex: relation \"%s\" is not an index",
indexRelationName);
- }
-
- /*
- * Extract info from the pg_index tuple
- */
index = (Form_pg_index) GETSTRUCT(tuple);
Assert(index->indexrelid == indexId);
relationId = index->indrelid;
- indproc = index->indproc;
- unique = index->indisunique;
-
- for (i = 0; i < INDEX_MAX_KEYS; i++)
- {
- if (index->indkey[i] == InvalidAttrNumber)
- break;
- }
- numberOfAttributes = i;
+ indexInfo = BuildIndexInfo(tuple);
+ oldPred = indexInfo->ii_Predicate;
- if (VARSIZE(&index->indpred) != 0)
- {
- char *predString;
-
- predString = DatumGetCString(DirectFunctionCall1(textout,
- PointerGetDatum(&index->indpred)));
- oldPred = stringToNode(predString);
- pfree(predString);
- }
if (oldPred == NULL)
elog(ERROR, "ExtendIndex: \"%s\" is not a partial index",
indexRelationName);
@@ -316,8 +270,11 @@ ExtendIndex(char *indexRelationName, Expr *predicate, List *rangetable)
/*
* Convert the extension predicate from parsetree form to plan form,
* so it can be readily evaluated during index creation. Note:
- * "predicate" comes in as a list containing (1) the predicate itself
- * (a where_clause), and (2) a corresponding range table.
+ * "predicate" comes in two parts (1) the predicate expression itself,
+ * and (2) a corresponding range table.
+ *
+ * XXX I think this code is broken --- index_build expects a single
+ * expression not a list --- tgl Jul 00
*/
if (rangetable != NIL)
{
@@ -326,47 +283,20 @@ ExtendIndex(char *indexRelationName, Expr *predicate, List *rangetable)
CheckPredicate(cnfPred, rangetable, relationId);
}
- /* make predInfo list to pass to index_build */
- predInfo = (PredInfo *) palloc(sizeof(PredInfo));
- predInfo->pred = (Node *) cnfPred;
- predInfo->oldPred = oldPred;
-
- attributeNumberA = (AttrNumber *) palloc(numberOfAttributes *
- sizeof attributeNumberA[0]);
- classObjectId = (Oid *) palloc(numberOfAttributes * sizeof classObjectId[0]);
-
-
- for (i = 0; i < numberOfAttributes; i++)
- {
- attributeNumberA[i] = index->indkey[i];
- classObjectId[i] = index->indclass[i];
- }
-
- if (indproc != InvalidOid)
- {
- funcInfo = &fInfo;
- FIsetnArgs(funcInfo, numberOfAttributes);
-
- tuple = SearchSysCacheTuple(PROCOID,
- ObjectIdGetDatum(indproc),
- 0, 0, 0);
- if (!HeapTupleIsValid(tuple))
- elog(ERROR, "ExtendIndex: index procedure %u not found",
- indproc);
-
- namecpy(&(funcInfo->funcName),
- &(((Form_pg_proc) GETSTRUCT(tuple))->proname));
-
- FIsetProcOid(funcInfo, tuple->t_data->t_oid);
- }
+ /* pass new predicate to index_build */
+ indexInfo->ii_Predicate = (Node *) cnfPred;
+ /* Open heap and index rels, and get suitable locks */
heapRelation = heap_open(relationId, ShareLock);
indexRelation = index_open(indexId);
- InitIndexStrategy(numberOfAttributes, indexRelation, accessMethodId);
+ /* Obtain exclusive lock on it, just to be sure */
+ LockRelation(indexRelation, AccessExclusiveLock);
+
+ InitIndexStrategy(indexInfo->ii_NumIndexAttrs,
+ indexRelation, accessMethodId);
- index_build(heapRelation, indexRelation, numberOfAttributes,
- attributeNumberA, funcInfo, predInfo, unique);
+ index_build(heapRelation, indexRelation, indexInfo, oldPred);
/* heap and index rels are closed as a side-effect of index_build */
}
@@ -431,15 +361,15 @@ CheckPredClause(Expr *predicate, List *rangeTable, Oid baseRelOid)
static void
-FuncIndexArgs(IndexElem *funcIndex,
- FuncIndexInfo *funcInfo,
- AttrNumber *attNumP,
- Oid *opOidP,
+FuncIndexArgs(IndexInfo *indexInfo,
+ Oid *classOidP,
+ IndexElem *funcIndex,
Oid relId,
char *accessMethodName,
Oid accessMethodId)
{
- List *rest;
+ Oid argTypes[FUNC_MAX_ARGS];
+ List *arglist;
HeapTuple tuple;
Oid retType;
int argn = 0;
@@ -447,68 +377,77 @@ FuncIndexArgs(IndexElem *funcIndex,
/*
* process the function arguments, which are a list of T_String
* (someday ought to allow more general expressions?)
+ *
+ * Note caller already checked that list is not too long.
*/
- MemSet(funcInfo->arglist, 0, FUNC_MAX_ARGS * sizeof(Oid));
+ MemSet(argTypes, 0, sizeof(argTypes));
- foreach(rest, funcIndex->args)
+ foreach(arglist, funcIndex->args)
{
- char *arg = strVal(lfirst(rest));
+ char *arg = strVal(lfirst(arglist));
Form_pg_attribute att;
tuple = SearchSysCacheTuple(ATTNAME,
ObjectIdGetDatum(relId),
- PointerGetDatum(arg), 0, 0);
-
+ PointerGetDatum(arg),
+ 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "DefineIndex: attribute \"%s\" not found", arg);
att = (Form_pg_attribute) GETSTRUCT(tuple);
- *attNumP++ = att->attnum;
- funcInfo->arglist[argn++] = att->atttypid;
+
+ indexInfo->ii_KeyAttrNumbers[argn] = att->attnum;
+ argTypes[argn] = att->atttypid;
+ argn++;
}
/* ----------------
* Lookup the function procedure to get its OID and result type.
+ *
+ * XXX need to accept binary-compatible functions here, not just
+ * an exact match.
* ----------------
*/
tuple = SearchSysCacheTuple(PROCNAME,
- PointerGetDatum(FIgetname(funcInfo)),
- Int32GetDatum(FIgetnArgs(funcInfo)),
- PointerGetDatum(FIgetArglist(funcInfo)),
+ PointerGetDatum(funcIndex->name),
+ Int32GetDatum(indexInfo->ii_NumKeyAttrs),
+ PointerGetDatum(argTypes),
0);
-
if (!HeapTupleIsValid(tuple))
{
- func_error("DefineIndex", FIgetname(funcInfo),
- FIgetnArgs(funcInfo), FIgetArglist(funcInfo), NULL);
+ func_error("DefineIndex", funcIndex->name,
+ indexInfo->ii_NumKeyAttrs, argTypes, NULL);
}
- FIsetProcOid(funcInfo, tuple->t_data->t_oid);
+ indexInfo->ii_FuncOid = tuple->t_data->t_oid;
retType = ((Form_pg_proc) GETSTRUCT(tuple))->prorettype;
- /* Process type and opclass, using func return type as default */
+ /* Process opclass, using func return type as default type */
- ProcessAttrTypename(funcIndex, retType, -1);
+ classOidP[0] = GetAttrOpClass(funcIndex, retType,
+ accessMethodName, accessMethodId);
- *opOidP = GetAttrOpClass(funcIndex, retType,
- accessMethodName, accessMethodId);
+ /* Need to do the fmgr function lookup now, too */
+
+ fmgr_info(indexInfo->ii_FuncOid, & indexInfo->ii_FuncInfo);
}
static void
-NormIndexAttrs(List *attList, /* list of IndexElem's */
- AttrNumber *attNumP,
+NormIndexAttrs(IndexInfo *indexInfo,
Oid *classOidP,
+ List *attList, /* list of IndexElem's */
Oid relId,
char *accessMethodName,
Oid accessMethodId)
{
List *rest;
+ int attn = 0;
/*
* process attributeList
*/
foreach(rest, attList)
{
- IndexElem *attribute = lfirst(rest);
+ IndexElem *attribute = (IndexElem *) lfirst(rest);
HeapTuple atttuple;
Form_pg_attribute attform;
@@ -524,36 +463,13 @@ NormIndexAttrs(List *attList, /* list of IndexElem's */
attribute->name);
attform = (Form_pg_attribute) GETSTRUCT(atttuple);
- *attNumP++ = attform->attnum;
-
- ProcessAttrTypename(attribute, attform->atttypid, attform->atttypmod);
+ indexInfo->ii_KeyAttrNumbers[attn] = attform->attnum;
- *classOidP++ = GetAttrOpClass(attribute, attform->atttypid,
- accessMethodName, accessMethodId);
+ classOidP[attn] = GetAttrOpClass(attribute, attform->atttypid,
+ accessMethodName, accessMethodId);
heap_freetuple(atttuple);
- }
-}
-
-static void
-ProcessAttrTypename(IndexElem *attribute,
- Oid defType, int32 defTypmod)
-{
- HeapTuple tuple;
-
- /* build a type node so we can set the proper alignment, etc. */
- if (attribute->typename == NULL)
- {
- tuple = SearchSysCacheTuple(TYPEOID,
- ObjectIdGetDatum(defType),
- 0, 0, 0);
- if (!HeapTupleIsValid(tuple))
- elog(ERROR, "DefineIndex: type for attribute \"%s\" undefined",
- attribute->name);
-
- attribute->typename = makeNode(TypeName);
- attribute->typename->name = nameout(&((Form_pg_type) GETSTRUCT(tuple))->typname);
- attribute->typename->typmod = defTypmod;
+ attn++;
}
}
@@ -626,7 +542,7 @@ GetAttrOpClass(IndexElem *attribute, Oid attrType,
*
* If the opclass was the default for the datatype, assume we can skip
* this check --- that saves a few cycles in the most common case.
- * If pg_opclass is messed up then we're probably screwed anyway...
+ * If pg_opclass is wrong then we're probably screwed anyway...
*/
if (doTypeCheck)
{
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 71682baa8cd..ee0ebeb4bb7 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.162 2000/07/05 16:17:38 wieck Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.163 2000/07/14 22:17:42 tgl Exp $
*
*-------------------------------------------------------------------------
@@ -28,6 +28,7 @@
#include "catalog/index.h"
#include "commands/vacuum.h"
#include "miscadmin.h"
+#include "nodes/execnodes.h"
#include "storage/sinval.h"
#include "storage/smgr.h"
#include "tcop/tcopprot.h"
@@ -71,7 +72,8 @@ static void reap_page(VacPageList vacpagelist, VacPage vacpage);
static void vpage_insert(VacPageList vacpagelist, VacPage vpnew);
static void get_indices(Relation relation, int *nindices, Relation **Irel);
static void close_indices(int nindices, Relation *Irel);
-static void get_index_desc(Relation onerel, int nindices, Relation *Irel, IndDesc **Idesc);
+static IndexInfo **get_index_desc(Relation onerel, int nindices,
+ Relation *Irel);
static void *vac_find_eq(void *bot, int nelem, int size, void *elm,
int (*compar) (const void *, const void *));
static int vac_cmp_blk(const void *left, const void *right);
@@ -948,9 +950,10 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
newitemid;
HeapTupleData tuple,
newtup;
- TupleDesc tupdesc = NULL;
- Datum *idatum = NULL;
- char *inulls = NULL;
+ TupleDesc tupdesc;
+ IndexInfo **indexInfo = NULL;
+ Datum idatum[INDEX_MAX_KEYS];
+ char inulls[INDEX_MAX_KEYS];
InsertIndexResult iresult;
VacPageListData Nvacpagelist;
VacPage cur_page = NULL,
@@ -958,8 +961,6 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
vacpage,
*curpage;
int cur_item = 0;
- IndDesc *Idesc,
- *idcur;
int last_move_dest_block = -1,
last_vacuum_block,
i = 0;
@@ -980,13 +981,10 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
myXID = GetCurrentTransactionId();
myCID = GetCurrentCommandId();
+ tupdesc = RelationGetDescr(onerel);
+
if (Irel != (Relation *) NULL) /* preparation for index' inserts */
- {
- get_index_desc(onerel, nindices, Irel, &Idesc);
- tupdesc = RelationGetDescr(onerel);
- idatum = (Datum *) palloc(INDEX_MAX_KEYS * sizeof(*idatum));
- inulls = (char *) palloc(INDEX_MAX_KEYS * sizeof(*inulls));
- }
+ indexInfo = get_index_desc(onerel, nindices, Irel);
Nvacpagelist.num_pages = 0;
num_fraged_pages = fraged_pages->num_pages;
@@ -1456,15 +1454,22 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
if (Irel != (Relation *) NULL)
{
- for (i = 0, idcur = Idesc; i < nindices; i++, idcur++)
+ /*
+ * XXX using CurrentMemoryContext here means
+ * intra-vacuum memory leak for functional indexes.
+ * Should fix someday.
+ *
+ * XXX This code fails to handle partial indexes!
+ * Probably should change it to use ExecOpenIndices.
+ */
+ for (i = 0; i < nindices; i++)
{
- FormIndexDatum(idcur->natts,
- (AttrNumber *) &(idcur->tform->indkey[0]),
+ FormIndexDatum(indexInfo[i],
&newtup,
tupdesc,
+ CurrentMemoryContext,
idatum,
- inulls,
- idcur->finfoP);
+ inulls);
iresult = index_insert(Irel[i],
idatum,
inulls,
@@ -1575,15 +1580,22 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
/* insert index' tuples if needed */
if (Irel != (Relation *) NULL)
{
- for (i = 0, idcur = Idesc; i < nindices; i++, idcur++)
+ /*
+ * XXX using CurrentMemoryContext here means
+ * intra-vacuum memory leak for functional indexes.
+ * Should fix someday.
+ *
+ * XXX This code fails to handle partial indexes!
+ * Probably should change it to use ExecOpenIndices.
+ */
+ for (i = 0; i < nindices; i++)
{
- FormIndexDatum(idcur->natts,
- (AttrNumber *) &(idcur->tform->indkey[0]),
+ FormIndexDatum(indexInfo[i],
&newtup,
tupdesc,
+ CurrentMemoryContext,
idatum,
- inulls,
- idcur->finfoP);
+ inulls);
iresult = index_insert(Irel[i],
idatum,
inulls,
@@ -1821,10 +1833,8 @@ failed to add item with len = %u to page %u (free space %u, nusd %u, noff %u)",
if (Irel != (Relation *) NULL) /* pfree index' allocations */
{
- pfree(Idesc);
- pfree(idatum);
- pfree(inulls);
close_indices(nindices, Irel);
+ pfree(indexInfo);
}
pfree(vacpage);
@@ -2347,46 +2357,30 @@ close_indices(int nindices, Relation *Irel)
}
-static void
-get_index_desc(Relation onerel, int nindices, Relation *Irel, IndDesc **Idesc)
+/*
+ * Obtain IndexInfo data for each index on the rel
+ */
+static IndexInfo **
+get_index_desc(Relation onerel, int nindices, Relation *Irel)
{
- IndDesc *idcur;
- HeapTuple cachetuple;
- AttrNumber *attnumP;
- int natts;
+ IndexInfo **indexInfo;
int i;
+ HeapTuple cachetuple;
- *Idesc = (IndDesc *) palloc(nindices * sizeof(IndDesc));
+ indexInfo = (IndexInfo **) palloc(nindices * sizeof(IndexInfo *));
- for (i = 0, idcur = *Idesc; i < nindices; i++, idcur++)
+ for (i = 0; i < nindices; i++)
{
- cachetuple = SearchSysCacheTupleCopy(INDEXRELID,
+ cachetuple = SearchSysCacheTuple(INDEXRELID,
ObjectIdGetDatum(RelationGetRelid(Irel[i])),
- 0, 0, 0);
- Assert(cachetuple);
-
- /*
- * we never free the copy we make, because Idesc needs it for
- * later
- */
- idcur->tform = (Form_pg_index) GETSTRUCT(cachetuple);
- for (attnumP = &(idcur->tform->indkey[0]), natts = 0;
- natts < INDEX_MAX_KEYS && *attnumP != InvalidAttrNumber;
- attnumP++, natts++);
- if (idcur->tform->indproc != InvalidOid)
- {
- idcur->finfoP = &(idcur->finfo);
- FIgetnArgs(idcur->finfoP) = natts;
- natts = 1;
- FIgetProcOid(idcur->finfoP) = idcur->tform->indproc;
- *(FIgetname(idcur->finfoP)) = '\0';
- }
- else
- idcur->finfoP = (FuncIndexInfo *) NULL;
-
- idcur->natts = natts;
+ 0, 0, 0);
+ if (!HeapTupleIsValid(cachetuple))
+ elog(ERROR, "get_index_desc: index %u not found",
+ RelationGetRelid(Irel[i]));
+ indexInfo[i] = BuildIndexInfo(cachetuple);
}
+ return indexInfo;
}
diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c
index daa40dccf75..39e3d5cd48b 100644
--- a/src/backend/executor/execUtils.c
+++ b/src/backend/executor/execUtils.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.63 2000/07/12 02:37:03 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.64 2000/07/14 22:17:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -27,11 +27,9 @@
* QueryDescGetTypeInfo - moved here from main.c
* am not sure what uses it -cim 10/12/89
*
- * ExecGetIndexKeyInfo \
- * ExecOpenIndices | referenced by InitPlan, EndPlan,
- * ExecCloseIndices | ExecAppend, ExecReplace
- * ExecFormIndexTuple |
- * ExecInsertIndexTuple /
+ * ExecOpenIndices \
+ * ExecCloseIndices | referenced by InitPlan, EndPlan,
+ * ExecInsertIndexTuples / ExecAppend, ExecReplace
*
* NOTES
* This file has traditionally been the place to stick misc.
@@ -55,8 +53,6 @@
#include "utils/relcache.h"
#include "utils/syscache.h"
-static void ExecGetIndexKeyInfo(Form_pg_index indexTuple, int *numAttsOutP,
- AttrNumber **attsOutP, FuncIndexInfoPtr fInfoP);
/* ----------------------------------------------------------------
* global counters for number of tuples processed, retrieved,
@@ -684,93 +680,6 @@ QueryDescGetTypeInfo(QueryDesc *queryDesc)
* ExecInsertIndexTuples support
* ----------------------------------------------------------------
*/
-/* ----------------------------------------------------------------
- * ExecGetIndexKeyInfo
- *
- * Extracts the index key attribute numbers from
- * an index tuple form (i.e. a tuple from the pg_index relation)
- * into an array of attribute numbers. The array and the
- * size of the array are returned to the caller via return
- * parameters.
- * ----------------------------------------------------------------
- */
-static void
-ExecGetIndexKeyInfo(Form_pg_index indexTuple,
- int *numAttsOutP,
- AttrNumber **attsOutP,
- FuncIndexInfoPtr fInfoP)
-{
- int i;
- int numKeys;
- AttrNumber *attKeys;
-
- /* ----------------
- * check parameters
- * ----------------
- */
- if (numAttsOutP == NULL || attsOutP == NULL)
- {
- elog(DEBUG, "ExecGetIndexKeyInfo: %s",
- "invalid parameters: numAttsOutP and attsOutP must be non-NULL");
- }
-
- /* ----------------
- * set the procid for a possible functional index.
- * ----------------
- */
- FIsetProcOid(fInfoP, indexTuple->indproc);
-
- /* ----------------
- * count the number of keys..
- * ----------------
- */
- numKeys = 0;
- for (i = 0; i < INDEX_MAX_KEYS &&
- indexTuple->indkey[i] != InvalidAttrNumber; i++)
- numKeys++;
-
- /* ----------------
- * place number keys in callers return area
- * or the number of arguments for a functional index.
- *
- * If we have a functional index then the number of
- * attributes defined in the index must 1 (the function's
- * single return value).
- * ----------------
- */
- if (FIgetProcOid(fInfoP) != InvalidOid)
- {
- FIsetnArgs(fInfoP, numKeys);
- (*numAttsOutP) = 1;
- }
- else
- (*numAttsOutP) = numKeys;
-
- if (numKeys < 1)
- {
- elog(DEBUG, "ExecGetIndexKeyInfo: %s",
- "all index key attribute numbers are zero!");
- (*attsOutP) = NULL;
- return;
- }
-
- /* ----------------
- * allocate and fill in array of key attribute numbers
- * ----------------
- */
- CXT1_printf("ExecGetIndexKeyInfo: context is %d\n", CurrentMemoryContext);
-
- attKeys = (AttrNumber *) palloc(numKeys * sizeof(AttrNumber));
-
- for (i = 0; i < numKeys; i++)
- attKeys[i] = indexTuple->indkey[i];
-
- /* ----------------
- * return array to caller.
- * ----------------
- */
- (*attsOutP) = attKeys;
-}
/* ----------------------------------------------------------------
* ExecOpenIndices
@@ -838,11 +747,6 @@ ExecOpenIndices(RelationInfo *resultRelationInfo)
Oid indexOid = lfirsti(indexoidscan);
Relation indexDesc;
HeapTuple indexTuple;
- Form_pg_index indexStruct;
- int numKeyAtts;
- AttrNumber *indexKeyAtts;
- FuncIndexInfoPtr fInfoP;
- PredInfo *predicate;
IndexInfo *ii;
/* ----------------
@@ -874,47 +778,17 @@ ExecOpenIndices(RelationInfo *resultRelationInfo)
* Get the pg_index tuple for the index
* ----------------
*/
- indexTuple = SearchSysCacheTupleCopy(INDEXRELID,
- ObjectIdGetDatum(indexOid),
- 0, 0, 0);
+ indexTuple = SearchSysCacheTuple(INDEXRELID,
+ ObjectIdGetDatum(indexOid),
+ 0, 0, 0);
if (!HeapTupleIsValid(indexTuple))
elog(ERROR, "ExecOpenIndices: index %u not found", indexOid);
- indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
/* ----------------
* extract the index key information from the tuple
* ----------------
*/
- fInfoP = (FuncIndexInfoPtr) palloc(sizeof(*fInfoP));
- ExecGetIndexKeyInfo(indexStruct,
- &numKeyAtts,
- &indexKeyAtts,
- fInfoP);
-
- /* ----------------
- * next get the index predicate from the tuple
- * ----------------
- */
- if (VARSIZE(&indexStruct->indpred) != 0)
- {
- char *predString;
-
- predString = DatumGetCString(DirectFunctionCall1(textout,
- PointerGetDatum(&indexStruct->indpred)));
- predicate = (PredInfo *) stringToNode(predString);
- pfree(predString);
- }
- else
- predicate = NULL;
-
- /* Save the index info */
- ii = makeNode(IndexInfo);
- ii->ii_NumKeyAttributes = numKeyAtts;
- ii->ii_KeyAttributeNumbers = indexKeyAtts;
- ii->ii_FuncIndexInfo = fInfoP;
- ii->ii_Predicate = (Node *) predicate;
-
- heap_freetuple(indexTuple);
+ ii = BuildIndexInfo(indexTuple);
relationDescs[i] = indexDesc;
indexInfoArray[i] = ii;
@@ -984,17 +858,11 @@ ExecInsertIndexTuples(TupleTableSlot *slot,
int numIndices;
RelationPtr relationDescs;
Relation heapRelation;
+ TupleDesc heapDescriptor;
IndexInfo **indexInfoArray;
- IndexInfo *indexInfo;
- Node *predicate;
ExprContext *econtext;
- InsertIndexResult result;
- int numberOfAttributes;
- AttrNumber *keyAttributeNumbers;
- FuncIndexInfoPtr fInfoP;
- TupleDesc heapDescriptor;
- Datum *datum;
- char *nulls;
+ Datum datum[INDEX_MAX_KEYS];
+ char nullv[INDEX_MAX_KEYS];
heapTuple = slot->val;
@@ -1007,14 +875,27 @@ ExecInsertIndexTuples(TupleTableSlot *slot,
relationDescs = resultRelationInfo->ri_IndexRelationDescs;
indexInfoArray = resultRelationInfo->ri_IndexRelationInfo;
heapRelation = resultRelationInfo->ri_RelationDesc;
+ heapDescriptor = RelationGetDescr(heapRelation);
+
+ /* ----------------
+ * Make a temporary expr/memory context for evaluating predicates
+ * and functional-index functions.
+ * XXX should do this once per command not once per tuple, and
+ * just reset it once per tuple.
+ * ----------------
+ */
+ econtext = MakeExprContext(slot, TransactionCommandContext);
/* ----------------
* for each index, form and insert the index tuple
* ----------------
*/
- econtext = NULL;
for (i = 0; i < numIndices; i++)
{
+ IndexInfo *indexInfo;
+ Node *predicate;
+ InsertIndexResult result;
+
if (relationDescs[i] == NULL)
continue;
@@ -1022,39 +903,26 @@ ExecInsertIndexTuples(TupleTableSlot *slot,
predicate = indexInfo->ii_Predicate;
if (predicate != NULL)
{
- if (econtext == NULL)
- econtext = MakeExprContext(slot,
- TransactionCommandContext);
-
/* Skip this index-update if the predicate isn't satisfied */
if (!ExecQual((List *) predicate, econtext, false))
continue;
}
/* ----------------
- * get information from index info structure
+ * FormIndexDatum fills in its datum and null parameters
+ * with attribute information taken from the given heap tuple.
* ----------------
*/
- numberOfAttributes = indexInfo->ii_NumKeyAttributes;
- keyAttributeNumbers = indexInfo->ii_KeyAttributeNumbers;
- fInfoP = indexInfo->ii_FuncIndexInfo;
- datum = (Datum *) palloc(numberOfAttributes * sizeof *datum);
- nulls = (char *) palloc(numberOfAttributes * sizeof *nulls);
- heapDescriptor = (TupleDesc) RelationGetDescr(heapRelation);
-
- FormIndexDatum(numberOfAttributes, /* num attributes */
- keyAttributeNumbers, /* array of att nums to
- * extract */
- heapTuple, /* tuple from base relation */
- heapDescriptor, /* heap tuple's descriptor */
- datum, /* return: array of attributes */
- nulls, /* return: array of char's */
- fInfoP); /* functional index information */
-
+ FormIndexDatum(indexInfo,
+ heapTuple,
+ heapDescriptor,
+ econtext->ecxt_per_tuple_memory,
+ datum,
+ nullv);
result = index_insert(relationDescs[i], /* index relation */
datum, /* array of heaptuple Datums */
- nulls, /* info on nulls */
+ nullv, /* info on nulls */
&(heapTuple->t_self), /* tid of heap tuple */
heapRelation);
@@ -1064,15 +932,11 @@ ExecInsertIndexTuples(TupleTableSlot *slot,
*/
IncrIndexInserted();
- /* ----------------
- * free index tuple after insertion
- * ----------------
- */
if (result)
pfree(result);
}
- if (econtext != NULL)
- FreeExprContext(econtext);
+
+ FreeExprContext(econtext);
}
void
@@ -1094,5 +958,4 @@ SetChangedParamList(Plan *node, List *newchg)
/* else - add this param to the list */
node->chgParam = lappendi(node->chgParam, paramId);
}
-
}
diff --git a/src/backend/storage/large_object/inv_api.c b/src/backend/storage/large_object/inv_api.c
index cbf15626781..d8abfb4a2b7 100644
--- a/src/backend/storage/large_object/inv_api.c
+++ b/src/backend/storage/large_object/inv_api.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.73 2000/07/04 06:11:39 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.74 2000/07/14 22:17:48 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -87,12 +87,12 @@ static int _inv_getsize(Relation hreln, TupleDesc hdesc, Relation ireln);
LargeObjectDesc *
inv_create(int flags)
{
- int file_oid;
LargeObjectDesc *retval;
+ Oid file_oid;
Relation r;
Relation indr;
TupleDesc tupdesc;
- AttrNumber attNums[1];
+ IndexInfo *indexInfo;
Oid classObjectId[1];
char objname[NAMEDATALEN];
char indname[NAMEDATALEN];
@@ -109,17 +109,13 @@ inv_create(int flags)
sprintf(indname, "xinx%u", file_oid);
if (RelnameFindRelid(objname) != InvalidOid)
- {
elog(ERROR,
"internal error: %s already exists -- cannot create large obj",
objname);
- }
if (RelnameFindRelid(indname) != InvalidOid)
- {
elog(ERROR,
"internal error: %s already exists -- cannot create large obj",
indname);
- }
/* this is pretty painful... want a tuple descriptor */
tupdesc = CreateTemplateTupleDesc(2);
@@ -155,21 +151,25 @@ inv_create(int flags)
/*
* Now create a btree index on the relation's olastbyte attribute to
- * make seeks go faster. The hardwired constants are embarassing to
- * me, and are symptomatic of the pressure under which this code was
- * written.
- *
- * ok, mao, let's put in some symbolic constants - jolly
+ * make seeks go faster.
*/
+ indexInfo = makeNode(IndexInfo);
+ indexInfo->ii_NumIndexAttrs = 1;
+ indexInfo->ii_NumKeyAttrs = 1;
+ indexInfo->ii_KeyAttrNumbers[0] = 1;
+ indexInfo->ii_Predicate = NULL;
+ indexInfo->ii_FuncOid = InvalidOid;
+ indexInfo->ii_Unique = false;
- attNums[0] = 1;
classObjectId[0] = INT4_OPS_OID;
- index_create(objname, indname, NULL, NULL, BTREE_AM_OID,
- 1, &attNums[0], &classObjectId[0],
- (Node *) NULL, false, false, false, false);
+
+ index_create(objname, indname, indexInfo,
+ BTREE_AM_OID, classObjectId,
+ false, false, false);
/* make the index visible in this transaction */
CommandCounterIncrement();
+
indr = index_openr(indname);
if (!RelationIsValid(indr))
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index c1cc688e8f6..a7cb0ecac49 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.106 2000/07/05 23:11:39 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.107 2000/07/14 22:17:50 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1065,6 +1065,7 @@ IndexedAccessMethodInitialize(Relation relation)
support = (RegProcedure *) NULL;
IndexSupportInitialize(strategy, support,
+ &relation->rd_uniqueindex,
relation->rd_att->attrs[0]->attrelid,
relation->rd_rel->relam,
relamstrategies, relamsupport, natts);
diff --git a/src/include/access/funcindex.h b/src/include/access/funcindex.h
deleted file mode 100644
index 0555755aaab..00000000000
--- a/src/include/access/funcindex.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * funcindex.h
- *
- *
- *
- * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- * $Id: funcindex.h,v 1.9 2000/01/26 05:57:50 momjian Exp $
- *
- *-------------------------------------------------------------------------
- */
-#ifndef _FUNC_INDEX_INCLUDED_
-#define _FUNC_INDEX_INCLUDED_
-
-typedef struct
-{
- int nargs;
- Oid arglist[FUNC_MAX_ARGS];
- Oid procOid;
- NameData funcName;
-} FuncIndexInfo;
-
-typedef FuncIndexInfo *FuncIndexInfoPtr;
-
-/*
- * some marginally useful macro definitions
- */
-/* #define FIgetname(FINFO) (&((FINFO)->funcName.data[0]))*/
-#define FIgetname(FINFO) (FINFO)->funcName.data
-#define FIgetnArgs(FINFO) (FINFO)->nargs
-#define FIgetProcOid(FINFO) (FINFO)->procOid
-#define FIgetArg(FINFO, argnum) (FINFO)->arglist[argnum]
-#define FIgetArglist(FINFO) (FINFO)->arglist
-
-#define FIsetnArgs(FINFO, numargs) ((FINFO)->nargs = numargs)
-#define FIsetProcOid(FINFO, id) ((FINFO)->procOid = id)
-#define FIsetArg(FINFO, argnum, argtype) ((FINFO)->arglist[argnum] = argtype)
-
-#define FIisFunctionalIndex(FINFO) (FINFO->procOid != InvalidOid)
-
-#endif /* FUNCINDEX_H */
diff --git a/src/include/access/genam.h b/src/include/access/genam.h
index c7e0c5021b4..b62a979f051 100644
--- a/src/include/access/genam.h
+++ b/src/include/access/genam.h
@@ -7,14 +7,13 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: genam.h,v 1.23 2000/01/26 05:57:50 momjian Exp $
+ * $Id: genam.h,v 1.24 2000/07/14 22:17:53 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef GENAM_H
#define GENAM_H
-#include "access/funcindex.h"
#include "access/itup.h"
#include "access/relscan.h"
#include "access/sdir.h"
@@ -42,9 +41,6 @@ extern RetrieveIndexResult index_getnext(IndexScanDesc scan,
extern RegProcedure index_cost_estimator(Relation relation);
extern RegProcedure index_getprocid(Relation irel, AttrNumber attnum,
uint16 procnum);
-extern Datum GetIndexValue(HeapTuple tuple, TupleDesc hTupDesc,
- int attOff, AttrNumber *attrNums, FuncIndexInfo *fInfo,
- bool *attNull);
/* in genam.c */
extern IndexScanDesc RelationGetIndexScan(Relation relation, bool scanFromEnd,
diff --git a/src/include/access/gist.h b/src/include/access/gist.h
index dd8f557e9ba..1297b02ff01 100644
--- a/src/include/access/gist.h
+++ b/src/include/access/gist.h
@@ -12,7 +12,6 @@
#ifndef GIST_H
#define GIST_H
-#include "access/funcindex.h"
#include "access/itup.h"
#include "access/relscan.h"
#include "access/sdir.h"
diff --git a/src/include/access/hash.h b/src/include/access/hash.h
index aa461a75e2b..17d3496dee0 100644
--- a/src/include/access/hash.h
+++ b/src/include/access/hash.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: hash.h,v 1.34 2000/06/19 03:54:35 tgl Exp $
+ * $Id: hash.h,v 1.35 2000/07/14 22:17:53 tgl Exp $
*
* NOTES
* modeled after Margo Seltzer's hash implementation for unix.
@@ -17,7 +17,6 @@
#ifndef HASH_H
#define HASH_H
-#include "access/funcindex.h"
#include "access/itup.h"
#include "access/relscan.h"
#include "access/sdir.h"
diff --git a/src/include/access/istrat.h b/src/include/access/istrat.h
index 99d4901bcdc..9178f8c410e 100644
--- a/src/include/access/istrat.h
+++ b/src/include/access/istrat.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: istrat.h,v 1.17 2000/06/08 22:37:36 momjian Exp $
+ * $Id: istrat.h,v 1.18 2000/07/14 22:17:53 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -56,9 +56,12 @@ extern StrategyNumber RelationGetStrategy(Relation relation,
AttrNumber attributeNumber, StrategyEvaluation evaluation,
RegProcedure procedure);
extern void IndexSupportInitialize(IndexStrategy indexStrategy,
- RegProcedure *indexSupport, Oid indexObjectId,
- Oid accessMethodObjectId, StrategyNumber maxStrategyNumber,
- StrategyNumber maxSupportNumber, AttrNumber maxAttributeNumber);
-
+ RegProcedure *indexSupport,
+ bool *isUnique,
+ Oid indexObjectId,
+ Oid accessMethodObjectId,
+ StrategyNumber maxStrategyNumber,
+ StrategyNumber maxSupportNumber,
+ AttrNumber maxAttributeNumber);
#endif /* ISTRAT_H */
diff --git a/src/include/access/itup.h b/src/include/access/itup.h
index e01cb7a31b6..a5047729616 100644
--- a/src/include/access/itup.h
+++ b/src/include/access/itup.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: itup.h,v 1.24 2000/03/17 02:36:37 tgl Exp $
+ * $Id: itup.h,v 1.25 2000/07/14 22:17:53 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -61,18 +61,6 @@ typedef struct RetrieveIndexResultData
typedef RetrieveIndexResultData *RetrieveIndexResult;
-/*-----------------
- * PredInfo -
- * used for partial indices
- *-----------------
- */
-typedef struct PredInfo
-{
- Node *pred;
- Node *oldPred;
-} PredInfo;
-
-
/* ----------------
* externs
* ----------------
diff --git a/src/include/bootstrap/bootstrap.h b/src/include/bootstrap/bootstrap.h
index b3ddea19d50..882ac3c7d1c 100644
--- a/src/include/bootstrap/bootstrap.h
+++ b/src/include/bootstrap/bootstrap.h
@@ -7,18 +7,21 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: bootstrap.h,v 1.18 2000/06/17 23:41:49 tgl Exp $
+ * $Id: bootstrap.h,v 1.19 2000/07/14 22:17:54 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef BOOTSTRAP_H
#define BOOTSTRAP_H
-#include "access/funcindex.h"
#include "access/itup.h"
+#include "nodes/execnodes.h"
#include "utils/rel.h"
-#define MAXATTR 40 /* max. number of attributes in a relation */
+/* MAXATTR is the maximum number of attributes in a relation supported
+ * at bootstrap time (ie, the max possible in a system table).
+ */
+#define MAXATTR 40
typedef struct hashnode
{
@@ -35,10 +38,7 @@ extern int DebugMode;
extern int BootstrapMain(int ac, char *av[]);
-extern void index_register(char *heap, char *ind,
- int natts, AttrNumber *attnos,
- FuncIndexInfo *finfo, PredInfo *predInfo,
- bool unique);
+extern void index_register(char *heap, char *ind, IndexInfo *indexInfo);
extern void err_out(void);
extern void InsertOneTuple(Oid objectid);
diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h
index 66b4f601be3..e00b25e6f07 100644
--- a/src/include/catalog/index.h
+++ b/src/include/catalog/index.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: index.h,v 1.28 2000/07/12 02:37:27 tgl Exp $
+ * $Id: index.h,v 1.29 2000/07/14 22:17:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -27,25 +27,24 @@ extern void InitIndexStrategy(int numatts,
Oid accessMethodObjectId);
extern void index_create(char *heapRelationName,
- char *indexRelationName,
- FuncIndexInfo *funcInfo,
- List *attributeList,
- Oid accessMethodObjectId,
- int numatts,
- AttrNumber *attNums,
- Oid *classObjectId,
- Node *predicate,
- bool islossy,
- bool unique,
- bool primary,
- bool allow_system_table_mods);
+ char *indexRelationName,
+ IndexInfo *indexInfo,
+ Oid accessMethodObjectId,
+ Oid *classObjectId,
+ bool islossy,
+ bool primary,
+ bool allow_system_table_mods);
extern void index_drop(Oid indexId);
-extern void FormIndexDatum(int numberOfAttributes,
- AttrNumber *attributeNumber, HeapTuple heapTuple,
- TupleDesc heapDescriptor, Datum *datum,
- char *nullv, FuncIndexInfoPtr fInfo);
+extern IndexInfo *BuildIndexInfo(HeapTuple indexTuple);
+
+extern void FormIndexDatum(IndexInfo *indexInfo,
+ HeapTuple heapTuple,
+ TupleDesc heapDescriptor,
+ MemoryContext resultCxt,
+ Datum *datum,
+ char *nullv);
extern void UpdateStats(Oid relid, long reltuples, bool inplace);
extern bool IndexesAreActive(Oid relid, bool comfirmCommitted);
@@ -54,11 +53,7 @@ extern bool SetReindexProcessing(bool processing);
extern bool IsReindexProcessing(void);
extern void index_build(Relation heapRelation, Relation indexRelation,
- int numberOfAttributes, AttrNumber *attributeNumber,
- FuncIndexInfo *funcInfo, PredInfo *predInfo,
- bool unique);
-
-extern bool IndexIsUnique(Oid indexId);
+ IndexInfo *indexInfo, Node *oldPred);
extern bool reindex_index(Oid indexId, bool force);
extern bool activate_indexes_of_a_table(Oid relid, bool activate);
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index bd260a827b4..538299773d9 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_proc.h,v 1.146 2000/07/08 03:04:21 tgl Exp $
+ * $Id: pg_proc.h,v 1.147 2000/07/14 22:17:56 tgl Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
@@ -677,7 +677,7 @@ DATA(insert OID = 321 ( rtdelete PGUID 12 f t f t 2 f 23 "0 0" 100 0 0 100
DESCR("r-tree(internal)");
DATA(insert OID = 322 ( rtgettuple PGUID 12 f t f t 2 f 23 "0 0" 100 0 0 100 rtgettuple - ));
DESCR("r-tree(internal)");
-DATA(insert OID = 323 ( rtbuild PGUID 12 f t f t 8 f 23 "0 0 0 0 0 0 0 0" 100 0 0 100 rtbuild - ));
+DATA(insert OID = 323 ( rtbuild PGUID 12 f t f t 5 f 23 "0 0 0 0 0" 100 0 0 100 rtbuild - ));
DESCR("r-tree(internal)");
DATA(insert OID = 324 ( rtbeginscan PGUID 12 f t f t 4 f 23 "0 0 0 0" 100 0 0 100 rtbeginscan - ));
DESCR("r-tree(internal)");
@@ -706,7 +706,7 @@ DATA(insert OID = 336 ( btmarkpos PGUID 12 f t f t 1 f 23 "0" 100 0 0 100
DESCR("btree(internal)");
DATA(insert OID = 337 ( btrestrpos PGUID 12 f t f t 1 f 23 "0" 100 0 0 100 btrestrpos - ));
DESCR("btree(internal)");
-DATA(insert OID = 338 ( btbuild PGUID 12 f t f t 8 f 23 "0 0 0 0 0 0 0 0" 100 0 0 100 btbuild - ));
+DATA(insert OID = 338 ( btbuild PGUID 12 f t f t 5 f 23 "0 0 0 0 0" 100 0 0 100 btbuild - ));
DESCR("btree(internal)");
DATA(insert OID = 339 ( poly_same PGUID 11 f t t t 2 f 16 "604 604" 100 0 1 0 poly_same - ));
@@ -810,7 +810,7 @@ DATA(insert OID = 446 ( hashmarkpos PGUID 12 f t f t 1 f 23 "0" 100 0 0 100
DESCR("hash(internal)");
DATA(insert OID = 447 ( hashrestrpos PGUID 12 f t f t 1 f 23 "0" 100 0 0 100 hashrestrpos - ));
DESCR("hash(internal)");
-DATA(insert OID = 448 ( hashbuild PGUID 12 f t f t 8 f 23 "0 0 0 0 0 0 0 0" 100 0 0 100 hashbuild - ));
+DATA(insert OID = 448 ( hashbuild PGUID 12 f t f t 5 f 23 "0 0 0 0 0" 100 0 0 100 hashbuild - ));
DESCR("hash(internal)");
DATA(insert OID = 449 ( hashint2 PGUID 12 f t t t 1 f 23 "21" 100 0 0 100 hashint2 - ));
DESCR("hash");
@@ -1033,7 +1033,7 @@ DATA(insert OID = 780 ( gistmarkpos PGUID 12 f t f t 1 f 23 "0" 100 0 0 100
DESCR("gist(internal)");
DATA(insert OID = 781 ( gistrestrpos PGUID 12 f t f t 1 f 23 "0" 100 0 0 100 gistrestrpos - ));
DESCR("gist(internal)");
-DATA(insert OID = 782 ( gistbuild PGUID 12 f t f t 8 f 23 "0 0 0 0 0 0 0 0" 100 0 0 100 gistbuild - ));
+DATA(insert OID = 782 ( gistbuild PGUID 12 f t f t 5 f 23 "0 0 0 0 0" 100 0 0 100 gistbuild - ));
DESCR("gist(internal)");
DATA(insert OID = 784 ( tintervaleq PGUID 12 f t f t 2 f 16 "704 704" 100 0 0 100 tintervaleq - ));
diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h
index fed4c6a9a16..b42a8e6a17f 100644
--- a/src/include/commands/vacuum.h
+++ b/src/include/commands/vacuum.h
@@ -7,17 +7,16 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: vacuum.h,v 1.31 2000/05/29 17:40:44 momjian Exp $
+ * $Id: vacuum.h,v 1.32 2000/07/14 22:17:57 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef VACUUM_H
#define VACUUM_H
-#include "fmgr.h"
-#include "access/funcindex.h"
-#include "catalog/pg_index.h"
#include "catalog/pg_attribute.h"
+#include "catalog/pg_index.h"
+#include "fmgr.h"
#include "nodes/pg_list.h"
#include "storage/itemptr.h"
@@ -56,14 +55,6 @@ typedef VacPageListData *VacPageList;
typedef struct
{
- FuncIndexInfo finfo;
- FuncIndexInfo *finfoP;
- Form_pg_index tform;
- int natts;
-} IndDesc;
-
-typedef struct
-{
Form_pg_attribute attr;
Datum best,
guess1,
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 2c21dba9c23..62a887d754b 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -7,39 +7,49 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: execnodes.h,v 1.43 2000/07/12 02:37:32 tgl Exp $
+ * $Id: execnodes.h,v 1.44 2000/07/14 22:17:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef EXECNODES_H
#define EXECNODES_H
-#include "access/funcindex.h"
#include "access/relscan.h"
#include "access/sdir.h"
#include "executor/hashjoin.h"
#include "executor/tuptable.h"
+#include "fmgr.h"
#include "nodes/params.h"
#include "nodes/primnodes.h"
/* ----------------
* IndexInfo information
*
- * this class holds the information saying what attributes
- * are the key attributes for this index. -cim 10/15/89
- *
- * NumKeyAttributes number of key attributes for this index
- * KeyAttributeNumbers array of attribute numbers used as keys
- * Predicate partial-index predicate for this index
+ * this class holds the information needed to construct new index
+ * entries for a particular index. Used for both index_build and
+ * retail creation of index entries.
+ *
+ * NumIndexAttrs number of columns in this index
+ * (1 if a func. index, else same as NumKeyAttrs)
+ * NumKeyAttrs number of key attributes for this index
+ * (ie, number of attrs from underlying relation)
+ * KeyAttrNumbers underlying-rel attribute numbers used as keys
+ * Predicate partial-index predicate, or NULL if none
+ * FuncOid OID of function, or InvalidOid if not f. index
+ * FuncInfo fmgr lookup data for function, if FuncOid valid
+ * Unique is it a unique index?
* ----------------
*/
typedef struct IndexInfo
{
NodeTag type;
- int ii_NumKeyAttributes;
- AttrNumber *ii_KeyAttributeNumbers;
- FuncIndexInfoPtr ii_FuncIndexInfo;
+ int ii_NumIndexAttrs;
+ int ii_NumKeyAttrs;
+ AttrNumber ii_KeyAttrNumbers[INDEX_MAX_KEYS];
Node *ii_Predicate;
+ Oid ii_FuncOid;
+ FmgrInfo ii_FuncInfo;
+ bool ii_Unique;
} IndexInfo;
/* ----------------
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index 121012d7fd4..c90ba3c5ee0 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: rel.h,v 1.39 2000/06/30 07:04:03 tgl Exp $
+ * $Id: rel.h,v 1.40 2000/07/14 22:18:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -92,6 +92,7 @@ typedef struct RelationData
bool rd_isnailed; /* rel is nailed in cache */
bool rd_unlinked; /* rel already unlinked or not created yet */
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_class rd_rel; /* RELATION tuple */
Oid rd_id; /* relation's object id */