mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
MDEV-30651: Assertion `sel->quick' in make_range_rowid_filters
(Variant for 10.6: return error code from SQL_SELECT::test_quick_select) The optimizer deals with Rowid Filters this way: 1. First, range optimizer is invoked. It saves information about all potential range accesses. 2. A query plan is chosen. Suppose, it uses a Rowid Filter on index $IDX. 3. JOIN::make_range_rowid_filters() calls the range optimizer again to create a quick select on index $IDX which will be used to populate the rowid filter. The problem: KILL command catches the query in step #3. Quick Select is not created which causes a crash. Fixed by checking if query was killed.
This commit is contained in:
parent
e60acae655
commit
ef9e3e73ed
5 changed files with 77 additions and 3 deletions
|
@ -55,5 +55,33 @@ disconnect con1;
|
|||
reap;
|
||||
set debug_sync='RESET';
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-30651: SIGSEGV in st_join_table::save_explain_data and
|
||||
--echo # Assertion `sel->quick' failed in make_range_rowid_filters
|
||||
--echo #
|
||||
|
||||
--echo # Reusing table t2 and t3 from previous test
|
||||
let $target_id= `select connection_id()`;
|
||||
|
||||
set debug_sync='in_forced_range_optimize SIGNAL ready1 WAIT_FOR go1';
|
||||
send
|
||||
explain
|
||||
select * from t2, t3
|
||||
where
|
||||
t3.key1=t2.a and t3.key2 in (2,3);
|
||||
|
||||
connect (con1, localhost, root,,);
|
||||
set debug_sync='now WAIT_FOR ready1';
|
||||
evalp kill query $target_id;
|
||||
set debug_sync='now SIGNAL go1';
|
||||
|
||||
connection default;
|
||||
disconnect con1;
|
||||
|
||||
--error ER_QUERY_INTERRUPTED
|
||||
reap;
|
||||
set debug_sync='RESET';
|
||||
|
||||
|
||||
drop table t2,t3;
|
||||
--source include/wait_until_count_sessions.inc
|
||||
|
|
|
@ -46,5 +46,23 @@ connection default;
|
|||
disconnect con1;
|
||||
ERROR 70100: Query execution was interrupted
|
||||
set debug_sync='RESET';
|
||||
#
|
||||
# MDEV-30651: SIGSEGV in st_join_table::save_explain_data and
|
||||
# Assertion `sel->quick' failed in make_range_rowid_filters
|
||||
#
|
||||
# Reusing table t2 and t3 from previous test
|
||||
set debug_sync='in_forced_range_optimize SIGNAL ready1 WAIT_FOR go1';
|
||||
explain
|
||||
select * from t2, t3
|
||||
where
|
||||
t3.key1=t2.a and t3.key2 in (2,3);
|
||||
connect con1, localhost, root,,;
|
||||
set debug_sync='now WAIT_FOR ready1';
|
||||
kill query $target_id;
|
||||
set debug_sync='now SIGNAL go1';
|
||||
connection default;
|
||||
disconnect con1;
|
||||
ERROR 70100: Query execution was interrupted
|
||||
set debug_sync='RESET';
|
||||
drop table t2,t3;
|
||||
set default_storage_engine=default;
|
||||
|
|
|
@ -45,4 +45,22 @@ connection default;
|
|||
disconnect con1;
|
||||
ERROR 70100: Query execution was interrupted
|
||||
set debug_sync='RESET';
|
||||
#
|
||||
# MDEV-30651: SIGSEGV in st_join_table::save_explain_data and
|
||||
# Assertion `sel->quick' failed in make_range_rowid_filters
|
||||
#
|
||||
# Reusing table t2 and t3 from previous test
|
||||
set debug_sync='in_forced_range_optimize SIGNAL ready1 WAIT_FOR go1';
|
||||
explain
|
||||
select * from t2, t3
|
||||
where
|
||||
t3.key1=t2.a and t3.key2 in (2,3);
|
||||
connect con1, localhost, root,,;
|
||||
set debug_sync='now WAIT_FOR ready1';
|
||||
kill query $target_id;
|
||||
set debug_sync='now SIGNAL go1';
|
||||
connection default;
|
||||
disconnect con1;
|
||||
ERROR 70100: Query execution was interrupted
|
||||
set debug_sync='RESET';
|
||||
drop table t2,t3;
|
||||
|
|
|
@ -2720,7 +2720,10 @@ SQL_SELECT::test_quick_select(THD *thd,
|
|||
only_single_index_range_scan= 1;
|
||||
|
||||
if (head->force_index || force_quick_range)
|
||||
{
|
||||
DEBUG_SYNC(thd, "in_forced_range_optimize");
|
||||
scan_time= read_time= DBL_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
scan_time= rows2double(records) / TIME_FOR_COMPARE;
|
||||
|
@ -3117,6 +3120,12 @@ SQL_SELECT::test_quick_select(THD *thd,
|
|||
free_root(&alloc,MYF(0)); // Return memory & allocator
|
||||
thd->mem_root= param.old_root;
|
||||
thd->no_errors=0;
|
||||
if (thd->killed || thd->is_error())
|
||||
{
|
||||
delete quick;
|
||||
quick= NULL;
|
||||
returnval= ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
DBUG_EXECUTE("info", print_quick(quick, &needed_reg););
|
||||
|
|
|
@ -1987,6 +1987,7 @@ bool JOIN::make_range_rowid_filters()
|
|||
tab->table->force_index= force_index_save;
|
||||
if (rc == SQL_SELECT::ERROR || thd->is_error())
|
||||
{
|
||||
delete sel;
|
||||
DBUG_RETURN(true); /* Fatal error */
|
||||
}
|
||||
/*
|
||||
|
@ -2012,8 +2013,6 @@ bool JOIN::make_range_rowid_filters()
|
|||
continue;
|
||||
}
|
||||
no_filter:
|
||||
if (sel->quick)
|
||||
delete sel->quick;
|
||||
delete sel;
|
||||
}
|
||||
|
||||
|
@ -2031,7 +2030,9 @@ bool JOIN::make_range_rowid_filters()
|
|||
rowid container employed by the filter. On success it lets the table engine
|
||||
know that what rowid filter will be used when accessing the table rows.
|
||||
|
||||
@retval false always
|
||||
@retval
|
||||
false OK
|
||||
true Error, query should abort
|
||||
*/
|
||||
|
||||
bool
|
||||
|
|
Loading…
Reference in a new issue