Merge remote-tracking branch 'origin/10.4' into 10.5

This commit is contained in:
Alexander Barkov 2019-09-24 12:41:38 +04:00
commit edef6a0074
24 changed files with 7220 additions and 599 deletions

View File

@ -2668,7 +2668,7 @@ static int fake_magic_space(const char *, int)
static void initialize_readline ()
{
/* Allow conditional parsing of the ~/.inputrc file. */
rl_readline_name= "mysql";
rl_readline_name= (char *) "mysql";
rl_terminal_name= getenv("TERM");
/* Tell the completer that we want a crack first. */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -25,7 +25,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 EXCEPT t2 ALL NULL NULL NULL NULL 2 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 (/* select#3 */ select `test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2`)) `a`
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`
EXPLAIN format=json (select a,b from t1) except (select c,d from t2);
EXPLAIN
{
@ -230,7 +230,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 EXCEPT t4 ALL NULL NULL NULL NULL 2 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 `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`
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`
EXPLAIN format=json (select a,b,e,f from t1,t3) except (select c,d,g,h from t2,t4);
EXPLAIN
{

View File

@ -103,7 +103,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
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`
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
{
@ -337,7 +337,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
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`
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
{

View File

@ -39,7 +39,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
4 INTERSECT t3 ALL NULL NULL NULL NULL 3 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 (/* 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`
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`
EXPLAIN format=json (select a,b from t1) intersect (select c,d from t2) intersect (select e,f from t3);
EXPLAIN
{
@ -280,7 +280,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 INTERSECT t3 ALL NULL NULL NULL NULL 3 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 (/* select#3 */ select `test`.`t2`.`c` AS `c`,`test`.`t3`.`e` AS `e` from `test`.`t2` join `test`.`t3`)) `a`
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`
set @@optimizer_switch='optimize_join_buffer_size=off';
EXPLAIN format=json (select a,b from t1) intersect (select c,e from t2,t3);
EXPLAIN
@ -688,7 +688,7 @@ a b
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 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
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
drop view v1;
drop tables t1,t2,t3;
#

View File

@ -51,7 +51,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
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`
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
{
@ -312,7 +312,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
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`
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
{
@ -741,7 +741,7 @@ a b
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
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);

View File

@ -1776,7 +1776,7 @@ End of 10.3 tests
#
create table t1 (a int);
(select * from t1) for update;
ERROR HY000: Incorrect usage of lock options and SELECT in brackets
a
(select * from t1) union (select * from t1) for update;
ERROR HY000: Incorrect usage of lock options and SELECT in brackets
(select * from t1 for update);

View File

@ -1544,7 +1544,6 @@ SELECT @@GLOBAL.role;
--echo #
create table t1 (a int);
--error ER_WRONG_USAGE
(select * from t1) for update;
--error ER_WRONG_USAGE
(select * from t1) union (select * from t1) for update;

View File

@ -3736,8 +3736,11 @@ WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1)));
i
explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12))
from t1;
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))
from t1' at line 1
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
3 UNION NULL NULL NULL NULL NULL NULL NULL no matching row in const table
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
explain select * from t1 where not exists
((select t11.i from t1 t11) union (select t12.i from t1 t12));
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 ) );
( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) )
1
SELECT ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1;
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
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
SELECT ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
( SELECT 1 UNION SELECT 1 UNION SELECT 1 )
1
@ -5335,7 +5338,8 @@ SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
a
1
SELECT * FROM t1 WHERE a = ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
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
a
1
SELECT * FROM t1 WHERE a = ALL ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
a
1
@ -5343,7 +5347,8 @@ SELECT * FROM t1 WHERE a = ANY ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE a IN ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
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
a
1
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
a
1

View File

@ -2611,8 +2611,6 @@ SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS
SELECT * FROM t1
WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1)));
#TODO:not supported
--error ER_PARSE_ERROR
explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12))
from t1;
@ -4414,11 +4412,9 @@ SELECT * FROM t1 WHERE a = ALL ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
--error ER_PARSE_ERROR
SELECT * FROM t1 WHERE a = ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
SELECT * FROM t1 WHERE a = ALL ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
SELECT * FROM t1 WHERE a = ANY ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
--error ER_PARSE_ERROR
SELECT * FROM t1 WHERE a IN ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );

View File

@ -3739,8 +3739,11 @@ WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1)));
i
explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12))
from t1;
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))
from t1' at line 1
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
3 UNION NULL NULL NULL NULL NULL NULL NULL no matching row in const table
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
explain select * from t1 where not exists
((select t11.i from t1 t11) union (select t12.i from t1 t12));
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 ) );
( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) )
1
SELECT ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1;
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
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
SELECT ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
( SELECT 1 UNION SELECT 1 UNION SELECT 1 )
1
@ -5337,7 +5340,8 @@ SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
a
1
SELECT * FROM t1 WHERE a = ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
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
a
1
SELECT * FROM t1 WHERE a = ALL ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
a
1
@ -5345,7 +5349,8 @@ SELECT * FROM t1 WHERE a = ANY ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE a IN ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
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
a
1
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
a
1

View File

@ -3739,8 +3739,11 @@ WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1)));
i
explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12))
from t1;
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))
from t1' at line 1
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
3 UNION NULL NULL NULL NULL NULL NULL NULL no matching row in const table
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
explain select * from t1 where not exists
((select t11.i from t1 t11) union (select t12.i from t1 t12));
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 ) );
( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) )
1
SELECT ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1;
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
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
SELECT ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
( SELECT 1 UNION SELECT 1 UNION SELECT 1 )
1
@ -5335,7 +5338,8 @@ SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
a
1
SELECT * FROM t1 WHERE a = ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
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
a
1
SELECT * FROM t1 WHERE a = ALL ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
a
1
@ -5343,7 +5347,8 @@ SELECT * FROM t1 WHERE a = ANY ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE a IN ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
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
a
1
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
a
1

View File

@ -3735,8 +3735,11 @@ WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1)));
i
explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12))
from t1;
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))
from t1' at line 1
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
3 UNION NULL NULL NULL NULL NULL NULL NULL no matching row in const table
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
explain select * from t1 where not exists
((select t11.i from t1 t11) union (select t12.i from t1 t12));
id select_type table type possible_keys key key_len ref rows Extra
@ -5301,7 +5304,7 @@ SELECT ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) )
1
SELECT ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1;
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
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
SELECT ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
( SELECT 1 UNION SELECT 1 UNION SELECT 1 )
1
@ -5331,7 +5334,8 @@ SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
a
1
SELECT * FROM t1 WHERE a = ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
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
a
1
SELECT * FROM t1 WHERE a = ALL ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
a
1
@ -5339,7 +5343,8 @@ SELECT * FROM t1 WHERE a = ANY ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE a IN ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
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
a
1
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
a
1

View File

@ -3742,8 +3742,11 @@ WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1)));
i
explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12))
from t1;
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))
from t1' at line 1
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
3 UNION NULL NULL NULL NULL NULL NULL NULL no matching row in const table
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
explain select * from t1 where not exists
((select t11.i from t1 t11) union (select t12.i from t1 t12));
id select_type table type possible_keys key key_len ref rows Extra
@ -5311,7 +5314,7 @@ SELECT ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) )
1
SELECT ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1;
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
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
SELECT ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
( SELECT 1 UNION SELECT 1 UNION SELECT 1 )
1
@ -5341,7 +5344,8 @@ SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
a
1
SELECT * FROM t1 WHERE a = ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
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
a
1
SELECT * FROM t1 WHERE a = ALL ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
a
1
@ -5349,7 +5353,8 @@ SELECT * FROM t1 WHERE a = ANY ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE a IN ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
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
a
1
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
a
1

View File

@ -3735,8 +3735,11 @@ WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1)));
i
explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12))
from t1;
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))
from t1' at line 1
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 0 Const row not found
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
3 UNION NULL NULL NULL NULL NULL NULL NULL no matching row in const table
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
explain select * from t1 where not exists
((select t11.i from t1 t11) union (select t12.i from t1 t12));
id select_type table type possible_keys key key_len ref rows Extra
@ -5301,7 +5304,7 @@ SELECT ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) )
1
SELECT ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1;
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
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
SELECT ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
( SELECT 1 UNION SELECT 1 UNION SELECT 1 )
1
@ -5331,7 +5334,8 @@ SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
a
1
SELECT * FROM t1 WHERE a = ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
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
a
1
SELECT * FROM t1 WHERE a = ALL ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
a
1
@ -5339,7 +5343,8 @@ SELECT * FROM t1 WHERE a = ANY ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE a IN ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
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
a
1
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
a
1

View File

@ -124,7 +124,8 @@ void Item_subselect::init(st_select_lex *select_lex,
parsing_place= (outer_select->in_sum_expr ?
NO_MATTER :
outer_select->parsing_place);
if (unit->is_unit_op() && unit->first_select()->next_select())
if (unit->is_unit_op() &&
(unit->first_select()->next_select() or unit->fake_select_lex))
engine= new subselect_union_engine(unit, result, this);
else
engine= new subselect_single_select_engine(select_lex, result, this);

View File

@ -1448,7 +1448,7 @@ int Lex_input_stream::lex_token(YYSTYPE *yylval, THD *thd)
return LEFT_PAREN_LIKE;
if (token == WITH)
return LEFT_PAREN_WITH;
if (token != left_paren && token != SELECT_SYM)
if (token != left_paren && token != SELECT_SYM && token != VALUES)
return LEFT_PAREN_ALT;
else
return left_paren;
@ -5344,10 +5344,9 @@ LEX::create_unit(SELECT_LEX *first_sel)
SELECT_LEX_UNIT *unit;
DBUG_ENTER("LEX::create_unit");
if (first_sel->master_unit())
DBUG_RETURN(first_sel->master_unit());
unit = first_sel->master_unit();
if (!(unit= alloc_unit()))
if (!unit && !(unit= alloc_unit()))
DBUG_RETURN(NULL);
unit->register_select_chain(first_sel);
@ -9019,7 +9018,8 @@ bool LEX::insert_select_hack(SELECT_LEX *sel)
builtin_select.link_prev= NULL; // indicator of removal
}
set_main_unit(sel->master_unit());
if (set_main_unit(sel->master_unit()))
return true;
DBUG_ASSERT(builtin_select.table_list.elements == 1);
TABLE_LIST *insert_table= builtin_select.table_list.first;
@ -9063,9 +9063,10 @@ bool LEX::insert_select_hack(SELECT_LEX *sel)
}
/*
/**
Create an Item_singlerow_subselect for a query expression.
*/
Item *LEX::create_item_query_expression(THD *thd,
st_select_lex_unit *unit)
{
@ -9080,118 +9081,17 @@ Item *LEX::create_item_query_expression(THD *thd,
SELECT_LEX *curr_sel= select_stack_head();
DBUG_ASSERT(current_select == curr_sel);
if (!curr_sel)
{
curr_sel= &builtin_select;
curr_sel->register_unit(unit, &curr_sel->context);
curr_sel->add_statistics(unit);
curr_sel->register_unit(unit, &curr_sel->context);
curr_sel->add_statistics(unit);
}
return new (thd->mem_root)
Item_singlerow_subselect(thd, unit->first_select());
}
/**
Process unit parsed in brackets
*/
bool LEX::parsed_unit_in_brackets(SELECT_LEX_UNIT *unit)
{
SELECT_LEX *first_in_nest= unit->pre_last_parse->next_select()->first_nested;
if (first_in_nest->first_nested != first_in_nest)
{
/* There is a priority jump starting from first_in_nest */
if (create_priority_nest(first_in_nest) == NULL)
return true;
unit->fix_distinct();
}
push_select(unit->fake_select_lex);
return false;
}
/**
Process tail of unit parsed in brackets
*/
SELECT_LEX *LEX::parsed_unit_in_brackets_tail(SELECT_LEX_UNIT *unit,
Lex_order_limit_lock * l)
{
pop_select();
if (l)
{
(l)->set_to(unit->fake_select_lex);
}
return unit->first_select();
}
/**
Process select parsed in brackets
*/
SELECT_LEX *LEX::parsed_select(SELECT_LEX *sel, Lex_order_limit_lock * l)
{
pop_select();
if (l)
{
if (sel->next_select())
{
SELECT_LEX_UNIT *unit= sel->master_unit();
if (!unit)
unit= create_unit(sel);
if (!unit)
return NULL;
if (!unit->fake_select_lex->is_set_query_expr_tail)
l->set_to(unit->fake_select_lex);
else
{
if (!l->order_list && !unit->fake_select_lex->explicit_limit)
{
sel= unit->fake_select_lex;
l->order_list= &sel->order_list;
}
else
sel= wrap_unit_into_derived(unit);
if (!sel)
return NULL;
l->set_to(sel);
}
}
else if (!sel->is_set_query_expr_tail)
{
l->set_to(sel);
}
else
{
if (!l->order_list && !sel->explicit_limit)
l->order_list= &sel->order_list;
else
{
SELECT_LEX_UNIT *unit= create_unit(sel);
if (!unit)
return NULL;
sel= wrap_unit_into_derived(unit);
}
if (!sel)
return NULL;
l->set_to(sel);
}
}
return sel;
}
/**
Process select parsed in brackets
*/
SELECT_LEX *LEX::parsed_select_in_brackets(SELECT_LEX *sel,
Lex_order_limit_lock * l)
{
sel->braces= TRUE;
return parsed_select(sel, l);
}
SELECT_LEX_UNIT *LEX::parsed_select_expr_start(SELECT_LEX *s1, SELECT_LEX *s2,
enum sub_select_type unit_type,
bool distinct)
@ -9222,6 +9122,7 @@ SELECT_LEX_UNIT *LEX::parsed_select_expr_start(SELECT_LEX *s1, SELECT_LEX *s2,
if (res == NULL)
return NULL;
res->pre_last_parse= sel1;
push_select(res->fake_select_lex);
return res;
}
@ -9234,12 +9135,6 @@ SELECT_LEX_UNIT *LEX::parsed_select_expr_cont(SELECT_LEX_UNIT *unit,
SELECT_LEX *sel1;
if (!s2->next_select())
sel1= s2;
else
{
sel1= wrap_unit_into_derived(s2->master_unit());
if (!sel1)
return NULL;
}
SELECT_LEX *last= unit->pre_last_parse->next_select();
int cmp= oracle? 0 : cmp_unit_op(unit_type, last->get_linkage());
@ -9271,41 +9166,73 @@ SELECT_LEX_UNIT *LEX::parsed_select_expr_cont(SELECT_LEX_UNIT *unit,
return unit;
}
/**
Process parsed select in body
Add primary expression as the next term in a given query expression body
pruducing a new query expression body
*/
SELECT_LEX_UNIT *LEX::parsed_body_select(SELECT_LEX *sel,
Lex_order_limit_lock * l)
SELECT_LEX_UNIT *
LEX::add_primary_to_query_expression_body(SELECT_LEX_UNIT *unit,
SELECT_LEX *sel,
enum sub_select_type unit_type,
bool distinct,
bool oracle)
{
if (sel->braces && l && l->lock.defined_lock)
SELECT_LEX *sel2= sel;
if (sel->master_unit() && sel->master_unit()->first_select()->next_select())
{
my_error(ER_WRONG_USAGE, MYF(0), "lock options",
"SELECT in brackets");
return NULL;
}
if (!(sel= parsed_select(sel, l)))
return NULL;
SELECT_LEX_UNIT *res= create_unit(sel);
if (res && sel->tvc && sel->order_list.elements)
{
if (res->add_fake_select_lex(thd))
sel2= wrap_unit_into_derived(sel->master_unit());
if (!sel2)
return NULL;
SELECT_LEX *fake= res->fake_select_lex;
fake->order_list= sel->order_list;
fake->explicit_limit= sel->explicit_limit;
fake->select_limit= sel->select_limit;
fake->offset_limit= sel->offset_limit;
}
return res;
SELECT_LEX *sel1= unit->first_select();
if (!sel1->next_select())
unit= parsed_select_expr_start(sel1, sel2, unit_type, distinct);
else
unit= parsed_select_expr_cont(unit, sel2, unit_type, distinct, oracle);
return unit;
}
/**
Process parsed unit in body
Add query primary to a parenthesized query primary
pruducing a new query expression body
*/
bool LEX::parsed_body_unit(SELECT_LEX_UNIT *unit)
SELECT_LEX_UNIT *
LEX::add_primary_to_query_expression_body_ext_parens(
SELECT_LEX_UNIT *unit,
SELECT_LEX *sel,
enum sub_select_type unit_type,
bool distinct)
{
SELECT_LEX *sel1= unit->first_select();
if (unit->first_select()->next_select())
{
sel1= wrap_unit_into_derived(unit);
if (!sel1)
return NULL;
if (!create_unit(sel1))
return NULL;
}
SELECT_LEX *sel2= sel;
if (sel->master_unit() && sel->master_unit()->first_select()->next_select())
{
sel2= wrap_unit_into_derived(sel->master_unit());
if (!sel2)
return NULL;
}
unit= parsed_select_expr_start(sel1, sel2, unit_type, distinct);
return unit;
}
/**
Process multi-operand query expression body
*/
bool LEX::parsed_multi_operand_query_expression_body(SELECT_LEX_UNIT *unit)
{
SELECT_LEX *first_in_nest=
unit->pre_last_parse->next_select()->first_nested;
@ -9316,27 +9243,60 @@ bool LEX::parsed_body_unit(SELECT_LEX_UNIT *unit)
return true;
unit->fix_distinct();
}
push_select(unit->fake_select_lex);
return false;
}
/**
Process parsed tail of unit in body
TODO: make processing for double tail case
/**
Add non-empty tail to a query expression body
*/
SELECT_LEX_UNIT *LEX::parsed_body_unit_tail(SELECT_LEX_UNIT *unit,
Lex_order_limit_lock * l)
SELECT_LEX_UNIT *LEX::add_tail_to_query_expression_body(SELECT_LEX_UNIT *unit,
Lex_order_limit_lock *l)
{
DBUG_ASSERT(l != NULL);
pop_select();
if (l)
{
(l)->set_to(unit->fake_select_lex);
}
SELECT_LEX *sel= unit->first_select()->next_select() ? unit->fake_select_lex :
unit->first_select();
l->set_to(sel);
return unit;
}
/**
Add non-empty tail to a parenthesized query primary
*/
SELECT_LEX_UNIT *
LEX::add_tail_to_query_expression_body_ext_parens(SELECT_LEX_UNIT *unit,
Lex_order_limit_lock *l)
{
SELECT_LEX *sel= unit->first_select()->next_select() ? unit->fake_select_lex :
unit->first_select();
DBUG_ASSERT(l != NULL);
pop_select();
if (sel->is_set_query_expr_tail)
{
if (!l->order_list && !sel->explicit_limit)
l->order_list= &sel->order_list;
else
{
if (!unit)
return NULL;
sel= wrap_unit_into_derived(unit);
if (!sel)
return NULL;
if (!create_unit(sel))
return NULL;
}
}
l->set_to(sel);
return sel->master_unit();
}
/**
Process subselect parsing
*/
@ -9363,7 +9323,6 @@ SELECT_LEX *LEX::parsed_subselect(SELECT_LEX_UNIT *unit)
}
/**
Process INSERT-like select
*/
@ -9418,40 +9377,8 @@ SELECT_LEX *LEX::parsed_TVC_end()
}
TABLE_LIST *LEX::parsed_derived_select(SELECT_LEX *sel, int for_system_time,
LEX_CSTRING *alias)
{
TABLE_LIST *res;
derived_tables|= DERIVED_SUBQUERY;
sel->set_linkage(DERIVED_TABLE_TYPE);
sel->braces= FALSE;
// Add the subtree of subquery to the current SELECT_LEX
SELECT_LEX *curr_sel= select_stack_head();
DBUG_ASSERT(current_select == curr_sel);
SELECT_LEX_UNIT *unit= sel->master_unit();
if (!unit)
{
unit= create_unit(sel);
if (!unit)
return NULL;
}
curr_sel->register_unit(unit, &curr_sel->context);
curr_sel->add_statistics(unit);
Table_ident *ti= new (thd->mem_root) Table_ident(unit);
if (ti == NULL)
return NULL;
if (!(res= curr_sel->add_table_to_list(thd, ti, alias, 0,
TL_READ, MDL_SHARED_READ)))
return NULL;
if (for_system_time)
{
res->vers_conditions= vers_conditions;
}
return res;
}
TABLE_LIST *LEX::parsed_derived_unit(SELECT_LEX_UNIT *unit,
TABLE_LIST *LEX::parsed_derived_table(SELECT_LEX_UNIT *unit,
int for_system_time,
LEX_CSTRING *alias)
{
@ -9462,8 +9389,6 @@ TABLE_LIST *LEX::parsed_derived_unit(SELECT_LEX_UNIT *unit,
// Add the subtree of subquery to the current SELECT_LEX
SELECT_LEX *curr_sel= select_stack_head();
DBUG_ASSERT(current_select == curr_sel);
curr_sel->register_unit(unit, &curr_sel->context);
curr_sel->add_statistics(unit);
Table_ident *ti= new (thd->mem_root) Table_ident(unit);
if (ti == NULL)
@ -9481,7 +9406,8 @@ TABLE_LIST *LEX::parsed_derived_unit(SELECT_LEX_UNIT *unit,
bool LEX::parsed_create_view(SELECT_LEX_UNIT *unit, int check)
{
SQL_I_List<TABLE_LIST> *save= &first_select_lex()->table_list;
set_main_unit(unit);
if (set_main_unit(unit))
return true;
if (check_main_unit_semantics())
return true;
first_select_lex()->table_list.push_front(save);
@ -9504,7 +9430,8 @@ bool LEX::select_finalize(st_select_lex_unit *expr)
sql_command= SQLCOM_SELECT;
selects_allow_into= TRUE;
selects_allow_procedure= TRUE;
set_main_unit(expr);
if (set_main_unit(expr))
return true;
return check_main_unit_semantics();
}
@ -9515,6 +9442,7 @@ bool LEX::select_finalize(st_select_lex_unit *expr, Lex_select_lock l)
select_finalize(expr);
}
/*
"IN" and "EXISTS" subselect can appear in two statement types:
@ -9547,7 +9475,6 @@ void LEX::relink_hack(st_select_lex *select_lex)
}
bool SELECT_LEX_UNIT::set_lock_to_the_last_select(Lex_select_lock l)
{
if (l.defined_lock)

View File

@ -4435,9 +4435,6 @@ public:
insert_list= 0;
}
bool make_select_in_brackets(SELECT_LEX* dummy_select,
SELECT_LEX *nselect, bool automatic);
SELECT_LEX_UNIT *alloc_unit();
SELECT_LEX *alloc_select(bool is_select);
SELECT_LEX_UNIT *create_unit(SELECT_LEX*);
@ -4453,7 +4450,7 @@ public:
bool insert_select_hack(SELECT_LEX *sel);
SELECT_LEX *create_priority_nest(SELECT_LEX *first_in_nest);
void set_main_unit(st_select_lex_unit *u)
bool set_main_unit(st_select_lex_unit *u)
{
unit.options= u->options;
unit.uncacheable= u->uncacheable;
@ -4463,16 +4460,10 @@ public:
unit.union_distinct= u->union_distinct;
unit.set_with_clause(u->with_clause);
builtin_select.exclude_from_global();
return false;
}
bool check_main_unit_semantics();
// reaction on different parsed parts (bodies are in sql_yacc.yy)
bool parsed_unit_in_brackets(SELECT_LEX_UNIT *unit);
SELECT_LEX *parsed_select(SELECT_LEX *sel, Lex_order_limit_lock * l);
SELECT_LEX *parsed_unit_in_brackets_tail(SELECT_LEX_UNIT *unit,
Lex_order_limit_lock * l);
SELECT_LEX *parsed_select_in_brackets(SELECT_LEX *sel,
Lex_order_limit_lock * l);
SELECT_LEX_UNIT *parsed_select_expr_start(SELECT_LEX *s1, SELECT_LEX *s2,
enum sub_select_type unit_type,
bool distinct);
@ -4480,20 +4471,35 @@ public:
SELECT_LEX *s2,
enum sub_select_type unit_type,
bool distinct, bool oracle);
SELECT_LEX_UNIT *parsed_body_select(SELECT_LEX *sel,
Lex_order_limit_lock * l);
bool parsed_body_unit(SELECT_LEX_UNIT *unit);
SELECT_LEX_UNIT *parsed_body_unit_tail(SELECT_LEX_UNIT *unit,
Lex_order_limit_lock * l);
bool parsed_multi_operand_query_expression_body(SELECT_LEX_UNIT *unit);
SELECT_LEX_UNIT *add_tail_to_query_expression_body(SELECT_LEX_UNIT *unit,
Lex_order_limit_lock *l);
SELECT_LEX_UNIT *
add_tail_to_query_expression_body_ext_parens(SELECT_LEX_UNIT *unit,
Lex_order_limit_lock *l);
SELECT_LEX_UNIT *parsed_body_ext_parens_primary(SELECT_LEX_UNIT *unit,
SELECT_LEX *primary,
enum sub_select_type unit_type,
bool distinct);
SELECT_LEX_UNIT *
add_primary_to_query_expression_body(SELECT_LEX_UNIT *unit,
SELECT_LEX *sel,
enum sub_select_type unit_type,
bool distinct,
bool oracle);
SELECT_LEX_UNIT *
add_primary_to_query_expression_body_ext_parens(
SELECT_LEX_UNIT *unit,
SELECT_LEX *sel,
enum sub_select_type unit_type,
bool distinct);
SELECT_LEX *parsed_subselect(SELECT_LEX_UNIT *unit);
bool parsed_insert_select(SELECT_LEX *firs_select);
bool parsed_TVC_start();
SELECT_LEX *parsed_TVC_end();
TABLE_LIST *parsed_derived_select(SELECT_LEX *sel, int for_system_time,
LEX_CSTRING *alias);
TABLE_LIST *parsed_derived_unit(SELECT_LEX_UNIT *unit,
int for_system_time,
LEX_CSTRING *alias);
TABLE_LIST *parsed_derived_table(SELECT_LEX_UNIT *unit,
int for_system_time,
LEX_CSTRING *alias);
bool parsed_create_view(SELECT_LEX_UNIT *unit, int check);
bool select_finalize(st_select_lex_unit *expr);
bool select_finalize(st_select_lex_unit *expr, Lex_select_lock l);

View File

@ -11310,7 +11310,7 @@ bool Sql_cmd_create_table_like::execute(THD *thd)
}
#endif
if (select_lex->item_list.elements) // With select
if (select_lex->item_list.elements || select_lex->tvc) // With select or TVC
{
select_result *result;

View File

@ -599,8 +599,8 @@ static bool create_tvc_name(THD *thd, st_select_lex *parent_select,
bool table_value_constr::to_be_wrapped_as_with_tail()
{
return select_lex->master_unit()->first_select()->next_select() &&
select_lex->order_list.elements && select_lex->explicit_limit;
return select_lex->master_unit()->first_select()->next_select() &&
select_lex->order_list.elements && select_lex->explicit_limit;
}

View File

@ -1304,8 +1304,8 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
bool have_except= false, have_intersect= false,
have_except_all_or_intersect_all= false;
bool instantiate_tmp_table= false;
bool single_tvc= !first_sl->next_select() && first_sl->tvc &&
!fake_select_lex;
bool single_tvc= !first_sl->next_select() && first_sl->tvc;
bool single_tvc_wo_order= single_tvc && !first_sl->order_list.elements;
DBUG_ENTER("st_select_lex_unit::prepare");
DBUG_ASSERT(thd == current_thd);
@ -1409,8 +1409,9 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
if (is_union_select || is_recursive)
{
if ((is_unit_op() && !union_needs_tmp_table() &&
!have_except && !have_intersect) || single_tvc)
if ((single_tvc_wo_order && !fake_select_lex) ||
(is_unit_op() && !union_needs_tmp_table() &&
!have_except && !have_intersect && !single_tvc))
{
SELECT_LEX *last= first_select();
while (last->next_select())
@ -1425,6 +1426,7 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
else
{
if (!is_recursive)
{
/*
class "select_unit_ext" handles query contains EXCEPT ALL and / or
INTERSECT ALL. Others are handled by class "select_unit"
@ -1437,7 +1439,8 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
first_sl->distinct= false;
}
else
union_result= new (thd->mem_root) select_unit(thd);
union_result= new (thd->mem_root) select_unit(thd);
}
else
{
with_element->rec_result=
@ -1483,17 +1486,40 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
if (sl->tvc && sl->order_list.elements &&
!sl->tvc->to_be_wrapped_as_with_tail())
{
SELECT_LEX_UNIT *unit= sl->master_unit();
if (thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW)
{
sl->master_unit()->fake_select_lex= 0;
sl->master_unit()->saved_fake_select_lex= 0;
unit->fake_select_lex= 0;
unit->saved_fake_select_lex= 0;
}
else
{
sl->order_list.empty();
sl->explicit_limit= 0;
sl->select_limit= 0;
sl->offset_limit= 0;
if (!unit->first_select()->next_select())
{
if (!unit->fake_select_lex)
{
Query_arena *arena, backup_arena;
arena= thd->activate_stmt_arena_if_needed(&backup_arena);
bool rc= unit->add_fake_select_lex(thd);
if (arena)
thd->restore_active_arena(arena, &backup_arena);
if (rc)
goto err;
}
SELECT_LEX *fake= unit->fake_select_lex;
fake->order_list= sl->order_list;
fake->explicit_limit= sl->explicit_limit;
fake->select_limit= sl->select_limit;
fake->offset_limit= sl->offset_limit;
sl->order_list.empty();
sl->explicit_limit= 0;
sl->select_limit= 0;
sl->offset_limit= 0;
if (describe)
fake->options|= SELECT_DESCRIBE;
}
else if (!sl->explicit_limit)
sl->order_list.empty();
}
}
@ -1518,7 +1544,7 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
goto err;
}
else if (sl->tvc->prepare(thd, sl, tmp_result, this))
goto err;
goto err;
}
else if (prepare_join(thd, sl, tmp_result, additional_options,
is_union_select))

View File

@ -829,10 +829,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%parse-param { THD *thd }
%lex-param { THD *thd }
/*
Currently there are 46 shift/reduce conflicts.
Currently there are 37 shift/reduce conflicts.
We should not introduce new conflicts any more.
*/
%expect 46
%expect 37
/*
Comments for TOKENS.
@ -1644,6 +1644,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%left MYSQL_CONCAT_SYM
%left NEG '~' NOT2_SYM BINARY
%left COLLATE_SYM
%left SUBQUERY_AS_EXPR
/*
Tokens that can change their meaning from identifier to something else
@ -1734,7 +1735,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
ALTER TABLE t1 ADD SYSTEM VERSIONING;
*/
%left PREC_BELOW_CONTRACTION_TOKEN2
%left TEXT_STRING '(' VALUE_SYM VERSIONING_SYM
%left TEXT_STRING '(' ')' VALUE_SYM VERSIONING_SYM
%left EMPTY_FROM_CLAUSE
%right INTO
%type <lex_str>
DECIMAL_NUM FLOAT_NUM NUM LONG_NUM
@ -1997,16 +2000,18 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
query_specification
table_value_constructor
simple_table
query_simple
query_primary
query_primary_parens
subquery
select_into_query_specification
%type <select_lex_unit>
query_specification_start
query_expression_body
query_expression
query_expression_unit
query_expression_no_with_clause
query_expression_body_ext
query_expression_body_ext_parens
query_expression_body
query_specification_start
%type <boolfunc2creator> comp_op
@ -2031,7 +2036,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%type <order_limit_lock>
query_expression_tail
opt_query_expression_tail
order_or_limit
order_limit_lock
opt_order_limit_lock
%type <select_order> opt_order_clause order_clause order_list
@ -2184,7 +2191,7 @@ END_OF_INPUT
THEN_SYM WHEN_SYM DIV_SYM MOD_SYM OR2_SYM AND_AND_SYM DELETE_SYM
MYSQL_CONCAT_SYM ORACLE_CONCAT_SYM
%type <with_clause> opt_with_clause with_clause
%type <with_clause> with_clause
%type <lex_str_ptr> query_name
@ -5272,7 +5279,7 @@ create_select_query_expression:
if (Lex->parsed_insert_select($1->first_select()))
MYSQL_YYABORT;
}
| LEFT_PAREN_WITH with_clause query_expression_body ')'
| LEFT_PAREN_WITH with_clause query_expression_no_with_clause ')'
{
SELECT_LEX *first_select= $3->first_select();
$3->set_with_clause($2);
@ -6785,12 +6792,7 @@ parse_vcol_expr:
;
parenthesized_expr:
query_expression
{
if (!($$= Lex->create_item_query_expression(thd, $1)))
MYSQL_YYABORT;
}
| expr
expr
| expr ',' expr_list
{
$3->push_front($1, thd->mem_root);
@ -6809,6 +6811,16 @@ virtual_column_func:
MYSQL_YYABORT;
$$= v;
}
| subquery
{
Item *item;
if (!(item= new (thd->mem_root) Item_singlerow_subselect(thd, $1)))
MYSQL_YYABORT;
Virtual_column_info *v= add_virtual_expression(thd, item);
if (unlikely(!v))
MYSQL_YYABORT;
$$= v;
}
;
expr_or_literal: column_default_non_parenthesized_expr | signed_literal ;
@ -9175,8 +9187,9 @@ opt_ignore_leaves:
Select : retrieve data from table
*/
select:
query_expression_body
query_expression_no_with_clause
{
if (Lex->push_select($1->fake_select_lex ?
$1->fake_select_lex :
@ -9186,10 +9199,11 @@ select:
opt_procedure_or_into
{
Lex->pop_select();
$1->set_with_clause(NULL);
if (Lex->select_finalize($1, $3))
MYSQL_YYABORT;
}
| with_clause query_expression_body
| with_clause query_expression_no_with_clause
{
if (Lex->push_select($2->fake_select_lex ?
$2->fake_select_lex :
@ -9206,7 +9220,6 @@ select:
}
;
select_into:
select_into_query_specification
{
@ -9215,14 +9228,15 @@ select_into:
}
opt_order_limit_lock
{
st_select_lex_unit *unit;
if (!(unit= Lex->parsed_body_select($1, $3)))
SELECT_LEX_UNIT *unit;
if (!(unit = Lex->create_unit($1)))
MYSQL_YYABORT;
if ($3)
unit= Lex->add_tail_to_query_expression_body(unit, $3);
if (Lex->select_finalize(unit))
MYSQL_YYABORT;
}
;
}
;
simple_table:
query_specification { $$= $1; }
@ -9288,94 +9302,193 @@ select_into_query_specification:
}
;
opt_from_clause:
/* Empty */
| from_clause
;
/**
The following grammar for query expressions conformant to
the latest SQL Standard is supported:
query_primary:
simple_table
{ $$= $1; }
| query_primary_parens
{ $$= $1; }
;
<query expression> ::=
[ <with clause> ] <query expression body>
[ <order by clause> ] [ <result offset clause> ] [ <fetch first clause> ]
query_primary_parens:
'(' query_expression_unit
{
if (Lex->parsed_unit_in_brackets($2))
MYSQL_YYABORT;
}
query_expression_tail ')'
{
$$= Lex->parsed_unit_in_brackets_tail($2, $4);
}
| '(' query_primary
{
Lex->push_select($2);
}
query_expression_tail ')'
{
if (!($$= Lex->parsed_select_in_brackets($2, $4)))
YYABORT;
}
;
<with clause> ::=
WITH [ RECURSIVE ] <with_list
query_expression_unit:
query_primary
unit_type_decl
query_primary
{
if (!($$= Lex->parsed_select_expr_start($1, $3, $2.unit_type,
$2.distinct)))
YYABORT;
}
| query_expression_unit
unit_type_decl
query_primary
{
if (!($$= Lex->parsed_select_expr_cont($1, $3, $2.unit_type,
$2.distinct, FALSE)))
YYABORT;
}
;
<with list> ::=
<with list element> [ { <comma> <with list element> }... ]
query_expression_body:
query_primary
{
Lex->push_select($1);
}
query_expression_tail
{
if (!($$= Lex->parsed_body_select($1, $3)))
MYSQL_YYABORT;
}
| query_expression_unit
{
if (Lex->parsed_body_unit($1))
MYSQL_YYABORT;
}
query_expression_tail
{
if (!($$= Lex->parsed_body_unit_tail($1, $3)))
MYSQL_YYABORT;
}
;
<with list element> ::=
<query name> [ '(' <with column list> ')' ]
AS <table subquery>
<with column list> ::=
<column name list>
<query expression body> ::
<query term>
| <query expression body> UNION [ ALL | DISTINCT ] <query term>
| <query expression body> EXCEPT [ DISTINCT ] <query term>
<query term> ::=
<query primary>
| <query term> INTERSECT [ DISTINCT ] <query primary>
<query primary> ::=
<simple table>
| '(' <query expression body>
[ <order by clause> ] [ <result offset clause> ] [ <fetch first clause> ]
')'
<simple table>
<query specification>
| <table value constructor>
<subquery>
'(' <query_expression> ')'
*/
/*
query_expression produces the same expressions as
<query expression>
*/
query_expression:
opt_with_clause
query_expression_body
query_expression_no_with_clause
{
if ($1)
{
$2->set_with_clause($1);
$1->attach_to($2->first_select());
}
$1->set_with_clause(NULL);
$$= $1;
}
| with_clause
query_expression_no_with_clause
{
$2->set_with_clause($1);
$1->attach_to($2->first_select());
$$= $2;
}
;
/*
query_expression_no_with_clause produces the same expressions as
<query expression> without [ <with clause> ]
*/
query_expression_no_with_clause:
query_expression_body_ext { $$= $1; }
| query_expression_body_ext_parens { $$= $1; }
;
/*
query_expression_body_ext produces the same expressions as
<query expression body>
[ <order by clause> ] [ <result offset clause> ] [ <fetch first clause> ]
| '('... <query expression body>
[ <order by clause> ] [ <result offset clause> ] [ <fetch first clause> ]
')'...
Note: number of ')' must be equal to the number of '(' in the rule above
*/
query_expression_body_ext:
query_expression_body
{
if ($1->first_select()->next_select())
{
if (Lex->parsed_multi_operand_query_expression_body($1))
MYSQL_YYABORT;
}
}
opt_query_expression_tail
{
if (!$3)
$$= $1;
else
$$= Lex->add_tail_to_query_expression_body($1, $3);
}
| query_expression_body_ext_parens
{
Lex->push_select(!$1->first_select()->next_select() ?
$1->first_select() : $1->fake_select_lex);
}
query_expression_tail
{
if (!($$= Lex->add_tail_to_query_expression_body_ext_parens($1, $3)))
MYSQL_YYABORT;
}
;
query_expression_body_ext_parens:
'(' query_expression_body_ext_parens ')'
{ $$= $2; }
| '(' query_expression_body_ext ')'
{
SELECT_LEX *sel= $2->first_select()->next_select() ?
$2->fake_select_lex : $2->first_select();
sel->braces= true;
$$= $2;
}
;
/*
query_expression_body produces the same expressions as
<query expression body>
*/
query_expression_body:
query_simple
{
Lex->push_select($1);
if (!($$= Lex->create_unit($1)))
MYSQL_YYABORT;
}
| query_expression_body
unit_type_decl
{
if (!$1->first_select()->next_select())
{
Lex->pop_select();
}
}
query_primary
{
if (!($$= Lex->add_primary_to_query_expression_body($1, $4,
$2.unit_type,
$2.distinct,
FALSE)))
MYSQL_YYABORT;
}
| query_expression_body_ext_parens
unit_type_decl
query_primary
{
if (!($$= Lex->add_primary_to_query_expression_body_ext_parens(
$1, $3,
$2.unit_type,
$2.distinct)))
MYSQL_YYABORT;
}
;
/*
query_primary produces the same expressions as
<query primary>
*/
query_primary:
query_simple
{ $$= $1; }
| query_expression_body_ext_parens
{ $$= $1->first_select(); }
;
/*
query_simple produces the same expressions as
<simple table>
*/
query_simple:
simple_table { $$= $1;}
;
subselect:
query_expression
{
@ -9384,11 +9497,63 @@ subselect:
}
;
/*
subquery produces the same expressions as
<subquery>
/**
<table expression>, as in the SQL standard.
Consider the production rule of the SQL Standard
subquery:
'(' query_expression')'
This rule is equivalent to the rule
subquery:
'(' query_expression_no_with_clause ')'
| '(' with_clause query_expression_no_with_clause ')'
that in its turn is equivalent to
subquery:
'(' query_expression_body_ext ')'
| query_expression_body_ext_parens
| '(' with_clause query_expression_no_with_clause ')'
The latter can be re-written into
subquery:
query_expression_body_ext_parens ')'
| '(' with_clause query_expression_no_with_clause ')'
The last rule allows us to resolve properly the shift/reduce conflict
when subquery is used in expressions such as in the following queries
select (select * from t1 limit 1) + t2.a from t2
select * from t1 where t1.a [not] in (select t2.a from t2)
In the rule below %prec SUBQUERY_AS_EXPR forces the parser to perform a shift
operation rather then a reduce operation when ')' is encountered and can be
considered as the last symbol a query expression.
*/
subquery:
query_expression_body_ext_parens %prec SUBQUERY_AS_EXPR
{
if (!$1->fake_select_lex)
$1->first_select()->braces= false;
else
$1->fake_select_lex->braces= false;
if (!($$= Lex->parsed_subselect($1)))
YYABORT;
}
| '(' with_clause query_expression_no_with_clause ')'
{
$3->set_with_clause($2);
$2->attach_to($3->first_select());
if (!($$= Lex->parsed_subselect($3)))
YYABORT;
}
;
opt_from_clause:
/* empty */ %prec EMPTY_FROM_CLAUSE
| from_clause
;
from_clause:
FROM table_reference_list
;
@ -9552,6 +9717,7 @@ select_lock_type:
}
;
opt_select_lock_type:
/* empty */
{
@ -9563,6 +9729,7 @@ opt_select_lock_type:
}
;
opt_lock_wait_timeout_new:
/* empty */
{
@ -9849,15 +10016,15 @@ bool_pri:
;
predicate:
bit_expr IN_SYM '(' subselect ')'
bit_expr IN_SYM subquery
{
$$= new (thd->mem_root) Item_in_subselect(thd, $1, $4);
$$= new (thd->mem_root) Item_in_subselect(thd, $1, $3);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
| bit_expr not IN_SYM '(' subselect ')'
| bit_expr not IN_SYM subquery
{
Item *item= new (thd->mem_root) Item_in_subselect(thd, $1, $5);
Item *item= new (thd->mem_root) Item_in_subselect(thd, $1, $4);
if (unlikely(item == NULL))
MYSQL_YYABORT;
$$= negate_expression(thd, item);
@ -10378,6 +10545,11 @@ primary_expr:
column_default_non_parenthesized_expr
| explicit_cursor_attr
| '(' parenthesized_expr ')' { $$= $2; }
| subquery
{
if (!($$= Lex->create_item_query_expression(thd, $1->master_unit())))
MYSQL_YYABORT;
}
;
string_factor_expr:
@ -12129,35 +12301,12 @@ table_primary_ident:
}
;
/*
Represents a flattening of the following rules from the SQL:2003
standard. This sub-rule corresponds to the sub-rule
<table primary> ::= ... | <derived table> [ AS ] <correlation name>
<derived table> ::= <table subquery>
<table subquery> ::= <subquery>
<subquery> ::= <left paren> <query expression> <right paren>
<query expression> ::= [ <with clause> ] <query expression body>
For the time being we use the non-standard rule
select_derived_union which is a compromise between the standard
and our parser. Possibly this rule could be replaced by our
query_expression_body.
*/
table_primary_derived:
query_primary_parens opt_for_system_time_clause table_alias_clause
subquery
opt_for_system_time_clause table_alias_clause
{
if (!($$= Lex->parsed_derived_select($1, $2, $3)))
YYABORT;
}
| '('
query_expression
')' opt_for_system_time_clause table_alias_clause
{
if (!($$= Lex->parsed_derived_unit($2, $4, $5)))
YYABORT;
if (!($$= Lex->parsed_derived_table($1->master_unit(), $2, $3)))
MYSQL_YYABORT;
}
;
@ -12293,7 +12442,6 @@ table_alias:
opt_table_alias_clause:
/* empty */ { $$=0; }
| table_alias_clause { $$= $1; }
;
@ -12427,7 +12575,7 @@ opt_window_clause:
{}
| WINDOW_SYM
window_def_list
{}
{}
;
window_def_list:
@ -12756,10 +12904,8 @@ delete_limit_clause:
| LIMIT limit_option ROWS_SYM EXAMINED_SYM { thd->parse_error(); MYSQL_YYABORT; }
;
opt_order_limit_lock:
/* empty */
{ $$= NULL; }
| order_or_limit
order_limit_lock:
order_or_limit
{
$$= $1;
$$->lock.empty();
@ -12779,32 +12925,45 @@ opt_order_limit_lock:
$$->lock= $1;
}
;
opt_order_limit_lock:
/* empty */
{
Lex->pop_select();
$$= NULL;
}
| order_limit_lock { $$= $1; }
;
query_expression_tail:
order_limit_lock
;
opt_query_expression_tail:
opt_order_limit_lock
;
opt_procedure_or_into:
/* empty */
{
$$.empty();
}
/* empty */
{
$$.empty();
}
| procedure_clause opt_select_lock_type
{
$$= $2;
}
{
$$= $2;
}
| into opt_select_lock_type
{
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_WARN_DEPRECATED_SYNTAX,
ER_THD(thd, ER_WARN_DEPRECATED_SYNTAX),
"<select expression> INTO <destination>;",
"'SELECT <select list> INTO <destination>"
" FROM...'");
$$= $2;
}
{
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_WARN_DEPRECATED_SYNTAX,
ER_THD(thd, ER_WARN_DEPRECATED_SYNTAX),
"<select expression> INTO <destination>;",
"'SELECT <select list> INTO <destination>"
" FROM...'");
$$= $2;
}
;
order_or_limit:
order_clause opt_limit_clause
{
@ -15199,16 +15358,6 @@ temporal_literal:
}
;
opt_with_clause:
/*empty */ { $$= 0; }
| with_clause
{
$$= $1;
}
;
with_clause:
WITH opt_recursive
{

View File

@ -294,10 +294,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%parse-param { THD *thd }
%lex-param { THD *thd }
/*
Currently there are 49 shift/reduce conflicts.
Currently there are 40 shift/reduce conflicts.
We should not introduce new conflicts any more.
*/
%expect 49
%expect 40
/*
Comments for TOKENS.
@ -1108,6 +1108,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%left '^'
%left MYSQL_CONCAT_SYM
%left NEG '~' NOT2_SYM BINARY
%left SUBQUERY_AS_EXPR
%left COLLATE_SYM
/*
@ -1199,7 +1200,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
ALTER TABLE t1 ADD SYSTEM VERSIONING;
*/
%left PREC_BELOW_CONTRACTION_TOKEN2
%left TEXT_STRING '(' VALUE_SYM VERSIONING_SYM
%left TEXT_STRING '(' ')' VALUE_SYM VERSIONING_SYM
%left EMPTY_FROM_CLAUSE
%right INTO
%type <lex_str>
DECIMAL_NUM FLOAT_NUM NUM LONG_NUM
@ -1472,16 +1475,18 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
query_specification
table_value_constructor
simple_table
query_simple
query_primary
query_primary_parens
subquery
select_into_query_specification
%type <select_lex_unit>
query_specification_start
query_expression_body
query_expression
query_expression_unit
query_expression_no_with_clause
query_expression_body_ext
query_expression_body_ext_parens
query_expression_body
query_specification_start
%type <boolfunc2creator> comp_op
@ -1506,7 +1511,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%type <order_limit_lock>
query_expression_tail
opt_query_expression_tail
order_or_limit
order_limit_lock
opt_order_limit_lock
%type <select_order> opt_order_clause order_clause order_list
@ -1675,7 +1682,7 @@ END_OF_INPUT
THEN_SYM WHEN_SYM DIV_SYM MOD_SYM OR2_SYM AND_AND_SYM DELETE_SYM
MYSQL_CONCAT_SYM ORACLE_CONCAT_SYM
%type <with_clause> opt_with_clause with_clause
%type <with_clause> with_clause
%type <lex_str_ptr> query_name
@ -5270,7 +5277,7 @@ create_select_query_expression:
if (Lex->parsed_insert_select($1->first_select()))
MYSQL_YYABORT;
}
| LEFT_PAREN_WITH with_clause query_expression_body ')'
| LEFT_PAREN_WITH with_clause query_expression_no_with_clause ')'
{
SELECT_LEX *first_select= $3->first_select();
$3->set_with_clause($2);
@ -6784,12 +6791,7 @@ parse_vcol_expr:
;
parenthesized_expr:
query_expression
{
if (!($$= Lex->create_item_query_expression(thd, $1)))
MYSQL_YYABORT;
}
| expr
expr
| expr ',' expr_list
{
$3->push_front($1, thd->mem_root);
@ -6808,6 +6810,16 @@ virtual_column_func:
MYSQL_YYABORT;
$$= v;
}
| subquery
{
Item *item;
if (!(item= new (thd->mem_root) Item_singlerow_subselect(thd, $1)))
MYSQL_YYABORT;
Virtual_column_info *v= add_virtual_expression(thd, item);
if (unlikely(!v))
MYSQL_YYABORT;
$$= v;
}
;
expr_or_literal: column_default_non_parenthesized_expr | signed_literal ;
@ -9267,7 +9279,7 @@ opt_ignore_leaves:
*/
select:
query_expression_body
query_expression_no_with_clause
{
if (Lex->push_select($1->fake_select_lex ?
$1->fake_select_lex :
@ -9277,10 +9289,11 @@ select:
opt_procedure_or_into
{
Lex->pop_select();
$1->set_with_clause(NULL);
if (Lex->select_finalize($1, $3))
MYSQL_YYABORT;
}
| with_clause query_expression_body
| with_clause query_expression_no_with_clause
{
if (Lex->push_select($2->fake_select_lex ?
$2->fake_select_lex :
@ -9306,9 +9319,11 @@ select_into:
}
opt_order_limit_lock
{
st_select_lex_unit *unit;
if (!(unit= Lex->parsed_body_select($1, $3)))
SELECT_LEX_UNIT *unit;
if (!(unit = Lex->create_unit($1)))
MYSQL_YYABORT;
if ($3)
unit= Lex->add_tail_to_query_expression_body(unit, $3);
if (Lex->select_finalize(unit))
MYSQL_YYABORT;
}
@ -9379,94 +9394,193 @@ select_into_query_specification:
}
;
opt_from_clause:
/* Empty */
| from_clause
;
/**
The following grammar for query expressions conformant to
the latest SQL Standard is supported:
query_primary:
simple_table
{ $$= $1; }
| query_primary_parens
{ $$= $1; }
;
<query expression> ::=
[ <with clause> ] <query expression body>
[ <order by clause> ] [ <result offset clause> ] [ <fetch first clause> ]
query_primary_parens:
'(' query_expression_unit
{
if (Lex->parsed_unit_in_brackets($2))
MYSQL_YYABORT;
}
query_expression_tail ')'
{
$$= Lex->parsed_unit_in_brackets_tail($2, $4);
}
| '(' query_primary
{
Lex->push_select($2);
}
query_expression_tail ')'
{
if (!($$= Lex->parsed_select_in_brackets($2, $4)))
YYABORT;
}
;
<with clause> ::=
WITH [ RECURSIVE ] <with_list
query_expression_unit:
query_primary
unit_type_decl
query_primary
{
if (!($$= Lex->parsed_select_expr_start($1, $3, $2.unit_type,
$2.distinct)))
YYABORT;
}
| query_expression_unit
unit_type_decl
query_primary
{
if (!($$= Lex->parsed_select_expr_cont($1, $3, $2.unit_type,
$2.distinct, TRUE)))
YYABORT;
}
;
<with list> ::=
<with list element> [ { <comma> <with list element> }... ]
query_expression_body:
query_primary
{
Lex->push_select($1);
}
query_expression_tail
{
if (!($$= Lex->parsed_body_select($1, $3)))
MYSQL_YYABORT;
}
| query_expression_unit
{
if (Lex->parsed_body_unit($1))
MYSQL_YYABORT;
}
query_expression_tail
{
if (!($$= Lex->parsed_body_unit_tail($1, $3)))
MYSQL_YYABORT;
}
;
<with list element> ::=
<query name> [ '(' <with column list> ')' ]
AS <table subquery>
<with column list> ::=
<column name list>
<query expression body> ::
<query term>
| <query expression body> UNION [ ALL | DISTINCT ] <query term>
| <query expression body> EXCEPT [ DISTINCT ] <query term>
<query term> ::=
<query primary>
| <query term> INTERSECT [ DISTINCT ] <query primary>
<query primary> ::=
<simple table>
| '(' <query expression body>
[ <order by clause> ] [ <result offset clause> ] [ <fetch first clause> ]
')'
<simple table>
<query specification>
| <table value constructor>
<subquery>
'(' <query_expression> ')'
*/
/*
query_expression produces the same expressions as
<query expression>
*/
query_expression:
opt_with_clause
query_expression_body
query_expression_no_with_clause
{
if ($1)
{
$2->set_with_clause($1);
$1->attach_to($2->first_select());
}
$1->set_with_clause(NULL);
$$= $1;
}
| with_clause
query_expression_no_with_clause
{
$2->set_with_clause($1);
$1->attach_to($2->first_select());
$$= $2;
}
;
/*
query_expression_no_with_clause produces the same expressions as
<query expression> without [ <with clause> ]
*/
query_expression_no_with_clause:
query_expression_body_ext { $$= $1; }
| query_expression_body_ext_parens { $$= $1; }
;
/*
query_expression_body_ext produces the same expressions as
<query expression body>
[ <order by clause> ] [ <result offset clause> ] [ <fetch first clause> ]
| '('... <query expression body>
[ <order by clause> ] [ <result offset clause> ] [ <fetch first clause> ]
')'...
Note: number of ')' must be equal to the number of '(' in the rule above
*/
query_expression_body_ext:
query_expression_body
{
if ($1->first_select()->next_select())
{
if (Lex->parsed_multi_operand_query_expression_body($1))
MYSQL_YYABORT;
}
}
opt_query_expression_tail
{
if (!$3)
$$= $1;
else
$$= Lex->add_tail_to_query_expression_body($1, $3);
}
| query_expression_body_ext_parens
{
Lex->push_select(!$1->first_select()->next_select() ?
$1->first_select() : $1->fake_select_lex);
}
query_expression_tail
{
if (!($$= Lex->add_tail_to_query_expression_body_ext_parens($1, $3)))
MYSQL_YYABORT;
}
;
query_expression_body_ext_parens:
'(' query_expression_body_ext_parens ')'
{ $$= $2; }
| '(' query_expression_body_ext ')'
{
SELECT_LEX *sel= $2->first_select()->next_select() ?
$2->fake_select_lex : $2->first_select();
sel->braces= true;
$$= $2;
}
;
/*
query_expression_body produces the same expressions as
<query expression body>
*/
query_expression_body:
query_simple
{
Lex->push_select($1);
if (!($$= Lex->create_unit($1)))
MYSQL_YYABORT;
}
| query_expression_body
unit_type_decl
{
if (!$1->first_select()->next_select())
{
Lex->pop_select();
}
}
query_primary
{
if (!($$= Lex->add_primary_to_query_expression_body($1, $4,
$2.unit_type,
$2.distinct,
TRUE)))
MYSQL_YYABORT;
}
| query_expression_body_ext_parens
unit_type_decl
query_primary
{
if (!($$= Lex->add_primary_to_query_expression_body_ext_parens(
$1, $3,
$2.unit_type,
$2.distinct)))
MYSQL_YYABORT;
}
;
/*
query_primary produces the same expressions as
<query primary>
*/
query_primary:
query_simple
{ $$= $1; }
| query_expression_body_ext_parens
{ $$= $1->first_select(); }
;
/*
query_simple produces the same expressions as
<simple table>
*/
query_simple:
simple_table { $$= $1;}
;
subselect:
query_expression
{
@ -9475,11 +9589,63 @@ subselect:
}
;
/*
subquery produces the same expressions as
<subquery>
/**
<table expression>, as in the SQL standard.
Consider the production rule of the SQL Standard
subquery:
'(' query_expression ')'
This rule is equivalent to the rule
subquery:
'(' query_expression_no_with_clause ')'
| '(' with_clause query_expression_no_with_clause ')'
that in its turn is equivalent to
subquery:
'(' query_expression_body_ext ')'
| query_expression_body_ext_parens
| '(' with_clause query_expression_no_with_clause ')'
The latter can be re-written into
subquery:
query_expression_body_ext_parens
| '(' with_clause query_expression_no_with_clause ')'
The last rule allows us to resolve properly the shift/reduce conflict
when subquery is used in expressions such as in the following queries
select (select * from t1 limit 1) + t2.a from t2
select * from t1 where t1.a [not] in (select t2.a from t2)
In the rule below %prec SUBQUERY_AS_EXPR forces the parser to perform a shift
operation rather then a reduce operation when ')' is encountered and can be
considered as the last symbol a query expression.
*/
subquery:
query_expression_body_ext_parens %prec SUBQUERY_AS_EXPR
{
if (!$1->fake_select_lex)
$1->first_select()->braces= false;
else
$1->fake_select_lex->braces= false;
if (!($$= Lex->parsed_subselect($1)))
YYABORT;
}
| '(' with_clause query_expression_no_with_clause ')'
{
$3->set_with_clause($2);
$2->attach_to($3->first_select());
if (!($$= Lex->parsed_subselect($3)))
YYABORT;
}
;
opt_from_clause:
/* empty */ %prec EMPTY_FROM_CLAUSE
| from_clause
;
from_clause:
FROM table_reference_list
;
@ -9949,15 +10115,15 @@ bool_pri:
;
predicate:
bit_expr IN_SYM '(' subselect ')'
bit_expr IN_SYM subquery
{
$$= new (thd->mem_root) Item_in_subselect(thd, $1, $4);
$$= new (thd->mem_root) Item_in_subselect(thd, $1, $3);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
| bit_expr not IN_SYM '(' subselect ')'
| bit_expr not IN_SYM subquery
{
Item *item= new (thd->mem_root) Item_in_subselect(thd, $1, $5);
Item *item= new (thd->mem_root) Item_in_subselect(thd, $1, $4);
if (unlikely(item == NULL))
MYSQL_YYABORT;
$$= negate_expression(thd, item);
@ -10478,6 +10644,11 @@ primary_expr:
column_default_non_parenthesized_expr
| explicit_cursor_attr
| '(' parenthesized_expr ')' { $$= $2; }
| subquery
{
if (!($$= Lex->create_item_query_expression(thd, $1->master_unit())))
MYSQL_YYABORT;
}
;
string_factor_expr:
@ -12229,37 +12400,15 @@ table_primary_ident:
}
;
/*
Represents a flattening of the following rules from the SQL:2003
standard. This sub-rule corresponds to the sub-rule
<table primary> ::= ... | <derived table> [ AS ] <correlation name>
<derived table> ::= <table subquery>
<table subquery> ::= <subquery>
<subquery> ::= <left paren> <query expression> <right paren>
<query expression> ::= [ <with clause> ] <query expression body>
For the time being we use the non-standard rule
select_derived_union which is a compromise between the standard
and our parser. Possibly this rule could be replaced by our
query_expression_body.
*/
table_primary_derived:
query_primary_parens opt_for_system_time_clause table_alias_clause
subquery
opt_for_system_time_clause table_alias_clause
{
if (!($$= Lex->parsed_derived_select($1, $2, $3)))
YYABORT;
}
| '('
query_expression
')' opt_for_system_time_clause table_alias_clause
{
if (!($$= Lex->parsed_derived_unit($2, $4, $5)))
YYABORT;
if (!($$= Lex->parsed_derived_table($1->master_unit(), $2, $3)))
MYSQL_YYABORT;
}
;
;
opt_outer:
/* empty */ {}
@ -12393,7 +12542,6 @@ table_alias:
opt_table_alias_clause:
/* empty */ { $$=0; }
| table_alias_clause { $$= $1; }
;
@ -12856,10 +13004,8 @@ delete_limit_clause:
| LIMIT limit_option ROWS_SYM EXAMINED_SYM { thd->parse_error(); MYSQL_YYABORT; }
;
opt_order_limit_lock:
/* empty */
{ $$= NULL; }
| order_or_limit
order_limit_lock:
order_or_limit
{
$$= $1;
$$->lock.empty();
@ -12879,29 +13025,42 @@ opt_order_limit_lock:
$$->lock= $1;
}
;
opt_order_limit_lock:
/* empty */
{
Lex->pop_select();
$$= NULL;
}
| order_limit_lock { $$= $1; }
;
query_expression_tail:
order_limit_lock
;
opt_query_expression_tail:
opt_order_limit_lock
;
opt_procedure_or_into:
/* empty */
{
$$.empty();
}
{
$$.empty();
}
| procedure_clause opt_select_lock_type
{
$$= $2;
}
{
$$= $2;
}
| into opt_select_lock_type
{
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_WARN_DEPRECATED_SYNTAX,
ER_THD(thd, ER_WARN_DEPRECATED_SYNTAX),
"<select expression> INTO <destination>;",
"'SELECT <select list> INTO <destination>"
" FROM...'");
$$= $2;
}
{
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_WARN_DEPRECATED_SYNTAX,
ER_THD(thd, ER_WARN_DEPRECATED_SYNTAX),
"<select expression> INTO <destination>;",
"'SELECT <select list> INTO <destination>"
" FROM...'");
$$= $2;
}
;
@ -15321,16 +15480,6 @@ temporal_literal:
}
;
opt_with_clause:
/*empty */ { $$= 0; }
| with_clause
{
$$= $1;
}
;
with_clause:
WITH opt_recursive
{