From: Heikki Linnakangas Date: Fri, 29 Aug 2014 11:19:34 +0000 (+0300) Subject: Fix bug in compressed GIN data leaf page splitting code. X-Git-Tag: REL9_4_BETA3~72 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=08bff295a7e7ac66a35f42e92e97782b9af64cdc;p=postgresql 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. --- diff --git a/src/backend/access/gin/gindatapage.c b/src/backend/access/gin/gindatapage.c index 272a9ca7c0..0ea4f3fe28 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; + 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); } }