Skip to content

Commit e992464

Browse files
committed
Update Frame_positional_cursor to also take an optional bound
The positional cursor now fetches rows based on the positional cursor and an offset (if present). It will fetch rows, based on the offset, only if the required position is not out of bounds.
1 parent 88a8abb commit e992464

File tree

1 file changed

+69
-7
lines changed

1 file changed

+69
-7
lines changed

sql/sql_window.cc

Lines changed: 69 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1891,7 +1891,15 @@ class Frame_positional_cursor : public Frame_cursor
18911891
{
18921892
public:
18931893
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) {}
18951903

18961904
void init(READ_RECORD *info)
18971905
{
@@ -1905,8 +1913,13 @@ class Frame_positional_cursor : public Frame_cursor
19051913

19061914
void next_partition(ha_rows rownum)
19071915
{
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+
}
19101923
}
19111924

19121925
void pre_next_row()
@@ -1915,11 +1928,15 @@ class Frame_positional_cursor : public Frame_cursor
19151928

19161929
void next_row()
19171930
{
1918-
if (position_cursor.is_outside_computation_bounds())
1931+
ha_rows position= get_current_position();
1932+
if (!position_is_within_bounds(position))
19191933
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+
}
19231940
}
19241941

19251942
ha_rows get_curr_rownum() const
@@ -1928,8 +1945,53 @@ class Frame_positional_cursor : public Frame_cursor
19281945
}
19291946

19301947
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+
19311989
const Frame_cursor &position_cursor;
1990+
const Frame_cursor *bound;
1991+
Item *offset;
19321992
Table_read_cursor cursor;
1993+
1994+
bool negative_offset;
19331995
};
19341996

19351997

0 commit comments

Comments
 (0)