Below is the list of changes that have just been committed into a local
4.1 repository of bar. When bar does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://www.mysql.com/doc/I/n/Installing_source_tree.html
ChangeSet
1.1592 03/09/25 17:31:20 bar@xxxxxxxxxxxxxxxx +2 -0
LPAD() and RPAD() are now multibyte-compatible
sql/item_strfunc.cc
1.138 03/09/25 17:31:18 bar@xxxxxxxxxxxxxxxx +60 -55
LPAD() and RPAD() are now multibyte-compatible
mysql-test/r/func_str.result
1.43 03/09/25 17:31:18 bar@xxxxxxxxxxxxxxxx +1 -1
LPAD() and RPAD() are now multibyte-compatible
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: bar
# Host: bar.mysql.r18.ru
# Root: /usr/home/bar/mysql-4.1
--- 1.137/sql/item_strfunc.cc Wed Sep 24 11:14:55 2003
+++ 1.138/sql/item_strfunc.cc Thu Sep 25 17:31:18 2003
@@ -1885,7 +1885,7 @@
if (args[1]->const_item())
{
- uint32 length= (uint32) args[1]->val_int();
+ uint32 length= (uint32) args[1]->val_int() * collation.collation->mbmaxlen;
max_length=max(args[0]->max_length,length);
if (max_length >= MAX_BLOB_WIDTH)
{
@@ -1903,36 +1903,46 @@
String *Item_func_rpad::val_str(String *str)
{
- uint32 res_length,length_pad;
+ uint32 res_byte_length,res_char_length,pad_char_length,pad_byte_length;
char *to;
const char *ptr_pad;
int32 count= (int32) args[1]->val_int();
+ int32 byte_count= count * collation.collation->mbmaxlen;
String *res =args[0]->val_str(str);
String *rpad = args[2]->val_str(str);
if (!res || args[1]->null_value || !rpad || count < 0)
goto err;
null_value=0;
- if (count <= (int32) (res_length=res->length()))
+ if (count <= (int32) (res_char_length=res->numchars()))
{ // String to pad is big enough
- res->length(count); // Shorten result if
longer
+ res->length(res->charpos(count)); // Shorten result if longer
return (res);
}
- length_pad= rpad->length();
- if ((ulong) count > current_thd->variables.max_allowed_packet ||
- args[2]->null_value || !length_pad)
+ pad_char_length= rpad->numchars();
+ if ((ulong) byte_count > current_thd->variables.max_allowed_packet ||
+ args[2]->null_value || !pad_char_length)
goto err;
- if (!(res= alloc_buffer(res,str,&tmp_value,count)))
+ res_byte_length= res->length(); /* Must be done before alloc_buffer */
+ if (!(res= alloc_buffer(res,str,&tmp_value,byte_count)))
goto err;
- to= (char*) res->ptr()+res_length;
+ to= (char*) res->ptr()+res_byte_length;
ptr_pad=rpad->ptr();
- for (count-= res_length; (uint32) count > length_pad; count-= length_pad)
+ pad_byte_length= rpad->length();
+ count-= res_char_length;
+ for ( ; (uint32) count > pad_char_length; count-= pad_char_length)
{
- memcpy(to,ptr_pad,length_pad);
- to+= length_pad;
+ memcpy(to,ptr_pad,pad_byte_length);
+ to+= pad_byte_length;
}
- memcpy(to,ptr_pad,(size_t) count);
+ if (count)
+ {
+ pad_byte_length= rpad->charpos(count);
+ memcpy(to,ptr_pad,(size_t) pad_byte_length);
+ to+= pad_byte_length;
+ }
+ res->length(to- (char*) res->ptr());
return (res);
err:
@@ -1951,7 +1961,7 @@
if (args[1]->const_item())
{
- uint32 length= (uint32) args[1]->val_int();
+ uint32 length= (uint32) args[1]->val_int() * collation.collation->mbmaxlen;
max_length=max(args[0]->max_length,length);
if (max_length >= MAX_BLOB_WIDTH)
{
@@ -1969,57 +1979,52 @@
String *Item_func_lpad::val_str(String *str)
{
- uint32 res_length,length_pad;
- char *to;
- const char *ptr_pad;
- ulong count= (long) args[1]->val_int();
- String *res= args[0]->val_str(str);
- String *lpad= args[2]->val_str(str);
+ uint32 res_byte_length,res_char_length,pad_byte_length,pad_char_length;
+ ulong count= (long) args[1]->val_int(), byte_count;
+ String a1,a3;
+ String *res= args[0]->val_str(&a1);
+ String *pad= args[2]->val_str(&a3);
- if (!res || args[1]->null_value || !lpad)
+ if (!res || args[1]->null_value || !pad)
goto err;
+
null_value=0;
- if (count <= (res_length=res->length()))
- { // String to pad is big enough
- res->length(count); // Shorten result if
longer
- return (res);
+ res_byte_length= res->length();
+ res_char_length= res->numchars();
+
+ if (count <= res_char_length)
+ {
+ res->length(res->charpos(count));
+ return res;
}
- length_pad= lpad->length();
- if (count > current_thd->variables.max_allowed_packet ||
- args[2]->null_value || !length_pad)
+
+ pad_byte_length= pad->length();
+ pad_char_length= pad->numchars();
+ byte_count= count * collation.collation->mbmaxlen;
+
+ if (byte_count > current_thd->variables.max_allowed_packet ||
+ args[2]->null_value || !pad_char_length || str->alloc(byte_count))
goto err;
-
- if (res->alloced_length() < count)
+
+ str->length(0);
+ str->set_charset(collation.collation);
+ count-= res_char_length;
+ while (count >= pad_char_length)
{
- if (str->alloced_length() >= count)
- {
- memcpy((char*) str->ptr()+(count-res_length),res->ptr(),res_length);
- res=str;
- }
- else
- {
- if (tmp_value.alloc(count))
- goto err;
- memcpy((char*) tmp_value.ptr()+(count-res_length),res->ptr(),res_length);
- res=&tmp_value;
- }
+ str->append(*pad);
+ count-= pad_char_length;
}
- else
- bmove_upp((char*) res->ptr()+count,res->ptr()+res_length,res_length);
- res->length(count);
-
- to= (char*) res->ptr();
- ptr_pad= lpad->ptr();
- for (count-= res_length; count > length_pad; count-= length_pad)
+ if (count > 0)
{
- memcpy(to,ptr_pad,length_pad);
- to+= length_pad;
+ pad->length(pad->charpos(count));
+ str->append(*pad);
}
- memcpy(to,ptr_pad,(size_t) count);
- return (res);
+ str->append(*res);
+ null_value= 0;
+ return str;
- err:
- null_value=1;
+err:
+ null_value= 1;
return 0;
}
--- 1.42/mysql-test/r/func_str.result Tue Aug 19 02:08:00 2003
+++ 1.43/mysql-test/r/func_str.result Thu Sep 25 17:31:18 2003
@@ -410,7 +410,7 @@
latin2_general_ci 3
select collation(lpad(_latin2'a',4,_latin2'b')),
coercibility(lpad(_latin2'a',4,_latin2'b'));
collation(lpad(_latin2'a',4,_latin2'b'))
coercibility(lpad(_latin2'a',4,_latin2'b'))
-binary 3
+latin2_general_ci 3
select collation(rpad(_latin2'a',4,_latin2'b')),
coercibility(rpad(_latin2'a',4,_latin2'b'));
collation(rpad(_latin2'a',4,_latin2'b'))
coercibility(rpad(_latin2'a',4,_latin2'b'))
latin2_general_ci 3
--
MySQL Internals Mailing List
For list archives: http://lists.mysql.com/internals
To unsubscribe:
http://lists.mysql.com/internals?unsub=gcdmd-internals@xxxxxxxxxxx
|