mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
A fix for MDEV-10411 Providing compatibility for basic PL/SQL constructs (Part 6: Assignment operator)
Fixed that a crash in this script: SET sql_mode=ORACLE; max_sort_length:= 1024;
This commit is contained in:
39
mysql-test/suite/compat/oracle/r/variables.result
Normal file
39
mysql-test/suite/compat/oracle/r/variables.result
Normal file
@ -0,0 +1,39 @@
|
||||
SET sql_mode=oracle;
|
||||
#
|
||||
# MDEV-10411 Providing compatibility for basic PL/SQL constructs
|
||||
# Part 6: Assignment operator
|
||||
#
|
||||
max_sort_length:=1030;
|
||||
SELECT @@max_sort_length;
|
||||
@@max_sort_length
|
||||
1030
|
||||
max_sort_length:=DEFAULT;
|
||||
#
|
||||
# Testing that SP variables shadow global variables in assignments
|
||||
#
|
||||
CREATE PROCEDURE p1
|
||||
AS
|
||||
BEGIN
|
||||
max_sort_length:=1030;
|
||||
DECLARE
|
||||
max_sort_length INT DEFAULT 1031;
|
||||
BEGIN
|
||||
SELECT @@max_sort_length, max_sort_length;
|
||||
max_sort_length:=1032;
|
||||
SELECT @@max_sort_length, max_sort_length;
|
||||
END;
|
||||
SELECT @@max_sort_length;
|
||||
max_sort_length:= DEFAULT;
|
||||
END;
|
||||
$$
|
||||
CALL p1();
|
||||
@@max_sort_length max_sort_length
|
||||
1030 1031
|
||||
@@max_sort_length max_sort_length
|
||||
1030 1032
|
||||
@@max_sort_length
|
||||
1030
|
||||
DROP PROCEDURE p1;
|
||||
#
|
||||
# End of MDEV-10411 Providing compatibility for basic PL/SQL constructs (part 6)
|
||||
#
|
38
mysql-test/suite/compat/oracle/t/variables.test
Normal file
38
mysql-test/suite/compat/oracle/t/variables.test
Normal file
@ -0,0 +1,38 @@
|
||||
SET sql_mode=oracle;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-10411 Providing compatibility for basic PL/SQL constructs
|
||||
--echo # Part 6: Assignment operator
|
||||
--echo #
|
||||
|
||||
max_sort_length:=1030;
|
||||
SELECT @@max_sort_length;
|
||||
max_sort_length:=DEFAULT;
|
||||
|
||||
--echo #
|
||||
--echo # Testing that SP variables shadow global variables in assignments
|
||||
--echo #
|
||||
|
||||
DELIMITER $$;
|
||||
CREATE PROCEDURE p1
|
||||
AS
|
||||
BEGIN
|
||||
max_sort_length:=1030;
|
||||
DECLARE
|
||||
max_sort_length INT DEFAULT 1031;
|
||||
BEGIN
|
||||
SELECT @@max_sort_length, max_sort_length;
|
||||
max_sort_length:=1032;
|
||||
SELECT @@max_sort_length, max_sort_length;
|
||||
END;
|
||||
SELECT @@max_sort_length;
|
||||
max_sort_length:= DEFAULT;
|
||||
END;
|
||||
$$
|
||||
DELIMITER ;$$
|
||||
CALL p1();
|
||||
DROP PROCEDURE p1;
|
||||
|
||||
--echo #
|
||||
--echo # End of MDEV-10411 Providing compatibility for basic PL/SQL constructs (part 6)
|
||||
--echo #
|
@ -5922,6 +5922,35 @@ bool LEX::add_resignal_statement(THD *thd, const sp_condition_value *v)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Perform assignment for a trigger, a system variable, or an SP variable.
|
||||
"variable" be previously set by init_internal_variable(variable, name).
|
||||
*/
|
||||
bool LEX::set_variable(struct sys_var_with_base *variable, Item *item)
|
||||
{
|
||||
if (variable->var == trg_new_row_fake_var)
|
||||
{
|
||||
/* We are in trigger and assigning value to field of new row */
|
||||
return set_trigger_new_row(&variable->base_name, item);
|
||||
}
|
||||
if (variable->var)
|
||||
{
|
||||
/* It is a system variable. */
|
||||
return set_system_variable(variable, option_type, item);
|
||||
}
|
||||
|
||||
/*
|
||||
spcont and spv should not be NULL, as the variable
|
||||
was previously checked by init_internal_variable().
|
||||
*/
|
||||
DBUG_ASSERT(spcont);
|
||||
sp_variable *spv= spcont->find_variable(variable->base_name, false);
|
||||
DBUG_ASSERT(spv);
|
||||
/* It is a local variable. */
|
||||
return set_local_variable(spv, item);
|
||||
}
|
||||
|
||||
|
||||
#ifdef MYSQL_SERVER
|
||||
uint binlog_unsafe_map[256];
|
||||
|
||||
|
@ -3104,6 +3104,7 @@ public:
|
||||
LEX_STRING dbname, LEX_STRING name);
|
||||
bool init_default_internal_variable(struct sys_var_with_base *variable,
|
||||
LEX_STRING name);
|
||||
bool set_variable(struct sys_var_with_base *variable, Item *item);
|
||||
void sp_variable_declarations_init(THD *thd, int nvars);
|
||||
bool sp_variable_declarations_finalize(THD *thd, int nvars,
|
||||
const Column_definition &cdef,
|
||||
|
@ -14709,30 +14709,9 @@ option_value_following_option_type:
|
||||
option_value_no_option_type:
|
||||
internal_variable_name equal set_expr_or_default
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
|
||||
if ($1.var == trg_new_row_fake_var)
|
||||
{
|
||||
/* We are in trigger and assigning value to field of new row */
|
||||
if (lex->set_trigger_new_row(&$1.base_name, $3))
|
||||
if (Lex->set_variable(&$1, $3))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
else if ($1.var)
|
||||
{
|
||||
/* It is a system variable. */
|
||||
if (lex->set_system_variable(&$1, lex->option_type, $3))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
else
|
||||
{
|
||||
sp_pcontext *spc= lex->spcont;
|
||||
sp_variable *spv= spc->find_variable($1.base_name, false);
|
||||
|
||||
/* It is a local variable. */
|
||||
if (lex->set_local_variable(spv, $3))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
}
|
||||
| '@' ident_or_text equal expr
|
||||
{
|
||||
Item_func_set_user_var *item;
|
||||
|
@ -14599,26 +14599,10 @@ set_assign:
|
||||
}
|
||||
set_expr_or_default
|
||||
{
|
||||
if ($1.var == trg_new_row_fake_var)
|
||||
{
|
||||
/* We are in trigger and assigning value to field of new row */
|
||||
if (Lex->set_trigger_new_row(&$1.base_name, $4) ||
|
||||
Lex->sphead->restore_lex(thd))
|
||||
if (Lex->set_variable(&$1, $4) ||
|
||||
sp_create_assignment_instr(thd, yychar == YYEMPTY))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
else
|
||||
{
|
||||
sp_pcontext *spc= Lex->spcont;
|
||||
sp_variable *spv= spc->find_variable($1.base_name, false);
|
||||
|
||||
/* It is a local variable. */
|
||||
if (Lex->set_local_variable(spv, $4))
|
||||
MYSQL_YYABORT;
|
||||
|
||||
if (sp_create_assignment_instr(thd, yychar == YYEMPTY))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
set_stmt_option_value_following_option_type_list:
|
||||
@ -14755,30 +14739,9 @@ option_value_following_option_type:
|
||||
option_value_no_option_type:
|
||||
internal_variable_name equal set_expr_or_default
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
|
||||
if ($1.var == trg_new_row_fake_var)
|
||||
{
|
||||
/* We are in trigger and assigning value to field of new row */
|
||||
if (lex->set_trigger_new_row(&$1.base_name, $3))
|
||||
if (Lex->set_variable(&$1, $3))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
else if ($1.var)
|
||||
{
|
||||
/* It is a system variable. */
|
||||
if (lex->set_system_variable(&$1, lex->option_type, $3))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
else
|
||||
{
|
||||
sp_pcontext *spc= lex->spcont;
|
||||
sp_variable *spv= spc->find_variable($1.base_name, false);
|
||||
|
||||
/* It is a local variable. */
|
||||
if (lex->set_local_variable(spv, $3))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
}
|
||||
| '@' ident_or_text equal expr
|
||||
{
|
||||
Item_func_set_user_var *item;
|
||||
|
Reference in New Issue
Block a user