Skip to content

Commit 0e9a255

Browse files
committed
MDEV-28871: Assert ... failed in JOIN::dbug_verify_sj_inner_tables...
optimize_semi_joins() calls update_sj_state() to update semi-join optimization state in the JOIN class. greedy_search() algorithm considers different join prefixes, and then picks one table to put into the join prefix. Most of the semi-join optimization state is in the table's entry in the join->positions[cur_prefix_size]. However, it also needs to call update_sj_state() to update the semi-join optimization state in the JOIN class. There is one exception, which is the cause of this bug: when we're inside optimize_semi_join_nests() and are optimizing a subquery, optimize_semi_joins() does nothing, it doesn't call update_sj_state(). greedy_search() must not do that either.
1 parent 66c0673 commit 0e9a255

File tree

5 files changed

+46
-1
lines changed

5 files changed

+46
-1
lines changed

mysql-test/main/subselect_sj.result

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3327,4 +3327,17 @@ ERROR HY000: Illegal parameter data types geometry and int for operation '='
33273327
EXECUTE stmt;
33283328
ERROR HY000: Illegal parameter data types geometry and int for operation '='
33293329
DROP TABLE t1, t2;
3330+
#
3331+
# MDEV-28871: Assert ... failed in JOIN::dbug_verify_sj_inner_tables with low optimizer_search_depth
3332+
#
3333+
set @tmp_28871=@@optimizer_search_depth;
3334+
CREATE TABLE t1 (a INT);
3335+
CREATE TABLE t2 (b INT);
3336+
INSERT INTO t1 VALUES (1),(2);
3337+
INSERT INTO t1 VALUES (3),(4);
3338+
SET optimizer_search_depth= 1;
3339+
SELECT * FROM t1 WHERE a IN (SELECT b FROM t2 JOIN t1);
3340+
a
3341+
DROP TABLE t1, t2;
3342+
set optimizer_search_depth= @tmp_28871;
33303343
set optimizer_switch=@subselect_sj_tmp;

mysql-test/main/subselect_sj.test

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3016,5 +3016,22 @@ EXECUTE stmt;
30163016

30173017
DROP TABLE t1, t2;
30183018

3019+
--echo #
3020+
--echo # MDEV-28871: Assert ... failed in JOIN::dbug_verify_sj_inner_tables with low optimizer_search_depth
3021+
--echo #
3022+
set @tmp_28871=@@optimizer_search_depth;
3023+
CREATE TABLE t1 (a INT);
3024+
CREATE TABLE t2 (b INT);
3025+
3026+
# Data is optional, fails either way
3027+
INSERT INTO t1 VALUES (1),(2);
3028+
INSERT INTO t1 VALUES (3),(4);
3029+
3030+
SET optimizer_search_depth= 1;
3031+
3032+
SELECT * FROM t1 WHERE a IN (SELECT b FROM t2 JOIN t1);
3033+
DROP TABLE t1, t2;
3034+
set optimizer_search_depth= @tmp_28871;
3035+
30193036
# The following command must be the last one the file
30203037
set optimizer_switch=@subselect_sj_tmp;

mysql-test/main/subselect_sj_jcl6.result

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3338,6 +3338,19 @@ ERROR HY000: Illegal parameter data types geometry and int for operation '='
33383338
EXECUTE stmt;
33393339
ERROR HY000: Illegal parameter data types geometry and int for operation '='
33403340
DROP TABLE t1, t2;
3341+
#
3342+
# MDEV-28871: Assert ... failed in JOIN::dbug_verify_sj_inner_tables with low optimizer_search_depth
3343+
#
3344+
set @tmp_28871=@@optimizer_search_depth;
3345+
CREATE TABLE t1 (a INT);
3346+
CREATE TABLE t2 (b INT);
3347+
INSERT INTO t1 VALUES (1),(2);
3348+
INSERT INTO t1 VALUES (3),(4);
3349+
SET optimizer_search_depth= 1;
3350+
SELECT * FROM t1 WHERE a IN (SELECT b FROM t2 JOIN t1);
3351+
a
3352+
DROP TABLE t1, t2;
3353+
set optimizer_search_depth= @tmp_28871;
33413354
set optimizer_switch=@subselect_sj_tmp;
33423355
#
33433356
# BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off

sql/opt_subselect.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2894,6 +2894,7 @@ void optimize_semi_joins(JOIN *join, table_map remaining_tables, uint idx,
28942894
void update_sj_state(JOIN *join, const JOIN_TAB *new_tab,
28952895
uint idx, table_map remaining_tables)
28962896
{
2897+
DBUG_ASSERT(!join->emb_sjm_nest);
28972898
if (TABLE_LIST *emb_sj_nest= new_tab->emb_sj_nest)
28982899
{
28992900
join->cur_sj_inner_tables |= emb_sj_nest->sj_inner_tables;

sql/sql_select.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8210,7 +8210,8 @@ greedy_search(JOIN *join,
82108210
picked semi-join operation is in best_pos->...picker, but we need to
82118211
update the global state in the JOIN object, too.
82128212
*/
8213-
update_sj_state(join, best_table, idx, remaining_tables);
8213+
if (!join->emb_sjm_nest)
8214+
update_sj_state(join, best_table, idx, remaining_tables);
82148215

82158216
/* find the position of 'best_table' in 'join->best_ref' */
82168217
best_idx= idx;

0 commit comments

Comments
 (0)