Commit eb7319e8 authored by pem@mysql.comhem.se's avatar pem@mysql.comhem.se

Fixed BUG#2772: Function with character set clause fails in stored procedures.

Complex return types were not stored correctly in the mysql.proc table.
parent 95dcdde1
Branches unavailable
Tags unavailable
No related merge requests found
...@@ -1015,6 +1015,12 @@ call bUG3259_3()| ...@@ -1015,6 +1015,12 @@ call bUG3259_3()|
drop procedure bUg3259_1| drop procedure bUg3259_1|
drop procedure BuG3259_2| drop procedure BuG3259_2|
drop procedure BUG3259_3| drop procedure BUG3259_3|
create function bug2772() returns char(10) character set latin2
return 'a'|
select bug2772()|
bug2772()
a
drop function bug2772|
drop table if exists fac| drop table if exists fac|
create table fac (n int unsigned not null primary key, f bigint unsigned)| create table fac (n int unsigned not null primary key, f bigint unsigned)|
create procedure ifac(n int unsigned) create procedure ifac(n int unsigned)
......
...@@ -1152,7 +1152,6 @@ drop procedure bug2614| ...@@ -1152,7 +1152,6 @@ drop procedure bug2614|
# #
# BUG#2674 # BUG#2674
# #
create function bug2674 () returns int create function bug2674 () returns int
return @@sort_buffer_size| return @@sort_buffer_size|
...@@ -1165,7 +1164,6 @@ set @@sort_buffer_size = @osbs| ...@@ -1165,7 +1164,6 @@ set @@sort_buffer_size = @osbs|
# #
# BUG#3259 # BUG#3259
# #
create procedure bug3259_1 () begin end| create procedure bug3259_1 () begin end|
create procedure BUG3259_2 () begin end| create procedure BUG3259_2 () begin end|
create procedure Bug3259_3 () begin end| create procedure Bug3259_3 () begin end|
...@@ -1181,6 +1179,15 @@ drop procedure bUg3259_1| ...@@ -1181,6 +1179,15 @@ drop procedure bUg3259_1|
drop procedure BuG3259_2| drop procedure BuG3259_2|
drop procedure BUG3259_3| drop procedure BUG3259_3|
#
# BUG##2772
#
create function bug2772() returns char(10) character set latin2
return 'a'|
select bug2772()|
drop function bug2772|
# #
# Some "real" examples # Some "real" examples
......
...@@ -207,7 +207,7 @@ sp_head::operator delete(void *ptr, size_t size) ...@@ -207,7 +207,7 @@ sp_head::operator delete(void *ptr, size_t size)
sp_head::sp_head() sp_head::sp_head()
: Sql_alloc(), m_has_return(FALSE), m_simple_case(FALSE), : Sql_alloc(), m_has_return(FALSE), m_simple_case(FALSE),
m_multi_results(FALSE), m_free_list(NULL) m_multi_results(FALSE), m_free_list(NULL), m_returns_cs(NULL)
{ {
DBUG_ENTER("sp_head::sp_head"); DBUG_ENTER("sp_head::sp_head");
...@@ -228,6 +228,7 @@ sp_head::init(LEX *lex) ...@@ -228,6 +228,7 @@ sp_head::init(LEX *lex)
m_body.str= m_defstr.str= 0; m_body.str= m_defstr.str= 0;
m_qname.length= m_db.length= m_name.length= m_params.length= m_qname.length= m_db.length= m_name.length= m_params.length=
m_retstr.length= m_body.length= m_defstr.length= 0; m_retstr.length= m_body.length= m_defstr.length= 0;
m_returns_cs= NULL;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -266,7 +267,10 @@ sp_head::init_strings(THD *thd, LEX *lex, sp_name *name) ...@@ -266,7 +267,10 @@ sp_head::init_strings(THD *thd, LEX *lex, sp_name *name)
if (m_returns_begin && m_returns_end) if (m_returns_begin && m_returns_end)
{ {
/* QQ KLUDGE: We can't seem to cut out just the type in the parser /* QQ KLUDGE: We can't seem to cut out just the type in the parser
(without the RETURNS), so we'll have to do it here. :-( */ (without the RETURNS), so we'll have to do it here. :-(
Furthermore, if there's a character type as well, it's not include
(beyond the m_returns_end pointer), in which case we need
m_returns_cs. */
char *p= (char *)m_returns_begin+strspn((char *)m_returns_begin,"\t\n\r "); char *p= (char *)m_returns_begin+strspn((char *)m_returns_begin,"\t\n\r ");
p+= strcspn(p, "\t\n\r "); p+= strcspn(p, "\t\n\r ");
p+= strspn(p, "\t\n\r "); p+= strspn(p, "\t\n\r ");
...@@ -278,9 +282,22 @@ sp_head::init_strings(THD *thd, LEX *lex, sp_name *name) ...@@ -278,9 +282,22 @@ sp_head::init_strings(THD *thd, LEX *lex, sp_name *name)
(*p == '\t' || *p == '\n' || *p == '\r' || *p == ' ')) (*p == '\t' || *p == '\n' || *p == '\r' || *p == ' '))
p-= 1; p-= 1;
m_returns_end= (uchar *)p+1; m_returns_end= (uchar *)p+1;
m_retstr.length= m_returns_end - m_returns_begin; if (m_returns_cs)
m_retstr.str= strmake_root(root, {
(char *)m_returns_begin, m_retstr.length); String s((char *)m_returns_begin, m_returns_end - m_returns_begin,
system_charset_info);
s.append(' ');
s.append(m_returns_cs->csname);
m_retstr.length= s.length();
m_retstr.str= strmake_root(root, s.ptr(), m_retstr.length);
}
else
{
m_retstr.length= m_returns_end - m_returns_begin;
m_retstr.str= strmake_root(root,
(char *)m_returns_begin, m_retstr.length);
}
} }
m_body.length= lex->end_of_query - m_body_begin; m_body.length= lex->end_of_query - m_body_begin;
m_body.str= strmake_root(root, (char *)m_body_begin, m_body.length); m_body.str= strmake_root(root, (char *)m_body_begin, m_body.length);
...@@ -894,7 +911,7 @@ sp_instr_stmt::print(String *str) ...@@ -894,7 +911,7 @@ sp_instr_stmt::print(String *str)
{ {
str->reserve(12); str->reserve(12);
str->append("stmt "); str->append("stmt ");
str->qs_append(m_lex->sql_command); str->qs_append((uint)m_lex->sql_command);
} }
...@@ -1117,7 +1134,7 @@ sp_instr_freturn::print(String *str) ...@@ -1117,7 +1134,7 @@ sp_instr_freturn::print(String *str)
{ {
str->reserve(12); str->reserve(12);
str->append("freturn "); str->append("freturn ");
str->qs_append(m_type); str->qs_append((uint)m_type);
str->append(' '); str->append(' ');
m_value->print(str); m_value->print(str);
} }
......
...@@ -79,6 +79,7 @@ class sp_head : public Sql_alloc ...@@ -79,6 +79,7 @@ class sp_head : public Sql_alloc
int m_type; // TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE int m_type; // TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE
enum enum_field_types m_returns; // For FUNCTIONs only enum enum_field_types m_returns; // For FUNCTIONs only
CHARSET_INFO *m_returns_cs; // For FUNCTIONs only
my_bool m_has_return; // For FUNCTIONs only my_bool m_has_return; // For FUNCTIONs only
my_bool m_simple_case; // TRUE if parsing simple case, FALSE otherwise my_bool m_simple_case; // TRUE if parsing simple case, FALSE otherwise
my_bool m_multi_results; // TRUE if a procedure with SELECT(s) my_bool m_multi_results; // TRUE if a procedure with SELECT(s)
......
...@@ -1145,14 +1145,20 @@ create_function_tail: ...@@ -1145,14 +1145,20 @@ create_function_tail:
} }
RETURNS_SYM RETURNS_SYM
{ {
Lex->sphead->m_returns_begin= Lex->tok_start; LEX *lex= Lex;
sp_head *sp= lex->sphead;
sp->m_returns_begin= lex->tok_start;
sp->m_returns_cs= lex->charset= NULL;
} }
type type
{ {
LEX *lex= Lex; LEX *lex= Lex;
sp_head *sp= lex->sphead;
lex->sphead->m_returns_end= lex->tok_start; sp->m_returns_end= lex->tok_start;
lex->sphead->m_returns= (enum enum_field_types)$8; sp->m_returns= (enum enum_field_types)$8;
sp->m_returns_cs= lex->charset;
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics)); bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
} }
sp_c_chistics sp_c_chistics
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment