mariadb/mysql-test/t/table_elim.test

221 lines
6.9 KiB
Text
Raw Normal View History

#
# Table elimination (MWL#17) tests
#
--disable_warnings
drop table if exists t0, t1, t2, t3;
drop view if exists v1, v2;
--enable_warnings
create table t1 (a int);
insert into t1 values (0),(1),(2),(3);
create table t0 as select * from t1;
create table t2 (a int primary key, b int)
as select a, a as b from t1 where a in (1,2);
create table t3 (a int primary key, b int)
as select a, a as b from t1 where a in (1,3);
--echo # This will be eliminated:
explain select t1.a from t1 left join t2 on t2.a=t1.a;
explain extended select t1.a from t1 left join t2 on t2.a=t1.a;
select t1.a from t1 left join t2 on t2.a=t1.a;
--echo # This will not be eliminated as t2.b is in in select list:
explain select * from t1 left join t2 on t2.a=t1.a;
--echo # This will not be eliminated as t2.b is in in order list:
explain select t1.a from t1 left join t2 on t2.a=t1.a order by t2.b;
--echo # This will not be eliminated as t2.b is in group list:
explain select t1.a from t1 left join t2 on t2.a=t1.a group by t2.b;
--echo # This will not be eliminated as t2.b is in the WHERE
explain select t1.a from t1 left join t2 on t2.a=t1.a where t2.b < 3 or t2.b is null;
--echo # Elimination of multiple tables:
explain select t1.a from t1 left join (t2 join t3) on t2.a=t1.a and t3.a=t1.a;
--echo # Elimination of multiple tables (2):
explain select t1.a from t1 left join (t2 join t3 on t2.b=t3.b) on t2.a=t1.a and t3.a=t1.a;
--echo # Elimination when done within an outer join nest:
explain extended
select t0.*
from
t0 left join (t1 left join (t2 join t3 on t2.b=t3.b) on t2.a=t1.a and
t3.a=t1.a) on t0.a=t1.a;
MWL#17: Table elimination - Make elimination work with aggregate functions. The problem was that aggregate functions reported all table bits in used_tables(), and that prevented table elimination. Fixed by making aggregate functions return more correct value from used_tables(). mysql-test/r/ps_11bugs.result: MWL#17: Table elimination - Update test results. The difference is because of Item_ref change: outer references to constants are now recognized as constants, too. mysql-test/r/subselect.result: - Update test results. The difference is because of Item_ref change: outer references to constants are now recognized as constants, too. mysql-test/r/table_elim.result: MWL#17: Table elimination - Check that elimination works in presense of aggreagate functions mysql-test/t/table_elim.test: MWL#17: Table elimination - Check that elimination works in presense of aggreagate functions sql/item.h: MWL#17: Table elimination - Add Item_ref::const_item() which calls (*ref)->const_item(). Before this diff Item_ref used the default implementation of const_item(){ return used_tables()==0; }. This is no longer true, as COUNT(*) now has used_tables()==0 but const_item()==FALSE. sql/item_sum.cc: MWL#17: Table elimination - Make Item_sum() and it descendants not to return all bits in used_tables(). This is needed because otherwise table elimination can't work in presense of aggregate functions - COUNT(*) now has used_tables()==0 and const_item()==FALSE. Had to change Item_ref::const_item() to account for this. sql/item_sum.h: MWL#17: Table elimination - Add comments
2009-06-09 23:11:33 +02:00
--echo # Elimination with aggregate functions
explain select count(*) from t1 left join t2 on t2.a=t1.a;
explain select count(1) from t1 left join t2 on t2.a=t1.a;
explain select count(1) from t1 left join t2 on t2.a=t1.a group by t1.a;
--echo This must not use elimination:
explain select count(1) from t1 left join t2 on t2.a=t1.a group by t2.a;
drop table t0, t1, t2, t3;
# This will stand for elim_facts
create table t0 ( id integer, primary key (id));
# Attribute1, non-versioned
create table t1 (
id integer,
attr1 integer,
primary key (id),
key (attr1)
);
# Attribute2, time-versioned
create table t2 (
id integer,
attr2 integer,
fromdate date,
primary key (id, fromdate),
key (attr2,fromdate)
);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
insert into t0 select A.id + 10*B.id from t0 A, t0 B where B.id > 0;
insert into t1 select id, id from t0;
insert into t2 select id, id, date_add('2009-06-22', interval id day) from t0;
insert into t2 select id, id+1, date_add('2008-06-22', interval id day) from t0;
create view v1 as
select
F.id, A1.attr1, A2.attr2
from
t0 F
left join t1 A1 on A1.id=F.id
left join t2 A2 on A2.id=F.id and
A2.fromdate=(select MAX(fromdate) from
t2 where id=A2.id);
create view v2 as
select
F.id, A1.attr1, A2.attr2
from
t0 F
left join t1 A1 on A1.id=F.id
left join t2 A2 on A2.id=F.id and
A2.fromdate=(select MAX(fromdate) from
t2 where id=F.id);
--echo This should use one table:
explain select id from v1 where id=2;
--echo This should use one table:
explain extended select id from v1 where id in (1,2,3,4);
--echo This should use facts and A1 tables:
explain extended select id from v1 where attr1 between 12 and 14;
--echo This should use facts, A2 and its subquery:
explain extended select id from v1 where attr2 between 12 and 14;
# Repeat for v2:
--echo This should use one table:
explain select id from v2 where id=2;
--echo This should use one table:
explain extended select id from v2 where id in (1,2,3,4);
--echo This should use facts and A1 tables:
explain extended select id from v2 where attr1 between 12 and 14;
--echo This should use facts, A2 and its subquery:
explain extended select id from v2 where attr2 between 12 and 14;
drop view v1, v2;
drop table t0, t1, t2;
#
# Tests for the code that uses t.keypartX=func(t.keypartY) equalities to
# make table elimination inferences
#
create table t1 (a int);
insert into t1 values (0),(1),(2),(3);
create table t2 (pk1 int, pk2 int, pk3 int, col int, primary key(pk1, pk2, pk3));
insert into t2 select a,a,a,a from t1;
--echo This must use only t1:
explain select t1.* from t1 left join t2 on t2.pk1=t1.a and
t2.pk2=t2.pk1+1 and
t2.pk3=t2.pk2+1;
--echo This must use only t1:
explain select t1.* from t1 left join t2 on t2.pk1=t1.a and
t2.pk3=t2.pk1+1 and
t2.pk2=t2.pk3+1;
--echo This must use both:
explain select t1.* from t1 left join t2 on t2.pk1=t1.a and
t2.pk3=t2.pk1+1 and
t2.pk2=t2.pk3+t2.col;
--echo This must use only t1:
explain select t1.* from t1 left join t2 on t2.pk2=t1.a and
t2.pk1=t2.pk2+1 and
t2.pk3=t2.pk1;
drop table t1, t2;
#
# Check that equality propagation is taken into account
#
create table t1 (pk int primary key, col int);
insert into t1 values (1,1),(2,2);
create table t2 like t1;
insert into t2 select * from t1;
create table t3 like t1;
insert into t3 select * from t1;
explain
select t1.* from t1 left join ( t2 left join t3 on t3.pk=t2.col) on t2.col=t1.col;
explain
select t1.*, t2.* from t1 left join (t2 left join t3 on t3.pk=t2.col) on t2.pk=t1.col;
drop table t1, t2, t3;
--echo #
--echo # Check things that look like functional dependencies but really are not
--echo #
create table t1 (a char(10) character set latin1 collate latin1_general_ci primary key);
insert into t1 values ('foo');
insert into t1 values ('bar');
create table t2 (a char(10) character set latin1 collate latin1_general_cs primary key);
insert into t2 values ('foo');
insert into t2 values ('FOO');
-- echo this must not use table elimination:
explain select t1.* from t1 left join t2 on t2.a='foo' collate latin1_general_ci;
-- echo this must not use table elimination:
explain select t1.* from t1 left join t2 on t2.a=t1.a collate latin1_general_ci;
drop table t1,t2;
create table t1 (a int primary key);
insert into t1 values (1),(2);
create table t2 (a char(10) primary key);
insert into t2 values ('1'),('1.0');
-- echo this must not use table elimination:
explain select t1.* from t1 left join t2 on t2.a=1;
-- echo this must not use table elimination:
explain select t1.* from t1 left join t2 on t2.a=t1.a;
drop table t1, t2;
# partial unique keys do not work at the moment, although they are able to
# provide one-match guarantees:
create table t1 (a char(10) primary key);
insert into t1 values ('foo'),('bar');
create table t2 (a char(10), unique key(a(2)));
insert into t2 values ('foo'),('bar');
explain select t1.* from t1 left join t2 on t2.a=t1.a;
drop table t1, t2;