mirror of
https://github.com/MariaDB/server.git
synced 2025-12-24 11:21:21 +03:00
MDEV-10017: Get unexpected Empty Set for correlated subquery with aggregate functions
take into account all arguments of aggregate function
This commit is contained in:
@@ -2397,5 +2397,40 @@ Note 1276 Field or reference 'test.t10.b' of SELECT #3 was resolved in SELECT #1
|
||||
Note 1003 select `test`.`t10`.`a` AS `a` from `test`.`t10` where ((`test`.`t10`.`c` < 3) or <expr_cache><`test`.`t10`.`a`,`test`.`t10`.`b`>(<in_optimizer>(`test`.`t10`.`a`,<exists>(select `test`.`t12`.`c` from `test`.`t12` where (<cache>(`test`.`t10`.`a`) = `test`.`t12`.`c`) union select max(`test`.`t10`.`b`) from `test`.`t11` group by `test`.`t11`.`c` having (<cache>(`test`.`t10`.`a`) = <ref_null_helper>(max(`test`.`t10`.`b`)))))))
|
||||
drop table t10,t11,t12;
|
||||
#
|
||||
# MDEV-10017: Get unexpected `Empty Set` for correlated subquery
|
||||
# with aggregate functions
|
||||
#
|
||||
create table t1(c1 int, c2 int, c3 int);
|
||||
insert into t1 values(1,1,1),(2,2,2),(3,3,3);
|
||||
select * from t1;
|
||||
c1 c2 c3
|
||||
1 1 1
|
||||
2 2 2
|
||||
3 3 3
|
||||
create table t2(c1 int, c2 int);
|
||||
insert into t2 values(2,2);
|
||||
select * from t2;
|
||||
c1 c2
|
||||
2 2
|
||||
explain extended
|
||||
select c1 from t1 having c1 >= (select t.c1 as c from t2 t order by (select min(t1.c1+c) from t2 tt));
|
||||
ERROR HY000: Invalid use of group function
|
||||
select c1 from t1 having c1 >= (select t.c1 as c from t2 t order by (select min(t1.c1+c) from t2 tt));
|
||||
ERROR HY000: Invalid use of group function
|
||||
explain extended
|
||||
select c1 from t1 having c1 >= (select t.c1 as c from t2 t order by (select min(t1.c1+tt.c1) from t2 tt));
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
|
||||
2 DEPENDENT SUBQUERY t system NULL NULL NULL NULL 1 100.00
|
||||
3 DEPENDENT SUBQUERY tt system NULL NULL NULL NULL 1 100.00
|
||||
Warnings:
|
||||
Note 1276 Field or reference 'test.t1.c1' of SELECT #3 was resolved in SELECT #1
|
||||
Note 1003 select `test`.`t1`.`c1` AS `c1` from `test`.`t1` having (`test`.`t1`.`c1` >= <expr_cache><`test`.`t1`.`c1`>((select 2 AS `c` from dual order by (select min((`test`.`t1`.`c1` + 2)) from dual))))
|
||||
select c1 from t1 having c1 >= (select t.c1 as c from t2 t order by (select min(t1.c1+tt.c1) from t2 tt));
|
||||
c1
|
||||
2
|
||||
3
|
||||
drop table t1,t2;
|
||||
#
|
||||
# End of 10.1 tests
|
||||
#
|
||||
|
||||
@@ -1657,6 +1657,28 @@ create table t11 as select * from t10;
|
||||
create table t12 as select * from t10;
|
||||
explain extended select a from t10 where c<3 or a in (select c from t12 union select max(t10.b) from t11 group by t11.c);
|
||||
drop table t10,t11,t12;
|
||||
--echo #
|
||||
--echo # MDEV-10017: Get unexpected `Empty Set` for correlated subquery
|
||||
--echo # with aggregate functions
|
||||
--echo #
|
||||
|
||||
create table t1(c1 int, c2 int, c3 int);
|
||||
insert into t1 values(1,1,1),(2,2,2),(3,3,3);
|
||||
select * from t1;
|
||||
create table t2(c1 int, c2 int);
|
||||
insert into t2 values(2,2);
|
||||
select * from t2;
|
||||
--error ER_INVALID_GROUP_FUNC_USE
|
||||
explain extended
|
||||
select c1 from t1 having c1 >= (select t.c1 as c from t2 t order by (select min(t1.c1+c) from t2 tt));
|
||||
--error ER_INVALID_GROUP_FUNC_USE
|
||||
select c1 from t1 having c1 >= (select t.c1 as c from t2 t order by (select min(t1.c1+c) from t2 tt));
|
||||
|
||||
explain extended
|
||||
select c1 from t1 having c1 >= (select t.c1 as c from t2 t order by (select min(t1.c1+tt.c1) from t2 tt));
|
||||
select c1 from t1 having c1 >= (select t.c1 as c from t2 t order by (select min(t1.c1+tt.c1) from t2 tt));
|
||||
drop table t1,t2;
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.1 tests
|
||||
--echo #
|
||||
|
||||
31
sql/item.cc
31
sql/item.cc
@@ -57,6 +57,17 @@ bool cmp_items(Item *a, Item *b)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Set max_sum_func_level if it is needed
|
||||
*/
|
||||
inline void set_max_sum_func_level(THD *thd, SELECT_LEX *select)
|
||||
{
|
||||
if (thd->lex->in_sum_func &&
|
||||
thd->lex->in_sum_func->nest_level >= select->nest_level)
|
||||
set_if_bigger(thd->lex->in_sum_func->max_sum_func_level,
|
||||
select->nest_level - 1);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
** Item functions
|
||||
*****************************************************************************/
|
||||
@@ -4885,6 +4896,11 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
|
||||
if (rf->fix_fields(thd, reference) || rf->check_cols(1))
|
||||
return -1;
|
||||
|
||||
/*
|
||||
We can not "move" aggregate function in the place where
|
||||
its arguments are not defined.
|
||||
*/
|
||||
set_max_sum_func_level(thd, select);
|
||||
mark_as_dependent(thd, last_checked_context->select_lex,
|
||||
context->select_lex, rf,
|
||||
rf);
|
||||
@@ -4893,6 +4909,11 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
We can not "move" aggregate function in the place where
|
||||
its arguments are not defined.
|
||||
*/
|
||||
set_max_sum_func_level(thd, select);
|
||||
mark_as_dependent(thd, last_checked_context->select_lex,
|
||||
context->select_lex,
|
||||
this, (Item_ident*)*reference);
|
||||
@@ -5024,6 +5045,11 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
|
||||
return(1);
|
||||
}
|
||||
|
||||
/*
|
||||
We can not "move" aggregate function in the place where
|
||||
its arguments are not defined.
|
||||
*/
|
||||
set_max_sum_func_level(thd, thd->lex->current_select);
|
||||
set_field(new_field);
|
||||
return 0;
|
||||
}
|
||||
@@ -5048,6 +5074,11 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
|
||||
select->parsing_place == IN_GROUP_BY &&
|
||||
alias_name_used ? *rf->ref : rf);
|
||||
|
||||
/*
|
||||
We can not "move" aggregate function in the place where
|
||||
its arguments are not defined.
|
||||
*/
|
||||
set_max_sum_func_level(thd, thd->lex->current_select);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user