Skip to content

Commit a765b19

Browse files
author
Galina Shalygina
committed
MDEV-19245: Impossible WHERE should be noticed earlier after HAVING pushdown
The bug appears because not all conditions are found to be knowingly true or false in WHERE after HAVING pushdown optimization. Impossible WHERE can be found much earlier compared with how it is done now. To fix it and_new_conditions_to_optimized_cond() is changed.
1 parent a65d3b2 commit a765b19

File tree

5 files changed

+89
-12
lines changed

5 files changed

+89
-12
lines changed

mysql-test/main/having_cond_pushdown.result

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4733,3 +4733,46 @@ EXPLAIN
47334733
}
47344734
}
47354735
drop table t1;
4736+
#
4737+
# MDEV-19245: Impossible WHERE should be noticed earlier
4738+
# after HAVING pushdown
4739+
#
4740+
CREATE TABLE t1 (a INT, b INT, c INT);
4741+
INSERT INTO t1 VALUES (1,2,1),(3,2,2),(5,6,4),(3,4,1);
4742+
EXPLAIN SELECT t1.a,MAX(t1.b) FROM t1
4743+
WHERE t1.a > 3 GROUP BY t1.a HAVING t1.a = 3;
4744+
id select_type table type possible_keys key key_len ref rows Extra
4745+
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
4746+
EXPLAIN SELECT t1.a,MAX(t1.b) FROM t1
4747+
WHERE t1.a = 3 GROUP BY t1.a HAVING t1.a > 3;
4748+
id select_type table type possible_keys key key_len ref rows Extra
4749+
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
4750+
EXPLAIN SELECT t1.a,MAX(t1.b) FROM t1
4751+
WHERE t1.a > 3 AND t1.a = 3 GROUP BY t1.a ;
4752+
id select_type table type possible_keys key key_len ref rows Extra
4753+
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
4754+
EXPLAIN SELECT t1.a,MAX(t1.b) FROM t1
4755+
WHERE (t1.a < 2 OR t1.c > 1) GROUP BY t1.a HAVING t1.a = 3;
4756+
id select_type table type possible_keys key key_len ref rows Extra
4757+
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where
4758+
EXPLAIN SELECT t1.a,MAX(t1.b) FROM t1
4759+
WHERE t1.a = 3 GROUP BY t1.a HAVING (t1.a < 2 OR t1.a > 3);
4760+
id select_type table type possible_keys key key_len ref rows Extra
4761+
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
4762+
EXPLAIN SELECT t1.a,MAX(t1.b) FROM t1
4763+
WHERE t1.a = 3 AND (t1.a < 2 OR t1.a > 3) GROUP BY t1.a;
4764+
id select_type table type possible_keys key key_len ref rows Extra
4765+
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
4766+
EXPLAIN SELECT t1.a,MAX(t1.b),t1.c FROM t1
4767+
WHERE (t1.a < 2 AND t1.c > 1) GROUP BY t1.a HAVING t1.a = 3;
4768+
id select_type table type possible_keys key key_len ref rows Extra
4769+
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
4770+
EXPLAIN SELECT t1.a,MAX(t1.b),t1.c FROM t1
4771+
WHERE t1.a = 3 GROUP BY t1.a HAVING (t1.a < 2 AND t1.c > 1);
4772+
id select_type table type possible_keys key key_len ref rows Extra
4773+
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
4774+
EXPLAIN SELECT t1.a,MAX(t1.b),t1.c FROM t1
4775+
WHERE t1.a = 3 AND (t1.a < 2 AND t1.b > 3) GROUP BY t1.a;
4776+
id select_type table type possible_keys key key_len ref rows Extra
4777+
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
4778+
DROP TABLE t1;

mysql-test/main/having_cond_pushdown.test

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1370,3 +1370,34 @@ eval explain extended $q2;
13701370
eval explain format=json $q2;
13711371

