MDEV-4316 MariaDB server crash with signal 11
fulltext search was initialized for all MATCH ... AGAINST items at the end of the JOIN::optimize(). But since 5.3 derived tables are initialized lazily on first use, very late in the sub_select(). Skip Item_func_match::init_search initialization if the corresponding table isn't open yet; repeat fulltext initialization for all not-yet-initialized MATCH ... AGAINST items after creating derived tables.
This commit is contained in:
parent
385de8743a
commit
6770a9a836
8
mysql-test/r/fulltext_derived_4316.result
Normal file
8
mysql-test/r/fulltext_derived_4316.result
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
create table t1 (ft text) engine=myisam;
|
||||||
|
insert into t1 values ('test1'),('test2');
|
||||||
|
select distinct match(ft) against("test1" in boolean mode) from
|
||||||
|
(select distinct ft from t1) as t;
|
||||||
|
match(ft) against("test1" in boolean mode)
|
||||||
|
1
|
||||||
|
0
|
||||||
|
drop table t1;
|
14
mysql-test/t/fulltext_derived_4316.test
Normal file
14
mysql-test/t/fulltext_derived_4316.test
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#
|
||||||
|
# MATCH on the derived tables
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# MDEV-4316 MariaDB server crash with signal 11
|
||||||
|
#
|
||||||
|
|
||||||
|
create table t1 (ft text) engine=myisam;
|
||||||
|
insert into t1 values ('test1'),('test2');
|
||||||
|
select distinct match(ft) against("test1" in boolean mode) from
|
||||||
|
(select distinct ft from t1) as t;
|
||||||
|
drop table t1;
|
||||||
|
|
@ -5514,15 +5514,12 @@ void Item_func_match::init_search(bool no_order)
|
|||||||
{
|
{
|
||||||
DBUG_ENTER("Item_func_match::init_search");
|
DBUG_ENTER("Item_func_match::init_search");
|
||||||
|
|
||||||
|
if (!table->file->get_table()) // the handler isn't opened yet
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
|
||||||
/* Check if init_search() has been called before */
|
/* Check if init_search() has been called before */
|
||||||
if (ft_handler)
|
if (ft_handler)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
We should reset ft_handler as it is cleaned up
|
|
||||||
on destruction of FT_SELECT object
|
|
||||||
(necessary in case of re-execution of subquery).
|
|
||||||
TODO: FT_SELECT should not clean up ft_handler.
|
|
||||||
*/
|
|
||||||
if (join_key)
|
if (join_key)
|
||||||
table->file->ft_handler= ft_handler;
|
table->file->ft_handler= ft_handler;
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
@ -5531,10 +5528,10 @@ void Item_func_match::init_search(bool no_order)
|
|||||||
if (key == NO_SUCH_KEY)
|
if (key == NO_SUCH_KEY)
|
||||||
{
|
{
|
||||||
List<Item> fields;
|
List<Item> fields;
|
||||||
fields.push_back(new Item_string(" ",1, cmp_collation.collation));
|
fields.push_back(new Item_string(" ", 1, cmp_collation.collation));
|
||||||
for (uint i=1; i < arg_count; i++)
|
for (uint i= 1; i < arg_count; i++)
|
||||||
fields.push_back(args[i]);
|
fields.push_back(args[i]);
|
||||||
concat_ws=new Item_func_concat_ws(fields);
|
concat_ws= new Item_func_concat_ws(fields);
|
||||||
/*
|
/*
|
||||||
Above function used only to get value and do not need fix_fields for it:
|
Above function used only to get value and do not need fix_fields for it:
|
||||||
Item_string - basic constant
|
Item_string - basic constant
|
||||||
@ -5546,10 +5543,10 @@ void Item_func_match::init_search(bool no_order)
|
|||||||
|
|
||||||
if (master)
|
if (master)
|
||||||
{
|
{
|
||||||
join_key=master->join_key=join_key|master->join_key;
|
join_key= master->join_key= join_key | master->join_key;
|
||||||
master->init_search(no_order);
|
master->init_search(no_order);
|
||||||
ft_handler=master->ft_handler;
|
ft_handler= master->ft_handler;
|
||||||
join_key=master->join_key;
|
join_key= master->join_key;
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5559,7 +5556,7 @@ void Item_func_match::init_search(bool no_order)
|
|||||||
if (!(ft_tmp=key_item()->val_str(&value)))
|
if (!(ft_tmp=key_item()->val_str(&value)))
|
||||||
{
|
{
|
||||||
ft_tmp= &value;
|
ft_tmp= &value;
|
||||||
value.set("",0,cmp_collation.collation);
|
value.set("", 0, cmp_collation.collation);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ft_tmp->charset() != cmp_collation.collation)
|
if (ft_tmp->charset() != cmp_collation.collation)
|
||||||
@ -5572,7 +5569,11 @@ void Item_func_match::init_search(bool no_order)
|
|||||||
|
|
||||||
if (join_key && !no_order)
|
if (join_key && !no_order)
|
||||||
flags|=FT_SORTED;
|
flags|=FT_SORTED;
|
||||||
ft_handler=table->file->ft_init_ext(flags, key, ft_tmp);
|
|
||||||
|
if (key != NO_SUCH_KEY)
|
||||||
|
thd_proc_info(table->in_use, "FULLTEXT initialization");
|
||||||
|
|
||||||
|
ft_handler= table->file->ft_init_ext(flags, key, ft_tmp);
|
||||||
|
|
||||||
if (join_key)
|
if (join_key)
|
||||||
table->file->ft_handler=ft_handler;
|
table->file->ft_handler=ft_handler;
|
||||||
|
@ -9241,7 +9241,6 @@ int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order)
|
|||||||
List_iterator<Item_func_match> li(*(select_lex->ftfunc_list));
|
List_iterator<Item_func_match> li(*(select_lex->ftfunc_list));
|
||||||
Item_func_match *ifm;
|
Item_func_match *ifm;
|
||||||
DBUG_PRINT("info",("Performing FULLTEXT search"));
|
DBUG_PRINT("info",("Performing FULLTEXT search"));
|
||||||
thd_proc_info(thd, "FULLTEXT initialization");
|
|
||||||
|
|
||||||
while ((ifm=li++))
|
while ((ifm=li++))
|
||||||
ifm->init_search(no_order);
|
ifm->init_search(no_order);
|
||||||
|
@ -10191,6 +10191,11 @@ bool JOIN_TAB::preread_init()
|
|||||||
preread_init_done= TRUE;
|
preread_init_done= TRUE;
|
||||||
if (select && select->quick)
|
if (select && select->quick)
|
||||||
select->quick->replace_handler(table->file);
|
select->quick->replace_handler(table->file);
|
||||||
|
|
||||||
|
/* init ftfuns for just initialized derived table */
|
||||||
|
if (table->fulltext_searched)
|
||||||
|
init_ftfuncs(join->thd, join->select_lex, test(join->order));
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user