MDEV-21683 Server crashes in get_quick_keys with not_null_range_scan
ANding of the range built from inferred NOT NULL conditions and the range built from other conditions used in WHERE/ON clauses may produce an IMPOSSIBLE range. The code of MDEV-15777 did not take into account this possibility.
This commit is contained in:
parent
83e75b39b3
commit
41541a7c48
@ -3116,7 +3116,6 @@ drop table t1,ten,t2;
|
|||||||
#
|
#
|
||||||
# MDEV-15777: Use inferred IS NOT NULL predicates in the range optimizer
|
# MDEV-15777: Use inferred IS NOT NULL predicates in the range optimizer
|
||||||
#
|
#
|
||||||
set @save_optimizer_switch= @@optimizer_switch;
|
|
||||||
set @@optimizer_switch='not_null_range_scan=on';
|
set @@optimizer_switch='not_null_range_scan=on';
|
||||||
create table ten(a int);
|
create table ten(a int);
|
||||||
insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
||||||
@ -3404,6 +3403,25 @@ drop table t1,t2;
|
|||||||
drop table ten,one_k;
|
drop table ten,one_k;
|
||||||
set @@optimizer_switch= @save_optimizer_switch;
|
set @@optimizer_switch= @save_optimizer_switch;
|
||||||
#
|
#
|
||||||
|
# MDEV-21683: ANDing of the range from inferred NOT NULL condition and
|
||||||
|
# the range from other conditions produces IMPOSSIBLE range
|
||||||
|
#
|
||||||
|
SET @save_optimizer_switch= @@optimizer_switch;
|
||||||
|
CREATE TABLE t1 (a INT, KEY(a));
|
||||||
|
INSERT INTO t1 VALUES (8),(9);
|
||||||
|
CREATE TABLE t2 (pk INT, b INT, PRIMARY KEY(pk));
|
||||||
|
INSERT INTO t2 VALUES (1,1),(2,2);
|
||||||
|
SET optimizer_switch = 'not_null_range_scan=on';
|
||||||
|
EXPLAIN EXTENDED SELECT * FROM t1 LEFT JOIN t2 ON a = pk WHERE b >= 0 AND pk IS NULL;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select NULL AS `a`,0 AS `pk`,NULL AS `b` from `test`.`t1` join `test`.`t2` where 0
|
||||||
|
SELECT * FROM t1 LEFT JOIN t2 ON a = pk WHERE b >= 0 AND pk IS NULL;
|
||||||
|
a pk b
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
SET @@optimizer_switch= @save_optimizer_switch;
|
||||||
|
#
|
||||||
# End of 10.5 tests
|
# End of 10.5 tests
|
||||||
#
|
#
|
||||||
set global innodb_stats_persistent= @innodb_stats_persistent_save;
|
set global innodb_stats_persistent= @innodb_stats_persistent_save;
|
||||||
|
@ -2106,7 +2106,6 @@ drop table t1,ten,t2;
|
|||||||
--echo # MDEV-15777: Use inferred IS NOT NULL predicates in the range optimizer
|
--echo # MDEV-15777: Use inferred IS NOT NULL predicates in the range optimizer
|
||||||
--echo #
|
--echo #
|
||||||
|
|
||||||
set @save_optimizer_switch= @@optimizer_switch;
|
|
||||||
set @@optimizer_switch='not_null_range_scan=on';
|
set @@optimizer_switch='not_null_range_scan=on';
|
||||||
create table ten(a int);
|
create table ten(a int);
|
||||||
insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
||||||
@ -2280,6 +2279,29 @@ drop table t1,t2;
|
|||||||
drop table ten,one_k;
|
drop table ten,one_k;
|
||||||
set @@optimizer_switch= @save_optimizer_switch;
|
set @@optimizer_switch= @save_optimizer_switch;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-21683: ANDing of the range from inferred NOT NULL condition and
|
||||||
|
--echo # the range from other conditions produces IMPOSSIBLE range
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SET @save_optimizer_switch= @@optimizer_switch;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT, KEY(a));
|
||||||
|
INSERT INTO t1 VALUES (8),(9);
|
||||||
|
|
||||||
|
CREATE TABLE t2 (pk INT, b INT, PRIMARY KEY(pk));
|
||||||
|
INSERT INTO t2 VALUES (1,1),(2,2);
|
||||||
|
|
||||||
|
SET optimizer_switch = 'not_null_range_scan=on';
|
||||||
|
let $q=
|
||||||
|
SELECT * FROM t1 LEFT JOIN t2 ON a = pk WHERE b >= 0 AND pk IS NULL;
|
||||||
|
eval EXPLAIN EXTENDED $q;
|
||||||
|
eval $q;
|
||||||
|
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
|
SET @@optimizer_switch= @save_optimizer_switch;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.5 tests
|
--echo # End of 10.5 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -3113,7 +3113,6 @@ drop table t1,ten,t2;
|
|||||||
#
|
#
|
||||||
# MDEV-15777: Use inferred IS NOT NULL predicates in the range optimizer
|
# MDEV-15777: Use inferred IS NOT NULL predicates in the range optimizer
|
||||||
#
|
#
|
||||||
set @save_optimizer_switch= @@optimizer_switch;
|
|
||||||
set @@optimizer_switch='not_null_range_scan=on';
|
set @@optimizer_switch='not_null_range_scan=on';
|
||||||
create table ten(a int);
|
create table ten(a int);
|
||||||
insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
||||||
@ -3401,6 +3400,25 @@ drop table t1,t2;
|
|||||||
drop table ten,one_k;
|
drop table ten,one_k;
|
||||||
set @@optimizer_switch= @save_optimizer_switch;
|
set @@optimizer_switch= @save_optimizer_switch;
|
||||||
#
|
#
|
||||||
|
# MDEV-21683: ANDing of the range from inferred NOT NULL condition and
|
||||||
|
# the range from other conditions produces IMPOSSIBLE range
|
||||||
|
#
|
||||||
|
SET @save_optimizer_switch= @@optimizer_switch;
|
||||||
|
CREATE TABLE t1 (a INT, KEY(a));
|
||||||
|
INSERT INTO t1 VALUES (8),(9);
|
||||||
|
CREATE TABLE t2 (pk INT, b INT, PRIMARY KEY(pk));
|
||||||
|
INSERT INTO t2 VALUES (1,1),(2,2);
|
||||||
|
SET optimizer_switch = 'not_null_range_scan=on';
|
||||||
|
EXPLAIN EXTENDED SELECT * FROM t1 LEFT JOIN t2 ON a = pk WHERE b >= 0 AND pk IS NULL;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select NULL AS `a`,0 AS `pk`,NULL AS `b` from `test`.`t1` join `test`.`t2` where 0
|
||||||
|
SELECT * FROM t1 LEFT JOIN t2 ON a = pk WHERE b >= 0 AND pk IS NULL;
|
||||||
|
a pk b
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
SET @@optimizer_switch= @save_optimizer_switch;
|
||||||
|
#
|
||||||
# End of 10.5 tests
|
# End of 10.5 tests
|
||||||
#
|
#
|
||||||
set global innodb_stats_persistent= @innodb_stats_persistent_save;
|
set global innodb_stats_persistent= @innodb_stats_persistent_save;
|
||||||
|
@ -2838,12 +2838,15 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
|
|||||||
if (notnull_cond)
|
if (notnull_cond)
|
||||||
notnull_cond_tree= notnull_cond->get_mm_tree(¶m, ¬null_cond);
|
notnull_cond_tree= notnull_cond->get_mm_tree(¶m, ¬null_cond);
|
||||||
|
|
||||||
if (cond)
|
if (cond || notnull_cond_tree)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
Json_writer_array trace_range_summary(thd,
|
Json_writer_array trace_range_summary(thd,
|
||||||
"setup_range_conditions");
|
"setup_range_conditions");
|
||||||
|
if (cond)
|
||||||
tree= cond->get_mm_tree(¶m, &cond);
|
tree= cond->get_mm_tree(¶m, &cond);
|
||||||
|
if (notnull_cond_tree)
|
||||||
|
tree= tree_and(¶m, tree, notnull_cond_tree);
|
||||||
}
|
}
|
||||||
if (tree)
|
if (tree)
|
||||||
{
|
{
|
||||||
@ -2865,7 +2868,6 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tree= tree_and(¶m, tree, notnull_cond_tree);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Try to construct a QUICK_GROUP_MIN_MAX_SELECT.
|
Try to construct a QUICK_GROUP_MIN_MAX_SELECT.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user