13721372
drop table t1;
1373+
1374+
--echo #
1375+
--echo # MDEV-19245: Impossible WHERE should be noticed earlier
1376+
--echo # after HAVING pushdown
1377+
--echo #
1378+
1379+
CREATE TABLE t1 (a INT, b INT, c INT);
1380+
INSERT INTO t1 VALUES (1,2,1),(3,2,2),(5,6,4),(3,4,1);
1381+
1382+
EXPLAIN SELECT t1.a,MAX(t1.b) FROM t1
1383+
WHERE t1.a > 3 GROUP BY t1.a HAVING t1.a = 3;
1384+
EXPLAIN SELECT t1.a,MAX(t1.b) FROM t1
1385+
WHERE t1.a = 3 GROUP BY t1.a HAVING t1.a > 3;
1386+
EXPLAIN SELECT t1.a,MAX(t1.b) FROM t1
1387+
WHERE t1.a > 3 AND t1.a = 3 GROUP BY t1.a ;
1388+
1389+
EXPLAIN SELECT t1.a,MAX(t1.b) FROM t1
1390+
WHERE (t1.a < 2 OR t1.c > 1) GROUP BY t1.a HAVING t1.a = 3;
1391+
EXPLAIN SELECT t1.a,MAX(t1.b) FROM t1
1392+
WHERE t1.a = 3 GROUP BY t1.a HAVING (t1.a < 2 OR t1.a > 3);
1393+
EXPLAIN SELECT t1.a,MAX(t1.b) FROM t1
1394+
WHERE t1.a = 3 AND (t1.a < 2 OR t1.a > 3) GROUP BY t1.a;
1395+
1396+
EXPLAIN SELECT t1.a,MAX(t1.b),t1.c FROM t1
1397+
WHERE (t1.a < 2 AND t1.c > 1) GROUP BY t1.a HAVING t1.a = 3;
1398+
EXPLAIN SELECT t1.a,MAX(t1.b),t1.c FROM t1
1399+
WHERE t1.a = 3 GROUP BY t1.a HAVING (t1.a < 2 AND t1.c > 1);
1400+
EXPLAIN SELECT t1.a,MAX(t1.b),t1.c FROM t1
1401+
WHERE t1.a = 3 AND (t1.a < 2 AND t1.b > 3) GROUP BY t1.a;
1402+
1403+
DROP TABLE t1;

sql/item.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1947,6 +1947,12 @@ class Item: public Value_source,
19471947
virtual bool check_partition_func_processor(void *arg) { return 1;}
19481948
virtual bool post_fix_fields_part_expr_processor(void *arg) { return 0; }
19491949
virtual bool rename_fields_processor(void *arg) { return 0; }
1950+
/*
1951+
TRUE if the function is knowingly TRUE or FALSE.
1952+
Not to be used for AND/OR formulas.
1953+
*/
1954+
virtual bool is_simplified_cond_processor(void *arg) { return false; }
1955+
19501956
/** Processor used to check acceptability of an item in the defining
19511957
expression for a virtual column
19521958

sql/item_func.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,8 @@ class Item_func :public Item_func_or_sum,
398398
bool with_sum_func() const { return m_with_sum_func; }
399399
With_sum_func_cache* get_with_sum_func_cache() { return this; }
400400
Item_func *get_item_func() { return this; }
401+
bool is_simplified_cond_processor(void *arg)
402+
{ return const_item() && !val_int(); }
401403
};
402404

403405

sql/opt_subselect.cc

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5723,12 +5723,6 @@ Item *and_new_conditions_to_optimized_cond(THD *thd, Item *cond,
57235723
&((Item_cond_and *) cond)->m_cond_equal,
57245724
false, NULL);
57255725
}
5726-
/*
5727-
Check if equalities that can't be transformed into multiple
5728-
equalities are knowingly true or false.
5729-
*/
5730-
if (item->const_item() && !item->val_int())
5731-
is_simplified_cond= true;
57325726
and_args->push_back(item, thd->mem_root);
57335727
}
57345728
and_args->append((List<Item> *) cond_equalities);
@@ -5821,12 +5815,6 @@ Item *and_new_conditions_to_optimized_cond(THD *thd, Item *cond,
58215815
{
58225816
item= item->build_equal_items(thd, inherited, false, NULL);
58235817
}
5824-
/*
5825-
Check if equalities that can't be transformed into multiple
5826-
equalities are knowingly true or false.
5827-
*/
5828-
if (item->const_item() && !item->val_int())
5829-
is_simplified_cond= true;
58305818
new_conds_list.push_back(item, thd->mem_root);
58315819
}
58325820
new_conds_list.append((List<Item> *)&new_cond_equal.current_level);
@@ -5870,7 +5858,14 @@ Item *and_new_conditions_to_optimized_cond(THD *thd, Item *cond,
58705858
cond= cond->propagate_equal_fields(thd,
58715859
Item::Context_boolean(),
58725860
*cond_eq);
5861+
cond->update_used_tables();
58735862
}
5863+
/* Check if conds has knowingly true or false parts. */
5864+
if (cond &&
5865+
!is_simplified_cond &&
5866+
cond->walk(&Item::is_simplified_cond_processor, 0, 0))
5867+
is_simplified_cond= true;
5868+
58745869

58755870
/*
58765871
If it was found that there are some knowingly true or false equalities

0 commit comments

Comments
 (0)