From 08bff295a7e7ac66a35f42e92e97782b9af64cdc Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas 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 272a9ca7c09..0ea4f3fe284 100644 --- a/src/backend/access/gin/gindatapage.c +++ b/src/backend/access/gin/gindatapage.c @@ -642,20 +642,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; - } - else - { - if ((leaf->lsize - segsize) - (leaf->rsize + segsize) < 0) - 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; + leaf->lsize -= segsize; + leaf->rsize += segsize; + } leaf->lastleft = dlist_prev_node(&leaf->segments, leaf->lastleft); } }