OSDN Git Service

pgindent run.
[pg-rex/syncrep.git] / src / backend / access / gist / gist.c
index db57a5f..c238ea2 100644 (file)
@@ -4,11 +4,11 @@
  *       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 $
  *
  *-------------------------------------------------------------------------
  */
@@ -87,12 +87,10 @@ static OffsetNumber gistwritebuffer(Relation r,
                                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);
@@ -117,7 +115,7 @@ static IndexTuple *gistSplit(Relation r,
                  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,
@@ -299,6 +297,7 @@ gistinsert(PG_FUNCTION_ARGS)
 
 #ifdef NOT_USED
        Relation        heapRel = (Relation) PG_GETARG_POINTER(4);
+       bool            checkUnique = PG_GETARG_BOOL(5);
 #endif
        InsertIndexResult res;
        IndexTuple      itup;
@@ -359,11 +358,11 @@ gistinsert(PG_FUNCTION_ARGS)
 
 #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,
@@ -425,7 +424,7 @@ gistdoinsert(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]);
@@ -452,7 +451,7 @@ gistlayerinsert(Relation r, BlockNumber blkno,
        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;
@@ -496,6 +495,14 @@ gistlayerinsert(Relation r, BlockNumber blkno,
                /* 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;
@@ -509,7 +516,7 @@ gistlayerinsert(Relation r, BlockNumber blkno,
                                        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,
@@ -534,7 +541,7 @@ gistlayerinsert(Relation r, BlockNumber blkno,
                        FirstOffsetNumber
                        :
                        OffsetNumberNext(PageGetMaxOffsetNumber(page));
-               l = gistwritebuffer(r, page, (*itup), *len, off, giststate);
+               l = gistwritebuffer(r, page, (*itup), *len, off);
                WriteBuffer(buffer);
 
                /*
@@ -570,7 +577,7 @@ gistlayerinsert(Relation r, BlockNumber blkno,
  */
 static OffsetNumber
 gistwritebuffer(Relation r, Page page, IndexTuple *itup,
-                               int len, OffsetNumber off, GISTSTATE *giststate)
+                               int len, OffsetNumber off)
 {
        OffsetNumber l = InvalidOffsetNumber;
        int                     i;
@@ -609,7 +616,7 @@ gistwritebuffer(Relation r, Page page, IndexTuple *itup,
 static int
 gistnospace(Page page, IndexTuple *itvec, int len)
 {
-       int                     size = 0;
+       unsigned int size = 0;
        int                     i;
 
        for (i = 0; i < len; i++)
@@ -622,7 +629,7 @@ gistnospace(Page page, IndexTuple *itvec, int len)
  * Read buffer into itup vector
  */
 static IndexTuple *
-gistreadbuffer(Relation r, Buffer buffer, int *len /* out */ )
+gistreadbuffer(Buffer buffer, int *len /* out */ )
 {
        OffsetNumber i,
                                maxoff;
@@ -659,6 +666,7 @@ gistunion(Relation r, IndexTuple *itvec, int len, GISTSTATE *giststate)
        Datum           attr[INDEX_MAX_KEYS];
        bool            whatfree[INDEX_MAX_KEYS];
        char            isnull[INDEX_MAX_KEYS];
+       char       *storage;
        bytea      *evec;
        Datum           datum;
        int                     datumsize,
@@ -671,7 +679,9 @@ gistunion(Relation r, IndexTuple *itvec, int len, GISTSTATE *giststate)
        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++)
        {
@@ -737,7 +747,7 @@ gistunion(Relation r, IndexTuple *itvec, int len, GISTSTATE *giststate)
                }
        }
 
-       pfree(evec);
+       pfree(storage);                         /* pfree(evec); */
        pfree(needfree);
 
        newtup = (IndexTuple) index_formtuple(giststate->tupdesc, attr, isnull);
@@ -772,11 +782,13 @@ gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *gis
                                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];
@@ -844,7 +856,7 @@ gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *gis
                                whatfree[j] = FALSE;
                }
        }
