summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <gshchepa/uchum@gleb.loc>2007-06-27 03:41:50 +0500
committerunknown <gshchepa/uchum@gleb.loc>2007-06-27 03:41:50 +0500
commit7fbf6303d264a84bd225e0113a910459a067e3d0 (patch)
tree790fb430c7654eb9815829f13e5dd0dc1b1abe72
parentbe684dc0ee86be11af02f918bd9063baa637a753 (diff)
downloadmariadb-git-7fbf6303d264a84bd225e0113a910459a067e3d0.tar.gz
Fixed bug #29251.
Sometimes special 0 ENUM values was ALTERed to normal empty string ENUM values. Special 0 ENUM value has the same string representation as normal ENUM value defined as '' (empty string). The do_field_string function was used to convert ENUM data at an ALTER TABLE request, but this function doesn't care about numerical "indices" of ENUM values, i.e. do_field_string doesn't distinguish a special 0 value from an empty string value. A new copy function called do_field_enum has been added to copy special 0 ENUM values without conversion to an empty string. sql/field_conv.cc: Fixed bug #29251. The Copy_field::get_copy_func method has been modified to return a pointer to the do_field_enum function if a conversion between two columns of incompatible enum types is required. The do_field_enum function has been added for the correct conversion of special 0 enum values. mysql-test/t/type_enum.test: Updated test case for bug #29251. mysql-test/r/type_enum.result: Updated test case for bug #29251.
-rw-r--r--mysql-test/r/type_enum.result23
-rw-r--r--mysql-test/t/type_enum.test17
-rw-r--r--sql/field_conv.cc17
3 files changed, 56 insertions, 1 deletions
diff --git a/mysql-test/r/type_enum.result b/mysql-test/r/type_enum.result
index b5ec72ffe5a..415c391ebb8 100644
--- a/mysql-test/r/type_enum.result
+++ b/mysql-test/r/type_enum.result
@@ -1778,4 +1778,27 @@ drop table t1;
create table t1(exhausting_charset enum('ABCDEFGHIJKLMNOPQRSTUVWXYZ','
 !"','#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~','xx\','yy\','zz'));
ERROR 42000: Field separator argument is not what is expected; check the manual
+CREATE TABLE t1 (
+id INT AUTO_INCREMENT PRIMARY KEY,
+c1 ENUM('a', '', 'b')
+);
+INSERT INTO t1 (c1) VALUES (0), ('a'), (''), ('b');
+Warnings:
+Warning 1265 Data truncated for column 'c1' at row 1
+SELECT id, c1 + 0, c1 FROM t1;
+id c1 + 0 c1
+1 0
+2 1 a
+3 2
+4 3 b
+ALTER TABLE t1 CHANGE c1 c1 ENUM('a', '') NOT NULL;
+Warnings:
+Warning 1265 Data truncated for column 'c1' at row 4
+SELECT id, c1 + 0, c1 FROM t1;
+id c1 + 0 c1
+1 0
+2 1 a
+3 2
+4 0
+DROP TABLE t1;
End of 4.1 tests
diff --git a/mysql-test/t/type_enum.test b/mysql-test/t/type_enum.test
index 4b3429d9ea0..765c3b6d7cc 100644
--- a/mysql-test/t/type_enum.test
+++ b/mysql-test/t/type_enum.test
@@ -156,4 +156,21 @@ drop table t1;
create table t1(exhausting_charset enum('ABCDEFGHIJKLMNOPQRSTUVWXYZ','
 !"','#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~','xx\','yy\','zz'));
+#
+# Bug #29251: MySQL coerces special 0 enum values to normal '' value
+# when ALTERing the column
+#
+
+CREATE TABLE t1 (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ c1 ENUM('a', '', 'b')
+);
+INSERT INTO t1 (c1) VALUES (0), ('a'), (''), ('b');
+SELECT id, c1 + 0, c1 FROM t1;
+
+ALTER TABLE t1 CHANGE c1 c1 ENUM('a', '') NOT NULL;
+SELECT id, c1 + 0, c1 FROM t1;
+
+DROP TABLE t1;
+
--echo End of 4.1 tests
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index 59b550572c3..4a7935a4be7 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -311,6 +311,15 @@ static void do_field_string(Copy_field *copy)
}
+static void do_field_enum(Copy_field *copy)
+{
+ if (copy->from_field->val_int() == 0)
+ ((Field_enum *) copy->to_field)->store_type((ulonglong) 0);
+ else
+ do_field_string(copy);
+}
+
+
static void do_field_int(Copy_field *copy)
{
longlong value=copy->from_field->val_int();
@@ -538,7 +547,13 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*)
to->real_type() == FIELD_TYPE_SET)
{
if (!to->eq_def(from))
- return do_field_string;
+ {
+ if (from->real_type() == MYSQL_TYPE_ENUM &&
+ to->real_type() == MYSQL_TYPE_ENUM)
+ return do_field_enum;
+ else
+ return do_field_string;
+ }
}
else if (to->charset() != from->charset())
return do_field_string;