summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authormsvensson@neptunus.(none) <>2006-10-03 14:24:43 +0200
committermsvensson@neptunus.(none) <>2006-10-03 14:24:43 +0200
commit3f8edc3706e56684bc77896219e062874fecad29 (patch)
treece65490bd585d1b82550064472dd7946246fc32b /sql
parent9a8bc01f8c2af11fe8c877c2df496f0a74556cd5 (diff)
parent40bcedf4e3dc03b63064ab278218764cc4829bdf (diff)
downloadmariadb-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.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 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, &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;
@@ -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, &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;
@@ -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, &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;
@@ -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 ?