@@ -1596,7 +1596,8 @@ scanPage(RumState * rumstate, RumScanEntry entry, RumKey *item, Page page,
1596
1596
OffsetNumber first = FirstOffsetNumber ,
1597
1597
i ,
1598
1598
maxoff ;
1599
- bool found ;
1599
+ int16 bound = -1 ;
1600
+ bool found_eq = false;
1600
1601
int cmp ;
1601
1602
1602
1603
ItemPointerSetMin (& iter_item .iptr );
@@ -1611,6 +1612,7 @@ scanPage(RumState * rumstate, RumScanEntry entry, RumKey *item, Page page,
1611
1612
1612
1613
ptr = RumDataPageGetData (page );
1613
1614
maxoff = RumPageGetOpaque (page )-> maxoff ;
1615
+
1614
1616
for (j = 0 ; j < RumDataLeafIndexCount ; j ++ )
1615
1617
{
1616
1618
RumDataLeafItemIndex * index = & RumPageGetIndexes (page )[j ];
@@ -1629,39 +1631,71 @@ scanPage(RumState * rumstate, RumScanEntry entry, RumKey *item, Page page,
1629
1631
else
1630
1632
cmp = rumCompareItemPointers (& index -> iptr , & item -> iptr );
1631
1633
1632
- if (cmp < 0 || (cmp <= 0 && ! equalOk ))
1634
+ if (cmp < 0 || (cmp <= 0 && equalOk ))
1633
1635
{
1634
1636
ptr = RumDataPageGetData (page ) + index -> pageOffset ;
1635
1637
first = index -> offsetNumer ;
1636
1638
iter_item .iptr = index -> iptr ;
1637
1639
}
1638
1640
else
1639
1641
{
1640
- maxoff = index -> offsetNumer - 1 ;
1642
+ if (ScanDirectionIsBackward (entry -> scanDirection ))
1643
+ {
1644
+ if (j + 1 < RumDataLeafIndexCount )
1645
+ maxoff = RumPageGetIndexes (page )[j + 1 ].offsetNumer ;
1646
+ }
1647
+ else
1648
+ maxoff = index -> offsetNumer - 1 ;
1641
1649
break ;
1642
1650
}
1643
1651
}
1644
1652
1653
+ if (ScanDirectionIsBackward (entry -> scanDirection ))
1654
+ {
1655
+ first = FirstOffsetNumber ;
1656
+ ItemPointerSetMin (& iter_item .iptr );
1657
+ ptr = RumDataPageGetData (page );
1658
+ }
1659
+
1645
1660
entry -> nlist = maxoff - first + 1 ;
1646
- entry -> offset = InvalidOffsetNumber ;
1647
- found = false;
1661
+ bound = -1 ;
1648
1662
for (i = first ; i <= maxoff ; i ++ )
1649
1663
{
1650
1664
ptr = rumDataPageLeafRead (ptr , entry -> attnum , & iter_item , rumstate );
1651
1665
entry -> list [i - first ] = iter_item ;
1652
1666
1667
+ if (bound != -1 )
1668
+ continue ;
1669
+
1653
1670
cmp = compareRumKey (rumstate , entry -> attnumOrig ,
1654
1671
item , & iter_item );
1655
- if ((cmp < 0 || (cmp <= 0 && equalOk )) && entry -> offset == InvalidOffsetNumber )
1672
+
1673
+ if (cmp <= 0 )
1656
1674
{
1657
- found = true;
1658
- entry -> offset = i - first + 1 ;
1675
+ bound = i - first ;
1676
+ if (cmp == 0 )
1677
+ found_eq = true;
1659
1678
}
1660
1679
}
1661
- if (!found )
1680
+
1681
+ if (bound == -1 )
1662
1682
return false;
1663
1683
1664
- entry -> curRumKey = entry -> list [entry -> offset - 1 ];
1684
+ if (found_eq )
1685
+ {
1686
+ entry -> offset = bound ;
1687
+ if (!equalOk )
1688
+ entry -> offset += entry -> scanDirection ;
1689
+ }
1690
+ else if (ScanDirectionIsBackward (entry -> scanDirection ))
1691
+ entry -> offset = bound - 1 ;
1692
+ else
1693
+ entry -> offset = bound ;
1694
+
1695
+ if (entry -> offset < 0 || entry -> offset >= entry -> nlist )
1696
+ return false;
1697
+
1698
+ entry -> curRumKey = entry -> list [entry -> offset ];
1665
1699
return true;
1666
1700
}
1667
1701
@@ -1692,7 +1726,7 @@ entryFindItem(RumState * rumstate, RumScanEntry entry, RumKey * item)
1692
1726
entry -> scanDirection ,
1693
1727
& entry -> curRumKey , item ) >= 0 )
1694
1728
return ;
1695
- while (entry -> offset < entry -> nlist )
1729
+ while (entry -> offset >= 0 && entry -> offset < entry -> nlist )
1696
1730
{
1697
1731
if (compareRumKeyScanDirection (rumstate , entry -> attnumOrig ,
1698
1732
entry -> scanDirection ,
0 commit comments