Commit 8224d955 authored by Igor Babaev's avatar Igor Babaev

Merge

parents 2394fa67 c0f31dc9
...@@ -43,46 +43,3 @@ a ...@@ -43,46 +43,3 @@ a
4828532208463511553 4828532208463511553
drop table t1; drop table t1;
#End of 4.1 tests #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
...@@ -1773,7 +1773,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -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 t1 const PRIMARY,idx PRIMARY 4 const 1 100.00
1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 100.00 Using index 1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 100.00 Using index
Warnings: 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 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 WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5
ORDER BY t1.pk; ORDER BY t1.pk;
......
...@@ -1784,7 +1784,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -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 t1 const PRIMARY,idx PRIMARY 4 const 1 100.00
1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 100.00 Using index 1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 100.00 Using index
Warnings: 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 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 WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5
ORDER BY t1.pk; ORDER BY t1.pk;
......
...@@ -5125,7 +5125,7 @@ SELECT * FROM t1 WHERE (1=2 OR t1.pk=2) AND t1.a <> 0; ...@@ -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 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 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings: 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; DROP TABLE t1;
SELECT * FROM mysql.time_zone SELECT * FROM mysql.time_zone
WHERE ( NOT (Use_leap_seconds <= Use_leap_seconds AND Time_zone_id != 1) WHERE ( NOT (Use_leap_seconds <= Use_leap_seconds AND Time_zone_id != 1)
......
...@@ -5136,7 +5136,7 @@ SELECT * FROM t1 WHERE (1=2 OR t1.pk=2) AND t1.a <> 0; ...@@ -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 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 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings: 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; DROP TABLE t1;
SELECT * FROM mysql.time_zone SELECT * FROM mysql.time_zone
WHERE ( NOT (Use_leap_seconds <= Use_leap_seconds AND Time_zone_id != 1) WHERE ( NOT (Use_leap_seconds <= Use_leap_seconds AND Time_zone_id != 1)
......
...@@ -5125,7 +5125,7 @@ SELECT * FROM t1 WHERE (1=2 OR t1.pk=2) AND t1.a <> 0; ...@@ -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 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 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings: 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; DROP TABLE t1;
SELECT * FROM mysql.time_zone SELECT * FROM mysql.time_zone
WHERE ( NOT (Use_leap_seconds <= Use_leap_seconds AND Time_zone_id != 1) WHERE ( NOT (Use_leap_seconds <= Use_leap_seconds AND Time_zone_id != 1)
......
...@@ -2326,5 +2326,27 @@ x NULL NULL NULL ...@@ -2326,5 +2326,27 @@ x NULL NULL NULL
d NULL NULL NULL d NULL NULL NULL
drop table t1,t2; drop table t1,t2;
set @@optimizer_switch = @optimizer_switch_MDEV4056; 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 optimizer_switch= @@global.optimizer_switch;
set @@tmp_table_size= @@global.tmp_table_size; set @@tmp_table_size= @@global.tmp_table_size;
...@@ -46,7 +46,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -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 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings: Warnings:
Note 1276 Field or reference 'test.t1.cur_date' of SELECT #2 was resolved in SELECT #1 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 select * from t1
where id in (select id from t1 as x1 where (t1.cur_date is null)); where id in (select id from t1 as x1 where (t1.cur_date is null));
id cur_date id cur_date
...@@ -57,7 +57,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -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 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings: Warnings:
Note 1276 Field or reference 'test.t2.cur_date' of SELECT #2 was resolved in SELECT #1 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 select * from t2
where id in (select id from t2 as x1 where (t2.cur_date is null)); where id in (select id from t2 as x1 where (t2.cur_date is null));
id cur_date id cur_date
......
...@@ -519,7 +519,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -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 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings: Warnings:
Note 1276 Field or reference 'test.t1.cur_date' of SELECT #2 was resolved in SELECT #1 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 select * from t1
where id in (select id from t1 as x1 where (t1.cur_date is null)); where id in (select id from t1 as x1 where (t1.cur_date is null));
id cur_date id cur_date
...@@ -530,7 +530,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -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 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings: Warnings:
Note 1276 Field or reference 'test.t2.cur_date' of SELECT #2 was resolved in SELECT #1 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 select * from t2
where id in (select id from t2 as x1 where (t2.cur_date is null)); where id in (select id from t2 as x1 where (t2.cur_date is null));
id cur_date id cur_date
......
...@@ -44,53 +44,3 @@ select * from t1 where a in ('4828532208463511553'); ...@@ -44,53 +44,3 @@ select * from t1 where a in ('4828532208463511553');
drop table t1; drop table t1;
--echo #End of 4.1 tests --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
...@@ -1910,7 +1910,31 @@ WHERE b IS NULL OR a < 'u'; ...@@ -1910,7 +1910,31 @@ WHERE b IS NULL OR a < 'u';
drop table t1,t2; drop table t1,t2;
set @@optimizer_switch = @optimizer_switch_MDEV4056; 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 optimizer_switch= @@global.optimizer_switch;
set @@tmp_table_size= @@global.tmp_table_size; set @@tmp_table_size= @@global.tmp_table_size;
...@@ -5488,7 +5488,8 @@ Item *Item_bool_rowready_func2::negated_item() ...@@ -5488,7 +5488,8 @@ Item *Item_bool_rowready_func2::negated_item()
*/ */
Item_equal::Item_equal(Item *f1, Item *f2, bool with_const_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; const_item_cache= 0;
with_const= with_const_item; with_const= with_const_item;
...@@ -5513,7 +5514,8 @@ Item_equal::Item_equal(Item *f1, Item *f2, bool with_const_item) ...@@ -5513,7 +5514,8 @@ Item_equal::Item_equal(Item *f1, Item *f2, bool with_const_item)
*/ */
Item_equal::Item_equal(Item_equal *item_equal) 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; const_item_cache= 0;
List_iterator_fast<Item> li(item_equal->equal_items); List_iterator_fast<Item> li(item_equal->equal_items);
...@@ -5572,12 +5574,6 @@ void Item_equal::add_const(Item *c, Item *f) ...@@ -5572,12 +5574,6 @@ void Item_equal::add_const(Item *c, Item *f)
func->quick_fix_field(); func->quick_fix_field();
cond_false= !func->val_int(); 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) if (cond_false)
const_item_cache= 1; const_item_cache= 1;
} }
...@@ -5782,8 +5778,7 @@ void Item_equal::merge_into_list(List<Item_equal> *list, ...@@ -5782,8 +5778,7 @@ void Item_equal::merge_into_list(List<Item_equal> *list,
void Item_equal::sort(Item_field_cmpfunc compare, void *arg) 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);
} }
...@@ -5819,6 +5814,9 @@ void Item_equal::update_const() ...@@ -5819,6 +5814,9 @@ void Item_equal::update_const()
{ {
it.remove(); it.remove();
add_const(item); add_const(item);
if (equal_items.elements == 1)
cond_true= TRUE;
update_used_tables();
} }
} }
} }
...@@ -5883,13 +5881,7 @@ bool Item_equal::fix_fields(THD *thd, Item **ref) ...@@ -5883,13 +5881,7 @@ bool Item_equal::fix_fields(THD *thd, Item **ref)
void Item_equal::update_used_tables() void Item_equal::update_used_tables()
{ {
not_null_tables_cache= used_tables_cache= 0; not_null_tables_cache= used_tables_cache= 0;
/* if ((const_item_cache= cond_false || cond_true))
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))
return; return;
Item_equal_fields_iterator it(*this); Item_equal_fields_iterator it(*this);
Item *item; Item *item;
...@@ -5937,7 +5929,7 @@ longlong Item_equal::val_int() ...@@ -5937,7 +5929,7 @@ longlong Item_equal::val_int()
{ {
if (cond_false) if (cond_false)
return 0; return 0;
if (is_cond_true()) if (cond_true)
return 1; return 1;
Item *item= get_const(); Item *item= get_const();
Item_equal_fields_iterator it(*this); Item_equal_fields_iterator it(*this);
...@@ -5963,11 +5955,6 @@ longlong Item_equal::val_int() ...@@ -5963,11 +5955,6 @@ longlong Item_equal::val_int()
void Item_equal::fix_length_and_dec() void Item_equal::fix_length_and_dec()
{ {
Item *item= get_first(NO_PARTICULAR_TAB, NULL); 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, eval_item= cmp_item::get_comparator(item->cmp_type(), item,
item->collation.collation); item->collation.collation);
} }
......
...@@ -1695,6 +1695,12 @@ class Item_equal: public Item_bool_func ...@@ -1695,6 +1695,12 @@ class Item_equal: public Item_bool_func
the equal_items should be ignored. the equal_items should be ignored.
*/ */
bool cond_false; 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 compare_as_dates=TRUE <-> constants equal to fields from equal_items
must be compared as datetimes and not as strings. must be compared as datetimes and not as strings.
...@@ -1725,7 +1731,6 @@ public: ...@@ -1725,7 +1731,6 @@ public:
Item_equal(Item_equal *item_equal); Item_equal(Item_equal *item_equal);
/* Currently the const item is always the first in the list of equal items */ /* 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 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); void add_const(Item *c, Item *f = NULL);
/** Add a non-constant item to the multiple equality */ /** Add a non-constant item to the multiple equality */
void add(Item *f) { equal_items.push_back(f); } void add(Item *f) { equal_items.push_back(f); }
......
...@@ -13394,16 +13394,44 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value) ...@@ -13394,16 +13394,44 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
{ {
if (cond->type() == Item::COND_ITEM) if (cond->type() == Item::COND_ITEM)
{ {
List<Item_equal> new_equalities;
bool and_level= ((Item_cond*) cond)->functype() bool and_level= ((Item_cond*) cond)->functype()
== Item_func::COND_AND_FUNC; == Item_func::COND_AND_FUNC;
List<Item> *cond_arg_list= ((Item_cond*) cond)->argument_list(); 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); List_iterator<Item> li(*cond_arg_list);
bool should_fix_fields= 0;
Item::cond_result tmp_cond_value; Item::cond_result tmp_cond_value;
bool should_fix_fields=0;
*cond_value=Item::COND_UNDEF;
Item *item; 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++)) while ((item=li++))
{ {
Item *new_item=remove_eq_conds(thd, item, &tmp_cond_value); Item *new_item=remove_eq_conds(thd, item, &tmp_cond_value);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment