Commit f8bf427b authored by gshchepa/uchum@gleb.loc's avatar gshchepa/uchum@gleb.loc
Browse files

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.
parent 78e900dd
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -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
+17 −0
Original line number Diff line number Diff line
@@ -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
+16 −1
Original line number Diff line number Diff line
@@ -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,8 +547,14 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*)
	  to->real_type() == FIELD_TYPE_SET)
      {
	if (!to->eq_def(from))
        {
          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;
      else if (to->real_type() == FIELD_TYPE_VAR_STRING && to_length !=