Skip to content

Commit

Permalink
MDEV-30651: Assertion `sel->quick' in make_range_rowid_filters
Browse files Browse the repository at this point in the history
(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.
  • Loading branch information
spetrunia committed Jun 17, 2024
1 parent e60acae commit ef9e3e7
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 3 deletions.
28 changes: 28 additions & 0 deletions mysql-test/include/rowid_filter_debug_kill.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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
18 changes: 18 additions & 0 deletions mysql-test/main/rowid_filter_innodb_debug.result
Original file line number Diff line number Diff line change
Expand Up @@ -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;
18 changes: 18 additions & 0 deletions mysql-test/main/rowid_filter_myisam_debug.result
Original file line number Diff line number Diff line change
Expand Up @@ -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;
9 changes: 9 additions & 0 deletions sql/opt_range.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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););
Expand Down
7 changes: 4 additions & 3 deletions sql/sql_select.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
}
/*
Expand All @@ -2012,8 +2013,6 @@ bool JOIN::make_range_rowid_filters()
continue;
}
no_filter:
if (sel->quick)
delete sel->quick;
delete sel;
}

Expand All @@ -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
Expand Down

0 comments on commit ef9e3e7

Please sign in to comment.