-       pfree(evec);
+       pfree(storage);                         /* pfree(evec); */
 
        if (neednew)
        {
@@ -873,6 +885,7 @@ gistunionsubkey(Relation r, GISTSTATE *giststate, IndexTuple *itvec, GIST_SPLITV
                           *attrsize;
        OffsetNumber *entries;
        bytea      *evec;
+       char       *storage;
        Datum           datum;
        int                     datumsize;
        int                     reallen;
@@ -898,7 +911,10 @@ gistunionsubkey(Relation r, GISTSTATE *giststate, IndexTuple *itvec, GIST_SPLITV
                }
 
                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;
@@ -958,7 +974,7 @@ gistunionsubkey(Relation r, GISTSTATE *giststate, IndexTuple *itvec, GIST_SPLITV
                        attr[j] = datum;
                        attrsize[j] = datumsize;
                }
-               pfree(evec);
+               pfree(storage);                 /* pfree(evec); */
                pfree(needfree);
        }
 }
@@ -1050,6 +1066,7 @@ gistadjsubkey(Relation r,
        float           lpenalty,
                                rpenalty;
        bytea      *evec;
+       char       *storage;
        int                     datumsize;
        bool            isnull[INDEX_MAX_KEYS];
        int                     i,
@@ -1081,7 +1098,9 @@ gistadjsubkey(Relation r,
                        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];
@@ -1189,7 +1208,7 @@ gistadjsubkey(Relation r,
                }
                gistFreeAtt(r, identry, decfree);
        }
-       pfree(evec);
+       pfree(storage);                         /* pfree(evec); */
 }
 
 /*
@@ -1216,6 +1235,7 @@ gistSplit(Relation r,
        GISTPageOpaque opaque;
        GIST_SPLITVEC v;
        bytea      *entryvec;
+       char       *storage;
        bool       *decompvec;
        int                     i,
                                j,
@@ -1227,7 +1247,6 @@ gistSplit(Relation r,
        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
@@ -1255,8 +1274,10 @@ gistSplit(Relation r,
        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++)
        {
@@ -1322,7 +1343,7 @@ gistSplit(Relation r,
        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 */
@@ -1351,7 +1372,7 @@ gistSplit(Relation r,
        {
                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)
@@ -1384,7 +1405,7 @@ gistSplit(Relation r,
        {
                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);
 
@@ -1399,10 +1420,6 @@ gistSplit(Relation r,
                ItemPointerSet(&(newtup[nlen - 1]->t_tid), lbknum, 1);
        }
 
-
-       /* adjust active scans */
-       gistadjscans(r, GISTOP_SPLIT, BufferGetBlockNumber(buffer), FirstOffsetNumber);
-
        /* !!! pfree */
        pfree(rvectup);
        pfree(lvectup);
@@ -1414,7 +1431,7 @@ gistSplit(Relation r,
 }
 
 static void
-gistnewroot(GISTSTATE *giststate, Relation r, IndexTuple *itup, int len)
+gistnewroot(Relation r, IndexTuple *itup, int len)
 {
        Buffer          b;
        Page            p;
@@ -1423,7 +1440,7 @@ gistnewroot(GISTSTATE *giststate, Relation r, IndexTuple *itup, int len)
        GISTInitBuffer(b, 0);
        p = BufferGetPage(b);
 
-       gistwritebuffer(r, p, itup, len, FirstOffsetNumber, giststate);
+       gistwritebuffer(r, p, itup, len, FirstOffsetNumber);
        WriteBuffer(b);
 }
 
@@ -1578,7 +1595,6 @@ gistbulkdelete(PG_FUNCTION_ARGS)
        BlockNumber num_pages;
        double          tuples_removed;
        double          num_index_tuples;
-       RetrieveIndexResult res;
        IndexScanDesc iscan;
 
        tuples_removed = 0;
@@ -1595,23 +1611,22 @@ gistbulkdelete(PG_FUNCTION_ARGS)
         */
 
        /* 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);
@@ -1628,8 +1643,6 @@ gistbulkdelete(PG_FUNCTION_ARGS)
                }
                else
                        num_index_tuples += 1;
-
-               pfree(res);
        }
 
        index_endscan(iscan);
@@ -1914,7 +1927,7 @@ gist_dumptree(Relation r, int level, BlockNumber blk, OffsetNumber coff)
 
        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));
 
@@ -1924,7 +1937,7 @@ gist_dumptree(Relation r, int level, BlockNumber blk, OffsetNumber coff)
                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
 
@@ -1939,13 +1952,13 @@ gist_dumptree(Relation r, int level, BlockNumber blk, OffsetNumber coff)
 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