Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions mysql-test/main/having_cond_pushdown.result
Original file line number Diff line number Diff line change
Expand Up @@ -6090,4 +6090,16 @@ EXPLAIN
}
}
drop table t1, t2;
#
# MDEV-39916: Crash when pushing "NOT col" from HAVING into WHERE
#
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (0), (1);
SELECT a
FROM t1
GROUP BY a
HAVING (NOT a) AND TRUE;
a
0
DROP TABLE t1;
# End of 10.11 tests
14 changes: 14 additions & 0 deletions mysql-test/main/having_cond_pushdown.test
Original file line number Diff line number Diff line change
Expand Up @@ -1657,4 +1657,18 @@ execute stmt;

drop table t1, t2;

--echo #
--echo # MDEV-39916: Crash when pushing "NOT col" from HAVING into WHERE
--echo #

CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (0), (1);

SELECT a
FROM t1
GROUP BY a
HAVING (NOT a) AND TRUE;

DROP TABLE t1;

--echo # End of 10.11 tests
4 changes: 3 additions & 1 deletion sql/item_cmpfunc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6676,7 +6676,9 @@ Item *Item_func_not::neg_transformer(THD *thd) /* NOT(x) -> x */
bool Item_func_not::fix_fields(THD *thd, Item **ref)
{
args[0]->under_not(this);
if (args[0]->type() == FIELD_ITEM)
if (args[0]->fix_fields_if_needed(thd, &args[0]))
return true;
if (args[0]->real_item()->type() == FIELD_ITEM)
{
/* replace "NOT <field>" with "<field> == 0" */
Query_arena backup, *arena;
Expand Down
7 changes: 4 additions & 3 deletions sql/sql_lex.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11574,7 +11574,7 @@ Item *st_select_lex::pushdown_from_having_into_where(THD *thd, Item *having)
list of all its conjuncts saved in attach_to_conds. Otherwise,
the condition is put into attach_to_conds as the only its element.
*/
List_iterator_fast<Item> it(attach_to_conds);
List_iterator<Item> it(attach_to_conds);
Item *item;
check_cond_extraction_for_grouping_fields(thd, having);
if (build_pushable_cond_for_having_pushdown(thd, having))
Expand Down Expand Up @@ -11638,8 +11638,9 @@ Item *st_select_lex::pushdown_from_having_into_where(THD *thd, Item *having)
&Item::field_transformer_for_having_pushdown,
(uchar *)this);

if (item->walk(&Item::cleanup_excluding_immutables_processor, 0, STOP_PTR)
|| item->fix_fields(thd, NULL))
if (item->walk(&Item::cleanup_excluding_immutables_processor, 0,
STOP_PTR) ||
item->fix_fields(thd, it.ref()))
{
attach_to_conds.empty();
goto exit;
Expand Down
6 changes: 6 additions & 0 deletions sql/sql_lex.h
Original file line number Diff line number Diff line change
Expand Up @@ -1180,7 +1180,13 @@ class st_select_lex: public st_select_lex_node

/* List of references to fields referenced from inner selects */
List<Item_outer_ref> inner_refs_list;

/*
Pushdown from HAVING into WHERE optimization: conditions from the HAVING
clause that should be added into the WHERE.
*/
List<Item> attach_to_conds;

/* Saved values of the WHERE and HAVING clauses*/
Item::cond_result cond_value, having_value;
/*
Expand Down