mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
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.
This commit is contained in:
@ -810,4 +810,19 @@ SELECT t1.* FROM t1 JOIN (SELECT id, COUNT(*) FROM t2 GROUP BY id) sq ON sq.id=
|
|||||||
a
|
a
|
||||||
set optimizer_switch= @tmp1, join_cache_level= @tmp2;
|
set optimizer_switch= @tmp1, join_cache_level= @tmp2;
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
#
|
||||||
|
# MDEV-31403: Server crashes in st_join_table::choose_best_splitting (still)
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t1 VALUES
|
||||||
|
(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15);
|
||||||
|
CREATE TABLE t2 (b INT) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t2 VALUES (100),(200);
|
||||||
|
CREATE TABLE t3 (c INT, d INT, KEY(c)) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t3 VALUES (1,1),(2,2);
|
||||||
|
CREATE VIEW v AS SELECT c, d FROM t3 GROUP BY c, d;
|
||||||
|
SELECT * FROM t1 JOIN t2 WHERE (t1.a, t2.b) IN (SELECT * FROM v);
|
||||||
|
a b
|
||||||
|
DROP VIEW v;
|
||||||
|
DROP TABLE t1, t2, t3;
|
||||||
# End of 10.4 tests
|
# End of 10.4 tests
|
||||||
|
@ -462,4 +462,25 @@ set optimizer_switch= @tmp1, join_cache_level= @tmp2;
|
|||||||
# Cleanup
|
# Cleanup
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-31403: Server crashes in st_join_table::choose_best_splitting (still)
|
||||||
|
--echo #
|
||||||
|
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t1 VALUES
|
||||||
|
(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15);
|
||||||
|
|
||||||
|
CREATE TABLE t2 (b INT) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t2 VALUES (100),(200);
|
||||||
|
|
||||||
|
CREATE TABLE t3 (c INT, d INT, KEY(c)) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t3 VALUES (1,1),(2,2);
|
||||||
|
|
||||||
|
CREATE VIEW v AS SELECT c, d FROM t3 GROUP BY c, d;
|
||||||
|
|
||||||
|
SELECT * FROM t1 JOIN t2 WHERE (t1.a, t2.b) IN (SELECT * FROM v);
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
DROP VIEW v;
|
||||||
|
DROP TABLE t1, t2, t3;
|
||||||
|
|
||||||
--echo # End of 10.4 tests
|
--echo # End of 10.4 tests
|
||||||
|
@ -948,6 +948,7 @@ void reset_validity_vars_for_keyuses(KEYUSE_EXT *key_keyuse_ext_start,
|
|||||||
|
|
||||||
SplM_plan_info * JOIN_TAB::choose_best_splitting(uint idx,
|
SplM_plan_info * JOIN_TAB::choose_best_splitting(uint idx,
|
||||||
table_map remaining_tables,
|
table_map remaining_tables,
|
||||||
|
const POSITION *join_positions,
|
||||||
table_map *spl_pd_boundary)
|
table_map *spl_pd_boundary)
|
||||||
{
|
{
|
||||||
SplM_opt_info *spl_opt_info= table->spl_opt_info;
|
SplM_opt_info *spl_opt_info= table->spl_opt_info;
|
||||||
@ -1045,7 +1046,7 @@ SplM_plan_info * JOIN_TAB::choose_best_splitting(uint idx,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
table_map last_found= this->table->map;
|
table_map last_found= this->table->map;
|
||||||
for (POSITION *pos= &this->join->positions[idx - 1]; ; pos--)
|
for (const POSITION *pos= &join_positions[idx - 1]; ; pos--)
|
||||||
{
|
{
|
||||||
if (pos->table->table->map & excluded_tables)
|
if (pos->table->table->map & excluded_tables)
|
||||||
continue;
|
continue;
|
||||||
|
@ -7452,6 +7452,7 @@ best_access_path(JOIN *join,
|
|||||||
if (s->table->is_splittable())
|
if (s->table->is_splittable())
|
||||||
spl_plan= s->choose_best_splitting(idx,
|
spl_plan= s->choose_best_splitting(idx,
|
||||||
remaining_tables,
|
remaining_tables,
|
||||||
|
join_positions,
|
||||||
&spl_pd_boundary);
|
&spl_pd_boundary);
|
||||||
|
|
||||||
Json_writer_array trace_paths(thd, "considered_access_paths");
|
Json_writer_array trace_paths(thd, "considered_access_paths");
|
||||||
|
@ -694,6 +694,7 @@ typedef struct st_join_table {
|
|||||||
void add_keyuses_for_splitting();
|
void add_keyuses_for_splitting();
|
||||||
SplM_plan_info *choose_best_splitting(uint idx,
|
SplM_plan_info *choose_best_splitting(uint idx,
|
||||||
table_map remaining_tables,
|
table_map remaining_tables,
|
||||||
|
const POSITION *join_positions,
|
||||||
table_map *spl_pd_boundary);
|
table_map *spl_pd_boundary);
|
||||||
bool fix_splitting(SplM_plan_info *spl_plan, table_map excluded_tables,
|
bool fix_splitting(SplM_plan_info *spl_plan, table_map excluded_tables,
|
||||||
bool is_const_table);
|
bool is_const_table);
|
||||||
|
Reference in New Issue
Block a user