]> granicus.if.org Git - postgresql/commitdiff
Fix coredump during replay WAL after crash. Change entrySplitPage() to prevent
authorTeodor Sigaev <teodor@sigaev.ru>
Mon, 29 Oct 2007 13:49:21 +0000 (13:49 +0000)
committerTeodor Sigaev <teodor@sigaev.ru>
Mon, 29 Oct 2007 13:49:21 +0000 (13:49 +0000)
usage of any information from system catalog, because it could be called during
replay of WAL.

Per bug report from Craig McElroy <craig.mcelroy@contegix.com>. Patch doesn't
change on-disk storage.

src/backend/access/gin/ginentrypage.c

index 70867ac40bab57c99a15291b2648cd9f5812fb2d..2c335aea0cd7553d261d85a888a9254bfea6f7b9 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *                     $PostgreSQL: pgsql/src/backend/access/gin/ginentrypage.c,v 1.9 2007/09/20 17:56:30 tgl Exp $
+ *                     $PostgreSQL: pgsql/src/backend/access/gin/ginentrypage.c,v 1.10 2007/10/29 13:49:21 teodor Exp $
  *-------------------------------------------------------------------------
  */
 
@@ -403,6 +403,31 @@ entryPlaceToPage(GinBtree btree, Buffer buf, OffsetNumber off, XLogRecData **prd
        btree->entry = NULL;
 }
 
+/*
+ * Returns new tuple with copied value from source tuple.
+ * New tuple will not store posting list
+ */
+static IndexTuple
+copyIndexTuple(IndexTuple itup, Page page)
+{
+       IndexTuple      nitup;
+
+       if (GinPageIsLeaf(page) && !GinIsPostingTree(itup))
+       {
+               nitup = (IndexTuple) palloc(MAXALIGN(GinGetOrigSizePosting(itup)));
+               memcpy(nitup, itup, GinGetOrigSizePosting(itup));
+               nitup->t_info &= ~INDEX_SIZE_MASK;
+               nitup->t_info |= GinGetOrigSizePosting(itup);
+       }
+       else
+       {
+               nitup = (IndexTuple) palloc(MAXALIGN(IndexTupleSize(itup)));
+               memcpy(nitup, itup, IndexTupleSize(itup));
+       }
+
+       return nitup;
+}
+
 /*
  * Place tuple and split page, original buffer(lbuf) leaves untouched,
  * returns shadow page of lbuf filled new data.
@@ -424,8 +449,6 @@ entrySplitPage(GinBtree btree, Buffer lbuf, Buffer rbuf, OffsetNumber off, XLogR
        IndexTuple      itup,
                                leftrightmost = NULL;
        static ginxlogSplit data;
-       Datum           value;
-       bool            isnull;
        Page            page;
        Page            lpage = GinPageGetCopyPage(BufferGetPage(lbuf));
        Page            rpage = BufferGetPage(rbuf);
@@ -494,9 +517,9 @@ entrySplitPage(GinBtree btree, Buffer lbuf, Buffer rbuf, OffsetNumber off, XLogR
                ptr += MAXALIGN(IndexTupleSize(itup));
        }
 
-       value = index_getattr(leftrightmost, FirstOffsetNumber, btree->ginstate->tupdesc, &isnull);
-       btree->entry = GinFormTuple(btree->ginstate, value, NULL, 0);
+       btree->entry = copyIndexTuple(leftrightmost, lpage);
        ItemPointerSet(&(btree->entry)->t_tid, BufferGetBlockNumber(lbuf), InvalidOffsetNumber);
+
        btree->rightblkno = BufferGetBlockNumber(rbuf);
 
        data.node = btree->index->rd_node;
@@ -533,20 +556,9 @@ ginPageGetLinkItup(Buffer buf)
        Page            page = BufferGetPage(buf);
 
        itup = getRightMostTuple(page);
-       if (GinPageIsLeaf(page) && !GinIsPostingTree(itup))
-       {
-               nitup = (IndexTuple) palloc(MAXALIGN(GinGetOrigSizePosting(itup)));
-               memcpy(nitup, itup, GinGetOrigSizePosting(itup));
-               nitup->t_info &= ~INDEX_SIZE_MASK;
-               nitup->t_info |= GinGetOrigSizePosting(itup);
-       }
-       else
-       {
-               nitup = (IndexTuple) palloc(MAXALIGN(IndexTupleSize(itup)));
-               memcpy(nitup, itup, IndexTupleSize(itup));
-       }
-
+       nitup = copyIndexTuple(itup, page);
        ItemPointerSet(&nitup->t_tid, BufferGetBlockNumber(buf), InvalidOffsetNumber);
+
        return nitup;
 }