/* A bitmap result */
         BlockNumber advancePastBlk = GinItemPointerGetBlockNumber(&advancePast);
         OffsetNumber advancePastOff = GinItemPointerGetOffsetNumber(&advancePast);
 -       bool        gotitem = false;
  
 -       do
 +       for (;;)
         {
             /*
              * If we've exhausted all items on this block, move to next block
                   * estimate number of results on this page to support correct
                  * reducing of result even if it's enabled.
                  */
 -               gotitem = true;
                 break;
             }
  
                  /*
                  * First, do a quick check against the last offset on the
                  * page. If that's > advancePast, so are all the other
 -                * offsets.
 +                * offsets, so just go back to the top to get the next page.
                  */
                 if (entry->matchResult->offsets[entry->matchResult->ntuples - 1] <= advancePastOff)
                 {
                             entry->matchResult->blockno,
                            entry->matchResult->offsets[entry->offset]);
             entry->offset++;
 -           gotitem = true;
 -       } while (!gotitem || (entry->reduceResult == true && dropItem(entry)));
 +
 +           /* Done unless we need to reduce the result */
 +           if (!entry->reduceResult || !dropItem(entry))
 +               break;
 +       }
     }
     else if (!BufferIsValid(entry->buffer))
     {
           * A posting list from an entry tuple, or the last page of a posting
          * tree.
          */
 -       do
 +       for (;;)
         {
             if (entry->offset >= entry->nlist)
             {
              }
  
             entry->curItem = entry->list[entry->offset++];
 -       } while (ginCompareItemPointers(&entry->curItem, &advancePast) <= 0);
 -       /* XXX: shouldn't we apply the fuzzy search limit here? */
 +
 +           /* If we're not past advancePast, keep scanning */
 +           if (ginCompareItemPointers(&entry->curItem, &advancePast) <= 0)
 +               continue;
 +
 +           /* Done unless we need to reduce the result */
 +           if (!entry->reduceResult || !dropItem(entry))
 +               break;
 +       }
     }
     else
     {
         /* A posting tree */
 -       do
 +       for (;;)
         {
             /* If we've processed the current batch, load more items */
             while (entry->offset >= entry->nlist)
   
             entry->curItem = entry->list[entry->offset++];
  
 -       } while (ginCompareItemPointers(&entry->curItem, &advancePast) <= 0 ||
 -                (entry->reduceResult == true && dropItem(entry)));
 +           /* If we're not past advancePast, keep scanning */
 +           if (ginCompareItemPointers(&entry->curItem, &advancePast) <= 0)
 +               continue;
 +
 +           /* Done unless we need to reduce the result */
 +           if (!entry->reduceResult || !dropItem(entry))
 +               break;
 +
 +           /*
 +            * Advance advancePast (so that entryLoadMoreItems will load the
 +            * right data), and keep scanning
 +            */
 +           advancePast = entry->curItem;
 +       }
     }
  }
  
          insert into gin_test_tbl select array[1, 3, g] from generate_series(1, 1000) g;
  delete from gin_test_tbl where i @> array[2];
  vacuum gin_test_tbl;
 +-- Test for "rare && frequent" searches
 +explain (costs off)
 +select count(*) from gin_test_tbl where i @> array[1, 999];
 +                      QUERY PLAN                       
 +-------------------------------------------------------
 + Aggregate
 +   ->  Bitmap Heap Scan on gin_test_tbl
 +         Recheck Cond: (i @> '{1,999}'::integer[])
 +         ->  Bitmap Index Scan on gin_test_idx
 +               Index Cond: (i @> '{1,999}'::integer[])
 +(5 rows)
 +
 +select count(*) from gin_test_tbl where i @> array[1, 999];
 + count 
 +-------
 +     3
 +(1 row)
 +
 +-- Very weak test for gin_fuzzy_search_limit
 +set gin_fuzzy_search_limit = 1000;
 +explain (costs off)
 +select count(*) > 0 as ok from gin_test_tbl where i @> array[1];
 +                    QUERY PLAN                     
 +---------------------------------------------------
 + Aggregate
 +   ->  Bitmap Heap Scan on gin_test_tbl
 +         Recheck Cond: (i @> '{1}'::integer[])
 +         ->  Bitmap Index Scan on gin_test_idx
 +               Index Cond: (i @> '{1}'::integer[])
 +(5 rows)
 +
 +select count(*) > 0 as ok from gin_test_tbl where i @> array[1];
 + ok 
 +----
 + t
 +(1 row)
 +
 +reset gin_fuzzy_search_limit;
  -- Test optimization of empty queries
  create temp table t_gin_test_tbl(i int4[], j int4[]);
  create index on t_gin_test_tbl using gin (i, j);
          delete from gin_test_tbl where i @> array[2];
  vacuum gin_test_tbl;
  
 +-- Test for "rare && frequent" searches
 +explain (costs off)
 +select count(*) from gin_test_tbl where i @> array[1, 999];
 +
 +select count(*) from gin_test_tbl where i @> array[1, 999];
 +
 +-- Very weak test for gin_fuzzy_search_limit
 +set gin_fuzzy_search_limit = 1000;
 +
 +explain (costs off)
 +select count(*) > 0 as ok from gin_test_tbl where i @> array[1];
 +
 +select count(*) > 0 as ok from gin_test_tbl where i @> array[1];
 +
 +reset gin_fuzzy_search_limit;
 +
  -- Test optimization of empty queries
  create temp table t_gin_test_tbl(i int4[], j int4[]);
  create index on t_gin_test_tbl using gin (i, j);