summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Shulga <dmitry.shulga@mariadb.com>2023-03-05 20:20:56 +0700
committerDmitry Shulga <dmitry.shulga@mariadb.com>2023-03-06 17:01:48 +0700
commit45ca4938c39590f893700c3ad6934e6dc2e56a18 (patch)
tree4b4d54259066741fedde13694d0e6f5cf0e5b156
parentc7fabfb91b224088ce371b09ff4199ec9062879d (diff)
downloadmariadb-git-45ca4938c39590f893700c3ad6934e6dc2e56a18.tar.gz
MDEV-5816: Stored programs: validation of stored program statements
Fixed an issue with wrong instantiation of sp_instr_stmt on re-parsing an assignment statement caused by changes in metadata of tables/routines that a user variable depends on. On re-parsing the statement 'SET @var=val' neither a new sp_instr_stmt instruction nor a new intance of sp_lex_set_var should be created but current instances be used. Fixed a typo in the comment at the implementation of the method sp_lex_instr::parse_expr
-rw-r--r--sql/sp_instr.cc2
-rw-r--r--sql/sql_lex.cc19
2 files changed, 20 insertions, 1 deletions
diff --git a/sql/sp_instr.cc b/sql/sp_instr.cc
index 7f1cd1c9ea5..de908ca361c 100644
--- a/sql/sp_instr.cc
+++ b/sql/sp_instr.cc
@@ -708,7 +708,7 @@ LEX* sp_lex_instr::parse_expr(THD *thd, sp_head *sp, LEX *sp_instr_lex)
Item **cursor_free_list= nullptr;
/*
- sp_instr_lex == nullptr for cursor relating SP instructions (sp_instr_cpush,
+ sp_instr_lex != nullptr for cursor relating SP instructions (sp_instr_cpush,
sp_instr_cursor_copy_struct) and in some cases for sp_instr_set.
*/
if (sp_instr_lex == nullptr)
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index d82db8d13a0..e17c4f99b4c 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -403,6 +403,15 @@ bool sp_create_assignment_lex(THD *thd, const char *pos)
{
if (thd->lex->sphead)
{
+ if (thd->lex->sphead->is_invoked())
+ /*
+ sphead->is_invoked() is true in case the assignment statement
+ is re-parsed. In this case, a new lex for re-parsing the statement
+ has been already created by sp_lex_instr::parse_expr and it should
+ be used for parsing the assignment SP instruction.
+ */
+ return false;
+
sp_lex_local *new_lex;
if (!(new_lex= new (thd->mem_root) sp_lex_set_var(thd, thd->lex)) ||
new_lex->main_select_push())
@@ -437,6 +446,16 @@ bool sp_create_assignment_instr(THD *thd, bool no_lookahead,
if (lex->sphead)
{
+ if (lex->sphead->is_invoked())
+ /*
+ Don't create a new SP assignment instruction in case the current
+ one is re-parsed by reasoning of metadata changes. Since in that case
+ a new lex is also not instantiated (@sa sp_create_assignment_lex)
+ it is safe to just return without restoring old lex that was active
+ before calling SP instruction.
+ */
+ return false;
+
if (!lex->var_list.is_empty())
{
/*