summaryrefslogtreecommitdiff
path: root/src/backend/access/gin/gindatapage.c
diff options
context:
space:
mode:
authorAlexander Korotkov <akorotkov@postgresql.org>2018-07-19 21:04:17 +0300
committerAlexander Korotkov <akorotkov@postgresql.org>2018-07-19 21:22:07 +0300
commit3c09b032afe548a4f0c3fd0658957650c3e22832 (patch)
treea6041b0f8c7b5c2c7ddf7f5ce914857099dbea64 /src/backend/access/gin/gindatapage.c
parent3ecd6c4ab9ddfe22e0c6df0fba412c900614aa23 (diff)
Fix handling of empty uncompressed posting list pages in GIN
PostgreSQL 9.4 introduces posting list compression in GIN. This feature supports online upgrade, so that after pg_upgrade uncompressed posting lists are compressed on-the-fly. Underlying code appears to always expect at least one item on uncompressed posting list page. But there could be completely empty pages, because VACUUM never deletes leftmost and rightmost pages from posting trees. This commit fixes that. Reported-by: Sivasubramanian Ramasubramanian Discussion: https://postgr.es/m/1531867212836.63354%40amazon.com Author: Sivasubramanian Ramasubramanian, Alexander Korotkov Backpatch-through: 9.4
Diffstat (limited to 'src/backend/access/gin/gindatapage.c')
-rw-r--r--src/backend/access/gin/gindatapage.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/src/backend/access/gin/gindatapage.c b/src/backend/access/gin/gindatapage.c
index 93f2d8f350d..d25684949f5 100644
--- a/src/backend/access/gin/gindatapage.c
+++ b/src/backend/access/gin/gindatapage.c
@@ -1392,7 +1392,8 @@ disassembleLeaf(Page page)
{
/*
* A pre-9.4 format uncompressed page is represented by a single
- * segment, with an array of items.
+ * segment, with an array of items. The corner case is uncompressed
+ * page containing no items, which is represented as no segments.
*/
ItemPointer uncompressed;
int nuncompressed;
@@ -1400,15 +1401,18 @@ disassembleLeaf(Page page)
uncompressed = dataLeafPageGetUncompressed(page, &nuncompressed);
- seginfo = palloc(sizeof(leafSegmentInfo));
+ if (nuncompressed > 0)
+ {
+ seginfo = palloc(sizeof(leafSegmentInfo));
- seginfo->action = GIN_SEGMENT_REPLACE;
- seginfo->seg = NULL;
- seginfo->items = palloc(nuncompressed * sizeof(ItemPointerData));
- memcpy(seginfo->items, uncompressed, nuncompressed * sizeof(ItemPointerData));
- seginfo->nitems = nuncompressed;
+ seginfo->action = GIN_SEGMENT_REPLACE;
+ seginfo->seg = NULL;
+ seginfo->items = palloc(nuncompressed * sizeof(ItemPointerData));
+ memcpy(seginfo->items, uncompressed, nuncompressed * sizeof(ItemPointerData));
+ seginfo->nitems = nuncompressed;
- dlist_push_tail(&leaf->segments, &seginfo->node);
+ dlist_push_tail(&leaf->segments, &seginfo->node);
+ }
leaf->oldformat = true;
}