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

@ -1,5 +1,5 @@
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/indexam.sgml,v 2.1 2005/02/13 03:04:15 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/indexam.sgml,v 2.2 2005/03/21 01:23:55 tgl Exp $
--> -->
<chapter id="indexam"> <chapter id="indexam">
@ -151,16 +151,16 @@ ambuild (Relation heapRelation,
<para> <para>
<programlisting> <programlisting>
InsertIndexResult bool
aminsert (Relation indexRelation, aminsert (Relation indexRelation,
Datum *datums, Datum *values,
char *nulls, bool *isnull,
ItemPointer heap_tid, ItemPointer heap_tid,
Relation heapRelation, Relation heapRelation,
bool check_uniqueness); bool check_uniqueness);
</programlisting> </programlisting>
Insert a new tuple into an existing index. The <literal>datums</> and Insert a new tuple into an existing index. The <literal>values</> and
<literal>nulls</> arrays give the key values to be indexed, and <literal>isnull</> arrays give the key values to be indexed, and
<literal>heap_tid</> is the TID to be indexed. <literal>heap_tid</> is the TID to be indexed.
If the access method supports unique indexes (its If the access method supports unique indexes (its
<structname>pg_am</>.<structfield>amcanunique</> flag is true) then <structname>pg_am</>.<structfield>amcanunique</> flag is true) then
@ -168,8 +168,9 @@ aminsert (Relation indexRelation,
must verify that there is no conflicting row; this is the only situation in must verify that there is no conflicting row; this is the only situation in
which the access method normally needs the <literal>heapRelation</> which the access method normally needs the <literal>heapRelation</>
parameter. See <xref linkend="index-unique-checks"> for details. parameter. See <xref linkend="index-unique-checks"> for details.
The result is a struct that must be pfree'd by the caller. (The result The result is TRUE if an index entry was inserted, FALSE if not. (A FALSE
struct is really quite useless and should be removed...) result does not denote an error condition, but is used for cases such
as an index AM refusing to index a NULL.)
</para> </para>
<para> <para>

View File

