Skip to content

Commit b441714

Browse files
committed
MDEV-19956 Queries with subqueries containing UNION are not parsed
Shift-Reduce conflicts prevented parsing some queries with subqueries that used set operations when the subqueries occurred in expressions or in IN predicands. The grammar rules for query expression were transformed in order to avoid these conflicts. New grammar rules employ an idea taken from MySQL 8.0.
1 parent e3da362 commit b441714

21 files changed

+7163
-544
lines changed

mysql-test/main/brackets.result

Lines changed: 4021 additions & 1 deletion
Large diffs are not rendered by default.

mysql-test/main/brackets.test

Lines changed: 2318 additions & 0 deletions
Large diffs are not rendered by default.

mysql-test/main/except.result

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2525
3 EXCEPT t2 ALL NULL NULL NULL NULL 2 100.00
2626
NULL EXCEPT RESULT <except2,3> ALL NULL NULL NULL NULL NULL NULL
2727
Warnings:
28-
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 (/* select#3 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2`)) `a`
28+
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 (/* select#3 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2`)) `a`
2929
EXPLAIN format=json (select a,b from t1) except (select c,d from t2);
3030
EXPLAIN
3131
{
@@ -230,7 +230,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
230230
3 EXCEPT t4 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
231231
NULL EXCEPT RESULT <except2,3> ALL NULL NULL NULL NULL NULL NULL
232232
Warnings:
233-
Note 1003 /* select#1 */ select `a`.`a` AS `a`,`a`.`b` AS `b`,`a`.`e` AS `e`,`a`.`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 (/* 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`)) `a`
233+
Note 1003 /* select#1 */ select `a`.`a` AS `a`,`a`.`b` AS `b`,`a`.`e` AS `e`,`a`.`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 (/* 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`)) `a`
234234
EXPLAIN format=json (select a,b,e,f from t1,t3) except (select c,d,g,h from t2,t4);
235235
EXPLAIN
236236
{

mysql-test/main/intersect.result

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3939
4 INTERSECT t3 ALL NULL NULL NULL NULL 3 100.00
4040
NULL INTERSECT RESULT <intersect2,3,4> ALL NULL NULL NULL NULL NULL NULL
4141
Warnings:
42-
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 (/* select#3 */ 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`)) `a`
42+
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 (/* select#3 */ 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`)) `a`
4343
EXPLAIN format=json (select a,b from t1) intersect (select c,d from t2) intersect (select e,f from t3);
4444
EXPLAIN
4545
{
@@ -280,7 +280,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
280280
3 INTERSECT t3 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join)
281281
NULL INTERSECT RESULT <intersect2,3> ALL NULL NULL NULL NULL NULL NULL
282282
Warnings:
283-
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 (/* select#3 */ select `test`.`t2`.`c` AS `c`,`test`.`t3`.`e` AS `e` from `test`.`t2` join `test`.`t3`)) `a`
283+
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 (/* select#3 */ select `test`.`t2`.`c` AS `c`,`test`.`t3`.`e` AS `e` from `test`.`t2` join `test`.`t3`)) `a`
284284
set @@optimizer_switch='optimize_join_buffer_size=off';
285285
EXPLAIN format=json (select a,b from t1) intersect (select c,e from t2,t3);
286286
EXPLAIN
@@ -724,7 +724,7 @@ a b
724724
drop procedure p1;
725725
show create view v1;
726726
View Create View character_set_client collation_connection
727-
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 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 (select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3`)) `__6` union (select 4 AS `4`,4 AS `4`) latin1 latin1_swedish_ci
727+
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 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 (select `test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t3`)) `__6` union (select 4 AS `4`,4 AS `4`) latin1 latin1_swedish_ci
728728
drop view v1;
729729
drop tables t1,t2,t3;
730730
#

mysql-test/main/parser.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1776,7 +1776,7 @@ End of 10.3 tests
17761776
#
17771777
create table t1 (a int);
17781778
(select * from t1) for update;
1779-
ERROR HY000: Incorrect usage of lock options and SELECT in brackets
1779+
a
17801780
(select * from t1) union (select * from t1) for update;
17811781
ERROR HY000: Incorrect usage of lock options and SELECT in brackets
17821782
(select * from t1 for update);

mysql-test/main/parser.test

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1544,7 +1544,6 @@ SELECT @@GLOBAL.role;
15441544
--echo #
15451545

15461546
create table t1 (a int);
1547-
--error ER_WRONG_USAGE
15481547
(select * from t1) for update;
15491548
--error ER_WRONG_USAGE
15501549
(select * from t1) union (select * from t1) for update;

mysql-test/main/subselect.result

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3736,8 +3736,11 @@ WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1)));
37363736
i
37373737
explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12))
37383738
from t1;
3739-
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 'union (select t12.i from t1 t12))
3740-
from t1' at line 1
3739+
id select_type table type possible_keys key key_len ref rows Extra
3740+
1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found
3741+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
3742+
3 UNION NULL NULL NULL NULL NULL NULL NULL no matching row in const table
3743+
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
37413744
explain select * from t1 where not exists
37423745
((select t11.i from t1 t11) union (select t12.i from t1 t12));
37433746
id select_type table type possible_keys key key_len ref rows Extra
@@ -5305,7 +5308,7 @@ SELECT ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
53055308
( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) )
53065309
1
53075310
SELECT ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1;
5308-
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 'UNION SELECT 1' at line 1
5311+
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 '' at line 1
53095312
SELECT ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
53105313
( SELECT 1 UNION SELECT 1 UNION SELECT 1 )
53115314
1
@@ -5335,15 +5338,17 @@ SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
53355338
a
53365339
1
53375340
SELECT * FROM t1 WHERE a = ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
5338-
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 'UNION SELECT 1 )' at line 1
5341+
a
5342+
1
53395343
SELECT * FROM t1 WHERE a = ALL ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
53405344
a
53415345
1
53425346
SELECT * FROM t1 WHERE a = ANY ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
53435347
a
53445348
1
53455349
SELECT * FROM t1 WHERE a IN ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
5346-
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 'UNION SELECT 1 )' at line 1
5350+
a
5351+
1
53475352
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
53485353
a
53495354
1

mysql-test/main/subselect.test

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2611,8 +2611,6 @@ SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS
26112611
SELECT * FROM t1
26122612
WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1)));
26132613

2614-
#TODO:not supported
2615-
--error ER_PARSE_ERROR
26162614
explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12))
26172615
from t1;
26182616

@@ -4414,11 +4412,9 @@ SELECT * FROM t1 WHERE a = ALL ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
44144412
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
44154413
SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
44164414

4417-
--error ER_PARSE_ERROR
44184415
SELECT * FROM t1 WHERE a = ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
44194416
SELECT * FROM t1 WHERE a = ALL ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
44204417
SELECT * FROM t1 WHERE a = ANY ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
4421-
--error ER_PARSE_ERROR
44224418
SELECT * FROM t1 WHERE a IN ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
44234419

44244420
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );

mysql-test/main/subselect_no_exists_to_in.result

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3739,8 +3739,11 @@ WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1)));
37393739
i
37403740
explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12))
37413741
from t1;
3742-
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 'union (select t12.i from t1 t12))
3743-
from t1' at line 1
3742+
id select_type table type possible_keys key key_len ref rows Extra
3743+
1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found
3744+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
3745+
3 UNION NULL NULL NULL NULL NULL NULL NULL no matching row in const table
3746+
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
37443747
explain select * from t1 where not exists
37453748
((select t11.i from t1 t11) union (select t12.i from t1 t12));
37463749
id select_type table type possible_keys key key_len ref rows Extra
@@ -5307,7 +5310,7 @@ SELECT ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
53075310
( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) )
53085311
1
53095312
SELECT ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1;
5310-
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 'UNION SELECT 1' at line 1
5313+
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 '' at line 1
53115314
SELECT ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
53125315
( SELECT 1 UNION SELECT 1 UNION SELECT 1 )
53135316
1
@@ -5337,15 +5340,17 @@ SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
53375340
a
53385341
1
53395342
SELECT * FROM t1 WHERE a = ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
5340-
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 'UNION SELECT 1 )' at line 1
5343+
a
5344+
1
53415345
SELECT * FROM t1 WHERE a = ALL ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
53425346
a
53435347
1
53445348
SELECT * FROM t1 WHERE a = ANY ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
53455349
a
53465350
1
53475351
SELECT * FROM t1 WHERE a IN ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
5348-
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 'UNION SELECT 1 )' at line 1
5352+
a
5353+
1
53495354
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
53505355
a
53515356
1

mysql-test/main/subselect_no_mat.result

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3739,8 +3739,11 @@ WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1)));
37393739
i
37403740
explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12))
37413741
from t1;
3742-
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 'union (select t12.i from t1 t12))
3743-
from t1' at line 1
3742+
id select_type table type possible_keys key key_len ref rows Extra
3743+
1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found
3744+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
3745+
3 UNION NULL NULL NULL NULL NULL NULL NULL no matching row in const table
3746+
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
37443747
explain select * from t1 where not exists
37453748
((select t11.i from t1 t11) union (select t12.i from t1 t12));
37463749
id select_type table type possible_keys key key_len ref rows Extra
@@ -5305,7 +5308,7 @@ SELECT ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
53055308
( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) )
53065309
1
53075310
SELECT ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1;
5308-
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 'UNION SELECT 1' at line 1
5311+
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 '' at line 1
53095312
SELECT ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
53105313
( SELECT 1 UNION SELECT 1 UNION SELECT 1 )
53115314
1
@@ -5335,15 +5338,17 @@ SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
53355338
a
53365339
1
53375340
SELECT * FROM t1 WHERE a = ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
5338-
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 'UNION SELECT 1 )' at line 1
5341+
a
5342+
1
53395343
SELECT * FROM t1 WHERE a = ALL ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
53405344
a
53415345
1
53425346
SELECT * FROM t1 WHERE a = ANY ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
53435347
a
53445348
1
53455349
SELECT * FROM t1 WHERE a IN ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
5346-
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 'UNION SELECT 1 )' at line 1
5350+
a
5351+
1
53475352
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
53485353
a
53495354
1

0 commit comments

Comments
 (0)