diff options
author | Alexander Nozdrin <alik@sun.com> | 2009-10-23 15:22:21 +0400 |
---|---|---|
committer | Alexander Nozdrin <alik@sun.com> | 2009-10-23 15:22:21 +0400 |
commit | 069d78c06714233dcdc6011fa3262a54df6a1ed4 (patch) | |
tree | 9a94748e3f29d58645ae7979faaf09464080033d /sql/field.cc | |
parent | 40c0ae812965d86406f8e44fc0c4af0914858d46 (diff) | |
parent | 2f5413ebc5a47ed45abe0d3c660cfbf673c666e2 (diff) | |
download | mariadb-git-069d78c06714233dcdc6011fa3262a54df6a1ed4.tar.gz |
Merge from mysql-next-mr.
Diffstat (limited to 'sql/field.cc')
-rw-r--r-- | sql/field.cc | 134 |
1 files changed, 96 insertions, 38 deletions
diff --git a/sql/field.cc b/sql/field.cc index 2d29c0b7f74..460fca04959 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1139,11 +1139,12 @@ int Field_num::check_int(CHARSET_INFO *cs, const char *str, int length, /* Test if we get an empty string or wrong integer */ if (str == int_end || error == MY_ERRNO_EDOM) { - push_numerical_conversion_warning(table->in_use, str, length, - cs, "integer", - ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, - field_name, - table->in_use->warning_info->current_row_for_warning()); + ErrConvString err(str, length, cs); + push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, + ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD), + "integer", err.ptr(), field_name, + (ulong) table->in_use->warning_info->current_row_for_warning()); return 1; } /* Test if we have garbage at the end of the given string. */ @@ -2701,11 +2702,13 @@ int Field_new_decimal::store(const char *from, uint length, &decimal_value)) && table->in_use->abort_on_warning) { - push_numerical_conversion_warning(table->in_use, from, length, - &my_charset_bin, "decimal", - ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, - field_name, - table->in_use->warning_info->current_row_for_warning()); + ErrConvString errmsg(from, length, &my_charset_bin); + push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, + ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD), + "decimal", errmsg.ptr(), field_name, + (ulong) table->in_use->warning_info->current_row_for_warning()); + DBUG_RETURN(err); } @@ -2719,11 +2722,13 @@ int Field_new_decimal::store(const char *from, uint length, break; case E_DEC_BAD_NUM: { - push_numerical_conversion_warning(table->in_use, from, length, - &my_charset_bin, "decimal", - ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, - field_name, - table->in_use->warning_info->current_row_for_warning()); + ErrConvString errmsg(from, length, &my_charset_bin); + push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, + ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD), + "decimal", errmsg.ptr(), field_name, + (ulong) table->in_use->warning_info-> + current_row_for_warning()); my_decimal_set_zero(&decimal_value); break; } @@ -4586,10 +4591,11 @@ warn: char buf[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE]; String tmp(buf, sizeof(buf), &my_charset_latin1), *str; str= val_str(&tmp, 0); + ErrConvString err(str); push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_TRUNCATED_WRONG_VALUE, ER(ER_TRUNCATED_WRONG_VALUE), "INTEGER", - str->c_ptr()); + err.ptr()); } return res; } @@ -6627,8 +6633,11 @@ double Field_string::val_real(void) !check_if_only_end_space(cs, end, (char*) ptr + field_length)))) { - push_numerical_conversion_warning(current_thd, (char*)ptr, field_length, - cs, "DOUBLE", ER_TRUNCATED_WRONG_VALUE); + ErrConvString err((char*) ptr, field_length, cs); + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TRUNCATED_WRONG_VALUE, + ER(ER_TRUNCATED_WRONG_VALUE), "DOUBLE", + err.ptr()); } return result; } @@ -6648,8 +6657,11 @@ longlong Field_string::val_int(void) !check_if_only_end_space(cs, end, (char*) ptr + field_length)))) { - push_numerical_conversion_warning(current_thd, (char*)ptr, field_length, - cs, "INTEGER", ER_TRUNCATED_WRONG_VALUE); + ErrConvString err((char*) ptr, field_length, cs); + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TRUNCATED_WRONG_VALUE, + ER(ER_TRUNCATED_WRONG_VALUE), + "INTEGER", err.ptr()); } return result; } @@ -6681,8 +6693,11 @@ my_decimal *Field_string::val_decimal(my_decimal *decimal_value) charset(), decimal_value); if (!table->in_use->no_errors && err) { - push_numerical_conversion_warning(current_thd, (char*)ptr, field_length, - charset(), "DECIMAL", ER_TRUNCATED_WRONG_VALUE); + ErrConvString errmsg((char*) ptr, field_length, charset()); + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TRUNCATED_WRONG_VALUE, + ER(ER_TRUNCATED_WRONG_VALUE), + "DECIMAL", errmsg.ptr()); } return decimal_value; @@ -8865,38 +8880,81 @@ bool Field::eq_def(Field *field) /** + Compare the first t1::count type names. + + @return TRUE if the type names of t1 match those of t2. FALSE otherwise. +*/ + +static bool compare_type_names(CHARSET_INFO *charset, TYPELIB *t1, TYPELIB *t2) +{ + for (uint i= 0; i < t1->count; i++) + if (my_strnncoll(charset, + (const uchar*) t1->type_names[i], + t1->type_lengths[i], + (const uchar*) t2->type_names[i], + t2->type_lengths[i])) + return FALSE; + return TRUE; +} + +/** @return returns 1 if the fields are equally defined */ bool Field_enum::eq_def(Field *field) { + TYPELIB *values; + if (!Field::eq_def(field)) - return 0; - return compare_enum_values(((Field_enum*) field)->typelib); -} + return FALSE; + values= ((Field_enum*) field)->typelib; -bool Field_enum::compare_enum_values(TYPELIB *values) -{ + /* Definition must be strictly equal. */ if (typelib->count != values->count) return FALSE; - for (uint i= 0; i < typelib->count; i++) - if (my_strnncoll(field_charset, - (const uchar*) typelib->type_names[i], - typelib->type_lengths[i], - (const uchar*) values->type_names[i], - values->type_lengths[i])) - return FALSE; - return TRUE; + + return compare_type_names(field_charset, typelib, values); } +/** + Check whether two fields can be considered 'equal' for table + alteration purposes. Fields are equal if they retain the same + pack length and if new members are added to the end of the list. + + @return IS_EQUAL_YES if fields are compatible. + IS_EQUAL_NO otherwise. +*/ + uint Field_enum::is_equal(Create_field *new_field) { - if (!Field_str::is_equal(new_field)) - return 0; - return compare_enum_values(new_field->interval); + TYPELIB *values= new_field->interval; + + /* + The fields are compatible if they have the same flags, + type, charset and have the same underlying length. + */ + if (compare_str_field_flags(new_field, flags) || + new_field->sql_type != real_type() || + new_field->charset != field_charset || + new_field->pack_length != pack_length()) + return IS_EQUAL_NO; + + /* + Changing the definition of an ENUM or SET column by adding a new + enumeration or set members to the end of the list of valid member + values only alters table metadata and not table data. + */ + if (typelib->count > values->count) + return IS_EQUAL_NO; + + /* Check whether there are modification before the end. */ + if (! compare_type_names(field_charset, typelib, new_field->interval)) + return IS_EQUAL_NO; + + return IS_EQUAL_YES; } |