summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <gshchepa/uchum@gleb.loc>2007-07-31 12:09:59 +0500
committerunknown <gshchepa/uchum@gleb.loc>2007-07-31 12:09:59 +0500
commit6312042ca7575ecbc2839cc07e6ba21a9c4ae56d (patch)
tree945e9b5bc53933eaf05007cb042ff06b2ea86aaf
parent03adaa85c4a95480661688f3af251ef4fa05c83f (diff)
parent33fc4ad4e124413ef617a1a073bb50135f6a12af (diff)
downloadmariadb-git-6312042ca7575ecbc2839cc07e6ba21a9c4ae56d.tar.gz
Merge gleb.loc:/home/uchum/work/bk/5.0-opt-30120
into gleb.loc:/home/uchum/work/bk/5.1-opt sql/item.cc: Auto merged sql/item.h: Auto merged sql/sp_head.cc: Auto merged sql/sql_yacc.yy: Auto merged mysql-test/r/sp.result: Merge with 5.0-opt. mysql-test/t/sp.test: Merge with 5.0-opt.
-rw-r--r--mysql-test/r/sp.result11
-rw-r--r--mysql-test/t/sp.test21
-rw-r--r--sql/item.cc4
-rw-r--r--sql/item.h11
-rw-r--r--sql/sp_head.cc2
-rw-r--r--sql/sql_yacc.yy3
6 files changed, 47 insertions, 5 deletions
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index a17c3e4492e..4ac88b995dd 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -6378,6 +6378,17 @@ Level Code Message
use test;
drop procedure sp_bug29050;
drop table t1;
+SET NAMES latin1;
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE бвд INT;
+SELECT бвд;
+END|
+CALL p1();
+бвд
+NULL
+SET NAMES default;
+DROP PROCEDURE p1;
drop procedure if exists proc_25411_a;
drop procedure if exists proc_25411_b;
drop procedure if exists proc_25411_c;
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index f834a57c5b1..46ef6bc6ddd 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -7365,6 +7365,27 @@ drop procedure sp_bug29050;
drop table t1;
#
+# Bug #30120 SP with local variables with non-ASCII names crashes server.
+#
+
+SET NAMES latin1;
+
+DELIMITER |;
+
+CREATE PROCEDURE p1()
+BEGIN
+ DECLARE бвд INT;
+ SELECT бвд;
+END|
+
+DELIMITER ;|
+
+CALL p1();
+
+SET NAMES default;
+DROP PROCEDURE p1;
+
+#
# Bug#25411 (trigger code truncated)
#
diff --git a/sql/item.cc b/sql/item.cc
index d6785461a7d..593915ef172 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1082,9 +1082,9 @@ bool Item_sp_variable::is_null()
Item_splocal::Item_splocal(const LEX_STRING &sp_var_name,
uint sp_var_idx,
enum_field_types sp_var_type,
- uint pos_in_q)
+ uint pos_in_q, uint len_in_q)
:Item_sp_variable(sp_var_name.str, sp_var_name.length),
- m_var_idx(sp_var_idx), pos_in_query(pos_in_q)
+ m_var_idx(sp_var_idx), pos_in_query(pos_in_q), len_in_query(len_in_q)
{
maybe_null= TRUE;
diff --git a/sql/item.h b/sql/item.h
index 5f4e0117d02..ab39505bf5f 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1054,9 +1054,18 @@ public:
SP variable in query text.
*/
uint pos_in_query;
+ /*
+ Byte length of SP variable name in the statement (see pos_in_query).
+ The value of this field may differ from the name_length value because
+ name_length contains byte length of UTF8-encoded item name, but
+ the query string (see sp_instr_stmt::m_query) is currently stored with
+ a charset from the SET NAMES statement.
+ */
+ uint len_in_query;
Item_splocal(const LEX_STRING &sp_var_name, uint sp_var_idx,
- enum_field_types sp_var_type, uint pos_in_q= 0);
+ enum_field_types sp_var_type,
+ uint pos_in_q= 0, uint len_in_q= 0);
bool is_splocal() { return 1; } /* Needed for error checking */
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 74714a42591..eab1228b880 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -927,7 +927,7 @@ subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str)
/* append the text between sp ref occurences */
res|= qbuf.append(cur + prev_pos, (*splocal)->pos_in_query - prev_pos);
- prev_pos= (*splocal)->pos_in_query + (*splocal)->m_name.length;
+ prev_pos= (*splocal)->pos_in_query + (*splocal)->len_in_query;
/* append the spvar substitute */
res|= qbuf.append(STRING_WITH_LEN(" NAME_CONST('"));
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 468c3305c57..5d665d5a6a2 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -9505,7 +9505,8 @@ simple_ident:
Item_splocal *splocal;
splocal= new Item_splocal($1, spv->offset, spv->type,
lip->get_tok_start_prev() -
- lex->sphead->m_tmp_query);
+ lex->sphead->m_tmp_query,
+ lip->tok_end - lip->tok_start_prev);
#ifndef DBUG_OFF
if (splocal)
splocal->m_sp= lex->sphead;