Commit a896bebf authored by WayneXia's avatar WayneXia

MDEV-18844 Implement EXCEPT ALL and INTERSECT ALL operations

parent afe969ba
...@@ -54,7 +54,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -54,7 +54,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used 3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNION RESULT <union1,4> ALL NULL NULL NULL NULL NULL NULL NULL UNION RESULT <union1,4> ALL NULL NULL NULL NULL NULL NULL
Warnings: Warnings:
Note 1003 /* select#1 */ select 1 AS `1` union /* select#4 */ select `__4`.`1` AS `1` from (/* select#2 */ select 1 AS `1` union all /* select#3 */ select 1 AS `1`) `__4` Note 1003 /* select#1 */ select 1 AS `1` union /* select#4 */ select `__4`.`1` AS `1` from (/* select#2 */ select 1 AS `1` union /* select#3 */ select 1 AS `1`) `__4`
select 1 union select 1 union all select 1; select 1 union select 1 union all select 1;
1 1
1 1
......
...@@ -507,8 +507,6 @@ select 1 as a from dual union all select 1 from dual; ...@@ -507,8 +507,6 @@ select 1 as a from dual union all select 1 from dual;
a a
1 1
1 1
select 1 from dual except all select 1 from dual;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'all select 1 from dual' at line 1
create table t1 (a int, b blob, a1 int, b1 blob) engine=MyISAM; create table t1 (a int, b blob, a1 int, b1 blob) engine=MyISAM;
create table t2 (c int, d blob, c1 int, d1 blob) engine=MyISAM; create table t2 (c int, d blob, c1 int, d1 blob) engine=MyISAM;
insert into t1 values (1,"ddd", 1, "sdfrrwwww"),(2, "fgh", 2, "dffggtt"); insert into t1 values (1,"ddd", 1, "sdfrrwwww"),(2, "fgh", 2, "dffggtt");
......
...@@ -67,7 +67,6 @@ select 1 from dual ORDER BY 1 except select 1 from dual; ...@@ -67,7 +67,6 @@ select 1 from dual ORDER BY 1 except select 1 from dual;
select 1 as a from dual union all select 1 from dual; select 1 as a from dual union all select 1 from dual;
--error ER_PARSE_ERROR --error ER_PARSE_ERROR
select 1 from dual except all select 1 from dual;
create table t1 (a int, b blob, a1 int, b1 blob) engine=MyISAM; create table t1 (a int, b blob, a1 int, b1 blob) engine=MyISAM;
......
create table t1 (a int, b int) engine=MyISAM;
create table t2 (c int, d int) engine=MyISAM;
insert into t1 values (1,1),(2,2),(3,3),(2,2),(4,4),(4,4),(4,4);
insert into t2 values (1,1),(1,1),(1,1),(2,2),(3,3),(3,3),(5,5);
select * from t1 except select * from t2;
a b
4 4
select * from t1 except all select * from t2;
a b
4 4
2 2
4 4
4 4
select * from t1 except all select c+1,d+1 from t2;
a b
1 1
4 4
(select * from t1) except all (select * from t2);
a b
4 4
2 2
4 4
4 4
select * from ((select * from t1) except all (select * from t2)) a;
a b
4 4
2 2
4 4
4 4
select * from ((select a from t1) except all (select c from t2)) a;
a
4
2
4
4
select * from t1 except all select * from t1 union all select * from t1 union all select * from t1 except select * from t2;
a b
4 4
select * from t1 except all select * from t1 union all select * from t1 union all select * from t1 except all select * from t2;
a b
4 4
2 2
4 4
4 4
4 4
4 4
4 4
2 2
2 2
select * from (select * from t1 except all select * from t2) q1 except all select * from (select * from t1 except all select * from t2) q2;
a b
EXPLAIN select * from t1 except all select * from t2;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 7
2 EXCEPT t2 ALL NULL NULL NULL NULL 7
NULL EXCEPT RESULT <except1,2> ALL NULL NULL NULL NULL NULL
EXPLAIN format=json select * from t1 except all select * from t2;
EXPLAIN
{
"query_block": {
"union_result": {
"table_name": "<except1,2>",
"access_type": "ALL",
"query_specifications": [
{
"query_block": {
"select_id": 1,
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 7,
"filtered": 100
}
}
},
{
"query_block": {
"select_id": 2,
"operation": "EXCEPT",
"table": {
"table_name": "t2",
"access_type": "ALL",
"rows": 7,
"filtered": 100
}
}
}
]
}
}
}
EXPLAIN extended (select * from t1) except all (select * from t2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 7 100.00
2 EXCEPT t2 ALL NULL NULL NULL NULL 7 100.00
NULL EXCEPT RESULT <except1,2> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 (/* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`) except all (/* select#2 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2`)
EXPLAIN extended select * from ((select * from t1) except all (select * from t2)) a;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 7 100.00
2 DERIVED t1 ALL NULL NULL NULL NULL 7 100.00
3 EXCEPT t2 ALL NULL NULL NULL NULL 7 100.00
NULL EXCEPT RESULT <except2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 /* select#1 */ select `a`.`a` AS `a`,`a`.`b` AS `b` from (/* select#2 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` except all (/* select#3 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2`)) `a`
ANALYZE format=json select * from ((select a,b from t1) except all (select c,d from t2)) a;
ANALYZE
{
"query_block": {
"select_id": 1,
"r_loops": 1,
"r_total_time_ms": "REPLACED",
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"r_loops": 1,
"rows": 7,
"r_rows": 4,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100,
"materialized": {
"query_block": {
"union_result": {
"table_name": "<except2,3>",
"access_type": "ALL",
"r_loops": 1,
"r_rows": 4,
"query_specifications": [
{
"query_block": {
"select_id": 2,
"r_loops": 1,
"r_total_time_ms": "REPLACED",
"table": {
"table_name": "t1",
"access_type": "ALL",
"r_loops": 1,
"rows": 7,
"r_rows": 7,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100
}
}
},
{
"query_block": {
"select_id": 3,
"operation": "EXCEPT",
"r_loops": 1,
"r_total_time_ms": "REPLACED",
"table": {
"table_name": "t2",
"access_type": "ALL",
"r_loops": 1,
"rows": 7,
"r_rows": 7,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100
}
}
}
]
}
}
}
}
}
}
ANALYZE format=json select * from ((select a from t1) except all (select c from t2)) a;
ANALYZE
{
"query_block": {
"select_id": 1,
"r_loops": 1,
"r_total_time_ms": "REPLACED",
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"r_loops": 1,
"rows": 7,
"r_rows": 4,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100,
"materialized": {
"query_block": {
"union_result": {
"table_name": "<except2,3>",
"access_type": "ALL",
"r_loops": 1,
"r_rows": 4,
"query_specifications": [
{
"query_block": {
"select_id": 2,
"r_loops": 1,
"r_total_time_ms": "REPLACED",
"table": {
"table_name": "t1",
"access_type": "ALL",
"r_loops": 1,
"rows": 7,
"r_rows": 7,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100
}
}
},
{
"query_block": {
"select_id": 3,
"operation": "EXCEPT",
"r_loops": 1,
"r_total_time_ms": "REPLACED",
"table": {
"table_name": "t2",
"access_type": "ALL",
"r_loops": 1,
"rows": 7,
"r_rows": 7,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100
}
}
}
]
}
}
}
}
}
}
select * from ((select a from t1) except all (select c from t2)) a;
a
4
2
4
4
prepare stmt from "(select a,b from t1) except all (select c,d from t2)";
execute stmt;
a b
4 4
2 2
4 4
4 4
execute stmt;
a b
4 4
2 2
4 4
4 4
prepare stmt from "select * from ((select a,b from t1) except all (select c,d from t2)) a";
execute stmt;
a b
4 4
2 2
4 4
4 4
execute stmt;
a b
4 4
2 2
4 4
4 4
drop tables t1,t2;
create table t1 (a int, b int) engine=MyISAM;
create table t2 (c int, d int) engine=MyISAM;
create table t3 (e int, f int) engine=MyISAM;
create table t4 (g int, h int) engine=MyISAM;
insert into t1 values (1,1),(2,2),(2,2);
insert into t2 values (2,2),(3,3);
insert into t3 values (4,4),(5,5),(4,4);
insert into t4 values (4,4),(7,7),(4,4);
(select a,b,e,f from t1,t3) except all (select c,d,g,h from t2,t4);
a b e f
1 1 4 4
2 2 4 4
1 1 5 5
2 2 5 5
1 1 4 4
2 2 4 4
2 2 5 5
select * from ((select a,b,e,f from t1,t3) except all (select c,d,g,h from t2,t4)) t;
a b e f
1 1 4 4
2 2 4 4
1 1 5 5
2 2 5 5
1 1 4 4
2 2 4 4
2 2 5 5
(select * from t1,t3) except all (select * from t2,t4);
a b e f
1 1 4 4
2 2 4 4
1 1 5 5
2 2 5 5
1 1 4 4
2 2 4 4
2 2 5 5
(select a,b,e from t1,t3) except all (select c,d,g from t2,t4);
a b e
1 1 4
2 2 4
1 1 5
2 2 5
1 1 4
2 2 4
2 2 5
EXPLAIN (select a,b,e,f from t1,t3) except all (select c,d,g,h from t2,t4);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
2 EXCEPT t2 ALL NULL NULL NULL NULL 2
2 EXCEPT t4 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
NULL EXCEPT RESULT <except1,2> ALL NULL NULL NULL NULL NULL
EXPLAIN select * from ((select a,b,e,f from t1,t3) except all (select c,d,g,h from t2,t4)) t;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 9
2 DERIVED t1 ALL NULL NULL NULL NULL 3
2 DERIVED t3 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
3 EXCEPT t2 ALL NULL NULL NULL NULL 2
3 EXCEPT t4 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
NULL EXCEPT RESULT <except2,3> ALL NULL NULL NULL NULL NULL
EXPLAIN extended select * from ((select a,b,e,f from t1,t3) except all (select c,d,g,h from t2,t4)) t;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 9 100.00
2 DERIVED t1 ALL NULL NULL NULL NULL 3 100.00
2 DERIVED t3 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join)
3 EXCEPT t2 ALL NULL NULL NULL NULL 2 100.00
3 EXCEPT t4 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join)
NULL EXCEPT RESULT <except2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 /* select#1 */ select `t`.`a` AS `a`,`t`.`b` AS `b`,`t`.`e` AS `e`,`t`.`f` AS `f` from (/* select#2 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t1` join `test`.`t3` except all (/* select#3 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t4`.`g` AS `g`,`test`.`t4`.`h` AS `h` from `test`.`t2` join `test`.`t4`)) `t`
EXPLAIN format=json select * from ((select a,b,e,f from t1,t3) except all (select c,d,g,h from t2,t4)) t;
EXPLAIN
{
"query_block": {
"select_id": 1,
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"rows": 9,
"filtered": 100,
"materialized": {
"query_block": {
"union_result": {
"table_name": "<except2,3>",
"access_type": "ALL",
"query_specifications": [
{
"query_block": {
"select_id": 2,
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 3,
"filtered": 100
},
"block-nl-join": {
"table": {
"table_name": "t3",
"access_type": "ALL",
"rows": 3,
"filtered": 100
},
"buffer_type": "flat",
"buffer_size": "119",
"join_type": "BNL"
}
}
},
{
"query_block": {
"select_id": 3,
"operation": "EXCEPT",
"table": {
"table_name": "t2",
"access_type": "ALL",
"rows": 2,
"filtered": 100
},
"block-nl-join": {
"table": {
"table_name": "t4",
"access_type": "ALL",
"rows": 3,
"filtered": 100
},
"buffer_type": "flat",
"buffer_size": "119",
"join_type": "BNL"
}
}
}
]
}
}
}
}
}
}
ANALYZE format=json (select a,b,e,f from t1,t3) except all (select c,d,g,h from t2,t4);
ANALYZE
{
"query_block": {
"union_result": {
"table_name": "<except1,2>",
"access_type": "ALL",
"r_loops": 1,
"r_rows": 7,
"query_specifications": [
{
"query_block": {
"select_id": 1,
"r_loops": 1,
"r_total_time_ms": "REPLACED",
"table": {
"table_name": "t1",
"access_type": "ALL",
"r_loops": 1,
"rows": 3,
"r_rows": 3,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100
},
"block-nl-join": {
"table": {
"table_name": "t3",
"access_type": "ALL",
"r_loops": 1,
"rows": 3,
"r_rows": 3,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100
},
"buffer_type": "flat",
"buffer_size": "119",
"join_type": "BNL",
"r_filtered": 100
}
}
},
{
"query_block": {
"select_id": 2,
"operation": "EXCEPT",
"r_loops": 1,
"r_total_time_ms": "REPLACED",
"table": {
"table_name": "t2",
"access_type": "ALL",
"r_loops": 1,
"rows": 2,
"r_rows": 2,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100
},
"block-nl-join": {
"table": {
"table_name": "t4",
"access_type": "ALL",
"r_loops": 1,
"rows": 3,
"r_rows": 3,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100
},
"buffer_type": "flat",
"buffer_size": "119",
"join_type": "BNL",
"r_filtered": 100
}
}
}
]
}
}
}
ANALYZE format=json select * from ((select a,b,e,f from t1,t3) except all (select c,d,g,h from t2,t4)) t;
ANALYZE
{
"query_block": {
"select_id": 1,
"r_loops": 1,
"r_total_time_ms": "REPLACED",
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"r_loops": 1,
"rows": 9,
"r_rows": 7,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100,
"materialized": {
"query_block": {
"union_result": {
"table_name": "<except2,3>",
"access_type": "ALL",
"r_loops": 1,
"r_rows": 7,
"query_specifications": [
{
"query_block": {
"select_id": 2,
"r_loops": 1,
"r_total_time_ms": "REPLACED",
"table": {
"table_name": "t1",
"access_type": "ALL",
"r_loops": 1,
"rows": 3,
"r_rows": 3,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100
},
"block-nl-join": {
"table": {
"table_name": "t3",
"access_type": "ALL",
"r_loops": 1,
"rows": 3,
"r_rows": 3,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100
},
"buffer_type": "flat",
"buffer_size": "119",
"join_type": "BNL",
"r_filtered": 100
}
}
},
{
"query_block": {
"select_id": 3,
"operation": "EXCEPT",
"r_loops": 1,
"r_total_time_ms": "REPLACED",
"table": {
"table_name": "t2",
"access_type": "ALL",
"r_loops": 1,
"rows": 2,
"r_rows": 2,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100
},
"block-nl-join": {
"table": {
"table_name": "t4",
"access_type": "ALL",
"r_loops": 1,
"rows": 3,
"r_rows": 3,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100
},
"buffer_type": "flat",
"buffer_size": "119",
"join_type": "BNL",
"r_filtered": 100
}
}
}
]
}
}
}
}
}
}
prepare stmt from "(select a,b,e,f from t1,t3) except all (select c,d,g,h from t2,t4)";
execute stmt;
a b e f
1 1 4 4
2 2 4 4
1 1 5 5
2 2 5 5
1 1 4 4
2 2 4 4
2 2 5 5
execute stmt;
a b e f
1 1 4 4
2 2 4 4
1 1 5 5
2 2 5 5
1 1 4 4
2 2 4 4
2 2 5 5
prepare stmt from "select * from ((select a,b,e,f from t1,t3) except all (select c,d,g,h from t2,t4)) a";
execute stmt;
a b e f
1 1 4 4
2 2 4 4
1 1 5 5
2 2 5 5
1 1 4 4
2 2 4 4
2 2 5 5
execute stmt;
a b e f
1 1 4 4
2 2 4 4
1 1 5 5
2 2 5 5
1 1 4 4
2 2 4 4
2 2 5 5
drop tables t1,t2,t3,t4;
select 1 as a from dual except all select 1 from dual;
a
(select 1 from dual) except all (select 1 from dual);
1
(select 1 from dual into @v) except all (select 1 from dual);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'into @v) except all (select 1 from dual)' at line 1
select 1 from dual ORDER BY 1 except all select 1 from dual;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'except all select 1 from dual' at line 1
select 1 as a from dual union all select 1 from dual;
a
1
1
create table t1 (a int, b blob, a1 int, b1 blob) engine=MyISAM;
create table t2 (c int, d blob, c1 int, d1 blob) engine=MyISAM;
insert into t1 values (1,"ddd", 1, "sdfrrwwww"),(2, "fgh", 2, "dffggtt"),(2, "fgh", 2, "dffggtt");
insert into t2 values (2, "fgh", 2, "dffggtt"),(3, "ffggddd", 3, "dfgg");
(select a,b,b1 from t1) except all (select c,d,d1 from t2);
a b b1
1 ddd sdfrrwwww
2 fgh dffggtt
create table t3 (select a,b,b1 from t1) except all (select c,d,d1 from t2);
show create table t3;
Table Create Table
t3 CREATE TABLE `t3` (
`a` int(11) DEFAULT NULL,
`b` blob DEFAULT NULL,
`b1` blob DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop tables t1,t2,t3;
CREATE TABLE t (i INT);
INSERT INTO t VALUES (1),(2);
SELECT * FROM t WHERE i != ANY ( SELECT 3 EXCEPT ALL SELECT 3 );
i
drop table t;
create table t1 (a int, b int) engine=MyISAM;
create table t2 (c int, d int) engine=MyISAM;
insert into t1 values (1,1),(2,2),(3,3),(2,2),(4,4),(4,4),(4,4);
insert into t2 values (1,1),(1,1),(1,1),(2,2),(3,3),(3,3),(5,5);
select * from t1 except select * from t2;
select * from t1 except all select * from t2;
select * from t1 except all select c+1,d+1 from t2;
(select * from t1) except all (select * from t2);
select * from ((select * from t1) except all (select * from t2)) a;
select * from ((select a from t1) except all (select c from t2)) a;
select * from t1 except all select * from t1 union all select * from t1 union all select * from t1 except select * from t2;
select * from t1 except all select * from t1 union all select * from t1 union all select * from t1 except all select * from t2;
select * from (select * from t1 except all select * from t2) q1 except all select * from (select * from t1 except all select * from t2) q2;
EXPLAIN select * from t1 except all select * from t2;
EXPLAIN format=json select * from t1 except all select * from t2;
EXPLAIN extended (select * from t1) except all (select * from t2);
EXPLAIN extended select * from ((select * from t1) except all (select * from t2)) a;
--source include/analyze-format.inc
ANALYZE format=json select * from ((select a,b from t1) except all (select c,d from t2)) a;
--source include/analyze-format.inc
ANALYZE format=json select * from ((select a from t1) except all (select c from t2)) a;
select * from ((select a from t1) except all (select c from t2)) a;
prepare stmt from "(select a,b from t1) except all (select c,d from t2)";
execute stmt;
execute stmt;
prepare stmt from "select * from ((select a,b from t1) except all (select c,d from t2)) a";
execute stmt;
execute stmt;
drop tables t1,t2;
create table t1 (a int, b int) engine=MyISAM;
create table t2 (c int, d int) engine=MyISAM;
create table t3 (e int, f int) engine=MyISAM;
create table t4 (g int, h int) engine=MyISAM;
insert into t1 values (1,1),(2,2),(2,2);
insert into t2 values (2,2),(3,3);
insert into t3 values (4,4),(5,5),(4,4);
insert into t4 values (4,4),(7,7),(4,4);
(select a,b,e,f from t1,t3) except all (select c,d,g,h from t2,t4);
select * from ((select a,b,e,f from t1,t3) except all (select c,d,g,h from t2,t4)) t;
(select * from t1,t3) except all (select * from t2,t4);
(select a,b,e from t1,t3) except all (select c,d,g from t2,t4);
EXPLAIN (select a,b,e,f from t1,t3) except all (select c,d,g,h from t2,t4);
EXPLAIN select * from ((select a,b,e,f from t1,t3) except all (select c,d,g,h from t2,t4)) t;
EXPLAIN extended select * from ((select a,b,e,f from t1,t3) except all (select c,d,g,h from t2,t4)) t;
EXPLAIN format=json select * from ((select a,b,e,f from t1,t3) except all (select c,d,g,h from t2,t4)) t;
--source include/analyze-format.inc
ANALYZE format=json (select a,b,e,f from t1,t3) except all (select c,d,g,h from t2,t4);
--source include/analyze-format.inc
ANALYZE format=json select * from ((select a,b,e,f from t1,t3) except all (select c,d,g,h from t2,t4)) t;
prepare stmt from "(select a,b,e,f from t1,t3) except all (select c,d,g,h from t2,t4)";
execute stmt;
execute stmt;
prepare stmt from "select * from ((select a,b,e,f from t1,t3) except all (select c,d,g,h from t2,t4)) a";
execute stmt;
execute stmt;
drop tables t1,t2,t3,t4;
select 1 as a from dual except all select 1 from dual;
(select 1 from dual) except all (select 1 from dual);
--error ER_PARSE_ERROR
(select 1 from dual into @v) except all (select 1 from dual);
--error ER_PARSE_ERROR
select 1 from dual ORDER BY 1 except all select 1 from dual;
select 1 as a from dual union all select 1 from dual;
create table t1 (a int, b blob, a1 int, b1 blob) engine=MyISAM;
create table t2 (c int, d blob, c1 int, d1 blob) engine=MyISAM;
insert into t1 values (1,"ddd", 1, "sdfrrwwww"),(2, "fgh", 2, "dffggtt"),(2, "fgh", 2, "dffggtt");
insert into t2 values (2, "fgh", 2, "dffggtt"),(3, "ffggddd", 3, "dfgg");
(select a,b,b1 from t1) except all (select c,d,d1 from t2);
# make sure that blob is used
create table t3 (select a,b,b1 from t1) except all (select c,d,d1 from t2);
show create table t3;
drop tables t1,t2,t3;
CREATE TABLE t (i INT);
INSERT INTO t VALUES (1),(2);
SELECT * FROM t WHERE i != ANY ( SELECT 3 EXCEPT ALL SELECT 3 );
drop table t;
\ No newline at end of file
...@@ -504,8 +504,6 @@ select 1 as a from dual union all select 1 from dual; ...@@ -504,8 +504,6 @@ select 1 as a from dual union all select 1 from dual;
a a
1 1
1 1
select 1 from dual intersect all select 1 from dual;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'all select 1 from dual' at line 1
create table t1 (a int, b blob, a1 int, b1 blob); create table t1 (a int, b blob, a1 int, b1 blob);
create table t2 (c int, d blob, c1 int, d1 blob); create table t2 (c int, d blob, c1 int, d1 blob);
insert into t1 values (1,"ddd", 1, "sdfrrwwww"),(2, "fgh", 2, "dffggtt"); insert into t1 values (1,"ddd", 1, "sdfrrwwww"),(2, "fgh", 2, "dffggtt");
...@@ -607,22 +605,6 @@ NULL INTERSECT RESULT <intersect2,3> ALL NULL NULL NULL NULL NULL NULL ...@@ -607,22 +605,6 @@ NULL INTERSECT RESULT <intersect2,3> ALL NULL NULL NULL NULL NULL NULL
NULL UNION RESULT <union1,5,4> ALL NULL NULL NULL NULL NULL NULL NULL UNION RESULT <union1,5,4> ALL NULL NULL NULL NULL NULL NULL
Warnings: Warnings:
Note 1003 (/* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`) union /* select#5 */ select `__5`.`c` AS `c`,`__5`.`d` AS `d` from ((/* select#2 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2`) intersect (/* select#3 */ select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3`)) `__5` union (/* select#4 */ select 4 AS `4`,4 AS `4`) Note 1003 (/* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`) union /* select#5 */ select `__5`.`c` AS `c`,`__5`.`d` AS `d` from ((/* select#2 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2`) intersect (/* select#3 */ select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3`)) `__5` union (/* select#4 */ select 4 AS `4`,4 AS `4`)
set SQL_MODE=ORACLE;
(select a,b from t1) union (select c,d from t2) intersect (select e,f from t3) union (select 4,4);
a b
3 3
4 4
explain extended
(select a,b from t1) union (select c,d from t2) intersect (select e,f from t3) union (select 4,4);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
2 UNION t2 ALL NULL NULL NULL NULL 2 100.00
3 INTERSECT t3 ALL NULL NULL NULL NULL 2 100.00
4 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNIT RESULT <unit1,2,3,4> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 (/* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1") union (/* select#2 */ select "test"."t2"."c" AS "c","test"."t2"."d" AS "d" from "test"."t2") intersect (/* select#3 */ select "test"."t3"."e" AS "e","test"."t3"."f" AS "f" from "test"."t3") union (/* select#4 */ select 4 AS "4",4 AS "4")
set SQL_MODE=default;
(select e,f from t3) intersect (select c,d from t2) union (select a,b from t1) union (select 4,4); (select e,f from t3) intersect (select c,d from t2) union (select a,b from t1) union (select 4,4);
e f e f
3 3 3 3
...@@ -639,24 +621,6 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -639,24 +621,6 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
NULL UNIT RESULT <unit1,2,3,4> ALL NULL NULL NULL NULL NULL NULL NULL UNIT RESULT <unit1,2,3,4> ALL NULL NULL NULL NULL NULL NULL
Warnings: Warnings:
Note 1003 (/* select#1 */ select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3`) intersect (/* select#2 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2`) union (/* select#3 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`) union (/* select#4 */ select 4 AS `4`,4 AS `4`) Note 1003 (/* select#1 */ select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3`) intersect (/* select#2 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2`) union (/* select#3 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`) union (/* select#4 */ select 4 AS `4`,4 AS `4`)
set SQL_MODE=ORACLE;
(select e,f from t3) intersect (select c,d from t2) union (select a,b from t1) union (select 4,4);
e f
3 3
4 4
5 5
6 6
explain extended
(select e,f from t3) intersect (select c,d from t2) union (select a,b from t1) union (select 4,4);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 2 100.00
2 INTERSECT t2 ALL NULL NULL NULL NULL 2 100.00
3 UNION t1 ALL NULL NULL NULL NULL 2 100.00
4 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNIT RESULT <unit1,2,3,4> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 (/* select#1 */ select "test"."t3"."e" AS "e","test"."t3"."f" AS "f" from "test"."t3") intersect (/* select#2 */ select "test"."t2"."c" AS "c","test"."t2"."d" AS "d" from "test"."t2") union (/* select#3 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1") union (/* select#4 */ select 4 AS "4",4 AS "4")
set SQL_MODE=default;
(/* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`) union /* select#3 */ select `__3`.`c` AS `c`,`__3`.`d` AS `d` from ((/* select#2 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2`) intersect (/* select#4 */ select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3`)) `__3` union (/* select#5 */ select 4 AS `4`,4 AS `4`); (/* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`) union /* select#3 */ select `__3`.`c` AS `c`,`__3`.`d` AS `d` from ((/* select#2 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2`) intersect (/* select#4 */ select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3`)) `__3` union (/* select#5 */ select 4 AS `4`,4 AS `4`);
a b a b
3 3 3 3
...@@ -820,12 +784,6 @@ create table t234(c1 int); ...@@ -820,12 +784,6 @@ create table t234(c1 int);
insert into t234 values(2); insert into t234 values(2);
insert into t234 values(3); insert into t234 values(3);
insert into t234 values(4); insert into t234 values(4);
set SQL_MODE=oracle;
select * from t13 union select * from t234 intersect select * from t12;
c1
1
2
set SQL_MODE=default;
select * from t13 union select * from t234 intersect select * from t12; select * from t13 union select * from t234 intersect select * from t12;
c1 c1
1 1
...@@ -848,9 +806,9 @@ select * from t2 where a < 5 ...@@ -848,9 +806,9 @@ select * from t2 where a < 5
intersect intersect
select * from t3 where a < 5; select * from t3 where a < 5;
a a
1
7 7
7 7
1
explain extended explain extended
select * from t1 where a > 4 select * from t1 where a > 4
union all union all
......
...@@ -66,7 +66,6 @@ select 1 from dual ORDER BY 1 intersect select 1 from dual; ...@@ -66,7 +66,6 @@ select 1 from dual ORDER BY 1 intersect select 1 from dual;
select 1 as a from dual union all select 1 from dual; select 1 as a from dual union all select 1 from dual;
--error ER_PARSE_ERROR --error ER_PARSE_ERROR
select 1 from dual intersect all select 1 from dual;
...@@ -147,12 +146,6 @@ insert into t3 values (1,1),(3,3); ...@@ -147,12 +146,6 @@ insert into t3 values (1,1),(3,3);
(select a,b from t1) union (select c,d from t2) intersect (select e,f from t3) union (select 4,4); (select a,b from t1) union (select c,d from t2) intersect (select e,f from t3) union (select 4,4);
explain extended explain extended
(select a,b from t1) union (select c,d from t2) intersect (select e,f from t3) union (select 4,4); (select a,b from t1) union (select c,d from t2) intersect (select e,f from t3) union (select 4,4);
set SQL_MODE=ORACLE;
--sorted_result
(select a,b from t1) union (select c,d from t2) intersect (select e,f from t3) union (select 4,4);
explain extended
(select a,b from t1) union (select c,d from t2) intersect (select e,f from t3) union (select 4,4);
set SQL_MODE=default;
# test result of linear mix operation # test result of linear mix operation
...@@ -160,12 +153,6 @@ set SQL_MODE=default; ...@@ -160,12 +153,6 @@ set SQL_MODE=default;
(select e,f from t3) intersect (select c,d from t2) union (select a,b from t1) union (select 4,4); (select e,f from t3) intersect (select c,d from t2) union (select a,b from t1) union (select 4,4);
explain extended explain extended
(select e,f from t3) intersect (select c,d from t2) union (select a,b from t1) union (select 4,4); (select e,f from t3) intersect (select c,d from t2) union (select a,b from t1) union (select 4,4);
set SQL_MODE=ORACLE;
--sorted_result
(select e,f from t3) intersect (select c,d from t2) union (select a,b from t1) union (select 4,4);
explain extended
(select e,f from t3) intersect (select c,d from t2) union (select a,b from t1) union (select 4,4);
set SQL_MODE=default;
--sorted_result --sorted_result
(/* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`) union /* select#3 */ select `__3`.`c` AS `c`,`__3`.`d` AS `d` from ((/* select#2 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2`) intersect (/* select#4 */ select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3`)) `__3` union (/* select#5 */ select 4 AS `4`,4 AS `4`); (/* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`) union /* select#3 */ select `__3`.`c` AS `c`,`__3`.`d` AS `d` from ((/* select#2 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2`) intersect (/* select#4 */ select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3`)) `__3` union (/* select#5 */ select 4 AS `4`,4 AS `4`);
...@@ -311,10 +298,6 @@ insert into t234 values(2); ...@@ -311,10 +298,6 @@ insert into t234 values(2);
insert into t234 values(3); insert into t234 values(3);
insert into t234 values(4); insert into t234 values(4);
set SQL_MODE=oracle;
--sorted_result
select * from t13 union select * from t234 intersect select * from t12;
set SQL_MODE=default;
--sorted_result --sorted_result
select * from t13 union select * from t234 intersect select * from t12; select * from t13 union select * from t234 intersect select * from t12;
...@@ -333,7 +316,7 @@ insert into t2 values (4), (5), (9), (1), (8), (9); ...@@ -333,7 +316,7 @@ insert into t2 values (4), (5), (9), (1), (8), (9);
create table t3 (a int); create table t3 (a int);
insert into t3 values (8), (1), (8), (2), (3), (7), (2); insert into t3 values (8), (1), (8), (2), (3), (7), (2);
--sorted_result
select * from t1 where a > 4 select * from t1 where a > 4
union all union all
select * from t2 where a < 5 select * from t2 where a < 5
......
create table t1 (a int, b int) engine=MyISAM;
create table t2 (c int, d int) engine=MyISAM;
insert into t1 values (1,1),(2,2),(3,3),(2,2);
insert into t2 values (2,2),(2,2),(5,5);
select * from t1 intersect all select * from t2;
a b
2 2
2 2
(select a,b from t1) intersect all (select c,d from t2);
a b
2 2
2 2
select * from ((select a,b from t1) intersect all (select c,d from t2)) t;
a b
2 2
2 2
select * from ((select a from t1) intersect all (select c from t2)) t;
a
2
2
drop tables t1,t2;
create table t1 (a int, b int) engine=MyISAM;
create table t2 (c int, d int) engine=MyISAM;
create table t3 (e int, f int) engine=MyISAM;
insert into t1 values (1,1),(2,2),(3,3),(2,2);
insert into t2 values (2,2),(3,3),(4,4),(2,2);
insert into t3 values (1,1),(2,2),(5,5),(2,2);
(select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3);
a b
2 2
2 2
EXPLAIN (select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4
2 INTERSECT t2 ALL NULL NULL NULL NULL 4
3 INTERSECT t3 ALL NULL NULL NULL NULL 4
NULL INTERSECT RESULT <intersect1,2,3> ALL NULL NULL NULL NULL NULL
EXPLAIN extended (select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00
2 INTERSECT t2 ALL NULL NULL NULL NULL 4 100.00
3 INTERSECT t3 ALL NULL NULL NULL NULL 4 100.00
NULL INTERSECT RESULT <intersect1,2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 (/* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`) intersect all (/* select#2 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2`) intersect all (/* select#3 */ select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3`)
EXPLAIN extended select * from ((select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3)) a;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 100.00
2 DERIVED t1 ALL NULL NULL NULL NULL 4 100.00
3 INTERSECT t2 ALL NULL NULL NULL NULL 4 100.00
4 INTERSECT t3 ALL NULL NULL NULL NULL 4 100.00
NULL INTERSECT RESULT <intersect2,3,4> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 /* select#1 */ select `a`.`a` AS `a`,`a`.`b` AS `b` from (/* select#2 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` intersect all (/* select#3 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2`) intersect all (/* select#4 */ select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3`)) `a`
EXPLAIN format=json (select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3);
EXPLAIN
{
"query_block": {
"union_result": {
"table_name": "<intersect1,2,3>",
"access_type": "ALL",
"query_specifications": [
{
"query_block": {
"select_id": 1,
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 4,
"filtered": 100
}
}
},
{
"query_block": {
"select_id": 2,
"operation": "INTERSECT",
"table": {
"table_name": "t2",
"access_type": "ALL",
"rows": 4,
"filtered": 100
}
}
},
{
"query_block": {
"select_id": 3,
"operation": "INTERSECT",
"table": {
"table_name": "t3",
"access_type": "ALL",
"rows": 4,
"filtered": 100
}
}
}
]
}
}
}
ANALYZE format=json (select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3);
ANALYZE
{
"query_block": {
"union_result": {
"table_name": "<intersect1,2,3>",
"access_type": "ALL",
"r_loops": 1,
"r_rows": 2,
"query_specifications": [
{
"query_block": {
"select_id": 1,
"r_loops": 1,
"r_total_time_ms": "REPLACED",
"table": {
"table_name": "t1",
"access_type": "ALL",
"r_loops": 1,
"rows": 4,
"r_rows": 4,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100
}
}
},
{
"query_block": {
"select_id": 2,
"operation": "INTERSECT",
"r_loops": 1,
"r_total_time_ms": "REPLACED",
"table": {
"table_name": "t2",
"access_type": "ALL",
"r_loops": 1,
"rows": 4,
"r_rows": 4,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100
}
}
},
{
"query_block": {
"select_id": 3,
"operation": "INTERSECT",
"r_loops": 1,
"r_total_time_ms": "REPLACED",
"table": {
"table_name": "t3",
"access_type": "ALL",
"r_loops": 1,
"rows": 4,
"r_rows": 4,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100
}
}
}
]
}
}
}
ANALYZE format=json select * from ((select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3)) a;
ANALYZE
{
"query_block": {
"select_id": 1,
"r_loops": 1,
"r_total_time_ms": "REPLACED",
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"r_loops": 1,
"rows": 4,
"r_rows": 2,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100,
"materialized": {
"query_block": {
"union_result": {
"table_name": "<intersect2,3,4>",
"access_type": "ALL",
"r_loops": 1,
"r_rows": 2,
"query_specifications": [
{
"query_block": {
"select_id": 2,
"r_loops": 1,
"r_total_time_ms": "REPLACED",
"table": {
"table_name": "t1",
"access_type": "ALL",
"r_loops": 1,
"rows": 4,
"r_rows": 4,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100
}
}
},
{
"query_block": {
"select_id": 3,
"operation": "INTERSECT",
"r_loops": 1,
"r_total_time_ms": "REPLACED",
"table": {
"table_name": "t2",
"access_type": "ALL",
"r_loops": 1,
"rows": 4,
"r_rows": 4,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100
}
}
},
{
"query_block": {
"select_id": 4,
"operation": "INTERSECT",
"r_loops": 1,
"r_total_time_ms": "REPLACED",
"table": {
"table_name": "t3",
"access_type": "ALL",
"r_loops": 1,
"rows": 4,
"r_rows": 4,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100
}
}
}
]
}
}
}
}
}
}
select * from ((select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3)) a;
a b
2 2
2 2
prepare stmt from "(select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3);";
execute stmt;
a b
2 2
2 2
execute stmt;
a b
2 2
2 2
prepare stmt from "select * from ((select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3)) a";
execute stmt;
a b
2 2
2 2
execute stmt;
a b
2 2
2 2
insert into t1 values (2,2),(3,3);
insert into t2 values (2,2),(2,2),(2,2);
(select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3);
a b
2 2
2 2
(select a,b from t1) intersect (select c,d from t2) intersect all (select e,f from t3);
a b
2 2
insert into t3 values (2,2);
(select a,b from t1) intersect all (select c,d from t2) intersect (select e,f from t3);
a b
2 2
(select a,b from t1) intersect all (select c,e from t2,t3);
a b
2 2
2 2
2 2
EXPLAIN (select a,b from t1) intersect all (select c,e from t2,t3);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 6
2 INTERSECT t3 ALL NULL NULL NULL NULL 5
2 INTERSECT t2 ALL NULL NULL NULL NULL 7 Using join buffer (flat, BNL join)
NULL INTERSECT RESULT <intersect1,2> ALL NULL NULL NULL NULL NULL
EXPLAIN extended (select a,b from t1) intersect all (select c,e from t2,t3);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00
2 INTERSECT t3 ALL NULL NULL NULL NULL 5 100.00
2 INTERSECT t2 ALL NULL NULL NULL NULL 7 100.00 Using join buffer (flat, BNL join)
NULL INTERSECT RESULT <intersect1,2> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 (/* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`) intersect all (/* select#2 */ select `test`.`t2`.`c` AS `c`,`test`.`t3`.`e` AS `e` from `test`.`t2` join `test`.`t3`)
EXPLAIN extended select * from ((select a,b from t1) intersect all (select c,e from t2,t3)) a;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6 100.00
2 DERIVED t1 ALL NULL NULL NULL NULL 6 100.00
3 INTERSECT t3 ALL NULL NULL NULL NULL 5 100.00
3 INTERSECT t2 ALL NULL NULL NULL NULL 7 100.00 Using join buffer (flat, BNL join)
NULL INTERSECT RESULT <intersect2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 /* select#1 */ select `a`.`a` AS `a`,`a`.`b` AS `b` from (/* select#2 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` intersect all (/* select#3 */ select `test`.`t2`.`c` AS `c`,`test`.`t3`.`e` AS `e` from `test`.`t2` join `test`.`t3`)) `a`
EXPLAIN format=json (select a,b from t1) intersect all (select c,e from t2,t3);
EXPLAIN
{
"query_block": {
"union_result": {
"table_name": "<intersect1,2>",
"access_type": "ALL",
"query_specifications": [
{
"query_block": {
"select_id": 1,
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 6,
"filtered": 100
}
}
},
{
"query_block": {
"select_id": 2,
"operation": "INTERSECT",
"table": {
"table_name": "t3",
"access_type": "ALL",
"rows": 5,
"filtered": 100
},
"block-nl-join": {
"table": {
"table_name": "t2",
"access_type": "ALL",
"rows": 7,
"filtered": 100
},
"buffer_type": "flat",
"buffer_size": "65",
"join_type": "BNL"
}
}
}
]
}
}
}
ANALYZE format=json (select a,b from t1) intersect all (select c,e from t2,t3);
ANALYZE
{
"query_block": {
"union_result": {
"table_name": "<intersect1,2>",
"access_type": "ALL",
"r_loops": 1,
"r_rows": 3,
"query_specifications": [
{
"query_block": {
"select_id": 1,
"r_loops": 1,
"r_total_time_ms": "REPLACED",
"table": {
"table_name": "t1",
"access_type": "ALL",
"r_loops": 1,
"rows": 6,
"r_rows": 6,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100
}
}
},
{
"query_block": {
"select_id": 2,
"operation": "INTERSECT",
"r_loops": 1,
"r_total_time_ms": "REPLACED",
"table": {
"table_name": "t3",
"access_type": "ALL",
"r_loops": 1,
"rows": 5,
"r_rows": 5,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100
},
"block-nl-join": {
"table": {
"table_name": "t2",
"access_type": "ALL",
"r_loops": 1,
"rows": 7,
"r_rows": 7,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100
},
"buffer_type": "flat",
"buffer_size": "65",
"join_type": "BNL",
"r_filtered": 100
}
}
}
]
}
}
}
ANALYZE format=json select * from ((select a,b from t1) intersect all (select c,e from t2,t3)) a;
ANALYZE
{
"query_block": {
"select_id": 1,
"r_loops": 1,
"r_total_time_ms": "REPLACED",
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"r_loops": 1,
"rows": 6,
"r_rows": 3,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100,
"materialized": {
"query_block": {
"union_result": {
"table_name": "<intersect2,3>",
"access_type": "ALL",
"r_loops": 1,
"r_rows": 3,
"query_specifications": [
{
"query_block": {
"select_id": 2,
"r_loops": 1,
"r_total_time_ms": "REPLACED",
"table": {
"table_name": "t1",
"access_type": "ALL",
"r_loops": 1,
"rows": 6,
"r_rows": 6,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100
}
}
},
{
"query_block": {
"select_id": 3,
"operation": "INTERSECT",
"r_loops": 1,
"r_total_time_ms": "REPLACED",
"table": {
"table_name": "t3",
"access_type": "ALL",
"r_loops": 1,
"rows": 5,
"r_rows": 5,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100
},
"block-nl-join": {
"table": {
"table_name": "t2",
"access_type": "ALL",
"r_loops": 1,
"rows": 7,
"r_rows": 7,
"r_total_time_ms": "REPLACED",
"filtered": 100,
"r_filtered": 100
},
"buffer_type": "flat",
"buffer_size": "65",
"join_type": "BNL",
"r_filtered": 100
}
}
}
]
}
}
}
}
}
}
select * from ((select a,b from t1) intersect all (select c,e from t2,t3)) a;
a b
2 2
2 2
2 2
prepare stmt from "(select a,b from t1) intersect all (select c,e from t2,t3);";
execute stmt;
a b
2 2
2 2
2 2
execute stmt;
a b
2 2
2 2
2 2
prepare stmt from "select * from ((select a,b from t1) intersect all (select c,e from t2,t3)) a";
execute stmt;
a b
2 2
2 2
2 2
execute stmt;
a b
2 2
2 2
2 2
drop tables t1,t2,t3;
select 1 as a from dual intersect all select 1 from dual;
a
1
(select 1 from dual) intersect all (select 1 from dual);
1
1
(select 1 from dual into @v) intersect all (select 1 from dual);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'into @v) intersect all (select 1 from dual)' at line 1
select 1 from dual ORDER BY 1 intersect all select 1 from dual;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'intersect all select 1 from dual' at line 1
select 1 as a from dual union all select 1 from dual;
a
1
1
create table t1 (a int, b blob, a1 int, b1 blob);
create table t2 (c int, d blob, c1 int, d1 blob);
insert into t1 values (1,"ddd", 1, "sdfrrwwww"),(2, "fgh", 2, "dffggtt"),(2, "fgh", 2, "dffggtt");
insert into t2 values (2, "fgh", 2, "dffggtt"),(3, "ffggddd", 3, "dfgg"),(2, "fgh", 2, "dffggtt");
(select a,b,b1 from t1) intersect all (select c,d,d1 from t2);
a b b1
2 fgh dffggtt
2 fgh dffggtt
drop tables t1,t2;
create table t1 (a int, b blob) engine=MyISAM;
create table t2 (c int, d blob) engine=MyISAM;
create table t3 (e int, f blob) engine=MyISAM;
insert into t1 values (1,1),(2,2),(3,3),(2,2),(3,3);
insert into t2 values (2,2),(3,3),(4,4),(2,2),(2,2),(2,2);
insert into t3 values (1,1),(2,2),(5,5),(2,2),(5,5);
(select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3);
a b
2 2
2 2
select * from ((select a,b from t1) intersect all (select c,d from t2) intersect (select e,f from t3)) a;
a b
2 2
prepare stmt from "(select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3);";
execute stmt;
a b
2 2
2 2
execute stmt;
a b
2 2
2 2
prepare stmt from "select * from ((select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3)) a";
execute stmt;
a b
2 2
2 2
execute stmt;
a b
2 2
2 2
create table t4 (select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3);
show create table t4;
Table Create Table
t4 CREATE TABLE `t4` (
`a` int(11) DEFAULT NULL,
`b` blob DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop tables t4;
(select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3) union all (select 4,4);
a b
4 4
2 2
2 2
(select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3) union all (select 4,4) except all (select 2,2);
a b
4 4
2 2
drop tables t1,t2,t3;
create table t1 (a int, b int);
create table t2 (c int, d int);
create table t3 (e int, f int);
insert into t1 values (1,1),(2,2),(3,3),(2,2),(3,3);
insert into t2 values (2,2),(3,3),(4,4),(2,2),(2,2),(2,2);
insert into t3 values (1,1),(2,2),(5,5),(2,2),(5,5);
(select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3) union all (select 4,4);
a b
4 4
2 2
2 2
(select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3) union all (select 4,4) except all (select 2,2);
a b
4 4
2 2
drop tables t1,t2,t3;
#
# INTERSECT precedence
#
create table t1 (a int, b blob) engine=MyISAM;
create table t2 (c int, d blob) engine=MyISAM;
create table t3 (e int, f blob) engine=MyISAM;
insert into t1 values (5,5),(6,6);
insert into t2 values (2,2),(3,3);
insert into t3 values (1,1),(3,3);
(select a,b from t1) union all (select c,d from t2) intersect (select e,f from t3) union all (select 4,4);
a b
5 5
6 6
3 3
4 4
(select a,b from t1) union all (select c,d from t2) intersect all (select e,f from t3) union all (select 4,4);
a b
5 5
6 6
3 3
4 4
explain extended (select a,b from t1) union all (select c,d from t2) intersect all (select e,f from t3) union all (select 4,4);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
5 UNION <derived2> ALL NULL NULL NULL NULL 2 100.00
2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00
3 INTERSECT t3 ALL NULL NULL NULL NULL 2 100.00
NULL INTERSECT RESULT <intersect2,3> ALL NULL NULL NULL NULL NULL NULL
4 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 (/* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`) union all /* select#5 */ select `__5`.`c` AS `c`,`__5`.`d` AS `d` from ((/* select#2 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2`) intersect all (/* select#3 */ select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3`)) `__5` union all (/* select#4 */ select 4 AS `4`,4 AS `4`)
insert into t2 values (3,3);
insert into t3 values (3,3);
(select e,f from t3) intersect all (select c,d from t2) union all (select a,b from t1) union all (select 4,4);
e f
3 3
3 3
5 5
6 6
4 4
explain extended (select e,f from t3) intersect all (select c,d from t2) union all (select a,b from t1) union all (select 4,4);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 INTERSECT t2 ALL NULL NULL NULL NULL 3 100.00
3 UNION t1 ALL NULL NULL NULL NULL 2 100.00
4 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNIT RESULT <unit1,2,3,4> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 (/* select#1 */ select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3`) intersect all (/* select#2 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2`) union all (/* select#3 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`) union all (/* select#4 */ select 4 AS `4`,4 AS `4`)
(/* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`) union /* select#3 */ select `__3`.`c` AS `c`,`__3`.`d` AS `d` from ((/* select#2 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2`) intersect all (/* select#4 */ select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3`)) `__3` union (/* select#5 */ select 4 AS `4`,4 AS `4`);
a b
5 5
6 6
3 3
4 4
prepare stmt from "(select a,b from t1) union all (select c,d from t2) intersect all (select e,f from t3) union all (select 4,4)";
execute stmt;
a b
5 5
6 6
3 3
3 3
4 4
execute stmt;
a b
5 5
6 6
3 3
3 3
4 4
create view v1 as (select a,b from t1) union all (select c,d from t2) intersect all (select e,f from t3) union all (select 4,4);
select b,a,b+1 from v1;
b a b+1
5 5 6
6 6 7
3 3 4
3 3 4
4 4 5
select b,a,b+1 from v1 where a > 3;
b a b+1
5 5 6
6 6 7
4 4 5
create procedure p1()
select * from v1;
call p1();
a b
5 5
6 6
3 3
3 3
4 4
call p1();
a b
5 5
6 6
3 3
3 3
4 4
drop procedure p1;
create procedure p1()
(select a,b from t1) union all (select c,d from t2) intersect all (select e,f from t3) union all (select 4,4);
call p1();
a b
5 5
6 6
3 3
3 3
4 4
call p1();
a b
5 5
6 6
3 3
3 3
4 4
drop procedure p1;
show create view v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS (select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`) union all select `__6`.`c` AS `c`,`__6`.`d` AS `d` from (select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` intersect all (select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3`)) `__6` union all (select 4 AS `4`,4 AS `4`) latin1 latin1_swedish_ci
drop view v1;
drop tables t1,t2,t3;
CREATE TABLE t (i INT);
INSERT INTO t VALUES (1),(2);
SELECT * FROM t WHERE i != ANY ( SELECT 6 INTERSECT ALL SELECT 3 );
i
select i from t where
exists ((select 6 as r from dual having t.i <> 6)
intersect all
(select 3 from dual having t.i <> 3));
i
drop table t;
CREATE TABLE t1 (a varchar(32)) ENGINE=MyISAM;
INSERT INTO t1 VALUES
('Jakarta'),('Lisbon'),('Honolulu'),('Lusaka'),('Barcelona'),('Taipei'),
('Brussels'),('Orlando'),('Osaka'),('Quito'),('Lima'),('Tunis'),
('Unalaska'),('Rotterdam'),('Zagreb'),('Ufa'),('Ryazan'),('Xiamen'),
('London'),('Izmir'),('Samara'),('Bern'),('Zhengzhou'),('Vladivostok'),
('Yangon'),('Victoria'),('Warsaw'),('Luanda'),('Leon'),('Bangkok'),
('Wellington'),('Zibo'),('Qiqihar'),('Delhi'),('Hamburg'),('Ottawa'),
('Vaduz');
CREATE TABLE t2 (b varchar(32)) ENGINE=MyISAM;
INSERT INTO t2 VALUES
('Gaza'),('Jeddah'),('Beirut'),('Incheon'),('Tbilisi'),('Izmir'),
('Quito'),('Riga'),('Freetown'),('Zagreb'),('Caracas'),('Orlando'),
('Kingston'),('Turin'),('Xinyang'),('Osaka'),('Albany'),('Geneva'),
('Omsk'),('Kazan'),('Quezon'),('Indore'),('Odessa'),('Xiamen'),
('Winnipeg'),('Yakutsk'),('Nairobi'),('Ufa'),('Helsinki'),('Vilnius'),
('Aden'),('Liverpool'),('Honolulu'),('Frankfurt'),('Glasgow'),
('Vienna'),('Jackson'),('Jakarta'),('Sydney'),('Oslo'),('Novgorod'),
('Norilsk'),('Izhevsk'),('Istanbul'),('Nice');
CREATE TABLE t3 (c varchar(32)) ENGINE=MyISAM;
INSERT INTO t3 VALUES
('Nicosia'),('Istanbul'),('Richmond'),('Stockholm'),('Dublin'),
('Wichita'),('Warsaw'),('Glasgow'),('Winnipeg'),('Irkutsk'),('Quito'),
('Xiamen'),('Berlin'),('Rome'),('Denver'),('Dallas'),('Kabul'),
('Prague'),('Izhevsk'),('Tirana'),('Sofia'),('Detroit'),('Sorbonne');
select count(*) from (
SELECT * FROM t1 LEFT OUTER JOIN t2 LEFT OUTER JOIN t3 ON b < c ON a > b
INTERSECT
SELECT * FROM t1 LEFT OUTER JOIN t2 LEFT OUTER JOIN t3 ON b < c ON a > b
) a;
count(*)
14848
select count(*) from (
SELECT * FROM t1 LEFT OUTER JOIN t2 LEFT OUTER JOIN t3 ON b < c ON a > b
INTERSECT ALL
SELECT * FROM t1 LEFT OUTER JOIN t2 LEFT OUTER JOIN t3 ON b < c ON a > b
) a;
count(*)
14848
insert into t1 values ('Xiamen');
insert into t2 values ('Xiamen'),('Xiamen');
insert into t3 values ('Xiamen');
select count(*) from (
SELECT * FROM t1 LEFT OUTER JOIN t2 LEFT OUTER JOIN t3 ON b < c ON a > b
INTERSECT ALL
SELECT * FROM t1 LEFT OUTER JOIN t2 LEFT OUTER JOIN t3 ON b < c ON a > b
) a;
count(*)
16430
drop table t1,t2,t3;
CREATE TABLE t1 (a varchar(32) not null) ENGINE=MyISAM;
INSERT INTO t1 VALUES
('Jakarta'),('Lisbon'),('Honolulu'),('Lusaka'),('Barcelona'),('Taipei'),
('Brussels'),('Orlando'),('Osaka'),('Quito'),('Lima'),('Tunis'),
('Unalaska'),('Rotterdam'),('Zagreb'),('Ufa'),('Ryazan'),('Xiamen'),
('London'),('Izmir'),('Samara'),('Bern'),('Zhengzhou'),('Vladivostok'),
('Yangon'),('Victoria'),('Warsaw'),('Luanda'),('Leon'),('Bangkok'),
('Wellington'),('Zibo'),('Qiqihar'),('Delhi'),('Hamburg'),('Ottawa'),
('Vaduz'),('Detroit'),('Detroit');
CREATE TABLE t2 (b varchar(32) not null) ENGINE=MyISAM;
INSERT INTO t2 VALUES
('Gaza'),('Jeddah'),('Beirut'),('Incheon'),('Tbilisi'),('Izmir'),
('Quito'),('Riga'),('Freetown'),('Zagreb'),('Caracas'),('Orlando'),
('Kingston'),('Turin'),('Xinyang'),('Osaka'),('Albany'),('Geneva'),
('Omsk'),('Kazan'),('Quezon'),('Indore'),('Odessa'),('Xiamen'),
('Winnipeg'),('Yakutsk'),('Nairobi'),('Ufa'),('Helsinki'),('Vilnius'),
('Aden'),('Liverpool'),('Honolulu'),('Frankfurt'),('Glasgow'),
('Vienna'),('Jackson'),('Jakarta'),('Sydney'),('Oslo'),('Novgorod'),
('Norilsk'),('Izhevsk'),('Istanbul'),('Nice'),('Detroit'),('Detroit');
CREATE TABLE t3 (c varchar(32) not null) ENGINE=MyISAM;
INSERT INTO t3 VALUES
('Nicosia'),('Istanbul'),('Richmond'),('Stockholm'),('Dublin'),
('Wichita'),('Warsaw'),('Glasgow'),('Winnipeg'),('Irkutsk'),('Quito'),
('Xiamen'),('Berlin'),('Rome'),('Denver'),('Dallas'),('Kabul'),
('Prague'),('Izhevsk'),('Tirana'),('Sofia'),('Detroit'),('Sorbonne'),
('Detroit');
select count(*) from (
SELECT * FROM t1 LEFT OUTER JOIN t2 LEFT OUTER JOIN t3 ON b < c ON a > b
INTERSECT
SELECT * FROM t1 LEFT OUTER JOIN t2 LEFT OUTER JOIN t3 ON b < c ON a > b
) a;
count(*)
15547
drop table t1,t2,t3;
create table t12(c1 int);
insert into t12 values(1);
insert into t12 values(2);
create table t13(c1 int);
insert into t13 values(1);
insert into t13 values(3);
create table t234(c1 int);
insert into t234 values(2);
insert into t234 values(3);
insert into t234 values(4);
select * from t13 union select * from t234 intersect all select * from t12;
c1
1
3
2
drop table t12,t13,t234;
create table t1 (a int);
insert into t1 values (3), (1), (7), (3), (2), (7), (4);
create table t2 (a int);
insert into t2 values (4), (5), (9), (1), (8), (9), (2), (2);
create table t3 (a int);
insert into t3 values (8), (1), (8), (2), (3), (7), (2);
select * from t1 where a > 4
union all
select * from t2 where a < 5
intersect all
select * from t3 where a < 5;
a
7
7
2
1
2
explain extended
select * from t1 where a > 4
union all
select * from t2 where a < 5
intersect all
select * from t3 where a < 5;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 7 100.00 Using where
4 UNION <derived2> ALL NULL NULL NULL NULL 7 100.00
2 DERIVED t2 ALL NULL NULL NULL NULL 8 100.00 Using where
3 INTERSECT t3 ALL NULL NULL NULL NULL 7 100.00 Using where
NULL INTERSECT RESULT <intersect2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 4 union all /* select#4 */ select `__4`.`a` AS `a` from (/* select#2 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where `test`.`t2`.`a` < 5 intersect all /* select#3 */ select `test`.`t3`.`a` AS `a` from `test`.`t3` where `test`.`t3`.`a` < 5) `__4`
drop table t1,t2,t3;
create table t1 (a int, b int) engine=MyISAM;
create table t2 (c int, d int) engine=MyISAM;
insert into t1 values (1,1),(2,2),(3,3),(2,2);
insert into t2 values (2,2),(2,2),(5,5);
select * from t1 intersect all select * from t2;
(select a,b from t1) intersect all (select c,d from t2);
select * from ((select a,b from t1) intersect all (select c,d from t2)) t;
select * from ((select a from t1) intersect all (select c from t2)) t;
drop tables t1,t2;
create table t1 (a int, b int) engine=MyISAM;
create table t2 (c int, d int) engine=MyISAM;
create table t3 (e int, f int) engine=MyISAM;
insert into t1 values (1,1),(2,2),(3,3),(2,2);
insert into t2 values (2,2),(3,3),(4,4),(2,2);
insert into t3 values (1,1),(2,2),(5,5),(2,2);
(select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3);
EXPLAIN (select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3);
EXPLAIN extended (select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3);
EXPLAIN extended select * from ((select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3)) a;
EXPLAIN format=json (select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3);
--source include/analyze-format.inc
ANALYZE format=json (select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3);
--source include/analyze-format.inc
ANALYZE format=json select * from ((select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3)) a;
select * from ((select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3)) a;
prepare stmt from "(select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3);";
execute stmt;
execute stmt;
prepare stmt from "select * from ((select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3)) a";
execute stmt;
execute stmt;
insert into t1 values (2,2),(3,3);
insert into t2 values (2,2),(2,2),(2,2);
(select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3);
(select a,b from t1) intersect (select c,d from t2) intersect all (select e,f from t3);
insert into t3 values (2,2);
(select a,b from t1) intersect all (select c,d from t2) intersect (select e,f from t3);
(select a,b from t1) intersect all (select c,e from t2,t3);
EXPLAIN (select a,b from t1) intersect all (select c,e from t2,t3);
EXPLAIN extended (select a,b from t1) intersect all (select c,e from t2,t3);
EXPLAIN extended select * from ((select a,b from t1) intersect all (select c,e from t2,t3)) a;
EXPLAIN format=json (select a,b from t1) intersect all (select c,e from t2,t3);
--source include/analyze-format.inc
ANALYZE format=json (select a,b from t1) intersect all (select c,e from t2,t3);
--source include/analyze-format.inc
ANALYZE format=json select * from ((select a,b from t1) intersect all (select c,e from t2,t3)) a;
select * from ((select a,b from t1) intersect all (select c,e from t2,t3)) a;
prepare stmt from "(select a,b from t1) intersect all (select c,e from t2,t3);";
execute stmt;
execute stmt;
prepare stmt from "select * from ((select a,b from t1) intersect all (select c,e from t2,t3)) a";
execute stmt;
execute stmt;
drop tables t1,t2,t3;
select 1 as a from dual intersect all select 1 from dual;
(select 1 from dual) intersect all (select 1 from dual);
--error ER_PARSE_ERROR
(select 1 from dual into @v) intersect all (select 1 from dual);
--error ER_PARSE_ERROR
select 1 from dual ORDER BY 1 intersect all select 1 from dual;
select 1 as a from dual union all select 1 from dual;
create table t1 (a int, b blob, a1 int, b1 blob);
create table t2 (c int, d blob, c1 int, d1 blob);
insert into t1 values (1,"ddd", 1, "sdfrrwwww"),(2, "fgh", 2, "dffggtt"),(2, "fgh", 2, "dffggtt");
insert into t2 values (2, "fgh", 2, "dffggtt"),(3, "ffggddd", 3, "dfgg"),(2, "fgh", 2, "dffggtt");
(select a,b,b1 from t1) intersect all (select c,d,d1 from t2);
drop tables t1,t2;
create table t1 (a int, b blob) engine=MyISAM;
create table t2 (c int, d blob) engine=MyISAM;
create table t3 (e int, f blob) engine=MyISAM;
insert into t1 values (1,1),(2,2),(3,3),(2,2),(3,3);
insert into t2 values (2,2),(3,3),(4,4),(2,2),(2,2),(2,2);
insert into t3 values (1,1),(2,2),(5,5),(2,2),(5,5);
(select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3);
select * from ((select a,b from t1) intersect all (select c,d from t2) intersect (select e,f from t3)) a;
prepare stmt from "(select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3);";
execute stmt;
execute stmt;
prepare stmt from "select * from ((select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3)) a";
execute stmt;
execute stmt;
# make sure that blob is used
create table t4 (select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3);
show create table t4;
drop tables t4;
(select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3) union all (select 4,4);
(select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3) union all (select 4,4) except all (select 2,2);
drop tables t1,t2,t3;
create table t1 (a int, b int);
create table t2 (c int, d int);
create table t3 (e int, f int);
insert into t1 values (1,1),(2,2),(3,3),(2,2),(3,3);
insert into t2 values (2,2),(3,3),(4,4),(2,2),(2,2),(2,2);
insert into t3 values (1,1),(2,2),(5,5),(2,2),(5,5);
(select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3) union all (select 4,4);
(select a,b from t1) intersect all (select c,d from t2) intersect all (select e,f from t3) union all (select 4,4) except all (select 2,2);
drop tables t1,t2,t3;
--echo #
--echo # INTERSECT precedence
--echo #
create table t1 (a int, b blob) engine=MyISAM;
create table t2 (c int, d blob) engine=MyISAM;
create table t3 (e int, f blob) engine=MyISAM;
insert into t1 values (5,5),(6,6);
insert into t2 values (2,2),(3,3);
insert into t3 values (1,1),(3,3);
(select a,b from t1) union all (select c,d from t2) intersect (select e,f from t3) union all (select 4,4);
(select a,b from t1) union all (select c,d from t2) intersect all (select e,f from t3) union all (select 4,4);
explain extended (select a,b from t1) union all (select c,d from t2) intersect all (select e,f from t3) union all (select 4,4);
# test result of linear mix operation
insert into t2 values (3,3);
insert into t3 values (3,3);
(select e,f from t3) intersect all (select c,d from t2) union all (select a,b from t1) union all (select 4,4);
explain extended (select e,f from t3) intersect all (select c,d from t2) union all (select a,b from t1) union all (select 4,4);
(/* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`) union /* select#3 */ select `__3`.`c` AS `c`,`__3`.`d` AS `d` from ((/* select#2 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2`) intersect all (/* select#4 */ select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3`)) `__3` union (/* select#5 */ select 4 AS `4`,4 AS `4`);
prepare stmt from "(select a,b from t1) union all (select c,d from t2) intersect all (select e,f from t3) union all (select 4,4)";
execute stmt;
execute stmt;
create view v1 as (select a,b from t1) union all (select c,d from t2) intersect all (select e,f from t3) union all (select 4,4);
select b,a,b+1 from v1;
select b,a,b+1 from v1 where a > 3;
create procedure p1()
select * from v1;
call p1();
call p1();
drop procedure p1;
create procedure p1()
(select a,b from t1) union all (select c,d from t2) intersect all (select e,f from t3) union all (select 4,4);
call p1();
call p1();
drop procedure p1;
show create view v1;
drop view v1;
drop tables t1,t2,t3;
CREATE TABLE t (i INT);
INSERT INTO t VALUES (1),(2);
SELECT * FROM t WHERE i != ANY ( SELECT 6 INTERSECT ALL SELECT 3 );
select i from t where
exists ((select 6 as r from dual having t.i <> 6)
intersect all
(select 3 from dual having t.i <> 3));
drop table t;
CREATE TABLE t1 (a varchar(32)) ENGINE=MyISAM;
INSERT INTO t1 VALUES
('Jakarta'),('Lisbon'),('Honolulu'),('Lusaka'),('Barcelona'),('Taipei'),
('Brussels'),('Orlando'),('Osaka'),('Quito'),('Lima'),('Tunis'),
('Unalaska'),('Rotterdam'),('Zagreb'),('Ufa'),('Ryazan'),('Xiamen'),
('London'),('Izmir'),('Samara'),('Bern'),('Zhengzhou'),('Vladivostok'),
('Yangon'),('Victoria'),('Warsaw'),('Luanda'),('Leon'),('Bangkok'),
('Wellington'),('Zibo'),('Qiqihar'),('Delhi'),('Hamburg'),('Ottawa'),
('Vaduz');
CREATE TABLE t2 (b varchar(32)) ENGINE=MyISAM;
INSERT INTO t2 VALUES
('Gaza'),('Jeddah'),('Beirut'),('Incheon'),('Tbilisi'),('Izmir'),
('Quito'),('Riga'),('Freetown'),('Zagreb'),('Caracas'),('Orlando'),
('Kingston'),('Turin'),('Xinyang'),('Osaka'),('Albany'),('Geneva'),
('Omsk'),('Kazan'),('Quezon'),('Indore'),('Odessa'),('Xiamen'),
('Winnipeg'),('Yakutsk'),('Nairobi'),('Ufa'),('Helsinki'),('Vilnius'),
('Aden'),('Liverpool'),('Honolulu'),('Frankfurt'),('Glasgow'),
('Vienna'),('Jackson'),('Jakarta'),('Sydney'),('Oslo'),('Novgorod'),
('Norilsk'),('Izhevsk'),('Istanbul'),('Nice');
CREATE TABLE t3 (c varchar(32)) ENGINE=MyISAM;
INSERT INTO t3 VALUES
('Nicosia'),('Istanbul'),('Richmond'),('Stockholm'),('Dublin'),
('Wichita'),('Warsaw'),('Glasgow'),('Winnipeg'),('Irkutsk'),('Quito'),
('Xiamen'),('Berlin'),('Rome'),('Denver'),('Dallas'),('Kabul'),
('Prague'),('Izhevsk'),('Tirana'),('Sofia'),('Detroit'),('Sorbonne');
select count(*) from (
SELECT * FROM t1 LEFT OUTER JOIN t2 LEFT OUTER JOIN t3 ON b < c ON a > b
INTERSECT
SELECT * FROM t1 LEFT OUTER JOIN t2 LEFT OUTER JOIN t3 ON b < c ON a > b
) a;
select count(*) from (
SELECT * FROM t1 LEFT OUTER JOIN t2 LEFT OUTER JOIN t3 ON b < c ON a > b
INTERSECT ALL
SELECT * FROM t1 LEFT OUTER JOIN t2 LEFT OUTER JOIN t3 ON b < c ON a > b
) a;
insert into t1 values ('Xiamen');
insert into t2 values ('Xiamen'),('Xiamen');
insert into t3 values ('Xiamen');
select count(*) from (
SELECT * FROM t1 LEFT OUTER JOIN t2 LEFT OUTER JOIN t3 ON b < c ON a > b
INTERSECT ALL
SELECT * FROM t1 LEFT OUTER JOIN t2 LEFT OUTER JOIN t3 ON b < c ON a > b
) a;
drop table t1,t2,t3;
CREATE TABLE t1 (a varchar(32) not null) ENGINE=MyISAM;
INSERT INTO t1 VALUES
('Jakarta'),('Lisbon'),('Honolulu'),('Lusaka'),('Barcelona'),('Taipei'),
('Brussels'),('Orlando'),('Osaka'),('Quito'),('Lima'),('Tunis'),
('Unalaska'),('Rotterdam'),('Zagreb'),('Ufa'),('Ryazan'),('Xiamen'),
('London'),('Izmir'),('Samara'),('Bern'),('Zhengzhou'),('Vladivostok'),
('Yangon'),('Victoria'),('Warsaw'),('Luanda'),('Leon'),('Bangkok'),
('Wellington'),('Zibo'),('Qiqihar'),('Delhi'),('Hamburg'),('Ottawa'),
('Vaduz'),('Detroit'),('Detroit');
CREATE TABLE t2 (b varchar(32) not null) ENGINE=MyISAM;
INSERT INTO t2 VALUES
('Gaza'),('Jeddah'),('Beirut'),('Incheon'),('Tbilisi'),('Izmir'),
('Quito'),('Riga'),('Freetown'),('Zagreb'),('Caracas'),('Orlando'),
('Kingston'),('Turin'),('Xinyang'),('Osaka'),('Albany'),('Geneva'),
('Omsk'),('Kazan'),('Quezon'),('Indore'),('Odessa'),('Xiamen'),
('Winnipeg'),('Yakutsk'),('Nairobi'),('Ufa'),('Helsinki'),('Vilnius'),
('Aden'),('Liverpool'),('Honolulu'),('Frankfurt'),('Glasgow'),
('Vienna'),('Jackson'),('Jakarta'),('Sydney'),('Oslo'),('Novgorod'),
('Norilsk'),('Izhevsk'),('Istanbul'),('Nice'),('Detroit'),('Detroit');
CREATE TABLE t3 (c varchar(32) not null) ENGINE=MyISAM;
INSERT INTO t3 VALUES
('Nicosia'),('Istanbul'),('Richmond'),('Stockholm'),('Dublin'),
('Wichita'),('Warsaw'),('Glasgow'),('Winnipeg'),('Irkutsk'),('Quito'),
('Xiamen'),('Berlin'),('Rome'),('Denver'),('Dallas'),('Kabul'),
('Prague'),('Izhevsk'),('Tirana'),('Sofia'),('Detroit'),('Sorbonne'),
('Detroit');
select count(*) from (
SELECT * FROM t1 LEFT OUTER JOIN t2 LEFT OUTER JOIN t3 ON b < c ON a > b
INTERSECT
SELECT * FROM t1 LEFT OUTER JOIN t2 LEFT OUTER JOIN t3 ON b < c ON a > b
) a;
drop table t1,t2,t3;
create table t12(c1 int);
insert into t12 values(1);
insert into t12 values(2);
create table t13(c1 int);
insert into t13 values(1);
insert into t13 values(3);
create table t234(c1 int);
insert into t234 values(2);
insert into t234 values(3);
insert into t234 values(4);
select * from t13 union select * from t234 intersect all select * from t12;
drop table t12,t13,t234;
create table t1 (a int);
insert into t1 values (3), (1), (7), (3), (2), (7), (4);
create table t2 (a int);
insert into t2 values (4), (5), (9), (1), (8), (9), (2), (2);
create table t3 (a int);
insert into t3 values (8), (1), (8), (2), (3), (7), (2);
select * from t1 where a > 4
union all
select * from t2 where a < 5
intersect all
select * from t3 where a < 5;
explain extended
select * from t1 where a > 4
union all
select * from t2 where a < 5
intersect all
select * from t3 where a < 5;
drop table t1,t2,t3;
\ No newline at end of file
create table t1 (a int, b int) engine=MyISAM;
create table t2 (c int, d int) engine=MyISAM;
create table t3 (e int, f int) engine=MyISAM;
create table t4 (g int, h int) engine=MyISAM;
insert into t1 values (1,1),(2,2),(3,3),(2,2),(3,3);
insert into t2 values (2,2),(3,3),(5,5),(2,2),(2,2),(3,3);
insert into t3 values (4,4),(2,2),(2,2),(1,1),(3,3);
insert into t4 values (2,2),(4,4),(1,1);
create view v0(g, h) as select a,c from t1,t2;
# test optimization
select * from t1
INTERSECT ALL
select * from t2
INTERSECT ALL
select * from t3;
a b
2 2
2 2
3 3
EXPLAIN EXTENDED select * from t1
INTERSECT ALL
select * from t2
INTERSECT ALL
select * from t3;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 5 100.00
2 INTERSECT t2 ALL NULL NULL NULL NULL 6 100.00
3 INTERSECT t3 ALL NULL NULL NULL NULL 5 100.00
NULL INTERSECT RESULT <intersect1,2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` intersect all /* select#2 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` intersect all /* select#3 */ select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3`
select * from t1
INTERSECT ALL
select * from t2
INTERSECT ALL
select * from t3
INTERSECT
select * from t1;
a b
2 2
3 3
EXPLAIN EXTENDED select * from t1
INTERSECT ALL
select * from t2
INTERSECT ALL
select * from t3
INTERSECT
select * from t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 5 100.00
2 INTERSECT t2 ALL NULL NULL NULL NULL 6 100.00
3 INTERSECT t3 ALL NULL NULL NULL NULL 5 100.00
4 INTERSECT t1 ALL NULL NULL NULL NULL 5 100.00
NULL INTERSECT RESULT <intersect1,2,3,4> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` intersect /* select#2 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` intersect /* select#3 */ select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3` intersect /* select#4 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`
select * from t1
INTERSECT ALL
select * from t2
INTERSECT ALL
select * from t3
EXCEPT ALL
select * from t4;
a b
2 2
3 3
EXPLAIN EXTENDED select * from t1
INTERSECT ALL
select * from t2
INTERSECT ALL
select * from t3
EXCEPT ALL
select * from t4;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 5 100.00
2 INTERSECT t2 ALL NULL NULL NULL NULL 6 100.00
3 INTERSECT t3 ALL NULL NULL NULL NULL 5 100.00
4 EXCEPT t4 ALL NULL NULL NULL NULL 3 100.00
NULL UNIT RESULT <unit1,2,3,4> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` intersect all /* select#2 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` intersect all /* select#3 */ select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3` except all /* select#4 */ select `test`.`t4`.`g` AS `g`,`test`.`t4`.`h` AS `h` from `test`.`t4`
select * from t1
INTERSECT
select * from t2
EXCEPT ALL
select * from t4;
a b
3 3
EXPLAIN EXTENDED select * from t1
INTERSECT
select * from t2
EXCEPT ALL
select * from t4;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 5 100.00
2 INTERSECT t2 ALL NULL NULL NULL NULL 6 100.00
3 EXCEPT t4 ALL NULL NULL NULL NULL 3 100.00
NULL UNIT RESULT <unit1,2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` intersect /* select#2 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` except /* select#3 */ select `test`.`t4`.`g` AS `g`,`test`.`t4`.`h` AS `h` from `test`.`t4`
insert into t4 values (1,1),(9,9);
select * from t1
UNION ALL
select * from t2
UNION ALL
select * from t3
EXCEPT
select * from t4;
a b
3 3
5 5
EXPLAIN EXTENDED select * from t1
UNION ALL
select * from t2
UNION ALL
select * from t3
EXCEPT
select * from t4;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 5 100.00
2 UNION t2 ALL NULL NULL NULL NULL 6 100.00
3 UNION t3 ALL NULL NULL NULL NULL 5 100.00
4 EXCEPT t4 ALL NULL NULL NULL NULL 5 100.00
NULL UNIT RESULT <unit1,2,3,4> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` union /* select#2 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` union /* select#3 */ select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3` except /* select#4 */ select `test`.`t4`.`g` AS `g`,`test`.`t4`.`h` AS `h` from `test`.`t4`
delete from t4;
insert into t4 values (3,3),(3,3);
select * from t1
INTERSECT ALL
select * from t2
UNION ALL
select * from t3
EXCEPT ALL
select * from t1
UNION
select * from t4
EXCEPT
select * from t3
UNION ALL
select * from t1;
a b
2 2
2 2
1 1
3 3
3 3
EXPLAIN EXTENDED select * from t1
INTERSECT ALL
select * from t2
UNION ALL
select * from t3
EXCEPT ALL
select * from t1
UNION
select * from t4
EXCEPT
select * from t3
UNION ALL
select * from t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 5 100.00
2 INTERSECT t2 ALL NULL NULL NULL NULL 6 100.00
3 UNION t3 ALL NULL NULL NULL NULL 5 100.00
4 EXCEPT t1 ALL NULL NULL NULL NULL 5 100.00
5 UNION t4 ALL NULL NULL NULL NULL 2 100.00
6 EXCEPT t3 ALL NULL NULL NULL NULL 5 100.00
7 UNION t1 ALL NULL NULL NULL NULL 5 100.00
NULL UNIT RESULT <unit1,2,3,4,5,6,7> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` intersect all /* select#2 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` union all /* select#3 */ select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3` except all /* select#4 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` union /* select#5 */ select `test`.`t4`.`g` AS `g`,`test`.`t4`.`h` AS `h` from `test`.`t4` except /* select#6 */ select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3` union all /* select#7 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`
drop table t4;
# test optimization with brackets
(
(select 1 except select 5 union all select 6)
union
(select 2 intersect all select 3 intersect all select 4)
except
(select 7 intersect all select 8)
)
union all
(select 9 union all select 10)
except all
select 11;
1
1
6
9
10
EXPLAIN EXTENDED (
(select 1 except select 5 union all select 6)
union
(select 2 intersect all select 3 intersect all select 4)
except
(select 7 intersect all select 8)
)
union all
(select 9 union all select 10)
except all
select 11;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived8> ALL NULL NULL NULL NULL 4 100.00
8 DERIVED <derived2> ALL NULL NULL NULL NULL 2 100.00
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
3 EXCEPT NULL NULL NULL NULL NULL NULL NULL NULL No tables used
4 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNIT RESULT <unit2,3,4> ALL NULL NULL NULL NULL NULL NULL
9 UNION <derived5> ALL NULL NULL NULL NULL 2 100.00
5 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
6 INTERSECT NULL NULL NULL NULL NULL NULL NULL NULL No tables used
7 INTERSECT NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL INTERSECT RESULT <intersect5,6,7> ALL NULL NULL NULL NULL NULL NULL
12 EXCEPT <derived10> ALL NULL NULL NULL NULL 2 100.00
10 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
11 INTERSECT NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL INTERSECT RESULT <intersect10,11> ALL NULL NULL NULL NULL NULL NULL
NULL UNIT RESULT <unit8,9,12> ALL NULL NULL NULL NULL NULL NULL
15 UNION <derived13> ALL NULL NULL NULL NULL 2 100.00
13 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
14 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
16 EXCEPT NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNIT RESULT <unit1,15,16> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 /* select#1 */ select `__14`.`1` AS `1` from (/* select#8 */ select `__7`.`1` AS `1` from (/* select#2 */ select 1 AS `1` except /* select#3 */ select 5 AS `5` union /* select#4 */ select 6 AS `6`) `__7` union /* select#9 */ select `__8`.`2` AS `2` from (/* select#5 */ select 2 AS `2` intersect /* select#6 */ select 3 AS `3` intersect /* select#7 */ select 4 AS `4`) `__8` except /* select#12 */ select `__11`.`7` AS `7` from (/* select#10 */ select 7 AS `7` intersect /* select#11 */ select 8 AS `8`) `__11`) `__14` union all /* select#15 */ select `__15`.`9` AS `9` from (/* select#13 */ select 9 AS `9` union all /* select#14 */ select 10 AS `10`) `__15` except all /* select#16 */ select 11 AS `11`
(select 1 union all select 2)
union
(select 3 union all select 4);
1
1
2
3
4
EXPLAIN EXTENDED (select 1 union all select 2)
union
(select 3 union all select 4);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
6 UNION <derived4> ALL NULL NULL NULL NULL 2 100.00
4 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
5 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNION RESULT <union1,6> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 /* select#1 */ select `__5`.`1` AS `1` from (/* select#2 */ select 1 AS `1` union /* select#3 */ select 2 AS `2`) `__5` union /* select#6 */ select `__6`.`3` AS `3` from (/* select#4 */ select 3 AS `3` union /* select#5 */ select 4 AS `4`) `__6`
(select 1 intersect all select 2)
except
select 3;
1
EXPLAIN EXTENDED (select 1 intersect all select 2)
except
select 3;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
3 INTERSECT NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL INTERSECT RESULT <intersect2,3> ALL NULL NULL NULL NULL NULL NULL
4 EXCEPT NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL EXCEPT RESULT <except1,4> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 /* select#1 */ select `__4`.`1` AS `1` from (/* select#2 */ select 1 AS `1` intersect /* select#3 */ select 2 AS `2`) `__4` except /* select#4 */ select 3 AS `3`
(select 1 intersect all select 2 intersect all select 3)
intersect
(select 4 intersect all select 5);
1
EXPLAIN EXTENDED (select 1 intersect all select 2 intersect all select 3)
intersect
(select 4 intersect all select 5);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
3 INTERSECT NULL NULL NULL NULL NULL NULL NULL NULL No tables used
4 INTERSECT NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL INTERSECT RESULT <intersect2,3,4> ALL NULL NULL NULL NULL NULL NULL
7 INTERSECT <derived5> ALL NULL NULL NULL NULL 2 100.00
5 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
6 INTERSECT NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL INTERSECT RESULT <intersect5,6> ALL NULL NULL NULL NULL NULL NULL
NULL INTERSECT RESULT <intersect1,7> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 /* select#1 */ select `__6`.`1` AS `1` from (/* select#2 */ select 1 AS `1` intersect /* select#3 */ select 2 AS `2` intersect /* select#4 */ select 3 AS `3`) `__6` intersect /* select#7 */ select `__7`.`4` AS `4` from (/* select#5 */ select 4 AS `4` intersect /* select#6 */ select 5 AS `5`) `__7`
# test set operations with table value constructor
(values (1,1),(1,1),(1,1),(2,2),(2,2),(3,3),(9,9))
INTERSECT ALL
(values (1,1),(2,2),(2,2),(3,3),(3,3),(3,3),(8,8))
EXCEPT ALL
(values (7,7),(1,1));
1 1
2 2
2 2
3 3
delete from t1;
insert into t1 values(1,1),(1,1),(2,2),(4,4),(9,9);
select * from t1
UNION ALL
(values (11,12),(3,3),(2,2),(3,3),(4,4),(8,8))
INTERSECT
(values (13,14),(7,7),(2,2),(3,3),(1,1))
INTERSECT ALL
(values (15,16),(2,2),(1,1))
EXCEPT
(values (17,18),(1,1));
a b
2 2
4 4
9 9
# test set operations with derived table
select * from (
select * from t1
UNION ALL
select * from t2
)dt1
INTERSECT ALL
select * from (
select * from t2
EXCEPT ALL
select * from t3
)dt2;
a b
2 2
3 3
5 5
select * from (
select * from t1
UNION ALL
select * from t3
)dt1
EXCEPT ALL
select * from (
select * from t2
INTERSECT ALL
select * from t2
)dt2;
a b
1 1
1 1
4 4
9 9
1 1
4 4
SELECT * from(
select * from (
select * from t1
UNION ALL
select * from t2
)dt1
INTERSECT ALL
select * from (
select * from t2
EXCEPT ALL
select * from t3
)dt2
)dt3;
a b
2 2
3 3
5 5
# integration test
select * from t1
UNION ALL
select * from t2
INTERSECT ALL
(values (1,1), (2,2), (2,2), (5,5), (2,2))
INTERSECT ALL
select * from (select * from t1 union all select * from t1) sq
EXCEPT ALL
select * from t3
UNION ALL
select * from t2
UNION
select * from t3
EXCEPT
select a,c from t1,t2
UNION ALL
select * from v0 where g < 4
UNION ALL
select * from t3;
a b
1 1
1 2
3 3
9 9
5 5
4 4
1 2
2 2
1 3
1 3
2 3
1 5
1 5
2 5
1 2
1 2
2 2
1 2
1 2
2 2
1 3
1 3
2 3
4 4
2 2
2 2
1 1
3 3
select * from t1
UNION ALL
select * from t2
INTERSECT ALL
(values (1,1), (2,2), (2,2), (5,5), (2,2))
INTERSECT ALL
select * from (select * from t1 union all select * from t1) sq
EXCEPT ALL
select * from t3
UNION ALL
select * from t2
UNION
select * from t3
EXCEPT
select a,c from t1,t2
UNION ALL
select * from v0 where g < 4
UNION ALL
select * from t3
ORDER BY a;
a b
1 1
1 1
1 2
1 2
1 2
1 2
1 2
1 2
1 3
1 3
1 3
1 3
1 5
1 5
2 2
2 2
2 2
2 2
2 2
2 3
2 3
2 5
3 3
3 3
4 4
4 4
5 5
9 9
select * from (
select * from t1
UNION ALL
select * from t2
INTERSECT ALL
(values (1,1), (2,2), (2,2), (5,5), (2,2) )
INTERSECT ALL
select * from (select * from t1 union all select * from t1) sq
EXCEPT ALL
select * from t3
UNION ALL
select * from t2
UNION
select * from t3
EXCEPT
select a,c from t1,t2
UNION ALL
select * from v0 where g < 4
UNION ALL
select * from t3
) dt;
a b
1 1
1 2
3 3
9 9
5 5
4 4
1 2
2 2
1 3
1 3
2 3
1 5
1 5
2 5
1 2
1 2
2 2
1 2
1 2
2 2
1 3
1 3
2 3
4 4
2 2
2 2
1 1
3 3
EXPLAIN
select * from t1
UNION ALL
select * from t2
INTERSECT ALL
(values (1,1), (2,2), (2,2), (5,5), (2,2) )
INTERSECT ALL
select * from (select * from t1 union all select * from t1) sq
EXCEPT ALL
select * from t3
UNION ALL
select * from t2
UNION
select * from t3
EXCEPT
select a,c from t1,t2
UNION ALL
select * from v0 where g < 4
UNION ALL
select * from t3;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 5
8 UNION <derived2> ALL NULL NULL NULL NULL 5
2 DERIVED t2 ALL NULL NULL NULL NULL 6
3 INTERSECT NULL NULL NULL NULL NULL NULL NULL No tables used
4 INTERSECT <derived5> ALL NULL NULL NULL NULL 10
5 DERIVED t1 ALL NULL NULL NULL NULL 5
6 UNION t1 ALL NULL NULL NULL NULL 5
NULL INTERSECT RESULT <intersect2,3,4> ALL NULL NULL NULL NULL NULL
7 EXCEPT t3 ALL NULL NULL NULL NULL 5
9 UNION t2 ALL NULL NULL NULL NULL 6
10 UNION t3 ALL NULL NULL NULL NULL 5
11 EXCEPT t1 ALL NULL NULL NULL NULL 5
11 EXCEPT t2 ALL NULL NULL NULL NULL 6 Using join buffer (flat, BNL join)
12 UNION t1 ALL NULL NULL NULL NULL 5 Using where
12 UNION t2 ALL NULL NULL NULL NULL 6 Using join buffer (flat, BNL join)
13 UNION t3 ALL NULL NULL NULL NULL 5
NULL UNIT RESULT <unit1,8,7,9,10,11,12,13> ALL NULL NULL NULL NULL NULL
EXPLAIN format=json
select * from t1
UNION ALL
select * from t2
INTERSECT ALL
(values (1,1), (2,2), (2,2), (5,5), (2,2) )
INTERSECT ALL
select * from (select * from t1 union all select * from t1) sq
EXCEPT ALL
select * from t3
UNION ALL
select * from t2
UNION
select * from t3
EXCEPT
select a,c from t1,t2
UNION ALL
select * from v0 where g < 4
UNION ALL
select * from t3;
EXPLAIN
{
"query_block": {
"union_result": {
"table_name": "<unit1,8,7,9,10,11,12,13>",
"access_type": "ALL",
"query_specifications": [
{
"query_block": {
"select_id": 1,
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 5,
"filtered": 100
}
}
},
{
"query_block": {
"select_id": 8,
"operation": "UNION",
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"rows": 5,
"filtered": 100,
"materialized": {
"query_block": {
"union_result": {
"table_name": "<intersect2,3,4>",
"access_type": "ALL",
"query_specifications": [
{
"query_block": {
"select_id": 2,
"table": {
"table_name": "t2",
"access_type": "ALL",
"rows": 6,
"filtered": 100
}
}
},
{
"query_block": {
"select_id": 3,
"operation": "INTERSECT",
"table": {
"message": "No tables used"
}
}
},
{
"query_block": {
"select_id": 4,
"operation": "INTERSECT",
"table": {
"table_name": "<derived5>",
"access_type": "ALL",
"rows": 10,
"filtered": 100,
"materialized": {
"query_block": {
"union_result": {
"table_name": "<union5,6>",
"access_type": "ALL",
"query_specifications": [
{
"query_block": {
"select_id": 5,
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 5,
"filtered": 100
}
}
},
{
"query_block": {
"select_id": 6,
"operation": "UNION",
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 5,
"filtered": 100
}
}
}
]
}
}
}
}
}
}
]
}
}
}
}
}
},
{
"query_block": {
"select_id": 7,
"operation": "EXCEPT",
"table": {
"table_name": "t3",
"access_type": "ALL",
"rows": 5,
"filtered": 100
}
}
},
{
"query_block": {
"select_id": 9,
"operation": "UNION",
"table": {
"table_name": "t2",
"access_type": "ALL",
"rows": 6,
"filtered": 100
}
}
},
{
"query_block": {
"select_id": 10,
"operation": "UNION",
"table": {
"table_name": "t3",
"access_type": "ALL",
"rows": 5,
"filtered": 100
}
}
},
{
"query_block": {
"select_id": 11,
"operation": "EXCEPT",
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 5,
"filtered": 100
},
"block-nl-join": {
"table": {
"table_name": "t2",
"access_type": "ALL",
"rows": 6,
"filtered": 100
},
"buffer_type": "flat",
"buffer_size": "65",
"join_type": "BNL"
}
}
},
{
"query_block": {
"select_id": 12,
"operation": "UNION",
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 5,
"filtered": 100,
"attached_condition": "t1.a < 4"
},
"block-nl-join": {
"table": {
"table_name": "t2",
"access_type": "ALL",
"rows": 6,
"filtered": 100
},
"buffer_type": "flat",
"buffer_size": "65",
"join_type": "BNL"
}
}
},
{
"query_block": {
"select_id": 13,
"operation": "UNION",
"table": {
"table_name": "t3",
"access_type": "ALL",
"rows": 5,
"filtered": 100
}
}
}
]
}
}
}
EXPLAIN EXTENDED
select * from t1
UNION ALL
select * from t2
INTERSECT ALL
(values (1,1), (2,2), (2,2), (5,5), (2,2) )
INTERSECT ALL
select * from (select * from t1 union all select * from t1) sq
EXCEPT ALL
select * from t3
UNION ALL
select * from t2
UNION
select * from t3
EXCEPT
select a,c from t1,t2
UNION ALL
select * from v0 where g < 4
UNION ALL
select * from t3;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 5 100.00
8 UNION <derived2> ALL NULL NULL NULL NULL 5 100.00
2 DERIVED t2 ALL NULL NULL NULL NULL 6 100.00
3 INTERSECT NULL NULL NULL NULL NULL NULL NULL NULL No tables used
4 INTERSECT <derived5> ALL NULL NULL NULL NULL 10 100.00
5 DERIVED t1 ALL NULL NULL NULL NULL 5 100.00
6 UNION t1 ALL NULL NULL NULL NULL 5 100.00
NULL INTERSECT RESULT <intersect2,3,4> ALL NULL NULL NULL NULL NULL NULL
7 EXCEPT t3 ALL NULL NULL NULL NULL 5 100.00
9 UNION t2 ALL NULL NULL NULL NULL 6 100.00
10 UNION t3 ALL NULL NULL NULL NULL 5 100.00
11 EXCEPT t1 ALL NULL NULL NULL NULL 5 100.00
11 EXCEPT t2 ALL NULL NULL NULL NULL 6 100.00 Using join buffer (flat, BNL join)
12 UNION t1 ALL NULL NULL NULL NULL 5 100.00 Using where
12 UNION t2 ALL NULL NULL NULL NULL 6 100.00 Using join buffer (flat, BNL join)
13 UNION t3 ALL NULL NULL NULL NULL 5 100.00
NULL UNIT RESULT <unit1,8,7,9,10,11,12,13> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` union all /* select#8 */ select `__8`.`c` AS `c`,`__8`.`d` AS `d` from (/* select#2 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` intersect all (values (1,1),(2,2),(2,2),(5,5),(2,2)) intersect all /* select#4 */ select `sq`.`a` AS `a`,`sq`.`b` AS `b` from (/* select#5 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` union all /* select#6 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`) `sq`) `__8` except all /* select#7 */ select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3` union /* select#9 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` union /* select#10 */ select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3` except /* select#11 */ select `test`.`t1`.`a` AS `a`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` union all /* select#12 */ select `test`.`t1`.`a` AS `g`,`test`.`t2`.`c` AS `h` from `test`.`t1` join `test`.`t2` where `test`.`t1`.`a` < 4 union all /* select#13 */ select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3`
PREPARE stmt from"
select * from t1
UNION ALL
select * from t2
INTERSECT ALL
(values (1,1), (2,2), (2,2), (5,5), (2,2) )
INTERSECT ALL
select * from (select * from t1 union all select * from t1) sq
EXCEPT ALL
select * from t3
UNION ALL
select * from t2
UNION
select * from t3
EXCEPT
select a,c from t1,t2
UNION ALL
select * from v0 where g < 4
UNION ALL
select * from t3
";
EXECUTE stmt;
a b
1 1
1 2
3 3
9 9
5 5
4 4
1 2
2 2
1 3
1 3
2 3
1 5
1 5
2 5
1 2
1 2
2 2
1 2
1 2
2 2
1 3
1 3
2 3
4 4
2 2
2 2
1 1
3 3
EXECUTE stmt;
a b
1 1
1 2
3 3
9 9
5 5
4 4
1 2
2 2
1 3
1 3
2 3
1 5
1 5
2 5
1 2
1 2
2 2
1 2
1 2
2 2
1 3
1 3
2 3
4 4
2 2
2 2
1 1
3 3
deallocate prepare stmt;
create view v1(i1, i2) as
select * from t1
UNION ALL
select * from t2
INTERSECT ALL
(values (1,1), (2,2), (2,2), (5,5), (2,2) )
INTERSECT ALL
select * from (select * from t1 union all select * from t1) sq
EXCEPT ALL
select * from t3
UNION ALL
select * from t2
UNION
select * from t3
EXCEPT
select a,c from t1,t2
UNION ALL
select * from v0 where g < 4
UNION ALL
select * from t3;
show create view v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`t1`.`a` AS `i1`,`test`.`t1`.`b` AS `i2` from `test`.`t1` union all select `__9`.`c` AS `c`,`__9`.`d` AS `d` from (select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` intersect all (values (1,1),(2,2),(2,2),(5,5),(2,2)) intersect all select `sq`.`a` AS `a`,`sq`.`b` AS `b` from (select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` union all select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1`) `sq`) `__9` except all select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3` union all select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` union select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3` except select `test`.`t1`.`a` AS `a`,`test`.`t2`.`c` AS `c` from (`test`.`t1` join `test`.`t2`) union all select `v0`.`g` AS `g`,`v0`.`h` AS `h` from `test`.`v0` where `v0`.`g` < 4 union all select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3` latin1 latin1_swedish_ci
select * from v1 limit 14;
i1 i2
1 1
1 2
3 3
9 9
5 5
4 4
1 2
2 2
1 3
1 3
2 3
1 5
1 5
2 5
select * from v1 order by i1 limit 14;
i1 i2
1 1
1 1
1 2
1 2
1 2
1 2
1 2
1 2
1 3
1 3
1 3
1 3
1 5
1 5
drop table t1,t2,t3;
drop view v0,v1;
# compare result
create table t1 (a int, b int);
create table t2 (c int, d int);
create table t3 (e int, f int);
create table t4 (g int, h int);
insert into t1 values (1,1),(1,1),(2,2);
insert into t2 values (1,1),(1,1),(2,2),(3,3);
insert into t3 values (1,1);
insert into t4 values (4,4);
select * from t1 intersect all select * from t2 except select * from t3 union select * from t4;
a b
4 4
2 2
select * from t1 intersect all select * from t2 except ALL select * from t3 union select * from t4;
a b
1 1
2 2
4 4
select * from t1 intersect DISTINCT select * from t2 except select * from t3 union select * from t4;
a b
4 4
2 2
select * from t1 intersect DISTINCT select * from t2 except ALL select * from t3 union select * from t4;
a b
4 4
2 2
delete from t1;
delete from t2;
delete from t3;
delete from t4;
insert into t1 values (1,1),(1,1),(1,1),(2,2),(2,2),(4,4),(5,5);
insert into t2 values (1,1),(1,1),(1,1),(2,2),(2,2),(3,3);
insert into t3 values (1,1),(2,2),(2,2);
select * from t1 intersect all select * from t2 intersect all select * from t3;
a b
1 1
2 2
2 2
select * from t1 intersect all select * from t2 intersect select * from t3;
a b
1 1
2 2
select * from t1 intersect all select * from t1 intersect all select * from t2 intersect select * from t3;
a b
1 1
2 2
delete from t1;
delete from t2;
delete from t3;
insert into t1 values (1,1),(1,1),(2,2);
insert into t2 values (1,1),(1,1),(2,2),(3,3);
insert into t3 values (1,1),(5,5);
insert into t4 values (4,4),(4,4),(4,4);
select * from t1 intersect all select * from t2 union all select * from t3 union select * from t4;
a b
1 1
2 2
5 5
4 4
select * from t1 intersect DISTINCT select * from t2 union DISTINCT select * from t3 union select * from t4;
a b
1 1
2 2
5 5
4 4
select * from t1 intersect all select * from t2 intersect all select * from t3 union select * from t4;
a b
1 1
4 4
select * from t1 intersect all select * from t2 intersect DISTINCT select * from t3 union select * from t4;
a b
1 1
4 4
select * from t1 intersect DISTINCT select * from t2 intersect DISTINCT select * from t3 union select * from t4;
a b
1 1
4 4
select * from t1 intersect all select * from t2 EXCEPT select * from t3 union select * from t4;
a b
4 4
2 2
select * from t1 intersect DISTINCT select * from t2 EXCEPT select * from t3 union select * from t4;
a b
4 4
2 2
select * from t1 intersect all select * from t2 EXCEPT ALL select * from t3 union select * from t4;
a b
1 1
2 2
4 4
select * from t1 EXCEPT select * from t2 union all select * from t3 union select * from t4;
a b
5 5
1 1
4 4
select * from t1 EXCEPT select * from t2 union DISTINCT select * from t3 union select * from t4;
a b
5 5
1 1
4 4
delete from t1;
delete from t2;
delete from t3;
delete from t4;
insert into t1 values (1,1),(2,2);
insert into t2 values (1,1),(2,2);
insert into t3 values (1,1),(3,3);
select * from t1 union all select * from t2 except all select * from t3;
a b
1 1
2 2
2 2
select * from t1 union all select * from t2 except DISTINCT select * from t3;
a b
2 2
select * from t1 union DISTINCT select * from t2 except all select * from t3;
a b
2 2
select * from t1 union DISTINCT select * from t2 except DISTINCT select * from t3;
a b
2 2
drop table t1;
drop table t2;
drop table t3;
drop table t4;
select 1 intersect all select 2 intersect all select 3 intersect select 4 union select 5;
1
5
select 1 intersect all select 2 intersect all select 3 union select 4 except select 5;
1
4
select 1 union select 2 except all select 3 union select 4;
1
1
2
4
select 1 union all select 2 union all select 3 union select 4;
1
1
2
3
4
# test with limited resource
set @@max_heap_table_size= 1024;
Warnings:
Warning 1292 Truncated incorrect max_heap_table_size value: '1024'
set @@tmp_table_size= 1024;
create table t1 (a int, b int);
insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(0,0);
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select a+100, b+100 from t1;
create table t2 (a int, b int);
insert into t2 values (10,10),(11,11),(12,12),(13,13),(14,14),(5,5),(6,6),(7,7),(8,8),(9,9);
insert into t2 select * from t2;
insert into t2 select * from t2;
insert into t2 select * from t2;
insert into t2 select a+100, b+100 from t2;
select count(*) from
(
select * from t1
INTERSECT ALL
select * from t2
) c;
count(*)
80
select count(*) from
(
select * from t1
EXCEPT ALL
select * from t2
) c;
count(*)
80
select count(*) from
(
select * from t1
INTERSECT ALL
select * from t2
UNION ALL
select * from t1
EXCEPT ALL
select * from t2
) c;
count(*)
160
delete from t1;
delete from t2;
insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(0,0);
insert into t1 select a+10, b+10 from t1;
insert into t1 select a+20, b+20 from t1;
insert into t1 select a+40, b+40 from t1;
insert into t1 select a+80, b+80 from t1;
insert into t2 values (1110,1110),(1111,1111),(1112,1112),(1113,1113),(1114,1114),(1105,1105),(1106,1106),(1107,1107),(1108,1108),(1109,1109);
insert into t2 select a+10, b+10 from t2;
insert into t2 select a+20, b+20 from t2;
insert into t2 select a+40, b+40 from t2;
insert into t2 select a+80, b+80 from t2;
select count(*) from
(
select * from t1
UNION ALL
select * from t2
EXCEPT ALL
values (1,1)
) c;
count(*)
319
drop table t1;
drop table t2;
create table t1 (a int, b int) engine=MyISAM;
create table t2 (c int, d int) engine=MyISAM;
create table t3 (e int, f int) engine=MyISAM;
create table t4 (g int, h int) engine=MyISAM;
insert into t1 values (1,1),(2,2),(3,3),(2,2),(3,3);
insert into t2 values (2,2),(3,3),(5,5),(2,2),(2,2),(3,3);
insert into t3 values (4,4),(2,2),(2,2),(1,1),(3,3);
insert into t4 values (2,2),(4,4),(1,1);
create view v0(g, h) as select a,c from t1,t2;
--echo # test optimization
let $q=
select * from t1
INTERSECT ALL
select * from t2
INTERSECT ALL
select * from t3;
eval $q;
eval EXPLAIN EXTENDED $q;
let $q=
select * from t1
INTERSECT ALL
select * from t2
INTERSECT ALL
select * from t3
INTERSECT
select * from t1;
eval $q;
eval EXPLAIN EXTENDED $q;
let $q=
select * from t1
INTERSECT ALL
select * from t2
INTERSECT ALL
select * from t3
EXCEPT ALL
select * from t4;
eval $q;
eval EXPLAIN EXTENDED $q;
let $q=
select * from t1
INTERSECT
select * from t2
EXCEPT ALL
select * from t4;
eval $q;
eval EXPLAIN EXTENDED $q;
insert into t4 values (1,1),(9,9);
let $q=
select * from t1
UNION ALL
select * from t2
UNION ALL
select * from t3
EXCEPT
select * from t4;
eval $q;
eval EXPLAIN EXTENDED $q;
delete from t4;
insert into t4 values (3,3),(3,3);
let $q=
select * from t1
INTERSECT ALL
select * from t2
UNION ALL
select * from t3
EXCEPT ALL
select * from t1
UNION
select * from t4
EXCEPT
select * from t3
UNION ALL
select * from t1;
eval $q;
eval EXPLAIN EXTENDED $q;
drop table t4;
--echo # test optimization with brackets
let $q=
(
(select 1 except select 5 union all select 6)
union
(select 2 intersect all select 3 intersect all select 4)
except
(select 7 intersect all select 8)
)
union all
(select 9 union all select 10)
except all
select 11;
eval $q;
eval EXPLAIN EXTENDED $q;
let $q=
(select 1 union all select 2)
union
(select 3 union all select 4);
eval $q;
eval EXPLAIN EXTENDED $q;
let $q=
(select 1 intersect all select 2)
except
select 3;
eval $q;
eval EXPLAIN EXTENDED $q;
let $q=
(select 1 intersect all select 2 intersect all select 3)
intersect
(select 4 intersect all select 5);
eval $q;
eval EXPLAIN EXTENDED $q;
--echo # test set operations with table value constructor
(values (1,1),(1,1),(1,1),(2,2),(2,2),(3,3),(9,9))
INTERSECT ALL
(values (1,1),(2,2),(2,2),(3,3),(3,3),(3,3),(8,8))
EXCEPT ALL
(values (7,7),(1,1));
delete from t1;
insert into t1 values(1,1),(1,1),(2,2),(4,4),(9,9);
select * from t1
UNION ALL
(values (11,12),(3,3),(2,2),(3,3),(4,4),(8,8))
INTERSECT
(values (13,14),(7,7),(2,2),(3,3),(1,1))
INTERSECT ALL
(values (15,16),(2,2),(1,1))
EXCEPT
(values (17,18),(1,1));
--echo # test set operations with derived table
select * from (
select * from t1
UNION ALL
select * from t2
)dt1
INTERSECT ALL
select * from (
select * from t2
EXCEPT ALL
select * from t3
)dt2;
select * from (
select * from t1
UNION ALL
select * from t3
)dt1
EXCEPT ALL
select * from (
select * from t2
INTERSECT ALL
select * from t2
)dt2;
SELECT * from(
select * from (
select * from t1
UNION ALL
select * from t2
)dt1
INTERSECT ALL
select * from (
select * from t2
EXCEPT ALL
select * from t3
)dt2
)dt3;
--echo # integration test
select * from t1
UNION ALL
select * from t2
INTERSECT ALL
(values (1,1), (2,2), (2,2), (5,5), (2,2))
INTERSECT ALL
select * from (select * from t1 union all select * from t1) sq
EXCEPT ALL
select * from t3
UNION ALL
select * from t2
UNION
select * from t3
EXCEPT
select a,c from t1,t2
UNION ALL
select * from v0 where g < 4
UNION ALL
select * from t3;
--sorted_result
select * from t1
UNION ALL
select * from t2
INTERSECT ALL
(values (1,1), (2,2), (2,2), (5,5), (2,2))
INTERSECT ALL
select * from (select * from t1 union all select * from t1) sq
EXCEPT ALL
select * from t3
UNION ALL
select * from t2
UNION
select * from t3
EXCEPT
select a,c from t1,t2
UNION ALL
select * from v0 where g < 4
UNION ALL
select * from t3
ORDER BY a;
select * from (
select * from t1
UNION ALL
select * from t2
INTERSECT ALL
(values (1,1), (2,2), (2,2), (5,5), (2,2) )
INTERSECT ALL
select * from (select * from t1 union all select * from t1) sq
EXCEPT ALL
select * from t3
UNION ALL
select * from t2
UNION
select * from t3
EXCEPT
select a,c from t1,t2
UNION ALL
select * from v0 where g < 4
UNION ALL
select * from t3
) dt;
EXPLAIN
select * from t1
UNION ALL
select * from t2
INTERSECT ALL
(values (1,1), (2,2), (2,2), (5,5), (2,2) )
INTERSECT ALL
select * from (select * from t1 union all select * from t1) sq
EXCEPT ALL
select * from t3
UNION ALL
select * from t2
UNION
select * from t3
EXCEPT
select a,c from t1,t2
UNION ALL
select * from v0 where g < 4
UNION ALL
select * from t3;
EXPLAIN format=json
select * from t1
UNION ALL
select * from t2
INTERSECT ALL
(values (1,1), (2,2), (2,2), (5,5), (2,2) )
INTERSECT ALL
select * from (select * from t1 union all select * from t1) sq
EXCEPT ALL
select * from t3
UNION ALL
select * from t2
UNION
select * from t3
EXCEPT
select a,c from t1,t2
UNION ALL
select * from v0 where g < 4
UNION ALL
select * from t3;
EXPLAIN EXTENDED
select * from t1
UNION ALL
select * from t2
INTERSECT ALL
(values (1,1), (2,2), (2,2), (5,5), (2,2) )
INTERSECT ALL
select * from (select * from t1 union all select * from t1) sq
EXCEPT ALL
select * from t3
UNION ALL
select * from t2
UNION
select * from t3
EXCEPT
select a,c from t1,t2
UNION ALL
select * from v0 where g < 4
UNION ALL
select * from t3;
PREPARE stmt from"
select * from t1
UNION ALL
select * from t2
INTERSECT ALL
(values (1,1), (2,2), (2,2), (5,5), (2,2) )
INTERSECT ALL
select * from (select * from t1 union all select * from t1) sq
EXCEPT ALL
select * from t3
UNION ALL
select * from t2
UNION
select * from t3
EXCEPT
select a,c from t1,t2
UNION ALL
select * from v0 where g < 4
UNION ALL
select * from t3
";
EXECUTE stmt;
EXECUTE stmt;
deallocate prepare stmt;
create view v1(i1, i2) as
select * from t1
UNION ALL
select * from t2
INTERSECT ALL
(values (1,1), (2,2), (2,2), (5,5), (2,2) )
INTERSECT ALL
select * from (select * from t1 union all select * from t1) sq
EXCEPT ALL
select * from t3
UNION ALL
select * from t2
UNION
select * from t3
EXCEPT
select a,c from t1,t2
UNION ALL
select * from v0 where g < 4
UNION ALL
select * from t3;
show create view v1;
select * from v1 limit 14;
--sorted_result
select * from v1 order by i1 limit 14;
drop table t1,t2,t3;
drop view v0,v1;
--echo # compare result
create table t1 (a int, b int);
create table t2 (c int, d int);
create table t3 (e int, f int);
create table t4 (g int, h int);
insert into t1 values (1,1),(1,1),(2,2);
insert into t2 values (1,1),(1,1),(2,2),(3,3);
insert into t3 values (1,1);
insert into t4 values (4,4);
select * from t1 intersect all select * from t2 except select * from t3 union select * from t4;
select * from t1 intersect all select * from t2 except ALL select * from t3 union select * from t4;
select * from t1 intersect DISTINCT select * from t2 except select * from t3 union select * from t4;
select * from t1 intersect DISTINCT select * from t2 except ALL select * from t3 union select * from t4;
delete from t1;
delete from t2;
delete from t3;
delete from t4;
insert into t1 values (1,1),(1,1),(1,1),(2,2),(2,2),(4,4),(5,5);
insert into t2 values (1,1),(1,1),(1,1),(2,2),(2,2),(3,3);
insert into t3 values (1,1),(2,2),(2,2);
select * from t1 intersect all select * from t2 intersect all select * from t3;
select * from t1 intersect all select * from t2 intersect select * from t3;
select * from t1 intersect all select * from t1 intersect all select * from t2 intersect select * from t3;
delete from t1;
delete from t2;
delete from t3;
insert into t1 values (1,1),(1,1),(2,2);
insert into t2 values (1,1),(1,1),(2,2),(3,3);
insert into t3 values (1,1),(5,5);
insert into t4 values (4,4),(4,4),(4,4);
select * from t1 intersect all select * from t2 union all select * from t3 union select * from t4;
select * from t1 intersect DISTINCT select * from t2 union DISTINCT select * from t3 union select * from t4;
select * from t1 intersect all select * from t2 intersect all select * from t3 union select * from t4;
select * from t1 intersect all select * from t2 intersect DISTINCT select * from t3 union select * from t4;
select * from t1 intersect DISTINCT select * from t2 intersect DISTINCT select * from t3 union select * from t4;
select * from t1 intersect all select * from t2 EXCEPT select * from t3 union select * from t4;
select * from t1 intersect DISTINCT select * from t2 EXCEPT select * from t3 union select * from t4;
select * from t1 intersect all select * from t2 EXCEPT ALL select * from t3 union select * from t4;
select * from t1 EXCEPT select * from t2 union all select * from t3 union select * from t4;
select * from t1 EXCEPT select * from t2 union DISTINCT select * from t3 union select * from t4;
delete from t1;
delete from t2;
delete from t3;
delete from t4;
insert into t1 values (1,1),(2,2);
insert into t2 values (1,1),(2,2);
insert into t3 values (1,1),(3,3);
select * from t1 union all select * from t2 except all select * from t3;
select * from t1 union all select * from t2 except DISTINCT select * from t3;
select * from t1 union DISTINCT select * from t2 except all select * from t3;
select * from t1 union DISTINCT select * from t2 except DISTINCT select * from t3;
drop table t1;
drop table t2;
drop table t3;
drop table t4;
select 1 intersect all select 2 intersect all select 3 intersect select 4 union select 5;
select 1 intersect all select 2 intersect all select 3 union select 4 except select 5;
select 1 union select 2 except all select 3 union select 4;
select 1 union all select 2 union all select 3 union select 4;
--echo # test with limited resource
set @@max_heap_table_size= 1024;
set @@tmp_table_size= 1024;
create table t1 (a int, b int);
insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(0,0);
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select a+100, b+100 from t1;
create table t2 (a int, b int);
insert into t2 values (10,10),(11,11),(12,12),(13,13),(14,14),(5,5),(6,6),(7,7),(8,8),(9,9);
insert into t2 select * from t2;
insert into t2 select * from t2;
insert into t2 select * from t2;
insert into t2 select a+100, b+100 from t2;
select count(*) from
(
select * from t1
INTERSECT ALL
select * from t2
) c;
select count(*) from
(
select * from t1
EXCEPT ALL
select * from t2
) c;
select count(*) from
(
select * from t1
INTERSECT ALL
select * from t2
UNION ALL
select * from t1
EXCEPT ALL
select * from t2
) c;
delete from t1;
delete from t2;
insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(0,0);
insert into t1 select a+10, b+10 from t1;
insert into t1 select a+20, b+20 from t1;
insert into t1 select a+40, b+40 from t1;
insert into t1 select a+80, b+80 from t1;
insert into t2 values (1110,1110),(1111,1111),(1112,1112),(1113,1113),(1114,1114),(1105,1105),(1106,1106),(1107,1107),(1108,1108),(1109,1109);
insert into t2 select a+10, b+10 from t2;
insert into t2 select a+20, b+20 from t2;
insert into t2 select a+40, b+40 from t2;
insert into t2 select a+80, b+80 from t2;
select count(*) from
(
select * from t1
UNION ALL
select * from t2
EXCEPT ALL
values (1,1)
) c;
drop table t1;
drop table t2;
create table t1 (a int, b blob) engine=MyISAM;
create table t2 (c int, d blob) engine=MyISAM;
create table t3 (e int, f blob) engine=MyISAM;
insert into t1 values (5,5),(6,6);
insert into t2 values (2,2),(3,3);
insert into t3 values (1,1),(3,3);
set SQL_MODE=ORACLE;
(select a,b from t1) union (select c,d from t2) intersect (select e,f from t3) union (select 4,4);
a b
4 4
3 3
explain extended
(select a,b from t1) union (select c,d from t2) intersect (select e,f from t3) union (select 4,4);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
2 UNION t2 ALL NULL NULL NULL NULL 2 100.00
3 INTERSECT t3 ALL NULL NULL NULL NULL 2 100.00
4 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNIT RESULT <unit1,2,3,4> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 (/* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1") union (/* select#2 */ select "test"."t2"."c" AS "c","test"."t2"."d" AS "d" from "test"."t2") intersect (/* select#3 */ select "test"."t3"."e" AS "e","test"."t3"."f" AS "f" from "test"."t3") union (/* select#4 */ select 4 AS "4",4 AS "4")
(select e,f from t3) intersect (select c,d from t2) union (select a,b from t1) union (select 4,4);
e f
5 5
3 3
6 6
4 4
explain extended
(select e,f from t3) intersect (select c,d from t2) union (select a,b from t1) union (select 4,4);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 2 100.00
2 INTERSECT t2 ALL NULL NULL NULL NULL 2 100.00
3 UNION t1 ALL NULL NULL NULL NULL 2 100.00
4 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNIT RESULT <unit1,2,3,4> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 (/* select#1 */ select "test"."t3"."e" AS "e","test"."t3"."f" AS "f" from "test"."t3") intersect (/* select#2 */ select "test"."t2"."c" AS "c","test"."t2"."d" AS "d" from "test"."t2") union (/* select#3 */ select "test"."t1"."a" AS "a","test"."t1"."b" AS "b" from "test"."t1") union (/* select#4 */ select 4 AS "4",4 AS "4")
create table t12(c1 int);
insert into t12 values(1);
insert into t12 values(2);
create table t13(c1 int);
insert into t13 values(1);
insert into t13 values(3);
create table t234(c1 int);
insert into t234 values(2);
insert into t234 values(3);
insert into t234 values(4);
select * from t13 union select * from t234 intersect select * from t12;
c1
1
2
set SQL_MODE=default;
drop table t1,t2,t3;
drop table t12,t13, t234;
create table t1 (a int, b blob) engine=MyISAM;
create table t2 (c int, d blob) engine=MyISAM;
create table t3 (e int, f blob) engine=MyISAM;
insert into t1 values (5,5),(6,6);
insert into t2 values (2,2),(3,3);
insert into t3 values (1,1),(3,3);
set SQL_MODE=ORACLE;
(select a,b from t1) union all (select c,d from t2) intersect all (select e,f from t3) union all (select 4,4);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'all (select e,f from t3) union all (select 4,4)' at line 1
explain extended (select a,b from t1) union all (select c,d from t2) intersect all (select e,f from t3) union all (select 4,4);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'all (select e,f from t3) union all (select 4,4)' at line 1
(select e,f from t3) intersect all (select c,d from t2) union all (select a,b from t1) union all (select 4,4);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'all (select c,d from t2) union all (select a,b from t1) union all (select 4,4)' at line 1
explain extended (select e,f from t3) intersect all (select c,d from t2) union all (select a,b from t1) union all (select 4,4);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'all (select c,d from t2) union all (select a,b from t1) union all (select 4,4)' at line 1
set SQL_MODE=default;
drop table t1,t2,t3;
set SQL_MODE=oracle;
select * from t13 union select * from t234 intersect all select * from t12;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'all select * from t12' at line 1
set SQL_MODE=default;
# from intersect.test
create table t1 (a int, b blob) engine=MyISAM;
create table t2 (c int, d blob) engine=MyISAM;
create table t3 (e int, f blob) engine=MyISAM;
insert into t1 values (5,5),(6,6);
insert into t2 values (2,2),(3,3);
insert into t3 values (1,1),(3,3);
set SQL_MODE=ORACLE;
(select a,b from t1) union (select c,d from t2) intersect (select e,f from t3) union (select 4,4);
explain extended
(select a,b from t1) union (select c,d from t2) intersect (select e,f from t3) union (select 4,4);
(select e,f from t3) intersect (select c,d from t2) union (select a,b from t1) union (select 4,4);
explain extended
(select e,f from t3) intersect (select c,d from t2) union (select a,b from t1) union (select 4,4);
create table t12(c1 int);
insert into t12 values(1);
insert into t12 values(2);
create table t13(c1 int);
insert into t13 values(1);
insert into t13 values(3);
create table t234(c1 int);
insert into t234 values(2);
insert into t234 values(3);
insert into t234 values(4);
select * from t13 union select * from t234 intersect select * from t12;
set SQL_MODE=default;
drop table t1,t2,t3;
drop table t12,t13, t234;
#from intersect_all.test
create table t1 (a int, b blob) engine=MyISAM;
create table t2 (c int, d blob) engine=MyISAM;
create table t3 (e int, f blob) engine=MyISAM;
insert into t1 values (5,5),(6,6);
insert into t2 values (2,2),(3,3);
insert into t3 values (1,1),(3,3);
set SQL_MODE=ORACLE;
#(select a,b from t1) union all (select c,d from t2) intersect (select e,f from t3) union all (select 4,4);
--error ER_PARSE_ERROR
(select a,b from t1) union all (select c,d from t2) intersect all (select e,f from t3) union all (select 4,4);
--error ER_PARSE_ERROR
explain extended (select a,b from t1) union all (select c,d from t2) intersect all (select e,f from t3) union all (select 4,4);
--error ER_PARSE_ERROR
(select e,f from t3) intersect all (select c,d from t2) union all (select a,b from t1) union all (select 4,4);
--error ER_PARSE_ERROR
explain extended (select e,f from t3) intersect all (select c,d from t2) union all (select a,b from t1) union all (select 4,4);
set SQL_MODE=default;
drop table t1,t2,t3;
set SQL_MODE=oracle;
--error ER_PARSE_ERROR
select * from t13 union select * from t234 intersect all select * from t12;
set SQL_MODE=default;
\ No newline at end of file
...@@ -5708,17 +5708,18 @@ class TMP_TABLE_PARAM :public Sql_alloc ...@@ -5708,17 +5708,18 @@ class TMP_TABLE_PARAM :public Sql_alloc
class select_unit :public select_result_interceptor class select_unit :public select_result_interceptor
{ {
public:
uint curr_step, prev_step, curr_sel; uint curr_step, prev_step, curr_sel;
enum sub_select_type step; enum sub_select_type step;
public: public:
Item_int *intersect_mark;
TMP_TABLE_PARAM tmp_table_param; TMP_TABLE_PARAM tmp_table_param;
/* Number of additional (hidden) field of the used temporary table */
int addon_cnt;
int write_err; /* Error code from the last send_data->ha_write_row call. */ int write_err; /* Error code from the last send_data->ha_write_row call. */
TABLE *table; TABLE *table;
select_unit(THD *thd_arg): select_unit(THD *thd_arg):
select_result_interceptor(thd_arg), select_result_interceptor(thd_arg), addon_cnt(0), table(0)
intersect_mark(0), table(0)
{ {
init(); init();
tmp_table_param.init(); tmp_table_param.init();
...@@ -5735,6 +5736,9 @@ class select_unit :public select_result_interceptor ...@@ -5735,6 +5736,9 @@ class select_unit :public select_result_interceptor
virtual bool postponed_prepare(List<Item> &types) virtual bool postponed_prepare(List<Item> &types)
{ return false; } { return false; }
int send_data(List<Item> &items); int send_data(List<Item> &items);
int write_record();
int update_counter(Field *counter, longlong value);
int delete_record();
bool send_eof(); bool send_eof();
virtual bool flush(); virtual bool flush();
void cleanup(); void cleanup();
...@@ -5753,7 +5757,148 @@ class select_unit :public select_result_interceptor ...@@ -5753,7 +5757,148 @@ class select_unit :public select_result_interceptor
step= UNION_TYPE; step= UNION_TYPE;
write_err= 0; write_err= 0;
} }
virtual void change_select();
virtual bool force_enable_index_if_needed() { return false; }
};
/**
@class select_unit_ext
The class used when processing rows produced by operands of query expressions
containing INTERSECT ALL and/or EXCEPT all operations. One or two extra fields
of the temporary to store the rows of the partial and final result can be employed.
Both of them contain counters. The second additional field is used only when
the processed query expression contains INTERSECT ALL.
Consider how these extra fields are used.
Let
table t1 (f char(8))
table t2 (f char(8))
table t3 (f char(8))
contain the following sets:
("b"),("a"),("d"),("c"),("b"),("a"),("c"),("a")
("c"),("b"),("c"),("c"),("a"),("b"),("g")
("c"),("a"),("b"),("d"),("b"),("e")
- Let's demonstrate how the the set operation INTERSECT ALL is proceesed
for the query
SELECT f FROM t1 INTERSECT ALL SELECT f FROM t2
When send_data() is called for the rows of the first operand we put
the processed record into the temporary table if there was no such record
setting dup_cnt field to 1 and add_cnt field to 0 and increment the
counter in the dup_cnt field by one otherwise. We get
|add_cnt|dup_cnt| f |
|0 |2 |b |
|0 |3 |a |
|0 |1 |d |
|0 |2 |c |
The call of send_eof() for the first operand swaps the values stored in
dup_cnt and add_cnt. After this, we'll see the following rows in the
temporary table
|add_cnt|dup_cnt| f |
|2 |0 |b |
|3 |0 |a |
|1 |0 |d |
|2 |0 |c |
When send_data() is called for the rows of the second operand we increment
the counter in dup_cnt if the processed row is found in the table and do
nothing otherwise. As a result we get
|add_cnt|dup_cnt| f |
|2 |2 |b |
|3 |1 |a |
|1 |0 |d |
|2 |3 |c |
At the call of send_eof() for the second operand first we disable index.
Then for each record, the minimum of counters from dup_cnt and add_cnt m is
taken. If m == 0 then the record is deleted. Otherwise record is replaced
with m copies of it. Yet the counter in this copies are set to 1 for
dup_cnt and to 0 for add_cnt
|add_cnt|dup_cnt| f |
|0 |1 |b |
|0 |1 |b |
|0 |1 |a |
|0 |1 |c |
|0 |1 |c |
- Let's demonstrate how the the set operation EXCEPT ALL is proceesed
for the query
SELECT f FROM t1 EXCEPT ALL SELECT f FROM t3
Only one additional counter field dup_cnt is used for EXCEPT ALL.
After the first operand has been processed we have in the temporary table
|dup_cnt| f |
|2 |b |
|3 |a |
|1 |d |
|2 |c |
When send_data() is called for the rows of the second operand we decrement
the counter in dup_cnt if the processed row is found in the table and do
nothing otherwise. If the counter becomes 0 we delete the record
|dup_cnt| f |
|2 |a |
|1 |c |
Finally at the call of send_eof() for the second operand we disable index
unfold rows adding duplicates
|dup_cnt| f |
|1 |a |
|1 |a |
|1 |c |
*/
class select_unit_ext :public select_unit
{
public:
select_unit_ext(THD *thd_arg):
select_unit(thd_arg), increment(0), is_index_enabled(TRUE),
curr_op_type(UNSPECIFIED)
{
};
int send_data(List<Item> &items);
void change_select(); void change_select();
int unfold_record(int cnt);
bool send_eof();
bool force_enable_index_if_needed()
{
is_index_enabled= true;
return true;
}
bool disable_index_if_needed(SELECT_LEX *curr_sl);
/*
How to change increment/decrement the counter in duplicate_cnt field
when processing a record produced by the current operand in send_data().
The value can be 1 or -1
*/
int increment;
/* TRUE <=> the index of the result temporary table is enabled */
bool is_index_enabled;
/* The type of the set operation currently executed */
enum set_op_type curr_op_type;
/*
Points to the extra field of the temporary table where
duplicate counters are stored
*/
Field *duplicate_cnt;
/*
Points to the extra field of the temporary table where additional
counters used only for INTERSECT ALL operations are stored
*/
Field *additional_cnt;
}; };
class select_union_recursive :public select_unit class select_union_recursive :public select_unit
......
...@@ -2354,6 +2354,7 @@ void st_select_lex_unit::init_query() ...@@ -2354,6 +2354,7 @@ void st_select_lex_unit::init_query()
offset_limit_cnt= 0; offset_limit_cnt= 0;
union_distinct= 0; union_distinct= 0;
prepared= optimized= optimized_2= executed= 0; prepared= optimized= optimized_2= executed= 0;
bag_set_op_optimized= 0;
optimize_started= 0; optimize_started= 0;
item= 0; item= 0;
union_result= 0; union_result= 0;
...@@ -2369,8 +2370,8 @@ void st_select_lex_unit::init_query() ...@@ -2369,8 +2370,8 @@ void st_select_lex_unit::init_query()
with_clause= 0; with_clause= 0;
with_element= 0; with_element= 0;
columns_are_renamed= false; columns_are_renamed= false;
intersect_mark= NULL;
with_wrapped_tvc= false; with_wrapped_tvc= false;
have_except_all_or_intersect_all= false;
} }
void st_select_lex::init_query() void st_select_lex::init_query()
...@@ -2468,6 +2469,7 @@ void st_select_lex::init_select() ...@@ -2468,6 +2469,7 @@ void st_select_lex::init_select()
curr_tvc_name= 0; curr_tvc_name= 0;
in_tvc= false; in_tvc= false;
versioned_tables= 0; versioned_tables= 0;
nest_flags= 0;
} }
/* /*
...@@ -2986,7 +2988,6 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num) ...@@ -2986,7 +2988,6 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
void st_select_lex_unit::print(String *str, enum_query_type query_type) void st_select_lex_unit::print(String *str, enum_query_type query_type)
{ {
bool union_all= !union_distinct;
if (with_clause) if (with_clause)
with_clause->print(str, query_type); with_clause->print(str, query_type);
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select()) for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
...@@ -2999,8 +3000,6 @@ void st_select_lex_unit::print(String *str, enum_query_type query_type) ...@@ -2999,8 +3000,6 @@ void st_select_lex_unit::print(String *str, enum_query_type query_type)
DBUG_ASSERT(0); DBUG_ASSERT(0);
case UNION_TYPE: case UNION_TYPE:
str->append(STRING_WITH_LEN(" union ")); str->append(STRING_WITH_LEN(" union "));
if (union_all)
str->append(STRING_WITH_LEN("all "));
break; break;
case INTERSECT_TYPE: case INTERSECT_TYPE:
str->append(STRING_WITH_LEN(" intersect ")); str->append(STRING_WITH_LEN(" intersect "));
...@@ -3009,8 +3008,8 @@ void st_select_lex_unit::print(String *str, enum_query_type query_type) ...@@ -3009,8 +3008,8 @@ void st_select_lex_unit::print(String *str, enum_query_type query_type)
str->append(STRING_WITH_LEN(" except ")); str->append(STRING_WITH_LEN(" except "));
break; break;
} }
if (sl == union_distinct) if (!sl->distinct)
union_all= TRUE; str->append(STRING_WITH_LEN("all "));
} }
if (sl->braces) if (sl->braces)
str->append('('); str->append('(');
...@@ -3523,6 +3522,8 @@ bool st_select_lex_unit::union_needs_tmp_table() ...@@ -3523,6 +3522,8 @@ bool st_select_lex_unit::union_needs_tmp_table()
with_wrapped_tvc= true; with_wrapped_tvc= true;
break; break;
} }
if (sl != first_select() && sl->linkage != UNION_TYPE)
return true;
} }
} }
if (with_wrapped_tvc) if (with_wrapped_tvc)
...@@ -5394,7 +5395,7 @@ LEX::wrap_unit_into_derived(SELECT_LEX_UNIT *unit) ...@@ -5394,7 +5395,7 @@ LEX::wrap_unit_into_derived(SELECT_LEX_UNIT *unit)
Name_resolution_context *context= &wrapping_sel->context; Name_resolution_context *context= &wrapping_sel->context;
context->init(); context->init();
wrapping_sel->automatic_brackets= FALSE; wrapping_sel->automatic_brackets= FALSE;
wrapping_sel->mark_as_unit_nest();
wrapping_sel->register_unit(unit, context); wrapping_sel->register_unit(unit, context);
/* stuff dummy SELECT * FROM (...) */ /* stuff dummy SELECT * FROM (...) */
......
...@@ -207,6 +207,14 @@ enum sub_select_type ...@@ -207,6 +207,14 @@ enum sub_select_type
GLOBAL_OPTIONS_TYPE, DERIVED_TABLE_TYPE, OLAP_TYPE GLOBAL_OPTIONS_TYPE, DERIVED_TABLE_TYPE, OLAP_TYPE
}; };
enum set_op_type
{
UNSPECIFIED,
UNION_DISTINCT, UNION_ALL,
EXCEPT_DISTINCT, EXCEPT_ALL,
INTERSECT_DISTINCT, INTERSECT_ALL
};
inline int cmp_unit_op(enum sub_select_type op1, enum sub_select_type op2) inline int cmp_unit_op(enum sub_select_type op1, enum sub_select_type op2)
{ {
DBUG_ASSERT(op1 >= UNION_TYPE && op1 <= EXCEPT_TYPE); DBUG_ASSERT(op1 >= UNION_TYPE && op1 <= EXCEPT_TYPE);
...@@ -841,8 +849,8 @@ class st_select_lex_unit: public st_select_lex_node { ...@@ -841,8 +849,8 @@ class st_select_lex_unit: public st_select_lex_node {
// Ensures that at least all members used during cleanup() are initialized. // Ensures that at least all members used during cleanup() are initialized.
st_select_lex_unit() st_select_lex_unit()
: union_result(NULL), table(NULL), result(NULL), : union_result(NULL), table(NULL), result(NULL),
cleaned(false), cleaned(false), bag_set_op_optimized(false),
fake_select_lex(NULL) have_except_all_or_intersect_all(false), fake_select_lex(NULL)
{ {
} }
...@@ -853,9 +861,11 @@ class st_select_lex_unit: public st_select_lex_node { ...@@ -853,9 +861,11 @@ class st_select_lex_unit: public st_select_lex_node {
optimized, // optimize phase already performed for UNION (unit) optimized, // optimize phase already performed for UNION (unit)
optimized_2, optimized_2,
executed, // already executed executed, // already executed
cleaned; cleaned,
bag_set_op_optimized;
bool optimize_started; bool optimize_started;
bool have_except_all_or_intersect_all;
// list of fields which points to temporary table for union // list of fields which points to temporary table for union
List<Item> item_list; List<Item> item_list;
...@@ -867,11 +877,6 @@ class st_select_lex_unit: public st_select_lex_node { ...@@ -867,11 +877,6 @@ class st_select_lex_unit: public st_select_lex_node {
any SELECT of this unit execution any SELECT of this unit execution
*/ */
List<Item> types; List<Item> types;
/**
There is INTERSECT and it is item used in creating temporary
table for it
*/
Item_int *intersect_mark;
/** /**
TRUE if the unit contained TVC at the top level that has been wrapped TRUE if the unit contained TVC at the top level that has been wrapped
into SELECT: into SELECT:
...@@ -929,7 +934,8 @@ class st_select_lex_unit: public st_select_lex_node { ...@@ -929,7 +934,8 @@ class st_select_lex_unit: public st_select_lex_node {
*/ */
st_select_lex *saved_fake_select_lex; st_select_lex *saved_fake_select_lex;
st_select_lex *union_distinct; /* pointer to the last UNION DISTINCT */ /* pointer to the last node before last subsequence of UNION ALL */
st_select_lex *union_distinct;
bool describe; /* union exec() called for EXPLAIN */ bool describe; /* union exec() called for EXPLAIN */
Procedure *last_procedure; /* Pointer to procedure, if such exists */ Procedure *last_procedure; /* Pointer to procedure, if such exists */
...@@ -955,6 +961,7 @@ class st_select_lex_unit: public st_select_lex_node { ...@@ -955,6 +961,7 @@ class st_select_lex_unit: public st_select_lex_node {
bool prepare(TABLE_LIST *derived_arg, select_result *sel_result, bool prepare(TABLE_LIST *derived_arg, select_result *sel_result,
ulong additional_options); ulong additional_options);
bool optimize(); bool optimize();
void optimize_bag_operation(bool is_outer_distinct);
bool exec(); bool exec();
bool exec_recursive(); bool exec_recursive();
bool cleanup(); bool cleanup();
...@@ -1025,7 +1032,7 @@ Field_pair *find_matching_field_pair(Item *item, List<Field_pair> pair_list); ...@@ -1025,7 +1032,7 @@ Field_pair *find_matching_field_pair(Item *item, List<Field_pair> pair_list);
#define TOUCHED_SEL_COND 1/* WHERE/HAVING/ON should be reinited before use */ #define TOUCHED_SEL_COND 1/* WHERE/HAVING/ON should be reinited before use */
#define TOUCHED_SEL_DERIVED (1<<1)/* derived should be reinited before use */ #define TOUCHED_SEL_DERIVED (1<<1)/* derived should be reinited before use */
#define UNIT_NEST_FL 1
/* /*
SELECT_LEX - store information of parsed SELECT statment SELECT_LEX - store information of parsed SELECT statment
*/ */
...@@ -1048,7 +1055,7 @@ class st_select_lex: public st_select_lex_node ...@@ -1048,7 +1055,7 @@ class st_select_lex: public st_select_lex_node
select1->first_nested points to select1. select1->first_nested points to select1.
*/ */
st_select_lex *first_nested; st_select_lex *first_nested;
uint8 nest_flags;
Name_resolution_context context; Name_resolution_context context;
LEX_CSTRING db; LEX_CSTRING db;
Item *where, *having; /* WHERE & HAVING clauses */ Item *where, *having; /* WHERE & HAVING clauses */
...@@ -1524,6 +1531,13 @@ class st_select_lex: public st_select_lex_node ...@@ -1524,6 +1531,13 @@ class st_select_lex: public st_select_lex_node
select_handler *find_select_handler(THD *thd); select_handler *find_select_handler(THD *thd);
bool is_set_op()
{
return linkage == UNION_TYPE ||
linkage == EXCEPT_TYPE ||
linkage == INTERSECT_TYPE;
}
private: private:
bool m_non_agg_field_used; bool m_non_agg_field_used;
bool m_agg_func_used; bool m_agg_func_used;
...@@ -1570,6 +1584,8 @@ class st_select_lex: public st_select_lex_node ...@@ -1570,6 +1584,8 @@ class st_select_lex: public st_select_lex_node
void add_statistics(SELECT_LEX_UNIT *unit); void add_statistics(SELECT_LEX_UNIT *unit);
bool make_unique_derived_name(THD *thd, LEX_CSTRING *alias); bool make_unique_derived_name(THD *thd, LEX_CSTRING *alias);
void lex_start(LEX *plex); void lex_start(LEX *plex);
bool is_unit_nest() { return (nest_flags & UNIT_NEST_FL); }
void mark_as_unit_nest() { nest_flags= UNIT_NEST_FL; }
}; };
typedef class st_select_lex SELECT_LEX; typedef class st_select_lex SELECT_LEX;
......
...@@ -751,6 +751,7 @@ st_select_lex *wrap_tvc_with_tail(THD *thd, st_select_lex *tvc_sl) ...@@ -751,6 +751,7 @@ st_select_lex *wrap_tvc_with_tail(THD *thd, st_select_lex *tvc_sl)
{ {
wrapper_sl->master_unit()->union_distinct= wrapper_sl; wrapper_sl->master_unit()->union_distinct= wrapper_sl;
} }
wrapper_sl->distinct= tvc_sl->distinct;
thd->lex->current_select= wrapper_sl; thd->lex->current_select= wrapper_sl;
return wrapper_sl; return wrapper_sl;
} }
......
...@@ -72,7 +72,7 @@ void select_unit::change_select() ...@@ -72,7 +72,7 @@ void select_unit::change_select()
switch (step) switch (step)
{ {
case INTERSECT_TYPE: case INTERSECT_TYPE:
intersect_mark->value= prev_step= curr_step; prev_step= curr_step;
curr_step= current_select_number; curr_step= current_select_number;
break; break;
case EXCEPT_TYPE: case EXCEPT_TYPE:
...@@ -83,6 +83,7 @@ void select_unit::change_select() ...@@ -83,6 +83,7 @@ void select_unit::change_select()
} }
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/** /**
Fill temporary tables for UNION/EXCEPT/INTERSECT Fill temporary tables for UNION/EXCEPT/INTERSECT
...@@ -93,7 +94,7 @@ void select_unit::change_select() ...@@ -93,7 +94,7 @@ void select_unit::change_select()
EXCEPT: EXCEPT:
looks for the record in the table (with 'counter' field first if looks for the record in the table (with 'counter' field first if
INTERSECT present in the sequence) and delete it if found INTERSECT present in the sequence) and delete it if found
INTESECT: INTERSECT:
looks for the same record with 'counter' field of previous operation, looks for the same record with 'counter' field of previous operation,
put as a 'counter' number of the current SELECT. put as a 'counter' number of the current SELECT.
We scan the table and remove all records which marked with not last We scan the table and remove all records which marked with not last
...@@ -108,7 +109,7 @@ void select_unit::change_select() ...@@ -108,7 +109,7 @@ void select_unit::change_select()
*/ */
int select_unit::send_data(List<Item> &values) int select_unit::send_data(List<Item> &values)
{ {
int rc; int rc= 0;
int not_reported_error= 0; int not_reported_error= 0;
if (unit->offset_limit_cnt) if (unit->offset_limit_cnt)
{ // using limit offset,count { // using limit offset,count
...@@ -119,17 +120,24 @@ int select_unit::send_data(List<Item> &values) ...@@ -119,17 +120,24 @@ int select_unit::send_data(List<Item> &values)
return 0; return 0;
if (table->no_rows_with_nulls) if (table->no_rows_with_nulls)
table->null_catch_flags= CHECK_ROW_FOR_NULLS_TO_REJECT; table->null_catch_flags= CHECK_ROW_FOR_NULLS_TO_REJECT;
if (intersect_mark)
fill_record(thd, table, table->field + addon_cnt, values, true, false);
/* set up initial values for records to be written */
if (addon_cnt && step == UNION_TYPE)
{ {
fill_record(thd, table, table->field + 1, values, TRUE, FALSE); DBUG_ASSERT(addon_cnt == 1);
table->field[0]->store((ulonglong) curr_step, 1); table->field[0]->store((longlong) curr_step, 1);
} }
else
fill_record(thd, table, table->field, values, TRUE, FALSE);
if (unlikely(thd->is_error())) if (unlikely(thd->is_error()))
{ {
rc= 1; rc= 1;
goto end; if (unlikely(not_reported_error))
{
DBUG_ASSERT(rc);
table->file->print_error(not_reported_error, MYF(0));
}
return rc;
} }
if (table->no_rows_with_nulls) if (table->no_rows_with_nulls)
{ {
...@@ -137,72 +145,37 @@ int select_unit::send_data(List<Item> &values) ...@@ -137,72 +145,37 @@ int select_unit::send_data(List<Item> &values)
if (table->null_catch_flags) if (table->null_catch_flags)
{ {
rc= 0; rc= 0;
goto end; if (unlikely(not_reported_error))
{
DBUG_ASSERT(rc);
table->file->print_error(not_reported_error, MYF(0));
}
return rc;
} }
} }
// select_unit::change_select() change step & Co correctly for each SELECT /* select_unit::change_select() change step & Co correctly for each SELECT */
int find_res;
switch (step) switch (step)
{ {
case UNION_TYPE: case UNION_TYPE:
{ rc= write_record();
if (unlikely((write_err= /* no reaction with conversion */
table->file->ha_write_tmp_row(table->record[0])))) if (rc == -2)
{ rc= 0;
if (write_err == HA_ERR_FOUND_DUPP_KEY)
{
/*
Inform upper level that we found a duplicate key, that should not
be counted as part of limit
*/
rc= -1;
goto end;
}
bool is_duplicate= FALSE;
/* create_internal_tmp_table_from_heap will generate error if needed */
if (table->file->is_fatal_error(write_err, HA_CHECK_DUP) &&
create_internal_tmp_table_from_heap(thd, table,
tmp_table_param.start_recinfo,
&tmp_table_param.recinfo,
write_err, 1, &is_duplicate))
{
rc= 1;
goto end;
}
if (is_duplicate)
{
rc= -1;
goto end;
}
}
break; break;
}
case EXCEPT_TYPE: case EXCEPT_TYPE:
{
int find_res;
/* /*
The temporary table uses very first index or constrain for The temporary table uses very first index or constrain for
checking unique constrain. checking unique constrain.
*/ */
if (!(find_res= table->file->find_unique_row(table->record[0], 0))) if (!(find_res= table->file->find_unique_row(table->record[0], 0)))
{ rc= delete_record();
DBUG_ASSERT(!table->triggers);
table->status|= STATUS_DELETED;
not_reported_error= table->file->ha_delete_tmp_row(table->record[0]);
rc= MY_TEST(not_reported_error);
goto end;
}
else else
{ rc= not_reported_error= (find_res != 1);
if ((rc= not_reported_error= (find_res != 1)))
goto end;
}
break; break;
}
case INTERSECT_TYPE: case INTERSECT_TYPE:
{
int find_res;
/* /*
The temporary table uses very first index or constrain for The temporary table uses very first index or constrain for
checking unique constrain. checking unique constrain.
...@@ -210,32 +183,20 @@ int select_unit::send_data(List<Item> &values) ...@@ -210,32 +183,20 @@ int select_unit::send_data(List<Item> &values)
if (!(find_res= table->file->find_unique_row(table->record[0], 0))) if (!(find_res= table->file->find_unique_row(table->record[0], 0)))
{ {
DBUG_ASSERT(!table->triggers); DBUG_ASSERT(!table->triggers);
if (table->field[0]->val_int() != prev_step) if (table->field[0]->val_int() == prev_step)
{ {
rc= 0; not_reported_error= update_counter(table->field[0], curr_step);
goto end;
}
store_record(table, record[1]);
table->field[0]->store(curr_step, 0);
not_reported_error= table->file->ha_update_tmp_row(table->record[1],
table->record[0]);
rc= MY_TEST(not_reported_error); rc= MY_TEST(not_reported_error);
DBUG_ASSERT(rc != HA_ERR_RECORD_IS_THE_SAME); DBUG_ASSERT(rc != HA_ERR_RECORD_IS_THE_SAME);
goto end;
} }
else
{
if ((rc= not_reported_error= (find_res != 1)))
goto end;
} }
else
rc= not_reported_error= (find_res != 1);
break; break;
}
default: default:
DBUG_ASSERT(0); DBUG_ASSERT(0);
} }
rc= 0;
end:
if (unlikely(not_reported_error)) if (unlikely(not_reported_error))
{ {
DBUG_ASSERT(rc); DBUG_ASSERT(rc);
...@@ -251,7 +212,7 @@ bool select_unit::send_eof() ...@@ -251,7 +212,7 @@ bool select_unit::send_eof()
thd->lex->current_select->next_select()->get_linkage() == INTERSECT_TYPE)) thd->lex->current_select->next_select()->get_linkage() == INTERSECT_TYPE))
{ {
/* /*
it is not INTESECT or next SELECT in the sequence is INTERSECT so no it is not INTERSECT or next SELECT in the sequence is INTERSECT so no
need filtering (the last INTERSECT in this sequence of intersects will need filtering (the last INTERSECT in this sequence of intersects will
filter). filter).
*/ */
...@@ -265,15 +226,14 @@ bool select_unit::send_eof() ...@@ -265,15 +226,14 @@ bool select_unit::send_eof()
TODO: as optimization for simple case this could be moved to TODO: as optimization for simple case this could be moved to
'fake_select' WHERE condition 'fake_select' WHERE condition
*/ */
handler *file= table->file;
int error; int error;
if (unlikely(file->ha_rnd_init_with_error(1))) if (table->file->ha_rnd_init_with_error(1))
return 1; return 1;
do do
{ {
if (unlikely(error= file->ha_rnd_next(table->record[0]))) error= table->file->ha_rnd_next(table->record[0]);
if (unlikely(error))
{ {
if (error == HA_ERR_END_OF_FILE) if (error == HA_ERR_END_OF_FILE)
{ {
...@@ -283,9 +243,9 @@ bool select_unit::send_eof() ...@@ -283,9 +243,9 @@ bool select_unit::send_eof()
break; break;
} }
if (table->field[0]->val_int() != curr_step) if (table->field[0]->val_int() != curr_step)
error= file->ha_delete_tmp_row(table->record[0]); error= delete_record();
} while (likely(!error)); } while (!error);
file->ha_rnd_end(); table->file->ha_rnd_end();
if (unlikely(error)) if (unlikely(error))
table->file->print_error(error, MYF(0)); table->file->print_error(error, MYF(0));
...@@ -345,6 +305,7 @@ bool select_unit::flush() ...@@ -345,6 +305,7 @@ bool select_unit::flush()
create_table whether to physically create result table create_table whether to physically create result table
keep_row_order keep rows in order as they were inserted keep_row_order keep rows in order as they were inserted
hidden number of hidden fields (for INTERSECT) hidden number of hidden fields (for INTERSECT)
plus one for `ALL`
DESCRIPTION DESCRIPTION
Create a temporary table that is used to store the result of a UNION, Create a temporary table that is used to store the result of a UNION,
...@@ -369,6 +330,11 @@ select_unit::create_result_table(THD *thd_arg, List<Item> *column_types, ...@@ -369,6 +330,11 @@ select_unit::create_result_table(THD *thd_arg, List<Item> *column_types,
tmp_table_param.bit_fields_as_long= bit_fields_as_long; tmp_table_param.bit_fields_as_long= bit_fields_as_long;
tmp_table_param.hidden_field_count= hidden; tmp_table_param.hidden_field_count= hidden;
/*
At least one of `duplicate_cnt` and `intersect_cnt` are used.
in this case table can keep unique actually.
*/
if (hidden > 0) is_union_distinct= true;
if (! (table= create_tmp_table(thd_arg, &tmp_table_param, *column_types, if (! (table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
(ORDER*) 0, is_union_distinct, 1, (ORDER*) 0, is_union_distinct, 1,
options, HA_POS_ERROR, alias, options, HA_POS_ERROR, alias,
...@@ -433,6 +399,143 @@ select_union_recursive::create_result_table(THD *thd_arg, ...@@ -433,6 +399,143 @@ select_union_recursive::create_result_table(THD *thd_arg,
} }
/*
@brief
Write a record
@retval
-2 conversion happened
-1 found a duplicate key
0 no error
1 if an error is reported
*/
int select_unit::write_record()
{
if (unlikely((write_err= table->file->ha_write_tmp_row(table->record[0]))))
{
if (write_err == HA_ERR_FOUND_DUPP_KEY)
{
/*
Inform upper level that we found a duplicate key, that should not
be counted as part of limit
*/
return -1;
}
bool is_duplicate= false;
/* create_internal_tmp_table_from_heap will generate error if needed */
if (table->file->is_fatal_error(write_err, HA_CHECK_DUP))
{
if (!create_internal_tmp_table_from_heap(thd, table,
tmp_table_param.start_recinfo,
&tmp_table_param.recinfo,
write_err, 1, &is_duplicate))
{
return -2;
}
else
{
return 1;
}
}
if (is_duplicate)
{
return -1;
}
}
return 0;
}
/*
@brief
Update counter for a record
@retval
0 no error
-1 error occurred
*/
int select_unit::update_counter(Field* counter, longlong value)
{
store_record(table, record[1]);
counter->store(value, 0);
int error= table->file->ha_update_tmp_row(table->record[1],
table->record[0]);
return error;
}
/*
@brief
Try to disable index
@retval
true index is disabled this time
false this time did not disable the index
*/
bool select_unit_ext::disable_index_if_needed(SELECT_LEX *curr_sl)
{
if (is_index_enabled &&
(curr_sl == curr_sl->master_unit()->union_distinct ||
!curr_sl->next_select()) )
{
is_index_enabled= false;
if (table->file->ha_disable_indexes(HA_KEY_SWITCH_ALL))
return false;
table->no_keyread=1;
return true;
}
return false;
}
/*
@brief
Unfold a record
@retval
0 no error
-1 conversion happened
*/
int select_unit_ext::unfold_record(int cnt)
{
DBUG_ASSERT(cnt > 0);
int error= 0;
bool is_convertion_happened= false;
while (--cnt)
{
error= write_record();
if (error == -2)
{
is_convertion_happened= true;
error= -1;
}
}
if (is_convertion_happened)
return -1;
return error;
}
/*
@brief
Delete a record
@retval
0 no error
1 if an error is reported
*/
int select_unit::delete_record()
{
DBUG_ASSERT(!table->triggers);
table->status|= STATUS_DELETED;
int not_reported_error= table->file->ha_delete_tmp_row(table->record[0]);
return MY_TEST(not_reported_error);
}
/** /**
Reset and empty the temporary table that stores the materialized query Reset and empty the temporary table that stores the materialized query
result. result.
...@@ -448,6 +551,357 @@ void select_unit::cleanup() ...@@ -448,6 +551,357 @@ void select_unit::cleanup()
} }
/*
@brief
Set up value needed by send_data() and send_eof()
@detail
- For EXCEPT we will decrease the counter by one
and INTERSECT / UNION we increase the counter.
- For INTERSECT we will modify the second extra field (intersect counter)
and for EXCEPT / UNION we modify the first (duplicate counter)
*/
void select_unit_ext::change_select()
{
select_unit::change_select();
switch(step){
case UNION_TYPE:
increment= 1;
curr_op_type= UNION_DISTINCT;
break;
case EXCEPT_TYPE:
increment= -1;
curr_op_type= EXCEPT_DISTINCT;
break;
case INTERSECT_TYPE:
increment= 1;
curr_op_type= INTERSECT_DISTINCT;
break;
default: DBUG_ASSERT(0);
}
if (!thd->lex->current_select->distinct)
/* change type from DISTINCT to ALL */
curr_op_type= (set_op_type)(curr_op_type + 1);
duplicate_cnt= table->field[addon_cnt - 1];
if (addon_cnt == 2)
additional_cnt= table->field[addon_cnt - 2];
else
additional_cnt= NULL;
}
/*
@brief
Fill temporary tables for operations need extra fields
@detail
- If this operation is not distinct, we try to find it and increase the
counter by "increment" setted in select_unit_ext::change_select().
- If it is distinct, for UNION we write this record; for INTERSECT we
try to find it and increase the intersect counter if found; for EXCEPT
we try to find it and delete that record if found.
*/
int select_unit_ext::send_data(List<Item> &values)
{
int rc= 0;
int not_reported_error= 0;
int find_res;
if (unit->offset_limit_cnt)
{
/* using limit offset,count */
unit->offset_limit_cnt--;
return 0;
}
if (thd->killed == ABORT_QUERY)
return 0;
if (table->no_rows_with_nulls)
table->null_catch_flags= CHECK_ROW_FOR_NULLS_TO_REJECT;
fill_record(thd, table, table->field + addon_cnt, values, true, false);
/* set up initial values for records to be written */
if ( step == UNION_TYPE )
{
/* set duplicate counter to 1 */
duplicate_cnt->store((longlong) 1, 1);
/* set the other counter to 0 */
if (curr_op_type == INTERSECT_ALL)
additional_cnt->store((longlong) 0, 1);
}
if (unlikely(thd->is_error()))
{
rc= 1;
if (unlikely(not_reported_error))
{
DBUG_ASSERT(rc);
table->file->print_error(not_reported_error, MYF(0));
}
return rc;
}
if (table->no_rows_with_nulls)
{
table->null_catch_flags&= ~CHECK_ROW_FOR_NULLS_TO_REJECT;
if (table->null_catch_flags)
{
if (unlikely(not_reported_error))
{
DBUG_ASSERT(rc);
table->file->print_error(not_reported_error, MYF(0));
}
return rc;
}
}
switch(curr_op_type)
{
case UNION_ALL:
if (!is_index_enabled ||
(find_res= table->file->find_unique_row(table->record[0], 0)))
{
rc= write_record();
/* no reaction with conversion */
if (rc == -2)
rc= 0;
}
else
{
longlong cnt= duplicate_cnt->val_int() + increment;
not_reported_error= update_counter(duplicate_cnt, cnt);
DBUG_ASSERT(!table->triggers);
rc= MY_TEST(not_reported_error);
}
break;
case EXCEPT_ALL:
if (!(find_res= table->file->find_unique_row(table->record[0], 0)))
{
longlong cnt= duplicate_cnt->val_int() + increment;
if (cnt == 0)
rc= delete_record();
else
{
not_reported_error= update_counter(duplicate_cnt, cnt);
DBUG_ASSERT(!table->triggers);
rc= MY_TEST(not_reported_error);
}
}
break;
case INTERSECT_ALL:
if (!(find_res= table->file->find_unique_row(table->record[0], 0)))
{
longlong cnt= duplicate_cnt->val_int() + increment;
if (cnt <= additional_cnt->val_int())
{
not_reported_error= update_counter(duplicate_cnt, cnt);
DBUG_ASSERT(!table->triggers);
rc= MY_TEST(not_reported_error);
}
}
break;
case UNION_DISTINCT:
rc= write_record();
/* no reaction with conversion */
if (rc == -2)
rc= 0;
break;
case EXCEPT_DISTINCT:
if (!(find_res= table->file->find_unique_row(table->record[0], 0)))
rc= delete_record();
else
rc= not_reported_error= (find_res != 1);
break;
case INTERSECT_DISTINCT:
if (!(find_res= table->file->find_unique_row(table->record[0], 0)))
{
if (additional_cnt->val_int() == prev_step)
{
not_reported_error= update_counter(additional_cnt, curr_step);
rc= MY_TEST(not_reported_error);
DBUG_ASSERT(rc != HA_ERR_RECORD_IS_THE_SAME);
}
else if (additional_cnt->val_int() != curr_step)
rc= delete_record();
}
else
rc= not_reported_error= (find_res != 1);
break;
default:
DBUG_ASSERT(0);
}
if (unlikely(not_reported_error))
{
DBUG_ASSERT(rc);
table->file->print_error(not_reported_error, MYF(0));
}
return rc;
}
/*
@brief
Do post-operation after a operator
@detail
We need to scan in these cases:
- If this operation is DISTINCT and next is ALL,
duplicate counter needs to be set to 1.
- If this operation is INTERSECT ALL and counter needs to be updated.
- If next operation is INTERSECT ALL,
set up the second extra field (called "intersect_counter") to 0.
this extra field counts records in the second operand.
If this operation is equal to "union_distinct" or is the last operation,
we'll disable index. Then if this operation is ALL we'll unfold records.
*/
bool select_unit_ext::send_eof()
{
int error= 0;
SELECT_LEX *curr_sl= thd->lex->current_select;
SELECT_LEX *next_sl= curr_sl->next_select();
bool is_next_distinct= next_sl && next_sl->distinct;
bool is_next_intersect_all=
next_sl &&
next_sl->get_linkage() == INTERSECT_TYPE &&
!next_sl->distinct;
bool need_unfold= (disable_index_if_needed(curr_sl) &&
!curr_sl->distinct);
if (((curr_sl->distinct && !is_next_distinct) ||
curr_op_type == INTERSECT_ALL ||
is_next_intersect_all) &&
!need_unfold)
{
if (!next_sl)
DBUG_ASSERT(curr_op_type != INTERSECT_ALL);
bool need_update_row;
if (unlikely(table->file->ha_rnd_init_with_error(1)))
return 1;
do
{
need_update_row= false;
if (unlikely(error= table->file->ha_rnd_next(table->record[0])))
{
if (error == HA_ERR_END_OF_FILE)
{
error= 0;
break;
}
break;
}
store_record(table, record[1]);
if (curr_sl->distinct && !is_next_distinct)
{
/* set duplicate counter to 1 if next operation is ALL */
duplicate_cnt->store(1, 0);
need_update_row= true;
}
if (is_next_intersect_all)
{
longlong d_cnt_val= duplicate_cnt->val_int();
if (d_cnt_val == 0)
error= delete_record();
else
{
if (curr_op_type == INTERSECT_ALL)
{
longlong a_cnt_val= additional_cnt->val_int();
if (a_cnt_val < d_cnt_val)
d_cnt_val= a_cnt_val;
}
additional_cnt->store(d_cnt_val, 0);
duplicate_cnt->store((longlong)0, 0);
need_update_row= true;
}
}
if (need_update_row)
error= table->file->ha_update_tmp_row(table->record[1],
table->record[0]);
} while (likely(!error));
table->file->ha_rnd_end();
}
/* unfold */
else if (need_unfold)
{
/* unfold if is ALL operation */
longlong dup_cnt;
if (unlikely(table->file->ha_rnd_init_with_error(1)))
return 1;
do
{
if (unlikely(error= table->file->ha_rnd_next(table->record[0])))
{
if (error == HA_ERR_END_OF_FILE)
{
error= 0;
break;
}
break;
}
dup_cnt= duplicate_cnt->val_int();
/* delete record if not exist in the second operand */
if (dup_cnt == 0)
{
error= delete_record();
continue;
}
if (curr_op_type == INTERSECT_ALL)
{
longlong add_cnt= additional_cnt->val_int();
if (dup_cnt > add_cnt && add_cnt > 0)
dup_cnt= add_cnt;
}
if (dup_cnt == 1)
continue;
duplicate_cnt->store((longlong)1, 0);
if (additional_cnt)
additional_cnt->store((longlong)0, 0);
error= table->file->ha_update_tmp_row(table->record[1],
table->record[0]);
if (unlikely(error))
break;
if (unfold_record(dup_cnt) == -1)
{
/* restart the scan */
if (unlikely(table->file->ha_rnd_init_with_error(1)))
return 1;
duplicate_cnt= table->field[addon_cnt - 1];
if (addon_cnt == 2)
additional_cnt= table->field[addon_cnt - 2];
else
additional_cnt= NULL;
continue;
}
} while (likely(!error));
table->file->ha_rnd_end();
}
if (unlikely(error))
table->file->print_error(error, MYF(0));
return (MY_TEST(error));
}
void select_union_recursive::cleanup() void select_union_recursive::cleanup()
{ {
if (table) if (table)
...@@ -818,6 +1272,29 @@ bool st_select_lex_unit::join_union_item_types(THD *thd_arg, ...@@ -818,6 +1272,29 @@ bool st_select_lex_unit::join_union_item_types(THD *thd_arg,
} }
bool init_item_int(THD* thd, Item_int* &item)
{
if (!item)
{
Query_arena *arena, backup_arena;
arena= thd->activate_stmt_arena_if_needed(&backup_arena);
item= new (thd->mem_root) Item_int(thd, 0);
if (arena)
thd->restore_active_arena(arena, &backup_arena);
if (!item)
return false;
}
else
{
item->value= 0;
}
return true;
}
bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg, bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
select_result *sel_result, select_result *sel_result,
ulong additional_options) ulong additional_options)
...@@ -829,7 +1306,8 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg, ...@@ -829,7 +1306,8 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
uint union_part_count= 0; uint union_part_count= 0;
select_result *tmp_result; select_result *tmp_result;
bool is_union_select; bool is_union_select;
bool have_except= FALSE, have_intersect= FALSE; bool have_except= false, have_intersect= false,
have_except_all_or_intersect_all= false;
bool instantiate_tmp_table= false; bool instantiate_tmp_table= false;
bool single_tvc= !first_sl->next_select() && first_sl->tvc && bool single_tvc= !first_sl->next_select() && first_sl->tvc &&
!fake_select_lex; !fake_select_lex;
...@@ -906,15 +1384,27 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg, ...@@ -906,15 +1384,27 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
found_rows_for_union= first_sl->options & OPTION_FOUND_ROWS; found_rows_for_union= first_sl->options & OPTION_FOUND_ROWS;
is_union_select= is_unit_op() || fake_select_lex || single_tvc; is_union_select= is_unit_op() || fake_select_lex || single_tvc;
/* will only optimize once */
if (!bag_set_op_optimized && !is_recursive)
{
optimize_bag_operation(false);
}
for (SELECT_LEX *s= first_sl; s; s= s->next_select()) for (SELECT_LEX *s= first_sl; s; s= s->next_select())
{ {
switch (s->linkage) switch (s->linkage)
{ {
case INTERSECT_TYPE: case INTERSECT_TYPE:
have_intersect= TRUE; have_intersect= TRUE;
if (!s->distinct){
have_except_all_or_intersect_all= true;
}
break; break;
case EXCEPT_TYPE: case EXCEPT_TYPE:
have_except= TRUE; have_except= TRUE;
if (!s->distinct){
have_except_all_or_intersect_all= TRUE;
}
break; break;
default: default:
break; break;
...@@ -940,6 +1430,18 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg, ...@@ -940,6 +1430,18 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
else else
{ {
if (!is_recursive) if (!is_recursive)
/*
class "select_unit_ext" handles query contains EXCEPT ALL and / or
INTERSECT ALL. Others are handled by class "select_unit"
If have EXCEPT ALL or INTERSECT ALL in the query. First operand
should be UNION ALL
*/
if (have_except_all_or_intersect_all)
{
union_result= new (thd->mem_root) select_unit_ext(thd);
first_sl->distinct= false;
}
else
union_result= new (thd->mem_root) select_unit(thd); union_result= new (thd->mem_root) select_unit(thd);
else else
{ {
...@@ -1074,12 +1576,18 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg, ...@@ -1074,12 +1576,18 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
if (join_union_item_types(thd, types, union_part_count + 1)) if (join_union_item_types(thd, types, union_part_count + 1))
goto err; goto err;
if (union_result->create_result_table(thd, &types, if (union_result->create_result_table(thd, &types,
MY_TEST(union_distinct), MY_TEST(union_distinct) ||
have_except_all_or_intersect_all ||
have_intersect,
create_options, create_options,
&derived_arg->alias, false, &derived_arg->alias, false,
instantiate_tmp_table, false, instantiate_tmp_table, false,
0)) 0))
goto err; goto err;
if (have_except_all_or_intersect_all)
{
union_result->init();
}
if (!derived_arg->table) if (!derived_arg->table)
{ {
derived_arg->table= with_element->rec_result->rec_tables.head(); derived_arg->table= with_element->rec_result->rec_tables.head();
...@@ -1091,6 +1599,7 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg, ...@@ -1091,6 +1599,7 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
} }
} }
} }
// In case of a non-recursive UNION, join data types for all UNION parts. // In case of a non-recursive UNION, join data types for all UNION parts.
if (!is_recursive && join_union_item_types(thd, types, union_part_count)) if (!is_recursive && join_union_item_types(thd, types, union_part_count))
goto err; goto err;
...@@ -1166,36 +1675,26 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg, ...@@ -1166,36 +1675,26 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
if (global_parameters()->ftfunc_list->elements) if (global_parameters()->ftfunc_list->elements)
create_options= create_options | TMP_TABLE_FORCE_MYISAM; create_options= create_options | TMP_TABLE_FORCE_MYISAM;
if (!is_recursive) /* extra field counter */
{
uint hidden= 0; uint hidden= 0;
if (have_intersect) Item_int *addon_fields[2]= {0};
if (!is_recursive)
{ {
hidden= 1; if (have_except_all_or_intersect_all)
if (!intersect_mark)
{ {
/* /* add duplicate_count */
For intersect we add a hidden column first that contains ++hidden;
the current select number of the time when the row was
added to the temporary table
*/
Query_arena *arena, backup_arena;
arena= thd->activate_stmt_arena_if_needed(&backup_arena);
intersect_mark= new (thd->mem_root) Item_int(thd, 0);
if (arena)
thd->restore_active_arena(arena, &backup_arena);
if (!intersect_mark)
goto err;
} }
else /* add intersect_count */
intersect_mark->value= 0; //reset if (have_intersect)
types.push_front(union_result->intersect_mark= intersect_mark); ++hidden;
union_result->intersect_mark->name.str= "___";
union_result->intersect_mark->name.length= 3; for(uint i= 0; i< hidden; i++)
{
init_item_int(thd, addon_fields[i]);
types.push_front(addon_fields[i]);
addon_fields[i]->name.str= i ? "__CNT_1" : "__CNT_2";
addon_fields[i]->name.length= 7;
} }
bool error= bool error=
union_result->create_result_table(thd, &types, union_result->create_result_table(thd, &types,
...@@ -1203,11 +1702,13 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg, ...@@ -1203,11 +1702,13 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
create_options, &empty_clex_str, false, create_options, &empty_clex_str, false,
instantiate_tmp_table, false, instantiate_tmp_table, false,
hidden); hidden);
if (intersect_mark) union_result->addon_cnt= hidden;
for (uint i= 0; i < hidden; i++)
types.pop(); types.pop();
if (unlikely(error)) if (unlikely(error))
goto err; goto err;
} }
if (fake_select_lex && !fake_select_lex->first_cond_optimization) if (fake_select_lex && !fake_select_lex->first_cond_optimization)
{ {
save_tablenr= result_table_list.tablenr_exec; save_tablenr= result_table_list.tablenr_exec;
...@@ -1235,9 +1736,8 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg, ...@@ -1235,9 +1736,8 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
arena= thd->activate_stmt_arena_if_needed(&backup_arena); arena= thd->activate_stmt_arena_if_needed(&backup_arena);
saved_error= table->fill_item_list(&item_list); saved_error= table->fill_item_list(&item_list);
// Item_list is inherited from 'types', so there could be the counter for (uint i= 0; i < hidden; i++)
if (intersect_mark) item_list.pop();
item_list.pop(); // remove intersect counter
if (arena) if (arena)
thd->restore_active_arena(arena, &backup_arena); thd->restore_active_arena(arena, &backup_arena);
...@@ -1282,7 +1782,7 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg, ...@@ -1282,7 +1782,7 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
We're in execution of a prepared statement or stored procedure: We're in execution of a prepared statement or stored procedure:
reset field items to point at fields from the created temporary table. reset field items to point at fields from the created temporary table.
*/ */
table->reset_item_list(&item_list, intersect_mark ? 1 : 0); table->reset_item_list(&item_list, hidden);
} }
if (fake_select_lex != NULL && if (fake_select_lex != NULL &&
(thd->stmt_arena->is_stmt_prepare() || (thd->stmt_arena->is_stmt_prepare() ||
...@@ -1315,10 +1815,171 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg, ...@@ -1315,10 +1815,171 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
} }
/**
@brief
Optimize a sequence of set operations
@param first_sl first select of the level now under processing
@details
The method optimizes with the following rules:
- (1)If a subsequence of INTERSECT contains at least one INTERSECT DISTINCT
or this subsequence is followed by UNION/EXCEPT DISTINCT then all
elements in the subsequence can changed for INTERSECT DISTINCT
- (2)If previous set operation is DISTINCT then EXCEPT ALL can be replaced
for EXCEPT DISTINCT
- (3)If UNION DISTINCT / EXCEPT DISTINCT follows a subsequence of UNION ALL
then all set operations of this subsequence can be replaced for
UNION DISTINCT
For derived table it will look up outer select, and do optimize based on
outer select.
Variable "union_distinct" will be updated in the end.
Not compatible with Oracle Mode.
*/
void st_select_lex_unit::optimize_bag_operation(bool is_outer_distinct)
{
/*
skip run optimize for:
ORACLE MODE
CREATE VIEW
PREPARE ... FROM
recursive
*/
if ((thd->variables.sql_mode & MODE_ORACLE) ||
(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW) ||
(fake_select_lex != NULL && thd->stmt_arena->is_stmt_prepare()) ||
(with_element && with_element->is_recursive ))
return;
DBUG_ASSERT(!bag_set_op_optimized);
SELECT_LEX *sl;
/* INTERSECT subsequence can occur only at the very beginning */
/* The first select with linkage == INTERSECT_TYPE */
SELECT_LEX *intersect_start= NULL;
/* The first select after the INTERSECT subsequence */
SELECT_LEX *intersect_end= NULL;
/*
Will point to the last node before UNION ALL subsequence.
Index can be disable there.
*/
SELECT_LEX *disable_index= NULL;
/*
True if there is a select with:
linkage == INTERSECT_TYPE && distinct==true
*/
bool any_intersect_distinct= false;
SELECT_LEX *prev_sl= first_select();
/* process INTERSECT subsequence in the begining */
for (sl= prev_sl->next_select(); sl; prev_sl= sl, sl= sl->next_select())
{
if (sl->linkage != INTERSECT_TYPE)
{
intersect_end= sl;
break;
}
else
{
if (!intersect_start)
intersect_start= sl;
if (sl->distinct)
{
any_intersect_distinct= true;
disable_index= sl;
}
}
}
/* if subquery only contains INTERSECT and outer is UNION DISTINCT*/
if (!sl && is_outer_distinct)
any_intersect_distinct= true;
/* The first select of the current UNION ALL subsequence */
SELECT_LEX *union_all_start= NULL;
for ( ; sl; prev_sl= sl, sl= sl->next_select())
{
DBUG_ASSERT (sl->linkage != INTERSECT_TYPE);
if (!sl->distinct)
{
if (sl->linkage == UNION_TYPE)
{
if (!union_all_start)
{
union_all_start= sl;
}
}
else
{
DBUG_ASSERT (sl->linkage == EXCEPT_TYPE);
union_all_start= NULL;
if (prev_sl->distinct && prev_sl->is_set_op())
{
sl->distinct= true;
disable_index= sl;
}
}
}
else
{ /* sl->distinct == true */
for (SELECT_LEX *si= union_all_start; si && si != sl; si= si->next_select())
{
si->distinct= true;
}
union_all_start= NULL;
disable_index= sl;
}
}
if (is_outer_distinct)
{
for (SELECT_LEX *si= union_all_start; si && si != sl; si= si->next_select())
{
si->distinct= true;
}
union_all_start= NULL;
}
if (any_intersect_distinct ||
(intersect_end != NULL && intersect_end->distinct))
{
for (sl= intersect_start; sl && sl != intersect_end; sl= sl->next_select())
{
sl->distinct= true;
if (disable_index && disable_index->linkage == INTERSECT_TYPE)
disable_index= sl;
}
}
/*
if disable_index points to a INTERSECT, based on rule 1 we can set it
to the last INTERSECT node.
*/
if (disable_index && disable_index->linkage == INTERSECT_TYPE &&
intersect_end && intersect_end->distinct)
disable_index= intersect_end;
/* union_distinct controls when to disable index */
union_distinct= disable_index;
/* recursive call this function for whole lex tree */
for(sl= first_select(); sl; sl= sl->next_select())
{
if (sl->is_unit_nest() &&
sl->first_inner_unit() &&
!sl->first_inner_unit()->bag_set_op_optimized)
sl->first_inner_unit()->optimize_bag_operation(sl->distinct);
}
/* mark as optimized */
bag_set_op_optimized= true;
}
/** /**
Run optimization phase. Run optimization phase.
@return FALSE unit successfully passed optimization phase. @return false unit successfully passed optimization phase.
@return TRUE an error occur. @return TRUE an error occur.
*/ */
bool st_select_lex_unit::optimize() bool st_select_lex_unit::optimize()
...@@ -1328,10 +1989,10 @@ bool st_select_lex_unit::optimize() ...@@ -1328,10 +1989,10 @@ bool st_select_lex_unit::optimize()
DBUG_ENTER("st_select_lex_unit::optimize"); DBUG_ENTER("st_select_lex_unit::optimize");
if (optimized && !uncacheable && !describe) if (optimized && !uncacheable && !describe)
DBUG_RETURN(FALSE); DBUG_RETURN(false);
if (with_element && with_element->is_recursive && optimize_started) if (with_element && with_element->is_recursive && optimize_started)
DBUG_RETURN(FALSE); DBUG_RETURN(false);
optimize_started= true; optimize_started= true;
if (uncacheable || !item || !item->assigned() || describe) if (uncacheable || !item || !item->assigned() || describe)
...@@ -1351,9 +2012,12 @@ bool st_select_lex_unit::optimize() ...@@ -1351,9 +2012,12 @@ bool st_select_lex_unit::optimize()
table->file->info(HA_STATUS_VARIABLE); table->file->info(HA_STATUS_VARIABLE);
} }
/* re-enabling indexes for next subselect iteration */ /* re-enabling indexes for next subselect iteration */
if (union_distinct && table->file->ha_enable_indexes(HA_KEY_SWITCH_ALL)) if ((union_result->force_enable_index_if_needed() || union_distinct))
{ {
if(table->file->ha_enable_indexes(HA_KEY_SWITCH_ALL))
DBUG_ASSERT(0); DBUG_ASSERT(0);
else
table->no_keyread= 0;
} }
} }
for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select()) for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
...@@ -1512,7 +2176,7 @@ bool st_select_lex_unit::exec() ...@@ -1512,7 +2176,7 @@ bool st_select_lex_unit::exec()
sl->tvc->exec(sl); sl->tvc->exec(sl);
else else
sl->join->exec(); sl->join->exec();
if (sl == union_distinct && !(with_element && with_element->is_recursive)) if (sl == union_distinct && !have_except_all_or_intersect_all)
{ {
// This is UNION DISTINCT, so there should be a fake_select_lex // This is UNION DISTINCT, so there should be a fake_select_lex
DBUG_ASSERT(fake_select_lex != NULL); DBUG_ASSERT(fake_select_lex != NULL);
......
...@@ -17577,10 +17577,10 @@ release: ...@@ -17577,10 +17577,10 @@ release:
unit_type_decl: unit_type_decl:
UNION_SYM union_option UNION_SYM union_option
{ $$.unit_type= UNION_TYPE; $$.distinct= $2; } { $$.unit_type= UNION_TYPE; $$.distinct= $2; }
| INTERSECT_SYM | INTERSECT_SYM union_option
{ $$.unit_type= INTERSECT_TYPE; $$.distinct= 1; } { $$.unit_type= INTERSECT_TYPE; $$.distinct= $2; }
| EXCEPT_SYM | EXCEPT_SYM union_option
{ $$.unit_type= EXCEPT_TYPE; $$.distinct= 1; } { $$.unit_type= EXCEPT_TYPE; $$.distinct= $2; }
; ;
/* /*
......
...@@ -145,8 +145,6 @@ static uchar *next_free_record_pos(HP_SHARE *info) ...@@ -145,8 +145,6 @@ static uchar *next_free_record_pos(HP_SHARE *info)
DBUG_PRINT("exit",("Used old position: %p", pos)); DBUG_PRINT("exit",("Used old position: %p", pos));
DBUG_RETURN(pos); DBUG_RETURN(pos);
} }
if (!(block_pos=(info->records % info->block.records_in_block)))
{
if ((info->records > info->max_records && info->max_records) || if ((info->records > info->max_records && info->max_records) ||
(info->data_length + info->index_length >= info->max_table_size)) (info->data_length + info->index_length >= info->max_table_size))
{ {
...@@ -160,6 +158,8 @@ static uchar *next_free_record_pos(HP_SHARE *info) ...@@ -160,6 +158,8 @@ static uchar *next_free_record_pos(HP_SHARE *info)
my_errno=HA_ERR_RECORD_FILE_FULL; my_errno=HA_ERR_RECORD_FILE_FULL;
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
} }
if (!(block_pos=(info->records % info->block.records_in_block)))
{
if (hp_get_new_block(info, &info->block,&length)) if (hp_get_new_block(info, &info->block,&length))
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
info->data_length+=length; info->data_length+=length;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment