diff options
author | Dmitry Shulga <dmitry.shulga@mariadb.com> | 2023-03-05 20:20:56 +0700 |
---|---|---|
committer | Dmitry Shulga <dmitry.shulga@mariadb.com> | 2023-03-06 17:01:48 +0700 |
commit | 45ca4938c39590f893700c3ad6934e6dc2e56a18 (patch) | |
tree | 4b4d54259066741fedde13694d0e6f5cf0e5b156 | |
parent | c7fabfb91b224088ce371b09ff4199ec9062879d (diff) | |
download | mariadb-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.cc | 2 | ||||
-rw-r--r-- | sql/sql_lex.cc | 19 |
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()) { /* |