diff options
Diffstat (limited to 'src/backend/access')
-rw-r--r-- | src/backend/access/gist/gist.c | 154 | ||||
-rw-r--r-- | src/backend/access/hash/hash.c | 90 | ||||
-rw-r--r-- | src/backend/access/index/indexam.c | 55 | ||||
-rw-r--r-- | src/backend/access/index/istrat.c | 15 | ||||
-rw-r--r-- | src/backend/access/nbtree/nbtree.c | 105 | ||||
-rw-r--r-- | src/backend/access/rtree/rtree.c | 129 |
6 files changed, 187 insertions, 361 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(); } |