Commit 31ba0fa4 authored by Vicențiu Ciorbaru's avatar Vicențiu Ciorbaru

MDEV-12851: Case with window functions query crashes server

The "is null" function performs one operation which no other Item_func
does, which is to update used tables during fix_length_and_dec().

This however can not be performed before window functions have had a
chance to resolve their order by and partition by definitions, which
happens after the initial setup_fields call. Consequently, do not call
Item_func_isnull update_used_tables during fix_length_and_dec().

There was another issue detected once the crash was resolved.
Because window functions did not implement is_null() method, we would
end up returning bad results for "is null" and "is not null" functions.
Implemented is_null() method for Item_windowfunc.
parent 23edc7c8
......@@ -3097,3 +3097,33 @@ a
300
300
drop table t;
#
# MDEV-12851 case with window functions query crashes server
#
create table t1(dt datetime);
insert into t1 values ('2017-05-17'), ('2017-05-18');
select dt,
case when (max(dt) over (order by dt rows between 1 following and 1 following) is null)
then '9999-12-31 12:00:00'
else max(dt) over (order by dt rows between 1 following and 1 following)
end x,
case when (max(dt) over (order by dt rows between 1 following and 1 following) is not null)
then '9999-12-31 12:00:00'
else max(dt) over (order by dt rows between 1 following and 1 following)
end x
from t1;
dt x x
2017-05-17 00:00:00 2017-05-18 00:00:00 9999-12-31 12:00:00
2017-05-18 00:00:00 9999-12-31 12:00:00 NULL
drop table t1;
create table t1(i int);
insert into t1 values (null),(1),(2);
select max(i) over (order by i),
max(i) over (order by i) is null,
max(i) over (order by i) is not null
from t1;
max(i) over (order by i) max(i) over (order by i) is null max(i) over (order by i) is not null
NULL 1 0
1 0 1
2 0 1
drop table t1;
......@@ -1887,3 +1887,30 @@ insert into t values (1, 10), (2, 20), (3, 30);
prepare stmt from "SELECT (CASE WHEN sum(t.a) over (partition by t.b)=1 THEN 1000 ELSE 300 END) AS a FROM t";
execute stmt;
drop table t;
--echo #
--echo # MDEV-12851 case with window functions query crashes server
--echo #
create table t1(dt datetime);
insert into t1 values ('2017-05-17'), ('2017-05-18');
select dt,
case when (max(dt) over (order by dt rows between 1 following and 1 following) is null)
then '9999-12-31 12:00:00'
else max(dt) over (order by dt rows between 1 following and 1 following)
end x,
case when (max(dt) over (order by dt rows between 1 following and 1 following) is not null)
then '9999-12-31 12:00:00'
else max(dt) over (order by dt rows between 1 following and 1 following)
end x
from t1;
drop table t1;
create table t1(i int);
insert into t1 values (null),(1),(2);
select max(i) over (order by i),
max(i) over (order by i) is null,
max(i) over (order by i) is not null
from t1;
drop table t1;
......@@ -1770,11 +1770,6 @@ class Item_func_isnull :public Item_func_null_predicate
Item_func_isnull(THD *thd, Item *a): Item_func_null_predicate(thd, a) {}
longlong val_int();
enum Functype functype() const { return ISNULL_FUNC; }
void fix_length_and_dec()
{
Item_func_null_predicate::fix_length_and_dec();
update_used_tables();
}
const char *func_name() const { return "isnull"; }
void print(String *str, enum_query_type query_type);
enum precedence precedence() const { return CMP_PRECEDENCE; }
......
......@@ -155,6 +155,7 @@ void Item_func::sync_with_sum_func_and_with_field(List<Item> &list)
Sets as a side effect the following class variables:
maybe_null Set if any argument may return NULL
with_sum_func Set if any of the arguments contains a sum function
with_window_func Set if any of the arguments contain a window function
with_field Set if any of the arguments contains or is a field
used_tables_cache Set to union of the tables used by arguments
......
......@@ -848,6 +848,17 @@ class Item_window_func : public Item_func_or_sum
read_value_from_result_field= true;
}
bool is_null()
{
if (force_return_blank)
return false;
if (read_value_from_result_field)
return result_field->is_null();
return window_func()->is_null();
}
double val_real()
{
double res;
......
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