Skip to content

Commit a2066b2

Browse files
committed
MDEV-30651: Assertion `sel->quick' in make_range_rowid_filters
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. Note: the problem also affects 10.6, even if error handling for SQL_SELECT::test_quick_select is different there.
1 parent b47bd3f commit a2066b2

File tree

5 files changed

+75
-5
lines changed

5 files changed

+75
-5
lines changed

mysql-test/include/rowid_filter_debug_kill.inc

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,33 @@ disconnect con1;
5555
reap;
5656
set debug_sync='RESET';
5757

58+
--echo #
59+
--echo # MDEV-30651: SIGSEGV in st_join_table::save_explain_data and
60+
--echo # Assertion `sel->quick' failed in make_range_rowid_filters
61+
--echo #
62+
63+
--echo # Reusing table t2 and t3 from previous test
64+
let $target_id= `select connection_id()`;
65+
66+
set debug_sync='in_forced_range_optimize SIGNAL ready1 WAIT_FOR go1';
67+
send
68+
explain
69+
select * from t2, t3
70+
where
71+
t3.key1=t2.a and t3.key2 in (2,3);
72+
73+
connect (con1, localhost, root,,);
74+
set debug_sync='now WAIT_FOR ready1';
75+
evalp kill query $target_id;
76+
set debug_sync='now SIGNAL go1';
77+
78+
connection default;
79+
disconnect con1;
80+
81+
--error ER_QUERY_INTERRUPTED
82+
reap;
83+
set debug_sync='RESET';
84+
85+
5886
drop table t2,t3;
5987
--source include/wait_until_count_sessions.inc

mysql-test/main/rowid_filter_innodb_debug.result

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,23 @@ connection default;
4646
disconnect con1;
4747
ERROR 70100: Query execution was interrupted
4848
set debug_sync='RESET';
49+
#
50+
# MDEV-30651: SIGSEGV in st_join_table::save_explain_data and
51+
# Assertion `sel->quick' failed in make_range_rowid_filters
52+
#
53+
# Reusing table t2 and t3 from previous test
54+
set debug_sync='in_forced_range_optimize SIGNAL ready1 WAIT_FOR go1';
55+
explain
56+
select * from t2, t3
57+
where
58+
t3.key1=t2.a and t3.key2 in (2,3);
59+
connect con1, localhost, root,,;
60+
set debug_sync='now WAIT_FOR ready1';
61+
kill query $target_id;
62+
set debug_sync='now SIGNAL go1';
63+
connection default;
64+
disconnect con1;
65+
ERROR 70100: Query execution was interrupted
66+
set debug_sync='RESET';
4967
drop table t2,t3;
5068
set default_storage_engine=default;

mysql-test/main/rowid_filter_myisam_debug.result

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,22 @@ connection default;
4545
disconnect con1;
4646
ERROR 70100: Query execution was interrupted
4747
set debug_sync='RESET';
48+
#
49+
# MDEV-30651: SIGSEGV in st_join_table::save_explain_data and
50+
# Assertion `sel->quick' failed in make_range_rowid_filters
51+
#
52+
# Reusing table t2 and t3 from previous test
53+
set debug_sync='in_forced_range_optimize SIGNAL ready1 WAIT_FOR go1';
54+
explain
55+
select * from t2, t3
56+
where
57+
t3.key1=t2.a and t3.key2 in (2,3);
58+
connect con1, localhost, root,,;
59+
set debug_sync='now WAIT_FOR ready1';
60+
kill query $target_id;
61+
set debug_sync='now SIGNAL go1';
62+
connection default;
63+
disconnect con1;
64+
ERROR 70100: Query execution was interrupted
65+
set debug_sync='RESET';
4866
drop table t2,t3;

sql/opt_range.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2708,7 +2708,10 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
27082708
only_single_index_range_scan= 1;
27092709

27102710
if (head->force_index || force_quick_range)
2711+
{
2712+
DEBUG_SYNC(thd, "in_forced_range_optimize");
27112713
scan_time= read_time= DBL_MAX;
2714+
}
27122715
else
27132716
{
27142717
scan_time= rows2double(records) / TIME_FOR_COMPARE;

sql/sql_select.cc

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1783,7 +1783,9 @@ int JOIN::optimize()
17831783
object a pointer to which is set in the field JOIN_TAB::rowid_filter of
17841784
the joined table.
17851785

1786-
@retval false always
1786+
@retval
1787+
false OK
1788+
true Error, query should abort
17871789
*/
17881790

17891791
bool JOIN::make_range_rowid_filters()
@@ -1830,8 +1832,11 @@ bool JOIN::make_range_rowid_filters()
18301832
(ha_rows) HA_POS_ERROR,
18311833
true, false, true, true);
18321834
tab->table->force_index= force_index_save;
1833-
if (thd->is_error())
1834-
goto no_filter;
1835+
if (thd->is_error() || thd->check_killed())
1836+
{
1837+
delete sel;
1838+
DBUG_RETURN(true);
1839+
}
18351840
/*
18361841
If SUBS_IN_TO_EXISTS strtrategy is chosen for the subquery then
18371842
additional conditions are injected into WHERE/ON/HAVING and it may
@@ -1855,8 +1860,6 @@ bool JOIN::make_range_rowid_filters()
18551860
continue;
18561861
}
18571862
no_filter:
1858-
if (sel->quick)
1859-
delete sel->quick;
18601863
delete sel;
18611864
}
18621865

0 commit comments

Comments
 (0)