summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <bar@mysql.com>2004-10-28 15:21:20 +0500
committerunknown <bar@mysql.com>2004-10-28 15:21:20 +0500
commit5be6c328f5a9f78f37176bbbd88a538fa3b65fe9 (patch)
tree89a7308e5767cf2511c3186f862a93842a18065d /sql
parent9b041682cc605400d0ccf70ad8f3e98c829b1aab (diff)
downloadmariadb-git-5be6c328f5a9f78f37176bbbd88a538fa3b65fe9.tar.gz
Produce a "truncated" warning if a value cannot be converted
into the column character set on INSERT/UPDATE. sql/sql_string.cc: New argument to report an error. sql/sql_string.h: New argument to report an error.
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc32
-rw-r--r--sql/sql_string.cc21
-rw-r--r--sql/sql_string.h4
3 files changed, 41 insertions, 16 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 3e625f3a582..261494d2125 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -4275,9 +4275,12 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
/* Convert character set if nesessary */
if (String::needs_conversion(length, cs, field_charset, &not_used))
{
- tmpstr.copy(from, length, cs, field_charset);
+ uint conv_errors;
+ tmpstr.copy(from, length, cs, field_charset, &conv_errors);
from= tmpstr.ptr();
length= tmpstr.length();
+ if (conv_errors)
+ error= 1;
}
/*
@@ -4300,11 +4303,11 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
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, 1);
- error=1;
- }
+ error= 1;
}
+ if (error)
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
+
return error;
}
@@ -4528,16 +4531,20 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
/* Convert character set if nesessary */
if (String::needs_conversion(length, cs, field_charset, &not_used))
{
- tmpstr.copy(from, length, cs, field_charset);
+ uint conv_errors;
+ tmpstr.copy(from, length, cs, field_charset, &conv_errors);
from= tmpstr.ptr();
length= tmpstr.length();
+ if (conv_errors)
+ error= 1;
}
if (length > field_length)
{
length=field_length;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
error= 1;
}
+ if (error)
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
memcpy(ptr+HA_KEY_BLOB_LENGTH,from,length);
int2store(ptr, length);
return error;
@@ -4865,6 +4872,7 @@ void Field_blob::put_length(char *pos, uint32 length)
int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
{
+ int error= 0;
if (!length)
{
bzero(ptr,Field_blob::pack_length());
@@ -4881,9 +4889,12 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
if ((was_conversion= String::needs_conversion(length, cs, field_charset,
&not_used)))
{
- tmpstr.copy(from, length, cs, field_charset);
+ uint conv_errors;
+ tmpstr.copy(from, length, cs, field_charset, &conv_errors);
from= tmpstr.ptr();
length= tmpstr.length();
+ if (conv_errors)
+ error= 1;
}
copy_length= max_data_length();
@@ -4897,8 +4908,7 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
min(length, copy_length),
copy_length);
if (copy_length < length)
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
-
+ error= 1;
Field_blob::store_length(copy_length);
if (was_conversion || table->copy_blobs || copy_length <= MAX_FIELD_WIDTH)
{ // Must make a copy
@@ -4910,6 +4920,8 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
}
bmove(ptr+packlength,(char*) &from,sizeof(char*));
}
+ if (error)
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
return 0;
}
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index 1044dc4e58e..30559496fde 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -331,19 +331,26 @@ bool String::set_or_copy_aligned(const char *str,uint32 arg_length,
/* Copy with charset convertion */
bool String::copy(const char *str, uint32 arg_length,
- CHARSET_INFO *from_cs, CHARSET_INFO *to_cs)
+ CHARSET_INFO *from_cs, CHARSET_INFO *to_cs, uint *errors)
{
uint32 offset;
if (!needs_conversion(arg_length, from_cs, to_cs, &offset))
+ {
+ if (errors)
+ *errors= 0;
return copy(str, arg_length, to_cs);
+ }
if ((from_cs == &my_charset_bin) && offset)
+ {
+ if (errors)
+ *errors= 0;
return copy_aligned(str, arg_length, offset, to_cs);
-
+ }
uint32 new_length= to_cs->mbmaxlen*arg_length;
if (alloc(new_length))
return TRUE;
str_length=copy_and_convert((char*) Ptr, new_length, to_cs,
- str, arg_length, from_cs);
+ str, arg_length, from_cs, errors);
str_charset=to_cs;
return FALSE;
}
@@ -769,7 +776,8 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length)
uint32
copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs,
- const char *from, uint32 from_length, CHARSET_INFO *from_cs)
+ const char *from, uint32 from_length, CHARSET_INFO *from_cs,
+ uint *errors)
{
int cnvres;
my_wc_t wc;
@@ -780,6 +788,7 @@ copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs,
const uchar *) = from_cs->cset->mb_wc;
int (*wc_mb)(struct charset_info_st *, my_wc_t, uchar *s, uchar *e)=
to_cs->cset->wc_mb;
+ uint error_count= 0;
while (1)
{
@@ -788,6 +797,7 @@ copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs,
from+= cnvres;
else if (cnvres == MY_CS_ILSEQ)
{
+ error_count++;
from++;
wc= '?';
}
@@ -799,12 +809,15 @@ outp:
to+= cnvres;
else if (cnvres == MY_CS_ILUNI && wc != '?')
{
+ error_count++;
wc= '?';
goto outp;
}
else
break;
}
+ if (errors)
+ *errors= error_count;
return (uint32) (to - to_start);
}
diff --git a/sql/sql_string.h b/sql/sql_string.h
index 2d368991159..de8f4af58d9 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -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);
uint32 copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs,
const char *from, uint32 from_length,
- CHARSET_INFO *from_cs);
+ CHARSET_INFO *from_cs, uint *errors= 0);
class String
{
@@ -199,7 +199,7 @@ public:
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,
- CHARSET_INFO *csto);
+ CHARSET_INFO *csto, uint *errors= 0);
bool append(const String &s);
bool append(const char *s);
bool append(const char *s,uint32 arg_length);