Fix for bug#23113: Different behavior on altering ENUM fields between 5.0 and 5.1
Problem: mysqld doesn't detect that enum data must be reinserted performing 'ALTER TABLE' in some cases. Fix: reinsert data altering an enum field if enum values are changed.
This commit is contained in:
parent
a4890f896c
commit
adf630dcee
@ -1222,4 +1222,16 @@ ALTER TABLE t1 CHANGE d c varchar(10);
|
||||
affected rows: 0
|
||||
info: Records: 0 Duplicates: 0 Warnings: 0
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(a INT AUTO_INCREMENT PRIMARY KEY,
|
||||
b ENUM('a', 'b', 'c') NOT NULL);
|
||||
INSERT INTO t1 (b) VALUES ('a'), ('c'), ('b'), ('b'), ('a');
|
||||
ALTER TABLE t1 MODIFY b ENUM('a', 'z', 'b', 'c') NOT NULL;
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
1 a
|
||||
2 c
|
||||
3 b
|
||||
4 b
|
||||
5 a
|
||||
DROP TABLE t1;
|
||||
End of 5.1 tests
|
||||
|
@ -947,4 +947,16 @@ ALTER TABLE t1 CHANGE d c varchar(10);
|
||||
--disable_info
|
||||
DROP TABLE t1;
|
||||
|
||||
|
||||
#
|
||||
# Bug #23113: Different behavior on altering ENUM fields between 5.0 and 5.1
|
||||
#
|
||||
CREATE TABLE t1(a INT AUTO_INCREMENT PRIMARY KEY,
|
||||
b ENUM('a', 'b', 'c') NOT NULL);
|
||||
INSERT INTO t1 (b) VALUES ('a'), ('c'), ('b'), ('b'), ('a');
|
||||
ALTER TABLE t1 MODIFY b ENUM('a', 'z', 'b', 'c') NOT NULL;
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
|
||||
--echo End of 5.1 tests
|
||||
|
39
sql/field.cc
39
sql/field.cc
@ -8783,28 +8783,43 @@ bool Field::eq_def(Field *field)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@return
|
||||
returns 1 if the fields are equally defined
|
||||
*/
|
||||
|
||||
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++)
|
||||
if (my_strnncoll(field_charset,
|
||||
(const uchar*)typelib->type_names[i],
|
||||
strlen(typelib->type_names[i]),
|
||||
(const uchar*)from_lib->type_names[i],
|
||||
strlen(from_lib->type_names[i])))
|
||||
return 0;
|
||||
return 1;
|
||||
return compare_enum_values(((Field_enum*) field)->typelib);
|
||||
}
|
||||
|
||||
|
||||
bool Field_enum::compare_enum_values(TYPELIB *values)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@return
|
||||
returns 1 if the fields are equally defined
|
||||
|
@ -1853,6 +1853,8 @@ public:
|
||||
CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; }
|
||||
private:
|
||||
int do_save_field_metadata(uchar *first_byte);
|
||||
bool compare_enum_values(TYPELIB *values);
|
||||
uint is_equal(Create_field *new_field);
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user