summaryrefslogtreecommitdiff
path: root/sql/field.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/field.cc')
-rw-r--r--sql/field.cc734
1 files changed, 520 insertions, 214 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 42ddcc3b9d2..c9669c93c04 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -79,7 +79,8 @@ bool test_if_int(const char *str,int length)
{
const char *end=str+length;
- while (str != end && isspace(*str)) // Allow start space
+ // Allow start space
+ while (str != end && my_isspace(system_charset_info,*str))
str++; /* purecov: inspected */
if (str != end && (*str == '-' || *str == '+'))
str++;
@@ -87,7 +88,7 @@ bool test_if_int(const char *str,int length)
return 0; // Error: Empty string
for (; str != end ; str++)
{
- if (!isdigit(*str))
+ if (!my_isdigit(system_charset_info,*str))
{
if (*str == '.')
{ // Allow '.0000'
@@ -95,10 +96,10 @@ bool test_if_int(const char *str,int length)
if (str == end)
return 1;
}
- if (!isspace(*str))
+ if (!my_isspace(system_charset_info,*str))
return 0;
for (str++ ; str != end ; str++)
- if (!isspace(*str))
+ if (!my_isspace(system_charset_info,*str))
return 0;
return 1;
}
@@ -109,7 +110,7 @@ bool test_if_int(const char *str,int length)
static bool test_if_real(const char *str,int length)
{
- while (length && isspace(*str))
+ while (length && my_isspace(system_charset_info,*str))
{ // Allow start space
length--; str++;
}
@@ -118,10 +119,10 @@ static bool test_if_real(const char *str,int length)
if (*str == '+' || *str == '-')
{
length--; str++;
- if (!length || !(isdigit(*str) || *str == '.'))
+ if (!length || !(my_isdigit(system_charset_info,*str) || *str == '.'))
return 0;
}
- while (length && isdigit(*str))
+ while (length && my_isdigit(system_charset_info,*str))
{
length--; str++;
}
@@ -130,7 +131,7 @@ static bool test_if_real(const char *str,int length)
if (*str == '.')
{
length--; str++;
- while (length && isdigit(*str))
+ while (length && my_isdigit(system_charset_info,*str))
{
length--; str++;
}
@@ -139,18 +140,19 @@ static bool test_if_real(const char *str,int length)
return 1;
if (*str == 'E' || *str == 'e')
{
- if (length < 3 || (str[1] != '+' && str[1] != '-') || !isdigit(str[2]))
+ if (length < 3 || (str[1] != '+' && str[1] != '-') ||
+ !my_isdigit(system_charset_info,str[2]))
return 0;
length-=3;
str+=3;
- while (length && isdigit(*str))
+ while (length && my_isdigit(system_charset_info,*str))
{
length--; str++;
}
}
for (; length ; length--, str++)
{ // Allow end space
- if (!isspace(*str))
+ if (!my_isspace(system_charset_info,*str))
return 0;
}
return 1;
@@ -174,6 +176,8 @@ Field::Field(char *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
field_length(length_arg),null_bit(null_bit_arg)
{
flags=null_ptr ? 0: NOT_NULL_FLAG;
+ comment.str= (char*) "";
+ comment.length=0;
}
uint Field::offset()
@@ -198,7 +202,7 @@ bool Field::send(THD *thd, String *packet)
if (is_null())
return net_store_null(packet);
char buff[MAX_FIELD_WIDTH];
- String tmp(buff,sizeof(buff));
+ String tmp(buff,sizeof(buff),default_charset_info);
val_str(&tmp,&tmp);
CONVERT *convert;
if ((convert=thd->variables.convert_set))
@@ -218,8 +222,11 @@ void Field_num::add_zerofill_and_unsigned(String &res) const
void Field_num::make_field(Send_field *field)
{
+ /* table_cache_key is not set for temp tables */
+ field->db_name=table->table_cache_key ? table->table_cache_key : "";
+ field->org_table_name=table->real_name;
field->table_name=table_name;
- field->col_name=field_name;
+ field->col_name=field->org_col_name=field_name;
field->length=field_length;
field->type=type();
field->flags=table->maybe_null ? (flags & ~NOT_NULL_FLAG) : flags;
@@ -229,8 +236,11 @@ void Field_num::make_field(Send_field *field)
void Field_str::make_field(Send_field *field)
{
+ /* table_cache_key is not set for temp tables */
+ field->db_name=table->table_cache_key ? table->table_cache_key : "";
+ field->org_table_name=table->real_name;
field->table_name=table_name;
- field->col_name=field_name;
+ field->col_name=field->org_col_name=field_name;
field->length=field_length;
field->type=type();
field->flags=table->maybe_null ? (flags & ~NOT_NULL_FLAG) : flags;
@@ -261,7 +271,7 @@ uint Field::fill_cache_field(CACHE_FIELD *copy)
bool Field::get_date(TIME *ltime,bool fuzzydate)
{
char buff[40];
- String tmp(buff,sizeof(buff)),tmp2,*res;
+ String tmp(buff,sizeof(buff),default_charset_info),tmp2,*res;
if (!(res=val_str(&tmp,&tmp2)) ||
str_to_TIME(res->ptr(),res->length(),ltime,fuzzydate) == TIMESTAMP_NONE)
return 1;
@@ -271,7 +281,7 @@ bool Field::get_date(TIME *ltime,bool fuzzydate)
bool Field::get_time(TIME *ltime)
{
char buff[40];
- String tmp(buff,sizeof(buff)),tmp2,*res;
+ String tmp(buff,sizeof(buff),default_charset_info),tmp2,*res;
if (!(res=val_str(&tmp,&tmp2)) ||
str_to_time(res->ptr(),res->length(),ltime))
return 1;
@@ -285,22 +295,23 @@ void Field::store_time(TIME *ltime,timestamp_type type)
char buff[25];
switch (type) {
case TIMESTAMP_NONE:
- store("",0); // Probably an error
+ store("",0,default_charset_info); // Probably an error
break;
case TIMESTAMP_DATE:
sprintf(buff,"%04d-%02d-%02d", ltime->year,ltime->month,ltime->day);
- store(buff,10);
+ store(buff,10,default_charset_info);
break;
case TIMESTAMP_FULL:
sprintf(buff,"%04d-%02d-%02d %02d:%02d:%02d",
ltime->year,ltime->month,ltime->day,
ltime->hour,ltime->minute,ltime->second);
- store(buff,19);
+ store(buff,19,default_charset_info);
break;
case TIMESTAMP_TIME:
- sprintf(buff, "%02d:%02d:%02d",
- ltime->hour,ltime->minute,ltime->second);
- store(buff,(uint) strlen(buff));
+ {
+ ulong length= my_sprintf(buff, (buff, "%02d:%02d:%02d",
+ ltime->hour,ltime->minute,ltime->second));
+ store(buff,(uint) length, default_charset_info);
break;
}
}
@@ -319,7 +330,7 @@ bool Field::optimize_range(uint idx)
void
Field_decimal::reset(void)
{
- Field_decimal::store("0",1);
+ Field_decimal::store("0",1,default_charset_info);
}
void Field_decimal::overflow(bool negative)
@@ -361,7 +372,7 @@ void Field_decimal::overflow(bool negative)
}
-void Field_decimal::store(const char *from,uint len)
+int Field_decimal::store(const char *from, uint len, CHARSET_INFO *cs)
{
const char *end= from+len;
/* The pointer where the field value starts (i.e., "where to write") */
@@ -372,13 +383,13 @@ void Field_decimal::store(const char *from,uint len)
specified), '+' or '-'
*/
char sign_char=0;
- /* The pointers where prezeros start and stop */
+ /* The pointers where prezeros start and stop */
const char *pre_zeros_from, *pre_zeros_end;
- /* The pointers where digits at the left of '.' start and stop */
+ /* The pointers where digits at the left of '.' start and stop */
const char *int_digits_from, *int_digits_end;
- /* The pointers where digits at the right of '.' start and stop */
+ /* The pointers where digits at the right of '.' start and stop */
const char *frac_digits_from, *frac_digits_end;
- /* The sign of the exponent : will be 0 (means no exponent), '+' or '-' */
+ /* The sign of the exponent : will be 0 (means no exponent), '+' or '-' */
char expo_sign_char=0;
uint exponent=0; // value of the exponent
/*
@@ -388,21 +399,21 @@ void Field_decimal::store(const char *from,uint len)
const char *int_digits_tail_from;
/* Number of 0 that need to be added at the left of the '.' (1E3: 3 zeros) */
uint int_digits_added_zeros;
- /*
- Pointer used when digits move from the right of the '.' to the left
- of the '.'
- */
+ /*
+ Pointer used when digits move from the right of the '.' to the left
+ of the '.'
+ */
const char *frac_digits_head_end;
- /* Number of 0 that need to be added at the right of the '.' (for 1E-3) */
+ /* Number of 0 that need to be added at the right of the '.' (for 1E-3) */
uint frac_digits_added_zeros;
char *pos,*tmp_left_pos,*tmp_right_pos;
/* Pointers that are used as limits (begin and end of the field buffer) */
char *left_wall,*right_wall;
char tmp_char;
- /*
- To remember if current_thd->cuted_fields has already been incremented,
- to do that only once
- */
+ /*
+ To remember if current_thd->cuted_fields has already been incremented,
+ to do that only once
+ */
bool is_cuted_fields_incr=0;
LINT_INIT(int_digits_tail_from);
@@ -412,16 +423,18 @@ void Field_decimal::store(const char *from,uint len)
/*
There are three steps in this function :
- - parse the input string
- - modify the position of digits around the decimal dot '.'
- according to the exponent value (if specified)
- - write the formatted number
+ - parse the input string
+ - modify the position of digits around the decimal dot '.'
+ according to the exponent value (if specified)
+ - write the formatted number
*/
if ((tmp_dec=dec))
tmp_dec++;
- for (; from !=end && isspace(*from); from++) ; // Read spaces
+ /* skip pre-space */
+ while (from != end && my_isspace(system_charset_info,*from))
+ from++;
if (from == end)
{
current_thd->cuted_fields++;
@@ -440,11 +453,11 @@ void Field_decimal::store(const char *from,uint len)
if (sign_char=='-')
{
Field_decimal::overflow(1);
- return;
+ return 1;
}
/*
- Defining this will not store "+" for unsigned decimal type even if
- it is passed in numeric string. This will make some tests to fail
+ Defining this will not store "+" for unsigned decimal type even if
+ it is passed in numeric string. This will make some tests to fail
*/
#ifdef DONT_ALLOW_UNSIGNED_PLUS
else
@@ -457,13 +470,13 @@ void Field_decimal::store(const char *from,uint len)
for (; from!=end && *from == '0'; from++) ; // Read prezeros
pre_zeros_end=int_digits_from=from;
/* Read non zero digits at the left of '.'*/
- for (; from!=end && isdigit(*from);from++) ;
+ for (; from != end && my_isdigit(system_charset_info, *from) ; from++) ;
int_digits_end=from;
if (from!=end && *from == '.') // Some '.' ?
from++;
frac_digits_from= from;
/* Read digits at the right of '.' */
- for (;from!=end && isdigit(*from); from++) ;
+ for (;from!=end && my_isdigit(system_charset_info, (*from); from++) ;
frac_digits_end=from;
// Some exponentiation symbol ?
if (from != end && (*from == 'e' || *from == 'E'))
@@ -479,7 +492,7 @@ void Field_decimal::store(const char *from,uint len)
(the value of the field will be overflow anyway, or 0 anyway,
it does not change anything if the exponent is 2^32 or more
*/
- for (;from!=end && isdigit(*from); from++)
+ for (;from!=end && my_isdigit(system_charset_info, (*from)); from++)
exponent=10*exponent+(*from-'0');
}
@@ -504,21 +517,21 @@ void Field_decimal::store(const char *from,uint len)
Now "move" digits around the decimal dot according to the exponent value,
and add necessary zeros.
Examples :
- - 1E+3 : needs 3 more zeros at the left of '.' (int_digits_added_zeros=3)
- - 1E-3 : '1' moves at the right of '.', and 2 more zeros are needed
- between '.' and '1'
+ - 1E+3 : needs 3 more zeros at the left of '.' (int_digits_added_zeros=3)
+ - 1E-3 : '1' moves at the right of '.', and 2 more zeros are needed
+ between '.' and '1'
- 1234.5E-3 : '234' moves at the right of '.'
- These moves are implemented with pointers which point at the begin
- and end of each moved segment. Examples :
+ These moves are implemented with pointers which point at the begin
+ and end of each moved segment. Examples :
- 1234.5E-3 : before the code below is executed, the int_digits part is
- from '1' to '4' and the frac_digits part from '5' to '5'. After the code
- below, the int_digits part is from '1' to '1', the frac_digits_head
- part is from '2' to '4', and the frac_digits part from '5' to '5'.
+ from '1' to '4' and the frac_digits part from '5' to '5'. After the code
+ below, the int_digits part is from '1' to '1', the frac_digits_head
+ part is from '2' to '4', and the frac_digits part from '5' to '5'.
- 1234.5E3 : before the code below is executed, the int_digits part is
- from '1' to '4' and the frac_digits part from '5' to '5'. After the code
- below, the int_digits part is from '1' to '4', the int_digits_tail
- part is from '5' to '5', the frac_digits part is empty, and
- int_digits_added_zeros=2 (to make 1234500).
+ from '1' to '4' and the frac_digits part from '5' to '5'. After the code
+ below, the int_digits part is from '1' to '4', the int_digits_tail
+ part is from '5' to '5', the frac_digits part is empty, and
+ int_digits_added_zeros=2 (to make 1234500).
*/
if (!expo_sign_char)
@@ -573,7 +586,7 @@ void Field_decimal::store(const char *from,uint len)
{
// too big number, change to max or min number
Field_decimal::overflow(sign_char == '-');
- return;
+ return 1;
}
/*
@@ -655,7 +668,7 @@ void Field_decimal::store(const char *from,uint len)
{
if (current_thd->count_cuted_fields && !is_cuted_fields_incr)
break; // Go on below to see if we lose non zero digits
- return;
+ return 0;
}
*pos++='0';
}
@@ -668,7 +681,7 @@ void Field_decimal::store(const char *from,uint len)
{
if (!is_cuted_fields_incr)
current_thd->cuted_fields++;
- return;
+ return 0;
}
continue;
}
@@ -685,7 +698,7 @@ void Field_decimal::store(const char *from,uint len)
{
if (!is_cuted_fields_incr)
current_thd->cuted_fields++;
- return;
+ return 0;
}
continue;
}
@@ -695,25 +708,26 @@ void Field_decimal::store(const char *from,uint len)
while (pos != right_wall)
*pos++='0'; // Fill with zeros at right of '.'
}
+ return 0;
}
-void Field_decimal::store(double nr)
+int Field_decimal::store(double nr)
{
if (unsigned_flag && nr < 0)
{
overflow(1);
- return;
+ return 1;
}
#ifdef HAVE_FINITE
if (!finite(nr)) // Handle infinity as special case
{
overflow(nr < 0.0);
- return;
+ return 1;
}
#endif
-
+
reg4 uint i,length;
char fyllchar,*to;
char buff[320];
@@ -728,30 +742,37 @@ void Field_decimal::store(double nr)
length=(uint) strlen(buff);
if (length > field_length)
+ {
overflow(nr < 0.0);
+ return 1;
+ }
else
{
to=ptr;
for (i=field_length-length ; i-- > 0 ;)
*to++ = fyllchar;
memcpy(to,buff,length);
+ return 0;
}
}
-void Field_decimal::store(longlong nr)
+int Field_decimal::store(longlong nr)
{
if (unsigned_flag && nr < 0)
{
overflow(1);
- return;
+ return 1;
}
char buff[22];
uint length=(uint) (longlong10_to_str(nr,buff,-10)-buff);
uint int_part=field_length- (dec ? dec+1 : 0);
if (length > int_part)
+ {
overflow(test(nr < 0L)); /* purecov: inspected */
+ return 1;
+ }
else
{
char fyllchar = zerofill ? (char) '0' : (char) ' ';
@@ -764,6 +785,7 @@ void Field_decimal::store(longlong nr)
to[length]='.';
bfill(to+length+1,dec,'0');
}
+ return 0;
}
}
@@ -797,7 +819,7 @@ String *Field_decimal::val_str(String *val_buffer __attribute__((unused)),
if (field_length < tmp_length) // Error in data
val_ptr->length(0);
else
- val_ptr->set((const char*) str,field_length-tmp_length);
+ val_ptr->set((const char*) str,field_length-tmp_length,default_charset_info);
return val_ptr;
}
@@ -814,8 +836,10 @@ int Field_decimal::cmp(const char *a_ptr,const char *b_ptr)
for (end=a_ptr+field_length;
a_ptr != end &&
(*a_ptr == *b_ptr ||
- ((isspace(*a_ptr) || *a_ptr == '+' || *a_ptr == '0') &&
- (isspace(*b_ptr) || *b_ptr == '+' || *b_ptr == '0')));
+ ((my_isspace(system_charset_info,*a_ptr) || *a_ptr == '+' ||
+ *a_ptr == '0') &&
+ (my_isspace(system_charset_info,*b_ptr) || *b_ptr == '+' ||
+ *b_ptr == '0')));
a_ptr++,b_ptr++)
{
if (*a_ptr == '-') // If both numbers are negative
@@ -842,8 +866,8 @@ void Field_decimal::sort_string(char *to,uint length)
char *str,*end;
for (str=ptr,end=ptr+length;
str != end &&
- ((isspace(*str) || *str == '+' || *str == '0')) ;
-
+ ((my_isspace(system_charset_info,*str) || *str == '+' ||
+ *str == '0')) ;
str++)
*to++=' ';
if (str == end)
@@ -854,7 +878,7 @@ void Field_decimal::sort_string(char *to,uint length)
*to++=1; // Smaller than any number
str++;
while (str != end)
- if (isdigit(*str))
+ if (my_isdigit(system_charset_info,*str))
*to++= (char) ('9' - *str++);
else
*to++= *str++;
@@ -862,6 +886,7 @@ void Field_decimal::sort_string(char *to,uint length)
else memcpy(to,str,(uint) (end-str));
}
+
void Field_decimal::sql_type(String &res) const
{
uint tmp=field_length;
@@ -878,10 +903,11 @@ void Field_decimal::sql_type(String &res) const
** tiny int
****************************************************************************/
-void Field_tiny::store(const char *from,uint len)
+int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs)
{
- String tmp_str(from,len);
+ String tmp_str(from,len,default_charset_info);
long tmp= strtol(tmp_str.c_ptr(),NULL,10);
+ int error= 0;
if (unsigned_flag)
{
@@ -889,14 +915,19 @@ void Field_tiny::store(const char *from,uint len)
{
tmp=0; /* purecov: inspected */
current_thd->cuted_fields++; /* purecov: inspected */
+ error= 1;
}
else if (tmp > 255)
{
tmp= 255;
current_thd->cuted_fields++;
+ error= 1;
}
else if (current_thd->count_cuted_fields && !test_if_int(from,len))
+ {
current_thd->cuted_fields++;
+ error= 1;
+ }
}
else
{
@@ -904,21 +935,28 @@ void Field_tiny::store(const char *from,uint len)
{
tmp= -128;
current_thd->cuted_fields++;
+ error= 1;
}
else if (tmp >= 128)
{
tmp= 127;
current_thd->cuted_fields++;
+ error= 1;
}
else if (current_thd->count_cuted_fields && !test_if_int(from,len))
+ {
current_thd->cuted_fields++;
+ error= 1;
+ }
}
ptr[0]= (char) tmp;
+ return error;
}
-void Field_tiny::store(double nr)
+int Field_tiny::store(double nr)
{
+ int error= 0;
nr=rint(nr);
if (unsigned_flag)
{
@@ -926,11 +964,13 @@ void Field_tiny::store(double nr)
{
*ptr=0;
current_thd->cuted_fields++;
+ error= 1;
}
else if (nr > 255.0)
{
*ptr=(char) 255;
current_thd->cuted_fields++;
+ error= 1;
}
else
*ptr=(char) nr;
@@ -941,30 +981,36 @@ void Field_tiny::store(double nr)
{
*ptr= (char) -128;
current_thd->cuted_fields++;
+ error= 1;
}
else if (nr > 127.0)
{
*ptr=127;
current_thd->cuted_fields++;
+ error= 1;
}
else
*ptr=(char) nr;
}
+ return error;
}
-void Field_tiny::store(longlong nr)
+int Field_tiny::store(longlong nr)
{
+ int error= 0;
if (unsigned_flag)
{
if (nr < 0L)
{
*ptr=0;
current_thd->cuted_fields++;
+ error= 1;
}
else if (nr > 255L)
{
*ptr= (char) 255;
current_thd->cuted_fields++;
+ error= 1;
}
else
*ptr=(char) nr;
@@ -975,15 +1021,18 @@ void Field_tiny::store(longlong nr)
{
*ptr= (char) -128;
current_thd->cuted_fields++;
+ error= 1;
}
else if (nr > 127L)
{
*ptr=127;
current_thd->cuted_fields++;
+ error= 1;
}
else
*ptr=(char) nr;
}
+ return error;
}
@@ -1049,24 +1098,30 @@ void Field_tiny::sql_type(String &res) const
// Note: Sometimes this should be fixed to use one strtol() to use
// len and check for garbage after number.
-void Field_short::store(const char *from,uint len)
+int Field_short::store(const char *from,uint len,CHARSET_INFO *cs)
{
- String tmp_str(from,len);
+ String tmp_str(from,len,default_charset_info);
long tmp= strtol(tmp_str.c_ptr(),NULL,10);
+ int error= 0;
if (unsigned_flag)
{
if (tmp < 0)
{
tmp=0;
current_thd->cuted_fields++;
+ error= 1;
}
else if (tmp > (uint16) ~0)
{
tmp=(uint16) ~0;
current_thd->cuted_fields++;
+ error= 1;
}
else if (current_thd->count_cuted_fields && !test_if_int(from,len))
+ {
current_thd->cuted_fields++;
+ error= 1;
+ }
}
else
{
@@ -1074,14 +1129,19 @@ void Field_short::store(const char *from,uint len)
{
tmp= INT_MIN16;
current_thd->cuted_fields++;
+ error= 1;
}
else if (tmp > INT_MAX16)
{
tmp=INT_MAX16;
current_thd->cuted_fields++;
+ error= 1;
}
else if (current_thd->count_cuted_fields && !test_if_int(from,len))
+ {
current_thd->cuted_fields++;
+ error= 1;
+ }
}
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
@@ -1091,11 +1151,13 @@ void Field_short::store(const char *from,uint len)
else
#endif
shortstore(ptr,(short) tmp);
+ return error;
}
-void Field_short::store(double nr)
+int Field_short::store(double nr)
{
+ int error= 0;
int16 res;
nr=rint(nr);
if (unsigned_flag)
@@ -1104,11 +1166,13 @@ void Field_short::store(double nr)
{
res=0;
current_thd->cuted_fields++;
+ error= 1;
}
else if (nr > (double) (uint16) ~0)
{
res=(int16) (uint16) ~0;
current_thd->cuted_fields++;
+ error= 1;
}
else
res=(int16) (uint16) nr;
@@ -1119,11 +1183,13 @@ void Field_short::store(double nr)
{
res=INT_MIN16;
current_thd->cuted_fields++;
+ error= 1;
}
else if (nr > (double) INT_MAX16)
{
res=INT_MAX16;
current_thd->cuted_fields++;
+ error= 1;
}
else
res=(int16) nr;
@@ -1136,10 +1202,12 @@ void Field_short::store(double nr)
else
#endif
shortstore(ptr,res);
+ return error;
}
-void Field_short::store(longlong nr)
+int Field_short::store(longlong nr)
{
+ int error= 0;
int16 res;
if (unsigned_flag)
{
@@ -1147,11 +1215,13 @@ void Field_short::store(longlong nr)
{
res=0;
current_thd->cuted_fields++;
+ error= 1;
}
else if (nr > (longlong) (uint16) ~0)
{
res=(int16) (uint16) ~0;
current_thd->cuted_fields++;
+ error= 1;
}
else
res=(int16) (uint16) nr;
@@ -1162,11 +1232,13 @@ void Field_short::store(longlong nr)
{
res=INT_MIN16;
current_thd->cuted_fields++;
+ error= 1;
}
else if (nr > INT_MAX16)
{
res=INT_MAX16;
current_thd->cuted_fields++;
+ error= 1;
}
else
res=(int16) nr;
@@ -1179,6 +1251,7 @@ void Field_short::store(longlong nr)
else
#endif
shortstore(ptr,res);
+ return error;
}
@@ -1289,10 +1362,11 @@ void Field_short::sql_type(String &res) const
// Note: Sometimes this should be fixed to use one strtol() to use
// len and check for garbage after number.
-void Field_medium::store(const char *from,uint len)
+int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs)
{
- String tmp_str(from,len);
+ String tmp_str(from,len,default_charset_info);
long tmp= strtol(tmp_str.c_ptr(),NULL,10);
+ int error= 0;
if (unsigned_flag)
{
@@ -1300,14 +1374,19 @@ void Field_medium::store(const char *from,uint len)
{
tmp=0;
current_thd->cuted_fields++;
+ error= 1;
}
else if (tmp >= (long) (1L << 24))
{
tmp=(long) (1L << 24)-1L;
current_thd->cuted_fields++;
+ error= 1;
}
else if (current_thd->count_cuted_fields && !test_if_int(from,len))
+ {
current_thd->cuted_fields++;
+ error= 1;
+ }
}
else
{
@@ -1315,22 +1394,29 @@ void Field_medium::store(const char *from,uint len)
{
tmp= INT_MIN24;
current_thd->cuted_fields++;
+ error= 1;
}
else if (tmp > INT_MAX24)
{
tmp=INT_MAX24;
current_thd->cuted_fields++;
+ error= 1;
}
else if (current_thd->count_cuted_fields && !test_if_int(from,len))
+ {
current_thd->cuted_fields++;
+ error= 1;
+ }
}
int3store(ptr,tmp);
+ return error;
}
-void Field_medium::store(double nr)
+int Field_medium::store(double nr)
{
+ int error= 0;
nr=rint(nr);
if (unsigned_flag)
{
@@ -1338,12 +1424,14 @@ void Field_medium::store(double nr)
{
int3store(ptr,0);
current_thd->cuted_fields++;
+ error= 1;
}
else if (nr >= (double) (long) (1L << 24))
{
uint32 tmp=(uint32) (1L << 24)-1L;
int3store(ptr,tmp);
current_thd->cuted_fields++;
+ error= 1;
}
else
int3store(ptr,(uint32) nr);
@@ -1355,32 +1443,38 @@ void Field_medium::store(double nr)
long tmp=(long) INT_MIN24;
int3store(ptr,tmp);
current_thd->cuted_fields++;
+ error= 1;
}
else if (nr > (double) INT_MAX24)
{
long tmp=(long) INT_MAX24;
int3store(ptr,tmp);
current_thd->cuted_fields++;
+ error= 1;
}
else
int3store(ptr,(long) nr);
}
+ return error;
}
-void Field_medium::store(longlong nr)
+int Field_medium::store(longlong nr)
{
+ int error= 0;
if (unsigned_flag)
{
if (nr < 0L)
{
int3store(ptr,0);
current_thd->cuted_fields++;
+ error= 1;
}
else if (nr >= (longlong) (long) (1L << 24))
{
long tmp=(long) (1L << 24)-1L;;
int3store(ptr,tmp);
current_thd->cuted_fields++;
+ error= 1;
}
else
int3store(ptr,(uint32) nr);
@@ -1392,16 +1486,19 @@ void Field_medium::store(longlong nr)
long tmp=(long) INT_MIN24;
int3store(ptr,tmp);
current_thd->cuted_fields++;
+ error= 1;
}
else if (nr > (longlong) INT_MAX24)
{
long tmp=(long) INT_MAX24;
int3store(ptr,tmp);
current_thd->cuted_fields++;
+ error= 1;
}
else
int3store(ptr,(long) nr);
}
+ return error;
}
@@ -1474,14 +1571,15 @@ void Field_medium::sql_type(String &res) const
// Note: Sometimes this should be fixed to use one strtol() to use
// len and check for garbage after number.
-void Field_long::store(const char *from,uint len)
+int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
{
- while (len && isspace(*from))
+ while (len && my_isspace(system_charset_info,*from))
{
len--; from++;
}
long tmp;
- String tmp_str(from,len);
+ int error= 0;
+ String tmp_str(from,len,default_charset_info);
errno=0;
if (unsigned_flag)
{
@@ -1489,6 +1587,7 @@ void Field_long::store(const char *from,uint len)
{
tmp=0; // Set negative to 0
errno=ERANGE;
+ error= 1;
}
else
tmp=(long) strtoul(tmp_str.c_ptr(),NULL,10);
@@ -1496,7 +1595,10 @@ void Field_long::store(const char *from,uint len)
else
tmp=strtol(tmp_str.c_ptr(),NULL,10);
if (errno || current_thd->count_cuted_fields && !test_if_int(from,len))
+ {
current_thd->cuted_fields++;
+ error= 1;
+ }
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
{
@@ -1505,11 +1607,13 @@ void Field_long::store(const char *from,uint len)
else
#endif
longstore(ptr,tmp);
+ return error;
}
-void Field_long::store(double nr)
+int Field_long::store(double nr)
{
+ int error= 0;
int32 res;
nr=rint(nr);
if (unsigned_flag)
@@ -1518,11 +1622,13 @@ void Field_long::store(double nr)
{
res=0;
current_thd->cuted_fields++;
+ error= 1;
}
else if (nr > (double) (ulong) ~0L)
{
res=(int32) (uint32) ~0L;
current_thd->cuted_fields++;
+ error= 1;
}
else
res=(int32) (ulong) nr;
@@ -1533,11 +1639,13 @@ void Field_long::store(double nr)
{
res=(int32) INT_MIN32;
current_thd->cuted_fields++;
+ error= 1;
}
else if (nr > (double) INT_MAX32)
{
res=(int32) INT_MAX32;
current_thd->cuted_fields++;
+ error= 1;
}
else
res=(int32) nr;
@@ -1550,11 +1658,13 @@ void Field_long::store(double nr)
else
#endif
longstore(ptr,res);
+ return error;
}
-void Field_long::store(longlong nr)
+int Field_long::store(longlong nr)
{
+ int error= 0;
int32 res;
if (unsigned_flag)
{
@@ -1562,11 +1672,13 @@ void Field_long::store(longlong nr)
{
res=0;
current_thd->cuted_fields++;
+ error= 1;
}
else if (nr >= (LL(1) << 32))
{
res=(int32) (uint32) ~0L;
current_thd->cuted_fields++;
+ error= 1;
}
else
res=(int32) (uint32) nr;
@@ -1577,11 +1689,13 @@ void Field_long::store(longlong nr)
{
res=(int32) INT_MIN32;
current_thd->cuted_fields++;
+ error= 1;
}
else if (nr > (longlong) INT_MAX32)
{
res=(int32) INT_MAX32;
current_thd->cuted_fields++;
+ error= 1;
}
else
res=(int32) nr;
@@ -1594,6 +1708,7 @@ void Field_long::store(longlong nr)
else
#endif
longstore(ptr,res);
+ return error;
}
@@ -1702,14 +1817,15 @@ void Field_long::sql_type(String &res) const
** longlong int
****************************************************************************/
-void Field_longlong::store(const char *from,uint len)
+int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs)
{
- while (len && isspace(*from))
+ while (len && my_isspace(system_charset_info,*from))
{ // For easy error check
len--; from++;
}
longlong tmp;
- String tmp_str(from,len);
+ String tmp_str(from,len,default_charset_info);
+ int error= 0;
errno=0;
if (unsigned_flag)
{
@@ -1717,6 +1833,7 @@ void Field_longlong::store(const char *from,uint len)
{
tmp=0; // Set negative to 0
errno=ERANGE;
+ error= 1;
}
else
tmp=(longlong) strtoull(tmp_str.c_ptr(),NULL,10);
@@ -1724,7 +1841,10 @@ void Field_longlong::store(const char *from,uint len)
else
tmp=strtoll(tmp_str.c_ptr(),NULL,10);
if (errno || current_thd->count_cuted_fields && !test_if_int(from,len))
+ {
current_thd->cuted_fields++;
+ error= 1;
+ }
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
{
@@ -1733,11 +1853,13 @@ void Field_longlong::store(const char *from,uint len)
else
#endif
longlongstore(ptr,tmp);
+ return error;
}
-void Field_longlong::store(double nr)
+int Field_longlong::store(double nr)
{
+ int error= 0;
longlong res;
nr=rint(nr);
if (unsigned_flag)
@@ -1746,11 +1868,13 @@ void Field_longlong::store(double nr)
{
res=0;
current_thd->cuted_fields++;
+ error= 1;
}
else if (nr >= (double) ~ (ulonglong) 0)
{
res= ~(longlong) 0;
current_thd->cuted_fields++;
+ error= 1;
}
else
res=(longlong) (ulonglong) nr;
@@ -1761,11 +1885,13 @@ void Field_longlong::store(double nr)
{
res=(longlong) LONGLONG_MIN;
current_thd->cuted_fields++;
+ error= 1;
}
else if (nr >= (double) LONGLONG_MAX)
{
res=(longlong) LONGLONG_MAX;
current_thd->cuted_fields++;
+ error= 1;
}
else
res=(longlong) nr;
@@ -1778,10 +1904,11 @@ void Field_longlong::store(double nr)
else
#endif
longlongstore(ptr,res);
+ return error;
}
-void Field_longlong::store(longlong nr)
+int Field_longlong::store(longlong nr)
{
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
@@ -1791,6 +1918,7 @@ void Field_longlong::store(longlong nr)
else
#endif
longlongstore(ptr,nr);
+ return 0;
}
@@ -1909,35 +2037,43 @@ void Field_longlong::sql_type(String &res) const
** single precision float
****************************************************************************/
-void Field_float::store(const char *from,uint len)
+int Field_float::store(const char *from,uint len,CHARSET_INFO *cs)
{
- String tmp_str(from,len);
+ String tmp_str(from,len,default_charset_info);
errno=0;
Field_float::store(atof(tmp_str.c_ptr()));
if (errno || current_thd->count_cuted_fields && !test_if_real(from,len))
+ {
current_thd->cuted_fields++;
+ return 1;
+ }
+ return (errno) ? 1 : 0;
}
-void Field_float::store(double nr)
+int Field_float::store(double nr)
{
float j;
+ int error= 0;
if (dec < NOT_FIXED_DEC)
nr=floor(nr*log_10[dec]+0.5)/log_10[dec]; // To fixed point
if (unsigned_flag && nr < 0)
{
current_thd->cuted_fields++;
nr=0;
+ error= 1;
}
if (nr < -FLT_MAX)
{
j= -FLT_MAX;
current_thd->cuted_fields++;
+ error= 1;
}
else if (nr > FLT_MAX)
{
j=FLT_MAX;
current_thd->cuted_fields++;
+ error= 1;
}
else
j= (float) nr;
@@ -1949,16 +2085,19 @@ void Field_float::store(double nr)
else
#endif
memcpy_fixed(ptr,(byte*) &j,sizeof(j));
+ return error;
}
-void Field_float::store(longlong nr)
+int Field_float::store(longlong nr)
{
+ int error= 0;
float j= (float) nr;
if (unsigned_flag && j < 0)
{
current_thd->cuted_fields++;
j=0;
+ error= 1;
}
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
@@ -1968,6 +2107,7 @@ void Field_float::store(longlong nr)
else
#endif
memcpy_fixed(ptr,(byte*) &j,sizeof(j));
+ return error;
}
@@ -2159,17 +2299,22 @@ void Field_float::sql_type(String &res) const
** double precision floating point numbers
****************************************************************************/
-void Field_double::store(const char *from,uint len)
+int Field_double::store(const char *from,uint len,CHARSET_INFO *cs)
{
- String tmp_str(from,len);
+ String tmp_str(from,len,default_charset_info);
errno=0;
+ int error= 0;
double j= atof(tmp_str.c_ptr());
if (errno || current_thd->count_cuted_fields && !test_if_real(from,len))
+ {
current_thd->cuted_fields++;
+ error= 1;
+ }
if (unsigned_flag && j < 0)
{
current_thd->cuted_fields++;
j=0;
+ error= 1;
}
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
@@ -2179,17 +2324,20 @@ void Field_double::store(const char *from,uint len)
else
#endif
doublestore(ptr,j);
+ return error;
}
-void Field_double::store(double nr)
+int Field_double::store(double nr)
{
+ int error= 0;
if (dec < NOT_FIXED_DEC)
nr=floor(nr*log_10[dec]+0.5)/log_10[dec]; // To fixed point
if (unsigned_flag && nr < 0)
{
current_thd->cuted_fields++;
nr=0;
+ error= 1;
}
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
@@ -2199,15 +2347,18 @@ void Field_double::store(double nr)
else
#endif
doublestore(ptr,nr);
+ return error;
}
-void Field_double::store(longlong nr)
+int Field_double::store(longlong nr)
{
double j= (double) nr;
+ int error= 0;
if (unsigned_flag && j < 0)
{
current_thd->cuted_fields++;
+ error= 1;
j=0;
}
#ifdef WORDS_BIGENDIAN
@@ -2218,6 +2369,7 @@ void Field_double::store(longlong nr)
else
#endif
doublestore(ptr,j);
+ return error;
}
@@ -2415,7 +2567,7 @@ Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg,
}
-void Field_timestamp::store(const char *from,uint len)
+int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs)
{
long tmp=(long) str_to_timestamp(from,len);
#ifdef WORDS_BIGENDIAN
@@ -2426,6 +2578,7 @@ void Field_timestamp::store(const char *from,uint len)
else
#endif
longstore(ptr,tmp);
+ return 0;
}
void Field_timestamp::fill_and_store(char *from,uint len)
@@ -2457,14 +2610,17 @@ void Field_timestamp::fill_and_store(char *from,uint len)
}
-void Field_timestamp::store(double nr)
+int Field_timestamp::store(double nr)
{
+ int error= 0;
if (nr < 0 || nr > 99991231235959.0)
{
- nr=0; // Avoid overflow on buff
+ nr= 0; // Avoid overflow on buff
current_thd->cuted_fields++;
+ error= 1;
}
- Field_timestamp::store((longlong) rint(nr));
+ error|= Field_timestamp::store((longlong) rint(nr));
+ return error;
}
@@ -2505,7 +2661,7 @@ static longlong fix_datetime(longlong nr)
}
-void Field_timestamp::store(longlong nr)
+int Field_timestamp::store(longlong nr)
{
TIME l_time;
time_t timestamp;
@@ -2533,6 +2689,7 @@ void Field_timestamp::store(longlong nr)
else
#endif
longstore(ptr,(uint32) timestamp);
+ return 0;
}
@@ -2754,12 +2911,16 @@ void Field_timestamp::set_time()
** Stored as a 3 byte unsigned int
****************************************************************************/
-void Field_time::store(const char *from,uint len)
+int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
{
TIME ltime;
long tmp;
+ int error= 0;
if (str_to_time(from,len,&ltime))
+ {
tmp=0L;
+ error= 1;
+ }
else
{
if (ltime.month)
@@ -2769,26 +2930,31 @@ void Field_time::store(const char *from,uint len)
{
tmp=8385959;
current_thd->cuted_fields++;
+ error= 1;
}
}
if (ltime.neg)
tmp= -tmp;
- Field_time::store((longlong) tmp);
+ error |= Field_time::store((longlong) tmp);
+ return error;
}
-void Field_time::store(double nr)
+int Field_time::store(double nr)
{
long tmp;
+ int error= 0;
if (nr > 8385959.0)
{
tmp=8385959L;
current_thd->cuted_fields++;
+ error= 1;
}
else if (nr < -8385959.0)
{
tmp= -8385959L;
current_thd->cuted_fields++;
+ error= 1;
}
else
{
@@ -2799,24 +2965,29 @@ void Field_time::store(double nr)
{
tmp=0;
current_thd->cuted_fields++;
+ error= 1;
}
}
int3store(ptr,tmp);
+ return error;
}
-void Field_time::store(longlong nr)
+int Field_time::store(longlong nr)
{
long tmp;
+ int error= 0;
if (nr > (longlong) 8385959L)
{
tmp=8385959L;
current_thd->cuted_fields++;
+ error= 1;
}
else if (nr < (longlong) -8385959L)
{
tmp= -8385959L;
current_thd->cuted_fields++;
+ error= 1;
}
else
{
@@ -2825,9 +2996,11 @@ void Field_time::store(longlong nr)
{
tmp=0;
current_thd->cuted_fields++;
+ error= 1;
}
}
int3store(ptr,tmp);
+ return error;
}
@@ -2894,7 +3067,7 @@ void Field_time::sort_string(char *to,uint length __attribute__((unused)))
void Field_time::sql_type(String &res) const
{
- res.set("time",4);
+ res.set("time",4,default_charset_info);
}
/****************************************************************************
@@ -2903,16 +3076,16 @@ void Field_time::sql_type(String &res) const
** Can handle 2 byte or 4 byte years!
****************************************************************************/
-void Field_year::store(const char *from, uint len)
+int Field_year::store(const char *from, uint len,CHARSET_INFO *cs)
{
- String tmp_str(from,len);
+ String tmp_str(from,len,default_charset_info);
long nr= strtol(tmp_str.c_ptr(),NULL,10);
if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155)
{
*ptr=0;
current_thd->cuted_fields++;
- return;
+ return 1;
}
else if (current_thd->count_cuted_fields && !test_if_int(from,len))
current_thd->cuted_fields++;
@@ -2924,23 +3097,27 @@ void Field_year::store(const char *from, uint len)
nr-= 1900;
}
*ptr= (char) (unsigned char) nr;
+ return 0;
}
-void Field_year::store(double nr)
+int Field_year::store(double nr)
{
if (nr < 0.0 || nr >= 2155.0)
- Field_year::store((longlong) -1);
+ {
+ (void) Field_year::store((longlong) -1);
+ return 1;
+ }
else
- Field_year::store((longlong) nr);
+ return Field_year::store((longlong) nr);
}
-void Field_year::store(longlong nr)
+int Field_year::store(longlong nr)
{
if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155)
{
*ptr=0;
current_thd->cuted_fields++;
- return;
+ return 1;
}
if (nr != 0 || field_length != 4) // 0000 -> 0; 00 -> 2000
{
@@ -2950,6 +3127,7 @@ void Field_year::store(longlong nr)
nr-= 1900;
}
*ptr= (char) (unsigned char) nr;
+ return 0;
}
@@ -2992,12 +3170,16 @@ void Field_year::sql_type(String &res) const
** Stored as a 4 byte unsigned int
****************************************************************************/
-void Field_date::store(const char *from, uint len)
+int Field_date::store(const char *from, uint len,CHARSET_INFO *cs)
{
TIME l_time;
uint32 tmp;
+ int error= 0;
if (str_to_TIME(from,len,&l_time,1) == TIMESTAMP_NONE)
+ {
tmp=0;
+ error= 1;
+ }
else
tmp=(uint32) l_time.year*10000L + (uint32) (l_time.month*100+l_time.day);
#ifdef WORDS_BIGENDIAN
@@ -3008,18 +3190,21 @@ void Field_date::store(const char *from, uint len)
else
#endif
longstore(ptr,tmp);
+ return error;
}
-void Field_date::store(double nr)
+int Field_date::store(double nr)
{
long tmp;
+ int error= 0;
if (nr >= 19000000000000.0 && nr <= 99991231235959.0)
nr=floor(nr/1000000.0); // Timestamp to date
if (nr < 0.0 || nr > 99991231.0)
{
tmp=0L;
current_thd->cuted_fields++;
+ error= 1;
}
else
tmp=(long) rint(nr);
@@ -3031,18 +3216,21 @@ void Field_date::store(double nr)
else
#endif
longstore(ptr,tmp);
+ return error;
}
-void Field_date::store(longlong nr)
+int Field_date::store(longlong nr)
{
long tmp;
+ int error= 0;
if (nr >= LL(19000000000000) && nr < LL(99991231235959))
nr=nr/LL(1000000); // Timestamp to date
if (nr < 0 || nr > LL(99991231))
{
tmp=0L;
current_thd->cuted_fields++;
+ error= 1;
}
else
tmp=(long) nr;
@@ -3054,6 +3242,7 @@ void Field_date::store(longlong nr)
else
#endif
longstore(ptr,tmp);
+ return error;
}
@@ -3140,7 +3329,7 @@ void Field_date::sort_string(char *to,uint length __attribute__((unused)))
void Field_date::sql_type(String &res) const
{
- res.set("date",4);
+ res.set("date",4,default_charset_info);
}
/****************************************************************************
@@ -3149,35 +3338,45 @@ void Field_date::sql_type(String &res) const
** In number context: YYYYMMDD
****************************************************************************/
-void Field_newdate::store(const char *from,uint len)
+int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs)
{
TIME l_time;
long tmp;
+ int error= 0;
if (str_to_TIME(from,len,&l_time,1) == TIMESTAMP_NONE)
+ {
tmp=0L;
+ error= 1;
+ }
else
tmp= l_time.day + l_time.month*32 + l_time.year*16*32;
int3store(ptr,tmp);
+ return error;
}
-void Field_newdate::store(double nr)
+int Field_newdate::store(double nr)
{
if (nr < 0.0 || nr > 99991231235959.0)
- Field_newdate::store((longlong) -1);
+ {
+ (void) Field_newdate::store((longlong) -1);
+ return 1;
+ }
else
- Field_newdate::store((longlong) rint(nr));
+ return Field_newdate::store((longlong) rint(nr));
}
-void Field_newdate::store(longlong nr)
+int Field_newdate::store(longlong nr)
{
int32 tmp;
+ int error= 0;
if (nr >= LL(100000000) && nr <= LL(99991231235959))
nr=nr/LL(1000000); // Timestamp to date
if (nr < 0L || nr > 99991231L)
{
tmp=0;
current_thd->cuted_fields++;
+ error= 1;
}
else
{
@@ -3195,11 +3394,13 @@ void Field_newdate::store(longlong nr)
{
tmp=0L; // Don't allow date to change
current_thd->cuted_fields++;
+ error= 1;
}
else
tmp= day + month*32 + (tmp/10000)*16*32;
}
int3store(ptr,(int32) tmp);
+ return error;
}
void Field_newdate::store_time(TIME *ltime,timestamp_type type)
@@ -3291,7 +3492,7 @@ void Field_newdate::sort_string(char *to,uint length __attribute__((unused)))
void Field_newdate::sql_type(String &res) const
{
- res.set("date",4);
+ res.set("date",4,default_charset_info);
}
@@ -3302,7 +3503,7 @@ void Field_newdate::sql_type(String &res) const
** Stored as a 8 byte unsigned int. Should sometimes be change to a 6 byte int.
****************************************************************************/
-void Field_datetime::store(const char *from,uint len)
+int Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs)
{
longlong tmp=str_to_datetime(from,len,1);
#ifdef WORDS_BIGENDIAN
@@ -3313,26 +3514,32 @@ void Field_datetime::store(const char *from,uint len)
else
#endif
longlongstore(ptr,tmp);
+ return 0;
}
-void Field_datetime::store(double nr)
+int Field_datetime::store(double nr)
{
+ int error= 0;
if (nr < 0.0 || nr > 99991231235959.0)
{
nr=0.0;
current_thd->cuted_fields++;
+ error= 1;
}
- Field_datetime::store((longlong) rint(nr));
+ error |= Field_datetime::store((longlong) rint(nr));
+ return error;
}
-void Field_datetime::store(longlong nr)
+int Field_datetime::store(longlong nr)
{
+ int error= 0;
if (nr < 0 || nr > LL(99991231235959))
{
nr=0;
current_thd->cuted_fields++;
+ error= 1;
}
else
nr=fix_datetime(nr);
@@ -3344,6 +3551,7 @@ void Field_datetime::store(longlong nr)
else
#endif
longlongstore(ptr,nr);
+ return error;
}
void Field_datetime::store_time(TIME *ltime,timestamp_type type)
@@ -3508,7 +3716,7 @@ void Field_datetime::sort_string(char *to,uint length __attribute__((unused)))
void Field_datetime::sql_type(String &res) const
{
- res.set("datetime",8);
+ res.set("datetime",8,default_charset_info);
}
/****************************************************************************
@@ -3518,8 +3726,10 @@ void Field_datetime::sql_type(String &res) const
/* Copy a string and fill with space */
-void Field_string::store(const char *from,uint length)
+int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
{
+ field_charset=cs;
+ int error= 0;
#ifdef USE_TIS620
if (!binary_flag) {
ThNormalize((uchar *)ptr, field_length, (uchar *)from, length);
@@ -3542,33 +3752,35 @@ void Field_string::store(const char *from,uint length)
const char *end=from+length;
for (from+=field_length ; from != end ; from++)
{
- if (!isspace(*from))
+ if (!my_isspace(field_charset,*from))
{
current_thd->cuted_fields++;
+ error=1;
break;
}
}
}
}
#endif /* USE_TIS620 */
+ return error;
}
-void Field_string::store(double nr)
+int Field_string::store(double nr)
{
char buff[MAX_FIELD_WIDTH],*end;
int width=min(field_length,DBL_DIG+5);
sprintf(buff,"%-*.*g",width,max(width-5,0),nr);
end=strcend(buff,' ');
- Field_string::store(buff,(uint) (end - buff));
+ return Field_string::store(buff,(uint) (end - buff), default_charset_info);
}
-void Field_string::store(longlong nr)
+int Field_string::store(longlong nr)
{
char buff[22];
char *end=longlong10_to_str(nr,buff,-10);
- Field_string::store(buff,(uint) (end-buff));
+ return Field_string::store(buff,(uint) (end-buff), default_charset_info);
}
@@ -3603,7 +3815,7 @@ String *Field_string::val_str(String *val_buffer __attribute__((unused)),
#endif
while (end > ptr && end[-1] == ' ')
end--;
- val_ptr->set((const char*) ptr,(uint) (end - ptr));
+ val_ptr->set((const char*) ptr,(uint) (end - ptr),field_charset);
return val_ptr;
}
@@ -3613,7 +3825,7 @@ int Field_string::cmp(const char *a_ptr, const char *b_ptr)
if (binary_flag)
return memcmp(a_ptr,b_ptr,field_length);
else
- return my_sortcmp(a_ptr,b_ptr,field_length);
+ return my_sortcmp(field_charset,a_ptr,b_ptr,field_length);
}
void Field_string::sort_string(char *to,uint length)
@@ -3623,17 +3835,17 @@ void Field_string::sort_string(char *to,uint length)
else
{
#ifdef USE_STRCOLL
- if (use_strcoll(default_charset_info)) {
- uint tmp=my_strnxfrm(default_charset_info,
- (unsigned char *)to, (unsigned char *) ptr,
- length, field_length);
+ if (use_strcoll(field_charset)) {
+ uint tmp=my_strnxfrm(field_charset,
+ (unsigned char *)to, length,
+ (unsigned char *) ptr, field_length);
if (tmp < length)
bzero(to + tmp, length - tmp);
}
else
#endif
for (char *from=ptr,*end=ptr+length ; from != end ;)
- *to++=(char) my_sort_order[(uint) (uchar) *from++];
+ *to++=(char) field_charset->sort_order[(uint) (uchar) *from++];
}
}
@@ -3648,6 +3860,11 @@ void Field_string::sql_type(String &res) const
res.length((uint) strlen(res.ptr()));
if (binary_flag)
res.append(" binary");
+ else
+ {
+ res.append(" character set ");
+ res.append(field_charset->name);
+ }
}
@@ -3682,7 +3899,7 @@ int Field_string::pack_cmp(const char *a, const char *b, uint length)
int cmp= memcmp(a,b,min(a_length,b_length));
return cmp ? cmp : (int) (a_length - b_length);
}
- return my_sortncmp(a,a_length, b,b_length);
+ return my_sortncmp(field_charset, a,a_length, b,b_length);
}
@@ -3699,7 +3916,7 @@ int Field_string::pack_cmp(const char *b, uint length)
int cmp= memcmp(ptr,b,min(a_length,b_length));
return cmp ? cmp : (int) (a_length - b_length);
}
- return my_sortncmp(ptr,a_length, b, b_length);
+ return my_sortncmp(field_charset, ptr,a_length, b, b_length);
}
@@ -3722,8 +3939,10 @@ uint Field_string::max_packed_col_length(uint max_length)
****************************************************************************/
-void Field_varstring::store(const char *from,uint length)
+int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
{
+ int error= 0;
+ field_charset=cs;
#ifdef USE_TIS620
if (!binary_flag)
{
@@ -3739,27 +3958,29 @@ void Field_varstring::store(const char *from,uint length)
length=field_length;
memcpy(ptr+2,from,field_length);
current_thd->cuted_fields++;
+ error= 1;
}
#endif /* USE_TIS620 */
int2store(ptr,length);
+ return error;
}
-void Field_varstring::store(double nr)
+int Field_varstring::store(double nr)
{
char buff[MAX_FIELD_WIDTH],*end;
int width=min(field_length,DBL_DIG+5);
sprintf(buff,"%-*.*g",width,max(width-5,0),nr);
end=strcend(buff,' ');
- Field_varstring::store(buff,(uint) (end - buff));
+ return Field_varstring::store(buff,(uint) (end - buff), default_charset_info);
}
-void Field_varstring::store(longlong nr)
+int Field_varstring::store(longlong nr)
{
char buff[22];
char *end=longlong10_to_str(nr,buff,-10);
- Field_varstring::store(buff,(uint) (end-buff));
+ return Field_varstring::store(buff,(uint) (end-buff), default_charset_info);
}
@@ -3791,7 +4012,7 @@ String *Field_varstring::val_str(String *val_buffer __attribute__((unused)),
String *val_ptr)
{
uint length=uint2korr(ptr);
- val_ptr->set((const char*) ptr+2,length);
+ val_ptr->set((const char*) ptr+2,length,field_charset);
return val_ptr;
}
@@ -3804,7 +4025,7 @@ int Field_varstring::cmp(const char *a_ptr, const char *b_ptr)
if (binary_flag)
diff=memcmp(a_ptr+2,b_ptr+2,min(a_length,b_length));
else
- diff=my_sortcmp(a_ptr+2,b_ptr+2,min(a_length,b_length));
+ diff=my_sortcmp(field_charset, a_ptr+2,b_ptr+2,min(a_length,b_length));
return diff ? diff : (int) (a_length - b_length);
}
@@ -3816,10 +4037,10 @@ void Field_varstring::sort_string(char *to,uint length)
else
{
#ifdef USE_STRCOLL
- if (use_strcoll(default_charset_info))
- tot_length=my_strnxfrm(default_charset_info,
- (unsigned char *) to, (unsigned char *)ptr+2,
- length, tot_length);
+ if (use_strcoll(field_charset))
+ tot_length=my_strnxfrm(field_charset,
+ (unsigned char *) to, length,
+ (unsigned char *)ptr+2, tot_length);
else
{
#endif
@@ -3827,7 +4048,7 @@ void Field_varstring::sort_string(char *to,uint length)
if (tot_length > length)
tot_length=length;
for (char *from=ptr+2,*end=from+tot_length ; from != end ;)
- *tmp++=(char) my_sort_order[(uint) (uchar) *from++];
+ *tmp++=(char) field_charset->sort_order[(uint) (uchar) *from++];
#ifdef USE_STRCOLL
}
#endif
@@ -3843,6 +4064,11 @@ void Field_varstring::sql_type(String &res) const
res.length((uint) strlen(res.ptr()));
if (binary_flag)
res.append(" binary");
+ else
+ {
+ res.append(" character set ");
+ res.append(field_charset->name);
+ }
}
char *Field_varstring::pack(char *to, const char *from, uint max_length)
@@ -3898,7 +4124,7 @@ int Field_varstring::pack_cmp(const char *a, const char *b, uint key_length)
int cmp= memcmp(a,b,min(a_length,b_length));
return cmp ? cmp : (int) (a_length - b_length);
}
- return my_sortncmp(a,a_length, b,b_length);
+ return my_sortncmp(field_charset, a,a_length, b,b_length);
}
int Field_varstring::pack_cmp(const char *b, uint key_length)
@@ -3919,7 +4145,7 @@ int Field_varstring::pack_cmp(const char *b, uint key_length)
int cmp= memcmp(a,b,min(a_length,b_length));
return cmp ? cmp : (int) (a_length - b_length);
}
- return my_sortncmp(a,a_length, b,b_length);
+ return my_sortncmp(field_charset, a,a_length, b,b_length);
}
uint Field_varstring::packed_col_length(const char *ptr, uint length)
@@ -3944,11 +4170,11 @@ uint Field_varstring::max_packed_col_length(uint max_length)
Field_blob::Field_blob(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,uint blob_pack_length,
- bool binary_arg)
+ bool binary_arg, CHARSET_INFO *cs)
:Field_str(ptr_arg, (1L << min(blob_pack_length,3)*8)-1L,
null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg,
- table_arg),
- packlength(blob_pack_length),binary_flag(binary_arg)
+ table_arg, cs),
+ packlength(blob_pack_length),binary_flag(binary_arg), geom_flag(true)
{
flags|= BLOB_FLAG;
if (binary_arg)
@@ -4039,8 +4265,9 @@ uint32 Field_blob::get_length(const char *pos)
}
-void Field_blob::store(const char *from,uint len)
+int Field_blob::store(const char *from,uint len,CHARSET_INFO *cs)
{
+ field_charset=cs;
if (!len)
{
bzero(ptr,Field_blob::pack_length());
@@ -4072,20 +4299,23 @@ void Field_blob::store(const char *from,uint len)
}
bmove(ptr+packlength,(char*) &from,sizeof(char*));
}
+ return 0;
}
-void Field_blob::store(double nr)
+int Field_blob::store(double nr)
{
value.set(nr);
- Field_blob::store(value.ptr(),(uint) value.length());
+ return Field_blob::store(value.ptr(),(uint) value.length(),
+ default_charset_info);
}
-void Field_blob::store(longlong nr)
+int Field_blob::store(longlong nr)
{
value.set(nr);
- Field_blob::store(value.ptr(), (uint) value.length());
+ return Field_blob::store(value.ptr(), (uint) value.length(),
+ default_charset_info);
}
@@ -4128,9 +4358,9 @@ String *Field_blob::val_str(String *val_buffer __attribute__((unused)),
char *blob;
memcpy_fixed(&blob,ptr+packlength,sizeof(char*));
if (!blob)
- val_ptr->set("",0); // A bit safer than ->length(0)
+ val_ptr->set("",0,field_charset); // A bit safer than ->length(0)
else
- val_ptr->set((const char*) blob,get_length(ptr));
+ val_ptr->set((const char*) blob,get_length(ptr),field_charset);
return val_ptr;
}
@@ -4142,7 +4372,7 @@ int Field_blob::cmp(const char *a,uint32 a_length, const char *b,
if (binary_flag)
diff=memcmp(a,b,min(a_length,b_length));
else
- diff=my_sortcmp(a,b,min(a_length,b_length));
+ diff=my_sortcmp(field_charset, a,b,min(a_length,b_length));
return diff ? diff : (int) (a_length - b_length);
}
@@ -4190,11 +4420,30 @@ int Field_blob::cmp_binary(const char *a_ptr, const char *b_ptr,
/* The following is used only when comparing a key */
-void Field_blob::get_key_image(char *buff,uint length)
+void Field_blob::get_key_image(char *buff,uint length, imagetype type)
{
- length-=HA_KEY_BLOB_LENGTH;
- uint32 blob_length=get_length(ptr);
+ length-= HA_KEY_BLOB_LENGTH;
+ uint32 blob_length= get_length(ptr);
char *blob;
+
+ if (type == itMBR)
+ {
+ if (!blob_length)
+ return;
+ get_ptr(&blob);
+
+ MBR mbr;
+ Geometry gobj;
+ gobj.create_from_wkb(blob,blob_length);
+ gobj.get_mbr(&mbr);
+ float8store(buff, mbr.xmin);
+ float8store(buff+8, mbr.xmax);
+ float8store(buff+16, mbr.ymin);
+ float8store(buff+24, mbr.ymax);
+ return;
+ }
+
+ length-=HA_KEY_BLOB_LENGTH;
if ((uint32) length > blob_length)
{
#ifdef HAVE_purify
@@ -4210,9 +4459,34 @@ void Field_blob::get_key_image(char *buff,uint length)
void Field_blob::set_key_image(char *buff,uint length)
{
length=uint2korr(buff);
- Field_blob::store(buff+2,length);
+ (void) Field_blob::store(buff+2,length, default_charset_info);
}
+
+void Field_geom::get_key_image(char *buff,uint length, imagetype type)
+{
+ length-=HA_KEY_BLOB_LENGTH;
+ ulong blob_length=get_length(ptr);
+ char *blob;
+ get_ptr(&blob);
+ memcpy(buff+2,blob,length);
+
+ MBR mbr;
+ Geometry gobj;
+ gobj.create_from_wkb(blob,blob_length);
+ gobj.get_mbr(&mbr);
+ float8store(buff, mbr.xmin);
+ float8store(buff+8, mbr.xmax);
+ float8store(buff+16, mbr.ymin);
+ float8store(buff+24, mbr.ymax);
+ return;
+}
+
+void Field_geom::set_key_image(char *buff,uint length)
+{
+}
+
+
int Field_blob::key_cmp(const byte *key_ptr, uint max_key_length)
{
char *blob1;
@@ -4252,11 +4526,11 @@ void Field_blob::sort_string(char *to,uint length)
else
{
#ifdef USE_STRCOLL
- if (use_strcoll(default_charset_info))
+ if (use_strcoll(field_charset))
{
- blob_length=my_strnxfrm(default_charset_info,
- (unsigned char *)to,(unsigned char *)blob,
- length,blob_org_length);
+ blob_length=my_strnxfrm(field_charset,
+ (unsigned char *)to, length,
+ (unsigned char *)blob, blob_org_length);
if (blob_length >= length)
return;
to+=blob_length;
@@ -4264,7 +4538,7 @@ void Field_blob::sort_string(char *to,uint length)
else
#endif
for (char *end=blob+blob_length ; blob != end ;)
- *to++=(char) my_sort_order[(uint) (uchar) *blob++];
+ *to++=(char) field_charset->sort_order[(uint) (uchar) *blob++];
}
bzero(to,length-blob_length);
}
@@ -4280,8 +4554,13 @@ void Field_blob::sql_type(String &res) const
case 3: str="medium"; break;
case 4: str="long"; break;
}
- res.set(str,(uint) strlen(str));
+ res.set(str,(uint) strlen(str),default_charset_info);
res.append(binary_flag ? "blob" : "text");
+ if (!binary_flag)
+ {
+ res.append(" character set ");
+ res.append(field_charset->name);
+ }
}
@@ -4342,7 +4621,7 @@ int Field_blob::pack_cmp(const char *a, const char *b, uint key_length)
int cmp= memcmp(a,b,min(a_length,b_length));
return cmp ? cmp : (int) (a_length - b_length);
}
- return my_sortncmp(a,a_length, b,b_length);
+ return my_sortncmp(field_charset, a,a_length, b,b_length);
}
@@ -4368,7 +4647,7 @@ int Field_blob::pack_cmp(const char *b, uint key_length)
int cmp= memcmp(a,b,min(a_length,b_length));
return cmp ? cmp : (int) (a_length - b_length);
}
- return my_sortncmp(a,a_length, b,b_length);
+ return my_sortncmp(field_charset, a,a_length, b,b_length);
}
/* Create a packed key that will be used for storage from a MySQL row */
@@ -4479,14 +4758,16 @@ void Field_enum::store_type(ulonglong value)
uint find_enum(TYPELIB *lib,const char *x, uint length)
{
const char *end=x+length;
- while (end > x && isspace(end[-1]))
+ while (end > x && my_isspace(system_charset_info,end[-1]))
end--;
const char *i;
const char *j;
for (uint pos=0 ; (j=lib->type_names[pos]) ; pos++)
{
- for (i=x ; i != end && toupper(*i) == toupper(*j) ; i++, j++) ;
+ for (i=x ; i != end &&
+ my_toupper(system_charset_info,*i) ==
+ my_toupper(system_charset_info,*j) ; i++, j++) ;
if (i == end && ! *j)
return(pos+1);
}
@@ -4499,8 +4780,9 @@ uint find_enum(TYPELIB *lib,const char *x, uint length)
** (if there isn't a empty value in the enum)
*/
-void Field_enum::store(const char *from,uint length)
+int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs)
{
+ int error= 0;
uint tmp=find_enum(typelib,from,length);
if (!tmp)
{
@@ -4520,29 +4802,34 @@ void Field_enum::store(const char *from,uint length)
{
tmp=0;
current_thd->cuted_fields++;
+ error=1;
}
}
else
current_thd->cuted_fields++;
}
store_type((ulonglong) tmp);
+ return error;
}
-void Field_enum::store(double nr)
+int Field_enum::store(double nr)
{
- Field_enum::store((longlong) nr);
+ return Field_enum::store((longlong) nr);
}
-void Field_enum::store(longlong nr)
+int Field_enum::store(longlong nr)
{
+ int error= 0;
if ((uint) nr > typelib->count || nr == 0)
{
current_thd->cuted_fields++;
nr=0;
+ error=1;
}
store_type((ulonglong) (uint) nr);
+ return error;
}
@@ -4605,7 +4892,8 @@ String *Field_enum::val_str(String *val_buffer __attribute__((unused)),
val_ptr->length(0);
else
val_ptr->set((const char*) typelib->type_names[tmp-1],
- (uint) strlen(typelib->type_names[tmp-1]));
+ (uint) strlen(typelib->type_names[tmp-1]),
+ default_charset_info);
return val_ptr;
}
@@ -4642,9 +4930,7 @@ void Field_enum::sql_type(String &res) const
{
if (flag)
res.append(',');
- res.append('\'');
- append_unescaped(&res,*pos);
- res.append('\'');
+ append_unescaped(&res, *pos, strlen(*pos));
flag=1;
}
res.append(')');
@@ -4663,14 +4949,14 @@ void Field_enum::sql_type(String &res) const
ulonglong find_set(TYPELIB *lib,const char *x,uint length)
{
const char *end=x+length;
- while (end > x && isspace(end[-1]))
+ while (end > x && my_isspace(system_charset_info, end[-1]))
end--;
ulonglong found=0;
if (x != end)
{
const char *start=x;
- bool error=0;
+ bool error= 0;
for (;;)
{
const char *pos=start;
@@ -4691,8 +4977,9 @@ ulonglong find_set(TYPELIB *lib,const char *x,uint length)
}
-void Field_set::store(const char *from,uint length)
+int Field_set::store(const char *from,uint length,CHARSET_INFO *cs)
{
+ int error= 0;
ulonglong tmp=find_set(typelib,from,length);
if (!tmp && length && length < 22)
{
@@ -4708,23 +4995,30 @@ void Field_set::store(const char *from,uint length)
tmp=strtoull(conv,&end,10);
if (my_errno || end != conv+length ||
tmp > (ulonglong) (((longlong) 1 << typelib->count) - (longlong) 1))
+ {
tmp=0;
+ error=1;
+ }
else
current_thd->cuted_fields--; // Remove warning from find_set
}
store_type(tmp);
+ return error;
}
-void Field_set::store(longlong nr)
+int Field_set::store(longlong nr)
{
+ int error= 0;
if ((ulonglong) nr > (ulonglong) (((longlong) 1 << typelib->count) -
(longlong) 1))
{
nr&= (longlong) (((longlong) 1 << typelib->count) - (longlong) 1);
current_thd->cuted_fields++;
+ error=1;
}
store_type((ulonglong) nr);
+ return error;
}
@@ -4742,7 +5036,8 @@ String *Field_set::val_str(String *val_buffer,
if (val_buffer->length())
val_buffer->append(field_separator);
String str(typelib->type_names[bitnr],
- (uint) strlen(typelib->type_names[bitnr]));
+ (uint) strlen(typelib->type_names[bitnr]),
+ default_charset_info);
val_buffer->append(str);
}
tmp>>=1;
@@ -4762,9 +5057,7 @@ void Field_set::sql_type(String &res) const
{
if (flag)
res.append(',');
- res.append('\'');
- append_unescaped(&res,*pos);
- res.append('\'');
+ append_unescaped(&res, *pos, strlen(*pos));
flag=1;
}
res.append(')');
@@ -4789,7 +5082,8 @@ bool Field_enum::eq_def(Field *field)
if (typelib->count < from_lib->count)
return 0;
for (uint i=0 ; i < from_lib->count ; i++)
- if (my_strcasecmp(typelib->type_names[i],from_lib->type_names[i]))
+ if (my_strcasecmp(field_charset,
+ typelib->type_names[i],from_lib->type_names[i]))
return 0;
return 1;
}
@@ -4864,6 +5158,7 @@ uint pack_length_to_packflag(uint type)
Field *make_field(char *ptr, uint32 field_length,
uchar *null_pos, uchar null_bit,
uint pack_flag,
+ enum_field_types field_type,
Field::utype unireg_check,
TYPELIB *interval,
const char *field_name,
@@ -4879,7 +5174,8 @@ Field *make_field(char *ptr, uint32 field_length,
if (!f_is_packed(pack_flag))
return new Field_string(ptr,field_length,null_pos,null_bit,
unireg_check, field_name, table,
- f_is_binary(pack_flag) != 0);
+ f_is_binary(pack_flag) != 0,
+ default_charset_info);
uint pack_length=calc_pack_length((enum_field_types)
f_packtype(pack_flag),
@@ -4888,7 +5184,13 @@ Field *make_field(char *ptr, uint32 field_length,
if (f_is_blob(pack_flag))
return new Field_blob(ptr,null_pos,null_bit,
unireg_check, field_name, table,
+ pack_length,f_is_binary(pack_flag) != 0,
+ default_charset_info);
+ if (f_is_geom(pack_flag))
+ return new Field_geom(ptr,null_pos,null_bit,
+ unireg_check, field_name, table,
pack_length,f_is_binary(pack_flag) != 0);
+
if (interval)
{
if (f_is_enum(pack_flag))
@@ -4902,7 +5204,7 @@ Field *make_field(char *ptr, uint32 field_length,
}
}
- switch ((enum enum_field_types) f_packtype(pack_flag)) {
+ switch (field_type) {
case FIELD_TYPE_DECIMAL:
return new Field_decimal(ptr,field_length,null_pos,null_bit,
unireg_check, field_name, table,
@@ -4983,6 +5285,8 @@ create_field::create_field(Field *old_field,Field *orig_field)
unireg_check=old_field->unireg_check;
pack_length=old_field->pack_length();
sql_type= old_field->real_type();
+ charset= old_field->charset(); // May be NULL ptr
+ comment= old_field->comment;
/* Fix if the original table had 4 byte pointer blobs */
if (flags & BLOB_FLAG)
@@ -4991,6 +5295,7 @@ create_field::create_field(Field *old_field,Field *orig_field)
decimals= old_field->decimals();
if (sql_type == FIELD_TYPE_STRING)
{
+ /* Change CHAR -> VARCHAR if dynamic record length */
sql_type=old_field->type();
decimals=0;
}
@@ -5004,7 +5309,8 @@ create_field::create_field(Field *old_field,Field *orig_field)
orig_field)
{
char buff[MAX_FIELD_WIDTH],*pos;
- String tmp(buff,sizeof(buff));
+ CHARSET_INFO *field_charset= charset ? charset : default_charset_info;
+ String tmp(buff,sizeof(buff),field_charset);
/* Get the value from record[2] (the default value row) */
my_ptrdiff_t diff= (my_ptrdiff_t) (orig_field->table->rec_buff_length*2);
@@ -5016,7 +5322,7 @@ create_field::create_field(Field *old_field,Field *orig_field)
{
pos= (char*) sql_memdup(tmp.ptr(),tmp.length()+1);
pos[tmp.length()]=0;
- def=new Item_string(pos,tmp.length());
+ def=new Item_string(pos,tmp.length(),field_charset);
}
}
}