Commit ea9a393a authored by Alexander Barkov's avatar Alexander Barkov

MDEV-10103 Disallow syntactically UNION SELECT .. PROCEDURE ANALYSE()

parent 9a25c01f
...@@ -159,7 +159,7 @@ Field_name Min_value Max_value Min_length Max_length Empties_or_zeros Nulls Avg_ ...@@ -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 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 1 1 1 1 1 0 0 1.0000 0.0000 ENUM('1') NOT NULL
SELECT * FROM t1 UNION SELECT * FROM t1 PROCEDURE analyse(); 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 # MDEV-10030 sql_yacc.yy: Split table_expression and remove PROCEDURE from create_select, select_paren_derived, select_derived2, query_specification
# #
......
...@@ -705,7 +705,7 @@ SELECT 1 FROM t1 ...@@ -705,7 +705,7 @@ SELECT 1 FROM t1
UNION UNION
SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
PROCEDURE ANALYSE() FOR UPDATE; 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() SELECT 1 FROM DUAL PROCEDURE ANALYSE()
UNION UNION
SELECT 1 FROM t1; SELECT 1 FROM t1;
...@@ -721,7 +721,7 @@ FOR UPDATE); ...@@ -721,7 +721,7 @@ FOR UPDATE);
UNION UNION
(SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 (SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
PROCEDURE ANALYSE() FOR UPDATE); 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 # "FOR UPDATE" tests
SELECT 1 FROM t1 UNION SELECT 1 FROM t1 ORDER BY 1 LIMIT 1; SELECT 1 FROM t1 UNION SELECT 1 FROM t1 ORDER BY 1 LIMIT 1;
1 1
......
...@@ -165,7 +165,7 @@ DROP TABLE t1, t2; ...@@ -165,7 +165,7 @@ DROP TABLE t1, t2;
((SELECT 1 FROM DUAL PROCEDURE ANALYSE())); ((SELECT 1 FROM DUAL PROCEDURE ANALYSE()));
# TODO: # TODO:
--error ER_WRONG_USAGE --error ER_PARSE_ERROR
SELECT * FROM t1 UNION SELECT * FROM t1 PROCEDURE analyse(); SELECT * FROM t1 UNION SELECT * FROM t1 PROCEDURE analyse();
--echo # --echo #
......
...@@ -825,7 +825,7 @@ UNION ...@@ -825,7 +825,7 @@ UNION
SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
FOR UPDATE; FOR UPDATE;
--error ER_WRONG_USAGE --error ER_PARSE_ERROR
SELECT 1 FROM t1 SELECT 1 FROM t1
UNION UNION
SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
...@@ -841,7 +841,7 @@ UNION ...@@ -841,7 +841,7 @@ UNION
(SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 (SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
FOR UPDATE); FOR UPDATE);
--error ER_WRONG_USAGE --error ER_PARSE_ERROR
(SELECT 1 FROM t1) (SELECT 1 FROM t1)
UNION UNION
(SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1 (SELECT 1 FROM DUAL WHERE 1 GROUP BY 1 HAVING 1 ORDER BY 1
......
...@@ -8528,6 +8528,11 @@ select_init: ...@@ -8528,6 +8528,11 @@ select_init:
| '(' select_paren ')' union_opt | '(' 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: select_paren:
{ {
/* /*
...@@ -8545,6 +8550,23 @@ select_paren: ...@@ -8545,6 +8550,23 @@ select_paren:
| '(' 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: select_paren_view:
{ {
/* /*
...@@ -8597,6 +8619,23 @@ select_init3: ...@@ -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: select_init3_view:
opt_table_expression opt_select_lock_type opt_table_expression opt_select_lock_type
{ {
...@@ -8617,28 +8656,38 @@ select_init3_view: ...@@ -8617,28 +8656,38 @@ select_init3_view:
} }
; ;
/*
The SELECT parts after select_item_list that cannot be followed by UNION.
*/
select_part3: select_part3:
opt_table_expression opt_table_expression
| select_part3_union_not_ready | select_part3_union_not_ready
; ;
select_part3_union_query_term:
opt_table_expression
| select_part3_union_not_ready_noproc
;
select_part3_view: select_part3_view:
opt_table_expression opt_table_expression
| order_or_limit | order_or_limit
| 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:
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 order_or_limit
| into opt_table_expression opt_order_clause opt_limit_clause | into opt_table_expression opt_order_clause opt_limit_clause
| table_expression into | table_expression into
| table_expression procedure_clause
| table_expression order_or_limit | table_expression order_or_limit
| table_expression order_or_limit into | table_expression order_or_limit into
| table_expression order_or_limit procedure_clause
; ;
select_options_and_item_list: select_options_and_item_list:
...@@ -12012,12 +12061,7 @@ procedure_clause: ...@@ -12012,12 +12061,7 @@ procedure_clause:
{ {
LEX *lex=Lex; LEX *lex=Lex;
if (&lex->select_lex != lex->current_select) DBUG_ASSERT(&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;
}
lex->proc_list.elements=0; lex->proc_list.elements=0;
lex->proc_list.first=0; lex->proc_list.first=0;
...@@ -16361,7 +16405,7 @@ union_list: ...@@ -16361,7 +16405,7 @@ union_list:
if (add_select_to_union_list(Lex, (bool)$2, TRUE)) if (add_select_to_union_list(Lex, (bool)$2, TRUE))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
select_init union_list_part2
{ {
/* /*
Remove from the name resolution context stack the context of the Remove from the name resolution context stack the context of the
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment