diff options
author | Alexander Barkov <bar@mariadb.org> | 2017-04-05 10:52:31 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2017-04-05 15:03:02 +0400 |
commit | e1cff0ac5dd583732bb693b1d6eca3376e41f69a (patch) | |
tree | 9be1b50103f815bfacdd8c7cabf1265a13e25385 /sql/sp_pcontext.h | |
parent | d433277f530689aa3869bad93ed6105e5e0cf954 (diff) | |
download | mariadb-git-e1cff0ac5dd583732bb693b1d6eca3376e41f69a.tar.gz |
MDEV-12441 Variables declared after cursors with parameters lose values
Parse context frames (sp_pcontext) can have holes in variable run-time offsets,
the missing offsets reside on the children contexts in such cases.
Example:
CREATE PROCEDURE p1() AS
x0 INT:=100; -- context 0, position 0, run-time 0
CURSOR cur(
p0 INT, -- context 1, position 0, run-time 1
p1 INT -- context 1, position 1, run-time 2
) IS SELECT p0, p1;
x1 INT:=101; -- context 0, position 1, run-time 3
BEGIN
...
END;
Fixing a few methods to take this into account:
- sp_pcontext::find_variable()
- sp_pcontext::retrieve_field_definitions()
- LEX::sp_variable_declarations_init()
- LEX::sp_variable_declarations_finalize()
- LEX::sp_variable_declarations_rowtype_finalize()
- LEX::sp_variable_declarations_with_ref_finalize()
Adding a convenience method:
sp_pcontext::get_last_context_variable(uint offset_from_the_end);
to access variables from the end, rather than from the beginning.
This helps to loop through the context variable array (m_vars)
on the fragment that does not have any holes.
Additionally, renaming sp_pcontext::find_context_variable() to
sp_pcontext::get_context_variable(). This method simply returns
the variable by its index. So let's rename to avoid assumptions
that some heavy lookup is going on inside.
Diffstat (limited to 'sql/sp_pcontext.h')
-rw-r--r-- | sql/sp_pcontext.h | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h index 98ab4955198..c6c8084fee2 100644 --- a/sql/sp_pcontext.h +++ b/sql/sp_pcontext.h @@ -440,15 +440,21 @@ public: { return m_vars.elements(); } /// return the i-th variable on the current context - sp_variable *find_context_variable(uint i) const + sp_variable *get_context_variable(uint i) const { DBUG_ASSERT(i < m_vars.elements()); return m_vars.at(i); } - /// @return map index in this parsing context to runtime offset. - uint var_context2runtime(uint i) const - { return m_var_offset + i; } + /* + Return the i-th last context variable. + If i is 0, then return the very last variable in m_vars. + */ + sp_variable *get_last_context_variable(uint i= 0) const + { + DBUG_ASSERT(i < m_vars.elements()); + return m_vars.at(m_vars.elements() - i - 1); + } /// Add SP-variable to the parsing context. /// |