revision-id: 549bcceefd94e8700c9e629bdd2c2f5a73d2459b (mariadb-10.3.6-6-g549bcceefd9)
parent(s): a64a078e76c3372f075c7eaed9729a03e524cd47
author: Oleksandr Byelkin
committer: Oleksandr Byelkin
timestamp: 2018-05-22 19:38:27 +0200
message:
Applying Alexander Barkov patch:
This patch removes a lot of main_select_push() / pop_select() that
you had to add into *.yy files in the 10.3-MDEV-11953 branch.
The patch does the following:
- Disallows creation of Item_field in the select stack is empty.
An error is returned instead (ER_BAD_FIELD_ERROR).
The point is that Item_field requires a Name_resolution_context,
which is not available with the empty select stack.
This additionally fixed the problem reported in:
MDEV-14347 CREATE PROCEDURE returns no error when using an unknown
variable
- Disallows creation of Item_sum and Item_windowfunc the same way,
as they also need a Name_resolution_context.
It fixed the second part of MDEV-14347, about aggregate and window
functions.
It also fixed:
MDEV-15870 Using aggregate and window function in unexpected places
can crash the server
(repeatable since 10.2)
- Adds FOR_LOOP_BOUND into enum_parsing_place, to force creation of a
temporary
Item_field when inside a FOR loop:
FOR x IN ident
If the "ident" is later resolves to a cursor name,
then the loop is treated as "explicit cursor FOR loop", otherwise
it's a normal field name and therefore the same error (ER_BAD_FIELD_ERROR)
is returned.
- Adds a new method LEX::create_item_query_expression()
to reuse the same code in sql_yacc.yy and sql_yacc_ora.yy.
Adds a test for curr_sel, in case of NULL resets curr_sel
to &lex->builtin_select.
- Adds tests to cover IN and EXISTS subselects in various query parts.
This was very weakly covered. While working on this patch I had problems
with IN and EXISTS subselects, so I had to cover them.
- Adds a function relink_hack() to properly bind st_select_lex containing
an IN/EXISTS subselect to thd->lex->builtin_select. This is needed for
the cases when the statement does not do main_select_push().
I does not know this code well, so you can fine a better solution.
Please suggest.
---
mysql-test/main/get_diagnostics.result | 11 +-
mysql-test/main/get_diagnostics.test | 7 +-
mysql-test/main/mysqldump.result | 4 +-
mysql-test/main/mysqldump.test | 2 +-
mysql-test/main/signal.result | 6 -
mysql-test/main/signal.test | 13 +-
mysql-test/main/sp-error.result | 14 +-
mysql-test/main/sp-error.test | 19 +--
mysql-test/main/sp.result | 57 +------
mysql-test/main/sp.test | 33 ++--
mysql-test/suite/compat/oracle/r/sp.result | 8 -
mysql-test/suite/compat/oracle/t/sp.test | 16 +-
mysql-test/suite/funcs_1/r/storedproc.result | 3 +-
mysql-test/suite/funcs_1/t/storedproc.test | 1 +
sql/item_create.cc | 7 +-
sql/item_subselect.cc | 43 ++++-
sql/item_sum.cc | 1 +
sql/opt_subselect.cc | 1 +
sql/sql_lex.cc | 122 +++++++++++---
sql/sql_lex.h | 46 +++++-
sql/sql_priv.h | 1 +
sql/sql_yacc.yy | 212 +++++--------------------
sql/sql_yacc_ora.yy | 229 +++++----------------------
23 files changed, 327 insertions(+), 529 deletions(-)
diff --git a/mysql-test/main/get_diagnostics.result b/mysql-test/main/get_diagnostics.result
index 732be7c0283..6944103c805 100644
--- a/mysql-test/main/get_diagnostics.result
+++ b/mysql-test/main/get_diagnostics.result
@@ -133,7 +133,7 @@ DROP PROCEDURE p1;
GET DIAGNOSTICS CONDITION;
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
GET DIAGNOSTICS CONDITION a;
-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
+ERROR 42S22: Unknown column 'a' in 'field list'
GET DIAGNOSTICS CONDITION 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
GET DIAGNOSTICS CONDITION 1 @var;
@@ -212,9 +212,9 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp
GET DIAGNOSTICS CONDITION (1) @var = CLASS_ORIGIN;
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 '(1) @var = CLASS_ORIGIN' at line 1
GET DIAGNOSTICS CONDITION p1() @var = CLASS_ORIGIN;
-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 '() @var = CLASS_ORIGIN' at line 1
+ERROR 42S22: Unknown column 'p1' in 'field list'
GET DIAGNOSTICS CONDITION ABS(2) @var = CLASS_ORIGIN;
-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 '(2) @var = CLASS_ORIGIN' at line 1
+ERROR 42S22: Unknown column 'ABS' in 'field list'
GET DIAGNOSTICS CONDITION 1.1 @var = CLASS_ORIGIN;
GET DIAGNOSTICS CONDITION "1" @var = CLASS_ORIGIN;
SELECT COUNT(max_questions) INTO @var FROM mysql.user;
@@ -226,10 +226,7 @@ Warnings:
Error 1758 Invalid condition number
Error 1758 Invalid condition number
GET DIAGNOSTICS CONDITION a @var = CLASS_ORIGIN;
-Warnings:
-Error 1758 Invalid condition number
-Error 1758 Invalid condition number
-Error 1054 Unknown column 'a' in 'field list'
+ERROR 42S22: Unknown column 'a' in 'field list'
SELECT COUNT(max_questions) INTO @var FROM mysql.user;
SET @cond = 1;
GET DIAGNOSTICS CONDITION @cond @var1 = CLASS_ORIGIN;
diff --git a/mysql-test/main/get_diagnostics.test b/mysql-test/main/get_diagnostics.test
index a30bad72136..1553eb500b7 100644
--- a/mysql-test/main/get_diagnostics.test
+++ b/mysql-test/main/get_diagnostics.test
@@ -169,7 +169,7 @@ DROP PROCEDURE p1;
--error ER_PARSE_ERROR
GET DIAGNOSTICS CONDITION;
---error ER_PARSE_ERROR
+--error ER_BAD_FIELD_ERROR
GET DIAGNOSTICS CONDITION a;
--error ER_PARSE_ERROR
GET DIAGNOSTICS CONDITION 1;
@@ -271,9 +271,9 @@ GET DIAGNOSTICS CONDITION 1+1 @var = CLASS_ORIGIN;
GET DIAGNOSTICS CONDITION ? @var = CLASS_ORIGIN;
--error ER_PARSE_ERROR
GET DIAGNOSTICS CONDITION (1) @var = CLASS_ORIGIN;
---error ER_PARSE_ERROR
+--error ER_BAD_FIELD_ERROR
GET DIAGNOSTICS CONDITION p1() @var = CLASS_ORIGIN;
---error ER_PARSE_ERROR
+--error ER_BAD_FIELD_ERROR
GET DIAGNOSTICS CONDITION ABS(2) @var = CLASS_ORIGIN;
# Unfortunate side effects...
@@ -285,6 +285,7 @@ SELECT COUNT(max_questions) INTO @var FROM mysql.user;
GET DIAGNOSTICS CONDITION 9999 @var = CLASS_ORIGIN;
GET DIAGNOSTICS CONDITION NULL @var = CLASS_ORIGIN;
+--error ER_BAD_FIELD_ERROR
GET DIAGNOSTICS CONDITION a @var = CLASS_ORIGIN;
# Reset warnings
diff --git a/mysql-test/main/mysqldump.result b/mysql-test/main/mysqldump.result
index a1e206dffd7..7034a7ba2e1 100644
--- a/mysql-test/main/mysqldump.result
+++ b/mysql-test/main/mysqldump.result
@@ -5153,7 +5153,7 @@ USE BUG52792;
SET NAMES utf8;
CREATE FUNCTION `straße` ( c1 CHAR(20))
RETURNS CHAR(50) DETERMINISTIC
-RETURN CONCAT(']]>, ', s, '!');
+RETURN CONCAT(']]>, ', c1, '!');
<?xml version="1.0"?>
<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<database name="BUG52792">
@@ -5162,7 +5162,7 @@ RETURN CONCAT(']]>, ', s, '!');
<![CDATA[
CREATE DEFINER=`root`@`localhost` FUNCTION `straße`( c1 CHAR(20)) RETURNS char(50) CHARSET latin1
DETERMINISTIC
-RETURN CONCAT(']]]]><![CDATA[>, ', s, '!')
+RETURN CONCAT(']]]]><![CDATA[>, ', c1, '!')
]]>
</routine>
</routines>
diff --git a/mysql-test/main/mysqldump.test b/mysql-test/main/mysqldump.test
index 6dde5aa7bc6..05aabcce6ba 100644
--- a/mysql-test/main/mysqldump.test
+++ b/mysql-test/main/mysqldump.test
@@ -2351,7 +2351,7 @@ USE BUG52792;
SET NAMES utf8;
CREATE FUNCTION `straße` ( c1 CHAR(20))
RETURNS CHAR(50) DETERMINISTIC
-RETURN CONCAT(']]>, ', s, '!');
+RETURN CONCAT(']]>, ', c1, '!');
--exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --skip-comments --default-character-set=utf8 --compatible=mysql323 -R -X BUG52792
diff --git a/mysql-test/main/signal.result b/mysql-test/main/signal.result
index 215f7db8b0d..e329c58a47e 100644
--- a/mysql-test/main/signal.result
+++ b/mysql-test/main/signal.result
@@ -2285,17 +2285,13 @@ begin
DECLARE foo CONDITION FOR SQLSTATE '12345';
SIGNAL foo SET MYSQL_ERRNO = `65`; /* illegal */
end $$
-call test_signal $$
ERROR 42S22: Unknown column '65' in 'field list'
-drop procedure test_signal $$
create procedure test_signal()
begin
DECLARE foo CONDITION FOR SQLSTATE '12345';
SIGNAL foo SET MYSQL_ERRNO = `A`; /* illegal */
end $$
-call test_signal $$
ERROR 42S22: Unknown column 'A' in 'field list'
-drop procedure test_signal $$
create procedure test_signal()
begin
DECLARE foo CONDITION FOR SQLSTATE '12345';
@@ -2346,9 +2342,7 @@ DECLARE foo CONDITION FOR SQLSTATE '12345';
SIGNAL foo SET MYSQL_ERRNO = 1000,
MESSAGE_TEXT = `Hello`;
end $$
-call test_signal $$
ERROR 42S22: Unknown column 'Hello' in 'field list'
-drop procedure test_signal $$
create procedure test_signal()
begin
DECLARE foo CONDITION FOR SQLSTATE '12345';
diff --git a/mysql-test/main/signal.test b/mysql-test/main/signal.test
index e4dcb5a71cf..5b40863b0e6 100644
--- a/mysql-test/main/signal.test
+++ b/mysql-test/main/signal.test
@@ -2546,25 +2546,21 @@ end $$
call test_signal $$
drop procedure test_signal $$
+-- error ER_BAD_FIELD_ERROR
create procedure test_signal()
begin
DECLARE foo CONDITION FOR SQLSTATE '12345';
SIGNAL foo SET MYSQL_ERRNO = `65`; /* illegal */
end $$
--- error ER_BAD_FIELD_ERROR
-call test_signal $$
-drop procedure test_signal $$
+-- error ER_BAD_FIELD_ERROR
create procedure test_signal()
begin
DECLARE foo CONDITION FOR SQLSTATE '12345';
SIGNAL foo SET MYSQL_ERRNO = `A`; /* illegal */
end $$
--- error ER_BAD_FIELD_ERROR
-call test_signal $$
-drop procedure test_signal $$
create procedure test_signal()
begin
@@ -2620,6 +2616,7 @@ end $$
call test_signal $$
drop procedure test_signal $$
+-- error ER_BAD_FIELD_ERROR
create procedure test_signal()
begin
DECLARE foo CONDITION FOR SQLSTATE '12345';
@@ -2627,10 +2624,6 @@ begin
MESSAGE_TEXT = `Hello`;
end $$
--- error ER_BAD_FIELD_ERROR
-call test_signal $$
-drop procedure test_signal $$
-
create procedure test_signal()
begin
DECLARE foo CONDITION FOR SQLSTATE '12345';
diff --git a/mysql-test/main/sp-error.result b/mysql-test/main/sp-error.result
index de4c4cf3103..cf74e6c33cd 100644
--- a/mysql-test/main/sp-error.result
+++ b/mysql-test/main/sp-error.result
@@ -439,6 +439,9 @@ create procedure nodb.bug3339() begin end|
ERROR 42000: Unknown database 'nodb'
create procedure bug2653_1(a int, out b int)
set b = aa|
+call bug2653_1(1, @b)|
+ERROR 42S22: Unknown column 'aa' in 'field list'
+drop procedure bug2653_1|
create procedure bug2653_2(a int, out b int)
begin
if aa < 0 then
@@ -447,12 +450,7 @@ else
set b = a;
end if;
end|
-call bug2653_1(1, @b)|
-ERROR 42S22: Unknown column 'aa' in 'field list'
-call bug2653_2(2, @b)|
ERROR 42S22: Unknown column 'aa' in 'field list'
-drop procedure bug2653_1|
-drop procedure bug2653_2|
create procedure bug4344() drop procedure bug4344|
ERROR HY000: Can't drop or alter a PROCEDURE from within another stored routine
create procedure bug4344() drop function bug4344|
@@ -1067,6 +1065,7 @@ IF bug13037_foo THEN
SELECT 1;
END IF;
END|
+ERROR 42S22: Unknown column 'bug13037_foo' in 'field list'
CREATE PROCEDURE bug13037_p2()
BEGIN
SET @bug13037_foo = bug13037_bar;
@@ -1076,19 +1075,14 @@ BEGIN
SELECT bug13037_foo;
END|
-CALL bug13037_p1();
-ERROR 42S22: Unknown column 'bug13037_foo' in 'field list'
CALL bug13037_p2();
ERROR 42S22: Unknown column 'bug13037_bar' in 'field list'
CALL bug13037_p3();
ERROR 42S22: Unknown column 'bug13037_foo' in 'field list'
-CALL bug13037_p1();
-ERROR 42S22: Unknown column 'bug13037_foo' in 'field list'
CALL bug13037_p2();
ERROR 42S22: Unknown column 'bug13037_bar' in 'field list'
CALL bug13037_p3();
ERROR 42S22: Unknown column 'bug13037_foo' in 'field list'
-DROP PROCEDURE bug13037_p1;
DROP PROCEDURE bug13037_p2;
DROP PROCEDURE bug13037_p3;
create database mysqltest1;
diff --git a/mysql-test/main/sp-error.test b/mysql-test/main/sp-error.test
index 88d9809265a..e2adea88b5b 100644
--- a/mysql-test/main/sp-error.test
+++ b/mysql-test/main/sp-error.test
@@ -608,6 +608,12 @@ create procedure nodb.bug3339() begin end|
create procedure bug2653_1(a int, out b int)
set b = aa|
+--error ER_BAD_FIELD_ERROR
+call bug2653_1(1, @b)|
+
+drop procedure bug2653_1|
+
+--error ER_BAD_FIELD_ERROR
create procedure bug2653_2(a int, out b int)
begin
if aa < 0 then
@@ -617,13 +623,6 @@ begin
end if;
end|
---error 1054
-call bug2653_1(1, @b)|
---error 1054
-call bug2653_2(2, @b)|
-
-drop procedure bug2653_1|
-drop procedure bug2653_2|
#
# BUG#4344
@@ -1507,6 +1506,7 @@ DROP PROCEDURE IF EXISTS bug13037_p3;
delimiter |;
+--error ER_BAD_FIELD_ERROR
CREATE PROCEDURE bug13037_p1()
BEGIN
IF bug13037_foo THEN
@@ -1528,21 +1528,16 @@ delimiter ;|
--echo
---error 1054
-CALL bug13037_p1();
--error 1054
CALL bug13037_p2();
--error 1054
CALL bug13037_p3();
---error 1054
-CALL bug13037_p1();
--error 1054
CALL bug13037_p2();
--error 1054
CALL bug13037_p3();
-DROP PROCEDURE bug13037_p1;
DROP PROCEDURE bug13037_p2;
DROP PROCEDURE bug13037_p3;
diff --git a/mysql-test/main/sp.result b/mysql-test/main/sp.result
index 3e8e2243725..4745e1a1603 100644
--- a/mysql-test/main/sp.result
+++ b/mysql-test/main/sp.result
@@ -4179,6 +4179,7 @@ select v, isnull(v);
end if;
end;
end|
+ERROR 42S22: Unknown column 'undefined_var' in 'field list'
create procedure bug14643_2()
begin
declare continue handler for sqlexception select 'boo' as 'Handler';
@@ -4190,18 +4191,7 @@ select 2;
end case;
select undefined_var;
end|
-call bug14643_1()|
-Handler
-boo
-v isnull(v)
-NULL 1
-call bug14643_2()|
-Handler
-boo
-Handler
-boo
-drop procedure bug14643_1|
-drop procedure bug14643_2|
+ERROR 42S22: Unknown column 'undefined_var' in 'field list'
drop procedure if exists bug14304|
drop table if exists t3, t4|
create table t3(a int primary key auto_increment)|
@@ -4231,9 +4221,7 @@ create procedure bug14376()
begin
declare x int default x;
end|
-call bug14376()|
ERROR 42S22: Unknown column 'x' in 'field list'
-drop procedure bug14376|
create procedure bug14376()
begin
declare x int default 42;
@@ -4476,6 +4464,7 @@ select 'no' as 'v';
end if;
select 'done' as 'End';
end|
+ERROR 42S22: Unknown column 'v' in 'field list'
create procedure bug14498_2()
begin
declare continue handler for sqlexception select 'error' as 'Handler';
@@ -4484,6 +4473,7 @@ select 'yes' as 'v';
end while;
select 'done' as 'End';
end|
+ERROR 42S22: Unknown column 'v' in 'field list'
create procedure bug14498_3()
begin
declare continue handler for sqlexception select 'error' as 'Handler';
@@ -4492,6 +4482,7 @@ select 'maybe' as 'v';
until v end repeat;
select 'done' as 'End';
end|
+ERROR 42S22: Unknown column 'v' in 'field list'
create procedure bug14498_4()
begin
declare continue handler for sqlexception select 'error' as 'Handler';
@@ -4505,6 +4496,7 @@ select '?' as 'v';
end case;
select 'done' as 'End';
end|
+ERROR 42S22: Unknown column 'v' in 'field list'
create procedure bug14498_5()
begin
declare continue handler for sqlexception select 'error' as 'Handler';
@@ -4518,38 +4510,7 @@ select '?' as 'v';
end case;
select 'done' as 'End';
end|
-call bug14498_1()|
-Handler
-error
-End
-done
-call bug14498_2()|
-Handler
-error
-End
-done
-call bug14498_3()|
-v
-maybe
-Handler
-error
-End
-done
-call bug14498_4()|
-Handler
-error
-End
-done
-call bug14498_5()|
-Handler
-error
-End
-done
-drop procedure bug14498_1|
-drop procedure bug14498_2|
-drop procedure bug14498_3|
-drop procedure bug14498_4|
-drop procedure bug14498_5|
+ERROR 42S22: Unknown column 'v' in 'field list'
drop table if exists t3|
drop procedure if exists bug15231_1|
drop procedure if exists bug15231_2|
@@ -8328,14 +8289,12 @@ DECLARE name VARCHAR(10);
SET name="hello";
call p1(name2);
END|
+ERROR 42S22: Unknown column 'name2' in 'field list'
call p2();
a
hello
-call p3();
-ERROR 42S22: Unknown column 'name2' in 'field list'
drop procedure p1;
drop procedure p2;
-drop procedure p3;
#
# MDEV-15328: MariaDB 10.2.13 Crashes upon CALL PROCEDURE PARAM
# LAST_INSERT_ID ()
diff --git a/mysql-test/main/sp.test b/mysql-test/main/sp.test
index 6308a0906c7..b0f54ac9787 100644
--- a/mysql-test/main/sp.test
+++ b/mysql-test/main/sp.test
@@ -5040,6 +5040,7 @@ drop procedure if exists bug14643_1|
drop procedure if exists bug14643_2|
--enable_warnings
+--error ER_BAD_FIELD_ERROR
create procedure bug14643_1()
begin
declare continue handler for sqlexception select 'boo' as 'Handler';
@@ -5055,6 +5056,7 @@ begin
end;
end|
+--error ER_BAD_FIELD_ERROR
create procedure bug14643_2()
begin
declare continue handler for sqlexception select 'boo' as 'Handler';
@@ -5069,11 +5071,6 @@ begin
select undefined_var;
end|
-call bug14643_1()|
-call bug14643_2()|
-
-drop procedure bug14643_1|
-drop procedure bug14643_2|
#
# BUG#14304: auto_increment field incorrect set in SP
@@ -5114,15 +5111,12 @@ drop table t3, t4|
drop procedure if exists bug14376|
--enable_warnings
+--error ER_BAD_FIELD_ERROR
create procedure bug14376()
begin
declare x int default x;
end|
-# Not the error we want, but that's what we got for now...
---error ER_BAD_FIELD_ERROR
-call bug14376()|
-drop procedure bug14376|
create procedure bug14376()
begin
@@ -5344,6 +5338,7 @@ drop procedure if exists bug14498_4|
drop procedure if exists bug14498_5|
--enable_warnings
+--error ER_BAD_FIELD_ERROR
create procedure bug14498_1()
begin
declare continue handler for sqlexception select 'error' as 'Handler';
@@ -5356,6 +5351,7 @@ begin
select 'done' as 'End';
end|
+--error ER_BAD_FIELD_ERROR
create procedure bug14498_2()
begin
declare continue handler for sqlexception select 'error' as 'Handler';
@@ -5366,6 +5362,7 @@ begin
select 'done' as 'End';
end|
+--error ER_BAD_FIELD_ERROR
create procedure bug14498_3()
begin
declare continue handler for sqlexception select 'error' as 'Handler';
@@ -5376,6 +5373,7 @@ begin
select 'done' as 'End';
end|
+--error ER_BAD_FIELD_ERROR
create procedure bug14498_4()
begin
declare continue handler for sqlexception select 'error' as 'Handler';
@@ -5391,6 +5389,7 @@ begin
select 'done' as 'End';
end|
+--error ER_BAD_FIELD_ERROR
create procedure bug14498_5()
begin
declare continue handler for sqlexception select 'error' as 'Handler';
@@ -5406,17 +5405,6 @@ begin
select 'done' as 'End';
end|
-call bug14498_1()|
-call bug14498_2()|
-call bug14498_3()|
-call bug14498_4()|
-call bug14498_5()|
-
-drop procedure bug14498_1|
-drop procedure bug14498_2|
-drop procedure bug14498_3|
-drop procedure bug14498_4|
-drop procedure bug14498_5|
#
# BUG#15231: Stored procedure bug with not found condition handler
@@ -9827,6 +9815,8 @@ BEGIN
SET name="hello";
call p1(name);
END|
+
+--error ER_BAD_FIELD_ERROR
CREATE OR REPLACE PROCEDURE p3 ()
BEGIN
DECLARE name VARCHAR(10);
@@ -9837,11 +9827,8 @@ END|
DELIMITER ;|
call p2();
---error ER_BAD_FIELD_ERROR
-call p3();
drop procedure p1;
drop procedure p2;
-drop procedure p3;
--echo #
--echo # MDEV-15328: MariaDB 10.2.13 Crashes upon CALL PROCEDURE PARAM
diff --git a/mysql-test/suite/compat/oracle/r/sp.result b/mysql-test/suite/compat/oracle/r/sp.result
index 7f042825385..2049f234df3 100644
--- a/mysql-test/suite/compat/oracle/r/sp.result
+++ b/mysql-test/suite/compat/oracle/r/sp.result
@@ -1019,9 +1019,7 @@ LOOP
EXIT WHEN unknown_ident IS NULL;
END LOOP;
END$$
-CALL p1;
ERROR 42S22: Unknown column 'unknown_ident' in 'field list'
-DROP PROCEDURE p1;
CREATE PROCEDURE p1
AS
BEGIN
@@ -1030,9 +1028,7 @@ LOOP
EXIT label WHEN unknown_ident IS NULL;
END LOOP;
END$$
-CALL p1;
ERROR 42S22: Unknown column 'unknown_ident' in 'field list'
-DROP PROCEDURE p1;
CREATE PROCEDURE p1
AS
BEGIN
@@ -1040,9 +1036,7 @@ LOOP
CONTINUE WHEN unknown_ident IS NULL;
END LOOP;
END$$
-CALL p1;
ERROR 42S22: Unknown column 'unknown_ident' in 'field list'
-DROP PROCEDURE p1;
CREATE PROCEDURE p1
AS
BEGIN
@@ -1051,9 +1045,7 @@ LOOP
CONTINUE label WHEN unknown_ident IS NULL;
END LOOP;
END$$
-CALL p1;
ERROR 42S22: Unknown column 'unknown_ident' in 'field list'
-DROP PROCEDURE p1;
#
# MDEV-10583 sql_mode=ORACLE: SQL%ROWCOUNT
#
diff --git a/mysql-test/suite/compat/oracle/t/sp.test b/mysql-test/suite/compat/oracle/t/sp.test
index b88271ad3e2..de2a4a5e4e7 100644
--- a/mysql-test/suite/compat/oracle/t/sp.test
+++ b/mysql-test/suite/compat/oracle/t/sp.test
@@ -1092,6 +1092,7 @@ DROP FUNCTION f1;
--echo #
DELIMITER $$;
+--error ER_BAD_FIELD_ERROR
CREATE PROCEDURE p1
AS
BEGIN
@@ -1100,12 +1101,10 @@ BEGIN
END LOOP;
END$$
DELIMITER ;$$
---error ER_BAD_FIELD_ERROR
-CALL p1;
-DROP PROCEDURE p1;
DELIMITER $$;
+--error ER_BAD_FIELD_ERROR
CREATE PROCEDURE p1
AS
BEGIN
@@ -1115,12 +1114,10 @@ BEGIN
END LOOP;
END$$
DELIMITER ;$$
---error ER_BAD_FIELD_ERROR
-CALL p1;
-DROP PROCEDURE p1;
DELIMITER $$;
+--error ER_BAD_FIELD_ERROR
CREATE PROCEDURE p1
AS
BEGIN
@@ -1129,12 +1126,10 @@ BEGIN
END LOOP;
END$$
DELIMITER ;$$
---error ER_BAD_FIELD_ERROR
-CALL p1;
-DROP PROCEDURE p1;
DELIMITER $$;
+--error ER_BAD_FIELD_ERROR
CREATE PROCEDURE p1
AS
BEGIN
@@ -1144,9 +1139,6 @@ BEGIN
END LOOP;
END$$
DELIMITER ;$$
---error ER_BAD_FIELD_ERROR
-CALL p1;
-DROP PROCEDURE p1;
--echo #
--echo # MDEV-10583 sql_mode=ORACLE: SQL%ROWCOUNT
diff --git a/mysql-test/suite/funcs_1/r/storedproc.result b/mysql-test/suite/funcs_1/r/storedproc.result
index e5e009a86de..0fe7082bea1 100644
--- a/mysql-test/suite/funcs_1/r/storedproc.result
+++ b/mysql-test/suite/funcs_1/r/storedproc.result
@@ -15723,6 +15723,7 @@ Testcase 4.3.7:
DROP PROCEDURE IF EXISTS sp7;
CREATE PROCEDURE sp7()
BEGIN
+DECLARE count INT DEFAULT 100;
label1: loop
set @dummystring = 'temp value';
if count > 10 then leave label1;
@@ -15732,7 +15733,7 @@ END label1 loop;
END//
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 'iterate;
END label1 loop;
-END' at line 7
+END' at line 8
DROP PROCEDURE IF EXISTS sp7;
CREATE PROCEDURE sp7()
BEGIN
diff --git a/mysql-test/suite/funcs_1/t/storedproc.test b/mysql-test/suite/funcs_1/t/storedproc.test
index 98385d42b22..31786410a7b 100644
--- a/mysql-test/suite/funcs_1/t/storedproc.test
+++ b/mysql-test/suite/funcs_1/t/storedproc.test
@@ -18861,6 +18861,7 @@ delimiter //;
--error ER_PARSE_ERROR
CREATE PROCEDURE sp7()
BEGIN
+ DECLARE count INT DEFAULT 100;
label1: loop
set @dummystring = 'temp value';
if count > 10 then leave label1;
diff --git a/sql/item_create.cc b/sql/item_create.cc
index 901dfa06f40..b3fbdfd97cf 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -3487,12 +3487,11 @@ Create_sp_func::create_with_db(THD *thd, LEX_CSTRING *db, LEX_CSTRING *name,
sph->add_used_routine(lex, thd, qname);
if (pkgname.m_name.length)
sp_handler_package_body.add_used_routine(lex, thd, &pkgname);
+ Name_resolution_context *ctx= lex->current_context_or_default();
if (arg_count > 0)
- func= new (thd->mem_root) Item_func_sp(thd, lex->current_context(),
- qname, sph, *item_list);
+ func= new (thd->mem_root) Item_func_sp(thd, ctx, qname, sph, *item_list);
else
- func= new (thd->mem_root) Item_func_sp(thd, lex->current_context(),
- qname, sph);
+ func= new (thd->mem_root) Item_func_sp(thd, ctx, qname, sph);
lex->safe_to_cache_query= 0;
return func;
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 5a447cef23a..9ca44c616a5 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -115,7 +115,8 @@ void Item_subselect::init(st_select_lex *select_lex,
do not take into account expression inside aggregate functions because
they can access original table fields
*/
- parsing_place= (outer_select->in_sum_expr ?
+ // QQ: shouldn't we use relink_hack() instead ?
+ parsing_place= (!outer_select || outer_select->in_sum_expr ?
NO_MATTER :
outer_select->parsing_place);
if (unit->is_unit_op() && unit->first_select()->next_select())
@@ -239,6 +240,9 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
{
SELECT_LEX *upper= unit->outer_select();
+ // QQ: shouldn't we use relink_hack() instead?
+ if (!upper)
+ upper= &thd_param->lex->builtin_select;
if (upper->parsing_place == IN_HAVING)
upper->subquery_in_having= 1;
/* The subquery is an expression cache candidate */
@@ -1395,12 +1399,46 @@ bool Item_singlerow_subselect::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate)
}
+/*
+ "IN" and "EXISTS" subselect can appear in two statement types:
+
+ 1. Statements that can have table columns, such as SELECT, DELETE, UPDATE
+ 2. Statements that cannot have table columns, e.g:
+ RETURN ((1) IN (SELECT * FROM t1))
+ IF ((1) IN (SELECT * FROM t1))
+
+ Statements of the first type call master_select_push() in the beginning.
+ In such case everything is properly linked.
+
+ Statements of the second type do not call mastr_select_push().
+ Here we catch the second case and relink thd->lex->builtin_select and
+ select_lex to properly point to each other.
+
+ QQ: Shouldn't subselects of other type also call relink_hack()?
+ QQ: Can we do it at constructor time instead?
+*/
+static void relink_hack(THD *thd, st_select_lex *select_lex)
+{
+ if (!thd->lex->select_stack_top) // Statements of the second type
+ {
+ if (!select_lex->get_master()->get_master())
+ ((st_select_lex *) select_lex->get_master())->
+ set_master(&thd->lex->builtin_select);
+ if (!thd->lex->builtin_select.get_slave())
+ thd->lex->builtin_select.set_slave(select_lex->get_master());
+ }
+}
+
+
Item_exists_subselect::Item_exists_subselect(THD *thd,
st_select_lex *select_lex):
Item_subselect(thd), upper_not(NULL), abort_on_null(0),
emb_on_expr_nest(NULL), optimizer(0), exists_transformed(0)
{
DBUG_ENTER("Item_exists_subselect::Item_exists_subselect");
+
+ relink_hack(thd, select_lex);
+
init(select_lex, new (thd->mem_root) select_exists_subselect(thd, this));
max_columns= UINT_MAX;
null_value= FALSE; //can't be NULL
@@ -1443,6 +1481,9 @@ Item_in_subselect::Item_in_subselect(THD *thd, Item * left_exp,
{
DBUG_ENTER("Item_in_subselect::Item_in_subselect");
DBUG_PRINT("info", ("in_strategy: %u", (uint)in_strategy));
+
+ relink_hack(thd, select_lex);
+
left_expr_orig= left_expr= left_exp;
/* prepare to possible disassembling the item in convert_subq_to_sj() */
if (left_exp->type() == Item::ROW_ITEM)
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 2ec7e3c338f..a8800502daf 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -72,6 +72,7 @@ size_t Item_sum::ram_limitation(THD *thd)
bool Item_sum::init_sum_func_check(THD *thd)
{
SELECT_LEX *curr_sel= thd->lex->current_select;
+ DBUG_ASSERT(curr_sel);
if (!curr_sel->name_visibility_map)
{
for (SELECT_LEX *sl= curr_sel; sl; sl= sl->context.outer_select())
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index a55ce2d163c..70f82d53eba 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -518,6 +518,7 @@ bool is_materialization_applicable(THD *thd, Item_in_subselect *in_subs,
if (optimizer_flag(thd, OPTIMIZER_SWITCH_MATERIALIZATION) && // 0
!child_select->is_part_of_union() && // 1
parent_unit->first_select()->leaf_tables.elements && // 2
+ child_select->outer_select() &&
child_select->outer_select()->leaf_tables.elements && // 2A
subquery_types_allow_materialization(in_subs) &&
(in_subs->is_top_level_item() || //3
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index db055eb012e..55e76c7effd 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -6006,9 +6006,17 @@ bool LEX::sp_for_loop_implicit_cursor_statement(THD *thd,
bounds->m_index->sp_lex_in_use= true;
sphead->reset_lex(thd, bounds->m_index);
DBUG_ASSERT(thd->lex != this);
- if (!(item= new (thd->mem_root) Item_field(thd,
- thd->lex->current_context(),
- NullS, NullS, &name)))
+ /*
+ We pass NULL as Name_resolution_context here.
+ It's OK, fix_fields() will not be called for this Item_field created.
+ Item_field is only needed for LEX::sp_for_loop_cursor_declarations()
+ and is used to transfer the loop index variable name, "rec" in this example:
+ FOR rec IN (SELECT * FROM t1)
+ DO
+ SELECT rec.a, rec.b;
+ END FOR;
+ */
+ if (!(item= new (thd->mem_root) Item_field(thd, NULL, NullS, NullS, &name)))
return true;
bounds->m_index->set_item_and_free_list(item, NULL);
if (thd->lex->sphead->restore_lex(thd))
@@ -6112,6 +6120,19 @@ bool LEX::sp_for_loop_intrange_declarations(THD *thd, Lex_for_loop_st *loop,
const LEX_CSTRING *index,
const Lex_for_loop_bounds_st &bounds)
{
+ Item *item;
+ if ((item= bounds.m_index->get_item())->type() == Item::FIELD_ITEM)
+ {
+ // We're here is the lower bound is unknown identifier
+ my_error(ER_SP_UNDECLARED_VAR, MYF(0), item->full_name());
+ return true;
+ }
+ if ((item= bounds.m_upper_bound->get_item())->type() == Item::FIELD_ITEM)
+ {
+ // We're here is the upper bound is unknown identifier
+ my_error(ER_SP_UNDECLARED_VAR, MYF(0), item->full_name());
+ return true;
+ }
if (!(loop->m_index=
bounds.m_index->sp_add_for_loop_variable(thd, index,
bounds.m_index->get_item())))
@@ -6989,6 +7010,38 @@ bool LEX::add_resignal_statement(THD *thd, const sp_condition_value *v)
}
+/*
+ Make an Item when an identifier is found in the FOR loop bounds:
+ FOR rec IN cursor
+ FOR var IN var1 .. xxx
+ FOR var IN row1.field1 .. xxx
+ When we parse the first expression after the "IN" keyword,
+ we don't know yet if it's a cursor name, or a scalar SP variable name,
+ or a field of a ROW SP variable. Here we create Item_field to remember
+ the fully qualified name. Later sp_for_loop_cursor_declarations()
+ detects how to treat this name properly.
+*/
+Item *LEX::create_item_for_loop_bound(THD *thd,
+ const LEX_CSTRING *a,
+ const LEX_CSTRING *b,
+ const LEX_CSTRING *c)
+{
+ /*
+ Pass NULL as the name resolution context.
+ This is OK, fix_fields() won't be called for this Item_field.
+ */
+ return new (thd->mem_root) Item_field(thd, NULL, a->str, b->str, c);
+}
+
+
+bool LEX::check_expr_allows_fields_or_error(THD *thd, const char *name) const
+{
+ if (select_stack_top > 0)
+ return false; // OK, fields are allowed
+ my_error(ER_BAD_FIELD_ERROR, MYF(0), name, thd->where);
+ return true; // Error, fields are not allowed
+}
+
Item *LEX::create_item_ident_nospvar(THD *thd,
const LEX_CSTRING *a,
const LEX_CSTRING *b)
@@ -7011,12 +7064,11 @@ Item *LEX::create_item_ident_nospvar(THD *thd,
my_error(ER_TABLENAME_NOT_ALLOWED_HERE, MYF(0), a->str, thd->where);
return NULL;
}
- if ((current_select->parsing_place != IN_HAVING) ||
- (current_select->get_in_sum_expr() > 0))
- return new (thd->mem_root) Item_field(thd, current_context(),
- NullS, a->str, b);
- return new (thd->mem_root) Item_ref(thd, current_context(),
- NullS, a->str, b);
+
+ if (current_select->parsing_place == FOR_LOOP_BOUND)
+ return create_item_for_loop_bound(thd, &null_clex_str, a, b);
+
+ return create_item_ident_field(thd, NullS, a->str, b);
}
@@ -7217,12 +7269,11 @@ Item *LEX::create_item_ident(THD *thd,
my_error(ER_TABLENAME_NOT_ALLOWED_HERE, MYF(0), b->str, thd->where);
return NULL;
}
- if (current_select->parsing_place != IN_HAVING ||
- current_select->get_in_sum_expr() > 0)
- return new (thd->mem_root) Item_field(thd, current_context(),
- schema, b->str, c);
- return new (thd->mem_root) Item_ref(thd, current_context(),
- schema, b->str, c);
+
+ if (current_select->parsing_place == FOR_LOOP_BOUND)
+ return create_item_for_loop_bound(thd, &null_clex_str, b, c);
+
+ return create_item_ident_field(thd, schema, b->str, c);
}
@@ -7298,15 +7349,19 @@ bool LEX::set_user_variable(THD *thd, const LEX_CSTRING *name, Item *val)
}
-Item *LEX::create_item_ident_nosp(THD *thd, LEX_CSTRING *name)
+Item *LEX::create_item_ident_field(THD *thd, const char *db,
+ const char *table, const LEX_CSTRING *name)
{
+ if (check_expr_allows_fields_or_error(thd, name->str))
+ return NULL;
+
if (current_select->parsing_place != IN_HAVING ||
current_select->get_in_sum_expr() > 0)
return new (thd->mem_root) Item_field(thd, current_context(),
- NullS, NullS, name);
+ db, table, name);
return new (thd->mem_root) Item_ref(thd, current_context(),
- NullS, NullS, name);
+ db, table, name);
}
@@ -7352,6 +7407,11 @@ Item *LEX::create_item_ident_sp(THD *thd, LEX_CSTRING *name,
if (!my_strcasecmp(system_charset_info, name->str, "SQLERRM"))
return new (thd->mem_root) Item_func_sqlerrm(thd);
}
+
+ if (current_select->parsing_place == FOR_LOOP_BOUND)
+ return create_item_for_loop_bound(thd, &null_clex_str, &null_clex_str,
+ name);
+
return create_item_ident_nosp(thd, name);
}
@@ -8648,3 +8708,29 @@ bool LEX::insert_select_hack(SELECT_LEX *sel)
DBUG_RETURN(FALSE);
}
+
+
+/*
+ Create an Item_singlerow_subselect for a query expression.
+*/
+Item *LEX::create_item_query_expression(THD *thd,
+ const char *tok_start,
+ st_select_lex_unit *unit)
+{
+ if (!expr_allows_subselect || sql_command == SQLCOM_PURGE)
+ {
+ thd->parse_error(ER_SYNTAX_ERROR, tok_start);
+ return NULL;
+ }
+
+ // Add the subtree of subquery to the current SELECT_LEX
+ 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);
+
+ return new (thd->mem_root)
+ Item_singlerow_subselect(thd, unit->first_select());
+}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 4fc74474d56..f715fddc5f0 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -606,6 +606,7 @@ class st_select_lex_node {
}
inline st_select_lex_node* get_master() { return master; }
+ inline st_select_lex_node* get_slave() { return slave; }
void include_down(st_select_lex_node *upper);
void add_slave(st_select_lex_node *slave_arg);
void include_neighbour(st_select_lex_node *before);
@@ -1116,6 +1117,10 @@ class st_select_lex: public st_select_lex_node
{
master= (st_select_lex_node *)master_unit;
}
+ void set_master(st_select_lex *master_arg)
+ {
+ master= master_arg;
+ }
st_select_lex_unit* first_inner_unit()
{
return (st_select_lex_unit*) slave;
@@ -2843,6 +2848,12 @@ struct LEX: public Query_tables_list
bool sp_for_loop_condition(THD *thd, const Lex_for_loop_st &loop);
bool sp_for_loop_increment(THD *thd, const Lex_for_loop_st &loop);
+ /*
+ Check if Item_field and Item_ref are allowed in the current statement.
+ @retval false OK (fields are allowed)
+ @retval true ERROR (fields are not allowed). Error is raised.
+ */
+ bool check_expr_allows_fields_or_error(THD *thd, const char *name) const;
public:
void parse_error(uint err_number= ER_SYNTAX_ERROR);
inline bool is_arena_for_set_stmt() {return arena_for_set_stmt != 0;}
@@ -3312,12 +3323,25 @@ struct LEX: public Query_tables_list
DBUG_RETURN(select_lex);
}
+ SELECT_LEX *current_select_or_default()
+ {
+ return current_select ? current_select : &builtin_select;
+ }
+
bool copy_db_to(LEX_CSTRING *to);
Name_resolution_context *current_context()
{
return context_stack.head();
}
+ Name_resolution_context *current_context_or_default()
+ {
+ Name_resolution_context *ctx= current_context();
+ if (!ctx)
+ return &builtin_select.context;
+ return ctx;
+ }
+
/*
Restore the LEX and THD in case of a parse error.
*/
@@ -3484,7 +3508,12 @@ struct LEX: public Query_tables_list
Item_splocal *create_item_for_sp_var(LEX_CSTRING *name, sp_variable *spvar,
const char *start, const char *end);
- Item *create_item_ident_nosp(THD *thd, LEX_CSTRING *name);
+ Item *create_item_ident_field(THD *thd, const char *db, const char *table,
+ const LEX_CSTRING *name);
+ Item *create_item_ident_nosp(THD *thd, LEX_CSTRING *name)
+ {
+ return create_item_ident_field(thd, NullS, NullS, name);
+ }
Item *create_item_ident_sp(THD *thd, LEX_CSTRING *name,
const char *start, const char *end);
Item *create_item_ident(THD *thd, LEX_CSTRING *name,
@@ -3614,6 +3643,10 @@ struct LEX: public Query_tables_list
const char *start,
const char *end);
+ Item *create_item_query_expression(THD *thd,
+ const char *tok_start,
+ st_select_lex_unit *unit);
+
Item *make_item_func_replace(THD *thd, Item *org, Item *find, Item *replace);
Item *make_item_func_substr(THD *thd, Item *a, Item *b, Item *c);
Item *make_item_func_substr(THD *thd, Item *a, Item *b);
@@ -3791,6 +3824,17 @@ struct LEX: public Query_tables_list
sp_for_loop_cursor_finalize(thd, loop) :
sp_for_loop_intrange_finalize(thd, loop);
}
+
+ /*
+ Make an Item when an identifier is found in the FOR loop bounds:
+ FOR rec IN cursor
+ FOR rec IN var1 .. var2
+ FOR rec IN row1.field1 .. xxx
+ */
+ Item *create_item_for_loop_bound(THD *thd,
+ const LEX_CSTRING *a,
+ const LEX_CSTRING *b,
+ const LEX_CSTRING *c);
/* End of FOR LOOP methods */
bool add_signal_statement(THD *thd, const class sp_condition_value *value);
diff --git a/sql/sql_priv.h b/sql/sql_priv.h
index 7fda6198dcf..5ad21167b94 100644
--- a/sql/sql_priv.h
+++ b/sql/sql_priv.h
@@ -363,6 +363,7 @@ enum enum_parsing_place
IN_PART_FUNC,
BEFORE_OPT_LIST,
AFTER_LIST,
+ FOR_LOOP_BOUND,
PARSING_PLACE_SIZE /* always should be the last */
};
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index b5e3bb4f73d..491874b3b45 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -2222,12 +2222,7 @@ deallocate_or_drop:
;
prepare:
- PREPARE_SYM
- {
- if (Lex->main_select_push())
- MYSQL_YYABORT;
- }
- ident FROM prepare_src
+ PREPARE_SYM ident FROM prepare_src
{
LEX *lex= thd->lex;
if (lex->table_or_sp_used())
@@ -2236,8 +2231,7 @@ prepare:
if (Lex->check_main_unit_semantics())
MYSQL_YYABORT;
lex->sql_command= SQLCOM_PREPARE;
- lex->prepared_stmt_name= $3;
- Lex->pop_select(); //main select
+ lex->prepared_stmt_name= $2;
}
;
@@ -2256,21 +2250,13 @@ execute:
LEX *lex= thd->lex;
lex->sql_command= SQLCOM_EXECUTE;
lex->prepared_stmt_name= $2;
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
execute_using
{
- Lex->pop_select(); //main select
if (Lex->check_main_unit_semantics())
MYSQL_YYABORT;
}
- | EXECUTE_SYM IMMEDIATE_SYM
- {
- if (Lex->main_select_push())
- MYSQL_YYABORT;
- }
- prepare_src
+ | EXECUTE_SYM IMMEDIATE_SYM prepare_src
{
if (Lex->table_or_sp_used())
my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0),
@@ -2279,7 +2265,6 @@ execute:
}
execute_using
{
- Lex->pop_select(); //main select
if (Lex->check_main_unit_semantics())
MYSQL_YYABORT;
}
@@ -2812,7 +2797,6 @@ create:
if (Lex->main_select_push())
MYSQL_YYABORT;
Lex->create_info.set($1);
-
}
sf_tail_aggregate
{
@@ -3306,13 +3290,8 @@ call:
{
if (Lex->call_statement_start(thd, $2))
MYSQL_YYABORT;
- if (Lex->main_select_push())
- MYSQL_YYABORT;
- }
- opt_sp_cparam_list
- {
- Lex->pop_select(); //main select
}
+ opt_sp_cparam_list {}
;
/* CALL parameters */
@@ -3729,16 +3708,10 @@ sp_hcond:
;
signal_stmt:
- SIGNAL_SYM
- {
- if (Lex->main_select_push())
- YYABORT;
- }
- signal_value opt_set_signal_information
+ SIGNAL_SYM signal_value opt_set_signal_information
{
- if (Lex->add_signal_statement(thd, $3))
+ if (Lex->add_signal_statement(thd, $2))
MYSQL_YYABORT;
- Lex->pop_select(); //main select
}
;
@@ -3864,14 +3837,9 @@ resignal_stmt:
;
get_diagnostics:
- GET_SYM which_area DIAGNOSTICS_SYM
+ GET_SYM which_area DIAGNOSTICS_SYM diagnostics_information
{
- if (Lex->main_select_push())
- YYABORT;
- }
- diagnostics_information
- {
- Diagnostics_information *info= $5;
+ Diagnostics_information *info= $4;
info->set_which_da($2);
@@ -3880,7 +3848,6 @@ get_diagnostics:
if (Lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
- Lex->pop_select(); //main select
}
;
@@ -4048,16 +4015,7 @@ sp_decl_idents:
sp_opt_default:
/* Empty */ { $$ = NULL; }
- | DEFAULT
- {
- if (Lex->main_select_push())
- MYSQL_YYABORT;
- }
- expr
- {
- Lex->pop_select(); //main select
- $$ = $3;
- }
+ | DEFAULT expr { $$ = $2; }
;
/*
@@ -4159,15 +4117,10 @@ sp_proc_stmt_statement:
sp_proc_stmt_return:
RETURN_SYM
- {
- Lex->sphead->reset_lex(thd);
- if (Lex->main_select_push())
- MYSQL_YYABORT;
- }
+ { Lex->sphead->reset_lex(thd); }
expr
{
LEX *lex= Lex;
- lex->pop_select(); //main select
sp_head *sp= lex->sphead;
if (sp->m_handler->add_instr_freturn(thd, sp, lex->spcont,
$3, lex) ||
@@ -4205,8 +4158,6 @@ assignment_source_expr:
{
DBUG_ASSERT(thd->free_list == NULL);
Lex->sphead->reset_lex(thd, $1);
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
expr
{
@@ -4215,7 +4166,6 @@ assignment_source_expr:
$$->sp_lex_in_use= true;
$$->set_item_and_free_list($3, thd->free_list);
thd->free_list= NULL;
- Lex->pop_select(); //main select
if ($$->sphead->restore_lex(thd))
MYSQL_YYABORT;
}
@@ -4225,6 +4175,7 @@ for_loop_bound_expr:
assignment_source_lex
{
Lex->sphead->reset_lex(thd, $1);
+ Lex->current_select->parsing_place= FOR_LOOP_BOUND;
}
expr
{
@@ -4234,6 +4185,7 @@ for_loop_bound_expr:
$$->set_item_and_free_list($3, NULL);
if ($$->sphead->restore_lex(thd))
MYSQL_YYABORT;
+ Lex->current_select->parsing_place= NO_MATTER;
}
;
@@ -4348,14 +4300,9 @@ sp_fetch_list:
;
sp_if:
- {
- Lex->sphead->reset_lex(thd);
- if (Lex->main_select_push())
- MYSQL_YYABORT;
- }
+ { Lex->sphead->reset_lex(thd); }
expr THEN_SYM
{
- Lex->pop_select(); //main select
LEX *lex= Lex;
sp_head *sp= lex->sphead;
sp_pcontext *ctx= lex->spcont;
@@ -4467,18 +4414,12 @@ case_stmt_specification:
;
case_stmt_body:
- {
- Lex->sphead->reset_lex(thd); /* For expr $2 */
-
- if (Lex->main_select_push())
- MYSQL_YYABORT;
- }
+ { Lex->sphead->reset_lex(thd); /* For expr $2 */ }
expr
{
if (Lex->case_stmt_action_expr($2))
MYSQL_YYABORT;
- Lex->pop_select(); //main select
if (Lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
}
@@ -4502,9 +4443,6 @@ simple_when_clause:
WHEN_SYM
{
Lex->sphead->reset_lex(thd); /* For expr $3 */
-
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
expr
{
@@ -4513,8 +4451,6 @@ simple_when_clause:
LEX *lex= Lex;
if (lex->case_stmt_action_when($3, true))
MYSQL_YYABORT;
-
- lex->pop_select(); //main select
/* For expr $3 */
if (lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
@@ -4531,17 +4467,12 @@ searched_when_clause:
WHEN_SYM
{
Lex->sphead->reset_lex(thd); /* For expr $3 */
-
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
expr
{
LEX *lex= Lex;
if (lex->case_stmt_action_when($3, false))
MYSQL_YYABORT;
-
- lex->pop_select(); //main select
/* For expr $3 */
if (lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
@@ -4690,7 +4621,6 @@ while_body:
LEX *lex= Lex;
if (lex->sp_while_loop_expression(thd, $1))
MYSQL_YYABORT;
- Lex->pop_select(); //main select pushed before while_body use
if (lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
}
@@ -4703,12 +4633,7 @@ while_body:
repeat_body:
sp_proc_stmts1 UNTIL_SYM
- {
- Lex->sphead->reset_lex(thd);
-
- if (Lex->main_select_push())
- MYSQL_YYABORT;
- }
+ { Lex->sphead->reset_lex(thd); }
expr END REPEAT_SYM
{
LEX *lex= Lex;
@@ -4719,8 +4644,6 @@ repeat_body:
if (i == NULL ||
lex->sphead->add_instr(i))
MYSQL_YYABORT;
-
- lex->pop_select(); //main select
if (lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
/* We can shortcut the cont_backpatch here */
@@ -4749,12 +4672,8 @@ sp_labeled_control:
if (Lex->sp_push_loop_label(thd, &$1))
MYSQL_YYABORT;
Lex->sphead->reset_lex(thd);
-
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
while_body pop_sp_loop_label
-
{ }
| sp_label FOR_SYM
{
@@ -4806,13 +4725,9 @@ sp_unlabeled_control:
if (Lex->sp_push_loop_empty_label(thd))
MYSQL_YYABORT;
Lex->sphead->reset_lex(thd);
-
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
while_body
{
- // while body pop main select
Lex->sp_pop_loop_empty_label(thd);
}
| FOR_SYM
@@ -6907,22 +6822,7 @@ parenthesized_expr:
remember_tok_start
query_expression
{
- if (!Lex->expr_allows_subselect ||
- Lex->sql_command == (int)SQLCOM_PURGE)
- {
- thd->parse_error(ER_SYNTAX_ERROR, $1);
- MYSQL_YYABORT;
- }
-
- // Add the subtree of subquery to the current SELECT_LEX
- SELECT_LEX *curr_sel= Lex->select_stack_head();
- DBUG_ASSERT(Lex->current_select == curr_sel);
- curr_sel->register_unit($2, &curr_sel->context);
- curr_sel->add_statistics($2);
-
- $$= new (thd->mem_root)
- Item_singlerow_subselect(thd, $2->first_select());
- if ($$ == NULL)
+ if (!($$= Lex->create_item_query_expression(thd, $1, $2)))
MYSQL_YYABORT;
}
| expr
@@ -8765,13 +8665,9 @@ checksum:
lex->sql_command = SQLCOM_CHECKSUM;
/* Will be overridden during execution. */
YYPS->m_lock_type= TL_UNLOCK;
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
table_list opt_checksum_type
- {
- Lex->pop_select(); //main select
- }
+ {}
;
opt_checksum_type:
@@ -8797,8 +8693,6 @@ repair:
lex->alter_info.reset();
/* Will be overridden during execution. */
YYPS->m_lock_type= TL_UNLOCK;
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
repair_table_or_view
{
@@ -8807,7 +8701,6 @@ repair:
lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_repair_table();
if (lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
- Lex->pop_select(); //main select
}
;
@@ -8836,8 +8729,6 @@ analyze:
ANALYZE_SYM opt_no_write_to_binlog table_or_tables
{
LEX *lex=Lex;
- if (lex->main_select_push())
- YYABORT;
lex->sql_command = SQLCOM_ANALYZE;
lex->no_write_to_binlog= $2;
lex->check_opt.init();
@@ -8852,7 +8743,6 @@ analyze:
lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_analyze_table();
if (lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
- Lex->pop_select(); //main select
}
;
@@ -8969,8 +8859,6 @@ check: CHECK_SYM
lex->alter_info.reset();
/* Will be overridden during execution. */
YYPS->m_lock_type= TL_UNLOCK;
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
check_view_or_table
{
@@ -8981,7 +8869,6 @@ check: CHECK_SYM
lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_check_table();
if (lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
- Lex->pop_select(); //main select
}
;
@@ -9019,8 +8906,6 @@ optimize:
lex->alter_info.reset();
/* Will be overridden during execution. */
YYPS->m_lock_type= TL_UNLOCK;
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
table_list opt_lock_wait_timeout
{
@@ -9029,7 +8914,6 @@ optimize:
lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_optimize_table();
if (lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
- Lex->pop_select(); //main select
}
;
@@ -9043,13 +8927,9 @@ rename:
RENAME table_or_tables
{
Lex->sql_command= SQLCOM_RENAME_TABLE;
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
table_to_table_list
- {
- Lex->pop_select(); //main select
- }
+ {}
| RENAME USER_SYM clear_privileges rename_list
{
Lex->sql_command = SQLCOM_RENAME_USER;
@@ -9143,13 +9023,9 @@ preload:
LEX *lex=Lex;
lex->sql_command=SQLCOM_PRELOAD_KEYS;
lex->alter_info.reset();
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
preload_list_or_parts
- {
- Lex->pop_select(); //main select
- }
+ {}
;
preload_list_or_parts:
@@ -9534,6 +9410,7 @@ query_expression:
}
;
+
subselect:
remember_tok_start
query_expression
@@ -10338,7 +10215,21 @@ column_default_non_parenthesized_expr:
| param_marker { $$= $1; }
| variable
| sum_expr
+ {
+ if (!Lex->select_stack_top)
+ {
+ my_error(ER_INVALID_GROUP_FUNC_USE, MYF(0));
+ MYSQL_YYABORT;
+ }
+ }
| window_func_expr
+ {
+ if (!Lex->select_stack_top)
+ {
+ my_error(ER_WRONG_PLACEMENT_OF_WINDOW_FUNCTION, MYF(0));
+ MYSQL_YYABORT;
+ }
+ }
| inverse_distribution_function
| ROW_SYM '(' expr ',' expr_list ')'
{
@@ -11462,7 +11353,7 @@ sum_expr:
SELECT_LEX *sel= Select;
sel->in_sum_expr--;
$$= new (thd->mem_root)
- Item_func_group_concat(thd, Lex->current_context(),
+ Item_func_group_concat(thd, Lex->current_context_or_default(),
$3, $5,
sel->gorder_list, $7, $8,
sel->select_limit,
@@ -13166,15 +13057,10 @@ do:
LEX *lex=Lex;
lex->sql_command = SQLCOM_DO;
mysql_init_select(lex);
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
expr_list
{
Lex->insert_list= $3;
- Lex->pop_select(); //main select
- if (Lex->check_main_unit_semantics())
- MYSQL_YYABORT;
}
;
@@ -13316,7 +13202,8 @@ table_list:
table_name:
table_ident
{
- if (!Select->add_table_to_list(thd, $1, NULL,
+ if (!thd->lex->current_select_or_default()->
+ add_table_to_list(thd, $1, NULL,
TL_OPTION_UPDATING,
YYPS->m_lock_type,
YYPS->m_mdl_type))
@@ -13732,7 +13619,6 @@ delete_part2:
| HISTORY_SYM delete_single_table opt_delete_system_time
{
Lex->last_table()->vers_conditions= Lex->vers_conditions;
- Lex->pop_select(); //main select
}
;
@@ -13859,8 +13745,6 @@ truncate:
{
LEX* lex= Lex;
lex->sql_command= SQLCOM_TRUNCATE;
- if (lex->main_select_push())
- MYSQL_YYABORT;
lex->alter_info.reset();
lex->builtin_select.options= 0;
lex->builtin_select.sql_cache= SELECT_LEX::SQL_CACHE_UNSPECIFIED;
@@ -13875,7 +13759,6 @@ truncate:
lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_truncate_table();
if (lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
- Lex->pop_select(); //main select
}
;
@@ -14679,13 +14562,9 @@ purge:
LEX *lex=Lex;
lex->type=0;
lex->sql_command = SQLCOM_PURGE;
- if (lex->main_select_push())
- MYSQL_YYABORT;
}
purge_options
- {
- Lex->pop_select(); //main select
- }
+ {}
;
purge_options:
@@ -14714,8 +14593,6 @@ kill:
KILL_SYM
{
LEX *lex=Lex;
- if (lex->main_select_push())
- YYABORT;
lex->value_list.empty();
lex->users_list.empty();
lex->sql_command= SQLCOM_KILL;
@@ -14724,7 +14601,6 @@ kill:
kill_type kill_option kill_expr
{
Lex->kill_signal= (killed_state) ($3 | $4);
- Lex->pop_select(); //main select
}
;
@@ -16544,13 +16420,9 @@ lock:
if (lex->sphead)
my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "LOCK"));
lex->sql_command= SQLCOM_LOCK_TABLES;
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
table_lock_list opt_lock_wait_timeout
- {
- Lex->pop_select(); //main select
- }
+ {}
;
opt_lock_wait_timeout:
@@ -16615,13 +16487,9 @@ unlock:
if (lex->sphead)
my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "UNLOCK"));
lex->sql_command= SQLCOM_UNLOCK_TABLES;
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
table_or_tables
- {
- Lex->pop_select(); //main select
- }
+ {}
;
/*
diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy
index 7dd065d59ab..069fa0ae615 100644
--- a/sql/sql_yacc_ora.yy
+++ b/sql/sql_yacc_ora.yy
@@ -1640,22 +1640,14 @@ deallocate_or_drop:
;
prepare:
- PREPARE_SYM
- {
- if (Lex->main_select_push())
- MYSQL_YYABORT;
- }
- ident FROM prepare_src
+ PREPARE_SYM ident FROM prepare_src
{
LEX *lex= thd->lex;
if (lex->table_or_sp_used())
my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0),
"PREPARE..FROM"));
- if (Lex->check_main_unit_semantics())
- MYSQL_YYABORT;
lex->sql_command= SQLCOM_PREPARE;
- lex->prepared_stmt_name= $3;
- Lex->pop_select(); //main select
+ lex->prepared_stmt_name= $2;
}
;
@@ -1674,21 +1666,10 @@ execute:
LEX *lex= thd->lex;
lex->sql_command= SQLCOM_EXECUTE;
lex->prepared_stmt_name= $2;
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
execute_using
- {
- Lex->pop_select(); //main select
- if (Lex->check_main_unit_semantics())
- MYSQL_YYABORT;
- }
- | EXECUTE_SYM IMMEDIATE_SYM
- {
- if (Lex->main_select_push())
- MYSQL_YYABORT;
- }
- prepare_src
+ {}
+ | EXECUTE_SYM IMMEDIATE_SYM prepare_src
{
if (Lex->table_or_sp_used())
my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0),
@@ -1696,11 +1677,7 @@ execute:
Lex->sql_command= SQLCOM_EXECUTE_IMMEDIATE;
}
execute_using
- {
- Lex->pop_select(); //main select
- if (Lex->check_main_unit_semantics())
- MYSQL_YYABORT;
- }
+ {}
;
execute_using:
@@ -2952,13 +2929,8 @@ call:
{
if (Lex->call_statement_start(thd, $2))
MYSQL_YYABORT;
- if (Lex->main_select_push())
- MYSQL_YYABORT;
- }
- opt_sp_cparam_list
- {
- Lex->pop_select(); //main select
}
+ opt_sp_cparam_list {}
;
/* CALL parameters */
@@ -3488,16 +3460,10 @@ raise_stmt:
;
signal_stmt:
- SIGNAL_SYM
+ SIGNAL_SYM signal_value opt_set_signal_information
{
- if (Lex->main_select_push())
- YYABORT;
- }
- signal_value opt_set_signal_information
- {
- if (Lex->add_signal_statement(thd, $3))
+ if (Lex->add_signal_statement(thd, $2))
MYSQL_YYABORT;
- Lex->pop_select(); //main select
}
;
@@ -3623,14 +3589,9 @@ resignal_stmt:
;
get_diagnostics:
- GET_SYM which_area DIAGNOSTICS_SYM
+ GET_SYM which_area DIAGNOSTICS_SYM diagnostics_information
{
- if (Lex->main_select_push())
- YYABORT;
- }
- diagnostics_information
- {
- Diagnostics_information *info= $5;
+ Diagnostics_information *info= $4;
info->set_which_da($2);
@@ -3639,7 +3600,6 @@ get_diagnostics:
if (Lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
- Lex->pop_select(); //main select
}
;
@@ -3820,26 +3780,8 @@ sp_decl_idents:
sp_opt_default:
/* Empty */ { $$ = NULL; }
- | DEFAULT
- {
- if (Lex->main_select_push())
- MYSQL_YYABORT;
- }
- expr
- {
- Lex->pop_select(); //main select
- $$ = $3;
- }
- | SET_VAR
- {
- if (Lex->main_select_push())
- MYSQL_YYABORT;
- }
- expr
- {
- Lex->pop_select(); //main select
- $$ = $3;
- }
+ | DEFAULT expr { $$ = $2; }
+ | SET_VAR expr { $$ = $2; }
;
sp_proc_stmt:
@@ -3956,15 +3898,10 @@ sp_proc_stmt_statement:
sp_proc_stmt_return:
RETURN_SYM
- {
- Lex->sphead->reset_lex(thd);
- if (Lex->main_select_push())
- MYSQL_YYABORT;
- }
+ { Lex->sphead->reset_lex(thd); }
expr
{
LEX *lex= Lex;
- lex->pop_select(); //main select
sp_head *sp= lex->sphead;
if (sp->m_handler->add_instr_freturn(thd, sp, lex->spcont,
$3, lex) ||
@@ -4090,8 +4027,6 @@ assignment_source_expr:
{
DBUG_ASSERT(thd->free_list == NULL);
Lex->sphead->reset_lex(thd, $1);
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
expr
{
@@ -4100,7 +4035,6 @@ assignment_source_expr:
$$->sp_lex_in_use= true;
$$->set_item_and_free_list($3, thd->free_list);
thd->free_list= NULL;
- Lex->pop_select(); //main select
if ($$->sphead->restore_lex(thd))
MYSQL_YYABORT;
}
@@ -4110,6 +4044,7 @@ for_loop_bound_expr:
assignment_source_lex
{
Lex->sphead->reset_lex(thd, $1);
+ Lex->current_select->parsing_place= FOR_LOOP_BOUND;
}
expr
{
@@ -4119,6 +4054,7 @@ for_loop_bound_expr:
$$->set_item_and_free_list($3, NULL);
if ($$->sphead->restore_lex(thd))
MYSQL_YYABORT;
+ Lex->current_select->parsing_place= NO_MATTER;
}
;
@@ -4221,14 +4157,9 @@ sp_fetch_list:
;
sp_if:
- {
- Lex->sphead->reset_lex(thd);
- if (Lex->main_select_push())
- MYSQL_YYABORT;
- }
+ { Lex->sphead->reset_lex(thd); }
expr THEN_SYM
{
- Lex->pop_select(); //main select
LEX *lex= Lex;
sp_head *sp= lex->sphead;
sp_pcontext *ctx= lex->spcont;
@@ -4340,18 +4271,12 @@ case_stmt_specification:
;
case_stmt_body:
- {
- Lex->sphead->reset_lex(thd); /* For expr $2 */
-
- if (Lex->main_select_push())
- MYSQL_YYABORT;
- }
+ { Lex->sphead->reset_lex(thd); /* For expr $2 */ }
expr
{
if (Lex->case_stmt_action_expr($2))
MYSQL_YYABORT;
- Lex->pop_select(); //main select
if (Lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
}
@@ -4375,9 +4300,6 @@ simple_when_clause:
WHEN_SYM
{
Lex->sphead->reset_lex(thd); /* For expr $3 */
-
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
expr
{
@@ -4386,8 +4308,6 @@ simple_when_clause:
LEX *lex= Lex;
if (lex->case_stmt_action_when($3, true))
MYSQL_YYABORT;
-
- lex->pop_select(); //main select
/* For expr $3 */
if (lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
@@ -4404,17 +4324,12 @@ searched_when_clause:
WHEN_SYM
{
Lex->sphead->reset_lex(thd); /* For expr $3 */
-
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
expr
{
LEX *lex= Lex;
if (lex->case_stmt_action_when($3, false))
MYSQL_YYABORT;
-
- lex->pop_select(); //main select
/* For expr $3 */
if (lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
@@ -4654,7 +4569,6 @@ while_body:
LEX *lex= Lex;
if (lex->sp_while_loop_expression(thd, $1))
MYSQL_YYABORT;
- Lex->pop_select(); //main select pushed before while_body use
if (lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
}
@@ -4667,12 +4581,7 @@ while_body:
repeat_body:
sp_proc_stmts1 UNTIL_SYM
- {
- Lex->sphead->reset_lex(thd);
-
- if (Lex->main_select_push())
- MYSQL_YYABORT;
- }
+ { Lex->sphead->reset_lex(thd); }
expr END REPEAT_SYM
{
LEX *lex= Lex;
@@ -4683,8 +4592,6 @@ repeat_body:
if (i == NULL ||
lex->sphead->add_instr(i))
MYSQL_YYABORT;
-
- lex->pop_select(); //main select
if (lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
/* We can shortcut the cont_backpatch here */
@@ -4713,12 +4620,8 @@ sp_labeled_control:
if (Lex->sp_push_loop_label(thd, &$1))
MYSQL_YYABORT;
Lex->sphead->reset_lex(thd);
-
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
while_body pop_sp_loop_label
-
{ }
| labels_declaration_oracle FOR_SYM
{
@@ -4770,13 +4673,9 @@ sp_unlabeled_control:
if (Lex->sp_push_loop_empty_label(thd))
MYSQL_YYABORT;
Lex->sphead->reset_lex(thd);
-
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
while_body
{
- // while body pop main select
Lex->sp_pop_loop_empty_label(thd);
}
| FOR_SYM
@@ -6687,22 +6586,7 @@ parenthesized_expr:
remember_tok_start
query_expression
{
- if (!Lex->expr_allows_subselect ||
- Lex->sql_command == (int)SQLCOM_PURGE)
- {
- thd->parse_error(ER_SYNTAX_ERROR, $1);
- MYSQL_YYABORT;
- }
-
- // Add the subtree of subquery to the current SELECT_LEX
- SELECT_LEX *curr_sel= Lex->select_stack_head();
- DBUG_ASSERT(Lex->current_select == curr_sel);
- curr_sel->register_unit($2, &curr_sel->context);
- curr_sel->add_statistics($2);
-
- $$= new (thd->mem_root)
- Item_singlerow_subselect(thd, $2->first_select());
- if ($$ == NULL)
+ if (!($$= Lex->create_item_query_expression(thd, $1, $2)))
MYSQL_YYABORT;
}
| expr
@@ -8599,13 +8483,9 @@ checksum:
lex->sql_command = SQLCOM_CHECKSUM;
/* Will be overridden during execution. */
YYPS->m_lock_type= TL_UNLOCK;
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
table_list opt_checksum_type
- {
- Lex->pop_select(); //main select
- }
+ {}
;
opt_checksum_type:
@@ -8631,8 +8511,6 @@ repair:
lex->alter_info.reset();
/* Will be overridden during execution. */
YYPS->m_lock_type= TL_UNLOCK;
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
repair_table_or_view
{
@@ -8641,7 +8519,6 @@ repair:
lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_repair_table();
if (lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
- Lex->pop_select(); //main select
}
;
@@ -8670,8 +8547,6 @@ analyze:
ANALYZE_SYM opt_no_write_to_binlog table_or_tables
{
LEX *lex=Lex;
- if (lex->main_select_push())
- YYABORT;
lex->sql_command = SQLCOM_ANALYZE;
lex->no_write_to_binlog= $2;
lex->check_opt.init();
@@ -8686,7 +8561,6 @@ analyze:
lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_analyze_table();
if (lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
- Lex->pop_select(); //main select
}
;
@@ -8803,8 +8677,6 @@ check: CHECK_SYM
lex->alter_info.reset();
/* Will be overridden during execution. */
YYPS->m_lock_type= TL_UNLOCK;
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
check_view_or_table
{
@@ -8815,7 +8687,6 @@ check: CHECK_SYM
lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_check_table();
if (lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
- Lex->pop_select(); //main select
}
;
@@ -8853,8 +8724,6 @@ optimize:
lex->alter_info.reset();
/* Will be overridden during execution. */
YYPS->m_lock_type= TL_UNLOCK;
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
table_list opt_lock_wait_timeout
{
@@ -8863,7 +8732,6 @@ optimize:
lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_optimize_table();
if (lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
- Lex->pop_select(); //main select
}
;
@@ -8877,13 +8745,9 @@ rename:
RENAME table_or_tables
{
Lex->sql_command= SQLCOM_RENAME_TABLE;
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
table_to_table_list
- {
- Lex->pop_select(); //main select
- }
+ {}
| RENAME USER_SYM clear_privileges rename_list
{
Lex->sql_command = SQLCOM_RENAME_USER;
@@ -8977,13 +8841,9 @@ preload:
LEX *lex=Lex;
lex->sql_command=SQLCOM_PRELOAD_KEYS;
lex->alter_info.reset();
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
preload_list_or_parts
- {
- Lex->pop_select(); //main select
- }
+ {}
;
preload_list_or_parts:
@@ -10160,7 +10020,21 @@ column_default_non_parenthesized_expr:
| param_marker { $$= $1; }
| variable
| sum_expr
+ {
+ if (!Lex->select_stack_top)
+ {
+ my_error(ER_INVALID_GROUP_FUNC_USE, MYF(0));
+ MYSQL_YYABORT;
+ }
+ }
| window_func_expr
+ {
+ if (!Lex->select_stack_top)
+ {
+ my_error(ER_WRONG_PLACEMENT_OF_WINDOW_FUNCTION, MYF(0));
+ MYSQL_YYABORT;
+ }
+ }
| inverse_distribution_function
| ROW_SYM '(' expr ',' expr_list ')'
{
@@ -11283,7 +11157,7 @@ sum_expr:
SELECT_LEX *sel= Select;
sel->in_sum_expr--;
$$= new (thd->mem_root)
- Item_func_group_concat(thd, Lex->current_context(),
+ Item_func_group_concat(thd, Lex->current_context_or_default(),
$3, $5,
sel->gorder_list, $7, $8,
sel->select_limit,
@@ -12996,15 +12870,10 @@ do:
LEX *lex=Lex;
lex->sql_command = SQLCOM_DO;
mysql_init_select(lex);
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
expr_list
{
Lex->insert_list= $3;
- Lex->pop_select(); //main select
- if (Lex->check_main_unit_semantics())
- MYSQL_YYABORT;
}
;
@@ -13688,7 +13557,6 @@ truncate:
lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_truncate_table();
if (lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
- Lex->pop_select(); //main select
}
opt_truncate_table_storage_clause { }
;
@@ -14481,13 +14349,9 @@ purge:
LEX *lex=Lex;
lex->type=0;
lex->sql_command = SQLCOM_PURGE;
- if (lex->main_select_push())
- MYSQL_YYABORT;
}
purge_options
- {
- Lex->pop_select(); //main select
- }
+ {}
;
purge_options:
@@ -14505,8 +14369,6 @@ purge_option:
lex->value_list.empty();
lex->value_list.push_front($2, thd->mem_root);
lex->sql_command= SQLCOM_PURGE_BEFORE;
- if (Lex->check_main_unit_semantics())
- MYSQL_YYABORT;
}
;
@@ -14516,8 +14378,6 @@ kill:
KILL_SYM
{
LEX *lex=Lex;
- if (lex->main_select_push())
- YYABORT;
lex->value_list.empty();
lex->users_list.empty();
lex->sql_command= SQLCOM_KILL;
@@ -14526,7 +14386,6 @@ kill:
kill_type kill_option kill_expr
{
Lex->kill_signal= (killed_state) ($3 | $4);
- Lex->pop_select(); //main select
}
;
@@ -16479,13 +16338,9 @@ lock:
if (lex->sphead)
my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "LOCK"));
lex->sql_command= SQLCOM_LOCK_TABLES;
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
table_lock_list opt_lock_wait_timeout
- {
- Lex->pop_select(); //main select
- }
+ {}
;
opt_lock_wait_timeout:
@@ -16550,13 +16405,9 @@ unlock:
if (lex->sphead)
my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "UNLOCK"));
lex->sql_command= SQLCOM_UNLOCK_TABLES;
- if (Lex->main_select_push())
- MYSQL_YYABORT;
}
table_or_tables
- {
- Lex->pop_select(); //main select
- }
+ {}
;
/*
1
0
[Commits] a64a078e76c: MDEV-11953: support of brackets in UNION/EXCEPT/INTERSECT operations
by Oleksandr Byelkin 22 May '18
by Oleksandr Byelkin 22 May '18
22 May '18
revision-id: a64a078e76c3372f075c7eaed9729a03e524cd47 (mariadb-10.3.6-5-ga64a078e76c)
parent(s): d3ff133390231d8224843995af6b11f6a381803e
author: Oleksandr Byelkin
committer: Oleksandr Byelkin
timestamp: 2018-05-22 19:08:39 +0200
message:
MDEV-11953: support of brackets in UNION/EXCEPT/INTERSECT operations
---
mysql-test/include/deadlock.inc | 2 +-
mysql-test/main/brackets.result | 184 ++
mysql-test/main/brackets.test | 69 +
mysql-test/main/cte_nonrecursive.result | 40 +-
mysql-test/main/deadlock_innodb.result | 2 +-
mysql-test/main/derived_cond_pushdown.result | 6 +-
mysql-test/main/except.result | 8 +-
mysql-test/main/except.test | 4 +-
mysql-test/main/fulltext_order_by.result | 4 +-
mysql-test/main/func_analyse.result | 22 +-
mysql-test/main/func_analyse.test | 17 +-
mysql-test/main/intersect.result | 22 +-
mysql-test/main/intersect.test | 4 +-
mysql-test/main/join.result | 2 +-
mysql-test/main/join_nested.result | 2 +-
mysql-test/main/join_nested.test | 2 +-
mysql-test/main/join_nested_jcl6.result | 2 +-
mysql-test/main/parser.result | 55 +-
mysql-test/main/parser.test | 55 +-
mysql-test/main/query_cache.result | 26 +-
mysql-test/main/query_cache.test | 27 +-
mysql-test/main/show_check.result | 4 +-
mysql-test/main/show_check.test | 2 +-
mysql-test/main/sp-error.result | 10 +-
mysql-test/main/sp-error.test | 10 +-
mysql-test/main/sp.result | 2 +-
mysql-test/main/sp.test | 2 +-
mysql-test/main/subselect.result | 141 +-
mysql-test/main/subselect.test | 94 +-
mysql-test/main/subselect_mat.result | 4 +-
mysql-test/main/subselect_no_exists_to_in.result | 141 +-
mysql-test/main/subselect_no_mat.result | 141 +-
mysql-test/main/subselect_no_opts.result | 141 +-
mysql-test/main/subselect_no_scache.result | 141 +-
mysql-test/main/subselect_no_semijoin.result | 141 +-
mysql-test/main/subselect_sj.result | 2 +-
mysql-test/main/subselect_sj.test | 2 +-
mysql-test/main/subselect_sj_jcl6.result | 2 +-
mysql-test/main/subselect_sj_mat.result | 4 +-
mysql-test/main/subselect_sj_mat.test | 4 +-
mysql-test/main/table_value_constr.result | 1 -
mysql-test/main/union.result | 21 +-
mysql-test/main/union.test | 18 +-
mysql-test/main/view.result | 56 +-
mysql-test/main/view.test | 56 +-
mysql-test/suite/funcs_1/r/innodb_views.result | 2 +-
mysql-test/suite/funcs_1/r/memory_views.result | 2 +-
mysql-test/suite/funcs_1/views/views_master.inc | 2 +-
mysql-test/suite/innodb/r/innodb.result | 2 +-
mysql-test/suite/innodb/t/innodb.test | 2 +-
.../suite/innodb_fts/r/fulltext_order_by.result | 4 +-
mysql-test/suite/versioning/r/select2.result | 2 +-
sql/events.cc | 9 +-
sql/item.cc | 8 +-
sql/item_subselect.cc | 20 +-
sql/log_event.cc | 7 +-
sql/opt_range.cc | 2 +-
sql/opt_table_elimination.cc | 4 +-
sql/set_var.cc | 2 +-
sql/sp_head.cc | 13 +-
sql/sp_head.h | 5 +-
sql/sp_rcontext.cc | 14 +-
sql/sql_admin.cc | 18 +-
sql/sql_alter.cc | 4 +-
sql/sql_base.cc | 8 +-
sql/sql_base.h | 6 +-
sql/sql_cache.cc | 8 +-
sql/sql_class.cc | 4 +-
sql/sql_class.h | 8 +-
sql/sql_cte.cc | 16 +-
sql/sql_cte.h | 26 +-
sql/sql_delete.cc | 32 +-
sql/sql_derived.cc | 3 +-
sql/sql_do.cc | 2 +-
sql/sql_error.cc | 2 +-
sql/sql_help.cc | 11 +-
sql/sql_insert.cc | 40 +-
sql/sql_lex.cc | 953 +++++++-
sql/sql_lex.h | 234 +-
sql/sql_load.cc | 9 +-
sql/sql_parse.cc | 109 +-
sql/sql_partition.cc | 3 +-
sql/sql_partition_admin.cc | 4 +-
sql/sql_prepare.cc | 50 +-
sql/sql_priv.h | 5 +
sql/sql_profile.cc | 4 +-
sql/sql_select.cc | 50 +-
sql/sql_sequence.cc | 4 +-
sql/sql_show.cc | 28 +-
sql/sql_table.cc | 6 +-
sql/sql_truncate.cc | 2 +-
sql/sql_union.cc | 2 +-
sql/sql_update.cc | 30 +-
sql/sql_view.cc | 49 +-
sql/sql_yacc.yy | 2319 +++++++++++---------
sql/sql_yacc_ora.yy | 2205 +++++++++++--------
sql/structs.h | 53 +
sql/table.cc | 34 +-
sql/wsrep_mysqld.cc | 4 +-
storage/mroonga/ha_mroonga.cpp | 2 +-
storage/spider/spd_db_mysql.cc | 2 +-
storage/spider/spd_table.cc | 8 +-
storage/tokudb/tokudb_dir_cmd.cc | 4 +-
103 files changed, 4984 insertions(+), 3172 deletions(-)
diff --git a/mysql-test/include/deadlock.inc b/mysql-test/include/deadlock.inc
index 2fa61f48624..7ac2a16fc44 100644
--- a/mysql-test/include/deadlock.inc
+++ b/mysql-test/include/deadlock.inc
@@ -94,7 +94,7 @@ insert into t2 values(0, 0), (1, 20), (2, 30);
commit;
connection con1;
-select a,b from t2 UNION SELECT id, x from t1 FOR UPDATE;
+select a,b from t2 UNION (SELECT id, x from t1 FOR UPDATE);
select * from t2;
select * from t1;
diff --git a/mysql-test/main/brackets.result b/mysql-test/main/brackets.result
new file mode 100644
index 00000000000..a943dafecf7
--- /dev/null
+++ b/mysql-test/main/brackets.result
@@ -0,0 +1,184 @@
+select 1 union ( select 2 union select 3);
+1
+1
+2
+3
+explain extended
+select 1 union ( select 2 union select 3);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+4 UNION <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
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+NULL UNION RESULT <union1,4> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 /* select#1 */ select 1 AS `1` union /* select#4 */ select `__4`.`2` AS `2` from (/* select#2 */ select 2 AS `2` union /* select#3 */ select 3 AS `3`) `__4`
+select 1 union ( select 1 union select 1);
+1
+1
+explain extended
+select 1 union ( select 1 union select 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+4 UNION <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
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+NULL UNION RESULT <union1,4> ALL NULL NULL NULL NULL NULL NULL
+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 /* select#3 */ select 1 AS `1`) `__4`
+select 1 union all ( select 1 union select 1);
+1
+1
+1
+explain extended
+select 1 union all ( select 1 union select 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+4 UNION <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
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 /* select#1 */ select 1 AS `1` union all /* 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);
+1
+1
+explain extended
+select 1 union ( select 1 union all select 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+4 UNION <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
+NULL UNION RESULT <union1,4> ALL NULL NULL NULL NULL NULL NULL
+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`
+select 1 union select 1 union all select 1;
+1
+1
+1
+explain extended
+select 1 union select 1 union all select 1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 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,2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 /* select#1 */ select 1 AS `1` union /* select#2 */ select 1 AS `1` union all /* select#3 */ select 1 AS `1`
+(select 1 as a) union (select 2) order by a;
+a
+1
+2
+explain extended
+(select 1 as a) union (select 2) order by a;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL Using filesort
+Warnings:
+Note 1003 (/* select#1 */ select 1 AS `a`) union (/* select#2 */ select 2 AS `2`) order by `a`
+/* select#1 */ select 1 AS `a` union /* select#2 */ select 2 AS `2` order by `a`;
+a
+1
+2
+explain extended
+/* select#1 */ select 1 AS `a` union /* select#2 */ select 2 AS `2` order by `a`;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL Using filesort
+Warnings:
+Note 1003 /* select#1 */ select 1 AS `a` union /* select#2 */ select 2 AS `2` order by `a`
+select 1 union ( select 1 union (select 1 union (select 1 union select 1)));
+1
+1
+explain extended all
+select 1 union ( select 1 union (select 1 union (select 1 union select 1)));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+8 UNION <derived2> ALL NULL NULL NULL NULL 2 100.00
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+7 UNION <derived3> ALL NULL NULL NULL NULL 2 100.00
+3 DERIVED 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 <union4,5> ALL NULL NULL NULL NULL NULL NULL
+NULL UNION RESULT <union3,6> ALL NULL NULL NULL NULL NULL NULL
+NULL UNION RESULT <union2,7> ALL NULL NULL NULL NULL NULL NULL
+NULL UNION RESULT <union1,8> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 /* select#1/0 Filter Select: select `1` AS `1` */ select 1 AS `1` union /* select#8/0 */ select `__8`.`1` AS `1` from (/* select#2/1 Filter Select: select `1` AS `1` */ select 1 AS `1` union /* select#7/1 */ select `__7`.`1` AS `1` from (/* select#3/2 Filter Select: select `1` AS `1` */ select 1 AS `1` union /* select#6/2 */ select `__6`.`1` AS `1` from (/* select#4/3 Filter Select: select `1` AS `1` */ select 1 AS `1` union /* select#5/3 */ select 1 AS `1`) `__6`) `__7`) `__8`
+#
+# MDEV-6341: INSERT ... SELECT UNION with parenthesis
+#
+create table t1 (a int, b int);
+insert into t1 (select 1,1 union select 2,2);
+select * from t1 order by 1;
+a b
+1 1
+2 2
+delete from t1;
+insert into t1 select 1,1 union select 2,2;
+select * from t1 order by 1;
+a b
+1 1
+2 2
+drop table t1;
+CREATE OR REPLACE TABLE t1 AS SELECT 1 AS a UNION SELECT 2;
+select * from t1 order by 1;
+a
+1
+2
+drop table t1;
+CREATE OR REPLACE TABLE t1 AS (SELECT 1 AS a UNION SELECT 2);
+select * from t1 order by 1;
+a
+1
+2
+drop table t1;
+CREATE OR REPLACE VIEW v1 AS (SELECT 1 AS a);
+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 1 AS `a`) latin1 latin1_swedish_ci
+drop view v1;
+CREATE OR REPLACE VIEW v1 AS SELECT 1 AS a UNION SELECT 2;
+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 1 AS `a` union select 2 AS `2` latin1 latin1_swedish_ci
+drop view v1;
+CREATE OR REPLACE VIEW v1 AS (SELECT 1 AS a UNION SELECT 2);
+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 1 AS `a` union select 2 AS `2` latin1 latin1_swedish_ci
+drop view v1;
+#
+# MDEV-10028: Syntax error on ((SELECT ...) UNION (SELECT ...))
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (10);
+INSERT INTO t1 VALUES (20);
+INSERT INTO t1 VALUES (30);
+((SELECT a FROM t1) UNION (SELECT a FROM t1));
+a
+10
+20
+30
+(SELECT * FROM t1 UNION SELECT * FROM t1);
+a
+10
+20
+30
+((SELECT a FROM t1) LIMIT 1);
+a
+10
+SELECT * FROM (SELECT 1 UNION (SELECT 2 UNION SELECT 3)) t1;
+1
+1
+2
+3
+DROP TABLE t1;
+# End of 10.4 tests
diff --git a/mysql-test/main/brackets.test b/mysql-test/main/brackets.test
new file mode 100644
index 00000000000..d3477f501a1
--- /dev/null
+++ b/mysql-test/main/brackets.test
@@ -0,0 +1,69 @@
+select 1 union ( select 2 union select 3);
+explain extended
+select 1 union ( select 2 union select 3);
+select 1 union ( select 1 union select 1);
+explain extended
+select 1 union ( select 1 union select 1);
+select 1 union all ( select 1 union select 1);
+explain extended
+select 1 union all ( select 1 union select 1);
+select 1 union ( select 1 union all select 1);
+explain extended
+select 1 union ( select 1 union all select 1);
+select 1 union select 1 union all select 1;
+explain extended
+select 1 union select 1 union all select 1;
+
+(select 1 as a) union (select 2) order by a;
+explain extended
+(select 1 as a) union (select 2) order by a;
+/* select#1 */ select 1 AS `a` union /* select#2 */ select 2 AS `2` order by `a`;
+explain extended
+/* select#1 */ select 1 AS `a` union /* select#2 */ select 2 AS `2` order by `a`;
+
+select 1 union ( select 1 union (select 1 union (select 1 union select 1)));
+explain extended all
+select 1 union ( select 1 union (select 1 union (select 1 union select 1)));
+
+--echo #
+--echo # MDEV-6341: INSERT ... SELECT UNION with parenthesis
+--echo #
+create table t1 (a int, b int);
+insert into t1 (select 1,1 union select 2,2);
+select * from t1 order by 1;
+delete from t1;
+insert into t1 select 1,1 union select 2,2;
+select * from t1 order by 1;
+drop table t1;
+CREATE OR REPLACE TABLE t1 AS SELECT 1 AS a UNION SELECT 2;
+select * from t1 order by 1;
+drop table t1;
+CREATE OR REPLACE TABLE t1 AS (SELECT 1 AS a UNION SELECT 2);
+select * from t1 order by 1;
+drop table t1;
+CREATE OR REPLACE VIEW v1 AS (SELECT 1 AS a);
+show create view v1;
+drop view v1;
+CREATE OR REPLACE VIEW v1 AS SELECT 1 AS a UNION SELECT 2;
+show create view v1;
+drop view v1;
+CREATE OR REPLACE VIEW v1 AS (SELECT 1 AS a UNION SELECT 2);
+show create view v1;
+drop view v1;
+
+
+--echo #
+--echo # MDEV-10028: Syntax error on ((SELECT ...) UNION (SELECT ...))
+--echo #
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (10);
+INSERT INTO t1 VALUES (20);
+INSERT INTO t1 VALUES (30);
+
+((SELECT a FROM t1) UNION (SELECT a FROM t1));
+(SELECT * FROM t1 UNION SELECT * FROM t1);
+((SELECT a FROM t1) LIMIT 1);
+SELECT * FROM (SELECT 1 UNION (SELECT 2 UNION SELECT 3)) t1;
+DROP TABLE t1;
+
+--echo # End of 10.4 tests
diff --git a/mysql-test/main/cte_nonrecursive.result b/mysql-test/main/cte_nonrecursive.result
index 534a386fe12..89ffd94f9f7 100644
--- a/mysql-test/main/cte_nonrecursive.result
+++ b/mysql-test/main/cte_nonrecursive.result
@@ -418,10 +418,10 @@ t2.c in (with t as (select * from t1 where t1.a<5)
select t2.c from t2,t where t2.c=t.a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 4
-1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
-2 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where
-2 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
+3 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where
+3 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
explain
select t1.a,t1.b from t1,t2
where t1.a>t2.c and
@@ -461,10 +461,10 @@ t.c in (with t as (select * from t1 where t1.a<5)
select t2.c from t2,t where t2.c=t.a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where
-1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1
+1 PRIMARY <subquery4> eq_ref distinct_key distinct_key 4 func 1
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
-3 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where
-3 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
+4 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where
+4 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
explain
select t1.a,t1.b from t1, (select c from t2 where c >= 4) as t
where t1.a=t.c and
@@ -507,9 +507,9 @@ select t.a, count(*) from t1,t where t1.a=t.a group by t.a;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
-1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 35 func 1
-3 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where
-3 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY <subquery4> eq_ref distinct_key distinct_key 35 func 1
+4 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where
+4 MATERIALIZED t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
explain
select t.a, count(*)
from t1,
@@ -597,8 +597,8 @@ explain
select * from v2;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where
-1 PRIMARY <derived3> ref key0 key0 5 test.t2.c 2
-3 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.c 2
+2 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort
# with clause in the specification of a view that whose definition
# table alias for a with table
create view v3 as
@@ -863,8 +863,8 @@ SELECT * FROM (WITH a AS (SELECT * FROM t1) SELECT 1) AS t1;
1
EXPLAIN SELECT * FROM (WITH a AS (SELECT * FROM t1) SELECT 1) AS t1;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 1
-2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
+1 PRIMARY <derived3> system NULL NULL NULL NULL 1
+3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
DROP TABLE t1;
#
# MDEV-10058: Suspicious EXPLAIN output for a derived table + WITH + joined table
@@ -1116,17 +1116,17 @@ select * from cte_e as cte_e1 where a > 1
union
select * from cte_e as cte_e2;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY <derived2> ALL NULL NULL NULL NULL 14 100.00 Using where
-2 DERIVED t1 ALL NULL NULL NULL NULL 7 100.00 Using where
+1 PRIMARY <derived4> ALL NULL NULL NULL NULL 14 100.00 Using where
+4 DERIVED t1 ALL NULL NULL NULL NULL 7 100.00 Using where
5 UNION t1 ALL NULL NULL NULL NULL 7 100.00 Using where
-NULL UNION RESULT <union2,5> ALL NULL NULL NULL NULL NULL NULL
-6 UNION <derived9> ALL NULL NULL NULL NULL 14 100.00
-9 DERIVED t1 ALL NULL NULL NULL NULL 7 100.00 Using where
+NULL UNION RESULT <union4,5> ALL NULL NULL NULL NULL NULL NULL
+6 UNION <derived11> ALL NULL NULL NULL NULL 14 100.00
+11 DERIVED t1 ALL NULL NULL NULL NULL 7 100.00 Using where
12 UNION t1 ALL NULL NULL NULL NULL 7 100.00 Using where
-NULL UNION RESULT <union9,12> ALL NULL NULL NULL NULL NULL NULL
+NULL UNION RESULT <union11,12> ALL NULL NULL NULL NULL NULL NULL
NULL UNION RESULT <union1,6> ALL NULL NULL NULL NULL NULL NULL
Warnings:
-Note 1003 with cte_e as (with cte_o as (with cte_i as (/* select#4 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 7)/* select#3 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 1)/* select#2 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 3 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 and `test`.`t1`.`a` > 1 union /* select#5 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 4 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 and `test`.`t1`.`a` > 1)/* select#1 */ select `cte_e1`.`a` AS `a` from `cte_e` `cte_e1` where `cte_e1`.`a` > 1 union /* select#6 */ select `cte_e2`.`a` AS `a` from (with cte_o as (with cte_i as (/* select#11 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 7)/* select#10 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 1)/* select#9 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a`
< 3 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 union /* select#12 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 4 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7) `cte_e2`
+Note 1003 with cte_e as (with cte_o as (with cte_i as (select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 7)select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 1)select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 3 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 and `test`.`t1`.`a` > 1 union select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 4 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 and `test`.`t1`.`a` > 1)select `cte_e1`.`a` AS `a` from `cte_e` `cte_e1` where `cte_e1`.`a` > 1 union select `cte_e2`.`a` AS `a` from (with cte_o as (with cte_i as (select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 7)select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 1)select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 3 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 union select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 4 and `
test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7) `cte_e2`
drop table t1;
#
# MDEV-13753: embedded CTE in a VIEW created in prepared statement
diff --git a/mysql-test/main/deadlock_innodb.result b/mysql-test/main/deadlock_innodb.result
index af78a6aa9d5..fca0ff6be0c 100644
--- a/mysql-test/main/deadlock_innodb.result
+++ b/mysql-test/main/deadlock_innodb.result
@@ -72,7 +72,7 @@ insert into t1 values(0, 0), (300, 300);
insert into t2 values(0, 0), (1, 20), (2, 30);
commit;
connection con1;
-select a,b from t2 UNION SELECT id, x from t1 FOR UPDATE;
+select a,b from t2 UNION (SELECT id, x from t1 FOR UPDATE);
a b
0 0
20 1
diff --git a/mysql-test/main/derived_cond_pushdown.result b/mysql-test/main/derived_cond_pushdown.result
index 6887ad11284..353ae9d804f 100644
--- a/mysql-test/main/derived_cond_pushdown.result
+++ b/mysql-test/main/derived_cond_pushdown.result
@@ -8935,7 +8935,7 @@ EXPLAIN
"access_type": "ALL",
"rows": 18,
"filtered": 100,
- "attached_condition": "__3.a > 5 and __3.c > 200",
+ "attached_condition": "__5.a > 5 and __5.c > 200",
"materialized": {
"query_block": {
"union_result": {
@@ -9561,7 +9561,7 @@ EXPLAIN
"access_type": "ALL",
"rows": 18,
"filtered": 100,
- "attached_condition": "__3.a > 4 and __3.c < 130",
+ "attached_condition": "__5.a > 4 and __5.c < 130",
"materialized": {
"query_block": {
"union_result": {
@@ -9707,7 +9707,7 @@ EXPLAIN
"access_type": "ALL",
"rows": 18,
"filtered": 100,
- "attached_condition": "__3.a > 4 and __3.c < 130",
+ "attached_condition": "__6.a > 4 and __6.c < 130",
"materialized": {
"query_block": {
"union_result": {
diff --git a/mysql-test/main/except.result b/mysql-test/main/except.result
index 594bb7118eb..23da19d46e3 100644
--- a/mysql-test/main/except.result
+++ b/mysql-test/main/except.result
@@ -24,7 +24,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
{
@@ -229,7 +229,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
{
@@ -500,7 +500,7 @@ a
(select 1 from dual) except (select 1 from dual);
1
(select 1 from dual into @v) except (select 1 from dual);
-ERROR HY000: Incorrect usage of EXCEPT and INTO
+ERROR 42000: Incorrect usage/placement of 'INTO'
select 1 from dual ORDER BY 1 except 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 select 1 from dual' at line 1
select 1 as a from dual union all select 1 from dual;
@@ -508,7 +508,7 @@ a
1
1
select 1 from dual except all select 1 from dual;
-ERROR HY000: Incorrect usage of EXCEPT and ALL
+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 t2 (c int, d blob, c1 int, d1 blob) engine=MyISAM;
insert into t1 values (1,"ddd", 1, "sdfrrwwww"),(2, "fgh", 2, "dffggtt");
diff --git a/mysql-test/main/except.test b/mysql-test/main/except.test
index f88d9b29e35..cd672ae6fbd 100644
--- a/mysql-test/main/except.test
+++ b/mysql-test/main/except.test
@@ -60,13 +60,13 @@ drop tables t1,t2,t3,t4;
select 1 as a from dual except select 1 from dual;
(select 1 from dual) except (select 1 from dual);
---error ER_WRONG_USAGE
+--error ER_CANT_USE_OPTION_HERE
(select 1 from dual into @v) except (select 1 from dual);
--error ER_PARSE_ERROR
select 1 from dual ORDER BY 1 except select 1 from dual;
select 1 as a from dual union all select 1 from dual;
---error ER_WRONG_USAGE
+--error ER_PARSE_ERROR
select 1 from dual except all select 1 from dual;
diff --git a/mysql-test/main/fulltext_order_by.result b/mysql-test/main/fulltext_order_by.result
index c2f57c6f9c2..a350a55c75d 100644
--- a/mysql-test/main/fulltext_order_by.result
+++ b/mysql-test/main/fulltext_order_by.result
@@ -126,7 +126,7 @@ group by
a.text, b.id, b.betreff
order by
match(b.betreff) against ('+abc' in boolean mode) desc;
-ERROR 42000: Table 'b' from one of the SELECTs cannot be used in field list
+ERROR 42000: Table 'b' from one of the SELECTs cannot be used in ORDER clause
select a.text, b.id, b.betreff
from
t2 a inner join t3 b on a.id = b.forum inner join
@@ -142,7 +142,7 @@ where
match(c.beitrag) against ('+abc' in boolean mode)
order by
match(b.betreff) against ('+abc' in boolean mode) desc;
-ERROR 42000: Table 'b' from one of the SELECTs cannot be used in field list
+ERROR 42000: Table 'b' from one of the SELECTs cannot be used in ORDER clause
select a.text, b.id, b.betreff
from
t2 a inner join t3 b on a.id = b.forum inner join
diff --git a/mysql-test/main/func_analyse.result b/mysql-test/main/func_analyse.result
index 1e78e603bca..68ceb8aed02 100644
--- a/mysql-test/main/func_analyse.result
+++ b/mysql-test/main/func_analyse.result
@@ -19,7 +19,7 @@ test.t1.empty_string 0 0 4 0 0.0000 NULL CHAR(0) NOT NULL
test.t1.bool N Y 1 1 0 0 1.0000 NULL ENUM('N','Y') NOT NULL
test.t1.d 2002-03-03 2002-03-05 10 10 0 0 10.0000 NULL ENUM('2002-03-03','2002-03-04','2002-03-05') NOT NULL
create table t2 select * from t1 procedure analyse();
-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 'procedure analyse()' at line 1
+ERROR 42000: Incorrect usage/placement of 'PROCEDURE'
drop table t1;
EXPLAIN SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE();
ERROR HY000: Incorrect usage of PROCEDURE and subquery
@@ -120,7 +120,7 @@ CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES (1),(2);
# should not crash
CREATE TABLE t2 SELECT 1 FROM t1, t1 t3 GROUP BY t3.a PROCEDURE ANALYSE();
-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 'PROCEDURE ANALYSE()' at line 1
+ERROR 42000: Incorrect usage/placement of 'PROCEDURE'
DROP TABLE t1;
End of 5.0 tests
#
@@ -158,16 +158,24 @@ Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_
((SELECT 1 FROM DUAL PROCEDURE ANALYSE()));
Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
1 1 1 1 1 0 0 1.0000 0.0000 ENUM('1') NOT NULL
+(SELECT 1 FROM DUAL) PROCEDURE ANALYSE();
+Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
+1 1 1 1 1 0 0 1.0000 0.0000 ENUM('1') NOT NULL
+((SELECT 1 FROM DUAL)) PROCEDURE ANALYSE();
+Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_value_or_avg_length Std Optimal_fieldtype
+1 1 1 1 1 0 0 1.0000 0.0000 ENUM('1') NOT NULL
+create table t1 (a int);
SELECT * FROM t1 UNION SELECT * FROM t1 PROCEDURE analyse();
-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 'PROCEDURE analyse()' at line 1
+ERROR 42000: Incorrect usage/placement of 'PROCEDURE'
+drop table t1;
#
# MDEV-10030 sql_yacc.yy: Split table_expression and remove PROCEDURE from create_select, select_paren_derived, select_derived2, query_specification
#
SELECT * FROM (SELECT * FROM t1 PROCEDURE ANALYSE());
-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 'PROCEDURE ANALYSE())' 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 * FROM t1 NATURAL JOIN (SELECT * FROM t2 PROCEDURE ANALYSE());
-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 'PROCEDURE ANALYSE())' 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 FROM t1 PROCEDURE ANALYSE()) FROM t2;
-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 'PROCEDURE ANALYSE()) FROM t2' at line 1
+ERROR 42000: Incorrect usage/placement of 'PROCEDURE'
SELECT ((SELECT 1 FROM t1 PROCEDURE ANALYSE())) FROM t2;
-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 'PROCEDURE ANALYSE())) FROM t2' at line 1
+ERROR 42000: Incorrect usage/placement of 'PROCEDURE'
diff --git a/mysql-test/main/func_analyse.test b/mysql-test/main/func_analyse.test
index d99f5c0fa9a..24fdd9a10e2 100644
--- a/mysql-test/main/func_analyse.test
+++ b/mysql-test/main/func_analyse.test
@@ -11,7 +11,7 @@ insert into t1 values (1,2,"","Y","2002-03-03"), (3,4,"","N","2002-03-04"), (5,6
select count(*) from t1 procedure analyse();
select * from t1 procedure analyse();
select * from t1 procedure analyse(2);
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
create table t2 select * from t1 procedure analyse();
drop table t1;
@@ -127,7 +127,7 @@ CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES (1),(2);
--echo # should not crash
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
CREATE TABLE t2 SELECT 1 FROM t1, t1 t3 GROUP BY t3.a PROCEDURE ANALYSE();
DROP TABLE t1;
@@ -161,12 +161,17 @@ DROP TABLE t1, t2;
--echo #
--echo # Start of 10.2 tests
--echo #
+# --error ER_PARSE_ERROR
(SELECT 1 FROM DUAL PROCEDURE ANALYSE());
+# --error ER_PARSE_ERROR
((SELECT 1 FROM DUAL PROCEDURE ANALYSE()));
+(SELECT 1 FROM DUAL) PROCEDURE ANALYSE();
+((SELECT 1 FROM DUAL)) PROCEDURE ANALYSE();
-# TODO:
---error ER_PARSE_ERROR
+create table t1 (a int);
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM t1 UNION SELECT * FROM t1 PROCEDURE analyse();
+drop table t1;
--echo #
--echo # MDEV-10030 sql_yacc.yy: Split table_expression and remove PROCEDURE from create_select, select_paren_derived, select_derived2, query_specification
@@ -177,7 +182,7 @@ SELECT * FROM (SELECT * FROM t1 PROCEDURE ANALYSE());
--ERROR ER_PARSE_ERROR
SELECT * FROM t1 NATURAL JOIN (SELECT * FROM t2 PROCEDURE ANALYSE());
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT (SELECT 1 FROM t1 PROCEDURE ANALYSE()) FROM t2;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT ((SELECT 1 FROM t1 PROCEDURE ANALYSE())) FROM t2;
diff --git a/mysql-test/main/intersect.result b/mysql-test/main/intersect.result
index b589e8bd17e..b74c7ecbe0c 100644
--- a/mysql-test/main/intersect.result
+++ b/mysql-test/main/intersect.result
@@ -37,7 +37,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
{
@@ -278,7 +278,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`
EXPLAIN format=json (select a,b from t1) intersect (select c,e from t2,t3);
EXPLAIN
{
@@ -497,7 +497,7 @@ a
1
1
(select 1 from dual into @v) intersect (select 1 from dual);
-ERROR HY000: Incorrect usage of INTERSECT and INTO
+ERROR 42000: Incorrect usage/placement of 'INTO'
select 1 from dual ORDER BY 1 intersect 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 select 1 from dual' at line 1
select 1 as a from dual union all select 1 from dual;
@@ -505,7 +505,7 @@ a
1
1
select 1 from dual intersect all select 1 from dual;
-ERROR HY000: Incorrect usage of INTERSECT and ALL
+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 t2 (c int, d blob, c1 int, d1 blob);
insert into t1 values (1,"ddd", 1, "sdfrrwwww"),(2, "fgh", 2, "dffggtt");
@@ -599,14 +599,14 @@ 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
-3 UNION <derived2> 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
-4 INTERSECT t3 ALL NULL NULL NULL NULL 2 100.00
-NULL INTERSECT RESULT <intersect2,4> ALL NULL NULL NULL NULL NULL NULL
-5 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
-NULL UNION RESULT <union1,3,5> ALL NULL NULL NULL NULL NULL NULL
+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
+NULL UNION RESULT <union1,5,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#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`)
+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`)
(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
@@ -686,7 +686,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 `__3`.`c` AS `c`,`__3`.`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`)) `__3` 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;
#
diff --git a/mysql-test/main/intersect.test b/mysql-test/main/intersect.test
index d9d420c786b..72e6c3d632f 100644
--- a/mysql-test/main/intersect.test
+++ b/mysql-test/main/intersect.test
@@ -59,13 +59,13 @@ drop tables t1,t2,t3;
select 1 as a from dual intersect select 1 from dual;
(select 1 from dual) intersect (select 1 from dual);
---error ER_WRONG_USAGE
+--error ER_CANT_USE_OPTION_HERE
(select 1 from dual into @v) intersect (select 1 from dual);
--error ER_PARSE_ERROR
select 1 from dual ORDER BY 1 intersect select 1 from dual;
select 1 as a from dual union all select 1 from dual;
---error ER_WRONG_USAGE
+--error ER_PARSE_ERROR
select 1 from dual intersect all select 1 from dual;
diff --git a/mysql-test/main/join.result b/mysql-test/main/join.result
index 046674d5569..5978b261b3a 100644
--- a/mysql-test/main/join.result
+++ b/mysql-test/main/join.result
@@ -1484,7 +1484,7 @@ DROP TABLE t1,t2,t3,t4,t5;
# MDEV-4752: Segfault during parsing of illegal query
#
SELECT * FROM t5 JOIN (t1 JOIN t2 UNION SELECT * FROM t3 JOIN t4);
-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 'SELECT * FROM t3 JOIN t4)' 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 'UNION SELECT * FROM t3 JOIN t4)' at line 1
#
# MDEV-4959: join of const table with NULL fields
#
diff --git a/mysql-test/main/join_nested.result b/mysql-test/main/join_nested.result
index 708c72fffb5..b6b4716d8b1 100644
--- a/mysql-test/main/join_nested.result
+++ b/mysql-test/main/join_nested.result
@@ -1150,7 +1150,7 @@ a b a b
4 2 2 2
5 3 NULL NULL
SELECT t2.a,t2.b,t3.a,t3.b
-FROM t2 LEFT JOIN (t3) ON t2.b=t3.b
+FROM t2 LEFT JOIN t3 ON t2.b=t3.b
WHERE t2.a = 4 OR (t2.a > 4 AND t3.a IS NULL);
a b a b
4 2 1 2
diff --git a/mysql-test/main/join_nested.test b/mysql-test/main/join_nested.test
index e60b7827f75..77d0e4154c1 100644
--- a/mysql-test/main/join_nested.test
+++ b/mysql-test/main/join_nested.test
@@ -683,7 +683,7 @@ SELECT t2.a,t2.b,t3.a,t3.b
WHERE t2.a = 4 OR (t2.a > 4 AND t3.a IS NULL);
SELECT t2.a,t2.b,t3.a,t3.b
- FROM t2 LEFT JOIN (t3) ON t2.b=t3.b
+ FROM t2 LEFT JOIN t3 ON t2.b=t3.b
WHERE t2.a = 4 OR (t2.a > 4 AND t3.a IS NULL);
ALTER TABLE t3
diff --git a/mysql-test/main/join_nested_jcl6.result b/mysql-test/main/join_nested_jcl6.result
index eb59531b7d2..de5ebfbe989 100644
--- a/mysql-test/main/join_nested_jcl6.result
+++ b/mysql-test/main/join_nested_jcl6.result
@@ -1161,7 +1161,7 @@ a b a b
4 2 2 2
5 3 NULL NULL
SELECT t2.a,t2.b,t3.a,t3.b
-FROM t2 LEFT JOIN (t3) ON t2.b=t3.b
+FROM t2 LEFT JOIN t3 ON t2.b=t3.b
WHERE t2.a = 4 OR (t2.a > 4 AND t3.a IS NULL);
a b a b
4 2 1 2
diff --git a/mysql-test/main/parser.result b/mysql-test/main/parser.result
index a1c6e86a129..fd18b74be32 100644
--- a/mysql-test/main/parser.result
+++ b/mysql-test/main/parser.result
@@ -705,6 +705,9 @@ FOR UPDATE;
1
1
SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
+PROCEDURE ANALYSE();
+ERROR HY000: Can't use ORDER clause with this procedure
+SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
PROCEDURE ANALYSE() FOR UPDATE;
ERROR HY000: Can't use ORDER clause with this procedure
SELECT 1 FROM
@@ -715,7 +718,7 @@ FOR UPDATE) a;
SELECT 1 FROM
(SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
PROCEDURE ANALYSE() FOR UPDATE) a;
-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 'PROCEDURE ANALYSE() FOR UPDATE) a' at line 3
+ERROR 42000: Incorrect usage/placement of 'PROCEDURE'
SELECT 1 FROM t1
WHERE EXISTS(SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
FOR UPDATE);
@@ -723,7 +726,7 @@ FOR UPDATE);
SELECT 1 FROM t1
WHERE EXISTS(SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
PROCEDURE ANALYSE() FOR UPDATE);
-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 'PROCEDURE ANALYSE() FOR UPDATE)' at line 3
+ERROR 42000: Incorrect usage/placement of 'PROCEDURE'
SELECT 1 FROM t1
UNION
SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
@@ -734,7 +737,7 @@ SELECT 1 FROM t1
UNION
SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
PROCEDURE ANALYSE() FOR UPDATE;
-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 'PROCEDURE ANALYSE() FOR UPDATE' at line 4
+ERROR 42000: Incorrect usage/placement of 'PROCEDURE'
SELECT 1 FROM DUAL PROCEDURE ANALYSE()
UNION
SELECT 1 FROM t1;
@@ -750,11 +753,11 @@ FOR UPDATE);
UNION
(SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
PROCEDURE ANALYSE() FOR UPDATE);
-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 'PROCEDURE ANALYSE() FOR UPDATE)' at line 4
+ERROR 42000: Incorrect usage/placement of 'PROCEDURE'
# "FOR UPDATE" tests
SELECT 1 FROM t1 UNION SELECT 1 FROM t1 ORDER BY 1 LIMIT 1;
1
-SELECT 1 FROM t1 FOR UPDATE UNION SELECT 1 FROM t1 ORDER BY 1 LIMIT 1;
+(SELECT 1 FROM t1 FOR UPDATE) UNION SELECT 1 FROM t1 ORDER BY 1 LIMIT 1;
1
SELECT 1 FROM t1 UNION SELECT 1 FROM t1 ORDER BY 1 LIMIT 1 FOR UPDATE;
1
@@ -769,10 +772,10 @@ Warnings:
Warning 1329 No data - zero rows fetched, selected, or processed
SELECT 1 INTO @var17727401 FROM DUAL;
SELECT 1 INTO @var17727401_1 FROM t1 INTO @var17727401_2;
-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 @var17727401_2' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT 1 INTO @var17727401_1 FROM DUAL
INTO @var17727401_2;
-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 @var17727401_2' at line 2
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT 1 INTO @var17727401 FROM t1 WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 LIMIT 1;
Warnings:
Warning 1329 No data - zero rows fetched, selected, or processed
@@ -784,41 +787,29 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp
SELECT 1 INTO @var17727401_1
FROM t1 WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 LIMIT 1
INTO @var17727401_2;
-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 @var17727401_2' at line 3
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT (SELECT 1 FROM t1 INTO @var17727401);
-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 @var17727401)' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT 1 FROM (SELECT 1 FROM t1 INTO @var17727401) a;
-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 @var17727401) a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT EXISTS(SELECT 1 FROM t1 INTO @var17727401);
-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 @var17727401)' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT 1 FROM t1 INTO @var17727401 UNION SELECT 1 FROM t1 INTO 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 1 FROM t1 INTO t1' at line 1
(SELECT 1 FROM t1 INTO @var17727401) UNION (SELECT 1 FROM t1 INTO t1);
-ERROR HY000: Incorrect usage of UNION and INTO
+ERROR 42000: Undeclared variable: t1
SELECT 1 FROM t1 UNION SELECT 1 FROM t1 INTO @var17727401;
Warnings:
Warning 1329 No data - zero rows fetched, selected, or processed
SELECT 1 INTO @var17727401 FROM t1 PROCEDURE ANALYSE();
-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 'PROCEDURE ANALYSE()' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT 1 FROM t1 PROCEDURE ANALYSE() INTO @var17727401;
-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 @var17727401' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
# ORDER and LIMIT clause combinations
-(SELECT 1 FROM t1 ORDER BY 1) ORDER BY 1;
-1
-(SELECT 1 FROM t1 LIMIT 1) LIMIT 1;
-1
-((SELECT 1 FROM t1 ORDER BY 1) ORDER BY 1) ORDER BY 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 'ORDER BY 1) ORDER BY 1' at line 1
-((SELECT 1 FROM t1 LIMIT 1) LIMIT 1) LIMIT 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 'LIMIT 1) LIMIT 1' at line 1
-(SELECT 1 FROM t1 ORDER BY 1) LIMIT 1;
-1
-(SELECT 1 FROM t1 LIMIT 1) ORDER BY 1;
-1
((SELECT 1 FROM t1 ORDER BY 1) LIMIT 1) ORDER BY 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 'LIMIT 1) ORDER BY 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 1 FROM t1 LIMIT 1) ORDER BY 1) LIMIT 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 'ORDER BY 1) LIMIT 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 1 FROM t1 UNION SELECT 1 FROM t1 ORDER BY 1;
1
SELECT (SELECT 1 FROM t1 UNION SELECT 1 FROM t1 ORDER BY 1);
@@ -1265,19 +1256,19 @@ CREATE TABLE t1 (i INT);
(SELECT * FROM t1 PROCEDURE ANALYSE(10, 10))
UNION
(SELECT * FROM t1 PROCEDURE ANALYSE(10, 10));
-ERROR HY000: Incorrect usage of UNION and SELECT ... PROCEDURE ANALYSE()
+ERROR 42000: Incorrect usage/placement of 'PROCEDURE'
(SELECT * FROM t1 PROCEDURE ANALYSE(10, 10))
UNION
SELECT * FROM t1 PROCEDURE ANALYSE(10, 10);
-ERROR HY000: Incorrect usage of UNION and SELECT ... PROCEDURE ANALYSE()
+ERROR 42000: Incorrect usage/placement of 'PROCEDURE'
(SELECT * FROM t1 PROCEDURE ANALYSE(10, 10))
UNION
(SELECT 1);
-ERROR HY000: Incorrect usage of UNION and SELECT ... PROCEDURE ANALYSE()
+ERROR 42000: Incorrect usage/placement of 'PROCEDURE'
(SELECT * FROM t1 PROCEDURE ANALYSE(10, 10))
UNION
SELECT 1;
-ERROR HY000: Incorrect usage of UNION and SELECT ... PROCEDURE ANALYSE()
+ERROR 42000: Incorrect usage/placement of 'PROCEDURE'
SELECT * FROM t1 PROCEDURE ANALYSE(10, 10)
UNION
(SELECT * FROM t1 PROCEDURE ANALYSE(10, 10));
diff --git a/mysql-test/main/parser.test b/mysql-test/main/parser.test
index 1f176c6afc5..e9c10159260 100644
--- a/mysql-test/main/parser.test
+++ b/mysql-test/main/parser.test
@@ -825,6 +825,9 @@ SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
FOR UPDATE;
--error ER_ORDER_WITH_PROC
+SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
+ PROCEDURE ANALYSE();
+--error ER_ORDER_WITH_PROC
SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
PROCEDURE ANALYSE() FOR UPDATE;
@@ -832,7 +835,7 @@ SELECT 1 FROM
(SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
FOR UPDATE) a;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT 1 FROM
(SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
PROCEDURE ANALYSE() FOR UPDATE) a;
@@ -841,7 +844,7 @@ SELECT 1 FROM t1
WHERE EXISTS(SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
FOR UPDATE);
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT 1 FROM t1
WHERE EXISTS(SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
PROCEDURE ANALYSE() FOR UPDATE);
@@ -851,7 +854,7 @@ UNION
SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
FOR UPDATE;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT 1 FROM t1
UNION
SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
@@ -867,7 +870,7 @@ UNION
(SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
FOR UPDATE);
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
(SELECT 1 FROM t1)
UNION
(SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
@@ -876,7 +879,7 @@ UNION
--echo # "FOR UPDATE" tests
SELECT 1 FROM t1 UNION SELECT 1 FROM t1 ORDER BY 1 LIMIT 1;
-SELECT 1 FROM t1 FOR UPDATE UNION SELECT 1 FROM t1 ORDER BY 1 LIMIT 1;
+(SELECT 1 FROM t1 FOR UPDATE) UNION SELECT 1 FROM t1 ORDER BY 1 LIMIT 1;
SELECT 1 FROM t1 UNION SELECT 1 FROM t1 ORDER BY 1 LIMIT 1 FOR UPDATE;
@@ -889,10 +892,10 @@ SELECT 1 INTO @var17727401;
SELECT 1 INTO @var17727401 FROM t1;
SELECT 1 INTO @var17727401 FROM DUAL;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT 1 INTO @var17727401_1 FROM t1 INTO @var17727401_2;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT 1 INTO @var17727401_1 FROM DUAL
INTO @var17727401_2;
@@ -902,45 +905,45 @@ SELECT 1 FROM t1 WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 LIMIT 1 INTO @var1772740
--error ER_PARSE_ERROR
SELECT 1 FROM t1 WHERE 1 INTO @var17727401 GROUP BY 1 HAVING 1 ORDER BY 1 LIMIT 1;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT 1 INTO @var17727401_1
FROM t1 WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 LIMIT 1
INTO @var17727401_2;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT (SELECT 1 FROM t1 INTO @var17727401);
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT 1 FROM (SELECT 1 FROM t1 INTO @var17727401) a;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT EXISTS(SELECT 1 FROM t1 INTO @var17727401);
--error ER_PARSE_ERROR
SELECT 1 FROM t1 INTO @var17727401 UNION SELECT 1 FROM t1 INTO t1;
---error ER_WRONG_USAGE
+--error ER_SP_UNDECLARED_VAR
(SELECT 1 FROM t1 INTO @var17727401) UNION (SELECT 1 FROM t1 INTO t1);
SELECT 1 FROM t1 UNION SELECT 1 FROM t1 INTO @var17727401;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT 1 INTO @var17727401 FROM t1 PROCEDURE ANALYSE();
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT 1 FROM t1 PROCEDURE ANALYSE() INTO @var17727401;
--echo # ORDER and LIMIT clause combinations
# Limited support for (SELECT ...) ORDER/LIMIT:
-(SELECT 1 FROM t1 ORDER BY 1) ORDER BY 1;
-(SELECT 1 FROM t1 LIMIT 1) LIMIT 1;
+# (SELECT 1 FROM t1 ORDER BY 1) ORDER BY 1;
+# (SELECT 1 FROM t1 LIMIT 1) LIMIT 1;
---error ER_PARSE_ERROR
-((SELECT 1 FROM t1 ORDER BY 1) ORDER BY 1) ORDER BY 1;
---error ER_PARSE_ERROR
-((SELECT 1 FROM t1 LIMIT 1) LIMIT 1) LIMIT 1;
+#--error ER_PARSE_ERROR
+# ((SELECT 1 FROM t1 ORDER BY 1) ORDER BY 1) ORDER BY 1;
+#--error ER_PARSE_ERROR
+# ((SELECT 1 FROM t1 LIMIT 1) LIMIT 1) LIMIT 1;
-(SELECT 1 FROM t1 ORDER BY 1) LIMIT 1;
-(SELECT 1 FROM t1 LIMIT 1) ORDER BY 1;
+# (SELECT 1 FROM t1 ORDER BY 1) LIMIT 1;
+# (SELECT 1 FROM t1 LIMIT 1) ORDER BY 1;
--error ER_PARSE_ERROR
((SELECT 1 FROM t1 ORDER BY 1) LIMIT 1) ORDER BY 1);
@@ -1276,22 +1279,22 @@ DROP TABLE t1;
--echo #
CREATE TABLE t1 (i INT);
---error ER_WRONG_USAGE
+--error ER_CANT_USE_OPTION_HERE
(SELECT * FROM t1 PROCEDURE ANALYSE(10, 10))
UNION
(SELECT * FROM t1 PROCEDURE ANALYSE(10, 10));
---error ER_WRONG_USAGE
+--error ER_CANT_USE_OPTION_HERE
(SELECT * FROM t1 PROCEDURE ANALYSE(10, 10))
UNION
SELECT * FROM t1 PROCEDURE ANALYSE(10, 10);
---error ER_WRONG_USAGE
+--error ER_CANT_USE_OPTION_HERE
(SELECT * FROM t1 PROCEDURE ANALYSE(10, 10))
UNION
(SELECT 1);
---error ER_WRONG_USAGE
+--error ER_CANT_USE_OPTION_HERE
(SELECT * FROM t1 PROCEDURE ANALYSE(10, 10))
UNION
SELECT 1;
diff --git a/mysql-test/main/query_cache.result b/mysql-test/main/query_cache.result
index 9c010cbffc7..fa198ee6e17 100644
--- a/mysql-test/main/query_cache.result
+++ b/mysql-test/main/query_cache.result
@@ -1858,17 +1858,17 @@ DROP TABLE t1;
SET GLOBAL query_cache_size= default;
CREATE TABLE t1( a INT );
SET @v = ( SELECT SQL_CACHE 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 '1 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'SQL_CACHE'
SET @v = ( SELECT SQL_NO_CACHE 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 '1 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'SQL_NO_CACHE'
SELECT a FROM t1 WHERE a IN ( SELECT SQL_CACHE a FROM t1 );
-ERROR 42S22: Unknown column 'SQL_CACHE' in 'field list'
+ERROR 42000: Incorrect usage/placement of 'SQL_CACHE'
SELECT a FROM t1 WHERE a IN ( SELECT SQL_NO_CACHE a FROM t1 );
-ERROR 42S22: Unknown column 'SQL_NO_CACHE' in 'field list'
+ERROR 42000: Incorrect usage/placement of 'SQL_NO_CACHE'
SELECT ( SELECT SQL_CACHE a FROM t1 );
-ERROR 42S22: Unknown column 'SQL_CACHE' in 'field list'
+ERROR 42000: Incorrect usage/placement of 'SQL_CACHE'
SELECT ( SELECT SQL_NO_CACHE a FROM t1 );
-ERROR 42S22: Unknown column 'SQL_NO_CACHE' in 'field list'
+ERROR 42000: Incorrect usage/placement of 'SQL_NO_CACHE'
SELECT SQL_CACHE * FROM t1;
a
SELECT SQL_NO_CACHE * FROM t1;
@@ -1878,18 +1878,18 @@ ERROR 42000: Incorrect usage/placement of 'SQL_CACHE'
SELECT * FROM t1 UNION SELECT SQL_NO_CACHE * FROM t1;
ERROR 42000: Incorrect usage/placement of 'SQL_NO_CACHE'
SELECT * FROM t1 WHERE a IN (SELECT SQL_CACHE a FROM t1);
-ERROR 42S22: Unknown column 'SQL_CACHE' in 'field list'
+ERROR 42000: Incorrect usage/placement of 'SQL_CACHE'
SELECT * FROM t1 WHERE a IN (SELECT a FROM t1 UNION SELECT SQL_CACHE a FROM t1);
-ERROR 42S22: Unknown column 'SQL_CACHE' in 'field list'
+ERROR 42000: Incorrect usage/placement of 'SQL_CACHE'
SELECT * FROM t1 UNION SELECT SQL_NO_CACHE * FROM t1;
ERROR 42000: Incorrect usage/placement of 'SQL_NO_CACHE'
SELECT * FROM t1 WHERE a IN (SELECT SQL_NO_CACHE a FROM t1);
-ERROR 42S22: Unknown column 'SQL_NO_CACHE' in 'field list'
+ERROR 42000: Incorrect usage/placement of 'SQL_NO_CACHE'
SELECT * FROM t1 WHERE a IN
(SELECT a FROM t1 UNION SELECT SQL_NO_CACHE a FROM t1);
-ERROR 42S22: Unknown column 'SQL_NO_CACHE' in 'field list'
+ERROR 42000: Incorrect usage/placement of 'SQL_NO_CACHE'
SELECT SQL_CACHE SQL_NO_CACHE * FROM t1;
-ERROR HY000: Incorrect usage of SQL_CACHE and SQL_NO_CACHE
+ERROR HY000: Incorrect usage of SQL_NO_CACHE and SQL_CACHE
SELECT SQL_NO_CACHE SQL_CACHE * FROM t1;
ERROR HY000: Incorrect usage of SQL_NO_CACHE and SQL_CACHE
SELECT SQL_CACHE * FROM t1 UNION SELECT SQL_CACHE * FROM t1;
@@ -1902,10 +1902,10 @@ SELECT SQL_NO_CACHE * FROM t1 UNION SELECT SQL_NO_CACHE * FROM t1;
ERROR 42000: Incorrect usage/placement of 'SQL_NO_CACHE'
SELECT SQL_CACHE * FROM t1 WHERE a IN
(SELECT SQL_NO_CACHE a FROM t1);
-ERROR 42S22: Unknown column 'SQL_NO_CACHE' in 'field list'
+ERROR 42000: Incorrect usage/placement of 'SQL_NO_CACHE'
SELECT SQL_CACHE * FROM t1 WHERE a IN
(SELECT a FROM t1 UNION SELECT SQL_NO_CACHE a FROM t1);
-ERROR 42S22: Unknown column 'SQL_NO_CACHE' in 'field list'
+ERROR 42000: Incorrect usage/placement of 'SQL_NO_CACHE'
DROP TABLE t1;
End of 5.1 tests
#
diff --git a/mysql-test/main/query_cache.test b/mysql-test/main/query_cache.test
index 1b1e24bc6f4..389aa0de2fa 100644
--- a/mysql-test/main/query_cache.test
+++ b/mysql-test/main/query_cache.test
@@ -1534,22 +1534,21 @@ SET GLOBAL query_cache_size= default;
#
CREATE TABLE t1( a INT );
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SET @v = ( SELECT SQL_CACHE 1 );
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SET @v = ( SELECT SQL_NO_CACHE 1 );
#
-# Keywords 'SQL_CACHE' and 'SQL_NO_CACHE' are allowed as column names.
-# Hence the error messages are not intuitive.
+# Keywords 'SQL_CACHE' and 'SQL_NO_CACHE'.
#
---error ER_BAD_FIELD_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT a FROM t1 WHERE a IN ( SELECT SQL_CACHE a FROM t1 );
---error ER_BAD_FIELD_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT a FROM t1 WHERE a IN ( SELECT SQL_NO_CACHE a FROM t1 );
---error ER_BAD_FIELD_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT ( SELECT SQL_CACHE a FROM t1 );
---error ER_BAD_FIELD_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT ( SELECT SQL_NO_CACHE a FROM t1 );
SELECT SQL_CACHE * FROM t1;
@@ -1560,16 +1559,16 @@ SELECT SQL_NO_CACHE * FROM t1;
SELECT * FROM t1 UNION SELECT SQL_CACHE * FROM t1;
--error ER_CANT_USE_OPTION_HERE
SELECT * FROM t1 UNION SELECT SQL_NO_CACHE * FROM t1;
---error ER_BAD_FIELD_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM t1 WHERE a IN (SELECT SQL_CACHE a FROM t1);
---error ER_BAD_FIELD_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM t1 WHERE a IN (SELECT a FROM t1 UNION SELECT SQL_CACHE a FROM t1);
--error ER_CANT_USE_OPTION_HERE
SELECT * FROM t1 UNION SELECT SQL_NO_CACHE * FROM t1;
---error ER_BAD_FIELD_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM t1 WHERE a IN (SELECT SQL_NO_CACHE a FROM t1);
---error ER_BAD_FIELD_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM t1 WHERE a IN
(SELECT a FROM t1 UNION SELECT SQL_NO_CACHE a FROM t1);
--error ER_WRONG_USAGE
@@ -1584,10 +1583,10 @@ SELECT SQL_CACHE * FROM t1 UNION SELECT SQL_NO_CACHE * FROM t1;
SELECT SQL_NO_CACHE * FROM t1 UNION SELECT SQL_CACHE * FROM t1;
--error ER_CANT_USE_OPTION_HERE
SELECT SQL_NO_CACHE * FROM t1 UNION SELECT SQL_NO_CACHE * FROM t1;
---error ER_BAD_FIELD_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT SQL_CACHE * FROM t1 WHERE a IN
(SELECT SQL_NO_CACHE a FROM t1);
---error ER_BAD_FIELD_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT SQL_CACHE * FROM t1 WHERE a IN
(SELECT a FROM t1 UNION SELECT SQL_NO_CACHE a FROM t1);
diff --git a/mysql-test/main/show_check.result b/mysql-test/main/show_check.result
index 5083f1e615b..f4e2047414c 100644
--- a/mysql-test/main/show_check.result
+++ b/mysql-test/main/show_check.result
@@ -757,11 +757,11 @@ View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select sql_no_cache current_timestamp() AS `NOW()` binary binary
DROP VIEW v1;
CREATE VIEW v1 AS SELECT SQL_CACHE SQL_NO_CACHE NOW();
-ERROR HY000: Incorrect usage of SQL_CACHE and SQL_NO_CACHE
+ERROR HY000: Incorrect usage of SQL_NO_CACHE and SQL_CACHE
CREATE VIEW v1 AS SELECT SQL_NO_CACHE SQL_CACHE NOW();
ERROR HY000: Incorrect usage of SQL_NO_CACHE and SQL_CACHE
CREATE VIEW v1 AS SELECT SQL_CACHE SQL_NO_CACHE SQL_CACHE NOW();
-ERROR HY000: Incorrect usage of SQL_CACHE and SQL_NO_CACHE
+ERROR HY000: Option 'SQL_CACHE' used twice in statement
CREATE PROCEDURE p1()
BEGIN
SET @s= 'CREATE VIEW v1 AS SELECT SQL_CACHE 1';
diff --git a/mysql-test/main/show_check.test b/mysql-test/main/show_check.test
index a24fa632ea5..b6885b1fcaf 100644
--- a/mysql-test/main/show_check.test
+++ b/mysql-test/main/show_check.test
@@ -558,7 +558,7 @@ CREATE VIEW v1 AS SELECT SQL_CACHE SQL_NO_CACHE NOW();
--error ER_WRONG_USAGE
CREATE VIEW v1 AS SELECT SQL_NO_CACHE SQL_CACHE NOW();
---error ER_WRONG_USAGE
+--error ER_DUP_ARGUMENT
CREATE VIEW v1 AS SELECT SQL_CACHE SQL_NO_CACHE SQL_CACHE NOW();
# Check CREATE VIEW in a prepared statement in a procedure.
diff --git a/mysql-test/main/sp-error.result b/mysql-test/main/sp-error.result
index fc43bdf17e9..de4c4cf3103 100644
--- a/mysql-test/main/sp-error.result
+++ b/mysql-test/main/sp-error.result
@@ -1227,16 +1227,16 @@ DROP PROCEDURE IF EXISTS bug14702;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (i INT);
CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO @a;
-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 @a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO DUMPFILE "file";
-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 DUMPFILE "file"' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO OUTFILE "file";
-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 OUTFILE "file"' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
CREATE PROCEDURE bug20953()
CREATE VIEW v AS SELECT i FROM t1 PROCEDURE ANALYSE();
-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 'PROCEDURE ANALYSE()' at line 2
+ERROR 42000: Incorrect usage/placement of 'PROCEDURE'
CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 FROM (SELECT 1) AS d1 into @w;
-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 @w' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
CREATE PROCEDURE bug20953(i INT) CREATE VIEW v AS SELECT i;
ERROR HY000: View's SELECT contains a variable or parameter
CREATE PROCEDURE bug20953()
diff --git a/mysql-test/main/sp-error.test b/mysql-test/main/sp-error.test
index 0e16948f438..88d9809265a 100644
--- a/mysql-test/main/sp-error.test
+++ b/mysql-test/main/sp-error.test
@@ -1785,16 +1785,16 @@ CREATE TABLE t1 (i INT);
# We do not have to drop this procedure and view because they won't be
# created.
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO @a;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO DUMPFILE "file";
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO OUTFILE "file";
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
CREATE PROCEDURE bug20953()
CREATE VIEW v AS SELECT i FROM t1 PROCEDURE ANALYSE();
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 FROM (SELECT 1) AS d1 into @w;
--error ER_VIEW_SELECT_VARIABLE
CREATE PROCEDURE bug20953(i INT) CREATE VIEW v AS SELECT i;
diff --git a/mysql-test/main/sp.result b/mysql-test/main/sp.result
index 582ea33d903..3e8e2243725 100644
--- a/mysql-test/main/sp.result
+++ b/mysql-test/main/sp.result
@@ -314,7 +314,7 @@ delete from t1|
drop procedure b|
drop procedure if exists b2|
create procedure b2(x int)
-repeat(select 1 into outfile 'b2');
+repeat(select 1) into outfile 'b2';
insert into test.t1 values (repeat("b2",3), x);
set x = x-1;
until x = 0 end repeat|
diff --git a/mysql-test/main/sp.test b/mysql-test/main/sp.test
index 7a6fc3e711d..6308a0906c7 100644
--- a/mysql-test/main/sp.test
+++ b/mysql-test/main/sp.test
@@ -440,7 +440,7 @@ drop procedure b|
drop procedure if exists b2|
--enable_warnings
create procedure b2(x int)
-repeat(select 1 into outfile 'b2');
+repeat(select 1) into outfile 'b2';
insert into test.t1 values (repeat("b2",3), x);
set x = x-1;
until x = 0 end repeat|
diff --git a/mysql-test/main/subselect.result b/mysql-test/main/subselect.result
index 1c087a3199c..ce03034e0c1 100644
--- a/mysql-test/main/subselect.result
+++ b/mysql-test/main/subselect.result
@@ -80,7 +80,7 @@ SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a));
1
1
select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(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 'PROCEDURE ANALYSE(1))' at line 1
+ERROR 42000: Incorrect usage/placement of 'PROCEDURE'
SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((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 'SELECT 1))' at line 1
SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL;
@@ -179,7 +179,8 @@ select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1);
a b
1 7
2 7
-(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 order by a limit 2) limit 3;
+(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1))
+union (select * from t4 order by a limit 2) order by a limit 3;
a b
1 7
2 7
@@ -3726,7 +3727,7 @@ SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS
i
SELECT * FROM t1
WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i 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 i FROM t1)))' at line 2
+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))
@@ -5094,34 +5095,31 @@ INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2( a INT, b INT );
SELECT *
FROM (SELECT a INTO @var FROM t1 WHERE a = 2) t1a;
-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 @var FROM t1 WHERE a = 2) t1a' at line 2
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT *
FROM (SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2) t1a;
-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 OUTFILE 'file' FROM t1 WHERE a = 2) t1a' at line 2
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT *
FROM (SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2) t1a;
-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 DUMPFILE 'file' FROM t1 WHERE a = 2) t1a' at line 2
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (
SELECT 1 a
UNION
SELECT a INTO @var FROM t1 WHERE a = 2
) t1a;
-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 @var FROM t1 WHERE a = 2
-) t1a' at line 4
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (
SELECT 1 a
UNION
SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2
) t1a;
-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 OUTFILE 'file' FROM t1 WHERE a = 2
-) t1a' at line 4
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (
SELECT 1 a
UNION
SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2
) t1a;
-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 DUMPFILE 'file' FROM t1 WHERE a = 2
-) t1a' at line 4
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT a FROM t1 WHERE a = 2) t1a;
a
2
@@ -5152,23 +5150,23 @@ SELECT * FROM (SELECT 1 UNION SELECT 1) t1a;
1
1
SELECT * FROM ((SELECT 1 a INTO @a)) t1a;
-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 @a)) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM ((SELECT 1 a INTO OUTFILE 'file' )) t1a;
-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 OUTFILE 'file' )) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM ((SELECT 1 a INTO DUMPFILE 'file' )) t1a;
-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 DUMPFILE 'file' )) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO @a)) t1a;
-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 @a)) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO DUMPFILE 'file' )) t1a;
-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 DUMPFILE 'file' )) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO OUTFILE 'file' )) t1a;
-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 OUTFILE 'file' )) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO @a))) t1a;
-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 @a))) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO DUMPFILE 'file' ))) t1a;
-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 DUMPFILE 'file' ))) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO OUTFILE 'file' ))) t1a;
-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 OUTFILE 'file' ))) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a ORDER BY a) t1a;
a
1
@@ -5186,35 +5184,23 @@ a 1
1 1
2 1
SELECT * FROM t1 JOIN ((SELECT 1 UNION SELECT 1)) ON 1;
-ERROR 42000: Every derived table must have its own alias
+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 'ON 1' at line 1
SELECT * FROM t1 JOIN (t1 t1a UNION SELECT 1) ON 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 'SELECT 1) ON 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 'UNION SELECT 1) ON 1' at line 1
SELECT * FROM t1 JOIN ((t1 t1a UNION SELECT 1)) ON 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 'SELECT 1)) ON 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 'UNION SELECT 1)) ON 1' at line 1
SELECT * FROM t1 JOIN (t1 t1a) t1a ON 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 't1a ON 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 ') t1a ON 1' at line 1
SELECT * FROM t1 JOIN ((t1 t1a)) t1a ON 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 't1a ON 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 ')) t1a ON 1' at line 1
SELECT * FROM t1 JOIN (t1 t1a) ON 1;
-a a
-1 1
-2 1
-1 2
-2 2
+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 ') ON 1' at line 1
SELECT * FROM t1 JOIN ((t1 t1a)) ON 1;
-a a
-1 1
-2 1
-1 2
-2 2
+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 ')) ON 1' at line 1
SELECT * FROM (t1 t1a);
-a
-1
-2
+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 * FROM ((t1 t1a));
-a
-1
-2
+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 * FROM t1 JOIN (SELECT 1 t1a) alias ON 1;
a t1a
1 1
@@ -5243,11 +5229,11 @@ SELECT * FROM t1 WHERE a = ANY ( SELECT 3 UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO @a);
-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 @a)' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 );
a
1
@@ -5255,29 +5241,29 @@ SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE a = ( SELECT 1 INTO @a);
-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 @a)' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO @a);
-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 @a)' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 UNION SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT a FROM t1 WHERE a = 1 ), a FROM t1;
( SELECT a FROM t1 WHERE a = 1 ) a
1 1
@@ -5289,11 +5275,14 @@ SELECT ( SELECT a FROM t1 WHERE a = 1 UNION SELECT 1 ), a FROM t1;
SELECT * FROM t2 WHERE (a, b) IN (SELECT a, b FROM t2);
a b
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
+1
+1
( 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 ) UNION SELECT 1' at line 1
+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
+( 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
SELECT ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
@@ -5303,9 +5292,9 @@ SELECT ((SELECT 1 UNION SELECT 1 UNION SELECT 1));
((SELECT 1 UNION SELECT 1 UNION SELECT 1))
1
SELECT * FROM ( 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 * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
-ERROR 42000: Every derived table must have its own alias
+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 * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 ) a;
1
1
@@ -5313,19 +5302,25 @@ SELECT * FROM ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ) a;
1
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 ) );
-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 = ANY ( 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 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 );
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
SELECT * FROM t1 WHERE a = ALL ( ( 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 ) UNION SELECT 1 )' at line 1
+a
+1
SELECT * FROM t1 WHERE a = ANY ( ( 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 ) UNION SELECT 1 )' at line 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
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
@@ -5341,18 +5336,18 @@ SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE EXISTS ( SELECT 1 UNION SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT EXISTS(SELECT 1+1);
EXISTS(SELECT 1+1)
1
SELECT EXISTS(SELECT 1+1 INTO @test);
-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 @test)' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE EXISTS ( SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a IN ( SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
DROP TABLE t1, t2;
CREATE TABLE t1 (a ENUM('rainbow'));
INSERT INTO t1 VALUES (),(),(),(),();
diff --git a/mysql-test/main/subselect.test b/mysql-test/main/subselect.test
index c5cec99cebf..9af3727df21 100644
--- a/mysql-test/main/subselect.test
+++ b/mysql-test/main/subselect.test
@@ -53,7 +53,7 @@ SELECT * FROM (SELECT 1 as id) b WHERE id IN (SELECT * FROM (SELECT 1 as id) c O
SELECT * FROM (SELECT 1) a WHERE 1 IN (SELECT 1,1);
SELECT 1 IN (SELECT 1);
SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a));
--- error ER_PARSE_ERROR
+-- error ER_CANT_USE_OPTION_HERE
select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(1));
-- error ER_PARSE_ERROR
SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 1));
@@ -99,7 +99,8 @@ select (select a from t3), a from t2;
select * from t2 where t2.a=(select a from t1);
insert into t3 values (6),(7),(3);
select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1);
-(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 order by a limit 2) limit 3;
+(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1))
+union (select * from t4 order by a limit 2) order by a limit 3;
(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
explain extended (select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2;
@@ -2604,8 +2605,6 @@ SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS
(SELECT i FROM t1)
);
-#TODO:not supported
---error ER_PARSE_ERROR
SELECT * FROM t1
WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1)));
@@ -4229,31 +4228,31 @@ INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2( a INT, b INT );
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT *
FROM (SELECT a INTO @var FROM t1 WHERE a = 2) t1a;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT *
FROM (SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2) t1a;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT *
FROM (SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2) t1a;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM (
SELECT 1 a
UNION
SELECT a INTO @var FROM t1 WHERE a = 2
) t1a;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM (
SELECT 1 a
UNION
SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2
) t1a;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM (
SELECT 1 a
UNION
@@ -4281,25 +4280,25 @@ SELECT * FROM (
SELECT * FROM ((SELECT 1 a) UNION SELECT 1 a) q;
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a)) alias;
SELECT * FROM (SELECT 1 UNION SELECT 1) t1a;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM ((SELECT 1 a INTO @a)) t1a;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM ((SELECT 1 a INTO OUTFILE 'file' )) t1a;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM ((SELECT 1 a INTO DUMPFILE 'file' )) t1a;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO @a)) t1a;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO DUMPFILE 'file' )) t1a;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO OUTFILE 'file' )) t1a;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO @a))) t1a;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO DUMPFILE 'file' ))) t1a;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO OUTFILE 'file' ))) t1a;
SELECT * FROM (SELECT 1 a ORDER BY a) t1a;
@@ -4313,7 +4312,7 @@ SELECT * FROM (SELECT 1 a UNION SELECT 1 a ORDER BY a LIMIT 1) t1a;
# aliases after.
#
SELECT * FROM t1 JOIN (SELECT 1 UNION SELECT 1) alias ON 1;
---error ER_DERIVED_MUST_HAVE_ALIAS
+--error ER_PARSE_ERROR
SELECT * FROM t1 JOIN ((SELECT 1 UNION SELECT 1)) ON 1;
--error ER_PARSE_ERROR
SELECT * FROM t1 JOIN (t1 t1a UNION SELECT 1) ON 1;
@@ -4324,10 +4323,14 @@ SELECT * FROM t1 JOIN (t1 t1a) t1a ON 1;
--error ER_PARSE_ERROR
SELECT * FROM t1 JOIN ((t1 t1a)) t1a ON 1;
+--error ER_PARSE_ERROR
SELECT * FROM t1 JOIN (t1 t1a) ON 1;
+--error ER_PARSE_ERROR
SELECT * FROM t1 JOIN ((t1 t1a)) ON 1;
+--error ER_PARSE_ERROR
SELECT * FROM (t1 t1a);
+--error ER_PARSE_ERROR
SELECT * FROM ((t1 t1a));
SELECT * FROM t1 JOIN (SELECT 1 t1a) alias ON 1;
@@ -4345,41 +4348,41 @@ SELECT * FROM t1 WHERE a = ALL ( SELECT 1 );
SELECT * FROM t1 WHERE a = ALL ( SELECT 1 UNION SELECT 1 );
SELECT * FROM t1 WHERE a = ANY ( SELECT 3 UNION SELECT 1 );
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO @a);
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
SELECT * FROM t1 WHERE a = ( SELECT 1 );
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 );
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM t1 WHERE a = ( SELECT 1 INTO @a);
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM t1 WHERE a = ( SELECT 1 INTO OUTFILE 'file' );
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM t1 WHERE a = ( SELECT 1 INTO DUMPFILE 'file' );
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO @a);
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT ( SELECT 1 INTO @v );
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT ( SELECT 1 INTO OUTFILE 'file' );
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT ( SELECT 1 INTO DUMPFILE 'file' );
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT ( SELECT 1 UNION SELECT 1 INTO @v );
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
# Make sure context is popped when we leave the nested select
@@ -4391,12 +4394,9 @@ SELECT * FROM t2 WHERE (a, b) IN (SELECT a, b FROM t2);
# Make sure the parser does not allow nested UNIONs anywhere
---error ER_PARSE_ERROR
SELECT 1 UNION ( SELECT 1 UNION SELECT 1 );
---error ER_PARSE_ERROR
( SELECT 1 UNION SELECT 1 ) UNION SELECT 1;
---error ER_PARSE_ERROR
SELECT ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
--error ER_PARSE_ERROR
SELECT ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1;
@@ -4405,25 +4405,19 @@ SELECT ((SELECT 1 UNION SELECT 1 UNION SELECT 1));
--error ER_PARSE_ERROR
SELECT * FROM ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
---error ER_DERIVED_MUST_HAVE_ALIAS
+--error ER_PARSE_ERROR
SELECT * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
SELECT * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 ) a;
SELECT * FROM ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ) a;
---error ER_PARSE_ERROR
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
---error ER_PARSE_ERROR
SELECT * FROM t1 WHERE a = ALL ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
---error ER_PARSE_ERROR
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 ) );
--error ER_PARSE_ERROR
SELECT * FROM t1 WHERE a = ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
---error ER_PARSE_ERROR
SELECT * FROM t1 WHERE a = ALL ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
---error ER_PARSE_ERROR
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 );
@@ -4433,17 +4427,17 @@ 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
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM t1 WHERE EXISTS ( SELECT 1 UNION SELECT 1 INTO @v );
SELECT EXISTS(SELECT 1+1);
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT EXISTS(SELECT 1+1 INTO @test);
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 INTO @v );
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM t1 WHERE EXISTS ( SELECT 1 INTO @v );
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT * FROM t1 WHERE a IN ( SELECT 1 INTO @v );
DROP TABLE t1, t2;
diff --git a/mysql-test/main/subselect_mat.result b/mysql-test/main/subselect_mat.result
index 463ec53e7bb..39c0d1dd22b 100644
--- a/mysql-test/main/subselect_mat.result
+++ b/mysql-test/main/subselect_mat.result
@@ -2179,11 +2179,11 @@ drop database mysqltest4;
# (both 1st and further executions)
CREATE TABLE t1 (a INT NOT NULL) ENGINE=MyISAM;
INSERT INTO t1 VALUES (0),(8);
-SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2));
+SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM t1 AS t2);
a
0
PREPARE stmt FROM "
-SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2))
+SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM t1 AS t2)
";
execute stmt;
a
diff --git a/mysql-test/main/subselect_no_exists_to_in.result b/mysql-test/main/subselect_no_exists_to_in.result
index eb912d9e331..85b18c2ce9c 100644
--- a/mysql-test/main/subselect_no_exists_to_in.result
+++ b/mysql-test/main/subselect_no_exists_to_in.result
@@ -84,7 +84,7 @@ SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a));
1
1
select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(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 'PROCEDURE ANALYSE(1))' at line 1
+ERROR 42000: Incorrect usage/placement of 'PROCEDURE'
SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((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 'SELECT 1))' at line 1
SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL;
@@ -183,7 +183,8 @@ select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1);
a b
1 7
2 7
-(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 order by a limit 2) limit 3;
+(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1))
+union (select * from t4 order by a limit 2) order by a limit 3;
a b
1 7
2 7
@@ -3729,7 +3730,7 @@ SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS
i
SELECT * FROM t1
WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i 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 i FROM t1)))' at line 2
+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))
@@ -5096,34 +5097,31 @@ INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2( a INT, b INT );
SELECT *
FROM (SELECT a INTO @var FROM t1 WHERE a = 2) t1a;
-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 @var FROM t1 WHERE a = 2) t1a' at line 2
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT *
FROM (SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2) t1a;
-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 OUTFILE 'file' FROM t1 WHERE a = 2) t1a' at line 2
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT *
FROM (SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2) t1a;
-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 DUMPFILE 'file' FROM t1 WHERE a = 2) t1a' at line 2
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (
SELECT 1 a
UNION
SELECT a INTO @var FROM t1 WHERE a = 2
) t1a;
-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 @var FROM t1 WHERE a = 2
-) t1a' at line 4
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (
SELECT 1 a
UNION
SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2
) t1a;
-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 OUTFILE 'file' FROM t1 WHERE a = 2
-) t1a' at line 4
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (
SELECT 1 a
UNION
SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2
) t1a;
-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 DUMPFILE 'file' FROM t1 WHERE a = 2
-) t1a' at line 4
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT a FROM t1 WHERE a = 2) t1a;
a
2
@@ -5154,23 +5152,23 @@ SELECT * FROM (SELECT 1 UNION SELECT 1) t1a;
1
1
SELECT * FROM ((SELECT 1 a INTO @a)) t1a;
-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 @a)) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM ((SELECT 1 a INTO OUTFILE 'file' )) t1a;
-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 OUTFILE 'file' )) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM ((SELECT 1 a INTO DUMPFILE 'file' )) t1a;
-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 DUMPFILE 'file' )) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO @a)) t1a;
-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 @a)) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO DUMPFILE 'file' )) t1a;
-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 DUMPFILE 'file' )) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO OUTFILE 'file' )) t1a;
-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 OUTFILE 'file' )) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO @a))) t1a;
-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 @a))) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO DUMPFILE 'file' ))) t1a;
-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 DUMPFILE 'file' ))) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO OUTFILE 'file' ))) t1a;
-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 OUTFILE 'file' ))) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a ORDER BY a) t1a;
a
1
@@ -5188,35 +5186,23 @@ a 1
1 1
2 1
SELECT * FROM t1 JOIN ((SELECT 1 UNION SELECT 1)) ON 1;
-ERROR 42000: Every derived table must have its own alias
+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 'ON 1' at line 1
SELECT * FROM t1 JOIN (t1 t1a UNION SELECT 1) ON 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 'SELECT 1) ON 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 'UNION SELECT 1) ON 1' at line 1
SELECT * FROM t1 JOIN ((t1 t1a UNION SELECT 1)) ON 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 'SELECT 1)) ON 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 'UNION SELECT 1)) ON 1' at line 1
SELECT * FROM t1 JOIN (t1 t1a) t1a ON 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 't1a ON 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 ') t1a ON 1' at line 1
SELECT * FROM t1 JOIN ((t1 t1a)) t1a ON 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 't1a ON 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 ')) t1a ON 1' at line 1
SELECT * FROM t1 JOIN (t1 t1a) ON 1;
-a a
-1 1
-2 1
-1 2
-2 2
+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 ') ON 1' at line 1
SELECT * FROM t1 JOIN ((t1 t1a)) ON 1;
-a a
-1 1
-2 1
-1 2
-2 2
+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 ')) ON 1' at line 1
SELECT * FROM (t1 t1a);
-a
-1
-2
+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 * FROM ((t1 t1a));
-a
-1
-2
+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 * FROM t1 JOIN (SELECT 1 t1a) alias ON 1;
a t1a
1 1
@@ -5245,11 +5231,11 @@ SELECT * FROM t1 WHERE a = ANY ( SELECT 3 UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO @a);
-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 @a)' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 );
a
1
@@ -5257,29 +5243,29 @@ SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE a = ( SELECT 1 INTO @a);
-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 @a)' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO @a);
-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 @a)' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 UNION SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT a FROM t1 WHERE a = 1 ), a FROM t1;
( SELECT a FROM t1 WHERE a = 1 ) a
1 1
@@ -5291,11 +5277,14 @@ SELECT ( SELECT a FROM t1 WHERE a = 1 UNION SELECT 1 ), a FROM t1;
SELECT * FROM t2 WHERE (a, b) IN (SELECT a, b FROM t2);
a b
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
+1
+1
( 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 ) UNION SELECT 1' at line 1
+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
+( 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
SELECT ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
@@ -5305,9 +5294,9 @@ SELECT ((SELECT 1 UNION SELECT 1 UNION SELECT 1));
((SELECT 1 UNION SELECT 1 UNION SELECT 1))
1
SELECT * FROM ( 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 * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
-ERROR 42000: Every derived table must have its own alias
+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 * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 ) a;
1
1
@@ -5315,19 +5304,25 @@ SELECT * FROM ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ) a;
1
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 ) );
-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 = ANY ( 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 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 );
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
SELECT * FROM t1 WHERE a = ALL ( ( 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 ) UNION SELECT 1 )' at line 1
+a
+1
SELECT * FROM t1 WHERE a = ANY ( ( 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 ) UNION SELECT 1 )' at line 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
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
@@ -5343,18 +5338,18 @@ SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE EXISTS ( SELECT 1 UNION SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT EXISTS(SELECT 1+1);
EXISTS(SELECT 1+1)
1
SELECT EXISTS(SELECT 1+1 INTO @test);
-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 @test)' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE EXISTS ( SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a IN ( SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
DROP TABLE t1, t2;
CREATE TABLE t1 (a ENUM('rainbow'));
INSERT INTO t1 VALUES (),(),(),(),();
diff --git a/mysql-test/main/subselect_no_mat.result b/mysql-test/main/subselect_no_mat.result
index 72f30bbd21f..a2de845e5e4 100644
--- a/mysql-test/main/subselect_no_mat.result
+++ b/mysql-test/main/subselect_no_mat.result
@@ -87,7 +87,7 @@ SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a));
1
1
select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(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 'PROCEDURE ANALYSE(1))' at line 1
+ERROR 42000: Incorrect usage/placement of 'PROCEDURE'
SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((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 'SELECT 1))' at line 1
SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL;
@@ -186,7 +186,8 @@ select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1);
a b
1 7
2 7
-(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 order by a limit 2) limit 3;
+(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1))
+union (select * from t4 order by a limit 2) order by a limit 3;
a b
1 7
2 7
@@ -3729,7 +3730,7 @@ SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS
i
SELECT * FROM t1
WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i 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 i FROM t1)))' at line 2
+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))
@@ -5094,34 +5095,31 @@ INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2( a INT, b INT );
SELECT *
FROM (SELECT a INTO @var FROM t1 WHERE a = 2) t1a;
-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 @var FROM t1 WHERE a = 2) t1a' at line 2
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT *
FROM (SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2) t1a;
-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 OUTFILE 'file' FROM t1 WHERE a = 2) t1a' at line 2
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT *
FROM (SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2) t1a;
-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 DUMPFILE 'file' FROM t1 WHERE a = 2) t1a' at line 2
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (
SELECT 1 a
UNION
SELECT a INTO @var FROM t1 WHERE a = 2
) t1a;
-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 @var FROM t1 WHERE a = 2
-) t1a' at line 4
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (
SELECT 1 a
UNION
SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2
) t1a;
-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 OUTFILE 'file' FROM t1 WHERE a = 2
-) t1a' at line 4
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (
SELECT 1 a
UNION
SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2
) t1a;
-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 DUMPFILE 'file' FROM t1 WHERE a = 2
-) t1a' at line 4
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT a FROM t1 WHERE a = 2) t1a;
a
2
@@ -5152,23 +5150,23 @@ SELECT * FROM (SELECT 1 UNION SELECT 1) t1a;
1
1
SELECT * FROM ((SELECT 1 a INTO @a)) t1a;
-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 @a)) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM ((SELECT 1 a INTO OUTFILE 'file' )) t1a;
-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 OUTFILE 'file' )) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM ((SELECT 1 a INTO DUMPFILE 'file' )) t1a;
-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 DUMPFILE 'file' )) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO @a)) t1a;
-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 @a)) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO DUMPFILE 'file' )) t1a;
-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 DUMPFILE 'file' )) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO OUTFILE 'file' )) t1a;
-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 OUTFILE 'file' )) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO @a))) t1a;
-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 @a))) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO DUMPFILE 'file' ))) t1a;
-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 DUMPFILE 'file' ))) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO OUTFILE 'file' ))) t1a;
-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 OUTFILE 'file' ))) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a ORDER BY a) t1a;
a
1
@@ -5186,35 +5184,23 @@ a 1
1 1
2 1
SELECT * FROM t1 JOIN ((SELECT 1 UNION SELECT 1)) ON 1;
-ERROR 42000: Every derived table must have its own alias
+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 'ON 1' at line 1
SELECT * FROM t1 JOIN (t1 t1a UNION SELECT 1) ON 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 'SELECT 1) ON 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 'UNION SELECT 1) ON 1' at line 1
SELECT * FROM t1 JOIN ((t1 t1a UNION SELECT 1)) ON 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 'SELECT 1)) ON 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 'UNION SELECT 1)) ON 1' at line 1
SELECT * FROM t1 JOIN (t1 t1a) t1a ON 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 't1a ON 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 ') t1a ON 1' at line 1
SELECT * FROM t1 JOIN ((t1 t1a)) t1a ON 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 't1a ON 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 ')) t1a ON 1' at line 1
SELECT * FROM t1 JOIN (t1 t1a) ON 1;
-a a
-1 1
-2 1
-1 2
-2 2
+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 ') ON 1' at line 1
SELECT * FROM t1 JOIN ((t1 t1a)) ON 1;
-a a
-1 1
-2 1
-1 2
-2 2
+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 ')) ON 1' at line 1
SELECT * FROM (t1 t1a);
-a
-1
-2
+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 * FROM ((t1 t1a));
-a
-1
-2
+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 * FROM t1 JOIN (SELECT 1 t1a) alias ON 1;
a t1a
1 1
@@ -5243,11 +5229,11 @@ SELECT * FROM t1 WHERE a = ANY ( SELECT 3 UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO @a);
-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 @a)' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 );
a
1
@@ -5255,29 +5241,29 @@ SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE a = ( SELECT 1 INTO @a);
-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 @a)' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO @a);
-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 @a)' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 UNION SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT a FROM t1 WHERE a = 1 ), a FROM t1;
( SELECT a FROM t1 WHERE a = 1 ) a
1 1
@@ -5289,11 +5275,14 @@ SELECT ( SELECT a FROM t1 WHERE a = 1 UNION SELECT 1 ), a FROM t1;
SELECT * FROM t2 WHERE (a, b) IN (SELECT a, b FROM t2);
a b
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
+1
+1
( 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 ) UNION SELECT 1' at line 1
+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
+( 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
SELECT ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
@@ -5303,9 +5292,9 @@ SELECT ((SELECT 1 UNION SELECT 1 UNION SELECT 1));
((SELECT 1 UNION SELECT 1 UNION SELECT 1))
1
SELECT * FROM ( 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 * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
-ERROR 42000: Every derived table must have its own alias
+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 * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 ) a;
1
1
@@ -5313,19 +5302,25 @@ SELECT * FROM ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ) a;
1
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 ) );
-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 = ANY ( 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 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 );
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
SELECT * FROM t1 WHERE a = ALL ( ( 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 ) UNION SELECT 1 )' at line 1
+a
+1
SELECT * FROM t1 WHERE a = ANY ( ( 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 ) UNION SELECT 1 )' at line 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
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
@@ -5341,18 +5336,18 @@ SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE EXISTS ( SELECT 1 UNION SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT EXISTS(SELECT 1+1);
EXISTS(SELECT 1+1)
1
SELECT EXISTS(SELECT 1+1 INTO @test);
-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 @test)' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE EXISTS ( SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a IN ( SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
DROP TABLE t1, t2;
CREATE TABLE t1 (a ENUM('rainbow'));
INSERT INTO t1 VALUES (),(),(),(),();
diff --git a/mysql-test/main/subselect_no_opts.result b/mysql-test/main/subselect_no_opts.result
index de075d3245f..05cc0f44ff1 100644
--- a/mysql-test/main/subselect_no_opts.result
+++ b/mysql-test/main/subselect_no_opts.result
@@ -83,7 +83,7 @@ SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a));
1
1
select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(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 'PROCEDURE ANALYSE(1))' at line 1
+ERROR 42000: Incorrect usage/placement of 'PROCEDURE'
SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((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 'SELECT 1))' at line 1
SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL;
@@ -182,7 +182,8 @@ select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1);
a b
1 7
2 7
-(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 order by a limit 2) limit 3;
+(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1))
+union (select * from t4 order by a limit 2) order by a limit 3;
a b
1 7
2 7
@@ -3725,7 +3726,7 @@ SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS
i
SELECT * FROM t1
WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i 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 i FROM t1)))' at line 2
+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))
@@ -5090,34 +5091,31 @@ INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2( a INT, b INT );
SELECT *
FROM (SELECT a INTO @var FROM t1 WHERE a = 2) t1a;
-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 @var FROM t1 WHERE a = 2) t1a' at line 2
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT *
FROM (SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2) t1a;
-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 OUTFILE 'file' FROM t1 WHERE a = 2) t1a' at line 2
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT *
FROM (SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2) t1a;
-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 DUMPFILE 'file' FROM t1 WHERE a = 2) t1a' at line 2
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (
SELECT 1 a
UNION
SELECT a INTO @var FROM t1 WHERE a = 2
) t1a;
-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 @var FROM t1 WHERE a = 2
-) t1a' at line 4
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (
SELECT 1 a
UNION
SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2
) t1a;
-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 OUTFILE 'file' FROM t1 WHERE a = 2
-) t1a' at line 4
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (
SELECT 1 a
UNION
SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2
) t1a;
-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 DUMPFILE 'file' FROM t1 WHERE a = 2
-) t1a' at line 4
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT a FROM t1 WHERE a = 2) t1a;
a
2
@@ -5148,23 +5146,23 @@ SELECT * FROM (SELECT 1 UNION SELECT 1) t1a;
1
1
SELECT * FROM ((SELECT 1 a INTO @a)) t1a;
-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 @a)) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM ((SELECT 1 a INTO OUTFILE 'file' )) t1a;
-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 OUTFILE 'file' )) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM ((SELECT 1 a INTO DUMPFILE 'file' )) t1a;
-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 DUMPFILE 'file' )) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO @a)) t1a;
-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 @a)) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO DUMPFILE 'file' )) t1a;
-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 DUMPFILE 'file' )) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO OUTFILE 'file' )) t1a;
-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 OUTFILE 'file' )) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO @a))) t1a;
-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 @a))) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO DUMPFILE 'file' ))) t1a;
-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 DUMPFILE 'file' ))) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO OUTFILE 'file' ))) t1a;
-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 OUTFILE 'file' ))) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a ORDER BY a) t1a;
a
1
@@ -5182,35 +5180,23 @@ a 1
1 1
2 1
SELECT * FROM t1 JOIN ((SELECT 1 UNION SELECT 1)) ON 1;
-ERROR 42000: Every derived table must have its own alias
+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 'ON 1' at line 1
SELECT * FROM t1 JOIN (t1 t1a UNION SELECT 1) ON 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 'SELECT 1) ON 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 'UNION SELECT 1) ON 1' at line 1
SELECT * FROM t1 JOIN ((t1 t1a UNION SELECT 1)) ON 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 'SELECT 1)) ON 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 'UNION SELECT 1)) ON 1' at line 1
SELECT * FROM t1 JOIN (t1 t1a) t1a ON 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 't1a ON 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 ') t1a ON 1' at line 1
SELECT * FROM t1 JOIN ((t1 t1a)) t1a ON 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 't1a ON 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 ')) t1a ON 1' at line 1
SELECT * FROM t1 JOIN (t1 t1a) ON 1;
-a a
-1 1
-2 1
-1 2
-2 2
+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 ') ON 1' at line 1
SELECT * FROM t1 JOIN ((t1 t1a)) ON 1;
-a a
-1 1
-2 1
-1 2
-2 2
+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 ')) ON 1' at line 1
SELECT * FROM (t1 t1a);
-a
-1
-2
+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 * FROM ((t1 t1a));
-a
-1
-2
+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 * FROM t1 JOIN (SELECT 1 t1a) alias ON 1;
a t1a
1 1
@@ -5239,11 +5225,11 @@ SELECT * FROM t1 WHERE a = ANY ( SELECT 3 UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO @a);
-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 @a)' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 );
a
1
@@ -5251,29 +5237,29 @@ SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE a = ( SELECT 1 INTO @a);
-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 @a)' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO @a);
-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 @a)' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 UNION SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT a FROM t1 WHERE a = 1 ), a FROM t1;
( SELECT a FROM t1 WHERE a = 1 ) a
1 1
@@ -5285,11 +5271,14 @@ SELECT ( SELECT a FROM t1 WHERE a = 1 UNION SELECT 1 ), a FROM t1;
SELECT * FROM t2 WHERE (a, b) IN (SELECT a, b FROM t2);
a b
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
+1
+1
( 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 ) UNION SELECT 1' at line 1
+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
+( 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
SELECT ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
@@ -5299,9 +5288,9 @@ SELECT ((SELECT 1 UNION SELECT 1 UNION SELECT 1));
((SELECT 1 UNION SELECT 1 UNION SELECT 1))
1
SELECT * FROM ( 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 * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
-ERROR 42000: Every derived table must have its own alias
+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 * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 ) a;
1
1
@@ -5309,19 +5298,25 @@ SELECT * FROM ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ) a;
1
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 ) );
-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 = ANY ( 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 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 );
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
SELECT * FROM t1 WHERE a = ALL ( ( 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 ) UNION SELECT 1 )' at line 1
+a
+1
SELECT * FROM t1 WHERE a = ANY ( ( 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 ) UNION SELECT 1 )' at line 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
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
@@ -5337,18 +5332,18 @@ SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE EXISTS ( SELECT 1 UNION SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT EXISTS(SELECT 1+1);
EXISTS(SELECT 1+1)
1
SELECT EXISTS(SELECT 1+1 INTO @test);
-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 @test)' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE EXISTS ( SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a IN ( SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
DROP TABLE t1, t2;
CREATE TABLE t1 (a ENUM('rainbow'));
INSERT INTO t1 VALUES (),(),(),(),();
diff --git a/mysql-test/main/subselect_no_scache.result b/mysql-test/main/subselect_no_scache.result
index a594f5f85b9..1593ad50096 100644
--- a/mysql-test/main/subselect_no_scache.result
+++ b/mysql-test/main/subselect_no_scache.result
@@ -86,7 +86,7 @@ SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a));
1
1
select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(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 'PROCEDURE ANALYSE(1))' at line 1
+ERROR 42000: Incorrect usage/placement of 'PROCEDURE'
SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((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 'SELECT 1))' at line 1
SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL;
@@ -185,7 +185,8 @@ select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1);
a b
1 7
2 7
-(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 order by a limit 2) limit 3;
+(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1))
+union (select * from t4 order by a limit 2) order by a limit 3;
a b
1 7
2 7
@@ -3732,7 +3733,7 @@ SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS
i
SELECT * FROM t1
WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i 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 i FROM t1)))' at line 2
+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))
@@ -5100,34 +5101,31 @@ INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2( a INT, b INT );
SELECT *
FROM (SELECT a INTO @var FROM t1 WHERE a = 2) t1a;
-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 @var FROM t1 WHERE a = 2) t1a' at line 2
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT *
FROM (SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2) t1a;
-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 OUTFILE 'file' FROM t1 WHERE a = 2) t1a' at line 2
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT *
FROM (SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2) t1a;
-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 DUMPFILE 'file' FROM t1 WHERE a = 2) t1a' at line 2
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (
SELECT 1 a
UNION
SELECT a INTO @var FROM t1 WHERE a = 2
) t1a;
-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 @var FROM t1 WHERE a = 2
-) t1a' at line 4
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (
SELECT 1 a
UNION
SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2
) t1a;
-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 OUTFILE 'file' FROM t1 WHERE a = 2
-) t1a' at line 4
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (
SELECT 1 a
UNION
SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2
) t1a;
-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 DUMPFILE 'file' FROM t1 WHERE a = 2
-) t1a' at line 4
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT a FROM t1 WHERE a = 2) t1a;
a
2
@@ -5158,23 +5156,23 @@ SELECT * FROM (SELECT 1 UNION SELECT 1) t1a;
1
1
SELECT * FROM ((SELECT 1 a INTO @a)) t1a;
-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 @a)) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM ((SELECT 1 a INTO OUTFILE 'file' )) t1a;
-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 OUTFILE 'file' )) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM ((SELECT 1 a INTO DUMPFILE 'file' )) t1a;
-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 DUMPFILE 'file' )) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO @a)) t1a;
-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 @a)) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO DUMPFILE 'file' )) t1a;
-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 DUMPFILE 'file' )) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO OUTFILE 'file' )) t1a;
-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 OUTFILE 'file' )) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO @a))) t1a;
-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 @a))) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO DUMPFILE 'file' ))) t1a;
-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 DUMPFILE 'file' ))) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO OUTFILE 'file' ))) t1a;
-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 OUTFILE 'file' ))) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a ORDER BY a) t1a;
a
1
@@ -5192,35 +5190,23 @@ a 1
1 1
2 1
SELECT * FROM t1 JOIN ((SELECT 1 UNION SELECT 1)) ON 1;
-ERROR 42000: Every derived table must have its own alias
+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 'ON 1' at line 1
SELECT * FROM t1 JOIN (t1 t1a UNION SELECT 1) ON 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 'SELECT 1) ON 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 'UNION SELECT 1) ON 1' at line 1
SELECT * FROM t1 JOIN ((t1 t1a UNION SELECT 1)) ON 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 'SELECT 1)) ON 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 'UNION SELECT 1)) ON 1' at line 1
SELECT * FROM t1 JOIN (t1 t1a) t1a ON 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 't1a ON 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 ') t1a ON 1' at line 1
SELECT * FROM t1 JOIN ((t1 t1a)) t1a ON 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 't1a ON 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 ')) t1a ON 1' at line 1
SELECT * FROM t1 JOIN (t1 t1a) ON 1;
-a a
-1 1
-2 1
-1 2
-2 2
+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 ') ON 1' at line 1
SELECT * FROM t1 JOIN ((t1 t1a)) ON 1;
-a a
-1 1
-2 1
-1 2
-2 2
+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 ')) ON 1' at line 1
SELECT * FROM (t1 t1a);
-a
-1
-2
+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 * FROM ((t1 t1a));
-a
-1
-2
+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 * FROM t1 JOIN (SELECT 1 t1a) alias ON 1;
a t1a
1 1
@@ -5249,11 +5235,11 @@ SELECT * FROM t1 WHERE a = ANY ( SELECT 3 UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO @a);
-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 @a)' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 );
a
1
@@ -5261,29 +5247,29 @@ SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE a = ( SELECT 1 INTO @a);
-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 @a)' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO @a);
-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 @a)' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 UNION SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT a FROM t1 WHERE a = 1 ), a FROM t1;
( SELECT a FROM t1 WHERE a = 1 ) a
1 1
@@ -5295,11 +5281,14 @@ SELECT ( SELECT a FROM t1 WHERE a = 1 UNION SELECT 1 ), a FROM t1;
SELECT * FROM t2 WHERE (a, b) IN (SELECT a, b FROM t2);
a b
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
+1
+1
( 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 ) UNION SELECT 1' at line 1
+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
+( 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
SELECT ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
@@ -5309,9 +5298,9 @@ SELECT ((SELECT 1 UNION SELECT 1 UNION SELECT 1));
((SELECT 1 UNION SELECT 1 UNION SELECT 1))
1
SELECT * FROM ( 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 * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
-ERROR 42000: Every derived table must have its own alias
+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 * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 ) a;
1
1
@@ -5319,19 +5308,25 @@ SELECT * FROM ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ) a;
1
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 ) );
-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 = ANY ( 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 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 );
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
SELECT * FROM t1 WHERE a = ALL ( ( 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 ) UNION SELECT 1 )' at line 1
+a
+1
SELECT * FROM t1 WHERE a = ANY ( ( 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 ) UNION SELECT 1 )' at line 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
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
@@ -5347,18 +5342,18 @@ SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE EXISTS ( SELECT 1 UNION SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT EXISTS(SELECT 1+1);
EXISTS(SELECT 1+1)
1
SELECT EXISTS(SELECT 1+1 INTO @test);
-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 @test)' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE EXISTS ( SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a IN ( SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
DROP TABLE t1, t2;
CREATE TABLE t1 (a ENUM('rainbow'));
INSERT INTO t1 VALUES (),(),(),(),();
diff --git a/mysql-test/main/subselect_no_semijoin.result b/mysql-test/main/subselect_no_semijoin.result
index e068b28b017..2afc6dc8051 100644
--- a/mysql-test/main/subselect_no_semijoin.result
+++ b/mysql-test/main/subselect_no_semijoin.result
@@ -83,7 +83,7 @@ SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a));
1
1
select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(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 'PROCEDURE ANALYSE(1))' at line 1
+ERROR 42000: Incorrect usage/placement of 'PROCEDURE'
SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((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 'SELECT 1))' at line 1
SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL;
@@ -182,7 +182,8 @@ select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1);
a b
1 7
2 7
-(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 order by a limit 2) limit 3;
+(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1))
+union (select * from t4 order by a limit 2) order by a limit 3;
a b
1 7
2 7
@@ -3725,7 +3726,7 @@ SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS
i
SELECT * FROM t1
WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i 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 i FROM t1)))' at line 2
+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))
@@ -5090,34 +5091,31 @@ INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2( a INT, b INT );
SELECT *
FROM (SELECT a INTO @var FROM t1 WHERE a = 2) t1a;
-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 @var FROM t1 WHERE a = 2) t1a' at line 2
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT *
FROM (SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2) t1a;
-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 OUTFILE 'file' FROM t1 WHERE a = 2) t1a' at line 2
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT *
FROM (SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2) t1a;
-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 DUMPFILE 'file' FROM t1 WHERE a = 2) t1a' at line 2
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (
SELECT 1 a
UNION
SELECT a INTO @var FROM t1 WHERE a = 2
) t1a;
-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 @var FROM t1 WHERE a = 2
-) t1a' at line 4
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (
SELECT 1 a
UNION
SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2
) t1a;
-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 OUTFILE 'file' FROM t1 WHERE a = 2
-) t1a' at line 4
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (
SELECT 1 a
UNION
SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2
) t1a;
-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 DUMPFILE 'file' FROM t1 WHERE a = 2
-) t1a' at line 4
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT a FROM t1 WHERE a = 2) t1a;
a
2
@@ -5148,23 +5146,23 @@ SELECT * FROM (SELECT 1 UNION SELECT 1) t1a;
1
1
SELECT * FROM ((SELECT 1 a INTO @a)) t1a;
-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 @a)) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM ((SELECT 1 a INTO OUTFILE 'file' )) t1a;
-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 OUTFILE 'file' )) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM ((SELECT 1 a INTO DUMPFILE 'file' )) t1a;
-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 DUMPFILE 'file' )) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO @a)) t1a;
-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 @a)) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO DUMPFILE 'file' )) t1a;
-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 DUMPFILE 'file' )) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO OUTFILE 'file' )) t1a;
-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 OUTFILE 'file' )) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO @a))) t1a;
-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 @a))) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO DUMPFILE 'file' ))) t1a;
-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 DUMPFILE 'file' ))) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO OUTFILE 'file' ))) t1a;
-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 OUTFILE 'file' ))) t1a' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM (SELECT 1 a ORDER BY a) t1a;
a
1
@@ -5182,35 +5180,23 @@ a 1
1 1
2 1
SELECT * FROM t1 JOIN ((SELECT 1 UNION SELECT 1)) ON 1;
-ERROR 42000: Every derived table must have its own alias
+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 'ON 1' at line 1
SELECT * FROM t1 JOIN (t1 t1a UNION SELECT 1) ON 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 'SELECT 1) ON 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 'UNION SELECT 1) ON 1' at line 1
SELECT * FROM t1 JOIN ((t1 t1a UNION SELECT 1)) ON 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 'SELECT 1)) ON 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 'UNION SELECT 1)) ON 1' at line 1
SELECT * FROM t1 JOIN (t1 t1a) t1a ON 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 't1a ON 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 ') t1a ON 1' at line 1
SELECT * FROM t1 JOIN ((t1 t1a)) t1a ON 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 't1a ON 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 ')) t1a ON 1' at line 1
SELECT * FROM t1 JOIN (t1 t1a) ON 1;
-a a
-1 1
-2 1
-1 2
-2 2
+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 ') ON 1' at line 1
SELECT * FROM t1 JOIN ((t1 t1a)) ON 1;
-a a
-1 1
-2 1
-1 2
-2 2
+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 ')) ON 1' at line 1
SELECT * FROM (t1 t1a);
-a
-1
-2
+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 * FROM ((t1 t1a));
-a
-1
-2
+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 * FROM t1 JOIN (SELECT 1 t1a) alias ON 1;
a t1a
1 1
@@ -5239,11 +5225,11 @@ SELECT * FROM t1 WHERE a = ANY ( SELECT 3 UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO @a);
-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 @a)' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 );
a
1
@@ -5251,29 +5237,29 @@ SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE a = ( SELECT 1 INTO @a);
-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 @a)' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO @a);
-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 @a)' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 UNION SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
-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 OUTFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
-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 DUMPFILE 'file' )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT ( SELECT a FROM t1 WHERE a = 1 ), a FROM t1;
( SELECT a FROM t1 WHERE a = 1 ) a
1 1
@@ -5285,11 +5271,14 @@ SELECT ( SELECT a FROM t1 WHERE a = 1 UNION SELECT 1 ), a FROM t1;
SELECT * FROM t2 WHERE (a, b) IN (SELECT a, b FROM t2);
a b
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
+1
+1
( 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 ) UNION SELECT 1' at line 1
+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
+( 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
SELECT ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
@@ -5299,9 +5288,9 @@ SELECT ((SELECT 1 UNION SELECT 1 UNION SELECT 1));
((SELECT 1 UNION SELECT 1 UNION SELECT 1))
1
SELECT * FROM ( 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 * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
-ERROR 42000: Every derived table must have its own alias
+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 * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 ) a;
1
1
@@ -5309,19 +5298,25 @@ SELECT * FROM ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ) a;
1
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 ) );
-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 = ANY ( 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 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 );
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
SELECT * FROM t1 WHERE a = ALL ( ( 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 ) UNION SELECT 1 )' at line 1
+a
+1
SELECT * FROM t1 WHERE a = ANY ( ( 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 ) UNION SELECT 1 )' at line 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
SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
@@ -5337,18 +5332,18 @@ SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
a
1
SELECT * FROM t1 WHERE EXISTS ( SELECT 1 UNION SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT EXISTS(SELECT 1+1);
EXISTS(SELECT 1+1)
1
SELECT EXISTS(SELECT 1+1 INTO @test);
-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 @test)' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE EXISTS ( SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT * FROM t1 WHERE a IN ( SELECT 1 INTO @v );
-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 )' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
DROP TABLE t1, t2;
CREATE TABLE t1 (a ENUM('rainbow'));
INSERT INTO t1 VALUES (),(),(),(),();
diff --git a/mysql-test/main/subselect_sj.result b/mysql-test/main/subselect_sj.result
index 9631192da33..fb286bc3d53 100644
--- a/mysql-test/main/subselect_sj.result
+++ b/mysql-test/main/subselect_sj.result
@@ -1675,7 +1675,7 @@ CREATE TABLE t3 ( f11 int) ;
INSERT IGNORE INTO t3 VALUES (0);
SELECT alias1.f11 AS field2
FROM ( t3 AS alias2 JOIN t1 AS alias3 ON alias3.f10 = 1)
-LEFT JOIN ( t2 AS alias1 ) ON alias3.f11 = 1
+LEFT JOIN t2 AS alias1 ON alias3.f11 = 1
WHERE alias2.f11 IN ( SELECT f11 FROM t2 )
GROUP BY field2 ;
field2
diff --git a/mysql-test/main/subselect_sj.test b/mysql-test/main/subselect_sj.test
index 6fdccee339d..2eda8ee3e29 100644
--- a/mysql-test/main/subselect_sj.test
+++ b/mysql-test/main/subselect_sj.test
@@ -1462,7 +1462,7 @@ INSERT IGNORE INTO t3 VALUES (0);
SELECT alias1.f11 AS field2
FROM ( t3 AS alias2 JOIN t1 AS alias3 ON alias3.f10 = 1)
-LEFT JOIN ( t2 AS alias1 ) ON alias3.f11 = 1
+LEFT JOIN t2 AS alias1 ON alias3.f11 = 1
WHERE alias2.f11 IN ( SELECT f11 FROM t2 )
GROUP BY field2 ;
diff --git a/mysql-test/main/subselect_sj_jcl6.result b/mysql-test/main/subselect_sj_jcl6.result
index 77a073ea2d3..4810d06f1c3 100644
--- a/mysql-test/main/subselect_sj_jcl6.result
+++ b/mysql-test/main/subselect_sj_jcl6.result
@@ -1688,7 +1688,7 @@ CREATE TABLE t3 ( f11 int) ;
INSERT IGNORE INTO t3 VALUES (0);
SELECT alias1.f11 AS field2
FROM ( t3 AS alias2 JOIN t1 AS alias3 ON alias3.f10 = 1)
-LEFT JOIN ( t2 AS alias1 ) ON alias3.f11 = 1
+LEFT JOIN t2 AS alias1 ON alias3.f11 = 1
WHERE alias2.f11 IN ( SELECT f11 FROM t2 )
GROUP BY field2 ;
field2
diff --git a/mysql-test/main/subselect_sj_mat.result b/mysql-test/main/subselect_sj_mat.result
index 6a4a1a4ad5b..b241be77df7 100644
--- a/mysql-test/main/subselect_sj_mat.result
+++ b/mysql-test/main/subselect_sj_mat.result
@@ -2219,11 +2219,11 @@ drop database mysqltest4;
# (both 1st and further executions)
CREATE TABLE t1 (a INT NOT NULL) ENGINE=MyISAM;
INSERT INTO t1 VALUES (0),(8);
-SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2));
+SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM t1 AS t2);
a
0
PREPARE stmt FROM "
-SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2))
+SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM t1 AS t2)
";
execute stmt;
a
diff --git a/mysql-test/main/subselect_sj_mat.test b/mysql-test/main/subselect_sj_mat.test
index bfd3b28a5b2..66c11b61435 100644
--- a/mysql-test/main/subselect_sj_mat.test
+++ b/mysql-test/main/subselect_sj_mat.test
@@ -1848,9 +1848,9 @@ drop database mysqltest4;
CREATE TABLE t1 (a INT NOT NULL) ENGINE=MyISAM;
INSERT INTO t1 VALUES (0),(8);
-SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2));
+SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM t1 AS t2);
PREPARE stmt FROM "
-SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2))
+SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM t1 AS t2)
";
execute stmt;
execute stmt;
diff --git a/mysql-test/main/table_value_constr.result b/mysql-test/main/table_value_constr.result
index 39caba331ef..ed9c198197c 100644
--- a/mysql-test/main/table_value_constr.result
+++ b/mysql-test/main/table_value_constr.result
@@ -366,7 +366,6 @@ values (1,2);
1 2
1 2
3 4
-1 2
# combination of different structures that uses VALUES structures : UNION + UNION ALL
values (1,2),(3,4)
union all
diff --git a/mysql-test/main/union.result b/mysql-test/main/union.result
index 4e5f9312e03..47ac8cf5319 100644
--- a/mysql-test/main/union.result
+++ b/mysql-test/main/union.result
@@ -81,7 +81,7 @@ a b
2 b
1 a
(select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by t1.b;
-ERROR 42000: Table 't1' from one of the SELECTs cannot be used in global ORDER clause
+ERROR 42000: Table 't1' from one of the SELECTs cannot be used in ORDER clause
explain extended (select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by b desc;
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
@@ -494,7 +494,7 @@ drop temporary table t1;
create table t1 select a from t1 union select a from t2;
ERROR 42S01: Table 't1' already exists
select a from t1 union select a from t2 order by t2.a;
-ERROR 42000: Table 't2' from one of the SELECTs cannot be used in field list
+ERROR 42000: Table 't2' from one of the SELECTs cannot be used in ORDER clause
drop table t1,t2;
select length(version()) > 1 as `*` UNION select 2;
*
@@ -1532,11 +1532,8 @@ SELECT a FROM (SELECT a FROM t1 UNION SELECT a FROM t1 ORDER BY c) AS test;
ERROR 42S22: Unknown column 'c' in 'order clause'
DROP TABLE t1;
(select 1 into @var) union (select 1);
-ERROR HY000: Incorrect usage of UNION and INTO
+ERROR 42000: Incorrect usage/placement of 'INTO'
(select 1) union (select 1 into @var);
-select @var;
-@var
-1
(select 2) union (select 1 into @var);
ERROR 42000: Result consisted of more than one row
CREATE TABLE t1 (a int);
@@ -1666,11 +1663,11 @@ SELECT a FROM t1 UNION SELECT a INTO @v FROM t1;
SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file5' FROM t1;
SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file6' FROM t1;
SELECT a INTO @v FROM t1 UNION SELECT a 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 a FROM t1' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT a INTO OUTFILE 'union.out.file7' FROM t1 UNION SELECT a 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 a FROM t1' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
SELECT a INTO DUMPFILE 'union.out.file8' FROM t1 UNION SELECT a 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 a FROM t1' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
# Tests fix in parser rule query_expression_body.
SELECT ( SELECT a UNION SELECT a ) INTO @v FROM t1;
SELECT ( SELECT a UNION SELECT a ) INTO OUTFILE 'union.out.file3' FROM t1;
@@ -2019,14 +2016,14 @@ SET @@global.slow_query_log= @old_slow_query_log;
CREATE TABLE t1 (a int);
CREATE TABLE t2 (b int);
CREATE TABLE t3 (c int);
-SELECT a FROM t1 UNION SELECT b FROM t2 JOIN (t3) ON ( t2.b = t3.c );
+SELECT a FROM t1 UNION SELECT b FROM t2 JOIN t3 ON ( t2.b = t3.c );
a
DROP TABLE t1, t2, t3;
CREATE TABLE t1 (pk int NOT NULL);
CREATE TABLE t2 (pk int NOT NULL, fk int NOT NULL);
-SELECT t1.pk FROM t1 LEFT JOIN (t2) ON (t1.pk = t2.fk)
+SELECT t1.pk FROM t1 LEFT JOIN t2 ON (t1.pk = t2.fk)
UNION
-SELECT t1.pk FROM t1 LEFT JOIN (t2) ON (t1.pk = t2.fk);
+SELECT t1.pk FROM t1 LEFT JOIN t2 ON (t1.pk = t2.fk);
pk
DROP TABLE t1,t2;
create table t1 (a int);
diff --git a/mysql-test/main/union.test b/mysql-test/main/union.test
index f86cae87524..463eb609151 100644
--- a/mysql-test/main/union.test
+++ b/mysql-test/main/union.test
@@ -973,12 +973,12 @@ DROP TABLE t1;
#
# Bug#23345: Wrongly allowed INTO in a non-last select of a UNION.
+# (fixed)
#
---error 1221
+--error ER_CANT_USE_OPTION_HERE
(select 1 into @var) union (select 1);
(select 1) union (select 1 into @var);
-select @var;
---error 1172
+--error ER_TOO_MANY_ROWS
(select 2) union (select 1 into @var);
#
@@ -1102,11 +1102,11 @@ SELECT a INTO DUMPFILE 'union.out.file2' FROM (
SELECT a FROM t1 UNION SELECT a INTO @v FROM t1;
SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file5' FROM t1;
SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file6' FROM t1;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT a INTO @v FROM t1 UNION SELECT a FROM t1;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT a INTO OUTFILE 'union.out.file7' FROM t1 UNION SELECT a FROM t1;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
SELECT a INTO DUMPFILE 'union.out.file8' FROM t1 UNION SELECT a FROM t1;
-- echo # Tests fix in parser rule query_expression_body.
@@ -1361,15 +1361,15 @@ SET @@global.slow_query_log= @old_slow_query_log;
CREATE TABLE t1 (a int);
CREATE TABLE t2 (b int);
CREATE TABLE t3 (c int);
-SELECT a FROM t1 UNION SELECT b FROM t2 JOIN (t3) ON ( t2.b = t3.c );
+SELECT a FROM t1 UNION SELECT b FROM t2 JOIN t3 ON ( t2.b = t3.c );
DROP TABLE t1, t2, t3;
CREATE TABLE t1 (pk int NOT NULL);
CREATE TABLE t2 (pk int NOT NULL, fk int NOT NULL);
-SELECT t1.pk FROM t1 LEFT JOIN (t2) ON (t1.pk = t2.fk)
+SELECT t1.pk FROM t1 LEFT JOIN t2 ON (t1.pk = t2.fk)
UNION
-SELECT t1.pk FROM t1 LEFT JOIN (t2) ON (t1.pk = t2.fk);
+SELECT t1.pk FROM t1 LEFT JOIN t2 ON (t1.pk = t2.fk);
DROP TABLE t1,t2;
diff --git a/mysql-test/main/view.result b/mysql-test/main/view.result
index 63207ea6a67..ab02e48ebaa 100644
--- a/mysql-test/main/view.result
+++ b/mysql-test/main/view.result
@@ -919,12 +919,12 @@ select * from v4;
ERROR 21000: Subquery returns more than 1 row
drop view v4, v3, v2, v1;
create view v1 as select 5 into @w;
-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 @w' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
create view v1 as select 5 into outfile 'ttt';
-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 outfile 'ttt'' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
create table t1 (a int);
create view v1 as select a from t1 procedure analyse();
-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 'procedure analyse()' at line 1
+ERROR 42000: Incorrect usage/placement of 'PROCEDURE'
create view v1 as select 1 from (select 1) as d1;
drop view v1;
drop table t1;
@@ -3153,7 +3153,7 @@ DROP TABLE t1;
DROP VIEW IF EXISTS v1;
SELECT * FROM (SELECT 1) AS t into @w;
CREATE VIEW v1 AS SELECT * FROM (SELECT 1) AS t into @w;
-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 @w' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
# Previously the following would fail.
SELECT * FROM (SELECT 1) AS t into @w;
drop view if exists view_24532_a;
@@ -4093,7 +4093,7 @@ LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
;
SELECT 1
-FROM (( SELECT 1
+FROM ( SELECT 1
FROM t1 a_alias_1
LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
@@ -4101,8 +4101,8 @@ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t1)
-LEFT OUTER JOIN (( SELECT 1
+) t1
+LEFT OUTER JOIN ( SELECT 1
FROM t1 a_alias_1
LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
@@ -4110,8 +4110,8 @@ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t2) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
+) t2 ON 1=1
+LEFT OUTER JOIN ( SELECT 1
FROM t1 a_alias_1
LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
@@ -4119,8 +4119,8 @@ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t3) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
+) t3 ON 1=1
+LEFT OUTER JOIN ( SELECT 1
FROM t1 a_alias_1
LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
@@ -4128,8 +4128,8 @@ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t4) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
+) t4 ON 1=1
+LEFT OUTER JOIN ( SELECT 1
FROM t1 a_alias_1
LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
@@ -4137,8 +4137,8 @@ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t5) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
+) t5 ON 1=1
+LEFT OUTER JOIN ( SELECT 1
FROM t1 a_alias_1
LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
@@ -4146,8 +4146,8 @@ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t6) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
+) t6 ON 1=1
+LEFT OUTER JOIN ( SELECT 1
FROM t1 a_alias_1
LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
@@ -4155,8 +4155,8 @@ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t7) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
+) t7 ON 1=1
+LEFT OUTER JOIN ( SELECT 1
FROM t1 a_alias_1
LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
@@ -4164,18 +4164,18 @@ LEFT JOIN t4 d_alias_1 ON d_alias_1.d1 = a_alias_1.a1
LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t8) ON 1=1
+) t8 ON 1=1
;
1
SELECT 1
-FROM (v1 t1)
-LEFT OUTER JOIN (v1 t2) ON 1=1
-LEFT OUTER JOIN (v1 t3) ON 1=1
-LEFT OUTER JOIN (v1 t4) ON 1=1
-LEFT OUTER JOIN (v1 t5) ON 1=1
-LEFT OUTER JOIN (v1 t6) ON 1=1
-LEFT OUTER JOIN (v1 t7) ON 1=1
-LEFT OUTER JOIN (v1 t8) ON 1=1
+FROM v1 t1
+LEFT OUTER JOIN v1 t2 ON 1=1
+LEFT OUTER JOIN v1 t3 ON 1=1
+LEFT OUTER JOIN v1 t4 ON 1=1
+LEFT OUTER JOIN v1 t5 ON 1=1
+LEFT OUTER JOIN v1 t6 ON 1=1
+LEFT OUTER JOIN v1 t7 ON 1=1
+LEFT OUTER JOIN v1 t8 ON 1=1
;
1
drop view v1;
diff --git a/mysql-test/main/view.test b/mysql-test/main/view.test
index 82ef38f0eb6..615b9bf552c 100644
--- a/mysql-test/main/view.test
+++ b/mysql-test/main/view.test
@@ -833,12 +833,12 @@ drop view v4, v3, v2, v1;
#
# VIEW over SELECT with prohibited clauses
#
--- error ER_PARSE_ERROR
+-- error ER_CANT_USE_OPTION_HERE
create view v1 as select 5 into @w;
--- error ER_PARSE_ERROR
+-- error ER_CANT_USE_OPTION_HERE
create view v1 as select 5 into outfile 'ttt';
create table t1 (a int);
--- error ER_PARSE_ERROR
+-- error ER_CANT_USE_OPTION_HERE
create view v1 as select a from t1 procedure analyse();
# now derived tables are allowed
create view v1 as select 1 from (select 1) as d1;
@@ -3109,7 +3109,7 @@ DROP VIEW IF EXISTS v1;
let $query = SELECT * FROM (SELECT 1) AS t into @w;
eval $query;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
eval CREATE VIEW v1 AS $query;
--echo # Previously the following would fail.
eval $query;
@@ -4042,7 +4042,7 @@ CREATE OR REPLACE view v1 AS
;
SELECT 1
-FROM (( SELECT 1
+FROM ( SELECT 1
FROM t1 a_alias_1
LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
@@ -4050,8 +4050,8 @@ FROM (( SELECT 1
LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t1)
-LEFT OUTER JOIN (( SELECT 1
+) t1
+LEFT OUTER JOIN ( SELECT 1
FROM t1 a_alias_1
LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
@@ -4059,8 +4059,8 @@ LEFT OUTER JOIN (( SELECT 1
LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t2) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
+) t2 ON 1=1
+LEFT OUTER JOIN ( SELECT 1
FROM t1 a_alias_1
LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
@@ -4068,8 +4068,8 @@ LEFT OUTER JOIN (( SELECT 1
LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t3) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
+) t3 ON 1=1
+LEFT OUTER JOIN ( SELECT 1
FROM t1 a_alias_1
LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
@@ -4077,8 +4077,8 @@ LEFT OUTER JOIN (( SELECT 1
LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t4) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
+) t4 ON 1=1
+LEFT OUTER JOIN ( SELECT 1
FROM t1 a_alias_1
LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
@@ -4086,8 +4086,8 @@ LEFT OUTER JOIN (( SELECT 1
LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t5) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
+) t5 ON 1=1
+LEFT OUTER JOIN ( SELECT 1
FROM t1 a_alias_1
LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
@@ -4095,8 +4095,8 @@ LEFT OUTER JOIN (( SELECT 1
LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t6) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
+) t6 ON 1=1
+LEFT OUTER JOIN ( SELECT 1
FROM t1 a_alias_1
LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
@@ -4104,8 +4104,8 @@ LEFT OUTER JOIN (( SELECT 1
LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t7) ON 1=1
-LEFT OUTER JOIN (( SELECT 1
+) t7 ON 1=1
+LEFT OUTER JOIN ( SELECT 1
FROM t1 a_alias_1
LEFT JOIN (t2 b_alias_1 JOIN t1 a_alias_2) ON b_alias_1.b1 = a_alias_1.a1 AND a_alias_2.a1 = a_alias_1.a1
LEFT JOIN t3 c_alias_1 ON c_alias_1.c1 = a_alias_1.a1
@@ -4113,18 +4113,18 @@ LEFT OUTER JOIN (( SELECT 1
LEFT JOIN t3 c_alias_2 ON c_alias_2.c1 = a_alias_1.a1
LEFT JOIN t5 e_alias_1 ON e_alias_1.e1 = a_alias_1.a1
LEFT JOIN t6 f_alias_1 ON f_alias_1.f1 = a_alias_1.a1
-) t8) ON 1=1
+) t8 ON 1=1
;
SELECT 1
-FROM (v1 t1)
-LEFT OUTER JOIN (v1 t2) ON 1=1
-LEFT OUTER JOIN (v1 t3) ON 1=1
-LEFT OUTER JOIN (v1 t4) ON 1=1
-LEFT OUTER JOIN (v1 t5) ON 1=1
-LEFT OUTER JOIN (v1 t6) ON 1=1
-LEFT OUTER JOIN (v1 t7) ON 1=1
-LEFT OUTER JOIN (v1 t8) ON 1=1
+FROM v1 t1
+LEFT OUTER JOIN v1 t2 ON 1=1
+LEFT OUTER JOIN v1 t3 ON 1=1
+LEFT OUTER JOIN v1 t4 ON 1=1
+LEFT OUTER JOIN v1 t5 ON 1=1
+LEFT OUTER JOIN v1 t6 ON 1=1
+LEFT OUTER JOIN v1 t7 ON 1=1
+LEFT OUTER JOIN v1 t8 ON 1=1
;
drop view v1;
diff --git a/mysql-test/suite/funcs_1/r/innodb_views.result b/mysql-test/suite/funcs_1/r/innodb_views.result
index b00d1a56c90..bf523d47515 100644
--- a/mysql-test/suite/funcs_1/r/innodb_views.result
+++ b/mysql-test/suite/funcs_1/r/innodb_views.result
@@ -3497,7 +3497,7 @@ DROP VIEW IF EXISTS v2 ;
CREATE TABLE t1 (f1 BIGINT) ;
SET @x=0;
CREATE or REPLACE VIEW v1 AS Select 1 INTO @x;
-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 @x' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
Select @x;
@x
0
diff --git a/mysql-test/suite/funcs_1/r/memory_views.result b/mysql-test/suite/funcs_1/r/memory_views.result
index 5ac5c838fb5..57a6813b2fb 100644
--- a/mysql-test/suite/funcs_1/r/memory_views.result
+++ b/mysql-test/suite/funcs_1/r/memory_views.result
@@ -3498,7 +3498,7 @@ DROP VIEW IF EXISTS v2 ;
CREATE TABLE t1 (f1 BIGINT) ;
SET @x=0;
CREATE or REPLACE VIEW v1 AS Select 1 INTO @x;
-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 @x' at line 1
+ERROR 42000: Incorrect usage/placement of 'INTO'
Select @x;
@x
0
diff --git a/mysql-test/suite/funcs_1/views/views_master.inc b/mysql-test/suite/funcs_1/views/views_master.inc
index 17f5c1e5529..e4b58111612 100644
--- a/mysql-test/suite/funcs_1/views/views_master.inc
+++ b/mysql-test/suite/funcs_1/views/views_master.inc
@@ -266,7 +266,7 @@ CREATE TABLE t1 (f1 BIGINT) ;
# SELECT INTO is illegal
SET @x=0;
---error ER_PARSE_ERROR
+--error ER_CANT_USE_OPTION_HERE
CREATE or REPLACE VIEW v1 AS Select 1 INTO @x;
Select @x;
diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result
index aafd31ae6f1..005fd70534a 100644
--- a/mysql-test/suite/innodb/r/innodb.result
+++ b/mysql-test/suite/innodb/r/innodb.result
@@ -1608,7 +1608,7 @@ INSERT INTO t1 VALUES (1),(2),(3);
CREATE TABLE t2 (b_id tinyint(4) NOT NULL default '0',b_a tinyint(4) NOT NULL default '0', PRIMARY KEY (b_id), KEY (b_a),
CONSTRAINT fk_b_a FOREIGN KEY (b_a) REFERENCES t1 (a_id) ON DELETE CASCADE ON UPDATE NO ACTION) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO t2 VALUES (1,1),(2,1),(3,1),(4,2),(5,2);
-SELECT * FROM (SELECT t1.*,GROUP_CONCAT(t2.b_id SEPARATOR ',') as b_list FROM (t1 LEFT JOIN (t2) on t1.a_id = t2.b_a) GROUP BY t1.a_id ) AS xyz;
+SELECT * FROM (SELECT t1.*,GROUP_CONCAT(t2.b_id SEPARATOR ',') as b_list FROM (t1 LEFT JOIN t2 on t1.a_id = t2.b_a) GROUP BY t1.a_id ) AS xyz;
a_id b_list
1 1,2,3
2 4,5
diff --git a/mysql-test/suite/innodb/t/innodb.test b/mysql-test/suite/innodb/t/innodb.test
index 472b47899db..dd8a67eeec2 100644
--- a/mysql-test/suite/innodb/t/innodb.test
+++ b/mysql-test/suite/innodb/t/innodb.test
@@ -1253,7 +1253,7 @@ CREATE TABLE t2 (b_id tinyint(4) NOT NULL default '0',b_a tinyint(4) NOT NULL de
CONSTRAINT fk_b_a FOREIGN KEY (b_a) REFERENCES t1 (a_id) ON DELETE CASCADE ON UPDATE NO ACTION) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--enable_warnings
INSERT INTO t2 VALUES (1,1),(2,1),(3,1),(4,2),(5,2);
-SELECT * FROM (SELECT t1.*,GROUP_CONCAT(t2.b_id SEPARATOR ',') as b_list FROM (t1 LEFT JOIN (t2) on t1.a_id = t2.b_a) GROUP BY t1.a_id ) AS xyz;
+SELECT * FROM (SELECT t1.*,GROUP_CONCAT(t2.b_id SEPARATOR ',') as b_list FROM (t1 LEFT JOIN t2 on t1.a_id = t2.b_a) GROUP BY t1.a_id ) AS xyz;
DROP TABLE t2;
DROP TABLE t1;
diff --git a/mysql-test/suite/innodb_fts/r/fulltext_order_by.result b/mysql-test/suite/innodb_fts/r/fulltext_order_by.result
index 503f117d02f..0d3a4a85b86 100644
--- a/mysql-test/suite/innodb_fts/r/fulltext_order_by.result
+++ b/mysql-test/suite/innodb_fts/r/fulltext_order_by.result
@@ -129,7 +129,7 @@ group by
a.text, b.id, b.betreff
order by
match(b.betreff) against ('+abc' in boolean mode) desc;
-ERROR 42000: Table 'b' from one of the SELECTs cannot be used in field list
+ERROR 42000: Table 'b' from one of the SELECTs cannot be used in ORDER clause
select a.text, b.id, b.betreff
from
t2 a inner join t3 b on a.id = b.forum inner join
@@ -145,7 +145,7 @@ where
match(c.beitrag) against ('+abc' in boolean mode)
order by
match(b.betreff) against ('+abc' in boolean mode) desc;
-ERROR 42000: Table 'b' from one of the SELECTs cannot be used in field list
+ERROR 42000: Table 'b' from one of the SELECTs cannot be used in ORDER clause
select a.text, b.id, b.betreff
from
t2 a inner join t3 b on a.id = b.forum inner join
diff --git a/mysql-test/suite/versioning/r/select2.result b/mysql-test/suite/versioning/r/select2.result
index 9267ab8c913..3f29a958907 100644
--- a/mysql-test/suite/versioning/r/select2.result
+++ b/mysql-test/suite/versioning/r/select2.result
@@ -331,6 +331,6 @@ x y
select * from (select * from t1 for system_time all, t2 for system_time all) for system_time all as t;
ERROR HY000: Table `t` is not system-versioned
select * from (t1 for system_time all join t2 for system_time all) for system_time all;
-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
+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 'system_time all' at line 1
drop view v1;
drop table t1, t2;
diff --git a/sql/events.cc b/sql/events.cc
index 2fbb16861f6..7568d03c0e0 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -826,12 +826,13 @@ Events::fill_schema_events(THD *thd, TABLE_LIST *tables, COND * /* cond */)
*/
if (thd->lex->sql_command == SQLCOM_SHOW_EVENTS)
{
- DBUG_ASSERT(thd->lex->select_lex.db.str);
- if (!is_infoschema_db(&thd->lex->select_lex.db) && // There is no events in I_S
- check_access(thd, EVENT_ACL, thd->lex->select_lex.db.str,
+ DBUG_ASSERT(thd->lex->first_select_lex()->db.str);
+ if (!is_infoschema_db(&thd->lex->first_select_lex()->db) && // There is no events in I_S
+ check_access(thd, EVENT_ACL, thd->lex->first_select_lex()->db.str,
NULL, NULL, 0, 0))
DBUG_RETURN(1);
- db= normalize_db_name(thd->lex->select_lex.db.str, db_tmp, sizeof(db_tmp));
+ db= normalize_db_name(thd->lex->first_select_lex()->db.str,
+ db_tmp, sizeof(db_tmp));
}
ret= db_repository->fill_schema_events(thd, tables, db);
diff --git a/sql/item.cc b/sql/item.cc
index c19ad32f6ce..cee22e746d5 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -734,7 +734,8 @@ Item_ident::Item_ident(THD *thd, TABLE_LIST *view_arg,
:Item_result_field(thd), orig_db_name(NullS),
orig_table_name(view_arg->table_name.str),
orig_field_name(*field_name_arg),
- context(&view_arg->view->select_lex.context),
+ /* TODO: suspicious use of first_select_lex */
+ context(&view_arg->view->first_select_lex()->context),
db_name(NullS), table_name(view_arg->alias.str),
field_name(*field_name_arg),
alias_name_used(FALSE), cached_field_index(NO_CACHED_FIELD_INDEX),
@@ -3077,7 +3078,10 @@ Item_field::Item_field(THD *thd, Field *f)
have_privileges(0), any_privileges(0)
{
set_field(f);
-
+ /*
+ field_name and table_name should not point to garbage
+ if this item is to be reused
+ */
orig_table_name= table_name;
orig_field_name= field_name;
with_field= 1;
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 6378e9b76bf..5a447cef23a 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -123,14 +123,7 @@ void Item_subselect::init(st_select_lex *select_lex,
else
engine= new subselect_single_select_engine(select_lex, result, this);
}
- {
- SELECT_LEX *upper= unit->outer_select();
- if (upper->parsing_place == IN_HAVING)
- upper->subquery_in_having= 1;
- /* The subquery is an expression cache candidate */
- upper->expr_cache_may_be_used[upper->parsing_place]= TRUE;
- }
- DBUG_PRINT("info", ("engine: %p", engine));
+ DBUG_PRINT("info", ("engine: 0x%lx", (ulong)engine));
DBUG_VOID_RETURN;
}
@@ -219,7 +212,8 @@ Item_subselect::~Item_subselect()
if (own_engine)
delete engine;
else
- engine->cleanup();
+ if (engine) // can be empty in case of EOM
+ engine->cleanup();
engine= NULL;
DBUG_VOID_RETURN;
}
@@ -243,6 +237,14 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
DBUG_ASSERT(unit->thd == thd);
+ {
+ SELECT_LEX *upper= unit->outer_select();
+ if (upper->parsing_place == IN_HAVING)
+ upper->subquery_in_having= 1;
+ /* The subquery is an expression cache candidate */
+ upper->expr_cache_may_be_used[upper->parsing_place]= TRUE;
+ }
+
status_var_increment(thd_param->status_var.feature_subquery);
DBUG_ASSERT(fixed == 0);
diff --git a/sql/log_event.cc b/sql/log_event.cc
index cd47cbba9bd..2e342936893 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -4389,7 +4389,7 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, size_t que
have to use the transactional cache to ensure we don't
calculate any checksum for the CREATE part.
*/
- trx_cache= (lex->select_lex.item_list.elements &&
+ trx_cache= (lex->first_select_lex()->item_list.elements &&
thd->is_current_stmt_binlog_format_row()) ||
(thd->variables.option_bits & OPTION_GTID_BEGIN);
use_cache= (lex->tmp_table() &&
@@ -7339,8 +7339,9 @@ int Load_log_event::do_apply_event(NET* net, rpl_group_info *rgi,
ex.skip_lines = skip_lines;
List<Item> field_list;
- thd->lex->select_lex.context.resolve_in_table_list_only(&tables);
- set_fields(tables.db.str, field_list, &thd->lex->select_lex.context);
+ thd->lex->first_select_lex()->context.resolve_in_table_list_only(&tables);
+ set_fields(tables.db.str,
+ field_list, &thd->lex->first_select_lex()->context);
thd->variables.pseudo_thread_id= thread_id;
if (net)
{
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 38dbed92a22..39c36cdd529 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -4543,7 +4543,7 @@ double get_sweep_read_cost(const PARAM *param, ha_rows records)
if (max_cost != DBL_MAX && (busy_blocks+index_reads_cost) >= n_blocks)
return 1;
*/
- JOIN *join= param->thd->lex->select_lex.join;
+ JOIN *join= param->thd->lex->first_select_lex()->join;
if (!join || join->table_count == 1)
{
/* No join, assume reading is done in one 'sweep' */
diff --git a/sql/opt_table_elimination.cc b/sql/opt_table_elimination.cc
index ef9b07cca47..95743ecaad4 100644
--- a/sql/opt_table_elimination.cc
+++ b/sql/opt_table_elimination.cc
@@ -617,7 +617,7 @@ void eliminate_tables(JOIN *join)
we should also take into account tables mentioned in "val".
*/
if (join->thd->lex->sql_command == SQLCOM_INSERT_SELECT &&
- join->select_lex == &thd->lex->select_lex)
+ join->select_lex == thd->lex->first_select_lex())
{
List_iterator<Item> val_it(thd->lex->value_list);
while ((item= val_it++))
@@ -640,7 +640,7 @@ void eliminate_tables(JOIN *join)
used_tables |= (*(cur_list->item))->used_tables();
}
- if (join->select_lex == &thd->lex->select_lex)
+ if (join->select_lex == thd->lex->first_select_lex())
{
/* Multi-table UPDATE: don't eliminate tables referred from SET statement */
diff --git a/sql/set_var.cc b/sql/set_var.cc
index bf373dde905..0923682a486 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -730,7 +730,7 @@ int sql_set_variables(THD *thd, List<set_var_base> *var_list, bool free)
err:
if (free)
- free_underlaid_joins(thd, &thd->lex->select_lex);
+ free_underlaid_joins(thd, thd->lex->first_select_lex());
DBUG_RETURN(error);
}
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index f7847bae89d..7129f362fd2 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -317,7 +317,7 @@ sp_get_flags_for_command(LEX *lex)
- EXPLAIN DELETE ...
- ANALYZE DELETE ...
*/
- if (lex->select_lex.item_list.is_empty() &&
+ if (lex->first_select_lex()->item_list.is_empty() &&
!lex->describe && !lex->analyze_stmt)
flags= 0;
else
@@ -556,6 +556,7 @@ sp_head::sp_head(sp_package *parent, const Sp_handler *sph)
m_backpatch_goto.empty();
m_cont_backpatch.empty();
m_lex.empty();
+ m_stmt_lex.empty();
my_init_dynamic_array(&m_instr, sizeof(sp_instr *), 16, 8, MYF(0));
my_hash_init(&m_sptabs, system_charset_info, 0, 0, 0, sp_table_key, 0, 0);
my_hash_init(&m_sroutines, system_charset_info, 0, 0, 0, sp_sroutine_key,
@@ -830,13 +831,15 @@ sp_head::~sp_head()
THD::lex. It is safe to not update LEX::ptr because further query
string parsing and execution will be stopped anyway.
*/
+ DBUG_ASSERT(m_lex.elements == m_stmt_lex.elements);
while ((lex= (LEX *)m_lex.pop()))
{
THD *thd= lex->thd;
thd->lex->sphead= NULL;
lex_end(thd->lex);
delete thd->lex;
- thd->lex= thd->stmt_lex= lex;
+ thd->lex= lex;
+ thd->stmt_lex= m_stmt_lex.pop();
}
my_hash_free(&m_sptabs);
@@ -2285,6 +2288,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
if (!err_status)
{
err_status= execute(thd, TRUE);
+ DBUG_PRINT("info", ("execute returned %d", (int) err_status));
}
if (save_log_general)
@@ -2386,10 +2390,11 @@ sp_head::reset_lex(THD *thd, sp_lex_local *sublex)
{
DBUG_ENTER("sp_head::reset_lex");
LEX *oldlex= thd->lex;
+ LEX *oldstmtlex= thd->stmt_lex;
- thd->set_local_lex(sublex);
+ thd->set_local_lex(sublex, sublex);
- DBUG_RETURN(m_lex.push_front(oldlex));
+ DBUG_RETURN(m_lex.push_front(oldlex) || m_stmt_lex.push_front(oldstmtlex));
}
diff --git a/sql/sp_head.h b/sql/sp_head.h
index f588f79b599..f28e1919959 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -589,10 +589,12 @@ class sp_head :private Query_arena,
{
DBUG_ENTER("sp_head::restore_lex");
LEX *oldlex= (LEX *) m_lex.pop();
+ LEX *oldstmtlex= (LEX *) m_stmt_lex.pop();
if (!oldlex)
DBUG_RETURN(false); // Nothing to restore
LEX *sublex= thd->lex;
- if (thd->restore_from_local_lex_to_old_lex(oldlex))// This restores thd->lex
+ // This restores thd->lex and thd->stmt_lex
+ if (thd->restore_from_local_lex_to_old_lex(oldlex, oldstmtlex))
DBUG_RETURN(true);
if (!sublex->sp_lex_in_use)
{
@@ -858,6 +860,7 @@ class sp_head :private Query_arena,
sp_pcontext *m_pcont; ///< Parse context
List<LEX> m_lex; ///< Temp. store for the other lex
+ List<LEX> m_stmt_lex; ///< Temp. store for the other stmt_lex
DYNAMIC_ARRAY m_instr; ///< The "instructions"
enum backpatch_instr_type { GOTO, CPOP, HPOP };
diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc
index 2e9ae23d7f9..19b23cd59ee 100644
--- a/sql/sp_rcontext.cc
+++ b/sql/sp_rcontext.cc
@@ -227,9 +227,10 @@ bool Qualified_column_ident::resolve_type_ref(THD *thd, Column_definition *def)
// Make %TYPE variables see temporary tables that shadow permanent tables
thd->temporary_tables= open_tables_state_backup.temporary_tables;
- if ((table_list= lex.select_lex.add_table_to_list(thd, this, NULL, 0,
- TL_READ_NO_INSERT,
- MDL_SHARED_READ)) &&
+ if ((table_list=
+ lex.first_select_lex()->add_table_to_list(thd, this, NULL, 0,
+ TL_READ_NO_INSERT,
+ MDL_SHARED_READ)) &&
!check_table_access(thd, SELECT_ACL, table_list, TRUE, UINT_MAX, FALSE) &&
!open_tables_only_view_structure(thd, table_list,
thd->mdl_context.has_locks()))
@@ -285,9 +286,10 @@ bool Table_ident::resolve_table_rowtype_ref(THD *thd,
// Make %ROWTYPE variables see temporary tables that shadow permanent tables
thd->temporary_tables= open_tables_state_backup.temporary_tables;
- if ((table_list= lex.select_lex.add_table_to_list(thd, this, NULL, 0,
- TL_READ_NO_INSERT,
- MDL_SHARED_READ)) &&
+ if ((table_list=
+ lex.first_select_lex()->add_table_to_list(thd, this, NULL, 0,
+ TL_READ_NO_INSERT,
+ MDL_SHARED_READ)) &&
!check_table_access(thd, SELECT_ACL, table_list, TRUE, UINT_MAX, FALSE) &&
!open_tables_only_view_structure(thd, table_list,
thd->mdl_context.has_locks()))
diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc
index 82fc1cbfff7..610b1a9ffed 100644
--- a/sql/sql_admin.cc
+++ b/sql/sql_admin.cc
@@ -306,7 +306,7 @@ static bool open_only_one_table(THD* thd, TABLE_LIST* table,
bool is_view_operator_func)
{
LEX *lex= thd->lex;
- SELECT_LEX *select= &lex->select_lex;
+ SELECT_LEX *select= lex->first_select_lex();
TABLE_LIST *save_next_global, *save_next_local;
bool open_error;
save_next_global= table->next_global;
@@ -1295,7 +1295,7 @@ bool mysql_preload_keys(THD* thd, TABLE_LIST* tables)
bool Sql_cmd_analyze_table::execute(THD *thd)
{
LEX *m_lex= thd->lex;
- TABLE_LIST *first_table= m_lex->select_lex.table_list.first;
+ TABLE_LIST *first_table= m_lex->first_select_lex()->table_list.first;
bool res= TRUE;
thr_lock_type lock_type = TL_READ_NO_INSERT;
DBUG_ENTER("Sql_cmd_analyze_table::execute");
@@ -1315,7 +1315,7 @@ bool Sql_cmd_analyze_table::execute(THD *thd)
*/
res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
- m_lex->select_lex.table_list.first= first_table;
+ m_lex->first_select_lex()->table_list.first= first_table;
m_lex->query_tables= first_table;
error:
@@ -1326,7 +1326,7 @@ bool Sql_cmd_analyze_table::execute(THD *thd)
bool Sql_cmd_check_table::execute(THD *thd)
{
LEX *m_lex= thd->lex;
- TABLE_LIST *first_table= m_lex->select_lex.table_list.first;
+ TABLE_LIST *first_table= m_lex->first_select_lex()->table_list.first;
thr_lock_type lock_type = TL_READ_NO_INSERT;
bool res= TRUE;
DBUG_ENTER("Sql_cmd_check_table::execute");
@@ -1339,7 +1339,7 @@ bool Sql_cmd_check_table::execute(THD *thd)
lock_type, 0, 0, HA_OPEN_FOR_REPAIR, 0,
&handler::ha_check, &view_check);
- m_lex->select_lex.table_list.first= first_table;
+ m_lex->first_select_lex()->table_list.first= first_table;
m_lex->query_tables= first_table;
error:
@@ -1350,7 +1350,7 @@ bool Sql_cmd_check_table::execute(THD *thd)
bool Sql_cmd_optimize_table::execute(THD *thd)
{
LEX *m_lex= thd->lex;
- TABLE_LIST *first_table= m_lex->select_lex.table_list.first;
+ TABLE_LIST *first_table= m_lex->first_select_lex()->table_list.first;
bool res= TRUE;
DBUG_ENTER("Sql_cmd_optimize_table::execute");
@@ -1372,7 +1372,7 @@ bool Sql_cmd_optimize_table::execute(THD *thd)
*/
res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
- m_lex->select_lex.table_list.first= first_table;
+ m_lex->first_select_lex()->table_list.first= first_table;
m_lex->query_tables= first_table;
error:
@@ -1383,7 +1383,7 @@ bool Sql_cmd_optimize_table::execute(THD *thd)
bool Sql_cmd_repair_table::execute(THD *thd)
{
LEX *m_lex= thd->lex;
- TABLE_LIST *first_table= m_lex->select_lex.table_list.first;
+ TABLE_LIST *first_table= m_lex->first_select_lex()->table_list.first;
bool res= TRUE;
DBUG_ENTER("Sql_cmd_repair_table::execute");
@@ -1407,7 +1407,7 @@ bool Sql_cmd_repair_table::execute(THD *thd)
*/
res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
- m_lex->select_lex.table_list.first= first_table;
+ m_lex->first_select_lex()->table_list.first= first_table;
m_lex->query_tables= first_table;
error:
diff --git a/sql/sql_alter.cc b/sql/sql_alter.cc
index 77e0c9d5298..e4c84c1c3cb 100644
--- a/sql/sql_alter.cc
+++ b/sql/sql_alter.cc
@@ -201,7 +201,7 @@ bool Sql_cmd_alter_table::execute(THD *thd)
{
LEX *lex= thd->lex;
/* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */
- SELECT_LEX *select_lex= &lex->select_lex;
+ SELECT_LEX *select_lex= lex->first_select_lex();
/* first table of first SELECT_LEX */
TABLE_LIST *first_table= (TABLE_LIST*) select_lex->table_list.first;
/*
@@ -345,7 +345,7 @@ bool Sql_cmd_alter_table::execute(THD *thd)
bool Sql_cmd_discard_import_tablespace::execute(THD *thd)
{
/* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */
- SELECT_LEX *select_lex= &thd->lex->select_lex;
+ SELECT_LEX *select_lex= thd->lex->first_select_lex();
/* first table of first SELECT_LEX */
TABLE_LIST *table_list= (TABLE_LIST*) select_lex->table_list.first;
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 5ce6a6b001c..9ceede71792 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -7436,7 +7436,7 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
TABLE_LIST *first_select_table= (select_insert ?
tables->next_local:
0);
- SELECT_LEX *select_lex= select_insert ? &thd->lex->select_lex :
+ SELECT_LEX *select_lex= select_insert ? thd->lex->first_select_lex() :
thd->lex->current_select;
if (select_lex->first_cond_optimization)
{
@@ -7464,7 +7464,7 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
{
/* new counting for SELECT of INSERT ... SELECT command */
first_select_table= 0;
- thd->lex->select_lex.insert_tables= tablenr;
+ thd->lex->first_select_lex()->insert_tables= tablenr;
tablenr= 0;
}
if(table_list->jtbm_subselect)
@@ -8018,7 +8018,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves,
from subquery of VIEW, because tables of subquery belongs to VIEW
(see condition before prepare_check_option() call)
*/
- bool it_is_update= (select_lex == &thd->lex->select_lex) &&
+ bool it_is_update= (select_lex == thd->lex->first_select_lex()) &&
thd->lex->which_check_option_applicable();
bool save_is_item_list_lookup= select_lex->is_item_list_lookup;
TABLE_LIST *derived= select_lex->master_unit()->derived;
@@ -8034,7 +8034,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves,
for (table= tables; table; table= table->next_local)
{
- if (select_lex == &thd->lex->select_lex &&
+ if (select_lex == thd->lex->first_select_lex() &&
select_lex->first_cond_optimization &&
table->merged_for_insert &&
table->prepare_where(thd, conds, FALSE))
diff --git a/sql/sql_base.h b/sql/sql_base.h
index a6a85d47dc9..6cbf6005f04 100644
--- a/sql/sql_base.h
+++ b/sql/sql_base.h
@@ -358,10 +358,12 @@ inline bool setup_fields_with_no_wrap(THD *thd, Ref_ptr_array ref_pointer_array,
bool allow_sum_func)
{
bool res;
- thd->lex->select_lex.no_wrap_view_item= TRUE;
+ SELECT_LEX *first= thd->lex->first_select_lex();
+ DBUG_ASSERT(thd->lex->current_select == first);
+ first->no_wrap_view_item= TRUE;
res= setup_fields(thd, ref_pointer_array, item, column_usage,
sum_func_list, NULL, allow_sum_func);
- thd->lex->select_lex.no_wrap_view_item= FALSE;
+ first->no_wrap_view_item= FALSE;
return res;
}
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index c8f18556d50..9aee9e14870 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -4130,13 +4130,13 @@ Query_cache::is_cacheable(THD *thd, LEX *lex,
if (thd->lex->safe_to_cache_query &&
(thd->variables.query_cache_type == 1 ||
- (thd->variables.query_cache_type == 2 && (lex->select_lex.options &
- OPTION_TO_QUERY_CACHE))) &&
+ (thd->variables.query_cache_type == 2 &&
+ (lex->first_select_lex()->options & OPTION_TO_QUERY_CACHE))) &&
qc_is_able_to_intercept_result(thd))
{
DBUG_PRINT("qcache", ("options: %lx %lx type: %u",
(long) OPTION_TO_QUERY_CACHE,
- (long) lex->select_lex.options,
+ (long) lex->first_select_lex()->options,
(int) thd->variables.query_cache_type));
if (!(table_count= process_and_count_tables(thd, tables_used,
@@ -4157,7 +4157,7 @@ Query_cache::is_cacheable(THD *thd, LEX *lex,
("not interesting query: %d or not cacheable, options %lx %lx type: %u net->vio present: %u",
(int) lex->sql_command,
(long) OPTION_TO_QUERY_CACHE,
- (long) lex->select_lex.options,
+ (long) lex->first_select_lex()->options,
(int) thd->variables.query_cache_type,
(uint) MY_TEST(qc_is_able_to_intercept_result(thd))));
DBUG_RETURN(0);
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 7b7d34c6bc0..8f1deee3821 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1374,12 +1374,13 @@ void THD::init(bool skip_lock)
}
-bool THD::restore_from_local_lex_to_old_lex(LEX *oldlex)
+bool THD::restore_from_local_lex_to_old_lex(LEX *oldlex, LEX *oldstmtlex)
{
DBUG_ASSERT(lex->sphead);
if (lex->sphead->merge_lex(this, oldlex, lex))
return true;
lex= oldlex;
+ stmt_lex= oldstmtlex;
return false;
}
@@ -3798,6 +3799,7 @@ Statement::Statement(LEX *lex_arg, MEM_ROOT *mem_root_arg,
id(id_arg),
column_usage(MARK_COLUMNS_READ),
lex(lex_arg),
+ stmt_lex(lex_arg),
db(null_clex_str)
{
name= null_clex_str;
diff --git a/sql/sql_class.h b/sql/sql_class.h
index a7c33cbc504..b6476963727 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -4547,6 +4547,7 @@ class THD :public Statement,
TMP_TABLE_SHARE* save_tmp_table_share(TABLE *table);
void restore_tmp_table_share(TMP_TABLE_SHARE *share);
+ bool inline is_main_lex(LEX *lex) { return lex == &main_lex; }
private:
/* Whether a lock has been acquired? */
bool m_tmp_tables_locked;
@@ -4724,7 +4725,7 @@ class THD :public Statement,
/**
Switch to a sublex, to parse a substatement or an expression.
*/
- void set_local_lex(sp_lex_local *sublex)
+ void set_local_lex(sp_lex_local *sublex, LEX *stmtlex)
{
DBUG_ASSERT(lex->sphead);
lex= stmt_lex= sublex;
@@ -4743,7 +4744,7 @@ class THD :public Statement,
See also sp_head::merge_lex().
*/
- bool restore_from_local_lex_to_old_lex(LEX *oldlex);
+ bool restore_from_local_lex_to_old_lex(LEX *oldlex, LEX *oldstmtlex);
Item *sp_fix_func_item(Item **it_addr);
Item *sp_prepare_func_item(Item **it_addr, uint cols= 1);
@@ -6134,7 +6135,8 @@ class select_dumpvar :public select_result_interceptor {
inline bool add_item_to_list(THD *thd, Item *item)
{
- return thd->lex->current_select->add_item_to_list(thd, item);
+ bool res= thd->lex->current_select->add_item_to_list(thd, item);
+ return res;
}
inline bool add_value_to_list(THD *thd, Item *value)
diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc
index a58a9254a82..4a2ff42733e 100644
--- a/sql/sql_cte.cc
+++ b/sql/sql_cte.cc
@@ -55,6 +55,14 @@ bool With_clause::add_with_element(With_element *elem)
}
+void st_select_lex_unit::set_with_clause(With_clause *with_cl)
+{
+ with_clause= with_cl;
+ if (with_clause)
+ with_clause->set_owner(this);
+}
+
+
/**
@brief
Check dependencies between tables defined in a list of with clauses
@@ -683,7 +691,7 @@ void With_element::move_anchors_ahead()
st_select_lex *next_sl;
st_select_lex *new_pos= spec->first_select();
st_select_lex *UNINIT_VAR(last_sl);
- new_pos->linkage= UNION_TYPE;
+ new_pos->set_linkage(UNION_TYPE);
for (st_select_lex *sl= new_pos; sl; sl= next_sl)
{
next_sl= sl->next_select();
@@ -829,9 +837,8 @@ st_select_lex_unit *With_element::clone_parsed_spec(THD *thd,
if (parser_state.init(thd, (char*) unparsed_spec.str, (unsigned int)unparsed_spec.length))
goto err;
lex_start(thd);
- with_select= &lex->select_lex;
- with_select->select_number= ++thd->stmt_lex->current_select_number;
parse_status= parse_sql(thd, &parser_state, 0);
+ with_select= lex->first_select_lex();
if (parse_status)
goto err;
@@ -982,7 +989,7 @@ bool With_element::prepare_unreferenced(THD *thd)
rename_columns_of_derived_unit(thd, spec) ||
check_duplicate_names(thd, first_sl->item_list, 1)))
rc= true;
-
+
thd->lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_DERIVED;
return rc;
}
@@ -1094,6 +1101,7 @@ bool TABLE_LIST::set_as_with_table(THD *thd, With_element *with_elem)
return true;
}
derived->first_select()->linkage= DERIVED_TABLE_TYPE;
+ select_lex->add_statistics(derived);
with_elem->inc_references();
return false;
}
diff --git a/sql/sql_cte.h b/sql/sql_cte.h
index 16b473f0665..4a194b2a38f 100644
--- a/sql/sql_cte.h
+++ b/sql/sql_cte.h
@@ -279,8 +279,7 @@ class With_clause : public Sql_alloc
*/
With_clause *next_with_clause;
/* Set to true if dependencies between with elements have been checked */
- bool dependencies_are_checked;
-
+ bool dependencies_are_checked;
/*
The bitmap of all recursive with elements whose specifications
are not complied with restrictions imposed by the SQL standards
@@ -304,9 +303,8 @@ class With_clause : public Sql_alloc
bool with_recursive;
With_clause(bool recursive_fl, With_clause *emb_with_clause)
- : owner(NULL),
- embedding_with_clause(emb_with_clause), next_with_clause(NULL),
- dependencies_are_checked(false), unrestricted(0),
+ : owner(NULL), embedding_with_clause(emb_with_clause),
+ next_with_clause(NULL), dependencies_are_checked(false), unrestricted(0),
with_prepared_anchor(0), cleaned(0), stabilized(0),
with_recursive(recursive_fl)
{ }
@@ -320,8 +318,12 @@ class With_clause : public Sql_alloc
last_next= &this->next_with_clause;
}
+ st_select_lex_unit *get_owner() { return owner; }
+
void set_owner(st_select_lex_unit *unit) { owner= unit; }
+ void attach_to(st_select_lex *select_lex);
+
With_clause *pop() { return embedding_with_clause; }
bool check_dependencies();
@@ -354,7 +356,6 @@ bool With_element::is_unrestricted()
}
inline
-
bool With_element::is_with_prepared_anchor()
{
return owner->with_prepared_anchor & get_elem_map();
@@ -436,11 +437,14 @@ void With_element::prepare_for_next_iteration()
inline
-void st_select_lex_unit::set_with_clause(With_clause *with_cl)
-{
- with_clause= with_cl;
- if (with_clause)
- with_clause->set_owner(this);
+void With_clause::attach_to(st_select_lex *select_lex)
+{
+ for (With_element *with_elem= with_list.first;
+ with_elem;
+ with_elem= with_elem->next)
+ {
+ select_lex->register_unit(with_elem->spec, NULL);
+ }
}
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 0a12d01596b..4a8f4e71d1d 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -285,7 +285,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
bool has_triggers;
ORDER *order= (ORDER *) ((order_list && order_list->elements) ?
order_list->first : NULL);
- SELECT_LEX *select_lex= &thd->lex->select_lex;
+ SELECT_LEX *select_lex= thd->lex->first_select_lex();
killed_state killed_status= NOT_KILLED;
THD::enum_binlog_query_type query_type= THD::ROW_QUERY_TYPE;
bool binlog_is_row;
@@ -350,7 +350,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
DBUG_RETURN(TRUE);
}
table->map=1;
- query_plan.select_lex= &thd->lex->select_lex;
+ query_plan.select_lex= thd->lex->first_select_lex();
query_plan.table= table;
query_plan.updating_a_view= MY_TEST(table_list->view);
@@ -382,7 +382,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
setup_order(thd, select_lex->ref_pointer_array, &tables,
fields, all_fields, order))
{
- free_underlaid_joins(thd, &thd->lex->select_lex);
+ free_underlaid_joins(thd, thd->lex->first_select_lex());
DBUG_RETURN(TRUE);
}
}
@@ -926,14 +926,16 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list,
bool *delete_while_scanning)
{
Item *fake_conds= 0;
- SELECT_LEX *select_lex= &thd->lex->select_lex;
+ SELECT_LEX *select_lex= thd->lex->first_select_lex();
DBUG_ENTER("mysql_prepare_delete");
List<Item> all_fields;
*delete_while_scanning= true;
thd->lex->allow_sum_func= 0;
- if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
- &thd->lex->select_lex.top_join_list,
+ if (setup_tables_and_check_access(thd,
+ &thd->lex->first_select_lex()->context,
+ &thd->lex->first_select_lex()->
+ top_join_list,
table_list,
select_lex->leaf_tables, FALSE,
DELETE_ACL, SELECT_ACL, TRUE))
@@ -1015,21 +1017,23 @@ int mysql_multi_delete_prepare(THD *thd)
lex->query_tables also point on local list of DELETE SELECT_LEX
*/
- if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
- &thd->lex->select_lex.top_join_list,
+ if (setup_tables_and_check_access(thd,
+ &thd->lex->first_select_lex()->context,
+ &thd->lex->first_select_lex()->
+ top_join_list,
lex->query_tables,
- lex->select_lex.leaf_tables, FALSE,
- DELETE_ACL, SELECT_ACL, FALSE))
+ lex->first_select_lex()->leaf_tables,
+ FALSE, DELETE_ACL, SELECT_ACL, FALSE))
DBUG_RETURN(TRUE);
- if (lex->select_lex.handle_derived(thd->lex, DT_MERGE))
+ if (lex->first_select_lex()->handle_derived(thd->lex, DT_MERGE))
DBUG_RETURN(TRUE);
/*
Multi-delete can't be constructed over-union => we always have
single SELECT on top and have to check underlying SELECTs of it
*/
- lex->select_lex.exclude_from_table_unique_test= TRUE;
+ lex->first_select_lex()->exclude_from_table_unique_test= TRUE;
/* Fix tables-to-be-deleted-from list to point at opened tables */
for (target_tbl= (TABLE_LIST*) aux_tables;
target_tbl;
@@ -1071,8 +1075,8 @@ int mysql_multi_delete_prepare(THD *thd)
Reset the exclude flag to false so it doesn't interfare
with further calls to unique_table
*/
- lex->select_lex.exclude_from_table_unique_test= FALSE;
-
+ lex->first_select_lex()->exclude_from_table_unique_test= FALSE;
+
if (lex->save_prep_leaf_tables())
DBUG_RETURN(TRUE);
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index 2df740b6811..685b812196a 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -99,7 +99,8 @@ mysql_handle_derived(LEX *lex, uint phases)
processed normally.
*/
if (phases == DT_MERGE_FOR_INSERT &&
- cursor && cursor->top_table()->select_lex != &lex->select_lex)
+ cursor && (cursor->top_table()->select_lex !=
+ lex->first_select_lex()))
continue;
for (;
cursor && !res;
diff --git a/sql/sql_do.cc b/sql/sql_do.cc
index 20a7aa75590..72acbd763e1 100644
--- a/sql/sql_do.cc
+++ b/sql/sql_do.cc
@@ -33,7 +33,7 @@ bool mysql_do(THD *thd, List<Item> &values)
DBUG_RETURN(TRUE);
while ((value = li++))
(void) value->is_null();
- free_underlaid_joins(thd, &thd->lex->select_lex);
+ free_underlaid_joins(thd, thd->lex->first_select_lex());
if (thd->is_error())
{
diff --git a/sql/sql_error.cc b/sql/sql_error.cc
index 67440aeed33..160bf7469c5 100644
--- a/sql/sql_error.cc
+++ b/sql/sql_error.cc
@@ -781,7 +781,7 @@ bool mysqld_show_warnings(THD *thd, ulong levels_to_show)
List<Item> field_list;
MEM_ROOT *mem_root= thd->mem_root;
const Sql_condition *err;
- SELECT_LEX *sel= &thd->lex->select_lex;
+ SELECT_LEX *sel= thd->lex->first_select_lex();
SELECT_LEX_UNIT *unit= &thd->lex->unit;
ulonglong idx= 0;
Protocol *protocol=thd->protocol;
diff --git a/sql/sql_help.cc b/sql/sql_help.cc
index da38a2caf94..866bf86c733 100644
--- a/sql/sql_help.cc
+++ b/sql/sql_help.cc
@@ -87,7 +87,7 @@ enum enum_used_fields
static bool init_fields(THD *thd, TABLE_LIST *tables,
struct st_find_field *find_fields, uint count)
{
- Name_resolution_context *context= &thd->lex->select_lex.context;
+ Name_resolution_context *context= &thd->lex->first_select_lex()->context;
DBUG_ENTER("init_fields");
context->resolve_in_table_list_only(tables);
for (; count-- ; find_fields++)
@@ -719,10 +719,11 @@ static bool mysqld_help_internal(THD *thd, const char *mask)
Init tables and fields to be usable from items
tables do not contain VIEWs => we can pass 0 as conds
*/
- thd->lex->select_lex.context.table_list=
- thd->lex->select_lex.context.first_name_resolution_table= &tables[0];
- if (setup_tables(thd, &thd->lex->select_lex.context,
- &thd->lex->select_lex.top_join_list,
+ thd->lex->first_select_lex()->context.table_list=
+ thd->lex->first_select_lex()->context.first_name_resolution_table=
+ &tables[0];
+ if (setup_tables(thd, &thd->lex->first_select_lex()->context,
+ &thd->lex->first_select_lex()->top_join_list,
tables, leaves, FALSE, FALSE))
goto error;
memcpy((char*) used_fields, (char*) init_used_fields, sizeof(used_fields));
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 392aa52825e..aa51af80407 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -241,7 +241,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
}
else
{ // Part field list
- SELECT_LEX *select_lex= &thd->lex->select_lex;
+ SELECT_LEX *select_lex= thd->lex->first_select_lex();
Name_resolution_context *context= &select_lex->context;
Name_resolution_context_state ctx_state;
int res;
@@ -273,7 +273,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
/* Restore the current context. */
ctx_state.restore_state(context, table_list);
- thd->lex->select_lex.no_wrap_view_item= FALSE;
+ thd->lex->first_select_lex()->no_wrap_view_item= FALSE;
if (res)
DBUG_RETURN(-1);
@@ -657,7 +657,7 @@ static void save_insert_query_plan(THD* thd, TABLE_LIST *table_list)
bool skip= MY_TEST(table_list->view);
/* Save subquery children */
- for (SELECT_LEX_UNIT *unit= thd->lex->select_lex.first_inner_unit();
+ for (SELECT_LEX_UNIT *unit= thd->lex->first_select_lex()->first_inner_unit();
unit;
unit= unit->next_unit())
{
@@ -783,7 +783,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
/* mysql_prepare_insert sets table_list->table if it was not set */
table= table_list->table;
- context= &thd->lex->select_lex.context;
+ context= &thd->lex->first_select_lex()->context;
/*
These three asserts test the hypothesis that the resetting of the name
resolution context below is not necessary at all since the list of local
@@ -1073,7 +1073,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
} while (bulk_parameters_iterations(thd));
values_loop_end:
- free_underlaid_joins(thd, &thd->lex->select_lex);
+ free_underlaid_joins(thd, thd->lex->first_select_lex());
joins_freed= TRUE;
/*
@@ -1261,7 +1261,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
table->file->ha_release_auto_increment();
if (!joins_freed)
- free_underlaid_joins(thd, &thd->lex->select_lex);
+ free_underlaid_joins(thd, thd->lex->first_select_lex());
thd->abort_on_warning= 0;
DBUG_RETURN(retval);
}
@@ -1291,7 +1291,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
static bool check_view_insertability(THD * thd, TABLE_LIST *view)
{
- uint num= view->view->select_lex.item_list.elements;
+ uint num= view->view->first_select_lex()->item_list.elements;
TABLE *table= view->table;
Field_translator *trans_start= view->field_translation,
*trans_end= trans_start + num;
@@ -1391,10 +1391,12 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list,
than INSERT.
*/
- if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
- &thd->lex->select_lex.top_join_list,
+ if (setup_tables_and_check_access(thd,
+ &thd->lex->first_select_lex()->context,
+ &thd->lex->first_select_lex()->
+ top_join_list,
table_list,
- thd->lex->select_lex.leaf_tables,
+ thd->lex->first_select_lex()->leaf_tables,
select_insert, INSERT_ACL, SELECT_ACL,
TRUE))
DBUG_RETURN(TRUE);
@@ -1402,7 +1404,7 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list,
if (insert_into_view && !fields.elements)
{
thd->lex->empty_field_list_on_rset= 1;
- if (!thd->lex->select_lex.leaf_tables.head()->table ||
+ if (!thd->lex->first_select_lex()->leaf_tables.head()->table ||
table_list->is_multitable())
{
my_error(ER_VIEW_NO_INSERT_FIELD_LIST, MYF(0),
@@ -1476,7 +1478,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
enum_duplicates duplic, COND **where,
bool select_insert)
{
- SELECT_LEX *select_lex= &thd->lex->select_lex;
+ SELECT_LEX *select_lex= thd->lex->first_select_lex();
Name_resolution_context *context= &select_lex->context;
Name_resolution_context_state ctx_state;
bool insert_into_view= (table_list->view != 0);
@@ -3530,7 +3532,7 @@ bool Delayed_insert::handle_inserts(void)
bool mysql_insert_select_prepare(THD *thd)
{
LEX *lex= thd->lex;
- SELECT_LEX *select_lex= &lex->select_lex;
+ SELECT_LEX *select_lex= lex->first_select_lex();
DBUG_ENTER("mysql_insert_select_prepare");
@@ -3619,7 +3621,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
select, LEX::current_select should point to the first select while
we are fixing fields from insert list.
*/
- lex->current_select= &lex->select_lex;
+ lex->current_select= lex->first_select_lex();
res= (setup_fields(thd, Ref_ptr_array(),
values, MARK_COLUMNS_READ, 0, NULL, 0) ||
@@ -3636,7 +3638,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
if (info.handle_duplicates == DUP_UPDATE && !res)
{
- Name_resolution_context *context= &lex->select_lex.context;
+ Name_resolution_context *context= &lex->first_select_lex()->context;
Name_resolution_context_state ctx_state;
/* Save the state of the current name resolution context. */
@@ -3646,7 +3648,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
table_list->next_local= 0;
context->resolve_in_table_list_only(table_list);
- lex->select_lex.no_wrap_view_item= TRUE;
+ lex->first_select_lex()->no_wrap_view_item= TRUE;
res= res ||
check_update_fields(thd, context->table_list,
*info.update_fields, *info.update_values,
@@ -3657,15 +3659,15 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
*/
true,
&map);
- lex->select_lex.no_wrap_view_item= FALSE;
+ lex->first_select_lex()->no_wrap_view_item= FALSE;
/*
When we are not using GROUP BY and there are no ungrouped aggregate functions
we can refer to other tables in the ON DUPLICATE KEY part.
We use next_name_resolution_table descructively, so check it first (views?)
*/
DBUG_ASSERT (!table_list->next_name_resolution_table);
- if (lex->select_lex.group_list.elements == 0 &&
- !lex->select_lex.with_sum_func)
+ if (lex->first_select_lex()->group_list.elements == 0 &&
+ !lex->first_select_lex()->with_sum_func)
/*
We must make a single context out of the two separate name resolution contexts :
the INSERT table and the tables in the SELECT part of INSERT ... SELECT.
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 6f1d8b815fe..db055eb012e 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -176,7 +176,7 @@ init_lex_with_single_table(THD *thd, TABLE *table, LEX *lex)
{
TABLE_LIST *table_list;
Table_ident *table_ident;
- SELECT_LEX *select_lex= &lex->select_lex;
+ SELECT_LEX *select_lex= lex->first_select_lex();
Name_resolution_context *context= &select_lex->context;
/*
We will call the parser to create a part_info struct based on the
@@ -673,20 +673,26 @@ void LEX::start(THD *thd_arg)
this, thd_arg->lex, thd_arg->stmt_lex));
thd= unit.thd= thd_arg;
-
+ DBUG_PRINT("info", ("Lex %p stmt_lex: %p", thd->lex, thd->stmt_lex));
+
DBUG_ASSERT(!explain);
context_stack.empty();
+ //empty select_stack
+ select_stack_top= 0;
unit.init_query();
- current_select_number= 1;
- select_lex.linkage= UNSPECIFIED_TYPE;
+ current_select_number= 0;
+ builtin_select.linkage= UNSPECIFIED_TYPE;
+ builtin_select.set_linkage(UNSPECIFIED_TYPE);
+ builtin_select.distinct= TRUE;
/* 'parent_lex' is used in init_query() so it must be before it. */
- select_lex.parent_lex= this;
- select_lex.init_query();
+ builtin_select.parent_lex= this;
+ builtin_select.init_query();
curr_with_clause= 0;
with_clauses_list= 0;
with_clauses_list_last_next= &with_clauses_list;
create_view= NULL;
+ field_list.empty();
value_list.empty();
update_list.empty();
set_var_list.empty();
@@ -700,17 +706,17 @@ void LEX::start(THD *thd_arg)
auxiliary_table_list.empty();
unit.next= unit.master= unit.link_next= unit.return_to= 0;
unit.prev= unit.link_prev= 0;
- unit.slave= current_select= all_selects_list= &select_lex;
- select_lex.master= &unit;
- select_lex.prev= &unit.slave;
- select_lex.link_next= select_lex.slave= select_lex.next= 0;
- select_lex.link_prev= (st_select_lex_node**)&(all_selects_list);
- select_lex.options= 0;
- select_lex.sql_cache= SELECT_LEX::SQL_CACHE_UNSPECIFIED;
- select_lex.init_order();
- select_lex.group_list.empty();
- if (select_lex.group_list_ptrs)
- select_lex.group_list_ptrs->clear();
+ unit.slave= current_select= all_selects_list= &builtin_select;
+ builtin_select.master= &unit;
+ builtin_select.prev= &unit.slave;
+ builtin_select.link_next= builtin_select.slave= builtin_select.next= 0;
+ builtin_select.link_prev= (st_select_lex_node**)&(all_selects_list);
+ builtin_select.options= 0;
+ builtin_select.sql_cache= SELECT_LEX::SQL_CACHE_UNSPECIFIED;
+ builtin_select.init_order();
+ builtin_select.group_list.empty();
+ if (builtin_select.group_list_ptrs)
+ builtin_select.group_list_ptrs->clear();
describe= 0;
analyze_stmt= 0;
explain_json= false;
@@ -720,14 +726,14 @@ void LEX::start(THD *thd_arg)
safe_to_cache_query= 1;
parsing_options.reset();
empty_field_list_on_rset= 0;
- select_lex.select_number= 1;
+ builtin_select.select_number= 1;
part_info= 0;
- select_lex.in_sum_expr=0;
- select_lex.ftfunc_list_alloc.empty();
- select_lex.ftfunc_list= &select_lex.ftfunc_list_alloc;
- select_lex.group_list.empty();
- select_lex.order_list.empty();
- select_lex.gorder_list.empty();
+ builtin_select.in_sum_expr=0;
+ builtin_select.ftfunc_list_alloc.empty();
+ builtin_select.ftfunc_list= &builtin_select.ftfunc_list_alloc;
+ builtin_select.group_list.empty();
+ builtin_select.order_list.empty();
+ builtin_select.gorder_list.empty();
m_sql_cmd= NULL;
duplicates= DUP_ERROR;
ignore= 0;
@@ -739,6 +745,8 @@ void LEX::start(THD *thd_arg)
query_tables= 0;
reset_query_tables_list(FALSE);
expr_allows_subselect= TRUE;
+ selects_allow_into= FALSE;
+ selects_allow_procedure= FALSE;
use_only_table_context= FALSE;
parse_vcol_expr= FALSE;
check_exists= FALSE;
@@ -748,8 +756,8 @@ void LEX::start(THD *thd_arg)
name= null_clex_str;
event_parse_data= NULL;
profile_options= PROFILE_NONE;
- nest_level=0 ;
- select_lex.nest_level_base= &unit;
+ nest_level= 0;
+ builtin_select.nest_level_base= &unit;
allow_sum_func= 0;
in_sum_func= NULL;
@@ -773,6 +781,13 @@ void LEX::start(THD *thd_arg)
vers_conditions.empty();
is_lex_started= TRUE;
+
+ next_is_main= FALSE;
+ next_is_down= FALSE;
+
+ wild= 0;
+ exchange= 0;
+
DBUG_VOID_RETURN;
}
@@ -1308,7 +1323,8 @@ int MYSQLlex(YYSTYPE *yylval, THD *thd)
{
Lex_input_stream *lip= & thd->m_parser_state->m_lip;
int token;
-
+ const int left_paren= (int) '(';
+
if (lip->lookahead_token >= 0)
{
/*
@@ -1325,6 +1341,8 @@ int MYSQLlex(YYSTYPE *yylval, THD *thd)
token= lex_one_token(yylval, thd);
lip->add_digest_token(token, yylval);
+ SELECT_LEX *curr_sel= thd->lex->current_select;
+
switch(token) {
case WITH:
/*
@@ -1375,8 +1393,16 @@ int MYSQLlex(YYSTYPE *yylval, THD *thd)
}
break;
case VALUES:
- if (thd->lex->current_select->parsing_place == IN_UPDATE_ON_DUP_KEY ||
- thd->lex->current_select->parsing_place == IN_PART_FUNC)
+ if (curr_sel &&
+ (curr_sel->parsing_place == BEFORE_OPT_LIST ||
+ curr_sel->parsing_place == AFTER_LIST))
+ {
+ curr_sel->parsing_place= NO_MATTER;
+ break;
+ }
+ if (curr_sel &&
+ (curr_sel->parsing_place == IN_UPDATE_ON_DUP_KEY ||
+ curr_sel->parsing_place == IN_PART_FUNC))
return VALUE_SYM;
token= lex_one_token(yylval, thd);
lip->add_digest_token(token, yylval);
@@ -1391,6 +1417,43 @@ int MYSQLlex(YYSTYPE *yylval, THD *thd)
lip->lookahead_token= token;
return VALUES;
}
+ case VALUE_SYM:
+ if (curr_sel &&
+ (curr_sel->parsing_place == BEFORE_OPT_LIST ||
+ curr_sel->parsing_place == AFTER_LIST))
+ {
+ curr_sel->parsing_place= NO_MATTER;
+ return VALUES;
+ }
+ break;
+ case PARTITION_SYM:
+ case SELECT_SYM:
+ case UNION_SYM:
+ if (curr_sel &&
+ (curr_sel->parsing_place == BEFORE_OPT_LIST ||
+ curr_sel->parsing_place == AFTER_LIST))
+ {
+ curr_sel->parsing_place= NO_MATTER;
+ }
+ break;
+ case left_paren:
+ if (!curr_sel ||
+ curr_sel->parsing_place != BEFORE_OPT_LIST)
+ return token;
+ token= lex_one_token(yylval, thd);
+ lip->add_digest_token(token, yylval);
+ lip->lookahead_yylval= lip->yylval;
+ lip->yylval= NULL;
+ lip->lookahead_token= token;
+ curr_sel->parsing_place= NO_MATTER;
+ if (token == LIKE)
+ return LEFT_PAREN_LIKE;
+ if (token == WITH)
+ return LEFT_PAREN_WITH;
+ if (token != left_paren && token != SELECT_SYM)
+ return LEFT_PAREN_ALT;
+ else
+ return left_paren;
break;
default:
break;
@@ -1888,7 +1951,7 @@ static int lex_one_token(YYSTYPE *yylval, THD *thd)
return(TEXT_STRING);
}
case MY_LEX_COMMENT: // Comment
- lex->select_lex.options|= OPTION_FOUND_COMMENT;
+ lex->builtin_select.options|= OPTION_FOUND_COMMENT;
while ((c = lip->yyGet()) != '\n' && c) ;
lip->yyUnget(); // Safety against eof
state = MY_LEX_START; // Try again
@@ -1899,7 +1962,7 @@ static int lex_one_token(YYSTYPE *yylval, THD *thd)
state=MY_LEX_CHAR; // Probable division
break;
}
- lex->select_lex.options|= OPTION_FOUND_COMMENT;
+ lex->builtin_select.options|= OPTION_FOUND_COMMENT;
/* Reject '/' '*', since we might need to turn off the echo */
lip->yyUnget();
@@ -2184,7 +2247,8 @@ void st_select_lex_node::init_query_common()
{
options= 0;
sql_cache= SQL_CACHE_UNSPECIFIED;
- linkage= UNSPECIFIED_TYPE;
+ set_linkage(UNSPECIFIED_TYPE);
+ distinct= TRUE;
no_table_names_allowed= 0;
uncacheable= 0;
}
@@ -2192,7 +2256,7 @@ void st_select_lex_node::init_query_common()
void st_select_lex_unit::init_query()
{
init_query_common();
- linkage= GLOBAL_OPTIONS_TYPE;
+ set_linkage(GLOBAL_OPTIONS_TYPE);
select_limit_cnt= HA_POS_ERROR;
offset_limit_cnt= 0;
union_distinct= 0;
@@ -2233,16 +2297,6 @@ void st_select_lex::init_query()
having_fix_field= 0;
context.select_lex= this;
context.init();
- /*
- Add the name resolution context of the current (sub)query to the
- stack of contexts for the whole query.
- TODO:
- push_context may return an error if there is no memory for a new
- element in the stack, however this method has no return value,
- thus push_context should be moved to a place where query
- initialization is checked for failure.
- */
- parent_lex->push_context(&context, parent_lex->thd->mem_root);
cond_count= between_count= with_wild= 0;
max_equal_elems= 0;
ref_pointer_array.reset();
@@ -2297,6 +2351,7 @@ void st_select_lex::init_select()
/* Set limit and offset to default values */
select_limit= 0; /* denotes the default limit = HA_POS_ERROR */
offset_limit= 0; /* denotes the default offset = 0 */
+ is_set_query_expr_tail= false;
with_sum_func= 0;
is_correlated= 0;
cur_pos_in_select_list= UNDEF_POS;
@@ -2357,6 +2412,23 @@ void st_select_lex_node::add_slave(st_select_lex_node *slave_arg)
}
}
+void st_select_lex_node::link_chain_down(st_select_lex_node *first)
+{
+ st_select_lex_node *last_node;
+ st_select_lex_node *node= first;
+ do
+ {
+ last_node= node;
+ node->master= this;
+ node= node->next;
+ } while (node);
+ if ((last_node->next= slave))
+ {
+ slave->prev= &last_node->next;
+ }
+ first->prev= &slave;
+ slave= first;
+}
/*
include on level down (but do not link)
@@ -2406,7 +2478,7 @@ void st_select_lex_node::fast_exclude()
// Remove slave structure
for (; slave; slave= slave->next)
slave->fast_exclude();
-
+
}
@@ -3083,6 +3155,7 @@ LEX::LEX()
gtid_domain_static_buffer,
initial_gtid_domain_buffer_size,
initial_gtid_domain_buffer_size, 0);
+ unit.slave= &builtin_select;
}
@@ -3109,12 +3182,12 @@ bool LEX::can_be_merged()
// TODO: do not forget implement case when select_lex.table_list.elements==0
/* find non VIEW subqueries/unions */
- bool selects_allow_merge= (select_lex.next_select() == 0 &&
- !(select_lex.uncacheable &
+ bool selects_allow_merge= (first_select_lex()->next_select() == 0 &&
+ !(first_select_lex()->uncacheable &
UNCACHEABLE_RAND));
if (selects_allow_merge)
{
- for (SELECT_LEX_UNIT *tmp_unit= select_lex.first_inner_unit();
+ for (SELECT_LEX_UNIT *tmp_unit= first_select_lex()->first_inner_unit();
tmp_unit;
tmp_unit= tmp_unit->next_unit())
{
@@ -3131,12 +3204,12 @@ bool LEX::can_be_merged()
}
return (selects_allow_merge &&
- select_lex.group_list.elements == 0 &&
- select_lex.having == 0 &&
- select_lex.with_sum_func == 0 &&
- select_lex.table_list.elements >= 1 &&
- !(select_lex.options & SELECT_DISTINCT) &&
- select_lex.select_limit == 0);
+ first_select_lex()->group_list.elements == 0 &&
+ first_select_lex()->having == 0 &&
+ first_select_lex()->with_sum_func == 0 &&
+ first_select_lex()->table_list.elements >= 1 &&
+ !(first_select_lex()->options & SELECT_DISTINCT) &&
+ first_select_lex()->select_limit == 0);
}
@@ -3489,7 +3562,7 @@ void LEX::set_trg_event_type_for_tables()
Do not iterate over sub-selects, only the tables in the outermost
SELECT_LEX can be modified, if any.
*/
- TABLE_LIST *tables= select_lex.get_table_list();
+ TABLE_LIST *tables= first_select_lex()->get_table_list();
while (tables)
{
@@ -3545,12 +3618,13 @@ TABLE_LIST *LEX::unlink_first_table(bool *link_to_local)
/*
and from local list if it is not empty
*/
- if ((*link_to_local= MY_TEST(select_lex.table_list.first)))
+ if ((*link_to_local= MY_TEST(first_select_lex()->table_list.first)))
{
- select_lex.context.table_list=
- select_lex.context.first_name_resolution_table= first->next_local;
- select_lex.table_list.first= first->next_local;
- select_lex.table_list.elements--; //safety
+ first_select_lex()->context.table_list=
+ first_select_lex()->context.first_name_resolution_table=
+ first->next_local;
+ first_select_lex()->table_list.first= first->next_local;
+ first_select_lex()->table_list.elements--; //safety
first->next_local= 0;
/*
Ensure that the global list has the same first table as the local
@@ -3581,7 +3655,7 @@ TABLE_LIST *LEX::unlink_first_table(bool *link_to_local)
void LEX::first_lists_tables_same()
{
- TABLE_LIST *first_table= select_lex.table_list.first;
+ TABLE_LIST *first_table= first_select_lex()->table_list.first;
if (query_tables != first_table && first_table != 0)
{
TABLE_LIST *next;
@@ -3606,6 +3680,23 @@ void LEX::first_lists_tables_same()
}
}
+void LEX::fix_first_select_number()
+{
+ SELECT_LEX *first= first_select_lex();
+ if (first && first->select_number != 1)
+ {
+ uint num= first->select_number;
+ for (SELECT_LEX *sel= all_selects_list;
+ sel;
+ sel= sel->next_select_in_list())
+ {
+ if (sel->select_number < num)
+ sel->select_number++;
+ }
+ first->select_number= 1;
+ }
+}
+
/*
Link table back that was unlinked with unlink_first_table()
@@ -3631,10 +3722,10 @@ void LEX::link_first_table_back(TABLE_LIST *first,
if (link_to_local)
{
- first->next_local= select_lex.table_list.first;
- select_lex.context.table_list= first;
- select_lex.table_list.first= first;
- select_lex.table_list.elements++; //safety
+ first->next_local= first_select_lex()->table_list.first;
+ first_select_lex()->context.table_list= first;
+ first_select_lex()->table_list.first= first;
+ first_select_lex()->table_list.elements++; //safety
}
}
}
@@ -3663,19 +3754,19 @@ void LEX::cleanup_after_one_table_open()
NOTE: all units will be connected to thd->lex->select_lex, because we
have not UNION on most upper level.
*/
- if (all_selects_list != &select_lex)
+ if (all_selects_list != first_select_lex())
{
derived_tables= 0;
- select_lex.exclude_from_table_unique_test= false;
+ first_select_lex()->exclude_from_table_unique_test= false;
/* cleunup underlying units (units of VIEW) */
- for (SELECT_LEX_UNIT *un= select_lex.first_inner_unit();
+ for (SELECT_LEX_UNIT *un= first_select_lex()->first_inner_unit();
un;
un= un->next_unit())
un->cleanup();
/* reduce all selects list to default state */
- all_selects_list= &select_lex;
+ all_selects_list= first_select_lex();
/* remove underlying units (units of VIEW) subtree */
- select_lex.cut_subtree();
+ first_select_lex()->cut_subtree();
}
}
@@ -4541,7 +4632,7 @@ void st_select_lex::set_explain_type(bool on_the_fly)
using_materialization= TRUE;
}
- if (&master_unit()->thd->lex->select_lex == this)
+ if (master_unit()->thd->lex->first_select_lex() == this)
{
type= is_primary ? "PRIMARY" : "SIMPLE";
}
@@ -4736,8 +4827,8 @@ bool LEX::save_prep_leaf_tables()
Query_arena *arena= thd->stmt_arena, backup;
arena= thd->activate_stmt_arena_if_needed(&backup);
//It is used for DETETE/UPDATE so top level has only one SELECT
- DBUG_ASSERT(select_lex.next_select() == NULL);
- bool res= select_lex.save_prep_leaf_tables(thd);
+ DBUG_ASSERT(first_select_lex()->next_select() == NULL);
+ bool res= first_select_lex()->save_prep_leaf_tables(thd);
if (arena)
thd->restore_active_arena(arena, &backup);
@@ -5066,8 +5157,13 @@ bool LEX::is_partition_management() const
SELECT_LEX *LEX::exclude_last_select()
{
- DBUG_ENTER("SELECT_LEX::exclude_last_select");
- SELECT_LEX *exclude= current_select;
+ return exclude_not_first_select(current_select);
+}
+
+SELECT_LEX *LEX::exclude_not_first_select(SELECT_LEX *exclude)
+{
+ DBUG_ENTER("LEX::exclude_not_first_select");
+ DBUG_PRINT("enter", ("exclude %p #%u", exclude, exclude->select_number));
SELECT_LEX_UNIT *unit= exclude->master_unit();
SELECT_LEX *sl;
DBUG_ASSERT(unit->first_select() != exclude);
@@ -5078,13 +5174,228 @@ SELECT_LEX *LEX::exclude_last_select()
DBUG_PRINT("info", ("excl: %p unit: %p prev: %p", exclude, unit, sl));
if (!sl)
DBUG_RETURN(NULL);
- DBUG_ASSERT(exclude->next_select() == NULL);
- exclude->exclude_from_tree();
+ DBUG_ASSERT(&sl->next == exclude->prev);
+
+ exclude->prev= NULL;
+
current_select= sl;
DBUG_RETURN(exclude);
}
+SELECT_LEX_UNIT *LEX::alloc_unit()
+{
+ SELECT_LEX_UNIT *unit;
+ DBUG_ENTER("LEX::alloc_unit");
+ if (!(unit= new (thd->mem_root) SELECT_LEX_UNIT()))
+ DBUG_RETURN(NULL);
+
+ unit->init_query();
+ /* TODO: reentrant problem */
+ unit->thd= thd;
+ unit->link_next= 0;
+ unit->link_prev= 0;
+ /* TODO: remove return_to */
+ unit->return_to= NULL;
+ DBUG_RETURN(unit);
+}
+
+
+SELECT_LEX *LEX::alloc_select(bool select)
+{
+ SELECT_LEX *select_lex;
+ DBUG_ENTER("LEX::alloc_select");
+ if (!(select_lex= new (thd->mem_root) SELECT_LEX()))
+ DBUG_RETURN(NULL);
+ DBUG_PRINT("info", ("Allocate select: %p #%u statement lex: %p",
+ select_lex, thd->stmt_lex->current_select_number,
+ thd->stmt_lex));
+ select_lex->select_number= ++thd->stmt_lex->current_select_number;
+ select_lex->parent_lex= this; /* Used in init_query. */
+ select_lex->init_query();
+ if (select)
+ select_lex->init_select();
+ select_lex->nest_level_base= &this->unit;
+ select_lex->include_global((st_select_lex_node**)&all_selects_list);
+ select_lex->context.resolve_in_select_list= TRUE;
+ DBUG_RETURN(select_lex);
+}
+
+SELECT_LEX_UNIT *
+LEX::create_unit(SELECT_LEX *first_sel)
+{
+ SELECT_LEX_UNIT *unit;
+ DBUG_ENTER("LEX::create_unit");
+
+ if (!(unit= alloc_unit()))
+ DBUG_RETURN(NULL);
+
+ unit->register_select_chain(first_sel);
+ if (first_sel->next_select())
+ {
+ unit->reset_distinct();
+ DBUG_ASSERT(!unit->fake_select_lex);
+ if (unit->add_fake_select_lex(thd))
+ DBUG_RETURN(NULL);
+ }
+ DBUG_RETURN(unit);
+}
+
+SELECT_LEX_UNIT *
+SELECT_LEX::attach_selects_chain(SELECT_LEX *first_sel,
+ Name_resolution_context *context)
+{
+ SELECT_LEX_UNIT *unit;
+ DBUG_ENTER("SELECT_LEX::attach_select_chain");
+
+ if (!(unit= parent_lex->alloc_unit()))
+ DBUG_RETURN(NULL);
+
+ unit->register_select_chain(first_sel);
+ register_unit(unit, context);
+ if (first_sel->next_select())
+ {
+ unit->reset_distinct();
+ DBUG_ASSERT(!unit->fake_select_lex);
+ if (unit->add_fake_select_lex(parent_lex->thd))
+ DBUG_RETURN(NULL);
+ }
+
+ DBUG_RETURN(unit);
+}
+
+SELECT_LEX *
+LEX::wrap_unit_into_derived(SELECT_LEX_UNIT *unit)
+{
+ SELECT_LEX *wrapping_sel;
+ Table_ident *ti;
+ DBUG_ENTER("LEX::wrap_unit_into_derived");
+
+ if (!(wrapping_sel= alloc_select(TRUE)))
+ DBUG_RETURN(NULL);
+ Name_resolution_context *context= &wrapping_sel->context;
+ context->init();
+ wrapping_sel->automatic_brackets= FALSE;
+
+ wrapping_sel->register_unit(unit, context);
+
+ /* stuff dummy SELECT * FROM (...) */
+
+ if (push_select(wrapping_sel)) // for Items & TABLE_LIST
+ DBUG_RETURN(NULL);
+
+ /* add SELECT list*/
+ {
+ Item *item= new (thd->mem_root)
+ Item_field(thd, context, NULL, NULL, &star_clex_str);
+ if (item == NULL)
+ goto err;
+ if (add_item_to_list(thd, item))
+ goto err;
+ (wrapping_sel->with_wild)++;
+ }
+
+ unit->first_select()->set_linkage(DERIVED_TABLE_TYPE);
+
+ ti= new (thd->mem_root) Table_ident(unit);
+ if (ti == NULL)
+ goto err;
+ {
+ char buff[10];
+ TABLE_LIST *table_list;
+ LEX_CSTRING alias;
+ alias.length= my_snprintf(buff, sizeof(buff),
+ "__%u", wrapping_sel->select_number);
+ alias.str= thd->strmake(buff, alias.length);
+ if (!alias.str)
+ goto err;
+
+ if (!(table_list= wrapping_sel->add_table_to_list(thd, ti, &alias,
+ 0, TL_READ,
+ MDL_SHARED_READ)))
+ goto err;
+
+ context->resolve_in_table_list_only(table_list);
+ wrapping_sel->add_joined_table(table_list);
+ }
+
+ pop_select();
+
+ derived_tables|= DERIVED_SUBQUERY;
+
+ DBUG_RETURN(wrapping_sel);
+
+err:
+ pop_select();
+ DBUG_RETURN(NULL);
+}
+
+SELECT_LEX *LEX::link_selects_chain_down(SELECT_LEX *sel)
+{
+ SELECT_LEX *dummy_select;
+ SELECT_LEX_UNIT *unit;
+ Table_ident *ti;
+ DBUG_ENTER("LEX::link_selects_chain_down");
+
+ if (!(dummy_select= alloc_select(TRUE)))
+ DBUG_RETURN(NULL);
+ Name_resolution_context *context= &dummy_select->context;
+ dummy_select->automatic_brackets= FALSE;
+
+ if (!(unit= dummy_select->attach_selects_chain(sel, context)))
+ DBUG_RETURN(NULL);
+
+ /* stuff dummy SELECT * FROM (...) */
+
+ if (push_select(dummy_select)) // for Items & TABLE_LIST
+ DBUG_RETURN(NULL);
+
+ /* add SELECT list*/
+ {
+ Item *item= new (thd->mem_root)
+ Item_field(thd, context, NULL, NULL, &star_clex_str);
+ if (item == NULL)
+ goto err;
+ if (add_item_to_list(thd, item))
+ goto err;
+ (dummy_select->with_wild)++;
+ }
+
+ sel->set_linkage(DERIVED_TABLE_TYPE);
+
+ ti= new (thd->mem_root) Table_ident(unit);
+ if (ti == NULL)
+ goto err;
+ {
+ char buff[10];
+ TABLE_LIST *table_list;
+ LEX_CSTRING alias;
+ alias.length= my_snprintf(buff, sizeof(buff),
+ "__%u", dummy_select->select_number);
+ alias.str= thd->strmake(buff, alias.length);
+ if (!alias.str)
+ goto err;
+
+ if (!(table_list= dummy_select->add_table_to_list(thd, ti, &alias,
+ 0, TL_READ,
+ MDL_SHARED_READ)))
+ goto err;
+
+ context->resolve_in_table_list_only(table_list);
+ dummy_select->add_joined_table(table_list);
+ }
+
+ pop_select();
+
+ derived_tables|= DERIVED_SUBQUERY;
+
+ DBUG_RETURN(dummy_select);
+
+err:
+ pop_select();
+ DBUG_RETURN(NULL);
+}
+
/**
Put given (new) SELECT_LEX level below after currect (last) SELECT
@@ -5107,13 +5418,43 @@ SELECT_LEX *LEX::exclude_last_select()
bool LEX::add_unit_in_brackets(SELECT_LEX *nselect)
{
DBUG_ENTER("LEX::add_unit_in_brackets");
- bool distinct= nselect->master_unit()->union_distinct == nselect;
- bool rc= add_select_to_union_list(distinct, nselect->linkage, 0);
- if (rc)
+ SELECT_LEX_UNIT *unit= nselect->master_unit();
+ int old_nest_level= nselect->nest_level;
+ bool distinct= unit->union_distinct == nselect;
+ if (add_select_to_union_list(distinct, nselect->linkage, 0))
DBUG_RETURN(TRUE);
- SELECT_LEX* dummy_select= current_select;
- dummy_select->automatic_brackets= TRUE;
- dummy_select->linkage= nselect->linkage;
+
+ SELECT_LEX *dummy= current_select;
+ dummy->next= NULL;
+ if (make_select_in_brackets(current_select, nselect, FALSE))
+ DBUG_RETURN(TRUE);
+
+ if (!distinct && nselect->master_unit()->union_distinct)
+ {
+ // move distinct pointer
+ if (unit->union_distinct->master_unit() != unit)
+ {
+ unit->union_distinct->master_unit()->union_distinct= unit->union_distinct;
+ unit->union_distinct= NULL;
+ }
+ }
+ else if (distinct)
+ unit->union_distinct= NULL;// distinct was moved by add_select_to_union_list
+
+ dummy->set_nest_level(old_nest_level);
+ DBUG_RETURN(FALSE);
+}
+
+
+bool LEX::make_select_in_brackets(SELECT_LEX* dummy_select,
+ SELECT_LEX *nselect, bool automatic)
+{
+ DBUG_ENTER("LEX::make_select_in_brackets");
+
+ int old_nest_level= nselect->nest_level;
+ dummy_select->automatic_brackets= automatic;
+ dummy_select->set_linkage(nselect->linkage);
+ current_select= dummy_select; // for mysql_new_select & Items
/* stuff dummy SELECT * FROM (...) */
Name_resolution_context *context= &dummy_select->context;
@@ -5128,12 +5469,19 @@ bool LEX::add_unit_in_brackets(SELECT_LEX *nselect)
DBUG_RETURN(TRUE);
(dummy_select->with_wild)++;
- rc= mysql_new_select(this, 1, nselect);
- nselect->linkage= DERIVED_TABLE_TYPE;
- DBUG_ASSERT(nselect->outer_select() == dummy_select);
+ nselect->set_linkage(DERIVED_TABLE_TYPE);
+ SELECT_LEX *sl= nselect;
+ bool down= TRUE;
+ do{
+ SELECT_LEX *next= sl->next_select();
+ if (mysql_new_select(this, down, sl))
+ DBUG_RETURN(TRUE);
+ down= FALSE;
+ DBUG_ASSERT(sl->outer_select() == dummy_select);
+ sl= next;
+ } while (sl);
current_select= dummy_select;
- current_select->nest_level--;
SELECT_LEX_UNIT *unit= nselect->master_unit();
Table_ident *ti= new (thd->mem_root) Table_ident(unit);
@@ -5157,11 +5505,63 @@ bool LEX::add_unit_in_brackets(SELECT_LEX *nselect)
derived_tables|= DERIVED_SUBQUERY;
+ if (dummy_select->set_nest_level(old_nest_level))
+ DBUG_RETURN(TRUE);
+
current_select= nselect;
- current_select->nest_level++;
- DBUG_RETURN(rc);
+ DBUG_RETURN(FALSE);
}
+bool LEX::push_context(Name_resolution_context *context)
+{
+ DBUG_ENTER("LEX::push_context");
+ DBUG_PRINT("info", ("Context: %p Select: %p (%d)",
+ context, context->select_lex,
+ (context->select_lex ?
+ context->select_lex->select_number:
+ 0)));
+ bool res= context_stack.push_front(context, thd->mem_root);
+ DBUG_RETURN(res);
+}
+
+
+bool LEX::push_new_select(SELECT_LEX *last)
+{
+ DBUG_ENTER("LEX::push new_select");
+ DBUG_PRINT("info", ("Push last select: %p (%d)",
+ last, last->select_number));
+ bool res= last_select_stack.push_front(last, thd->mem_root);
+ DBUG_RETURN(res);
+}
+
+
+bool check_intersect_prefix(SELECT_LEX* first_in_unit)
+{
+ SELECT_LEX *sel;
+ for (sel= first_in_unit->next_select();
+ sel && sel->linkage == INTERSECT_TYPE;
+ sel= sel->next_select())
+ ;
+ return (sel == NULL);
+}
+
+
+SELECT_LEX *LEX::pop_new_select_and_wrap()
+{
+ DBUG_ENTER("LEX::pop_new_select_and_wrap");
+ SELECT_LEX *sel;
+ SELECT_LEX *last= pop_new_select();
+ SELECT_LEX *first= last->next_select();
+ last->cut_next();
+ enum sub_select_type op= first->linkage;
+ bool ds= first->distinct;
+ if (!(sel= link_selects_chain_down(first)))
+ DBUG_RETURN(NULL);
+ last->link_neighbour(sel);
+ sel->set_linkage_and_distinct(op, ds);
+ sel->set_master_unit(last->master_unit());
+ DBUG_RETURN(sel);
+}
/**
Checks if we need finish "automatic brackets" mode
@@ -6559,7 +6959,6 @@ Item_param *LEX::add_placeholder(THD *thd, const LEX_CSTRING *name,
my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
return NULL;
}
-
Query_fragment pos(thd, sphead, start, end);
Item_param *item= new (thd->mem_root) Item_param(thd, name,
pos.pos(), pos.length());
@@ -7415,6 +7814,156 @@ Item *st_select_lex::build_cond_for_grouping_fields(THD *thd, Item *cond,
}
+bool st_select_lex::set_nest_level(int new_nest_level)
+{
+ DBUG_ENTER("st_select_lex::set_nest_level");
+ DBUG_PRINT("enter", ("select #%d %p nest level: %d",
+ select_number, this, new_nest_level));
+ if (new_nest_level > (int) MAX_SELECT_NESTING)
+ {
+ my_error(ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT, MYF(0));
+ DBUG_RETURN(TRUE);
+ }
+ nest_level= new_nest_level;
+ new_nest_level++;
+ for (SELECT_LEX_UNIT *u= first_inner_unit(); u; u= u->next_unit())
+ {
+ if (u->set_nest_level(new_nest_level))
+ DBUG_RETURN(TRUE);
+ }
+ DBUG_RETURN(FALSE);
+}
+
+bool st_select_lex_unit::set_nest_level(int new_nest_level)
+{
+ DBUG_ENTER("st_select_lex_unit::set_nest_level");
+ for(SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
+ {
+ if (sl->set_nest_level(new_nest_level))
+ DBUG_RETURN(TRUE);
+ }
+ if (fake_select_lex &&
+ fake_select_lex->set_nest_level(new_nest_level))
+ DBUG_RETURN(TRUE);
+ DBUG_RETURN(FALSE);
+}
+
+
+bool st_select_lex::check_parameters(SELECT_LEX *main_select)
+{
+ DBUG_ENTER("st_select_lex::check_parameters");
+ DBUG_PRINT("enter", ("select #%d %p nest level: %d",
+ select_number, this, nest_level));
+
+
+ if ((options & OPTION_INTO_CLAUSE) &&
+ (!parent_lex->selects_allow_into ||
+ next_select() != NULL ||
+ nest_level != 0))
+ {
+ my_error(ER_CANT_USE_OPTION_HERE, MYF(0), "INTO");
+ DBUG_RETURN(TRUE);
+ }
+
+ if (options & OPTION_PROCEDURE_CLAUSE)
+ {
+ if (!parent_lex->selects_allow_procedure ||
+ next_select() != NULL ||
+ this != master_unit()->first_select() ||
+ nest_level != 0)
+ {
+ my_error(ER_CANT_USE_OPTION_HERE, MYF(0), "PROCEDURE");
+ DBUG_RETURN(TRUE);
+ }
+ if (options & OPTION_INTO_CLAUSE)
+ {
+ my_error(ER_CANT_USE_OPTION_HERE, MYF(0), "INTO");
+ DBUG_RETURN(TRUE);
+ }
+ }
+
+ if ((options & SELECT_HIGH_PRIORITY) && this != main_select)
+ {
+ my_error(ER_CANT_USE_OPTION_HERE, MYF(0), "HIGH_PRIORITY");
+ DBUG_RETURN(TRUE);
+ }
+ if ((options & OPTION_BUFFER_RESULT) && this != main_select)
+ {
+ my_error(ER_CANT_USE_OPTION_HERE, MYF(0), "SQL_BUFFER_RESULT");
+ DBUG_RETURN(TRUE);
+ }
+ if ((options & OPTION_FOUND_ROWS) && this != main_select)
+ {
+ my_error(ER_CANT_USE_OPTION_HERE, MYF(0), "SQL_CALC_FOUND_ROWS");
+ DBUG_RETURN(TRUE);
+ }
+ if (options & OPTION_NO_QUERY_CACHE)
+ {
+ /*
+ Allow this flag only on the first top-level SELECT statement, if
+ SQL_CACHE wasn't specified.
+ */
+ if (this != main_select)
+ {
+ my_error(ER_CANT_USE_OPTION_HERE, MYF(0), "SQL_NO_CACHE");
+ DBUG_RETURN(TRUE);
+ }
+ if (main_select->sql_cache == SELECT_LEX::SQL_CACHE)
+ {
+ my_error(ER_WRONG_USAGE, MYF(0), "SQL_CACHE", "SQL_NO_CACHE");
+ DBUG_RETURN(TRUE);
+ }
+ parent_lex->safe_to_cache_query=0;
+ main_select->sql_cache= SELECT_LEX::SQL_NO_CACHE;
+ }
+ if (options & OPTION_TO_QUERY_CACHE)
+ {
+ /*
+ Allow this flag only on the first top-level SELECT statement, if
+ SQL_NO_CACHE wasn't specified.
+ */
+ if (this != main_select)
+ {
+ my_error(ER_CANT_USE_OPTION_HERE, MYF(0), "SQL_CACHE");
+ DBUG_RETURN(TRUE);
+ }
+ if (main_select->sql_cache == SELECT_LEX::SQL_NO_CACHE)
+ {
+ my_error(ER_WRONG_USAGE, MYF(0), "SQL_NO_CACHE", "SQL_CACHE");
+ DBUG_RETURN(TRUE);
+ }
+ parent_lex->safe_to_cache_query=1;
+ main_select->sql_cache= SELECT_LEX::SQL_CACHE;
+ }
+
+ for (SELECT_LEX_UNIT *u= first_inner_unit(); u; u= u->next_unit())
+ {
+ if (u->check_parameters(main_select))
+ DBUG_RETURN(TRUE);
+ }
+ DBUG_RETURN(FALSE);
+}
+
+
+bool st_select_lex_unit::check_parameters(SELECT_LEX *main_select)
+{
+ for(SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
+ {
+ if (sl->check_parameters(main_select))
+ return TRUE;
+ }
+ return fake_select_lex && fake_select_lex->check_parameters(main_select);
+}
+
+
+bool LEX::check_main_unit_semantics()
+{
+ if (unit.set_nest_level(0) ||
+ unit.check_parameters(first_select_lex()))
+ return TRUE;
+ return FALSE;
+}
+
int set_statement_var_if_exists(THD *thd, const char *var_name,
size_t var_name_length, ulonglong value)
{
@@ -7468,10 +8017,10 @@ bool LEX::create_or_alter_view_finalize(THD *thd, Table_ident *table_ident)
{
sql_command= SQLCOM_CREATE_VIEW;
/* first table in list is target VIEW name */
- if (!select_lex.add_table_to_list(thd, table_ident, NULL,
- TL_OPTION_UPDATING,
- TL_IGNORE,
- MDL_EXCLUSIVE))
+ if (!first_select_lex()->add_table_to_list(thd, table_ident, NULL,
+ TL_OPTION_UPDATING,
+ TL_IGNORE,
+ MDL_EXCLUSIVE))
return true;
query_tables->open_strategy= TABLE_LIST::OPEN_STUB;
return false;
@@ -7881,3 +8430,221 @@ void st_select_lex::pushdown_cond_into_where_clause(THD *thd, Item *cond,
*remaining_cond= cond;
}
+
+
+void st_select_lex_unit::reset_distinct()
+{
+ union_distinct= NULL;
+ for(SELECT_LEX *sl= first_select()->next_select();
+ sl;
+ sl= sl->next_select())
+ {
+ if (sl->distinct)
+ {
+ union_distinct= sl;
+ return;
+ }
+ }
+}
+
+
+void st_select_lex_unit::fix_distinct(st_select_lex_unit *new_unit)
+{
+ if (union_distinct)
+ {
+ if (this != union_distinct->master_unit())
+ {
+ DBUG_ASSERT(new_unit == union_distinct->master_unit());
+ new_unit->union_distinct= union_distinct;
+ reset_distinct();
+ }
+ else
+ new_unit->reset_distinct();
+ }
+}
+
+
+void st_select_lex_unit::register_select_chain(SELECT_LEX *first_sel)
+{
+ DBUG_ASSERT(first_sel != 0);
+ slave= first_sel;
+ first_sel->prev= &slave;
+ for(SELECT_LEX *sel=first_sel; sel; sel= sel->next_select())
+ {
+ sel->master= (st_select_lex_node *)this;
+ uncacheable|= sel->uncacheable;
+ }
+}
+
+
+void st_select_lex::register_unit(SELECT_LEX_UNIT *unit,
+ Name_resolution_context *outer_context)
+{
+ if ((unit->next= slave))
+ slave->prev= &unit->next;
+ unit->prev= &slave;
+ slave= unit;
+ unit->master= this;
+ uncacheable|= unit->uncacheable;
+
+ for(SELECT_LEX *sel= unit->first_select();sel; sel= sel->next_select())
+ {
+ sel->context.outer_context= outer_context;
+ }
+}
+
+
+void st_select_lex::add_statistics(SELECT_LEX_UNIT *unit)
+{
+ for (;
+ unit;
+ unit= unit->next_unit())
+ for(SELECT_LEX *child= unit->first_select();
+ child;
+ child= child->next_select())
+ {
+ /*
+ A subselect can add fields to an outer select.
+ Reserve space for them.
+ */
+ select_n_where_fields+= child->select_n_where_fields;
+ /*
+ Aggregate functions in having clause may add fields
+ to an outer select. Count them also.
+ */
+ select_n_having_items+= child->select_n_having_items;
+ }
+}
+
+
+bool LEX::main_select_push()
+{
+ DBUG_ENTER("LEX::main_select_push");
+ current_select_number= 1;
+ builtin_select.select_number= 1;
+ if (push_select(&builtin_select))
+ DBUG_RETURN(TRUE);
+ DBUG_RETURN(FALSE);
+}
+
+bool Lex_order_limit_lock::set_to(SELECT_LEX *sel)
+{
+ /*TODO: lock */
+ //if (lock.defined_lock && sel == sel->master_unit()->fake_select_lex)
+ // return TRUE;
+ if (lock.defined_timeout)
+ {
+ THD *thd= sel->parent_lex->thd;
+ if (set_statement_var_if_exists(thd,
+ C_STRING_WITH_LEN("lock_wait_timeout"),
+ lock.timeout) ||
+ set_statement_var_if_exists(thd,
+ C_STRING_WITH_LEN("innodb_lock_wait_timeout"),
+ lock.timeout))
+ return TRUE;
+ }
+ if (lock.defined_lock)
+ {
+ sel->parent_lex->safe_to_cache_query= 0;
+ if (lock.update_lock)
+ {
+ sel->lock_type= TL_WRITE;
+ sel->set_lock_for_tables(TL_WRITE);
+ }
+ else
+ {
+ sel->lock_type= TL_READ_WITH_SHARED_LOCKS;
+ sel->set_lock_for_tables(TL_READ_WITH_SHARED_LOCKS);
+ }
+ }
+ sel->explicit_limit= limit.explicit_limit;
+ sel->select_limit= limit.select_limit;
+ sel->offset_limit= limit.offset_limit;
+ if (order_list)
+ {
+ if (sel->linkage != GLOBAL_OPTIONS_TYPE &&
+ sel->olap != UNSPECIFIED_OLAP_TYPE &&
+ (sel->linkage != UNION_TYPE || sel->braces))
+ {
+ my_error(ER_WRONG_USAGE, MYF(0),
+ "CUBE/ROLLUP", "ORDER BY");
+ return TRUE;
+ }
+ sel->order_list= *(order_list);
+ }
+ sel->is_set_query_expr_tail= true;
+ return FALSE;
+}
+
+
+static void change_item_list_context(List<Item> *list,
+ Name_resolution_context *context)
+{
+ List_iterator_fast<Item> it (*list);
+ Item *item;
+ while((item= it++))
+ {
+ item->walk(&Item::change_context_processor, FALSE, (void *)context);
+ }
+}
+
+
+bool LEX::insert_select_hack(SELECT_LEX *sel)
+{
+ DBUG_ENTER("LEX::insert_select_hack");
+
+ DBUG_ASSERT(first_select_lex() == &builtin_select);
+ DBUG_ASSERT(sel != NULL);
+
+ DBUG_ASSERT(builtin_select.first_inner_unit() == NULL);
+
+ if (builtin_select.link_prev)
+ {
+ if ((*builtin_select.link_prev= builtin_select.link_next))
+ ((st_select_lex *)builtin_select.link_next)->link_prev=
+ builtin_select.link_prev;
+ builtin_select.link_prev= NULL; // indicator of removal
+ }
+
+ set_main_unit(sel->master_unit());
+
+ DBUG_ASSERT(builtin_select.table_list.elements == 1);
+ TABLE_LIST *insert_table= builtin_select.table_list.first;
+
+ if (!(insert_table->next_local= sel->table_list.first))
+ {
+ sel->table_list.next= &insert_table->next_local;
+ }
+ sel->table_list.first= insert_table;
+ sel->table_list.elements++;
+ insert_table->select_lex= sel;
+
+ sel->context.first_name_resolution_table= insert_table;
+ builtin_select.context= sel->context;
+ change_item_list_context(&field_list, &sel->context);
+
+ if (sel->tvc && !sel->next_select() &&
+ (sql_command == SQLCOM_INSERT_SELECT ||
+ sql_command == SQLCOM_REPLACE_SELECT))
+ {
+ DBUG_PRINT("info", ("'Usual' INSERT detected"));
+ many_values= sel->tvc->lists_of_values;
+ sel->options= sel->tvc->select_options;
+ sel->tvc= NULL;
+ if (sql_command == SQLCOM_INSERT_SELECT)
+ sql_command= SQLCOM_INSERT;
+ else
+ sql_command= SQLCOM_REPLACE;
+ }
+
+
+ for (SELECT_LEX *sel= all_selects_list;
+ sel;
+ sel= sel->next_select_in_list())
+ {
+ if (sel->select_number != 1)
+ sel->select_number--;
+ };
+
+ DBUG_RETURN(FALSE);
+}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 89e3abe284f..4fc74474d56 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -74,6 +74,16 @@ enum sub_select_type
UNION_TYPE, INTERSECT_TYPE, EXCEPT_TYPE,
GLOBAL_OPTIONS_TYPE, DERIVED_TABLE_TYPE, OLAP_TYPE
};
+
+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(op2 >= UNION_TYPE && op2 <= EXCEPT_TYPE);
+ return (op1 == INTERSECT_TYPE ? 1 : 0) - (op2 == INTERSECT_TYPE ? 1 : 0);
+}
+
+bool check_intersect_prefix(SELECT_LEX* first_in_unit);
+
enum unit_common_op {OP_MIX, OP_UNION, OP_INTERSECT, OP_EXCEPT};
enum enum_view_suid
@@ -193,6 +203,7 @@ struct LEX_TYPE
additional "partitions" column even if partitioning is not compiled in.
*/
#define DESCRIBE_PARTITIONS 4
+#define DESCRIBE_EXTENDED2 8
#ifdef MYSQL_SERVER
@@ -431,7 +442,7 @@ class Index_hint : public Sql_alloc
unit is container of either
- One SELECT
- UNION of selects
- select_lex and unit are both inherited form select_lex_node
+ select_lex and unit are both inherited form st_select_lex_node
neighbors are two select_lex or units on the same level
All select describing structures linked with following pointers:
@@ -577,6 +588,7 @@ class st_select_lex_node {
{
return linkage == UNION_TYPE || linkage == INTERSECT_TYPE || linkage == EXCEPT_TYPE;
}
+ bool distinct;
bool no_table_names_allowed; /* used for global order by */
static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
@@ -597,10 +609,29 @@ class st_select_lex_node {
void include_down(st_select_lex_node *upper);
void add_slave(st_select_lex_node *slave_arg);
void include_neighbour(st_select_lex_node *before);
+ void link_chain_down(st_select_lex_node *first);
+ void link_neighbour(st_select_lex_node *neighbour)
+ {
+ DBUG_ASSERT(next == NULL);
+ DBUG_ASSERT(neighbour != NULL);
+ next= neighbour;
+ neighbour->prev= &next;
+ }
+ void cut_next() { next= NULL; }
void include_standalone(st_select_lex_node *sel, st_select_lex_node **ref);
void include_global(st_select_lex_node **plink);
void exclude();
void exclude_from_tree();
+ void exclude_from_global()
+ {
+ if (!link_prev)
+ return;
+ if (((*link_prev)= link_next))
+ link_next->link_prev= link_prev;
+ link_next= NULL;
+ link_prev= NULL;
+ }
+
void set_slave(st_select_lex_node *slave_arg) { slave= slave_arg; }
void move_node(st_select_lex_node *where_to_move)
@@ -616,6 +647,22 @@ class st_select_lex_node {
st_select_lex_node *insert_chain_before(st_select_lex_node **ptr_pos_to_insert,
st_select_lex_node *end_chain_node);
void move_as_slave(st_select_lex_node *new_master);
+ void set_linkage(enum sub_select_type l)
+ {
+ DBUG_ENTER("st_select_lex_node::set_linkage");
+ DBUG_PRINT("info", ("node: %p linkage: %d->%d", this, linkage, l));
+ linkage= l;
+ DBUG_VOID_RETURN;
+ }
+ /*
+ This method created for reiniting LEX in mysql_admin_table() and can be
+ used only if you are going remove all SELECT_LEX & units except belonger
+ to LEX (LEX::unit & LEX::select, for other purposes there are
+ SELECT_LEX_UNIT::exclude_level & SELECT_LEX_UNIT::exclude_tree.
+
+ It is also used in parsing to detach builtin select.
+ */
+ void cut_subtree() { slave= 0; }
friend class st_select_lex_unit;
friend bool mysql_new_select(LEX *lex, bool move_down, SELECT_LEX *sel);
friend bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
@@ -625,6 +672,8 @@ class st_select_lex_node {
friend bool mysql_derived_merge(THD *thd, LEX *lex,
TABLE_LIST *orig_table_list);
friend bool TABLE_LIST::init_derived(THD *thd, bool init_view);
+
+ friend class st_select_lex;
private:
void fast_exclude();
};
@@ -670,9 +719,9 @@ class st_select_lex_unit: public st_select_lex_node {
{
}
-
TABLE *table; /* temporary table using for appending UNION results */
select_result *result;
+ st_select_lex *pre_last_parse;
bool prepared, // prepare phase already performed for UNION (unit)
optimized, // optimize phase already performed for UNION (unit)
optimized_2,
@@ -759,7 +808,7 @@ class st_select_lex_unit: public st_select_lex_node {
{
return reinterpret_cast<st_select_lex*>(slave);
}
- inline void set_with_clause(With_clause *with_cl);
+ void set_with_clause(With_clause *with_cl);
st_select_lex_unit* next_unit()
{
return reinterpret_cast<st_select_lex_unit*>(next);
@@ -801,6 +850,16 @@ class st_select_lex_unit: public st_select_lex_node {
int save_union_explain(Explain_query *output);
int save_union_explain_part2(Explain_query *output);
unit_common_op common_op();
+
+ void reset_distinct();
+ void fix_distinct(st_select_lex_unit *new_unit);
+
+ void register_select_chain(SELECT_LEX *first_sel);
+
+ bool set_nest_level(int new_nest_level);
+ bool check_parameters(SELECT_LEX *main_select);
+
+ friend class st_select_lex;
};
typedef class st_select_lex_unit SELECT_LEX_UNIT;
@@ -922,6 +981,7 @@ class st_select_lex: public st_select_lex_node
SQL_I_List<ORDER> order_list; /* ORDER clause */
SQL_I_List<ORDER> gorder_list;
Item *select_limit, *offset_limit; /* LIMIT clause parameters */
+ bool is_set_query_expr_tail;
/// Array of pointers to top elements of all_fields list
Ref_ptr_array ref_pointer_array;
@@ -1052,6 +1112,10 @@ class st_select_lex: public st_select_lex_node
void init_query();
void init_select();
st_select_lex_unit* master_unit() { return (st_select_lex_unit*) master; }
+ inline void set_master_unit(st_select_lex_unit *master_unit)
+ {
+ master= (st_select_lex_node *)master_unit;
+ }
st_select_lex_unit* first_inner_unit()
{
return (st_select_lex_unit*) slave;
@@ -1288,6 +1352,32 @@ class st_select_lex: public st_select_lex_node
DBUG_ASSERT(this != sel);
select_n_where_fields+= sel->select_n_where_fields;
}
+ inline void set_linkage_and_distinct(enum sub_select_type l, bool d)
+ {
+ DBUG_ENTER("SELECT_LEX::set_linkage_and_distinct");
+ DBUG_PRINT("info", ("select: %p distinct %d", this, d));
+ set_linkage(l);
+ DBUG_ASSERT(l == UNION_TYPE ||
+ l == INTERSECT_TYPE ||
+ l == EXCEPT_TYPE);
+ if (d && master_unit() && master_unit()->union_distinct != this)
+ master_unit()->union_distinct= this;
+ distinct= d;
+ DBUG_VOID_RETURN;
+ }
+ bool set_nest_level(int new_nest_level);
+ bool check_parameters(SELECT_LEX *main_select);
+ void mark_select()
+ {
+ DBUG_ENTER("st_select_lex::mark_select()");
+ DBUG_PRINT("info", ("Select #%d", select_number));
+ DBUG_VOID_RETURN;
+ }
+ void register_unit(SELECT_LEX_UNIT *unit,
+ Name_resolution_context *outer_context);
+ SELECT_LEX_UNIT *attach_selects_chain(SELECT_LEX *sel,
+ Name_resolution_context *context);
+ void add_statistics(SELECT_LEX_UNIT *unit);
};
typedef class st_select_lex SELECT_LEX;
@@ -2669,7 +2759,8 @@ class Query_arena_memroot;
struct LEX: public Query_tables_list
{
SELECT_LEX_UNIT unit; /* most upper unit */
- SELECT_LEX select_lex; /* first SELECT_LEX */
+ inline SELECT_LEX *first_select_lex() {return unit.first_select();}
+ SELECT_LEX builtin_select;
/* current SELECT_LEX in parsing */
SELECT_LEX *current_select;
/* list of all SELECT_LEX */
@@ -2779,6 +2870,9 @@ struct LEX: public Query_tables_list
required a local context, the parser pops the top-most context.
*/
List<Name_resolution_context> context_stack;
+ List<SELECT_LEX> last_select_stack;
+ SELECT_LEX *select_stack[MAX_SELECT_NESTING];
+ uint select_stack_top;
SQL_I_List<ORDER> proc_list;
SQL_I_List<TABLE_LIST> auxiliary_table_list, save_list;
@@ -2818,6 +2912,8 @@ struct LEX: public Query_tables_list
syntax error back.
*/
bool expr_allows_subselect;
+ bool selects_allow_into;
+ bool selects_allow_procedure;
/*
A special command "PARSE_VCOL_EXPR" is defined for the parser
to translate a defining expression of a virtual column into an
@@ -2872,6 +2968,8 @@ struct LEX: public Query_tables_list
enum enum_yes_no_unknown tx_chain, tx_release;
bool safe_to_cache_query;
bool subqueries, ignore;
+ bool next_is_main; // use "main" SELECT_LEX for nrxt allocation;
+ bool next_is_down; // use "main" SELECT_LEX for nrxt allocation;
st_parsing_options parsing_options;
Alter_info alter_info;
/*
@@ -3073,20 +3171,24 @@ struct LEX: public Query_tables_list
SELECT_LEX *sl;
SELECT_LEX_UNIT *un;
for (sl= current_select, un= sl->master_unit();
- un != &unit;
- sl= sl->outer_select(), un= sl->master_unit())
+ un && un != &unit;
+ sl= sl->outer_select(), un= (sl ? sl->master_unit() : NULL))
{
- sl->uncacheable|= cause;
- un->uncacheable|= cause;
+ sl->uncacheable|= cause;
+ un->uncacheable|= cause;
}
- select_lex.uncacheable|= cause;
+ if (sl)
+ sl->uncacheable|= cause;
}
+ if (first_select_lex())
+ first_select_lex()->uncacheable|= cause;
}
void set_trg_event_type_for_tables();
TABLE_LIST *unlink_first_table(bool *link_to_local);
void link_first_table_back(TABLE_LIST *first, bool link_to_local);
void first_lists_tables_same();
+ void fix_first_select_number();
bool can_be_merged();
bool can_use_merged();
@@ -3124,14 +3226,90 @@ struct LEX: public Query_tables_list
void cleanup_after_one_table_open();
- bool push_context(Name_resolution_context *context, MEM_ROOT *mem_root)
+ bool push_context(Name_resolution_context *context);
+
+ void pop_context()
{
- return context_stack.push_front(context, mem_root);
+ DBUG_ENTER("LEX::pop_context");
+ Name_resolution_context *context= context_stack.pop();
+ DBUG_PRINT("info", ("Pop context %p Select: %p (%d)",
+ context, context->select_lex,
+ (context->select_lex ?
+ context->select_lex->select_number:
+ 0)));
+ DBUG_VOID_RETURN;
}
- void pop_context()
+ bool push_new_select(SELECT_LEX *last);
+
+ SELECT_LEX *pop_new_select()
+ {
+ DBUG_ENTER("LEX::pop_new_select");
+ SELECT_LEX* last= last_select_stack.pop();
+ DBUG_PRINT("info", ("Pop last elect: %p (%d)",
+ last, last->select_number));
+ DBUG_RETURN(last);
+ }
+
+ SELECT_LEX *select_stack_head()
+ {
+ if (likely(select_stack_top))
+ return select_stack[select_stack_top - 1];
+ return NULL;
+ }
+
+
+ bool push_select(SELECT_LEX *select_lex)
+ {
+ DBUG_ENTER("LEX::push_select");
+ DBUG_PRINT("info", ("Top Select was %p (%d) depth: %u pushed: %p (%d)",
+ select_stack_head(),
+ select_stack_top,
+ (select_stack_top ?
+ select_stack_head()->select_number :
+ 0),
+ select_lex, select_lex->select_number));
+ if (unlikely(select_stack_top == MAX_SELECT_NESTING))
+ {
+ my_error(ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT, MYF(0));
+ DBUG_RETURN(TRUE);
+ }
+ if (push_context(&select_lex->context))
+ DBUG_RETURN(TRUE);
+ select_stack[select_stack_top++]= select_lex;
+ current_select= select_lex;
+ DBUG_RETURN(FALSE);
+ }
+
+ SELECT_LEX *pop_select()
{
- context_stack.pop();
+ DBUG_ENTER("LEX::pop_select");
+ SELECT_LEX *select_lex;
+ if (likely(select_stack_top))
+ select_lex= select_stack[--select_stack_top];
+ else
+ select_lex= 0;
+ DBUG_PRINT("info", ("Top Select is %p (%d) depth: %u poped: %p (%d)",
+ select_stack_head(),
+ select_stack_top,
+ (select_stack_top ?
+ select_stack_head()->select_number :
+ 0),
+ select_lex,
+ (select_lex ? select_lex->select_number : 0)));
+ DBUG_ASSERT(select_lex);
+
+ pop_context();
+
+ if (unlikely(!select_stack_top))
+ {
+ current_select= NULL;
+ DBUG_PRINT("info", ("Top Select is empty"));
+ }
+ else
+ current_select= select_stack[select_stack_top - 1];
+
+ DBUG_RETURN(select_lex);
}
bool copy_db_to(LEX_CSTRING *to);
@@ -3165,9 +3343,8 @@ struct LEX: public Query_tables_list
on its top. So select_lex (as the first added) will be at the tail
of the list.
*/
- if (&select_lex == all_selects_list && !sroutines.records)
+ if (first_select_lex() == all_selects_list && !sroutines.records)
{
- DBUG_ASSERT(!all_selects_list->next_select_in_list());
return TRUE;
}
return FALSE;
@@ -3736,6 +3913,7 @@ struct LEX: public Query_tables_list
bool if_exists() const { return create_info.if_exists(); }
SELECT_LEX *exclude_last_select();
+ SELECT_LEX *exclude_not_first_select(SELECT_LEX *exclude);
bool add_unit_in_brackets(SELECT_LEX *nselect);
void check_automatic_up(enum sub_select_type type);
bool create_or_alter_view_finalize(THD *thd, Table_ident *table_ident);
@@ -3744,7 +3922,6 @@ struct LEX: public Query_tables_list
bool add_create_view(THD *thd, DDL_options_st ddl,
uint16 algorithm, enum_view_suid suid,
Table_ident *table_ident);
-
bool add_grant_command(THD *thd, enum_sql_command sql_command_arg,
stored_procedure_type type_arg);
@@ -3753,6 +3930,31 @@ struct LEX: public Query_tables_list
return create_info.vers_info;
}
sp_package *get_sp_package() const;
+
+ 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*);
+ SELECT_LEX *wrap_unit_into_derived(SELECT_LEX_UNIT *unit);
+ SELECT_LEX *link_selects_chain_down(SELECT_LEX *sel);
+ bool main_select_push();
+ bool insert_select_hack(SELECT_LEX *sel);
+ SELECT_LEX *pop_new_select_and_wrap();
+
+ void set_main_unit(st_select_lex_unit *u)
+ {
+ unit.options= u->options;
+ unit.uncacheable= u->uncacheable;
+ unit.register_select_chain(u->first_select());
+ unit.first_select()->options|= builtin_select.options;
+ unit.fake_select_lex= u->fake_select_lex;
+ unit.union_distinct= u->union_distinct;
+ unit.set_with_clause(u->with_clause);
+ builtin_select.exclude_from_global();
+ }
+ bool check_main_unit_semantics();
};
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index cfa92f170ab..c81a8203be9 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -390,10 +390,13 @@ int mysql_load(THD *thd, const sql_exchange *ex, TABLE_LIST *table_list,
if (mysql_handle_single_derived(thd->lex, table_list, DT_MERGE_FOR_INSERT) ||
mysql_handle_single_derived(thd->lex, table_list, DT_PREPARE))
DBUG_RETURN(TRUE);
- if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
- &thd->lex->select_lex.top_join_list,
+ if (setup_tables_and_check_access(thd,
+ &thd->lex->first_select_lex()->context,
+ &thd->lex->first_select_lex()->
+ top_join_list,
table_list,
- thd->lex->select_lex.leaf_tables, FALSE,
+ thd->lex->first_select_lex()->leaf_tables,
+ FALSE,
INSERT_ACL | UPDATE_ACL,
INSERT_ACL | UPDATE_ACL, FALSE))
DBUG_RETURN(-1);
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index fbcf09758e6..6dc7c195041 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2004,10 +2004,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
Init TABLE_LIST members necessary when the undelrying
table is view.
*/
- table_list.select_lex= &(thd->lex->select_lex);
+ table_list.select_lex= thd->lex->first_select_lex();
thd->lex->
- select_lex.table_list.link_in_list(&table_list,
- &table_list.next_local);
+ first_select_lex()->table_list.link_in_list(&table_list,
+ &table_list.next_local);
thd->lex->add_to_query_tables(&table_list);
if (is_infoschema_db(&table_list.db))
@@ -2570,23 +2570,24 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
DBUG_RETURN(1);
#else
{
- if (lex->select_lex.db.str == NULL &&
- lex->copy_db_to(&lex->select_lex.db))
+ if (lex->first_select_lex()->db.str == NULL &&
+ lex->copy_db_to(&lex->first_select_lex()->db))
{
DBUG_RETURN(1);
}
schema_select_lex= new (thd->mem_root) SELECT_LEX();
schema_select_lex->table_list.first= NULL;
if (lower_case_table_names == 1)
- lex->select_lex.db.str= thd->strdup(lex->select_lex.db.str);
- schema_select_lex->db= lex->select_lex.db;
+ lex->first_select_lex()->db.str=
+ thd->strdup(lex->first_select_lex()->db.str);
+ schema_select_lex->db= lex->first_select_lex()->db;
/*
check_db_name() may change db.str if lower_case_table_names == 1,
but that's ok as the db is allocted above in this case.
*/
- if (check_db_name((LEX_STRING*) &lex->select_lex.db))
+ if (check_db_name((LEX_STRING*) &lex->first_select_lex()->db))
{
- my_error(ER_WRONG_DB_NAME, MYF(0), lex->select_lex.db.str);
+ my_error(ER_WRONG_DB_NAME, MYF(0), lex->first_select_lex()->db.str);
DBUG_RETURN(1);
}
break;
@@ -2625,7 +2626,8 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
default:
break;
}
-
+ if (schema_select_lex)
+ schema_select_lex->set_master_unit(&lex->unit);
SELECT_LEX *select_lex= lex->current_select;
if (make_schema_select(thd, select_lex, get_schema_table(schema_table_idx)))
DBUG_RETURN(1);
@@ -3222,7 +3224,7 @@ mysql_execute_command(THD *thd)
int up_result= 0;
LEX *lex= thd->lex;
/* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */
- SELECT_LEX *select_lex= &lex->select_lex;
+ SELECT_LEX *select_lex= lex->first_select_lex();
/* first table of first SELECT_LEX */
TABLE_LIST *first_table= select_lex->table_list.first;
/* list of all tables in query */
@@ -3265,6 +3267,7 @@ mysql_execute_command(THD *thd)
DBUG_ASSERT(first_table == all_tables && first_table != 0);
*/
lex->first_lists_tables_same();
+ lex->fix_first_select_number();
/* should be assigned after making first tables same */
all_tables= lex->query_tables;
/* set context for commands which do not use setup_tables */
@@ -7534,7 +7537,7 @@ void THD::reset_for_next_command(bool do_clear_error)
We also assign stmt_lex in lex_start(), but during bootstrap this
code is executed first.
*/
- stmt_lex= &main_lex; stmt_lex->current_select_number= 1;
+ stmt_lex= &main_lex; stmt_lex->current_select_number= 0;
DBUG_PRINT("info", ("Lex %p stmt_lex: %p", lex, stmt_lex));
/*
Those two lines below are theoretically unneeded as
@@ -7621,11 +7624,7 @@ mysql_init_select(LEX *lex)
SELECT_LEX *select_lex= lex->current_select;
select_lex->init_select();
lex->wild= 0;
- if (select_lex == &lex->select_lex)
- {
- DBUG_ASSERT(lex->result == 0);
- lex->exchange= 0;
- }
+ lex->exchange= 0;
}
@@ -7646,6 +7645,7 @@ mysql_new_select(LEX *lex, bool move_down, SELECT_LEX *select_lex)
{
THD *thd= lex->thd;
bool new_select= select_lex == NULL;
+ int old_nest_level= lex->current_select->nest_level;
DBUG_ENTER("mysql_new_select");
if (new_select)
@@ -7657,27 +7657,19 @@ mysql_new_select(LEX *lex, bool move_down, SELECT_LEX *select_lex)
select_lex->init_query();
select_lex->init_select();
}
- lex->nest_level++;
- if (lex->nest_level > (int) MAX_SELECT_NESTING)
- {
- my_error(ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT, MYF(0));
- DBUG_RETURN(1);
- }
- select_lex->nest_level= lex->nest_level;
select_lex->nest_level_base= &thd->lex->unit;
if (move_down)
{
+ lex->nest_level++;
+ if (select_lex->set_nest_level(old_nest_level + 1))
+ DBUG_RETURN(1);
SELECT_LEX_UNIT *unit;
lex->subqueries= TRUE;
/* first select_lex of subselect or derived table */
- if (!(unit= new (thd->mem_root) SELECT_LEX_UNIT()))
+ if (!(unit= lex->alloc_unit()))
DBUG_RETURN(1);
- unit->init_query();
- unit->thd= thd;
unit->include_down(lex->current_select);
- unit->link_next= 0;
- unit->link_prev= 0;
unit->return_to= lex->current_select;
select_lex->include_down(unit);
/*
@@ -7711,15 +7703,13 @@ mysql_new_select(LEX *lex, bool move_down, SELECT_LEX *select_lex)
"SELECT ... PROCEDURE ANALYSE()");
DBUG_RETURN(TRUE);
}
- // SELECT 1 FROM t1 ORDER BY 1 UNION SELECT 1 FROM t1 -- not possible
- DBUG_ASSERT(!lex->current_select->order_list.first ||
- lex->current_select->braces);
- // SELECT 1 FROM t1 LIMIT 1 UNION SELECT 1 FROM t1; -- not possible
- DBUG_ASSERT(!lex->current_select->explicit_limit ||
- lex->current_select->braces);
+ SELECT_LEX_NODE *save_slave= select_lex->slave;
select_lex->include_neighbour(lex->current_select);
- SELECT_LEX_UNIT *unit= select_lex->master_unit();
+ select_lex->slave= save_slave;
+ SELECT_LEX_UNIT *unit= select_lex->master_unit();
+ if (select_lex->set_nest_level(old_nest_level))
+ DBUG_RETURN(1);
if (!unit->fake_select_lex && unit->add_fake_select_lex(lex->thd))
DBUG_RETURN(1);
select_lex->context.outer_context=
@@ -7775,9 +7765,10 @@ void mysql_init_multi_delete(LEX *lex)
{
lex->sql_command= SQLCOM_DELETE_MULTI;
mysql_init_select(lex);
- lex->select_lex.select_limit= 0;
+ lex->first_select_lex()->select_limit= 0;
lex->unit.select_limit_cnt= HA_POS_ERROR;
- lex->select_lex.table_list.save_and_clear(&lex->auxiliary_table_list);
+ lex->first_select_lex()->table_list.
+ save_and_clear(&lex->auxiliary_table_list);
lex->query_tables= 0;
lex->query_tables_last= &lex->query_tables;
}
@@ -8068,7 +8059,7 @@ bool mysql_test_parse_for_slave(THD *thd, char *rawbuf, uint length)
thd->reset_for_next_command();
if (!parse_sql(thd, & parser_state, NULL, true) &&
- all_tables_not_ok(thd, lex->select_lex.table_list.first))
+ all_tables_not_ok(thd, lex->first_select_lex()->table_list.first))
error= 1; /* Ignore question */
thd->end_statement();
}
@@ -8150,6 +8141,10 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
LEX_CSTRING alias_str;
LEX *lex= thd->lex;
DBUG_ENTER("add_table_to_list");
+ DBUG_PRINT("enter", ("Table '%s' (%p) Select %p (%u)",
+ (alias ? alias->str : table->table.str),
+ table,
+ this, select_number));
if (!table)
DBUG_RETURN(0); // End of memory
@@ -8243,7 +8238,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
ptr->schema_table_name= ptr->table_name;
ptr->schema_table= schema_table;
}
- ptr->select_lex= lex->current_select;
+ ptr->select_lex= this;
/*
We can't cache internal temporary tables between prepares as the
table may be deleted before next exection.
@@ -8349,7 +8344,6 @@ bool st_select_lex::init_nested_join(THD *thd)
nested_join= ptr->nested_join=
((NESTED_JOIN*) ((uchar*) ptr + ALIGN_SIZE(sizeof(TABLE_LIST))));
- join_list->push_front(ptr, thd->mem_root);
ptr->embedding= embedding;
ptr->join_list= join_list;
ptr->alias.str="(nested_join)";
@@ -8457,7 +8451,6 @@ TABLE_LIST *st_select_lex::nest_last_join(THD *thd)
ptr->join_using_fields= prev_join_using;
}
}
- join_list->push_front(ptr, thd->mem_root);
nested_join->used_tables= nested_join->not_null_tables= (table_map) 0;
DBUG_RETURN(ptr);
}
@@ -8649,7 +8642,7 @@ void st_select_lex::set_lock_for_tables(thr_lock_type lock_type)
bool st_select_lex_unit::add_fake_select_lex(THD *thd_arg)
{
SELECT_LEX *first_sl= first_select();
- DBUG_ENTER("add_fake_select_lex");
+ DBUG_ENTER("st_select_lex_unit::add_fake_select_lex");
DBUG_ASSERT(!fake_select_lex);
if (!(fake_select_lex= new (thd_arg->mem_root) SELECT_LEX()))
@@ -8659,16 +8652,19 @@ bool st_select_lex_unit::add_fake_select_lex(THD *thd_arg)
fake_select_lex->select_number= INT_MAX;
fake_select_lex->parent_lex= thd_arg->lex; /* Used in init_query. */
fake_select_lex->make_empty_select();
- fake_select_lex->linkage= GLOBAL_OPTIONS_TYPE;
+ fake_select_lex->set_linkage(GLOBAL_OPTIONS_TYPE);
fake_select_lex->select_limit= 0;
+ fake_select_lex->no_table_names_allowed= 1;
+
fake_select_lex->context.outer_context=first_sl->context.outer_context;
/* allow item list resolving in fake select for ORDER BY */
fake_select_lex->context.resolve_in_select_list= TRUE;
fake_select_lex->context.select_lex= fake_select_lex;
fake_select_lex->nest_level_base= first_select()->nest_level_base;
- fake_select_lex->nest_level=first_select()->nest_level;
+ if (fake_select_lex->set_nest_level(first_select()->nest_level))
+ DBUG_RETURN(1);
if (!is_unit_op())
{
@@ -8681,7 +8677,7 @@ bool st_select_lex_unit::add_fake_select_lex(THD *thd_arg)
fake_select_lex->no_table_names_allowed= 1;
thd_arg->lex->current_select= fake_select_lex;
}
- thd_arg->lex->pop_context();
+ //thd_arg->lex->pop_context("add fake");
DBUG_RETURN(0);
}
@@ -8717,7 +8713,7 @@ push_new_name_resolution_context(THD *thd,
left_op->first_leaf_for_name_resolution();
on_context->last_name_resolution_table=
right_op->last_leaf_for_name_resolution();
- return thd->lex->push_context(on_context, thd->mem_root);
+ return thd->lex->push_context(on_context);
}
@@ -9072,7 +9068,7 @@ bool check_simple_select()
{
THD *thd= current_thd;
LEX *lex= thd->lex;
- if (lex->current_select != &lex->select_lex)
+ if (lex->current_select != lex->first_select_lex())
{
char command[80];
Lex_input_stream *lip= & thd->m_parser_state->m_lip;
@@ -9171,7 +9167,7 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables)
{
TABLE_LIST *table;
LEX *lex= thd->lex;
- SELECT_LEX *select_lex= &lex->select_lex;
+ SELECT_LEX *select_lex= lex->first_select_lex();
DBUG_ENTER("multi_update_precheck");
if (select_lex->item_list.elements != lex->value_list.elements)
@@ -9207,7 +9203,7 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables)
/*
Is there tables of subqueries?
*/
- if (&lex->select_lex != lex->all_selects_list)
+ if (lex->first_select_lex() != lex->all_selects_list)
{
DBUG_PRINT("info",("Checking sub query list"));
for (table= tables; table; table= table->next_global)
@@ -9241,7 +9237,7 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables)
bool multi_delete_precheck(THD *thd, TABLE_LIST *tables)
{
- SELECT_LEX *select_lex= &thd->lex->select_lex;
+ SELECT_LEX *select_lex= thd->lex->first_select_lex();
TABLE_LIST *aux_tables= thd->lex->auxiliary_table_list.first;
TABLE_LIST **save_query_tables_own_last= thd->lex->query_tables_own_last;
DBUG_ENTER("multi_delete_precheck");
@@ -9358,7 +9354,7 @@ static TABLE_LIST *multi_delete_table_match(LEX *lex, TABLE_LIST *tbl,
bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
{
- TABLE_LIST *tables= lex->select_lex.table_list.first;
+ TABLE_LIST *tables= lex->first_select_lex()->table_list.first;
TABLE_LIST *target_tbl;
DBUG_ENTER("multi_delete_set_locks_and_link_aux_tables");
@@ -9400,7 +9396,8 @@ bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
bool update_precheck(THD *thd, TABLE_LIST *tables)
{
DBUG_ENTER("update_precheck");
- if (thd->lex->select_lex.item_list.elements != thd->lex->value_list.elements)
+ if (thd->lex->first_select_lex()->item_list.elements !=
+ thd->lex->value_list.elements)
{
my_message(ER_WRONG_VALUE_COUNT, ER_THD(thd, ER_WRONG_VALUE_COUNT), MYF(0));
DBUG_RETURN(TRUE);
@@ -9491,7 +9488,7 @@ void create_table_set_open_action_and_adjust_tables(LEX *lex)
else
create_table->open_type= OT_BASE_ONLY;
- if (!lex->select_lex.item_list.elements)
+ if (!lex->first_select_lex()->item_list.elements)
{
/*
Avoid opening and locking target table for ordinary CREATE TABLE
@@ -9522,7 +9519,7 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables,
TABLE_LIST *create_table)
{
LEX *lex= thd->lex;
- SELECT_LEX *select_lex= &lex->select_lex;
+ SELECT_LEX *select_lex= lex->first_select_lex();
ulong want_priv;
bool error= TRUE; // Error message is given
DBUG_ENTER("create_table_precheck");
@@ -10032,6 +10029,8 @@ bool parse_sql(THD *thd, Parser_state *parser_state,
((thd->variables.sql_mode & MODE_ORACLE) ?
ORAparse(thd) :
MYSQLparse(thd)) != 0;
+ DBUG_ASSERT(opt_bootstrap | mysql_parse_status || thd->lex->select_stack_top == 0);
+ thd->lex->current_select= thd->lex->first_select_lex();
/*
Check that if MYSQLparse() failed either thd->is_error() is set, or an
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 09c59c862ad..ef226526e8c 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -833,7 +833,8 @@ static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
goto end;
table->get_fields_in_item_tree= true;
- func_expr->walk(&Item::change_context_processor, 0, &lex.select_lex.context);
+ func_expr->walk(&Item::change_context_processor, 0,
+ &lex.first_select_lex()->context);
thd->where= "partition function";
/*
In execution we must avoid the use of thd->change_item_tree since
diff --git a/sql/sql_partition_admin.cc b/sql/sql_partition_admin.cc
index 6e176a40e6c..b4a42dd6bb2 100644
--- a/sql/sql_partition_admin.cc
+++ b/sql/sql_partition_admin.cc
@@ -51,7 +51,7 @@ bool Sql_cmd_alter_table_exchange_partition::execute(THD *thd)
/* Moved from mysql_execute_command */
LEX *lex= thd->lex;
/* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */
- SELECT_LEX *select_lex= &lex->select_lex;
+ SELECT_LEX *select_lex= lex->first_select_lex();
/* first table of first SELECT_LEX */
TABLE_LIST *first_table= (TABLE_LIST*) select_lex->table_list.first;
/*
@@ -735,7 +735,7 @@ bool Sql_cmd_alter_table_truncate_partition::execute(THD *thd)
int error;
ha_partition *partition;
ulong timeout= thd->variables.lock_wait_timeout;
- TABLE_LIST *first_table= thd->lex->select_lex.table_list.first;
+ TABLE_LIST *first_table= thd->lex->first_select_lex()->table_list.first;
Alter_info *alter_info= &thd->lex->alter_info;
uint table_counter, i;
List<String> partition_names_list;
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 24f3cc66c6b..bdc817b7432 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1340,7 +1340,7 @@ static int mysql_test_update(Prepared_statement *stmt,
THD *thd= stmt->thd;
uint table_count= 0;
TABLE_LIST *update_source_table;
- SELECT_LEX *select= &stmt->lex->select_lex;
+ SELECT_LEX *select= stmt->lex->first_select_lex();
#ifndef NO_EMBEDDED_ACCESS_CHECKS
uint want_privilege;
#endif
@@ -1396,10 +1396,10 @@ static int mysql_test_update(Prepared_statement *stmt,
table_list->table->grant.want_privilege= want_privilege;
table_list->register_want_access(want_privilege);
#endif
- thd->lex->select_lex.no_wrap_view_item= TRUE;
+ thd->lex->first_select_lex()->no_wrap_view_item= TRUE;
res= setup_fields(thd, Ref_ptr_array(),
select->item_list, MARK_COLUMNS_READ, 0, NULL, 0);
- thd->lex->select_lex.no_wrap_view_item= FALSE;
+ thd->lex->first_select_lex()->no_wrap_view_item= FALSE;
if (res)
goto error;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -1464,10 +1464,10 @@ static bool mysql_test_delete(Prepared_statement *stmt,
goto error;
}
- DBUG_RETURN(mysql_prepare_delete(thd, table_list,
- lex->select_lex.with_wild,
- lex->select_lex.item_list,
- &lex->select_lex.where,
+ DBUG_RETURN(mysql_prepare_delete(thd, table_list,
+ lex->first_select_lex()->with_wild,
+ lex->first_select_lex()->item_list,
+ &lex->first_select_lex()->where,
&delete_while_scanning));
error:
DBUG_RETURN(TRUE);
@@ -1499,7 +1499,7 @@ static int mysql_test_select(Prepared_statement *stmt,
SELECT_LEX_UNIT *unit= &lex->unit;
DBUG_ENTER("mysql_test_select");
- lex->select_lex.context.resolve_in_select_list= TRUE;
+ lex->first_select_lex()->context.resolve_in_select_list= TRUE;
ulong privilege= lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL;
if (tables)
@@ -1533,7 +1533,7 @@ static int mysql_test_select(Prepared_statement *stmt,
if (!lex->describe && !thd->lex->analyze_stmt && !stmt->is_sql_prepare())
{
/* Make copy of item list, as change_columns may change it */
- List<Item> fields(lex->select_lex.item_list);
+ List<Item> fields(lex->first_select_lex()->item_list);
/* Change columns if a procedure like analyse() */
if (unit->last_procedure && unit->last_procedure->change_columns(thd, fields))
@@ -1691,7 +1691,7 @@ static bool select_like_stmt_test(Prepared_statement *stmt,
THD *thd= stmt->thd;
LEX *lex= stmt->lex;
- lex->select_lex.context.resolve_in_select_list= TRUE;
+ lex->first_select_lex()->context.resolve_in_select_list= TRUE;
if (specific_prepare && (*specific_prepare)(thd))
DBUG_RETURN(TRUE);
@@ -1759,7 +1759,7 @@ static bool mysql_test_create_table(Prepared_statement *stmt)
DBUG_ENTER("mysql_test_create_table");
THD *thd= stmt->thd;
LEX *lex= stmt->lex;
- SELECT_LEX *select_lex= &lex->select_lex;
+ SELECT_LEX *select_lex= lex->first_select_lex();
bool res= FALSE;
bool link_to_local;
TABLE_LIST *create_table= lex->query_tables;
@@ -2079,7 +2079,7 @@ static bool mysql_test_multidelete(Prepared_statement *stmt,
{
THD *thd= stmt->thd;
- thd->lex->current_select= &thd->lex->select_lex;
+ thd->lex->current_select= thd->lex->first_select_lex();
if (add_item_to_list(thd, new (thd->mem_root)
Item_null(thd)))
{
@@ -2118,13 +2118,14 @@ static bool mysql_test_multidelete(Prepared_statement *stmt,
static int mysql_insert_select_prepare_tester(THD *thd)
{
- SELECT_LEX *first_select= &thd->lex->select_lex;
+ SELECT_LEX *first_select= thd->lex->first_select_lex();
TABLE_LIST *second_table= first_select->table_list.first->next_local;
/* Skip first table, which is the table we are inserting in */
first_select->table_list.first= second_table;
- thd->lex->select_lex.context.table_list=
- thd->lex->select_lex.context.first_name_resolution_table= second_table;
+ thd->lex->first_select_lex()->context.table_list=
+ thd->lex->first_select_lex()->context.first_name_resolution_table=
+ second_table;
return mysql_insert_select_prepare(thd);
}
@@ -2159,7 +2160,7 @@ static bool mysql_test_insert_select(Prepared_statement *stmt,
return 1;
/* store it, because mysql_insert_select_prepare_tester change it */
- first_local_table= lex->select_lex.table_list.first;
+ first_local_table= lex->first_select_lex()->table_list.first;
DBUG_ASSERT(first_local_table != 0);
res=
@@ -2167,7 +2168,7 @@ static bool mysql_test_insert_select(Prepared_statement *stmt,
&mysql_insert_select_prepare_tester,
OPTION_SETUP_TABLES_DONE);
/* revert changes made by mysql_insert_select_prepare_tester */
- lex->select_lex.table_list.first= first_local_table;
+ lex->first_select_lex()->table_list.first= first_local_table;
return res;
}
@@ -2193,7 +2194,7 @@ static int mysql_test_handler_read(Prepared_statement *stmt,
SQL_HANDLER *ha_table;
DBUG_ENTER("mysql_test_handler_read");
- lex->select_lex.context.resolve_in_select_list= TRUE;
+ lex->first_select_lex()->context.resolve_in_select_list= TRUE;
/*
We don't have to test for permissions as this is already done during
@@ -2202,7 +2203,7 @@ static int mysql_test_handler_read(Prepared_statement *stmt,
if (!(ha_table= mysql_ha_read_prepare(thd, tables, lex->ha_read_mode,
lex->ident.str,
lex->insert_list,
- lex->select_lex.where)))
+ lex->first_select_lex()->where)))
DBUG_RETURN(1);
if (!stmt->is_sql_prepare())
@@ -2241,7 +2242,7 @@ static bool check_prepared_statement(Prepared_statement *stmt)
{
THD *thd= stmt->thd;
LEX *lex= stmt->lex;
- SELECT_LEX *select_lex= &lex->select_lex;
+ SELECT_LEX *select_lex= lex->first_select_lex();
TABLE_LIST *tables;
enum enum_sql_command sql_command= lex->sql_command;
int res= 0;
@@ -2250,10 +2251,11 @@ static bool check_prepared_statement(Prepared_statement *stmt)
sql_command, stmt->param_count));
lex->first_lists_tables_same();
+ lex->fix_first_select_number();
tables= lex->query_tables;
/* set context for commands which do not use setup_tables */
- lex->select_lex.context.resolve_in_table_list_only(select_lex->
+ lex->first_select_lex()->context.resolve_in_table_list_only(select_lex->
get_table_list());
/* Reset warning count for each query that uses tables */
@@ -2999,7 +3001,7 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
{
tables->reinit_before_use(thd);
}
- lex->current_select= &lex->select_lex;
+ lex->current_select= lex->first_select_lex();
if (lex->result)
@@ -4535,8 +4537,8 @@ bool Prepared_statement::validate_metadata(Prepared_statement *copy)
if (is_sql_prepare() || lex->describe)
return FALSE;
- if (lex->select_lex.item_list.elements !=
- copy->lex->select_lex.item_list.elements)
+ if (lex->first_select_lex()->item_list.elements !=
+ copy->lex->first_select_lex()->item_list.elements)
{
/** Column counts mismatch, update the client */
thd->server_status|= SERVER_STATUS_METADATA_CHANGED;
diff --git a/sql/sql_priv.h b/sql/sql_priv.h
index 7d2e1bae741..7fda6198dcf 100644
--- a/sql/sql_priv.h
+++ b/sql/sql_priv.h
@@ -184,6 +184,9 @@
#define OPTION_SKIP_REPLICATION (1ULL << 37) // THD, user
#define OPTION_RPL_SKIP_PARALLEL (1ULL << 38)
#define OPTION_FOUND_COMMENT (1ULL << 39) // SELECT, intern, parser
+#define OPTION_NO_QUERY_CACHE (1ULL << 40) // SELECT, user
+#define OPTION_INTO_CLAUSE (1ULL << 41) // Internal usage
+#define OPTION_PROCEDURE_CLAUSE (1ULL << 42) // Internal usage
/* The rest of the file is included in the server only */
#ifndef MYSQL_CLIENT
@@ -358,6 +361,8 @@ enum enum_parsing_place
IN_ORDER_BY,
IN_UPDATE_ON_DUP_KEY,
IN_PART_FUNC,
+ BEFORE_OPT_LIST,
+ AFTER_LIST,
PARSING_PLACE_SIZE /* always should be the last */
};
diff --git a/sql/sql_profile.cc b/sql/sql_profile.cc
index 13f03fed5f3..6ca21aebb37 100644
--- a/sql/sql_profile.cc
+++ b/sql/sql_profile.cc
@@ -110,7 +110,7 @@ int make_profile_table_for_show(THD *thd, ST_SCHEMA_TABLE *schema_table)
};
ST_FIELD_INFO *field_info;
- Name_resolution_context *context= &thd->lex->select_lex.context;
+ Name_resolution_context *context= &thd->lex->first_select_lex()->context;
int i;
for (i= 0; schema_table->fields_info[i].field_name != NULL; i++)
@@ -402,7 +402,7 @@ bool PROFILING::show_profiles()
QUERY_PROFILE *prof;
List<Item> field_list;
MEM_ROOT *mem_root= thd->mem_root;
- SELECT_LEX *sel= &thd->lex->select_lex;
+ SELECT_LEX *sel= thd->lex->first_select_lex();
SELECT_LEX_UNIT *unit= &thd->lex->unit;
ha_rows idx= 0;
Protocol *protocol= thd->protocol;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 9672180080e..ac6b1a72337 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -351,7 +351,7 @@ bool handle_select(THD *thd, LEX *lex, select_result *result,
ulong setup_tables_done_option)
{
bool res;
- register SELECT_LEX *select_lex = &lex->select_lex;
+ register SELECT_LEX *select_lex= lex->first_select_lex();
DBUG_ENTER("handle_select");
MYSQL_SELECT_START(thd->query());
@@ -1388,13 +1388,14 @@ bool JOIN::prepare_stage2()
bool JOIN::build_explain()
{
+ DBUG_ENTER("JOIN::build_explain");
create_explain_query_if_not_exists(thd->lex, thd->mem_root);
have_query_plan= QEP_AVAILABLE;
if (save_explain_data(thd->lex->explain, false /* can overwrite */,
need_tmp,
!skip_sort_order && !no_order && (order || group_list),
select_distinct))
- return 1;
+ DBUG_RETURN(1);
uint select_nr= select_lex->select_number;
JOIN_TAB *curr_tab= join_tab + exec_join_tab_cnt();
for (uint i= 0; i < aggr_tables; i++, curr_tab++)
@@ -1412,7 +1413,7 @@ bool JOIN::build_explain()
get_using_temporary_read_tracker();
}
}
- return 0;
+ DBUG_RETURN(0);
}
@@ -3722,6 +3723,15 @@ bool JOIN::save_explain_data(Explain_query *output, bool can_overwrite,
bool need_tmp_table, bool need_order,
bool distinct)
{
+ DBUG_ENTER("JOIN::save_explain_data");
+ DBUG_PRINT("enter", ("Save explain Select_lex: %u (%p) parent lex: %p stmt_lex: %p present select: %u (%p)",
+ select_lex->select_number, select_lex,
+ select_lex->parent_lex, thd->stmt_lex,
+ (output->get_select(select_lex->select_number) ?
+ select_lex->select_number : 0),
+ (output->get_select(select_lex->select_number) ?
+ output->get_select(select_lex->select_number)
+ ->select_lex : NULL)));
/*
If there is SELECT in this statemet with the same number it must be the
same SELECT
@@ -3748,8 +3758,9 @@ bool JOIN::save_explain_data(Explain_query *output, bool can_overwrite,
/* It's a degenerate join */
message= zero_result_cause ? zero_result_cause : "No tables used";
}
- return save_explain_data_intern(thd->lex->explain, need_tmp_table, need_order,
- distinct, message);
+ bool rc= save_explain_data_intern(thd->lex->explain, need_tmp_table,
+ need_order, distinct, message);
+ DBUG_RETURN(rc);
}
/*
@@ -3771,11 +3782,11 @@ bool JOIN::save_explain_data(Explain_query *output, bool can_overwrite,
{
if (!(join_tab[i].filesort->tracker=
new Filesort_tracker(thd->lex->analyze_stmt)))
- return 1;
+ DBUG_RETURN(1);
}
}
}
- return 0;
+ DBUG_RETURN(0);
}
@@ -12618,7 +12629,8 @@ void JOIN::join_free()
!(select_options & SELECT_NO_UNLOCK) &&
!select_lex->subquery_in_having &&
(select_lex == (thd->lex->unit.fake_select_lex ?
- thd->lex->unit.fake_select_lex : &thd->lex->select_lex)))
+ thd->lex->unit.fake_select_lex :
+ thd->lex->first_select_lex())))
{
/*
TODO: unlock tables even if the join isn't top level select in the
@@ -18430,7 +18442,7 @@ create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
new_table.no_rows= table->no_rows;
if (create_internal_tmp_table(&new_table, table->key_info, start_recinfo,
recinfo,
- thd->lex->select_lex.options |
+ thd->lex->builtin_select.options |
thd->variables.option_bits))
goto err2;
if (open_tmp_table(&new_table))
@@ -24946,7 +24958,8 @@ bool JOIN_TAB::save_explain_data(Explain_table_access *eta,
*/
if (real_table->merged_for_insert)
{
- TABLE_LIST *view_child= real_table->view->select_lex.table_list.first;
+ TABLE_LIST *view_child=
+ real_table->view->first_select_lex()->table_list.first;
for (;view_child; view_child= view_child->next_local)
{
if (view_child->table == table)
@@ -25399,8 +25412,9 @@ int JOIN::save_explain_data_intern(Explain_query *output,
{
JOIN *join= this; /* Legacy: this code used to be a non-member function */
DBUG_ENTER("JOIN::save_explain_data_intern");
- DBUG_PRINT("info", ("Select %p, type %s, message %s",
- join->select_lex, join->select_lex->type,
+ DBUG_PRINT("info", ("Select %p (%u), type %s, message %s",
+ join->select_lex, join->select_lex->select_number,
+ join->select_lex->type,
message ? message : "NULL"));
DBUG_ASSERT(have_query_plan == QEP_AVAILABLE);
/* fake_select_lex is created/printed by Explain_union */
@@ -26054,6 +26068,18 @@ void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
{
str->append("/* select#");
str->append_ulonglong(select_number);
+ if (thd->lex->describe & DESCRIBE_EXTENDED2)
+ {
+ str->append("/");
+ str->append_ulonglong(nest_level);
+
+ if (master_unit()->fake_select_lex &&
+ master_unit()->first_select() == this)
+ {
+ str->append(" Filter Select: ");
+ master_unit()->fake_select_lex->print(thd, str, query_type);
+ }
+ }
str->append(" */ ");
}
diff --git a/sql/sql_sequence.cc b/sql/sql_sequence.cc
index 18f0028908f..1ee20785e9c 100644
--- a/sql/sql_sequence.cc
+++ b/sql/sql_sequence.cc
@@ -220,8 +220,8 @@ bool check_sequence_fields(LEX *lex, List<Create_field> *fields)
err:
my_error(ER_SEQUENCE_INVALID_TABLE_STRUCTURE, MYF(0),
- lex->select_lex.table_list.first->db.str,
- lex->select_lex.table_list.first->table_name.str, reason);
+ lex->first_select_lex()->table_list.first->db.str,
+ lex->first_select_lex()->table_list.first->table_name.str, reason);
DBUG_RETURN(TRUE);
}
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 38a13c49278..fb7a023e817 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -4144,8 +4144,9 @@ bool get_lookup_field_values(THD *thd, COND *cond, TABLE_LIST *tables,
case SQLCOM_SHOW_TABLE_STATUS:
case SQLCOM_SHOW_TRIGGERS:
case SQLCOM_SHOW_EVENTS:
- thd->make_lex_string(&lookup_field_values->db_value,
- lex->select_lex.db.str, lex->select_lex.db.length);
+ thd->make_lex_string(&lookup_field_values->db_value,
+ lex->first_select_lex()->db.str,
+ lex->first_select_lex()->db.length);
if (wild)
{
thd->make_lex_string(&lookup_field_values->table_value,
@@ -4538,10 +4539,10 @@ fill_schema_table_by_open(THD *thd, MEM_ROOT *mem_root,
temporary LEX. The latter is required to correctly open views and
produce table describing their structure.
*/
- if (make_table_list(thd, &lex->select_lex, &db_name, &table_name))
+ if (make_table_list(thd, lex->first_select_lex(), &db_name, &table_name))
goto end;
- table_list= lex->select_lex.table_list.first;
+ table_list= lex->first_select_lex()->table_list.first;
if (is_show_fields_or_keys)
{
@@ -6746,7 +6747,7 @@ static int get_schema_views_record(THD *thd, TABLE_LIST *tables,
& 'field_translation_end' are uninitialized is this
case.
*/
- List<Item> *fields= &tables->view->select_lex.item_list;
+ List<Item> *fields= &tables->view->first_select_lex()->item_list;
List_iterator<Item> it(*fields);
Item *item;
Item_field *field;
@@ -7725,7 +7726,8 @@ int fill_open_tables(THD *thd, TABLE_LIST *tables, COND *cond)
TABLE *table= tables->table;
CHARSET_INFO *cs= system_charset_info;
OPEN_TABLE_LIST *open_list;
- if (!(open_list=list_open_tables(thd,thd->lex->select_lex.db.str, wild))
+ if (!(open_list=list_open_tables(thd, thd->lex->first_select_lex()->db.str,
+ wild))
&& thd->is_fatal_error)
DBUG_RETURN(1);
@@ -8220,7 +8222,7 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
tmp_table_param->table_charset= cs;
tmp_table_param->field_count= field_count;
tmp_table_param->schema_table= 1;
- SELECT_LEX *select_lex= thd->lex->current_select;
+ SELECT_LEX *select_lex= table_list->select_lex;
bool keep_row_order= is_show_command(thd);
if (!(table= create_tmp_table(thd, tmp_table_param,
field_list, (ORDER*) 0, 0, 0,
@@ -8257,7 +8259,7 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
static int make_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
{
ST_FIELD_INFO *field_info= schema_table->fields_info;
- Name_resolution_context *context= &thd->lex->select_lex.context;
+ Name_resolution_context *context= &thd->lex->first_select_lex()->context;
for (; field_info->field_name; field_info++)
{
if (field_info->old_name)
@@ -8317,14 +8319,14 @@ int make_table_names_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
char tmp[128];
String buffer(tmp,sizeof(tmp), thd->charset());
LEX *lex= thd->lex;
- Name_resolution_context *context= &lex->select_lex.context;
+ Name_resolution_context *context= &lex->first_select_lex()->context;
ST_FIELD_INFO *field_info= &schema_table->fields_info[2];
LEX_CSTRING field_name= {field_info->field_name,
strlen(field_info->field_name) };
buffer.length(0);
buffer.append(field_info->old_name);
- buffer.append(&lex->select_lex.db);
+ buffer.append(&lex->first_select_lex()->db);
if (lex->wild && lex->wild->ptr())
{
buffer.append(STRING_WITH_LEN(" ("));
@@ -8357,7 +8359,7 @@ int make_columns_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
int fields_arr[]= {3, 15, 14, 6, 16, 5, 17, 18, 19, -1};
int *field_num= fields_arr;
ST_FIELD_INFO *field_info;
- Name_resolution_context *context= &thd->lex->select_lex.context;
+ Name_resolution_context *context= &thd->lex->first_select_lex()->context;
for (; *field_num >= 0; field_num++)
{
@@ -8388,7 +8390,7 @@ int make_character_sets_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
int fields_arr[]= {0, 2, 1, 3, -1};
int *field_num= fields_arr;
ST_FIELD_INFO *field_info;
- Name_resolution_context *context= &thd->lex->select_lex.context;
+ Name_resolution_context *context= &thd->lex->first_select_lex()->context;
for (; *field_num >= 0; field_num++)
{
@@ -8415,7 +8417,7 @@ int make_proc_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
int fields_arr[]= {2, 3, 4, 27, 24, 23, 22, 26, 28, 29, 30, -1};
int *field_num= fields_arr;
ST_FIELD_INFO *field_info;
- Name_resolution_context *context= &thd->lex->select_lex.context;
+ Name_resolution_context *context= &thd->lex->first_select_lex()->context;
for (; *field_num >= 0; field_num++)
{
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 448d095c876..1322d86302e 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -4890,7 +4890,7 @@ int create_table_impl(THD *thd,
/*
Restart statement transactions for the case of CREATE ... SELECT.
*/
- if (thd->lex->select_lex.item_list.elements &&
+ if (thd->lex->first_select_lex()->item_list.elements &&
restart_trans_for_tables(thd, thd->lex->query_tables))
goto err;
}
@@ -10237,8 +10237,8 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
Filesort_tracker dummy_tracker(false);
Filesort fsort(order, HA_POS_ERROR, true, NULL);
- if (thd->lex->select_lex.setup_ref_array(thd, order_num) ||
- setup_order(thd, thd->lex->select_lex.ref_pointer_array,
+ if (thd->lex->first_select_lex()->setup_ref_array(thd, order_num) ||
+ setup_order(thd, thd->lex->first_select_lex()->ref_pointer_array,
&tables, fields, all_fields, order))
goto err;
diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc
index 2ddb4bc042c..dabd88e90a4 100644
--- a/sql/sql_truncate.cc
+++ b/sql/sql_truncate.cc
@@ -489,7 +489,7 @@ bool Sql_cmd_truncate_table::truncate_table(THD *thd, TABLE_LIST *table_ref)
bool Sql_cmd_truncate_table::execute(THD *thd)
{
bool res= TRUE;
- TABLE_LIST *table= thd->lex->select_lex.table_list.first;
+ TABLE_LIST *table= thd->lex->first_select_lex()->table_list.first;
DBUG_ENTER("Sql_cmd_truncate_table::execute");
if (check_one_table_access(thd, DROP_ACL, table))
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 0149c2848c2..5b84ec45dba 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -1387,7 +1387,7 @@ bool st_select_lex_unit::exec()
union_result->change_select();
if (fake_select_lex)
{
- if (sl != &thd->lex->select_lex)
+ if (sl != thd->lex->first_select_lex())
fake_select_lex->uncacheable|= sl->uncacheable;
else
fake_select_lex->uncacheable= 0;
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 38638d3aa1d..8e7bbadf902 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -318,7 +318,7 @@ int mysql_update(THD *thd,
SQL_SELECT *select= NULL;
SORT_INFO *file_sort= 0;
READ_RECORD info;
- SELECT_LEX *select_lex= &thd->lex->select_lex;
+ SELECT_LEX *select_lex= thd->lex->first_select_lex();
ulonglong id;
List<Item> all_fields;
killed_state killed_status= NOT_KILLED;
@@ -375,7 +375,7 @@ int mysql_update(THD *thd,
table->covering_keys= table->s->keys_in_use;
table->quick_keys.clear_all();
- query_plan.select_lex= &thd->lex->select_lex;
+ query_plan.select_lex= thd->lex->first_select_lex();
query_plan.table= table;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/* Force privilege re-checking for views after they have been opened. */
@@ -1241,7 +1241,7 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
TABLE *table= table_list->table;
#endif
List<Item> all_fields;
- SELECT_LEX *select_lex= &thd->lex->select_lex;
+ SELECT_LEX *select_lex= thd->lex->first_select_lex();
DBUG_ENTER("mysql_prepare_update");
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -1518,7 +1518,7 @@ int mysql_multi_update_prepare(THD *thd)
LEX *lex= thd->lex;
TABLE_LIST *table_list= lex->query_tables;
TABLE_LIST *tl;
- List<Item> *fields= &lex->select_lex.item_list;
+ List<Item> *fields= &lex->first_select_lex()->item_list;
table_map tables_for_update;
bool update_view= 0;
/*
@@ -1560,14 +1560,15 @@ int mysql_multi_update_prepare(THD *thd)
if (mysql_handle_derived(lex, DT_PREPARE))
DBUG_RETURN(TRUE);
- if (setup_tables_and_check_access(thd, &lex->select_lex.context,
- &lex->select_lex.top_join_list,
+ if (setup_tables_and_check_access(thd,
+ &lex->first_select_lex()->context,
+ &lex->first_select_lex()->top_join_list,
table_list,
- lex->select_lex.leaf_tables, FALSE,
- UPDATE_ACL, SELECT_ACL, FALSE))
+ lex->first_select_lex()->leaf_tables,
+ FALSE, UPDATE_ACL, SELECT_ACL, FALSE))
DBUG_RETURN(TRUE);
- if (lex->select_lex.handle_derived(thd->lex, DT_MERGE))
+ if (lex->first_select_lex()->handle_derived(thd->lex, DT_MERGE))
DBUG_RETURN(TRUE);
if (setup_fields_with_no_wrap(thd, Ref_ptr_array(),
@@ -1590,13 +1591,14 @@ int mysql_multi_update_prepare(THD *thd)
thd->table_map_for_update= tables_for_update= get_table_map(fields);
- if (unsafe_key_update(lex->select_lex.leaf_tables, tables_for_update))
+ if (unsafe_key_update(lex->first_select_lex()->leaf_tables,
+ tables_for_update))
DBUG_RETURN(true);
/*
Setup timestamp handling and locking mode
*/
- List_iterator<TABLE_LIST> ti(lex->select_lex.leaf_tables);
+ List_iterator<TABLE_LIST> ti(lex->first_select_lex()->leaf_tables);
while ((tl= ti++))
{
TABLE *table= tl->table;
@@ -1689,7 +1691,7 @@ int mysql_multi_update_prepare(THD *thd)
Check that we are not using table that we are updating, but we should
skip all tables of UPDATE SELECT itself
*/
- lex->select_lex.exclude_from_table_unique_test= TRUE;
+ lex->first_select_lex()->exclude_from_table_unique_test= TRUE;
/* We only need SELECT privilege for columns in the values list */
ti.rewind();
while ((tl= ti++))
@@ -1711,7 +1713,7 @@ int mysql_multi_update_prepare(THD *thd)
Set exclude_from_table_unique_test value back to FALSE. It is needed for
further check in multi_update::prepare whether to use record cache.
*/
- lex->select_lex.exclude_from_table_unique_test= FALSE;
+ lex->first_select_lex()->exclude_from_table_unique_test= FALSE;
if (lex->save_prep_leaf_tables())
DBUG_RETURN(TRUE);
@@ -1740,7 +1742,7 @@ bool mysql_multi_update(THD *thd,
DBUG_ENTER("mysql_multi_update");
if (!(*result= new (thd->mem_root) multi_update(thd, table_list,
- &thd->lex->select_lex.leaf_tables,
+ &thd->lex->first_select_lex()->leaf_tables,
fields, values,
handle_duplicates, ignore)))
{
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index e910d48c75c..d1795f9c80f 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -254,7 +254,7 @@ bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view,
LEX *lex= thd->lex;
/* first table in list is target VIEW name => cut off it */
TABLE_LIST *tbl;
- SELECT_LEX *select_lex= &lex->select_lex;
+ SELECT_LEX *select_lex= lex->first_select_lex();
SELECT_LEX *sl;
bool res= TRUE;
DBUG_ENTER("create_view_precheck");
@@ -323,7 +323,9 @@ bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view,
}
}
- if (&lex->select_lex != lex->all_selects_list)
+#if 0
+ if (lex->first_select_lex() != lex->all_selects_list)
+#endif
{
/* check tables of subqueries */
for (tbl= tables; tbl; tbl= tbl->next_global)
@@ -399,7 +401,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
TABLE_LIST *view= lex->unlink_first_table(&link_to_local);
TABLE_LIST *tables= lex->query_tables;
TABLE_LIST *tbl;
- SELECT_LEX *select_lex= &lex->select_lex;
+ SELECT_LEX *select_lex= lex->first_select_lex();
SELECT_LEX *sl;
SELECT_LEX_UNIT *unit= &lex->unit;
bool res= FALSE;
@@ -995,7 +997,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
view->algorithm != VIEW_ALGORITHM_TMPTABLE)))
{
/* TODO: change here when we will support UNIONs */
- for (TABLE_LIST *tbl= lex->select_lex.table_list.first;
+ for (TABLE_LIST *tbl= lex->first_select_lex()->table_list.first;
tbl;
tbl= tbl->next_local)
{
@@ -1114,8 +1116,8 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
UNION
*/
if (view->updatable_view &&
- !lex->select_lex.master_unit()->is_unit_op() &&
- !(lex->select_lex.table_list.first)->next_local &&
+ !lex->first_select_lex()->master_unit()->is_unit_op() &&
+ !(lex->first_select_lex()->table_list.first)->next_local &&
find_table_in_global_list(lex->query_tables->next_global,
&lex->query_tables->db,
&lex->query_tables->table_name))
@@ -1162,7 +1164,8 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
bool open_view_no_parse)
{
- SELECT_LEX *end, *UNINIT_VAR(view_select);
+ SELECT_LEX_NODE *end;
+ SELECT_LEX *UNINIT_VAR(view_select);
LEX *old_lex, *lex;
Query_arena *arena, backup;
TABLE_LIST *top_view= table->top_table();
@@ -1359,8 +1362,6 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
goto end;
lex_start(thd);
- view_select= &lex->select_lex;
- view_select->select_number= ++thd->stmt_lex->current_select_number;
sql_mode_t saved_mode= thd->variables.sql_mode;
/* switch off modes which can prevent normal parsing of VIEW
@@ -1395,6 +1396,8 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
parse_status= parse_sql(thd, & parser_state, table->view_creation_ctx);
+ view_select= lex->first_select_lex();
+
/* Restore environment. */
if ((old_lex->sql_command == SQLCOM_SHOW_FIELDS) ||
@@ -1544,7 +1547,7 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
This may change in future, for example if we enable merging of
views with subqueries in select list.
*/
- view_main_select_tables= lex->select_lex.table_list.first;
+ view_main_select_tables= lex->first_select_lex()->table_list.first;
/*
Let us set proper lock type for tables of the view's main
@@ -1572,7 +1575,7 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
/* Fields in this view can be used in upper select in case of merge. */
if (table->select_lex)
- table->select_lex->add_where_field(&lex->select_lex);
+ table->select_lex->add_where_field(lex->first_select_lex());
}
/*
This method has a dependency on the proper lock type being set,
@@ -1594,8 +1597,8 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
old_lex->safe_to_cache_query= (old_lex->safe_to_cache_query &&
lex->safe_to_cache_query);
/* move SQL_CACHE to whole query */
- if (view_select->options & OPTION_TO_QUERY_CACHE)
- old_lex->select_lex.options|= OPTION_TO_QUERY_CACHE;
+ if (lex->first_select_lex()->options & OPTION_TO_QUERY_CACHE)
+ old_lex->first_select_lex()->options|= OPTION_TO_QUERY_CACHE;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (table->view_suid)
@@ -1677,9 +1680,10 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
tbl->grant.want_privilege= top_view->grant.orig_want_privilege;
/* prepare view context */
- lex->select_lex.context.resolve_in_table_list_only(view_main_select_tables);
- lex->select_lex.context.outer_context= 0;
- lex->select_lex.select_n_having_items+=
+ lex->first_select_lex()->
+ context.resolve_in_table_list_only(view_main_select_tables);
+ lex->first_select_lex()->context.outer_context= 0;
+ lex->first_select_lex()->select_n_having_items+=
table->select_lex->select_n_having_items;
table->where= view_select->where;
@@ -1690,12 +1694,13 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
*/
if (!table->select_lex->master_unit()->is_unit_op() &&
table->select_lex->order_list.elements == 0)
- table->select_lex->order_list.push_back(&lex->select_lex.order_list);
+ table->select_lex->order_list.
+ push_back(&lex->first_select_lex()->order_list);
else
{
if (old_lex->sql_command == SQLCOM_SELECT &&
(old_lex->describe & DESCRIBE_EXTENDED) &&
- lex->select_lex.order_list.elements &&
+ lex->first_select_lex()->order_list.elements &&
!table->select_lex->master_unit()->is_unit_op())
{
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
@@ -1730,7 +1735,11 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
lex->unit.include_down(table->select_lex);
lex->unit.slave= view_select; // fix include_down initialisation
/* global SELECT list linking */
- end= view_select; // primary SELECT_LEX is always last
+ /*
+ The primary SELECT_LEX is always last (because parsed first) if WITH not
+ used, otherwise it is good start point for last element finding
+ */
+ for (end= view_select; end->link_next; end= end->link_next);
end->link_next= old_lex->all_selects_list;
old_lex->all_selects_list->link_prev= &end->link_next;
old_lex->all_selects_list= lex->all_selects_list;
@@ -1913,7 +1922,7 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view)
*/
if ((!view->view && !view->belong_to_view) ||
thd->lex->sql_command == SQLCOM_INSERT ||
- thd->lex->select_lex.select_limit == 0)
+ thd->lex->first_select_lex()->select_limit == 0)
DBUG_RETURN(FALSE); /* it is normal table or query without LIMIT */
table= view->table;
view= view->top_table();
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index d69156ced9b..b5e3bb4f73d 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -511,6 +511,7 @@ bool LEX::add_select_to_union_list(bool is_union_distinct,
{
const char *type_name= (type == INTERSECT_TYPE ? "INTERSECT" :
(type == EXCEPT_TYPE ? "EXCEPT" : "UNION"));
+ DBUG_ENTER("LEX::add_select_to_union_list");
/*
Only the last SELECT can have INTO. Since the grammar won't allow INTO in
a nested SELECT, we make this check only when creating a top-level SELECT.
@@ -518,28 +519,28 @@ bool LEX::add_select_to_union_list(bool is_union_distinct,
if (is_top_level && result)
{
my_error(ER_WRONG_USAGE, MYF(0), type_name, "INTO");
- return TRUE;
+ DBUG_RETURN(TRUE);
}
if (current_select->order_list.first && !current_select->braces)
{
my_error(ER_WRONG_USAGE, MYF(0), type_name, "ORDER BY");
- return TRUE;
+ DBUG_RETURN(TRUE);
}
if (current_select->explicit_limit && !current_select->braces)
{
my_error(ER_WRONG_USAGE, MYF(0), type_name, "LIMIT");
- return TRUE;
+ DBUG_RETURN(TRUE);
}
if (current_select->linkage == GLOBAL_OPTIONS_TYPE)
{
thd->parse_error();
- return TRUE;
+ DBUG_RETURN(TRUE);
}
if (!is_union_distinct && (type == INTERSECT_TYPE || type == EXCEPT_TYPE))
{
my_error(ER_WRONG_USAGE, MYF(0), type_name, "ALL");
- return TRUE;
+ DBUG_RETURN(TRUE);
}
/*
Priority implementation, but also trying to keep things as flat
@@ -554,27 +555,24 @@ bool LEX::add_select_to_union_list(bool is_union_distinct,
*/
SELECT_LEX *prev= exclude_last_select();
if (add_unit_in_brackets(prev))
- return TRUE;
- return add_select_to_union_list(is_union_distinct, type, 0);
+ DBUG_RETURN(TRUE);
+ bool res= add_select_to_union_list(is_union_distinct, type, 0);
+ DBUG_RETURN(res);
}
else
{
check_automatic_up(type);
}
- /* This counter shouldn't be incremented for UNION parts */
- nest_level--;
if (mysql_new_select(this, 0, NULL))
- return TRUE;
+ DBUG_RETURN(TRUE);
mysql_init_select(this);
- current_select->linkage= type;
+ current_select->set_linkage(type);
if (is_union_distinct) /* UNION DISTINCT - remember position */
{
current_select->master_unit()->union_distinct=
current_select;
}
- else
- DBUG_ASSERT(type == UNION_TYPE);
- return FALSE;
+ DBUG_RETURN(FALSE);
}
@@ -619,6 +617,7 @@ void sp_create_assignment_lex(THD *thd, bool no_lookahead)
lex->sphead->m_tmp_query= lip->get_tok_end();
/* Inherit from outer lex. */
lex->option_type= old_lex->option_type;
+ lex->main_select_push();
}
}
@@ -678,6 +677,9 @@ bool sp_create_assignment_instr(THD *thd, bool no_lookahead)
if (sp->add_instr(i))
return true;
}
+ lex->pop_select();
+ if (Lex->check_main_unit_semantics())
+ return true;
enum_var_type inner_option_type= lex->option_type;
if (lex->sphead->restore_lex(thd))
return true;
@@ -796,6 +798,20 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr)
uint offset;
} sp_cursor_name_and_offset;
vers_history_point_t vers_history_point;
+ struct
+ {
+ enum sub_select_type unit_type;
+ bool distinct;
+ } unit_operation;
+ struct
+ {
+ SELECT_LEX *first;
+ SELECT_LEX *prev_last;
+ } select_list;
+ SQL_I_List<ORDER> *select_order;
+ Lex_select_lock select_lock;
+ Lex_select_limit select_limit;
+ Lex_order_limit_lock *order_limit_lock;
/* pointers */
Create_field *create_field;
@@ -841,6 +857,7 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr)
handlerton *db_type;
st_select_lex *select_lex;
+ st_select_lex_unit *select_lex_unit;
struct p_elem_val *p_elem_value;
class Window_frame *window_frame;
class Window_frame_bound *window_frame_bound;
@@ -849,7 +866,6 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr)
/* enums */
enum enum_view_suid view_suid;
- enum sub_select_type unit_type;
enum Condition_information_item::Name cond_info_item_name;
enum enum_diag_condition_item_name diag_condition_item_name;
enum Diagnostics_information::Which_area diag_area;
@@ -888,10 +904,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%parse-param { THD *thd }
%lex-param { THD *thd }
/*
- Currently there are 139 shift/reduce conflicts.
+ Currently there are 135 shift/reduce conflicts.
We should not introduce new conflicts any more.
*/
-%expect 139
+%expect 135
/*
Comments for TOKENS.
@@ -1210,6 +1226,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%token LEAVES
%token LEAVE_SYM
%token LEFT /* SQL-2003-R */
+%token LEFT_PAREN_ALT /* INTERNAL */
+%token LEFT_PAREN_WITH /* INTERNAL */
+%token LEFT_PAREN_LIKE /* INTERNAL */
%token LESS_SYM
%token LEVEL_SYM
%token LEX_HOSTNAME
@@ -1671,7 +1690,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
NCHAR_STRING
%type <lex_str_ptr>
- opt_table_alias
+ opt_table_alias_clause
+ table_alias_clause
%type <lex_string_with_pos>
ident ident_with_tok_start
@@ -1716,7 +1736,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
opt_temporary all_or_any opt_distinct opt_glimit_clause
opt_ignore_leaves fulltext_options union_option
opt_not
- select_derived_init transaction_access_mode_types
+ transaction_access_mode_types
opt_natural_language_mode opt_query_expansion
opt_ev_status opt_ev_on_completion ev_on_completion opt_ev_comment
ev_alter_on_schedule_completion opt_ev_rename_to opt_ev_sql_stmt
@@ -1834,11 +1854,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
join_table_list join_table
table_factor table_ref esc_table_ref
table_primary_ident table_primary_derived
- select_derived derived_table_list
- select_derived_union
- derived_simple_table
- derived_query_specification
- derived_table_value_constructor
+ derived_table_list table_reference_list_parens
+ nested_table_reference_list join_table_parens
%type <date_time_type> date_time_type;
%type <interval> interval
@@ -1876,14 +1893,16 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
UNDERSCORE_CHARSET
%type <select_lex> subselect
- get_select_lex get_select_lex_derived
- simple_table
query_specification
- query_term_union_not_ready
- query_term_union_ready
- query_expression_body
- select_paren_derived
table_value_constructor
+ simple_table
+ query_primary
+ query_primary_parens
+
+%type <select_lex_unit>
+ query_expression_body
+ query_expression
+ query_expression_unit
%type <boolfunc2creator> comp_op
@@ -1895,7 +1914,21 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%type <virtual_column> opt_check_constraint check_constraint virtual_column_func
column_default_expr
-%type <unit_type> unit_type_decl
+
+%type <unit_operation> unit_type_decl
+
+%type <select_lock>
+ opt_select_lock_type
+ select_lock_type
+ opt_lock_wait_timeout_new
+
+%type <select_limit> opt_limit_clause limit_clause limit_options
+
+%type <order_limit_lock>
+ query_expression_tail
+ order_or_limit
+
+%type <select_order> opt_order_clause order_clause order_list
%type <NONE>
analyze_stmt_command
@@ -1915,7 +1948,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
assign_to_keycache_parts
preload_list preload_list_or_parts preload_keys preload_keys_parts
select_item_list select_item values_list no_braces
- opt_limit_clause delete_limit_clause fields opt_values values
+ delete_limit_clause fields opt_values values
procedure_list procedure_list2 procedure_item
field_def handler opt_generated_always
opt_ignore opt_column opt_restrict
@@ -1935,9 +1968,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
table_to_table_list table_to_table opt_table_list opt_as
handler_rkey_function handler_read_or_scan
single_multi table_wild_list table_wild_one opt_wild
- union_clause union_list
- subselect_start opt_and charset
- subselect_end select_var_list select_var_list_init help
+ opt_and charset
+ select_var_list select_var_list_init help
opt_extended_describe shutdown
opt_format_json
prepare prepare_src execute deallocate
@@ -2066,7 +2098,7 @@ query:
END_OF_INPUT
{
if (!thd->bootstrap &&
- (!(thd->lex->select_lex.options & OPTION_FOUND_COMMENT)))
+ (!(thd->lex->builtin_select.options & OPTION_FOUND_COMMENT)))
my_yyabort_error((ER_EMPTY_QUERY, MYF(0)));
thd->lex->sql_command= SQLCOM_EMPTY_QUERY;
@@ -2190,14 +2222,22 @@ deallocate_or_drop:
;
prepare:
- PREPARE_SYM ident FROM prepare_src
+ PREPARE_SYM
+ {
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
+ ident FROM prepare_src
{
LEX *lex= thd->lex;
if (lex->table_or_sp_used())
my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0),
"PREPARE..FROM"));
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
lex->sql_command= SQLCOM_PREPARE;
- lex->prepared_stmt_name= $2;
+ lex->prepared_stmt_name= $3;
+ Lex->pop_select(); //main select
}
;
@@ -2216,10 +2256,21 @@ execute:
LEX *lex= thd->lex;
lex->sql_command= SQLCOM_EXECUTE;
lex->prepared_stmt_name= $2;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
execute_using
- {}
- | EXECUTE_SYM IMMEDIATE_SYM prepare_src
+ {
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+ }
+ | EXECUTE_SYM IMMEDIATE_SYM
+ {
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
+ prepare_src
{
if (Lex->table_or_sp_used())
my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0),
@@ -2227,7 +2278,11 @@ execute:
Lex->sql_command= SQLCOM_EXECUTE_IMMEDIATE;
}
execute_using
- {}
+ {
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+ }
;
execute_using:
@@ -2512,15 +2567,22 @@ connection_name:
/* create a table */
create:
- create_or_replace opt_temporary TABLE_SYM opt_if_not_exists table_ident
+ create_or_replace opt_temporary TABLE_SYM opt_if_not_exists
{
LEX *lex= thd->lex;
lex->create_info.init();
+ if (lex->main_select_push())
+ MYSQL_YYABORT;
+ lex->current_select->parsing_place= BEFORE_OPT_LIST;
if (lex->set_command_with_check(SQLCOM_CREATE_TABLE, $2, $1 | $4))
MYSQL_YYABORT;
- if (!lex->select_lex.add_table_to_list(thd, $5, NULL,
- TL_OPTION_UPDATING,
- TL_WRITE, MDL_EXCLUSIVE))
+ }
+ table_ident
+ {
+ LEX *lex= thd->lex;
+ if (!lex->builtin_select.add_table_to_list(thd, $6, NULL,
+ TL_OPTION_UPDATING,
+ TL_WRITE, MDL_EXCLUSIVE))
MYSQL_YYABORT;
lex->alter_info.reset();
/*
@@ -2535,7 +2597,7 @@ create:
create_body
{
LEX *lex= thd->lex;
- lex->current_select= &lex->select_lex;
+ lex->current_select= &lex->builtin_select;
if ((lex->create_info.used_fields & HA_CREATE_USED_ENGINE) &&
!lex->create_info.db_type)
{
@@ -2544,20 +2606,23 @@ create:
ER_WARN_USING_OTHER_HANDLER,
ER_THD(thd, ER_WARN_USING_OTHER_HANDLER),
hton_name(lex->create_info.db_type)->str,
- $5->table.str);
+ $6->table.str);
}
create_table_set_open_action_and_adjust_tables(lex);
+ Lex->pop_select(); //main select
}
| create_or_replace opt_temporary SEQUENCE_SYM opt_if_not_exists table_ident
{
LEX *lex= thd->lex;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
lex->create_info.init();
if (lex->set_command_with_check(SQLCOM_CREATE_SEQUENCE, $2, $1 | $4))
MYSQL_YYABORT;
- if (!lex->select_lex.add_table_to_list(thd, $5, NULL,
- TL_OPTION_UPDATING,
- TL_WRITE, MDL_EXCLUSIVE))
+ if (!lex->builtin_select.add_table_to_list(thd, $5, NULL,
+ TL_OPTION_UPDATING,
+ TL_WRITE, MDL_EXCLUSIVE))
MYSQL_YYABORT;
/*
@@ -2580,8 +2645,8 @@ create:
if (lex->create_info.seq_create_info->check_and_adjust(1))
{
my_error(ER_SEQUENCE_INVALID_DATA, MYF(0),
- lex->select_lex.table_list.first->db.str,
- lex->select_lex.table_list.first->table_name.str);
+ lex->builtin_select.table_list.first->db.str,
+ lex->builtin_select.table_list.first->table_name.str);
MYSQL_YYABORT;
}
@@ -2593,7 +2658,7 @@ create:
Lex->create_info.used_fields|= HA_CREATE_USED_SEQUENCE;
Lex->create_info.sequence= 1;
- lex->current_select= &lex->select_lex;
+ lex->current_select= &lex->builtin_select;
if ((lex->create_info.used_fields & HA_CREATE_USED_ENGINE) &&
!lex->create_info.db_type)
{
@@ -2605,42 +2670,69 @@ create:
$5->table.str);
}
create_table_set_open_action_and_adjust_tables(lex);
+ Lex->pop_select(); //main select
}
- | create_or_replace opt_unique INDEX_SYM opt_if_not_exists ident
+ | create_or_replace opt_unique INDEX_SYM opt_if_not_exists
+ {
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
+ ident
opt_key_algorithm_clause
ON table_ident
{
- if (Lex->add_create_index_prepare($8))
+ if (Lex->add_create_index_prepare($9))
MYSQL_YYABORT;
- if (Lex->add_create_index($2, &$5, $6, $1 | $4))
+ if (Lex->add_create_index($2, &$6, $7, $1 | $4))
MYSQL_YYABORT;
}
'(' key_list ')' opt_lock_wait_timeout normal_key_options
- opt_index_lock_algorithm { }
- | create_or_replace fulltext INDEX_SYM opt_if_not_exists ident
+ opt_index_lock_algorithm
+ {
+ Lex->pop_select(); //main select
+ }
+ | create_or_replace fulltext INDEX_SYM
+ {
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
+ opt_if_not_exists ident
ON table_ident
{
- if (Lex->add_create_index_prepare($7))
+ if (Lex->add_create_index_prepare($8))
MYSQL_YYABORT;
- if (Lex->add_create_index($2, &$5, HA_KEY_ALG_UNDEF, $1 | $4))
+ if (Lex->add_create_index($2, &$6, HA_KEY_ALG_UNDEF, $1 | $5))
MYSQL_YYABORT;
}
'(' key_list ')' opt_lock_wait_timeout fulltext_key_options
- opt_index_lock_algorithm { }
- | create_or_replace spatial INDEX_SYM opt_if_not_exists ident
+ opt_index_lock_algorithm
+ {
+ Lex->pop_select(); //main select
+ }
+ | create_or_replace spatial INDEX_SYM
+ {
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
+ opt_if_not_exists ident
ON table_ident
{
- if (Lex->add_create_index_prepare($7))
+ if (Lex->add_create_index_prepare($8))
MYSQL_YYABORT;
- if (Lex->add_create_index($2, &$5, HA_KEY_ALG_UNDEF, $1 | $4))
+ if (Lex->add_create_index($2, &$6, HA_KEY_ALG_UNDEF, $1 | $5))
MYSQL_YYABORT;
}
'(' key_list ')' opt_lock_wait_timeout spatial_key_options
- opt_index_lock_algorithm { }
+ opt_index_lock_algorithm
+ {
+ Lex->pop_select(); //main select
+ }
| create_or_replace DATABASE opt_if_not_exists ident
{
Lex->create_info.default_table_charset= NULL;
Lex->create_info.used_fields= 0;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
opt_create_database_options
{
@@ -2648,58 +2740,104 @@ create:
if (lex->set_command_with_check(SQLCOM_CREATE_DB, 0, $1 | $3))
MYSQL_YYABORT;
lex->name= $4;
+ Lex->pop_select(); //main select
}
| create_or_replace definer_opt opt_view_suid VIEW_SYM
opt_if_not_exists table_ident
{
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
if (Lex->add_create_view(thd, $1 | $5,
DTYPE_ALGORITHM_UNDEFINED, $3, $6))
MYSQL_YYABORT;
}
view_list_opt AS view_select
- { }
+ {
+ Lex->pop_select(); //main select
+ }
| create_or_replace view_algorithm definer_opt opt_view_suid VIEW_SYM
opt_if_not_exists table_ident
{
if (Lex->add_create_view(thd, $1 | $6, $2, $4, $7))
MYSQL_YYABORT;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
view_list_opt AS view_select
- { }
+ {
+ Lex->pop_select(); //main select
+ }
| create_or_replace definer_opt TRIGGER_SYM
- { Lex->create_info.set($1); }
+ {
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ Lex->create_info.set($1);
+ }
trigger_tail
- { }
+ {
+ Lex->pop_select(); //main select
+ }
| create_or_replace definer_opt PROCEDURE_SYM
- { Lex->create_info.set($1); }
+ {
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ Lex->create_info.set($1);
+ }
sp_tail
- { }
+ {
+ Lex->pop_select(); //main select
+ }
| create_or_replace definer_opt EVENT_SYM
- { Lex->create_info.set($1); }
+ {
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ Lex->create_info.set($1);
+ }
event_tail
- { }
+ {
+ Lex->pop_select(); //main select
+ }
| create_or_replace definer FUNCTION_SYM
{
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
Lex->create_info.set($1);
}
- sf_tail_not_aggregate
- { }
+ sf_tail
+ {
+ Lex->pop_select(); //main select
+ }
| create_or_replace definer AGGREGATE_SYM FUNCTION_SYM
{
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
Lex->create_info.set($1);
+
}
sf_tail_aggregate
- { }
+ {
+ Lex->pop_select(); //main select
+ }
| create_or_replace no_definer FUNCTION_SYM
- { Lex->create_info.set($1); }
+ {
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ Lex->create_info.set($1);
+ }
create_function_tail
- { }
+ {
+ Lex->pop_select(); //main select
+ }
| create_or_replace no_definer AGGREGATE_SYM FUNCTION_SYM
{
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
Lex->create_info.set($1);
}
create_aggregate_function_tail
- { }
+ {
+ Lex->pop_select(); //main select
+ }
| create_or_replace USER_SYM opt_if_not_exists clear_privileges grant_list
opt_require_clause opt_resource_options
{
@@ -3098,7 +3236,7 @@ clear_privileges:
lex->columns.empty();
lex->grant= lex->grant_tot_col= 0;
lex->all_privileges= 0;
- lex->select_lex.db= null_clex_str;
+ lex->builtin_select.db= null_clex_str;
lex->ssl_type= SSL_TYPE_NOT_SPECIFIED;
lex->ssl_cipher= lex->x509_subject= lex->x509_issuer= 0;
bzero((char *)&(lex->mqh),sizeof(lex->mqh));
@@ -3168,8 +3306,13 @@ call:
{
if (Lex->call_statement_start(thd, $2))
MYSQL_YYABORT;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
+ opt_sp_cparam_list
+ {
+ Lex->pop_select(); //main select
}
- opt_sp_cparam_list {}
;
/* CALL parameters */
@@ -3586,10 +3729,16 @@ sp_hcond:
;
signal_stmt:
- SIGNAL_SYM signal_value opt_set_signal_information
+ SIGNAL_SYM
+ {
+ if (Lex->main_select_push())
+ YYABORT;
+ }
+ signal_value opt_set_signal_information
{
- if (Lex->add_signal_statement(thd, $2))
+ if (Lex->add_signal_statement(thd, $3))
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
}
;
@@ -3715,9 +3864,14 @@ resignal_stmt:
;
get_diagnostics:
- GET_SYM which_area DIAGNOSTICS_SYM diagnostics_information
+ GET_SYM which_area DIAGNOSTICS_SYM
{
- Diagnostics_information *info= $4;
+ if (Lex->main_select_push())
+ YYABORT;
+ }
+ diagnostics_information
+ {
+ Diagnostics_information *info= $5;
info->set_which_da($2);
@@ -3726,6 +3880,7 @@ get_diagnostics:
if (Lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
}
;
@@ -3893,7 +4048,16 @@ sp_decl_idents:
sp_opt_default:
/* Empty */ { $$ = NULL; }
- | DEFAULT expr { $$ = $2; }
+ | DEFAULT
+ {
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
+ expr
+ {
+ Lex->pop_select(); //main select
+ $$ = $3;
+ }
;
/*
@@ -3995,10 +4159,15 @@ sp_proc_stmt_statement:
sp_proc_stmt_return:
RETURN_SYM
- { Lex->sphead->reset_lex(thd); }
+ {
+ Lex->sphead->reset_lex(thd);
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
expr
{
LEX *lex= Lex;
+ lex->pop_select(); //main select
sp_head *sp= lex->sphead;
if (sp->m_handler->add_instr_freturn(thd, sp, lex->spcont,
$3, lex) ||
@@ -4036,6 +4205,8 @@ assignment_source_expr:
{
DBUG_ASSERT(thd->free_list == NULL);
Lex->sphead->reset_lex(thd, $1);
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
expr
{
@@ -4044,6 +4215,7 @@ assignment_source_expr:
$$->sp_lex_in_use= true;
$$->set_item_and_free_list($3, thd->free_list);
thd->free_list= NULL;
+ Lex->pop_select(); //main select
if ($$->sphead->restore_lex(thd))
MYSQL_YYABORT;
}
@@ -4176,9 +4348,14 @@ sp_fetch_list:
;
sp_if:
- { Lex->sphead->reset_lex(thd); }
+ {
+ Lex->sphead->reset_lex(thd);
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
expr THEN_SYM
{
+ Lex->pop_select(); //main select
LEX *lex= Lex;
sp_head *sp= lex->sphead;
sp_pcontext *ctx= lex->spcont;
@@ -4290,12 +4467,18 @@ case_stmt_specification:
;
case_stmt_body:
- { Lex->sphead->reset_lex(thd); /* For expr $2 */ }
+ {
+ Lex->sphead->reset_lex(thd); /* For expr $2 */
+
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
expr
{
if (Lex->case_stmt_action_expr($2))
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
if (Lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
}
@@ -4319,6 +4502,9 @@ simple_when_clause:
WHEN_SYM
{
Lex->sphead->reset_lex(thd); /* For expr $3 */
+
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
expr
{
@@ -4327,6 +4513,8 @@ simple_when_clause:
LEX *lex= Lex;
if (lex->case_stmt_action_when($3, true))
MYSQL_YYABORT;
+
+ lex->pop_select(); //main select
/* For expr $3 */
if (lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
@@ -4343,12 +4531,17 @@ searched_when_clause:
WHEN_SYM
{
Lex->sphead->reset_lex(thd); /* For expr $3 */
+
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
expr
{
LEX *lex= Lex;
if (lex->case_stmt_action_when($3, false))
MYSQL_YYABORT;
+
+ lex->pop_select(); //main select
/* For expr $3 */
if (lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
@@ -4497,6 +4690,7 @@ while_body:
LEX *lex= Lex;
if (lex->sp_while_loop_expression(thd, $1))
MYSQL_YYABORT;
+ Lex->pop_select(); //main select pushed before while_body use
if (lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
}
@@ -4509,7 +4703,12 @@ while_body:
repeat_body:
sp_proc_stmts1 UNTIL_SYM
- { Lex->sphead->reset_lex(thd); }
+ {
+ Lex->sphead->reset_lex(thd);
+
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
expr END REPEAT_SYM
{
LEX *lex= Lex;
@@ -4520,6 +4719,8 @@ repeat_body:
if (i == NULL ||
lex->sphead->add_instr(i))
MYSQL_YYABORT;
+
+ lex->pop_select(); //main select
if (lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
/* We can shortcut the cont_backpatch here */
@@ -4548,8 +4749,12 @@ sp_labeled_control:
if (Lex->sp_push_loop_label(thd, &$1))
MYSQL_YYABORT;
Lex->sphead->reset_lex(thd);
+
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
while_body pop_sp_loop_label
+
{ }
| sp_label FOR_SYM
{
@@ -4601,9 +4806,13 @@ sp_unlabeled_control:
if (Lex->sp_push_loop_empty_label(thd))
MYSQL_YYABORT;
Lex->sphead->reset_lex(thd);
+
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
while_body
{
+ // while body pop main select
Lex->sp_pop_loop_empty_label(thd);
}
| FOR_SYM
@@ -5030,25 +5239,15 @@ size_number:
*/
create_body:
- '(' create_field_list ')'
+ create_field_list_parens
{ Lex->create_info.option_list= NULL; }
opt_create_table_options opt_create_partitioning opt_create_select {}
| opt_create_table_options opt_create_partitioning opt_create_select {}
- /*
- the following rule is redundant, but there's a shift/reduce
- conflict that prevents the rule above from parsing a syntax like
- CREATE TABLE t1 (SELECT 1);
- */
- | '(' create_select_query_specification ')'
- | '(' create_select_query_specification ')'
- { Select->set_braces(1);} union_list {}
- | '(' create_select_query_specification ')'
- { Select->set_braces(1);} union_order_or_limit {}
| create_like
{
Lex->create_info.add(DDL_options_st::OPT_LIKE);
- TABLE_LIST *src_table= Lex->select_lex.add_table_to_list(thd,
+ TABLE_LIST *src_table= Lex->builtin_select.add_table_to_list(thd,
$1, NULL, 0, TL_READ, MDL_SHARED_READ);
if (! src_table)
MYSQL_YYABORT;
@@ -5059,7 +5258,7 @@ create_body:
create_like:
LIKE table_ident { $$= $2; }
- | '(' LIKE table_ident ')' { $$= $3; }
+ | LEFT_PAREN_LIKE LIKE table_ident ')' { $$= $3; }
;
opt_create_select:
@@ -5068,23 +5267,51 @@ opt_create_select:
;
create_select_query_expression:
- opt_with_clause SELECT_SYM create_select_part2 opt_table_expression
- create_select_part4
- {
- Select->set_braces(0);
- Select->set_with_clause($1);
+ query_expression
+ {
+ SELECT_LEX *first_select= $1->first_select();
+
+ if (Lex->sql_command == SQLCOM_INSERT ||
+ Lex->sql_command == SQLCOM_REPLACE)
+ {
+ if (Lex->sql_command == SQLCOM_INSERT)
+ Lex->sql_command= SQLCOM_INSERT_SELECT;
+ else
+ Lex->sql_command= SQLCOM_REPLACE_SELECT;
+ }
+ Lex->insert_select_hack(first_select);
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+
+ // fix "main" select
+ SELECT_LEX *blt= Lex->pop_select();
+ DBUG_ASSERT(blt == &Lex->builtin_select);
+ Lex->push_select(first_select);
}
- union_clause
- | opt_with_clause SELECT_SYM create_select_part2
- create_select_part3_union_not_ready create_select_part4
+ | LEFT_PAREN_WITH with_clause query_expression_body ')'
{
- Select->set_with_clause($1);
+ SELECT_LEX *first_select= $3->first_select();
+ $3->set_with_clause($2);
+ $2->attach_to(first_select);
+
+ if (Lex->sql_command == SQLCOM_INSERT ||
+ Lex->sql_command == SQLCOM_REPLACE)
+ {
+ if (Lex->sql_command == SQLCOM_INSERT)
+ Lex->sql_command= SQLCOM_INSERT_SELECT;
+ else
+ Lex->sql_command= SQLCOM_REPLACE_SELECT;
+ }
+
+ Lex->insert_select_hack(first_select);
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+
+ // fix "main" select
+ SELECT_LEX *blt= Lex->pop_select();
+ DBUG_ASSERT(blt == &Lex->builtin_select);
+ Lex->push_select(first_select);
}
- | '(' create_select_query_specification ')'
- | '(' create_select_query_specification ')'
- { Select->set_braces(1);} union_list {}
- | '(' create_select_query_specification ')'
- { Select->set_braces(1);} union_order_or_limit {}
;
opt_create_partitioning:
@@ -5170,13 +5397,17 @@ partition_entry:
thd->parse_error(ER_PARTITION_ENTRY_ERROR);
MYSQL_YYABORT;
}
- DBUG_ASSERT(Lex->part_info->table);
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
/*
We enter here when opening the frm file to translate
partition info string into part_info data structure.
*/
}
- partition {}
+ partition
+ {
+ Lex->pop_select(); //main select
+ }
;
partition:
@@ -5898,56 +6129,6 @@ opt_versioning_interval_start:
End of partition parser part
*/
-create_select_query_specification:
- opt_with_clause SELECT_SYM create_select_part2 create_select_part3
- create_select_part4
- {
- Select->set_with_clause($1);
- }
- ;
-
-create_select_part2:
- {
- LEX *lex=Lex;
- if (lex->sql_command == SQLCOM_INSERT)
- lex->sql_command= SQLCOM_INSERT_SELECT;
- else if (lex->sql_command == SQLCOM_REPLACE)
- lex->sql_command= SQLCOM_REPLACE_SELECT;
- /*
- The following work only with the local list, the global list
- is created correctly in this case
- */
- lex->current_select->table_list.save_and_clear(&lex->save_list);
- mysql_init_select(lex);
- lex->current_select->parsing_place= SELECT_LIST;
- }
- select_options select_item_list
- {
- Select->parsing_place= NO_MATTER;
- }
- ;
-
-create_select_part3:
- opt_table_expression
- | create_select_part3_union_not_ready
- ;
-
-create_select_part3_union_not_ready:
- table_expression order_or_limit
- | order_or_limit
- ;
-
-create_select_part4:
- opt_select_lock_type
- {
- /*
- The following work only with the local list, the global list
- is created correctly in this case
- */
- Lex->current_select->table_list.push_front(&Lex->save_list);
- }
- ;
-
opt_as:
/* empty */ {}
| AS {}
@@ -6165,7 +6346,7 @@ create_table_option:
}
| UNION_SYM opt_equal
{
- Lex->select_lex.table_list.save_and_clear(&Lex->save_list);
+ Lex->builtin_select.table_list.save_and_clear(&Lex->save_list);
}
'(' opt_table_list ')'
{
@@ -6174,8 +6355,8 @@ create_table_option:
from the global list.
*/
LEX *lex=Lex;
- lex->create_info.merge_list= lex->select_lex.table_list;
- lex->select_lex.table_list= lex->save_list;
+ lex->create_info.merge_list= lex->builtin_select.table_list;
+ lex->builtin_select.table_list= lex->save_list;
/*
When excluding union list from the global list we assume that
elements of the former immediately follow elements which represent
@@ -6376,6 +6557,13 @@ create_field_list:
}
;
+create_field_list_parens:
+ LEFT_PAREN_ALT field_list ')'
+ {
+ Lex->create_last_non_select_table= Lex->last_table();
+ }
+ ;
+
field_list:
field_list_item
| field_list ',' field_list_item
@@ -6702,6 +6890,8 @@ parse_vcol_expr:
Prevent the end user from invoking this command.
*/
MYSQL_YYABORT_UNLESS(Lex->parse_vcol_expr);
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
expr
{
@@ -6709,13 +6899,29 @@ parse_vcol_expr:
if (!v)
MYSQL_YYABORT;
Lex->last_field->vcol_info= v;
+ Lex->pop_select(); //main select
}
;
parenthesized_expr:
- subselect
+ remember_tok_start
+ query_expression
{
- $$= new (thd->mem_root) Item_singlerow_subselect(thd, $1);
+ if (!Lex->expr_allows_subselect ||
+ Lex->sql_command == (int)SQLCOM_PURGE)
+ {
+ thd->parse_error(ER_SYNTAX_ERROR, $1);
+ MYSQL_YYABORT;
+ }
+
+ // Add the subtree of subquery to the current SELECT_LEX
+ SELECT_LEX *curr_sel= Lex->select_stack_head();
+ DBUG_ASSERT(Lex->current_select == curr_sel);
+ curr_sel->register_unit($2, &curr_sel->context);
+ curr_sel->add_statistics($2);
+
+ $$= new (thd->mem_root)
+ Item_singlerow_subselect(thd, $2->first_select());
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -7636,22 +7842,24 @@ alter:
Lex->table_type= TABLE_TYPE_UNKNOWN;
Lex->sql_command= SQLCOM_ALTER_TABLE;
Lex->duplicates= DUP_ERROR;
- Lex->select_lex.init_order();
+ Lex->builtin_select.init_order();
Lex->create_info.init();
Lex->create_info.row_type= ROW_TYPE_NOT_USED;
Lex->alter_info.reset();
Lex->no_write_to_binlog= 0;
Lex->create_info.storage_media= HA_SM_DEFAULT;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
DBUG_ASSERT(!Lex->m_sql_cmd);
}
alter_options TABLE_SYM table_ident opt_lock_wait_timeout
{
- if (!Lex->select_lex.add_table_to_list(thd, $5, NULL,
+ if (!Lex->builtin_select.add_table_to_list(thd, $5, NULL,
TL_OPTION_UPDATING,
TL_READ_NO_INSERT,
MDL_SHARED_UPGRADABLE))
MYSQL_YYABORT;
- Lex->select_lex.db= (Lex->select_lex.table_list.first)->db;
+ Lex->builtin_select.db= (Lex->builtin_select.table_list.first)->db;
Lex->create_last_non_select_table= Lex->last_table();
}
alter_commands
@@ -7663,11 +7871,14 @@ alter:
if (Lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
}
+ Lex->pop_select(); //main select
}
| ALTER DATABASE ident_or_empty
{
Lex->create_info.default_table_charset= NULL;
Lex->create_info.used_fields= 0;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
create_database_options
{
@@ -7676,6 +7887,7 @@ alter:
lex->name= $3;
if (lex->name.str == NULL && lex->copy_db_to(&lex->name))
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
}
| ALTER DATABASE ident UPGRADE_SYM DATA_SYM DIRECTORY_SYM NAME_SYM
{
@@ -7691,6 +7903,8 @@ alter:
if (lex->sphead)
my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "PROCEDURE"));
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
lex->sp_chistics.init();
}
sp_a_chistics
@@ -7699,6 +7913,9 @@ alter:
lex->sql_command= SQLCOM_ALTER_PROCEDURE;
lex->spname= $3;
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
}
| ALTER FUNCTION_SYM sp_name
{
@@ -7706,6 +7923,8 @@ alter:
if (lex->sphead)
my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "FUNCTION"));
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
lex->sp_chistics.init();
}
sp_a_chistics
@@ -7714,14 +7933,23 @@ alter:
lex->sql_command= SQLCOM_ALTER_FUNCTION;
lex->spname= $3;
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
}
| ALTER view_algorithm definer_opt opt_view_suid VIEW_SYM table_ident
{
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
if (Lex->add_alter_view(thd, $2, $4, $6))
MYSQL_YYABORT;
}
view_list_opt AS view_select
- {}
+ {
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+ }
| ALTER definer_opt opt_view_suid VIEW_SYM table_ident
/*
We have two separate rules for ALTER VIEW rather that
@@ -7729,14 +7957,22 @@ alter:
with the ALTER EVENT below.
*/
{
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
if (Lex->add_alter_view(thd, VIEW_ALGORITHM_INHERIT, $3, $5))
MYSQL_YYABORT;
}
view_list_opt AS view_select
- {}
+ {
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+ }
| ALTER definer_opt remember_name EVENT_SYM sp_name
{
- /*
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ /*
It is safe to use Lex->spname because
ALTER EVENT xxx RENATE TO yyy DO ALTER EVENT RENAME TO
is not allowed. Lex->spname is used in the case of RENAME TO
@@ -7768,6 +8004,8 @@ alter:
*/
Lex->sql_command= SQLCOM_ALTER_EVENT;
Lex->stmt_definition_end= (char*)YYLIP->get_cpp_ptr();
+
+ Lex->pop_select(); //main select
}
| ALTER TABLESPACE alter_tablespace_info
{
@@ -7811,15 +8049,17 @@ alter:
lex->create_info.init();
lex->no_write_to_binlog= 0;
DBUG_ASSERT(!lex->m_sql_cmd);
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
table_ident
{
LEX *lex= Lex;
if (!(lex->create_info.seq_create_info= new (thd->mem_root)
sequence_definition()) ||
- !lex->select_lex.add_table_to_list(thd, $5, NULL,
- TL_OPTION_SEQUENCE,
- TL_WRITE, MDL_EXCLUSIVE))
+ !lex->builtin_select.add_table_to_list(thd, $5, NULL,
+ TL_OPTION_SEQUENCE,
+ TL_WRITE, MDL_EXCLUSIVE))
MYSQL_YYABORT;
}
sequence_defs
@@ -7828,6 +8068,9 @@ alter:
Lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_sequence($3);
if (Lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
}
;
@@ -7977,18 +8220,18 @@ alter_commands:
WITH TABLE_SYM table_ident have_partitioning
{
LEX *lex= thd->lex;
- lex->select_lex.db= $6->db;
- if (lex->select_lex.db.str == NULL &&
- lex->copy_db_to(&lex->select_lex.db))
+ lex->builtin_select.db=$6->db;
+ if (lex->builtin_select.db.str == NULL &&
+ lex->copy_db_to(&lex->builtin_select.db))
{
MYSQL_YYABORT;
}
lex->name= $6->table;
lex->alter_info.partition_flags|= ALTER_PARTITION_EXCHANGE;
- if (!lex->select_lex.add_table_to_list(thd, $6, NULL,
- TL_OPTION_UPDATING,
- TL_READ_NO_INSERT,
- MDL_SHARED_NO_WRITE))
+ if (!lex->builtin_select.add_table_to_list(thd, $6, NULL,
+ TL_OPTION_UPDATING,
+ TL_READ_NO_INSERT,
+ MDL_SHARED_NO_WRITE))
MYSQL_YYABORT;
DBUG_ASSERT(!lex->m_sql_cmd);
lex->m_sql_cmd= new (thd->mem_root)
@@ -8233,9 +8476,9 @@ alter_list_item:
| RENAME opt_to table_ident
{
LEX *lex=Lex;
- lex->select_lex.db= $3->db;
- if (lex->select_lex.db.str == NULL &&
- lex->copy_db_to(&lex->select_lex.db))
+ lex->builtin_select.db= $3->db;
+ if (lex->builtin_select.db.str == NULL &&
+ lex->copy_db_to(&lex->builtin_select.db))
{
MYSQL_YYABORT;
}
@@ -8522,9 +8765,13 @@ checksum:
lex->sql_command = SQLCOM_CHECKSUM;
/* Will be overridden during execution. */
YYPS->m_lock_type= TL_UNLOCK;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
table_list opt_checksum_type
- {}
+ {
+ Lex->pop_select(); //main select
+ }
;
opt_checksum_type:
@@ -8550,6 +8797,8 @@ repair:
lex->alter_info.reset();
/* Will be overridden during execution. */
YYPS->m_lock_type= TL_UNLOCK;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
repair_table_or_view
{
@@ -8558,6 +8807,7 @@ repair:
lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_repair_table();
if (lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
}
;
@@ -8586,6 +8836,8 @@ analyze:
ANALYZE_SYM opt_no_write_to_binlog table_or_tables
{
LEX *lex=Lex;
+ if (lex->main_select_push())
+ YYABORT;
lex->sql_command = SQLCOM_ANALYZE;
lex->no_write_to_binlog= $2;
lex->check_opt.init();
@@ -8600,6 +8852,7 @@ analyze:
lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_analyze_table();
if (lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
}
;
@@ -8716,6 +8969,8 @@ check: CHECK_SYM
lex->alter_info.reset();
/* Will be overridden during execution. */
YYPS->m_lock_type= TL_UNLOCK;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
check_view_or_table
{
@@ -8726,6 +8981,7 @@ check: CHECK_SYM
lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_check_table();
if (lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
}
;
@@ -8763,6 +9019,8 @@ optimize:
lex->alter_info.reset();
/* Will be overridden during execution. */
YYPS->m_lock_type= TL_UNLOCK;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
table_list opt_lock_wait_timeout
{
@@ -8771,6 +9029,7 @@ optimize:
lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_optimize_table();
if (lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
}
;
@@ -8784,9 +9043,13 @@ rename:
RENAME table_or_tables
{
Lex->sql_command= SQLCOM_RENAME_TABLE;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
table_to_table_list
- {}
+ {
+ Lex->pop_select(); //main select
+ }
| RENAME USER_SYM clear_privileges rename_list
{
Lex->sql_command = SQLCOM_RENAME_USER;
@@ -8880,9 +9143,13 @@ preload:
LEX *lex=Lex;
lex->sql_command=SQLCOM_PRELOAD_KEYS;
lex->alter_info.reset();
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
preload_list_or_parts
- {}
+ {
+ Lex->pop_select(); //main select
+ }
;
preload_list_or_parts:
@@ -8925,8 +9192,8 @@ adm_partition:
cache_keys_spec:
{
- Lex->select_lex.alloc_index_hints(thd);
- Select->set_index_hint_type(INDEX_HINT_USE,
+ Lex->builtin_select.alloc_index_hints(thd);
+ Select->set_index_hint_type(INDEX_HINT_USE,
INDEX_HINT_MASK_ALL);
}
cache_key_list_or_empty
@@ -8947,217 +9214,347 @@ opt_ignore_leaves:
Select : retrieve data from table
*/
-
select:
- opt_with_clause select_init
+ query_expression
{
- LEX *lex= Lex;
- lex->sql_command= SQLCOM_SELECT;
- lex->current_select->set_with_clause($1);
+ Lex->selects_allow_into= TRUE;
+ Lex->selects_allow_procedure= TRUE;
+ Lex->set_main_unit($1);
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+
+ Lex->sql_command= SQLCOM_SELECT;
}
;
-select_init:
- SELECT_SYM select_options_and_item_list select_init3
- | table_value_constructor
- | table_value_constructor union_list
- | table_value_constructor union_order_or_limit
- | '(' select_paren ')'
- | '(' select_paren ')' union_list
- | '(' select_paren ')' union_order_or_limit
- ;
-union_list_part2:
- SELECT_SYM select_options_and_item_list select_init3_union_query_term
- | table_value_constructor
- | table_value_constructor union_list
- | table_value_constructor union_order_or_limit
- | '(' select_paren_union_query_term ')'
- | '(' select_paren_union_query_term ')' union_list
- | '(' select_paren_union_query_term ')' union_order_or_limit
+simple_table:
+ query_specification { $$= $1; }
+ | table_value_constructor { $$= $1; }
;
-
-select_paren:
+
+table_value_constructor:
+ VALUES
+ {
+ LEX *lex= Lex;
+ SELECT_LEX *sel;
+ //lex->field_list.empty();
+ lex->many_values.empty();
+ lex->insert_list=0;
+ if (!(sel= lex->alloc_select(TRUE)) ||
+ lex->push_select(sel))
+ MYSQL_YYABORT;
+ sel->init_select();
+ sel->braces= FALSE; // just initialisation
+ }
+ values_list
+ {
+ LEX *lex=Lex;
+ $$= lex->pop_select(); // above TVC select
+ if (!($$->tvc=
+ new (lex->thd->mem_root) table_value_constr(lex->many_values,
+ $$,
+ $$->options)))
+ MYSQL_YYABORT;
+ lex->many_values.empty();
+ }
+ ;
+
+query_specification:
+ SELECT_SYM
{
- Lex->current_select->set_braces(true);
+ SELECT_LEX *sel;
+ LEX *lex= Lex;
+ if (!(sel= lex->alloc_select(TRUE)) ||
+ lex->push_select(sel))
+ MYSQL_YYABORT;
+ sel->init_select();
+ sel->braces= FALSE;
}
- table_value_constructor
+ select_options
{
- DBUG_ASSERT(Lex->current_select->braces);
+ Select->parsing_place= SELECT_LIST;
}
- |
+ select_item_list
{
- /*
- In order to correctly parse UNION's global ORDER BY we need to
- set braces before parsing the clause.
- */
- Lex->current_select->set_braces(true);
+ Select->parsing_place= NO_MATTER;
}
- SELECT_SYM select_options_and_item_list select_part3
- opt_select_lock_type
+ opt_into
+ opt_from_clause
+ opt_where_clause
+ opt_group_clause
+ opt_having_clause
+ opt_window_clause
{
- DBUG_ASSERT(Lex->current_select->braces);
+ $$= Lex->pop_select();
}
- | '(' select_paren ')'
;
-select_paren_union_query_term:
- {
- /*
- In order to correctly parse UNION's global ORDER BY we need to
- set braces before parsing the clause.
- */
- Lex->current_select->set_braces(true);
- }
- SELECT_SYM select_options_and_item_list select_part3_union_query_term
- opt_select_lock_type
- {
- DBUG_ASSERT(Lex->current_select->braces);
- }
- | '(' select_paren_union_query_term ')'
+opt_from_clause:
+ /* Empty */
+ | from_clause
;
-select_paren_view:
- {
- /*
- In order to correctly parse UNION's global ORDER BY we need to
- set braces before parsing the clause.
- */
- Lex->current_select->set_braces(true);
- }
- SELECT_SYM select_options_and_item_list select_part3_view
- opt_select_lock_type
- {
- DBUG_ASSERT(Lex->current_select->braces);
- }
- | '(' select_paren_view ')'
+
+query_primary:
+ simple_table
+ { $$= $1; }
+ | query_primary_parens
+ { $$= $1; }
;
-/* The equivalent of select_paren for nested queries. */
-select_paren_derived:
+query_primary_parens:
+ '(' query_expression_unit
{
- Lex->current_select->set_braces(true);
+ SELECT_LEX *last= $2->pre_last_parse->next_select();
+ int cmp= cmp_unit_op($2->first_select()->next_select()->linkage,
+ last->linkage);
+ if (cmp < 0)
+ {
+ if (!check_intersect_prefix($2->first_select()))
+ {
+ if (Lex->pop_new_select_and_wrap() == NULL)
+ MYSQL_YYABORT;
+ }
+ }
+ Lex->push_select($2->fake_select_lex);
}
- table_value_constructor
+ query_expression_tail ')'
{
- DBUG_ASSERT(Lex->current_select->braces);
- $$= Lex->current_select->master_unit()->first_select();
+ Lex->pop_select();
+ if ($4)
+ {
+ ($4)->set_to($2->fake_select_lex);
+ }
+ $$= $2->first_select();
}
- |
+ | '(' query_primary
{
- Lex->current_select->set_braces(true);
+ Lex->push_select($2);
}
- SELECT_SYM select_part2_derived
- opt_table_expression
- opt_order_clause
- opt_limit_clause
- opt_select_lock_type
+ query_expression_tail ')'
{
- DBUG_ASSERT(Lex->current_select->braces);
- $$= Lex->current_select->master_unit()->first_select();
+ Lex->pop_select();
+ $$= $2;
+ $$->braces= TRUE;
+ if ($4)
+ {
+ if ($2->next_select())
+ {
+ SELECT_LEX_UNIT *unit= $2->master_unit();
+ if (!unit)
+ unit= Lex->create_unit($2);
+ if (!unit)
+ YYABORT;
+ if (!unit->fake_select_lex->is_set_query_expr_tail)
+ $4->set_to(unit->fake_select_lex);
+ else
+ {
+ $$= Lex->wrap_unit_into_derived(unit);
+ if (!$$)
+ YYABORT;
+ $4->set_to($$);
+ }
+ }
+ else if (!$2->is_set_query_expr_tail)
+ {
+ $4->set_to($2);
+ }
+ else
+ {
+ SELECT_LEX_UNIT *unit= Lex->create_unit($2);
+ if (!unit)
+ YYABORT;
+ $$= Lex->wrap_unit_into_derived(unit);
+ if (!$$)
+ YYABORT;
+ $4->set_to($$);
+ }
+ }
}
- | '(' select_paren_derived ')' { $$= $2; }
;
-select_init3:
- opt_table_expression
- opt_select_lock_type
+query_expression_unit:
+ query_primary
+ unit_type_decl
+ query_primary
{
- /* Parentheses carry no meaning here */
- Lex->current_select->set_braces(false);
+ SELECT_LEX *sel1;
+ SELECT_LEX *sel2;
+ if (!$1->next_select())
+ sel1= $1;
+ else
+ {
+ sel1= Lex->wrap_unit_into_derived($1->master_unit());
+ if (!sel1)
+ YYABORT;
+ }
+ if (!$3->next_select())
+ sel2= $3;
+ else
+ {
+ sel2= Lex->wrap_unit_into_derived($3->master_unit());
+ if (!sel2)
+ YYABORT;
+ }
+ sel1->link_neighbour(sel2);
+ sel2->set_linkage_and_distinct($2.unit_type, $2.distinct);
+ $$= Lex->create_unit(sel1);
+ $$->pre_last_parse= sel1;
+ if ($$ == NULL)
+ YYABORT;
}
- union_clause
- | select_part3_union_not_ready
- opt_select_lock_type
+ | query_expression_unit
+ unit_type_decl
+ query_primary
{
- /* Parentheses carry no meaning here */
- Lex->current_select->set_braces(false);
- }
- ;
-
+ SELECT_LEX *sel1;
+ if (!$3->next_select())
+ sel1= $3;
+ else
+ {
+ sel1= Lex->wrap_unit_into_derived($3->master_unit());
+ if (!sel1)
+ YYABORT;
+ }
+ SELECT_LEX *last= $1->pre_last_parse->next_select();
-select_init3_union_query_term:
- opt_table_expression
- opt_select_lock_type
- {
- /* Parentheses carry no meaning here */
- Lex->current_select->set_braces(false);
- }
- union_clause
- | select_part3_union_not_ready_noproc
- opt_select_lock_type
- {
- /* Parentheses carry no meaning here */
- Lex->current_select->set_braces(false);
+ int cmp= cmp_unit_op($2.unit_type, last->linkage);
+ if (cmp == 0)
+ {
+ // do nothing, this part will be just connected
+ }
+ else if (cmp > 0)
+ {
+ // Store beginning and continue to connect parts
+ if (Lex->push_new_select($1->pre_last_parse))
+ MYSQL_YYABORT;
+ }
+ else /* cmp < 0 */
+ {
+ // wrap stored part in a select, then continue to connect parts
+ if (!check_intersect_prefix($1->first_select()))
+ {
+ if ((last= Lex->pop_new_select_and_wrap()) == NULL)
+ MYSQL_YYABORT;
+ last->set_master_unit($1);
+ }
+ }
+ last->link_neighbour(sel1);
+ sel1->set_master_unit($1);
+ sel1->set_linkage_and_distinct($2.unit_type, $2.distinct);
+ $$= $1;
+ $$->pre_last_parse= last;
}
;
-
-select_init3_view:
- opt_table_expression opt_select_lock_type
+query_expression_body:
+ query_primary
{
- Lex->current_select->set_braces(false);
+ Lex->push_select($1);
}
- | opt_table_expression opt_select_lock_type
+ query_expression_tail
{
- Lex->current_select->set_braces(false);
+ Lex->pop_select();
+ SELECT_LEX *sel= $1;
+ if ($3)
+ {
+ if ($1->next_select())
+ {
+ SELECT_LEX_UNIT *unit= $1->master_unit();
+ if (!unit)
+ unit= Lex->create_unit($1);
+ if (!unit)
+ YYABORT;
+ if (!unit->fake_select_lex->is_set_query_expr_tail)
+ $3->set_to(unit->fake_select_lex);
+ else
+ {
+ SELECT_LEX *sel= Lex->wrap_unit_into_derived(unit);
+ if (!sel)
+ YYABORT;
+ $3->set_to(sel);
+ }
+ }
+ else if (!$1->is_set_query_expr_tail)
+ $3->set_to($1);
+ else
+ {
+ SELECT_LEX_UNIT *unit= $1->master_unit();
+ if (!unit)
+ unit= Lex->create_unit($1);
+ if (!unit)
+ YYABORT;
+ sel= Lex->wrap_unit_into_derived(unit);
+ if (!sel)
+ YYABORT;
+ $3->set_to(sel);
+ }
+ }
+ $$= Lex->create_unit(sel);
+ if ($$ == NULL)
+ YYABORT;
}
- union_list_view
- | order_or_limit opt_select_lock_type
+ | query_expression_unit
{
- Lex->current_select->set_braces(false);
+ SELECT_LEX *last= $1->pre_last_parse->next_select();
+ int cmp= cmp_unit_op($1->first_select()->next_select()->linkage,
+ last->linkage);
+ if (cmp < 0)
+ {
+ if (!check_intersect_prefix($1->first_select()))
+ {
+ if (Lex->pop_new_select_and_wrap() == NULL)
+ MYSQL_YYABORT;
+ }
+ }
+ Lex->push_select($1->fake_select_lex);
}
- | table_expression order_or_limit opt_select_lock_type
+ query_expression_tail
{
- Lex->current_select->set_braces(false);
+ Lex->pop_select();
+ if ($3)
+ {
+ ($3)->set_to($1->fake_select_lex);
+ }
+ $$= $1;
}
;
-/*
- The SELECT parts after select_item_list that cannot be followed by UNION.
-*/
-
-select_part3:
- opt_table_expression
- | select_part3_union_not_ready
- ;
-
-select_part3_union_query_term:
- opt_table_expression
- | select_part3_union_not_ready_noproc
- ;
-
-select_part3_view:
- opt_table_expression
- | order_or_limit
- | table_expression order_or_limit
+query_expression:
+ opt_with_clause
+ query_expression_body
+ {
+ if ($1)
+ {
+ $2->set_with_clause($1);
+ $1->attach_to($2->first_select());
+ }
+ $$= $2;
+ }
;
-select_part3_union_not_ready:
- select_part3_union_not_ready_noproc
- | table_expression procedure_clause
- | table_expression order_or_limit procedure_clause
- ;
+subselect:
+ remember_tok_start
+ query_expression
+ {
+ if (!Lex->expr_allows_subselect ||
+ Lex->sql_command == (int)SQLCOM_PURGE)
+ {
+ thd->parse_error(ER_SYNTAX_ERROR, $1);
+ MYSQL_YYABORT;
+ }
-select_part3_union_not_ready_noproc:
- order_or_limit
- | into opt_table_expression opt_order_clause opt_limit_clause
- | table_expression into
- | table_expression order_or_limit
- | table_expression order_or_limit into
- ;
+ // Add the subtree of subquery to the current SELECT_LEX
+ SELECT_LEX *curr_sel= Lex->select_stack_head();
+ DBUG_ASSERT(Lex->current_select == curr_sel);
+ if (curr_sel)
+ {
+ curr_sel->register_unit($2, &curr_sel->context);
+ curr_sel->add_statistics($2);
+ }
-select_options_and_item_list:
- {
- LEX *lex= Lex;
- SELECT_LEX *sel= lex->current_select;
- if (sel->linkage != UNION_TYPE)
- mysql_init_select(lex);
- lex->current_select->parsing_place= SELECT_LIST;
- }
- select_options select_item_list
- {
- Select->parsing_place= NO_MATTER;
+ $$= $2->first_select();
}
;
@@ -9165,18 +9562,6 @@ select_options_and_item_list:
/**
<table expression>, as in the SQL standard.
*/
-table_expression:
- from_clause
- opt_where_clause
- opt_group_clause
- opt_having_clause
- opt_window_clause
- ;
-
-opt_table_expression:
- /* Empty */
- | table_expression
- ;
from_clause:
FROM table_reference_list
@@ -9274,59 +9659,63 @@ select_option:
query_expression_option
| SQL_NO_CACHE_SYM
{
- /*
- Allow this flag only on the first top-level SELECT statement, if
- SQL_CACHE wasn't specified, and only once per query.
- */
- if (Lex->current_select != &Lex->select_lex)
- my_yyabort_error((ER_CANT_USE_OPTION_HERE, MYF(0), "SQL_NO_CACHE"));
- if (Lex->select_lex.sql_cache == SELECT_LEX::SQL_CACHE)
- my_yyabort_error((ER_WRONG_USAGE, MYF(0), "SQL_CACHE", "SQL_NO_CACHE"));
- if (Lex->select_lex.sql_cache == SELECT_LEX::SQL_NO_CACHE)
+ /*
+ Allow this flag once per query.
+ */
+ if (Select->options & OPTION_NO_QUERY_CACHE)
my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "SQL_NO_CACHE"));
-
- Lex->safe_to_cache_query=0;
- Lex->select_lex.options&= ~OPTION_TO_QUERY_CACHE;
- Lex->select_lex.sql_cache= SELECT_LEX::SQL_NO_CACHE;
+ Select->options|= OPTION_NO_QUERY_CACHE;
}
| SQL_CACHE_SYM
{
- /*
- Allow this flag only on the first top-level SELECT statement, if
- SQL_NO_CACHE wasn't specified, and only once per query.
- */
- if (Lex->current_select != &Lex->select_lex)
- my_yyabort_error((ER_CANT_USE_OPTION_HERE, MYF(0), "SQL_CACHE"));
- if (Lex->select_lex.sql_cache == SELECT_LEX::SQL_NO_CACHE)
- my_yyabort_error((ER_WRONG_USAGE, MYF(0), "SQL_NO_CACHE", "SQL_CACHE"));
- if (Lex->select_lex.sql_cache == SELECT_LEX::SQL_CACHE)
+ /*
+ Allow this flag once per query.
+ */
+ if (Select->options & OPTION_TO_QUERY_CACHE)
my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "SQL_CACHE"));
-
- Lex->safe_to_cache_query=1;
- Lex->select_lex.options|= OPTION_TO_QUERY_CACHE;
- Lex->select_lex.sql_cache= SELECT_LEX::SQL_CACHE;
+ Select->options|= OPTION_TO_QUERY_CACHE;
}
;
opt_select_lock_type:
/* empty */
- | FOR_SYM UPDATE_SYM opt_lock_wait_timeout
+ { $$.empty(); }
+ | select_lock_type
+ { $$= $1; }
+ ;
+
+select_lock_type:
+ FOR_SYM UPDATE_SYM opt_lock_wait_timeout_new
{
- LEX *lex=Lex;
- lex->current_select->lock_type= TL_WRITE;
- lex->current_select->set_lock_for_tables(TL_WRITE);
- lex->safe_to_cache_query=0;
+ $$= $3;
+ $$.defined_lock= TRUE;
+ $$.update_lock= TRUE;
}
- | LOCK_SYM IN_SYM SHARE_SYM MODE_SYM opt_lock_wait_timeout
+ | LOCK_SYM IN_SYM SHARE_SYM MODE_SYM opt_lock_wait_timeout_new
{
- LEX *lex=Lex;
- lex->current_select->lock_type= TL_READ_WITH_SHARED_LOCKS;
- lex->current_select->
- set_lock_for_tables(TL_READ_WITH_SHARED_LOCKS);
- lex->safe_to_cache_query=0;
+ $$= $5;
+ $$.defined_lock= TRUE;
+ $$.update_lock= FALSE;
}
;
+opt_lock_wait_timeout_new:
+ /* empty */
+ {
+ $$.empty();
+ }
+ | WAIT_SYM ulong_num
+ {
+ $$.defined_timeout= TRUE;
+ $$.timeout= $2;
+ }
+ | NOWAIT_SYM
+ {
+ $$.defined_timeout= TRUE;
+ $$.timeout= 0;
+ }
+ ;
+
select_item_list:
select_item_list ',' select_item
| select_item
@@ -11563,10 +11952,15 @@ esc_table_ref:
/* Equivalent to <table reference list> in the SQL:2003 standard. */
/* Warning - may return NULL in case of incomplete SELECT */
derived_table_list:
- esc_table_ref { $$=$1; }
+ esc_table_ref
+ {
+ $$=$1;
+ Select->add_joined_table($1);
+ }
| derived_table_list ',' esc_table_ref
{
MYSQL_YYABORT_UNLESS($1 && ($$=$3));
+ Select->add_joined_table($3);
}
;
@@ -11585,11 +11979,18 @@ join_table:
left-associative joins.
*/
table_ref normal_join table_ref %prec TABLE_REF_PRIORITY
- { MYSQL_YYABORT_UNLESS($1 && ($$=$3)); $3->straight=$2; }
+ {
+ MYSQL_YYABORT_UNLESS($1 && ($$=$3));
+ Select->add_joined_table($1);
+ Select->add_joined_table($3);
+ $3->straight=$2;
+ }
| table_ref normal_join table_ref
ON
{
MYSQL_YYABORT_UNLESS($1 && $3);
+ Select->add_joined_table($1);
+ Select->add_joined_table($3);
/* Change the current name resolution context to a local context. */
if (push_new_name_resolution_context(thd, $1, $3))
MYSQL_YYABORT;
@@ -11606,6 +12007,8 @@ join_table:
USING
{
MYSQL_YYABORT_UNLESS($1 && $3);
+ Select->add_joined_table($1);
+ Select->add_joined_table($3);
}
'(' using_list ')'
{
@@ -11616,6 +12019,8 @@ join_table:
| table_ref NATURAL inner_join table_factor
{
MYSQL_YYABORT_UNLESS($1 && ($$=$4));
+ Select->add_joined_table($1);
+ Select->add_joined_table($4);
$4->straight=$3;
add_join_natural($1,$4,NULL,Select);
}
@@ -11625,6 +12030,8 @@ join_table:
ON
{
MYSQL_YYABORT_UNLESS($1 && $5);
+ Select->add_joined_table($1);
+ Select->add_joined_table($5);
/* Change the current name resolution context to a local context. */
if (push_new_name_resolution_context(thd, $1, $5))
MYSQL_YYABORT;
@@ -11641,6 +12048,8 @@ join_table:
| table_ref LEFT opt_outer JOIN_SYM table_factor
{
MYSQL_YYABORT_UNLESS($1 && $5);
+ Select->add_joined_table($1);
+ Select->add_joined_table($5);
}
USING '(' using_list ')'
{
@@ -11651,6 +12060,8 @@ join_table:
| table_ref NATURAL LEFT opt_outer JOIN_SYM table_factor
{
MYSQL_YYABORT_UNLESS($1 && $6);
+ Select->add_joined_table($1);
+ Select->add_joined_table($6);
add_join_natural($1,$6,NULL,Select);
$6->outer_join|=JOIN_TYPE_LEFT;
$$=$6;
@@ -11661,6 +12072,8 @@ join_table:
ON
{
MYSQL_YYABORT_UNLESS($1 && $5);
+ Select->add_joined_table($1);
+ Select->add_joined_table($5);
/* Change the current name resolution context to a local context. */
if (push_new_name_resolution_context(thd, $1, $5))
MYSQL_YYABORT;
@@ -11678,6 +12091,8 @@ join_table:
| table_ref RIGHT opt_outer JOIN_SYM table_factor
{
MYSQL_YYABORT_UNLESS($1 && $5);
+ Select->add_joined_table($1);
+ Select->add_joined_table($5);
}
USING '(' using_list ')'
{
@@ -11689,6 +12104,8 @@ join_table:
| table_ref NATURAL RIGHT opt_outer JOIN_SYM table_factor
{
MYSQL_YYABORT_UNLESS($1 && $6);
+ Select->add_joined_table($1);
+ Select->add_joined_table($6);
add_join_natural($6,$1,NULL,Select);
LEX *lex= Lex;
if (!($$= lex->current_select->convert_right_join()))
@@ -11724,42 +12141,71 @@ use_partition:
}
;
-/*
- This is a flattening of the rules <table factor> and <table primary>
- in the SQL:2003 standard, since we don't have <sample clause>
-
- I.e.
- <table factor> ::= <table primary> [ <sample clause> ]
-*/
-/* Warning - may return NULL in case of incomplete SELECT */
table_factor:
- table_primary_ident
- | table_primary_derived
+ table_primary_ident { $$= $1; }
+ | table_primary_derived { $$= $1; }
+ | join_table_parens { $$= $1; }
+ | table_reference_list_parens { $$= $1; }
;
+table_reference_list_parens:
+ '(' table_reference_list_parens ')' { $$= $2; }
+ | '(' nested_table_reference_list ')'
+ {
+ if (!($$= Select->end_nested_join(thd)))
+ MYSQL_YYABORT;
+ }
+ ;
+
+nested_table_reference_list:
+ table_ref ',' table_ref
+ {
+ if (Select->init_nested_join(thd))
+ MYSQL_YYABORT;
+ Select->add_joined_table($1);
+ Select->add_joined_table($3);
+ $$= $1->embedding;
+ }
+ | nested_table_reference_list ',' table_ref
+ {
+ Select->add_joined_table($3);
+ $$= $1;
+ }
+ ;
+
+join_table_parens:
+ '(' join_table_parens ')' { $$= $2; }
+ | '(' join_table ')'
+ {
+ LEX *lex= Lex;
+ if (!($$= lex->current_select->nest_last_join(thd)))
+ {
+ thd->parse_error();
+ MYSQL_YYABORT;
+ }
+ }
+ ;
+
+
table_primary_ident:
+ table_ident opt_use_partition opt_for_system_time_clause
+ opt_table_alias_clause opt_key_definition
{
- DBUG_ASSERT(Select);
SELECT_LEX *sel= Select;
sel->table_join_options= 0;
- }
- table_ident opt_use_partition opt_for_system_time_clause opt_table_alias opt_key_definition
- {
- if (!($$= Select->add_table_to_list(thd, $2, $5,
+ if (!($$= Select->add_table_to_list(thd, $1, $4,
Select->get_table_join_options(),
YYPS->m_lock_type,
YYPS->m_mdl_type,
Select->pop_index_hints(),
- $3)))
+ $2)))
MYSQL_YYABORT;
- Select->add_joined_table($$);
- if ($4)
+ if ($3)
$$->vers_conditions= Lex->vers_conditions;
}
;
-
/*
Represents a flattening of the following rules from the SQL:2003
standard. This sub-rule corresponds to the sub-rule
@@ -11777,289 +12223,66 @@ table_primary_ident:
*/
table_primary_derived:
- '(' get_select_lex select_derived_union ')' opt_for_system_time_clause opt_table_alias
+ query_primary_parens opt_for_system_time_clause table_alias_clause
{
- /* Use $2 instead of Lex->current_select as derived table will
- alter value of Lex->current_select. */
- if (!($3 || $6) && $2->embedding &&
- !$2->embedding->nested_join->join_list.elements)
+ LEX *lex=Lex;
+ lex->derived_tables|= DERIVED_SUBQUERY;
+ $1->linkage= DERIVED_TABLE_TYPE;
+ $1->braces= FALSE;
+ // Add the subtree of subquery to the current SELECT_LEX
+ SELECT_LEX *curr_sel= Lex->select_stack_head();
+ DBUG_ASSERT(Lex->current_select == curr_sel);
+ SELECT_LEX_UNIT *unit= $1->master_unit();
+ if (!unit)
{
- /* we have a derived table ($3 == NULL) but no alias,
- Since we are nested in further parentheses so we
- can pass NULL to the outer level parentheses
- Permits parsing of "((((select ...))) as xyz)" */
- $$= 0;
+ unit= Lex->create_unit($1);
+ if (!unit)
+ YYABORT;
}
- else if (!$3)
- {
- /* Handle case of derived table, alias may be NULL if there
- are no outer parentheses, add_table_to_list() will throw
- error in this case */
- LEX *lex=Lex;
- lex->check_automatic_up(UNSPECIFIED_TYPE);
- SELECT_LEX *sel= lex->current_select;
- SELECT_LEX_UNIT *unit= sel->master_unit();
- lex->current_select= sel= unit->outer_select();
- Table_ident *ti= new (thd->mem_root) Table_ident(unit);
- if (ti == NULL)
- MYSQL_YYABORT;
- if (!($$= sel->add_table_to_list(thd,
- ti, $6, 0,
- TL_READ, MDL_SHARED_READ)))
+ curr_sel->register_unit(unit, &curr_sel->context);
+ curr_sel->add_statistics(unit);
- MYSQL_YYABORT;
- sel->add_joined_table($$);
- lex->pop_context();
- lex->nest_level--;
- }
- else if ($6 != NULL)
- {
- /*
- Tables with or without joins within parentheses cannot
- have aliases, and we ruled out derived tables above.
- */
- thd->parse_error();
- MYSQL_YYABORT;
- }
- else
- {
- /* nested join: FROM (t1 JOIN t2 ...),
- nest_level is the same as in the outer query */
- $$= $3;
- }
- /*
- Fields in derived table can be used in upper select in
- case of merge. We do not add HAVING fields because we do
- not merge such derived. We do not add union because
- also do not merge them
- */
- if ($$ && $$->derived &&
- !$$->derived->first_select()->next_select())
- $$->select_lex->add_where_field($$->derived->first_select());
- if ($5)
- {
- MYSQL_YYABORT_UNLESS(!$3);
- $$->vers_conditions= Lex->vers_conditions;
- }
- }
- /* Represents derived table with WITH clause */
- | '(' get_select_lex subselect_start
- with_clause query_expression_body
- subselect_end ')' opt_for_system_time_clause opt_table_alias
- {
- LEX *lex=Lex;
- SELECT_LEX *sel= $2;
- SELECT_LEX_UNIT *unit= $5->master_unit();
Table_ident *ti= new (thd->mem_root) Table_ident(unit);
if (ti == NULL)
MYSQL_YYABORT;
- $5->set_with_clause($4);
- lex->current_select= sel;
- if (!($$= sel->add_table_to_list(lex->thd,
- ti, $9, 0,
- TL_READ, MDL_SHARED_READ)))
+ if (!($$= curr_sel->add_table_to_list(lex->thd,
+ ti, $3, 0,
+ TL_READ, MDL_SHARED_READ)))
MYSQL_YYABORT;
- sel->add_joined_table($$);
- if ($8)
- $$->vers_conditions= Lex->vers_conditions;
- }
- ;
-
-/*
- This rule accepts just about anything. The reason is that we have
- empty-producing rules in the beginning of rules, in this case
- subselect_start. This forces bison to take a decision which rules to
- reduce by long before it has seen any tokens. This approach ties us
- to a very limited class of parseable languages, and unfortunately
- SQL is not one of them. The chosen 'solution' was this rule, which
- produces just about anything, even complete bogus statements, for
- instance ( table UNION SELECT 1 ).
- Fortunately, we know that the semantic value returned by
- select_derived is NULL if it contained a derived table, and a pointer to
- the base table's TABLE_LIST if it was a base table. So in the rule
- regarding union's, we throw a parse error manually and pretend it
- was bison that did it.
-
- Also worth noting is that this rule concerns query expressions in
- the from clause only. Top level select statements and other types of
- subqueries have their own union rules.
-*/
-select_derived_union:
- select_derived
- | select_derived union_order_or_limit
- {
- if ($1)
- {
- thd->parse_error();
- MYSQL_YYABORT;
- }
- }
- | select_derived union_head_non_top
- {
- if ($1)
+ if ($2)
{
- thd->parse_error();
- MYSQL_YYABORT;
+ $$->vers_conditions= Lex->vers_conditions;
}
}
- union_list_derived_part2
- | derived_simple_table opt_select_lock_type
- | derived_simple_table order_or_limit opt_select_lock_type
- | derived_simple_table opt_select_lock_type union_list_derived
- ;
-
-union_list_derived_part2:
- query_term_union_not_ready { Lex->pop_context(); }
- | query_term_union_ready { Lex->pop_context(); }
- | query_term_union_ready { Lex->pop_context(); } union_list_derived
- ;
-
-union_list_derived:
- union_head_non_top union_list_derived_part2
- ;
-
-
-/* The equivalent of select_init2 for nested queries. */
-select_init2_derived:
- select_part2_derived
- {
- Select->set_braces(0);
- }
- ;
-
-/* The equivalent of select_part2 for nested queries. */
-select_part2_derived:
- {
- LEX *lex= Lex;
- SELECT_LEX *sel= lex->current_select;
- if (sel->linkage != UNION_TYPE)
- mysql_init_select(lex);
- lex->current_select->parsing_place= SELECT_LIST;
- }
- opt_query_expression_options select_item_list
- {
- Select->parsing_place= NO_MATTER;
- }
- ;
-
-/* handle contents of parentheses in join expression */
-select_derived:
- get_select_lex_derived derived_table_list
+ | '('
+ query_expression
+ ')' opt_for_system_time_clause table_alias_clause
{
- LEX *lex= Lex;
- /* for normal joins, $2 != NULL and end_nested_join() != NULL,
- for derived tables, both must equal NULL */
+ LEX *lex=Lex;
+ lex->derived_tables|= DERIVED_SUBQUERY;
+ $2->first_select()->linkage= DERIVED_TABLE_TYPE;
- if (!($$= $1->end_nested_join(lex->thd)) && $2)
- MYSQL_YYABORT;
- if (!$2 && $$)
- {
- thd->parse_error();
- MYSQL_YYABORT;
- }
- }
- ;
-derived_simple_table:
- derived_query_specification { $$= $1; }
- | derived_table_value_constructor { $$= $1; }
- ;
-/*
- Similar to query_specification, but for derived tables.
- Example: the inner parenthesized SELECT in this query:
- SELECT * FROM (SELECT * FROM t1);
-*/
-derived_query_specification:
- SELECT_SYM select_derived_init select_derived2
- {
- if ($2)
- Select->set_braces(1);
- $$= NULL;
- }
- ;
+ // Add the subtree of subquery to the current SELECT_LEX
+ SELECT_LEX *curr_sel= Lex->select_stack_head();
+ DBUG_ASSERT(Lex->current_select == curr_sel);
+ curr_sel->register_unit($2, &curr_sel->context);
+ curr_sel->add_statistics($2);
-derived_table_value_constructor:
- VALUES
- {
- LEX *lex=Lex;
- lex->field_list.empty();
- lex->many_values.empty();
- lex->insert_list=0;
- }
- values_list
- {
- LEX *lex= Lex;
- lex->derived_tables|= DERIVED_SUBQUERY;
- if (!lex->expr_allows_subselect ||
- lex->sql_command == (int)SQLCOM_PURGE)
- {
- thd->parse_error();
+ Table_ident *ti= new (thd->mem_root) Table_ident($2);
+ if (ti == NULL)
MYSQL_YYABORT;
- }
- if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE ||
- mysql_new_select(lex, 1, NULL))
+ if (!($$= curr_sel->add_table_to_list(lex->thd,
+ ti, $5, 0,
+ TL_READ, MDL_SHARED_READ)))
MYSQL_YYABORT;
- mysql_init_select(lex);
- lex->current_select->linkage= DERIVED_TABLE_TYPE;
-
- if (!(lex->current_select->tvc=
- new (lex->thd->mem_root) table_value_constr(lex->many_values,
- lex->current_select,
- lex->current_select->options)))
- MYSQL_YYABORT;
- lex->many_values.empty();
- $$= NULL;
- }
- ;
-
-
-select_derived2:
- {
- LEX *lex= Lex;
- lex->derived_tables|= DERIVED_SUBQUERY;
- if (!lex->expr_allows_subselect ||
- lex->sql_command == (int)SQLCOM_PURGE)
+ if ($4)
{
- thd->parse_error();
- MYSQL_YYABORT;
+ $$->vers_conditions= Lex->vers_conditions;
}
- if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE ||
- mysql_new_select(lex, 1, NULL))
- MYSQL_YYABORT;
- mysql_init_select(lex);
- lex->current_select->linkage= DERIVED_TABLE_TYPE;
- lex->current_select->parsing_place= SELECT_LIST;
- }
- select_options select_item_list
- {
- Select->parsing_place= NO_MATTER;
}
- opt_table_expression
;
-get_select_lex:
- /* Empty */ { $$= Select; }
- ;
-
-get_select_lex_derived:
- get_select_lex
- {
- LEX *lex= Lex;
- if ($1->init_nested_join(lex->thd))
- MYSQL_YYABORT;
- }
- ;
-
-select_derived_init:
- {
- LEX *lex= Lex;
-
- TABLE_LIST *embedding= lex->current_select->embedding;
- $$= embedding &&
- !embedding->nested_join->join_list.elements;
- /* return true if we are deeply nested */
- }
- ;
opt_outer:
/* empty */ {}
@@ -12190,9 +12413,14 @@ table_alias:
| '='
;
-opt_table_alias:
+opt_table_alias_clause:
/* empty */ { $$=0; }
- | table_alias ident_table_alias
+
+ | table_alias_clause { $$= $1; }
+ ;
+
+table_alias_clause:
+ table_alias ident_table_alias
{
$$= (LEX_CSTRING*) thd->memdup(&$2,sizeof(LEX_STRING));
if ($$ == NULL)
@@ -12359,7 +12587,7 @@ opt_window_partition_clause:
opt_window_order_clause:
/* empty */ { }
- | ORDER_SYM BY order_list
+ | ORDER_SYM BY order_list { Select->order_list= *($3); }
;
opt_window_frame_clause:
@@ -12483,64 +12711,35 @@ alter_order_item:
opt_order_clause:
/* empty */
+ { $$= NULL; }
| order_clause
+ { $$= $1; }
;
order_clause:
ORDER_SYM BY
{
- LEX *lex=Lex;
- SELECT_LEX *sel= lex->current_select;
- SELECT_LEX_UNIT *unit= sel-> master_unit();
- if (sel->linkage != GLOBAL_OPTIONS_TYPE &&
- sel->olap != UNSPECIFIED_OLAP_TYPE &&
- (sel->linkage != UNION_TYPE || sel->braces))
- {
- my_error(ER_WRONG_USAGE, MYF(0),
- "CUBE/ROLLUP", "ORDER BY");
- MYSQL_YYABORT;
- }
- if (lex->sql_command != SQLCOM_ALTER_TABLE &&
- !unit->fake_select_lex)
- {
- /*
- A query of the of the form (SELECT ...) ORDER BY order_list is
- executed in the same way as the query
- SELECT ... ORDER BY order_list
- unless the SELECT construct contains ORDER BY or LIMIT clauses.
- Otherwise we create a fake SELECT_LEX if it has not been created
- yet.
- */
- SELECT_LEX *first_sl= unit->first_select();
- if (!unit->is_unit_op() &&
- (first_sl->order_list.elements ||
- first_sl->select_limit) &&
- unit->add_fake_select_lex(thd))
- MYSQL_YYABORT;
- }
- if (sel->master_unit()->is_unit_op() && !sel->braces)
- {
- /*
- At this point we don't know yet whether this is the last
- select in union or not, but we move ORDER BY to
- fake_select_lex anyway. If there would be one more select
- in union mysql_new_select will correctly throw error.
- */
- DBUG_ASSERT(sel->master_unit()->fake_select_lex);
- lex->current_select= sel->master_unit()->fake_select_lex;
- }
+ thd->where= "ORDER clause";
}
order_list
{
-
+ $$= $4;
}
;
order_list:
order_list ',' order_ident order_dir
- { if (add_order_to_list(thd, $3,(bool) $4)) MYSQL_YYABORT; }
+ {
+ $$= $1;
+ if (add_to_list(thd, *$$, $3,(bool) $4))
+ MYSQL_YYABORT;
+ }
| order_ident order_dir
- { if (add_order_to_list(thd, $1,(bool) $2)) MYSQL_YYABORT; }
+ {
+ $$= new (thd->mem_root) SQL_I_List<ORDER>();
+ if (add_to_list(thd, *$$, $1, (bool) $2))
+ MYSQL_YYABORT;
+ }
;
order_dir:
@@ -12550,63 +12749,61 @@ order_dir:
;
opt_limit_clause:
- /* empty */ {}
- | limit_clause {}
+ /* empty */
+ { $$.empty(); }
+ | limit_clause
+ { $$= $1; }
;
-limit_clause_init:
- LIMIT
- {
- SELECT_LEX *sel= Select;
- if (sel->master_unit()->is_unit_op() && !sel->braces)
- {
- /* Move LIMIT that belongs to UNION to fake_select_lex */
- Lex->current_select= sel->master_unit()->fake_select_lex;
- DBUG_ASSERT(Select);
- }
- }
- ;
-
limit_clause:
- limit_clause_init limit_options
+ LIMIT limit_options
{
- SELECT_LEX *sel= Select;
- if (!sel->select_limit->basic_const_item() ||
- sel->select_limit->val_int() > 0)
+ $$= $2;
+ if (!$$.select_limit->basic_const_item() ||
+ $$.select_limit->val_int() > 0)
Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT);
}
- | limit_clause_init limit_options
+ | LIMIT limit_options
ROWS_SYM EXAMINED_SYM limit_rows_option
{
+ $$= $2;
Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT);
}
- | limit_clause_init ROWS_SYM EXAMINED_SYM limit_rows_option
+ | LIMIT ROWS_SYM EXAMINED_SYM limit_rows_option
{
+ $$.select_limit= 0;
+ $$.offset_limit= 0;
+ $$.explicit_limit= 1;
Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT);
}
;
-limit_options:
- limit_option
+opt_global_limit_clause:
+ opt_limit_clause
{
- SELECT_LEX *sel= Select;
- sel->select_limit= $1;
- sel->offset_limit= 0;
- sel->explicit_limit= 1;
+ Select->explicit_limit= $1.explicit_limit;
+ Select->select_limit= $1.select_limit;
+ Select->offset_limit= $1.offset_limit;
+ }
+
+limit_options:
+ limit_option
+ {
+ $$.select_limit= $1;
+ $$.offset_limit= 0;
+ $$.explicit_limit= 1;
}
| limit_option ',' limit_option
{
- SELECT_LEX *sel= Select;
- sel->select_limit= $3;
- sel->offset_limit= $1;
- sel->explicit_limit= 1;
+ $$.select_limit= $3;
+ $$.offset_limit= $1;
+ $$.explicit_limit= 1;
}
| limit_option OFFSET_SYM limit_option
{
- SELECT_LEX *sel= Select;
- sel->select_limit= $1;
- sel->offset_limit= $3;
- sel->explicit_limit= 1;
+ $$.select_limit= $1;
+ $$.offset_limit= $3;
+ $$.explicit_limit= 1;
}
;
@@ -12675,6 +12872,66 @@ delete_limit_clause:
| LIMIT limit_option ROWS_SYM EXAMINED_SYM { thd->parse_error(); MYSQL_YYABORT; }
;
+query_expression_tail:
+ /* empty */ { $$= NULL; }
+ | order_or_limit opt_select_lock_type
+ {
+ $$= $1;
+ $$->lock= $2;
+ }
+ | order_or_limit procedure_or_into opt_select_lock_type
+ {
+ $$= $1;
+ $$->lock= $3;
+ }
+ | procedure_or_into opt_select_lock_type
+ {
+ $$= new(thd->mem_root) Lex_order_limit_lock;
+ if (!$$)
+ YYABORT;
+ $$->order_list= NULL;
+ $$->limit.empty();
+ $$->lock= $2;
+ }
+ | select_lock_type
+ {
+ $$= new(thd->mem_root) Lex_order_limit_lock;
+ if (!$$)
+ YYABORT;
+ $$->order_list= NULL;
+ $$->limit.empty();
+ $$->lock= $1;
+ }
+ ;
+
+procedure_or_into:
+ procedure_clause
+ | into
+ | procedure_clause into
+ ;
+
+order_or_limit:
+ order_clause opt_limit_clause
+ {
+ $$= new(thd->mem_root) Lex_order_limit_lock;
+ if (!$$)
+ YYABORT;
+ $$->order_list= $1;
+ $$->limit= $2;
+ }
+ | limit_clause
+ {
+ Lex_order_limit_lock *op= $$= new(thd->mem_root) Lex_order_limit_lock;
+ if (!$$)
+ YYABORT;
+ op->order_list= NULL;
+ op->limit= $1;
+ $$->order_list= NULL;
+ $$->limit= $1;
+ }
+ ;
+
+
opt_plus:
/* empty */
| '+'
@@ -12744,14 +13001,11 @@ bool:
| TRUE_SYM { $$= 1; }
| FALSE_SYM { $$= 0; }
-
procedure_clause:
PROCEDURE_SYM ident /* Procedure name */
{
LEX *lex=Lex;
- DBUG_ASSERT(&lex->select_lex == lex->current_select);
-
lex->proc_list.elements=0;
lex->proc_list.first=0;
lex->proc_list.next= &lex->proc_list.first;
@@ -12771,6 +13025,7 @@ procedure_clause:
parameters are reduced.
*/
Lex->expr_allows_subselect= false;
+ Select->options|= OPTION_PROCEDURE_CLAUSE;
}
'(' procedure_list ')'
{
@@ -12851,8 +13106,21 @@ select_outvar:
}
;
+opt_into:
+ /* empty */
+ | into
+ ;
into:
INTO into_destination
+ {
+ if (!(Select->options & OPTION_INTO_CLAUSE))
+ Select->options|= OPTION_INTO_CLAUSE;
+ else
+ {
+ my_error(ER_CANT_USE_OPTION_HERE, MYF(0), "INTO");
+ MYSQL_YYABORT;
+ }
+ }
;
into_destination:
@@ -12898,10 +13166,15 @@ do:
LEX *lex=Lex;
lex->sql_command = SQLCOM_DO;
mysql_init_select(lex);
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
expr_list
{
Lex->insert_list= $3;
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
}
;
@@ -13118,16 +13391,23 @@ insert:
LEX *lex= Lex;
lex->sql_command= SQLCOM_INSERT;
lex->duplicates= DUP_ERROR;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
mysql_init_select(lex);
+ lex->current_select->parsing_place= BEFORE_OPT_LIST;
}
insert_lock_option
opt_ignore insert2
{
Select->set_lock_for_tables($3);
- Lex->current_select= &Lex->select_lex;
+ Lex->current_select= Lex->first_select_lex();
}
insert_field_spec opt_insert_update
- {}
+ {
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+ }
;
replace:
@@ -13136,15 +13416,22 @@ replace:
LEX *lex=Lex;
lex->sql_command = SQLCOM_REPLACE;
lex->duplicates= DUP_REPLACE;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
mysql_init_select(lex);
+ lex->current_select->parsing_place= BEFORE_OPT_LIST;
}
replace_lock_option insert2
{
Select->set_lock_for_tables($3);
- Lex->current_select= &Lex->select_lex;
+ Lex->current_select= Lex->first_select_lex();
}
insert_field_spec
- {}
+ {
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+ }
;
insert_lock_option:
@@ -13190,35 +13477,47 @@ insert_table:
table_name_with_opt_use_partition
{
LEX *lex=Lex;
- lex->field_list.empty();
+ //lex->field_list.empty();
lex->many_values.empty();
lex->insert_list=0;
};
insert_field_spec:
insert_values {}
- | '(' ')' insert_values {}
- | '(' fields ')' insert_values {}
+ | insert_field_list insert_values {}
| SET
{
LEX *lex=Lex;
if (!(lex->insert_list= new (thd->mem_root) List_item) ||
lex->many_values.push_back(lex->insert_list, thd->mem_root))
MYSQL_YYABORT;
+ lex->current_select->parsing_place= NO_MATTER;
}
ident_eq_list
;
+insert_field_list:
+ LEFT_PAREN_ALT opt_fields ')'
+ {
+ Lex->current_select->parsing_place= AFTER_LIST;
+ }
+ ;
+
+opt_fields:
+ /* empty */
+ | fields
+ ;
+
fields:
fields ',' insert_ident
{ Lex->field_list.push_back($3, thd->mem_root); }
| insert_ident { Lex->field_list.push_back($1, thd->mem_root); }
;
+
+
insert_values:
- VALUES values_list {}
- | VALUE_SYM values_list {}
- | create_select_query_expression {}
+ create_select_query_expression {}
;
values_list:
@@ -13328,6 +13627,8 @@ update:
UPDATE_SYM
{
LEX *lex= Lex;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
mysql_init_select(lex);
lex->sql_command= SQLCOM_UPDATE;
lex->duplicates= DUP_ERROR;
@@ -13336,13 +13637,14 @@ update:
SET update_list
{
LEX *lex= Lex;
- if (lex->select_lex.table_list.elements > 1)
+ if (lex->builtin_select.table_list.elements > 1)
lex->sql_command= SQLCOM_UPDATE_MULTI;
- else if (lex->select_lex.get_table_list()->derived)
+ else if (lex->builtin_select.get_table_list()->derived)
{
/* it is single table update and it is update of derived table */
my_error(ER_NON_UPDATABLE_TABLE, MYF(0),
- lex->select_lex.get_table_list()->alias.str, "UPDATE");
+ lex->builtin_select.get_table_list()->alias.str,
+ "UPDATE");
MYSQL_YYABORT;
}
/*
@@ -13352,7 +13654,14 @@ update:
*/
Select->set_lock_for_tables($3);
}
- opt_where_clause opt_order_clause delete_limit_clause {}
+ opt_where_clause opt_order_clause delete_limit_clause
+ {
+ if ($10)
+ Select->order_list= *($10);
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+ }
;
update_list:
@@ -13398,9 +13707,11 @@ delete:
mysql_init_select(lex);
YYPS->m_lock_type= TL_WRITE_DEFAULT;
YYPS->m_mdl_type= MDL_SHARED_WRITE;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
lex->ignore= 0;
- lex->select_lex.init_order();
+ lex->builtin_select.init_order();
}
delete_part2
;
@@ -13421,6 +13732,7 @@ delete_part2:
| HISTORY_SYM delete_single_table opt_delete_system_time
{
Lex->last_table()->vers_conditions= Lex->vers_conditions;
+ Lex->pop_select(); //main select
}
;
@@ -13443,9 +13755,18 @@ single_multi:
opt_where_clause
opt_order_clause
delete_limit_clause
- opt_select_expressions {}
+ opt_select_expressions
+ {
+ if ($3)
+ Select->order_list= *($3);
+ Lex->pop_select(); //main select
+ }
| table_wild_list
{
+ /* XXX
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ */
mysql_init_multi_delete(Lex);
YYPS->m_lock_type= TL_READ_DEFAULT;
YYPS->m_mdl_type= MDL_SHARED_READ;
@@ -13454,9 +13775,16 @@ single_multi:
{
if (multi_delete_set_locks_and_link_aux_tables(Lex))
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
}
| FROM table_alias_ref_list
{
+ /* XXX
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ */
mysql_init_multi_delete(Lex);
YYPS->m_lock_type= TL_READ_DEFAULT;
YYPS->m_mdl_type= MDL_SHARED_READ;
@@ -13465,6 +13793,9 @@ single_multi:
{
if (multi_delete_set_locks_and_link_aux_tables(Lex))
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
}
;
@@ -13528,10 +13859,12 @@ truncate:
{
LEX* lex= Lex;
lex->sql_command= SQLCOM_TRUNCATE;
+ if (lex->main_select_push())
+ MYSQL_YYABORT;
lex->alter_info.reset();
- lex->select_lex.options= 0;
- lex->select_lex.sql_cache= SELECT_LEX::SQL_CACHE_UNSPECIFIED;
- lex->select_lex.init_order();
+ lex->builtin_select.options= 0;
+ lex->builtin_select.sql_cache= SELECT_LEX::SQL_CACHE_UNSPECIFIED;
+ lex->builtin_select.init_order();
YYPS->m_lock_type= TL_WRITE;
YYPS->m_mdl_type= MDL_EXCLUSIVE;
}
@@ -13542,6 +13875,7 @@ truncate:
lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_truncate_table();
if (lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
}
;
@@ -13616,6 +13950,8 @@ show:
LEX *lex=Lex;
lex->wild=0;
lex->ident= null_clex_str;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
mysql_init_select(lex);
lex->current_select->parsing_place= SELECT_LIST;
lex->create_info.init();
@@ -13623,6 +13959,7 @@ show:
show_param
{
Select->parsing_place= NO_MATTER;
+ Lex->pop_select(); //main select
}
;
@@ -13638,7 +13975,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_TABLES;
- lex->select_lex.db= $3;
+ lex->first_select_lex()->db= $3;
if (prepare_schema_table(thd, lex, 0, SCH_TABLE_NAMES))
MYSQL_YYABORT;
}
@@ -13646,7 +13983,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_TRIGGERS;
- lex->select_lex.db= $3;
+ lex->first_select_lex()->db= $3;
if (prepare_schema_table(thd, lex, 0, SCH_TRIGGERS))
MYSQL_YYABORT;
}
@@ -13654,7 +13991,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_EVENTS;
- lex->select_lex.db= $2;
+ lex->first_select_lex()->db= $2;
if (prepare_schema_table(thd, lex, 0, SCH_EVENTS))
MYSQL_YYABORT;
}
@@ -13662,7 +13999,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_TABLE_STATUS;
- lex->select_lex.db= $3;
+ lex->first_select_lex()->db= $3;
if (prepare_schema_table(thd, lex, 0, SCH_TABLES))
MYSQL_YYABORT;
}
@@ -13670,7 +14007,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_OPEN_TABLES;
- lex->select_lex.db= $3;
+ lex->first_select_lex()->db= $3;
if (prepare_schema_table(thd, lex, 0, SCH_OPEN_TABLES))
MYSQL_YYABORT;
}
@@ -13720,12 +14057,13 @@ show_param:
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_BINLOG_EVENTS;
}
- opt_limit_clause
+ opt_global_limit_clause
| RELAYLOG_SYM optional_connection_name EVENTS_SYM binlog_in binlog_from
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_RELAYLOG_EVENTS;
- } opt_limit_clause
+ }
+ opt_global_limit_clause
| keys_or_index from_or_in table_ident opt_db opt_where_clause
{
LEX *lex= Lex;
@@ -13767,13 +14105,13 @@ show_param:
LEX_CSTRING var= {STRING_WITH_LEN("error_count")};
(void) create_select_for_variable(thd, &var);
}
- | WARNINGS opt_limit_clause
+ | WARNINGS opt_global_limit_clause
{ Lex->sql_command = SQLCOM_SHOW_WARNS;}
- | ERRORS opt_limit_clause
+ | ERRORS opt_global_limit_clause
{ Lex->sql_command = SQLCOM_SHOW_ERRORS;}
| PROFILES_SYM
{ Lex->sql_command = SQLCOM_SHOW_PROFILES; }
- | PROFILE_SYM opt_profile_defs opt_profile_args opt_limit_clause
+ | PROFILE_SYM opt_profile_defs opt_profile_args opt_global_limit_clause
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_PROFILE;
@@ -13834,7 +14172,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command = SQLCOM_SHOW_CREATE;
- if (!lex->select_lex.add_table_to_list(thd, $3, NULL,0))
+ if (!lex->builtin_select.add_table_to_list(thd, $3, NULL,0))
MYSQL_YYABORT;
lex->create_info.storage_media= HA_SM_DEFAULT;
}
@@ -13842,7 +14180,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command = SQLCOM_SHOW_CREATE;
- if (!lex->select_lex.add_table_to_list(thd, $3, NULL, 0))
+ if (!lex->builtin_select.add_table_to_list(thd, $3, NULL, 0))
MYSQL_YYABORT;
lex->table_type= TABLE_TYPE_VIEW;
}
@@ -13850,7 +14188,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command = SQLCOM_SHOW_CREATE;
- if (!lex->select_lex.add_table_to_list(thd, $3, NULL, 0))
+ if (!lex->builtin_select.add_table_to_list(thd, $3, NULL, 0))
MYSQL_YYABORT;
lex->table_type= TABLE_TYPE_SEQUENCE;
}
@@ -14066,7 +14404,7 @@ describe:
mysql_init_select(lex);
lex->current_select->parsing_place= SELECT_LIST;
lex->sql_command= SQLCOM_SHOW_FIELDS;
- lex->select_lex.db= null_clex_str;
+ lex->builtin_select.db= null_clex_str;
lex->verbose= 0;
if (prepare_schema_table(thd, lex, $2, SCH_COLUMNS))
MYSQL_YYABORT;
@@ -14080,7 +14418,7 @@ describe:
explainable_command
{
LEX *lex=Lex;
- lex->select_lex.options|= SELECT_DESCRIBE;
+ lex->first_select_lex()->options|= SELECT_DESCRIBE;
}
;
@@ -14106,6 +14444,8 @@ analyze_stmt_command:
opt_extended_describe:
EXTENDED_SYM { Lex->describe|= DESCRIBE_EXTENDED; }
+ | EXTENDED_SYM ALL
+ { Lex->describe|= DESCRIBE_EXTENDED | DESCRIBE_EXTENDED2; }
| PARTITIONS_SYM { Lex->describe|= DESCRIBE_PARTITIONS; }
| opt_format_json {}
;
@@ -14148,8 +14488,7 @@ flush:
lex->type= 0;
lex->no_write_to_binlog= $2;
}
- flush_options
- {}
+ flush_options {}
;
flush_options:
@@ -14166,6 +14505,7 @@ flush_options:
opt_table_list opt_flush_lock
{}
| flush_options_list
+ {}
;
opt_flush_lock:
@@ -14339,9 +14679,13 @@ purge:
LEX *lex=Lex;
lex->type=0;
lex->sql_command = SQLCOM_PURGE;
+ if (lex->main_select_push())
+ MYSQL_YYABORT;
}
purge_options
- {}
+ {
+ Lex->pop_select(); //main select
+ }
;
purge_options:
@@ -14359,6 +14703,8 @@ purge_option:
lex->value_list.empty();
lex->value_list.push_front($2, thd->mem_root);
lex->sql_command= SQLCOM_PURGE_BEFORE;
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
}
;
@@ -14368,6 +14714,8 @@ kill:
KILL_SYM
{
LEX *lex=Lex;
+ if (lex->main_select_push())
+ YYABORT;
lex->value_list.empty();
lex->users_list.empty();
lex->sql_command= SQLCOM_KILL;
@@ -14376,6 +14724,7 @@ kill:
kill_type kill_option kill_expr
{
Lex->kill_signal= (killed_state) ($3 | $4);
+ Lex->pop_select(); //main select
}
;
@@ -14419,7 +14768,7 @@ use:
{
LEX *lex=Lex;
lex->sql_command=SQLCOM_CHANGE_DB;
- lex->select_lex.db= $2;
+ lex->builtin_select.db= $2;
}
;
@@ -14436,6 +14785,9 @@ load:
$2 == FILETYPE_CSV ? "LOAD DATA" : "LOAD XML");
MYSQL_YYABORT;
}
+ if (lex->main_select_push())
+ MYSQL_YYABORT;
+ mysql_init_select(lex);
}
load_data_lock opt_local INFILE TEXT_STRING_filesystem
{
@@ -14462,7 +14814,11 @@ load:
opt_xml_rows_identified_by
opt_field_term opt_line_term opt_ignore_lines opt_field_or_var_spec
opt_load_data_set_spec
- {}
+ {
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+ }
;
data_or_xml:
@@ -14854,17 +15210,21 @@ opt_with_clause:
with_clause:
- WITH opt_recursive
+ WITH opt_recursive
{
+ LEX *lex= Lex;
With_clause *with_clause=
new With_clause($2, Lex->curr_with_clause);
if (with_clause == NULL)
MYSQL_YYABORT;
- Lex->derived_tables|= DERIVED_WITH;
- Lex->curr_with_clause= with_clause;
+ lex->derived_tables|= DERIVED_WITH;
+ lex->curr_with_clause= with_clause;
with_clause->add_to_list(Lex->with_clauses_list_last_next);
+ if (lex->current_select &&
+ lex->current_select->parsing_place == BEFORE_OPT_LIST)
+ lex->current_select->parsing_place= NO_MATTER;
}
- with_list
+ with_list
{
$$= Lex->curr_with_clause;
Lex->curr_with_clause= Lex->curr_with_clause->pop();
@@ -14893,9 +15253,9 @@ with_list_element:
MYSQL_YYABORT;
Lex->with_column_list.empty();
}
- AS '(' remember_name subselect remember_end ')'
+ AS '(' remember_name query_expression remember_end ')'
{
- With_element *elem= new With_element($1, *$2, $7->master_unit());
+ With_element *elem= new With_element($1, *$2, $7);
if (elem == NULL || Lex->curr_with_clause->add_with_element(elem))
MYSQL_YYABORT;
if (elem->set_unparsed_spec(thd, $6+1, $8))
@@ -15775,14 +16135,22 @@ set:
SET
{
LEX *lex=Lex;
+ if (lex->main_select_push())
+ MYSQL_YYABORT;
lex->set_stmt_init();
lex->var_list.empty();
sp_create_assignment_lex(thd, yychar == YYEMPTY);
}
start_option_value_list
- {}
+ {
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+ }
| SET STATEMENT_SYM
{
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
Lex->set_stmt_init();
}
set_stmt_option_value_following_option_type_list
@@ -15792,6 +16160,9 @@ set:
my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0), "SET STATEMENT"));
lex->stmt_var_list= lex->var_list;
lex->var_list.empty();
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
}
FOR_SYM verb_clause
{}
@@ -16173,9 +16544,13 @@ lock:
if (lex->sphead)
my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "LOCK"));
lex->sql_command= SQLCOM_LOCK_TABLES;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
table_lock_list opt_lock_wait_timeout
- {}
+ {
+ Lex->pop_select(); //main select
+ }
;
opt_lock_wait_timeout:
@@ -16206,7 +16581,7 @@ table_lock_list:
;
table_lock:
- table_ident opt_table_alias lock_option
+ table_ident opt_table_alias_clause lock_option
{
thr_lock_type lock_type= (thr_lock_type) $3;
bool lock_for_write= (lock_type >= TL_WRITE_ALLOW_WRITE);
@@ -16240,9 +16615,13 @@ unlock:
if (lex->sphead)
my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "UNLOCK"));
lex->sql_command= SQLCOM_UNLOCK_TABLES;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
table_or_tables
- {}
+ {
+ Lex->pop_select(); //main select
+ }
;
/*
@@ -16250,25 +16629,36 @@ unlock:
*/
handler:
- HANDLER_SYM table_ident OPEN_SYM opt_table_alias
+ HANDLER_SYM
+ {
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
+ handler_tail
+ {
+ Lex->pop_select(); //main select
+ }
+
+handler_tail:
+ table_ident OPEN_SYM opt_table_alias_clause
{
LEX *lex= Lex;
if (lex->sphead)
my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "HANDLER"));
lex->sql_command = SQLCOM_HA_OPEN;
- if (!lex->current_select->add_table_to_list(thd, $2, $4, 0))
+ if (!lex->current_select->add_table_to_list(thd, $1, $3, 0))
MYSQL_YYABORT;
}
- | HANDLER_SYM table_ident_nodb CLOSE_SYM
+ | table_ident_nodb CLOSE_SYM
{
LEX *lex= Lex;
if (lex->sphead)
my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "HANDLER"));
lex->sql_command = SQLCOM_HA_CLOSE;
- if (!lex->current_select->add_table_to_list(thd, $2, 0, 0))
+ if (!lex->current_select->add_table_to_list(thd, $1, 0, 0))
MYSQL_YYABORT;
}
- | HANDLER_SYM table_ident_nodb READ_SYM
+ | table_ident_nodb READ_SYM
{
LEX *lex=Lex;
if (lex->sphead)
@@ -16276,20 +16666,24 @@ handler:
lex->expr_allows_subselect= FALSE;
lex->sql_command = SQLCOM_HA_READ;
lex->ha_rkey_mode= HA_READ_KEY_EXACT; /* Avoid purify warnings */
- Item *one= new (thd->mem_root) Item_int(thd, (int32) 1);
- if (one == NULL)
- MYSQL_YYABORT;
- lex->current_select->select_limit= one;
- lex->current_select->offset_limit= 0;
- lex->limit_rows_examined= 0;
- if (!lex->current_select->add_table_to_list(thd, $2, 0, 0))
+ if (!lex->current_select->add_table_to_list(thd, $1, 0, 0))
MYSQL_YYABORT;
}
- handler_read_or_scan opt_where_clause opt_limit_clause
+ handler_read_or_scan opt_where_clause opt_global_limit_clause
{
- Lex->expr_allows_subselect= TRUE;
+ LEX *lex=Lex;
+ lex->expr_allows_subselect= TRUE;
+ if (!lex->current_select->explicit_limit)
+ {
+ Item *one= new (thd->mem_root) Item_int(thd, (int32) 1);
+ if (one == NULL)
+ MYSQL_YYABORT;
+ lex->current_select->select_limit= one;
+ lex->current_select->offset_limit= 0;
+ lex->limit_rows_examined= 0;
+ }
/* Stored functions are not supported for HANDLER READ. */
- if (Lex->uses_stored_routines())
+ if (lex->uses_stored_routines())
{
my_error(ER_NOT_SUPPORTED_YET, MYF(0),
"stored functions in HANDLER ... READ");
@@ -16920,219 +17314,27 @@ release:
*/
unit_type_decl:
- UNION_SYM
- { $$= UNION_TYPE; }
+ UNION_SYM union_option
+ { $$.unit_type= UNION_TYPE; $$.distinct= $2; }
| INTERSECT_SYM
- { $$= INTERSECT_TYPE; }
+ { $$.unit_type= INTERSECT_TYPE; $$.distinct= 1; }
| EXCEPT_SYM
- { $$= EXCEPT_TYPE; }
-
-
-union_clause:
- /* empty */ {}
- | union_list
- ;
-
-union_list:
- unit_type_decl union_option
- {
- if (Lex->add_select_to_union_list((bool)$2, $1, TRUE))
- MYSQL_YYABORT;
- }
- union_list_part2
- {
- /*
- Remove from the name resolution context stack the context of the
- last select in the union.
- */
- Lex->pop_context();
- }
- ;
-
-union_list_view:
- unit_type_decl union_option
- {
- if (Lex->add_select_to_union_list((bool)$2, $1, TRUE))
- MYSQL_YYABORT;
- }
- query_expression_body_view
- {
- Lex->pop_context();
- }
- ;
-
-union_order_or_limit:
- {
- LEX *lex= thd->lex;
- DBUG_ASSERT(lex->current_select->linkage != GLOBAL_OPTIONS_TYPE);
- SELECT_LEX *sel= lex->current_select;
- SELECT_LEX_UNIT *unit= sel->master_unit();
- SELECT_LEX *fake= unit->fake_select_lex;
- if (fake)
- {
- fake->no_table_names_allowed= 1;
- lex->current_select= fake;
- }
- thd->where= "global ORDER clause";
- }
- order_or_limit
- {
- thd->lex->current_select->no_table_names_allowed= 0;
- thd->where= "";
- }
- ;
+ { $$.unit_type= EXCEPT_TYPE; $$.distinct= 1; }
-order_or_limit:
- order_clause opt_limit_clause
- | limit_clause
- ;
/*
Start a UNION, for non-top level query expressions.
*/
-union_head_non_top:
- unit_type_decl union_option
- {
- if (Lex->add_select_to_union_list((bool)$2, $1, FALSE))
- MYSQL_YYABORT;
- }
- ;
-
union_option:
/* empty */ { $$=1; }
| DISTINCT { $$=1; }
| ALL { $$=0; }
;
-simple_table:
- query_specification { $$= $1; }
- | table_value_constructor { $$= $1; }
- ;
-
-table_value_constructor:
- VALUES
- {
- LEX *lex=Lex;
- lex->field_list.empty();
- lex->many_values.empty();
- lex->insert_list=0;
- }
- values_list
- {
- LEX *lex=Lex;
- $$= lex->current_select;
- mysql_init_select(Lex);
- if (!($$->tvc=
- new (lex->thd->mem_root) table_value_constr(lex->many_values, $$, $$->options)))
- MYSQL_YYABORT;
- lex->many_values.empty();
- }
- ;
-
-/*
- Corresponds to the SQL Standard
- <query specification> ::=
- SELECT [ <set quantifier> ] <select list> <table expression>
-
- Notes:
- - We allow more options in addition to <set quantifier>
- - <table expression> is optional in MariaDB
-*/
-query_specification:
- SELECT_SYM select_init2_derived opt_table_expression
- {
- $$= Lex->current_select->master_unit()->first_select();
- }
- ;
-
-query_term_union_not_ready:
- simple_table order_or_limit opt_select_lock_type { $$= $1; }
- | '(' select_paren_derived ')' union_order_or_limit { $$= $2; }
- ;
-
-query_term_union_ready:
- simple_table opt_select_lock_type { $$= $1; }
- | '(' select_paren_derived ')' { $$= $2; }
- ;
-
-query_expression_body:
- query_term_union_not_ready { $$= $1; }
- | query_term_union_ready { $$= $1; }
- | query_term_union_ready union_list_derived { $$= $1; }
- ;
-
-/* Corresponds to <query expression> in the SQL:2003 standard. */
-subselect:
- subselect_start opt_with_clause query_expression_body subselect_end
- {
- $3->set_with_clause($2);
- $$= $3;
- }
- ;
-
-subselect_start:
- {
- LEX *lex=Lex;
- if (!lex->expr_allows_subselect ||
- lex->sql_command == (int)SQLCOM_PURGE)
- {
- thd->parse_error();
- MYSQL_YYABORT;
- }
- /*
- we are making a "derived table" for the parenthesis
- as we need to have a lex level to fit the union
- after the parenthesis, e.g.
- (SELECT .. ) UNION ... becomes
- SELECT * FROM ((SELECT ...) UNION ...)
- */
- if (mysql_new_select(Lex, 1, NULL))
- MYSQL_YYABORT;
- }
- ;
-
-subselect_end:
- {
- LEX *lex=Lex;
-
- lex->check_automatic_up(UNSPECIFIED_TYPE);
- lex->pop_context();
- SELECT_LEX *child= lex->current_select;
- lex->current_select = lex->current_select->return_after_parsing();
- lex->nest_level--;
- lex->current_select->n_child_sum_items += child->n_sum_items;
- /*
- A subselect can add fields to an outer select. Reserve space for
- them.
- */
- lex->current_select->select_n_where_fields+=
- child->select_n_where_fields;
-
- /*
- Aggregate functions in having clause may add fields to an outer
- select. Count them also.
- */
- lex->current_select->select_n_having_items+=
- child->select_n_having_items;
- }
- ;
-
-opt_query_expression_options:
- /* empty */
- | query_expression_option_list
- ;
-
-query_expression_option_list:
- query_expression_option_list query_expression_option
- | query_expression_option
- ;
-
query_expression_option:
STRAIGHT_JOIN { Select->options|= SELECT_STRAIGHT_JOIN; }
| HIGH_PRIORITY
{
- if (check_simple_select())
- MYSQL_YYABORT;
YYPS->m_lock_type= TL_READ_HIGH_PRIORITY;
YYPS->m_mdl_type= MDL_SHARED_READ;
Select->options|= SELECT_HIGH_PRIORITY;
@@ -17140,18 +17342,8 @@ query_expression_option:
| DISTINCT { Select->options|= SELECT_DISTINCT; }
| SQL_SMALL_RESULT { Select->options|= SELECT_SMALL_RESULT; }
| SQL_BIG_RESULT { Select->options|= SELECT_BIG_RESULT; }
- | SQL_BUFFER_RESULT
- {
- if (check_simple_select())
- MYSQL_YYABORT;
- Select->options|= OPTION_BUFFER_RESULT;
- }
- | SQL_CALC_FOUND_ROWS
- {
- if (check_simple_select())
- MYSQL_YYABORT;
- Select->options|= OPTION_FOUND_ROWS;
- }
+ | SQL_BUFFER_RESULT { Select->options|= OPTION_BUFFER_RESULT; }
+ | SQL_CALC_FOUND_ROWS { Select->options|= OPTION_FOUND_ROWS; }
| ALL { Select->options|= SELECT_ALL; }
;
@@ -17239,35 +17431,28 @@ view_select:
lex->parsing_options.allows_variable= FALSE;
lex->create_view->select.str= (char *) YYLIP->get_cpp_ptr();
}
- opt_with_clause query_expression_body_view view_check_option
+ query_expression
+ view_check_option
{
LEX *lex= Lex;
+ SQL_I_List<TABLE_LIST> *save= &lex->first_select_lex()->table_list;
+ lex->set_main_unit($2);
+ if (lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+ lex->first_select_lex()->table_list.push_front(save);
+ lex->current_select= Lex->first_select_lex();
size_t len= YYLIP->get_cpp_ptr() - lex->create_view->select.str;
void *create_view_select= thd->memdup(lex->create_view->select.str, len);
lex->create_view->select.length= len;
lex->create_view->select.str= (char *) create_view_select;
+ size_t not_used;
trim_whitespace(thd->charset(),
- &lex->create_view->select);
- lex->create_view->check= $4;
+ &lex->create_view->select, ¬_used);
+ lex->create_view->check= $3;
lex->parsing_options.allows_variable= TRUE;
- lex->current_select->set_with_clause($2);
}
;
-/*
- SQL Standard <query expression body> for VIEWs.
- Does not include INTO and PROCEDURE clauses.
-*/
-query_expression_body_view:
- SELECT_SYM select_options_and_item_list select_init3_view
- | table_value_constructor
- | table_value_constructor union_order_or_limit
- | table_value_constructor union_list_view
- | '(' select_paren_view ')'
- | '(' select_paren_view ')' union_order_or_limit
- | '(' select_paren_view ')' union_list_view
- ;
-
view_check_option:
/* empty */ { $$= VIEW_CHECK_NONE; }
| WITH CHECK_SYM OPTION { $$= VIEW_CHECK_CASCADED; }
@@ -17371,11 +17556,11 @@ trigger_tail:
sp_proc_stmt alternatives are not saving/restoring LEX, so
lex->query_tables can be wiped out.
*/
- if (!lex->select_lex.add_table_to_list(thd, $10,
- (LEX_CSTRING*) 0,
- TL_OPTION_UPDATING,
- TL_READ_NO_INSERT,
- MDL_SHARED_NO_WRITE))
+ if (!lex->builtin_select.add_table_to_list(thd, $10,
+ (LEX_CSTRING*) 0,
+ TL_OPTION_UPDATING,
+ TL_READ_NO_INSERT,
+ MDL_SHARED_NO_WRITE))
MYSQL_YYABORT;
}
;
diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy
index ec2aeeaefba..7dd065d59ab 100644
--- a/sql/sql_yacc_ora.yy
+++ b/sql/sql_yacc_ora.yy
@@ -186,6 +186,20 @@ void ORAerror(THD *thd, const char *s)
LEX_CSTRING name;
uint offset;
} sp_cursor_name_and_offset;
+ struct
+ {
+ enum sub_select_type unit_type;
+ bool distinct;
+ } unit_operation;
+ struct
+ {
+ SELECT_LEX *first;
+ SELECT_LEX *prev_last;
+ } select_list;
+ SQL_I_List<ORDER> *select_order;
+ Lex_select_lock select_lock;
+ Lex_select_limit select_limit;
+ Lex_order_limit_lock *order_limit_lock;
/* pointers */
Create_field *create_field;
@@ -231,6 +245,7 @@ void ORAerror(THD *thd, const char *s)
handlerton *db_type;
st_select_lex *select_lex;
+ st_select_lex_unit *select_lex_unit;
struct p_elem_val *p_elem_value;
class Window_frame *window_frame;
class Window_frame_bound *window_frame_bound;
@@ -240,7 +255,6 @@ void ORAerror(THD *thd, const char *s)
/* enums */
enum enum_sp_suid_behaviour sp_suid;
enum enum_view_suid view_suid;
- enum sub_select_type unit_type;
enum Condition_information_item::Name cond_info_item_name;
enum enum_diag_condition_item_name diag_condition_item_name;
enum Diagnostics_information::Which_area diag_area;
@@ -277,10 +291,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%parse-param { THD *thd }
%lex-param { THD *thd }
/*
- Currently there are 104 shift/reduce conflicts.
+ Currently there are 99 shift/reduce conflicts.
We should not introduce new conflicts any more.
*/
-%expect 104
+%expect 99
/*
Comments for TOKENS.
@@ -599,6 +613,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%token LEAVES
%token LEAVE_SYM
%token LEFT /* SQL-2003-R */
+%token LEFT_PAREN_ALT /* INTERNAL */
+%token LEFT_PAREN_WITH /* INTERNAL */
+%token LEFT_PAREN_LIKE /* INTERNAL */
%token LESS_SYM
%token LEVEL_SYM
%token LEX_HOSTNAME
@@ -1063,7 +1080,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
NCHAR_STRING
%type <lex_str_ptr>
- opt_table_alias
+ opt_table_alias_clause
+ table_alias_clause
%type <lex_string_with_pos>
ident ident_with_tok_start
@@ -1111,7 +1129,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
opt_temporary all_or_any opt_distinct opt_glimit_clause
opt_ignore_leaves fulltext_options union_option
opt_not
- select_derived_init transaction_access_mode_types
+ transaction_access_mode_types
opt_natural_language_mode opt_query_expansion
opt_ev_status opt_ev_on_completion ev_on_completion opt_ev_comment
ev_alter_on_schedule_completion opt_ev_rename_to opt_ev_sql_stmt
@@ -1231,9 +1249,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
join_table_list join_table
table_factor table_ref esc_table_ref
table_primary_ident table_primary_derived
- select_derived derived_table_list
- select_derived_union
- derived_query_specification
+ derived_table_list table_reference_list_parens
+ nested_table_reference_list join_table_parens
%type <date_time_type> date_time_type;
%type <interval> interval
@@ -1276,12 +1293,16 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
UNDERSCORE_CHARSET
%type <select_lex> subselect
- get_select_lex get_select_lex_derived
query_specification
- query_term_union_not_ready
- query_term_union_ready
+ table_value_constructor
+ simple_table
+ query_primary
+ query_primary_parens
+
+%type <select_lex_unit>
query_expression_body
- select_paren_derived
+ query_expression
+ query_expression_unit
%type <boolfunc2creator> comp_op
@@ -1293,7 +1314,21 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%type <virtual_column> opt_check_constraint check_constraint virtual_column_func
column_default_expr
-%type <unit_type> unit_type_decl
+
+%type <unit_operation> unit_type_decl
+
+%type <select_lock>
+ opt_select_lock_type
+ select_lock_type
+ opt_lock_wait_timeout_new
+
+%type <select_limit> opt_limit_clause limit_clause limit_options
+
+%type <order_limit_lock>
+ query_expression_tail
+ order_or_limit
+
+%type <select_order> opt_order_clause order_clause order_list
%type <NONE>
analyze_stmt_command
@@ -1313,7 +1348,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
assign_to_keycache_parts
preload_list preload_list_or_parts preload_keys preload_keys_parts
select_item_list select_item values_list no_braces
- opt_limit_clause delete_limit_clause fields opt_values values
+ delete_limit_clause fields opt_values values
procedure_list procedure_list2 procedure_item
field_def handler opt_generated_always
opt_ignore opt_column opt_restrict
@@ -1333,9 +1368,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
table_to_table_list table_to_table opt_table_list opt_as
handler_rkey_function handler_read_or_scan
single_multi table_wild_list table_wild_one opt_wild
- union_clause union_list
- subselect_start opt_and charset
- subselect_end select_var_list select_var_list_init help
+ opt_and charset
+ select_var_list select_var_list_init help
opt_extended_describe shutdown
opt_format_json
prepare prepare_src execute deallocate
@@ -1481,7 +1515,7 @@ query:
END_OF_INPUT
{
if (!thd->bootstrap &&
- (!(thd->lex->select_lex.options & OPTION_FOUND_COMMENT)))
+ (!(thd->lex->builtin_select.options & OPTION_FOUND_COMMENT)))
my_yyabort_error((ER_EMPTY_QUERY, MYF(0)));
thd->lex->sql_command= SQLCOM_EMPTY_QUERY;
@@ -1606,14 +1640,22 @@ deallocate_or_drop:
;
prepare:
- PREPARE_SYM ident FROM prepare_src
+ PREPARE_SYM
+ {
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
+ ident FROM prepare_src
{
LEX *lex= thd->lex;
if (lex->table_or_sp_used())
my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0),
"PREPARE..FROM"));
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
lex->sql_command= SQLCOM_PREPARE;
- lex->prepared_stmt_name= $2;
+ lex->prepared_stmt_name= $3;
+ Lex->pop_select(); //main select
}
;
@@ -1632,10 +1674,21 @@ execute:
LEX *lex= thd->lex;
lex->sql_command= SQLCOM_EXECUTE;
lex->prepared_stmt_name= $2;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
execute_using
- {}
- | EXECUTE_SYM IMMEDIATE_SYM prepare_src
+ {
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+ }
+ | EXECUTE_SYM IMMEDIATE_SYM
+ {
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
+ prepare_src
{
if (Lex->table_or_sp_used())
my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0),
@@ -1643,7 +1696,11 @@ execute:
Lex->sql_command= SQLCOM_EXECUTE_IMMEDIATE;
}
execute_using
- {}
+ {
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+ }
;
execute_using:
@@ -1928,15 +1985,22 @@ connection_name:
/* create a table */
create:
- create_or_replace opt_temporary TABLE_SYM opt_if_not_exists table_ident
+ create_or_replace opt_temporary TABLE_SYM opt_if_not_exists
{
LEX *lex= thd->lex;
lex->create_info.init();
+ if (lex->main_select_push())
+ MYSQL_YYABORT;
+ lex->current_select->parsing_place= BEFORE_OPT_LIST;
if (lex->set_command_with_check(SQLCOM_CREATE_TABLE, $2, $1 | $4))
MYSQL_YYABORT;
- if (!lex->select_lex.add_table_to_list(thd, $5, NULL,
- TL_OPTION_UPDATING,
- TL_WRITE, MDL_EXCLUSIVE))
+ }
+ table_ident
+ {
+ LEX *lex= thd->lex;
+ if (!lex->builtin_select.add_table_to_list(thd, $6, NULL,
+ TL_OPTION_UPDATING,
+ TL_WRITE, MDL_EXCLUSIVE))
MYSQL_YYABORT;
lex->alter_info.reset();
/*
@@ -1951,7 +2015,7 @@ create:
create_body
{
LEX *lex= thd->lex;
- lex->current_select= &lex->select_lex;
+ lex->current_select= &lex->builtin_select;
if ((lex->create_info.used_fields & HA_CREATE_USED_ENGINE) &&
!lex->create_info.db_type)
{
@@ -1960,20 +2024,23 @@ create:
ER_WARN_USING_OTHER_HANDLER,
ER_THD(thd, ER_WARN_USING_OTHER_HANDLER),
hton_name(lex->create_info.db_type)->str,
- $5->table.str);
+ $6->table.str);
}
create_table_set_open_action_and_adjust_tables(lex);
+ Lex->pop_select(); //main select
}
| create_or_replace opt_temporary SEQUENCE_SYM opt_if_not_exists table_ident
{
LEX *lex= thd->lex;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
lex->create_info.init();
if (lex->set_command_with_check(SQLCOM_CREATE_SEQUENCE, $2, $1 | $4))
MYSQL_YYABORT;
- if (!lex->select_lex.add_table_to_list(thd, $5, NULL,
- TL_OPTION_UPDATING,
- TL_WRITE, MDL_EXCLUSIVE))
+ if (!lex->builtin_select.add_table_to_list(thd, $5, NULL,
+ TL_OPTION_UPDATING,
+ TL_WRITE, MDL_EXCLUSIVE))
MYSQL_YYABORT;
/*
@@ -1996,8 +2063,8 @@ create:
if (lex->create_info.seq_create_info->check_and_adjust(1))
{
my_error(ER_SEQUENCE_INVALID_DATA, MYF(0),
- lex->select_lex.table_list.first->db.str,
- lex->select_lex.table_list.first->table_name.str);
+ lex->builtin_select.table_list.first->db.str,
+ lex->builtin_select.table_list.first->table_name.str);
MYSQL_YYABORT;
}
@@ -2009,7 +2076,7 @@ create:
Lex->create_info.used_fields|= HA_CREATE_USED_SEQUENCE;
Lex->create_info.sequence= 1;
- lex->current_select= &lex->select_lex;
+ lex->current_select= &lex->builtin_select;
if ((lex->create_info.used_fields & HA_CREATE_USED_ENGINE) &&
!lex->create_info.db_type)
{
@@ -2021,42 +2088,69 @@ create:
$5->table.str);
}
create_table_set_open_action_and_adjust_tables(lex);
+ Lex->pop_select(); //main select
+ }
+ | create_or_replace opt_unique INDEX_SYM opt_if_not_exists
+ {
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
- | create_or_replace opt_unique INDEX_SYM opt_if_not_exists ident
+ ident
opt_key_algorithm_clause
ON table_ident
{
- if (Lex->add_create_index_prepare($8))
+ if (Lex->add_create_index_prepare($9))
MYSQL_YYABORT;
- if (Lex->add_create_index($2, &$5, $6, $1 | $4))
+ if (Lex->add_create_index($2, &$6, $7, $1 | $4))
MYSQL_YYABORT;
}
'(' key_list ')' opt_lock_wait_timeout normal_key_options
- opt_index_lock_algorithm { }
- | create_or_replace fulltext INDEX_SYM opt_if_not_exists ident
+ opt_index_lock_algorithm
+ {
+ Lex->pop_select(); //main select
+ }
+ | create_or_replace fulltext INDEX_SYM
+ {
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
+ opt_if_not_exists ident
ON table_ident
{
- if (Lex->add_create_index_prepare($7))
+ if (Lex->add_create_index_prepare($8))
MYSQL_YYABORT;
- if (Lex->add_create_index($2, &$5, HA_KEY_ALG_UNDEF, $1 | $4))
+ if (Lex->add_create_index($2, &$6, HA_KEY_ALG_UNDEF, $1 | $5))
MYSQL_YYABORT;
}
'(' key_list ')' opt_lock_wait_timeout fulltext_key_options
- opt_index_lock_algorithm { }
- | create_or_replace spatial INDEX_SYM opt_if_not_exists ident
+ opt_index_lock_algorithm
+ {
+ Lex->pop_select(); //main select
+ }
+ | create_or_replace spatial INDEX_SYM
+ {
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
+ opt_if_not_exists ident
ON table_ident
{
- if (Lex->add_create_index_prepare($7))
+ if (Lex->add_create_index_prepare($8))
MYSQL_YYABORT;
- if (Lex->add_create_index($2, &$5, HA_KEY_ALG_UNDEF, $1 | $4))
+ if (Lex->add_create_index($2, &$6, HA_KEY_ALG_UNDEF, $1 | $5))
MYSQL_YYABORT;
}
'(' key_list ')' opt_lock_wait_timeout spatial_key_options
- opt_index_lock_algorithm { }
+ opt_index_lock_algorithm
+ {
+ Lex->pop_select(); //main select
+ }
| create_or_replace DATABASE opt_if_not_exists ident
{
Lex->create_info.default_table_charset= NULL;
Lex->create_info.used_fields= 0;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
opt_create_database_options
{
@@ -2064,51 +2158,94 @@ create:
if (lex->set_command_with_check(SQLCOM_CREATE_DB, 0, $1 | $3))
MYSQL_YYABORT;
lex->name= $4;
+ Lex->pop_select(); //main select
}
| create_or_replace definer_opt opt_view_suid VIEW_SYM
opt_if_not_exists table_ident
{
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
if (Lex->add_create_view(thd, $1 | $5,
DTYPE_ALGORITHM_UNDEFINED, $3, $6))
MYSQL_YYABORT;
}
view_list_opt AS view_select
- { }
+ {
+ Lex->pop_select(); //main select
+ }
| create_or_replace view_algorithm definer_opt opt_view_suid VIEW_SYM
opt_if_not_exists table_ident
{
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
if (Lex->add_create_view(thd, $1 | $6, $2, $4, $7))
MYSQL_YYABORT;
}
view_list_opt AS view_select
- { }
+ {
+ Lex->pop_select(); //main select
+ }
| create_or_replace definer_opt TRIGGER_SYM
- { Lex->create_info.set($1); }
+ {
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ Lex->create_info.set($1);
+ }
trigger_tail
- { }
+ {
+ Lex->pop_select(); //main select
+ }
| create_or_replace definer_opt PROCEDURE_SYM
- { Lex->create_info.set($1); }
+ {
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ Lex->create_info.set($1);
+ }
sp_tail_standalone
- { }
+ {
+ Lex->pop_select(); //main select
+ }
| create_or_replace definer_opt EVENT_SYM
- { Lex->create_info.set($1); }
+ {
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ Lex->create_info.set($1);
+ }
event_tail
- { }
+ {
+ Lex->pop_select(); //main select
+ }
| create_or_replace definer FUNCTION_SYM
- { Lex->create_info.set($1); }
+ {
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ Lex->create_info.set($1);
+ }
sf_tail_standalone
- { }
+ {
+ Lex->pop_select(); //main select
+ }
| create_or_replace no_definer FUNCTION_SYM
- { Lex->create_info.set($1); }
+ {
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ Lex->create_info.set($1);
+ }
create_function_tail
- { }
+ {
+ Lex->pop_select(); //main select
+ }
| create_or_replace no_definer AGGREGATE_SYM FUNCTION_SYM
{
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
Lex->create_info.set($1);
Lex->udf.type= UDFTYPE_AGGREGATE;
}
udf_tail
- { }
+ {
+ Lex->pop_select(); //main select
+ }
| create_or_replace USER_SYM opt_if_not_exists clear_privileges grant_list
opt_require_clause opt_resource_options
{
@@ -2724,7 +2861,7 @@ clear_privileges:
lex->columns.empty();
lex->grant= lex->grant_tot_col= 0;
lex->all_privileges= 0;
- lex->select_lex.db= null_clex_str;
+ lex->builtin_select.db= null_clex_str;
lex->ssl_type= SSL_TYPE_NOT_SPECIFIED;
lex->ssl_cipher= lex->x509_subject= lex->x509_issuer= 0;
bzero((char *)&(lex->mqh),sizeof(lex->mqh));
@@ -2815,8 +2952,13 @@ call:
{
if (Lex->call_statement_start(thd, $2))
MYSQL_YYABORT;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
+ opt_sp_cparam_list
+ {
+ Lex->pop_select(); //main select
}
- opt_sp_cparam_list {}
;
/* CALL parameters */
@@ -3346,10 +3488,16 @@ raise_stmt:
;
signal_stmt:
- SIGNAL_SYM signal_value opt_set_signal_information
+ SIGNAL_SYM
{
- if (Lex->add_signal_statement(thd, $2))
+ if (Lex->main_select_push())
+ YYABORT;
+ }
+ signal_value opt_set_signal_information
+ {
+ if (Lex->add_signal_statement(thd, $3))
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
}
;
@@ -3475,9 +3623,14 @@ resignal_stmt:
;
get_diagnostics:
- GET_SYM which_area DIAGNOSTICS_SYM diagnostics_information
+ GET_SYM which_area DIAGNOSTICS_SYM
{
- Diagnostics_information *info= $4;
+ if (Lex->main_select_push())
+ YYABORT;
+ }
+ diagnostics_information
+ {
+ Diagnostics_information *info= $5;
info->set_which_da($2);
@@ -3486,6 +3639,7 @@ get_diagnostics:
if (Lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
}
;
@@ -3666,8 +3820,26 @@ sp_decl_idents:
sp_opt_default:
/* Empty */ { $$ = NULL; }
- | DEFAULT expr { $$ = $2; }
- | SET_VAR expr { $$ = $2; }
+ | DEFAULT
+ {
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
+ expr
+ {
+ Lex->pop_select(); //main select
+ $$ = $3;
+ }
+ | SET_VAR
+ {
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
+ expr
+ {
+ Lex->pop_select(); //main select
+ $$ = $3;
+ }
;
sp_proc_stmt:
@@ -3784,10 +3956,15 @@ sp_proc_stmt_statement:
sp_proc_stmt_return:
RETURN_SYM
- { Lex->sphead->reset_lex(thd); }
+ {
+ Lex->sphead->reset_lex(thd);
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
expr
{
LEX *lex= Lex;
+ lex->pop_select(); //main select
sp_head *sp= lex->sphead;
if (sp->m_handler->add_instr_freturn(thd, sp, lex->spcont,
$3, lex) ||
@@ -3804,7 +3981,14 @@ sp_proc_stmt_return:
;
reset_lex_expr:
- { Lex->sphead->reset_lex(thd); } expr { $$= $2; }
+ {
+ Lex->sphead->reset_lex(thd);
+ // will be poped in sp_proc_stmt_exit or sp_proc_stmt_continue
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
+ expr
+ { $$= $2; }
;
sp_proc_stmt_exit:
@@ -3820,12 +4004,14 @@ sp_proc_stmt_exit:
}
| EXIT_SYM WHEN_SYM reset_lex_expr
{
+ Lex->pop_select(); //main select pushed in reset_lex_expr
if (Lex->sp_exit_statement(thd, $3) ||
Lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
}
| EXIT_SYM label_ident WHEN_SYM reset_lex_expr
{
+ Lex->pop_select(); //main select pushed in reset_lex_expr
if (Lex->sp_exit_statement(thd, &$2, $4) ||
Lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
@@ -3845,12 +4031,14 @@ sp_proc_stmt_continue:
}
| CONTINUE_SYM WHEN_SYM reset_lex_expr
{
+ Lex->pop_select(); //main select pushed in reset_lex_expr
if (Lex->sp_continue_statement(thd, $3) ||
Lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
}
| CONTINUE_SYM label_ident WHEN_SYM reset_lex_expr
{
+ Lex->pop_select(); //main select pushed in reset_lex_expr
if (Lex->sp_continue_statement(thd, &$2, $4) ||
Lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
@@ -3902,6 +4090,8 @@ assignment_source_expr:
{
DBUG_ASSERT(thd->free_list == NULL);
Lex->sphead->reset_lex(thd, $1);
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
expr
{
@@ -3910,6 +4100,7 @@ assignment_source_expr:
$$->sp_lex_in_use= true;
$$->set_item_and_free_list($3, thd->free_list);
thd->free_list= NULL;
+ Lex->pop_select(); //main select
if ($$->sphead->restore_lex(thd))
MYSQL_YYABORT;
}
@@ -4030,9 +4221,14 @@ sp_fetch_list:
;
sp_if:
- { Lex->sphead->reset_lex(thd); }
+ {
+ Lex->sphead->reset_lex(thd);
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
expr THEN_SYM
{
+ Lex->pop_select(); //main select
LEX *lex= Lex;
sp_head *sp= lex->sphead;
sp_pcontext *ctx= lex->spcont;
@@ -4144,12 +4340,18 @@ case_stmt_specification:
;
case_stmt_body:
- { Lex->sphead->reset_lex(thd); /* For expr $2 */ }
+ {
+ Lex->sphead->reset_lex(thd); /* For expr $2 */
+
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
expr
{
if (Lex->case_stmt_action_expr($2))
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
if (Lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
}
@@ -4173,6 +4375,9 @@ simple_when_clause:
WHEN_SYM
{
Lex->sphead->reset_lex(thd); /* For expr $3 */
+
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
expr
{
@@ -4181,6 +4386,8 @@ simple_when_clause:
LEX *lex= Lex;
if (lex->case_stmt_action_when($3, true))
MYSQL_YYABORT;
+
+ lex->pop_select(); //main select
/* For expr $3 */
if (lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
@@ -4197,12 +4404,17 @@ searched_when_clause:
WHEN_SYM
{
Lex->sphead->reset_lex(thd); /* For expr $3 */
+
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
expr
{
LEX *lex= Lex;
if (lex->case_stmt_action_when($3, false))
MYSQL_YYABORT;
+
+ lex->pop_select(); //main select
/* For expr $3 */
if (lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
@@ -4442,6 +4654,7 @@ while_body:
LEX *lex= Lex;
if (lex->sp_while_loop_expression(thd, $1))
MYSQL_YYABORT;
+ Lex->pop_select(); //main select pushed before while_body use
if (lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
}
@@ -4454,7 +4667,12 @@ while_body:
repeat_body:
sp_proc_stmts1 UNTIL_SYM
- { Lex->sphead->reset_lex(thd); }
+ {
+ Lex->sphead->reset_lex(thd);
+
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
expr END REPEAT_SYM
{
LEX *lex= Lex;
@@ -4465,6 +4683,8 @@ repeat_body:
if (i == NULL ||
lex->sphead->add_instr(i))
MYSQL_YYABORT;
+
+ lex->pop_select(); //main select
if (lex->sphead->restore_lex(thd))
MYSQL_YYABORT;
/* We can shortcut the cont_backpatch here */
@@ -4493,8 +4713,12 @@ sp_labeled_control:
if (Lex->sp_push_loop_label(thd, &$1))
MYSQL_YYABORT;
Lex->sphead->reset_lex(thd);
+
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
while_body pop_sp_loop_label
+
{ }
| labels_declaration_oracle FOR_SYM
{
@@ -4546,9 +4770,13 @@ sp_unlabeled_control:
if (Lex->sp_push_loop_empty_label(thd))
MYSQL_YYABORT;
Lex->sphead->reset_lex(thd);
+
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
while_body
{
+ // while body pop main select
Lex->sp_pop_loop_empty_label(thd);
}
| FOR_SYM
@@ -4981,25 +5209,15 @@ size_number:
*/
create_body:
- '(' create_field_list ')'
+ create_field_list_parens
{ Lex->create_info.option_list= NULL; }
opt_create_table_options opt_create_partitioning opt_create_select {}
| opt_create_table_options opt_create_partitioning opt_create_select {}
- /*
- the following rule is redundant, but there's a shift/reduce
- conflict that prevents the rule above from parsing a syntax like
- CREATE TABLE t1 (SELECT 1);
- */
- | '(' create_select_query_specification ')'
- | '(' create_select_query_specification ')'
- { Select->set_braces(1);} union_list {}
- | '(' create_select_query_specification ')'
- { Select->set_braces(1);} union_order_or_limit {}
| create_like
{
Lex->create_info.add(DDL_options_st::OPT_LIKE);
- TABLE_LIST *src_table= Lex->select_lex.add_table_to_list(thd,
+ TABLE_LIST *src_table= Lex->builtin_select.add_table_to_list(thd,
$1, NULL, 0, TL_READ, MDL_SHARED_READ);
if (! src_table)
MYSQL_YYABORT;
@@ -5010,7 +5228,7 @@ create_body:
create_like:
LIKE table_ident { $$= $2; }
- | '(' LIKE table_ident ')' { $$= $3; }
+ | LEFT_PAREN_LIKE LIKE table_ident ')' { $$= $3; }
;
opt_create_select:
@@ -5019,23 +5237,51 @@ opt_create_select:
;
create_select_query_expression:
- opt_with_clause SELECT_SYM create_select_part2 opt_table_expression
- create_select_part4
- {
- Select->set_braces(0);
- Select->set_with_clause($1);
+ query_expression
+ {
+ SELECT_LEX *first_select= $1->first_select();
+
+ if (Lex->sql_command == SQLCOM_INSERT ||
+ Lex->sql_command == SQLCOM_REPLACE)
+ {
+ if (Lex->sql_command == SQLCOM_INSERT)
+ Lex->sql_command= SQLCOM_INSERT_SELECT;
+ else
+ Lex->sql_command= SQLCOM_REPLACE_SELECT;
+ }
+ Lex->insert_select_hack(first_select);
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+
+ // fix "main" select
+ SELECT_LEX *blt= Lex->pop_select();
+ DBUG_ASSERT(blt == &Lex->builtin_select);
+ Lex->push_select(first_select);
}
- union_clause
- | opt_with_clause SELECT_SYM create_select_part2
- create_select_part3_union_not_ready create_select_part4
+ | LEFT_PAREN_WITH with_clause query_expression_body ')'
{
- Select->set_with_clause($1);
+ SELECT_LEX *first_select= $3->first_select();
+ $3->set_with_clause($2);
+ $2->attach_to(first_select);
+
+ if (Lex->sql_command == SQLCOM_INSERT ||
+ Lex->sql_command == SQLCOM_REPLACE)
+ {
+ if (Lex->sql_command == SQLCOM_INSERT)
+ Lex->sql_command= SQLCOM_INSERT_SELECT;
+ else
+ Lex->sql_command= SQLCOM_REPLACE_SELECT;
+ }
+
+ Lex->insert_select_hack(first_select);
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+
+ // fix "main" select
+ SELECT_LEX *blt= Lex->pop_select();
+ DBUG_ASSERT(blt == &Lex->builtin_select);
+ Lex->push_select(first_select);
}
- | '(' create_select_query_specification ')'
- | '(' create_select_query_specification ')'
- { Select->set_braces(1);} union_list {}
- | '(' create_select_query_specification ')'
- { Select->set_braces(1);} union_order_or_limit {}
;
opt_create_partitioning:
@@ -5126,8 +5372,13 @@ partition_entry:
We enter here when opening the frm file to translate
partition info string into part_info data structure.
*/
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
+ partition
+ {
+ Lex->pop_select(); //main select
}
- partition {}
;
partition:
@@ -5742,56 +5993,6 @@ opt_part_option:
End of partition parser part
*/
-create_select_query_specification:
- opt_with_clause SELECT_SYM create_select_part2 create_select_part3
- create_select_part4
- {
- Select->set_with_clause($1);
- }
- ;
-
-create_select_part2:
- {
- LEX *lex=Lex;
- if (lex->sql_command == SQLCOM_INSERT)
- lex->sql_command= SQLCOM_INSERT_SELECT;
- else if (lex->sql_command == SQLCOM_REPLACE)
- lex->sql_command= SQLCOM_REPLACE_SELECT;
- /*
- The following work only with the local list, the global list
- is created correctly in this case
- */
- lex->current_select->table_list.save_and_clear(&lex->save_list);
- mysql_init_select(lex);
- lex->current_select->parsing_place= SELECT_LIST;
- }
- select_options select_item_list
- {
- Select->parsing_place= NO_MATTER;
- }
- ;
-
-create_select_part3:
- opt_table_expression
- | create_select_part3_union_not_ready
- ;
-
-create_select_part3_union_not_ready:
- table_expression order_or_limit
- | order_or_limit
- ;
-
-create_select_part4:
- opt_select_lock_type
- {
- /*
- The following work only with the local list, the global list
- is created correctly in this case
- */
- Lex->current_select->table_list.push_front(&Lex->save_list);
- }
- ;
-
opt_as:
/* empty */ {}
| AS {}
@@ -6009,7 +6210,7 @@ create_table_option:
}
| UNION_SYM opt_equal
{
- Lex->select_lex.table_list.save_and_clear(&Lex->save_list);
+ Lex->builtin_select.table_list.save_and_clear(&Lex->save_list);
}
'(' opt_table_list ')'
{
@@ -6018,8 +6219,8 @@ create_table_option:
from the global list.
*/
LEX *lex=Lex;
- lex->create_info.merge_list= lex->select_lex.table_list;
- lex->select_lex.table_list= lex->save_list;
+ lex->create_info.merge_list= lex->builtin_select.table_list;
+ lex->builtin_select.table_list= lex->save_list;
/*
When excluding union list from the global list we assume that
elements of the former immediately follow elements which represent
@@ -6195,6 +6396,13 @@ create_field_list:
}
;
+create_field_list_parens:
+ LEFT_PAREN_ALT field_list ')'
+ {
+ Lex->create_last_non_select_table= Lex->last_table();
+ }
+ ;
+
field_list:
field_list_item
| field_list ',' field_list_item
@@ -6462,6 +6670,8 @@ parse_vcol_expr:
Prevent the end user from invoking this command.
*/
MYSQL_YYABORT_UNLESS(Lex->parse_vcol_expr);
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
expr
{
@@ -6469,13 +6679,29 @@ parse_vcol_expr:
if (!v)
MYSQL_YYABORT;
Lex->last_field->vcol_info= v;
+ Lex->pop_select(); //main select
}
;
parenthesized_expr:
- subselect
+ remember_tok_start
+ query_expression
{
- $$= new (thd->mem_root) Item_singlerow_subselect(thd, $1);
+ if (!Lex->expr_allows_subselect ||
+ Lex->sql_command == (int)SQLCOM_PURGE)
+ {
+ thd->parse_error(ER_SYNTAX_ERROR, $1);
+ MYSQL_YYABORT;
+ }
+
+ // Add the subtree of subquery to the current SELECT_LEX
+ SELECT_LEX *curr_sel= Lex->select_stack_head();
+ DBUG_ASSERT(Lex->current_select == curr_sel);
+ curr_sel->register_unit($2, &curr_sel->context);
+ curr_sel->add_statistics($2);
+
+ $$= new (thd->mem_root)
+ Item_singlerow_subselect(thd, $2->first_select());
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -7468,22 +7694,24 @@ alter:
Lex->table_type= TABLE_TYPE_UNKNOWN;
Lex->sql_command= SQLCOM_ALTER_TABLE;
Lex->duplicates= DUP_ERROR;
- Lex->select_lex.init_order();
+ Lex->builtin_select.init_order();
Lex->create_info.init();
Lex->create_info.row_type= ROW_TYPE_NOT_USED;
Lex->alter_info.reset();
Lex->no_write_to_binlog= 0;
Lex->create_info.storage_media= HA_SM_DEFAULT;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
DBUG_ASSERT(!Lex->m_sql_cmd);
}
alter_options TABLE_SYM table_ident opt_lock_wait_timeout
{
- if (!Lex->select_lex.add_table_to_list(thd, $5, NULL,
- TL_OPTION_UPDATING,
- TL_READ_NO_INSERT,
- MDL_SHARED_UPGRADABLE))
+ if (!Lex->builtin_select.add_table_to_list(thd, $5, NULL,
+ TL_OPTION_UPDATING,
+ TL_READ_NO_INSERT,
+ MDL_SHARED_UPGRADABLE))
MYSQL_YYABORT;
- Lex->select_lex.db= (Lex->select_lex.table_list.first)->db;
+ Lex->builtin_select.db= (Lex->builtin_select.table_list.first)->db;
Lex->create_last_non_select_table= Lex->last_table();
}
alter_commands
@@ -7495,11 +7723,14 @@ alter:
if (Lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
}
+ Lex->pop_select(); //main select
}
| ALTER DATABASE ident_or_empty
{
Lex->create_info.default_table_charset= NULL;
Lex->create_info.used_fields= 0;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
create_database_options
{
@@ -7508,6 +7739,7 @@ alter:
lex->name= $3;
if (lex->name.str == NULL && lex->copy_db_to(&lex->name))
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
}
| ALTER DATABASE ident UPGRADE_SYM DATA_SYM DIRECTORY_SYM NAME_SYM
{
@@ -7523,6 +7755,8 @@ alter:
if (lex->sphead)
my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "PROCEDURE"));
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
lex->sp_chistics.init();
}
sp_a_chistics
@@ -7531,6 +7765,9 @@ alter:
lex->sql_command= SQLCOM_ALTER_PROCEDURE;
lex->spname= $3;
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
}
| ALTER FUNCTION_SYM sp_name
{
@@ -7538,6 +7775,8 @@ alter:
if (lex->sphead)
my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "FUNCTION"));
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
lex->sp_chistics.init();
}
sp_a_chistics
@@ -7546,14 +7785,23 @@ alter:
lex->sql_command= SQLCOM_ALTER_FUNCTION;
lex->spname= $3;
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
}
| ALTER view_algorithm definer_opt opt_view_suid VIEW_SYM table_ident
{
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
if (Lex->add_alter_view(thd, $2, $4, $6))
MYSQL_YYABORT;
}
view_list_opt AS view_select
- {}
+ {
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+ }
| ALTER definer_opt opt_view_suid VIEW_SYM table_ident
/*
We have two separate rules for ALTER VIEW rather that
@@ -7561,14 +7809,22 @@ alter:
with the ALTER EVENT below.
*/
{
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
if (Lex->add_alter_view(thd, VIEW_ALGORITHM_INHERIT, $3, $5))
MYSQL_YYABORT;
}
view_list_opt AS view_select
- {}
+ {
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+ }
| ALTER definer_opt remember_name EVENT_SYM sp_name
{
- /*
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ /*
It is safe to use Lex->spname because
ALTER EVENT xxx RENATE TO yyy DO ALTER EVENT RENAME TO
is not allowed. Lex->spname is used in the case of RENAME TO
@@ -7600,6 +7856,8 @@ alter:
*/
Lex->sql_command= SQLCOM_ALTER_EVENT;
Lex->stmt_definition_end= (char*)YYLIP->get_cpp_ptr();
+
+ Lex->pop_select(); //main select
}
| ALTER TABLESPACE alter_tablespace_info
{
@@ -7643,15 +7901,17 @@ alter:
lex->create_info.init();
lex->no_write_to_binlog= 0;
DBUG_ASSERT(!lex->m_sql_cmd);
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
table_ident
{
LEX *lex= Lex;
if (!(lex->create_info.seq_create_info= new (thd->mem_root)
sequence_definition()) ||
- !lex->select_lex.add_table_to_list(thd, $5, NULL,
- TL_OPTION_SEQUENCE,
- TL_WRITE, MDL_EXCLUSIVE))
+ !lex->builtin_select.add_table_to_list(thd, $5, NULL,
+ TL_OPTION_SEQUENCE,
+ TL_WRITE, MDL_EXCLUSIVE))
MYSQL_YYABORT;
}
sequence_defs
@@ -7660,6 +7920,9 @@ alter:
Lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_sequence($3);
if (Lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
}
;
@@ -7809,18 +8072,17 @@ alter_commands:
WITH TABLE_SYM table_ident have_partitioning
{
LEX *lex= thd->lex;
- lex->select_lex.db= $6->db;
- if (lex->select_lex.db.str == NULL &&
- lex->copy_db_to(&lex->select_lex.db))
+ if (lex->builtin_select.db.str == NULL &&
+ lex->copy_db_to(&lex->builtin_select.db))
{
MYSQL_YYABORT;
}
lex->name= $6->table;
lex->alter_info.partition_flags|= ALTER_PARTITION_EXCHANGE;
- if (!lex->select_lex.add_table_to_list(thd, $6, NULL,
- TL_OPTION_UPDATING,
- TL_READ_NO_INSERT,
- MDL_SHARED_NO_WRITE))
+ if (!lex->builtin_select.add_table_to_list(thd, $6, NULL,
+ TL_OPTION_UPDATING,
+ TL_READ_NO_INSERT,
+ MDL_SHARED_NO_WRITE))
MYSQL_YYABORT;
DBUG_ASSERT(!lex->m_sql_cmd);
lex->m_sql_cmd= new (thd->mem_root)
@@ -8061,9 +8323,9 @@ alter_list_item:
| RENAME opt_to table_ident
{
LEX *lex=Lex;
- lex->select_lex.db= $3->db;
- if (lex->select_lex.db.str == NULL &&
- lex->copy_db_to(&lex->select_lex.db))
+ lex->builtin_select.db= $3->db;
+ if (lex->builtin_select.db.str == NULL &&
+ lex->copy_db_to(&lex->builtin_select.db))
{
MYSQL_YYABORT;
}
@@ -8337,9 +8599,13 @@ checksum:
lex->sql_command = SQLCOM_CHECKSUM;
/* Will be overridden during execution. */
YYPS->m_lock_type= TL_UNLOCK;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
table_list opt_checksum_type
- {}
+ {
+ Lex->pop_select(); //main select
+ }
;
opt_checksum_type:
@@ -8365,6 +8631,8 @@ repair:
lex->alter_info.reset();
/* Will be overridden during execution. */
YYPS->m_lock_type= TL_UNLOCK;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
repair_table_or_view
{
@@ -8373,6 +8641,7 @@ repair:
lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_repair_table();
if (lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
}
;
@@ -8401,6 +8670,8 @@ analyze:
ANALYZE_SYM opt_no_write_to_binlog table_or_tables
{
LEX *lex=Lex;
+ if (lex->main_select_push())
+ YYABORT;
lex->sql_command = SQLCOM_ANALYZE;
lex->no_write_to_binlog= $2;
lex->check_opt.init();
@@ -8415,6 +8686,7 @@ analyze:
lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_analyze_table();
if (lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
}
;
@@ -8531,6 +8803,8 @@ check: CHECK_SYM
lex->alter_info.reset();
/* Will be overridden during execution. */
YYPS->m_lock_type= TL_UNLOCK;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
check_view_or_table
{
@@ -8541,6 +8815,7 @@ check: CHECK_SYM
lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_check_table();
if (lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
}
;
@@ -8578,6 +8853,8 @@ optimize:
lex->alter_info.reset();
/* Will be overridden during execution. */
YYPS->m_lock_type= TL_UNLOCK;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
table_list opt_lock_wait_timeout
{
@@ -8586,6 +8863,7 @@ optimize:
lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_optimize_table();
if (lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
}
;
@@ -8599,9 +8877,13 @@ rename:
RENAME table_or_tables
{
Lex->sql_command= SQLCOM_RENAME_TABLE;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
table_to_table_list
- {}
+ {
+ Lex->pop_select(); //main select
+ }
| RENAME USER_SYM clear_privileges rename_list
{
Lex->sql_command = SQLCOM_RENAME_USER;
@@ -8695,9 +8977,13 @@ preload:
LEX *lex=Lex;
lex->sql_command=SQLCOM_PRELOAD_KEYS;
lex->alter_info.reset();
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
preload_list_or_parts
- {}
+ {
+ Lex->pop_select(); //main select
+ }
;
preload_list_or_parts:
@@ -8740,8 +9026,8 @@ adm_partition:
cache_keys_spec:
{
- Lex->select_lex.alloc_index_hints(thd);
- Select->set_index_hint_type(INDEX_HINT_USE,
+ Lex->builtin_select.alloc_index_hints(thd);
+ Select->set_index_hint_type(INDEX_HINT_USE,
INDEX_HINT_MASK_ALL);
}
cache_key_list_or_empty
@@ -8764,192 +9050,345 @@ opt_ignore_leaves:
select:
- opt_with_clause select_init
+ query_expression
{
- LEX *lex= Lex;
- lex->sql_command= SQLCOM_SELECT;
- lex->current_select->set_with_clause($1);
+ Lex->selects_allow_into= TRUE;
+ Lex->selects_allow_procedure= TRUE;
+ Lex->set_main_unit($1);
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+
+ Lex->sql_command= SQLCOM_SELECT;
}
;
-select_init:
- SELECT_SYM select_options_and_item_list select_init3
- | '(' select_paren ')'
- | '(' select_paren ')' union_list
- | '(' select_paren ')' union_order_or_limit
- ;
-union_list_part2:
- SELECT_SYM select_options_and_item_list select_init3_union_query_term
- | '(' select_paren_union_query_term ')'
- | '(' select_paren_union_query_term ')' union_list
- | '(' select_paren_union_query_term ')' union_order_or_limit
+simple_table:
+ query_specification { $$= $1; }
+ | table_value_constructor { $$= $1; }
;
-
-select_paren:
+
+table_value_constructor:
+ VALUES
+ {
+ LEX *lex= Lex;
+ SELECT_LEX *sel;
+ //lex->field_list.empty();
+ lex->many_values.empty();
+ lex->insert_list=0;
+ if (!(sel= lex->alloc_select(TRUE)) ||
+ lex->push_select(sel))
+ MYSQL_YYABORT;
+ sel->init_select();
+ sel->braces= FALSE; // just initialisation
+ }
+ values_list
+ {
+ LEX *lex=Lex;
+ $$= lex->pop_select(); // above TVC select
+ if (!($$->tvc=
+ new (lex->thd->mem_root) table_value_constr(lex->many_values,
+ $$,
+ $$->options)))
+ MYSQL_YYABORT;
+ lex->many_values.empty();
+ }
+ ;
+
+query_specification:
+ SELECT_SYM
{
- /*
- In order to correctly parse UNION's global ORDER BY we need to
- set braces before parsing the clause.
- */
- Lex->current_select->set_braces(true);
+ SELECT_LEX *sel;
+ LEX *lex= Lex;
+ if (!(sel= lex->alloc_select(TRUE)) ||
+ lex->push_select(sel))
+ MYSQL_YYABORT;
+ sel->init_select();
+ sel->braces= FALSE;
}
- SELECT_SYM select_options_and_item_list select_part3
- opt_select_lock_type
+ select_options
{
- DBUG_ASSERT(Lex->current_select->braces);
+ Select->parsing_place= SELECT_LIST;
}
- | '(' select_paren ')'
- ;
-
-select_paren_union_query_term:
+ select_item_list
{
- /*
- In order to correctly parse UNION's global ORDER BY we need to
- set braces before parsing the clause.
- */
- Lex->current_select->set_braces(true);
+ Select->parsing_place= NO_MATTER;
}
- SELECT_SYM select_options_and_item_list select_part3_union_query_term
- opt_select_lock_type
+ opt_into
+ opt_from_clause
+ opt_where_clause
+ opt_group_clause
+ opt_having_clause
+ opt_window_clause
{
- DBUG_ASSERT(Lex->current_select->braces);
+ $$= Lex->pop_select();
}
- | '(' select_paren_union_query_term ')'
;
-select_paren_view:
- {
- /*
- In order to correctly parse UNION's global ORDER BY we need to
- set braces before parsing the clause.
- */
- Lex->current_select->set_braces(true);
- }
- SELECT_SYM select_options_and_item_list select_part3_view
- opt_select_lock_type
- {
- DBUG_ASSERT(Lex->current_select->braces);
- }
- | '(' select_paren_view ')'
+opt_from_clause:
+ /* Empty */
+ | from_clause
+ ;
+
+query_primary:
+ simple_table
+ { $$= $1; }
+ | query_primary_parens
+ { $$= $1; }
;
-/* The equivalent of select_paren for nested queries. */
-select_paren_derived:
+query_primary_parens:
+ '(' query_expression_unit
{
- Lex->current_select->set_braces(true);
+ SELECT_LEX *last= $2->pre_last_parse->next_select();
+ int cmp= cmp_unit_op($2->first_select()->next_select()->linkage,
+ last->linkage);
+ if (cmp < 0)
+ {
+ if (!check_intersect_prefix($2->first_select()))
+ {
+ if (Lex->pop_new_select_and_wrap() == NULL)
+ MYSQL_YYABORT;
+ }
+ }
+ Lex->push_select($2->fake_select_lex);
}
- SELECT_SYM select_part2_derived
- opt_table_expression
- opt_order_clause
- opt_limit_clause
- opt_select_lock_type
+ query_expression_tail ')'
{
- DBUG_ASSERT(Lex->current_select->braces);
- $$= Lex->current_select->master_unit()->first_select();
+ Lex->pop_select();
+ if ($4)
+ {
+ ($4)->set_to($2->fake_select_lex);
+ }
+ $$= $2->first_select();
}
- | '(' select_paren_derived ')' { $$= $2; }
- ;
-
-select_init3:
- opt_table_expression
- opt_select_lock_type
+ | '(' query_primary
{
- /* Parentheses carry no meaning here */
- Lex->current_select->set_braces(false);
+ Lex->push_select($2);
}
- union_clause
- | select_part3_union_not_ready
- opt_select_lock_type
+ query_expression_tail ')'
{
- /* Parentheses carry no meaning here */
- Lex->current_select->set_braces(false);
+ Lex->pop_select();
+ $$= $2;
+ $$->braces= TRUE;
+ if ($4)
+ {
+ if ($2->next_select())
+ {
+ SELECT_LEX_UNIT *unit= $2->master_unit();
+ if (!unit)
+ unit= Lex->create_unit($2);
+ if (!unit)
+ YYABORT;
+ if (!unit->fake_select_lex->is_set_query_expr_tail)
+ $4->set_to(unit->fake_select_lex);
+ else
+ {
+ $$= Lex->wrap_unit_into_derived(unit);
+ if (!$$)
+ YYABORT;
+ $4->set_to($$);
+ }
+ }
+ else if (!$2->is_set_query_expr_tail)
+ {
+ $4->set_to($2);
+ }
+ else
+ {
+ SELECT_LEX_UNIT *unit= Lex->create_unit($2);
+ if (!unit)
+ YYABORT;
+ $$= Lex->wrap_unit_into_derived(unit);
+ if (!$$)
+ YYABORT;
+ $4->set_to($$);
+ }
+ }
}
;
-
-select_init3_union_query_term:
- opt_table_expression
- opt_select_lock_type
+query_expression_unit:
+ query_primary
+ unit_type_decl
+ query_primary
{
- /* Parentheses carry no meaning here */
- Lex->current_select->set_braces(false);
+ SELECT_LEX *sel1;
+ SELECT_LEX *sel2;
+ if (!$1->next_select())
+ sel1= $1;
+ else
+ {
+ sel1= Lex->wrap_unit_into_derived($1->master_unit());
+ if (!sel1)
+ YYABORT;
+ }
+ if (!$3->next_select())
+ sel2= $3;
+ else
+ {
+ sel2= Lex->wrap_unit_into_derived($3->master_unit());
+ if (!sel2)
+ YYABORT;
+ }
+ sel1->link_neighbour(sel2);
+ sel2->set_linkage_and_distinct($2.unit_type, $2.distinct);
+ $$= Lex->create_unit(sel1);
+ $$->pre_last_parse= sel1;
+ if ($$ == NULL)
+ YYABORT;
}
- union_clause
- | select_part3_union_not_ready_noproc
- opt_select_lock_type
+ | query_expression_unit
+ unit_type_decl
+ query_primary
{
- /* Parentheses carry no meaning here */
- Lex->current_select->set_braces(false);
+ SELECT_LEX *sel1;
+ if (!$3->next_select())
+ sel1= $3;
+ else
+ {
+ sel1= Lex->wrap_unit_into_derived($3->master_unit());
+ if (!sel1)
+ YYABORT;
+ }
+ SELECT_LEX *last= $1->pre_last_parse->next_select();
+
+ int cmp= cmp_unit_op($2.unit_type, last->linkage);
+ if (cmp == 0)
+ {
+ // do nothing, this part will be just connected
+ }
+ else if (cmp > 0)
+ {
+ // Store beginning and continue to connect parts
+ if (Lex->push_new_select($1->pre_last_parse))
+ MYSQL_YYABORT;
+ }
+ else /* cmp < 0 */
+ {
+ // wrap stored part in a select, then continue to connect parts
+ if (!check_intersect_prefix($1->first_select()))
+ {
+ if ((last= Lex->pop_new_select_and_wrap()) == NULL)
+ MYSQL_YYABORT;
+ last->set_master_unit($1);
+ }
+ }
+ last->link_neighbour(sel1);
+ sel1->set_master_unit($1);
+ sel1->set_linkage_and_distinct($2.unit_type, $2.distinct);
+ $$= $1;
+ $$->pre_last_parse= last;
}
;
-
-select_init3_view:
- opt_table_expression opt_select_lock_type
+query_expression_body:
+ query_primary
{
- Lex->current_select->set_braces(false);
+ Lex->push_select($1);
}
- | opt_table_expression opt_select_lock_type
+ query_expression_tail
{
- Lex->current_select->set_braces(false);
+ Lex->pop_select();
+ SELECT_LEX *sel= $1;
+ if ($3)
+ {
+ if ($1->next_select())
+ {
+ SELECT_LEX_UNIT *unit= $1->master_unit();
+ if (!unit)
+ unit= Lex->create_unit($1);
+ if (!unit)
+ YYABORT;
+ if (!unit->fake_select_lex->is_set_query_expr_tail)
+ $3->set_to(unit->fake_select_lex);
+ else
+ {
+ SELECT_LEX *sel= Lex->wrap_unit_into_derived(unit);
+ if (!sel)
+ YYABORT;
+ $3->set_to(sel);
+ }
+ }
+ else if (!$1->is_set_query_expr_tail)
+ $3->set_to($1);
+ else
+ {
+ SELECT_LEX_UNIT *unit= $1->master_unit();
+ if (!unit)
+ unit= Lex->create_unit($1);
+ if (!unit)
+ YYABORT;
+ sel= Lex->wrap_unit_into_derived(unit);
+ if (!sel)
+ YYABORT;
+ $3->set_to(sel);
+ }
+ }
+ $$= Lex->create_unit(sel);
+ if ($$ == NULL)
+ YYABORT;
}
- union_list_view
- | order_or_limit opt_select_lock_type
+ | query_expression_unit
{
- Lex->current_select->set_braces(false);
+ SELECT_LEX *last= $1->pre_last_parse->next_select();
+ int cmp= cmp_unit_op($1->first_select()->next_select()->linkage,
+ last->linkage);
+ if (cmp < 0)
+ {
+ if (!check_intersect_prefix($1->first_select()))
+ {
+ if (Lex->pop_new_select_and_wrap() == NULL)
+ MYSQL_YYABORT;
+ }
+ }
+ Lex->push_select($1->fake_select_lex);
}
- | table_expression order_or_limit opt_select_lock_type
+ query_expression_tail
{
- Lex->current_select->set_braces(false);
+ Lex->pop_select();
+ if ($3)
+ {
+ ($3)->set_to($1->fake_select_lex);
+ }
+ $$= $1;
}
;
-/*
- The SELECT parts after select_item_list that cannot be followed by UNION.
-*/
-
-select_part3:
- opt_table_expression
- | select_part3_union_not_ready
- ;
-
-select_part3_union_query_term:
- opt_table_expression
- | select_part3_union_not_ready_noproc
- ;
-
-select_part3_view:
- opt_table_expression
- | order_or_limit
- | table_expression order_or_limit
+query_expression:
+ opt_with_clause
+ query_expression_body
+ {
+ if ($1)
+ {
+ $2->set_with_clause($1);
+ $1->attach_to($2->first_select());
+ }
+ $$= $2;
+ }
;
-select_part3_union_not_ready:
- select_part3_union_not_ready_noproc
- | table_expression procedure_clause
- | table_expression order_or_limit procedure_clause
- ;
+subselect:
+ remember_tok_start
+ query_expression
+ {
+ if (!Lex->expr_allows_subselect ||
+ Lex->sql_command == (int)SQLCOM_PURGE)
+ {
+ thd->parse_error(ER_SYNTAX_ERROR, $1);
+ MYSQL_YYABORT;
+ }
-select_part3_union_not_ready_noproc:
- order_or_limit
- | into opt_table_expression opt_order_clause opt_limit_clause
- | table_expression into
- | table_expression order_or_limit
- | table_expression order_or_limit into
- ;
+ // Add the subtree of subquery to the current SELECT_LEX
+ SELECT_LEX *curr_sel= Lex->select_stack_head();
+ DBUG_ASSERT(Lex->current_select == curr_sel);
+ if (curr_sel)
+ {
+ curr_sel->register_unit($2, &curr_sel->context);
+ curr_sel->add_statistics($2);
+ }
-select_options_and_item_list:
- {
- LEX *lex= Lex;
- SELECT_LEX *sel= lex->current_select;
- if (sel->linkage != UNION_TYPE)
- mysql_init_select(lex);
- lex->current_select->parsing_place= SELECT_LIST;
- }
- select_options select_item_list
- {
- Select->parsing_place= NO_MATTER;
+ $$= $2->first_select();
}
;
@@ -8957,18 +9396,6 @@ select_options_and_item_list:
/**
<table expression>, as in the SQL standard.
*/
-table_expression:
- from_clause
- opt_where_clause
- opt_group_clause
- opt_having_clause
- opt_window_clause
- ;
-
-opt_table_expression:
- /* Empty */
- | table_expression
- ;
from_clause:
FROM table_reference_list
@@ -9006,59 +9433,63 @@ select_option:
query_expression_option
| SQL_NO_CACHE_SYM
{
- /*
- Allow this flag only on the first top-level SELECT statement, if
- SQL_CACHE wasn't specified, and only once per query.
- */
- if (Lex->current_select != &Lex->select_lex)
- my_yyabort_error((ER_CANT_USE_OPTION_HERE, MYF(0), "SQL_NO_CACHE"));
- if (Lex->select_lex.sql_cache == SELECT_LEX::SQL_CACHE)
- my_yyabort_error((ER_WRONG_USAGE, MYF(0), "SQL_CACHE", "SQL_NO_CACHE"));
- if (Lex->select_lex.sql_cache == SELECT_LEX::SQL_NO_CACHE)
+ /*
+ Allow this flag once per query.
+ */
+ if (Select->options & OPTION_NO_QUERY_CACHE)
my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "SQL_NO_CACHE"));
-
- Lex->safe_to_cache_query=0;
- Lex->select_lex.options&= ~OPTION_TO_QUERY_CACHE;
- Lex->select_lex.sql_cache= SELECT_LEX::SQL_NO_CACHE;
+ Select->options|= OPTION_NO_QUERY_CACHE;
}
| SQL_CACHE_SYM
{
- /*
- Allow this flag only on the first top-level SELECT statement, if
- SQL_NO_CACHE wasn't specified, and only once per query.
- */
- if (Lex->current_select != &Lex->select_lex)
- my_yyabort_error((ER_CANT_USE_OPTION_HERE, MYF(0), "SQL_CACHE"));
- if (Lex->select_lex.sql_cache == SELECT_LEX::SQL_NO_CACHE)
- my_yyabort_error((ER_WRONG_USAGE, MYF(0), "SQL_NO_CACHE", "SQL_CACHE"));
- if (Lex->select_lex.sql_cache == SELECT_LEX::SQL_CACHE)
+ /*
+ Allow this flag once per query.
+ */
+ if (Select->options & OPTION_TO_QUERY_CACHE)
my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "SQL_CACHE"));
-
- Lex->safe_to_cache_query=1;
- Lex->select_lex.options|= OPTION_TO_QUERY_CACHE;
- Lex->select_lex.sql_cache= SELECT_LEX::SQL_CACHE;
+ Select->options|= OPTION_TO_QUERY_CACHE;
}
;
opt_select_lock_type:
/* empty */
- | FOR_SYM UPDATE_SYM opt_lock_wait_timeout
+ { $$.empty(); }
+ | select_lock_type
+ { $$= $1; }
+ ;
+
+select_lock_type:
+ FOR_SYM UPDATE_SYM opt_lock_wait_timeout_new
{
- LEX *lex=Lex;
- lex->current_select->lock_type= TL_WRITE;
- lex->current_select->set_lock_for_tables(TL_WRITE);
- lex->safe_to_cache_query=0;
+ $$= $3;
+ $$.defined_lock= TRUE;
+ $$.update_lock= TRUE;
}
- | LOCK_SYM IN_SYM SHARE_SYM MODE_SYM opt_lock_wait_timeout
+ | LOCK_SYM IN_SYM SHARE_SYM MODE_SYM opt_lock_wait_timeout_new
{
- LEX *lex=Lex;
- lex->current_select->lock_type= TL_READ_WITH_SHARED_LOCKS;
- lex->current_select->
- set_lock_for_tables(TL_READ_WITH_SHARED_LOCKS);
- lex->safe_to_cache_query=0;
+ $$= $5;
+ $$.defined_lock= TRUE;
+ $$.update_lock= FALSE;
}
;
+opt_lock_wait_timeout_new:
+ /* empty */
+ {
+ $$.empty();
+ }
+ | WAIT_SYM ulong_num
+ {
+ $$.defined_timeout= TRUE;
+ $$.timeout= $2;
+ }
+ | NOWAIT_SYM
+ {
+ $$.defined_timeout= TRUE;
+ $$.timeout= 0;
+ }
+ ;
+
select_item_list:
select_item_list ',' select_item
| select_item
@@ -11362,10 +11793,15 @@ esc_table_ref:
/* Equivalent to <table reference list> in the SQL:2003 standard. */
/* Warning - may return NULL in case of incomplete SELECT */
derived_table_list:
- esc_table_ref { $$=$1; }
+ esc_table_ref
+ {
+ $$=$1;
+ Select->add_joined_table($1);
+ }
| derived_table_list ',' esc_table_ref
{
MYSQL_YYABORT_UNLESS($1 && ($$=$3));
+ Select->add_joined_table($3);
}
;
@@ -11384,11 +11820,18 @@ join_table:
left-associative joins.
*/
table_ref normal_join table_ref %prec TABLE_REF_PRIORITY
- { MYSQL_YYABORT_UNLESS($1 && ($$=$3)); $3->straight=$2; }
+ {
+ MYSQL_YYABORT_UNLESS($1 && ($$=$3));
+ Select->add_joined_table($1);
+ Select->add_joined_table($3);
+ $3->straight=$2;
+ }
| table_ref normal_join table_ref
ON
{
MYSQL_YYABORT_UNLESS($1 && $3);
+ Select->add_joined_table($1);
+ Select->add_joined_table($3);
/* Change the current name resolution context to a local context. */
if (push_new_name_resolution_context(thd, $1, $3))
MYSQL_YYABORT;
@@ -11405,6 +11848,8 @@ join_table:
USING
{
MYSQL_YYABORT_UNLESS($1 && $3);
+ Select->add_joined_table($1);
+ Select->add_joined_table($3);
}
'(' using_list ')'
{
@@ -11415,6 +11860,8 @@ join_table:
| table_ref NATURAL inner_join table_factor
{
MYSQL_YYABORT_UNLESS($1 && ($$=$4));
+ Select->add_joined_table($1);
+ Select->add_joined_table($4);
$4->straight=$3;
add_join_natural($1,$4,NULL,Select);
}
@@ -11424,6 +11871,8 @@ join_table:
ON
{
MYSQL_YYABORT_UNLESS($1 && $5);
+ Select->add_joined_table($1);
+ Select->add_joined_table($5);
/* Change the current name resolution context to a local context. */
if (push_new_name_resolution_context(thd, $1, $5))
MYSQL_YYABORT;
@@ -11440,6 +11889,8 @@ join_table:
| table_ref LEFT opt_outer JOIN_SYM table_factor
{
MYSQL_YYABORT_UNLESS($1 && $5);
+ Select->add_joined_table($1);
+ Select->add_joined_table($5);
}
USING '(' using_list ')'
{
@@ -11450,6 +11901,8 @@ join_table:
| table_ref NATURAL LEFT opt_outer JOIN_SYM table_factor
{
MYSQL_YYABORT_UNLESS($1 && $6);
+ Select->add_joined_table($1);
+ Select->add_joined_table($6);
add_join_natural($1,$6,NULL,Select);
$6->outer_join|=JOIN_TYPE_LEFT;
$$=$6;
@@ -11460,6 +11913,8 @@ join_table:
ON
{
MYSQL_YYABORT_UNLESS($1 && $5);
+ Select->add_joined_table($1);
+ Select->add_joined_table($5);
/* Change the current name resolution context to a local context. */
if (push_new_name_resolution_context(thd, $1, $5))
MYSQL_YYABORT;
@@ -11477,6 +11932,8 @@ join_table:
| table_ref RIGHT opt_outer JOIN_SYM table_factor
{
MYSQL_YYABORT_UNLESS($1 && $5);
+ Select->add_joined_table($1);
+ Select->add_joined_table($5);
}
USING '(' using_list ')'
{
@@ -11488,6 +11945,8 @@ join_table:
| table_ref NATURAL RIGHT opt_outer JOIN_SYM table_factor
{
MYSQL_YYABORT_UNLESS($1 && $6);
+ Select->add_joined_table($1);
+ Select->add_joined_table($6);
add_join_natural($6,$1,NULL,Select);
LEX *lex= Lex;
if (!($$= lex->current_select->convert_right_join()))
@@ -11522,40 +11981,70 @@ use_partition:
$$= $3;
}
;
-
-/*
- This is a flattening of the rules <table factor> and <table primary>
- in the SQL:2003 standard, since we don't have <sample clause>
- I.e.
- <table factor> ::= <table primary> [ <sample clause> ]
-*/
-/* Warning - may return NULL in case of incomplete SELECT */
table_factor:
- table_primary_ident
- | table_primary_derived
+ table_primary_ident { $$= $1; }
+ | table_primary_derived { $$= $1; }
+ | join_table_parens { $$= $1; }
+ | table_reference_list_parens { $$= $1; }
+ ;
+
+table_reference_list_parens:
+ '(' table_reference_list_parens ')' { $$= $2; }
+ | '(' nested_table_reference_list ')'
+ {
+ if (!($$= Select->end_nested_join(thd)))
+ MYSQL_YYABORT;
+ }
+ ;
+
+nested_table_reference_list:
+ table_ref ',' table_ref
+ {
+ if (Select->init_nested_join(thd))
+ MYSQL_YYABORT;
+ Select->add_joined_table($1);
+ Select->add_joined_table($3);
+ $$= $1->embedding;
+ }
+ | nested_table_reference_list ',' table_ref
+ {
+ Select->add_joined_table($3);
+ $$= $1;
+ }
;
+join_table_parens:
+ '(' join_table_parens ')' { $$= $2; }
+ | '(' join_table ')'
+ {
+ LEX *lex= Lex;
+ if (!($$= lex->current_select->nest_last_join(thd)))
+ {
+ thd->parse_error();
+ MYSQL_YYABORT;
+ }
+ }
+ ;
+
+
table_primary_ident:
+ table_ident opt_use_partition
+ opt_table_alias_clause opt_key_definition
{
SELECT_LEX *sel= Select;
sel->table_join_options= 0;
- }
- table_ident opt_use_partition opt_table_alias opt_key_definition
- {
- if (!($$= Select->add_table_to_list(thd, $2, $4,
+ if (!($$= Select->add_table_to_list(thd, $1, $3,
Select->get_table_join_options(),
YYPS->m_lock_type,
YYPS->m_mdl_type,
Select->pop_index_hints(),
- $3)))
+ $2)))
MYSQL_YYABORT;
- Select->add_joined_table($$);
}
;
-
/*
Represents a flattening of the following rules from the SQL:2003
standard. This sub-rule corresponds to the sub-rule
@@ -11573,242 +12062,56 @@ table_primary_ident:
*/
table_primary_derived:
- '(' get_select_lex select_derived_union ')' opt_table_alias
+ query_primary_parens table_alias_clause
{
- /* Use $2 instead of Lex->current_select as derived table will
- alter value of Lex->current_select. */
- if (!($3 || $5) && $2->embedding &&
- !$2->embedding->nested_join->join_list.elements)
+ LEX *lex=Lex;
+ lex->derived_tables|= DERIVED_SUBQUERY;
+ $1->linkage= DERIVED_TABLE_TYPE;
+ $1->braces= FALSE;
+ // Add the subtree of subquery to the current SELECT_LEX
+ SELECT_LEX *curr_sel= Lex->select_stack_head();
+ DBUG_ASSERT(Lex->current_select == curr_sel);
+ SELECT_LEX_UNIT *unit= $1->master_unit();
+ if (!unit)
{
- /* we have a derived table ($3 == NULL) but no alias,
- Since we are nested in further parentheses so we
- can pass NULL to the outer level parentheses
- Permits parsing of "((((select ...))) as xyz)" */
- $$= 0;
+ unit= Lex->create_unit($1);
+ if (!unit)
+ YYABORT;
}
- else if (!$3)
- {
- /* Handle case of derived table, alias may be NULL if there
- are no outer parentheses, add_table_to_list() will throw
- error in this case */
- LEX *lex=Lex;
- lex->check_automatic_up(UNSPECIFIED_TYPE);
- SELECT_LEX *sel= lex->current_select;
- SELECT_LEX_UNIT *unit= sel->master_unit();
- lex->current_select= sel= unit->outer_select();
- Table_ident *ti= new (thd->mem_root) Table_ident(unit);
- if (ti == NULL)
- MYSQL_YYABORT;
- if (!($$= sel->add_table_to_list(thd,
- ti, $5, 0,
- TL_READ, MDL_SHARED_READ)))
+ curr_sel->register_unit(unit, &curr_sel->context);
+ curr_sel->add_statistics(unit);
- MYSQL_YYABORT;
- sel->add_joined_table($$);
- lex->pop_context();
- lex->nest_level--;
- }
- else if ($5 != NULL)
- {
- /*
- Tables with or without joins within parentheses cannot
- have aliases, and we ruled out derived tables above.
- */
- thd->parse_error();
- MYSQL_YYABORT;
- }
- else
- {
- /* nested join: FROM (t1 JOIN t2 ...),
- nest_level is the same as in the outer query */
- $$= $3;
- }
- /*
- Fields in derived table can be used in upper select in
- case of merge. We do not add HAVING fields because we do
- not merge such derived. We do not add union because
- also do not merge them
- */
- if ($$ && $$->derived &&
- !$$->derived->first_select()->next_select())
- $$->select_lex->add_where_field($$->derived->first_select());
- }
- /* Represents derived table with WITH clause */
- | '(' get_select_lex subselect_start
- with_clause query_expression_body
- subselect_end ')' opt_table_alias
- {
- LEX *lex=Lex;
- SELECT_LEX *sel= $2;
- SELECT_LEX_UNIT *unit= $5->master_unit();
Table_ident *ti= new (thd->mem_root) Table_ident(unit);
if (ti == NULL)
MYSQL_YYABORT;
- $5->set_with_clause($4);
- lex->current_select= sel;
- if (!($$= sel->add_table_to_list(lex->thd,
- ti, $8, 0,
- TL_READ, MDL_SHARED_READ)))
+ if (!($$= curr_sel->add_table_to_list(lex->thd,
+ ti, $2, 0,
+ TL_READ, MDL_SHARED_READ)))
MYSQL_YYABORT;
- sel->add_joined_table($$);
- }
- ;
-
-/*
- This rule accepts just about anything. The reason is that we have
- empty-producing rules in the beginning of rules, in this case
- subselect_start. This forces bison to take a decision which rules to
- reduce by long before it has seen any tokens. This approach ties us
- to a very limited class of parseable languages, and unfortunately
- SQL is not one of them. The chosen 'solution' was this rule, which
- produces just about anything, even complete bogus statements, for
- instance ( table UNION SELECT 1 ).
- Fortunately, we know that the semantic value returned by
- select_derived is NULL if it contained a derived table, and a pointer to
- the base table's TABLE_LIST if it was a base table. So in the rule
- regarding union's, we throw a parse error manually and pretend it
- was bison that did it.
-
- Also worth noting is that this rule concerns query expressions in
- the from clause only. Top level select statements and other types of
- subqueries have their own union rules.
-*/
-select_derived_union:
- select_derived
- | select_derived union_order_or_limit
- {
- if ($1)
- {
- thd->parse_error();
- MYSQL_YYABORT;
- }
- }
- | select_derived union_head_non_top
- {
- if ($1)
- {
- thd->parse_error();
- MYSQL_YYABORT;
- }
}
- union_list_derived_part2
- | derived_query_specification opt_select_lock_type
- | derived_query_specification order_or_limit opt_select_lock_type
- | derived_query_specification opt_select_lock_type union_list_derived
- ;
-
-union_list_derived_part2:
- query_term_union_not_ready { Lex->pop_context(); }
- | query_term_union_ready { Lex->pop_context(); }
- | query_term_union_ready { Lex->pop_context(); } union_list_derived
- ;
-
-union_list_derived:
- union_head_non_top union_list_derived_part2
- ;
-
-
-/* The equivalent of select_init2 for nested queries. */
-select_init2_derived:
- select_part2_derived
- {
- Select->set_braces(0);
- }
- ;
-
-/* The equivalent of select_part2 for nested queries. */
-select_part2_derived:
- {
- LEX *lex= Lex;
- SELECT_LEX *sel= lex->current_select;
- if (sel->linkage != UNION_TYPE)
- mysql_init_select(lex);
- lex->current_select->parsing_place= SELECT_LIST;
- }
- opt_query_expression_options select_item_list
- {
- Select->parsing_place= NO_MATTER;
- }
- ;
-
-/* handle contents of parentheses in join expression */
-select_derived:
- get_select_lex_derived derived_table_list
+ | '('
+ query_expression
+ ')' table_alias_clause
{
- LEX *lex= Lex;
- /* for normal joins, $2 != NULL and end_nested_join() != NULL,
- for derived tables, both must equal NULL */
+ LEX *lex=Lex;
+ lex->derived_tables|= DERIVED_SUBQUERY;
+ $2->first_select()->linkage= DERIVED_TABLE_TYPE;
- if (!($$= $1->end_nested_join(lex->thd)) && $2)
- MYSQL_YYABORT;
- if (!$2 && $$)
- {
- thd->parse_error();
- MYSQL_YYABORT;
- }
- }
- ;
-/*
- Similar to query_specification, but for derived tables.
- Example: the inner parenthesized SELECT in this query:
- SELECT * FROM (SELECT * FROM t1);
-*/
-derived_query_specification:
- SELECT_SYM select_derived_init select_derived2
- {
- if ($2)
- Select->set_braces(1);
- $$= NULL;
- }
- ;
+ // Add the subtree of subquery to the current SELECT_LEX
+ SELECT_LEX *curr_sel= Lex->select_stack_head();
+ DBUG_ASSERT(Lex->current_select == curr_sel);
+ curr_sel->register_unit($2, &curr_sel->context);
+ curr_sel->add_statistics($2);
-select_derived2:
- {
- LEX *lex= Lex;
- lex->derived_tables|= DERIVED_SUBQUERY;
- if (!lex->expr_allows_subselect ||
- lex->sql_command == (int)SQLCOM_PURGE)
- {
- thd->parse_error();
- MYSQL_YYABORT;
- }
- if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE ||
- mysql_new_select(lex, 1, NULL))
+ Table_ident *ti= new (thd->mem_root) Table_ident($2);
+ if (ti == NULL)
MYSQL_YYABORT;
- mysql_init_select(lex);
- lex->current_select->linkage= DERIVED_TABLE_TYPE;
- lex->current_select->parsing_place= SELECT_LIST;
- }
- select_options select_item_list
- {
- Select->parsing_place= NO_MATTER;
- }
- opt_table_expression
- ;
-
-get_select_lex:
- /* Empty */ { $$= Select; }
- ;
-
-get_select_lex_derived:
- get_select_lex
- {
- LEX *lex= Lex;
- if ($1->init_nested_join(lex->thd))
+ if (!($$= curr_sel->add_table_to_list(lex->thd,
+ ti, $4, 0,
+ TL_READ, MDL_SHARED_READ)))
MYSQL_YYABORT;
}
- ;
-
-select_derived_init:
- {
- LEX *lex= Lex;
-
- TABLE_LIST *embedding= lex->current_select->embedding;
- $$= embedding &&
- !embedding->nested_join->join_list.elements;
- /* return true if we are deeply nested */
- }
;
opt_outer:
@@ -11940,9 +12243,14 @@ table_alias:
| '='
;
-opt_table_alias:
+opt_table_alias_clause:
/* empty */ { $$=0; }
- | table_alias ident
+
+ | table_alias_clause { $$= $1; }
+ ;
+
+table_alias_clause:
+ table_alias ident
{
$$= (LEX_CSTRING*) thd->memdup(&$2,sizeof(LEX_STRING));
if ($$ == NULL)
@@ -12109,7 +12417,7 @@ opt_window_partition_clause:
opt_window_order_clause:
/* empty */ { }
- | ORDER_SYM BY order_list
+ | ORDER_SYM BY order_list { Select->order_list= *($3); }
;
opt_window_frame_clause:
@@ -12233,64 +12541,35 @@ alter_order_item:
opt_order_clause:
/* empty */
+ { $$= NULL; }
| order_clause
+ { $$= $1; }
;
order_clause:
ORDER_SYM BY
{
- LEX *lex=Lex;
- SELECT_LEX *sel= lex->current_select;
- SELECT_LEX_UNIT *unit= sel-> master_unit();
- if (sel->linkage != GLOBAL_OPTIONS_TYPE &&
- sel->olap != UNSPECIFIED_OLAP_TYPE &&
- (sel->linkage != UNION_TYPE || sel->braces))
- {
- my_error(ER_WRONG_USAGE, MYF(0),
- "CUBE/ROLLUP", "ORDER BY");
- MYSQL_YYABORT;
- }
- if (lex->sql_command != SQLCOM_ALTER_TABLE &&
- !unit->fake_select_lex)
- {
- /*
- A query of the of the form (SELECT ...) ORDER BY order_list is
- executed in the same way as the query
- SELECT ... ORDER BY order_list
- unless the SELECT construct contains ORDER BY or LIMIT clauses.
- Otherwise we create a fake SELECT_LEX if it has not been created
- yet.
- */
- SELECT_LEX *first_sl= unit->first_select();
- if (!unit->is_unit_op() &&
- (first_sl->order_list.elements ||
- first_sl->select_limit) &&
- unit->add_fake_select_lex(thd))
- MYSQL_YYABORT;
- }
- if (sel->master_unit()->is_unit_op() && !sel->braces)
- {
- /*
- At this point we don't know yet whether this is the last
- select in union or not, but we move ORDER BY to
- fake_select_lex anyway. If there would be one more select
- in union mysql_new_select will correctly throw error.
- */
- DBUG_ASSERT(sel->master_unit()->fake_select_lex);
- lex->current_select= sel->master_unit()->fake_select_lex;
- }
+ thd->where= "ORDER clause";
}
order_list
{
-
+ $$= $4;
}
;
order_list:
order_list ',' order_ident order_dir
- { if (add_order_to_list(thd, $3,(bool) $4)) MYSQL_YYABORT; }
+ {
+ $$= $1;
+ if (add_to_list(thd, *$$, $3,(bool) $4))
+ MYSQL_YYABORT;
+ }
| order_ident order_dir
- { if (add_order_to_list(thd, $1,(bool) $2)) MYSQL_YYABORT; }
+ {
+ $$= new (thd->mem_root) SQL_I_List<ORDER>();
+ if (add_to_list(thd, *$$, $1, (bool) $2))
+ MYSQL_YYABORT;
+ }
;
order_dir:
@@ -12300,63 +12579,61 @@ order_dir:
;
opt_limit_clause:
- /* empty */ {}
- | limit_clause {}
+ /* empty */
+ { $$.empty(); }
+ | limit_clause
+ { $$= $1; }
;
-limit_clause_init:
- LIMIT
- {
- SELECT_LEX *sel= Select;
- if (sel->master_unit()->is_unit_op() && !sel->braces)
- {
- /* Move LIMIT that belongs to UNION to fake_select_lex */
- Lex->current_select= sel->master_unit()->fake_select_lex;
- DBUG_ASSERT(Select);
- }
- }
- ;
-
limit_clause:
- limit_clause_init limit_options
+ LIMIT limit_options
{
- SELECT_LEX *sel= Select;
- if (!sel->select_limit->basic_const_item() ||
- sel->select_limit->val_int() > 0)
+ $$= $2;
+ if (!$$.select_limit->basic_const_item() ||
+ $$.select_limit->val_int() > 0)
Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT);
}
- | limit_clause_init limit_options
+ | LIMIT limit_options
ROWS_SYM EXAMINED_SYM limit_rows_option
{
+ $$= $2;
Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT);
}
- | limit_clause_init ROWS_SYM EXAMINED_SYM limit_rows_option
+ | LIMIT ROWS_SYM EXAMINED_SYM limit_rows_option
{
+ $$.select_limit= 0;
+ $$.offset_limit= 0;
+ $$.explicit_limit= 1;
Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT);
}
;
+opt_global_limit_clause:
+ opt_limit_clause
+ {
+ Select->explicit_limit= $1.explicit_limit;
+ Select->select_limit= $1.select_limit;
+ Select->offset_limit= $1.offset_limit;
+ }
+
limit_options:
limit_option
{
- SELECT_LEX *sel= Select;
- sel->select_limit= $1;
- sel->offset_limit= 0;
- sel->explicit_limit= 1;
+ $$.select_limit= $1;
+ $$.offset_limit= 0;
+ $$.explicit_limit= 1;
}
| limit_option ',' limit_option
{
- SELECT_LEX *sel= Select;
- sel->select_limit= $3;
- sel->offset_limit= $1;
- sel->explicit_limit= 1;
+ $$.select_limit= $3;
+ $$.offset_limit= $1;
+ $$.explicit_limit= 1;
}
| limit_option OFFSET_SYM limit_option
{
- SELECT_LEX *sel= Select;
- sel->select_limit= $1;
- sel->offset_limit= $3;
- sel->explicit_limit= 1;
+ $$.select_limit= $1;
+ $$.offset_limit= $3;
+ $$.explicit_limit= 1;
}
;
@@ -12425,6 +12702,66 @@ delete_limit_clause:
| LIMIT limit_option ROWS_SYM EXAMINED_SYM { thd->parse_error(); MYSQL_YYABORT; }
;
+query_expression_tail:
+ /* empty */ { $$= NULL; }
+ | order_or_limit opt_select_lock_type
+ {
+ $$= $1;
+ $$->lock= $2;
+ }
+ | order_or_limit procedure_or_into opt_select_lock_type
+ {
+ $$= $1;
+ $$->lock= $3;
+ }
+ | procedure_or_into opt_select_lock_type
+ {
+ $$= new(thd->mem_root) Lex_order_limit_lock;
+ if (!$$)
+ YYABORT;
+ $$->order_list= NULL;
+ $$->limit.empty();
+ $$->lock= $2;
+ }
+ | select_lock_type
+ {
+ $$= new(thd->mem_root) Lex_order_limit_lock;
+ if (!$$)
+ YYABORT;
+ $$->order_list= NULL;
+ $$->limit.empty();
+ $$->lock= $1;
+ }
+ ;
+
+procedure_or_into:
+ procedure_clause
+ | into
+ | procedure_clause into
+ ;
+
+order_or_limit:
+ order_clause opt_limit_clause
+ {
+ $$= new(thd->mem_root) Lex_order_limit_lock;
+ if (!$$)
+ YYABORT;
+ $$->order_list= $1;
+ $$->limit= $2;
+ }
+ | limit_clause
+ {
+ Lex_order_limit_lock *op= $$= new(thd->mem_root) Lex_order_limit_lock;
+ if (!$$)
+ YYABORT;
+ op->order_list= NULL;
+ op->limit= $1;
+ $$->order_list= NULL;
+ $$->limit= $1;
+ }
+ ;
+
+
opt_plus:
/* empty */
| '+'
@@ -12494,14 +12831,11 @@ bool:
| TRUE_SYM { $$= 1; }
| FALSE_SYM { $$= 0; }
-
procedure_clause:
PROCEDURE_SYM ident /* Procedure name */
{
LEX *lex=Lex;
- DBUG_ASSERT(&lex->select_lex == lex->current_select);
-
lex->proc_list.elements=0;
lex->proc_list.first=0;
lex->proc_list.next= &lex->proc_list.first;
@@ -12521,6 +12855,7 @@ procedure_clause:
parameters are reduced.
*/
Lex->expr_allows_subselect= false;
+ Select->options|= OPTION_PROCEDURE_CLAUSE;
}
'(' procedure_list ')'
{
@@ -12601,8 +12936,21 @@ select_outvar:
}
;
+opt_into:
+ /* empty */
+ | into
+ ;
into:
INTO into_destination
+ {
+ if (!(Select->options & OPTION_INTO_CLAUSE))
+ Select->options|= OPTION_INTO_CLAUSE;
+ else
+ {
+ my_error(ER_CANT_USE_OPTION_HERE, MYF(0), "INTO");
+ MYSQL_YYABORT;
+ }
+ }
;
into_destination:
@@ -12648,10 +12996,15 @@ do:
LEX *lex=Lex;
lex->sql_command = SQLCOM_DO;
mysql_init_select(lex);
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
expr_list
{
Lex->insert_list= $3;
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
}
;
@@ -12883,17 +13236,24 @@ insert:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_INSERT;
- lex->duplicates= DUP_ERROR;
- mysql_init_select(lex);
+ lex->duplicates= DUP_ERROR;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ mysql_init_select(lex);
+ lex->current_select->parsing_place= BEFORE_OPT_LIST;
}
insert_lock_option
opt_ignore insert2
{
Select->set_lock_for_tables($3);
- Lex->current_select= &Lex->select_lex;
+ Lex->current_select= Lex->first_select_lex();
}
insert_field_spec opt_insert_update
- {}
+ {
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+ }
;
replace:
@@ -12902,15 +13262,22 @@ replace:
LEX *lex=Lex;
lex->sql_command = SQLCOM_REPLACE;
lex->duplicates= DUP_REPLACE;
- mysql_init_select(lex);
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ mysql_init_select(lex);
+ lex->current_select->parsing_place= BEFORE_OPT_LIST;
}
replace_lock_option insert2
{
Select->set_lock_for_tables($3);
- Lex->current_select= &Lex->select_lex;
+ Lex->current_select= Lex->first_select_lex();
}
insert_field_spec
- {}
+ {
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+ }
;
insert_lock_option:
@@ -12956,35 +13323,47 @@ insert_table:
table_name_with_opt_use_partition
{
LEX *lex=Lex;
- lex->field_list.empty();
+ //lex->field_list.empty();
lex->many_values.empty();
lex->insert_list=0;
};
insert_field_spec:
insert_values {}
- | '(' ')' insert_values {}
- | '(' fields ')' insert_values {}
+ | insert_field_list insert_values {}
| SET
{
LEX *lex=Lex;
if (!(lex->insert_list= new (thd->mem_root) List_item) ||
lex->many_values.push_back(lex->insert_list, thd->mem_root))
MYSQL_YYABORT;
+ lex->current_select->parsing_place= NO_MATTER;
}
ident_eq_list
;
+insert_field_list:
+ LEFT_PAREN_ALT opt_fields ')'
+ {
+ Lex->current_select->parsing_place= AFTER_LIST;
+ }
+ ;
+
+opt_fields:
+ /* empty */
+ | fields
+ ;
+
fields:
fields ',' insert_ident
{ Lex->field_list.push_back($3, thd->mem_root); }
| insert_ident { Lex->field_list.push_back($1, thd->mem_root); }
;
+
+
insert_values:
- VALUES values_list {}
- | VALUE_SYM values_list {}
- | create_select_query_expression {}
+ create_select_query_expression {}
;
values_list:
@@ -13094,6 +13473,8 @@ update:
UPDATE_SYM
{
LEX *lex= Lex;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
mysql_init_select(lex);
lex->sql_command= SQLCOM_UPDATE;
lex->duplicates= DUP_ERROR;
@@ -13102,13 +13483,14 @@ update:
SET update_list
{
LEX *lex= Lex;
- if (lex->select_lex.table_list.elements > 1)
+ if (lex->builtin_select.table_list.elements > 1)
lex->sql_command= SQLCOM_UPDATE_MULTI;
- else if (lex->select_lex.get_table_list()->derived)
+ else if (lex->builtin_select.get_table_list()->derived)
{
/* it is single table update and it is update of derived table */
my_error(ER_NON_UPDATABLE_TABLE, MYF(0),
- lex->select_lex.get_table_list()->alias.str, "UPDATE");
+ lex->builtin_select.get_table_list()->alias.str,
+ "UPDATE");
MYSQL_YYABORT;
}
/*
@@ -13118,7 +13500,14 @@ update:
*/
Select->set_lock_for_tables($3);
}
- opt_where_clause opt_order_clause delete_limit_clause {}
+ opt_where_clause opt_order_clause delete_limit_clause
+ {
+ if ($10)
+ Select->order_list= *($10);
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+ }
;
update_list:
@@ -13164,9 +13553,11 @@ delete:
mysql_init_select(lex);
YYPS->m_lock_type= TL_WRITE_DEFAULT;
YYPS->m_mdl_type= MDL_SHARED_WRITE;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
lex->ignore= 0;
- lex->select_lex.init_order();
+ lex->builtin_select.init_order();
}
opt_delete_options single_multi
;
@@ -13185,7 +13576,12 @@ single_multi:
}
opt_where_clause opt_order_clause
delete_limit_clause {}
- opt_select_expressions {}
+ opt_select_expressions
+ {
+ if ($6)
+ Select->order_list= *($6);
+ Lex->pop_select(); //main select
+ }
| table_wild_list
{
mysql_init_multi_delete(Lex);
@@ -13196,6 +13592,9 @@ single_multi:
{
if (multi_delete_set_locks_and_link_aux_tables(Lex))
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
}
| FROM table_alias_ref_list
{
@@ -13207,6 +13606,9 @@ single_multi:
{
if (multi_delete_set_locks_and_link_aux_tables(Lex))
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
}
;
@@ -13270,10 +13672,12 @@ truncate:
{
LEX* lex= Lex;
lex->sql_command= SQLCOM_TRUNCATE;
+ if (lex->main_select_push())
+ MYSQL_YYABORT;
lex->alter_info.reset();
- lex->select_lex.options= 0;
- lex->select_lex.sql_cache= SELECT_LEX::SQL_CACHE_UNSPECIFIED;
- lex->select_lex.init_order();
+ lex->builtin_select.options= 0;
+ lex->builtin_select.sql_cache= SELECT_LEX::SQL_CACHE_UNSPECIFIED;
+ lex->builtin_select.init_order();
YYPS->m_lock_type= TL_WRITE;
YYPS->m_mdl_type= MDL_EXCLUSIVE;
}
@@ -13284,6 +13688,7 @@ truncate:
lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_truncate_table();
if (lex->m_sql_cmd == NULL)
MYSQL_YYABORT;
+ Lex->pop_select(); //main select
}
opt_truncate_table_storage_clause { }
;
@@ -13365,6 +13770,8 @@ show:
LEX *lex=Lex;
lex->wild=0;
lex->ident= null_clex_str;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
mysql_init_select(lex);
lex->current_select->parsing_place= SELECT_LIST;
lex->create_info.init();
@@ -13372,6 +13779,7 @@ show:
show_param
{
Select->parsing_place= NO_MATTER;
+ Lex->pop_select(); //main select
}
;
@@ -13387,7 +13795,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_TABLES;
- lex->select_lex.db= $3;
+ lex->first_select_lex()->db= $3;
if (prepare_schema_table(thd, lex, 0, SCH_TABLE_NAMES))
MYSQL_YYABORT;
}
@@ -13395,7 +13803,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_TRIGGERS;
- lex->select_lex.db= $3;
+ lex->first_select_lex()->db= $3;
if (prepare_schema_table(thd, lex, 0, SCH_TRIGGERS))
MYSQL_YYABORT;
}
@@ -13403,7 +13811,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_EVENTS;
- lex->select_lex.db= $2;
+ lex->first_select_lex()->db= $2;
if (prepare_schema_table(thd, lex, 0, SCH_EVENTS))
MYSQL_YYABORT;
}
@@ -13411,7 +13819,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_TABLE_STATUS;
- lex->select_lex.db= $3;
+ lex->first_select_lex()->db= $3;
if (prepare_schema_table(thd, lex, 0, SCH_TABLES))
MYSQL_YYABORT;
}
@@ -13419,7 +13827,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_OPEN_TABLES;
- lex->select_lex.db= $3;
+ lex->first_select_lex()->db= $3;
if (prepare_schema_table(thd, lex, 0, SCH_OPEN_TABLES))
MYSQL_YYABORT;
}
@@ -13469,12 +13877,13 @@ show_param:
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_BINLOG_EVENTS;
}
- opt_limit_clause
+ opt_global_limit_clause
| RELAYLOG_SYM optional_connection_name EVENTS_SYM binlog_in binlog_from
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_RELAYLOG_EVENTS;
- } opt_limit_clause
+ }
+ opt_global_limit_clause
| keys_or_index from_or_in table_ident opt_db opt_where_clause
{
LEX *lex= Lex;
@@ -13516,13 +13925,13 @@ show_param:
LEX_CSTRING var= {STRING_WITH_LEN("error_count")};
(void) create_select_for_variable(thd, &var);
}
- | WARNINGS opt_limit_clause
+ | WARNINGS opt_global_limit_clause
{ Lex->sql_command = SQLCOM_SHOW_WARNS;}
- | ERRORS opt_limit_clause
+ | ERRORS opt_global_limit_clause
{ Lex->sql_command = SQLCOM_SHOW_ERRORS;}
| PROFILES_SYM
{ Lex->sql_command = SQLCOM_SHOW_PROFILES; }
- | PROFILE_SYM opt_profile_defs opt_profile_args opt_limit_clause
+ | PROFILE_SYM opt_profile_defs opt_profile_args opt_global_limit_clause
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SHOW_PROFILE;
@@ -13583,7 +13992,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command = SQLCOM_SHOW_CREATE;
- if (!lex->select_lex.add_table_to_list(thd, $3, NULL,0))
+ if (!lex->builtin_select.add_table_to_list(thd, $3, NULL,0))
MYSQL_YYABORT;
lex->create_info.storage_media= HA_SM_DEFAULT;
}
@@ -13591,7 +14000,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command = SQLCOM_SHOW_CREATE;
- if (!lex->select_lex.add_table_to_list(thd, $3, NULL, 0))
+ if (!lex->builtin_select.add_table_to_list(thd, $3, NULL, 0))
MYSQL_YYABORT;
lex->table_type= TABLE_TYPE_VIEW;
}
@@ -13599,7 +14008,7 @@ show_param:
{
LEX *lex= Lex;
lex->sql_command = SQLCOM_SHOW_CREATE;
- if (!lex->select_lex.add_table_to_list(thd, $3, NULL, 0))
+ if (!lex->builtin_select.add_table_to_list(thd, $3, NULL, 0))
MYSQL_YYABORT;
lex->table_type= TABLE_TYPE_SEQUENCE;
}
@@ -13815,7 +14224,7 @@ describe:
mysql_init_select(lex);
lex->current_select->parsing_place= SELECT_LIST;
lex->sql_command= SQLCOM_SHOW_FIELDS;
- lex->select_lex.db= null_clex_str;
+ lex->builtin_select.db= null_clex_str;
lex->verbose= 0;
if (prepare_schema_table(thd, lex, $2, SCH_COLUMNS))
MYSQL_YYABORT;
@@ -13829,7 +14238,7 @@ describe:
explainable_command
{
LEX *lex=Lex;
- lex->select_lex.options|= SELECT_DESCRIBE;
+ lex->first_select_lex()->options|= SELECT_DESCRIBE;
}
;
@@ -13855,6 +14264,8 @@ analyze_stmt_command:
opt_extended_describe:
EXTENDED_SYM { Lex->describe|= DESCRIBE_EXTENDED; }
+ | EXTENDED_SYM ALL
+ { Lex->describe|= DESCRIBE_EXTENDED | DESCRIBE_EXTENDED2; }
| PARTITIONS_SYM { Lex->describe|= DESCRIBE_PARTITIONS; }
| opt_format_json {}
;
@@ -13897,8 +14308,7 @@ flush:
lex->type= 0;
lex->no_write_to_binlog= $2;
}
- flush_options
- {}
+ flush_options {}
;
flush_options:
@@ -13915,6 +14325,7 @@ flush_options:
opt_table_list opt_flush_lock
{}
| flush_options_list
+ {}
;
opt_flush_lock:
@@ -14070,9 +14481,13 @@ purge:
LEX *lex=Lex;
lex->type=0;
lex->sql_command = SQLCOM_PURGE;
+ if (lex->main_select_push())
+ MYSQL_YYABORT;
}
purge_options
- {}
+ {
+ Lex->pop_select(); //main select
+ }
;
purge_options:
@@ -14090,6 +14505,8 @@ purge_option:
lex->value_list.empty();
lex->value_list.push_front($2, thd->mem_root);
lex->sql_command= SQLCOM_PURGE_BEFORE;
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
}
;
@@ -14099,6 +14516,8 @@ kill:
KILL_SYM
{
LEX *lex=Lex;
+ if (lex->main_select_push())
+ YYABORT;
lex->value_list.empty();
lex->users_list.empty();
lex->sql_command= SQLCOM_KILL;
@@ -14107,6 +14526,7 @@ kill:
kill_type kill_option kill_expr
{
Lex->kill_signal= (killed_state) ($3 | $4);
+ Lex->pop_select(); //main select
}
;
@@ -14150,7 +14570,7 @@ use:
{
LEX *lex=Lex;
lex->sql_command=SQLCOM_CHANGE_DB;
- lex->select_lex.db= $2;
+ lex->builtin_select.db= $2;
}
;
@@ -14167,6 +14587,8 @@ load:
$2 == FILETYPE_CSV ? "LOAD DATA" : "LOAD XML");
MYSQL_YYABORT;
}
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
load_data_lock opt_local INFILE TEXT_STRING_filesystem
{
@@ -14193,7 +14615,11 @@ load:
opt_xml_rows_identified_by
opt_field_term opt_line_term opt_ignore_lines opt_field_or_var_spec
opt_load_data_set_spec
- {}
+ {
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+ }
;
data_or_xml:
@@ -14597,17 +15023,21 @@ opt_with_clause:
with_clause:
- WITH opt_recursive
+ WITH opt_recursive
{
+ LEX *lex= Lex;
With_clause *with_clause=
new With_clause($2, Lex->curr_with_clause);
if (with_clause == NULL)
MYSQL_YYABORT;
- Lex->derived_tables|= DERIVED_WITH;
- Lex->curr_with_clause= with_clause;
+ lex->derived_tables|= DERIVED_WITH;
+ lex->curr_with_clause= with_clause;
with_clause->add_to_list(Lex->with_clauses_list_last_next);
+ if (lex->current_select &&
+ lex->current_select->parsing_place == BEFORE_OPT_LIST)
+ lex->current_select->parsing_place= NO_MATTER;
}
- with_list
+ with_list
{
$$= Lex->curr_with_clause;
Lex->curr_with_clause= Lex->curr_with_clause->pop();
@@ -14636,9 +15066,9 @@ with_list_element:
MYSQL_YYABORT;
Lex->with_column_list.empty();
}
- AS '(' remember_name subselect remember_end ')'
+ AS '(' remember_name query_expression remember_end ')'
{
- With_element *elem= new With_element($1, *$2, $7->master_unit());
+ With_element *elem= new With_element($1, *$2, $7);
if (elem == NULL || Lex->curr_with_clause->add_with_element(elem))
MYSQL_YYABORT;
if (elem->set_unparsed_spec(thd, $6+1, $8))
@@ -15589,14 +16019,22 @@ set:
SET
{
LEX *lex=Lex;
+ if (lex->main_select_push())
+ MYSQL_YYABORT;
lex->set_stmt_init();
lex->var_list.empty();
sp_create_assignment_lex(thd, yychar == YYEMPTY);
}
start_option_value_list
- {}
+ {
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+ }
| SET STATEMENT_SYM
{
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
Lex->set_stmt_init();
}
set_stmt_option_value_following_option_type_list
@@ -15606,6 +16044,9 @@ set:
my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0), "SET STATEMENT"));
lex->stmt_var_list= lex->var_list;
lex->var_list.empty();
+ Lex->pop_select(); //main select
+ if (Lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
}
FOR_SYM verb_clause
{}
@@ -16038,9 +16479,13 @@ lock:
if (lex->sphead)
my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "LOCK"));
lex->sql_command= SQLCOM_LOCK_TABLES;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
table_lock_list opt_lock_wait_timeout
- {}
+ {
+ Lex->pop_select(); //main select
+ }
;
opt_lock_wait_timeout:
@@ -16071,7 +16516,7 @@ table_lock_list:
;
table_lock:
- table_ident opt_table_alias lock_option
+ table_ident opt_table_alias_clause lock_option
{
thr_lock_type lock_type= (thr_lock_type) $3;
bool lock_for_write= (lock_type >= TL_WRITE_ALLOW_WRITE);
@@ -16105,9 +16550,13 @@ unlock:
if (lex->sphead)
my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "UNLOCK"));
lex->sql_command= SQLCOM_UNLOCK_TABLES;
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
}
table_or_tables
- {}
+ {
+ Lex->pop_select(); //main select
+ }
;
/*
@@ -16115,25 +16564,36 @@ unlock:
*/
handler:
- HANDLER_SYM table_ident OPEN_SYM opt_table_alias
+ HANDLER_SYM
+ {
+ if (Lex->main_select_push())
+ MYSQL_YYABORT;
+ }
+ handler_tail
+ {
+ Lex->pop_select(); //main select
+ }
+
+handler_tail:
+ table_ident OPEN_SYM opt_table_alias_clause
{
LEX *lex= Lex;
if (lex->sphead)
my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "HANDLER"));
lex->sql_command = SQLCOM_HA_OPEN;
- if (!lex->current_select->add_table_to_list(thd, $2, $4, 0))
+ if (!lex->current_select->add_table_to_list(thd, $1, $3, 0))
MYSQL_YYABORT;
}
- | HANDLER_SYM table_ident_nodb CLOSE_SYM
+ | table_ident_nodb CLOSE_SYM
{
LEX *lex= Lex;
if (lex->sphead)
my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "HANDLER"));
lex->sql_command = SQLCOM_HA_CLOSE;
- if (!lex->current_select->add_table_to_list(thd, $2, 0, 0))
+ if (!lex->current_select->add_table_to_list(thd, $1, 0, 0))
MYSQL_YYABORT;
}
- | HANDLER_SYM table_ident_nodb READ_SYM
+ | table_ident_nodb READ_SYM
{
LEX *lex=Lex;
if (lex->sphead)
@@ -16141,20 +16601,24 @@ handler:
lex->expr_allows_subselect= FALSE;
lex->sql_command = SQLCOM_HA_READ;
lex->ha_rkey_mode= HA_READ_KEY_EXACT; /* Avoid purify warnings */
- Item *one= new (thd->mem_root) Item_int(thd, (int32) 1);
- if (one == NULL)
- MYSQL_YYABORT;
- lex->current_select->select_limit= one;
- lex->current_select->offset_limit= 0;
- lex->limit_rows_examined= 0;
- if (!lex->current_select->add_table_to_list(thd, $2, 0, 0))
+ if (!lex->current_select->add_table_to_list(thd, $1, 0, 0))
MYSQL_YYABORT;
}
- handler_read_or_scan opt_where_clause opt_limit_clause
+ handler_read_or_scan opt_where_clause opt_global_limit_clause
{
- Lex->expr_allows_subselect= TRUE;
+ LEX *lex=Lex;
+ lex->expr_allows_subselect= TRUE;
+ if (!lex->current_select->explicit_limit)
+ {
+ Item *one= new (thd->mem_root) Item_int(thd, (int32) 1);
+ if (one == NULL)
+ MYSQL_YYABORT;
+ lex->current_select->select_limit= one;
+ lex->current_select->offset_limit= 0;
+ lex->limit_rows_examined= 0;
+ }
/* Stored functions are not supported for HANDLER READ. */
- if (Lex->uses_stored_routines())
+ if (lex->uses_stored_routines())
{
my_error(ER_NOT_SUPPORTED_YET, MYF(0),
"stored functions in HANDLER ... READ");
@@ -16800,83 +17264,16 @@ release:
*/
unit_type_decl:
- UNION_SYM
- { $$= UNION_TYPE; }
+ UNION_SYM union_option
+ { $$.unit_type= UNION_TYPE; $$.distinct= $2; }
| INTERSECT_SYM
- { $$= INTERSECT_TYPE; }
+ { $$.unit_type= INTERSECT_TYPE; $$.distinct= 1; }
| EXCEPT_SYM
- { $$= EXCEPT_TYPE; }
-
-
-union_clause:
- /* empty */ {}
- | union_list
- ;
-
-union_list:
- unit_type_decl union_option
- {
- if (Lex->add_select_to_union_list((bool)$2, $1, TRUE))
- MYSQL_YYABORT;
- }
- union_list_part2
- {
- /*
- Remove from the name resolution context stack the context of the
- last select in the union.
- */
- Lex->pop_context();
- }
- ;
-
-union_list_view:
- unit_type_decl union_option
- {
- if (Lex->add_select_to_union_list((bool)$2, $1, TRUE))
- MYSQL_YYABORT;
- }
- query_expression_body_view
- {
- Lex->pop_context();
- }
- ;
-
-union_order_or_limit:
- {
- LEX *lex= thd->lex;
- DBUG_ASSERT(lex->current_select->linkage != GLOBAL_OPTIONS_TYPE);
- SELECT_LEX *sel= lex->current_select;
- SELECT_LEX_UNIT *unit= sel->master_unit();
- SELECT_LEX *fake= unit->fake_select_lex;
- if (fake)
- {
- fake->no_table_names_allowed= 1;
- lex->current_select= fake;
- }
- thd->where= "global ORDER clause";
- }
- order_or_limit
- {
- thd->lex->current_select->no_table_names_allowed= 0;
- thd->where= "";
- }
- ;
-
-order_or_limit:
- order_clause opt_limit_clause
- | limit_clause
- ;
+ { $$.unit_type= EXCEPT_TYPE; $$.distinct= 1; }
/*
Start a UNION, for non-top level query expressions.
*/
-union_head_non_top:
- unit_type_decl union_option
- {
- if (Lex->add_select_to_union_list((bool)$2, $1, FALSE))
- MYSQL_YYABORT;
- }
- ;
union_option:
/* empty */ { $$=1; }
@@ -16884,110 +17281,10 @@ union_option:
| ALL { $$=0; }
;
-/*
- Corresponds to the SQL Standard
- <query specification> ::=
- SELECT [ <set quantifier> ] <select list> <table expression>
-
- Notes:
- - We allow more options in addition to <set quantifier>
- - <table expression> is optional in MariaDB
-*/
-query_specification:
- SELECT_SYM select_init2_derived opt_table_expression
- {
- $$= Lex->current_select->master_unit()->first_select();
- }
- ;
-
-query_term_union_not_ready:
- query_specification order_or_limit opt_select_lock_type { $$= $1; }
- | '(' select_paren_derived ')' union_order_or_limit { $$= $2; }
- ;
-
-query_term_union_ready:
- query_specification opt_select_lock_type { $$= $1; }
- | '(' select_paren_derived ')' { $$= $2; }
- ;
-
-query_expression_body:
- query_term_union_not_ready { $$= $1; }
- | query_term_union_ready { $$= $1; }
- | query_term_union_ready union_list_derived { $$= $1; }
- ;
-
-/* Corresponds to <query expression> in the SQL:2003 standard. */
-subselect:
- subselect_start opt_with_clause query_expression_body subselect_end
- {
- $3->set_with_clause($2);
- $$= $3;
- }
- ;
-
-subselect_start:
- {
- LEX *lex=Lex;
- if (!lex->expr_allows_subselect ||
- lex->sql_command == (int)SQLCOM_PURGE)
- {
- thd->parse_error();
- MYSQL_YYABORT;
- }
- /*
- we are making a "derived table" for the parenthesis
- as we need to have a lex level to fit the union
- after the parenthesis, e.g.
- (SELECT .. ) UNION ... becomes
- SELECT * FROM ((SELECT ...) UNION ...)
- */
- if (mysql_new_select(Lex, 1, NULL))
- MYSQL_YYABORT;
- }
- ;
-
-subselect_end:
- {
- LEX *lex=Lex;
-
- lex->check_automatic_up(UNSPECIFIED_TYPE);
- lex->pop_context();
- SELECT_LEX *child= lex->current_select;
- lex->current_select = lex->current_select->return_after_parsing();
- lex->nest_level--;
- lex->current_select->n_child_sum_items += child->n_sum_items;
- /*
- A subselect can add fields to an outer select. Reserve space for
- them.
- */
- lex->current_select->select_n_where_fields+=
- child->select_n_where_fields;
-
- /*
- Aggregate functions in having clause may add fields to an outer
- select. Count them also.
- */
- lex->current_select->select_n_having_items+=
- child->select_n_having_items;
- }
- ;
-
-opt_query_expression_options:
- /* empty */
- | query_expression_option_list
- ;
-
-query_expression_option_list:
- query_expression_option_list query_expression_option
- | query_expression_option
- ;
-
query_expression_option:
STRAIGHT_JOIN { Select->options|= SELECT_STRAIGHT_JOIN; }
| HIGH_PRIORITY
{
- if (check_simple_select())
- MYSQL_YYABORT;
YYPS->m_lock_type= TL_READ_HIGH_PRIORITY;
YYPS->m_mdl_type= MDL_SHARED_READ;
Select->options|= SELECT_HIGH_PRIORITY;
@@ -16996,18 +17293,8 @@ query_expression_option:
| UNIQUE_SYM { Select->options|= SELECT_DISTINCT; }
| SQL_SMALL_RESULT { Select->options|= SELECT_SMALL_RESULT; }
| SQL_BIG_RESULT { Select->options|= SELECT_BIG_RESULT; }
- | SQL_BUFFER_RESULT
- {
- if (check_simple_select())
- MYSQL_YYABORT;
- Select->options|= OPTION_BUFFER_RESULT;
- }
- | SQL_CALC_FOUND_ROWS
- {
- if (check_simple_select())
- MYSQL_YYABORT;
- Select->options|= OPTION_FOUND_ROWS;
- }
+ | SQL_BUFFER_RESULT { Select->options|= OPTION_BUFFER_RESULT; }
+ | SQL_CALC_FOUND_ROWS { Select->options|= OPTION_FOUND_ROWS; }
| ALL { Select->options|= SELECT_ALL; }
;
@@ -17095,32 +17382,28 @@ view_select:
lex->parsing_options.allows_variable= FALSE;
lex->create_view->select.str= (char *) YYLIP->get_cpp_ptr();
}
- opt_with_clause query_expression_body_view view_check_option
+ query_expression
+ view_check_option
{
LEX *lex= Lex;
+ SQL_I_List<TABLE_LIST> *save= &lex->first_select_lex()->table_list;
+ lex->set_main_unit($2);
+ if (lex->check_main_unit_semantics())
+ MYSQL_YYABORT;
+ lex->first_select_lex()->table_list.push_front(save);
+ lex->current_select= Lex->first_select_lex();
size_t len= YYLIP->get_cpp_ptr() - lex->create_view->select.str;
void *create_view_select= thd->memdup(lex->create_view->select.str, len);
lex->create_view->select.length= len;
lex->create_view->select.str= (char *) create_view_select;
+ size_t not_used;
trim_whitespace(thd->charset(),
- &lex->create_view->select);
- lex->create_view->check= $4;
+ &lex->create_view->select, ¬_used);
+ lex->create_view->check= $3;
lex->parsing_options.allows_variable= TRUE;
- lex->current_select->set_with_clause($2);
}
;
-/*
- SQL Standard <query expression body> for VIEWs.
- Does not include INTO and PROCEDURE clauses.
-*/
-query_expression_body_view:
- SELECT_SYM select_options_and_item_list select_init3_view
- | '(' select_paren_view ')'
- | '(' select_paren_view ')' union_order_or_limit
- | '(' select_paren_view ')' union_list_view
- ;
-
view_check_option:
/* empty */ { $$= VIEW_CHECK_NONE; }
| WITH CHECK_SYM OPTION { $$= VIEW_CHECK_CASCADED; }
@@ -17221,11 +17504,11 @@ trigger_tail:
sp_proc_stmt alternatives are not saving/restoring LEX, so
lex->query_tables can be wiped out.
*/
- if (!lex->select_lex.add_table_to_list(thd, $10,
- (LEX_CSTRING*) 0,
- TL_OPTION_UPDATING,
- TL_READ_NO_INSERT,
- MDL_SHARED_NO_WRITE))
+ if (!lex->builtin_select.add_table_to_list(thd, $10,
+ (LEX_CSTRING*) 0,
+ TL_OPTION_UPDATING,
+ TL_READ_NO_INSERT,
+ MDL_SHARED_NO_WRITE))
MYSQL_YYABORT;
}
;
diff --git a/sql/structs.h b/sql/structs.h
index 01d99517fed..19c2405e75d 100644
--- a/sql/structs.h
+++ b/sql/structs.h
@@ -759,6 +759,59 @@ struct Lex_string_with_pos_st: public LEX_CSTRING
const char *m_pos;
};
+class Lex_select_lock
+{
+public:
+ struct
+ {
+ uint defined_lock:1;
+ uint update_lock:1;
+ uint defined_timeout:1;
+ };
+ ulong timeout;
+
+
+ void empty()
+ {
+ defined_lock= update_lock= defined_timeout= FALSE;
+ timeout= 0;
+ }
+};
+
+class Lex_select_limit
+{
+public:
+ bool explicit_limit;
+ Item *select_limit, *offset_limit;
+
+ void empty()
+ {
+ explicit_limit= FALSE;
+ select_limit= offset_limit= NULL;
+ }
+};
+
+struct st_order;
+class st_select_lex;
+
+/**
+ ORDER BY ... LIMIT parameters;
+*/
+class Lex_order_limit_lock
+{
+public:
+ SQL_I_List<st_order> *order_list; /* ORDER clause */
+ Lex_select_lock lock;
+ Lex_select_limit limit;
+
+ static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
+ { return alloc_root(mem_root, size); }
+ Lex_order_limit_lock() :order_list(NULL)
+ {}
+
+ bool set_to(st_select_lex *sel);
+};
+
class Load_data_param
{
diff --git a/sql/table.cc b/sql/table.cc
index cb3eb068e68..116d5bb135b 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -2689,7 +2689,7 @@ static bool sql_unusable_for_discovery(THD *thd, handlerton *engine,
if (lex->create_info.like())
return 1;
// ... create select
- if (lex->select_lex.item_list.elements)
+ if (lex->first_select_lex()->item_list.elements)
return 1;
// ... temporary
if (create_info->tmp_table())
@@ -4938,13 +4938,13 @@ bool TABLE_LIST::single_table_updatable()
{
if (!updatable)
return false;
- if (view && view->select_lex.table_list.elements == 1)
+ if (view && view->first_select_lex()->table_list.elements == 1)
{
/*
We need to check deeply only single table views. Multi-table views
will be turned to multi-table updates and then checked by leaf tables
*/
- return (((TABLE_LIST *)view->select_lex.table_list.first)->
+ return (((TABLE_LIST *)view->first_select_lex()->table_list.first)->
single_table_updatable());
}
return true;
@@ -4981,7 +4981,8 @@ merge_on_conds(THD *thd, TABLE_LIST *table, bool is_cascaded)
cond= table->on_expr->copy_andor_structure(thd);
if (!table->view)
DBUG_RETURN(cond);
- for (TABLE_LIST *tbl= (TABLE_LIST*)table->view->select_lex.table_list.first;
+ for (TABLE_LIST *tbl=
+ (TABLE_LIST*)table->view->first_select_lex()->table_list.first;
tbl;
tbl= tbl->next_local)
{
@@ -5023,7 +5024,7 @@ bool TABLE_LIST::prep_check_option(THD *thd, uint8 check_opt_type)
{
DBUG_ENTER("TABLE_LIST::prep_check_option");
bool is_cascaded= check_opt_type == VIEW_CHECK_CASCADED;
- TABLE_LIST *merge_underlying_list= view->select_lex.get_table_list();
+ TABLE_LIST *merge_underlying_list= view->first_select_lex()->get_table_list();
for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
{
/* see comment of check_opt_type parameter */
@@ -5145,7 +5146,7 @@ TABLE_LIST *TABLE_LIST::find_underlying_table(TABLE *table_to_find)
if (!view)
return 0;
- for (TABLE_LIST *tbl= view->select_lex.get_table_list();
+ for (TABLE_LIST *tbl= view->first_select_lex()->get_table_list();
tbl;
tbl= tbl->next_local)
{
@@ -5316,7 +5317,8 @@ bool TABLE_LIST::set_insert_values(MEM_ROOT *mem_root)
{
DBUG_PRINT("info", ("setting insert_value for view"));
DBUG_ASSERT(is_view_or_derived() && is_merged_derived());
- for (TABLE_LIST *tbl= (TABLE_LIST*)view->select_lex.table_list.first;
+ for (TABLE_LIST *tbl=
+ (TABLE_LIST*)view->first_select_lex()->table_list.first;
tbl;
tbl= tbl->next_local)
if (tbl->set_insert_values(mem_root))
@@ -5483,7 +5485,7 @@ void TABLE_LIST::register_want_access(ulong want_access)
}
if (!view)
return;
- for (TABLE_LIST *tbl= view->select_lex.get_table_list();
+ for (TABLE_LIST *tbl= view->first_select_lex()->get_table_list();
tbl;
tbl= tbl->next_local)
tbl->register_want_access(want_access);
@@ -5675,6 +5677,7 @@ void TABLE_LIST::set_check_materialized()
The subtree should be already excluded
*/
DBUG_ASSERT(!derived->first_select()->first_inner_unit() ||
+ derived->first_select()->first_inner_unit()->with_element ||
derived->first_select()->first_inner_unit()->first_select()->
exclude_from_table_unique_test);
}
@@ -5691,14 +5694,14 @@ TABLE *TABLE_LIST::get_real_join_table()
break;
/* we do not support merging of union yet */
DBUG_ASSERT(tbl->view == NULL ||
- tbl->view->select_lex.next_select() == NULL);
+ tbl->view->first_select_lex()->next_select() == NULL);
DBUG_ASSERT(tbl->derived == NULL ||
tbl->derived->first_select()->next_select() == NULL);
{
List_iterator_fast<TABLE_LIST>
ti(tbl->view != NULL ?
- tbl->view->select_lex.top_join_list :
+ tbl->view->first_select_lex()->top_join_list :
tbl->derived->first_select()->top_join_list);
for (;;)
{
@@ -5869,7 +5872,7 @@ Item *Field_iterator_view::create_item(THD *thd)
Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref,
LEX_CSTRING *name)
{
- bool save_wrapper= thd->lex->select_lex.no_wrap_view_item;
+ bool save_wrapper= thd->lex->first_select_lex()->no_wrap_view_item;
Item *field= *field_ref;
DBUG_ENTER("create_view_field");
@@ -5900,8 +5903,9 @@ Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref,
{
DBUG_RETURN(field);
}
- Name_resolution_context *context= view->view ? &view->view->select_lex.context :
- &thd->lex->select_lex.context;
+ Name_resolution_context *context= (view->view ?
+ &view->view->first_select_lex()->context:
+ &thd->lex->first_select_lex()->context);
Item *item= (new (thd->mem_root)
Item_direct_view_ref(thd, context, field_ref, view->alias.str,
name, view));
@@ -8424,7 +8428,7 @@ bool TR_table::query(ulonglong trx_id)
READ_RECORD info;
int error;
List<TABLE_LIST> dummy;
- SELECT_LEX &slex= thd->lex->select_lex;
+ SELECT_LEX &slex= *(thd->lex->first_select_lex());
Name_resolution_context_backup backup(slex.context, *this);
Item *field= newx Item_field(thd, &slex.context, (*this)[FLD_TRX_ID]);
Item *value= newx Item_int(thd, trx_id);
@@ -8454,7 +8458,7 @@ bool TR_table::query(MYSQL_TIME &commit_time, bool backwards)
READ_RECORD info;
int error;
List<TABLE_LIST> dummy;
- SELECT_LEX &slex= thd->lex->select_lex;
+ SELECT_LEX &slex= *(thd->lex->first_select_lex());
Name_resolution_context_backup backup(slex.context, *this);
Item *field= newx Item_field(thd, &slex.context, (*this)[FLD_COMMIT_TS]);
Item *value= newx Item_datetime_literal(thd, &commit_time, 6);
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index def52cb2675..4f9ff51eaf7 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -1329,7 +1329,7 @@ static int
create_view_query(THD *thd, uchar** buf, size_t* buf_len)
{
LEX *lex= thd->lex;
- SELECT_LEX *select_lex= &lex->select_lex;
+ SELECT_LEX *select_lex= lex->first_select_lex();
TABLE_LIST *first_table= select_lex->table_list.first;
TABLE_LIST *views = first_table;
LEX_USER *definer;
@@ -1421,7 +1421,7 @@ static bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table,
DBUG_ASSERT(table_list || db);
LEX* lex= thd->lex;
- SELECT_LEX* select_lex= &lex->select_lex;
+ SELECT_LEX* select_lex= lex->first_select_lex();
TABLE_LIST* first_table= select_lex->table_list.first;
switch (lex->sql_command)
diff --git a/storage/mroonga/ha_mroonga.cpp b/storage/mroonga/ha_mroonga.cpp
index 55c6b5d330e..cf486c199b3 100644
--- a/storage/mroonga/ha_mroonga.cpp
+++ b/storage/mroonga/ha_mroonga.cpp
@@ -193,7 +193,7 @@ static mysql_mutex_t *mrn_LOCK_open;
#if MYSQL_VERSION_ID >= 50706 && !defined(MRN_MARIADB_P)
# define MRN_LEX_GET_TABLE_LIST(lex) (lex)->select_lex->table_list.first
#else
-# define MRN_LEX_GET_TABLE_LIST(lex) (lex)->select_lex.table_list.first
+# define MRN_LEX_GET_TABLE_LIST(lex) (lex)->first_select_lex()->table_list.first
#endif
#if MYSQL_VERSION_ID >= 50706 && !defined(MRN_MARIADB_P)
diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc
index 6ff2e25bc27..b8463adcfef 100644
--- a/storage/spider/spd_db_mysql.cc
+++ b/storage/spider/spd_db_mysql.cc
@@ -7217,7 +7217,7 @@ int spider_mysql_handler::append_select(
if (result_list->lock_type != F_WRLCK && spider->lock_mode < 1)
{
/* no lock */
- st_select_lex *select_lex = &spider->trx->thd->lex->select_lex;
+ st_select_lex *select_lex = spider->trx->thd->lex->first_select_lex();
if (
select_lex->sql_cache == SELECT_LEX::SQL_CACHE &&
(spider->share->query_cache_sync & 1)
diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc
index 76032ca80f0..48d29602bf2 100644
--- a/storage/spider/spd_table.cc
+++ b/storage/spider/spd_table.cc
@@ -9077,8 +9077,14 @@ int spider_set_direct_limit_offset(
)
DBUG_RETURN(FALSE);
+ /*
+ TODO: following comment is wrong or the check is wrong (correct
+ check for derived table will be something like select_lex->linkage,
+ if they need only top level it is better to check nested level and do
+ not loose UNIONS & Co
+ */
// must not be derived table
- if (&thd->lex->select_lex != select_lex)
+ if (thd->lex->first_select_lex() != select_lex)
DBUG_RETURN(FALSE);
spider->direct_select_offset = offset_limit;
diff --git a/storage/tokudb/tokudb_dir_cmd.cc b/storage/tokudb/tokudb_dir_cmd.cc
index 5431cbab7aa..d0da92eab27 100644
--- a/storage/tokudb/tokudb_dir_cmd.cc
+++ b/storage/tokudb/tokudb_dir_cmd.cc
@@ -50,11 +50,11 @@ static int MDL_and_TDC(THD *thd,
table_arg.str = const_cast<char *>(table);
table_arg.length = strlen(table);
Table_ident table_ident(thd, &db_arg, &table_arg, true);;
- thd->lex->select_lex.add_table_to_list(
+ thd->lex->first_select_lex()->add_table_to_list(
thd, &table_ident, NULL, 1, TL_UNLOCK, MDL_EXCLUSIVE, 0, 0, 0);
/* The lock will be released at the end of mysq_execute_command() */
error = lock_table_names(thd,
- thd->lex->select_lex.table_list.first,
+ thd->lex->first_select_lex()->table_list.first,
NULL,
thd->variables.lock_wait_timeout,
0);
1
0
[Commits] f07e70d: MDEV-12439: MariaRocks produces numerous (spurious?) valgrind failures
by psergey@askmonty.org 22 May '18
by psergey@askmonty.org 22 May '18
22 May '18
revision-id: f07e70d91426c504df32df0ec7e1f121b742c2c9
parent(s): 31584c8bb8204b27626fae0127eff4889b8f4383
committer: Sergei Petrunia
branch nick: 10.2-r12
timestamp: 2018-05-22 19:36:51 +0300
message:
MDEV-12439: MariaRocks produces numerous (spurious?) valgrind failures
Step#1: RocksDB files require a special #define when they are compiled
with valgrind. Without that, valgrind fails with an 'unimplemented syscall'
error for fcntl call.
---
storage/rocksdb/CMakeLists.txt | 3 +++
1 file changed, 3 insertions(+)
diff --git a/storage/rocksdb/CMakeLists.txt b/storage/rocksdb/CMakeLists.txt
index 2821b74..2a4ea4d 100644
--- a/storage/rocksdb/CMakeLists.txt
+++ b/storage/rocksdb/CMakeLists.txt
@@ -19,6 +19,9 @@ IF(HAVE_SCHED_GETCPU)
ADD_DEFINITIONS(-DHAVE_SCHED_GETCPU=1 -DROCKSDB_SCHED_GETCPU_PRESENT)
ENDIF()
+IF(WITH_VALGRIND)
+ ADD_DEFINITIONS(-DROCKSDB_VALGRIND_RUN=1)
+ENDIF()
# We've had our builders hang during the build process. This prevents MariaRocks
# to be built on 32 bit intel OS kernels.
1
0
[Commits] 6f3c27eb59a: MDEV-13727 top-level query timestamp reset at stored func/trigger internal statements
by andrei.elkin@pp.inet.fi 22 May '18
by andrei.elkin@pp.inet.fi 22 May '18
22 May '18
revision-id: 6f3c27eb59a04041e4dbbeae8231c0aafdc967e5 (mariadb-10.3.6-102-g6f3c27eb59a)
parent(s): 73a10cbcc5178ae5378abb821428d35d3276b4da
author: Andrei Elkin
committer: Andrei Elkin
timestamp: 2018-05-22 09:38:14 +0300
message:
MDEV-13727 top-level query timestamp reset at stored func/trigger internal statements
Being executed under slow_log is ON the test revealed a "side-effect"
in MDEV-8305 implementation which inadvertently made the trigger or
stored function statements to reset the top-level query's
THD::start_time et al. (Details of the test failure analysis are footnoted).
Unlike the SP case the SF and Trigger's internal statement should not
do that.
Fixed with refining the MDEV-8305 decision to reset the session timestamp
with consulting the sub-statement type flag.
Timestamps related tests are extended to cover the trigger and stored function case.
Footnote:
--------
Specifically to the failing test, a query on the master was logged
okay with a timestamp of the query's top-level statement but its post
update trigger managed to compute one more (later) timestamp which got
inserted into another table. The latter table master-vs-slave
no fractional part timestamp discrepancy became evident
thanks to different execution time of the trigger combined with the
fact of the logged with micro-second fractional part master timestamp
was truncated on the slave. On master when the fractional part was
close to 1 the trigger execution added up its own latency to overflow
to next second value. That's how the master timestamp surprisingly
turned out to bigger than the slave's one.
---
mysql-test/main/func_time.result | 26 ++++++++++++++++++
mysql-test/main/func_time.test | 59 ++++++++++++++++++++++++++++++++++++++++
sql/sp_head.cc | 18 ++++++++++--
3 files changed, 100 insertions(+), 3 deletions(-)
diff --git a/mysql-test/main/func_time.result b/mysql-test/main/func_time.result
index 2772f850ce9..9babfc6a48b 100644
--- a/mysql-test/main/func_time.result
+++ b/mysql-test/main/func_time.result
@@ -3484,3 +3484,29 @@ t1 CREATE TABLE `t1` (
`c5` varchar(100) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
+CREATE TABLE t_ts (a timestamp(6));
+CREATE TABLE t_trig (a timestamp(6));
+CREATE FUNCTION fn_sleep_before_now() returns int
+BEGIN
+INSERT INTO t_ts SET a= current_timestamp(6);
+RETURN 0;
+END//
+CREATE TRIGGER trg_insert_t_ts after INSERT on t_ts for each row
+BEGIN
+INSERT into t_trig set a= current_timestamp(6);
+END//
+SET @sav_slow_query_log= @@session.slow_query_log;
+SET @@session.slow_query_log= ON;
+SELECT current_timestamp(6),fn_sleep_before_now() INTO @ts_cur, @ts_func;
+SELECT a FROM t_ts LIMIT 1 into @ts_func;
+SELECT a FROM t_trig LIMIT 1 into @ts_trig;
+DELETE FROM t_ts;
+DELETE FROM t_trig;
+SET @@session.slow_query_log= OFF;
+SELECT current_timestamp(6),fn_sleep_before_now() INTO @ts_cur, @func_ts;
+SELECT a FROM t_ts LIMIT 1 into @ts_func;
+SELECT a FROM t_trig LIMIT 1 into @ts_trig;
+SET @@session.slow_query_log= @sav_slow_query_log;
+DROP FUNCTION fn_sleep_before_now;
+DROP TRIGGER trg_insert_t_ts;
+DROP TABLE t_ts, t_trig;
diff --git a/mysql-test/main/func_time.test b/mysql-test/main/func_time.test
index 5417cb20a92..ad207218969 100644
--- a/mysql-test/main/func_time.test
+++ b/mysql-test/main/func_time.test
@@ -2057,3 +2057,62 @@ EXECUTE IMMEDIATE
USING NULL, '10', 10, 10.0, 10e0, TIME'10:20:30';
SHOW CREATE TABLE t1;
DROP TABLE t1;
+
+
+############
+# MDEV-13727
+# Current timestamp functions inside stored functions must return the
+# value of the top-level statement's timestamp (its start time).
+# This must hold regardless of @@slow_query_log option.
+#
+
+CREATE TABLE t_ts (a timestamp(6));
+CREATE TABLE t_trig (a timestamp(6));
+delimiter //;
+CREATE FUNCTION fn_sleep_before_now() returns int
+BEGIN
+ INSERT INTO t_ts SET a= current_timestamp(6);
+ RETURN 0;
+END//
+CREATE TRIGGER trg_insert_t_ts after INSERT on t_ts for each row
+BEGIN
+ INSERT into t_trig set a= current_timestamp(6);
+END//
+delimiter ;//
+
+SET @sav_slow_query_log= @@session.slow_query_log;
+
+# @@slow_query_log ON check
+SET @@session.slow_query_log= ON;
+SELECT current_timestamp(6),fn_sleep_before_now() INTO @ts_cur, @ts_func;
+
+SELECT a FROM t_ts LIMIT 1 into @ts_func;
+SELECT a FROM t_trig LIMIT 1 into @ts_trig;
+if (!`SELECT @ts_cur = @ts_func and @ts_func = @ts_trig`)
+{
+ SELECT @ts_cur, @ts_func, @ts_trig;
+ --die Error: timestamps must be equal but they diverge
+}
+DELETE FROM t_ts;
+DELETE FROM t_trig;
+
+# @@slow_query_log OFF check
+SET @@session.slow_query_log= OFF;
+SELECT current_timestamp(6),fn_sleep_before_now() INTO @ts_cur, @func_ts;
+SELECT a FROM t_ts LIMIT 1 into @ts_func;
+SELECT a FROM t_trig LIMIT 1 into @ts_trig;
+if (!`SELECT @ts_cur = @ts_func and @ts_func = @ts_trig`)
+{
+ SELECT @ts_cur, @ts_func, @ts_trig;
+ --die Error: timestamps must be equal but they diverge
+}
+
+# Cleanup
+SET @@session.slow_query_log= @sav_slow_query_log;
+DROP FUNCTION fn_sleep_before_now;
+DROP TRIGGER trg_insert_t_ts;
+DROP TABLE t_ts, t_trig;
+
+#
+# End of MDEV-13727
+###################
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index edaa4de942e..c5c69bc8614 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1690,6 +1690,9 @@ sp_head::execute_trigger(THD *thd,
MEM_ROOT call_mem_root;
Query_arena call_arena(&call_mem_root, Query_arena::STMT_INITIALIZED_FOR_SP);
Query_arena backup_arena;
+ // Alternative MDEV-13727 fixes
+ // bool save_enable_slow_log;
+
DBUG_ENTER("sp_head::execute_trigger");
DBUG_PRINT("info", ("trigger %s", m_name.str));
@@ -1758,8 +1761,10 @@ sp_head::execute_trigger(THD *thd,
}
thd->spcont= nctx;
-
+ // save_enable_slow_log= thd->enable_slow_log;
+ // thd->enable_slow_log= false;
err_status= execute(thd, FALSE);
+ // thd->enable_slow_log= save_enable_slow_log;
err_with_cleanup:
thd->restore_active_arena(&call_arena, &backup_arena);
@@ -3476,7 +3481,14 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
thd->profiling.set_query_source(m_query.str, m_query.length);
#endif
- if ((save_enable_slow_log= thd->enable_slow_log))
+ // Todo: remove upon review
+ // Fixme: alternatively `thd->enable_slow_log' could be set to `false'
+ // by grand-caller similarly to how it's done to the SP case
+ // by
+ // commit 21518ab2e4538e1a6c9b3a136a93885a98492218
+ // Author: Monty <monty(a)mariadb.org>
+ // Date: Fri Jul 21 19:56:41 2017 +0300
+ if ((save_enable_slow_log= thd->enable_slow_log) && !thd->in_sub_stmt)
{
/*
Save start time info for the CALL statement and overwrite it with the
@@ -3549,7 +3561,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
}
}
/* Restore the original query start time */
- if (thd->enable_slow_log)
+ if (thd->enable_slow_log && !thd->in_sub_stmt)
thd->restore_query_start_time(&time_info);
DBUG_RETURN(res || thd->is_error());
1
0
[Commits] 0768dcbbde5: MDEV-13727 top-level query timestamp reset at stored func/trigger internal statements
by andrei.elkin@pp.inet.fi 21 May '18
by andrei.elkin@pp.inet.fi 21 May '18
21 May '18
revision-id: 0768dcbbde546a4665e9607b2de3509b995c2b14 (mariadb-10.3.6-103-g0768dcbbde5)
parent(s): 1d296fa18a875248a91ba03f1e84c497223cfd33
author: Andrei Elkin
committer: Andrei Elkin
timestamp: 2018-05-21 22:10:14 +0300
message:
MDEV-13727 top-level query timestamp reset at stored func/trigger internal statements
Being executed under slow_log is ON the test revealed a "side-effect"
in MDEV-8305 implementation which inadvertently made the trigger or
stored function statements to reset the top-level query's
THD::start_time et al. (Details of the test failure analysis are footnoted).
Unlike the SP case the SF and Trigger's internal statement should not
do that.
Fixed with refining the MDEV-8305 decision to reset the session timestamp
with consulting the sub-statement type flag.
Timestamps related tests are extended to cover the trigger and stored function case.
Footnote:
--------
Specifically to the failing test, a query on the master was logged
okay with a timestamp of the query's top-level statement but its post
update trigger managed to compute one more (later) timestamp which got
inserted into another table. The latter table master-vs-slave
no fractional part timestamp discrepancy became evident
thanks to different execution time of the trigger combined with the
fact of the logged with micro-second fractional part master timestamp
was truncated on the slave. On master when the fractional part was
close to 1 the trigger execution added up its own latency to overflow
to next second value. That's how the master timestamp surprisingly
turned out to bigger than the slave's one.
---
sql/sp_head.cc | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 1c1e11ab90c..c5c69bc8614 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1690,6 +1690,9 @@ sp_head::execute_trigger(THD *thd,
MEM_ROOT call_mem_root;
Query_arena call_arena(&call_mem_root, Query_arena::STMT_INITIALIZED_FOR_SP);
Query_arena backup_arena;
+ // Alternative MDEV-13727 fixes
+ // bool save_enable_slow_log;
+
DBUG_ENTER("sp_head::execute_trigger");
DBUG_PRINT("info", ("trigger %s", m_name.str));
@@ -1758,8 +1761,10 @@ sp_head::execute_trigger(THD *thd,
}
thd->spcont= nctx;
-
+ // save_enable_slow_log= thd->enable_slow_log;
+ // thd->enable_slow_log= false;
err_status= execute(thd, FALSE);
+ // thd->enable_slow_log= save_enable_slow_log;
err_with_cleanup:
thd->restore_active_arena(&call_arena, &backup_arena);
@@ -3476,6 +3481,13 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
thd->profiling.set_query_source(m_query.str, m_query.length);
#endif
+ // Todo: remove upon review
+ // Fixme: alternatively `thd->enable_slow_log' could be set to `false'
+ // by grand-caller similarly to how it's done to the SP case
+ // by
+ // commit 21518ab2e4538e1a6c9b3a136a93885a98492218
+ // Author: Monty <monty(a)mariadb.org>
+ // Date: Fri Jul 21 19:56:41 2017 +0300
if ((save_enable_slow_log= thd->enable_slow_log) && !thd->in_sub_stmt)
{
/*
1
0
[Commits] 223ff38: MDEV-16033: rocksdb.deadlock fails in buildbot with timeout
by psergey@askmonty.org 21 May '18
by psergey@askmonty.org 21 May '18
21 May '18
revision-id: 223ff38cd2ad19727f067869d2824cbada97a8d0
parent(s): 31584c8bb8204b27626fae0127eff4889b8f4383
committer: Sergei Petrunia
branch nick: 10.2-r10
timestamp: 2018-05-21 20:25:38 +0300
message:
MDEV-16033: rocksdb.deadlock fails in buildbot with timeout
Update to recent version of RocksDB to include the fix
---
storage/rocksdb/build_rocksdb.cmake | 2 ++
storage/rocksdb/rocksdb | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/storage/rocksdb/build_rocksdb.cmake b/storage/rocksdb/build_rocksdb.cmake
index c76f711..5478b6b 100644
--- a/storage/rocksdb/build_rocksdb.cmake
+++ b/storage/rocksdb/build_rocksdb.cmake
@@ -179,6 +179,7 @@ set(ROCKSDB_SOURCES
db/internal_stats.cc
db/log_reader.cc
db/log_writer.cc
+ db/logs_with_prep_tracker.cc
db/malloc_stats.cc
db/managed_iterator.cc
db/memtable.cc
@@ -295,6 +296,7 @@ set(ROCKSDB_SOURCES
util/status_message.cc
util/string_util.cc
util/sync_point.cc
+ util/sync_point_impl.cc
util/testutil.cc
util/thread_local.cc
util/threadpool_imp.cc
diff --git a/storage/rocksdb/rocksdb b/storage/rocksdb/rocksdb
index ba295cd..46fde6b 160000
--- a/storage/rocksdb/rocksdb
+++ b/storage/rocksdb/rocksdb
@@ -1 +1 @@
-Subproject commit ba295cda29daee3ffe58549542804efdfd969784
+Subproject commit 46fde6b65336c5e176d347b80422fd5f6a7ae7c2
1
0
[Commits] 4b2d2b3: MDEV-16033: rocksdb.deadlock fails in buildbot with timeout
by psergey@askmonty.org 21 May '18
by psergey@askmonty.org 21 May '18
21 May '18
revision-id: 4b2d2b3fb20f43516310298be5b03aa7cdb35e7e
parent(s): 31584c8bb8204b27626fae0127eff4889b8f4383
committer: Sergei Petrunia
branch nick: 10.2-r10
timestamp: 2018-05-21 20:16:17 +0300
message:
MDEV-16033: rocksdb.deadlock fails in buildbot with timeout
Update to recent version of RocksDB to include the fix
---
storage/rocksdb/rocksdb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/storage/rocksdb/rocksdb b/storage/rocksdb/rocksdb
index ba295cd..46fde6b 160000
--- a/storage/rocksdb/rocksdb
+++ b/storage/rocksdb/rocksdb
@@ -1 +1 @@
-Subproject commit ba295cda29daee3ffe58549542804efdfd969784
+Subproject commit 46fde6b65336c5e176d347b80422fd5f6a7ae7c2
1
0
21 May '18
revision-id: 31584c8bb8204b27626fae0127eff4889b8f4383
parent(s): 36043c58f518be7ace35bd2e2c00a8d769f9c4c5
committer: Sergei Petrunia
branch nick: 10.2-r11
timestamp: 2018-05-21 13:43:50 +0300
message:
Set MyRocks plugin version to Stable
---
storage/rocksdb/ha_rocksdb.h | 2 +-
.../mysql-test/rocksdb/r/mariadb_port_fixes.result | 26 +++++++++++-----------
2 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/storage/rocksdb/ha_rocksdb.h b/storage/rocksdb/ha_rocksdb.h
index 5f3d979..739a2c8 100644
--- a/storage/rocksdb/ha_rocksdb.h
+++ b/storage/rocksdb/ha_rocksdb.h
@@ -1473,7 +1473,7 @@ struct Rdb_inplace_alter_ctx : public my_core::inplace_alter_handler_ctx {
// file name indicating RocksDB data corruption
std::string rdb_corruption_marker_file_name();
-const int MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL= MariaDB_PLUGIN_MATURITY_GAMMA;
+const int MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL= MariaDB_PLUGIN_MATURITY_STABLE;
extern bool prevent_myrocks_loading;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result
index e9fe026..d9e2bf5 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result
@@ -69,19 +69,19 @@ set global rocksdb_strict_collation_check=@tmp_rscc;
#
select plugin_name, plugin_maturity from information_schema.plugins where plugin_name like '%rocksdb%';
plugin_name plugin_maturity
-ROCKSDB Gamma
-ROCKSDB_CFSTATS Gamma
-ROCKSDB_DBSTATS Gamma
-ROCKSDB_PERF_CONTEXT Gamma
-ROCKSDB_PERF_CONTEXT_GLOBAL Gamma
-ROCKSDB_CF_OPTIONS Gamma
-ROCKSDB_COMPACTION_STATS Gamma
-ROCKSDB_GLOBAL_INFO Gamma
-ROCKSDB_DDL Gamma
-ROCKSDB_INDEX_FILE_MAP Gamma
-ROCKSDB_LOCKS Gamma
-ROCKSDB_TRX Gamma
-ROCKSDB_DEADLOCK Gamma
+ROCKSDB Stable
+ROCKSDB_CFSTATS Stable
+ROCKSDB_DBSTATS Stable
+ROCKSDB_PERF_CONTEXT Stable
+ROCKSDB_PERF_CONTEXT_GLOBAL Stable
+ROCKSDB_CF_OPTIONS Stable
+ROCKSDB_COMPACTION_STATS Stable
+ROCKSDB_GLOBAL_INFO Stable
+ROCKSDB_DDL Stable
+ROCKSDB_INDEX_FILE_MAP Stable
+ROCKSDB_LOCKS Stable
+ROCKSDB_TRX Stable
+ROCKSDB_DEADLOCK Stable
#
# MDEV-12466 : Assertion `thd->transaction.stmt.is_empty() || thd->in_sub_stmt || ...
#
1
0
[Commits] dd51082: MDEV-12465: Server crashes in my_scan_weight_utf8_bin upon collecting stats for RocksDB table
by psergey@askmonty.org 18 May '18
by psergey@askmonty.org 18 May '18
18 May '18
revision-id: dd51082eca82fe7b61ee2e62f75b84c39f180450
parent(s): 06aaaef51a90cf21f9361ca6901cfc1ab854e5b9
committer: Sergei Petrunia
branch nick: 10.2-r11
timestamp: 2018-05-19 00:26:35 +0300
message:
MDEV-12465: Server crashes in my_scan_weight_utf8_bin upon collecting stats for RocksDB table
Apply patch by Oleksandr Byelkin:
Do not use "only index read" in analyzing indices if there is a field which present in the index only partially.
---
sql/sql_statistics.cc | 14 ++++++++++--
.../mysql-test/rocksdb/r/analyze_table.result | 26 ++++++++++++++++++++++
.../mysql-test/rocksdb/t/analyze_table.test | 26 ++++++++++++++++++++++
3 files changed, 64 insertions(+), 2 deletions(-)
diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc
index 0194746..903ebb9 100644
--- a/sql/sql_statistics.cc
+++ b/sql/sql_statistics.cc
@@ -1801,6 +1801,7 @@ class Index_prefix_calc: public Sql_alloc
public:
bool is_single_comp_pk;
+ bool is_partial_fields_present;
Index_prefix_calc(THD *thd, TABLE *table, KEY *key_info)
: index_table(table), index_info(key_info)
@@ -1812,7 +1813,7 @@ class Index_prefix_calc: public Sql_alloc
prefixes= 0;
LINT_INIT_STRUCT(calc_state);
- is_single_comp_pk= FALSE;
+ is_partial_fields_present= is_single_comp_pk= FALSE;
uint pk= table->s->primary_key;
if ((uint) (table->key_info - key_info) == pk &&
table->key_info[pk].user_defined_key_parts == 1)
@@ -1834,7 +1835,10 @@ class Index_prefix_calc: public Sql_alloc
calculating the values of 'avg_frequency' for prefixes.
*/
if (!key_info->key_part[i].field->part_of_key.is_set(keyno))
+ {
+ is_partial_fields_present= TRUE;
break;
+ }
if (!(state->last_prefix=
new (thd->mem_root) Cached_item_field(thd,
@@ -2633,7 +2637,13 @@ int collect_statistics_for_index(THD *thd, TABLE *table, uint index)
DBUG_RETURN(rc);
}
- table->file->ha_start_keyread(index);
+ /*
+ Request "only index read" in case of absence of fields which are
+ partially in the index to avoid problems with partitioning (for example)
+ which want to get whole field value.
+ */
+ if (!index_prefix_calc.is_partial_fields_present)
+ table->file->ha_start_keyread(index);
table->file->ha_index_init(index, TRUE);
rc= table->file->ha_index_first(table->record[0]);
while (rc != HA_ERR_END_OF_FILE)
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/analyze_table.result b/storage/rocksdb/mysql-test/rocksdb/r/analyze_table.result
index ff29732..b666a17 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/analyze_table.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/analyze_table.result
@@ -27,3 +27,29 @@ ANALYZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
DROP TABLE t1;
+#
+# MDEV-12465: Server crashes in my_scan_weight_utf8_bin upon
+# collecting stats for RocksDB table
+#
+CREATE TABLE t1 (
+pk INT,
+f1 CHAR(255),
+f2 TEXT,
+f3 VARCHAR(255),
+f4 TEXT,
+PRIMARY KEY (pk),
+KEY (f4(255))
+) ENGINE=RocksDB
+CHARSET utf8
+COLLATE utf8_bin
+PARTITION BY KEY (pk) PARTITIONS 2;
+INSERT INTO t1 VALUES
+(1,'foo','bar','foo','bar'), (2,'bar','foo','bar','foo');
+ANALYZE TABLE t1 PERSISTENT FOR ALL;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze Warning Engine-independent statistics are not collected for column 'f2'
+test.t1 analyze Warning Engine-independent statistics are not collected for column 'f4'
+test.t1 analyze status OK
+drop table t1;
+# End of 10.2 tests
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/analyze_table.test b/storage/rocksdb/mysql-test/rocksdb/t/analyze_table.test
index 1072219..b24398b 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/analyze_table.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/analyze_table.test
@@ -1,4 +1,5 @@
--source include/have_rocksdb.inc
+--source include/have_partition.inc
#
# ANALYZE TABLE statements
@@ -29,3 +30,28 @@ INSERT INTO t1 VALUES (5,8),(6,10),(7,11),(8,12);
ANALYZE TABLE t1;
DROP TABLE t1;
+--echo #
+--echo # MDEV-12465: Server crashes in my_scan_weight_utf8_bin upon
+--echo # collecting stats for RocksDB table
+--echo #
+
+CREATE TABLE t1 (
+ pk INT,
+ f1 CHAR(255),
+ f2 TEXT,
+ f3 VARCHAR(255),
+ f4 TEXT,
+ PRIMARY KEY (pk),
+ KEY (f4(255))
+) ENGINE=RocksDB
+ CHARSET utf8
+ COLLATE utf8_bin
+ PARTITION BY KEY (pk) PARTITIONS 2;
+INSERT INTO t1 VALUES
+(1,'foo','bar','foo','bar'), (2,'bar','foo','bar','foo');
+
+ANALYZE TABLE t1 PERSISTENT FOR ALL;
+
+drop table t1;
+
+--echo # End of 10.2 tests
1
0
[Commits] 06aaaef: MDEV-16200: -DPLUGIN_ROCKSDB=YES leads to errors during build
by psergey@askmonty.org 18 May '18
by psergey@askmonty.org 18 May '18
18 May '18
revision-id: 06aaaef51a90cf21f9361ca6901cfc1ab854e5b9
parent(s): 727d0d4f9bd0d5df04ebca3c67cb33405f221c38
committer: Sergei Petrunia
branch nick: 10.2-r11
timestamp: 2018-05-18 23:58:24 +0300
message:
MDEV-16200: -DPLUGIN_ROCKSDB=YES leads to errors during build
Mark the plugin as dynamic-only.
---
storage/rocksdb/CMakeLists.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/storage/rocksdb/CMakeLists.txt b/storage/rocksdb/CMakeLists.txt
index 7156150..2821b74 100644
--- a/storage/rocksdb/CMakeLists.txt
+++ b/storage/rocksdb/CMakeLists.txt
@@ -104,7 +104,7 @@ SET(ROCKSDB_SE_SOURCES
#ADD_DEFINITIONS(-DROCKSDB_PLATFORM_POSIX -DROCKSDB_LIB_IO_POSIX
#)
-MYSQL_ADD_PLUGIN(rocksdb ${ROCKSDB_SE_SOURCES} STORAGE_ENGINE
+MYSQL_ADD_PLUGIN(rocksdb ${ROCKSDB_SE_SOURCES} MODULE_ONLY STORAGE_ENGINE
MODULE_OUTPUT_NAME ha_rocksdb
COMPONENT rocksdb-engine)
1
0