diff options
-rw-r--r-- | mysql-test/r/varbinary.result | 52 | ||||
-rw-r--r-- | mysql-test/std_data/bug19371.MYD | bin | 0 -> 40 bytes | |||
-rw-r--r-- | mysql-test/std_data/bug19371.MYI | bin | 0 -> 1024 bytes | |||
-rw-r--r-- | mysql-test/std_data/bug19371.frm | bin | 0 -> 8578 bytes | |||
-rw-r--r-- | mysql-test/t/varbinary.test | 40 | ||||
-rw-r--r-- | sql/field_conv.cc | 24 | ||||
-rw-r--r-- | sql/handler.cc | 4 |
7 files changed, 120 insertions, 0 deletions
diff --git a/mysql-test/r/varbinary.result b/mysql-test/r/varbinary.result index e62051df5cd..2b8a9c625a5 100644 --- a/mysql-test/r/varbinary.result +++ b/mysql-test/r/varbinary.result @@ -26,3 +26,55 @@ select x,xx from t1; x xx 1 2 drop table t1; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varbinary(255) default NULL, + `b` varchar(255) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +select length(a), length(b) from t1; +length(a) length(b) +255 3 +255 3 +CHECK TABLE t1 FOR UPGRADE; +Table Op Msg_type Msg_text +test.t1 check error Table upgrade required. Please do "REPAIR TABLE `t1`" to fix it! +REPAIR TABLE t1; +Table Op Msg_type Msg_text +test.t1 repair status OK +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` varbinary(255) default NULL, + `b` varchar(255) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +select length(a), length(b) from t1; +length(a) length(b) +3 3 +3 3 +insert into t1 values("ccc", "ddd"); +select length(a), length(b) from t1; +length(a) length(b) +3 3 +3 3 +3 3 +select hex(a), hex(b) from t1; +hex(a) hex(b) +616161 636363 +626262 646464 +636363 646464 +select concat("'", a, "'"), concat("'", b, "'") from t1; +concat("'", a, "'") concat("'", b, "'") +'aaa' 'ccc' +'bbb' 'ddd' +'ccc' 'ddd' +drop table t1; +create table t1(a varbinary(255)); +insert into t1 values("aaa "); +select length(a) from t1; +length(a) +6 +alter table t1 modify a varchar(255); +select length(a) from t1; +length(a) +6 diff --git a/mysql-test/std_data/bug19371.MYD b/mysql-test/std_data/bug19371.MYD Binary files differnew file mode 100644 index 00000000000..1b58a70832f --- /dev/null +++ b/mysql-test/std_data/bug19371.MYD diff --git a/mysql-test/std_data/bug19371.MYI b/mysql-test/std_data/bug19371.MYI Binary files differnew file mode 100644 index 00000000000..06ee5b2d766 --- /dev/null +++ b/mysql-test/std_data/bug19371.MYI diff --git a/mysql-test/std_data/bug19371.frm b/mysql-test/std_data/bug19371.frm Binary files differnew file mode 100644 index 00000000000..7be45d6f8da --- /dev/null +++ b/mysql-test/std_data/bug19371.frm diff --git a/mysql-test/t/varbinary.test b/mysql-test/t/varbinary.test index 5fbd116d7b8..a20359ac00e 100644 --- a/mysql-test/t/varbinary.test +++ b/mysql-test/t/varbinary.test @@ -37,3 +37,43 @@ select x,xx from t1; drop table t1; # End of 4.1 tests + +# +# Bug #19371 VARBINARY() have trailing zeros after upgrade from 4.1 +# + +# Test with a saved table from 4.1 +copy_file std_data/bug19371.frm $MYSQLTEST_VARDIR/master-data/test/t1.frm; +copy_file std_data/bug19371.MYD $MYSQLTEST_VARDIR/master-data/test/t1.MYD; +copy_file std_data/bug19371.MYI $MYSQLTEST_VARDIR/master-data/test/t1.MYI; + +# Everything _looks_ fine +show create table t1; + +# But the length of the varbinary columns are too long +select length(a), length(b) from t1; + +# Run CHECK TABLE, it should indicate table need a REPAIR TABLE +CHECK TABLE t1 FOR UPGRADE; + +# Run REPAIR TABLE to alter the table and repair +# the varbinary fields +REPAIR TABLE t1; + +# Now check it's back to normal +show create table t1; +select length(a), length(b) from t1; +insert into t1 values("ccc", "ddd"); +select length(a), length(b) from t1; +select hex(a), hex(b) from t1; +select concat("'", a, "'"), concat("'", b, "'") from t1; + +drop table t1; + +# Check that the fix does not affect table created with current version +create table t1(a varbinary(255)); +insert into t1 values("aaa "); +select length(a) from t1; +alter table t1 modify a varchar(255); +select length(a) from t1; + diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 95ff985376d..3286695d733 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -309,6 +309,21 @@ static void do_field_string(Copy_field *copy) } +static void do_field_varbinary_pre50(Copy_field *copy) +{ + char buff[MAX_FIELD_WIDTH]; + copy->tmp.set_quick(buff,sizeof(buff),copy->tmp.charset()); + copy->from_field->val_str(©->tmp); + + /* Use the same function as in 4.1 to trim trailing spaces */ + uint length= my_lengthsp_8bit(&my_charset_bin, copy->tmp.c_ptr_quick(), + copy->from_field->field_length); + + copy->to_field->store(copy->tmp.c_ptr_quick(), length, + copy->tmp.charset()); +} + + static void do_field_int(Copy_field *copy) { longlong value= copy->from_field->val_int(); @@ -571,6 +586,15 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*) if (from->result_type() == STRING_RESULT) { /* + Detect copy from pre 5.0 varbinary to varbinary as of 5.0 and + use special copy function that removes trailing spaces and thus + repairs data. + */ + if (from->type() == MYSQL_TYPE_VAR_STRING && !from->has_charset() && + to->type() == MYSQL_TYPE_VARCHAR && !to->has_charset()) + return do_field_varbinary_pre50; + + /* If we are copying date or datetime's we have to check the dates if we don't allow 'all' dates. */ diff --git a/sql/handler.cc b/sql/handler.cc index 4accc746664..09e83247bb5 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1972,6 +1972,10 @@ int handler::check_old_types() { return HA_ADMIN_NEEDS_ALTER; } + if ((*field)->type() == MYSQL_TYPE_VAR_STRING) + { + return HA_ADMIN_NEEDS_ALTER; + } } } return 0; |