@@ -1891,7 +1891,15 @@ class Frame_positional_cursor : public Frame_cursor
1891
1891
{
1892
1892
public:
1893
1893
Frame_positional_cursor (const Frame_cursor &position_cursor) :
1894
- position_cursor (position_cursor) {}
1894
+ position_cursor (position_cursor), bound(NULL ), offset(NULL ),
1895
+ negative_offset (false ) {}
1896
+
1897
+ Frame_positional_cursor (const Frame_cursor &position_cursor,
1898
+ const Frame_cursor &bound,
1899
+ Item &offset,
1900
+ bool negative_offset) :
1901
+ position_cursor (position_cursor), bound(&bound), offset(&offset),
1902
+ negative_offset (negative_offset) {}
1895
1903
1896
1904
void init (READ_RECORD *info)
1897
1905
{
@@ -1905,8 +1913,13 @@ class Frame_positional_cursor : public Frame_cursor
1905
1913
1906
1914
void next_partition (ha_rows rownum)
1907
1915
{
1908
- cursor.move_to (position_cursor.get_curr_rownum ());
1909
- add_value_to_items ();
1916
+ ha_rows position= get_current_position ();
1917
+ if (position_is_within_bounds (position))
1918
+ {
1919
+ cursor.move_to (position);
1920
+ cursor.fetch ();
1921
+ add_value_to_items ();
1922
+ }
1910
1923
}
1911
1924
1912
1925
void pre_next_row ()
@@ -1915,11 +1928,15 @@ class Frame_positional_cursor : public Frame_cursor
1915
1928
1916
1929
void next_row ()
1917
1930
{
1918
- if (position_cursor.is_outside_computation_bounds ())
1931
+ ha_rows position= get_current_position ();
1932
+ if (!position_is_within_bounds (position))
1919
1933
clear_sum_functions ();
1920
-
1921
- cursor.move_to (position_cursor.get_curr_rownum ());
1922
- add_value_to_items ();
1934
+ else
1935
+ {
1936
+ cursor.move_to (position_cursor.get_curr_rownum ());
1937
+ cursor.fetch ();
1938
+ add_value_to_items ();
1939
+ }
1923
1940
}
1924
1941
1925
1942
ha_rows get_curr_rownum () const
@@ -1928,8 +1945,53 @@ class Frame_positional_cursor : public Frame_cursor
1928
1945
}
1929
1946
1930
1947
private:
1948
+ /* Check if a our position is within bounds.
1949
+ * The position is passed as a parameter to avoid recalculating it. */
1950
+ bool position_is_within_bounds (ha_rows position)
1951
+ {
1952
+ if (!offset)
1953
+ return !position_cursor.is_outside_computation_bounds ();
1954
+
1955
+ /* No valid bound to compare to. */
1956
+ if (position_cursor.is_outside_computation_bounds () ||
1957
+ bound->is_outside_computation_bounds ())
1958
+ return false ;
1959
+
1960
+ if (negative_offset)
1961
+ {
1962
+ if (position_cursor.get_curr_rownum () < position)
1963
+ return false ; /* Overflow below 0. */
1964
+ if (position < bound->get_curr_rownum ()) /* We are over the bound. */
1965
+ return false ;
1966
+ }
1967
+ else
1968
+ {
1969
+ if (position_cursor.get_curr_rownum () > position)
1970
+ return false ; /* Overflow over MAX_HA_ROWS. */
1971
+ if (position > bound->get_curr_rownum ()) /* We are over the bound. */
1972
+ return false ;
1973
+ }
1974
+
1975
+ return true ;
1976
+ }
1977
+
1978
+ /* Get the current position, accounting for the offset value, if present.
1979
+ NOTE: This function does not check over/underflow.
1980
+ */
1981
+ ha_rows get_current_position ()
1982
+ {
1983
+ ha_rows position = position_cursor.get_curr_rownum ();
1984
+ if (offset)
1985
+ position += offset->val_int () * (negative_offset ? -1 : 1 );
1986
+ return position;
1987
+ }
1988
+
1931
1989
const Frame_cursor &position_cursor;
1990
+ const Frame_cursor *bound;
1991
+ Item *offset;
1932
1992
Table_read_cursor cursor;
1993
+
1994
+ bool negative_offset;
1933
1995
};
1934
1996
1935
1997
0 commit comments