diff options
Diffstat (limited to 'sql/field.cc')
-rw-r--r-- | sql/field.cc | 97 |
1 files changed, 91 insertions, 6 deletions
diff --git a/sql/field.cc b/sql/field.cc index b70e2a92618..dbc8d2a49d7 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -67,6 +67,7 @@ inline int field_type2index (enum_field_types field_type) ((int)FIELDTYPE_TEAR_FROM) + (field_type - FIELDTYPE_TEAR_TO) - 1); } + static enum_field_types field_types_merge_rules [FIELDTYPE_NUM][FIELDTYPE_NUM]= { /* MYSQL_TYPE_DECIMAL -> */ @@ -1233,6 +1234,7 @@ Field::Field(char *ptr_arg,uint32 length_arg,uchar *null_ptr_arg, flags=null_ptr ? 0: NOT_NULL_FLAG; comment.str= (char*) ""; comment.length=0; + fieldnr= 0; } uint Field::offset() @@ -2382,7 +2384,7 @@ bool Field_new_decimal::store_value(const my_decimal *decimal_value) #ifndef DBUG_OFF { char dbug_buff[DECIMAL_MAX_STR_LENGTH+1]; - DBUG_PRINT("info", ("saving with precision %d, scale: %d, value %s", + DBUG_PRINT("info", ("saving with precision %d scale: %d value %s", (int)precision, (int)dec, dbug_decimal_as_string(dbug_buff, decimal_value))); } @@ -2397,7 +2399,8 @@ bool Field_new_decimal::store_value(const my_decimal *decimal_value) my_decimal2binary(E_DEC_FATAL_ERROR, &buff, ptr, precision, dec); error= 1; } - DBUG_EXECUTE("info", print_decimal_buff(decimal_value, (byte *) ptr, bin_size);); + DBUG_EXECUTE("info", print_decimal_buff(decimal_value, (byte *) ptr, + bin_size);); DBUG_RETURN(error); } @@ -5951,6 +5954,26 @@ int Field_str::store(double nr) } +uint Field::is_equal(create_field *new_field) +{ + return (new_field->sql_type == type()); +} + + +uint Field_str::is_equal(create_field *new_field) +{ + if (((new_field->flags & (BINCMP_FLAG | BINARY_FLAG)) && + !(flags & (BINCMP_FLAG | BINARY_FLAG))) || + (!(new_field->flags & (BINCMP_FLAG | BINARY_FLAG)) && + (flags & (BINCMP_FLAG | BINARY_FLAG)))) + return 0; /* One of the fields is binary and the other one isn't */ + + return ((new_field->sql_type == type()) && + new_field->charset == field_charset && + new_field->length == max_length()); +} + + int Field_string::store(longlong nr, bool unsigned_val) { char buff[64]; @@ -6342,7 +6365,8 @@ my_decimal *Field_varstring::val_decimal(my_decimal *decimal_value) } -int Field_varstring::cmp(const char *a_ptr, const char *b_ptr) +int Field_varstring::cmp_max(const char *a_ptr, const char *b_ptr, + uint max_len) { uint a_length, b_length; int diff; @@ -6357,6 +6381,8 @@ int Field_varstring::cmp(const char *a_ptr, const char *b_ptr) a_length= uint2korr(a_ptr); b_length= uint2korr(b_ptr); } + set_if_smaller(a_length, max_len); + set_if_smaller(b_length, max_len); diff= field_charset->coll->strnncollsp(field_charset, (const uchar*) a_ptr+ length_bytes, @@ -6731,6 +6757,22 @@ Field *Field_varstring::new_key_field(MEM_ROOT *root, } +uint Field_varstring::is_equal(create_field *new_field) +{ + if (new_field->sql_type == type() && + new_field->charset == field_charset) + { + if (new_field->length == max_length()) + return IS_EQUAL_YES; + if (new_field->length > max_length() && + ((new_field->length <= 255 && max_length() <= 255) || + (new_field->length > 255 && max_length() > 255))) + return IS_EQUAL_PACK_LENGTH; // VARCHAR, longer variable length + } + return IS_EQUAL_NO; +} + + /**************************************************************************** ** blob type ** A blob is saved as a length and a pointer. The length is stored in the @@ -7002,13 +7044,16 @@ int Field_blob::cmp(const char *a,uint32 a_length, const char *b, } -int Field_blob::cmp(const char *a_ptr, const char *b_ptr) +int Field_blob::cmp_max(const char *a_ptr, const char *b_ptr, + uint max_length) { char *blob1,*blob2; memcpy_fixed(&blob1,a_ptr+packlength,sizeof(char*)); memcpy_fixed(&blob2,b_ptr+packlength,sizeof(char*)); - return Field_blob::cmp(blob1,get_length(a_ptr), - blob2,get_length(b_ptr)); + uint a_len= get_length(a_ptr), b_len= get_length(b_ptr); + set_if_smaller(a_len, max_length); + set_if_smaller(b_len, max_length); + return Field_blob::cmp(blob1,a_len,blob2,b_len); } @@ -7871,6 +7916,17 @@ bool Field_num::eq_def(Field *field) } +uint Field_num::is_equal(create_field *new_field) +{ + return ((new_field->sql_type == type()) && + ((new_field->flags & UNSIGNED_FLAG) == (uint) (flags & + UNSIGNED_FLAG)) && + ((new_field->flags & AUTO_INCREMENT_FLAG) == + (uint) (flags & AUTO_INCREMENT_FLAG)) && + (new_field->length >= max_length())); +} + + /* Bit field. @@ -8058,6 +8114,35 @@ my_decimal *Field_bit::val_decimal(my_decimal *deciaml_value) } +/* + Compare two bit fields using pointers within the record. + SYNOPSIS + cmp_max() + a Pointer to field->ptr in first record + b Pointer to field->ptr in second record + max_len Maximum length used in index + DESCRIPTION + This method is used from key_rec_cmp used by merge sorts used + by partitioned index read and later other similar places. + The a and b pointer must be pointers to the field in a record + (not the table->record[0] necessarily) +*/ +int Field_bit::cmp_max(const char *a, const char *b, uint max_len) +{ + my_ptrdiff_t a_diff= a - ptr; + my_ptrdiff_t b_diff= b - ptr; + if (bit_len) + { + int flag; + uchar bits_a= get_rec_bits(bit_ptr+a_diff, bit_ofs, bit_len); + uchar bits_b= get_rec_bits(bit_ptr+b_diff, bit_ofs, bit_len); + if ((flag= (int) (bits_a - bits_b))) + return flag; + } + return memcmp(a, b, field_length); +} + + int Field_bit::key_cmp(const byte *str, uint length) { if (bit_len) |