1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-30 21:42:05 +03:00

Convert index-related tuple handling routines from char 'n'/' ' to bool

convention for isnull flags.  Also, remove the useless InsertIndexResult
return struct from index AM aminsert calls --- there is no reason for
the caller to know where in the index the tuple was inserted, and we
were wasting a palloc cycle per insert to deliver this uninteresting
value (plus nontrivial complexity in some AMs).
I forced initdb because of the change in the signature of the aminsert
routines, even though nothing really looks at those pg_proc entries...
This commit is contained in:
Tom Lane
2005-03-21 01:24:04 +00:00
parent fe7015f5e8
commit ee4ddac137
24 changed files with 288 additions and 405 deletions

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/gist/gist.c,v 1.112 2004/12/31 21:59:10 pgsql Exp $
* $PostgreSQL: pgsql/src/backend/access/gist/gist.c,v 1.113 2005/03/21 01:23:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -71,18 +71,16 @@ typedef struct
/* non-export function prototypes */
static void gistbuildCallback(Relation index,
HeapTuple htup,
Datum *attdata,
char *nulls,
Datum *values,
bool *isnull,
bool tupleIsAlive,
void *state);
static void gistdoinsert(Relation r,
IndexTuple itup,
InsertIndexResult *res,
GISTSTATE *GISTstate);
static int gistlayerinsert(Relation r, BlockNumber blkno,
IndexTuple **itup,
int *len,
InsertIndexResult *res,
GISTSTATE *giststate);
static OffsetNumber gistwritebuffer(Relation r,
Page page,
@ -114,8 +112,7 @@ static IndexTuple *gistSplit(Relation r,
Buffer buffer,
IndexTuple *itup,
int *len,
GISTSTATE *giststate,
InsertIndexResult *res);
GISTSTATE *giststate);
static void gistnewroot(Relation r,
IndexTuple *itup, int len);
static void GISTInitBuffer(Buffer b, uint32 f);
@ -223,8 +220,8 @@ gistbuild(PG_FUNCTION_ARGS)
static void
gistbuildCallback(Relation index,
HeapTuple htup,
Datum *attdata,
char *nulls,
Datum *values,
bool *isnull,
bool tupleIsAlive,
void *state)
{
@ -235,33 +232,33 @@ gistbuildCallback(Relation index,
int i;
/* GiST cannot index tuples with leading NULLs */
if (nulls[0] == 'n')
if (isnull[0])
return;
/* immediately compress keys to normalize */
for (i = 0; i < buildstate->numindexattrs; i++)
{
if (nulls[i] == 'n')
if (isnull[i])
{
attdata[i] = (Datum) 0;
values[i] = (Datum) 0;
compvec[i] = FALSE;
}
else
{
gistcentryinit(&buildstate->giststate, i, &tmpcentry, attdata[i],
gistcentryinit(&buildstate->giststate, i, &tmpcentry, values[i],
NULL, NULL, (OffsetNumber) 0,
-1 /* size is currently bogus */ , TRUE, FALSE);
if (attdata[i] != tmpcentry.key &&
if (values[i] != tmpcentry.key &&
!(isAttByVal(&buildstate->giststate, i)))
compvec[i] = TRUE;
else
compvec[i] = FALSE;
attdata[i] = tmpcentry.key;
values[i] = tmpcentry.key;
}
}
/* form an index tuple and point it at the heap tuple */
itup = index_formtuple(buildstate->giststate.tupdesc, attdata, nulls);
itup = index_form_tuple(buildstate->giststate.tupdesc, values, isnull);
itup->t_tid = htup->t_self;
/*
@ -271,13 +268,13 @@ gistbuildCallback(Relation index,
* thing to do if you're inserting single tups, but not when you're
* initializing the whole index at once.
*/
gistdoinsert(index, itup, NULL, &buildstate->giststate);
gistdoinsert(index, itup, &buildstate->giststate);
buildstate->indtuples += 1;
for (i = 0; i < buildstate->numindexattrs; i++)
if (compvec[i])
pfree(DatumGetPointer(attdata[i]));
pfree(DatumGetPointer(values[i]));
pfree(itup);
}
@ -292,15 +289,14 @@ Datum
gistinsert(PG_FUNCTION_ARGS)
{
Relation r = (Relation) PG_GETARG_POINTER(0);
Datum *datum = (Datum *) PG_GETARG_POINTER(1);
char *nulls = (char *) PG_GETARG_POINTER(2);
Datum *values = (Datum *) PG_GETARG_POINTER(1);
bool *isnull = (bool *) PG_GETARG_POINTER(2);
ItemPointer ht_ctid = (ItemPointer) PG_GETARG_POINTER(3);
#ifdef NOT_USED
Relation heapRel = (Relation) PG_GETARG_POINTER(4);
bool checkUnique = PG_GETARG_BOOL(5);
#endif
InsertIndexResult res;
IndexTuple itup;
GISTSTATE giststate;
GISTENTRY tmpentry;
@ -314,47 +310,43 @@ gistinsert(PG_FUNCTION_ARGS)
*/
/* GiST cannot index tuples with leading NULLs */
if (nulls[0] == 'n')
{
res = NULL;
PG_RETURN_POINTER(res);
}
if (isnull[0])
PG_RETURN_BOOL(false);
initGISTstate(&giststate, r);
/* immediately compress keys to normalize */
for (i = 0; i < r->rd_att->natts; i++)
{
if (nulls[i] == 'n')
if (isnull[i])
{
datum[i] = (Datum) 0;
values[i] = (Datum) 0;
compvec[i] = FALSE;
}
else
{
gistcentryinit(&giststate, i, &tmpentry, datum[i],
gistcentryinit(&giststate, i, &tmpentry, values[i],
NULL, NULL, (OffsetNumber) 0,
-1 /* size is currently bogus */ , TRUE, FALSE);
if (datum[i] != tmpentry.key && !(isAttByVal(&giststate, i)))
if (values[i] != tmpentry.key && !(isAttByVal(&giststate, i)))
compvec[i] = TRUE;
else
compvec[i] = FALSE;
datum[i] = tmpentry.key;
values[i] = tmpentry.key;
}
}
itup = index_formtuple(giststate.tupdesc, datum, nulls);
itup = index_form_tuple(giststate.tupdesc, values, isnull);
itup->t_tid = *ht_ctid;
res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData));
gistdoinsert(r, itup, &res, &giststate);
gistdoinsert(r, itup, &giststate);
for (i = 0; i < r->rd_att->natts; i++)
if (compvec[i] == TRUE)
pfree(DatumGetPointer(datum[i]));
pfree(DatumGetPointer(values[i]));
pfree(itup);
freeGISTstate(&giststate);
PG_RETURN_POINTER(res);
PG_RETURN_BOOL(true);
}
#ifdef GIST_PAGEADDITEM
@ -411,7 +403,6 @@ gistPageAddItem(GISTSTATE *giststate,
static void
gistdoinsert(Relation r,
IndexTuple itup,
InsertIndexResult *res,
GISTSTATE *giststate)
{
IndexTuple *instup;
@ -423,7 +414,7 @@ gistdoinsert(Relation r,
instup[0] = (IndexTuple) palloc(IndexTupleSize(itup));
memcpy(instup[0], itup, IndexTupleSize(itup));
ret = gistlayerinsert(r, GISTP_ROOT, &instup, &len, res, giststate);
ret = gistlayerinsert(r, GISTP_ROOT, &instup, &len, giststate);
if (ret & SPLITED)
gistnewroot(r, instup, len);
@ -436,7 +427,6 @@ static int
gistlayerinsert(Relation r, BlockNumber blkno,
IndexTuple **itup, /* in - out, has compressed entry */
int *len, /* in - out */
InsertIndexResult *res, /* out */
GISTSTATE *giststate)
{
Buffer buffer;
@ -468,7 +458,7 @@ gistlayerinsert(Relation r, BlockNumber blkno,
* contains keys for each page 2. if child page wasn't splited,
* then itup contains additional for adjustment of current key
*/
ret = gistlayerinsert(r, nblkno, itup, len, res, giststate);
ret = gistlayerinsert(r, nblkno, itup, len, giststate);
/* nothing inserted in child */
if (!(ret & INSERTED))
@ -520,9 +510,7 @@ gistlayerinsert(Relation r, BlockNumber blkno,
itvec = gistreadbuffer(buffer, &tlen);
itvec = gistjoinvector(itvec, &tlen, (*itup), *len);
oldlen = *len;
newitup = gistSplit(r, buffer, itvec, &tlen, giststate,
(opaque->flags & F_LEAF) ? res : NULL); /* res only for
* inserting in leaf */
newitup = gistSplit(r, buffer, itvec, &tlen, giststate);
ReleaseBuffer(buffer);
do
pfree((*itup)[oldlen - 1]);
@ -545,12 +533,6 @@ gistlayerinsert(Relation r, BlockNumber blkno,
l = gistwritebuffer(r, page, (*itup), *len, off);
WriteBuffer(buffer);
/*
* set res if insert into leaf page, in this case, len = 1 always
*/
if (res && (opaque->flags & F_LEAF))
ItemPointerSet(&((*res)->pointerData), blkno, l);
if (*len > 1)
{ /* previous insert ret & SPLITED != 0 */
int i;
@ -666,7 +648,7 @@ gistunion(Relation r, IndexTuple *itvec, int len, GISTSTATE *giststate)
{
Datum attr[INDEX_MAX_KEYS];
bool whatfree[INDEX_MAX_KEYS];
char isnull[INDEX_MAX_KEYS];
bool isnull[INDEX_MAX_KEYS];
GistEntryVector *evec;
Datum datum;
int datumsize,
@ -706,7 +688,7 @@ gistunion(Relation r, IndexTuple *itvec, int len, GISTSTATE *giststate)
if (reallen == 0)
{
attr[j] = (Datum) 0;
isnull[j] = 'n';
isnull[j] = TRUE;
whatfree[j] = FALSE;
}
else
@ -732,7 +714,7 @@ gistunion(Relation r, IndexTuple *itvec, int len, GISTSTATE *giststate)
gistcentryinit(giststate, j, &centry[j], datum,
NULL, NULL, (OffsetNumber) 0,
datumsize, FALSE, FALSE);
isnull[j] = ' ';
isnull[j] = FALSE;
attr[j] = centry[j].key;
if (!isAttByVal(giststate, j))
{
@ -748,7 +730,7 @@ gistunion(Relation r, IndexTuple *itvec, int len, GISTSTATE *giststate)
pfree(evec);
pfree(needfree);
newtup = (IndexTuple) index_formtuple(giststate->tupdesc, attr, isnull);
newtup = index_form_tuple(giststate->tupdesc, attr, isnull);
for (j = 0; j < r->rd_att->natts; j++)
if (whatfree[j])
pfree(DatumGetPointer(attr[j]));
@ -768,7 +750,7 @@ gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *gis
int datumsize;
bool result,
neednew = false;
char isnull[INDEX_MAX_KEYS],
bool isnull[INDEX_MAX_KEYS],
whatfree[INDEX_MAX_KEYS];
Datum attr[INDEX_MAX_KEYS];
GISTENTRY centry[INDEX_MAX_KEYS],
@ -799,8 +781,8 @@ gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *gis
{
if (oldisnull[j] && addisnull[j])
{
isnull[j] = 'n';
attr[j] = (Datum) 0;
isnull[j] = TRUE;
whatfree[j] = FALSE;
}
else
@ -839,8 +821,8 @@ gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *gis
NULL, NULL, (OffsetNumber) 0,
datumsize, FALSE, FALSE);
isnull[j] = ' ';
attr[j] = centry[j].key;
isnull[j] = FALSE;
if ((!isAttByVal(giststate, j)))
{
whatfree[j] = TRUE;
@ -856,7 +838,7 @@ gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *gis
if (neednew)
{
/* need to update key */
newtup = (IndexTuple) index_formtuple(giststate->tupdesc, attr, isnull);
newtup = index_form_tuple(giststate->tupdesc, attr, isnull);
newtup->t_tid = oldtup->t_tid;
}
@ -1010,7 +992,7 @@ gistfindgroup(GISTSTATE *giststate, GISTENTRY *valvec, GIST_SPLITVEC *spl)
/* find all other equal value in left part */
if (len)
{
/* add current val to list of equial values */
/* add current val to list of equal values */
spl->spl_idgrp[spl->spl_left[i]] = curid;
/* searching .. */
for (j = i + 1; j < spl->spl_nleft; j++)
@ -1207,8 +1189,7 @@ gistSplit(Relation r,
Buffer buffer,
IndexTuple *itup, /* contains compressed entry */
int *len,
GISTSTATE *giststate,
InsertIndexResult *res)
GISTSTATE *giststate)
{
Page p;
Buffer leftbuf,
@ -1344,8 +1325,7 @@ gistSplit(Relation r,
if (gistnospace(right, rvectup, v.spl_nright))
{
nlen = v.spl_nright;
newtup = gistSplit(r, rightbuf, rvectup, &nlen, giststate,
(res && rvectup[nlen - 1] == itup[*len - 1]) ? res : NULL);
newtup = gistSplit(r, rightbuf, rvectup, &nlen, giststate);
ReleaseBuffer(rightbuf);
for (j = 1; j < r->rd_att->natts; j++)
if ((!isAttByVal(giststate, j)) && !v.spl_risnull[j])
@ -1358,9 +1338,6 @@ gistSplit(Relation r,
l = gistwritebuffer(r, right, rvectup, v.spl_nright, FirstOffsetNumber);
WriteBuffer(rightbuf);
if (res)
ItemPointerSet(&((*res)->pointerData), rbknum, l);
nlen = 1;
newtup = (IndexTuple *) palloc(sizeof(IndexTuple) * 1);
newtup[0] = gistFormTuple(giststate, r, v.spl_rattr, v.spl_rattrsize, v.spl_risnull);
@ -1373,8 +1350,7 @@ gistSplit(Relation r,
int llen = v.spl_nleft;
IndexTuple *lntup;
lntup = gistSplit(r, leftbuf, lvectup, &llen, giststate,
(res && lvectup[llen - 1] == itup[*len - 1]) ? res : NULL);
lntup = gistSplit(r, leftbuf, lvectup, &llen, giststate);
ReleaseBuffer(leftbuf);
for (j = 1; j < r->rd_att->natts; j++)
@ -1394,9 +1370,6 @@ gistSplit(Relation r,
WriteBuffer(leftbuf);
if (res)
ItemPointerSet(&((*res)->pointerData), lbknum, l);
nlen += 1;
newtup = (IndexTuple *) repalloc((void *) newtup, sizeof(IndexTuple) * nlen);
newtup[nlen - 1] = gistFormTuple(giststate, r, v.spl_lattr, v.spl_lattrsize, v.spl_lisnull);
@ -1704,7 +1677,7 @@ gist_tuple_replacekey(Relation r, GISTENTRY entry, IndexTuple t)
/*
* If new entry fits in index tuple, copy it in. To avoid worrying
* about null-value bitmask, pass it off to the general
* index_formtuple routine if either the previous or new value is
* index_form_tuple routine if either the previous or new value is
* NULL.
*/
if (!IsNull && DatumGetPointer(entry.key) != NULL &&
@ -1725,12 +1698,10 @@ gist_tuple_replacekey(Relation r, GISTENTRY entry, IndexTuple t)
/* generate a new index tuple for the compressed entry */
TupleDesc tupDesc = r->rd_att;
IndexTuple newtup;
char isnull;
bool isnull;
isnull = DatumGetPointer(entry.key) != NULL ? ' ' : 'n';
newtup = (IndexTuple) index_formtuple(tupDesc,
&(entry.key),
&isnull);
isnull = (DatumGetPointer(entry.key) == NULL);
newtup = index_form_tuple(tupDesc, &(entry.key), &isnull);
newtup->t_tid = t->t_tid;
return newtup;
}
@ -1799,7 +1770,6 @@ gistFormTuple(GISTSTATE *giststate, Relation r,
Datum attdata[], int datumsize[], bool isnull[])
{
IndexTuple tup;
char isnullchar[INDEX_MAX_KEYS];
bool whatfree[INDEX_MAX_KEYS];
GISTENTRY centry[INDEX_MAX_KEYS];
Datum compatt[INDEX_MAX_KEYS];
@ -1809,7 +1779,6 @@ gistFormTuple(GISTSTATE *giststate, Relation r,
{
if (isnull[j])
{
isnullchar[j] = 'n';
compatt[j] = (Datum) 0;
whatfree[j] = FALSE;
}
@ -1818,7 +1787,6 @@ gistFormTuple(GISTSTATE *giststate, Relation r,
gistcentryinit(giststate, j, &centry[j], attdata[j],
NULL, NULL, (OffsetNumber) 0,
datumsize[j], FALSE, FALSE);
isnullchar[j] = ' ';
compatt[j] = centry[j].key;
if (!isAttByVal(giststate, j))
{
@ -1831,7 +1799,7 @@ gistFormTuple(GISTSTATE *giststate, Relation r,
}
}
tup = (IndexTuple) index_formtuple(giststate->tupdesc, compatt, isnullchar);
tup = index_form_tuple(giststate->tupdesc, compatt, isnull);
for (j = 0; j < r->rd_att->natts; j++)
if (whatfree[j])
pfree(DatumGetPointer(compatt[j]));