@ -16,7 +16,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/common/heaptuple.c,v 1.98 2005/03/16 21:38:04 tgl Exp $ * $PostgreSQL: pgsql/src/backend/access/common/heaptuple.c,v 1.99 2005/03/21 01:23:55 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -68,7 +68,7 @@ heap_compute_data_size(TupleDesc tupleDesc,
* OLD API with char 'n'/' ' convention for indicating nulls * OLD API with char 'n'/' ' convention for indicating nulls
* ---------------- * ----------------
*/ */
Size static Size
ComputeDataSize(TupleDesc tupleDesc, ComputeDataSize(TupleDesc tupleDesc,
Datum *values, Datum *values,
char *nulls) char *nulls)
@ -193,7 +193,7 @@ heap_fill_tuple(TupleDesc tupleDesc,
* OLD API with char 'n'/' ' convention for indicating nulls * OLD API with char 'n'/' ' convention for indicating nulls
* ---------------- * ----------------
*/ */
void static void
DataFill(char *data, DataFill(char *data,
TupleDesc tupleDesc, TupleDesc tupleDesc,
Datum *values, Datum *values,

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/common/indextuple.c,v 1.72 2004/12/31 21:59:07 pgsql Exp $ * $PostgreSQL: pgsql/src/backend/access/common/indextuple.c,v 1.73 2005/03/21 01:23:55 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -28,13 +28,13 @@
*/ */
/* ---------------- /* ----------------
* index_formtuple * index_form_tuple
* ---------------- * ----------------
*/ */
IndexTuple IndexTuple
index_formtuple(TupleDesc tupleDescriptor, index_form_tuple(TupleDesc tupleDescriptor,
Datum *value, Datum *values,
char *null) bool *isnull)
{ {
char *tp; /* tuple pointer */ char *tp; /* tuple pointer */
IndexTuple tuple; /* return tuple */ IndexTuple tuple; /* return tuple */
@ -47,7 +47,7 @@ index_formtuple(TupleDesc tupleDescriptor,
int numberOfAttributes = tupleDescriptor->natts; int numberOfAttributes = tupleDescriptor->natts;
#ifdef TOAST_INDEX_HACK #ifdef TOAST_INDEX_HACK
Datum untoasted_value[INDEX_MAX_KEYS]; Datum untoasted_values[INDEX_MAX_KEYS];
bool untoasted_free[INDEX_MAX_KEYS]; bool untoasted_free[INDEX_MAX_KEYS];
#endif #endif
@ -62,22 +62,22 @@ index_formtuple(TupleDesc tupleDescriptor,
{ {
Form_pg_attribute att = tupleDescriptor->attrs[i]; Form_pg_attribute att = tupleDescriptor->attrs[i];
untoasted_value[i] = value[i]; untoasted_values[i] = values[i];
untoasted_free[i] = false; untoasted_free[i] = false;
/* Do nothing if value is NULL or not of varlena type */ /* Do nothing if value is NULL or not of varlena type */
if (null[i] != ' ' || att->attlen != -1) if (isnull[i] || att->attlen != -1)
continue; continue;
/* /*
* If value is stored EXTERNAL, must fetch it so we are not * If value is stored EXTERNAL, must fetch it so we are not
* depending on outside storage. This should be improved someday. * depending on outside storage. This should be improved someday.
*/ */
if (VARATT_IS_EXTERNAL(value[i])) if (VARATT_IS_EXTERNAL(values[i]))
{ {
untoasted_value[i] = PointerGetDatum( untoasted_values[i] = PointerGetDatum(
heap_tuple_fetch_attr( heap_tuple_fetch_attr(
(varattrib *) DatumGetPointer(value[i]))); (varattrib *) DatumGetPointer(values[i])));
untoasted_free[i] = true; untoasted_free[i] = true;
} }
@ -85,18 +85,18 @@ index_formtuple(TupleDesc tupleDescriptor,
* If value is above size target, and is of a compressible * If value is above size target, and is of a compressible
* datatype, try to compress it in-line. * datatype, try to compress it in-line.
*/ */
if (VARATT_SIZE(untoasted_value[i]) > TOAST_INDEX_TARGET && if (VARATT_SIZE(untoasted_values[i]) > TOAST_INDEX_TARGET &&
!VARATT_IS_EXTENDED(untoasted_value[i]) && !VARATT_IS_EXTENDED(untoasted_values[i]) &&
(att->attstorage == 'x' || att->attstorage == 'm')) (att->attstorage == 'x' || att->attstorage == 'm'))
{ {
Datum cvalue = toast_compress_datum(untoasted_value[i]); Datum cvalue = toast_compress_datum(untoasted_values[i]);
if (DatumGetPointer(cvalue) != NULL) if (DatumGetPointer(cvalue) != NULL)
{ {
/* successful compression */ /* successful compression */
if (untoasted_free[i]) if (untoasted_free[i])
pfree(DatumGetPointer(untoasted_value[i])); pfree(DatumGetPointer(untoasted_values[i]));
untoasted_value[i] = cvalue; untoasted_values[i] = cvalue;
untoasted_free[i] = true; untoasted_free[i] = true;
} }
} }
@ -105,7 +105,7 @@ index_formtuple(TupleDesc tupleDescriptor,
for (i = 0; i < numberOfAttributes; i++) for (i = 0; i < numberOfAttributes; i++)
{ {
if (null[i] != ' ') if (isnull[i])
{ {
hasnull = true; hasnull = true;
break; break;
@ -117,41 +117,42 @@ index_formtuple(TupleDesc tupleDescriptor,
hoff = IndexInfoFindDataOffset(infomask); hoff = IndexInfoFindDataOffset(infomask);
#ifdef TOAST_INDEX_HACK #ifdef TOAST_INDEX_HACK
size = hoff + ComputeDataSize(tupleDescriptor, untoasted_value, null); size = hoff + heap_compute_data_size(tupleDescriptor,
untoasted_values, isnull);
#else #else
size = hoff + ComputeDataSize(tupleDescriptor, value, null); size = hoff + heap_compute_data_size(tupleDescriptor,
values, isnull);
#endif #endif
size = MAXALIGN(size); /* be conservative */ size = MAXALIGN(size); /* be conservative */
tp = (char *) palloc0(size); tp = (char *) palloc0(size);
tuple = (IndexTuple) tp; tuple = (IndexTuple) tp;
DataFill((char *) tp + hoff, heap_fill_tuple(tupleDescriptor,
tupleDescriptor,
#ifdef TOAST_INDEX_HACK #ifdef TOAST_INDEX_HACK
untoasted_value, untoasted_values,
#else #else
value, values,
#endif #endif
null, isnull,
&tupmask, (char *) tp + hoff,
(hasnull ? (bits8 *) tp + sizeof(*tuple) : NULL)); &tupmask,
(hasnull ? (bits8 *) tp + sizeof(*tuple) : NULL));
#ifdef TOAST_INDEX_HACK #ifdef TOAST_INDEX_HACK
for (i = 0; i < numberOfAttributes; i++) for (i = 0; i < numberOfAttributes; i++)
{ {
if (untoasted_free[i]) if (untoasted_free[i])
pfree(DatumGetPointer(untoasted_value[i])); pfree(DatumGetPointer(untoasted_values[i]));
} }
#endif #endif
/* /*
* We do this because DataFill wants to initialize a "tupmask" which * We do this because heap_fill_tuple wants to initialize a "tupmask"
* is used for HeapTuples, but we want an indextuple infomask. The * which is used for HeapTuples, but we want an indextuple infomask.
* only relevant info is the "has variable attributes" field. We have * The only relevant info is the "has variable attributes" field.
* already set the hasnull bit above. * We have already set the hasnull bit above.
*/ */
if (tupmask & HEAP_HASVARWIDTH) if (tupmask & HEAP_HASVARWIDTH)
infomask |= INDEX_VAR_MASK; infomask |= INDEX_VAR_MASK;

View File

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

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/hash/hash.c,v 1.76 2004/12/31 21:59:13 pgsql Exp $ * $PostgreSQL: pgsql/src/backend/access/hash/hash.c,v 1.77 2005/03/21 01:23:57 tgl Exp $
* *
* NOTES * NOTES
* This file contains only the public interface routines. * This file contains only the public interface routines.
@ -36,8 +36,8 @@ typedef struct
static void hashbuildCallback(Relation index, static void hashbuildCallback(Relation index,
HeapTuple htup, HeapTuple htup,
Datum *attdata, Datum *values,
char *nulls, bool *isnull,
bool tupleIsAlive, bool tupleIsAlive,
void *state); void *state);
@ -103,18 +103,17 @@ hashbuild(PG_FUNCTION_ARGS)
static void static void
hashbuildCallback(Relation index, hashbuildCallback(Relation index,
HeapTuple htup, HeapTuple htup,
Datum *attdata, Datum *values,
char *nulls, bool *isnull,
bool tupleIsAlive, bool tupleIsAlive,
void *state) void *state)
{ {
HashBuildState *buildstate = (HashBuildState *) state; HashBuildState *buildstate = (HashBuildState *) state;
IndexTuple itup; IndexTuple itup;
HashItem hitem; HashItem hitem;
InsertIndexResult res;
/* form an index tuple and point it at the heap tuple */ /* form an index tuple and point it at the heap tuple */
itup = index_formtuple(RelationGetDescr(index), attdata, nulls); itup = index_form_tuple(RelationGetDescr(index), values, isnull);
itup->t_tid = htup->t_self; itup->t_tid = htup->t_self;
/* Hash indexes don't index nulls, see notes in hashinsert */ /* Hash indexes don't index nulls, see notes in hashinsert */
@ -126,10 +125,7 @@ hashbuildCallback(Relation index,
hitem = _hash_formitem(itup); hitem = _hash_formitem(itup);
res = _hash_doinsert(index, hitem); _hash_doinsert(index, hitem);
if (res)
pfree(res);
buildstate->indtuples += 1; buildstate->indtuples += 1;
@ -141,27 +137,25 @@ hashbuildCallback(Relation index,
* hashinsert() -- insert an index tuple into a hash table. * hashinsert() -- insert an index tuple into a hash table.
* *
* Hash on the index tuple's key, find the appropriate location * Hash on the index tuple's key, find the appropriate location
* for the new tuple, put it there, and return an InsertIndexResult * for the new tuple, and put it there.
* to the caller.
*/ */
Datum Datum
hashinsert(PG_FUNCTION_ARGS) hashinsert(PG_FUNCTION_ARGS)
{ {
Relation rel = (Relation) PG_GETARG_POINTER(0); Relation rel = (Relation) PG_GETARG_POINTER(0);
Datum *datum = (Datum *) PG_GETARG_POINTER(1); Datum *values = (Datum *) PG_GETARG_POINTER(1);
char *nulls = (char *) PG_GETARG_POINTER(2); bool *isnull = (bool *) PG_GETARG_POINTER(2);
ItemPointer ht_ctid = (ItemPointer) PG_GETARG_POINTER(3); ItemPointer ht_ctid = (ItemPointer) PG_GETARG_POINTER(3);
#ifdef NOT_USED #ifdef NOT_USED
Relation heapRel = (Relation) PG_GETARG_POINTER(4); Relation heapRel = (Relation) PG_GETARG_POINTER(4);
bool checkUnique = PG_GETARG_BOOL(5); bool checkUnique = PG_GETARG_BOOL(5);
#endif #endif
InsertIndexResult res;
HashItem hitem; HashItem hitem;
IndexTuple itup; IndexTuple itup;
/* generate an index tuple */ /* generate an index tuple */
itup = index_formtuple(RelationGetDescr(rel), datum, nulls); itup = index_form_tuple(RelationGetDescr(rel), values, isnull);
itup->t_tid = *ht_ctid; itup->t_tid = *ht_ctid;
/* /*
@ -176,17 +170,17 @@ hashinsert(PG_FUNCTION_ARGS)
if (IndexTupleHasNulls(itup)) if (IndexTupleHasNulls(itup))
{ {
pfree(itup); pfree(itup);
PG_RETURN_POINTER(NULL); PG_RETURN_BOOL(false);
} }
hitem = _hash_formitem(itup); hitem = _hash_formitem(itup);
res = _hash_doinsert(rel, hitem); _hash_doinsert(rel, hitem);
pfree(hitem); pfree(hitem);
pfree(itup); pfree(itup);
PG_RETURN_POINTER(res); PG_RETURN_BOOL(true);
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/hash/hashinsert.c,v 1.35 2004/12/31 21:59:13 pgsql Exp $ * $PostgreSQL: pgsql/src/backend/access/hash/hashinsert.c,v 1.36 2005/03/21 01:23:57 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -30,7 +30,7 @@ static OffsetNumber _hash_pgaddtup(Relation rel, Buffer buf,
* and hashinsert. By here, hashitem is completely filled in. * and hashinsert. By here, hashitem is completely filled in.
* The datum to be used as a "key" is in the hashitem. * The datum to be used as a "key" is in the hashitem.
*/ */
InsertIndexResult void
_hash_doinsert(Relation rel, HashItem hitem) _hash_doinsert(Relation rel, HashItem hitem)
{ {
Buffer buf; Buffer buf;
@ -39,7 +39,6 @@ _hash_doinsert(Relation rel, HashItem hitem)
IndexTuple itup; IndexTuple itup;
BlockNumber itup_blkno; BlockNumber itup_blkno;
OffsetNumber itup_off; OffsetNumber itup_off;
InsertIndexResult res;
BlockNumber blkno; BlockNumber blkno;
Page page; Page page;
HashPageOpaque pageopaque; HashPageOpaque pageopaque;
@ -190,13 +189,6 @@ _hash_doinsert(Relation rel, HashItem hitem)
/* Finally drop our pin on the metapage */ /* Finally drop our pin on the metapage */
_hash_dropbuf(rel, metabuf); _hash_dropbuf(rel, metabuf);
/* Create the return data structure */
res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData));
ItemPointerSet(&(res->pointerData), itup_blkno, itup_off);
return res;
} }
/* /*

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/heap/tuptoaster.c,v 1.48 2005/03/14 04:41:12 tgl Exp $ * $PostgreSQL: pgsql/src/backend/access/heap/tuptoaster.c,v 1.49 2005/03/21 01:23:58 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
@ -283,7 +283,7 @@ toast_delete(Relation rel, HeapTuple oldtup)
int numAttrs; int numAttrs;
int i; int i;
Datum toast_values[MaxHeapAttributeNumber]; Datum toast_values[MaxHeapAttributeNumber];
char toast_nulls[MaxHeapAttributeNumber]; bool toast_isnull[MaxHeapAttributeNumber];
/* /*
* Get the tuple descriptor and break down the tuple into fields. * Get the tuple descriptor and break down the tuple into fields.
@ -301,7 +301,7 @@ toast_delete(Relation rel, HeapTuple oldtup)
numAttrs = tupleDesc->natts; numAttrs = tupleDesc->natts;
Assert(numAttrs <= MaxHeapAttributeNumber); Assert(numAttrs <= MaxHeapAttributeNumber);
heap_deformtuple(oldtup, tupleDesc, toast_values, toast_nulls); heap_deform_tuple(oldtup, tupleDesc, toast_values, toast_isnull);
/* /*
* Check for external stored attributes and delete them from the * Check for external stored attributes and delete them from the
@ -313,7 +313,7 @@ toast_delete(Relation rel, HeapTuple oldtup)
{ {
Datum value = toast_values[i]; Datum value = toast_values[i];
if (toast_nulls[i] != 'n' && VARATT_IS_EXTERNAL(value)) if (!toast_isnull[i] && VARATT_IS_EXTERNAL(value))
toast_delete_datum(rel, value); toast_delete_datum(rel, value);
} }
} }
@ -343,8 +343,8 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
Size maxDataLen; Size maxDataLen;
char toast_action[MaxHeapAttributeNumber]; char toast_action[MaxHeapAttributeNumber];
char toast_nulls[MaxHeapAttributeNumber]; bool toast_isnull[MaxHeapAttributeNumber];
char toast_oldnulls[MaxHeapAttributeNumber]; bool toast_oldisnull[MaxHeapAttributeNumber];
Datum toast_values[MaxHeapAttributeNumber]; Datum toast_values[MaxHeapAttributeNumber];
Datum toast_oldvalues[MaxHeapAttributeNumber]; Datum toast_oldvalues[MaxHeapAttributeNumber];
int32 toast_sizes[MaxHeapAttributeNumber]; int32 toast_sizes[MaxHeapAttributeNumber];
@ -359,9 +359,9 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
numAttrs = tupleDesc->natts; numAttrs = tupleDesc->natts;
Assert(numAttrs <= MaxHeapAttributeNumber); Assert(numAttrs <= MaxHeapAttributeNumber);
heap_deformtuple(newtup, tupleDesc, toast_values, toast_nulls); heap_deform_tuple(newtup, tupleDesc, toast_values, toast_isnull);
if (oldtup != NULL) if (oldtup != NULL)
heap_deformtuple(oldtup, tupleDesc, toast_oldvalues, toast_oldnulls); heap_deform_tuple(oldtup, tupleDesc, toast_oldvalues, toast_oldisnull);
/* ---------- /* ----------
* Then collect information about the values given * Then collect information about the values given
@ -396,10 +396,10 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
* If the old value is an external stored one, check if it has * If the old value is an external stored one, check if it has
* changed so we have to delete it later. * changed so we have to delete it later.
*/ */
if (att[i]->attlen == -1 && toast_oldnulls[i] != 'n' && if (att[i]->attlen == -1 && !toast_oldisnull[i] &&
VARATT_IS_EXTERNAL(old_value)) VARATT_IS_EXTERNAL(old_value))
{ {
if (toast_nulls[i] == 'n' || !VARATT_IS_EXTERNAL(new_value) || if (toast_isnull[i] || !VARATT_IS_EXTERNAL(new_value) ||
old_value->va_content.va_external.va_valueid != old_value->va_content.va_external.va_valueid !=
new_value->va_content.va_external.va_valueid || new_value->va_content.va_external.va_valueid ||
old_value->va_content.va_external.va_toastrelid != old_value->va_content.va_external.va_toastrelid !=
@ -436,7 +436,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
/* /*
* Handle NULL attributes * Handle NULL attributes
*/ */
if (toast_nulls[i] == 'n') if (toast_isnull[i])
{ {
toast_action[i] = 'p'; toast_action[i] = 'p';
has_nulls = true; has_nulls = true;
@ -499,7 +499,8 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
/* /*
* Look for attributes with attstorage 'x' to compress * Look for attributes with attstorage 'x' to compress
*/ */
while (MAXALIGN(ComputeDataSize(tupleDesc, toast_values, toast_nulls)) > while (MAXALIGN(heap_compute_data_size(tupleDesc,
toast_values, toast_isnull)) >
maxDataLen) maxDataLen)
{ {
int biggest_attno = -1; int biggest_attno = -1;
@ -560,7 +561,8 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
* Second we look for attributes of attstorage 'x' or 'e' that are * Second we look for attributes of attstorage 'x' or 'e' that are
* still inline. * still inline.
*/ */
while (MAXALIGN(ComputeDataSize(tupleDesc, toast_values, toast_nulls)) > while (MAXALIGN(heap_compute_data_size(tupleDesc,
toast_values, toast_isnull)) >
maxDataLen && rel->rd_rel->reltoastrelid != InvalidOid) maxDataLen && rel->rd_rel->reltoastrelid != InvalidOid)
{ {
int biggest_attno = -1; int biggest_attno = -1;
@ -611,7 +613,8 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
* Round 3 - this time we take attributes with storage 'm' into * Round 3 - this time we take attributes with storage 'm' into
* compression * compression
*/ */
while (MAXALIGN(ComputeDataSize(tupleDesc, toast_values, toast_nulls)) > while (MAXALIGN(heap_compute_data_size(tupleDesc,
toast_values, toast_isnull)) >
maxDataLen) maxDataLen)
{ {
int biggest_attno = -1; int biggest_attno = -1;
@ -671,7 +674,8 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
/* /*
* Finally we store attributes of type 'm' external * Finally we store attributes of type 'm' external
*/ */
while (MAXALIGN(ComputeDataSize(tupleDesc, toast_values, toast_nulls)) > while (MAXALIGN(heap_compute_data_size(tupleDesc,
toast_values, toast_isnull)) >
maxDataLen && rel->rd_rel->reltoastrelid != InvalidOid) maxDataLen && rel->rd_rel->reltoastrelid != InvalidOid)
{ {
int biggest_attno = -1; int biggest_attno = -1;
@ -739,7 +743,8 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
new_len += sizeof(Oid); new_len += sizeof(Oid);
new_len = MAXALIGN(new_len); new_len = MAXALIGN(new_len);
Assert(new_len == olddata->t_hoff); Assert(new_len == olddata->t_hoff);
new_len += ComputeDataSize(tupleDesc, toast_values, toast_nulls); new_len += heap_compute_data_size(tupleDesc,
toast_values, toast_isnull);
/* /*
* Allocate new tuple in same context as old one. * Allocate new tuple in same context as old one.
@ -753,12 +758,12 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
*/ */
memcpy(new_data, olddata, olddata->t_hoff); memcpy(new_data, olddata, olddata->t_hoff);
DataFill((char *) new_data + olddata->t_hoff, heap_fill_tuple(tupleDesc,
tupleDesc, toast_values,
toast_values, toast_isnull,
toast_nulls, (char *) new_data + olddata->t_hoff,
&(newtup->t_data->t_infomask), &(newtup->t_data->t_infomask),
has_nulls ? newtup->t_data->t_bits : NULL); has_nulls ? newtup->t_data->t_bits : NULL);
/* /*
* In the case we modified a previously modified tuple again, free * In the case we modified a previously modified tuple again, free
@ -810,7 +815,7 @@ toast_flatten_tuple_attribute(Datum value,
bool need_change = false; bool need_change = false;
bool has_nulls = false; bool has_nulls = false;
Datum toast_values[MaxTupleAttributeNumber]; Datum toast_values[MaxTupleAttributeNumber];
char toast_nulls[MaxTupleAttributeNumber]; bool toast_isnull[MaxTupleAttributeNumber];
bool toast_free[MaxTupleAttributeNumber]; bool toast_free[MaxTupleAttributeNumber];
/* /*
@ -836,7 +841,7 @@ toast_flatten_tuple_attribute(Datum value,
tmptup.t_data = olddata; tmptup.t_data = olddata;
Assert(numAttrs <= MaxTupleAttributeNumber); Assert(numAttrs <= MaxTupleAttributeNumber);
heap_deformtuple(&tmptup, tupleDesc, toast_values, toast_nulls); heap_deform_tuple(&tmptup, tupleDesc, toast_values, toast_isnull);
memset(toast_free, 0, numAttrs * sizeof(bool)); memset(toast_free, 0, numAttrs * sizeof(bool));
@ -845,7 +850,7 @@ toast_flatten_tuple_attribute(Datum value,
/* /*
* Look at non-null varlena attributes * Look at non-null varlena attributes
*/ */
if (toast_nulls[i] == 'n') if (toast_isnull[i])
has_nulls = true; has_nulls = true;
else if (att[i]->attlen == -1) else if (att[i]->attlen == -1)
{ {
@ -879,7 +884,7 @@ toast_flatten_tuple_attribute(Datum value,
new_len += sizeof(Oid); new_len += sizeof(Oid);
new_len = MAXALIGN(new_len); new_len = MAXALIGN(new_len);
Assert(new_len == olddata->t_hoff); Assert(new_len == olddata->t_hoff);
new_len += ComputeDataSize(tupleDesc, toast_values, toast_nulls); new_len += heap_compute_data_size(tupleDesc, toast_values, toast_isnull);
new_data = (HeapTupleHeader) palloc0(new_len); new_data = (HeapTupleHeader) palloc0(new_len);
@ -890,12 +895,12 @@ toast_flatten_tuple_attribute(Datum value,
HeapTupleHeaderSetDatumLength(new_data, new_len); HeapTupleHeaderSetDatumLength(new_data, new_len);
DataFill((char *) new_data + olddata->t_hoff, heap_fill_tuple(tupleDesc,
tupleDesc, toast_values,
toast_values, toast_isnull,
toast_nulls, (char *) new_data + olddata->t_hoff,
&(new_data->t_infomask), &(new_data->t_infomask),
has_nulls ? new_data->t_bits : NULL); has_nulls ? new_data->t_bits : NULL);
/* /*
* Free allocated temp values * Free allocated temp values
@ -955,10 +960,9 @@ toast_save_datum(Relation rel, Datum value)
Relation toastrel; Relation toastrel;
Relation toastidx; Relation toastidx;
HeapTuple toasttup; HeapTuple toasttup;
InsertIndexResult idxres;
TupleDesc toasttupDesc; TupleDesc toasttupDesc;
Datum t_values[3]; Datum t_values[3];
char t_nulls[3]; bool t_isnull[3];
varattrib *result; varattrib *result;
struct struct
{ {
@ -996,9 +1000,9 @@ toast_save_datum(Relation rel, Datum value)
*/ */
t_values[0] = ObjectIdGetDatum(result->va_content.va_external.va_valueid); t_values[0] = ObjectIdGetDatum(result->va_content.va_external.va_valueid);
t_values[2] = PointerGetDatum(&chunk_data); t_values[2] = PointerGetDatum(&chunk_data);
t_nulls[0] = ' '; t_isnull[0] = false;
t_nulls[1] = ' '; t_isnull[1] = false;
t_nulls[2] = ' '; t_isnull[2] = false;
/* /*
* Get the data to process * Get the data to process
@ -1031,7 +1035,7 @@ toast_save_datum(Relation rel, Datum value)
t_values[1] = Int32GetDatum(chunk_seq++); t_values[1] = Int32GetDatum(chunk_seq++);
VARATT_SIZEP(&chunk_data) = chunk_size + VARHDRSZ; VARATT_SIZEP(&chunk_data) = chunk_size + VARHDRSZ;
memcpy(VARATT_DATA(&chunk_data), data_p, chunk_size); memcpy(VARATT_DATA(&chunk_data), data_p, chunk_size);
toasttup = heap_formtuple(toasttupDesc, t_values, t_nulls); toasttup = heap_form_tuple(toasttupDesc, t_values, t_isnull);
if (!HeapTupleIsValid(toasttup)) if (!HeapTupleIsValid(toasttup))
elog(ERROR, "failed to build TOAST tuple"); elog(ERROR, "failed to build TOAST tuple");
@ -1045,16 +1049,13 @@ toast_save_datum(Relation rel, Datum value)
* Note also that there had better not be any user-created index on * Note also that there had better not be any user-created index on
* the TOAST table, since we don't bother to update anything else. * the TOAST table, since we don't bother to update anything else.
*/ */
idxres = index_insert(toastidx, t_values, t_nulls, index_insert(toastidx, t_values, t_isnull,
&(toasttup->t_self), &(toasttup->t_self),
toastrel, toastidx->rd_index->indisunique); toastrel, toastidx->rd_index->indisunique);
if (idxres == NULL)
elog(ERROR, "failed to insert index entry for TOAST tuple");
/* /*
* Free memory * Free memory
*/ */
pfree(idxres);
heap_freetuple(toasttup); heap_freetuple(toasttup);
/* /*

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/index/indexam.c,v 1.77 2004/12/31 21:59:19 pgsql Exp $ * $PostgreSQL: pgsql/src/backend/access/index/indexam.c,v 1.78 2005/03/21 01:23:58 tgl Exp $
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
* index_open - open an index relation by relation OID * index_open - open an index relation by relation OID
@ -211,16 +211,15 @@ index_close(Relation relation)
* index_insert - insert an index tuple into a relation * index_insert - insert an index tuple into a relation
* ---------------- * ----------------
*/ */
InsertIndexResult bool
index_insert(Relation indexRelation, index_insert(Relation indexRelation,
Datum *datums, Datum *values,
char *nulls, bool *isnull,
ItemPointer heap_t_ctid, ItemPointer heap_t_ctid,
Relation heapRelation, Relation heapRelation,
bool check_uniqueness) bool check_uniqueness)
{ {
RegProcedure procedure; RegProcedure procedure;
InsertIndexResult specificResult;
RELATION_CHECKS; RELATION_CHECKS;
GET_REL_PROCEDURE(insert, aminsert); GET_REL_PROCEDURE(insert, aminsert);
@ -228,17 +227,13 @@ index_insert(Relation indexRelation,
/* /*
* have the am's insert proc do all the work. * have the am's insert proc do all the work.
*/ */
specificResult = (InsertIndexResult) return DatumGetBool(OidFunctionCall6(procedure,
DatumGetPointer(OidFunctionCall6(procedure,
PointerGetDatum(indexRelation), PointerGetDatum(indexRelation),
PointerGetDatum(datums), PointerGetDatum(values),
PointerGetDatum(nulls), PointerGetDatum(isnull),
PointerGetDatum(heap_t_ctid), PointerGetDatum(heap_t_ctid),
PointerGetDatum(heapRelation), PointerGetDatum(heapRelation),
BoolGetDatum(check_uniqueness))); BoolGetDatum(check_uniqueness)));
/* must be pfree'ed */
return specificResult;
} }
/* ---------------- /* ----------------

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.119 2004/12/31 21:59:22 pgsql Exp $ * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.120 2005/03/21 01:23:59 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -41,7 +41,7 @@ static Buffer _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf);
static TransactionId _bt_check_unique(Relation rel, BTItem btitem, static TransactionId _bt_check_unique(Relation rel, BTItem btitem,
Relation heapRel, Buffer buf, Relation heapRel, Buffer buf,
ScanKey itup_scankey); ScanKey itup_scankey);
static InsertIndexResult _bt_insertonpg(Relation rel, Buffer buf, static void _bt_insertonpg(Relation rel, Buffer buf,
BTStack stack, BTStack stack,
int keysz, ScanKey scankey, int keysz, ScanKey scankey,
BTItem btitem, BTItem btitem,
@ -71,7 +71,7 @@ static bool _bt_isequal(TupleDesc itupdesc, Page page, OffsetNumber offnum,
* This routine is called by the public interface routines, btbuild * This routine is called by the public interface routines, btbuild
* and btinsert. By here, btitem is filled in, including the TID. * and btinsert. By here, btitem is filled in, including the TID.
*/ */
InsertIndexResult void
_bt_doinsert(Relation rel, BTItem btitem, _bt_doinsert(Relation rel, BTItem btitem,
bool index_is_unique, Relation heapRel) bool index_is_unique, Relation heapRel)
{ {
@ -80,7 +80,6 @@ _bt_doinsert(Relation rel, BTItem btitem,
ScanKey itup_scankey; ScanKey itup_scankey;
BTStack stack; BTStack stack;
Buffer buf; Buffer buf;
InsertIndexResult res;
/* we need a scan key to do our search, so build one */ /* we need a scan key to do our search, so build one */
itup_scankey = _bt_mkscankey(rel, itup); itup_scankey = _bt_mkscankey(rel, itup);
@ -138,14 +137,11 @@ top:
} }
/* do the insertion */ /* do the insertion */
res = _bt_insertonpg(rel, buf, stack, natts, itup_scankey, btitem, _bt_insertonpg(rel, buf, stack, natts, itup_scankey, btitem, 0, false);
0, false);
/* be tidy */ /* be tidy */
_bt_freestack(stack); _bt_freestack(stack);
_bt_freeskey(itup_scankey); _bt_freeskey(itup_scankey);
return res;
} }
/* /*
@ -357,7 +353,7 @@ _bt_check_unique(Relation rel, BTItem btitem, Relation heapRel,
* insertion on internal pages. * insertion on internal pages.
*---------- *----------
*/ */
static InsertIndexResult static void
_bt_insertonpg(Relation rel, _bt_insertonpg(Relation rel,
Buffer buf, Buffer buf,
BTStack stack, BTStack stack,
@ -367,7 +363,6 @@ _bt_insertonpg(Relation rel,
OffsetNumber afteritem, OffsetNumber afteritem,
bool split_only_page) bool split_only_page)
{ {
InsertIndexResult res;
Page page; Page page;
BTPageOpaque lpageop; BTPageOpaque lpageop;
OffsetNumber itup_off; OffsetNumber itup_off;
@ -630,12 +625,6 @@ _bt_insertonpg(Relation rel,
_bt_wrtbuf(rel, buf); _bt_wrtbuf(rel, buf);
} }
/* by here, the new tuple is inserted at itup_blkno/itup_off */
res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData));
ItemPointerSet(&(res->pointerData), itup_blkno, itup_off);
return res;
} }
/* /*
@ -1190,7 +1179,6 @@ _bt_insert_parent(Relation rel,
BlockNumber bknum = BufferGetBlockNumber(buf); BlockNumber bknum = BufferGetBlockNumber(buf);
BlockNumber rbknum = BufferGetBlockNumber(rbuf); BlockNumber rbknum = BufferGetBlockNumber(rbuf);
Page page = BufferGetPage(buf); Page page = BufferGetPage(buf);
InsertIndexResult newres;
BTItem new_item; BTItem new_item;
BTStackData fakestack; BTStackData fakestack;
BTItem ritem; BTItem ritem;
@ -1244,12 +1232,11 @@ _bt_insert_parent(Relation rel,
RelationGetRelationName(rel)); RelationGetRelationName(rel));
/* Recursively update the parent */ /* Recursively update the parent */
newres = _bt_insertonpg(rel, pbuf, stack->bts_parent, _bt_insertonpg(rel, pbuf, stack->bts_parent,
0, NULL, new_item, stack->bts_offset, 0, NULL, new_item, stack->bts_offset,
is_only); is_only);
/* be tidy */ /* be tidy */
pfree(newres);
pfree(new_item); pfree(new_item);
} }
} }

View File

@ -12,7 +12,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.125 2005/03/20 22:00:50 tgl Exp $ * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.126 2005/03/21 01:23:59 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -52,8 +52,8 @@ bool FastBuild = true; /* use SORT instead of insertion build */
static void _bt_restscan(IndexScanDesc scan); static void _bt_restscan(IndexScanDesc scan);
static void btbuildCallback(Relation index, static void btbuildCallback(Relation index,
HeapTuple htup, HeapTuple htup,
Datum *attdata, Datum *values,
char *nulls, bool *isnull,
bool tupleIsAlive, bool tupleIsAlive,
void *state); void *state);
@ -178,18 +178,17 @@ btbuild(PG_FUNCTION_ARGS)
static void static void
btbuildCallback(Relation index, btbuildCallback(Relation index,
HeapTuple htup, HeapTuple htup,
Datum *attdata, Datum *values,
char *nulls, bool *isnull,
bool tupleIsAlive, bool tupleIsAlive,
void *state) void *state)
{ {
BTBuildState *buildstate = (BTBuildState *) state; BTBuildState *buildstate = (BTBuildState *) state;
IndexTuple itup; IndexTuple itup;
BTItem btitem; BTItem btitem;
InsertIndexResult res;
/* form an index tuple and point it at the heap tuple */ /* form an index tuple and point it at the heap tuple */
itup = index_formtuple(RelationGetDescr(index), attdata, nulls); itup = index_form_tuple(RelationGetDescr(index), values, isnull);
itup->t_tid = htup->t_self; itup->t_tid = htup->t_self;
btitem = _bt_formitem(itup); btitem = _bt_formitem(itup);
@ -212,10 +211,8 @@ btbuildCallback(Relation index,
} }
else else
{ {
res = _bt_doinsert(index, btitem, _bt_doinsert(index, btitem,
buildstate->isUnique, buildstate->heapRel); buildstate->isUnique, buildstate->heapRel);
if (res)
pfree(res);
} }
buildstate->indtuples += 1; buildstate->indtuples += 1;
@ -228,33 +225,31 @@ btbuildCallback(Relation index,
* btinsert() -- insert an index tuple into a btree. * btinsert() -- insert an index tuple into a btree.
* *
* Descend the tree recursively, find the appropriate location for our * Descend the tree recursively, find the appropriate location for our
* new tuple, put it there, set its unique OID as appropriate, and * new tuple, and put it there.
* return an InsertIndexResult to the caller.
*/ */
Datum Datum
btinsert(PG_FUNCTION_ARGS) btinsert(PG_FUNCTION_ARGS)
{ {
Relation rel = (Relation) PG_GETARG_POINTER(0); Relation rel = (Relation) PG_GETARG_POINTER(0);
Datum *datum = (Datum *) PG_GETARG_POINTER(1); Datum *values = (Datum *) PG_GETARG_POINTER(1);
char *nulls = (char *) PG_GETARG_POINTER(2); bool *isnull = (bool *) PG_GETARG_POINTER(2);
ItemPointer ht_ctid = (ItemPointer) PG_GETARG_POINTER(3); ItemPointer ht_ctid = (ItemPointer) PG_GETARG_POINTER(3);
Relation heapRel = (Relation) PG_GETARG_POINTER(4); Relation heapRel = (Relation) PG_GETARG_POINTER(4);
bool checkUnique = PG_GETARG_BOOL(5); bool checkUnique = PG_GETARG_BOOL(5);
InsertIndexResult res;
BTItem btitem; BTItem btitem;
IndexTuple itup; IndexTuple itup;
/* generate an index tuple */ /* generate an index tuple */
itup = index_formtuple(RelationGetDescr(rel), datum, nulls); itup = index_form_tuple(RelationGetDescr(rel), values, isnull);
itup->t_tid = *ht_ctid; itup->t_tid = *ht_ctid;
btitem = _bt_formitem(itup); btitem = _bt_formitem(itup);
res = _bt_doinsert(rel, btitem, checkUnique, heapRel); _bt_doinsert(rel, btitem, checkUnique, heapRel);
pfree(btitem); pfree(btitem);
pfree(itup); pfree(itup);
PG_RETURN_POINTER(res); PG_RETURN_BOOL(true);
} }
/* /*

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/rtree/rtree.c,v 1.87 2005/01/24 02:47:26 tgl Exp $ * $PostgreSQL: pgsql/src/backend/access/rtree/rtree.c,v 1.88 2005/03/21 01:24:00 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -81,15 +81,14 @@ typedef struct
/* non-export function prototypes */ /* non-export function prototypes */
static void rtbuildCallback(Relation index, static void rtbuildCallback(Relation index,
HeapTuple htup, HeapTuple htup,
Datum *attdata, Datum *values,
char *nulls, bool *isnull,
bool tupleIsAlive, bool tupleIsAlive,
void *state); void *state);
static InsertIndexResult rtdoinsert(Relation r, IndexTuple itup, static void rtdoinsert(Relation r, IndexTuple itup, RTSTATE *rtstate);
RTSTATE *rtstate);
static void rttighten(Relation r, RTSTACK *stk, Datum datum, int att_size, static void rttighten(Relation r, RTSTACK *stk, Datum datum, int att_size,
RTSTATE *rtstate); RTSTATE *rtstate);
static InsertIndexResult rtdosplit(Relation r, Buffer buffer, RTSTACK *stack, static void rtdosplit(Relation r, Buffer buffer, RTSTACK *stack,
IndexTuple itup, RTSTATE *rtstate); IndexTuple itup, RTSTATE *rtstate);
static void rtintinsert(Relation r, RTSTACK *stk, IndexTuple ltup, static void rtintinsert(Relation r, RTSTACK *stk, IndexTuple ltup,
IndexTuple rtup, RTSTATE *rtstate); IndexTuple rtup, RTSTATE *rtstate);
@ -174,17 +173,16 @@ rtbuild(PG_FUNCTION_ARGS)
static void static void
rtbuildCallback(Relation index, rtbuildCallback(Relation index,
HeapTuple htup, HeapTuple htup,
Datum *attdata, Datum *values,
char *nulls, bool *isnull,
bool tupleIsAlive, bool tupleIsAlive,
void *state) void *state)
{ {
RTBuildState *buildstate = (RTBuildState *) state; RTBuildState *buildstate = (RTBuildState *) state;
IndexTuple itup; IndexTuple itup;
InsertIndexResult res;
/* form an index tuple and point it at the heap tuple */ /* form an index tuple and point it at the heap tuple */
itup = index_formtuple(RelationGetDescr(index), attdata, nulls); itup = index_form_tuple(RelationGetDescr(index), values, isnull);
itup->t_tid = htup->t_self; itup->t_tid = htup->t_self;
/* rtree indexes don't index nulls, see notes in rtinsert */ /* rtree indexes don't index nulls, see notes in rtinsert */
@ -201,10 +199,7 @@ rtbuildCallback(Relation index,
* if you're inserting single tups, but not when you're initializing * if you're inserting single tups, but not when you're initializing
* the whole index at once. * the whole index at once.
*/ */
res = rtdoinsert(index, itup, &buildstate->rtState); rtdoinsert(index, itup, &buildstate->rtState);
if (res)
pfree(res);
buildstate->indtuples += 1; buildstate->indtuples += 1;
@ -221,20 +216,19 @@ Datum
rtinsert(PG_FUNCTION_ARGS) rtinsert(PG_FUNCTION_ARGS)
{ {
Relation r = (Relation) PG_GETARG_POINTER(0); Relation r = (Relation) PG_GETARG_POINTER(0);
Datum *datum = (Datum *) PG_GETARG_POINTER(1); Datum *values = (Datum *) PG_GETARG_POINTER(1);
char *nulls = (char *) PG_GETARG_POINTER(2); bool *isnull = (bool *) PG_GETARG_POINTER(2);
ItemPointer ht_ctid = (ItemPointer) PG_GETARG_POINTER(3); ItemPointer ht_ctid = (ItemPointer) PG_GETARG_POINTER(3);
#ifdef NOT_USED #ifdef NOT_USED
Relation heapRel = (Relation) PG_GETARG_POINTER(4); Relation heapRel = (Relation) PG_GETARG_POINTER(4);
bool checkUnique = PG_GETARG_BOOL(5); bool checkUnique = PG_GETARG_BOOL(5);
#endif #endif
InsertIndexResult res;
IndexTuple itup; IndexTuple itup;
RTSTATE rtState; RTSTATE rtState;
/* generate an index tuple */ /* generate an index tuple */
itup = index_formtuple(RelationGetDescr(r), datum, nulls); itup = index_form_tuple(RelationGetDescr(r), values, isnull);
itup->t_tid = *ht_ctid; itup->t_tid = *ht_ctid;
/* /*
@ -245,7 +239,7 @@ rtinsert(PG_FUNCTION_ARGS)
if (IndexTupleHasNulls(itup)) if (IndexTupleHasNulls(itup))
{ {
pfree(itup); pfree(itup);
PG_RETURN_POINTER(NULL); PG_RETURN_BOOL(false);
} }
initRtstate(&rtState, r); initRtstate(&rtState, r);
@ -255,13 +249,12 @@ rtinsert(PG_FUNCTION_ARGS)
* have acquired exclusive lock on index relation. We need no locking * have acquired exclusive lock on index relation. We need no locking
* here. * here.
*/ */
rtdoinsert(r, itup, &rtState);
res = rtdoinsert(r, itup, &rtState); PG_RETURN_BOOL(true);
PG_RETURN_POINTER(res);
} }
static InsertIndexResult static void
rtdoinsert(Relation r, IndexTuple itup, RTSTATE *rtstate) rtdoinsert(Relation r, IndexTuple itup, RTSTATE *rtstate)
{ {
Page page; Page page;
@ -270,7 +263,6 @@ rtdoinsert(Relation r, IndexTuple itup, RTSTATE *rtstate)
IndexTuple which; IndexTuple which;
OffsetNumber l; OffsetNumber l;
RTSTACK *stack; RTSTACK *stack;
InsertIndexResult res;
RTreePageOpaque opaque; RTreePageOpaque opaque;
Datum datum; Datum datum;
@ -305,10 +297,10 @@ rtdoinsert(Relation r, IndexTuple itup, RTSTATE *rtstate)
if (nospace(page, itup)) if (nospace(page, itup))
{ {
/* need to do a split */ /* need to do a split */
res = rtdosplit(r, buffer, stack, itup, rtstate); rtdosplit(r, buffer, stack, itup, rtstate);
freestack(stack); freestack(stack);
WriteBuffer(buffer); /* don't forget to release buffer! */ WriteBuffer(buffer); /* don't forget to release buffer! */
return res; return;
} }
/* add the item and write the buffer */ /* add the item and write the buffer */
@ -335,12 +327,6 @@ rtdoinsert(Relation r, IndexTuple itup, RTSTATE *rtstate)
/* now expand the page boundary in the parent to include the new child */ /* now expand the page boundary in the parent to include the new child */
rttighten(r, stack, datum, IndexTupleAttSize(itup), rtstate); rttighten(r, stack, datum, IndexTupleAttSize(itup), rtstate);
freestack(stack); freestack(stack);
/* build and return an InsertIndexResult for this insertion */
res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData));
ItemPointerSet(&(res->pointerData), blk, l);
return res;
} }
static void static void
@ -422,7 +408,7 @@ rttighten(Relation r,
* rtpicksplit does the interesting work of choosing the split. * rtpicksplit does the interesting work of choosing the split.
* This routine just does the bit-pushing. * This routine just does the bit-pushing.
*/ */
static InsertIndexResult static void
rtdosplit(Relation r, rtdosplit(Relation r,
Buffer buffer, Buffer buffer,
RTSTACK *stack, RTSTACK *stack,
@ -446,9 +432,7 @@ rtdosplit(Relation r,
rbknum; rbknum;
BlockNumber bufblock; BlockNumber bufblock;
RTreePageOpaque opaque; RTreePageOpaque opaque;
int blank; bool *isnull;
InsertIndexResult res;
char *isnull;
SPLITVEC v; SPLITVEC v;
OffsetNumber *spl_left, OffsetNumber *spl_left,
*spl_right; *spl_right;
@ -493,9 +477,6 @@ rtdosplit(Relation r,
maxoff = PageGetMaxOffsetNumber(p); maxoff = PageGetMaxOffsetNumber(p);
newitemoff = OffsetNumberNext(maxoff); newitemoff = OffsetNumberNext(maxoff);
/* build an InsertIndexResult for this insertion */
res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData));
/* /*
* spl_left contains a list of the offset numbers of the tuples that * spl_left contains a list of the offset numbers of the tuples that
* will go to the left page. For each offset number, get the tuple * will go to the left page. For each offset number, get the tuple
@ -521,9 +502,6 @@ rtdosplit(Relation r,
RelationGetRelationName(r)); RelationGetRelationName(r));
leftoff = OffsetNumberNext(leftoff); leftoff = OffsetNumberNext(leftoff);
if (i == newitemoff)
ItemPointerSet(&(res->pointerData), lbknum, leftoff);
spl_left++; /* advance in left split vector */ spl_left++; /* advance in left split vector */
} }
@ -545,9 +523,6 @@ rtdosplit(Relation r,
RelationGetRelationName(r)); RelationGetRelationName(r));
rightoff = OffsetNumberNext(rightoff); rightoff = OffsetNumberNext(rightoff);
if (i == newitemoff)
ItemPointerSet(&(res->pointerData), rbknum, rightoff);
spl_right++; /* advance in right split vector */ spl_right++; /* advance in right split vector */
} }
@ -582,14 +557,12 @@ rtdosplit(Relation r,
rtadjscans(r, RTOP_SPLIT, bufblock, FirstOffsetNumber); rtadjscans(r, RTOP_SPLIT, bufblock, FirstOffsetNumber);
tupDesc = r->rd_att; tupDesc = r->rd_att;
isnull = (char *) palloc(r->rd_rel->relnatts); isnull = (bool *) palloc(r->rd_rel->relnatts * sizeof(bool));
for (blank = 0; blank < r->rd_rel->relnatts; blank++) memset(isnull, false, r->rd_rel->relnatts * sizeof(bool));
isnull[blank] = ' ';
ltup = index_form_tuple(tupDesc, &(v.spl_ldatum), isnull);
rtup = index_form_tuple(tupDesc, &(v.spl_rdatum), isnull);
ltup = (IndexTuple) index_formtuple(tupDesc,
&(v.spl_ldatum), isnull);
rtup = (IndexTuple) index_formtuple(tupDesc,
&(v.spl_rdatum), isnull);
pfree(isnull); pfree(isnull);
pfree(DatumGetPointer(v.spl_ldatum)); pfree(DatumGetPointer(v.spl_ldatum));
pfree(DatumGetPointer(v.spl_rdatum)); pfree(DatumGetPointer(v.spl_rdatum));
@ -602,8 +575,6 @@ rtdosplit(Relation r,
pfree(ltup); pfree(ltup);
pfree(rtup); pfree(rtup);
return res;
} }
static void static void
@ -619,7 +590,6 @@ rtintinsert(Relation r,
Datum ldatum, Datum ldatum,
rdatum, rdatum,
newdatum; newdatum;
InsertIndexResult res;
if (stk == NULL) if (stk == NULL)
{ {
@ -651,10 +621,9 @@ rtintinsert(Relation r,
newdatum = IndexTupleGetDatum(ltup); newdatum = IndexTupleGetDatum(ltup);
rttighten(r, stk->rts_parent, newdatum, rttighten(r, stk->rts_parent, newdatum,
IndexTupleAttSize(ltup), rtstate); IndexTupleAttSize(ltup), rtstate);
res = rtdosplit(r, b, stk->rts_parent, rtup, rtstate); rtdosplit(r, b, stk->rts_parent, rtup, rtstate);
WriteBuffer(b); /* don't forget to release buffer! - WriteBuffer(b); /* don't forget to release buffer! -
* 01/31/94 */ * 01/31/94 */
pfree(res);
} }
else else
{ {

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.248 2005/03/20 22:00:51 tgl Exp $ * $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.249 2005/03/21 01:24:01 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
@ -889,28 +889,29 @@ BuildIndexInfo(Relation index)
/* ---------------- /* ----------------
* FormIndexDatum * FormIndexDatum
* Construct Datum[] and nullv[] arrays for a new index tuple. * Construct values[] and isnull[] arrays for a new index tuple.
* *
* indexInfo Info about the index * indexInfo Info about the index
* slot Heap tuple for which we must prepare an index entry * slot Heap tuple for which we must prepare an index entry
* estate executor state for evaluating any index expressions * estate executor state for evaluating any index expressions
* datum Array of index Datums (output area) * values Array of index Datums (output area)
* nullv Array of is-null indicators (output area) * isnull Array of is-null indicators (output area)
* *
* When there are no index expressions, estate may be NULL. Otherwise it * When there are no index expressions, estate may be NULL. Otherwise it
* must be supplied, *and* the ecxt_scantuple slot of its per-tuple expr * must be supplied, *and* the ecxt_scantuple slot of its per-tuple expr
* context must point to the heap tuple passed in. * context must point to the heap tuple passed in.
* *
* For largely historical reasons, we don't actually call index_formtuple() * Notice we don't actually call index_form_tuple() here; we just prepare
* here, we just prepare its input arrays datum[] and nullv[]. * its input arrays values[] and isnull[]. This is because the index AM
* may wish to alter the data before storage.
* ---------------- * ----------------
*/ */
void void
FormIndexDatum(IndexInfo *indexInfo, FormIndexDatum(IndexInfo *indexInfo,
TupleTableSlot *slot, TupleTableSlot *slot,
EState *estate, EState *estate,
Datum *datum, Datum *values,
char *nullv) bool *isnull)
{ {
ListCell *indexpr_item; ListCell *indexpr_item;
int i; int i;
@ -954,8 +955,8 @@ FormIndexDatum(IndexInfo *indexInfo,
NULL); NULL);
indexpr_item = lnext(indexpr_item); indexpr_item = lnext(indexpr_item);
} }
datum[i] = iDatum; values[i] = iDatum;
nullv[i] = (isNull) ? 'n' : ' '; isnull[i] = isNull;
} }
if (indexpr_item != NULL) if (indexpr_item != NULL)
@ -1332,8 +1333,8 @@ IndexBuildHeapScan(Relation heapRelation,
{ {
HeapScanDesc scan; HeapScanDesc scan;
HeapTuple heapTuple; HeapTuple heapTuple;
Datum attdata[INDEX_MAX_KEYS]; Datum values[INDEX_MAX_KEYS];
char nulls[INDEX_MAX_KEYS]; bool isnull[INDEX_MAX_KEYS];
double reltuples; double reltuples;
List *predicate; List *predicate;
TupleTableSlot *slot; TupleTableSlot *slot;
@ -1509,17 +1510,17 @@ IndexBuildHeapScan(Relation heapRelation,
FormIndexDatum(indexInfo, FormIndexDatum(indexInfo,
slot, slot,
estate, estate,
attdata, values,
nulls); isnull);
/* /*
* You'd think we should go ahead and build the index tuple here, * You'd think we should go ahead and build the index tuple here,
* but some index AMs want to do further processing on the data * but some index AMs want to do further processing on the data
* first. So pass the attdata and nulls arrays, instead. * first. So pass the values[] and isnull[] arrays, instead.
*/ */
/* Call the AM's callback routine to process the tuple */ /* Call the AM's callback routine to process the tuple */
callback(indexRelation, heapTuple, attdata, nulls, tupleIsAlive, callback(indexRelation, heapTuple, values, isnull, tupleIsAlive,
callback_state); callback_state);
} }

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/indexing.c,v 1.108 2005/03/16 21:38:04 tgl Exp $ * $PostgreSQL: pgsql/src/backend/catalog/indexing.c,v 1.109 2005/03/21 01:24:01 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -75,8 +75,8 @@ CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple)
Relation heapRelation; Relation heapRelation;
TupleTableSlot *slot; TupleTableSlot *slot;
IndexInfo **indexInfoArray; IndexInfo **indexInfoArray;
Datum datum[INDEX_MAX_KEYS]; Datum values[INDEX_MAX_KEYS];
char nullv[INDEX_MAX_KEYS]; bool isnull[INDEX_MAX_KEYS];
/* /*
* Get information from the state structure. Fall out if nothing to do. * Get information from the state structure. Fall out if nothing to do.
@ -98,7 +98,6 @@ CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple)
for (i = 0; i < numIndexes; i++) for (i = 0; i < numIndexes; i++)
{ {
IndexInfo *indexInfo; IndexInfo *indexInfo;
InsertIndexResult result;
indexInfo = indexInfoArray[i]; indexInfo = indexInfoArray[i];
@ -110,27 +109,24 @@ CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple)
Assert(indexInfo->ii_Predicate == NIL); Assert(indexInfo->ii_Predicate == NIL);
/* /*
* FormIndexDatum fills in its datum and null parameters with * FormIndexDatum fills in its values and isnull parameters with
* attribute information taken from the given tuple. * the appropriate values for the column(s) of the index.
*/ */
FormIndexDatum(indexInfo, FormIndexDatum(indexInfo,
slot, slot,
NULL, /* no expression eval to do */ NULL, /* no expression eval to do */
datum, values,
nullv); isnull);
/* /*
* The index AM does the rest. * The index AM does the rest.
*/ */
result = index_insert(relationDescs[i], /* index relation */ index_insert(relationDescs[i], /* index relation */
datum, /* array of heaptuple Datums */ values, /* array of index Datums */
nullv, /* info on nulls */ isnull, /* is-null flags */
&(heapTuple->t_self), /* tid of heap tuple */ &(heapTuple->t_self), /* tid of heap tuple */
heapRelation, heapRelation,
relationDescs[i]->rd_index->indisunique); relationDescs[i]->rd_index->indisunique);
if (result)
pfree(result);
} }
ExecDropSingleTupleTableSlot(slot); ExecDropSingleTupleTableSlot(slot);

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.83 2005/03/16 21:38:05 tgl Exp $ * $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.84 2005/03/21 01:24:02 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -448,8 +448,8 @@ compute_index_stats(Relation onerel, double totalrows,
{ {
MemoryContext ind_context, MemoryContext ind_context,
old_context; old_context;
Datum attdata[INDEX_MAX_KEYS]; Datum values[INDEX_MAX_KEYS];
char nulls[INDEX_MAX_KEYS]; bool isnull[INDEX_MAX_KEYS];
int ind, int ind,
i; i;
@ -528,8 +528,8 @@ compute_index_stats(Relation onerel, double totalrows,
FormIndexDatum(indexInfo, FormIndexDatum(indexInfo,
slot, slot,
estate, estate,
attdata, values,
nulls); isnull);
/* /*
* Save just the columns we care about. * Save just the columns we care about.
@ -539,8 +539,8 @@ compute_index_stats(Relation onerel, double totalrows,
VacAttrStats *stats = thisdata->vacattrstats[i]; VacAttrStats *stats = thisdata->vacattrstats[i];
int attnum = stats->attr->attnum; int attnum = stats->attr->attnum;
exprvals[tcnt] = attdata[attnum - 1]; exprvals[tcnt] = values[attnum - 1];
exprnulls[tcnt] = (nulls[attnum - 1] == 'n'); exprnulls[tcnt] = isnull[attnum - 1];
tcnt++; tcnt++;
} }
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/execUtils.c,v 1.118 2005/03/16 21:38:07 tgl Exp $ * $PostgreSQL: pgsql/src/backend/executor/execUtils.c,v 1.119 2005/03/21 01:24:03 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -861,8 +861,8 @@ ExecInsertIndexTuples(TupleTableSlot *slot,
Relation heapRelation; Relation heapRelation;
IndexInfo **indexInfoArray; IndexInfo **indexInfoArray;
ExprContext *econtext; ExprContext *econtext;
Datum datum[INDEX_MAX_KEYS]; Datum values[INDEX_MAX_KEYS];
char nullv[INDEX_MAX_KEYS]; bool isnull[INDEX_MAX_KEYS];
/* /*
* Get information from the result relation info structure. * Get information from the result relation info structure.
@ -889,7 +889,6 @@ ExecInsertIndexTuples(TupleTableSlot *slot,
for (i = 0; i < numIndices; i++) for (i = 0; i < numIndices; i++)
{ {
IndexInfo *indexInfo; IndexInfo *indexInfo;
InsertIndexResult result;
if (relationDescs[i] == NULL) if (relationDescs[i] == NULL)
continue; continue;
@ -920,35 +919,31 @@ ExecInsertIndexTuples(TupleTableSlot *slot,
} }
/* /*
* FormIndexDatum fills in its datum and null parameters with * FormIndexDatum fills in its values and isnull parameters with
* attribute information taken from the given tuple. It also * the appropriate values for the column(s) of the index.
* computes any expressions needed.
*/ */
FormIndexDatum(indexInfo, FormIndexDatum(indexInfo,
slot, slot,
estate, estate,
datum, values,
nullv); isnull);
/* /*
* The index AM does the rest. Note we suppress unique-index * The index AM does the rest. Note we suppress unique-index
* checks if we are being called from VACUUM, since VACUUM may * checks if we are being called from VACUUM, since VACUUM may
* need to move dead tuples that have the same keys as live ones. * need to move dead tuples that have the same keys as live ones.
*/ */
result = index_insert(relationDescs[i], /* index relation */ index_insert(relationDescs[i], /* index relation */
datum, /* array of index Datums */ values, /* array of index Datums */
nullv, /* info on nulls */ isnull, /* null flags */
tupleid, /* tid of heap tuple */ tupleid, /* tid of heap tuple */
heapRelation, heapRelation,
relationDescs[i]->rd_index->indisunique && !is_vacuum); relationDescs[i]->rd_index->indisunique && !is_vacuum);
/* /*
* keep track of index inserts for debugging * keep track of index inserts for debugging
*/ */
IncrIndexInserted(); IncrIndexInserted();
if (result)
pfree(result);
} }
} }

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/access/genam.h,v 1.47 2004/12/31 22:03:21 pgsql Exp $ * $PostgreSQL: pgsql/src/include/access/genam.h,v 1.48 2005/03/21 01:24:04 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -72,8 +72,8 @@ extern Relation index_open(Oid relationId);
extern Relation index_openrv(const RangeVar *relation); extern Relation index_openrv(const RangeVar *relation);
extern Relation index_openr(const char *sysRelationName); extern Relation index_openr(const char *sysRelationName);
extern void index_close(Relation relation); extern void index_close(Relation relation);
extern InsertIndexResult index_insert(Relation indexRelation, extern bool index_insert(Relation indexRelation,
Datum *datums, char *nulls, Datum *values, bool *isnull,
ItemPointer heap_t_ctid, ItemPointer heap_t_ctid,
Relation heapRelation, Relation heapRelation,
bool check_uniqueness); bool check_uniqueness);

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/access/hash.h,v 1.59 2004/12/31 22:03:21 pgsql Exp $ * $PostgreSQL: pgsql/src/include/access/hash.h,v 1.60 2005/03/21 01:24:04 tgl Exp $
* *
* NOTES * NOTES
* modeled after Margo Seltzer's hash implementation for unix. * modeled after Margo Seltzer's hash implementation for unix.
@ -266,7 +266,7 @@ extern Datum hash_any(register const unsigned char *k, register int keylen);
/* private routines */ /* private routines */
/* hashinsert.c */ /* hashinsert.c */
extern InsertIndexResult _hash_doinsert(Relation rel, HashItem hitem); extern void _hash_doinsert(Relation rel, HashItem hitem);
/* hashovfl.c */ /* hashovfl.c */
extern Buffer _hash_addovflpage(Relation rel, Buffer metabuf, Buffer buf); extern Buffer _hash_addovflpage(Relation rel, Buffer metabuf, Buffer buf);

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/access/heapam.h,v 1.97 2005/03/20 23:40:29 neilc Exp $ * $PostgreSQL: pgsql/src/include/access/heapam.h,v 1.98 2005/03/21 01:24:04 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -180,13 +180,9 @@ extern XLogRecPtr log_heap_move(Relation reln, Buffer oldbuf,
/* in common/heaptuple.c */ /* in common/heaptuple.c */
extern Size heap_compute_data_size(TupleDesc tupleDesc, extern Size heap_compute_data_size(TupleDesc tupleDesc,
Datum *values, bool *isnull); Datum *values, bool *isnull);
extern Size ComputeDataSize(TupleDesc tupleDesc, Datum *values, char *nulls);
extern void heap_fill_tuple(TupleDesc tupleDesc, extern void heap_fill_tuple(TupleDesc tupleDesc,
Datum *values, bool *isnull, Datum *values, bool *isnull,
char *data, uint16 *infomask, bits8 *bit); char *data, uint16 *infomask, bits8 *bit);
extern void DataFill(char *data, TupleDesc tupleDesc,
Datum *values, char *nulls, uint16 *infomask,
bits8 *bit);
extern bool heap_attisnull(HeapTuple tup, int attnum); extern bool heap_attisnull(HeapTuple tup, int attnum);
extern Datum nocachegetattr(HeapTuple tup, int attnum, extern Datum nocachegetattr(HeapTuple tup, int attnum,
TupleDesc att, bool *isnull); TupleDesc att, bool *isnull);

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/access/itup.h,v 1.41 2004/12/31 22:03:21 pgsql Exp $ * $PostgreSQL: pgsql/src/include/access/itup.h,v 1.42 2005/03/21 01:24:04 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -46,14 +46,6 @@ typedef struct IndexTupleData
typedef IndexTupleData *IndexTuple; typedef IndexTupleData *IndexTuple;
typedef struct InsertIndexResultData
{
ItemPointerData pointerData;
} InsertIndexResultData;
typedef InsertIndexResultData *InsertIndexResult;
/* ---------------- /* ----------------
* externs * externs
* ---------------- * ----------------
@ -73,7 +65,7 @@ typedef InsertIndexResultData *InsertIndexResult;
/* /*
* Takes an infomask as argument (primarily because this needs to be usable * Takes an infomask as argument (primarily because this needs to be usable
* at index_formtuple time so enough space is allocated). * at index_form_tuple time so enough space is allocated).
* *
* Change me if adding an attribute to IndexTuples!!!!!!!!!!! * Change me if adding an attribute to IndexTuples!!!!!!!!!!!
*/ */
@ -134,8 +126,8 @@ typedef InsertIndexResultData *InsertIndexResult;
/* routines in indextuple.c */ /* routines in indextuple.c */
extern IndexTuple index_formtuple(TupleDesc tupleDescriptor, extern IndexTuple index_form_tuple(TupleDesc tupleDescriptor,
Datum *value, char *null); Datum *values, bool *isnull);
extern Datum nocache_index_getattr(IndexTuple tup, int attnum, extern Datum nocache_index_getattr(IndexTuple tup, int attnum,
TupleDesc tupleDesc, bool *isnull); TupleDesc tupleDesc, bool *isnull);
extern IndexTuple CopyIndexTuple(IndexTuple source); extern IndexTuple CopyIndexTuple(IndexTuple source);

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/access/nbtree.h,v 1.83 2004/12/31 22:03:21 pgsql Exp $ * $PostgreSQL: pgsql/src/include/access/nbtree.h,v 1.84 2005/03/21 01:24:04 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -416,7 +416,7 @@ extern Datum btvacuumcleanup(PG_FUNCTION_ARGS);
/* /*
* prototypes for functions in nbtinsert.c * prototypes for functions in nbtinsert.c
*/ */
extern InsertIndexResult _bt_doinsert(Relation rel, BTItem btitem, extern void _bt_doinsert(Relation rel, BTItem btitem,
bool index_is_unique, Relation heapRel); bool index_is_unique, Relation heapRel);
extern Buffer _bt_getstackbuf(Relation rel, BTStack stack, int access); extern Buffer _bt_getstackbuf(Relation rel, BTStack stack, int access);
extern void _bt_insert_parent(Relation rel, Buffer buf, Buffer rbuf, extern void _bt_insert_parent(Relation rel, Buffer buf, Buffer rbuf,

View File

@ -6,7 +6,7 @@
* *
* Copyright (c) 2000-2005, PostgreSQL Global Development Group * Copyright (c) 2000-2005, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/include/access/tuptoaster.h,v 1.21 2005/01/01 05:43:09 momjian Exp $ * $PostgreSQL: pgsql/src/include/access/tuptoaster.h,v 1.22 2005/03/21 01:24:04 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -41,7 +41,7 @@
/* /*
* If an index value is larger than TOAST_INDEX_TARGET, we will try to * If an index value is larger than TOAST_INDEX_TARGET, we will try to
* compress it (we can't move it out-of-line, however). Note that this * compress it (we can't move it out-of-line, however). Note that this
* number is per-datum, not per-tuple, for simplicity in index_formtuple(). * number is per-datum, not per-tuple, for simplicity in index_form_tuple().
*/ */
#define TOAST_INDEX_TARGET (MaxTupleSize / 16) #define TOAST_INDEX_TARGET (MaxTupleSize / 16)

View File

@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.258 2005/03/16 22:59:42 momjian Exp $ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.259 2005/03/21 01:24:04 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200503161 #define CATALOG_VERSION_NO 200503201
#endif #endif

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/index.h,v 1.60 2005/03/16 21:38:09 tgl Exp $ * $PostgreSQL: pgsql/src/include/catalog/index.h,v 1.61 2005/03/21 01:24:04 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -23,11 +23,11 @@
/* Typedef for callback function for IndexBuildHeapScan */ /* Typedef for callback function for IndexBuildHeapScan */
typedef void (*IndexBuildCallback) (Relation index, typedef void (*IndexBuildCallback) (Relation index,
HeapTuple htup, HeapTuple htup,
Datum *attdata, Datum *values,
char *nulls, bool *isnull,
bool tupleIsAlive, bool tupleIsAlive,
void *state); void *state);
extern Oid index_create(Oid heapRelationId, extern Oid index_create(Oid heapRelationId,
@ -48,8 +48,8 @@ extern IndexInfo *BuildIndexInfo(Relation index);
extern void FormIndexDatum(IndexInfo *indexInfo, extern void FormIndexDatum(IndexInfo *indexInfo,
TupleTableSlot *slot, TupleTableSlot *slot,
EState *estate, EState *estate,
Datum *datum, Datum *values,
char *nullv); bool *isnull);
extern void UpdateStats(Oid relid, double reltuples); extern void UpdateStats(Oid relid, double reltuples);

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.352 2005/02/28 03:45:22 neilc Exp $ * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.353 2005/03/21 01:24:04 tgl Exp $
* *
* NOTES * NOTES
* The script catalog/genbki.sh reads this file and generates .bki * The script catalog/genbki.sh reads this file and generates .bki
@ -660,7 +660,7 @@ DESCR("convert int4 to float4");
DATA(insert OID = 319 ( int4 PGNSP PGUID 12 f f t f i 1 23 "700" _null_ ftoi4 - _null_ )); DATA(insert OID = 319 ( int4 PGNSP PGUID 12 f f t f i 1 23 "700" _null_ ftoi4 - _null_ ));
DESCR("convert float4 to int4"); DESCR("convert float4 to int4");
DATA(insert OID = 320 ( rtinsert PGNSP PGUID 12 f f t f v 6 2281 "2281 2281 2281 2281 2281 2281" _null_ rtinsert - _null_ )); DATA(insert OID = 320 ( rtinsert PGNSP PGUID 12 f f t f v 6 16 "2281 2281 2281 2281 2281 2281" _null_ rtinsert - _null_ ));
DESCR("r-tree(internal)"); DESCR("r-tree(internal)");
DATA(insert OID = 322 ( rtgettuple PGNSP PGUID 12 f f t f v 2 16 "2281 2281" _null_ rtgettuple - _null_ )); DATA(insert OID = 322 ( rtgettuple PGNSP PGUID 12 f f t f v 2 16 "2281 2281" _null_ rtgettuple - _null_ ));
DESCR("r-tree(internal)"); DESCR("r-tree(internal)");
@ -683,7 +683,7 @@ DESCR("r-tree(internal)");
DATA(insert OID = 330 ( btgettuple PGNSP PGUID 12 f f t f v 2 16 "2281 2281" _null_ btgettuple - _null_ )); DATA(insert OID = 330 ( btgettuple PGNSP PGUID 12 f f t f v 2 16 "2281 2281" _null_ btgettuple - _null_ ));
DESCR("btree(internal)"); DESCR("btree(internal)");
DATA(insert OID = 331 ( btinsert PGNSP PGUID 12 f f t f v 6 2281 "2281 2281 2281 2281 2281 2281" _null_ btinsert - _null_ )); DATA(insert OID = 331 ( btinsert PGNSP PGUID 12 f f t f v 6 16 "2281 2281 2281 2281 2281 2281" _null_ btinsert - _null_ ));
DESCR("btree(internal)"); DESCR("btree(internal)");
DATA(insert OID = 333 ( btbeginscan PGNSP PGUID 12 f f t f v 3 2281 "2281 2281 2281" _null_ btbeginscan - _null_ )); DATA(insert OID = 333 ( btbeginscan PGNSP PGUID 12 f f t f v 3 2281 "2281 2281 2281" _null_ btbeginscan - _null_ ));
DESCR("btree(internal)"); DESCR("btree(internal)");
@ -798,7 +798,7 @@ DESCR("convert char(n) to name");
DATA(insert OID = 440 ( hashgettuple PGNSP PGUID 12 f f t f v 2 16 "2281 2281" _null_ hashgettuple - _null_ )); DATA(insert OID = 440 ( hashgettuple PGNSP PGUID 12 f f t f v 2 16 "2281 2281" _null_ hashgettuple - _null_ ));
DESCR("hash(internal)"); DESCR("hash(internal)");
DATA(insert OID = 441 ( hashinsert PGNSP PGUID 12 f f t f v 6 2281 "2281 2281 2281 2281 2281 2281" _null_ hashinsert - _null_ )); DATA(insert OID = 441 ( hashinsert PGNSP PGUID 12 f f t f v 6 16 "2281 2281 2281 2281 2281 2281" _null_ hashinsert - _null_ ));
DESCR("hash(internal)"); DESCR("hash(internal)");
DATA(insert OID = 443 ( hashbeginscan PGNSP PGUID 12 f f t f v 3 2281 "2281 2281 2281" _null_ hashbeginscan - _null_ )); DATA(insert OID = 443 ( hashbeginscan PGNSP PGUID 12 f f t f v 3 2281 "2281 2281 2281" _null_ hashbeginscan - _null_ ));
DESCR("hash(internal)"); DESCR("hash(internal)");
@ -1060,7 +1060,7 @@ DESCR("smaller of two");
DATA(insert OID = 774 ( gistgettuple PGNSP PGUID 12 f f t f v 2 16 "2281 2281" _null_ gistgettuple - _null_ )); DATA(insert OID = 774 ( gistgettuple PGNSP PGUID 12 f f t f v 2 16 "2281 2281" _null_ gistgettuple - _null_ ));
DESCR("gist(internal)"); DESCR("gist(internal)");
DATA(insert OID = 775 ( gistinsert PGNSP PGUID 12 f f t f v 6 2281 "2281 2281 2281 2281 2281 2281" _null_ gistinsert - _null_ )); DATA(insert OID = 775 ( gistinsert PGNSP PGUID 12 f f t f v 6 16 "2281 2281 2281 2281 2281 2281" _null_ gistinsert - _null_ ));
DESCR("gist(internal)"); DESCR("gist(internal)");
DATA(insert OID = 777 ( gistbeginscan PGNSP PGUID 12 f f t f v 3 2281 "2281 2281 2281" _null_ gistbeginscan - _null_ )); DATA(insert OID = 777 ( gistbeginscan PGNSP PGUID 12 f f t f v 3 2281 "2281 2281 2281" _null_ gistbeginscan - _null_ ));
DESCR("gist(internal)"); DESCR("gist(internal)");