summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/user_var.result1
-rw-r--r--mysql-test/t/user_var.test1
-rw-r--r--sql/set_var.h2
-rw-r--r--sql/sql_yacc.yy181
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;