XLogRecData **prdata, Page lpage, Page rpage);
 
 /*
- * Read all TIDs from leaf data page to single uncompressed array.
+ * Read TIDs from leaf data page to single uncompressed array. The TIDs are
+ * returned in ascending order.
+ *
+ * advancePast is a hint, indicating that the caller is only interested in
+ * TIDs > advancePast. To return all items, use ItemPointerSetMin.
+ *
+ * Note: This function can still return items smaller than advancePast that
+ * are in the same posting list as the items of interest, so the caller must
+ * still check all the returned items. But passing it allows this function to
+ * skip whole posting lists.
  */
 ItemPointer
-GinDataLeafPageGetItems(Page page, int *nitems)
+GinDataLeafPageGetItems(Page page, int *nitems, ItemPointerData advancePast)
 {
    ItemPointer result;
 
    if (GinPageIsCompressed(page))
    {
-       GinPostingList *ptr = GinDataLeafPageGetPostingList(page);
+       GinPostingList *seg = GinDataLeafPageGetPostingList(page);
        Size        len = GinDataLeafPageGetPostingListSize(page);
+       Pointer     endptr = ((Pointer) seg) + len;
+       GinPostingList *next;
+
+       /* Skip to the segment containing advancePast+1 */
+       if (ItemPointerIsValid(&advancePast))
+       {
+           next = GinNextPostingListSegment(seg);
+           while ((Pointer) next < endptr &&
+                  ginCompareItemPointers(&next->first, &advancePast) <= 0)
+           {
+               seg = next;
+               next = GinNextPostingListSegment(seg);
+           }
+           len = endptr - (Pointer) seg;
+       }
 
-       result = ginPostingListDecodeAllSegments(ptr, len, nitems);
+       if (len > 0)
+           result = ginPostingListDecodeAllSegments(seg, len, nitems);
+       else
+       {
+           result = NULL;
+           *nitems = 0;
+       }
    }
    else
    {
 
            BlockNumber rootPostingTree = GinGetPostingTree(itup);
            GinBtreeStack *stack;
            Page        page;
+           ItemPointerData minItem;
 
            /*
             * We should unlock entry page before touching posting tree to
            /*
             * Load the first page into memory.
             */
-           entry->list = GinDataLeafPageGetItems(page, &entry->nlist);
+           ItemPointerSetMin(&minItem);
+           entry->list = GinDataLeafPageGetItems(page, &entry->nlist, minItem);
 
            entry->predictNumberResult = stack->predictNumber * entry->nlist;
 
            continue;
        }
 
-       entry->list = GinDataLeafPageGetItems(page, &entry->nlist);
+       entry->list = GinDataLeafPageGetItems(page, &entry->nlist, advancePast);
 
        for (i = 0; i < entry->nlist; i++)
        {
 
             IndexTuple itup, int *nitems);
 
 /* gindatapage.c */
-extern ItemPointer GinDataLeafPageGetItems(Page page, int *nitems);
+extern ItemPointer GinDataLeafPageGetItems(Page page, int *nitems, ItemPointerData advancePast);
 extern int GinDataLeafPageGetItemsToTbm(Page page, TIDBitmap *tbm);
 extern BlockNumber createPostingTree(Relation index,
                  ItemPointerData *items, uint32 nitems,