<!--
-$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">
<para>
<programlisting>
-InsertIndexResult
+bool
aminsert (Relation indexRelation,
- Datum *datums,
- char *nulls,
+ Datum *values,
+ bool *isnull,
ItemPointer heap_tid,
Relation heapRelation,
bool check_uniqueness);
</programlisting>
- Insert a new tuple into an existing index. The <literal>datums</> and
- <literal>nulls</> arrays give the key values to be indexed, and
+ Insert a new tuple into an existing index. The <literal>values</> and
+ <literal>isnull</> arrays give the key values to be indexed, and
<literal>heap_tid</> is the TID to be indexed.
If the access method supports unique indexes (its
<structname>pg_am</>.<structfield>amcanunique</> flag is true) then
must verify that there is no conflicting row; this is the only situation in
which the access method normally needs the <literal>heapRelation</>
parameter. See <xref linkend="index-unique-checks"> for details.
- The result is a struct that must be pfree'd by the caller. (The result
- struct is really quite useless and should be removed...)
+ The result is TRUE if an index entry was inserted, FALSE if not. (A FALSE
+ result does not denote an error condition, but is used for cases such
+ as an index AM refusing to index a NULL.)
</para>
<para>
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
* OLD API with char 'n'/' ' convention for indicating nulls
* ----------------
*/
-Size
+static Size
ComputeDataSize(TupleDesc tupleDesc,
Datum *values,
char *nulls)
* OLD API with char 'n'/' ' convention for indicating nulls
* ----------------
*/
-void
+static void
DataFill(char *data,
TupleDesc tupleDesc,
Datum *values,
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
*/
/* ----------------
- * index_formtuple
+ * index_form_tuple
* ----------------
*/
IndexTuple
-index_formtuple(TupleDesc tupleDescriptor,
- Datum *value,
- char *null)
+index_form_tuple(TupleDesc tupleDescriptor,
+ Datum *values,
+ bool *isnull)
{
char *tp; /* tuple pointer */
IndexTuple tuple; /* return tuple */
int numberOfAttributes = tupleDescriptor->natts;
#ifdef TOAST_INDEX_HACK
- Datum untoasted_value[INDEX_MAX_KEYS];
+ Datum untoasted_values[INDEX_MAX_KEYS];
bool untoasted_free[INDEX_MAX_KEYS];
#endif
{
Form_pg_attribute att = tupleDescriptor->attrs[i];
- untoasted_value[i] = value[i];
+ untoasted_values[i] = values[i];
untoasted_free[i] = false;
/* Do nothing if value is NULL or not of varlena type */
- if (null[i] != ' ' || att->attlen != -1)
+ if (isnull[i] || att->attlen != -1)
continue;
/*
* If value is stored EXTERNAL, must fetch it so we are not
* 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(
- (varattrib *) DatumGetPointer(value[i])));
+ (varattrib *) DatumGetPointer(values[i])));
untoasted_free[i] = true;
}
* If value is above size target, and is of a compressible
* datatype, try to compress it in-line.
*/
- if (VARATT_SIZE(untoasted_value[i]) > TOAST_INDEX_TARGET &&
- !VARATT_IS_EXTENDED(untoasted_value[i]) &&
+ if (VARATT_SIZE(untoasted_values[i]) > TOAST_INDEX_TARGET &&
+ !VARATT_IS_EXTENDED(untoasted_values[i]) &&
(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)
{
/* successful compression */
if (untoasted_free[i])
- pfree(DatumGetPointer(untoasted_value[i]));
- untoasted_value[i] = cvalue;
+ pfree(DatumGetPointer(untoasted_values[i]));
+ untoasted_values[i] = cvalue;
untoasted_free[i] = true;
}
}
for (i = 0; i < numberOfAttributes; i++)
{
- if (null[i] != ' ')
+ if (isnull[i])
{
hasnull = true;
break;
hoff = IndexInfoFindDataOffset(infomask);
#ifdef TOAST_INDEX_HACK
- size = hoff + ComputeDataSize(tupleDescriptor, untoasted_value, null);
+ size = hoff + heap_compute_data_size(tupleDescriptor,
+ untoasted_values, isnull);
#else
- size = hoff + ComputeDataSize(tupleDescriptor, value, null);
+ size = hoff + heap_compute_data_size(tupleDescriptor,
+ values, isnull);
#endif
size = MAXALIGN(size); /* be conservative */
tp = (char *) palloc0(size);
tuple = (IndexTuple) tp;
- DataFill((char *) tp + hoff,
- tupleDescriptor,
+ heap_fill_tuple(tupleDescriptor,
#ifdef TOAST_INDEX_HACK
- untoasted_value,
+ untoasted_values,
#else
- value,
+ values,
#endif
- null,
- &tupmask,
- (hasnull ? (bits8 *) tp + sizeof(*tuple) : NULL));
+ isnull,
+ (char *) tp + hoff,
+ &tupmask,
+ (hasnull ? (bits8 *) tp + sizeof(*tuple) : NULL));
#ifdef TOAST_INDEX_HACK
for (i = 0; i < numberOfAttributes; i++)
{
if (untoasted_free[i])
- pfree(DatumGetPointer(untoasted_value[i]));
+ pfree(DatumGetPointer(untoasted_values[i]));
}
#endif
/*
- * We do this because DataFill wants to initialize a "tupmask" which
- * is used for HeapTuples, but we want an indextuple infomask. The
- * only relevant info is the "has variable attributes" field. We have
- * already set the hasnull bit above.
+ * We do this because heap_fill_tuple wants to initialize a "tupmask"
+ * which is used for HeapTuples, but we want an indextuple infomask.
+ * The only relevant info is the "has variable attributes" field.
+ * We have already set the hasnull bit above.
*/
-
if (tupmask & HEAP_HASVARWIDTH)
infomask |= INDEX_VAR_MASK;
* 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 $
*
*-------------------------------------------------------------------------
*/
/* 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,
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);
static void
gistbuildCallback(Relation index,
HeapTuple htup,
- Datum *attdata,
- char *nulls,
+ Datum *values,
+ bool *isnull,
bool tupleIsAlive,
void *state)
{
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;
/*
* 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);
}
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;
*/
/* 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
static void
gistdoinsert(Relation r,
IndexTuple itup,
- InsertIndexResult *res,
GISTSTATE *giststate)
{
IndexTuple *instup;
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);
gistlayerinsert(Relation r, BlockNumber blkno,
IndexTuple **itup, /* in - out, has compressed entry */
int *len, /* in - out */
- InsertIndexResult *res, /* out */
GISTSTATE *giststate)
{
Buffer buffer;
* 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))
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]);
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;
{
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,
if (reallen == 0)
{
attr[j] = (Datum) 0;
- isnull[j] = 'n';
+ isnull[j] = TRUE;
whatfree[j] = FALSE;
}
else
gistcentryinit(giststate, j, ¢ry[j], datum,
NULL, NULL, (OffsetNumber) 0,
datumsize, FALSE, FALSE);
- isnull[j] = ' ';
+ isnull[j] = FALSE;
attr[j] = centry[j].key;
if (!isAttByVal(giststate, j))
{
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]));
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],
{
if (oldisnull[j] && addisnull[j])
{
- isnull[j] = 'n';
attr[j] = (Datum) 0;
+ isnull[j] = TRUE;
whatfree[j] = FALSE;
}
else
NULL, NULL, (OffsetNumber) 0,
datumsize, FALSE, FALSE);
- isnull[j] = ' ';
attr[j] = centry[j].key;
+ isnull[j] = FALSE;
if ((!isAttByVal(giststate, j)))
{
whatfree[j] = TRUE;
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;
}
/* 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++)
Buffer buffer,
IndexTuple *itup, /* contains compressed entry */
int *len,
- GISTSTATE *giststate,
- InsertIndexResult *res)
+ GISTSTATE *giststate)
{
Page p;
Buffer leftbuf,
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])
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);
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++)
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);
/*
* 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 &&
/* 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;
}
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];
{
if (isnull[j])
{
- isnullchar[j] = 'n';
compatt[j] = (Datum) 0;
whatfree[j] = FALSE;
}
gistcentryinit(giststate, j, ¢ry[j], attdata[j],
NULL, NULL, (OffsetNumber) 0,
datumsize[j], FALSE, FALSE);
- isnullchar[j] = ' ';
compatt[j] = centry[j].key;
if (!isAttByVal(giststate, j))
{
}
}
- 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]));
*
*
* 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
* This file contains only the public interface routines.
static void hashbuildCallback(Relation index,
HeapTuple htup,
- Datum *attdata,
- char *nulls,
+ Datum *values,
+ bool *isnull,
bool tupleIsAlive,
void *state);
static void
hashbuildCallback(Relation index,
HeapTuple htup,
- Datum *attdata,
- char *nulls,
+ Datum *values,
+ bool *isnull,
bool tupleIsAlive,
void *state)
{
HashBuildState *buildstate = (HashBuildState *) state;
IndexTuple itup;
HashItem hitem;
- InsertIndexResult res;
/* 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;
/* Hash indexes don't index nulls, see notes in hashinsert */
hitem = _hash_formitem(itup);
- res = _hash_doinsert(index, hitem);
-
- if (res)
- pfree(res);
+ _hash_doinsert(index, hitem);
buildstate->indtuples += 1;
* hashinsert() -- insert an index tuple into a hash table.
*
* Hash on the index tuple's key, find the appropriate location
- * for the new tuple, put it there, and return an InsertIndexResult
- * to the caller.
+ * for the new tuple, and put it there.
*/
Datum
hashinsert(PG_FUNCTION_ARGS)
{
Relation rel = (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;
HashItem hitem;
IndexTuple itup;
/* generate an index tuple */
- itup = index_formtuple(RelationGetDescr(rel), datum, nulls);
+ itup = index_form_tuple(RelationGetDescr(rel), values, isnull);
itup->t_tid = *ht_ctid;
/*
if (IndexTupleHasNulls(itup))
{
pfree(itup);
- PG_RETURN_POINTER(NULL);
+ PG_RETURN_BOOL(false);
}
hitem = _hash_formitem(itup);
- res = _hash_doinsert(rel, hitem);
+ _hash_doinsert(rel, hitem);
pfree(hitem);
pfree(itup);
- PG_RETURN_POINTER(res);
+ PG_RETURN_BOOL(true);
}
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
* and hashinsert. By here, hashitem is completely filled in.
* The datum to be used as a "key" is in the hashitem.
*/
-InsertIndexResult
+void
_hash_doinsert(Relation rel, HashItem hitem)
{
Buffer buf;
IndexTuple itup;
BlockNumber itup_blkno;
OffsetNumber itup_off;
- InsertIndexResult res;
BlockNumber blkno;
Page page;
HashPageOpaque pageopaque;
/* Finally drop our pin on the metapage */
_hash_dropbuf(rel, metabuf);
-
- /* Create the return data structure */
- res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData));
-
- ItemPointerSet(&(res->pointerData), itup_blkno, itup_off);
-
- return res;
}
/*
*
*
* 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
int numAttrs;
int i;
Datum toast_values[MaxHeapAttributeNumber];
- char toast_nulls[MaxHeapAttributeNumber];
+ bool toast_isnull[MaxHeapAttributeNumber];
/*
* Get the tuple descriptor and break down the tuple into fields.
numAttrs = tupleDesc->natts;
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
{
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);
}
}
Size maxDataLen;
char toast_action[MaxHeapAttributeNumber];
- char toast_nulls[MaxHeapAttributeNumber];
- char toast_oldnulls[MaxHeapAttributeNumber];
+ bool toast_isnull[MaxHeapAttributeNumber];
+ bool toast_oldisnull[MaxHeapAttributeNumber];
Datum toast_values[MaxHeapAttributeNumber];
Datum toast_oldvalues[MaxHeapAttributeNumber];
int32 toast_sizes[MaxHeapAttributeNumber];
numAttrs = tupleDesc->natts;
Assert(numAttrs <= MaxHeapAttributeNumber);
- heap_deformtuple(newtup, tupleDesc, toast_values, toast_nulls);
+ heap_deform_tuple(newtup, tupleDesc, toast_values, toast_isnull);
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
* If the old value is an external stored one, check if it has
* 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))
{
- 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 !=
new_value->va_content.va_external.va_valueid ||
old_value->va_content.va_external.va_toastrelid !=
/*
* Handle NULL attributes
*/
- if (toast_nulls[i] == 'n')
+ if (toast_isnull[i])
{
toast_action[i] = 'p';
has_nulls = true;
/*
* 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)
{
int biggest_attno = -1;
* Second we look for attributes of attstorage 'x' or 'e' that are
* 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)
{
int biggest_attno = -1;
* Round 3 - this time we take attributes with storage 'm' into
* compression
*/
- while (MAXALIGN(ComputeDataSize(tupleDesc, toast_values, toast_nulls)) >
+ while (MAXALIGN(heap_compute_data_size(tupleDesc,
+ toast_values, toast_isnull)) >
maxDataLen)
{
int biggest_attno = -1;
/*
* 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)
{
int biggest_attno = -1;
new_len += sizeof(Oid);
new_len = MAXALIGN(new_len);
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.
*/
memcpy(new_data, olddata, olddata->t_hoff);
- DataFill((char *) new_data + olddata->t_hoff,
- tupleDesc,
- toast_values,
- toast_nulls,
- &(newtup->t_data->t_infomask),
- has_nulls ? newtup->t_data->t_bits : NULL);
+ heap_fill_tuple(tupleDesc,
+ toast_values,
+ toast_isnull,
+ (char *) new_data + olddata->t_hoff,
+ &(newtup->t_data->t_infomask),
+ has_nulls ? newtup->t_data->t_bits : NULL);
/*
* In the case we modified a previously modified tuple again, free
bool need_change = false;
bool has_nulls = false;
Datum toast_values[MaxTupleAttributeNumber];
- char toast_nulls[MaxTupleAttributeNumber];
+ bool toast_isnull[MaxTupleAttributeNumber];
bool toast_free[MaxTupleAttributeNumber];
/*
tmptup.t_data = olddata;
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));
/*
* Look at non-null varlena attributes
*/
- if (toast_nulls[i] == 'n')
+ if (toast_isnull[i])
has_nulls = true;
else if (att[i]->attlen == -1)
{
new_len += sizeof(Oid);
new_len = MAXALIGN(new_len);
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);
HeapTupleHeaderSetDatumLength(new_data, new_len);
- DataFill((char *) new_data + olddata->t_hoff,
- tupleDesc,
- toast_values,
- toast_nulls,
- &(new_data->t_infomask),
- has_nulls ? new_data->t_bits : NULL);
+ heap_fill_tuple(tupleDesc,
+ toast_values,
+ toast_isnull,
+ (char *) new_data + olddata->t_hoff,
+ &(new_data->t_infomask),
+ has_nulls ? new_data->t_bits : NULL);
/*
* Free allocated temp values
Relation toastrel;
Relation toastidx;
HeapTuple toasttup;
- InsertIndexResult idxres;
TupleDesc toasttupDesc;
Datum t_values[3];
- char t_nulls[3];
+ bool t_isnull[3];
varattrib *result;
struct
{
*/
t_values[0] = ObjectIdGetDatum(result->va_content.va_external.va_valueid);
t_values[2] = PointerGetDatum(&chunk_data);
- t_nulls[0] = ' ';
- t_nulls[1] = ' ';
- t_nulls[2] = ' ';
+ t_isnull[0] = false;
+ t_isnull[1] = false;
+ t_isnull[2] = false;
/*
* Get the data to process
t_values[1] = Int32GetDatum(chunk_seq++);
VARATT_SIZEP(&chunk_data) = chunk_size + VARHDRSZ;
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))
elog(ERROR, "failed to build TOAST tuple");
* 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.
*/
- idxres = index_insert(toastidx, t_values, t_nulls,
- &(toasttup->t_self),
- toastrel, toastidx->rd_index->indisunique);
- if (idxres == NULL)
- elog(ERROR, "failed to insert index entry for TOAST tuple");
+ index_insert(toastidx, t_values, t_isnull,
+ &(toasttup->t_self),
+ toastrel, toastidx->rd_index->indisunique);
/*
* Free memory
*/
- pfree(idxres);
heap_freetuple(toasttup);
/*
*
*
* 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
* index_open - open an index relation by relation OID
* index_insert - insert an index tuple into a relation
* ----------------
*/
-InsertIndexResult
+bool
index_insert(Relation indexRelation,
- Datum *datums,
- char *nulls,
+ Datum *values,
+ bool *isnull,
ItemPointer heap_t_ctid,
Relation heapRelation,
bool check_uniqueness)
{
RegProcedure procedure;
- InsertIndexResult specificResult;
RELATION_CHECKS;
GET_REL_PROCEDURE(insert, aminsert);
/*
* have the am's insert proc do all the work.
*/
- specificResult = (InsertIndexResult)
- DatumGetPointer(OidFunctionCall6(procedure,
+ return DatumGetBool(OidFunctionCall6(procedure,
PointerGetDatum(indexRelation),
- PointerGetDatum(datums),
- PointerGetDatum(nulls),
+ PointerGetDatum(values),
+ PointerGetDatum(isnull),
PointerGetDatum(heap_t_ctid),
PointerGetDatum(heapRelation),
BoolGetDatum(check_uniqueness)));
-
- /* must be pfree'ed */
- return specificResult;
}
/* ----------------
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
static TransactionId _bt_check_unique(Relation rel, BTItem btitem,
Relation heapRel, Buffer buf,
ScanKey itup_scankey);
-static InsertIndexResult _bt_insertonpg(Relation rel, Buffer buf,
+static void _bt_insertonpg(Relation rel, Buffer buf,
BTStack stack,
int keysz, ScanKey scankey,
BTItem btitem,
* This routine is called by the public interface routines, btbuild
* and btinsert. By here, btitem is filled in, including the TID.
*/
-InsertIndexResult
+void
_bt_doinsert(Relation rel, BTItem btitem,
bool index_is_unique, Relation heapRel)
{
ScanKey itup_scankey;
BTStack stack;
Buffer buf;
- InsertIndexResult res;
/* we need a scan key to do our search, so build one */
itup_scankey = _bt_mkscankey(rel, itup);
}
/* do the insertion */
- res = _bt_insertonpg(rel, buf, stack, natts, itup_scankey, btitem,
- 0, false);
+ _bt_insertonpg(rel, buf, stack, natts, itup_scankey, btitem, 0, false);
/* be tidy */
_bt_freestack(stack);
_bt_freeskey(itup_scankey);
-
- return res;
}
/*
* insertion on internal pages.
*----------
*/
-static InsertIndexResult
+static void
_bt_insertonpg(Relation rel,
Buffer buf,
BTStack stack,
OffsetNumber afteritem,
bool split_only_page)
{
- InsertIndexResult res;
Page page;
BTPageOpaque lpageop;
OffsetNumber itup_off;
_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;
}
/*
BlockNumber bknum = BufferGetBlockNumber(buf);
BlockNumber rbknum = BufferGetBlockNumber(rbuf);
Page page = BufferGetPage(buf);
- InsertIndexResult newres;
BTItem new_item;
BTStackData fakestack;
BTItem ritem;
RelationGetRelationName(rel));
/* Recursively update the parent */
- newres = _bt_insertonpg(rel, pbuf, stack->bts_parent,
- 0, NULL, new_item, stack->bts_offset,
- is_only);
+ _bt_insertonpg(rel, pbuf, stack->bts_parent,
+ 0, NULL, new_item, stack->bts_offset,
+ is_only);
/* be tidy */
- pfree(newres);
pfree(new_item);
}
}
* Portions Copyright (c) 1994, Regents of the University of California
*
* 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 $
*
*-------------------------------------------------------------------------
*/
static void _bt_restscan(IndexScanDesc scan);
static void btbuildCallback(Relation index,
HeapTuple htup,
- Datum *attdata,
- char *nulls,
+ Datum *values,
+ bool *isnull,
bool tupleIsAlive,
void *state);
static void
btbuildCallback(Relation index,
HeapTuple htup,
- Datum *attdata,
- char *nulls,
+ Datum *values,
+ bool *isnull,
bool tupleIsAlive,
void *state)
{
BTBuildState *buildstate = (BTBuildState *) state;
IndexTuple itup;
BTItem btitem;
- InsertIndexResult res;
/* 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;
btitem = _bt_formitem(itup);
}
else
{
- res = _bt_doinsert(index, btitem,
- buildstate->isUnique, buildstate->heapRel);
- if (res)
- pfree(res);
+ _bt_doinsert(index, btitem,
+ buildstate->isUnique, buildstate->heapRel);
}
buildstate->indtuples += 1;
* btinsert() -- insert an index tuple into a btree.
*
* Descend the tree recursively, find the appropriate location for our
- * new tuple, put it there, set its unique OID as appropriate, and
- * return an InsertIndexResult to the caller.
+ * new tuple, and put it there.
*/
Datum
btinsert(PG_FUNCTION_ARGS)
{
Relation rel = (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);
Relation heapRel = (Relation) PG_GETARG_POINTER(4);
bool checkUnique = PG_GETARG_BOOL(5);
- InsertIndexResult res;
BTItem btitem;
IndexTuple itup;
/* generate an index tuple */
- itup = index_formtuple(RelationGetDescr(rel), datum, nulls);
+ itup = index_form_tuple(RelationGetDescr(rel), values, isnull);
itup->t_tid = *ht_ctid;
btitem = _bt_formitem(itup);
- res = _bt_doinsert(rel, btitem, checkUnique, heapRel);
+ _bt_doinsert(rel, btitem, checkUnique, heapRel);
pfree(btitem);
pfree(itup);
- PG_RETURN_POINTER(res);
+ PG_RETURN_BOOL(true);
}
/*
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
/* non-export function prototypes */
static void rtbuildCallback(Relation index,
HeapTuple htup,
- Datum *attdata,
- char *nulls,
+ Datum *values,
+ bool *isnull,
bool tupleIsAlive,
void *state);
-static InsertIndexResult rtdoinsert(Relation r, IndexTuple itup,
- RTSTATE *rtstate);
+static void rtdoinsert(Relation r, IndexTuple itup, RTSTATE *rtstate);
static void rttighten(Relation r, RTSTACK *stk, Datum datum, int att_size,
RTSTATE *rtstate);
-static InsertIndexResult rtdosplit(Relation r, Buffer buffer, RTSTACK *stack,
+static void rtdosplit(Relation r, Buffer buffer, RTSTACK *stack,
IndexTuple itup, RTSTATE *rtstate);
static void rtintinsert(Relation r, RTSTACK *stk, IndexTuple ltup,
IndexTuple rtup, RTSTATE *rtstate);
static void
rtbuildCallback(Relation index,
HeapTuple htup,
- Datum *attdata,
- char *nulls,
+ Datum *values,
+ bool *isnull,
bool tupleIsAlive,
void *state)
{
RTBuildState *buildstate = (RTBuildState *) state;
IndexTuple itup;
- InsertIndexResult res;
/* 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;
/* rtree indexes don't index nulls, see notes in rtinsert */
* if you're inserting single tups, but not when you're initializing
* the whole index at once.
*/
- res = rtdoinsert(index, itup, &buildstate->rtState);
-
- if (res)
- pfree(res);
+ rtdoinsert(index, itup, &buildstate->rtState);
buildstate->indtuples += 1;
rtinsert(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;
RTSTATE rtState;
/* generate an index tuple */
- itup = index_formtuple(RelationGetDescr(r), datum, nulls);
+ itup = index_form_tuple(RelationGetDescr(r), values, isnull);
itup->t_tid = *ht_ctid;
/*
if (IndexTupleHasNulls(itup))
{
pfree(itup);
- PG_RETURN_POINTER(NULL);
+ PG_RETURN_BOOL(false);
}
initRtstate(&rtState, r);
* have acquired exclusive lock on index relation. We need no locking
* here.
*/
+ rtdoinsert(r, itup, &rtState);
- res = rtdoinsert(r, itup, &rtState);
-
- PG_RETURN_POINTER(res);
+ PG_RETURN_BOOL(true);
}
-static InsertIndexResult
+static void
rtdoinsert(Relation r, IndexTuple itup, RTSTATE *rtstate)
{
Page page;
IndexTuple which;
OffsetNumber l;
RTSTACK *stack;
- InsertIndexResult res;
RTreePageOpaque opaque;
Datum datum;
if (nospace(page, itup))
{
/* need to do a split */
- res = rtdosplit(r, buffer, stack, itup, rtstate);
+ rtdosplit(r, buffer, stack, itup, rtstate);
freestack(stack);
WriteBuffer(buffer); /* don't forget to release buffer! */
- return res;
+ return;
}
/* add the item and write the buffer */
/* now expand the page boundary in the parent to include the new child */
rttighten(r, stack, datum, IndexTupleAttSize(itup), rtstate);
freestack(stack);
-
- /* build and return an InsertIndexResult for this insertion */
- res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData));
- ItemPointerSet(&(res->pointerData), blk, l);
-
- return res;
}
static void
* rtpicksplit does the interesting work of choosing the split.
* This routine just does the bit-pushing.
*/
-static InsertIndexResult
+static void
rtdosplit(Relation r,
Buffer buffer,
RTSTACK *stack,
rbknum;
BlockNumber bufblock;
RTreePageOpaque opaque;
- int blank;
- InsertIndexResult res;
- char *isnull;
+ bool *isnull;
SPLITVEC v;
OffsetNumber *spl_left,
*spl_right;
maxoff = PageGetMaxOffsetNumber(p);
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
* will go to the left page. For each offset number, get the tuple
RelationGetRelationName(r));
leftoff = OffsetNumberNext(leftoff);
- if (i == newitemoff)
- ItemPointerSet(&(res->pointerData), lbknum, leftoff);
-
spl_left++; /* advance in left split vector */
}
RelationGetRelationName(r));
rightoff = OffsetNumberNext(rightoff);
- if (i == newitemoff)
- ItemPointerSet(&(res->pointerData), rbknum, rightoff);
-
spl_right++; /* advance in right split vector */
}
rtadjscans(r, RTOP_SPLIT, bufblock, FirstOffsetNumber);
tupDesc = r->rd_att;
- isnull = (char *) palloc(r->rd_rel->relnatts);
- for (blank = 0; blank < r->rd_rel->relnatts; blank++)
- isnull[blank] = ' ';
-
- ltup = (IndexTuple) index_formtuple(tupDesc,
- &(v.spl_ldatum), isnull);
- rtup = (IndexTuple) index_formtuple(tupDesc,
- &(v.spl_rdatum), isnull);
+ isnull = (bool *) palloc(r->rd_rel->relnatts * sizeof(bool));
+ memset(isnull, false, r->rd_rel->relnatts * sizeof(bool));
+
+ ltup = index_form_tuple(tupDesc, &(v.spl_ldatum), isnull);
+ rtup = index_form_tuple(tupDesc, &(v.spl_rdatum), isnull);
+
pfree(isnull);
pfree(DatumGetPointer(v.spl_ldatum));
pfree(DatumGetPointer(v.spl_rdatum));
pfree(ltup);
pfree(rtup);
-
- return res;
}
static void
Datum ldatum,
rdatum,
newdatum;
- InsertIndexResult res;
if (stk == NULL)
{
newdatum = IndexTupleGetDatum(ltup);
rttighten(r, stk->rts_parent, newdatum,
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! -
* 01/31/94 */
- pfree(res);
}
else
{
*
*
* 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
/* ----------------
* 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
* slot Heap tuple for which we must prepare an index entry
* estate executor state for evaluating any index expressions
- * datum Array of index Datums (output area)
- * nullv Array of is-null indicators (output area)
+ * values Array of index Datums (output area)
+ * isnull Array of is-null indicators (output area)
*
* 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
* context must point to the heap tuple passed in.
*
- * For largely historical reasons, we don't actually call index_formtuple()
- * here, we just prepare its input arrays datum[] and nullv[].
+ * Notice we don't actually call index_form_tuple() here; we just prepare
+ * its input arrays values[] and isnull[]. This is because the index AM
+ * may wish to alter the data before storage.
* ----------------
*/
void
FormIndexDatum(IndexInfo *indexInfo,
TupleTableSlot *slot,
EState *estate,
- Datum *datum,
- char *nullv)
+ Datum *values,
+ bool *isnull)
{
ListCell *indexpr_item;
int i;
NULL);
indexpr_item = lnext(indexpr_item);
}
- datum[i] = iDatum;
- nullv[i] = (isNull) ? 'n' : ' ';
+ values[i] = iDatum;
+ isnull[i] = isNull;
}
if (indexpr_item != NULL)
{
HeapScanDesc scan;
HeapTuple heapTuple;
- Datum attdata[INDEX_MAX_KEYS];
- char nulls[INDEX_MAX_KEYS];
+ Datum values[INDEX_MAX_KEYS];
+ bool isnull[INDEX_MAX_KEYS];
double reltuples;
List *predicate;
TupleTableSlot *slot;
FormIndexDatum(indexInfo,
slot,
estate,
- attdata,
- nulls);
+ values,
+ isnull);
/*
* 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
- * 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 */
- callback(indexRelation, heapTuple, attdata, nulls, tupleIsAlive,
+ callback(indexRelation, heapTuple, values, isnull, tupleIsAlive,
callback_state);
}
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
Relation heapRelation;
TupleTableSlot *slot;
IndexInfo **indexInfoArray;
- Datum datum[INDEX_MAX_KEYS];
- char nullv[INDEX_MAX_KEYS];
+ Datum values[INDEX_MAX_KEYS];
+ bool isnull[INDEX_MAX_KEYS];
/*
* Get information from the state structure. Fall out if nothing to do.
for (i = 0; i < numIndexes; i++)
{
IndexInfo *indexInfo;
- InsertIndexResult result;
indexInfo = indexInfoArray[i];
Assert(indexInfo->ii_Predicate == NIL);
/*
- * FormIndexDatum fills in its datum and null parameters with
- * attribute information taken from the given tuple.
+ * FormIndexDatum fills in its values and isnull parameters with
+ * the appropriate values for the column(s) of the index.
*/
FormIndexDatum(indexInfo,
slot,
NULL, /* no expression eval to do */
- datum,
- nullv);
+ values,
+ isnull);
/*
* The index AM does the rest.
*/
- result = index_insert(relationDescs[i], /* index relation */
- datum, /* array of heaptuple Datums */
- nullv, /* info on nulls */
- &(heapTuple->t_self), /* tid of heap tuple */
- heapRelation,
- relationDescs[i]->rd_index->indisunique);
-
- if (result)
- pfree(result);
+ index_insert(relationDescs[i], /* index relation */
+ values, /* array of index Datums */
+ isnull, /* is-null flags */
+ &(heapTuple->t_self), /* tid of heap tuple */
+ heapRelation,
+ relationDescs[i]->rd_index->indisunique);
}
ExecDropSingleTupleTableSlot(slot);
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
{
MemoryContext ind_context,
old_context;
- Datum attdata[INDEX_MAX_KEYS];
- char nulls[INDEX_MAX_KEYS];
+ Datum values[INDEX_MAX_KEYS];
+ bool isnull[INDEX_MAX_KEYS];
int ind,
i;
FormIndexDatum(indexInfo,
slot,
estate,
- attdata,
- nulls);
+ values,
+ isnull);
/*
* Save just the columns we care about.
VacAttrStats *stats = thisdata->vacattrstats[i];
int attnum = stats->attr->attnum;
- exprvals[tcnt] = attdata[attnum - 1];
- exprnulls[tcnt] = (nulls[attnum - 1] == 'n');
+ exprvals[tcnt] = values[attnum - 1];
+ exprnulls[tcnt] = isnull[attnum - 1];
tcnt++;
}
}
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
Relation heapRelation;
IndexInfo **indexInfoArray;
ExprContext *econtext;
- Datum datum[INDEX_MAX_KEYS];
- char nullv[INDEX_MAX_KEYS];
+ Datum values[INDEX_MAX_KEYS];
+ bool isnull[INDEX_MAX_KEYS];
/*
* Get information from the result relation info structure.
for (i = 0; i < numIndices; i++)
{
IndexInfo *indexInfo;
- InsertIndexResult result;
if (relationDescs[i] == NULL)
continue;
}
/*
- * FormIndexDatum fills in its datum and null parameters with
- * attribute information taken from the given tuple. It also
- * computes any expressions needed.
+ * FormIndexDatum fills in its values and isnull parameters with
+ * the appropriate values for the column(s) of the index.
*/
FormIndexDatum(indexInfo,
slot,
estate,
- datum,
- nullv);
+ values,
+ isnull);
/*
* The index AM does the rest. Note we suppress unique-index
* checks if we are being called from VACUUM, since VACUUM may
* need to move dead tuples that have the same keys as live ones.
*/
- result = index_insert(relationDescs[i], /* index relation */
- datum, /* array of index Datums */
- nullv, /* info on nulls */
- tupleid, /* tid of heap tuple */
- heapRelation,
- relationDescs[i]->rd_index->indisunique && !is_vacuum);
+ index_insert(relationDescs[i], /* index relation */
+ values, /* array of index Datums */
+ isnull, /* null flags */
+ tupleid, /* tid of heap tuple */
+ heapRelation,
+ relationDescs[i]->rd_index->indisunique && !is_vacuum);
/*
* keep track of index inserts for debugging
*/
IncrIndexInserted();
-
- if (result)
- pfree(result);
}
}
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* 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 $
*
*-------------------------------------------------------------------------
*/
extern Relation index_openrv(const RangeVar *relation);
extern Relation index_openr(const char *sysRelationName);
extern void index_close(Relation relation);
-extern InsertIndexResult index_insert(Relation indexRelation,
- Datum *datums, char *nulls,
+extern bool index_insert(Relation indexRelation,
+ Datum *values, bool *isnull,
ItemPointer heap_t_ctid,
Relation heapRelation,
bool check_uniqueness);
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* 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
* modeled after Margo Seltzer's hash implementation for unix.
/* private routines */
/* hashinsert.c */
-extern InsertIndexResult _hash_doinsert(Relation rel, HashItem hitem);
+extern void _hash_doinsert(Relation rel, HashItem hitem);
/* hashovfl.c */
extern Buffer _hash_addovflpage(Relation rel, Buffer metabuf, Buffer buf);
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* 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 $
*
*-------------------------------------------------------------------------
*/
/* in common/heaptuple.c */
extern Size heap_compute_data_size(TupleDesc tupleDesc,
Datum *values, bool *isnull);
-extern Size ComputeDataSize(TupleDesc tupleDesc, Datum *values, char *nulls);
extern void heap_fill_tuple(TupleDesc tupleDesc,
Datum *values, bool *isnull,
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 Datum nocachegetattr(HeapTuple tup, int attnum,
TupleDesc att, bool *isnull);
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* 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 $
*
*-------------------------------------------------------------------------
*/
typedef IndexTupleData *IndexTuple;
-typedef struct InsertIndexResultData
-{
- ItemPointerData pointerData;
-} InsertIndexResultData;
-
-typedef InsertIndexResultData *InsertIndexResult;
-
-
/* ----------------
* externs
* ----------------
/*
* 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!!!!!!!!!!!
*/
/* routines in indextuple.c */
-extern IndexTuple index_formtuple(TupleDesc tupleDescriptor,
- Datum *value, char *null);
+extern IndexTuple index_form_tuple(TupleDesc tupleDescriptor,
+ Datum *values, bool *isnull);
extern Datum nocache_index_getattr(IndexTuple tup, int attnum,
TupleDesc tupleDesc, bool *isnull);
extern IndexTuple CopyIndexTuple(IndexTuple source);
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* 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 $
*
*-------------------------------------------------------------------------
*/
/*
* 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);
extern Buffer _bt_getstackbuf(Relation rel, BTStack stack, int access);
extern void _bt_insert_parent(Relation rel, Buffer buf, Buffer rbuf,
*
* 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 $
*
*-------------------------------------------------------------------------
*/
/*
* 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
- * 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)
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* 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 $
*
*-------------------------------------------------------------------------
*/
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 200503161
+#define CATALOG_VERSION_NO 200503201
#endif
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* 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 $
*
*-------------------------------------------------------------------------
*/
/* Typedef for callback function for IndexBuildHeapScan */
typedef void (*IndexBuildCallback) (Relation index,
- HeapTuple htup,
- Datum *attdata,
- char *nulls,
- bool tupleIsAlive,
- void *state);
+ HeapTuple htup,
+ Datum *values,
+ bool *isnull,
+ bool tupleIsAlive,
+ void *state);
extern Oid index_create(Oid heapRelationId,
extern void FormIndexDatum(IndexInfo *indexInfo,
TupleTableSlot *slot,
EState *estate,
- Datum *datum,
- char *nullv);
+ Datum *values,
+ bool *isnull);
extern void UpdateStats(Oid relid, double reltuples);
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* 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
* The script catalog/genbki.sh reads this file and generates .bki
DATA(insert OID = 319 ( int4 PGNSP PGUID 12 f f t f i 1 23 "700" _null_ ftoi4 - _null_ ));
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)");
DATA(insert OID = 322 ( rtgettuple PGNSP PGUID 12 f f t f v 2 16 "2281 2281" _null_ rtgettuple - _null_ ));
DESCR("r-tree(internal)");
DATA(insert OID = 330 ( btgettuple PGNSP PGUID 12 f f t f v 2 16 "2281 2281" _null_ btgettuple - _null_ ));
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)");
DATA(insert OID = 333 ( btbeginscan PGNSP PGUID 12 f f t f v 3 2281 "2281 2281 2281" _null_ btbeginscan - _null_ ));
DESCR("btree(internal)");
DATA(insert OID = 440 ( hashgettuple PGNSP PGUID 12 f f t f v 2 16 "2281 2281" _null_ hashgettuple - _null_ ));
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)");
DATA(insert OID = 443 ( hashbeginscan PGNSP PGUID 12 f f t f v 3 2281 "2281 2281 2281" _null_ hashbeginscan - _null_ ));
DESCR("hash(internal)");
DATA(insert OID = 774 ( gistgettuple PGNSP PGUID 12 f f t f v 2 16 "2281 2281" _null_ gistgettuple - _null_ ));
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)");
DATA(insert OID = 777 ( gistbeginscan PGNSP PGUID 12 f f t f v 3 2281 "2281 2281 2281" _null_ gistbeginscan - _null_ ));
DESCR("gist(internal)");