From 4c0e2960d458cb437d4aa06d9193f5576c027448 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Mon, 23 May 2016 10:54:09 +0400 Subject: [PATCH] MDEV-10051 Fix subselect to return a syntax error instead of "Incorrect usage of UNION and LIMIT" --- mysql-test/r/parser.result | 14 +++--- mysql-test/r/subselect.result | 2 +- mysql-test/r/subselect_no_exists_to_in.result | 2 +- mysql-test/r/subselect_no_mat.result | 2 +- mysql-test/r/subselect_no_opts.result | 2 +- mysql-test/r/subselect_no_scache.result | 2 +- mysql-test/r/subselect_no_semijoin.result | 2 +- mysql-test/t/parser.test | 14 +++--- mysql-test/t/subselect.test | 2 +- sql/sql_yacc.yy | 48 +++++++++---------- 10 files changed, 43 insertions(+), 47 deletions(-) diff --git a/mysql-test/r/parser.result b/mysql-test/r/parser.result index f42346608d5..54f84f88e05 100644 --- a/mysql-test/r/parser.result +++ b/mysql-test/r/parser.result @@ -820,19 +820,19 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp SELECT 1 FROM t1 ORDER BY 1 UNION SELECT 1 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 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 +ERROR 42000: You 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 1 FROM (SELECT 1 FROM t1 ORDER BY 1 UNION SELECT 1 FROM t1) 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 'UNION SELECT 1 FROM t1) a' at line 1 SELECT 1 FROM t1 LIMIT 1 UNION SELECT 1 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 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 +ERROR 42000: You 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 1 FROM (SELECT 1 FROM t1 LIMIT 1 UNION SELECT 1 FROM t1) 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 'UNION SELECT 1 FROM t1) a' at line 1 SELECT 1 FROM t1 ORDER BY 1 LIMIT 1 UNION SELECT 1 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 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 +ERROR 42000: You 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 1 FROM (SELECT 1 FROM t1 ORDER BY 1 LIMIT 1 UNION SELECT 1 FROM t1) 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 'UNION SELECT 1 FROM t1) a' at line 1 SELECT 1 FROM t1 LIMIT 1 ORDER BY 1 UNION SELECT 1 FROM t1; @@ -844,25 +844,25 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp SELECT 1 FROM t1 ORDER BY 1 UNION SELECT 1 FROM t1 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 '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 +ERROR 42000: You 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 1 FROM (SELECT 1 FROM t1 ORDER BY 1 UNION SELECT 1 FROM t1 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 'UNION SELECT 1 FROM t1 ORDER BY 1) a' at line 1 SELECT 1 FROM t1 LIMIT 1 UNION SELECT 1 FROM t1 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 '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 +ERROR 42000: You 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 1 FROM (SELECT 1 FROM t1 LIMIT 1 UNION SELECT 1 FROM t1 LIMIT 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 'UNION SELECT 1 FROM t1 LIMIT 1) a' at line 1 SELECT 1 FROM t1 LIMIT 1 UNION SELECT 1 FROM t1 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 '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 +ERROR 42000: You 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 1 FROM (SELECT 1 FROM t1 LIMIT 1 UNION SELECT 1 FROM t1 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 'UNION SELECT 1 FROM t1 ORDER BY 1) a' at line 1 SELECT 1 FROM t1 ORDER BY 1 UNION SELECT 1 FROM t1 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 '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 +ERROR 42000: You 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 1 FROM (SELECT 1 FROM t1 ORDER BY 1 UNION SELECT 1 FROM t1 LIMIT 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 'UNION SELECT 1 FROM t1 LIMIT 1) a' at line 1 DROP TABLE t1; diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 974c60d381d..c973bbe11d5 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -1056,7 +1056,7 @@ create table t1 (a float); select 10.5 IN (SELECT * from t1 LIMIT 1); ERROR 42000: This version of MariaDB doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' select 10.5 IN (SELECT * from t1 LIMIT 1 UNION SELECT 1.5); -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.5)' at line 1 select 10.5 IN (SELECT * from t1 UNION SELECT 1.5 LIMIT 1); ERROR 42000: This version of MariaDB doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' drop table t1; diff --git a/mysql-test/r/subselect_no_exists_to_in.result b/mysql-test/r/subselect_no_exists_to_in.result index 6183a3bc2e4..8ad01c0816c 100644 --- a/mysql-test/r/subselect_no_exists_to_in.result +++ b/mysql-test/r/subselect_no_exists_to_in.result @@ -1060,7 +1060,7 @@ create table t1 (a float); select 10.5 IN (SELECT * from t1 LIMIT 1); ERROR 42000: This version of MariaDB doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' select 10.5 IN (SELECT * from t1 LIMIT 1 UNION SELECT 1.5); -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.5)' at line 1 select 10.5 IN (SELECT * from t1 UNION SELECT 1.5 LIMIT 1); ERROR 42000: This version of MariaDB doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' drop table t1; diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result index c9c86acf63c..6dc3cba5a77 100644 --- a/mysql-test/r/subselect_no_mat.result +++ b/mysql-test/r/subselect_no_mat.result @@ -1063,7 +1063,7 @@ create table t1 (a float); select 10.5 IN (SELECT * from t1 LIMIT 1); ERROR 42000: This version of MariaDB doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' select 10.5 IN (SELECT * from t1 LIMIT 1 UNION SELECT 1.5); -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.5)' at line 1 select 10.5 IN (SELECT * from t1 UNION SELECT 1.5 LIMIT 1); ERROR 42000: This version of MariaDB doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' drop table t1; diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result index ce1136057bc..843adafe2b9 100644 --- a/mysql-test/r/subselect_no_opts.result +++ b/mysql-test/r/subselect_no_opts.result @@ -1059,7 +1059,7 @@ create table t1 (a float); select 10.5 IN (SELECT * from t1 LIMIT 1); ERROR 42000: This version of MariaDB doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' select 10.5 IN (SELECT * from t1 LIMIT 1 UNION SELECT 1.5); -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.5)' at line 1 select 10.5 IN (SELECT * from t1 UNION SELECT 1.5 LIMIT 1); ERROR 42000: This version of MariaDB doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' drop table t1; diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result index e18468b9975..348258f5ee1 100644 --- a/mysql-test/r/subselect_no_scache.result +++ b/mysql-test/r/subselect_no_scache.result @@ -1062,7 +1062,7 @@ create table t1 (a float); select 10.5 IN (SELECT * from t1 LIMIT 1); ERROR 42000: This version of MariaDB doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' select 10.5 IN (SELECT * from t1 LIMIT 1 UNION SELECT 1.5); -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.5)' at line 1 select 10.5 IN (SELECT * from t1 UNION SELECT 1.5 LIMIT 1); ERROR 42000: This version of MariaDB doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' drop table t1; diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result index a28cc7cb0d6..cd28339e4c9 100644 --- a/mysql-test/r/subselect_no_semijoin.result +++ b/mysql-test/r/subselect_no_semijoin.result @@ -1059,7 +1059,7 @@ create table t1 (a float); select 10.5 IN (SELECT * from t1 LIMIT 1); ERROR 42000: This version of MariaDB doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' select 10.5 IN (SELECT * from t1 LIMIT 1 UNION SELECT 1.5); -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.5)' at line 1 select 10.5 IN (SELECT * from t1 UNION SELECT 1.5 LIMIT 1); ERROR 42000: This version of MariaDB doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' drop table t1; diff --git a/mysql-test/t/parser.test b/mysql-test/t/parser.test index 7d1582c397c..0065c5d0b5c 100644 --- a/mysql-test/t/parser.test +++ b/mysql-test/t/parser.test @@ -949,7 +949,7 @@ eval SELECT 1 FROM ($q) a; let $q=SELECT 1 FROM t1 ORDER BY 1 UNION SELECT 1 FROM t1; --error ER_PARSE_ERROR eval $q; ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR eval SELECT ($q); --error ER_PARSE_ERROR eval SELECT 1 FROM ($q) a; @@ -957,7 +957,7 @@ eval SELECT 1 FROM ($q) a; let $q=SELECT 1 FROM t1 LIMIT 1 UNION SELECT 1 FROM t1; --error ER_PARSE_ERROR eval $q; ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR eval SELECT ($q); --error ER_PARSE_ERROR eval SELECT 1 FROM ($q) a; @@ -965,7 +965,7 @@ eval SELECT 1 FROM ($q) a; let $q=SELECT 1 FROM t1 ORDER BY 1 LIMIT 1 UNION SELECT 1 FROM t1; --error ER_PARSE_ERROR eval $q; ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR eval SELECT ($q); --error ER_PARSE_ERROR eval SELECT 1 FROM ($q) a; @@ -981,7 +981,7 @@ 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_PARSE_ERROR eval $q; ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR eval SELECT ($q); --error ER_PARSE_ERROR eval SELECT 1 FROM ($q) a; @@ -989,7 +989,7 @@ eval SELECT 1 FROM ($q) a; let $q=SELECT 1 FROM t1 LIMIT 1 UNION SELECT 1 FROM t1 LIMIT 1; --error ER_PARSE_ERROR eval $q; ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR eval SELECT ($q); --error ER_PARSE_ERROR eval SELECT 1 FROM ($q) a; @@ -997,7 +997,7 @@ eval SELECT 1 FROM ($q) a; let $q=SELECT 1 FROM t1 LIMIT 1 UNION SELECT 1 FROM t1 ORDER BY 1; --error ER_PARSE_ERROR eval $q; ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR eval SELECT ($q); --error ER_PARSE_ERROR eval SELECT 1 FROM ($q) a; @@ -1005,7 +1005,7 @@ eval SELECT 1 FROM ($q) a; let $q=SELECT 1 FROM t1 ORDER BY 1 UNION SELECT 1 FROM t1 LIMIT 1; --error ER_PARSE_ERROR eval $q; ---error ER_WRONG_USAGE +--error ER_PARSE_ERROR eval SELECT ($q); --error ER_PARSE_ERROR eval SELECT 1 FROM ($q) a; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 5313a4b8a39..c19613da493 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -569,7 +569,7 @@ drop table t1, t2; create table t1 (a float); -- error ER_NOT_SUPPORTED_YET select 10.5 IN (SELECT * from t1 LIMIT 1); --- error ER_WRONG_USAGE +-- error ER_PARSE_ERROR select 10.5 IN (SELECT * from t1 LIMIT 1 UNION SELECT 1.5); -- error ER_NOT_SUPPORTED_YET select 10.5 IN (SELECT * from t1 UNION SELECT 1.5 LIMIT 1); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 89f1430a1c1..50b943c7ea0 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1883,7 +1883,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); select_derived derived_table_list select_derived_union derived_query_specification - %type date_time_type; %type interval @@ -1922,7 +1921,11 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %type subselect get_select_lex get_select_lex_derived + query_specification + query_term_union_not_ready + query_term_union_ready query_expression_body + select_paren_derived %type comp_op @@ -8555,8 +8558,9 @@ select_paren_derived: { if (setup_select_in_parentheses(Lex)) MYSQL_YYABORT; + $$= Lex->current_select->master_unit()->first_select(); } - | '(' select_paren_derived ')' + | '(' select_paren_derived ')' { $$= $2; } ; select_init3: @@ -16402,33 +16406,25 @@ union_option: */ query_specification: SELECT_SYM select_init2_derived opt_table_expression - ; - -query_term: - query_term_union_ready - | query_term_union_not_ready - ; - -query_term_union_not_ready: - query_specification order_or_limit opt_select_lock_type - | '(' select_paren_derived ')' union_order_or_limit - ; - -query_term_union_ready: - query_specification opt_select_lock_type - | '(' select_paren_derived ')' - ; - -query_expression_body: - query_term { $$= Lex->current_select->master_unit()->first_select(); } - | query_expression_body union_head_non_top query_term - { - Lex->pop_context(); - $$= $1; - } + ; + +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 in the SQL:2003 standard. */