Skip to content

Commit 3630a00

Browse files
committed
Fixed bug mdev-10782.
This bug in the code of Item_ref::build_clone could cause corruption of items in where conditions. Also made sure that equality predicates extracted from multiple equality items to be pushed into materialized views were cloned.
1 parent 9810d5e commit 3630a00

File tree

4 files changed

+68
-4
lines changed

4 files changed

+68
-4
lines changed

mysql-test/r/derived_cond_pushdown.result

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6982,3 +6982,28 @@ drop view v1,v2,v3,v4;
69826982
drop view v_union,v2_union,v3_union,v4_union;
69836983
drop view v_double,v_char,v_decimal;
69846984
drop table t1,t2,t1_double,t2_double,t1_char,t2_char,t1_decimal,t2_decimal;
6985+
#
6986+
# MDEV-10782: condition extracted from a multiple equality
6987+
# pushed into HAVING
6988+
#
6989+
CREATE TABLE t1 (i int);
6990+
INSERT INTO t1 VALUES (1),(2);
6991+
EXPLAIN EXTENDED
6992+
SELECT *
6993+
FROM ( SELECT * FROM ( SELECT MIN(i) as f FROM t1 ) sq1 ) AS sq2
6994+
WHERE f = 8;
6995+
id select_type table type possible_keys key key_len ref rows filtered Extra
6996+
1 PRIMARY <derived3> ALL NULL NULL NULL NULL 2 100.00 Using where
6997+
3 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00
6998+
Warnings:
6999+
Note 1003 select `sq1`.`f` AS `f` from (select min(`test`.`t1`.`i`) AS `f` from `test`.`t1` having (`f` = 8)) `sq1` where (`sq1`.`f` = 8)
7000+
SELECT *
7001+
FROM ( SELECT * FROM ( SELECT MIN(i) as f FROM t1 ) sq1 ) AS sq2
7002+
WHERE f = 8;
7003+
f
7004+
SELECT *
7005+
FROM ( SELECT * FROM ( SELECT MIN(i) as f FROM t1 ) sq1 ) AS sq2
7006+
WHERE f = 1;
7007+
f
7008+
1
7009+
DROP TABLE t1;

mysql-test/t/derived_cond_pushdown.test

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -877,4 +877,26 @@ eval explain format=json $query;
877877
drop view v1,v2,v3,v4;
878878
drop view v_union,v2_union,v3_union,v4_union;
879879
drop view v_double,v_char,v_decimal;
880-
drop table t1,t2,t1_double,t2_double,t1_char,t2_char,t1_decimal,t2_decimal;
880+
drop table t1,t2,t1_double,t2_double,t1_char,t2_char,t1_decimal,t2_decimal;
881+
882+
--echo #
883+
--echo # MDEV-10782: condition extracted from a multiple equality
884+
--echo # pushed into HAVING
885+
--echo #
886+
887+
CREATE TABLE t1 (i int);
888+
INSERT INTO t1 VALUES (1),(2);
889+
EXPLAIN EXTENDED
890+
SELECT *
891+
FROM ( SELECT * FROM ( SELECT MIN(i) as f FROM t1 ) sq1 ) AS sq2
892+
WHERE f = 8;
893+
SELECT *
894+
FROM ( SELECT * FROM ( SELECT MIN(i) as f FROM t1 ) sq1 ) AS sq2
895+
WHERE f = 8;
896+
SELECT *
897+
FROM ( SELECT * FROM ( SELECT MIN(i) as f FROM t1 ) sq1 ) AS sq2
898+
WHERE f = 1;
899+
DROP TABLE t1;
900+
901+
902+

sql/item.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2296,10 +2296,16 @@ Item* Item_func_or_sum::build_clone(THD *thd, MEM_ROOT *mem_root)
22962296
if (!copy)
22972297
return 0;
22982298
if (arg_count > 2)
2299+
{
22992300
copy->args=
23002301
(Item**) alloc_root(mem_root, sizeof(Item*) * arg_count);
2302+
if (!copy->args)
2303+
return 0;
2304+
}
23012305
else if (arg_count > 0)
23022306
copy->args= copy->tmp_arg;
2307+
2308+
23032309
for (uint i= 0; i < arg_count; i++)
23042310
{
23052311
Item *arg_clone= args[i]->build_clone(thd, mem_root);
@@ -2332,6 +2338,10 @@ Item* Item_ref::build_clone(THD *thd, MEM_ROOT *mem_root)
23322338
Item_ref *copy= (Item_ref *) get_copy(thd, mem_root);
23332339
if (!copy)
23342340
return 0;
2341+
copy->ref=
2342+
(Item**) alloc_root(mem_root, sizeof(Item*));
2343+
if (!copy->ref)
2344+
return 0;
23352345
Item *item_clone= (* ref)->build_clone(thd, mem_root);
23362346
if (!item_clone)
23372347
return 0;

sql/table.cc

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8057,8 +8057,12 @@ Item* TABLE_LIST::build_pushable_cond_for_table(THD *thd, Item *cond)
80578057
{
80588058
if (!(item->used_tables() == tab_map))
80598059
continue;
8060-
Item_func_eq *eq=
8061-
new (thd->mem_root) Item_func_eq(thd, item, left_item);
8060+
Item_func_eq *eq= 0;
8061+
Item *left_item_clone= left_item->build_clone(thd, thd->mem_root);
8062+
Item *right_item_clone= item->build_clone(thd, thd->mem_root);
8063+
if (left_item_clone && right_item_clone)
8064+
eq= new (thd->mem_root) Item_func_eq(thd, right_item_clone,
8065+
left_item_clone);
80628066
if (eq)
80638067
{
80648068
i++;
@@ -8071,10 +8075,13 @@ Item* TABLE_LIST::build_pushable_cond_for_table(THD *thd, Item *cond)
80718075
new_cond= new (thd->mem_root) Item_cond_and(thd, new_cond, eq);
80728076
break;
80738077
default:
8074-
((Item_cond_and*)new_cond)->argument_list()->push_back(eq, thd->mem_root);
8078+
((Item_cond_and*)new_cond)->argument_list()->push_back(eq,
8079+
thd->mem_root);
80758080
}
80768081
}
80778082
}
8083+
if (new_cond)
8084+
new_cond->fix_fields(thd, &new_cond);
80788085
return new_cond;
80798086
}
80808087
else if (cond->get_extraction_flag() != NO_EXTRACTION_FL)

0 commit comments

Comments
 (0)