From b2a5641311ef21b590d40e1ad46f4d76795e8501 Mon Sep 17 00:00:00 2001 From: Teodor Sigaev Date: Mon, 29 Oct 2007 13:49:51 +0000 Subject: [PATCH] Fix coredump during replay WAL after crash. Change entrySplitPage() to prevent usage of any information from system catalog, because it could be called during replay of WAL. Per bug report from Craig McElroy . Patch doesn't change on-disk storage. --- src/backend/access/gin/ginentrypage.c | 48 +++++++++++++++++---------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/src/backend/access/gin/ginentrypage.c b/src/backend/access/gin/ginentrypage.c index ca409666030..eb8e23a0c86 100644 --- a/src/backend/access/gin/ginentrypage.c +++ b/src/backend/access/gin/ginentrypage.c @@ -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.5.2.1 2007/06/04 15:59:19 teodor Exp $ + * $PostgreSQL: pgsql/src/backend/access/gin/ginentrypage.c,v 1.5.2.2 2007/10/29 13:49:51 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; } -- 2.47.2