diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 544dfd0814f..1fbbde998f5 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -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; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index dcb049c16c6..42c3b78a6ed 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -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; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 3eb796cd72d..4d50572e599 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1302,8 +1302,9 @@ event_tail: $$= 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: $$= 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;