Skip to content

Commit 928012a

Browse files
committed
MDEV-31403: Server crashes in st_join_table::choose_best_splitting
The code in choose_best_splitting() assumed that the join prefix is in join->positions[]. This is not necessarily the case. This function might be called when the join prefix is in join->best_positions[], too. Follow the approach from best_access_path(), which calls this function: pass the current join prefix as an argument, "const POSITION *join_positions" and use that.
1 parent eb472f7 commit 928012a

File tree

5 files changed

+40
-1
lines changed

5 files changed

+40
-1
lines changed

mysql-test/main/derived_split_innodb.result

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -810,4 +810,19 @@ SELECT t1.* FROM t1 JOIN (SELECT id, COUNT(*) FROM t2 GROUP BY id) sq ON sq.id=
810810
a
811811
set optimizer_switch= @tmp1, join_cache_level= @tmp2;
812812
DROP TABLE t1, t2;
813+
#
814+
# MDEV-31403: Server crashes in st_join_table::choose_best_splitting (still)
815+
#
816+
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
817+
INSERT INTO t1 VALUES
818+
(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15);
819+
CREATE TABLE t2 (b INT) ENGINE=InnoDB;
820+
INSERT INTO t2 VALUES (100),(200);
821+
CREATE TABLE t3 (c INT, d INT, KEY(c)) ENGINE=InnoDB;
822+
INSERT INTO t3 VALUES (1,1),(2,2);
823+
CREATE VIEW v AS SELECT c, d FROM t3 GROUP BY c, d;
824+
SELECT * FROM t1 JOIN t2 WHERE (t1.a, t2.b) IN (SELECT * FROM v);
825+
a b
826+
DROP VIEW v;
827+
DROP TABLE t1, t2, t3;
813828
# End of 10.4 tests

mysql-test/main/derived_split_innodb.test

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,4 +462,25 @@ set optimizer_switch= @tmp1, join_cache_level= @tmp2;
462462
# Cleanup
463463
DROP TABLE t1, t2;
464464

465+
--echo #
466+
--echo # MDEV-31403: Server crashes in st_join_table::choose_best_splitting (still)
467+
--echo #
468+
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
469+
INSERT INTO t1 VALUES
470+
(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15);
471+
472+
CREATE TABLE t2 (b INT) ENGINE=InnoDB;
473+
INSERT INTO t2 VALUES (100),(200);
474+
475+
CREATE TABLE t3 (c INT, d INT, KEY(c)) ENGINE=InnoDB;
476+
INSERT INTO t3 VALUES (1,1),(2,2);
477+
478+
CREATE VIEW v AS SELECT c, d FROM t3 GROUP BY c, d;
479+
480+
SELECT * FROM t1 JOIN t2 WHERE (t1.a, t2.b) IN (SELECT * FROM v);
481+
482+
# Cleanup
483+
DROP VIEW v;
484+
DROP TABLE t1, t2, t3;
485+
465486
--echo # End of 10.4 tests

sql/opt_split.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -948,6 +948,7 @@ void reset_validity_vars_for_keyuses(KEYUSE_EXT *key_keyuse_ext_start,
948948

949949
SplM_plan_info * JOIN_TAB::choose_best_splitting(uint idx,
950950
table_map remaining_tables,
951+
const POSITION *join_positions,
951952
table_map *spl_pd_boundary)
952953
{
953954
SplM_opt_info *spl_opt_info= table->spl_opt_info;
@@ -1045,7 +1046,7 @@ SplM_plan_info * JOIN_TAB::choose_best_splitting(uint idx,
10451046
else
10461047
{
10471048
table_map last_found= this->table->map;
1048-
for (POSITION *pos= &this->join->positions[idx - 1]; ; pos--)
1049+
for (const POSITION *pos= &join_positions[idx - 1]; ; pos--)
10491050
{
10501051
if (pos->table->table->map & excluded_tables)
10511052
continue;

sql/sql_select.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7452,6 +7452,7 @@ best_access_path(JOIN *join,
74527452
if (s->table->is_splittable())
74537453
spl_plan= s->choose_best_splitting(idx,
74547454
remaining_tables,
7455+
join_positions,
74557456
&spl_pd_boundary);
74567457

74577458
Json_writer_array trace_paths(thd, "considered_access_paths");

sql/sql_select.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,7 @@ typedef struct st_join_table {
694694
void add_keyuses_for_splitting();
695695
SplM_plan_info *choose_best_splitting(uint idx,
696696
table_map remaining_tables,
697+
const POSITION *join_positions,
697698
table_map *spl_pd_boundary);
698699
bool fix_splitting(SplM_plan_info *spl_plan, table_map excluded_tables,
699700
bool is_const_table);

0 commit comments

Comments
 (0)