mirror of
https://github.com/MariaDB/server.git
synced 2025-01-20 14:02:32 +01:00
54a713aac5
Evaluate "NULL IN (SELECT ...)" in a special way: Disable pushed-down conditions and their "consequences": = Do full table scans instead of unique_[index_subquery] lookups. = Change appropriate "ref_or_null" accesses to full table scans in subquery's joins. Also cache value of NULL IN (SELECT ...) if the SELECT is not correlated wrt any upper select.
137 lines
3.4 KiB
Text
137 lines
3.4 KiB
Text
--disable_warnings
|
|
drop table if exists t0, t1, t2, t3, t4;
|
|
--enable_warnings
|
|
|
|
#
|
|
# 1. Subquery with GROUP/HAVING
|
|
#
|
|
create table t1 (oref int, grp int, ie int) ;
|
|
insert into t1 (oref, grp, ie) values
|
|
(1, 1, 1),
|
|
(1, 1, 1),
|
|
(1, 2, NULL),
|
|
|
|
(2, 1, 3),
|
|
|
|
(3, 1, 4),
|
|
(3, 2, NULL);
|
|
|
|
# Ok, for
|
|
# select max(ie) from t1 where oref=PARAM group by grp
|
|
# we'll have:
|
|
# 1 -> (1, NULL) matching + NULL
|
|
# 2 -> (3) non-matching
|
|
# 3 -> (3, NULL) non-matching + NULL
|
|
# 4 -> () nothing.
|
|
|
|
create table t2 (oref int, a int);
|
|
insert into t2 values
|
|
(1, 1),
|
|
(2, 2),
|
|
(3, 3),
|
|
(4, NULL),
|
|
(2, NULL);
|
|
|
|
# true, false, null, false, null
|
|
select a, oref, a in (select max(ie)
|
|
from t1 where oref=t2.oref group by grp) from t2;
|
|
|
|
# This must have a trigcond
|
|
explain extended
|
|
select a, oref, a in (select max(ie)
|
|
from t1 where oref=t2.oref group by grp) from t2;
|
|
|
|
# This must not have a trigcond:
|
|
explain extended
|
|
select a, oref from t2
|
|
where a in (select max(ie) from t1 where oref=t2.oref group by grp);
|
|
|
|
|
|
# Non-correlated subquery, 2 NULL evaluations
|
|
create table t3 (a int);
|
|
insert into t3 values (NULL), (NULL);
|
|
flush status;
|
|
select a in (select max(ie) from t1 where oref=4 group by grp) from t3;
|
|
show status like 'Handler_read_rnd_next';
|
|
select ' ^ This must show 11' Z;
|
|
|
|
# This must show trigcond:
|
|
explain extended select a in (select max(ie) from t1 where oref=4 group by grp) from t3;
|
|
|
|
drop table t1, t2, t3;
|
|
|
|
#
|
|
# 2. Subquery handled with 'index_subquery':
|
|
#
|
|
create table t1 (a int, oref int, key(a));
|
|
insert into t1 values
|
|
(1, 1),
|
|
(1, NULL),
|
|
(2, 3),
|
|
(2, NULL),
|
|
(3, NULL);
|
|
|
|
create table t2 (a int, oref int);
|
|
insert into t2 values (1, 1), (2,2), (NULL, 3), (NULL, 4);
|
|
|
|
select oref, a, a in (select a from t1 where oref=t2.oref) Z from t2;
|
|
|
|
# The next explain shows "using index" but that is just incorrect display
|
|
# (there is a bug filed about this).
|
|
explain extended
|
|
select oref, a, a in (select a from t1 where oref=t2.oref) Z from t2;
|
|
|
|
flush status;
|
|
select oref, a from t2 where a in (select a from t1 where oref=t2.oref);
|
|
# This will only show access to t2:
|
|
show status like '%Handler_read_rnd_next';
|
|
|
|
# Check that repeated NULL-scans are not cached (subq. is not correlated):
|
|
delete from t2;
|
|
insert into t2 values (NULL, 0),(NULL, 0), (NULL, 0), (NULL, 0);
|
|
|
|
flush status;
|
|
select oref, a, a in (select a from t1 where oref=t2.oref) Z from t2;
|
|
show status like '%Handler_read%';
|
|
select 'No key lookups, seq reads: 29= 5 reads from t2 + 4 * 6 reads from t1.' Z;
|
|
|
|
drop table t1, t2;
|
|
|
|
#
|
|
# 3. Subquery handled with 'unique_index_subquery':
|
|
#
|
|
create table t1 (a int, b int, primary key (a));
|
|
insert into t1 values (1,1), (3,1),(100,1);
|
|
|
|
create table t2 (a int, b int);
|
|
insert into t2 values (1,1),(2,1),(NULL,1),(NULL,0);
|
|
|
|
select a,b, a in (select a from t1 where t1.b = t2.b) Z from t2 ;
|
|
|
|
drop table t1, t2;
|
|
|
|
#
|
|
# 4. Subquery that is a join, with ref access
|
|
#
|
|
create table t1 (a int, b int, key(a));
|
|
insert into t1 values
|
|
(0,0),(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9);
|
|
|
|
create table t2 like t1;
|
|
insert into t2 select * from t1;
|
|
update t2 set b=1;
|
|
|
|
create table t3 (a int, oref int);
|
|
insert into t3 values (1, 1), (NULL,1), (NULL,0);
|
|
select a, oref,
|
|
t3.a in (select t1.a from t1, t2 where t1.b=t2.a and t2.b=t3.oref) Z
|
|
from t3;
|
|
|
|
# This must have trigcond in WHERE and HAVING:
|
|
explain extended
|
|
select a, oref,
|
|
t3.a in (select t1.a from t1, t2 where t1.b=t2.a and t2.b=t3.oref) Z
|
|
from t3;
|
|
|
|
drop table t1, t2, t3;
|
|
|