summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2016-05-24 14:18:46 +0400
committerAlexander Barkov <bar@mariadb.org>2016-05-24 14:18:46 +0400
commitea9a393a868dda808bd0c7a3f03b28208eb6570f (patch)
treec1f15bf73159c484bcac51d8a2d81eb7498464f0
parent9a25c01f7848324dd63c64ea4e1c86ef1cebfbc8 (diff)
downloadmariadb-git-ea9a393a868dda808bd0c7a3f03b28208eb6570f.tar.gz
MDEV-10103 Disallow syntactically UNION SELECT .. PROCEDURE ANALYSE()
-rw-r--r--mysql-test/r/func_analyse.result2
-rw-r--r--mysql-test/r/parser.result4
-rw-r--r--mysql-test/t/func_analyse.test2
-rw-r--r--mysql-test/t/parser.test4
-rw-r--r--sql/sql_yacc.yy68
5 files changed, 62 insertions, 18 deletions
diff --git a/mysql-test/r/func_analyse.result b/mysql-test/r/func_analyse.result
index bc8ec445e73..1e78e603bca 100644
--- a/mysql-test/r/func_analyse.result
+++ b/mysql-test/r/func_analyse.result
@@ -159,7 +159,7 @@ Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_
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 * FROM t1 UNION SELECT * FROM t1 PROCEDURE analyse();
-ERROR HY000: Incorrect usage of PROCEDURE and subquery
+ERROR 42000: You 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
#
# MDEV-10030 sql_yacc.yy: Split table_expression and remove PROCEDURE from create_select, select_paren_derived, select_derived2, query_specification
#
diff --git a/mysql-test/r/parser.result b/mysql-test/r/parser.result
index 54f84f88e05..f0cfde65b57 100644
--- a/mysql-test/r/parser.result
+++ b/mysql-test/r/parser.result
@@ -705,7 +705,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 HY000: Incorrect usage of PROCEDURE and subquery
+ERROR 42000: You 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
SELECT 1 FROM DUAL PROCEDURE ANALYSE()
UNION
SELECT 1 FROM t1;
@@ -721,7 +721,7 @@ FOR UPDATE);
UNION
(SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
PROCEDURE ANALYSE() FOR UPDATE);
-ERROR HY000: Incorrect usage of PROCEDURE and subquery
+ERROR 42000: You 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
# "FOR UPDATE" tests
SELECT 1 FROM t1 UNION SELECT 1 FROM t1 ORDER BY 1 LIMIT 1;
1
diff --git a/mysql-test/t/func_analyse.test b/mysql-test/t/func_analyse.test
index 6c30c0ca630..d99f5c0fa9a 100644
--- a/mysql-test/t/func_analyse.test
+++ b/mysql-test/t/func_analyse.test
@@ -165,7 +165,7 @@ DROP TABLE t1, t2;
((SELECT 1 FROM DUAL PROCEDURE ANALYSE()));
# TODO:
---error ER_WRONG_USAGE
+--error ER_PARSE_ERROR
SELECT * FROM t1 UNION SELECT * FROM t1 PROCEDURE analyse();
--echo #
diff --git a/mysql-test/t/parser.test b/mysql-test/t/parser.test
index 0065c5d0b5c..aae6b2c34be 100644
--- a/mysql-test/t/parser.test
+++ b/mysql-test/t/parser.test
@@ -825,7 +825,7 @@ UNION
SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
FOR UPDATE;
---error ER_WRONG_USAGE
+--error ER_PARSE_ERROR
SELECT 1 FROM t1
UNION
SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
@@ -841,7 +841,7 @@ UNION
(SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
FOR UPDATE);
---error ER_WRONG_USAGE
+--error ER_PARSE_ERROR
(SELECT 1 FROM t1)
UNION
(SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index ac43129372c..260f570ffd2 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -8528,6 +8528,11 @@ select_init:
| '(' select_paren ')' union_opt
;
+union_list_part2:
+ SELECT_SYM select_options_and_item_list select_init3_union_query_term
+ | '(' select_paren_union_query_term ')' union_opt
+ ;
+
select_paren:
{
/*
@@ -8545,6 +8550,23 @@ select_paren:
| '(' 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
+ {
+ if (setup_select_in_parentheses(Lex))
+ MYSQL_YYABORT;
+ }
+ | '(' select_paren_union_query_term ')'
+ ;
+
select_paren_view:
{
/*
@@ -8597,6 +8619,23 @@ select_init3:
;
+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);
+ }
+ ;
+
+
select_init3_view:
opt_table_expression opt_select_lock_type
{
@@ -8617,28 +8656,38 @@ select_init3_view:
}
;
+/*
+ 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
;
-/*
- The SELECT parts after select_item_list that cannot be followed by UNION.
-*/
select_part3_union_not_ready:
+ select_part3_union_not_ready_noproc
+ | table_expression procedure_clause
+ | table_expression order_or_limit procedure_clause
+ ;
+
+select_part3_union_not_ready_noproc:
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:
@@ -12012,12 +12061,7 @@ procedure_clause:
{
LEX *lex=Lex;
- if (&lex->select_lex != lex->current_select)
- {
- // SELECT * FROM t1 UNION SELECT * FROM t2 PROCEDURE ANALYSE();
- my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE", "subquery");
- MYSQL_YYABORT;
- }
+ DBUG_ASSERT(&lex->select_lex == lex->current_select);
lex->proc_list.elements=0;
lex->proc_list.first=0;
@@ -16361,7 +16405,7 @@ union_list:
if (add_select_to_union_list(Lex, (bool)$2, TRUE))
MYSQL_YYABORT;
}
- select_init
+ union_list_part2
{
/*
Remove from the name resolution context stack the context of the