mirror of
https://github.com/postgres/postgres.git
synced 2025-11-10 17:42:29 +03:00
Cleanup of code for creating index entries. Functional indexes with
pass-by-ref data types --- eg, an index on lower(textfield) --- no longer leak memory during index creation or update. Clean up a lot of redundant code ... did you know that copy, vacuum, truncate, reindex, extend index, and bootstrap each basically duplicated the main executor's logic for extracting information about an index and preparing index entries? Functional indexes should be a little faster now too, due to removal of repeated function lookups. CREATE INDEX 'opt_type' clause is deimplemented by these changes, but I haven't removed it from the parser yet (need to merge with Thomas' latest change set first).
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user