diff options
Diffstat (limited to 'sql/field.cc')
-rw-r--r-- | sql/field.cc | 884 |
1 files changed, 536 insertions, 348 deletions
diff --git a/sql/field.cc b/sql/field.cc index 246427cc2ac..aae4fac2a38 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1,15 +1,15 @@ /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -41,8 +41,13 @@ #include <floatingpoint.h> #endif +// Maximum allowed exponent value for converting string to decimal +#define MAX_EXPONENT 1024 + + + /***************************************************************************** -** Instansiate templates and static variables + Instansiate templates and static variables *****************************************************************************/ #ifdef __GNUC__ @@ -50,69 +55,13 @@ template class List<create_field>; template class List_iterator<create_field>; #endif -struct st_decstr { - uint nr_length,nr_dec,sign,extra; - char sign_char; -}; - uchar Field_null::null[1]={1}; const char field_separator=','; /***************************************************************************** -** Static help functions + Static help functions *****************************************************************************/ - /* - Calculate length of number and it's parts - Increment cuted_fields if wrong number - */ - -static bool -number_dec(struct st_decstr *sdec, const char *str, const char *end) -{ - sdec->sign=sdec->extra=0; - if (str == end) - { - current_thd->cuted_fields++; - sdec->nr_length=sdec->nr_dec=sdec->sign=0; - sdec->extra=1; // We must put one 0 before . - return 1; - } - - if (*str == '-' || *str == '+') /* sign */ - { - sdec->sign_char= *str; - sdec->sign=1; - str++; - } - const char *start=str; - while (str != end && isdigit(*str)) - str++; - if (!(sdec->nr_length=(uint) (str-start))) - sdec->extra=1; // We must put one 0 before . - start=str; - if (str != end && *str == '.') - { - str++; - start=str; - while (str != end && isdigit(*str)) - str++; - } - sdec->nr_dec=(uint) (str-start); - if (current_thd->count_cuted_fields) - { - while (str != end && isspace(*str)) - str++; /* purecov: inspected */ - if (str != end) - { - current_thd->cuted_fields++; - return 1; - } - } - return 0; -} - - void Field_num::prepend_zeros(String *value) { int diff; @@ -127,8 +76,8 @@ void Field_num::prepend_zeros(String *value) } /* -** Test if given number is a int (or a fixed format float with .000) -** This is only used to give warnings in ALTER TABLE or LOAD DATA... + Test if given number is a int (or a fixed format float with .000) + This is only used to give warnings in ALTER TABLE or LOAD DATA... */ bool test_if_int(const char *str,int length) @@ -141,7 +90,7 @@ bool test_if_int(const char *str,int length) str++; if (str == end) return 0; // Error: Empty string - for ( ; str != end ; str++) + for (; str != end ; str++) { if (!isdigit(*str)) { @@ -204,7 +153,7 @@ static bool test_if_real(const char *str,int length) length--; str++; } } - for ( ; length ; length--, str++) + for (; length ; length--, str++) { // Allow end space if (!isspace(*str)) return 0; @@ -215,18 +164,19 @@ static bool test_if_real(const char *str,int length) /**************************************************************************** ** Functions for the base classes -** This is a unpacked number. +** This is an unpacked number. ****************************************************************************/ Field::Field(char *ptr_arg,uint32 length_arg,uchar *null_ptr_arg, - uint null_bit_arg, + uchar null_bit_arg, utype unireg_check_arg, const char *field_name_arg, struct st_table *table_arg) - :ptr(ptr_arg),null_ptr(null_ptr_arg),null_bit(null_bit_arg), - table(table_arg),query_id(0),key_start(0),part_of_key(0),part_of_sortkey(0), - table_name(table_arg ? table_arg->table_name : 0), - field_name(field_name_arg), unireg_check(unireg_check_arg), - field_length(length_arg) + :ptr(ptr_arg),null_ptr(null_ptr_arg), + table(table_arg),table_name(table_arg ? table_arg->table_name : 0), + field_name(field_name_arg), + query_id(0),key_start(0),part_of_key(0),part_of_sortkey(0), + unireg_check(unireg_check_arg), + field_length(length_arg),null_bit(null_bit_arg) { flags=null_ptr ? 0: NOT_NULL_FLAG; } @@ -242,13 +192,13 @@ void Field::copy_from_tmp(int row_offset) memcpy(ptr,ptr+row_offset,pack_length()); if (null_ptr) { - *null_ptr= ((null_ptr[0] & (uchar) ~(uint) null_bit) | - null_ptr[row_offset] & (uchar) null_bit); + *null_ptr= (uchar) ((null_ptr[0] & (uchar) ~(uint) null_bit) | + null_ptr[row_offset] & (uchar) null_bit); } } -bool Field::send(String *packet) +bool Field::send(THD *thd, String *packet) { if (is_null()) return net_store_null(packet); @@ -256,7 +206,7 @@ bool Field::send(String *packet) String tmp(buff,sizeof(buff)); val_str(&tmp,&tmp); CONVERT *convert; - if ((convert=current_thd->convert_set)) + if ((convert=thd->variables.convert_set)) return convert->store(packet,tmp.ptr(),tmp.length()); return net_store_data(packet,tmp.ptr(),tmp.length()); } @@ -361,14 +311,14 @@ void Field::store_time(TIME *ltime,timestamp_type type) } -bool Field::optimize_range() +bool Field::optimize_range(uint idx) { - return test(table->file->option_flag() & HA_READ_NEXT); + return test(table->file->index_flags(idx) & HA_READ_NEXT); } /**************************************************************************** -** Functions for the Field_decimal class -** This is a unpacked number. + Functions for the Field_decimal class + This is an number stored as a pre-space (or pre-zero) string ****************************************************************************/ void @@ -381,6 +331,8 @@ void Field_decimal::overflow(bool negative) { uint len=field_length; char *to=ptr, filler= '9'; + + current_thd->cuted_fields++; if (negative) { if (!unsigned_flag) @@ -416,100 +368,348 @@ void Field_decimal::overflow(bool negative) void Field_decimal::store(const char *from,uint len) { - reg3 int i; - uint tmp_dec; - char fyllchar; - const char *end=from+len; - struct st_decstr decstr; - bool error; + const char *end= from+len; + /* The pointer where the field value starts (i.e., "where to write") */ + char *to=ptr; + uint tmp_dec, tmp_uint; + /* + The sign of the number : will be 0 (means positive but sign not + specified), '+' or '-' + */ + char sign_char=0; + /* 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 */ + const char *int_digits_from, *int_digits_end; + /* 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 '-' */ + char expo_sign_char=0; + uint exponent=0; // value of the exponent + /* + Pointers used when digits move from the left of the '.' to the + right of the '.' (explained below) + */ + 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 '.' + */ + const char *frac_digits_head_end; + /* 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 + */ + bool is_cuted_fields_incr=0; + + LINT_INIT(int_digits_tail_from); + LINT_INIT(int_digits_added_zeros); + LINT_INIT(frac_digits_head_end); + LINT_INIT(frac_digits_added_zeros); - if ((tmp_dec= dec)) - tmp_dec++; // Calculate pos of '.' - while (from != end && isspace(*from)) - from++; - if (zerofill) + /* + 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 + */ + + if ((tmp_dec=dec)) + tmp_dec++; + + for (; from !=end && isspace(*from); from++) ; // Read spaces + if (from == end) { - fyllchar = '0'; - if (from != end) - while (*from == '0' && from != end-1) // Skipp prezero - from++; + current_thd->cuted_fields++; + is_cuted_fields_incr=1; + } + else if (*from == '+' || *from == '-') // Found some sign ? + { + sign_char= *from++; + /* + We allow "+" for unsigned decimal unless defined different + Both options allowed as one may wish not to have "+" for unsigned numbers + because of data processing issues + */ + if (unsigned_flag) + { + if (sign_char=='-') + { + Field_decimal::overflow(1); + return; + } + /* + 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 + sign_char=0; +#endif + } } - else - fyllchar=' '; - error=number_dec(&decstr,from,end); - if (decstr.sign) - { + + pre_zeros_from= from; + 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++) ; + 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++) ; + frac_digits_end=from; + // Some exponentiation symbol ? + if (from != end && (*from == 'e' || *from == 'E')) + { from++; - if (unsigned_flag) // No sign with zerofill + if (from != end && (*from == '+' || *from == '-')) // Some exponent sign ? + expo_sign_char= *from++; + else + expo_sign_char= '+'; + /* + Read digits of the exponent and compute its value. We must care about + 'exponent' overflow, because as unsigned arithmetic is "modulo", big + exponents will become small (e.g. 1e4294967296 will become 1e0, and the + field will finally contain 1 instead of its max possible value). + */ + for (;from!=end && isdigit(*from); from++) { - if (decstr.sign_char == '+') // just remove "+" - decstr.sign= 0; - else - { - if (!error) - current_thd->cuted_fields++; - Field_decimal::overflow(1); - return; - } + exponent=10*exponent+(*from-'0'); + if (exponent>MAX_EXPONENT) + break; } } + /* - ** Remove pre-zeros if too big number + We only have to generate warnings if count_cuted_fields is set. + This is to avoid extra checks of the number when they are not needed. + Even if this flag is not set, it's ok to increment warnings, if + it makes the code easer to read. */ - for (i= (int) (decstr.nr_length+decstr.extra -(field_length-tmp_dec)+ - decstr.sign) ; - i > 0 ; - i--) + + if (current_thd->count_cuted_fields) { - if (*from == '0') + for (;from != end && isspace(*from); from++) ; // Read end spaces + if (from != end) // If still something left, warn { - from++; - decstr.nr_length--; - continue; + current_thd->cuted_fields++; + is_cuted_fields_incr=1; } - if (decstr.sign && decstr.sign_char == '+' && i == 1) - { // Remove pre '+' - decstr.sign=0; - break; + } + + /* + 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' + - 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 : + - 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'. + - 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). + */ + + /* + Below tmp_uint cannot overflow with small enough MAX_EXPONENT setting, + as int_digits_added_zeros<=exponent<4G and + (int_digits_end-int_digits_from)<=max_allowed_packet<=2G and + (frac_digits_from-int_digits_tail_from)<=max_allowed_packet<=2G + */ + + if (!expo_sign_char) + tmp_uint=tmp_dec+(uint)(int_digits_end-int_digits_from); + else if (expo_sign_char == '-') + { + tmp_uint=min(exponent,(uint)(int_digits_end-int_digits_from)); + frac_digits_added_zeros=exponent-tmp_uint; + int_digits_end -= tmp_uint; + frac_digits_head_end=int_digits_end+tmp_uint; + tmp_uint=tmp_dec+(uint)(int_digits_end-int_digits_from); + } + else // (expo_sign_char=='+') + { + tmp_uint=min(exponent,(uint)(frac_digits_end-frac_digits_from)); + int_digits_added_zeros=exponent-tmp_uint; + int_digits_tail_from=frac_digits_from; + frac_digits_from=frac_digits_from+tmp_uint; + /* + We "eat" the heading zeros of the + int_digits.int_digits_tail.int_digits_added_zeros concatenation + (for example 0.003e3 must become 3 and not 0003) + */ + if (int_digits_from == int_digits_end) + { + /* + There was nothing in the int_digits part, so continue + eating int_digits_tail zeros + */ + for (; int_digits_tail_from != frac_digits_from && + *int_digits_tail_from == '0'; int_digits_tail_from++) ; + if (int_digits_tail_from == frac_digits_from) + { + // there were only zeros in int_digits_tail too + int_digits_added_zeros=0; + } } - current_thd->cuted_fields++; + tmp_uint= (tmp_dec+(int_digits_end-int_digits_from)+ + (uint)(frac_digits_from-int_digits_tail_from)+ + int_digits_added_zeros); + } + + /* + Now write the formated number + + First the digits of the int_% parts. + Do we have enough room to write these digits ? + If the sign is defined and '-', we need one position for it + */ + + if (field_length < tmp_uint + (int) (sign_char == '-')) + { // too big number, change to max or min number - Field_decimal::overflow(decstr.sign && decstr.sign_char == '-'); + Field_decimal::overflow(sign_char == '-'); return; } - char *to=ptr; - for (i=(int) (field_length-tmp_dec-decstr.nr_length-decstr.extra - decstr.sign) ; - i-- > 0 ;) - *to++ = fyllchar; - if (decstr.sign) - *to++= decstr.sign_char; - if (decstr.extra) - *to++ = '0'; - for (i=(int) decstr.nr_length ; i-- > 0 ; ) - *to++ = *from++; - if (tmp_dec--) - { - *to++ ='.'; - if (decstr.nr_dec) from++; // Skipp '.' - for (i=(int) min(decstr.nr_dec,tmp_dec) ; i-- > 0 ; ) *to++ = *from++; - for (i=(int) (tmp_dec-min(decstr.nr_dec,tmp_dec)) ; i-- > 0 ; ) *to++ = '0'; + + /* + Tmp_left_pos is the position where the leftmost digit of + the int_% parts will be written + */ + tmp_left_pos=pos=to+(uint)(field_length-tmp_uint); + + // Write all digits of the int_% parts + while (int_digits_from != int_digits_end) + *pos++ = *int_digits_from++ ; + + if (expo_sign_char == '+') + { + while (int_digits_tail_from != frac_digits_from) + *pos++= *int_digits_tail_from++; + while (int_digits_added_zeros-- >0) + *pos++= '0'; } + /* + Note the position where the rightmost digit of the int_% parts has been + written (this is to later check if the int_% parts contained nothing, + meaning an extra 0 is needed). + */ + tmp_right_pos=pos; /* - ** Check for incorrect string if in batch mode (ALTER TABLE/LOAD DATA...) + Step back to the position of the leftmost digit of the int_% parts, + to write sign and fill with zeros or blanks or prezeros. */ - if (!error && current_thd->count_cuted_fields && from != end) - { // Check if number was cuted - for (; from != end ; from++) + pos=tmp_left_pos-1; + if (zerofill) + { + left_wall=to-1; + while (pos != left_wall) // Fill with zeros + *pos--='0'; + } + else + { + left_wall=to+(sign_char != 0)-1; + if (!expo_sign_char) // If exponent was specified, ignore prezeros { - if (*from != '0') + for (;pos != left_wall && pre_zeros_from !=pre_zeros_end; + pre_zeros_from++) + *pos--= '0'; + } + if (pos == tmp_right_pos-1) + *pos--= '0'; // no 0 has ever been written, so write one + left_wall= to-1; + if (sign_char && pos != left_wall) + { + /* Write sign if possible (it is if sign is '-') */ + *pos--= sign_char; + } + while (pos != left_wall) + *pos--=' '; //fill with blanks + } + + /* + Write digits of the frac_% parts ; + Depending on current_thd->count_cutted_fields, we may also want + to know if some non-zero tail of these parts will + be truncated (for example, 0.002->0.00 will generate a warning, + while 0.000->0.00 will not) + (and 0E1000000000 will not, while 1E-1000000000 will) + */ + + pos=to+(uint)(field_length-tmp_dec); // Calculate post to '.' + right_wall=to+field_length; + if (pos != right_wall) + *pos++='.'; + + if (expo_sign_char == '-') + { + while (frac_digits_added_zeros-- > 0) + { + if (pos == right_wall) + { + if (current_thd->count_cuted_fields && !is_cuted_fields_incr) + break; // Go on below to see if we lose non zero digits + return; + } + *pos++='0'; + } + while (int_digits_end != frac_digits_head_end) + { + tmp_char= *int_digits_end++; + if (pos == right_wall) + { + if (tmp_char != '0') // Losing a non zero digit ? + { + if (!is_cuted_fields_incr) + current_thd->cuted_fields++; + return; + } + continue; + } + *pos++= tmp_char; + } + } + + for (;frac_digits_from!=frac_digits_end;) + { + tmp_char= *frac_digits_from++; + if (pos == right_wall) + { + if (tmp_char != '0') // Losing a non zero digit ? { - if (!isspace(*from)) // Space is ok + if (!is_cuted_fields_incr) current_thd->cuted_fields++; - break; + return; } + continue; } + *pos++= tmp_char; } + + while (pos != right_wall) + *pos++='0'; // Fill with zeros at right of '.' + } @@ -518,9 +718,17 @@ void Field_decimal::store(double nr) if (unsigned_flag && nr < 0) { overflow(1); - current_thd->cuted_fields++; return; } + +#ifdef HAVE_FINITE + if (!finite(nr)) // Handle infinity as special case + { + overflow(nr < 0.0); + return; + } +#endif + reg4 uint i,length; char fyllchar,*to; char buff[320]; @@ -535,10 +743,7 @@ void Field_decimal::store(double nr) length=(uint) strlen(buff); if (length > field_length) - { overflow(nr < 0.0); - current_thd->cuted_fields++; - } else { to=ptr; @@ -554,7 +759,6 @@ void Field_decimal::store(longlong nr) if (unsigned_flag && nr < 0) { overflow(1); - current_thd->cuted_fields++; return; } char buff[22]; @@ -562,10 +766,7 @@ void Field_decimal::store(longlong nr) uint int_part=field_length- (dec ? dec+1 : 0); if (length > int_part) - { overflow(test(nr < 0L)); /* purecov: inspected */ - current_thd->cuted_fields++; /* purecov: inspected */ - } else { char fyllchar = zerofill ? (char) '0' : (char) ' '; @@ -1075,7 +1276,7 @@ void Field_short::sort_string(char *to,uint length __attribute__((unused))) if (unsigned_flag) to[0] = ptr[0]; else - to[0] = ptr[0] ^ 128; /* Revers signbit */ + to[0] = (char) (ptr[0] ^ 128); /* Revers signbit */ to[1] = ptr[1]; } else @@ -1084,7 +1285,7 @@ void Field_short::sort_string(char *to,uint length __attribute__((unused))) if (unsigned_flag) to[0] = ptr[1]; else - to[0] = ptr[1] ^ 128; /* Revers signbit */ + to[0] = (char) (ptr[1] ^ 128); /* Revers signbit */ to[1] = ptr[0]; } } @@ -1155,12 +1356,12 @@ void Field_medium::store(double nr) } else if (nr >= (double) (long) (1L << 24)) { - ulong tmp=(ulong) (1L << 24)-1L; + uint32 tmp=(uint32) (1L << 24)-1L; int3store(ptr,tmp); current_thd->cuted_fields++; } else - int3store(ptr,(ulong) nr); + int3store(ptr,(uint32) nr); } else { @@ -1197,7 +1398,7 @@ void Field_medium::store(longlong nr) current_thd->cuted_fields++; } else - int3store(ptr,(ulong) nr); + int3store(ptr,(uint32) nr); } else { @@ -1290,12 +1491,14 @@ void Field_medium::sql_type(String &res) const void Field_long::store(const char *from,uint len) { + char *end; while (len && isspace(*from)) { len--; from++; } long tmp; String tmp_str(from,len); + from= tmp_str.c_ptr(); // Add end null if needed errno=0; if (unsigned_flag) { @@ -1305,11 +1508,13 @@ void Field_long::store(const char *from,uint len) errno=ERANGE; } else - tmp=(long) strtoul(tmp_str.c_ptr(),NULL,10); + tmp=(long) strtoul(from, &end, 10); } else - tmp=strtol(tmp_str.c_ptr(),NULL,10); - if (errno || current_thd->count_cuted_fields && !test_if_int(from,len)) + tmp=strtol(from, &end, 10); + if (errno || + (from+len != end && current_thd->count_cuted_fields && + !test_if_int(from,len))) current_thd->cuted_fields++; #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) @@ -1475,7 +1680,7 @@ int Field_long::cmp(const char *a_ptr, const char *b_ptr) longget(b,b_ptr); } if (unsigned_flag) - return ((ulong) a < (ulong) b) ? -1 : ((ulong) a > (ulong) b) ? 1 : 0; + return ((uint32) a < (uint32) b) ? -1 : ((uint32) a > (uint32) b) ? 1 : 0; return (a < b) ? -1 : (a > b) ? 1 : 0; } @@ -1487,7 +1692,7 @@ void Field_long::sort_string(char *to,uint length __attribute__((unused))) if (unsigned_flag) to[0] = ptr[0]; else - to[0] = ptr[0] ^ 128; /* Revers signbit */ + to[0] = (char) (ptr[0] ^ 128); /* Revers signbit */ to[1] = ptr[1]; to[2] = ptr[2]; to[3] = ptr[3]; @@ -1498,7 +1703,7 @@ void Field_long::sort_string(char *to,uint length __attribute__((unused))) if (unsigned_flag) to[0] = ptr[3]; else - to[0] = ptr[3] ^ 128; /* Revers signbit */ + to[0] = (char) (ptr[3] ^ 128); /* Revers signbit */ to[1] = ptr[2]; to[2] = ptr[1]; to[3] = ptr[0]; @@ -1518,12 +1723,14 @@ void Field_long::sql_type(String &res) const void Field_longlong::store(const char *from,uint len) { + char *end; while (len && isspace(*from)) { // For easy error check len--; from++; } longlong tmp; String tmp_str(from,len); + from= tmp_str.c_ptr(); // Add end null if needed errno=0; if (unsigned_flag) { @@ -1533,12 +1740,14 @@ void Field_longlong::store(const char *from,uint len) errno=ERANGE; } else - tmp=(longlong) strtoull(tmp_str.c_ptr(),NULL,10); + tmp=(longlong) strtoull(from, &end, 10); } 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++; + tmp=strtoll(from, &end, 10); + if (errno || + (from+len != end && current_thd->count_cuted_fields && + !test_if_int(from,len))) + current_thd->cuted_fields++; #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) { @@ -1686,7 +1895,7 @@ void Field_longlong::sort_string(char *to,uint length __attribute__((unused))) if (unsigned_flag) to[0] = ptr[0]; else - to[0] = ptr[0] ^ 128; /* Revers signbit */ + to[0] = (char) (ptr[0] ^ 128); /* Revers signbit */ to[1] = ptr[1]; to[2] = ptr[2]; to[3] = ptr[3]; @@ -1701,7 +1910,7 @@ void Field_longlong::sort_string(char *to,uint length __attribute__((unused))) if (unsigned_flag) to[0] = ptr[7]; else - to[0] = ptr[7] ^ 128; /* Revers signbit */ + to[0] = (char) (ptr[7] ^ 128); /* Revers signbit */ to[1] = ptr[6]; to[2] = ptr[5]; to[3] = ptr[4]; @@ -1738,6 +1947,11 @@ void Field_float::store(double nr) float j; 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; + } if (nr < -FLT_MAX) { j= -FLT_MAX; @@ -1764,6 +1978,11 @@ void Field_float::store(double nr) void Field_float::store(longlong nr) { float j= (float) nr; + if (unsigned_flag && j < 0) + { + current_thd->cuted_fields++; + j=0; + } #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) { @@ -1936,7 +2155,7 @@ void Field_float::sort_string(char *to,uint length __attribute__((unused))) { /* make complement */ uint i; for (i=0 ; i < sizeof(nr); i++) - tmp[i]=tmp[i] ^ (uchar) 255; + tmp[i]= (uchar) (tmp[i] ^ (uchar) 255); } else { @@ -1970,6 +2189,11 @@ void Field_double::store(const char *from,uint len) double j= atof(tmp_str.c_ptr()); if (errno || current_thd->count_cuted_fields && !test_if_real(from,len)) current_thd->cuted_fields++; + if (unsigned_flag && j < 0) + { + current_thd->cuted_fields++; + j=0; + } #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) { @@ -1985,6 +2209,11 @@ void Field_double::store(double nr) { 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; + } #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) { @@ -1999,6 +2228,11 @@ void Field_double::store(double nr) void Field_double::store(longlong nr) { double j= (double) nr; + if (unsigned_flag && j < 0) + { + current_thd->cuted_fields++; + j=0; + } #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) { @@ -2304,10 +2538,10 @@ void Field_timestamp::store(longlong nr) { part1=(long) (nr/LL(1000000)); part2=(long) (nr - (longlong) part1*LL(1000000)); - l_time.year= part1/10000L; part1%=10000L; + l_time.year= (int) (part1/10000L); part1%=10000L; l_time.month= (int) part1 / 100; - l_time.day= (int) part1 % 100; - l_time.hour= part2/10000L; part2%=10000L; + l_time.day= (int) part1 % 100; + l_time.hour= (int) (part2/10000L); part2%=10000L; l_time.minute=(int) part2 / 100; l_time.second=(int) part2 % 100; timestamp=my_gmt_sec(&l_time); @@ -2321,7 +2555,7 @@ void Field_timestamp::store(longlong nr) } else #endif - longstore(ptr,(ulong)timestamp); + longstore(ptr,(uint32) timestamp); } @@ -2622,7 +2856,7 @@ void Field_time::store(longlong nr) double Field_time::val_real(void) { - ulong j= (ulong) uint3korr(ptr); + uint32 j= (uint32) uint3korr(ptr); return (double) j; } @@ -2658,19 +2892,19 @@ bool Field_time::get_time(TIME *ltime) ltime->neg= 1; tmp=-tmp; } - ltime->hour=tmp/10000; + ltime->hour= (int) (tmp/10000); tmp-=ltime->hour*10000; - ltime->minute= tmp/100; - ltime->second= tmp % 100; + ltime->minute= (int) tmp/100; + ltime->second= (int) tmp % 100; ltime->second_part=0; return 0; } int Field_time::cmp(const char *a_ptr, const char *b_ptr) { - long a,b; - a=(long) sint3korr(a_ptr); - b=(long) sint3korr(b_ptr); + int32 a,b; + a=(int32) sint3korr(a_ptr); + b=(int32) sint3korr(b_ptr); return (a < b) ? -1 : (a > b) ? 1 : 0; } @@ -2781,14 +3015,14 @@ void Field_year::sql_type(String &res) const ** Stored as a 4 byte unsigned int ****************************************************************************/ -void Field_date::store(const char *from,uint len) +void Field_date::store(const char *from, uint len) { TIME l_time; - ulong tmp; + uint32 tmp; if (str_to_TIME(from,len,&l_time,1) == TIMESTAMP_NONE) tmp=0; else - tmp=(ulong) l_time.year*10000L + (ulong) (l_time.month*100+l_time.day); + tmp=(uint32) l_time.year*10000L + (uint32) (l_time.month*100+l_time.day); #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) { @@ -2960,7 +3194,7 @@ void Field_newdate::store(double nr) void Field_newdate::store(longlong nr) { - long tmp; + int32 tmp; if (nr >= LL(100000000) && nr <= LL(99991231235959)) nr=nr/LL(1000000); // Timestamp to date if (nr < 0L || nr > 99991231L) @@ -2970,16 +3204,16 @@ void Field_newdate::store(longlong nr) } else { - tmp=(long) nr; + tmp=(int32) nr; if (tmp) { if (tmp < YY_PART_YEAR*10000L) // Fix short dates - tmp+=20000000L; + tmp+= (uint32) 20000000L; else if (tmp < 999999L) - tmp+=19000000L; + tmp+= (uint32) 19000000L; } - uint month=((tmp/100) % 100); - uint day= tmp%100; + uint month= (uint) ((tmp/100) % 100); + uint day= (uint) (tmp%100); if (month > 12 || day > 31) { tmp=0L; // Don't allow date to change @@ -2988,7 +3222,7 @@ void Field_newdate::store(longlong nr) else tmp= day + month*32 + (tmp/10000)*16*32; } - int3store(ptr,tmp); + int3store(ptr,(int32) tmp); } void Field_newdate::store_time(TIME *ltime,timestamp_type type) @@ -3013,7 +3247,7 @@ double Field_newdate::val_real(void) longlong Field_newdate::val_int(void) { - ulong j=uint3korr(ptr); + ulong j= uint3korr(ptr); j= (j % 32L)+(j / 32L % 16L)*100L + (j/(16L*32L))*10000L; return (longlong) j; } @@ -3023,25 +3257,25 @@ String *Field_newdate::val_str(String *val_buffer, { val_buffer->alloc(field_length); val_buffer->length(field_length); - ulong tmp=(ulong) uint3korr(ptr); + uint32 tmp=(uint32) uint3korr(ptr); int part; char *pos=(char*) val_buffer->ptr()+10; /* Open coded to get more speed */ - *pos--=0; + *pos--=0; // End NULL part=(int) (tmp & 31); - *pos--='0'+part%10; - *pos--='0'+part/10; - *pos--='-'; + *pos--= (char) ('0'+part%10); + *pos--= (char) ('0'+part/10); + *pos--= '-'; part=(int) (tmp >> 5 & 15); - *pos--='0'+part%10; - *pos--='0'+part/10; - *pos--='-'; + *pos--= (char) ('0'+part%10); + *pos--= (char) ('0'+part/10); + *pos--= '-'; part=(int) (tmp >> 9); - *pos--='0'+part%10; part/=10; - *pos--='0'+part%10; part/=10; - *pos--='0'+part%10; part/=10; - *pos='0'+part; + *pos--= (char) ('0'+part%10); part/=10; + *pos--= (char) ('0'+part%10); part/=10; + *pos--= (char) ('0'+part%10); part/=10; + *pos= (char) ('0'+part); return val_buffer; } @@ -3049,7 +3283,7 @@ bool Field_newdate::get_date(TIME *ltime,bool fuzzydate) { if (is_null()) return 1; - ulong tmp=(ulong) uint3korr(ptr); + uint32 tmp=(uint32) uint3korr(ptr); bzero((char*) ltime,sizeof(*ltime)); ltime->day= tmp & 31; ltime->month= (tmp >> 5) & 15; @@ -3065,9 +3299,9 @@ bool Field_newdate::get_time(TIME *ltime) int Field_newdate::cmp(const char *a_ptr, const char *b_ptr) { - ulong a,b; - a=(ulong) uint3korr(a_ptr); - b=(ulong) uint3korr(b_ptr); + uint32 a,b; + a=(uint32) uint3korr(a_ptr); + b=(uint32) uint3korr(b_ptr); return (a < b) ? -1 : (a > b) ? 1 : 0; } @@ -3201,44 +3435,44 @@ String *Field_datetime::val_str(String *val_buffer, pos=(char*) val_buffer->ptr()+19; *pos--=0; - *pos--='0'+(char) (part2%10); part2/=10; - *pos--='0'+(char) (part2%10); part3= (int) (part2 / 10); - *pos--=':'; - *pos--='0'+(char) (part3%10); part3/=10; - *pos--='0'+(char) (part3%10); part3/=10; - *pos--=':'; - *pos--='0'+(char) (part3%10); part3/=10; - *pos--='0'+(char) part3; - *pos--=' '; - *pos--='0'+(char) (part1%10); part1/=10; - *pos--='0'+(char) (part1%10); part1/=10; - *pos--='-'; - *pos--='0'+(char) (part1%10); part1/=10; - *pos--='0'+(char) (part1%10); part3= (int) (part1/10); - *pos--='-'; - *pos--='0'+(char) (part3%10); part3/=10; - *pos--='0'+(char) (part3%10); part3/=10; - *pos--='0'+(char) (part3%10); part3/=10; - *pos='0'+(char) part3; + *pos--= (char) ('0'+(char) (part2%10)); part2/=10; + *pos--= (char) ('0'+(char) (part2%10)); part3= (int) (part2 / 10); + *pos--= ':'; + *pos--= (char) ('0'+(char) (part3%10)); part3/=10; + *pos--= (char) ('0'+(char) (part3%10)); part3/=10; + *pos--= ':'; + *pos--= (char) ('0'+(char) (part3%10)); part3/=10; + *pos--= (char) ('0'+(char) part3); + *pos--= ' '; + *pos--= (char) ('0'+(char) (part1%10)); part1/=10; + *pos--= (char) ('0'+(char) (part1%10)); part1/=10; + *pos--= '-'; + *pos--= (char) ('0'+(char) (part1%10)); part1/=10; + *pos--= (char) ('0'+(char) (part1%10)); part3= (int) (part1/10); + *pos--= '-'; + *pos--= (char) ('0'+(char) (part3%10)); part3/=10; + *pos--= (char) ('0'+(char) (part3%10)); part3/=10; + *pos--= (char) ('0'+(char) (part3%10)); part3/=10; + *pos=(char) ('0'+(char) part3); return val_buffer; } bool Field_datetime::get_date(TIME *ltime,bool fuzzydate) { longlong tmp=Field_datetime::val_int(); - long part1,part2; - part1=(long) (tmp/LL(1000000)); - part2=(long) (tmp - (ulonglong) part1*LL(1000000)); + uint32 part1,part2; + part1=(uint32) (tmp/LL(1000000)); + part2=(uint32) (tmp - (ulonglong) part1*LL(1000000)); ltime->time_type= TIMESTAMP_FULL; - ltime->neg=0; - ltime->second_part=0; - ltime->second= part2%100; - ltime->minute= part2/100%100; - ltime->hour= part2/10000; - ltime->day= part1%100; - ltime->month= part1/100%100; - ltime->year= part1/10000; + ltime->neg= 0; + ltime->second_part= 0; + ltime->second= (int) (part2%100); + ltime->minute= (int) (part2/100%100); + ltime->hour= (int) (part2/10000); + ltime->day= (int) (part1%100); + ltime->month= (int) (part1/100%100); + ltime->year= (int) (part1/10000); return (!fuzzydate && (!ltime->month || !ltime->day)) ? 1 : 0; } @@ -3310,9 +3544,9 @@ void Field_datetime::sql_type(String &res) const void Field_string::store(const char *from,uint length) { #ifdef USE_TIS620 - if(!binary_flag) { + if (!binary_flag) { ThNormalize((uchar *)ptr, field_length, (uchar *)from, length); - if(length < field_length) { + if (length < field_length) { bfill(ptr + length, field_length - length, ' '); } } @@ -3357,7 +3591,7 @@ void Field_string::store(longlong nr) { char buff[22]; char *end=longlong10_to_str(nr,buff,-10); - Field_string::store(buff,end-buff); + Field_string::store(buff,(uint) (end-buff)); } @@ -3492,12 +3726,12 @@ int Field_string::pack_cmp(const char *b, uint length) } -uint Field_string::packed_col_length(const char *ptr, uint length) +uint Field_string::packed_col_length(const char *data_ptr, uint length) { if (length > 255) - return uint2korr(ptr)+2; + return uint2korr(data_ptr)+2; else - return (uint) ((uchar) *ptr)+1; + return (uint) ((uchar) *data_ptr)+1; } uint Field_string::max_packed_col_length(uint max_length) @@ -3514,7 +3748,7 @@ uint Field_string::max_packed_col_length(uint max_length) void Field_varstring::store(const char *from,uint length) { #ifdef USE_TIS620 - if(!binary_flag) + if (!binary_flag) { ThNormalize((uchar *) ptr+2, field_length, (uchar *) from, length); } @@ -3548,7 +3782,7 @@ void Field_varstring::store(longlong nr) { char buff[22]; char *end=longlong10_to_str(nr,buff,-10); - Field_varstring::store(buff,end-buff); + Field_varstring::store(buff,(uint) (end-buff)); } @@ -3639,9 +3873,9 @@ char *Field_varstring::pack(char *to, const char *from, uint max_length) uint length=uint2korr(from); if (length > max_length) length=max_length; - *to++= (length & 255); + *to++= (char) (length & 255); if (max_length > 255) - *to++= (uchar) (length >> 8); + *to++= (char) (length >> 8); if (length) memcpy(to, from+2, length); return to+length; @@ -3711,12 +3945,12 @@ int Field_varstring::pack_cmp(const char *b, uint key_length) return my_sortncmp(a,a_length, b,b_length); } -uint Field_varstring::packed_col_length(const char *ptr, uint length) +uint Field_varstring::packed_col_length(const char *data_ptr, uint length) { if (length > 255) - return uint2korr(ptr)+2; + return uint2korr(data_ptr)+2; else - return (uint) ((uchar) *ptr)+1; + return (uint) ((uchar) *data_ptr)+1; } uint Field_varstring::max_packed_col_length(uint max_length) @@ -3730,7 +3964,7 @@ uint Field_varstring::max_packed_col_length(uint max_length) ** packlength slot and may be from 1-4. ****************************************************************************/ -Field_blob::Field_blob(char *ptr_arg, uchar *null_ptr_arg, uint null_bit_arg, +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) @@ -3747,7 +3981,7 @@ Field_blob::Field_blob(char *ptr_arg, uchar *null_ptr_arg, uint null_bit_arg, } -void Field_blob::store_length(ulong number) +void Field_blob::store_length(uint32 number) { switch (packlength) { case 1: @@ -3774,9 +4008,9 @@ void Field_blob::store_length(ulong number) shortstore(ptr,(unsigned short) number); break; case 3: - if (number > (ulong) (1L << 24)) + if (number > (uint32) (1L << 24)) { - number= (ulong) (1L << 24)-1L; + number= (uint32) (1L << 24)-1L; current_thd->cuted_fields++; } int3store(ptr,number); @@ -3794,11 +4028,11 @@ void Field_blob::store_length(ulong number) } -ulong Field_blob::get_length(const char *pos) +uint32 Field_blob::get_length(const char *pos) { switch (packlength) { case 1: - return (ulong) (uchar) pos[0]; + return (uint32) (uchar) pos[0]; case 2: { uint16 tmp; @@ -3808,10 +4042,10 @@ ulong Field_blob::get_length(const char *pos) else #endif shortget(tmp,pos); - return (ulong) tmp; + return (uint32) tmp; } case 3: - return (ulong) uint3korr(pos); + return (uint32) uint3korr(pos); case 4: { uint32 tmp; @@ -3821,7 +4055,7 @@ ulong Field_blob::get_length(const char *pos) else #endif longget(tmp,pos); - return (ulong) tmp; + return (uint32) tmp; } } return 0; // Impossible @@ -3843,7 +4077,7 @@ void Field_blob::store(const char *from,uint len) if (table->copy_blobs || len <= MAX_FIELD_WIDTH) { // Must make a copy #ifdef USE_TIS620 - if(!binary_flag) + if (!binary_flag) { /* If there isn't enough memory, use original string */ if ((th_ptr=(char * ) my_malloc(sizeof(char) * len,MYF(0)))) @@ -3867,14 +4101,14 @@ void Field_blob::store(const char *from,uint len) void Field_blob::store(double nr) { value.set(nr); - Field_blob::store(value.ptr(),value.length()); + Field_blob::store(value.ptr(),(uint) value.length()); } void Field_blob::store(longlong nr) { value.set(nr); - Field_blob::store(value.ptr(),value.length()); + Field_blob::store(value.ptr(), (uint) value.length()); } @@ -3885,7 +4119,7 @@ double Field_blob::val_real(void) memcpy_fixed(&blob,ptr+packlength,sizeof(char*)); if (!blob) return 0.0; - ulong length=get_length(ptr); + uint32 length=get_length(ptr); char save=blob[length]; // Ok to patch blob in NISAM blob[length]=0; @@ -3901,7 +4135,7 @@ longlong Field_blob::val_int(void) memcpy_fixed(&blob,ptr+packlength,sizeof(char*)); if (!blob) return 0; - ulong length=get_length(ptr); + uint32 length=get_length(ptr); char save=blob[length]; // Ok to patch blob in NISAM blob[length]=0; @@ -3924,8 +4158,8 @@ String *Field_blob::val_str(String *val_buffer __attribute__((unused)), } -int Field_blob::cmp(const char *a,ulong a_length, const char *b, - ulong b_length) +int Field_blob::cmp(const char *a,uint32 a_length, const char *b, + uint32 b_length) { int diff; if (binary_flag) @@ -3959,11 +4193,11 @@ int Field_blob::cmp_binary_offset(uint row_offset) int Field_blob::cmp_binary(const char *a_ptr, const char *b_ptr, - ulong max_length) + uint32 max_length) { char *a,*b; uint diff; - ulong a_length,b_length; + uint32 a_length,b_length; memcpy_fixed(&a,a_ptr+packlength,sizeof(char*)); memcpy_fixed(&b,b_ptr+packlength,sizeof(char*)); a_length=get_length(a_ptr); @@ -3982,13 +4216,15 @@ int Field_blob::cmp_binary(const char *a_ptr, const char *b_ptr, void Field_blob::get_key_image(char *buff,uint length) { length-=HA_KEY_BLOB_LENGTH; - ulong blob_length=get_length(ptr); + uint32 blob_length=get_length(ptr); char *blob; - if ((ulong) length > blob_length) + if ((uint32) length > blob_length) { -#ifdef HAVE_purify + /* + Must clear this as we do a memcmp in opt_range.cc to detect + identical keys + */ bzero(buff+2+blob_length, (length-blob_length)); -#endif length=(uint) blob_length; } int2store(buff,length); @@ -4078,7 +4314,7 @@ char *Field_blob::pack(char *to, const char *from, uint max_length) { char *save=ptr; ptr=(char*) from; - ulong length=get_length(); // Length of from string + uint32 length=get_length(); // Length of from string if (length > max_length) { ptr=to; @@ -4101,7 +4337,7 @@ char *Field_blob::pack(char *to, const char *from, uint max_length) const char *Field_blob::unpack(char *to, const char *from) { memcpy(to,from,packlength); - ulong length=get_length(from); + uint32 length=get_length(from); from+=packlength; if (length) memcpy_fixed(to+packlength, &from, sizeof(from)); @@ -4110,60 +4346,6 @@ const char *Field_blob::unpack(char *to, const char *from) return from+length; } - -#ifdef HAVE_GEMINI_DB -/* Blobs in Gemini tables are stored separately from the rows which contain -** them (except for tiny blobs, which are stored in the row). For all other -** blob types (blob, mediumblob, longblob), the row contains the length of -** the blob data and a blob id. These methods (pack_id, get_id, and -** unpack_id) handle packing and unpacking blob fields in Gemini rows. -*/ -char *Field_blob::pack_id(char *to, const char *from, ulonglong id, uint max_length) -{ - char *save=ptr; - ptr=(char*) from; - ulong length=get_length(); // Length of from string - if (length > max_length) - { - ptr=to; - length=max_length; - store_length(length); // Store max length - ptr=(char*) from; - } - else - memcpy(to,from,packlength); // Copy length - if (length) - { - int8store(to+packlength, id); - } - ptr=save; // Restore org row pointer - return to+packlength+sizeof(id); -} - - -ulonglong Field_blob::get_id(const char *from) -{ - ulonglong id = 0; - ulong length=get_length(from); - if (length) - id=uint8korr(from+packlength); - return id; -} - - -const char *Field_blob::unpack_id(char *to, const char *from, const char *bdata) -{ - memcpy(to,from,packlength); - ulong length=get_length(from); - from+=packlength; - if (length) - memcpy_fixed(to+packlength, &bdata, sizeof(bdata)); - else - bzero(to+packlength,sizeof(bdata)); - return from+sizeof(ulonglong); -} -#endif /* HAVE_GEMINI_DB */ - /* Keys for blobs are like keys on varchars */ int Field_blob::pack_cmp(const char *a, const char *b, uint key_length) @@ -4220,7 +4402,7 @@ char *Field_blob::pack_key(char *to, const char *from, uint max_length) { char *save=ptr; ptr=(char*) from; - ulong length=get_length(); // Length of from string + uint32 length=get_length(); // Length of from string if (length > max_length) length=max_length; *to++= (uchar) length; @@ -4243,20 +4425,20 @@ char *Field_blob::pack_key_from_key_image(char *to, const char *from, uint length=uint2korr(from); if (length > max_length) length=max_length; - *to++= (length & 255); + *to++= (char) (length & 255); if (max_length > 255) - *to++= (uchar) (length >> 8); + *to++= (char) (length >> 8); if (length) memcpy(to, from+2, length); return to+length; } -uint Field_blob::packed_col_length(const char *ptr, uint length) +uint Field_blob::packed_col_length(const char *data_ptr, uint length) { if (length > 255) - return uint2korr(ptr)+2; + return uint2korr(data_ptr)+2; else - return (uint) ((uchar) *ptr)+1; + return (uint) ((uchar) *data_ptr)+1; } uint Field_blob::max_packed_col_length(uint max_length) @@ -4358,7 +4540,7 @@ void Field_enum::store(const char *from,uint length) conv=buff; } my_errno=0; - tmp=strtoul(conv,&end,10); + tmp=(uint) strtoul(conv,&end,10); if (my_errno || end != conv+length || tmp > typelib->count) { tmp=0; @@ -4517,7 +4699,7 @@ ulonglong find_set(TYPELIB *lib,const char *x,uint length) for (;;) { const char *pos=start; - for ( ; pos != end && *pos != field_separator ; pos++) ; + for (; pos != end && *pos != field_separator ; pos++) ; uint find=find_enum(lib,start,(uint) (pos-start)); if (!find) error=1; @@ -4628,7 +4810,7 @@ bool Field_enum::eq_def(Field *field) if (!Field::eq_def(field)) return 0; TYPELIB *from_lib=((Field_enum*) field)->typelib; - + if (typelib->count < from_lib->count) return 0; for (uint i=0 ; i < from_lib->count ; i++) @@ -4638,7 +4820,7 @@ bool Field_enum::eq_def(Field *field) } bool Field_num::eq_def(Field *field) -{ +{ if (!Field::eq_def(field)) return 0; Field_num *from_num= (Field_num*) field; @@ -4656,7 +4838,7 @@ bool Field_num::eq_def(Field *field) *****************************************************************************/ /* -** Make a field from the .frm file info + Make a field from the .frm file info */ uint32 calc_pack_length(enum_field_types type,uint32 length) @@ -4685,6 +4867,7 @@ uint32 calc_pack_length(enum_field_types type,uint32 length) case FIELD_TYPE_LONG_BLOB: return 4+portable_sizeof_char_ptr; case FIELD_TYPE_SET: case FIELD_TYPE_ENUM: abort(); return 0; // This shouldn't happen + default: return 0; } return 0; // This shouldn't happen } @@ -4704,8 +4887,9 @@ uint pack_length_to_packflag(uint type) Field *make_field(char *ptr, uint32 field_length, - uchar *null_pos, uint null_bit, + uchar *null_pos, uchar null_bit, uint pack_flag, + enum_field_types field_type, Field::utype unireg_check, TYPELIB *interval, const char *field_name, @@ -4731,6 +4915,9 @@ Field *make_field(char *ptr, uint32 field_length, return new Field_blob(ptr,null_pos,null_bit, unireg_check, field_name, table, pack_length,f_is_binary(pack_flag) != 0); + if (f_is_geom(pack_flag)) + return 0; + if (interval) { if (f_is_enum(pack_flag)) @@ -4744,7 +4931,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, @@ -4807,10 +4994,11 @@ Field *make_field(char *ptr, uint32 field_length, return new Field_datetime(ptr,null_pos,null_bit, unireg_check, field_name, table); case FIELD_TYPE_NULL: - default: // Impossible (Wrong version) return new Field_null(ptr,field_length,unireg_check,field_name,table); + default: // Impossible (Wrong version) + break; } - return 0; // Impossible (Wrong version) + return 0; // Impossible } |