mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
Cleanup patch for handling of subselects in commands which cannot
handle them. Problem: CREATE|ALTER EVENT, HANDLER READ, KILL, Partitioning uses `expr` from the parser. This rule comes with all the rings and bells including subqueries. However, these commands are not subquery safe. For this reason there are two fuse checks in the parser. They were checking by command id. CREATE EVENT should forbid subquery is the fix for bug#16394 Events: Crash if schedule contains SELECT The fix has been incorporated as part of the patch for WL#3337 (Event scheduler new architecture). Solution: A new flag was added to LEX command_forbids_subselect. The fuse checks were changed. The commands are responsible to set the value to true whenever they can't handle subselects.
This commit is contained in:
parent
089b284c49
commit
0a9b523e9a
3 changed files with 29 additions and 12 deletions
|
@ -175,6 +175,7 @@ void lex_start(THD *thd, const uchar *buf, uint length)
|
|||
lex->proc_list.first= 0;
|
||||
lex->escape_used= FALSE;
|
||||
lex->reset_query_tables_list(FALSE);
|
||||
lex->expr_allows_subselect= TRUE;
|
||||
|
||||
lex->name= 0;
|
||||
lex->event_parse_data= NULL;
|
||||
|
|
|
@ -958,6 +958,14 @@ typedef struct st_lex : public Query_tables_list
|
|||
*/
|
||||
nesting_map allow_sum_func;
|
||||
enum_sql_command sql_command;
|
||||
/*
|
||||
Usually `expr` rule of yacc is quite reused but some commands better
|
||||
not support subqueries which comes standard with this rule, like
|
||||
KILL, HA_READ, CREATE/ALTER EVENT etc. Set this to `false` to get
|
||||
syntax error back.
|
||||
*/
|
||||
bool expr_allows_subselect;
|
||||
|
||||
thr_lock_type lock_option;
|
||||
enum SSL_type ssl_type; /* defined in violite.h */
|
||||
enum my_lex_states next_state;
|
||||
|
|
|
@ -1302,8 +1302,9 @@ event_tail:
|
|||
$<ulong_num>$= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES;
|
||||
YYTHD->client_capabilities &= (~CLIENT_MULTI_QUERIES);
|
||||
|
||||
/* We need that for disallowing subqueries */
|
||||
Lex->sql_command= SQLCOM_CREATE_EVENT;
|
||||
/* We need that for disallowing subqueries */
|
||||
Lex->expr_allows_subselect= FALSE;
|
||||
}
|
||||
ON SCHEDULE_SYM ev_schedule_time
|
||||
opt_ev_on_completion
|
||||
|
@ -1325,6 +1326,7 @@ event_tail:
|
|||
can overwrite it
|
||||
*/
|
||||
Lex->sql_command= SQLCOM_CREATE_EVENT;
|
||||
Lex->expr_allows_subselect= TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -4697,8 +4699,9 @@ alter:
|
|||
$<ulong_num>$= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES;
|
||||
YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES;
|
||||
|
||||
/* we need that for disallowing subqueries */
|
||||
Lex->sql_command= SQLCOM_ALTER_EVENT;
|
||||
/* we need that for disallowing subqueries */
|
||||
Lex->expr_allows_subselect= FALSE;
|
||||
}
|
||||
ev_alter_on_schedule_completion
|
||||
opt_ev_rename_to
|
||||
|
@ -4724,6 +4727,7 @@ alter:
|
|||
can overwrite it
|
||||
*/
|
||||
Lex->sql_command= SQLCOM_ALTER_EVENT;
|
||||
Lex->expr_allows_subselect= TRUE;
|
||||
}
|
||||
| ALTER TABLESPACE alter_tablespace_info
|
||||
{
|
||||
|
@ -7048,10 +7052,7 @@ select_derived2:
|
|||
{
|
||||
LEX *lex= Lex;
|
||||
lex->derived_tables|= DERIVED_SUBQUERY;
|
||||
if (lex->sql_command == SQLCOM_HA_READ ||
|
||||
lex->sql_command == SQLCOM_KILL ||
|
||||
lex->sql_command == SQLCOM_CREATE_EVENT ||
|
||||
lex->sql_command == SQLCOM_ALTER_EVENT)
|
||||
if (!lex->expr_allows_subselect)
|
||||
{
|
||||
yyerror(ER(ER_SYNTAX_ERROR));
|
||||
YYABORT;
|
||||
|
@ -8554,11 +8555,17 @@ purge_option:
|
|||
/* kill threads */
|
||||
|
||||
kill:
|
||||
KILL_SYM { Lex->sql_command= SQLCOM_KILL; } kill_option expr
|
||||
KILL_SYM
|
||||
{
|
||||
Lex->sql_command= SQLCOM_KILL;
|
||||
Lex->expr_allows_subselect= FALSE;
|
||||
}
|
||||
kill_option expr
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
lex->value_list.empty();
|
||||
lex->value_list.push_front($4);
|
||||
Lex->expr_allows_subselect= TRUE;
|
||||
};
|
||||
|
||||
kill_option:
|
||||
|
@ -10038,6 +10045,7 @@ handler:
|
|||
my_error(ER_SP_BADSTATEMENT, MYF(0), "HANDLER");
|
||||
YYABORT;
|
||||
}
|
||||
lex->expr_allows_subselect= FALSE;
|
||||
lex->sql_command = SQLCOM_HA_READ;
|
||||
lex->ha_rkey_mode= HA_READ_KEY_EXACT; /* Avoid purify warnings */
|
||||
lex->current_select->select_limit= new Item_int((int32) 1);
|
||||
|
@ -10045,7 +10053,10 @@ handler:
|
|||
if (!lex->current_select->add_table_to_list(lex->thd, $2, 0, 0))
|
||||
YYABORT;
|
||||
}
|
||||
handler_read_or_scan where_clause opt_limit_clause {}
|
||||
handler_read_or_scan where_clause opt_limit_clause
|
||||
{
|
||||
Lex->expr_allows_subselect= TRUE;
|
||||
}
|
||||
;
|
||||
|
||||
handler_read_or_scan:
|
||||
|
@ -10670,10 +10681,7 @@ subselect_start:
|
|||
'(' SELECT_SYM
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
if (lex->sql_command == SQLCOM_HA_READ ||
|
||||
lex->sql_command == SQLCOM_KILL ||
|
||||
lex->sql_command == SQLCOM_CREATE_EVENT ||
|
||||
lex->sql_command == SQLCOM_ALTER_EVENT)
|
||||
if (!lex->expr_allows_subselect)
|
||||
{
|
||||
yyerror(ER(ER_SYNTAX_ERROR));
|
||||
YYABORT;
|
||||
|
|
Loading…
Reference in a new issue