From 612267301f9261f309e9a6b4dc7dd2660ecbf12f Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 10 May 2016 11:48:01 +0400 Subject: [PATCH] MDEV-10036 sql_yacc.yy: Split select_part2 to disallow syntactically bad constructs with INTO, PROCEDURE, UNION MDEV-10037 UNION with LIMIT ROWS EXAMINED does not require parentheses --- mysql-test/r/limit_rows_examined.result | 6 +- mysql-test/r/parser.result | 29 +++++----- mysql-test/r/union.result | 23 ++++---- mysql-test/t/limit_rows_examined.test | 1 + mysql-test/t/parser.test | 28 ++++----- mysql-test/t/union.test | 22 ++++---- sql/sql_yacc.yy | 75 ++++++++++--------------- 7 files changed, 85 insertions(+), 99 deletions(-) diff --git a/mysql-test/r/limit_rows_examined.result b/mysql-test/r/limit_rows_examined.result index 318039db068..cce8ee5a8e2 100644 --- a/mysql-test/r/limit_rows_examined.result +++ b/mysql-test/r/limit_rows_examined.result @@ -173,10 +173,8 @@ Warning 1931 Query execution was interrupted. The query examined at least 8 rows select * from t1, t2 where c1 = c2 LIMIT ROWS EXAMINED 0 UNION select * from t1, t2 where c1 < c2 LIMIT ROWS EXAMINED 6; -c1 c2 -bb bb -Warnings: -Warning 1931 Query execution was interrupted. The query examined at least 8 rows, which exceeds LIMIT ROWS EXAMINED (6). The query result may be incomplete. +ERROR 42000: You 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 t1, t2 where c1 < c2 LIMIT ROWS EXAMINED 6' at line 2 (select * from t1, t2 where c1 = c2 LIMIT ROWS EXAMINED 0) UNION (select * from t1, t2 where c1 < c2 LIMIT ROWS EXAMINED 0) diff --git a/mysql-test/r/parser.result b/mysql-test/r/parser.result index 18a8e13815c..1a39bca40db 100644 --- a/mysql-test/r/parser.result +++ b/mysql-test/r/parser.result @@ -709,7 +709,8 @@ ERROR HY000: Incorrect usage of PROCEDURE and subquery SELECT 1 FROM DUAL PROCEDURE ANALYSE() UNION SELECT 1 FROM t1; -ERROR HY000: Incorrect usage of UNION and SELECT ... 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 'UNION +SELECT 1 FROM t1' at line 2 (SELECT 1 FROM t1) UNION (SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 @@ -739,10 +740,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 HY000: Incorrect usage of INTO and INTO +ERROR 42000: You 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 SELECT 1 INTO @var17727401_1 FROM DUAL INTO @var17727401_2; -ERROR HY000: Incorrect usage of INTO and INTO +ERROR 42000: You 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 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 @@ -754,7 +755,7 @@ 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 HY000: Incorrect usage of INTO and INTO +ERROR 42000: You 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 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 SELECT 1 FROM (SELECT 1 FROM t1 INTO @var17727401) a; @@ -762,16 +763,16 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp 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 SELECT 1 FROM t1 INTO @var17727401 UNION SELECT 1 FROM t1 INTO t1; -ERROR HY000: Incorrect usage of UNION and INTO +ERROR 42000: You 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 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 HY000: Incorrect usage of PROCEDURE and INTO +ERROR 42000: You 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 SELECT 1 FROM t1 PROCEDURE ANALYSE() INTO @var17727401; -ERROR HY000: Incorrect usage of PROCEDURE and INTO +ERROR 42000: You 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 # ORDER and LIMIT clause combinations (SELECT 1 FROM t1 ORDER BY 1) ORDER BY 1; 1 @@ -817,19 +818,19 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp SELECT 1 FROM (SELECT 1 FROM t1 UNION SELECT 1 FROM t1 LIMIT 1 ORDER BY 1) 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 'ORDER BY 1) a' at line 1 SELECT 1 FROM t1 ORDER BY 1 UNION SELECT 1 FROM t1; -ERROR HY000: Incorrect usage of UNION and ORDER BY +ERROR 42000: You 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' at line 1 SELECT (SELECT 1 FROM t1 ORDER BY 1 UNION SELECT 1 FROM t1); ERROR HY000: Incorrect usage of UNION and ORDER BY SELECT 1 FROM (SELECT 1 FROM t1 ORDER BY 1 UNION SELECT 1 FROM t1) a; ERROR HY000: Incorrect usage of UNION and ORDER BY SELECT 1 FROM t1 LIMIT 1 UNION SELECT 1 FROM t1; -ERROR HY000: Incorrect usage of UNION and LIMIT +ERROR 42000: You 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' at line 1 SELECT (SELECT 1 FROM t1 LIMIT 1 UNION SELECT 1 FROM t1); ERROR HY000: Incorrect usage of UNION and LIMIT SELECT 1 FROM (SELECT 1 FROM t1 LIMIT 1 UNION SELECT 1 FROM t1) a; ERROR HY000: Incorrect usage of UNION and LIMIT SELECT 1 FROM t1 ORDER BY 1 LIMIT 1 UNION SELECT 1 FROM t1; -ERROR HY000: Incorrect usage of UNION and ORDER BY +ERROR 42000: You 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' at line 1 SELECT (SELECT 1 FROM t1 ORDER BY 1 LIMIT 1 UNION SELECT 1 FROM t1); ERROR HY000: Incorrect usage of UNION and ORDER BY SELECT 1 FROM (SELECT 1 FROM t1 ORDER BY 1 LIMIT 1 UNION SELECT 1 FROM t1) a; @@ -841,25 +842,25 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp SELECT 1 FROM (SELECT 1 FROM t1 LIMIT 1 ORDER BY 1 UNION SELECT 1 FROM t1) a; ERROR HY000: Incorrect usage of UNION and ORDER BY SELECT 1 FROM t1 ORDER BY 1 UNION SELECT 1 FROM t1 ORDER BY 1; -ERROR HY000: Incorrect usage of UNION and ORDER BY +ERROR 42000: You 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 ORDER BY 1' at line 1 SELECT (SELECT 1 FROM t1 ORDER BY 1 UNION SELECT 1 FROM t1 ORDER BY 1); ERROR HY000: Incorrect usage of UNION and ORDER BY SELECT 1 FROM (SELECT 1 FROM t1 ORDER BY 1 UNION SELECT 1 FROM t1 ORDER BY 1) a; ERROR HY000: Incorrect usage of UNION and ORDER BY SELECT 1 FROM t1 LIMIT 1 UNION SELECT 1 FROM t1 LIMIT 1; -ERROR HY000: Incorrect usage of UNION and LIMIT +ERROR 42000: You 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 LIMIT 1' at line 1 SELECT (SELECT 1 FROM t1 LIMIT 1 UNION SELECT 1 FROM t1 LIMIT 1); ERROR HY000: Incorrect usage of UNION and LIMIT SELECT 1 FROM (SELECT 1 FROM t1 LIMIT 1 UNION SELECT 1 FROM t1 LIMIT 1) a; ERROR HY000: Incorrect usage of UNION and LIMIT SELECT 1 FROM t1 LIMIT 1 UNION SELECT 1 FROM t1 ORDER BY 1; -ERROR HY000: Incorrect usage of UNION and LIMIT +ERROR 42000: You 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 ORDER BY 1' at line 1 SELECT (SELECT 1 FROM t1 LIMIT 1 UNION SELECT 1 FROM t1 ORDER BY 1); ERROR HY000: Incorrect usage of UNION and LIMIT SELECT 1 FROM (SELECT 1 FROM t1 LIMIT 1 UNION SELECT 1 FROM t1 ORDER BY 1) a; ERROR HY000: Incorrect usage of UNION and LIMIT SELECT 1 FROM t1 ORDER BY 1 UNION SELECT 1 FROM t1 LIMIT 1; -ERROR HY000: Incorrect usage of UNION and ORDER BY +ERROR 42000: You 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 LIMIT 1' at line 1 SELECT (SELECT 1 FROM t1 ORDER BY 1 UNION SELECT 1 FROM t1 LIMIT 1); ERROR HY000: Incorrect usage of UNION and ORDER BY SELECT 1 FROM (SELECT 1 FROM t1 ORDER BY 1 UNION SELECT 1 FROM t1 LIMIT 1) a; diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 12f18d6038d..6a52bc023e1 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -124,9 +124,9 @@ ERROR 21000: The used SELECT statements have a different number of columns explain select a,b from t1 union select 1 limit 0; ERROR 21000: The used SELECT statements have a different number of columns select a,b from t1 into outfile 'skr' union select a,b from t2; -ERROR HY000: Incorrect usage of UNION and INTO +ERROR 42000: You 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,b from t2' at line 1 select a,b from t1 order by a union select a,b from t2; -ERROR HY000: Incorrect usage of UNION and ORDER BY +ERROR 42000: You 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,b from t2' at line 1 insert into t3 select a from t1 order by a union select a from t2; ERROR HY000: Incorrect usage of UNION and ORDER BY create table t3 select a,b from t1 union select a from t2; @@ -380,7 +380,7 @@ select found_rows(); found_rows() 4 SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1 UNION all SELECT * FROM t2 LIMIT 2; -ERROR HY000: Incorrect usage of UNION and LIMIT +ERROR 42000: You 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 all SELECT * FROM t2 LIMIT 2' at line 1 SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION all SELECT * FROM t2 LIMIT 2; a 1 @@ -422,7 +422,7 @@ select found_rows(); found_rows() 5 SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 100 UNION SELECT * FROM t2; -ERROR HY000: Incorrect usage of UNION and LIMIT +ERROR 42000: You 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 t2' at line 1 SELECT COUNT(*) FROM ( (SELECT * FROM t1 LIMIT 100) UNION SELECT * FROM t2) q; COUNT(*) @@ -435,7 +435,7 @@ a 4 5 SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1 UNION SELECT * FROM t2; -ERROR HY000: Incorrect usage of UNION and LIMIT +ERROR 42000: You 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 t2' at line 1 SELECT COUNT(*) FROM ( (SELECT * FROM t1 LIMIT 1) UNION SELECT * FROM t2) q; COUNT(*) @@ -447,7 +447,7 @@ a 4 5 SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1 UNION SELECT * FROM t2 LIMIT 2; -ERROR HY000: Incorrect usage of UNION and LIMIT +ERROR 42000: You 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 t2 LIMIT 2' at line 1 SELECT COUNT(*) FROM ( (SELECT * FROM t1 LIMIT 1) UNION SELECT * FROM t2) q; COUNT(*) @@ -468,7 +468,7 @@ SELECT * FROM t1 UNION SELECT * FROM t2) q; COUNT(*) 5 SELECT SQL_CALC_FOUND_ROWS * FROM t1 limit 2,2 UNION SELECT * FROM t2; -ERROR HY000: Incorrect usage of UNION and LIMIT +ERROR 42000: You 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 t2' at line 1 SELECT COUNT(*) FROM ( (SELECT * FROM t1 limit 2,2) UNION SELECT * FROM t2) q; COUNT(*) @@ -1569,7 +1569,8 @@ UNION ALL SELECT b, COUNT(*) FROM t2 GROUP BY b WITH ROLLUP ORDER BY a UNION SELECT 1,1; -ERROR HY000: Incorrect usage of UNION and ORDER BY +ERROR 42000: You 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,1' at line 4 DROP TABLE t1,t2; CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1), (2), (3); @@ -1647,11 +1648,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 HY000: Incorrect usage of UNION and INTO +ERROR 42000: You 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 SELECT a INTO OUTFILE 'union.out.file7' FROM t1 UNION SELECT a FROM t1; -ERROR HY000: Incorrect usage of UNION and INTO +ERROR 42000: You 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 SELECT a INTO DUMPFILE 'union.out.file8' FROM t1 UNION SELECT a FROM t1; -ERROR HY000: Incorrect usage of UNION and INTO +ERROR 42000: You 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 # 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; diff --git a/mysql-test/t/limit_rows_examined.test b/mysql-test/t/limit_rows_examined.test index 382530234be..3f7424d5541 100644 --- a/mysql-test/t/limit_rows_examined.test +++ b/mysql-test/t/limit_rows_examined.test @@ -125,6 +125,7 @@ UNION UNION (select * from t1, t2 where c1 < c2 LIMIT ROWS EXAMINED 6); +--error ER_PARSE_ERROR select * from t1, t2 where c1 = c2 LIMIT ROWS EXAMINED 0 UNION select * from t1, t2 where c1 < c2 LIMIT ROWS EXAMINED 6; diff --git a/mysql-test/t/parser.test b/mysql-test/t/parser.test index 86cc3c47c37..a143a61f995 100644 --- a/mysql-test/t/parser.test +++ b/mysql-test/t/parser.test @@ -831,7 +831,7 @@ UNION SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 PROCEDURE ANALYSE() FOR UPDATE; ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR SELECT 1 FROM DUAL PROCEDURE ANALYSE() UNION SELECT 1 FROM t1; @@ -863,10 +863,10 @@ SELECT 1 INTO @var17727401; SELECT 1 INTO @var17727401 FROM t1; SELECT 1 INTO @var17727401 FROM DUAL; ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR SELECT 1 INTO @var17727401_1 FROM t1 INTO @var17727401_2; ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR SELECT 1 INTO @var17727401_1 FROM DUAL INTO @var17727401_2; @@ -876,7 +876,7 @@ 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_WRONG_USAGE +--error ER_PARSE_ERROR SELECT 1 INTO @var17727401_1 FROM t1 WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 LIMIT 1 INTO @var17727401_2; @@ -888,17 +888,17 @@ SELECT 1 FROM (SELECT 1 FROM t1 INTO @var17727401) a; --error ER_PARSE_ERROR SELECT EXISTS(SELECT 1 FROM t1 INTO @var17727401); ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR SELECT 1 FROM t1 INTO @var17727401 UNION SELECT 1 FROM t1 INTO t1; --error ER_WRONG_USAGE (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_WRONG_USAGE +--error ER_PARSE_ERROR SELECT 1 INTO @var17727401 FROM t1 PROCEDURE ANALYSE(); ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR SELECT 1 FROM t1 PROCEDURE ANALYSE() INTO @var17727401; --echo # ORDER and LIMIT clause combinations @@ -947,7 +947,7 @@ eval SELECT ($q); eval SELECT 1 FROM ($q) a; let $q=SELECT 1 FROM t1 ORDER BY 1 UNION SELECT 1 FROM t1; ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR eval $q; --error ER_WRONG_USAGE eval SELECT ($q); @@ -955,7 +955,7 @@ eval SELECT ($q); eval SELECT 1 FROM ($q) a; let $q=SELECT 1 FROM t1 LIMIT 1 UNION SELECT 1 FROM t1; ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR eval $q; --error ER_WRONG_USAGE eval SELECT ($q); @@ -963,7 +963,7 @@ eval SELECT ($q); eval SELECT 1 FROM ($q) a; let $q=SELECT 1 FROM t1 ORDER BY 1 LIMIT 1 UNION SELECT 1 FROM t1; ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR eval $q; --error ER_WRONG_USAGE eval SELECT ($q); @@ -979,7 +979,7 @@ eval SELECT ($q); eval SELECT 1 FROM ($q) a; let $q=SELECT 1 FROM t1 ORDER BY 1 UNION SELECT 1 FROM t1 ORDER BY 1; ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR eval $q; --error ER_WRONG_USAGE eval SELECT ($q); @@ -987,7 +987,7 @@ eval SELECT ($q); eval SELECT 1 FROM ($q) a; let $q=SELECT 1 FROM t1 LIMIT 1 UNION SELECT 1 FROM t1 LIMIT 1; ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR eval $q; --error ER_WRONG_USAGE eval SELECT ($q); @@ -995,7 +995,7 @@ eval SELECT ($q); eval SELECT 1 FROM ($q) a; let $q=SELECT 1 FROM t1 LIMIT 1 UNION SELECT 1 FROM t1 ORDER BY 1; ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR eval $q; --error ER_WRONG_USAGE eval SELECT ($q); @@ -1003,7 +1003,7 @@ eval SELECT ($q); eval SELECT 1 FROM ($q) a; let $q=SELECT 1 FROM t1 ORDER BY 1 UNION SELECT 1 FROM t1 LIMIT 1; ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR eval $q; --error ER_WRONG_USAGE eval SELECT ($q); diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index f2026a67bc2..d7c67444015 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -50,10 +50,10 @@ explain select 1 union select a,b from t1 union select 1; --error 1222 explain select a,b from t1 union select 1 limit 0; ---error 1221 +--error ER_PARSE_ERROR select a,b from t1 into outfile 'skr' union select a,b from t2; ---error 1221 +--error ER_PARSE_ERROR select a,b from t1 order by a union select a,b from t2; --error 1221 @@ -236,7 +236,7 @@ SELECT COUNT(*) FROM ( select found_rows(); # In these case found_rows() should work ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1 UNION all SELECT * FROM t2 LIMIT 2; SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION all SELECT * FROM t2 LIMIT 2; select found_rows(); @@ -253,17 +253,17 @@ SELECT COUNT(*) FROM ( SELECT * FROM t1 UNION all SELECT * FROM t2) q; SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION SELECT * FROM t2 LIMIT 100; select found_rows(); ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 100 UNION SELECT * FROM t2; SELECT COUNT(*) FROM ( (SELECT * FROM t1 LIMIT 100) UNION SELECT * FROM t2) q; (SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 100) UNION SELECT * FROM t2; ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1 UNION SELECT * FROM t2; SELECT COUNT(*) FROM ( (SELECT * FROM t1 LIMIT 1) UNION SELECT * FROM t2) q; (SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1) UNION SELECT * FROM t2; ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1 UNION SELECT * FROM t2 LIMIT 2; SELECT COUNT(*) FROM ( (SELECT * FROM t1 LIMIT 1) UNION SELECT * FROM t2) q; @@ -272,7 +272,7 @@ SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION SELECT * FROM t2 LIMIT 2,2; select found_rows(); SELECT COUNT(*) FROM ( SELECT * FROM t1 UNION SELECT * FROM t2) q; ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR SELECT SQL_CALC_FOUND_ROWS * FROM t1 limit 2,2 UNION SELECT * FROM t2; SELECT COUNT(*) FROM ( (SELECT * FROM t1 limit 2,2) UNION SELECT * FROM t2) q; @@ -999,7 +999,7 @@ SELECT a,1 FROM t1 UNION (SELECT b, COUNT(*) FROM t2 GROUP BY b WITH ROLLUP ORDER BY a); ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR SELECT a,1 FROM t1 UNION ALL SELECT b, COUNT(*) FROM t2 GROUP BY b WITH ROLLUP ORDER BY a @@ -1087,11 +1087,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_WRONG_USAGE +--error ER_PARSE_ERROR SELECT a INTO @v FROM t1 UNION SELECT a FROM t1; ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR SELECT a INTO OUTFILE 'union.out.file7' FROM t1 UNION SELECT a FROM t1; ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR SELECT a INTO DUMPFILE 'union.out.file8' FROM t1 UNION SELECT a FROM t1; -- echo # Tests fix in parser rule query_expression_body. diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 04c1ba7e99a..755bf326f1f 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1793,7 +1793,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); opt_default_time_precision case_stmt_body opt_bin_mod opt_if_exists_table_element opt_if_not_exists_table_element - opt_into opt_procedure_clause opt_recursive %type @@ -8533,7 +8532,8 @@ select_paren: */ Lex->current_select->set_braces(true); } - SELECT_SYM select_part2 + SELECT_SYM select_options_and_item_list select_part3 + opt_select_lock_type { if (setup_select_in_parentheses(Lex)) MYSQL_YYABORT; @@ -8559,48 +8559,40 @@ select_paren_derived: ; select_init2: - select_part2 + select_options_and_item_list + opt_table_expression + opt_select_lock_type { - LEX *lex= Lex; /* Parentheses carry no meaning here */ - lex->current_select->set_braces(false); + Lex->current_select->set_braces(false); } union_clause + | select_options_and_item_list + select_part3_union_not_ready + opt_select_lock_type + { + /* Parentheses carry no meaning here */ + Lex->current_select->set_braces(false); + } + ; + + +select_part3: + opt_table_expression + | select_part3_union_not_ready ; /* - Theoretically we can merge all 3 right hand sides of the select_part2 - rule into one, however such a transformation adds one shift/reduce - conflict more. + The SELECT parts after select_item_list that cannot be followed by UNION. */ -select_part2: - select_options_and_item_list - opt_order_clause - opt_limit_clause - opt_select_lock_type - | select_options_and_item_list into opt_select_lock_type - | select_options_and_item_list - opt_into - table_expression - opt_order_clause - opt_limit_clause - opt_procedure_clause - opt_into - opt_select_lock_type - { - if ($2 && $7) - { - /* double "INTO" clause */ - my_error(ER_WRONG_USAGE, MYF(0), "INTO", "INTO"); - MYSQL_YYABORT; - } - if ($6 && ($2 || $7)) - { - /* "INTO" with "PROCEDURE ANALYSE" */ - my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE", "INTO"); - MYSQL_YYABORT; - } - } +select_part3_union_not_ready: + order_or_limit + | into opt_table_expression opt_order_clause opt_limit_clause + | table_expression into + | table_expression procedure_clause + | table_expression order_or_limit + | table_expression order_or_limit into + | table_expression order_or_limit procedure_clause ; select_options_and_item_list: @@ -11946,9 +11938,8 @@ choice: | DEFAULT { $$= HA_CHOICE_UNDEF; } ; -opt_procedure_clause: - /* empty */ { $$= false; } - | PROCEDURE_SYM ident /* Procedure name */ +procedure_clause: + PROCEDURE_SYM ident /* Procedure name */ { LEX *lex=Lex; @@ -11989,7 +11980,6 @@ opt_procedure_clause: { /* Subqueries are allowed from now.*/ Lex->expr_allows_subselect= true; - $$= true; } ; @@ -12069,11 +12059,6 @@ select_outvar: } ; -opt_into: - /* empty */ { $$= false; } - | into { $$= true; } - ; - into: INTO {