Commit 1adc3fab authored by Vicențiu Ciorbaru's avatar Vicențiu Ciorbaru

MDEV-10097: Assertion `count > 0' failed in Item_sum_sum::add_helper(bool)

When specifying a RANGE type frame that exceeds the partition size, both
for the top and bottom cursors we end up removing more rows than added
to the aggregate function. This happens because our TOP range cursor,
which removes values from the aggregate function, would be allowed to breach
partition boundaries, while the BOTTOM range cursor would not.

To prevent this from happening, force the TOP range cursor to only move
within the current partition, as does the BOTTOM range cursor.
parent 23e8b508
...@@ -1959,3 +1959,24 @@ select rank() over (order by i) from v1; ...@@ -1959,3 +1959,24 @@ select rank() over (order by i) from v1;
rank() over (order by i) rank() over (order by i)
1 1
drop view v1; drop view v1;
#
# MDEV-10097: Assertion `count > 0' failed in Item_sum_sum::add_helper(bool)
#
CREATE TABLE `orders` (
`o_orderkey` int(11) NOT NULL,
`o_custkey` int(11) DEFAULT NULL,
PRIMARY KEY (`o_orderkey`)
) DEFAULT CHARSET=latin1;
INSERT INTO `orders` VALUES (59908,242);
INSERT INTO `orders` VALUES (59940,238);
SELECT o_custkey, avg(o_custkey) OVER (PARTITION BY abs(o_custkey)
ORDER BY o_custkey
RANGE BETWEEN 15 FOLLOWING
AND 15 FOLLOWING) from orders;
o_custkey avg(o_custkey) OVER (PARTITION BY abs(o_custkey)
ORDER BY o_custkey
RANGE BETWEEN 15 FOLLOWING
AND 15 FOLLOWING)
242 NULL
238 NULL
DROP table orders;
...@@ -1201,3 +1201,20 @@ create view v1 as select 1 as i; ...@@ -1201,3 +1201,20 @@ create view v1 as select 1 as i;
select rank() over (order by i) from v1; select rank() over (order by i) from v1;
drop view v1; drop view v1;
--echo #
--echo # MDEV-10097: Assertion `count > 0' failed in Item_sum_sum::add_helper(bool)
--echo #
CREATE TABLE `orders` (
`o_orderkey` int(11) NOT NULL,
`o_custkey` int(11) DEFAULT NULL,
PRIMARY KEY (`o_orderkey`)
) DEFAULT CHARSET=latin1;
INSERT INTO `orders` VALUES (59908,242);
INSERT INTO `orders` VALUES (59940,238);
SELECT o_custkey, avg(o_custkey) OVER (PARTITION BY abs(o_custkey)
ORDER BY o_custkey
RANGE BETWEEN 15 FOLLOWING
AND 15 FOLLOWING) from orders;
DROP table orders;
...@@ -877,7 +877,7 @@ class Cursor_manager ...@@ -877,7 +877,7 @@ class Cursor_manager
class Frame_range_n_top : public Frame_cursor class Frame_range_n_top : public Frame_cursor
{ {
Table_read_cursor cursor; Partition_read_cursor cursor;
Cached_item_item *range_expr; Cached_item_item *range_expr;
...@@ -885,6 +885,9 @@ class Frame_range_n_top : public Frame_cursor ...@@ -885,6 +885,9 @@ class Frame_range_n_top : public Frame_cursor
Item *item_add; Item *item_add;
const bool is_preceding; const bool is_preceding;
bool end_of_partition;
/* /*
1 when order_list uses ASC ordering 1 when order_list uses ASC ordering
-1 when order_list uses DESC ordering -1 when order_list uses DESC ordering
...@@ -895,7 +898,8 @@ class Frame_range_n_top : public Frame_cursor ...@@ -895,7 +898,8 @@ class Frame_range_n_top : public Frame_cursor
SQL_I_List<ORDER> *partition_list, SQL_I_List<ORDER> *partition_list,
SQL_I_List<ORDER> *order_list, SQL_I_List<ORDER> *order_list,
bool is_preceding_arg, Item *n_val_arg) : bool is_preceding_arg, Item *n_val_arg) :
n_val(n_val_arg), item_add(NULL), is_preceding(is_preceding_arg) cursor(thd, partition_list), n_val(n_val_arg), item_add(NULL),
is_preceding(is_preceding_arg)
{ {
DBUG_ASSERT(order_list->elements == 1); DBUG_ASSERT(order_list->elements == 1);
Item *src_expr= order_list->first->item[0]; Item *src_expr= order_list->first->item[0];
...@@ -921,13 +925,15 @@ class Frame_range_n_top : public Frame_cursor ...@@ -921,13 +925,15 @@ class Frame_range_n_top : public Frame_cursor
void init(READ_RECORD *info) void init(READ_RECORD *info)
{ {
cursor.init(info); cursor.init(info);
} }
void pre_next_partition(ha_rows rownum) void pre_next_partition(ha_rows rownum)
{ {
// Save the value of FUNC(current_row) // Save the value of FUNC(current_row)
range_expr->fetch_value_from(item_add); range_expr->fetch_value_from(item_add);
cursor.on_next_partition(rownum);
end_of_partition= false;
} }
void next_partition(ha_rows rownum) void next_partition(ha_rows rownum)
...@@ -938,11 +944,15 @@ class Frame_range_n_top : public Frame_cursor ...@@ -938,11 +944,15 @@ class Frame_range_n_top : public Frame_cursor
void pre_next_row() void pre_next_row()
{ {
if (end_of_partition)
return;
range_expr->fetch_value_from(item_add); range_expr->fetch_value_from(item_add);
} }
void next_row() void next_row()
{ {
if (end_of_partition)
return;
/* /*
Ok, our cursor is at the first row R where Ok, our cursor is at the first row R where
(prev_row + n) >= R (prev_row + n) >= R
...@@ -960,12 +970,15 @@ class Frame_range_n_top : public Frame_cursor ...@@ -960,12 +970,15 @@ class Frame_range_n_top : public Frame_cursor
private: private:
void walk_till_non_peer() void walk_till_non_peer()
{ {
while (!cursor.get_next()) int res;
while (!(res= cursor.get_next()))
{ {
if (order_direction * range_expr->cmp_read_only() <= 0) if (order_direction * range_expr->cmp_read_only() <= 0)
break; break;
remove_value_from_items(); remove_value_from_items();
} }
if (res)
end_of_partition= true;
} }
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment