From f90f1e306fe1b25fabfecc0e64875dd9109b2a20 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 9 Nov 2006 12:00:27 +0100 Subject: [PATCH 1/4] Bug#19371 VARBINARY() have trailing zeros after upgrade from 4.1 - Detect if a table has field of type MYSQL_TYPE_VAR_STRING while running "CHECK TABLE t FOR UPGRADE" and indicate it need to be fixed with "REPAIR TABLE t". - When running a "REPAIR TABLE t" or "ALTER TABLE t FORCE" on the above table, install a special copy function to trim off the trailing spaces which we safely can say that the pre 5.0 mysqld didn't put there. mysql-test/r/varbinary.result: Add test to see that a table with varbinary from 4.1 can be REPAIRED mysql-test/t/varbinary.test: Add test to see that a table with varbinary from 4.1 can be REPAIRED sql/field_conv.cc: Add new field copy function 'do_field_varbinary_pre50' used for copying between MYSQL_TYPE_VAR_STRING and MYSQL_TYPE_VARCHAR. It will remove trailing spaces from the field as MySQL <= 4.1 never stores the trailing spaces for a MYSQL_TYPE_VAR_STRING. Install this new copy function in ALTER TABLEs list of functions to use for copying data during and alter if from field is a <= 4.1 varbinary and to field is 5.0 varbinary. sql/handler.cc: If the table has a pre 5.0 varbinary, table not to be altered so the field type is upgraded to 5.0 version and trailing space can be trimmed. mysql-test/std_data/bug19371.MYD: New BitKeeper file ``mysql-test/std_data/bug19371.MYD'' mysql-test/std_data/bug19371.MYI: New BitKeeper file ``mysql-test/std_data/bug19371.MYI'' mysql-test/std_data/bug19371.frm: New BitKeeper file ``mysql-test/std_data/bug19371.frm'' --- mysql-test/r/varbinary.result | 52 +++++++++++++++++++++++++++++++ mysql-test/std_data/bug19371.MYD | Bin 0 -> 40 bytes mysql-test/std_data/bug19371.MYI | Bin 0 -> 1024 bytes mysql-test/std_data/bug19371.frm | Bin 0 -> 8578 bytes mysql-test/t/varbinary.test | 40 ++++++++++++++++++++++++ sql/field_conv.cc | 24 ++++++++++++++ sql/handler.cc | 4 +++ 7 files changed, 120 insertions(+) create mode 100644 mysql-test/std_data/bug19371.MYD create mode 100644 mysql-test/std_data/bug19371.MYI create mode 100644 mysql-test/std_data/bug19371.frm 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 new file mode 100644 index 0000000000000000000000000000000000000000..1b58a70832fd265c905eb935049ff73af5cf51ef GIT binary patch literal 40 jcmZQ(;9_I`!Jal>86jF)%@C7{&A-3LpY3FmVkS12=7U4Jao9m4}<_ z>LrwctOuQsEC*r3?ZlKq5n%-S0fZTV8kj)#f$U}mVn!A)31l%aK)efP!U;wYi;>|! Thz3${r@|GCGDbsSID`NI%jguS literal 0 HcmV?d00001 diff --git a/mysql-test/std_data/bug19371.frm b/mysql-test/std_data/bug19371.frm new file mode 100644 index 0000000000000000000000000000000000000000..7be45d6f8da3d128b42f6b4fe863f559cab9d694 GIT binary patch literal 8578 zcmeI&u?~VT5XSMZ2N>8Gj5Dhf&MZEGiLU@pVtj8o4?~$9jr?!9>kV!5OQ*JTYMMf7 zlXQtBk75n0)vRTmdu=Xq?t7`r12O^#Abtmp.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(); @@ -570,6 +585,15 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*) // Check if identical fields 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; From 6f1c384854e8aa15178fb77e0d0b29eafb679454 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 29 Nov 2006 21:38:38 +0100 Subject: [PATCH 2/4] Change mode of the checked in 4.1 version files so they are writable mysql-test/std_data/bug19371.frm: Change mode to -rw-rw--w- mysql-test/std_data/bug19371.MYD: Change mode to -rw-rw--w- mysql-test/std_data/bug19371.MYI: Change mode to -rw-rw--w- From 0e8ed1b5f2235281ec1b2a143de48d3370db8a50 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 29 Nov 2006 23:02:06 +0100 Subject: [PATCH 3/4] Add command "chmod" to mysqltest client/mysqltest.c: Add "chmod" command mysql-test/r/mysqltest.result: Update result file mysql-test/t/mysqltest.test: Add tests for chmod --- client/mysqltest.c | 45 +++++++++++++++++++++++++++++++++++ mysql-test/r/mysqltest.result | 6 +++++ mysql-test/t/mysqltest.test | 39 ++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+) diff --git a/client/mysqltest.c b/client/mysqltest.c index efb5f1915f4..29a31a6c60c 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -265,6 +265,7 @@ enum enum_commands { Q_DISABLE_PARSING, Q_ENABLE_PARSING, Q_REPLACE_REGEX, Q_REMOVE_FILE, Q_FILE_EXIST, Q_WRITE_FILE, Q_COPY_FILE, Q_PERL, Q_DIE, + Q_CHMOD_FILE, Q_UNKNOWN, /* Unknown command. */ Q_COMMENT, /* Comments, ignored. */ @@ -345,6 +346,7 @@ const char *command_names[]= "copy_file", "perl", "die", + "chmod", 0 }; @@ -1751,6 +1753,48 @@ void do_copy_file(struct st_command *command) } +/* + SYNOPSIS + do_chmod_file + command command handle + + DESCRIPTION + chmod + Change file permission of + + NOTE! Simplified version, only supports +r, -r, +w, -w +*/ + +void do_chmod_file(struct st_command *command) +{ + mode_t mode= 0; + DYNAMIC_STRING ds_mode; + DYNAMIC_STRING ds_file; + const struct command_arg chmod_file_args[] = { + "mode", ARG_STRING, TRUE, &ds_mode, "Mode of file", + "file", ARG_STRING, TRUE, &ds_file, "Filename of file to modify" + }; + DBUG_ENTER("do_chmod_file"); + + check_command_args(command, command->first_argument, + chmod_file_args, + sizeof(chmod_file_args)/sizeof(struct command_arg), + ' '); + + /* Parse what mode to set */ + if (ds_mode.length != 4) + die("You must write a 4 digit octal number for mode"); + + str2int(ds_mode.str, 8, 0, INT_MAX, (long*)&mode); + + DBUG_PRINT("info", ("chmod %o %s", mode, ds_file.str)); + handle_command_error(command, chmod(ds_file.str, mode)); + dynstr_free(&ds_mode); + dynstr_free(&ds_file); + DBUG_VOID_RETURN; +} + + /* SYNOPSIS do_file_exists @@ -5604,6 +5648,7 @@ int main(int argc, char **argv) case Q_FILE_EXIST: do_file_exist(command); break; case Q_WRITE_FILE: do_write_file(command); break; case Q_COPY_FILE: do_copy_file(command); break; + case Q_CHMOD_FILE: do_chmod_file(command); break; case Q_PERL: do_perl(command); break; case Q_DELIMITER: do_delimiter(command); diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index a0fce5f483f..ea9221fc476 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -512,6 +512,12 @@ mysqltest: At line 1: End of line junk detected: "write_file filename "; mysqltest: At line 1: Missing required argument 'filename' to command 'file_exists' mysqltest: At line 1: Missing required argument 'from_file' to command 'copy_file' mysqltest: At line 1: Missing required argument 'to_file' to command 'copy_file' +mysqltest: At line 1: Missing required argument 'mode' to command 'chmod' +mysqltest: At line 1: You must write a 4 digit octal number for mode +mysqltest: At line 1: You must write a 4 digit octal number for mode +mysqltest: At line 1: Missing required argument 'file' to command 'chmod' +mysqltest: At line 1: command "chmod" failed with error -1 +mysqltest: At line 1: You must write a 4 digit octal number for mode hello hello hello diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index d98375ca746..e11a0c5099f 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -1521,6 +1521,45 @@ remove_file $MYSQLTEST_VARDIR/tmp/file2.tmp; --error 1 --exec echo "copy_file from_file;" | $MYSQL_TEST 2>&1 +# ---------------------------------------------------------------------------- +# test for chmod +# ---------------------------------------------------------------------------- +--write_file $MYSQLTEST_VARDIR/tmp/file1.tmp +file1 +EOF + +chmod 0000 $MYSQLTEST_VARDIR/tmp/file1.tmp; +# The below write fails, but --error is not implemented +# for write_file +#--write_file $MYSQLTEST_VARDIR/tmp/file1.tmp +#test should fail +#EOF + +chmod 0777 $MYSQLTEST_VARDIR/tmp/file1.tmp; +--write_file $MYSQLTEST_VARDIR/tmp/file1.tmp +test2 +EOF + +remove_file $MYSQLTEST_VARDIR/tmp/file1.tmp; + +--error 1 +--exec echo "chmod ;" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "chmod 0 from_file;" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "chmod 08 from_file;" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "chmod from_file;" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "chmod ABZD from_file;" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "chmod 06789 from_file;" | $MYSQL_TEST 2>&1 + # ---------------------------------------------------------------------------- # test for perl # ---------------------------------------------------------------------------- From 8e0614c83950b6189eb1dfc218b13546fa663c13 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 29 Nov 2006 23:03:45 +0100 Subject: [PATCH 4/4] Bug#19371 VARBINARY() have trailing zeros after upgrade from 4.1 - chmod the saved files from 4.1 to make sure they are writable mysql-test/t/varbinary.test: As the files saved from 4.1 has been in bk they muight be readonly Use "chmod" to make sure they are writable --- mysql-test/t/varbinary.test | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mysql-test/t/varbinary.test b/mysql-test/t/varbinary.test index a20359ac00e..0e45bfb5e1b 100644 --- a/mysql-test/t/varbinary.test +++ b/mysql-test/t/varbinary.test @@ -44,8 +44,11 @@ drop table t1; # Test with a saved table from 4.1 copy_file std_data/bug19371.frm $MYSQLTEST_VARDIR/master-data/test/t1.frm; +chmod 0777 $MYSQLTEST_VARDIR/master-data/test/t1.frm; copy_file std_data/bug19371.MYD $MYSQLTEST_VARDIR/master-data/test/t1.MYD; +chmod 0777 $MYSQLTEST_VARDIR/master-data/test/t1.MYD; copy_file std_data/bug19371.MYI $MYSQLTEST_VARDIR/master-data/test/t1.MYI; +chmod 0777 $MYSQLTEST_VARDIR/master-data/test/t1.MYI; # Everything _looks_ fine show create table t1;