@@ -1596,7 +1596,8 @@ scanPage(RumState * rumstate, RumScanEntry entry, RumKey *item, Page page,
15961596OffsetNumber first = FirstOffsetNumber ,
15971597i ,
15981598maxoff ;
1599- bool found ;
1599+ int16 bound = -1 ;
1600+ bool found_eq = false;
16001601int cmp ;
16011602
16021603ItemPointerSetMin (& iter_item .iptr );
@@ -1611,6 +1612,7 @@ scanPage(RumState * rumstate, RumScanEntry entry, RumKey *item, Page page,
16111612
16121613ptr = RumDataPageGetData (page );
16131614maxoff = RumPageGetOpaque (page )-> maxoff ;
1615+
16141616for (j = 0 ;j < RumDataLeafIndexCount ;j ++ )
16151617{
16161618RumDataLeafItemIndex * index = & RumPageGetIndexes (page )[j ];
@@ -1629,39 +1631,71 @@ scanPage(RumState * rumstate, RumScanEntry entry, RumKey *item, Page page,
16291631else
16301632cmp = rumCompareItemPointers (& index -> iptr ,& item -> iptr );
16311633
1632- if (cmp < 0 || (cmp <=0 && ! equalOk ))
1634+ if (cmp < 0 || (cmp <=0 && equalOk ))
16331635{
16341636ptr = RumDataPageGetData (page )+ index -> pageOffset ;
16351637first = index -> offsetNumer ;
16361638iter_item .iptr = index -> iptr ;
16371639}
16381640else
16391641{
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 ;
16411649break ;
16421650}
16431651}
16441652
1653+ if (ScanDirectionIsBackward (entry -> scanDirection ))
1654+ {
1655+ first = FirstOffsetNumber ;
1656+ ItemPointerSetMin (& iter_item .iptr );
1657+ ptr = RumDataPageGetData (page );
1658+ }
1659+
16451660entry -> nlist = maxoff - first + 1 ;
1646- entry -> offset = InvalidOffsetNumber ;
1647- found = false;
1661+ bound = -1 ;
16481662for (i = first ;i <=maxoff ;i ++ )
16491663{
16501664ptr = rumDataPageLeafRead (ptr ,entry -> attnum ,& iter_item ,rumstate );
16511665entry -> list [i - first ]= iter_item ;
16521666
1667+ if (bound != -1 )
1668+ continue ;
1669+
16531670cmp = compareRumKey (rumstate ,entry -> attnumOrig ,
16541671item ,& iter_item );
1655- if ((cmp < 0 || (cmp <=0 && equalOk ))&& entry -> offset == InvalidOffsetNumber )
1672+
1673+ if (cmp <=0 )
16561674{
1657- found = true;
1658- entry -> offset = i - first + 1 ;
1675+ bound = i - first ;
1676+ if (cmp == 0 )
1677+ found_eq = true;
16591678}
16601679}
1661- if (!found )
1680+
1681+ if (bound == -1 )
16621682return false;
16631683
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 ];
16651699return true;
16661700}
16671701
@@ -1692,7 +1726,7 @@ entryFindItem(RumState * rumstate, RumScanEntry entry, RumKey * item)
16921726entry -> scanDirection ,
16931727& entry -> curRumKey ,item ) >=0 )
16941728return ;
1695- while (entry -> offset < entry -> nlist )
1729+ while (entry -> offset >= 0 && entry -> offset < entry -> nlist )
16961730{
16971731if (compareRumKeyScanDirection (rumstate ,entry -> attnumOrig ,
16981732entry -> scanDirection ,