Bug#26093 (SELECT BENCHMARK() for SELECT statements does not produce valid

  results)

Before this fix, the function BENCHMARK() would fail to evaluate expressions
like "(select avg(a) from t1)" in debug builds (with an assert),
or would report a time of zero in non debug builds.

The root cause is that evaluation of DECIMAL_RESULT expressions was not
supported in Item_func_benchmark::val_int().

This has been fixed by this change.
parent 4e556b23
...@@ -141,4 +141,48 @@ t1 CREATE TABLE `t1` ( ...@@ -141,4 +141,48 @@ t1 CREATE TABLE `t1` (
`a` bigint(21) unsigned default NULL `a` bigint(21) unsigned default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1; drop table t1;
drop table if exists table_26093;
drop function if exists func_26093_a;
drop function if exists func_26093_b;
create table table_26093(a int);
insert into table_26093 values
(1), (2), (3), (4), (5),
(6), (7), (8), (9), (10);
create function func_26093_a(x int) returns int
begin
set @invoked := @invoked + 1;
return x;
end//
create function func_26093_b(x int, y int) returns int
begin
set @invoked := @invoked + 1;
return x;
end//
select avg(a) from table_26093;
avg(a)
5.5000
select benchmark(100, (select avg(a) from table_26093));
benchmark(100, (select avg(a) from table_26093))
0
set @invoked := 0;
select benchmark(100, (select avg(func_26093_a(a)) from table_26093));
benchmark(100, (select avg(func_26093_a(a)) from table_26093))
0
select @invoked;
@invoked
10
set @invoked := 0;
select benchmark(100, (select avg(func_26093_b(a, rand())) from table_26093));
benchmark(100, (select avg(func_26093_b(a, rand())) from table_26093))
0
select @invoked;
@invoked
1000
select benchmark(100, (select (a) from table_26093));
ERROR 21000: Subquery returns more than 1 row
select benchmark(100, (select 1, 1));
ERROR 21000: Operand should contain 1 column(s)
drop table table_26093;
drop function func_26093_a;
drop function func_26093_b;
End of 5.0 tests End of 5.0 tests
...@@ -132,4 +132,61 @@ set global query_cache_size=default; ...@@ -132,4 +132,61 @@ set global query_cache_size=default;
create table t1 select INET_ATON('255.255.0.1') as `a`; create table t1 select INET_ATON('255.255.0.1') as `a`;
show create table t1; show create table t1;
drop table t1; drop table t1;
#
# Bug#26093 (SELECT BENCHMARK() for SELECT statements does not produce
# valid results)
#
--disable_warnings
drop table if exists table_26093;
drop function if exists func_26093_a;
drop function if exists func_26093_b;
--enable_warnings
create table table_26093(a int);
insert into table_26093 values
(1), (2), (3), (4), (5),
(6), (7), (8), (9), (10);
delimiter //;
create function func_26093_a(x int) returns int
begin
set @invoked := @invoked + 1;
return x;
end//
create function func_26093_b(x int, y int) returns int
begin
set @invoked := @invoked + 1;
return x;
end//
delimiter ;//
select avg(a) from table_26093;
select benchmark(100, (select avg(a) from table_26093));
set @invoked := 0;
select benchmark(100, (select avg(func_26093_a(a)) from table_26093));
# Returns only 10, since intermediate results are cached.
select @invoked;
set @invoked := 0;
select benchmark(100, (select avg(func_26093_b(a, rand())) from table_26093));
# Returns 1000, due to rand() preventing caching.
select @invoked;
--error ER_SUBQUERY_NO_1_ROW
select benchmark(100, (select (a) from table_26093));
--error ER_OPERAND_COLUMNS
select benchmark(100, (select 1, 1));
drop table table_26093;
drop function func_26093_a;
drop function func_26093_b;
--echo End of 5.0 tests --echo End of 5.0 tests
...@@ -3456,6 +3456,7 @@ longlong Item_func_benchmark::val_int() ...@@ -3456,6 +3456,7 @@ longlong Item_func_benchmark::val_int()
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
char buff[MAX_FIELD_WIDTH]; char buff[MAX_FIELD_WIDTH];
String tmp(buff,sizeof(buff), &my_charset_bin); String tmp(buff,sizeof(buff), &my_charset_bin);
my_decimal tmp_decimal;
THD *thd=current_thd; THD *thd=current_thd;
for (ulong loop=0 ; loop < loop_count && !thd->killed; loop++) for (ulong loop=0 ; loop < loop_count && !thd->killed; loop++)
...@@ -3470,6 +3471,9 @@ longlong Item_func_benchmark::val_int() ...@@ -3470,6 +3471,9 @@ longlong Item_func_benchmark::val_int()
case STRING_RESULT: case STRING_RESULT:
(void) args[0]->val_str(&tmp); (void) args[0]->val_str(&tmp);
break; break;
case DECIMAL_RESULT:
(void) args[0]->val_decimal(&tmp_decimal);
break;
case ROW_RESULT: case ROW_RESULT:
default: default:
// This case should never be chosen // This case should never be chosen
......
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