@@ -390,7 +390,15 @@ GinDataPageAddPostingItem(Page page, PostingItem *data, OffsetNumber offset)
390390}
391391memcpy (ptr ,data ,sizeof (PostingItem ));
392392
393- GinPageGetOpaque (page )-> maxoff ++ ;
393+ maxoff ++ ;
394+ GinPageGetOpaque (page )-> maxoff = maxoff ;
395+
396+ /*
397+ * Also set pd_lower to the end of the posting items, to follow the
398+ * "standard" page layout, so that we can squeeze out the unused space
399+ * from full-page images.
400+ */
401+ GinDataPageSetDataSize (page ,maxoff * sizeof (PostingItem ));
394402}
395403
396404/*
@@ -409,7 +417,10 @@ GinPageDeletePostingItem(Page page, OffsetNumber offset)
409417GinDataPageGetPostingItem (page ,offset + 1 ),
410418sizeof (PostingItem )* (maxoff - offset ));
411419
412- GinPageGetOpaque (page )-> maxoff -- ;
420+ maxoff -- ;
421+ GinPageGetOpaque (page )-> maxoff = maxoff ;
422+
423+ GinDataPageSetDataSize (page ,maxoff * sizeof (PostingItem ));
413424}
414425
415426/*
@@ -520,7 +531,7 @@ dataPlaceToPageLeaf(GinBtree btree, Buffer buf, GinBtreeStack *stack,
520531 * a single byte, and we can use all the free space on the old page as
521532 * well as the new page. For simplicity, ignore segment overhead etc.
522533 */
523- maxitems = Min (maxitems ,freespace + GinDataLeafMaxContentSize );
534+ maxitems = Min (maxitems ,freespace + GinDataPageMaxDataSize );
524535}
525536else
526537{
@@ -535,7 +546,7 @@ dataPlaceToPageLeaf(GinBtree btree, Buffer buf, GinBtreeStack *stack,
535546int nnewsegments ;
536547
537548nnewsegments = freespace /GinPostingListSegmentMaxSize ;
538- nnewsegments += GinDataLeafMaxContentSize /GinPostingListSegmentMaxSize ;
549+ nnewsegments += GinDataPageMaxDataSize /GinPostingListSegmentMaxSize ;
539550maxitems = Min (maxitems ,nnewsegments * MinTuplesPerSegment );
540551}
541552
@@ -648,8 +659,8 @@ dataPlaceToPageLeaf(GinBtree btree, Buffer buf, GinBtreeStack *stack,
648659leaf -> lastleft = dlist_prev_node (& leaf -> segments ,leaf -> lastleft );
649660}
650661}
651- Assert (leaf -> lsize <=GinDataLeafMaxContentSize );
652- Assert (leaf -> rsize <=GinDataLeafMaxContentSize );
662+ Assert (leaf -> lsize <=GinDataPageMaxDataSize );
663+ Assert (leaf -> rsize <=GinDataPageMaxDataSize );
653664
654665/*
655666 * Fetch the max item in the left page's last segment; it becomes the
@@ -716,7 +727,7 @@ ginVacuumPostingTreeLeaf(Relation indexrel, Buffer buffer, GinVacuumState *gvs)
716727if (seginfo -> seg )
717728oldsegsize = SizeOfGinPostingList (seginfo -> seg );
718729else
719- oldsegsize = GinDataLeafMaxContentSize ;
730+ oldsegsize = GinDataPageMaxDataSize ;
720731
721732cleaned = ginVacuumItemPointers (gvs ,
722733seginfo -> items ,
@@ -987,8 +998,8 @@ dataPlaceToPageLeafRecompress(Buffer buf, disassembledLeaf *leaf)
987998}
988999}
9891000
990- Assert (newsize <=GinDataLeafMaxContentSize );
991- GinDataLeafPageSetPostingListSize (page ,newsize );
1001+ Assert (newsize <=GinDataPageMaxDataSize );
1002+ GinDataPageSetDataSize (page ,newsize );
9921003}
9931004
9941005/*
@@ -1043,7 +1054,7 @@ dataPlaceToPageLeafSplit(Buffer buf, disassembledLeaf *leaf,
10431054}
10441055}
10451056Assert (lsize == leaf -> lsize );
1046- GinDataLeafPageSetPostingListSize (lpage ,lsize );
1057+ GinDataPageSetDataSize (lpage ,lsize );
10471058* GinDataPageGetRightBound (lpage )= lbound ;
10481059
10491060/* Copy the segments that go to the right page */
@@ -1067,7 +1078,7 @@ dataPlaceToPageLeafSplit(Buffer buf, disassembledLeaf *leaf,
10671078break ;
10681079}
10691080Assert (rsize == leaf -> rsize );
1070- GinDataLeafPageSetPostingListSize (rpage ,rsize );
1081+ GinDataPageSetDataSize (rpage ,rsize );
10711082* GinDataPageGetRightBound (rpage )= rbound ;
10721083
10731084/* Create WAL record */
@@ -1139,7 +1150,7 @@ dataPlaceToPageInternal(GinBtree btree, Buffer buf, GinBtreeStack *stack,
11391150data .newitem = * pitem ;
11401151
11411152rdata .buffer = buf ;
1142- rdata .buffer_std = false ;
1153+ rdata .buffer_std = TRUE ;
11431154rdata .data = (char * )& data ;
11441155rdata .len = sizeof (ginxlogInsertDataInternal );
11451156rdata .next = NULL ;
@@ -1183,6 +1194,8 @@ dataSplitPageInternal(GinBtree btree, Buffer origbuf,
11831194Page oldpage = BufferGetPage (origbuf );
11841195OffsetNumber off = stack -> off ;
11851196int nitems = GinPageGetOpaque (oldpage )-> maxoff ;
1197+ int nleftitems ;
1198+ int nrightitems ;
11861199Size pageSize = PageGetPageSize (oldpage );
11871200ItemPointerData oldbound = * GinDataPageGetRightBound (oldpage );
11881201ItemPointer bound ;
@@ -1226,17 +1239,27 @@ dataSplitPageInternal(GinBtree btree, Buffer origbuf,
12261239separator = GinNonLeafDataPageGetFreeSpace (rpage ) /sizeof (PostingItem );
12271240else
12281241separator = nitems /2 ;
1242+ nleftitems = separator ;
1243+ nrightitems = nitems - separator ;
12291244
1230- memcpy (GinDataPageGetPostingItem (lpage ,FirstOffsetNumber ),allitems ,separator * sizeof (PostingItem ));
1231- GinPageGetOpaque (lpage )-> maxoff = separator ;
1245+ memcpy (GinDataPageGetPostingItem (lpage ,FirstOffsetNumber ),
1246+ allitems ,
1247+ nleftitems * sizeof (PostingItem ));
1248+ GinPageGetOpaque (lpage )-> maxoff = nleftitems ;
12321249memcpy (GinDataPageGetPostingItem (rpage ,FirstOffsetNumber ),
1233- & allitems [separator ], (nitems - separator )* sizeof (PostingItem ));
1234- GinPageGetOpaque (rpage )-> maxoff = nitems - separator ;
1250+ & allitems [separator ],
1251+ nrightitems * sizeof (PostingItem ));
1252+ GinPageGetOpaque (rpage )-> maxoff = nrightitems ;
1253+
1254+ /*
1255+ * Also set pd_lower for both pages, like GinDataPageAddPostingItem does.
1256+ */
1257+ GinDataPageSetDataSize (lpage ,nleftitems * sizeof (PostingItem ));
1258+ GinDataPageSetDataSize (rpage ,nrightitems * sizeof (PostingItem ));
12351259
12361260/* set up right bound for left page */
12371261bound = GinDataPageGetRightBound (lpage );
1238- * bound = GinDataPageGetPostingItem (lpage ,
1239- GinPageGetOpaque (lpage )-> maxoff )-> key ;
1262+ * bound = GinDataPageGetPostingItem (lpage ,nleftitems )-> key ;
12401263
12411264/* set up right bound for right page */
12421265* GinDataPageGetRightBound (rpage )= oldbound ;
@@ -1619,7 +1642,7 @@ leafRepackItems(disassembledLeaf *leaf, ItemPointer remaining)
16191642 * copying to the page. Did we exceed the size that fits on one page?
16201643 */
16211644segsize = SizeOfGinPostingList (seginfo -> seg );
1622- if (pgused + segsize > GinDataLeafMaxContentSize )
1645+ if (pgused + segsize > GinDataPageMaxDataSize )
16231646{
16241647if (!needsplit )
16251648{
@@ -1659,8 +1682,8 @@ leafRepackItems(disassembledLeaf *leaf, ItemPointer remaining)
16591682else
16601683leaf -> rsize = pgused ;
16611684
1662- Assert (leaf -> lsize <=GinDataLeafMaxContentSize );
1663- Assert (leaf -> rsize <=GinDataLeafMaxContentSize );
1685+ Assert (leaf -> lsize <=GinDataPageMaxDataSize );
1686+ Assert (leaf -> rsize <=GinDataPageMaxDataSize );
16641687
16651688/*
16661689 * Make a palloc'd copy of every segment after the first modified one,
@@ -1735,7 +1758,7 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
17351758GinPostingListSegmentMaxSize ,
17361759& npacked );
17371760segsize = SizeOfGinPostingList (segment );
1738- if (rootsize + segsize > GinDataLeafMaxContentSize )
1761+ if (rootsize + segsize > GinDataPageMaxDataSize )
17391762break ;
17401763
17411764memcpy (ptr ,segment ,segsize );
@@ -1744,7 +1767,7 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
17441767nrootitems += npacked ;
17451768pfree (segment );
17461769}
1747- GinDataLeafPageSetPostingListSize (tmppage ,rootsize );
1770+ GinDataPageSetDataSize (tmppage ,rootsize );
17481771
17491772/*
17501773 * All set. Get a new physical page, and copy the in-memory page to it.