summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <lars@mysql.com/black.(none)>2006-10-10 21:58:46 +0200
committerunknown <lars@mysql.com/black.(none)>2006-10-10 21:58:46 +0200
commit687f44fe8e5fca0553a839e19e614167e092de5d (patch)
tree1fbe1de1e77b535596569e6f09687a1e0b5853e4 /sql
parent9397becc6d9c5af98ba1fd89a699b389d83a91c3 (diff)
parentc317c2d224c8d7753cf7acd238968a9a8584dbc4 (diff)
downloadmariadb-git-687f44fe8e5fca0553a839e19e614167e092de5d.tar.gz
Merge mysql.com:/home/bkroot/mysql-5.0-rpl
into mysql.com:/home/bk/MERGE/mysql-5.0-merge
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc195
-rw-r--r--sql/field_conv.cc18
2 files changed, 101 insertions, 112 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 4860f6ea3da..d3016d2ec72 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -2482,30 +2482,27 @@ void Field_new_decimal::sql_type(String &str) const
int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs)
{
- int not_used; // We can ignore result from str2int
char *end;
- long tmp= my_strntol(cs, from, len, 10, &end, &not_used);
- int error= 0;
+ int error;
if (unsigned_flag)
{
- if (tmp < 0)
+ ulonglong tmp= cs->cset->strntoull10rnd(cs, from, len, 1, &end, &error);
+ if (error == MY_ERRNO_ERANGE || tmp > 255)
{
- tmp=0; /* purecov: inspected */
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
- error= 1;
- }
- else if (tmp > 255)
- {
- tmp= 255;
+ set_if_smaller(tmp, 255);
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
error= 1;
+ else
+ error= 0;
+ ptr[0]= (char) tmp;
}
else
{
+ longlong tmp= cs->cset->strntoull10rnd(cs, from, len, 0, &end, &error);
if (tmp < -128)
{
tmp= -128;
@@ -2520,8 +2517,10 @@ int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs)
}
else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
error= 1;
+ else
+ error= 0;
+ ptr[0]= (char) tmp;
}
- ptr[0]= (char) tmp;
return error;
}
@@ -2686,30 +2685,34 @@ void Field_tiny::sql_type(String &res) const
int Field_short::store(const char *from,uint len,CHARSET_INFO *cs)
{
- int not_used; // We can ignore result from str2int
char *end;
- long tmp= my_strntol(cs, from, len, 10, &end, &not_used);
- int error= 0;
+ int error;
if (unsigned_flag)
{
- if (tmp < 0)
+ ulonglong tmp= cs->cset->strntoull10rnd(cs, from, len, 1, &end, &error);
+ if (error == MY_ERRNO_ERANGE || tmp > UINT_MAX16)
{
- tmp=0;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
- error= 1;
- }
- else if (tmp > UINT_MAX16)
- {
- tmp=UINT_MAX16;
+ set_if_smaller(tmp, UINT_MAX16);
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
error= 1;
+ else
+ error= 0;
+#ifdef WORDS_BIGENDIAN
+ if (table->s->db_low_byte_first)
+ {
+ int2store(ptr,tmp);
+ }
+ else
+#endif
+ shortstore(ptr,(short) tmp);
}
else
{
+ longlong tmp= cs->cset->strntoull10rnd(cs, from, len, 0, &end, &error);
if (tmp < INT_MIN16)
{
tmp= INT_MIN16;
@@ -2724,15 +2727,17 @@ int Field_short::store(const char *from,uint len,CHARSET_INFO *cs)
}
else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
error= 1;
- }
+ else
+ error= 0;
#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- {
- int2store(ptr,tmp);
- }
- else
+ if (table->s->db_low_byte_first)
+ {
+ int2store(ptr,tmp);
+ }
+ else
#endif
- shortstore(ptr,(short) tmp);
+ shortstore(ptr,(short) tmp);
+ }
return error;
}
@@ -2960,30 +2965,27 @@ void Field_short::sql_type(String &res) const
int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs)
{
- int not_used; // We can ignore result from str2int
char *end;
- long tmp= my_strntol(cs, from, len, 10, &end, &not_used);
- int error= 0;
+ int error;
if (unsigned_flag)
{
- if (tmp < 0)
- {
- tmp=0;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
- error= 1;
- }
- else if (tmp >= (long) (1L << 24))
+ ulonglong tmp= cs->cset->strntoull10rnd(cs, from, len, 1, &end, &error);
+ if (error == MY_ERRNO_ERANGE || tmp > UINT_MAX24)
{
- tmp=(long) (1L << 24)-1L;
+ set_if_smaller(tmp, UINT_MAX24);
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
error= 1;
+ else
+ error= 0;
+ int3store(ptr,tmp);
}
else
{
+ longlong tmp= cs->cset->strntoull10rnd(cs, from, len, 0, &end, &error);
if (tmp < INT_MIN24)
{
tmp= INT_MIN24;
@@ -2998,9 +3000,10 @@ int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs)
}
else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
error= 1;
+ else
+ error= 0;
+ int3store(ptr,tmp);
}
-
- int3store(ptr,tmp);
return error;
}
@@ -3196,64 +3199,47 @@ static bool test_if_minus(CHARSET_INFO *cs,
int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
{
- ulong tmp_scan;
- longlong tmp;
long store_tmp;
int error;
char *end;
- tmp_scan= cs->cset->scan(cs, from, from+len, MY_SEQ_SPACES);
- len-= tmp_scan;
- from+= tmp_scan;
-
- end= (char*) from+len;
- tmp= cs->cset->strtoll10(cs, from, &end, &error);
-
- if (error != MY_ERRNO_EDOM)
+ if (unsigned_flag)
{
- if (unsigned_flag)
+ ulonglong tmp= cs->cset->strntoull10rnd(cs, from, len, 1, &end, &error);
+ if (error == MY_ERRNO_ERANGE || tmp > (ulonglong) UINT_MAX32)
{
- if (error < 0)
- {
- error= 1;
- tmp= 0;
- }
- else if ((ulonglong) tmp > (ulonglong) UINT_MAX32)
- {
- tmp= UINT_MAX32;
- error= 1;
- }
- else
- error= 0;
+ set_if_smaller(tmp, (ulonglong) UINT_MAX32);
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
+ error= 1;
}
+ else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
+ error= 1;
else
- {
- if (error < 0)
- {
- error= 0;
- if (tmp < INT_MIN32)
- {
- tmp= INT_MIN32;
- error= 1;
- }
- }
- else if (tmp > INT_MAX32)
- {
- tmp= INT_MAX32;
- error= 1;
- }
- }
+ error= 0;
+ store_tmp= (long) tmp;
}
- if (error)
+ else
{
- error= error != MY_ERRNO_EDOM ? 1 : 2;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
+ longlong tmp= cs->cset->strntoull10rnd(cs, from, len, 0, &end, &error);
+ if (tmp < INT_MIN32)
+ {
+ tmp= INT_MIN32;
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
+ error= 1;
+ }
+ else if (tmp > INT_MAX32)
+ {
+ tmp=INT_MAX32;
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
+ error= 1;
+ }
+ else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
+ error= 1;
+ else
+ error= 0;
+ store_tmp= (long) tmp;
}
- else if (from+len != end && table->in_use->count_cuted_fields &&
- check_int(from,len,end,cs))
- error= 2;
- store_tmp= (long) tmp;
#ifdef WORDS_BIGENDIAN
if (table->s->db_low_byte_first)
{
@@ -3489,33 +3475,20 @@ void Field_long::sql_type(String &res) const
int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs)
{
- longlong tmp;
- int error= 0;
+ int error;
char *end;
+ ulonglong tmp;
- tmp= cs->cset->scan(cs, from, from+len, MY_SEQ_SPACES);
- len-= (uint)tmp;
- from+= tmp;
- if (unsigned_flag)
- {
- if (!len || test_if_minus(cs, from, from + len))
- {
- tmp=0; // Set negative to 0
- error= 1;
- }
- else
- tmp=(longlong) my_strntoull(cs,from,len,10,&end,&error);
- }
- else
- tmp=my_strntoll(cs,from,len,10,&end,&error);
- if (error)
+ tmp= cs->cset->strntoull10rnd(cs,from,len,unsigned_flag,&end,&error);
+ if (error == MY_ERRNO_ERANGE)
{
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
- else if (from+len != end && table->in_use->count_cuted_fields &&
- check_int(from,len,end,cs))
- error= 2;
+ else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
+ error= 1;
+ else
+ error= 0;
#ifdef WORDS_BIGENDIAN
if (table->s->db_low_byte_first)
{
@@ -8877,7 +8850,7 @@ create_field::create_field(Field *old_field,Field *orig_field)
case 3: sql_type= FIELD_TYPE_MEDIUM_BLOB; break;
default: sql_type= FIELD_TYPE_LONG_BLOB; break;
}
- length=(length+charset->mbmaxlen-1) / charset->mbmaxlen;
+ length/= charset->mbmaxlen;
key_length/= charset->mbmaxlen;
break;
case MYSQL_TYPE_STRING:
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index 3200f2ca9b2..95ff985376d 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -428,6 +428,21 @@ static void do_varstring2(Copy_field *copy)
length);
}
+
+static void do_varstring2_mb(Copy_field *copy)
+{
+ int well_formed_error;
+ CHARSET_INFO *cs= copy->from_field->charset();
+ uint char_length= (copy->to_length - HA_KEY_BLOB_LENGTH) / cs->mbmaxlen;
+ uint from_length= uint2korr(copy->from_ptr);
+ const char *from_beg= copy->from_ptr + HA_KEY_BLOB_LENGTH;
+ uint length= cs->cset->well_formed_len(cs, from_beg, from_beg + from_length,
+ char_length, &well_formed_error);
+ int2store(copy->to_ptr, length);
+ memcpy(copy->to_ptr+HA_KEY_BLOB_LENGTH, from_beg, length);
+}
+
+
/***************************************************************************
** The different functions that fills in a Copy_field class
***************************************************************************/
@@ -587,7 +602,8 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*)
return do_field_string;
if (to_length != from_length)
return (((Field_varstring*) to)->length_bytes == 1 ?
- do_varstring1 : do_varstring2);
+ do_varstring1 : (from->charset()->mbmaxlen == 1 ?
+ do_varstring2 : do_varstring2_mb));
}
else if (to_length < from_length)
return (from->charset()->mbmaxlen == 1 ?