aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/gist/gist.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/gist/gist.c')
-rw-r--r--src/backend/access/gist/gist.c154
1 files changed, 64 insertions, 90 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();
}