From 88231ec5784a00ce406553276be8a5a443dd3ba0 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas <heikki.linnakangas@iki.fi> Date: Fri, 29 Aug 2014 14:19:34 +0300 Subject: [PATCH] Fix bug in compressed GIN data leaf page splitting code. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- src/backend/access/gin/gindatapage.c | 28 ++++++++++++++++------------ 1 file 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); } } -- GitLab