diff options
-rw-r--r-- | mysql-test/main/sp-code.result | 25 | ||||
-rw-r--r-- | mysql-test/main/sp-code.test | 16 | ||||
-rw-r--r-- | mysql-test/suite/compat/oracle/r/sp-code.result | 27 | ||||
-rw-r--r-- | mysql-test/suite/compat/oracle/t/sp-code.test | 31 | ||||
-rw-r--r-- | sql/sql_lex.cc | 28 | ||||
-rw-r--r-- | sql/sql_lex.h | 51 | ||||
-rw-r--r-- | sql/sql_parse.cc | 5 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 358 | ||||
-rw-r--r-- | sql/sql_yacc_ora.yy | 335 |
9 files changed, 592 insertions, 284 deletions
diff --git a/mysql-test/main/sp-code.result b/mysql-test/main/sp-code.result index 0ff30ba7764..13bd2d6a677 100644 --- a/mysql-test/main/sp-code.result +++ b/mysql-test/main/sp-code.result @@ -847,8 +847,8 @@ drop procedure if exists p_20906_b; create procedure p_20906_a() SET @a=@a+1, @b=@b+1; show procedure code p_20906_a; Pos Instruction -0 stmt 31 "SET @a=@a+1" -1 stmt 31 "SET @b=@b+1" +0 stmt 31 "SET @a=@a+1" +1 stmt 31 "SET @b=@b+1" set @a=1; set @b=1; call p_20906_a(); @@ -858,9 +858,9 @@ select @a, @b; create procedure p_20906_b() SET @a=@a+1, @b=@b+1, @c=@c+1; show procedure code p_20906_b; Pos Instruction -0 stmt 31 "SET @a=@a+1" -1 stmt 31 "SET @b=@b+1" -2 stmt 31 "SET @c=@c+1" +0 stmt 31 "SET @a=@a+1" +1 stmt 31 "SET @b=@b+1" +2 stmt 31 "SET @c=@c+1" set @a=1; set @b=1; set @c=1; @@ -1328,3 +1328,18 @@ Pos Instruction 4 jump 2 5 hpop 1 drop function f1; +# +# MDEV-19640 Wrong SHOW PROCEDURE output for SET GLOBAL sysvar1=expr, sysvar2=expr +# +CREATE OR REPLACE PROCEDURE p1() +BEGIN +SET GLOBAL max_allowed_packet=16000000, max_error_count=60; +SELECT @@GLOBAL.max_allowed_packet, @@GLOBAL.max_error_count; +END; +$$ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 stmt 31 "SET GLOBAL max_allowed_packet=16000000" +1 stmt 31 "SET GLOBAL max_error_count=60" +2 stmt 0 "SELECT @@GLOBAL.max_allowed_packet, @..." +DROP PROCEDURE p1; diff --git a/mysql-test/main/sp-code.test b/mysql-test/main/sp-code.test index f8c1b4f0a92..533cc35a0a5 100644 --- a/mysql-test/main/sp-code.test +++ b/mysql-test/main/sp-code.test @@ -946,3 +946,19 @@ end| delimiter ;| show function code f1; drop function f1; + + +--echo # +--echo # MDEV-19640 Wrong SHOW PROCEDURE output for SET GLOBAL sysvar1=expr, sysvar2=expr +--echo # + +DELIMITER $$; +CREATE OR REPLACE PROCEDURE p1() +BEGIN + SET GLOBAL max_allowed_packet=16000000, max_error_count=60; + SELECT @@GLOBAL.max_allowed_packet, @@GLOBAL.max_error_count; +END; +$$ +DELIMITER ;$$ +SHOW PROCEDURE CODE p1; +DROP PROCEDURE p1; diff --git a/mysql-test/suite/compat/oracle/r/sp-code.result b/mysql-test/suite/compat/oracle/r/sp-code.result index 1c6aacc8743..0fc980a3b84 100644 --- a/mysql-test/suite/compat/oracle/r/sp-code.result +++ b/mysql-test/suite/compat/oracle/r/sp-code.result @@ -1487,3 +1487,30 @@ CALL p1(); x0 x1.a x1.b 100 101 102 DROP PROCEDURE p1; +# +# MDEV-19640 Wrong SHOW PROCEDURE output for SET GLOBAL sysvar1=expr, sysvar2=expr +# +CREATE OR REPLACE PROCEDURE p1() AS +BEGIN +SET GLOBAL max_allowed_packet=16000000, max_error_count=60; +SELECT @@GLOBAL.max_allowed_packet, @@GLOBAL.max_error_count; +END; +$$ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 stmt 31 "SET GLOBAL max_allowed_packet=16000000" +1 stmt 31 "SET GLOBAL max_error_count=60" +2 stmt 0 "SELECT @@GLOBAL.max_allowed_packet, @..." +DROP PROCEDURE p1; +# +# MDEV-19639 sql_mode=ORACLE: Wrong SHOW PROCEDURE output for sysvar:=expr +# +CREATE OR REPLACE PROCEDURE p1() AS +BEGIN +max_error_count:=10; +END; +$$ +SHOW PROCEDURE CODE p1; +Pos Instruction +0 stmt 31 "max_error_count:=10" +DROP PROCEDURE p1; diff --git a/mysql-test/suite/compat/oracle/t/sp-code.test b/mysql-test/suite/compat/oracle/t/sp-code.test index ea66ed80d2a..1ffd3b948e6 100644 --- a/mysql-test/suite/compat/oracle/t/sp-code.test +++ b/mysql-test/suite/compat/oracle/t/sp-code.test @@ -1055,3 +1055,34 @@ DELIMITER ;$$ SHOW PROCEDURE CODE p1; CALL p1(); DROP PROCEDURE p1; + +--echo # +--echo # MDEV-19640 Wrong SHOW PROCEDURE output for SET GLOBAL sysvar1=expr, sysvar2=expr +--echo # + +DELIMITER $$; +CREATE OR REPLACE PROCEDURE p1() AS +BEGIN + SET GLOBAL max_allowed_packet=16000000, max_error_count=60; + SELECT @@GLOBAL.max_allowed_packet, @@GLOBAL.max_error_count; +END; +$$ +DELIMITER ;$$ +SHOW PROCEDURE CODE p1; +DROP PROCEDURE p1; + +--echo # +--echo # MDEV-19639 sql_mode=ORACLE: Wrong SHOW PROCEDURE output for sysvar:=expr +--echo # + +DELIMITER $$; +CREATE OR REPLACE PROCEDURE p1() AS +BEGIN + max_error_count:=10; +END; +$$ +DELIMITER ;$$ +SHOW PROCEDURE CODE p1; +DROP PROCEDURE p1; + + diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 97e43ceaa90..c6140e35b24 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2023,7 +2023,7 @@ int Lex_input_stream::lex_one_token(YYSTYPE *yylval, THD *thd) next_state= MY_LEX_HOSTNAME; break; } - yylval->lex_str.str= (char*) get_ptr(); + yylval->lex_str.str= (char*) get_ptr() - 1; yylval->lex_str.length= 1; return((int) '@'); case MY_LEX_HOSTNAME: // end '@' of user@hostname @@ -5579,6 +5579,7 @@ void LEX::set_stmt_init() mysql_init_select(this); option_type= OPT_SESSION; autocommit= 0; + var_list.empty(); }; @@ -7574,7 +7575,7 @@ Item *LEX::create_item_ident_sp(THD *thd, Lex_ident_sys_st *name, -bool LEX::set_variable(const LEX_CSTRING *name, Item *item) +bool LEX::set_variable(const Lex_ident_sys_st *name, Item *item) { sp_pcontext *ctx; const Sp_rcontext_handler *rh; @@ -7588,8 +7589,8 @@ bool LEX::set_variable(const LEX_CSTRING *name, Item *item) Generate instructions for: SET x.y= expr; */ -bool LEX::set_variable(const LEX_CSTRING *name1, - const LEX_CSTRING *name2, +bool LEX::set_variable(const Lex_ident_sys_st *name1, + const Lex_ident_sys_st *name2, Item *item) { const Sp_rcontext_handler *rh; @@ -7619,10 +7620,10 @@ bool LEX::set_variable(const LEX_CSTRING *name1, bool LEX::set_default_system_variable(enum_var_type var_type, - const LEX_CSTRING *name, + const Lex_ident_sys_st *name, Item *val) { - static LEX_CSTRING default_base_name= {STRING_WITH_LEN("default")}; + static Lex_ident_sys default_base_name= {STRING_WITH_LEN("default")}; sys_var *var= find_sys_var(thd, name->str, name->length); if (!var) return true; @@ -7636,18 +7637,19 @@ bool LEX::set_default_system_variable(enum_var_type var_type, bool LEX::set_system_variable(enum_var_type var_type, - const LEX_CSTRING *name, + const Lex_ident_sys_st *name, Item *val) { sys_var *var= find_sys_var(thd, name->str, name->length); DBUG_ASSERT(thd->is_error() || var != NULL); - return likely(var) ? set_system_variable(var_type, var, &null_clex_str, val) : true; + static Lex_ident_sys null_str; + return likely(var) ? set_system_variable(var_type, var, &null_str, val) : true; } bool LEX::set_system_variable(THD *thd, enum_var_type var_type, - const LEX_CSTRING *name1, - const LEX_CSTRING *name2, + const Lex_ident_sys_st *name1, + const Lex_ident_sys_st *name2, Item *val) { sys_var *tmp; @@ -8328,15 +8330,15 @@ bool LEX::call_statement_start(THD *thd, sp_name *name) } -bool LEX::call_statement_start(THD *thd, const LEX_CSTRING *name) +bool LEX::call_statement_start(THD *thd, const Lex_ident_sys_st *name) { sp_name *spname= make_sp_name(thd, name); return unlikely(!spname) || call_statement_start(thd, spname); } -bool LEX::call_statement_start(THD *thd, const LEX_CSTRING *name1, - const LEX_CSTRING *name2) +bool LEX::call_statement_start(THD *thd, const Lex_ident_sys_st *name1, + const Lex_ident_sys_st *name2) { sp_name *spname= make_sp_name(thd, name1, name2); return unlikely(!spname) || call_statement_start(thd, spname); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index aaff2866b11..021eedb0a71 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -3741,15 +3741,15 @@ public: bool set_trigger_field(const LEX_CSTRING *name1, const LEX_CSTRING *name2, Item *val); bool set_system_variable(enum_var_type var_type, sys_var *var, - const LEX_CSTRING *base_name, Item *val); - bool set_system_variable(enum_var_type var_type, const LEX_CSTRING *name, - Item *val); + const Lex_ident_sys_st *base_name, Item *val); + bool set_system_variable(enum_var_type var_type, + const Lex_ident_sys_st *name, Item *val); bool set_system_variable(THD *thd, enum_var_type var_type, - const LEX_CSTRING *name1, - const LEX_CSTRING *name2, + const Lex_ident_sys_st *name1, + const Lex_ident_sys_st *name2, Item *val); bool set_default_system_variable(enum_var_type var_type, - const LEX_CSTRING *name, + const Lex_ident_sys_st *name, Item *val); bool set_user_variable(THD *thd, const LEX_CSTRING *name, Item *val); void set_stmt_init(); @@ -3779,9 +3779,9 @@ public: const char *body_start, const char *body_end); bool call_statement_start(THD *thd, sp_name *name); - bool call_statement_start(THD *thd, const LEX_CSTRING *name); - bool call_statement_start(THD *thd, const LEX_CSTRING *name1, - const LEX_CSTRING *name2); + bool call_statement_start(THD *thd, const Lex_ident_sys_st *name); + bool call_statement_start(THD *thd, const Lex_ident_sys_st *name1, + const Lex_ident_sys_st *name2); sp_variable *find_variable(const LEX_CSTRING *name, sp_pcontext **ctx, const Sp_rcontext_handler **rh) const; @@ -3791,9 +3791,9 @@ public: sp_pcontext *not_used_ctx; return find_variable(name, ¬_used_ctx, rh); } - bool set_variable(const LEX_CSTRING *name, Item *item); - bool set_variable(const LEX_CSTRING *name1, const LEX_CSTRING *name2, - Item *item); + bool set_variable(const Lex_ident_sys_st *name, Item *item); + bool set_variable(const Lex_ident_sys_st *name1, + const Lex_ident_sys_st *name2, Item *item); void sp_variable_declarations_init(THD *thd, int nvars); bool sp_variable_declarations_finalize(THD *thd, int nvars, const Column_definition *cdef, @@ -4439,6 +4439,12 @@ public: SELECT_LEX_UNIT *create_unit(SELECT_LEX*); SELECT_LEX *wrap_unit_into_derived(SELECT_LEX_UNIT *unit); SELECT_LEX *wrap_select_chain_into_derived(SELECT_LEX *sel); + void init_select() + { + current_select->init_select(); + wild= 0; + exchange= 0; + } bool main_select_push(); bool insert_select_hack(SELECT_LEX *sel); SELECT_LEX *create_priority_nest(SELECT_LEX *first_in_nest); @@ -4747,6 +4753,22 @@ public: }; +class sp_lex_set_var: public sp_lex_local +{ +public: + sp_lex_set_var(THD *thd, const LEX *oldlex) + :sp_lex_local(thd, oldlex) + { + // Set new LEX as if we at start of set rule + init_select(); + sql_command= SQLCOM_SET_OPTION; + var_list.empty(); + autocommit= 0; + option_type= oldlex->option_type; // Inherit from the outer lex + } +}; + + /** An assignment specific LEX, which additionally has an Item (an expression) and an associated with the Item free_list, which is usually freed @@ -4826,8 +4848,9 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr); Item* handle_sql2003_note184_exception(THD *thd, Item* left, bool equal, Item *expr); -void sp_create_assignment_lex(THD *thd, bool no_lookahead); -bool sp_create_assignment_instr(THD *thd, bool no_lookahead); +bool sp_create_assignment_lex(THD *thd, const char *pos); +bool sp_create_assignment_instr(THD *thd, bool no_lookahead, + bool need_set_keyword= true); void mark_or_conds_to_avoid_pushdown(Item *cond); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 05a34c03efc..8ec5741bc5f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -7760,10 +7760,7 @@ void THD::reset_for_next_command(bool do_clear_error) void mysql_init_select(LEX *lex) { - SELECT_LEX *select_lex= lex->current_select; - select_lex->init_select(); - lex->wild= 0; - lex->exchange= 0; + lex->init_select(); } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index e76e0c4f509..20946797a0c 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -289,7 +289,7 @@ int LEX::case_stmt_action_then() bool LEX::set_system_variable(enum enum_var_type var_type, - sys_var *sysvar, const LEX_CSTRING *base_name, + sys_var *sysvar, const Lex_ident_sys_st *base_name, Item *val) { set_var *setvar; @@ -506,34 +506,22 @@ Item* handle_sql2003_note184_exception(THD *thd, Item* left, bool equal, @see sp_create_assignment_instr @param thd Thread context - @param no_lookahead True if the parser has no lookahead + @param pos The position in the raw SQL buffer */ -void sp_create_assignment_lex(THD *thd, bool no_lookahead) -{ - LEX *lex= thd->lex; - if (lex->sphead) +bool sp_create_assignment_lex(THD *thd, const char *pos) +{ + if (thd->lex->sphead) { - Lex_input_stream *lip= &thd->m_parser_state->m_lip; - LEX *old_lex= lex; - lex->sphead->reset_lex(thd); - lex= thd->lex; - - /* Set new LEX as if we at start of set rule. */ - lex->sql_command= SQLCOM_SET_OPTION; - mysql_init_select(lex); - lex->var_list.empty(); - lex->autocommit= 0; - /* get_ptr() is only correct with no lookahead. */ - if (no_lookahead) - lex->sphead->m_tmp_query= lip->get_ptr(); - else - lex->sphead->m_tmp_query= lip->get_tok_end(); - /* Inherit from outer lex. */ - lex->option_type= old_lex->option_type; - lex->main_select_push(); + sp_lex_local *new_lex; + if (!(new_lex= new (thd->mem_root) sp_lex_set_var(thd, thd->lex)) || + new_lex->main_select_push()) + return true; + new_lex->sphead->m_tmp_query= pos; + return thd->lex->sphead->reset_lex(thd, new_lex); } + return false; } @@ -542,13 +530,15 @@ void sp_create_assignment_lex(THD *thd, bool no_lookahead) @see sp_create_assignment_lex - @param thd Thread context - @param no_lookahead True if the parser has no lookahead - + @param thd - Thread context + @param no_lookahead - True if the parser has no lookahead + @param need_set_keyword - if a SET statement "SET a=10", + or a direct assignment overwise "a:=10" @return false if success, true otherwise. */ -bool sp_create_assignment_instr(THD *thd, bool no_lookahead) +bool sp_create_assignment_instr(THD *thd, bool no_lookahead, + bool need_set_keyword) { LEX *lex= thd->lex; @@ -557,6 +547,24 @@ bool sp_create_assignment_instr(THD *thd, bool no_lookahead) if (!lex->var_list.is_empty()) { /* + - Every variable assignment from the same SET command, e.g.: + SET @var1=expr1, @var2=expr2; + produce each own sp_create_assignment_instr() call + lex->var_list.elements is 1 in this case. + - This query: + SET TRANSACTION READ ONLY, ISOLATION LEVEL SERIALIZABLE; + in translated to: + SET tx_read_only=1, tx_isolation=ISO_SERIALIZABLE; + but produces a single sp_create_assignment_instr() call + which includes the query fragment covering both options. + */ + DBUG_ASSERT(lex->var_list.elements >= 1 && lex->var_list.elements <= 2); + /* + sql_mode=ORACLE's direct assignment of a global variable + is not possible by the grammar. + */ + DBUG_ASSERT(Lex->option_type != OPT_GLOBAL || need_set_keyword); + /* We have assignment to user or system variable or option setting, so we should construct sp_instr_stmt for it. @@ -568,10 +576,15 @@ bool sp_create_assignment_instr(THD *thd, bool no_lookahead) end is either lip->ptr, if there was no lookahead, lip->tok_end otherwise. */ - static const LEX_CSTRING setsp= { STRING_WITH_LEN("SET ") }; + static const LEX_CSTRING setlc= { STRING_WITH_LEN("SET ") }; + static const LEX_CSTRING setgl= { STRING_WITH_LEN("SET GLOBAL ") }; const char *qend= no_lookahead ? lip->get_ptr() : lip->get_tok_end(); Lex_cstring qbuf(lex->sphead->m_tmp_query, qend); - if (lex->new_sp_instr_stmt(thd, setsp, qbuf)) + if (lex->new_sp_instr_stmt(thd, + Lex->option_type == OPT_GLOBAL ? setgl : + need_set_keyword ? setlc : + null_clex_str, + qbuf)) return true; } lex->pop_select(); @@ -820,7 +833,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); Currently there are 48 shift/reduce conflicts. We should not introduce new conflicts any more. */ -%expect 48 +%expect 47 /* Comments for TOKENS. @@ -842,6 +855,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); */ +%token <lex_str> '@' + /* Reserved keywords and operators */ @@ -874,7 +889,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token CASE_SYM /* SQL-2003-R */ %token CAST_SYM /* SQL-2003-R */ %token CHANGE -%token CHAR_SYM /* SQL-2003-R */ +%token <kwd> CHAR_SYM /* SQL-2003-R */ %token CHECK_SYM /* SQL-2003-R */ %token COLLATE_SYM /* SQL-2003-R */ %token CONDITION_SYM /* SQL-2003-R, SQL-2008-R */ @@ -903,7 +918,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token DECIMAL_SYM /* SQL-2003-R */ %token DECLARE_MARIADB_SYM /* SQL-2003-R */ %token DECLARE_ORACLE_SYM /* Oracle-R */ -%token DEFAULT /* SQL-2003-R */ +%token <kwd> DEFAULT /* SQL-2003-R */ %token DELETE_DOMAIN_ID_SYM %token DELETE_SYM /* SQL-2003-R */ %token DENSE_RANK_SYM @@ -1748,7 +1763,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ident label_ident sp_decl_ident - ident_set_usual_case ident_or_empty ident_table_alias ident_sysvar_name @@ -1766,6 +1780,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); IDENT_QUOTED IDENT_cli ident_cli + ident_cli_set_usual_case %type <kwd> keyword_data_type @@ -1782,6 +1797,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); keyword_sysvar_type keyword_table_alias keyword_verb_clause + charset %type <table> table_ident table_ident_nodb references xid @@ -2070,7 +2086,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); table_to_table_list table_to_table opt_table_list opt_as handler_rkey_function handler_read_or_scan single_multi table_wild_list table_wild_one opt_wild - opt_and charset + opt_and select_var_list select_var_list_init help opt_extended_describe shutdown opt_format_json @@ -7284,8 +7300,8 @@ type_with_opt_collate: ; charset: - CHAR_SYM SET {} - | CHARSET {} + CHAR_SYM SET { $$= $1; } + | CHARSET { $$= $1; } ; charset_name: @@ -15540,13 +15556,9 @@ ident_table_alias: } ; -ident_set_usual_case: - IDENT_sys - | keyword_set_usual_case - { - if (unlikely($$.copy_keyword(thd, &$1))) - MYSQL_YYABORT; - } +ident_cli_set_usual_case: + IDENT_cli { $$= $1; } + | keyword_set_usual_case { $$= $1; } ; ident_sysvar_name: @@ -16256,111 +16268,78 @@ set: if (lex->main_select_push()) MYSQL_YYABORT; lex->set_stmt_init(); - lex->var_list.empty(); - sp_create_assignment_lex(thd, yychar == YYEMPTY); } - start_option_value_list + set_param { Lex->pop_select(); //main select if (Lex->check_main_unit_semantics()) MYSQL_YYABORT; } - | SET STATEMENT_SYM + ; + +set_param: + option_value_no_option_type + | option_value_no_option_type ',' option_value_list + | TRANSACTION_SYM { - if (Lex->main_select_push()) + Lex->option_type= OPT_DEFAULT; + if (sp_create_assignment_lex(thd, $1.pos())) MYSQL_YYABORT; - Lex->set_stmt_init(); } - set_stmt_option_value_following_option_type_list + transaction_characteristics + { + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; + } + | option_type + { + Lex->option_type= $1; + } + start_option_value_list_following_option_type + | STATEMENT_SYM + set_stmt_option_list { LEX *lex= Lex; if (unlikely(lex->table_or_sp_used())) my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0), "SET STATEMENT")); lex->stmt_var_list= lex->var_list; lex->var_list.empty(); - Lex->pop_select(); //main select if (Lex->check_main_unit_semantics()) MYSQL_YYABORT; } FOR_SYM verb_clause - {} ; -set_stmt_option_value_following_option_type_list: +set_stmt_option_list: /* Only system variables can be used here. If this condition is changed please check careful code under lex->option_type == OPT_STATEMENT condition on wrong type casts. */ - option_value_following_option_type - | set_stmt_option_value_following_option_type_list ',' option_value_following_option_type + set_stmt_option + | set_stmt_option_list ',' set_stmt_option ; -/* Start of option value list */ -start_option_value_list: - option_value_no_option_type - { - if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) - MYSQL_YYABORT; - } - option_value_list_continued - | TRANSACTION_SYM - { - Lex->option_type= OPT_DEFAULT; - } - transaction_characteristics - { - if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) - MYSQL_YYABORT; - } - | option_type - { - Lex->option_type= $1; - } - start_option_value_list_following_option_type - ; - - /* Start of option value list, option_type was given */ start_option_value_list_following_option_type: option_value_following_option_type + | option_value_following_option_type ',' option_value_list + | TRANSACTION_SYM { - if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + if (sp_create_assignment_lex(thd, $1.pos())) MYSQL_YYABORT; } - option_value_list_continued - | TRANSACTION_SYM transaction_characteristics + transaction_characteristics { if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } ; -/* Remainder of the option value list after first option value. */ -option_value_list_continued: - /* empty */ - | ',' option_value_list - ; - /* Repeating list of option values after first option value. */ option_value_list: - { - sp_create_assignment_lex(thd, yychar == YYEMPTY); - } option_value - { - if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) - MYSQL_YYABORT; - } - | option_value_list ',' - { - sp_create_assignment_lex(thd, yychar == YYEMPTY); - } - option_value - { - if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) - MYSQL_YYABORT; - } + | option_value_list ',' option_value ; /* Wrapper around option values following the first option value in the stmt. */ @@ -16393,16 +16372,21 @@ opt_var_ident_type: | SESSION_SYM '.' { $$=OPT_SESSION; } ; -/* Option values with preceding option_type. */ -option_value_following_option_type: - ident equal set_expr_or_default +/* + SET STATEMENT options do not need their own LEX or Query_arena. + Let's put them to the main ones. +*/ +set_stmt_option: + ident_cli equal set_expr_or_default { - if (unlikely(Lex->set_system_variable(Lex->option_type, &$1, $3))) + Lex_ident_sys tmp(thd, &$1); + if (unlikely(Lex->set_system_variable(Lex->option_type, &tmp, $3))) MYSQL_YYABORT; } - | ident '.' ident equal set_expr_or_default + | ident_cli '.' ident equal set_expr_or_default { - if (unlikely(Lex->set_system_variable(thd, Lex->option_type, &$1, &$3, $5))) + Lex_ident_sys tmp(thd, &$1); + if (unlikely(Lex->set_system_variable(thd, Lex->option_type, &tmp, &$3, $5))) MYSQL_YYABORT; } | DEFAULT '.' ident equal set_expr_or_default @@ -16412,45 +16396,132 @@ option_value_following_option_type: } ; + +/* Option values with preceding option_type. */ +option_value_following_option_type: + ident_cli equal + { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; + } + set_expr_or_default + { + Lex_ident_sys tmp(thd, &$1); + if (unlikely(Lex->set_system_variable(Lex->option_type, &tmp, $4)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; + } + | ident_cli '.' ident equal + { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; + } + set_expr_or_default + { + Lex_ident_sys tmp(thd, &$1); + if (unlikely(Lex->set_system_variable(thd, Lex->option_type, &tmp, &$3, $6)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; + } + | DEFAULT '.' ident equal + { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; + } + set_expr_or_default + { + if (unlikely(Lex->set_default_system_variable(Lex->option_type, &$3, $6)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; + } + ; + /* Option values without preceding option_type. */ option_value_no_option_type: - ident_set_usual_case equal set_expr_or_default + ident_cli_set_usual_case equal { - if (unlikely(Lex->set_variable(&$1, $3))) + if (sp_create_assignment_lex(thd, $1.pos())) MYSQL_YYABORT; } - | ident '.' ident equal set_expr_or_default + set_expr_or_default { - if (unlikely(Lex->set_variable(&$1, &$3, $5))) + Lex_ident_sys tmp(thd, &$1); + if (unlikely(Lex->set_variable(&tmp, $4)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } - | DEFAULT '.' ident equal set_expr_or_default + | ident_cli_set_usual_case '.' ident equal { - if (unlikely(Lex->set_default_system_variable(Lex->option_type, &$3, $5))) + if (sp_create_assignment_lex(thd, $1.pos())) MYSQL_YYABORT; } - | '@' ident_or_text equal expr + set_expr_or_default { - if (unlikely(Lex->set_user_variable(thd, &$2, $4))) + Lex_ident_sys tmp(thd, &$1); + if (unlikely(Lex->set_variable(&tmp, &$3, $6)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } - | '@' '@' opt_var_ident_type ident_sysvar_name equal set_expr_or_default + | DEFAULT '.' ident equal { - if (unlikely(Lex->set_system_variable($3, &$4, $6))) + if (sp_create_assignment_lex(thd, $1.pos())) MYSQL_YYABORT; } - | '@' '@' opt_var_ident_type ident_sysvar_name '.' ident equal set_expr_or_default + set_expr_or_default { - if (unlikely(Lex->set_system_variable(thd, $3, &$4, &$6, $8))) + if (unlikely(Lex->set_default_system_variable(Lex->option_type, &$3, $6))) + MYSQL_YYABORT; + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } - | '@' '@' opt_var_ident_type DEFAULT '.' ident equal set_expr_or_default + | '@' ident_or_text equal + { + if (sp_create_assignment_lex(thd, $1.str)) + MYSQL_YYABORT; + } + expr { - if (unlikely(Lex->set_default_system_variable($3, &$6, $8))) + if (unlikely(Lex->set_user_variable(thd, &$2, $5)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; + } + | '@' '@' opt_var_ident_type ident_sysvar_name equal + { + if (sp_create_assignment_lex(thd, $1.str)) + MYSQL_YYABORT; + } + set_expr_or_default + { + if (unlikely(Lex->set_system_variable($3, &$4, $7)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; + } + | '@' '@' opt_var_ident_type ident_sysvar_name '.' ident equal + { + if (sp_create_assignment_lex(thd, $1.str)) + MYSQL_YYABORT; + } + set_expr_or_default + { + if (unlikely(Lex->set_system_variable(thd, $3, &$4, &$6, $9)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; + } + | '@' '@' opt_var_ident_type DEFAULT '.' ident equal + { + if (sp_create_assignment_lex(thd, $1.str)) + MYSQL_YYABORT; + } + set_expr_or_default + { + if (unlikely(Lex->set_default_system_variable($3, &$6, $9)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } | charset old_or_new_charset_name_or_default { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; LEX *lex= thd->lex; CHARSET_INFO *cs2; cs2= $2 ? $2: global_system_variables.character_set_client; @@ -16462,6 +16533,8 @@ option_value_no_option_type: if (unlikely(var == NULL)) MYSQL_YYABORT; lex->var_list.push_back(var, thd->mem_root); + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; } | NAMES_SYM equal expr { @@ -16476,6 +16549,8 @@ option_value_no_option_type: } | NAMES_SYM charset_name_or_default opt_collate { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; LEX *lex= Lex; CHARSET_INFO *cs2; CHARSET_INFO *cs3; @@ -16490,11 +16565,14 @@ option_value_no_option_type: set_var_collation_client *var; var= new (thd->mem_root) set_var_collation_client(cs3, cs3, cs3); if (unlikely(var == NULL) || - unlikely(lex->var_list.push_back(var, thd->mem_root))) + unlikely(lex->var_list.push_back(var, thd->mem_root)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } | DEFAULT ROLE_SYM grant_role { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; LEX *lex = Lex; LEX_USER *user; if (unlikely(!(user=(LEX_USER *) thd->calloc(sizeof(LEX_USER))))) @@ -16510,9 +16588,13 @@ option_value_no_option_type: thd->lex->autocommit= TRUE; if (lex->sphead) lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT; + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; } | DEFAULT ROLE_SYM grant_role FOR_SYM user { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; LEX *lex = Lex; set_var_default_role *var= (new (thd->mem_root) set_var_default_role($5, $3->user)); @@ -16522,22 +16604,36 @@ option_value_no_option_type: thd->lex->autocommit= TRUE; if (lex->sphead) lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT; + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; } | ROLE_SYM ident_or_text { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; LEX *lex = Lex; set_var_role *var= new (thd->mem_root) set_var_role($2); if (unlikely(var == NULL) || - unlikely(lex->var_list.push_back(var, thd->mem_root))) + unlikely(lex->var_list.push_back(var, thd->mem_root)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } - | ROLE_SYM equal set_expr_or_default + | ROLE_SYM equal { - if (unlikely(Lex->set_variable(&$1, $3))) + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; + } + set_expr_or_default + { + Lex_ident_sys tmp(thd, &$1); + if (unlikely(Lex->set_variable(&tmp, $4)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } | PASSWORD_SYM opt_for_user text_or_password { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; LEX *lex = Lex; set_var_password *var= (new (thd->mem_root) set_var_password(lex->definer)); @@ -16547,6 +16643,8 @@ option_value_no_option_type: lex->autocommit= TRUE; if (lex->sphead) lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT; + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; } ; diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index b5387a86fc2..719a6e39e2a 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -295,10 +295,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %parse-param { THD *thd } %lex-param { THD *thd } /* - Currently there are 49 shift/reduce conflicts. + Currently there are 48 shift/reduce conflicts. We should not introduce new conflicts any more. */ -%expect 49 +%expect 48 /* Comments for TOKENS. @@ -320,6 +320,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); */ +%token <lex_str> '@' + /* Reserved keywords and operators */ @@ -352,7 +354,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token CASE_SYM /* SQL-2003-R */ %token CAST_SYM /* SQL-2003-R */ %token CHANGE -%token CHAR_SYM /* SQL-2003-R */ +%token <kwd> CHAR_SYM /* SQL-2003-R */ %token CHECK_SYM /* SQL-2003-R */ %token COLLATE_SYM /* SQL-2003-R */ %token CONDITION_SYM /* SQL-2003-R, SQL-2008-R */ @@ -381,7 +383,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token DECIMAL_SYM /* SQL-2003-R */ %token DECLARE_MARIADB_SYM /* SQL-2003-R */ %token DECLARE_ORACLE_SYM /* Oracle-R */ -%token DEFAULT /* SQL-2003-R */ +%token <kwd> DEFAULT /* SQL-2003-R */ %token DELETE_DOMAIN_ID_SYM %token DELETE_SYM /* SQL-2003-R */ %token DENSE_RANK_SYM @@ -1228,7 +1230,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ident label_ident sp_decl_ident - ident_set_usual_case ident_or_empty ident_table_alias ident_sysvar_name @@ -1247,6 +1248,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); IDENT_QUOTED IDENT_cli ident_cli + ident_cli_set_usual_case + ident_cli_directly_assignable %type <kwd> keyword_data_type @@ -1264,6 +1267,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); keyword_table_alias keyword_verb_clause keyword_directly_assignable + charset %type <table> table_ident table_ident_nodb references xid @@ -1557,7 +1561,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); table_to_table_list table_to_table opt_table_list opt_as handler_rkey_function handler_read_or_scan single_multi table_wild_list table_wild_one opt_wild - opt_and charset + opt_and select_var_list select_var_list_init help opt_extended_describe shutdown opt_format_json @@ -4046,16 +4050,18 @@ sp_proc_stmt_if: sp_statement: statement - | ident_directly_assignable + | ident_cli_directly_assignable { // Direct procedure call (without the CALL keyword) - if (unlikely(Lex->call_statement_start(thd, &$1))) + Lex_ident_sys tmp(thd, &$1); + if (unlikely(Lex->call_statement_start(thd, &tmp))) MYSQL_YYABORT; } opt_sp_cparam_list - | ident_directly_assignable '.' ident + | ident_cli_directly_assignable '.' ident { - if (unlikely(Lex->call_statement_start(thd, &$1, &$3))) + Lex_ident_sys tmp(thd, &$1); + if (unlikely(Lex->call_statement_start(thd, &tmp, &$3))) MYSQL_YYABORT; } opt_sp_cparam_list @@ -7385,8 +7391,8 @@ sp_param_type_with_opt_collate: ; charset: - CHAR_SYM SET {} - | CHARSET {} + CHAR_SYM SET { $$= $1; } + | CHARSET { $$= $1; } ; charset_name: @@ -15672,13 +15678,9 @@ ident_table_alias: } ; -ident_set_usual_case: - IDENT_sys - | keyword_set_usual_case - { - if (unlikely($$.copy_keyword(thd, &$1))) - MYSQL_YYABORT; - } +ident_cli_set_usual_case: + IDENT_cli { $$= $1; } + | keyword_set_usual_case { $$= $1; } ; ident_sysvar_name: @@ -15715,6 +15717,12 @@ ident_directly_assignable: ; +ident_cli_directly_assignable: + IDENT_cli + | keyword_directly_assignable { $$= $1; } + ; + + label_ident: IDENT_sys | keyword_label @@ -16424,63 +16432,79 @@ set: if (lex->main_select_push()) MYSQL_YYABORT; lex->set_stmt_init(); - lex->var_list.empty(); - sp_create_assignment_lex(thd, yychar == YYEMPTY); } - start_option_value_list + set_param { Lex->pop_select(); //main select if (Lex->check_main_unit_semantics()) MYSQL_YYABORT; } - | SET STATEMENT_SYM + ; + +set_param: + option_value_no_option_type + | option_value_no_option_type ',' option_value_list + | TRANSACTION_SYM { - if (Lex->main_select_push()) + Lex->option_type= OPT_DEFAULT; + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; + } + transaction_characteristics + { + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; - Lex->set_stmt_init(); } - set_stmt_option_value_following_option_type_list + | option_type + { + Lex->option_type= $1; + } + start_option_value_list_following_option_type + | STATEMENT_SYM + set_stmt_option_list { LEX *lex= Lex; if (unlikely(lex->table_or_sp_used())) my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0), "SET STATEMENT")); lex->stmt_var_list= lex->var_list; lex->var_list.empty(); - Lex->pop_select(); //main select if (Lex->check_main_unit_semantics()) MYSQL_YYABORT; } FOR_SYM verb_clause - {} ; set_assign: - ident_directly_assignable SET_VAR + ident_cli_directly_assignable SET_VAR { LEX *lex=Lex; lex->set_stmt_init(); - lex->var_list.empty(); - sp_create_assignment_lex(thd, yychar == YYEMPTY); + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; } set_expr_or_default { - if (unlikely(Lex->set_variable(&$1, $4)) || - unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + Lex_ident_sys tmp(thd, &$1); + if (unlikely(Lex->set_variable(&tmp, $4)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY, + false))) MYSQL_YYABORT; } - | ident_directly_assignable '.' ident SET_VAR + | ident_cli_directly_assignable '.' ident SET_VAR { LEX *lex=Lex; lex->set_stmt_init(); - lex->var_list.empty(); - sp_create_assignment_lex(thd, yychar == YYEMPTY); + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; } set_expr_or_default { LEX *lex= Lex; DBUG_ASSERT(lex->var_list.is_empty()); - if (unlikely(lex->set_variable(&$1, &$3, $6)) || - unlikely(lex->sphead->restore_lex(thd))) + Lex_ident_sys tmp(thd, &$1); + if (unlikely(lex->set_variable(&tmp, &$3, $6)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY, + false))) MYSQL_YYABORT; } | COLON_ORACLE_SYM ident '.' ident SET_VAR @@ -16492,93 +16516,49 @@ set_assign: MYSQL_YYABORT; } lex->set_stmt_init(); - lex->var_list.empty(); - sp_create_assignment_lex(thd, yychar == YYEMPTY); + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; } set_expr_or_default { LEX_CSTRING tmp= { $2.str, $2.length }; if (unlikely(Lex->set_trigger_field(&tmp, &$4, $7)) || - unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY, + false))) MYSQL_YYABORT; } ; -set_stmt_option_value_following_option_type_list: +set_stmt_option_list: /* Only system variables can be used here. If this condition is changed please check careful code under lex->option_type == OPT_STATEMENT condition on wrong type casts. */ - option_value_following_option_type - | set_stmt_option_value_following_option_type_list ',' option_value_following_option_type + set_stmt_option + | set_stmt_option_list ',' set_stmt_option ; -/* Start of option value list */ -start_option_value_list: - option_value_no_option_type - { - if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) - MYSQL_YYABORT; - } - option_value_list_continued - | TRANSACTION_SYM - { - Lex->option_type= OPT_DEFAULT; - } - transaction_characteristics - { - if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) - MYSQL_YYABORT; - } - | option_type - { - Lex->option_type= $1; - } - start_option_value_list_following_option_type - ; - - /* Start of option value list, option_type was given */ start_option_value_list_following_option_type: option_value_following_option_type + | option_value_following_option_type ',' option_value_list + | TRANSACTION_SYM { - if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + if (sp_create_assignment_lex(thd, $1.pos())) MYSQL_YYABORT; } - option_value_list_continued - | TRANSACTION_SYM transaction_characteristics + transaction_characteristics { if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } ; -/* Remainder of the option value list after first option value. */ -option_value_list_continued: - /* empty */ - | ',' option_value_list - ; - /* Repeating list of option values after first option value. */ option_value_list: - { - sp_create_assignment_lex(thd, yychar == YYEMPTY); - } option_value - { - if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) - MYSQL_YYABORT; - } - | option_value_list ',' - { - sp_create_assignment_lex(thd, yychar == YYEMPTY); - } - option_value - { - if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) - MYSQL_YYABORT; - } + | option_value_list ',' option_value ; /* Wrapper around option values following the first option value in the stmt. */ @@ -16611,16 +16591,21 @@ opt_var_ident_type: | SESSION_SYM '.' { $$=OPT_SESSION; } ; -/* Option values with preceding option_type. */ -option_value_following_option_type: - ident equal set_expr_or_default +/* + SET STATEMENT options do not need their own LEX or Query_arena. + Let's put them to the main ones. +*/ +set_stmt_option: + ident_cli equal set_expr_or_default { - if (unlikely(Lex->set_system_variable(Lex->option_type, &$1, $3))) + Lex_ident_sys tmp(thd, &$1); + if (unlikely(Lex->set_system_variable(Lex->option_type, &tmp, $3))) MYSQL_YYABORT; } - | ident '.' ident equal set_expr_or_default + | ident_cli '.' ident equal set_expr_or_default { - if (unlikely(Lex->set_system_variable(thd, Lex->option_type, &$1, &$3, $5))) + Lex_ident_sys tmp(thd, &$1); + if (unlikely(Lex->set_system_variable(thd, Lex->option_type, &tmp, &$3, $5))) MYSQL_YYABORT; } | DEFAULT '.' ident equal set_expr_or_default @@ -16630,45 +16615,132 @@ option_value_following_option_type: } ; + +/* Option values with preceding option_type. */ +option_value_following_option_type: + ident_cli equal + { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; + } + set_expr_or_default + { + Lex_ident_sys tmp(thd, &$1); + if (unlikely(Lex->set_system_variable(Lex->option_type, &tmp, $4)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; + } + | ident_cli '.' ident equal + { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; + } + set_expr_or_default + { + Lex_ident_sys tmp(thd, &$1); + if (unlikely(Lex->set_system_variable(thd, Lex->option_type, &tmp, &$3, $6)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; + } + | DEFAULT '.' ident equal + { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; + } + set_expr_or_default + { + if (unlikely(Lex->set_default_system_variable(Lex->option_type, &$3, $6)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; + } + ; + /* Option values without preceding option_type. */ option_value_no_option_type: - ident_set_usual_case equal set_expr_or_default + ident_cli_set_usual_case equal { - if (unlikely(Lex->set_variable(&$1, $3))) + if (sp_create_assignment_lex(thd, $1.pos())) MYSQL_YYABORT; } - | ident '.' ident equal set_expr_or_default + set_expr_or_default { - if (unlikely(Lex->set_variable(&$1, &$3, $5))) + Lex_ident_sys tmp(thd, &$1); + if (unlikely(Lex->set_variable(&tmp, $4)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } - | DEFAULT '.' ident equal set_expr_or_default + | ident_cli_set_usual_case '.' ident equal { - if (unlikely(Lex->set_default_system_variable(Lex->option_type, &$3, $5))) + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; + } + set_expr_or_default + { + Lex_ident_sys tmp(thd, &$1); + if (unlikely(Lex->set_variable(&tmp, &$3, $6)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; + } + | DEFAULT '.' ident equal + { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; + } + set_expr_or_default + { + if (unlikely(Lex->set_default_system_variable(Lex->option_type, &$3, $6))) + MYSQL_YYABORT; + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } - | '@' ident_or_text equal expr + | '@' ident_or_text equal { - if (unlikely(Lex->set_user_variable(thd, &$2, $4))) + if (sp_create_assignment_lex(thd, $1.str)) MYSQL_YYABORT; } - | '@' '@' opt_var_ident_type ident_sysvar_name equal set_expr_or_default + expr + { + if (unlikely(Lex->set_user_variable(thd, &$2, $5)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; + } + | '@' '@' opt_var_ident_type ident_sysvar_name equal + { + if (sp_create_assignment_lex(thd, $1.str)) + MYSQL_YYABORT; + } + set_expr_or_default + { + if (unlikely(Lex->set_system_variable($3, &$4, $7)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; + } + | '@' '@' opt_var_ident_type ident_sysvar_name '.' ident equal { - if (unlikely(Lex->set_system_variable($3, &$4, $6))) + if (sp_create_assignment_lex(thd, $1.str)) MYSQL_YYABORT; } - | '@' '@' opt_var_ident_type ident_sysvar_name '.' ident equal set_expr_or_default + set_expr_or_default { - if (unlikely(Lex->set_system_variable(thd, $3, &$4, &$6, $8))) + if (unlikely(Lex->set_system_variable(thd, $3, &$4, &$6, $9)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } - | '@' '@' opt_var_ident_type DEFAULT '.' ident equal set_expr_or_default + | '@' '@' opt_var_ident_type DEFAULT '.' ident equal { - if (unlikely(Lex->set_default_system_variable($3, &$6, $8))) + if (sp_create_assignment_lex(thd, $1.str)) + MYSQL_YYABORT; + } + set_expr_or_default + { + if (unlikely(Lex->set_default_system_variable($3, &$6, $9)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } | charset old_or_new_charset_name_or_default { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; LEX *lex= thd->lex; CHARSET_INFO *cs2; cs2= $2 ? $2: global_system_variables.character_set_client; @@ -16680,6 +16752,8 @@ option_value_no_option_type: if (unlikely(var == NULL)) MYSQL_YYABORT; lex->var_list.push_back(var, thd->mem_root); + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; } | NAMES_SYM equal expr { @@ -16694,6 +16768,8 @@ option_value_no_option_type: } | NAMES_SYM charset_name_or_default opt_collate { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; LEX *lex= Lex; CHARSET_INFO *cs2; CHARSET_INFO *cs3; @@ -16708,11 +16784,14 @@ option_value_no_option_type: set_var_collation_client *var; var= new (thd->mem_root) set_var_collation_client(cs3, cs3, cs3); if (unlikely(var == NULL) || - unlikely(lex->var_list.push_back(var, thd->mem_root))) + unlikely(lex->var_list.push_back(var, thd->mem_root)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } | DEFAULT ROLE_SYM grant_role { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; LEX *lex = Lex; LEX_USER *user; if (unlikely(!(user=(LEX_USER *) thd->calloc(sizeof(LEX_USER))))) @@ -16728,9 +16807,13 @@ option_value_no_option_type: thd->lex->autocommit= TRUE; if (lex->sphead) lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT; + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; } | DEFAULT ROLE_SYM grant_role FOR_SYM user { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; LEX *lex = Lex; set_var_default_role *var= (new (thd->mem_root) set_var_default_role($5, $3->user)); @@ -16740,22 +16823,36 @@ option_value_no_option_type: thd->lex->autocommit= TRUE; if (lex->sphead) lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT; + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; } | ROLE_SYM ident_or_text { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; LEX *lex = Lex; set_var_role *var= new (thd->mem_root) set_var_role($2); if (unlikely(var == NULL) || - unlikely(lex->var_list.push_back(var, thd->mem_root))) + unlikely(lex->var_list.push_back(var, thd->mem_root)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; + } + | ROLE_SYM equal + { + if (sp_create_assignment_lex(thd, $1.pos())) MYSQL_YYABORT; } - | ROLE_SYM equal set_expr_or_default + set_expr_or_default { - if (unlikely(Lex->set_variable(&$1, $3))) + Lex_ident_sys tmp(thd, &$1); + if (unlikely(Lex->set_variable(&tmp, $4)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } | PASSWORD_SYM opt_for_user text_or_password { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; LEX *lex = Lex; set_var_password *var= (new (thd->mem_root) set_var_password(lex->definer)); @@ -16765,6 +16862,8 @@ option_value_no_option_type: lex->autocommit= TRUE; if (lex->sphead) lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT; + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; } ; |