Fixed BUG#2772: Function with character set clause fails in stored procedures.
Complex return types were not stored correctly in the mysql.proc table.
This commit is contained in:
parent
95dcdde134
commit
eb7319e850
@ -1015,6 +1015,12 @@ call bUG3259_3()|
|
||||
drop procedure bUg3259_1|
|
||||
drop procedure BuG3259_2|
|
||||
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|
|
||||
create table fac (n int unsigned not null primary key, f bigint unsigned)|
|
||||
create procedure ifac(n int unsigned)
|
||||
|
@ -1152,7 +1152,6 @@ drop procedure bug2614|
|
||||
#
|
||||
# BUG#2674
|
||||
#
|
||||
|
||||
create function bug2674 () returns int
|
||||
return @@sort_buffer_size|
|
||||
|
||||
@ -1165,7 +1164,6 @@ set @@sort_buffer_size = @osbs|
|
||||
#
|
||||
# BUG#3259
|
||||
#
|
||||
|
||||
create procedure bug3259_1 () begin end|
|
||||
create procedure BUG3259_2 () begin end|
|
||||
create procedure Bug3259_3 () begin end|
|
||||
@ -1181,6 +1179,15 @@ drop procedure bUg3259_1|
|
||||
drop procedure BuG3259_2|
|
||||
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
|
||||
|
@ -207,7 +207,7 @@ sp_head::operator delete(void *ptr, size_t size)
|
||||
|
||||
sp_head::sp_head()
|
||||
: 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");
|
||||
|
||||
@ -228,6 +228,7 @@ sp_head::init(LEX *lex)
|
||||
m_body.str= m_defstr.str= 0;
|
||||
m_qname.length= m_db.length= m_name.length= m_params.length=
|
||||
m_retstr.length= m_body.length= m_defstr.length= 0;
|
||||
m_returns_cs= NULL;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
@ -266,7 +267,10 @@ sp_head::init_strings(THD *thd, LEX *lex, sp_name *name)
|
||||
if (m_returns_begin && m_returns_end)
|
||||
{
|
||||
/* 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 ");
|
||||
p+= strcspn(p, "\t\n\r ");
|
||||
p+= strspn(p, "\t\n\r ");
|
||||
@ -278,10 +282,23 @@ sp_head::init_strings(THD *thd, LEX *lex, sp_name *name)
|
||||
(*p == '\t' || *p == '\n' || *p == '\r' || *p == ' '))
|
||||
p-= 1;
|
||||
m_returns_end= (uchar *)p+1;
|
||||
if (m_returns_cs)
|
||||
{
|
||||
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.str= strmake_root(root, (char *)m_body_begin, m_body.length);
|
||||
m_defstr.length= lex->end_of_query - lex->buf;
|
||||
@ -894,7 +911,7 @@ sp_instr_stmt::print(String *str)
|
||||
{
|
||||
str->reserve(12);
|
||||
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)
|
||||
{
|
||||
str->reserve(12);
|
||||
str->append("freturn ");
|
||||
str->qs_append(m_type);
|
||||
str->qs_append((uint)m_type);
|
||||
str->append(' ');
|
||||
m_value->print(str);
|
||||
}
|
||||
|
@ -79,6 +79,7 @@ public:
|
||||
|
||||
int m_type; // TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE
|
||||
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_simple_case; // TRUE if parsing simple case, FALSE otherwise
|
||||
my_bool m_multi_results; // TRUE if a procedure with SELECT(s)
|
||||
|
@ -1145,14 +1145,20 @@ create_function_tail:
|
||||
}
|
||||
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
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
sp_head *sp= lex->sphead;
|
||||
|
||||
lex->sphead->m_returns_end= lex->tok_start;
|
||||
lex->sphead->m_returns= (enum enum_field_types)$8;
|
||||
sp->m_returns_end= lex->tok_start;
|
||||
sp->m_returns= (enum enum_field_types)$8;
|
||||
sp->m_returns_cs= lex->charset;
|
||||
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
|
||||
}
|
||||
sp_c_chistics
|
||||
|
Loading…
x
Reference in New Issue
Block a user