1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03: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:
Sergei Petrunia
2024-06-11 16:20:00 +03:00
parent e60acae655
commit ef9e3e73ed
5 changed files with 77 additions and 3 deletions

View File

@ -55,5 +55,33 @@ disconnect con1;
reap; reap;
set debug_sync='RESET'; 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; drop table t2,t3;
--source include/wait_until_count_sessions.inc --source include/wait_until_count_sessions.inc

View File

@ -46,5 +46,23 @@ connection default;
disconnect con1; disconnect con1;
ERROR 70100: Query execution was interrupted ERROR 70100: Query execution was interrupted
set debug_sync='RESET'; 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; drop table t2,t3;
set default_storage_engine=default; set default_storage_engine=default;

View File

@ -45,4 +45,22 @@ connection default;
disconnect con1; disconnect con1;
ERROR 70100: Query execution was interrupted ERROR 70100: Query execution was interrupted
set debug_sync='RESET'; 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; drop table t2,t3;

View File

@ -2720,7 +2720,10 @@ SQL_SELECT::test_quick_select(THD *thd,
only_single_index_range_scan= 1; only_single_index_range_scan= 1;
if (head->force_index || force_quick_range) if (head->force_index || force_quick_range)
{
DEBUG_SYNC(thd, "in_forced_range_optimize");
scan_time= read_time= DBL_MAX; scan_time= read_time= DBL_MAX;
}
else else
{ {
scan_time= rows2double(records) / TIME_FOR_COMPARE; 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 free_root(&alloc,MYF(0)); // Return memory & allocator
thd->mem_root= param.old_root; thd->mem_root= param.old_root;
thd->no_errors=0; thd->no_errors=0;
if (thd->killed || thd->is_error())
{
delete quick;
quick= NULL;
returnval= ERROR;
}
} }
DBUG_EXECUTE("info", print_quick(quick, &needed_reg);); DBUG_EXECUTE("info", print_quick(quick, &needed_reg););

View File

@ -1987,6 +1987,7 @@ bool JOIN::make_range_rowid_filters()
tab->table->force_index= force_index_save; tab->table->force_index= force_index_save;
if (rc == SQL_SELECT::ERROR || thd->is_error()) if (rc == SQL_SELECT::ERROR || thd->is_error())
{ {
delete sel;
DBUG_RETURN(true); /* Fatal error */ DBUG_RETURN(true); /* Fatal error */
} }
/* /*
@ -2012,8 +2013,6 @@ bool JOIN::make_range_rowid_filters()
continue; continue;
} }
no_filter: no_filter:
if (sel->quick)
delete sel->quick;
delete sel; 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 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. 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 bool