Commit 7577c8bf authored by bar@mysql.com's avatar bar@mysql.com

A fix according to Monty's request:

"uint *errors" is now a non-optional parameter in String:copy()
and copy_and_convert().
parent 64c59b37
...@@ -531,7 +531,8 @@ int Field_decimal::store(const char *from, uint len, CHARSET_INFO *cs) ...@@ -531,7 +531,8 @@ int Field_decimal::store(const char *from, uint len, CHARSET_INFO *cs)
/* Convert character set if the old one is multi byte */ /* Convert character set if the old one is multi byte */
if (cs->mbmaxlen > 1) if (cs->mbmaxlen > 1)
{ {
tmp.copy(from, len, cs, &my_charset_bin); uint dummy_errors;
tmp.copy(from, len, cs, &my_charset_bin, &dummy_errors);
from= tmp.ptr(); from= tmp.ptr();
len= tmp.length(); len= tmp.length();
} }
...@@ -5502,7 +5503,8 @@ int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs) ...@@ -5502,7 +5503,8 @@ int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs)
/* Convert character set if nesessary */ /* Convert character set if nesessary */
if (String::needs_conversion(length, cs, field_charset, &not_used)) if (String::needs_conversion(length, cs, field_charset, &not_used))
{ {
tmpstr.copy(from, length, cs, field_charset); uint dummy_errors;
tmpstr.copy(from, length, cs, field_charset, &dummy_errors);
from= tmpstr.ptr(); from= tmpstr.ptr();
length= tmpstr.length(); length= tmpstr.length();
} }
...@@ -5650,10 +5652,11 @@ void Field_enum::sql_type(String &res) const ...@@ -5650,10 +5652,11 @@ void Field_enum::sql_type(String &res) const
bool flag=0; bool flag=0;
for (const char **pos= typelib->type_names; *pos; pos++) for (const char **pos= typelib->type_names; *pos; pos++)
{ {
uint dummy_errors;
if (flag) if (flag)
res.append(','); res.append(',');
/* convert to res.charset() == utf8, then quote */ /* convert to res.charset() == utf8, then quote */
enum_item.copy(*pos, strlen(*pos), charset(), res.charset()); enum_item.copy(*pos, strlen(*pos), charset(), res.charset(), &dummy_errors);
append_unescaped(&res, enum_item.ptr(), enum_item.length()); append_unescaped(&res, enum_item.ptr(), enum_item.length());
flag= 1; flag= 1;
} }
...@@ -5684,7 +5687,8 @@ int Field_set::store(const char *from,uint length,CHARSET_INFO *cs) ...@@ -5684,7 +5687,8 @@ int Field_set::store(const char *from,uint length,CHARSET_INFO *cs)
/* Convert character set if nesessary */ /* Convert character set if nesessary */
if (String::needs_conversion(length, cs, field_charset, &not_used_offset)) if (String::needs_conversion(length, cs, field_charset, &not_used_offset))
{ {
tmpstr.copy(from, length, cs, field_charset); uint dummy_errors;
tmpstr.copy(from, length, cs, field_charset, &dummy_errors);
from= tmpstr.ptr(); from= tmpstr.ptr();
length= tmpstr.length(); length= tmpstr.length();
} }
...@@ -5760,10 +5764,11 @@ void Field_set::sql_type(String &res) const ...@@ -5760,10 +5764,11 @@ void Field_set::sql_type(String &res) const
bool flag=0; bool flag=0;
for (const char **pos= typelib->type_names; *pos; pos++) for (const char **pos= typelib->type_names; *pos; pos++)
{ {
uint dummy_errors;
if (flag) if (flag)
res.append(','); res.append(',');
/* convert to res.charset() == utf8, then quote */ /* convert to res.charset() == utf8, then quote */
set_item.copy(*pos, strlen(*pos), charset(), res.charset()); set_item.copy(*pos, strlen(*pos), charset(), res.charset(), &dummy_errors);
append_unescaped(&res, set_item.ptr(), set_item.length()); append_unescaped(&res, set_item.ptr(), set_item.length());
flag= 1; flag= 1;
} }
......
...@@ -818,7 +818,9 @@ bool Item_param::set_str(const char *str, ulong length) ...@@ -818,7 +818,9 @@ bool Item_param::set_str(const char *str, ulong length)
Assign string with no conversion: data is converted only after it's Assign string with no conversion: data is converted only after it's
been written to the binary log. been written to the binary log.
*/ */
if (str_value.copy(str, length, &my_charset_bin, &my_charset_bin)) uint dummy_errors;
if (str_value.copy(str, length, &my_charset_bin, &my_charset_bin,
&dummy_errors))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
state= STRING_VALUE; state= STRING_VALUE;
maybe_null= 0; maybe_null= 0;
......
...@@ -1832,8 +1832,9 @@ void Item_func_in::fix_length_and_dec() ...@@ -1832,8 +1832,9 @@ void Item_func_in::fix_length_and_dec()
{ {
Item_string *conv; Item_string *conv;
String tmp, cstr, *ostr= arg[0]->val_str(&tmp); String tmp, cstr, *ostr= arg[0]->val_str(&tmp);
uint dummy_errors;
cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(),
cmp_collation.collation); cmp_collation.collation, &dummy_errors);
conv= new Item_string(cstr.ptr(),cstr.length(), cstr.charset(), conv= new Item_string(cstr.ptr(),cstr.length(), cstr.charset(),
arg[0]->collation.derivation); arg[0]->collation.derivation);
conv->str_value.copy(); conv->str_value.copy();
......
...@@ -377,7 +377,10 @@ Item *create_func_space(Item *a) ...@@ -377,7 +377,10 @@ Item *create_func_space(Item *a)
{ {
sp= new Item_string("",0,cs); sp= new Item_string("",0,cs);
if (sp) if (sp)
sp->str_value.copy(" ",1,&my_charset_latin1,cs); {
uint dummy_errors;
sp->str_value.copy(" ", 1, &my_charset_latin1, cs, &dummy_errors);
}
} }
else else
{ {
......
...@@ -2906,8 +2906,9 @@ void Item_func_match::init_search(bool no_order) ...@@ -2906,8 +2906,9 @@ void Item_func_match::init_search(bool no_order)
if (ft_tmp->charset() != cmp_collation.collation) if (ft_tmp->charset() != cmp_collation.collation)
{ {
uint dummy_errors;
search_value.copy(ft_tmp->ptr(), ft_tmp->length(), ft_tmp->charset(), search_value.copy(ft_tmp->ptr(), ft_tmp->length(), ft_tmp->charset(),
cmp_collation.collation); cmp_collation.collation, &dummy_errors);
ft_tmp= &search_value; ft_tmp= &search_value;
} }
......
...@@ -2160,13 +2160,14 @@ String *Item_func_conv_charset::val_str(String *str) ...@@ -2160,13 +2160,14 @@ String *Item_func_conv_charset::val_str(String *str)
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
String *arg= args[0]->val_str(str); String *arg= args[0]->val_str(str);
uint dummy_errors;
if (!arg) if (!arg)
{ {
null_value=1; null_value=1;
return 0; return 0;
} }
null_value= str_value.copy(arg->ptr(),arg->length(),arg->charset(), null_value= str_value.copy(arg->ptr(),arg->length(),arg->charset(),
conv_charset); conv_charset, &dummy_errors);
return null_value ? 0 : &str_value; return null_value ? 0 : &str_value;
} }
...@@ -2249,11 +2250,12 @@ String *Item_func_charset::val_str(String *str) ...@@ -2249,11 +2250,12 @@ String *Item_func_charset::val_str(String *str)
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
String *res = args[0]->val_str(str); String *res = args[0]->val_str(str);
uint dummy_errors;
if ((null_value=(args[0]->null_value || !res->charset()))) if ((null_value=(args[0]->null_value || !res->charset())))
return 0; return 0;
str->copy(res->charset()->csname,strlen(res->charset()->csname), str->copy(res->charset()->csname,strlen(res->charset()->csname),
&my_charset_latin1, collation.collation); &my_charset_latin1, collation.collation, &dummy_errors);
return str; return str;
} }
...@@ -2261,11 +2263,12 @@ String *Item_func_collation::val_str(String *str) ...@@ -2261,11 +2263,12 @@ String *Item_func_collation::val_str(String *str)
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
String *res = args[0]->val_str(str); String *res = args[0]->val_str(str);
uint dummy_errors;
if ((null_value=(args[0]->null_value || !res->charset()))) if ((null_value=(args[0]->null_value || !res->charset())))
return 0; return 0;
str->copy(res->charset()->name,strlen(res->charset()->name), str->copy(res->charset()->name,strlen(res->charset()->name),
&my_charset_latin1, collation.collation); &my_charset_latin1, collation.collation, &dummy_errors);
return str; return str;
} }
......
...@@ -2121,8 +2121,10 @@ String *Item_char_typecast::val_str(String *str) ...@@ -2121,8 +2121,10 @@ String *Item_char_typecast::val_str(String *str)
else else
{ {
// Convert character set if differ // Convert character set if differ
uint dummy_errors;
if (!(res1= args[0]->val_str(&tmp_value)) || if (!(res1= args[0]->val_str(&tmp_value)) ||
str->copy(res1->ptr(), res1->length(),res1->charset(), cast_cs)) str->copy(res1->ptr(), res1->length(), res1->charset(),
cast_cs, &dummy_errors))
{ {
null_value= 1; null_value= 1;
return 0; return 0;
......
...@@ -713,7 +713,8 @@ bool Protocol::store_string_aux(const char *from, uint length, ...@@ -713,7 +713,8 @@ bool Protocol::store_string_aux(const char *from, uint length,
fromcs != &my_charset_bin && fromcs != &my_charset_bin &&
tocs != &my_charset_bin) tocs != &my_charset_bin)
{ {
return convert->copy(from, length, fromcs, tocs) || uint dummy_errors;
return convert->copy(from, length, fromcs, tocs, &dummy_errors) ||
net_store_data(convert->ptr(), convert->length()); net_store_data(convert->ptr(), convert->length());
} }
return net_store_data(from, length); return net_store_data(from, length);
......
...@@ -508,13 +508,14 @@ bool THD::convert_string(LEX_STRING *to, CHARSET_INFO *to_cs, ...@@ -508,13 +508,14 @@ bool THD::convert_string(LEX_STRING *to, CHARSET_INFO *to_cs,
{ {
DBUG_ENTER("convert_string"); DBUG_ENTER("convert_string");
size_s new_length= to_cs->mbmaxlen * from_length; size_s new_length= to_cs->mbmaxlen * from_length;
uint dummy_errors;
if (!(to->str= alloc(new_length+1))) if (!(to->str= alloc(new_length+1)))
{ {
to->length= 0; // Safety fix to->length= 0; // Safety fix
DBUG_RETURN(1); // EOM DBUG_RETURN(1); // EOM
} }
to->length= copy_and_convert((char*) to->str, new_length, to_cs, to->length= copy_and_convert((char*) to->str, new_length, to_cs,
from, from_length, from_cs); from, from_length, from_cs, &dummy_errors);
to->str[to->length]=0; // Safety to->str[to->length]=0; // Safety
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -537,7 +538,8 @@ bool THD::convert_string(LEX_STRING *to, CHARSET_INFO *to_cs, ...@@ -537,7 +538,8 @@ bool THD::convert_string(LEX_STRING *to, CHARSET_INFO *to_cs,
bool THD::convert_string(String *s, CHARSET_INFO *from_cs, CHARSET_INFO *to_cs) bool THD::convert_string(String *s, CHARSET_INFO *from_cs, CHARSET_INFO *to_cs)
{ {
if (convert_buffer.copy(s->ptr(), s->length(), from_cs, to_cs)) uint dummy_errors;
if (convert_buffer.copy(s->ptr(), s->length(), from_cs, to_cs, &dummy_errors))
return TRUE; return TRUE;
/* If convert_buffer >> s copying is more efficient long term */ /* If convert_buffer >> s copying is more efficient long term */
if (convert_buffer.alloced_length() >= convert_buffer.length() * 2 || if (convert_buffer.alloced_length() >= convert_buffer.length() * 2 ||
......
...@@ -882,18 +882,20 @@ static int check_connection(THD *thd) ...@@ -882,18 +882,20 @@ static int check_connection(THD *thd)
/* Since 4.1 all database names are stored in utf8 */ /* Since 4.1 all database names are stored in utf8 */
if (db) if (db)
{ {
uint dummy_errors;
db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1, db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
system_charset_info, system_charset_info,
db, strlen(db), db, strlen(db),
thd->charset())]= 0; thd->charset(), &dummy_errors)]= 0;
db= db_buff; db= db_buff;
} }
if (user) if (user)
{ {
uint dummy_errors;
user_buff[copy_and_convert(user_buff, sizeof(user_buff)-1, user_buff[copy_and_convert(user_buff, sizeof(user_buff)-1,
system_charset_info, user, strlen(user), system_charset_info, user, strlen(user),
thd->charset())]= '\0'; thd->charset(), &dummy_errors)]= '\0';
user= user_buff; user= user_buff;
} }
...@@ -1380,9 +1382,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1380,9 +1382,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
} }
#endif #endif
/* Convert database name to utf8 */ /* Convert database name to utf8 */
uint dummy_errors;
db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1, db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
system_charset_info, db, strlen(db), system_charset_info, db, strlen(db),
thd->charset())]= 0; thd->charset(), &dummy_errors)]= 0;
db= db_buff; db= db_buff;
/* Save user and privileges */ /* Save user and privileges */
...@@ -2066,8 +2069,12 @@ mysql_execute_command(THD *thd) ...@@ -2066,8 +2069,12 @@ mysql_execute_command(THD *thd)
} }
if (need_conversion) if (need_conversion)
query_len= copy_and_convert(query_str, query_len, to_cs, pstr->ptr(), {
pstr->length(), pstr->charset()); uint dummy_errors;
query_len= copy_and_convert(query_str, query_len, to_cs,
pstr->ptr(), pstr->length(),
pstr->charset(), &dummy_errors);
}
else else
memcpy(query_str, pstr->ptr(), pstr->length()); memcpy(query_str, pstr->ptr(), pstr->length());
query_str[query_len]= 0; query_str[query_len]= 0;
......
...@@ -752,8 +752,9 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, ...@@ -752,8 +752,9 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild,
String def(tmp1,sizeof(tmp1), system_charset_info); String def(tmp1,sizeof(tmp1), system_charset_info);
type.set(tmp, sizeof(tmp), field->charset()); type.set(tmp, sizeof(tmp), field->charset());
field->val_str(&type); field->val_str(&type);
uint dummy_errors;
def.copy(type.ptr(), type.length(), type.charset(), def.copy(type.ptr(), type.length(), type.charset(),
system_charset_info); system_charset_info, &dummy_errors);
protocol->store(def.ptr(), def.length(), def.charset()); protocol->store(def.ptr(), def.length(), def.charset());
} }
else if (field->unireg_check == Field::NEXT_NUMBER || else if (field->unireg_check == Field::NEXT_NUMBER ||
...@@ -1338,9 +1339,10 @@ store_create_info(THD *thd, TABLE *table, String *packet) ...@@ -1338,9 +1339,10 @@ store_create_info(THD *thd, TABLE *table, String *packet)
if (type.length()) if (type.length())
{ {
String def_val; String def_val;
uint dummy_errors;
/* convert to system_charset_info == utf8 */ /* convert to system_charset_info == utf8 */
def_val.copy(type.ptr(), type.length(), field->charset(), def_val.copy(type.ptr(), type.length(), field->charset(),
system_charset_info); system_charset_info, &dummy_errors);
append_unescaped(packet, def_val.ptr(), def_val.length()); append_unescaped(packet, def_val.ptr(), def_val.length());
} }
else else
......
...@@ -121,12 +121,13 @@ bool String::set(ulonglong num, CHARSET_INFO *cs) ...@@ -121,12 +121,13 @@ bool String::set(ulonglong num, CHARSET_INFO *cs)
bool String::set(double num,uint decimals, CHARSET_INFO *cs) bool String::set(double num,uint decimals, CHARSET_INFO *cs)
{ {
char buff[331]; char buff[331];
uint dummy_errors;
str_charset=cs; str_charset=cs;
if (decimals >= NOT_FIXED_DEC) if (decimals >= NOT_FIXED_DEC)
{ {
uint32 len= my_sprintf(buff,(buff, "%.14g",num));// Enough for a DATETIME uint32 len= my_sprintf(buff,(buff, "%.14g",num));// Enough for a DATETIME
return copy(buff, len, &my_charset_latin1, cs); return copy(buff, len, &my_charset_latin1, cs, &dummy_errors);
} }
#ifdef HAVE_FCONVERT #ifdef HAVE_FCONVERT
int decpt,sign; int decpt,sign;
...@@ -191,7 +192,8 @@ end: ...@@ -191,7 +192,8 @@ end:
#else #else
sprintf(buff,"%.*f",(int) decimals,num); sprintf(buff,"%.*f",(int) decimals,num);
#endif #endif
return copy(buff,(uint32) strlen(buff), &my_charset_latin1, cs); return copy(buff,(uint32) strlen(buff), &my_charset_latin1, cs,
&dummy_errors);
#endif #endif
} }
...@@ -336,13 +338,11 @@ bool String::copy(const char *str, uint32 arg_length, ...@@ -336,13 +338,11 @@ bool String::copy(const char *str, uint32 arg_length,
uint32 offset; uint32 offset;
if (!needs_conversion(arg_length, from_cs, to_cs, &offset)) if (!needs_conversion(arg_length, from_cs, to_cs, &offset))
{ {
if (errors)
*errors= 0; *errors= 0;
return copy(str, arg_length, to_cs); return copy(str, arg_length, to_cs);
} }
if ((from_cs == &my_charset_bin) && offset) if ((from_cs == &my_charset_bin) && offset)
{ {
if (errors)
*errors= 0; *errors= 0;
return copy_aligned(str, arg_length, offset, to_cs); return copy_aligned(str, arg_length, offset, to_cs);
} }
...@@ -382,7 +382,8 @@ bool String::set_ascii(const char *str, uint32 arg_length) ...@@ -382,7 +382,8 @@ bool String::set_ascii(const char *str, uint32 arg_length)
set(str, arg_length, str_charset); set(str, arg_length, str_charset);
return 0; return 0;
} }
return copy(str, arg_length, &my_charset_latin1, str_charset); uint dummy_errors;
return copy(str, arg_length, &my_charset_latin1, str_charset, &dummy_errors);
} }
...@@ -436,10 +437,12 @@ bool String::append(const char *s,uint32 arg_length) ...@@ -436,10 +437,12 @@ bool String::append(const char *s,uint32 arg_length)
if (str_charset->mbminlen > 1) if (str_charset->mbminlen > 1)
{ {
uint32 add_length=arg_length * str_charset->mbmaxlen; uint32 add_length=arg_length * str_charset->mbmaxlen;
uint dummy_errors;
if (realloc(str_length+ add_length)) if (realloc(str_length+ add_length))
return TRUE; return TRUE;
str_length+= copy_and_convert(Ptr+str_length, add_length, str_charset, str_length+= copy_and_convert(Ptr+str_length, add_length, str_charset,
s, arg_length, &my_charset_latin1); s, arg_length, &my_charset_latin1,
&dummy_errors);
return FALSE; return FALSE;
} }
...@@ -476,10 +479,11 @@ bool String::append(const char *s,uint32 arg_length, CHARSET_INFO *cs) ...@@ -476,10 +479,11 @@ bool String::append(const char *s,uint32 arg_length, CHARSET_INFO *cs)
if (needs_conversion(arg_length, cs, str_charset, &dummy_offset)) if (needs_conversion(arg_length, cs, str_charset, &dummy_offset))
{ {
uint32 add_length= arg_length / cs->mbminlen * str_charset->mbmaxlen; uint32 add_length= arg_length / cs->mbminlen * str_charset->mbmaxlen;
uint dummy_errors;
if (realloc(str_length + add_length)) if (realloc(str_length + add_length))
return TRUE; return TRUE;
str_length+= copy_and_convert(Ptr+str_length, add_length, str_charset, str_length+= copy_and_convert(Ptr+str_length, add_length, str_charset,
s, arg_length, cs); s, arg_length, cs, &dummy_errors);
} }
else else
{ {
...@@ -816,7 +820,6 @@ outp: ...@@ -816,7 +820,6 @@ outp:
else else
break; break;
} }
if (errors)
*errors= error_count; *errors= error_count;
return (uint32) (to - to_start); return (uint32) (to - to_start);
} }
......
...@@ -29,7 +29,7 @@ int sortcmp(const String *a,const String *b, CHARSET_INFO *cs); ...@@ -29,7 +29,7 @@ int sortcmp(const String *a,const String *b, CHARSET_INFO *cs);
String *copy_if_not_alloced(String *a,String *b,uint32 arg_length); String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
uint32 copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs, uint32 copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs,
const char *from, uint32 from_length, const char *from, uint32 from_length,
CHARSET_INFO *from_cs, uint *errors= 0); CHARSET_INFO *from_cs, uint *errors);
class String class String
{ {
...@@ -199,7 +199,7 @@ public: ...@@ -199,7 +199,7 @@ public:
CHARSET_INFO *cs); CHARSET_INFO *cs);
bool set_or_copy_aligned(const char *s, uint32 arg_length, CHARSET_INFO *cs); bool set_or_copy_aligned(const char *s, uint32 arg_length, CHARSET_INFO *cs);
bool copy(const char*s,uint32 arg_length, CHARSET_INFO *csfrom, bool copy(const char*s,uint32 arg_length, CHARSET_INFO *csfrom,
CHARSET_INFO *csto, uint *errors= 0); CHARSET_INFO *csto, uint *errors);
bool append(const String &s); bool append(const String &s);
bool append(const char *s); bool append(const char *s);
bool append(const char *s,uint32 arg_length); bool append(const char *s,uint32 arg_length);
......
...@@ -108,8 +108,11 @@ char *sql_strmake_with_convert(const char *str, uint32 arg_length, ...@@ -108,8 +108,11 @@ char *sql_strmake_with_convert(const char *str, uint32 arg_length,
memcpy(pos, str, new_length); memcpy(pos, str, new_length);
} }
else else
{
uint dummy_errors;
new_length= copy_and_convert((char*) pos, new_length, to_cs, str, new_length= copy_and_convert((char*) pos, new_length, to_cs, str,
arg_length, from_cs); arg_length, from_cs, &dummy_errors);
}
pos[new_length]= 0; pos[new_length]= 0;
*result_length= new_length; *result_length= new_length;
return pos; return pos;
......
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