Fix coredump during replay WAL after crash. Change entrySplitPage() to prevent
authorTeodor Sigaev <teodor@sigaev.ru>
Mon, 29 Oct 2007 13:49:51 +0000 (13:49 +0000)
committerTeodor Sigaev <teodor@sigaev.ru>
Mon, 29 Oct 2007 13:49:51 +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 a8180d817b4deb021e155ae815de2041d0f875a7..75c244b2356d6f47d22cc93a3989756d391cc77c 100644 (file)
@@ -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;
 }