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_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|
|
|||||||
#
|
#
|
||||||
# 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|
|
|||||||
#
|
#
|
||||||
# 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|
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
(*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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
{
|
{
|
||||||
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 @@ public:
|
|||||||
|
|
||||||
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:
|
|||||||
}
|
}
|
||||||
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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user