MDEV-30240 Wrong result upon aggregate function with SQL_BUFFER_RESULT
The problem was that when storing rows into a temporary table, MIN/MAX items that where marked as constants (as theire value had been computed at start of query) would be reset. Fixed by not reseting MIN/MAX items that are marked as const in Item_sum_min_max::clear().
This commit is contained in:
parent
8b9b4ab3f5
commit
d0603fc5ba
@ -4065,3 +4065,23 @@ SELECT DISTINCT owner_id FROM t1 WHERE foo = true GROUP BY owner_id HAVING (COUN
|
||||
owner_id
|
||||
1
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-30240 Wrong result upon aggregate function with SQL_BUFFER_RESULT
|
||||
#
|
||||
drop table if exists t1,t2;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 'test.t1,test.t2'
|
||||
CREATE TABLE t1 (pk INT PRIMARY KEY);
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
CREATE TABLE t2 (a INT);
|
||||
INSERT INTO t2 VALUES (1),(2);
|
||||
SELECT SQL_BUFFER_RESULT MIN(pk) FROM t1, t2;
|
||||
MIN(pk)
|
||||
1
|
||||
SELECT MIN(pk) FROM t1, t2;
|
||||
MIN(pk)
|
||||
1
|
||||
DROP TABLE t1, t2;
|
||||
#
|
||||
# End of 10.5 tests
|
||||
#
|
||||
|
@ -1723,3 +1723,20 @@ EXPLAIN
|
||||
SELECT DISTINCT owner_id FROM t1 WHERE foo = true GROUP BY owner_id HAVING (COUNT(*) = 1);
|
||||
SELECT DISTINCT owner_id FROM t1 WHERE foo = true GROUP BY owner_id HAVING (COUNT(*) = 1);
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-30240 Wrong result upon aggregate function with SQL_BUFFER_RESULT
|
||||
--echo #
|
||||
|
||||
drop table if exists t1,t2;
|
||||
CREATE TABLE t1 (pk INT PRIMARY KEY);
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
CREATE TABLE t2 (a INT);
|
||||
INSERT INTO t2 VALUES (1),(2);
|
||||
SELECT SQL_BUFFER_RESULT MIN(pk) FROM t1, t2;
|
||||
SELECT MIN(pk) FROM t1, t2;
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.5 tests
|
||||
--echo #
|
||||
|
@ -2361,8 +2361,15 @@ Item *Item_sum_variance::result_item(THD *thd, Field *field)
|
||||
void Item_sum_min_max::clear()
|
||||
{
|
||||
DBUG_ENTER("Item_sum_min_max::clear");
|
||||
value->clear();
|
||||
null_value= 1;
|
||||
/*
|
||||
We should not clear const items (from SELECT MIN(key) from t1) as then we would loose the
|
||||
value cached in opt_sum_query() where we replace MIN/MAX/COUNT with constants.
|
||||
*/
|
||||
if (!const_item())
|
||||
{
|
||||
value->clear();
|
||||
null_value= 1;
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
@ -2475,9 +2482,12 @@ void Item_sum_min_max::no_rows_in_result()
|
||||
/* We may be called here twice in case of ref field in function */
|
||||
if (was_values)
|
||||
{
|
||||
bool org_const_item_cache= const_item_cache;
|
||||
was_values= FALSE;
|
||||
was_null_value= value->null_value;
|
||||
const_item_cache= 0; // Ensure that clear works on const items
|
||||
clear();
|
||||
const_item_cache= org_const_item_cache;
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
@ -438,7 +438,7 @@ int opt_sum_query(THD *thd,
|
||||
The optimization is not applicable in both cases:
|
||||
(a) 'expr' is a non-constant expression. Then we can't
|
||||
replace 'expr' by a constant.
|
||||
(b) 'expr' is a costant. According to ANSI, MIN/MAX must return
|
||||
(b) 'expr' is a constant. According to ANSI, MIN/MAX must return
|
||||
NULL if the query does not return any rows. Thus, if we are not
|
||||
able to determine if the query returns any rows, we can't apply
|
||||
the optimization and replace MIN/MAX with a constant.
|
||||
|
@ -25871,7 +25871,6 @@ bool JOIN::alloc_func_list()
|
||||
@param field_list All items
|
||||
@param send_result_set_metadata Items in select list
|
||||
@param before_group_by Set to 1 if this is called before GROUP BY handling
|
||||
@param recompute Set to TRUE if sum_funcs must be recomputed
|
||||
|
||||
@retval
|
||||
0 ok
|
||||
|
Loading…
x
Reference in New Issue
Block a user