mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
MDEV-5103: server crashed on singular Item_equal
Singular Item_equal support added. The problem was that during constant table substitution Item_equal become containing only one constant which was not supported internally.
This commit is contained in:
@ -42,3 +42,47 @@ select * from t1 where a in ('4828532208463511553');
|
|||||||
a
|
a
|
||||||
4828532208463511553
|
4828532208463511553
|
||||||
drop table t1;
|
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
|
||||||
|
@ -43,4 +43,54 @@ select * from t1 where a = '4828532208463511553';
|
|||||||
select * from t1 where a in ('4828532208463511553');
|
select * from t1 where a in ('4828532208463511553');
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
# 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
|
||||||
|
@ -5564,6 +5564,12 @@ 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;
|
||||||
}
|
}
|
||||||
@ -5768,6 +5774,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5868,6 +5875,12 @@ 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;
|
||||||
|
/*
|
||||||
|
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))
|
||||||
return;
|
return;
|
||||||
Item_equal_fields_iterator it(*this);
|
Item_equal_fields_iterator it(*this);
|
||||||
@ -5916,6 +5929,8 @@ longlong Item_equal::val_int()
|
|||||||
{
|
{
|
||||||
if (cond_false)
|
if (cond_false)
|
||||||
return 0;
|
return 0;
|
||||||
|
if (is_cond_true())
|
||||||
|
return 1;
|
||||||
Item *item= get_const();
|
Item *item= get_const();
|
||||||
Item_equal_fields_iterator it(*this);
|
Item_equal_fields_iterator it(*this);
|
||||||
if (!item)
|
if (!item)
|
||||||
@ -5940,6 +5955,11 @@ 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);
|
||||||
}
|
}
|
||||||
|
@ -1725,6 +1725,7 @@ 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); }
|
||||||
|
Reference in New Issue
Block a user