summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/main/sp-code.result25
-rw-r--r--mysql-test/main/sp-code.test16
-rw-r--r--mysql-test/suite/compat/oracle/r/sp-code.result27
-rw-r--r--mysql-test/suite/compat/oracle/t/sp-code.test31
-rw-r--r--sql/sql_lex.cc28
-rw-r--r--sql/sql_lex.h51
-rw-r--r--sql/sql_parse.cc5
-rw-r--r--sql/sql_yacc.yy358
-rw-r--r--sql/sql_yacc_ora.yy335
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, &not_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;
}
;