diff options
author | Igor Babaev <igor@askmonty.org> | 2013-11-21 15:19:25 -0800 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2013-11-21 15:19:25 -0800 |
commit | c0f31dc9f3e0a42911beb6655a40601d2fddfe8e (patch) | |
tree | eceda1a471f3179d772999bf15a77d282e226c45 | |
parent | f8a6ee59acb082678cf601a10cbe9c1152748242 (diff) | |
download | mariadb-git-c0f31dc9f3e0a42911beb6655a40601d2fddfe8e.tar.gz |
Another attempt to fix bug mdev-5103.
The earlier pushed fix for the bug was incomplete. It did not remove
the main cause of the problem: the function remove_eq_conds()
removed always true multiple equalities from any conjunct, but did not
adjust the list of them stored in Item_cond_and::cond_equal.current_level.
Simplified the test case for the bug and moved it to another test file.
The fix triggered changes in EXPLAIN EXTENDED for some queries.
-rw-r--r-- | mysql-test/r/func_equal.result | 43 | ||||
-rw-r--r-- | mysql-test/r/join_outer.result | 2 | ||||
-rw-r--r-- | mysql-test/r/join_outer_jcl6.result | 2 | ||||
-rw-r--r-- | mysql-test/r/select.result | 2 | ||||
-rw-r--r-- | mysql-test/r/select_jcl6.result | 2 | ||||
-rw-r--r-- | mysql-test/r/select_pkeycache.result | 2 | ||||
-rw-r--r-- | mysql-test/r/subselect4.result | 22 | ||||
-rw-r--r-- | mysql-test/r/subselect_extra.result | 4 | ||||
-rw-r--r-- | mysql-test/r/type_datetime.result | 4 | ||||
-rw-r--r-- | mysql-test/t/func_equal.test | 50 | ||||
-rw-r--r-- | mysql-test/t/subselect4.test | 24 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 33 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 7 | ||||
-rw-r--r-- | sql/sql_select.cc | 36 |
14 files changed, 103 insertions, 130 deletions
diff --git a/mysql-test/r/func_equal.result b/mysql-test/r/func_equal.result index 02593529a91..f20b259191c 100644 --- a/mysql-test/r/func_equal.result +++ b/mysql-test/r/func_equal.result @@ -43,46 +43,3 @@ a 4828532208463511553 drop table t1; #End of 4.1 tests -# -# MDEV-5103: server crashed on singular Item_equal -# -CREATE TABLE `t1` ( -`tipo` enum('p','r') NOT NULL DEFAULT 'r', -`arquivo_id` bigint(20) unsigned NOT NULL DEFAULT '0', -`arquivo_md5` char(32) NOT NULL, -`conteudo` longblob NOT NULL, -`usuario` varchar(15) NOT NULL, -`datahora_gmt` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', -`tipo_arquivo` varchar(255) NOT NULL, -`nome_arquivo` varchar(255) NOT NULL, -`tamanho_arquivo` bigint(20) unsigned NOT NULL DEFAULT '0', -PRIMARY KEY (`tipo`,`arquivo_id`), -UNIQUE KEY `tipo` (`tipo`,`arquivo_md5`) -) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1; -INSERT INTO `t1` (`tipo`, `arquivo_id`, `arquivo_md5`, `conteudo`, `usuario`, `datahora_gmt`, `tipo_arquivo`, `nome_arquivo`, `tamanho_arquivo`) VALUES -('r', 1, 'ad18832202b199728921807033a8a515', '', 'rspadim', '2013-10-05 13:55:50', '001_cbr643', 'CBR6431677410201314132.ret', 21306); -CREATE TABLE `t2` ( -`tipo` enum('p','r') NOT NULL DEFAULT 'p', -`arquivo_id` bigint(20) NOT NULL DEFAULT '0', -`usuario` varchar(25) NOT NULL, -`datahora` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', -`erros` longblob NOT NULL, -`importados` bigint(20) unsigned NOT NULL DEFAULT '0', -`n_importados` bigint(20) unsigned NOT NULL DEFAULT '0', -PRIMARY KEY (`tipo`,`arquivo_id`,`datahora`) -) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1; -INSERT INTO `t2` (`tipo`, `arquivo_id`, `usuario`, `datahora`, `erros`, `importados`, `n_importados`) VALUES -('r', 1, 'rspadim', '2013-10-05 14:25:30', '', 32, 0); -SELECT -arquivo_id,usuario,datahora_gmt,tipo_arquivo,nome_arquivo,tamanho_arquivo -FROM t1 AS a -WHERE datahora_gmt>='0000-00-00 00:00:00' AND -datahora_gmt<='2013-10-07 02:59:59' AND tipo='r' AND -(tipo_arquivo,arquivo_id) NOT IN -(SELECT tipo_arquivo,arquivo_id -FROM t2 -WHERE (tipo_arquivo,arquivo_id)=(a.tipo_arquivo,a.arquivo_id)) -ORDER BY arquivo_id DESC; -arquivo_id usuario datahora_gmt tipo_arquivo nome_arquivo tamanho_arquivo -drop table t2, t1; -#End of 5.3 tests diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index 284a285dbe3..63d341d1c33 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -1773,7 +1773,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 const PRIMARY,idx PRIMARY 4 const 1 100.00 1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 100.00 Using index Warnings: -Note 1003 select 5 AS `pk` from `test`.`t2` join `test`.`t1` where ((((1 between 5 and 6) and isnull(5)) or 1)) order by 5 +Note 1003 select 5 AS `pk` from `test`.`t2` join `test`.`t1` where 1 order by 5 SELECT t1.pk FROM t2 LEFT JOIN t1 ON t2.pk = t1.a WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5 ORDER BY t1.pk; diff --git a/mysql-test/r/join_outer_jcl6.result b/mysql-test/r/join_outer_jcl6.result index 69fe7cbd6b9..eff47bf7c31 100644 --- a/mysql-test/r/join_outer_jcl6.result +++ b/mysql-test/r/join_outer_jcl6.result @@ -1784,7 +1784,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 const PRIMARY,idx PRIMARY 4 const 1 100.00 1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 100.00 Using index Warnings: -Note 1003 select 5 AS `pk` from `test`.`t2` join `test`.`t1` where ((((1 between 5 and 6) and isnull(5)) or 1)) order by 5 +Note 1003 select 5 AS `pk` from `test`.`t2` join `test`.`t1` where 1 order by 5 SELECT t1.pk FROM t2 LEFT JOIN t1 ON t2.pk = t1.a WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5 ORDER BY t1.pk; diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index f0de9622368..e8bcba8043a 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -5125,7 +5125,7 @@ SELECT * FROM t1 WHERE (1=2 OR t1.pk=2) AND t1.a <> 0; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables Warnings: -Note 1003 select 2 AS `pk`,0 AS `a` from `test`.`t1` where ((0 <> 0)) +Note 1003 select 2 AS `pk`,0 AS `a` from `test`.`t1` where (0 <> 0) DROP TABLE t1; SELECT * FROM mysql.time_zone WHERE ( NOT (Use_leap_seconds <= Use_leap_seconds AND Time_zone_id != 1) diff --git a/mysql-test/r/select_jcl6.result b/mysql-test/r/select_jcl6.result index 3c3d6188301..c8d206e161d 100644 --- a/mysql-test/r/select_jcl6.result +++ b/mysql-test/r/select_jcl6.result @@ -5136,7 +5136,7 @@ SELECT * FROM t1 WHERE (1=2 OR t1.pk=2) AND t1.a <> 0; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables Warnings: -Note 1003 select 2 AS `pk`,0 AS `a` from `test`.`t1` where ((0 <> 0)) +Note 1003 select 2 AS `pk`,0 AS `a` from `test`.`t1` where (0 <> 0) DROP TABLE t1; SELECT * FROM mysql.time_zone WHERE ( NOT (Use_leap_seconds <= Use_leap_seconds AND Time_zone_id != 1) diff --git a/mysql-test/r/select_pkeycache.result b/mysql-test/r/select_pkeycache.result index f0de9622368..e8bcba8043a 100644 --- a/mysql-test/r/select_pkeycache.result +++ b/mysql-test/r/select_pkeycache.result @@ -5125,7 +5125,7 @@ SELECT * FROM t1 WHERE (1=2 OR t1.pk=2) AND t1.a <> 0; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables Warnings: -Note 1003 select 2 AS `pk`,0 AS `a` from `test`.`t1` where ((0 <> 0)) +Note 1003 select 2 AS `pk`,0 AS `a` from `test`.`t1` where (0 <> 0) DROP TABLE t1; SELECT * FROM mysql.time_zone WHERE ( NOT (Use_leap_seconds <= Use_leap_seconds AND Time_zone_id != 1) diff --git a/mysql-test/r/subselect4.result b/mysql-test/r/subselect4.result index 83716429efe..20cb28c3ffb 100644 --- a/mysql-test/r/subselect4.result +++ b/mysql-test/r/subselect4.result @@ -2326,5 +2326,27 @@ x NULL NULL NULL d NULL NULL NULL drop table t1,t2; set @@optimizer_switch = @optimizer_switch_MDEV4056; +# +# MDEV-5103: server crashed on singular Item_equal +# +CREATE TABLE t1 ( +a enum('p','r') NOT NULL DEFAULT 'r', +b int NOT NULL DEFAULT '0', +c char(32) NOT NULL, +d varchar(255) NOT NULL, +PRIMARY KEY (a, b), UNIQUE KEY idx(a, c) +); +INSERT INTO t1 VALUES ('r', 1, 'ad18832202b199728921807033a8a515', '001_cbr643'); +CREATE TABLE t2 ( +a enum('p','r') NOT NULL DEFAULT 'r', +b int NOT NULL DEFAULT '0', +e datetime NOT NULL DEFAULT '0000-00-00 00:00:00', +PRIMARY KEY (a, b, e) +); +INSERT INTO t2 VALUES ('r', 1, '2013-10-05 14:25:30'); +SELECT * FROM t1 AS t +WHERE a='r' AND (c,b) NOT IN (SELECT c,b FROM t2 WHERE (c,b)=(t.c,t.b)); +a b c d +DROP TABLE t1, t2; SET optimizer_switch= @@global.optimizer_switch; set @@tmp_table_size= @@global.tmp_table_size; diff --git a/mysql-test/r/subselect_extra.result b/mysql-test/r/subselect_extra.result index 53a38bf6e8e..d29d57c764c 100644 --- a/mysql-test/r/subselect_extra.result +++ b/mysql-test/r/subselect_extra.result @@ -46,7 +46,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables Warnings: Note 1276 Field or reference 'test.t1.cur_date' of SELECT #2 was resolved in SELECT #1 -Note 1003 select 1 AS `id`,'2007-04-25 18:30:22' AS `cur_date` from `test`.`t1` semi join (`test`.`t1` `x1`) where (('2007-04-25 18:30:22' = 0)) +Note 1003 select 1 AS `id`,'2007-04-25 18:30:22' AS `cur_date` from `test`.`t1` semi join (`test`.`t1` `x1`) where ('2007-04-25 18:30:22' = 0) select * from t1 where id in (select id from t1 as x1 where (t1.cur_date is null)); id cur_date @@ -57,7 +57,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables Warnings: Note 1276 Field or reference 'test.t2.cur_date' of SELECT #2 was resolved in SELECT #1 -Note 1003 select 1 AS `id`,'2007-04-25' AS `cur_date` from `test`.`t2` semi join (`test`.`t2` `x1`) where (('2007-04-25' = 0)) +Note 1003 select 1 AS `id`,'2007-04-25' AS `cur_date` from `test`.`t2` semi join (`test`.`t2` `x1`) where ('2007-04-25' = 0) select * from t2 where id in (select id from t2 as x1 where (t2.cur_date is null)); id cur_date diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result index de0bc2a0b80..861ae974b9a 100644 --- a/mysql-test/r/type_datetime.result +++ b/mysql-test/r/type_datetime.result @@ -519,7 +519,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables Warnings: Note 1276 Field or reference 'test.t1.cur_date' of SELECT #2 was resolved in SELECT #1 -Note 1003 select 1 AS `id`,'2007-04-25 18:30:22' AS `cur_date` from `test`.`t1` semi join (`test`.`t1` `x1`) where (('2007-04-25 18:30:22' = 0)) +Note 1003 select 1 AS `id`,'2007-04-25 18:30:22' AS `cur_date` from `test`.`t1` semi join (`test`.`t1` `x1`) where ('2007-04-25 18:30:22' = 0) select * from t1 where id in (select id from t1 as x1 where (t1.cur_date is null)); id cur_date @@ -530,7 +530,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables Warnings: Note 1276 Field or reference 'test.t2.cur_date' of SELECT #2 was resolved in SELECT #1 -Note 1003 select 1 AS `id`,'2007-04-25' AS `cur_date` from `test`.`t2` semi join (`test`.`t2` `x1`) where (('2007-04-25' = 0)) +Note 1003 select 1 AS `id`,'2007-04-25' AS `cur_date` from `test`.`t2` semi join (`test`.`t2` `x1`) where ('2007-04-25' = 0) select * from t2 where id in (select id from t2 as x1 where (t2.cur_date is null)); id cur_date diff --git a/mysql-test/t/func_equal.test b/mysql-test/t/func_equal.test index 990b6d8e74e..f17ebb5bd84 100644 --- a/mysql-test/t/func_equal.test +++ b/mysql-test/t/func_equal.test @@ -44,53 +44,3 @@ select * from t1 where a in ('4828532208463511553'); drop table t1; --echo #End of 4.1 tests - ---echo # ---echo # MDEV-5103: server crashed on singular Item_equal ---echo # - -CREATE TABLE `t1` ( - `tipo` enum('p','r') NOT NULL DEFAULT 'r', - `arquivo_id` bigint(20) unsigned NOT NULL DEFAULT '0', - `arquivo_md5` char(32) NOT NULL, - `conteudo` longblob NOT NULL, - `usuario` varchar(15) NOT NULL, - `datahora_gmt` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `tipo_arquivo` varchar(255) NOT NULL, - `nome_arquivo` varchar(255) NOT NULL, - `tamanho_arquivo` bigint(20) unsigned NOT NULL DEFAULT '0', - PRIMARY KEY (`tipo`,`arquivo_id`), - UNIQUE KEY `tipo` (`tipo`,`arquivo_md5`) -) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1; - -INSERT INTO `t1` (`tipo`, `arquivo_id`, `arquivo_md5`, `conteudo`, `usuario`, `datahora_gmt`, `tipo_arquivo`, `nome_arquivo`, `tamanho_arquivo`) VALUES - ('r', 1, 'ad18832202b199728921807033a8a515', '', 'rspadim', '2013-10-05 13:55:50', '001_cbr643', 'CBR6431677410201314132.ret', 21306); - - -CREATE TABLE `t2` ( - `tipo` enum('p','r') NOT NULL DEFAULT 'p', - `arquivo_id` bigint(20) NOT NULL DEFAULT '0', - `usuario` varchar(25) NOT NULL, - `datahora` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', - `erros` longblob NOT NULL, - `importados` bigint(20) unsigned NOT NULL DEFAULT '0', - `n_importados` bigint(20) unsigned NOT NULL DEFAULT '0', - PRIMARY KEY (`tipo`,`arquivo_id`,`datahora`) -) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1; - -INSERT INTO `t2` (`tipo`, `arquivo_id`, `usuario`, `datahora`, `erros`, `importados`, `n_importados`) VALUES - ('r', 1, 'rspadim', '2013-10-05 14:25:30', '', 32, 0); - -SELECT -arquivo_id,usuario,datahora_gmt,tipo_arquivo,nome_arquivo,tamanho_arquivo - FROM t1 AS a - WHERE datahora_gmt>='0000-00-00 00:00:00' AND - datahora_gmt<='2013-10-07 02:59:59' AND tipo='r' AND - (tipo_arquivo,arquivo_id) NOT IN - (SELECT tipo_arquivo,arquivo_id - FROM t2 - WHERE (tipo_arquivo,arquivo_id)=(a.tipo_arquivo,a.arquivo_id)) - ORDER BY arquivo_id DESC; - -drop table t2, t1; ---echo #End of 5.3 tests diff --git a/mysql-test/t/subselect4.test b/mysql-test/t/subselect4.test index 51247e2c3ea..ad0e135f37e 100644 --- a/mysql-test/t/subselect4.test +++ b/mysql-test/t/subselect4.test @@ -1910,7 +1910,31 @@ WHERE b IS NULL OR a < 'u'; drop table t1,t2; set @@optimizer_switch = @optimizer_switch_MDEV4056; +--echo # +--echo # MDEV-5103: server crashed on singular Item_equal +--echo # + +CREATE TABLE t1 ( + a enum('p','r') NOT NULL DEFAULT 'r', + b int NOT NULL DEFAULT '0', + c char(32) NOT NULL, + d varchar(255) NOT NULL, + PRIMARY KEY (a, b), UNIQUE KEY idx(a, c) +); +INSERT INTO t1 VALUES ('r', 1, 'ad18832202b199728921807033a8a515', '001_cbr643'); + +CREATE TABLE t2 ( + a enum('p','r') NOT NULL DEFAULT 'r', + b int NOT NULL DEFAULT '0', + e datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (a, b, e) +); +INSERT INTO t2 VALUES ('r', 1, '2013-10-05 14:25:30'); + +SELECT * FROM t1 AS t + WHERE a='r' AND (c,b) NOT IN (SELECT c,b FROM t2 WHERE (c,b)=(t.c,t.b)); +DROP TABLE t1, t2; SET optimizer_switch= @@global.optimizer_switch; set @@tmp_table_size= @@global.tmp_table_size; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 49e56a46e84..f5c41ff854c 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -5485,7 +5485,8 @@ Item *Item_bool_rowready_func2::negated_item() */ Item_equal::Item_equal(Item *f1, Item *f2, bool with_const_item) - : Item_bool_func(), eval_item(0), cond_false(0), context_field(NULL) + : Item_bool_func(), eval_item(0), cond_false(0), cond_true(0), + context_field(NULL) { const_item_cache= 0; with_const= with_const_item; @@ -5510,7 +5511,8 @@ Item_equal::Item_equal(Item *f1, Item *f2, bool with_const_item) */ Item_equal::Item_equal(Item_equal *item_equal) - : Item_bool_func(), eval_item(0), cond_false(0), context_field(NULL) + : Item_bool_func(), eval_item(0), cond_false(0), cond_true(0), + context_field(NULL) { const_item_cache= 0; List_iterator_fast<Item> li(item_equal->equal_items); @@ -5569,12 +5571,6 @@ void Item_equal::add_const(Item *c, Item *f) func->quick_fix_field(); cond_false= !func->val_int(); } - /* - TODO: also support the case where Item_equal becomes singular with - this->is_cond_true()=1. When I attempted to mark the item as constant, - the optimizer attempted to remove it, however it is still referenced from - COND_EQUAL and I got a crash. - */ if (cond_false) const_item_cache= 1; } @@ -5779,8 +5775,7 @@ void Item_equal::merge_into_list(List<Item_equal> *list, void Item_equal::sort(Item_field_cmpfunc compare, void *arg) { - if (equal_items.elements > 1) - bubble_sort<Item>(&equal_items, compare, arg); + bubble_sort<Item>(&equal_items, compare, arg); } @@ -5816,6 +5811,9 @@ void Item_equal::update_const() { it.remove(); add_const(item); + if (equal_items.elements == 1) + cond_true= TRUE; + update_used_tables(); } } } @@ -5880,13 +5878,7 @@ bool Item_equal::fix_fields(THD *thd, Item **ref) void Item_equal::update_used_tables() { not_null_tables_cache= used_tables_cache= 0; - /* - TODO: also support the case where Item_equal becomes singular with - this->is_cond_true()=1. When I attempted to mark the item as constant, - the optimizer attempted to remove it, however it is still referenced from - COND_EQUAL and I got a crash. - */ - if ((const_item_cache= cond_false)) + if ((const_item_cache= cond_false || cond_true)) return; Item_equal_fields_iterator it(*this); Item *item; @@ -5934,7 +5926,7 @@ longlong Item_equal::val_int() { if (cond_false) return 0; - if (is_cond_true()) + if (cond_true) return 1; Item *item= get_const(); Item_equal_fields_iterator it(*this); @@ -5960,11 +5952,6 @@ longlong Item_equal::val_int() void Item_equal::fix_length_and_dec() { Item *item= get_first(NO_PARTICULAR_TAB, NULL); - if (!item) - { - DBUG_ASSERT(is_cond_true()); // it should be the only constant - item= equal_items.head(); - } eval_item= cmp_item::get_comparator(item->cmp_type(), item, item->collation.collation); } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index d00f177fc8e..a5d6ec02ace 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1695,6 +1695,12 @@ class Item_equal: public Item_bool_func the equal_items should be ignored. */ bool cond_false; + /* + This initially is set to FALSE. It becomes TRUE when this item is evaluated + as being always true. If the flag is TRUE the contents of the list + the equal_items should be ignored. + */ + bool cond_true; /* compare_as_dates=TRUE <-> constants equal to fields from equal_items must be compared as datetimes and not as strings. @@ -1725,7 +1731,6 @@ public: Item_equal(Item_equal *item_equal); /* Currently the const item is always the first in the list of equal items */ inline Item* get_const() { return with_const ? equal_items.head() : NULL; } - inline bool is_cond_true() { return equal_items.elements == 1; } void add_const(Item *c, Item *f = NULL); /** Add a non-constant item to the multiple equality */ void add(Item *f) { equal_items.push_back(f); } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 46797d66bb2..1d919d78508 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -13394,16 +13394,44 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value) { if (cond->type() == Item::COND_ITEM) { - List<Item_equal> new_equalities; bool and_level= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC; List<Item> *cond_arg_list= ((Item_cond*) cond)->argument_list(); + + if (and_level) + { + /* + Remove multiple equalities that became always true (e.g. after + constant row substitution). + They would be removed later in the function anyway, but the list of + them cond_equal.current_level also must be adjusted correspondingly. + So it's easier to do it at one pass through the list of the equalities. + */ + List<Item_equal> *cond_equalities= + &((Item_cond_and *) cond)->cond_equal.current_level; + cond_arg_list->disjoin((List<Item> *) cond_equalities); + List_iterator<Item_equal> it(*cond_equalities); + Item_equal *eq_item; + while ((eq_item= it++)) + { + if (eq_item->const_item() && eq_item->val_int()) + it.remove(); + } + cond_arg_list->concat((List<Item> *) cond_equalities); + } + + List<Item_equal> new_equalities; List_iterator<Item> li(*cond_arg_list); + bool should_fix_fields= 0; Item::cond_result tmp_cond_value; - bool should_fix_fields=0; - - *cond_value=Item::COND_UNDEF; Item *item; + + /* + If the list cond_arg_list became empty then it consisted only + of always true multiple equalities. + */ + *cond_value= cond_arg_list->elements ? Item::COND_UNDEF : Item::COND_TRUE; + while ((item=li++)) { Item *new_item=remove_eq_conds(thd, item, &tmp_cond_value); |