summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/compat/oracle/r/sp-code.result133
-rw-r--r--mysql-test/suite/compat/oracle/r/sp-cursor.result89
-rw-r--r--mysql-test/suite/compat/oracle/t/sp-code.test84
-rw-r--r--mysql-test/suite/compat/oracle/t/sp-cursor.test96
-rw-r--r--sql/sp_head.cc2
-rw-r--r--sql/sp_head.h2
-rw-r--r--sql/sp_pcontext.cc79
-rw-r--r--sql/sp_pcontext.h14
-rw-r--r--sql/sql_lex.cc31
9 files changed, 499 insertions, 31 deletions
diff --git a/mysql-test/suite/compat/oracle/r/sp-code.result b/mysql-test/suite/compat/oracle/r/sp-code.result
index 4ac4b6115ff..9d1b2e3f3f5 100644
--- a/mysql-test/suite/compat/oracle/r/sp-code.result
+++ b/mysql-test/suite/compat/oracle/r/sp-code.result
@@ -1348,3 +1348,136 @@ rec1.a
rec2.a
11
DROP PROCEDURE p1;
+#
+# MDEV-12441 Variables declared after cursors with parameters lose values
+#
+CREATE PROCEDURE p1() AS
+x0 INT:=100;
+CURSOR cur(cp1 INT, cp2 INT) IS SELECT cp1+cp2;
+x1 INT:=101;
+BEGIN
+OPEN cur(10,11);
+CLOSE cur;
+SELECT x0, x1;
+END;
+$$
+SHOW PROCEDURE CODE p1;
+Pos Instruction
+0 set x0@0 100
+1 set x1@3 101
+2 cpush cur@0
+3 set cp1@1 10
+4 set cp2@2 11
+5 copen cur@0
+6 cclose cur@0
+7 stmt 0 "SELECT x0, x1"
+8 cpop 1
+CALL p1();
+x0 x1
+100 101
+DROP PROCEDURE p1;
+CREATE PROCEDURE p1() AS
+x0 INT:=100;
+CURSOR cur0(cp1 INT, cp2 INT) IS SELECT cp1+cp2;
+x1 INT:=101;
+CURSOR cur1(cp1 INT, cp2 INT) IS SELECT cp1+cp2;
+x2 INT:=102;
+CURSOR cur2(cp1 INT, cp2 INT) IS SELECT cp1+cp2;
+x3 INT:=103;
+BEGIN
+OPEN cur0(0,1);
+CLOSE cur0;
+SELECT x0, x1, x2, x3;
+OPEN cur1(10,11);
+CLOSE cur1;
+SELECT x0, x1, x2, x3;
+OPEN cur2(20,21);
+CLOSE cur2;
+SELECT x0, x1, x2, x3;
+END;
+$$
+SHOW PROCEDURE CODE p1;
+Pos Instruction
+0 set x0@0 100
+1 set x1@3 101
+2 set x2@6 102
+3 set x3@9 103
+4 cpush cur0@0
+5 cpush cur1@1
+6 cpush cur2@2
+7 set cp1@1 0
+8 set cp2@2 1
+9 copen cur0@0
+10 cclose cur0@0
+11 stmt 0 "SELECT x0, x1, x2, x3"
+12 set cp1@4 10
+13 set cp2@5 11
+14 copen cur1@1
+15 cclose cur1@1
+16 stmt 0 "SELECT x0, x1, x2, x3"
+17 set cp1@7 20
+18 set cp2@8 21
+19 copen cur2@2
+20 cclose cur2@2
+21 stmt 0 "SELECT x0, x1, x2, x3"
+22 cpop 3
+CALL p1();
+x0 x1 x2 x3
+100 101 102 103
+x0 x1 x2 x3
+100 101 102 103
+x0 x1 x2 x3
+100 101 102 103
+DROP PROCEDURE p1;
+CREATE TABLE t1 (a INT);
+CREATE PROCEDURE p1() AS
+x0 INT:=100;
+CURSOR cur(cp1 INT, cp2 INT) IS SELECT cp1+cp2;
+x1 t1.a%TYPE:=101;
+BEGIN
+OPEN cur(10,11);
+CLOSE cur;
+SELECT x0, x1;
+END;
+$$
+SHOW PROCEDURE CODE p1;
+Pos Instruction
+0 set x0@0 100
+1 set x1@3 101
+2 cpush cur@0
+3 set cp1@1 10
+4 set cp2@2 11
+5 copen cur@0
+6 cclose cur@0
+7 stmt 0 "SELECT x0, x1"
+8 cpop 1
+CALL p1();
+x0 x1
+100 101
+DROP PROCEDURE p1;
+DROP TABLE t1;
+CREATE PROCEDURE p1() AS
+x0 INT:=100;
+CURSOR cur(cp1 INT, cp2 INT) IS SELECT cp1+cp2;
+x1 ROW(a INT,b INT):=ROW(101,102);
+BEGIN
+OPEN cur(10,11);
+CLOSE cur;
+SELECT x0, x1.a, x1.b;
+END;
+$$
+SHOW PROCEDURE CODE p1;
+Pos Instruction
+0 set x0@0 100
+1 set x1@3 (101,102)
+2 cpush cur@0
+3 set cp1@1 10
+4 set cp2@2 11
+5 copen cur@0
+6 cclose cur@0
+7 stmt 0 "SELECT x0, x1.a, x1.b"
+8 cpop 1
+CALL p1();
+x0 x1.a x1.b
+100 101 102
+DROP PROCEDURE p1;
diff --git a/mysql-test/suite/compat/oracle/r/sp-cursor.result b/mysql-test/suite/compat/oracle/r/sp-cursor.result
index bfade1963c9..f50fb2c84e1 100644
--- a/mysql-test/suite/compat/oracle/r/sp-cursor.result
+++ b/mysql-test/suite/compat/oracle/r/sp-cursor.result
@@ -838,3 +838,92 @@ c
rec=(30,b30)
DROP PROCEDURE p1;
DROP TABLE t1;
+#
+# MDEV-12441 Variables declared after cursors with parameters lose values
+#
+CREATE PROCEDURE p1() AS
+x0 INT:=100;
+CURSOR cur(cp1 INT, cp2 INT) IS SELECT cp1+cp2;
+x1 INT:=101;
+BEGIN
+OPEN cur(10,11);
+CLOSE cur;
+SELECT x0, x1;
+END;
+$$
+CALL p1();
+x0 x1
+100 101
+DROP PROCEDURE p1;
+CREATE TABLE t1 (a INT);
+CREATE PROCEDURE p1() AS
+x0 INT:=100;
+CURSOR cur(cp1 INT, cp2 INT) IS SELECT cp1+cp2;
+x1 t1.a%TYPE:=101;
+BEGIN
+OPEN cur(10,11);
+CLOSE cur;
+SELECT x0, x1;
+END;
+$$
+CALL p1();
+x0 x1
+100 101
+DROP PROCEDURE p1;
+DROP TABLE t1;
+CREATE PROCEDURE p1() AS
+x0 INT:=100;
+CURSOR cur(cp1 INT, cp2 INT) IS SELECT cp1+cp2;
+x1 ROW(a INT,b INT):=ROW(101,102);
+BEGIN
+OPEN cur(10,11);
+CLOSE cur;
+SELECT x0, x1.a, x1.b;
+END;
+$$
+CALL p1();
+x0 x1.a x1.b
+100 101 102
+DROP PROCEDURE p1;
+CREATE TABLE t1 (a INT, b VARCHAR(10));
+INSERT INTO t1 VALUES (10,'Tbl-t1.b0');
+CREATE PROCEDURE p1() AS
+x0 INT:=100;
+CURSOR cur(cp1 INT, cp2 INT) IS SELECT a,b FROM t1;
+x1 t1%ROWTYPE:=ROW(101,'Var-x1.b0');
+BEGIN
+SELECT x0, x1.a, x1.b;
+OPEN cur(10,11);
+FETCH cur INTO x1;
+CLOSE cur;
+SELECT x0, x1.a, x1.b;
+END;
+$$
+CALL p1();
+x0 x1.a x1.b
+100 101 Var-x1.b0
+x0 x1.a x1.b
+100 10 Tbl-t1.b0
+DROP PROCEDURE p1;
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b VARCHAR(10));
+INSERT INTO t1 VALUES (10,'Tbl-t1.b0');
+CREATE PROCEDURE p1() AS
+x0 INT:=100;
+CURSOR cur(cp1 INT, cp2 INT) IS SELECT a,b FROM t1;
+x1 cur%ROWTYPE:=ROW(101,'Var-x1.b0');
+BEGIN
+SELECT x0, x1.a, x1.b;
+OPEN cur(10,11);
+FETCH cur INTO x1;
+CLOSE cur;
+SELECT x0, x1.a, x1.b;
+END;
+$$
+CALL p1();
+x0 x1.a x1.b
+100 101 Var-x1.b0
+x0 x1.a x1.b
+100 10 Tbl-t1.b0
+DROP PROCEDURE p1;
+DROP TABLE t1;
diff --git a/mysql-test/suite/compat/oracle/t/sp-code.test b/mysql-test/suite/compat/oracle/t/sp-code.test
index ce2cb011fda..9a1f64e54b4 100644
--- a/mysql-test/suite/compat/oracle/t/sp-code.test
+++ b/mysql-test/suite/compat/oracle/t/sp-code.test
@@ -971,3 +971,87 @@ DELIMITER ;$$
SHOW PROCEDURE CODE p1;
CALL p1();
DROP PROCEDURE p1;
+
+
+--echo #
+--echo # MDEV-12441 Variables declared after cursors with parameters lose values
+--echo #
+
+DELIMITER $$;
+CREATE PROCEDURE p1() AS
+ x0 INT:=100;
+ CURSOR cur(cp1 INT, cp2 INT) IS SELECT cp1+cp2;
+ x1 INT:=101;
+BEGIN
+ OPEN cur(10,11);
+ CLOSE cur;
+ SELECT x0, x1;
+END;
+$$
+DELIMITER ;$$
+SHOW PROCEDURE CODE p1;
+CALL p1();
+DROP PROCEDURE p1;
+
+
+DELIMITER $$;
+CREATE PROCEDURE p1() AS
+ x0 INT:=100;
+ CURSOR cur0(cp1 INT, cp2 INT) IS SELECT cp1+cp2;
+ x1 INT:=101;
+ CURSOR cur1(cp1 INT, cp2 INT) IS SELECT cp1+cp2;
+ x2 INT:=102;
+ CURSOR cur2(cp1 INT, cp2 INT) IS SELECT cp1+cp2;
+ x3 INT:=103;
+BEGIN
+ OPEN cur0(0,1);
+ CLOSE cur0;
+ SELECT x0, x1, x2, x3;
+ OPEN cur1(10,11);
+ CLOSE cur1;
+ SELECT x0, x1, x2, x3;
+ OPEN cur2(20,21);
+ CLOSE cur2;
+ SELECT x0, x1, x2, x3;
+END;
+$$
+DELIMITER ;$$
+SHOW PROCEDURE CODE p1;
+CALL p1();
+DROP PROCEDURE p1;
+
+
+CREATE TABLE t1 (a INT);
+DELIMITER $$;
+CREATE PROCEDURE p1() AS
+ x0 INT:=100;
+ CURSOR cur(cp1 INT, cp2 INT) IS SELECT cp1+cp2;
+ x1 t1.a%TYPE:=101;
+BEGIN
+ OPEN cur(10,11);
+ CLOSE cur;
+ SELECT x0, x1;
+END;
+$$
+DELIMITER ;$$
+SHOW PROCEDURE CODE p1;
+CALL p1();
+DROP PROCEDURE p1;
+DROP TABLE t1;
+
+
+DELIMITER $$;
+CREATE PROCEDURE p1() AS
+ x0 INT:=100;
+ CURSOR cur(cp1 INT, cp2 INT) IS SELECT cp1+cp2;
+ x1 ROW(a INT,b INT):=ROW(101,102);
+BEGIN
+ OPEN cur(10,11);
+ CLOSE cur;
+ SELECT x0, x1.a, x1.b;
+END;
+$$
+DELIMITER ;$$
+SHOW PROCEDURE CODE p1;
+CALL p1();
+DROP PROCEDURE p1;
diff --git a/mysql-test/suite/compat/oracle/t/sp-cursor.test b/mysql-test/suite/compat/oracle/t/sp-cursor.test
index 0be76053f88..ff9ad78e680 100644
--- a/mysql-test/suite/compat/oracle/t/sp-cursor.test
+++ b/mysql-test/suite/compat/oracle/t/sp-cursor.test
@@ -833,3 +833,99 @@ DELIMITER ;$$
CALL p1();
DROP PROCEDURE p1;
DROP TABLE t1;
+
+
+--echo #
+--echo # MDEV-12441 Variables declared after cursors with parameters lose values
+--echo #
+
+DELIMITER $$;
+CREATE PROCEDURE p1() AS
+ x0 INT:=100;
+ CURSOR cur(cp1 INT, cp2 INT) IS SELECT cp1+cp2;
+ x1 INT:=101;
+BEGIN
+ OPEN cur(10,11);
+ CLOSE cur;
+ SELECT x0, x1;
+END;
+$$
+DELIMITER ;$$
+CALL p1();
+DROP PROCEDURE p1;
+
+
+CREATE TABLE t1 (a INT);
+DELIMITER $$;
+CREATE PROCEDURE p1() AS
+ x0 INT:=100;
+ CURSOR cur(cp1 INT, cp2 INT) IS SELECT cp1+cp2;
+ x1 t1.a%TYPE:=101;
+BEGIN
+ OPEN cur(10,11);
+ CLOSE cur;
+ SELECT x0, x1;
+END;
+$$
+DELIMITER ;$$
+CALL p1();
+DROP PROCEDURE p1;
+DROP TABLE t1;
+
+
+DELIMITER $$;
+CREATE PROCEDURE p1() AS
+ x0 INT:=100;
+ CURSOR cur(cp1 INT, cp2 INT) IS SELECT cp1+cp2;
+ x1 ROW(a INT,b INT):=ROW(101,102);
+BEGIN
+ OPEN cur(10,11);
+ CLOSE cur;
+ SELECT x0, x1.a, x1.b;
+END;
+$$
+DELIMITER ;$$
+CALL p1();
+DROP PROCEDURE p1;
+
+
+CREATE TABLE t1 (a INT, b VARCHAR(10));
+INSERT INTO t1 VALUES (10,'Tbl-t1.b0');
+DELIMITER $$;
+CREATE PROCEDURE p1() AS
+ x0 INT:=100;
+ CURSOR cur(cp1 INT, cp2 INT) IS SELECT a,b FROM t1;
+ x1 t1%ROWTYPE:=ROW(101,'Var-x1.b0');
+BEGIN
+ SELECT x0, x1.a, x1.b;
+ OPEN cur(10,11);
+ FETCH cur INTO x1;
+ CLOSE cur;
+ SELECT x0, x1.a, x1.b;
+END;
+$$
+DELIMITER ;$$
+CALL p1();
+DROP PROCEDURE p1;
+DROP TABLE t1;
+
+
+CREATE TABLE t1 (a INT, b VARCHAR(10));
+INSERT INTO t1 VALUES (10,'Tbl-t1.b0');
+DELIMITER $$;
+CREATE PROCEDURE p1() AS
+ x0 INT:=100;
+ CURSOR cur(cp1 INT, cp2 INT) IS SELECT a,b FROM t1;
+ x1 cur%ROWTYPE:=ROW(101,'Var-x1.b0');
+BEGIN
+ SELECT x0, x1.a, x1.b;
+ OPEN cur(10,11);
+ FETCH cur INTO x1;
+ CLOSE cur;
+ SELECT x0, x1.a, x1.b;
+END;
+$$
+DELIMITER ;$$
+CALL p1();
+DROP PROCEDURE p1;
+DROP TABLE t1;
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 9bd10aac473..a9c89aef0a8 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -4746,7 +4746,7 @@ sp_head::add_set_for_loop_cursor_param_variables(THD *thd,
See more comments in LEX::sp_for_loop_cursor_declarations in sql_lex.cc.
*/
bool last= idx + 1 == parameters->argument_count();
- sp_variable *spvar= param_spcont->find_context_variable(idx);
+ sp_variable *spvar= param_spcont->get_context_variable(idx);
if (set_local_variable(thd, param_spcont,
spvar, parameters->arguments()[idx],
param_lex, last))
diff --git a/sql/sp_head.h b/sql/sp_head.h
index 9f42ad151aa..78ec6e0e5b0 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -399,7 +399,7 @@ private:
sp_assignment_lex *prm)
{
DBUG_ASSERT(idx < param_spcont->context_var_count());
- sp_variable *spvar= param_spcont->find_context_variable(idx);
+ sp_variable *spvar= param_spcont->get_context_variable(idx);
/*
add_instr() gets free_list from m_thd->free_list.
Initialize it before the set_local_variable() call.
diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc
index dd70c444d4e..93d7bc11281 100644
--- a/sql/sp_pcontext.cc
+++ b/sql/sp_pcontext.cc
@@ -222,10 +222,46 @@ sp_variable *sp_pcontext::find_variable(LEX_STRING name,
}
+/*
+ Find a variable by its run-time offset.
+ If the variable with a desired run-time offset is not found in this
+ context frame, it's recursively searched on parent context frames.
+
+ Note, context frames can have holes:
+ CREATE PROCEDURE p1() AS
+ x0 INT:=100;
+ CURSOR cur(p0 INT, p1 INT) IS SELECT p0, p1;
+ x1 INT:=101;
+ BEGIN
+ ...
+ END;
+ The variables (x0 and x1) and the cursor parameters (p0 and p1)
+ reside in separate parse context frames.
+
+ The variables reside on the top level parse context frame:
+ - x0 has frame offset 0 and run-time offset 0
+ - x1 has frame offset 1 and run-time offset 3
+
+ The cursor parameters reside on the second level parse context frame:
+ - p0 has frame offset 0 and run-time offset 1
+ - p1 has frame offset 1 and run-time offset 2
+
+ Run-time offsets on a frame can have holes, but offsets monotonocally grow,
+ so run-time offsets of all variables are not greater than the run-time offset
+ of the very last variable in this frame.
+*/
sp_variable *sp_pcontext::find_variable(uint offset) const
{
- if (m_var_offset <= offset && offset < m_var_offset + m_vars.elements())
- return m_vars.at(offset - m_var_offset); // This frame
+ if (m_var_offset <= offset &&
+ m_vars.elements() &&
+ offset <= get_last_context_variable()->offset)
+ {
+ for (uint i= 0; i < m_vars.elements(); i++)
+ {
+ if (m_vars.at(i)->offset == offset)
+ return m_vars.at(i); // This frame
+ }
+ }
return m_parent ?
m_parent->find_variable(offset) : // Some previous frame
@@ -236,7 +272,7 @@ sp_variable *sp_pcontext::find_variable(uint offset) const
sp_variable *sp_pcontext::add_variable(THD *thd, LEX_STRING name)
{
sp_variable *p=
- new (thd->mem_root) sp_variable(name, current_var_count());
+ new (thd->mem_root) sp_variable(name, m_var_offset + m_max_var_index);
if (!p)
return NULL;
@@ -593,16 +629,49 @@ void sp_pcontext::retrieve_field_definitions(
{
/* Put local/context fields in the result list. */
+ size_t next_child= 0;
for (size_t i= 0; i < m_vars.elements(); ++i)
{
sp_variable *var_def= m_vars.at(i);
+ /*
+ The context can have holes in 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;
+ See more comments in sp_pcontext::find_variable().
+ We must retrieve the definitions in the order of their run-time offsets.
+ Check that there are children that should go before the current variable.
+ */
+ for ( ; next_child < m_children.elements(); next_child++)
+ {
+ sp_pcontext *child= m_children.at(next_child);
+ if (!child->context_var_count() ||
+ child->get_context_variable(0)->offset > var_def->offset)
+ break;
+ /*
+ All variables on the embedded context (that fills holes of the parent)
+ should have the run-time offset strictly less than var_def.
+ */
+ DBUG_ASSERT(child->get_context_variable(0)->offset < var_def->offset);
+ DBUG_ASSERT(child->get_last_context_variable()->offset < var_def->offset);
+ child->retrieve_field_definitions(field_def_lst);
+ }
field_def_lst->push_back(&var_def->field_def);
}
- /* Put the fields of the enclosed contexts in the result list. */
+ /* Put the fields of the remaining enclosed contexts in the result list. */
- for (size_t i= 0; i < m_children.elements(); ++i)
+ for (size_t i= next_child; i < m_children.elements(); ++i)
m_children.at(i)->retrieve_field_definitions(field_def_lst);
}
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.
///
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index f79acbffa40..38a6e84f509 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -5211,10 +5211,7 @@ bool LEX::init_default_internal_variable(struct sys_var_with_base *variable,
void LEX::sp_variable_declarations_init(THD *thd, int nvars)
{
- // get the last variable:
- uint num_vars= spcont->context_var_count();
- uint var_idx= spcont->var_context2runtime(num_vars - 1);
- sp_variable *spvar= spcont->find_variable(var_idx);
+ sp_variable *spvar= spcont->get_last_context_variable();
sphead->reset_lex(thd);
spcont->declare_var_boundary(nvars);
@@ -5227,8 +5224,6 @@ bool LEX::sp_variable_declarations_finalize(THD *thd, int nvars,
Row_definition_list *row,
Item *dflt_value_item)
{
- uint num_vars= spcont->context_var_count();
-
if (!dflt_value_item &&
!(dflt_value_item= new (thd->mem_root) Item_null(thd)))
return true;
@@ -5248,11 +5243,10 @@ bool LEX::sp_variable_declarations_finalize(THD *thd, int nvars,
if (row && sphead->row_fill_field_definitions(thd, row))
return true;
- for (uint i= num_vars - nvars ; i < num_vars ; i++)
+ for (uint i= 0 ; i < (uint) nvars ; i++)
{
- uint var_idx= spcont->var_context2runtime(i);
- sp_variable *spvar= spcont->find_variable(var_idx);
- bool last= i == num_vars - 1;
+ sp_variable *spvar= spcont->get_last_context_variable((uint) nvars - 1 - i);
+ bool last= i + 1 == (uint) nvars;
if (!spvar)
return true;
@@ -5271,7 +5265,7 @@ bool LEX::sp_variable_declarations_finalize(THD *thd, int nvars,
/* The last instruction is responsible for freeing LEX. */
sp_instr_set *is= new (this->thd->mem_root)
sp_instr_set(sphead->instructions(),
- spcont, var_idx, dflt_value_item,
+ spcont, spvar->offset, dflt_value_item,
this, last);
if (is == NULL || sphead->add_instr(is))
return true;
@@ -5299,17 +5293,15 @@ LEX::sp_variable_declarations_rowtype_finalize(THD *thd, int nvars,
uint coffp;
const sp_pcursor *pcursor= ref->table.str && ref->db.str ? NULL :
spcont->find_cursor(ref->m_column, &coffp, false);
- uint num_vars= spcont->context_var_count();
if (!def && !(def= new (thd->mem_root) Item_null(thd)))
return true;
// Loop through all variables in the same declaration
- for (uint i= num_vars - nvars; i < num_vars; i++)
+ for (uint i= 0 ; i < (uint) nvars; i++)
{
- bool last= i == num_vars - 1;
- uint var_idx= spcont->var_context2runtime(i);
- sp_variable *spvar= spcont->find_context_variable(i);
+ bool last= i + 1 == (uint) nvars;
+ sp_variable *spvar= spcont->get_last_context_variable((uint) nvars - 1 - i);
if (pcursor)
{
@@ -5347,7 +5339,7 @@ LEX::sp_variable_declarations_rowtype_finalize(THD *thd, int nvars,
/* The last instruction is responsible for freeing LEX. */
sp_instr_set *is= new (this->thd->mem_root)
sp_instr_set(sphead->instructions(),
- spcont, var_idx, def,
+ spcont, spvar->offset, def,
this, last);
if (is == NULL || sphead->add_instr(is))
return true;
@@ -5364,10 +5356,9 @@ LEX::sp_variable_declarations_with_ref_finalize(THD *thd, int nvars,
Qualified_column_ident *ref,
Item *def)
{
- uint num_vars= spcont->context_var_count();
- for (uint i= num_vars - nvars; i < num_vars; i++)
+ for (uint i= 0 ; i < (uint) nvars; i++)
{
- sp_variable *spvar= spcont->find_context_variable(i);
+ sp_variable *spvar= spcont->get_last_context_variable((uint) nvars - 1 - i);
spvar->field_def.set_column_type_ref(ref);
spvar->field_def.field_name= spvar->name.str;
}