aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTeodor Sigaev <teodor@sigaev.ru>2007-10-29 13:49:21 +0000
committerTeodor Sigaev <teodor@sigaev.ru>2007-10-29 13:49:21 +0000
commit85376c6f7d0e2f40b3aed13d1c9c5967cdea13e1 (patch)
tree6fc21d32215c512f4c04e03de7b0f8d3ffa5ada1 /src
parent811be893fa743ef553950a5d31b7e68230d3cf11 (diff)
downloadpostgresql-85376c6f7d0e2f40b3aed13d1c9c5967cdea13e1.tar.gz
postgresql-85376c6f7d0e2f40b3aed13d1c9c5967cdea13e1.zip
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 <craig.mcelroy@contegix.com>. Patch doesn't change on-disk storage.
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/gin/ginentrypage.c48
1 files changed, 30 insertions, 18 deletions
diff --git a/src/backend/access/gin/ginentrypage.c b/src/backend/access/gin/ginentrypage.c
index 70867ac40ba..2c335aea0cd 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.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 $
*-------------------------------------------------------------------------
*/
@@ -404,6 +404,31 @@ entryPlaceToPage(GinBtree btree, Buffer buf, OffsetNumber off, XLogRecData **prd
}
/*
+ * 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.
* Tuples are distributed between pages by equal size on its, not
@@ -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;
}