summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <bar@bar.intranet.mysql.r18.ru>2004-02-06 16:59:25 +0400
committerunknown <bar@bar.intranet.mysql.r18.ru>2004-02-06 16:59:25 +0400
commitfaa8a41b1db57e643617eda8c49803f6e1287f87 (patch)
tree1de54a5d40a817616ee8991ff03ebb355c4f1d18 /sql
parente5ab70702c082c77401052f940b18b5f6d50a8c3 (diff)
downloadmariadb-git-faa8a41b1db57e643617eda8c49803f6e1287f87.tar.gz
Problem fix:
http://bugs.mysql.com/bug.php?id=2366 Wrong utf8 behaviour when data is trancated
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc48
-rw-r--r--sql/item_strfunc.h3
-rw-r--r--sql/item_timefunc.cc5
3 files changed, 32 insertions, 24 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 9f25b770ab0..57b77693275 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -4060,6 +4060,8 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
int error= 0;
char buff[80];
String tmpstr(buff,sizeof(buff), &my_charset_bin);
+ uint copy_length;
+
/* Convert character set if nesessary */
if (String::needs_conversion(from, length, cs, field_charset))
{
@@ -4067,27 +4069,31 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
from= tmpstr.ptr();
length= tmpstr.length();
}
- if (length <= field_length)
- {
- memcpy(ptr,from,length);
- if (length < field_length)
- field_charset->cset->fill(field_charset,ptr+length,field_length-length,
- ' ');
- }
- else
- {
- memcpy(ptr,from,field_length);
- if (current_thd->count_cuted_fields)
- { // Check if we loosed some info
- const char *end=from+length;
- from+= field_length;
- from+= field_charset->cset->scan(field_charset, from, end,
- MY_SEQ_SPACES);
- if (from != end)
- {
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED);
- error=1;
- }
+
+ /*
+ Make sure we don't break a multybite sequence
+ as well as don't copy a malformed data.
+ */
+ copy_length= field_charset->cset->wellformedlen(field_charset,
+ from,from+length,
+ field_length/
+ field_charset->mbmaxlen);
+ memcpy(ptr,from,copy_length);
+ if (copy_length < field_length) // Append spaces if shorter
+ field_charset->cset->fill(field_charset,ptr+copy_length,
+ field_length-copy_length,' ');
+
+
+ if (current_thd->count_cuted_fields && (copy_length < length))
+ { // Check if we loosed some info
+ const char *end=from+length;
+ from+= copy_length;
+ from+= field_charset->cset->scan(field_charset, from, end,
+ MY_SEQ_SPACES);
+ if (from != end)
+ {
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED);
+ error=1;
}
}
return error;
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index fd0afb19726..465300e721e 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -518,7 +518,8 @@ public:
void fix_length_and_dec()
{
collation.set(default_charset());
- decimals=0; max_length=args[0]->max_length*2;
+ decimals=0;
+ max_length=args[0]->max_length*2*collation.collation->mbmaxlen;
}
};
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index ed5b9ecc0db..062e7fc7b44 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -1286,12 +1286,13 @@ void Item_func_date_format::fix_length_and_dec()
if (args[1]->type() == STRING_ITEM)
{ // Optimize the normal case
fixed_length=1;
- max_length=format_length(((Item_string*) args[1])->const_string());
+ max_length= format_length(((Item_string*) args[1])->const_string())*
+ collation.collation->mbmaxlen;
}
else
{
fixed_length=0;
- max_length=args[1]->max_length*10;
+ max_length=args[1]->max_length*10*collation.collation->mbmaxlen;
set_if_smaller(max_length,MAX_BLOB_WIDTH);
}
maybe_null=1; // If wrong date