diff options
-rw-r--r-- | mysql-test/r/user_var.result | 1 | ||||
-rw-r--r-- | mysql-test/t/user_var.test | 1 | ||||
-rw-r--r-- | sql/set_var.h | 2 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 181 |
4 files changed, 106 insertions, 79 deletions
diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index d9a647ce2c3..df71c97033f 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -180,6 +180,7 @@ select coercibility(@v1),coercibility(@v2),coercibility(@v3),coercibility(@v4); coercibility(@v1) coercibility(@v2) coercibility(@v3) coercibility(@v4) 2 2 2 2 set session @honk=99; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@honk=99' at line 1 set one_shot @honk=99; ERROR HY000: The 'SET ONE_SHOT' syntax is reserved for purposes internal to the MySQL server set @first_var= NULL; diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test index b9d06558f34..f8c441c7564 100644 --- a/mysql-test/t/user_var.test +++ b/mysql-test/t/user_var.test @@ -116,6 +116,7 @@ select coercibility(@v1),coercibility(@v2),coercibility(@v3),coercibility(@v4); # # Bug #9286 SESSION/GLOBAL should be disallowed for user variables # +--error 1064 set session @honk=99; --error 1382 set one_shot @honk=99; diff --git a/sql/set_var.h b/sql/set_var.h index 32f45187124..7994244af20 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -32,7 +32,7 @@ extern TYPELIB bool_typelib, delay_key_write_typelib, sql_mode_typelib; enum enum_var_type { - OPT_DEFAULT, OPT_SESSION, OPT_GLOBAL + OPT_DEFAULT= 0, OPT_SESSION, OPT_GLOBAL }; typedef int (*sys_check_func)(THD *, set_var *); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 5bb8c6d8ff3..793bfdef37c 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -698,7 +698,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); opt_var_ident_type delete_option opt_temporary all_or_any opt_distinct opt_ignore_leaves fulltext_options spatial_type union_option start_transaction_opts opt_chain opt_release - union_opt select_derived_init + union_opt select_derived_init option_type option_type2 %type <ulong_num> ulong_num raid_types merge_insert_types @@ -7475,7 +7475,7 @@ option_type_value: lex->sphead->m_tmp_query= lex->tok_start; } } - option_type option_value + ext_option_value { LEX *lex= Lex; @@ -7516,11 +7516,15 @@ option_type_value: }; option_type: - /* empty */ {} - | GLOBAL_SYM { Lex->option_type= OPT_GLOBAL; } - | LOCAL_SYM { Lex->option_type= OPT_SESSION; } - | SESSION_SYM { Lex->option_type= OPT_SESSION; } - | ONE_SHOT_SYM { Lex->option_type= OPT_SESSION; Lex->one_shot_set= 1; } + option_type2 {} + | GLOBAL_SYM { $$=OPT_GLOBAL; } + | LOCAL_SYM { $$=OPT_SESSION; } + | SESSION_SYM { $$=OPT_SESSION; } + ; + +option_type2: + /* empty */ { $$= OPT_DEFAULT; } + | ONE_SHOT_SYM { Lex->one_shot_set= 1; $$= OPT_SESSION; } ; opt_var_type: @@ -7537,89 +7541,110 @@ opt_var_ident_type: | SESSION_SYM '.' { $$=OPT_SESSION; } ; -option_value: - '@' ident_or_text equal expr - { - Lex->var_list.push_back(new set_var_user(new Item_func_set_user_var($2,$4))); - } - | internal_variable_name equal set_expr_or_default - { - LEX *lex=Lex; +ext_option_value: + sys_option_value + | option_type2 option_value; - if ($1.var == &trg_new_row_fake_var) - { - /* We are in trigger and assigning value to field of new row */ - Item *it; - sp_instr_set_trigger_field *i; - if (lex->query_tables) - { - my_message(ER_SP_SUBSELECT_NYI, ER(ER_SP_SUBSELECT_NYI), - MYF(0)); - YYABORT; - } - if ($3) - it= $3; - else - { - /* QQ: Shouldn't this be field's default value ? */ - it= new Item_null(); - } - - if (!(i= new sp_instr_set_trigger_field( - lex->sphead->instructions(), lex->spcont, - $1.base_name, it))) - YYABORT; - - /* - Let us add this item to list of all Item_trigger_field - objects in trigger. - */ - lex->trg_table_fields.link_in_list((byte *)&i->trigger_field, - (byte **)&i->trigger_field.next_trg_field); +sys_option_value: + option_type internal_variable_name equal set_expr_or_default + { + LEX *lex=Lex; - lex->sphead->add_instr(i); + if ($2.var == &trg_new_row_fake_var) + { + /* We are in trigger and assigning value to field of new row */ + Item *it; + sp_instr_set_trigger_field *i; + if ($1) + { + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; } - else if ($1.var) - { /* System variable */ - lex->var_list.push_back(new set_var(lex->option_type, $1.var, - &$1.base_name, $3)); - } + if (lex->query_tables) + { + my_message(ER_SP_SUBSELECT_NYI, ER(ER_SP_SUBSELECT_NYI), + MYF(0)); + YYABORT; + } + if ($4) + it= $4; else - { - /* An SP local variable */ - sp_pcontext *ctx= lex->spcont; - sp_pvar_t *spv; - sp_instr_set *i; - Item *it; + { + /* QQ: Shouldn't this be field's default value ? */ + it= new Item_null(); + } - spv= ctx->find_pvar(&$1.base_name); + if (!(i= new sp_instr_set_trigger_field( + lex->sphead->instructions(), lex->spcont, + $2.base_name, it))) + YYABORT; - if ($3) - it= $3; - else if (spv->dflt) - it= spv->dflt; - else - it= new Item_null(); - i= new sp_instr_set(lex->sphead->instructions(), ctx, - spv->offset, it, spv->type, lex, TRUE); - lex->sphead->add_instr(i); - spv->isset= TRUE; - } - } + /* + Let us add this item to list of all Item_trigger_field + objects in trigger. + */ + lex->trg_table_fields.link_in_list((byte *)&i->trigger_field, + (byte **)&i->trigger_field.next_trg_field); + + lex->sphead->add_instr(i); + } + else if ($2.var) + { /* System variable */ + if ($1) + lex->option_type= (enum_var_type)$1; + lex->var_list.push_back(new set_var(lex->option_type, $2.var, + &$2.base_name, $4)); + } + else + { + /* An SP local variable */ + sp_pcontext *ctx= lex->spcont; + sp_pvar_t *spv; + sp_instr_set *i; + Item *it; + if ($1) + { + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + + spv= ctx->find_pvar(&$2.base_name); + + if ($4) + it= $4; + else if (spv->dflt) + it= spv->dflt; + else + it= new Item_null(); + i= new sp_instr_set(lex->sphead->instructions(), ctx, + spv->offset, it, spv->type, lex, TRUE); + lex->sphead->add_instr(i); + spv->isset= TRUE; + } + } + | option_type TRANSACTION_SYM ISOLATION LEVEL_SYM isolation_types + { + LEX *lex=Lex; + if (!$1) + lex->option_type= (enum_var_type)$1; + lex->var_list.push_back(new set_var(lex->option_type, + find_sys_var("tx_isolation"), + &null_lex_str, + new Item_int((int32) $5))); + } + ; + +option_value: + '@' ident_or_text equal expr + { + Lex->var_list.push_back(new set_var_user(new Item_func_set_user_var($2,$4))); + } | '@' '@' opt_var_ident_type internal_variable_name equal set_expr_or_default { LEX *lex=Lex; lex->var_list.push_back(new set_var((enum_var_type) $3, $4.var, &$4.base_name, $6)); } - | TRANSACTION_SYM ISOLATION LEVEL_SYM isolation_types - { - LEX *lex=Lex; - lex->var_list.push_back(new set_var(lex->option_type, - find_sys_var("tx_isolation"), - &null_lex_str, - new Item_int((int32) $4))); - } | charset old_or_new_charset_name_or_default { THD *thd= YYTHD; |