Skip to content
This repository was archived by the owner on Mar 1, 2026. It is now read-only.

Commit f479bde

Browse files
author
Chaithra Gopalareddy
committed
Bug#33838439: ExtractValue not working properly with COUNT
If a derived table is implicitly grouped and if there is a condition that could be pushed down to this table, it needs to be pushed to the having clause of that derived table. However if the condition does not have expressions involving columns from a table and yet evaluates to a non const item, it is currently pushed to the where clause. For an implicitly grouped query, if this where clause evaluates to false, aggregation function results in a NULL. However if it is evaluated as a having condition it will result in an empty set. So the solution is to push conditions to the having clause instead of where clause as the result of the where clause influences the result of the aggregation function. Change-Id: I948892cbe0390f1fdfddaa94661ff460da935967
1 parent d77f156 commit f479bde

3 files changed

Lines changed: 45 additions & 6 deletions

File tree

‎mysql-test/r/derived_condition_pushdown.result‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1922,3 +1922,18 @@ JOIN information_schema.table_constraints b
19221922
USING (table_schema)
19231923
WHERE b.constraint_type = 'FOREIGN KEY';
19241924
TABLE_NAME
1925+
#
1926+
# Bug#33838439: ExtractValue not working properly with COUNT
1927+
#
1928+
CREATE TABLE t1 (f1 INTEGER);
1929+
SET @a = 0;
1930+
EXPLAIN SELECT COUNT(*) FROM (SELECT SUM(f1) FROM t1) as dt WHERE @a = 1;
1931+
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1932+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table
1933+
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible HAVING
1934+
Warnings:
1935+
Note 1003 /* select#1 */ select count(0) AS `COUNT(*)` from (/* select#2 */ select sum(`test`.`t1`.`f1`) AS `SUM(f1)` from `test`.`t1` having false) `dt`
1936+
SELECT COUNT(*) FROM (SELECT SUM(f1) FROM t1) as dt WHERE @a = 1;
1937+
COUNT(*)
1938+
0
1939+
DROP TABLE t1;

‎mysql-test/t/derived_condition_pushdown.test‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,3 +1195,15 @@ FROM information_schema.key_column_usage a
11951195
WHERE b.constraint_type = 'FOREIGN KEY';
11961196

11971197
#End of test for Bug#33791802
1198+
1199+
--echo #
1200+
--echo # Bug#33838439: ExtractValue not working properly with COUNT
1201+
--echo #
1202+
1203+
CREATE TABLE t1 (f1 INTEGER);
1204+
1205+
SET @a = 0;
1206+
EXPLAIN SELECT COUNT(*) FROM (SELECT SUM(f1) FROM t1) as dt WHERE @a = 1;
1207+
SELECT COUNT(*) FROM (SELECT SUM(f1) FROM t1) as dt WHERE @a = 1;
1208+
1209+
DROP TABLE t1;

‎sql/sql_derived.cc‎

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,19 +1209,31 @@ bool Condition_pushdown::push_past_window_functions() {
12091209
}
12101210

12111211
/**
1212-
Try to push the condition past GROUP BY into the WHERE clause of the
1213-
derived table. Check that all columns in the condition are present as
1214-
grouping columns of the current query block. If not, the condition
1215-
cannot be pushed to the WHERE clause. It will have to stay in HAVING
1216-
clause.
1212+
Try to push the condition or parts of the condition past GROUP BY into
1213+
the WHERE clause of the derived table.
1214+
1. For a non-grouped query, the condition is moved to the WHERE clause.
1215+
2. For an implicitly grouped query, condition remains in the HAVING
1216+
clause in order to preserve semantics.
1217+
3. For a query with ROLLUP, the condition will remain in the HAVING
1218+
clause because ROLLUP might add NULL values to the grouping columns.
1219+
4. For other grouped queries, predicates involving grouping columns
1220+
can be moved to the WHERE clause. Predicates that reference aggregate
1221+
functions remain in HAVING clause.
1222+
We perform the same checks for a non-standard compliant GROUP BY too.
1223+
If a window function's PARTITION BY clause is on non-grouping columns
1224+
(possible if GROUP BY is non-standard compliant or when these columns
1225+
are functionally dependednt on the grouping columns) then the condition
1226+
will stay in HAVING clause.
12171227
*/
12181228
bool Condition_pushdown::push_past_group_by() {
12191229
if (!m_query_block->is_grouped()) {
12201230
m_where_cond = m_having_cond;
12211231
m_having_cond = nullptr;
12221232
return false;
12231233
}
1224-
if (m_query_block->olap == ROLLUP_TYPE) return false;
1234+
if (m_query_block->is_implicitly_grouped() ||
1235+
m_query_block->olap == ROLLUP_TYPE)
1236+
return false;
12251237
m_checking_purpose = CHECK_FOR_WHERE;
12261238
Opt_trace_object step_wrapper(trace, "pushing_past_group_by");
12271239

0 commit comments

Comments
 (0)