aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2014-08-29 14:19:34 +0300
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2014-08-29 14:22:25 +0300
commit88231ec5784a00ce406553276be8a5a443dd3ba0 (patch)
treedf1b626ce50566bd9d21008bfe84b1b13416d474
parent65c9dc231a261691c76550f61f5b22f954dfcfd5 (diff)
downloadpostgresql-88231ec5784a00ce406553276be8a5a443dd3ba0.tar.gz
postgresql-88231ec5784a00ce406553276be8a5a443dd3ba0.zip
Fix bug in compressed GIN data leaf page splitting code.
The list of posting lists it's dealing with can contain placeholders for deleted posting lists. The placeholders are kept around so that they can be WAL-logged, but we must be careful to not try to access them. This fixes bug #11280, reported by MÃ¥rten Svantesson. Backpatch to 9.4, where the compressed data leaf page code was added.
-rw-r--r--src/backend/access/gin/gindatapage.c28
1 files changed, 16 insertions, 12 deletions
diff --git a/src/backend/access/gin/gindatapage.c b/src/backend/access/gin/gindatapage.c
index 5b7c49654c6..76e0cb3e19f 100644
--- a/src/backend/access/gin/gindatapage.c
+++ b/src/backend/access/gin/gindatapage.c
@@ -641,20 +641,24 @@ dataPlaceToPageLeaf(GinBtree btree, Buffer buf, GinBtreeStack *stack,
{
lastleftinfo = dlist_container(leafSegmentInfo, node, leaf->lastleft);
- segsize = SizeOfGinPostingList(lastleftinfo->seg);
- if (append)
+ /* ignore deleted segments */
+ if (lastleftinfo->action != GIN_SEGMENT_DELETE)
{
- if ((leaf->lsize - segsize) - (leaf->lsize - segsize) < BLCKSZ / 4)
- break;
+ segsize = SizeOfGinPostingList(lastleftinfo->seg);
+ if (append)
+ {
+ if ((leaf->lsize - segsize) - (leaf->lsize - segsize) < BLCKSZ / 4)
+ break;
+ }
+ else
+ {
+ if ((leaf->lsize - segsize) - (leaf->rsize + segsize) < 0)
+ break;
+ }
+
+ leaf->lsize -= segsize;
+ leaf->rsize += segsize;
}
- else
- {
- if ((leaf->lsize - segsize) - (leaf->rsize + segsize) < 0)
- break;
- }
-
- leaf->lsize -= segsize;
- leaf->rsize += segsize;
leaf->lastleft = dlist_prev_node(&leaf->segments, leaf->lastleft);
}
}