diff options
author | msvensson@neptunus.(none) <> | 2006-10-03 14:24:43 +0200 |
---|---|---|
committer | msvensson@neptunus.(none) <> | 2006-10-03 14:24:43 +0200 |
commit | 3f8edc3706e56684bc77896219e062874fecad29 (patch) | |
tree | ce65490bd585d1b82550064472dd7946246fc32b /sql | |
parent | 9a8bc01f8c2af11fe8c877c2df496f0a74556cd5 (diff) | |
parent | 40bcedf4e3dc03b63064ab278218764cc4829bdf (diff) | |
download | mariadb-git-3f8edc3706e56684bc77896219e062874fecad29.tar.gz |
Merge bk-internal:/home/bk/mysql-5.0-rpl
into neptunus.(none):/home/msvensson/mysql/mysql-5.0-maint
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.cc | 195 | ||||
-rw-r--r-- | sql/field_conv.cc | 18 |
2 files changed, 101 insertions, 112 deletions
diff --git a/sql/field.cc b/sql/field.cc index ac4d36d1bbd..9b512fc6d4b 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2494,30 +2494,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, ¬_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; @@ -2532,8 +2529,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; } @@ -2698,30 +2697,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, ¬_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; @@ -2736,15 +2739,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; } @@ -2972,30 +2977,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, ¬_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; @@ -3010,9 +3012,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; } @@ -3208,64 +3211,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) { @@ -3501,33 +3487,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) { @@ -8889,7 +8862,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 ? |