* interface routines for the postgres GiST index access method.
*
*
- * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.87 2002/01/15 22:14:16 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.96 2002/09/04 20:31:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
Page page,
IndexTuple *itup,
int len,
- OffsetNumber off,
- GISTSTATE *giststate);
+ OffsetNumber off);
static int gistnospace(Page page,
IndexTuple *itvec, int len);
-static IndexTuple *gistreadbuffer(Relation r,
- Buffer buffer, int *len);
+static IndexTuple *gistreadbuffer(Buffer buffer, int *len);
static IndexTuple *gistjoinvector(
IndexTuple *itvec, int *len,
IndexTuple *additvec, int addlen);
int *len,
GISTSTATE *giststate,
InsertIndexResult *res);
-static void gistnewroot(GISTSTATE *giststate, Relation r,
+static void gistnewroot(Relation r,
IndexTuple *itup, int len);
static void GISTInitBuffer(Buffer b, uint32 f);
static OffsetNumber gistchoose(Relation r, Page p,
#ifdef NOT_USED
Relation heapRel = (Relation) PG_GETARG_POINTER(4);
+ bool checkUnique = PG_GETARG_BOOL(5);
#endif
InsertIndexResult res;
IndexTuple itup;
#ifdef GIST_PAGEADDITEM
/*
-** Take a compressed entry, and install it on a page. Since we now know
-** where the entry will live, we decompress it and recompress it using
-** that knowledge (some compression routines may want to fish around
-** on the page, for example, or do something special for leaf nodes.)
-*/
+ * Take a compressed entry, and install it on a page. Since we now know
+ * where the entry will live, we decompress it and recompress it using
+ * that knowledge (some compression routines may want to fish around
+ * on the page, for example, or do something special for leaf nodes.)
+ */
static OffsetNumber
gistPageAddItem(GISTSTATE *giststate,
Relation r,
ret = gistlayerinsert(r, GISTP_ROOT, &instup, &len, res, giststate);
if (ret & SPLITED)
- gistnewroot(giststate, r, instup, len);
+ gistnewroot(r, instup, len);
for (i = 0; i < len; i++)
pfree(instup[i]);
if (!(opaque->flags & F_LEAF))
{
/* internal page, so we must walk on tree */
- /* len IS equial 1 */
+ /* len IS equal 1 */
ItemId iid;
BlockNumber nblkno;
ItemPointerData oldtid;
/* key is modified, so old version must be deleted */
ItemPointerSet(&oldtid, blkno, child);
gistdelete(r, &oldtid);
+
+ /*
+ * if child was splitted, new key for child will be inserted in
+ * the end list of child, so we must say to any scans that page is
+ * changed beginning from 'child' offset
+ */
+ if (ret & SPLITED)
+ gistadjscans(r, GISTOP_SPLIT, blkno, child);
}
ret = INSERTED;
oldlen;
ret |= SPLITED;
- itvec = gistreadbuffer(r, buffer, &tlen);
+ itvec = gistreadbuffer(buffer, &tlen);
itvec = gistjoinvector(itvec, &tlen, (*itup), *len);
oldlen = *len;
newitup = gistSplit(r, buffer, itvec, &tlen, giststate,
FirstOffsetNumber
:
OffsetNumberNext(PageGetMaxOffsetNumber(page));
- l = gistwritebuffer(r, page, (*itup), *len, off, giststate);
+ l = gistwritebuffer(r, page, (*itup), *len, off);
WriteBuffer(buffer);
/*
*/
static OffsetNumber
gistwritebuffer(Relation r, Page page, IndexTuple *itup,
- int len, OffsetNumber off, GISTSTATE *giststate)
+ int len, OffsetNumber off)
{
OffsetNumber l = InvalidOffsetNumber;
int i;
static int
gistnospace(Page page, IndexTuple *itvec, int len)
{
- int size = 0;
+ unsigned int size = 0;
int i;
for (i = 0; i < len; i++)
* Read buffer into itup vector
*/
static IndexTuple *
-gistreadbuffer(Relation r, Buffer buffer, int *len /* out */ )
+gistreadbuffer(Buffer buffer, int *len /* out */ )
{
OffsetNumber i,
maxoff;
Datum attr[INDEX_MAX_KEYS];
bool whatfree[INDEX_MAX_KEYS];
char isnull[INDEX_MAX_KEYS];
+ char *storage;
bytea *evec;
Datum datum;
int datumsize,
int reallen;
needfree = (bool *) palloc(((len == 1) ? 2 : len) * sizeof(bool));
- evec = (bytea *) palloc(((len == 1) ? 2 : len) * sizeof(GISTENTRY) + VARHDRSZ);
+ /* workaround for 64-bit: ensure GISTENTRY array is maxaligned */
+ storage = (char *) palloc(((len == 1) ? 2 : len) * sizeof(GISTENTRY) + MAXALIGN(VARHDRSZ));
+ evec = (bytea *) (storage + MAXALIGN(VARHDRSZ) - VARHDRSZ);
for (j = 0; j < r->rd_att->natts; j++)
{
}
}
- pfree(evec);
+ pfree(storage); /* pfree(evec); */
pfree(needfree);
newtup = (IndexTuple) index_formtuple(giststate->tupdesc, attr, isnull);
adddec[INDEX_MAX_KEYS];
bool oldisnull[INDEX_MAX_KEYS],
addisnull[INDEX_MAX_KEYS];
-
IndexTuple newtup = NULL;
+ char *storage;
int j;
- evec = (bytea *) palloc(2 * sizeof(GISTENTRY) + VARHDRSZ);
+ /* workaround for 64-bit: ensure GISTENTRY array is maxaligned */
+ storage = (char *) palloc(2 * sizeof(GISTENTRY) + MAXALIGN(VARHDRSZ));
+ evec = (bytea *) (storage + MAXALIGN(VARHDRSZ) - VARHDRSZ);
VARATT_SIZEP(evec) = 2 * sizeof(GISTENTRY) + VARHDRSZ;
ev0p = &((GISTENTRY *) VARDATA(evec))[0];
ev1p = &((GISTENTRY *) VARDATA(evec))[1];
whatfree[j] = FALSE;
}
}
- pfree(evec);
+ pfree(storage); /* pfree(evec); */
if (neednew)
{
*attrsize;
OffsetNumber *entries;
bytea *evec;
+ char *storage;
Datum datum;
int datumsize;
int reallen;
}
needfree = (bool *) palloc(((len == 1) ? 2 : len) * sizeof(bool));
- evec = (bytea *) palloc(((len == 1) ? 2 : len) * sizeof(GISTENTRY) + VARHDRSZ);
+ /* workaround for 64-bit: ensure GISTENTRY array is maxaligned */
+ storage = (char *) palloc(((len == 1) ? 2 : len) * sizeof(GISTENTRY) + MAXALIGN(VARHDRSZ));
+ evec = (bytea *) (storage + MAXALIGN(VARHDRSZ) - VARHDRSZ);
+
for (j = 1; j < r->rd_att->natts; j++)
{
reallen = 0;
attr[j] = datum;
attrsize[j] = datumsize;
}
- pfree(evec);
+ pfree(storage); /* pfree(evec); */
pfree(needfree);
}
}
float lpenalty,
rpenalty;
bytea *evec;
+ char *storage;
int datumsize;
bool isnull[INDEX_MAX_KEYS];
int i,
curlen--;
v->spl_nright = curlen;
- evec = (bytea *) palloc(2 * sizeof(GISTENTRY) + VARHDRSZ);
+ /* workaround for 64-bit: ensure GISTENTRY array is maxaligned */
+ storage = (char *) palloc(2 * sizeof(GISTENTRY) + MAXALIGN(VARHDRSZ));
+ evec = (bytea *) (storage + MAXALIGN(VARHDRSZ) - VARHDRSZ);
VARATT_SIZEP(evec) = 2 * sizeof(GISTENTRY) + VARHDRSZ;
ev0p = &((GISTENTRY *) VARDATA(evec))[0];
ev1p = &((GISTENTRY *) VARDATA(evec))[1];
}
gistFreeAtt(r, identry, decfree);
}
- pfree(evec);
+ pfree(storage); /* pfree(evec); */
}
/*
GISTPageOpaque opaque;
GIST_SPLITVEC v;
bytea *entryvec;
+ char *storage;
bool *decompvec;
int i,
j,
p = (Page) BufferGetPage(buffer);
opaque = (GISTPageOpaque) PageGetSpecialPointer(p);
-
/*
* The root of the tree is the first block in the relation. If we're
* about to split the root, we need to do some hocus-pocus to enforce
right = (Page) BufferGetPage(rightbuf);
/* generate the item array */
- entryvec = (bytea *) palloc(VARHDRSZ + (*len + 1) * sizeof(GISTENTRY));
- decompvec = (bool *) palloc(VARHDRSZ + (*len + 1) * sizeof(bool));
+ /* workaround for 64-bit: ensure GISTENTRY array is maxaligned */
+ storage = palloc(MAXALIGN(VARHDRSZ) + (*len + 1) * sizeof(GISTENTRY));
+ entryvec = (bytea *) (storage + MAXALIGN(VARHDRSZ) - VARHDRSZ);
+ decompvec = (bool *) palloc((*len + 1) * sizeof(bool));
VARATT_SIZEP(entryvec) = (*len + 1) * sizeof(GISTENTRY) + VARHDRSZ;
for (i = 1; i <= *len; i++)
{
for (i = 1; i <= *len; i++)
if (decompvec[i])
pfree(DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[i].key));
- pfree(entryvec);
+ pfree(storage); /* pfree(entryvec); */
pfree(decompvec);
/* form left and right vector */
{
OffsetNumber l;
- l = gistwritebuffer(r, right, rvectup, v.spl_nright, FirstOffsetNumber, giststate);
+ l = gistwritebuffer(r, right, rvectup, v.spl_nright, FirstOffsetNumber);
WriteBuffer(rightbuf);
if (res)
{
OffsetNumber l;
- l = gistwritebuffer(r, left, lvectup, v.spl_nleft, FirstOffsetNumber, giststate);
+ l = gistwritebuffer(r, left, lvectup, v.spl_nleft, FirstOffsetNumber);
if (BufferGetBlockNumber(buffer) != GISTP_ROOT)
PageRestoreTempPage(left, p);
ItemPointerSet(&(newtup[nlen - 1]->t_tid), lbknum, 1);
}
-
- /* adjust active scans */
- gistadjscans(r, GISTOP_SPLIT, BufferGetBlockNumber(buffer), FirstOffsetNumber);
-
/* !!! pfree */
pfree(rvectup);
pfree(lvectup);
}
static void
-gistnewroot(GISTSTATE *giststate, Relation r, IndexTuple *itup, int len)
+gistnewroot(Relation r, IndexTuple *itup, int len)
{
Buffer b;
Page p;
GISTInitBuffer(b, 0);
p = BufferGetPage(b);
- gistwritebuffer(r, p, itup, len, FirstOffsetNumber, giststate);
+ gistwritebuffer(r, p, itup, len, FirstOffsetNumber);
WriteBuffer(b);
}
BlockNumber num_pages;
double tuples_removed;
double num_index_tuples;
- RetrieveIndexResult res;
IndexScanDesc iscan;
tuples_removed = 0;
*/
/* walk through the entire index */
- iscan = index_beginscan(rel, false, 0, (ScanKey) NULL);
+ iscan = index_beginscan(NULL, rel, SnapshotAny, 0, (ScanKey) NULL);
+ /* including killed tuples */
+ iscan->ignore_killed_tuples = false;
- while ((res = index_getnext(iscan, ForwardScanDirection))
- != (RetrieveIndexResult) NULL)
+ while (index_getnext_indexitem(iscan, ForwardScanDirection))
{
- ItemPointer heapptr = &res->heap_iptr;
-
- if (callback(heapptr, callback_state))
+ if (callback(&iscan->xs_ctup.t_self, callback_state))
{
- ItemPointer indexptr = &res->index_iptr;
+ ItemPointerData indextup = iscan->currentItemData;
BlockNumber blkno;
OffsetNumber offnum;
Buffer buf;
Page page;
- blkno = ItemPointerGetBlockNumber(indexptr);
- offnum = ItemPointerGetOffsetNumber(indexptr);
+ blkno = ItemPointerGetBlockNumber(&indextup);
+ offnum = ItemPointerGetOffsetNumber(&indextup);
/* adjust any scans that will be affected by this deletion */
gistadjscans(rel, GISTOP_DEL, blkno, offnum);
}
else
num_index_tuples += 1;
-
- pfree(res);
}
index_endscan(iscan);
maxoff = PageGetMaxOffsetNumber(page);
- elog(NOTICE, "%sPage: %d %s blk: %d maxoff: %d free: %d", pred,
+ elog(DEBUG3, "%sPage: %d %s blk: %d maxoff: %d free: %d", pred,
coff, (opaque->flags & F_LEAF) ? "LEAF" : "INTE", (int) blk,
(int) maxoff, PageGetFreeSpace(page));
which = (IndexTuple) PageGetItem(page, iid);
cblk = ItemPointerGetBlockNumber(&(which->t_tid));
#ifdef PRINTTUPLE
- elog(NOTICE, "%s Tuple. blk: %d size: %d", pred, (int) cblk,
+ elog(DEBUG3, "%s Tuple. blk: %d size: %d", pred, (int) cblk,
IndexTupleSize(which));
#endif
void
gist_redo(XLogRecPtr lsn, XLogRecord *record)
{
- elog(STOP, "gist_redo: unimplemented");
+ elog(PANIC, "gist_redo: unimplemented");
}
void
gist_undo(XLogRecPtr lsn, XLogRecord *record)
{
- elog(STOP, "gist_undo: unimplemented");
+ elog(PANIC, "gist_undo: unimplemented");
}
void