From 510bda4bed61e3fc96249e693532874e21b1f274 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 7 Dec 2007 17:40:42 +0400 Subject: [PATCH 01/12] BUG#25677 - With --skip-symbolic-links option on, DATA DIRECTORY clause is silently ignored When symbolic links are disabled by command line option or NO_DIR_IN_CREATE sql mode, CREATE TABLE silently ignores DATA/INDEX DIRECTORY options. With this fix a warning is issued when symbolic links are disabled. mysql-test/r/symlink.result: A test case for BUG#25677. mysql-test/t/symlink.test: A test case for BUG#25677. sql/sql_parse.cc: Moved handling of situation when mysqld is compiled without HAVE_READLINK to mysql_create_table_no_lock(). sql/sql_table.cc: Issue a warning in case DATA/INDEX DIRECTORY is specified and: - server is compiled without HAVE_READLINK; - using symbolic links is disabled by command line option; - using symbolic links is disabled by NO_DIR_IN_CREATE sql mode. --- mysql-test/r/bdb_notembedded.result | 35 ++++++++++++++++++++++++++ mysql-test/r/symlink.result | 8 ++++++ mysql-test/t/bdb_notembedded.test | 38 +++++++++++++++++++++++++++++ mysql-test/t/symlink.test | 12 +++++++++ sql/sql_parse.cc | 10 +------- sql/sql_table.cc | 12 ++++++++- 6 files changed, 105 insertions(+), 10 deletions(-) create mode 100644 mysql-test/r/bdb_notembedded.result create mode 100644 mysql-test/t/bdb_notembedded.test diff --git a/mysql-test/r/bdb_notembedded.result b/mysql-test/r/bdb_notembedded.result new file mode 100644 index 00000000000..14cb5fad915 --- /dev/null +++ b/mysql-test/r/bdb_notembedded.result @@ -0,0 +1,35 @@ +set autocommit=1; +reset master; +create table bug16206 (a int); +insert into bug16206 values(1); +start transaction; +insert into bug16206 values(2); +commit; +show binlog events; +Log_name Pos Event_type Server_id End_log_pos Info +f n Format_desc 1 n Server ver: VERSION, Binlog ver: 4 +f n Query 1 n use `test`; create table bug16206 (a int) +f n Query 1 n use `test`; insert into bug16206 values(1) +f n Query 1 n use `test`; insert into bug16206 values(2) +drop table bug16206; +reset master; +create table bug16206 (a int) engine= bdb; +insert into bug16206 values(0); +insert into bug16206 values(1); +start transaction; +insert into bug16206 values(2); +commit; +insert into bug16206 values(3); +show binlog events; +Log_name Pos Event_type Server_id End_log_pos Info +f n Format_desc 1 n Server ver: VERSION, Binlog ver: 4 +f n Query 1 n use `test`; create table bug16206 (a int) engine= bdb +f n Query 1 n use `test`; insert into bug16206 values(0) +f n Query 1 n use `test`; insert into bug16206 values(1) +f n Query 1 n use `test`; BEGIN +f n Query 1 n use `test`; insert into bug16206 values(2) +f n Query 1 n use `test`; COMMIT +f n Query 1 n use `test`; insert into bug16206 values(3) +drop table bug16206; +set autocommit=0; +End of 5.0 tests diff --git a/mysql-test/r/symlink.result b/mysql-test/r/symlink.result index 4eece9d5b5a..7599d80588a 100644 --- a/mysql-test/r/symlink.result +++ b/mysql-test/r/symlink.result @@ -162,3 +162,11 @@ DROP DATABASE db1; DROP DATABASE db2; USE test; End of 5.0 tests +SET @OLD_SQL_MODE=@@SQL_MODE, @@SQL_MODE='NO_DIR_IN_CREATE'; +CREATE TABLE t1(a INT) DATA DIRECTORY='MYSQLTEST_VARDIR/tmp' INDEX DIRECTORY='MYSQLTEST_VARDIR/tmp'; +Warnings: +Warning 0 DATA DIRECTORY option ignored +Warning 0 INDEX DIRECTORY option ignored +DROP TABLE t1; +SET @@SQL_MODE=@OLD_SQL_MODE; +End of 5.1 tests diff --git a/mysql-test/t/bdb_notembedded.test b/mysql-test/t/bdb_notembedded.test new file mode 100644 index 00000000000..24e64ebbfb2 --- /dev/null +++ b/mysql-test/t/bdb_notembedded.test @@ -0,0 +1,38 @@ +-- source include/not_embedded.inc +-- source include/have_bdb.inc + +# +# Bug #16206: Superfluous COMMIT event in binlog when updating BDB in autocommit mode +# +set autocommit=1; + +let $VERSION=`select version()`; + +reset master; +create table bug16206 (a int); +insert into bug16206 values(1); +start transaction; +insert into bug16206 values(2); +commit; +--replace_result $VERSION VERSION +--replace_column 1 f 2 n 5 n +show binlog events; +drop table bug16206; + +reset master; +create table bug16206 (a int) engine= bdb; +insert into bug16206 values(0); +insert into bug16206 values(1); +start transaction; +insert into bug16206 values(2); +commit; +insert into bug16206 values(3); +--replace_result $VERSION VERSION +--replace_column 1 f 2 n 5 n +show binlog events; +drop table bug16206; + +set autocommit=0; + + +--echo End of 5.0 tests diff --git a/mysql-test/t/symlink.test b/mysql-test/t/symlink.test index f339b29c83a..eaad45d7d5d 100644 --- a/mysql-test/t/symlink.test +++ b/mysql-test/t/symlink.test @@ -226,3 +226,15 @@ USE test; --echo End of 5.0 tests + +# +# BUG#25677 - With --skip-symbolic-links option on, DATA DIRECTORY clause is +# silently ignored +# +SET @OLD_SQL_MODE=@@SQL_MODE, @@SQL_MODE='NO_DIR_IN_CREATE'; +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +eval CREATE TABLE t1(a INT) DATA DIRECTORY='$MYSQLTEST_VARDIR/tmp' INDEX DIRECTORY='$MYSQLTEST_VARDIR/tmp'; +DROP TABLE t1; +SET @@SQL_MODE=@OLD_SQL_MODE; + +--echo End of 5.1 tests diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 8ed658df90d..e5f96a96a00 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2237,15 +2237,7 @@ mysql_execute_command(THD *thd) /* Might have been updated in create_table_precheck */ create_info.alias= create_table->alias; -#ifndef HAVE_READLINK - if (create_info.data_file_name) - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0, - "DATA DIRECTORY option ignored"); - if (create_info.index_file_name) - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0, - "INDEX DIRECTORY option ignored"); - create_info.data_file_name= create_info.index_file_name= NULL; -#else +#ifdef HAVE_READLINK /* Fix names if symlinked tables */ if (append_file_to_dir(thd, &create_info.data_file_name, create_table->table_name) || diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 91acd8d20a3..4236028c9d8 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3437,8 +3437,18 @@ bool mysql_create_table_no_lock(THD *thd, thd->proc_info="creating table"; create_info->table_existed= 0; // Mark that table is created - if (thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE) +#ifdef HAVE_READLINK + if (!my_use_symdir || (thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE)) +#endif + { + if (create_info->data_file_name) + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0, + "DATA DIRECTORY option ignored"); + if (create_info->index_file_name) + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0, + "INDEX DIRECTORY option ignored"); create_info->data_file_name= create_info->index_file_name= 0; + } create_info->table_options=db_options; path[path_length - reg_ext_length]= '\0'; // Remove .frm extension From c9b46d56eb0304e6d9d58545ddb6a192eebbb795 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 12 Dec 2007 17:16:59 +0400 Subject: [PATCH 02/12] BUG#26978 - s->z_err not assigned a value? azio didn't handle situation when my_read() returns error. Added handling of situation when my_read() returns error. No test case for this fix. storage/archive/azio.c: Added handling of situation when my_read() returns error. --- mysql-test/r/bdb_notembedded.result | 35 ++++++++++++++++++++++++++ mysql-test/t/bdb_notembedded.test | 38 +++++++++++++++++++++++++++++ storage/archive/azio.c | 10 ++++++-- 3 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 mysql-test/r/bdb_notembedded.result create mode 100644 mysql-test/t/bdb_notembedded.test diff --git a/mysql-test/r/bdb_notembedded.result b/mysql-test/r/bdb_notembedded.result new file mode 100644 index 00000000000..14cb5fad915 --- /dev/null +++ b/mysql-test/r/bdb_notembedded.result @@ -0,0 +1,35 @@ +set autocommit=1; +reset master; +create table bug16206 (a int); +insert into bug16206 values(1); +start transaction; +insert into bug16206 values(2); +commit; +show binlog events; +Log_name Pos Event_type Server_id End_log_pos Info +f n Format_desc 1 n Server ver: VERSION, Binlog ver: 4 +f n Query 1 n use `test`; create table bug16206 (a int) +f n Query 1 n use `test`; insert into bug16206 values(1) +f n Query 1 n use `test`; insert into bug16206 values(2) +drop table bug16206; +reset master; +create table bug16206 (a int) engine= bdb; +insert into bug16206 values(0); +insert into bug16206 values(1); +start transaction; +insert into bug16206 values(2); +commit; +insert into bug16206 values(3); +show binlog events; +Log_name Pos Event_type Server_id End_log_pos Info +f n Format_desc 1 n Server ver: VERSION, Binlog ver: 4 +f n Query 1 n use `test`; create table bug16206 (a int) engine= bdb +f n Query 1 n use `test`; insert into bug16206 values(0) +f n Query 1 n use `test`; insert into bug16206 values(1) +f n Query 1 n use `test`; BEGIN +f n Query 1 n use `test`; insert into bug16206 values(2) +f n Query 1 n use `test`; COMMIT +f n Query 1 n use `test`; insert into bug16206 values(3) +drop table bug16206; +set autocommit=0; +End of 5.0 tests diff --git a/mysql-test/t/bdb_notembedded.test b/mysql-test/t/bdb_notembedded.test new file mode 100644 index 00000000000..24e64ebbfb2 --- /dev/null +++ b/mysql-test/t/bdb_notembedded.test @@ -0,0 +1,38 @@ +-- source include/not_embedded.inc +-- source include/have_bdb.inc + +# +# Bug #16206: Superfluous COMMIT event in binlog when updating BDB in autocommit mode +# +set autocommit=1; + +let $VERSION=`select version()`; + +reset master; +create table bug16206 (a int); +insert into bug16206 values(1); +start transaction; +insert into bug16206 values(2); +commit; +--replace_result $VERSION VERSION +--replace_column 1 f 2 n 5 n +show binlog events; +drop table bug16206; + +reset master; +create table bug16206 (a int) engine= bdb; +insert into bug16206 values(0); +insert into bug16206 values(1); +start transaction; +insert into bug16206 values(2); +commit; +insert into bug16206 values(3); +--replace_result $VERSION VERSION +--replace_column 1 f 2 n 5 n +show binlog events; +drop table bug16206; + +set autocommit=0; + + +--echo End of 5.0 tests diff --git a/storage/archive/azio.c b/storage/archive/azio.c index cada6c57918..59fbe2182ee 100644 --- a/storage/archive/azio.c +++ b/storage/archive/azio.c @@ -225,11 +225,17 @@ int get_byte(s) if (s->stream.avail_in == 0) { errno = 0; - s->stream.avail_in = my_read(s->file, (uchar *)s->inbuf, AZ_BUFSIZE_READ, MYF(0)); + s->stream.avail_in= (uInt) my_read(s->file, (uchar *)s->inbuf, + AZ_BUFSIZE_READ, MYF(0)); if (s->stream.avail_in == 0) { s->z_eof = 1; - /* if (ferror(s->file)) s->z_err = Z_ERRNO; */ + return EOF; + } + else if (s->stream.avail_in == (uInt) -1) + { + s->z_eof= 1; + s->z_err= Z_ERRNO; return EOF; } s->stream.next_in = s->inbuf; From 647fe5b3a12324918ebb1e75ff5619eec137efed Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 14 Dec 2007 17:05:27 +0400 Subject: [PATCH 03/12] BUG#22708 - Error message doesn't refer to storage engine unsupported When openning a table with unsupported (disabled or not compiled) storage engine, confusing error message is returned. Return better error message when we're attempting to open a table that uses unsupported engine. sql/table.cc: Return better error message when we're attempting to open a table that uses unsupported engine. --- mysql-test/r/bdb_notembedded.result | 35 ++++++++++++++++++++++++ mysql-test/t/bdb_notembedded.test | 38 ++++++++++++++++++++++++++ sql/table.cc | 41 +++++++++++++++++------------ 3 files changed, 97 insertions(+), 17 deletions(-) create mode 100644 mysql-test/r/bdb_notembedded.result create mode 100644 mysql-test/t/bdb_notembedded.test diff --git a/mysql-test/r/bdb_notembedded.result b/mysql-test/r/bdb_notembedded.result new file mode 100644 index 00000000000..14cb5fad915 --- /dev/null +++ b/mysql-test/r/bdb_notembedded.result @@ -0,0 +1,35 @@ +set autocommit=1; +reset master; +create table bug16206 (a int); +insert into bug16206 values(1); +start transaction; +insert into bug16206 values(2); +commit; +show binlog events; +Log_name Pos Event_type Server_id End_log_pos Info +f n Format_desc 1 n Server ver: VERSION, Binlog ver: 4 +f n Query 1 n use `test`; create table bug16206 (a int) +f n Query 1 n use `test`; insert into bug16206 values(1) +f n Query 1 n use `test`; insert into bug16206 values(2) +drop table bug16206; +reset master; +create table bug16206 (a int) engine= bdb; +insert into bug16206 values(0); +insert into bug16206 values(1); +start transaction; +insert into bug16206 values(2); +commit; +insert into bug16206 values(3); +show binlog events; +Log_name Pos Event_type Server_id End_log_pos Info +f n Format_desc 1 n Server ver: VERSION, Binlog ver: 4 +f n Query 1 n use `test`; create table bug16206 (a int) engine= bdb +f n Query 1 n use `test`; insert into bug16206 values(0) +f n Query 1 n use `test`; insert into bug16206 values(1) +f n Query 1 n use `test`; BEGIN +f n Query 1 n use `test`; insert into bug16206 values(2) +f n Query 1 n use `test`; COMMIT +f n Query 1 n use `test`; insert into bug16206 values(3) +drop table bug16206; +set autocommit=0; +End of 5.0 tests diff --git a/mysql-test/t/bdb_notembedded.test b/mysql-test/t/bdb_notembedded.test new file mode 100644 index 00000000000..24e64ebbfb2 --- /dev/null +++ b/mysql-test/t/bdb_notembedded.test @@ -0,0 +1,38 @@ +-- source include/not_embedded.inc +-- source include/have_bdb.inc + +# +# Bug #16206: Superfluous COMMIT event in binlog when updating BDB in autocommit mode +# +set autocommit=1; + +let $VERSION=`select version()`; + +reset master; +create table bug16206 (a int); +insert into bug16206 values(1); +start transaction; +insert into bug16206 values(2); +commit; +--replace_result $VERSION VERSION +--replace_column 1 f 2 n 5 n +show binlog events; +drop table bug16206; + +reset master; +create table bug16206 (a int) engine= bdb; +insert into bug16206 values(0); +insert into bug16206 values(1); +start transaction; +insert into bug16206 values(2); +commit; +insert into bug16206 values(3); +--replace_result $VERSION VERSION +--replace_column 1 f 2 n 5 n +show binlog events; +drop table bug16206; + +set autocommit=0; + + +--echo End of 5.0 tests diff --git a/sql/table.cc b/sql/table.cc index c3ddb809b9e..493a940fd2e 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -886,26 +886,31 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, ha_legacy_type(share->db_type()))); } #ifdef WITH_PARTITION_STORAGE_ENGINE - else + else if (str_db_type_length == 9 && + !strncmp((char *) next_chunk + 2, "partition", 9)) { - LEX_STRING pname= { C_STRING_WITH_LEN( "partition" ) }; - if (str_db_type_length == pname.length && - !strncmp((char *) next_chunk + 2, pname.str, pname.length)) - { - /* - Use partition handler - tmp_plugin is locked with a local lock. - we unlock the old value of share->db_plugin before - replacing it with a globally locked version of tmp_plugin - */ - plugin_unlock(NULL, share->db_plugin); - share->db_plugin= ha_lock_engine(NULL, partition_hton); - DBUG_PRINT("info", ("setting dbtype to '%.*s' (%d)", - str_db_type_length, next_chunk + 2, - ha_legacy_type(share->db_type()))); - } + /* + Use partition handler + tmp_plugin is locked with a local lock. + we unlock the old value of share->db_plugin before + replacing it with a globally locked version of tmp_plugin + */ + plugin_unlock(NULL, share->db_plugin); + share->db_plugin= ha_lock_engine(NULL, partition_hton); + DBUG_PRINT("info", ("setting dbtype to '%.*s' (%d)", + str_db_type_length, next_chunk + 2, + ha_legacy_type(share->db_type()))); } #endif + else if (!tmp_plugin) + { + /* purecov: begin inspected */ + error= 8; + my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str); + my_free(buff, MYF(0)); + goto err; + /* purecov: end */ + } next_chunk+= str_db_type_length + 2; } if (next_chunk + 5 < buff_end) @@ -2188,6 +2193,8 @@ void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg) "of MySQL and cannot be read", MYF(0), buff); break; + case 8: + break; default: /* Better wrong error than none */ case 4: strxmov(buff, share->normalized_path.str, reg_ext, NullS); From 53f762abfd26e432477016f00cd984e2c6c9e2d1 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 18 Dec 2007 12:29:50 +0100 Subject: [PATCH 04/12] Bug#32705 - myisam corruption: Key in wrong position at page 1024 with ucs2_bin Inserting strings with a common prefix into a table with characterset UCS2 corrupted the table. An efficient search method was used, which compares end space with ASCII blank. This doesn't work for character sets like UCS2, which do not encode blank like ASCII does. Use the less efficient search method _mi_seq_search() for charsets with mbminlen > 1. myisam/mi_open.c: Bug#32705 - myisam corruption: Key in wrong position at page 1024 with ucs2_bin Use _mi_seq_search() for charsets with mbminlen > 1. mysql-test/r/myisam.result: Bug#32705 - myisam corruption: Key in wrong position at page 1024 with ucs2_bin Added test result. mysql-test/t/myisam.test: Bug#32705 - myisam corruption: Key in wrong position at page 1024 with ucs2_bin Added test. --- myisam/mi_open.c | 11 ++++++++++- mysql-test/r/myisam.result | 10 ++++++++++ mysql-test/t/myisam.test | 13 +++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/myisam/mi_open.c b/myisam/mi_open.c index ec169ac8785..5314d6a9a6c 100644 --- a/myisam/mi_open.c +++ b/myisam/mi_open.c @@ -791,8 +791,17 @@ static void setup_key_functions(register MI_KEYDEF *keyinfo) keyinfo->get_key= _mi_get_pack_key; if (keyinfo->seg[0].flag & HA_PACK_KEY) { /* Prefix compression */ + /* + _mi_prefix_search() compares end-space against ASCII blank (' '). + It cannot be used for character sets, that do not encode the + blank character like ASCII does. UCS2 is an example. All + character sets with a fixed width > 1 or a mimimum width > 1 + cannot represent blank like ASCII does. In these cases we have + to use _mi_seq_search() for the search. + */ if (!keyinfo->seg->charset || use_strnxfrm(keyinfo->seg->charset) || - (keyinfo->seg->flag & HA_NULL_PART)) + (keyinfo->seg->flag & HA_NULL_PART) || + (keyinfo->seg->charset->mbminlen > 1)) keyinfo->bin_search=_mi_seq_search; else keyinfo->bin_search=_mi_prefix_search; diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 56933f45fbf..4ff7441c02e 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -1839,4 +1839,14 @@ CHECK TABLE t1 EXTENDED; Table Op Msg_type Msg_text test.t1 check status OK DROP TABLE t1; +CREATE TABLE t1 ( +c1 CHAR(255) CHARACTER SET UCS2 COLLATE UCS2_BIN NOT NULL, +KEY(c1) +) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('marshall\'s'); +INSERT INTO t1 VALUES ('marsh'); +CHECK TABLE t1 EXTENDED; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index 80c7a92c12f..b182c35514c 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -1193,4 +1193,17 @@ SET @@myisam_repair_threads=1; CHECK TABLE t1 EXTENDED; DROP TABLE t1; +# +# Bug#32705 - myisam corruption: Key in wrong position +# at page 1024 with ucs2_bin +# +CREATE TABLE t1 ( + c1 CHAR(255) CHARACTER SET UCS2 COLLATE UCS2_BIN NOT NULL, + KEY(c1) + ) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('marshall\'s'); +INSERT INTO t1 VALUES ('marsh'); +CHECK TABLE t1 EXTENDED; +DROP TABLE t1; + --echo End of 5.0 tests From c3bf70215b4515c2fcf21bbb9a93aaf66d8c3faf Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 14 Jan 2008 17:59:45 +0100 Subject: [PATCH 05/12] Bug#33222 - myisam-table drops rows when column is added and a char-field > 128 exists CHECK TABLE (non-QUICK) and any form of repair table did wrongly rate records as corrupted under the following conditions: 1. The table has dynamic row format and 2. it has a CHAR like column > 127 bytes (but not VARCHAR) (for multi-byte character sets this could be less than 127 characters) and 3. it has records with > 127 bytes significant length in that column (a byte beyond byte position 127 must be non-space). Affected were the statements CHECK TABLE, REPAIR TABLE, OPTIMIZE TABLE, ALTER TABLE. CHECK TABLE reported and marked the table as crashed if any record was present that fulfilled condition 3. The other statements deleted these records. The problem was a signed/unsigned compare in MyISAM code. A char to uchar change became necessary after the big byte to uchar change. mysql-test/r/myisam.result: Bug#33222 - myisam-table drops rows when column is added and a char-field > 128 exists Added test result. mysql-test/t/myisam.test: Bug#33222 - myisam-table drops rows when column is added and a char-field > 128 exists Added test. storage/myisam/mi_dynrec.c: Bug#33222 - myisam-table drops rows when column is added and a char-field > 128 exists char -> uchar became necessary after big byte -> uchar change. Fixed some small coding style violations near the changes. --- mysql-test/r/myisam.result | 162 +++++++++++++++++++++++++++++++++++ mysql-test/t/myisam.test | 170 +++++++++++++++++++++++++++++++++++++ storage/myisam/mi_dynrec.c | 32 +++---- 3 files changed, 349 insertions(+), 15 deletions(-) diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 353d66b1ad5..62220de0496 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -2001,4 +2001,166 @@ CHECK TABLE t1; Table Op Msg_type Msg_text test.t1 check status OK DROP TABLE t1; +CREATE TABLE t1 ( +c1 CHAR(130), +c2 VARCHAR(1) +) ENGINE=MyISAM; +INSERT INTO t1 VALUES(REPEAT("a",128), 'b'); +SELECT COUNT(*) FROM t1; +COUNT(*) +1 +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +REPAIR TABLE t1; +Table Op Msg_type Msg_text +test.t1 repair status OK +SELECT COUNT(*) FROM t1; +COUNT(*) +1 +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; +CREATE TABLE t1 ( +c1 CHAR(130), +c2 VARCHAR(1) +) ENGINE=MyISAM; +INSERT INTO t1 VALUES(REPEAT("a",128), 'b'); +SELECT COUNT(*) FROM t1; +COUNT(*) +1 +CHECK TABLE t1 EXTENDED; +Table Op Msg_type Msg_text +test.t1 check status OK +REPAIR TABLE t1 EXTENDED; +Table Op Msg_type Msg_text +test.t1 repair status OK +SELECT COUNT(*) FROM t1; +COUNT(*) +1 +CHECK TABLE t1 EXTENDED; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; +CREATE TABLE t1 ( +c1 CHAR(130), +c2 VARCHAR(1) +) ENGINE=MyISAM; +INSERT INTO t1 VALUES(REPEAT("a",128), 'b'); +INSERT INTO t1 VALUES('b', 'b'); +INSERT INTO t1 VALUES('c', 'b'); +DELETE FROM t1 WHERE c1='b'; +SELECT COUNT(*) FROM t1; +COUNT(*) +2 +OPTIMIZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 optimize status OK +SELECT COUNT(*) FROM t1; +COUNT(*) +2 +DROP TABLE t1; +CREATE TABLE t1 ( +c1 CHAR(130), +c2 VARCHAR(1), +KEY (c1) +) ENGINE=MyISAM; +# Insert 100 rows. Query log disabled. +UPDATE t1 SET c1=REPEAT("a",128) LIMIT 90; +SELECT COUNT(*) FROM t1; +COUNT(*) +100 +ALTER TABLE t1 ENGINE=MyISAM; +SELECT COUNT(*) FROM t1; +COUNT(*) +100 +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +CHECK TABLE t1 EXTENDED; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; +CREATE TABLE t1 ( +c1 CHAR(50), +c2 VARCHAR(1) +) ENGINE=MyISAM DEFAULT CHARSET UTF8; +INSERT INTO t1 VALUES(REPEAT(_utf8 x'e0ae85',43), 'b'); +SELECT COUNT(*) FROM t1; +COUNT(*) +1 +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +REPAIR TABLE t1; +Table Op Msg_type Msg_text +test.t1 repair status OK +SELECT COUNT(*) FROM t1; +COUNT(*) +1 +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; +CREATE TABLE t1 ( +c1 CHAR(50), +c2 VARCHAR(1) +) ENGINE=MyISAM DEFAULT CHARSET UTF8; +INSERT INTO t1 VALUES(REPEAT(_utf8 x'e0ae85',43), 'b'); +SELECT COUNT(*) FROM t1; +COUNT(*) +1 +CHECK TABLE t1 EXTENDED; +Table Op Msg_type Msg_text +test.t1 check status OK +REPAIR TABLE t1 EXTENDED; +Table Op Msg_type Msg_text +test.t1 repair status OK +SELECT COUNT(*) FROM t1; +COUNT(*) +1 +CHECK TABLE t1 EXTENDED; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; +CREATE TABLE t1 ( +c1 CHAR(50), +c2 VARCHAR(1) +) ENGINE=MyISAM DEFAULT CHARSET UTF8; +INSERT INTO t1 VALUES(REPEAT(_utf8 x'e0ae85',43), 'b'); +INSERT INTO t1 VALUES('b', 'b'); +INSERT INTO t1 VALUES('c', 'b'); +DELETE FROM t1 WHERE c1='b'; +SELECT COUNT(*) FROM t1; +COUNT(*) +2 +OPTIMIZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 optimize status OK +SELECT COUNT(*) FROM t1; +COUNT(*) +2 +DROP TABLE t1; +CREATE TABLE t1 ( +c1 CHAR(50), +c2 VARCHAR(1), +KEY (c1) +) ENGINE=MyISAM DEFAULT CHARSET UTF8; +# Insert 100 rows. Query log disabled. +UPDATE t1 SET c1=REPEAT(_utf8 x'e0ae85',43) LIMIT 90; +SELECT COUNT(*) FROM t1; +COUNT(*) +100 +ALTER TABLE t1 ENGINE=MyISAM; +SELECT COUNT(*) FROM t1; +COUNT(*) +100 +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +CHECK TABLE t1 EXTENDED; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index cadab8b3b70..334ecfd02d3 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -1261,5 +1261,175 @@ DELETE FROM t1 WHERE c1 >= 10; CHECK TABLE t1; DROP TABLE t1; +# +# Bug#33222 - myisam-table drops rows when column is added +# and a char-field > 128 exists +# +# Test #1 - CHECK TABLE sees wrong record, REPAR TABLE deletes it. +# Using a CHAR column that can have > 127 characters. +# Using a VARCHAR to create a table with dynamic row format. +CREATE TABLE t1 ( + c1 CHAR(130), + c2 VARCHAR(1) +) ENGINE=MyISAM; +INSERT INTO t1 VALUES(REPEAT("a",128), 'b'); +SELECT COUNT(*) FROM t1; +CHECK TABLE t1; +REPAIR TABLE t1; +SELECT COUNT(*) FROM t1; +CHECK TABLE t1; +DROP TABLE t1; +# +# Test #2 - same as test #1, but using EXTENDED. +# Using a CHAR column that can have > 127 characters. +# Using a VARCHAR to create a table with dynamic row format. +CREATE TABLE t1 ( + c1 CHAR(130), + c2 VARCHAR(1) +) ENGINE=MyISAM; +INSERT INTO t1 VALUES(REPEAT("a",128), 'b'); +SELECT COUNT(*) FROM t1; +CHECK TABLE t1 EXTENDED; +REPAIR TABLE t1 EXTENDED; +SELECT COUNT(*) FROM t1; +CHECK TABLE t1 EXTENDED; +DROP TABLE t1; +# +# Test #3 - same as test #1, but using OPTIMIZE TABLE. +# Using a CHAR column that can have > 127 characters. +# Using a VARCHAR to create a table with dynamic row format. +CREATE TABLE t1 ( + c1 CHAR(130), + c2 VARCHAR(1) +) ENGINE=MyISAM; +INSERT INTO t1 VALUES(REPEAT("a",128), 'b'); +# Insert more rows and delete one in the middle to force optimize. +INSERT INTO t1 VALUES('b', 'b'); +INSERT INTO t1 VALUES('c', 'b'); +DELETE FROM t1 WHERE c1='b'; +SELECT COUNT(*) FROM t1; +OPTIMIZE TABLE t1; +SELECT COUNT(*) FROM t1; +DROP TABLE t1; +# +# Test #4 - ALTER TABLE deletes rows. +# Using a CHAR column that can have > 127 characters. +# Using a VARCHAR to create a table with dynamic row format. +# Using an index which can be disabled during bulk insert. +CREATE TABLE t1 ( + c1 CHAR(130), + c2 VARCHAR(1), + KEY (c1) +) ENGINE=MyISAM; +# +# Insert 100 rows. This turns bulk insert on during the copy phase of +# ALTER TABLE. Bulk insert disables keys before the insert and re-enables +# them by repair after the insert. +--disable_query_log +let $count= 100; +--echo # Insert $count rows. Query log disabled. +while ($count) +{ + INSERT INTO t1 VALUES ('a', 'b'); + dec $count; +} +--enable_query_log +# +# Change most of the rows into long character values with > 127 characters. +UPDATE t1 SET c1=REPEAT("a",128) LIMIT 90; +SELECT COUNT(*) FROM t1; +ALTER TABLE t1 ENGINE=MyISAM; +# +# With bug present, this shows that all long rows are gone. +SELECT COUNT(*) FROM t1; +CHECK TABLE t1; +CHECK TABLE t1 EXTENDED; +DROP TABLE t1; +# +# Test #5 - same as test #1 but UTF-8. +# Using a CHAR column that can have > 127 characters. +# Using a VARCHAR to create a table with dynamic row format. +CREATE TABLE t1 ( + c1 CHAR(50), + c2 VARCHAR(1) +) ENGINE=MyISAM DEFAULT CHARSET UTF8; +# Using Tamil Letter A, Unicode U+0B85 +INSERT INTO t1 VALUES(REPEAT(_utf8 x'e0ae85',43), 'b'); +SELECT COUNT(*) FROM t1; +CHECK TABLE t1; +REPAIR TABLE t1; +SELECT COUNT(*) FROM t1; +CHECK TABLE t1; +DROP TABLE t1; +# +# Test #6 - same as test #2, but UTF-8. +# Using a CHAR column that can have > 127 characters. +# Using a VARCHAR to create a table with dynamic row format. +CREATE TABLE t1 ( + c1 CHAR(50), + c2 VARCHAR(1) +) ENGINE=MyISAM DEFAULT CHARSET UTF8; +# Using Tamil Letter A, Unicode U+0B85 +INSERT INTO t1 VALUES(REPEAT(_utf8 x'e0ae85',43), 'b'); +SELECT COUNT(*) FROM t1; +CHECK TABLE t1 EXTENDED; +REPAIR TABLE t1 EXTENDED; +SELECT COUNT(*) FROM t1; +CHECK TABLE t1 EXTENDED; +DROP TABLE t1; +# +# Test #7 - same as test #3, but UTF-8. +# Using a CHAR column that can have > 127 characters. +# Using a VARCHAR to create a table with dynamic row format. +CREATE TABLE t1 ( + c1 CHAR(50), + c2 VARCHAR(1) +) ENGINE=MyISAM DEFAULT CHARSET UTF8; +# Using Tamil Letter A, Unicode U+0B85 +INSERT INTO t1 VALUES(REPEAT(_utf8 x'e0ae85',43), 'b'); +# Insert more rows and delete one in the middle to force optimize. +INSERT INTO t1 VALUES('b', 'b'); +INSERT INTO t1 VALUES('c', 'b'); +DELETE FROM t1 WHERE c1='b'; +SELECT COUNT(*) FROM t1; +OPTIMIZE TABLE t1; +SELECT COUNT(*) FROM t1; +DROP TABLE t1; +# +# Test #8 - same as test #4, but UTF-8. +# Using a CHAR column that can have > 42 UTF-8 characters. +# Using a VARCHAR to create a table with dynamic row format. +# Using an index which can be disabled during bulk insert. +CREATE TABLE t1 ( + c1 CHAR(50), + c2 VARCHAR(1), + KEY (c1) +) ENGINE=MyISAM DEFAULT CHARSET UTF8; +# +# Insert 100 rows. This turns bulk insert on during the copy phase of +# ALTER TABLE. Bulk insert disables keys before the insert and re-enables +# them by repair after the insert. +--disable_query_log +let $count= 100; +--echo # Insert $count rows. Query log disabled. +while ($count) +{ + INSERT INTO t1 VALUES ('a', 'b'); + dec $count; +} +--enable_query_log +# +# Change most of the rows into long character values with > 42 characters. +# Using Tamil Letter A, Unicode U+0B85 +UPDATE t1 SET c1=REPEAT(_utf8 x'e0ae85',43) LIMIT 90; +SELECT COUNT(*) FROM t1; +ALTER TABLE t1 ENGINE=MyISAM; +# +# With bug present, this shows that all long rows are gone. +SELECT COUNT(*) FROM t1; +CHECK TABLE t1; +CHECK TABLE t1 EXTENDED; +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/storage/myisam/mi_dynrec.c b/storage/myisam/mi_dynrec.c index 9940cf62204..22fa3d18802 100644 --- a/storage/myisam/mi_dynrec.c +++ b/storage/myisam/mi_dynrec.c @@ -1006,12 +1006,12 @@ uint _mi_rec_pack(MI_INFO *info, register uchar *to, { if (rec->length > 255 && new_length > 127) { - to[0]=(char) ((new_length & 127)+128); - to[1]=(char) (new_length >> 7); - to+=2; - } - else - *to++= (char) new_length; + to[0]= (uchar) ((new_length & 127) + 128); + to[1]= (uchar) (new_length >> 7); + to+=2; + } + else + *to++= (uchar) new_length; memcpy((uchar*) to,pos,(size_t) new_length); to+=new_length; flag|=bit; } @@ -1045,7 +1045,7 @@ uint _mi_rec_pack(MI_INFO *info, register uchar *to, } if ((bit= bit << 1) >= 256) { - *packpos++ = (char) (uchar) flag; + *packpos++= (uchar) flag; bit=1; flag=0; } } @@ -1055,9 +1055,9 @@ uint _mi_rec_pack(MI_INFO *info, register uchar *to, } } if (bit != 1) - *packpos= (char) (uchar) flag; + *packpos= (uchar) flag; if (info->s->calc_checksum) - *to++=(char) info->checksum; + *to++= (uchar) info->checksum; DBUG_PRINT("exit",("packed length: %d",(int) (to-startpos))); DBUG_RETURN((uint) (to-startpos)); } /* _mi_rec_pack */ @@ -1128,12 +1128,14 @@ my_bool _mi_rec_check(MI_INFO *info,const uchar *record, uchar *rec_buff, goto err; if (rec->length > 255 && new_length > 127) { - if (to[0] != (char) ((new_length & 127)+128) || - to[1] != (char) (new_length >> 7)) - goto err; - to+=2; - } - else if (*to++ != (char) new_length) + /* purecov: begin inspected */ + if (to[0] != (uchar) ((new_length & 127) + 128) || + to[1] != (uchar) (new_length >> 7)) + goto err; + to+=2; + /* purecov: end */ + } + else if (*to++ != (uchar) new_length) goto err; to+=new_length; } From 082cfb87919999efe83216d572ba6c776ecf748d Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 15 Jan 2008 16:23:14 +0400 Subject: [PATCH 06/12] BUG#28884 - maybe a problem with malloc into base64.c Fixed that return value of malloc was not checked. Fixed wrong argument count (compilation failure) to base64_decode() function. Note: - there is no test case for this fix as this code is never compiled into mysql clients/server; - as this code is used for internal testing purposes only, no changelog entry needed. mysys/base64.c: Fixed that return value of malloc was not checked. Fixed wrong argument count to base64_decode function. --- mysys/base64.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mysys/base64.c b/mysys/base64.c index dbe8927290d..6157dcaa5af 100644 --- a/mysys/base64.c +++ b/mysys/base64.c @@ -256,6 +256,7 @@ main(void) char * str; char * dst; + require(src); for (j= 0; j Date: Wed, 16 Jan 2008 11:48:04 +0100 Subject: [PATCH 07/12] Bug#32705 - myisam corruption: Key in wrong position at page 1024 with ucs2_bin Post-pushbuild fix. Moved test from myisam.test to ctype_ucs2_def.test. UCS2 is not always available. mysql-test/r/ctype_ucs2_def.result: Bug#32705 - myisam corruption: Key in wrong position at page 1024 with ucs2_bin Moved test result from myisam.result to here. mysql-test/r/myisam.result: Bug#32705 - myisam corruption: Key in wrong position at page 1024 with ucs2_bin Moved test result from here to ctype_ucs2_def.result. mysql-test/t/ctype_ucs2_def.test: Bug#32705 - myisam corruption: Key in wrong position at page 1024 with ucs2_bin Moved test from myisam.test to here. UCS2 is not always available. mysql-test/t/myisam.test: Bug#32705 - myisam corruption: Key in wrong position at page 1024 with ucs2_bin Moved test from here to ctype_ucs2_def.test. UCS2 is not always available. --- mysql-test/r/ctype_ucs2_def.result | 10 ++++++++++ mysql-test/r/myisam.result | 10 ---------- mysql-test/t/ctype_ucs2_def.test | 13 +++++++++++++ mysql-test/t/myisam.test | 13 ------------- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/mysql-test/r/ctype_ucs2_def.result b/mysql-test/r/ctype_ucs2_def.result index d838c5d66b0..1bbb354798b 100644 --- a/mysql-test/r/ctype_ucs2_def.result +++ b/mysql-test/r/ctype_ucs2_def.result @@ -21,4 +21,14 @@ INSERT INTO t1 VALUES('A', 'A'), ('B', 'B'), ('C', 'C'); INSERT INTO t1 VALUES('A ', 'A '); ERROR 23000: Duplicate entry '' for key 1 DROP TABLE t1; +CREATE TABLE t1 ( +c1 CHAR(255) CHARACTER SET UCS2 COLLATE UCS2_BIN NOT NULL, +KEY(c1) +) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('marshall\'s'); +INSERT INTO t1 VALUES ('marsh'); +CHECK TABLE t1 EXTENDED; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 4ff7441c02e..56933f45fbf 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -1839,14 +1839,4 @@ CHECK TABLE t1 EXTENDED; Table Op Msg_type Msg_text test.t1 check status OK DROP TABLE t1; -CREATE TABLE t1 ( -c1 CHAR(255) CHARACTER SET UCS2 COLLATE UCS2_BIN NOT NULL, -KEY(c1) -) ENGINE=MyISAM; -INSERT INTO t1 VALUES ('marshall\'s'); -INSERT INTO t1 VALUES ('marsh'); -CHECK TABLE t1 EXTENDED; -Table Op Msg_type Msg_text -test.t1 check status OK -DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/ctype_ucs2_def.test b/mysql-test/t/ctype_ucs2_def.test index c80444daddd..b146dc63626 100644 --- a/mysql-test/t/ctype_ucs2_def.test +++ b/mysql-test/t/ctype_ucs2_def.test @@ -39,4 +39,17 @@ INSERT INTO t1 VALUES('A', 'A'), ('B', 'B'), ('C', 'C'); INSERT INTO t1 VALUES('A ', 'A '); DROP TABLE t1; +# +# Bug#32705 - myisam corruption: Key in wrong position +# at page 1024 with ucs2_bin +# +CREATE TABLE t1 ( + c1 CHAR(255) CHARACTER SET UCS2 COLLATE UCS2_BIN NOT NULL, + KEY(c1) + ) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('marshall\'s'); +INSERT INTO t1 VALUES ('marsh'); +CHECK TABLE t1 EXTENDED; +DROP TABLE t1; + --echo End of 5.0 tests diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index b182c35514c..80c7a92c12f 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -1193,17 +1193,4 @@ SET @@myisam_repair_threads=1; CHECK TABLE t1 EXTENDED; DROP TABLE t1; -# -# Bug#32705 - myisam corruption: Key in wrong position -# at page 1024 with ucs2_bin -# -CREATE TABLE t1 ( - c1 CHAR(255) CHARACTER SET UCS2 COLLATE UCS2_BIN NOT NULL, - KEY(c1) - ) ENGINE=MyISAM; -INSERT INTO t1 VALUES ('marshall\'s'); -INSERT INTO t1 VALUES ('marsh'); -CHECK TABLE t1 EXTENDED; -DROP TABLE t1; - --echo End of 5.0 tests From dd40d4ea407e640d47b0f34fdb177b4d6ee4a175 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 16 Jan 2008 15:38:40 +0100 Subject: [PATCH 08/12] Bug#32705 - myisam corruption: Key in wrong position at page 1024 with ucs2_bin Post merge fix --- mysql-test/r/myisam.result | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 6863259aa9a..a18018657e0 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -1809,16 +1809,6 @@ CHECK TABLE t1 EXTENDED; Table Op Msg_type Msg_text test.t1 check status OK DROP TABLE t1; -CREATE TABLE t1 ( -c1 CHAR(255) CHARACTER SET UCS2 COLLATE UCS2_BIN NOT NULL, -KEY(c1) -) ENGINE=MyISAM; -INSERT INTO t1 VALUES ('marshall\'s'); -INSERT INTO t1 VALUES ('marsh'); -CHECK TABLE t1 EXTENDED; -Table Op Msg_type Msg_text -test.t1 check status OK -DROP TABLE t1; CREATE TABLE t1 (id int NOT NULL, ref int NOT NULL, INDEX (id)) ENGINE=MyISAM; CREATE TABLE t2 LIKE t1; INSERT INTO t2 (id, ref) VALUES (1,3), (2,1), (3,2), (4,5), (4,4); From 8f3a0ea2c8e791f0ee84c3e1dd7f09ef7daf0d48 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 17 Jan 2008 15:37:18 -0800 Subject: [PATCH 09/12] Bug#33067 "Update of CSV row incorrect for some BLOBs" when reading in rows, move blob columns into temporary storage not allocated by Field_blob class or else row update operation will alter original row and make mysql think that nothing has been changed. fix incrementing wrong statistic values. mysql-test/r/csv.result: test for bug33067 mysql-test/t/csv.test: test for bug33067 storage/csv/ha_tina.cc: bug33067 when reading in rows, move blob columns into temporary storage not allocated by Field_blob class or else row update operation will alter original row and make mysql think that nothing has been changed. fix incrementing wrong statistic values. storage/csv/ha_tina.h: bug33067 new memroot attribute for blobs --- mysql-test/r/csv.result | 9 ++++++++ mysql-test/t/csv.test | 11 ++++++++++ storage/csv/ha_tina.cc | 47 +++++++++++++++++++++++++++++++++++------ storage/csv/ha_tina.h | 1 + 4 files changed, 62 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/csv.result b/mysql-test/r/csv.result index b0033383f00..b91272f7e59 100644 --- a/mysql-test/r/csv.result +++ b/mysql-test/r/csv.result @@ -5379,4 +5379,13 @@ SHOW WARNINGS; Level Code Message Error 1178 The storage engine for the table doesn't support nullable columns Error 1005 Can't create table 'test.t1' (errno: 138) +create table t1 (c1 tinyblob not null) engine=csv; +insert into t1 values("This"); +update t1 set c1="That" where c1="This"; +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +select * from t1; +c1 +That +drop table t1; End of 5.1 tests diff --git a/mysql-test/t/csv.test b/mysql-test/t/csv.test index 7b4f95bbf8a..dd8c940ac44 100644 --- a/mysql-test/t/csv.test +++ b/mysql-test/t/csv.test @@ -1773,4 +1773,15 @@ drop table t1; CREATE TABLE t1(a INT) ENGINE=CSV; SHOW WARNINGS; +# +# BUG#33067 - . +# +create table t1 (c1 tinyblob not null) engine=csv; +insert into t1 values("This"); +--enable_info +update t1 set c1="That" where c1="This"; +--disable_info +select * from t1; +drop table t1; + --echo End of 5.1 tests diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc index c9fab79a4c5..f8dd778045f 100644 --- a/storage/csv/ha_tina.cc +++ b/storage/csv/ha_tina.cc @@ -56,6 +56,7 @@ TODO: #define META_BUFFER_SIZE sizeof(uchar) + sizeof(uchar) + sizeof(ulonglong) \ + sizeof(ulonglong) + sizeof(ulonglong) + sizeof(ulonglong) + sizeof(uchar) #define TINA_CHECK_HEADER 254 // The number we use to determine corruption +#define BLOB_MEMROOT_ALLOC_SIZE 8192 /* The file extension */ #define CSV_EXT ".CSV" // The data file @@ -597,6 +598,8 @@ int ha_tina::find_current_row(uchar *buf) bool read_all; DBUG_ENTER("ha_tina::find_current_row"); + free_root(&blobroot, MYF(MY_MARK_BLOCKS_FREE)); + /* We do not read further then local_saved_data_file_length in order not to conflict with undergoing concurrent insert. @@ -684,6 +687,22 @@ int ha_tina::find_current_row(uchar *buf) if ((*field)->store(buffer.ptr(), buffer.length(), buffer.charset(), CHECK_FIELD_WARN)) goto err; + if ((*field)->flags & BLOB_FLAG) + { + Field_blob *blob= *(Field_blob**) field; + uchar *src, *tgt; + uint length, packlength; + + packlength= blob->pack_length_no_ptr(); + length= blob->get_length(blob->ptr); + memcpy_fixed(&src, blob->ptr + packlength, sizeof(char*)); + if (src) + { + tgt= (uchar*) alloc_root(&blobroot, length); + bmove(tgt, src, length); + memcpy_fixed(blob->ptr + packlength, &tgt, sizeof(char*)); + } + } } } next_position= end_offset + eoln_len; @@ -914,9 +933,10 @@ int ha_tina::open_update_temp_file_if_needed() int ha_tina::update_row(const uchar * old_data, uchar * new_data) { int size; + int rc= -1; DBUG_ENTER("ha_tina::update_row"); - ha_statistic_increment(&SSV::ha_read_rnd_next_count); + ha_statistic_increment(&SSV::ha_update_count); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) table->timestamp_field->set_time(); @@ -931,20 +951,23 @@ int ha_tina::update_row(const uchar * old_data, uchar * new_data) The temp_file_length is used to calculate new data file length. */ if (chain_append()) - DBUG_RETURN(-1); + goto err; if (open_update_temp_file_if_needed()) - DBUG_RETURN(-1); + goto err; if (my_write(update_temp_file, (uchar*)buffer.ptr(), size, MYF(MY_WME | MY_NABP))) - DBUG_RETURN(-1); + goto err; temp_file_length+= size; + rc= 0; /* UPDATE should never happen on the log tables */ DBUG_ASSERT(!share->is_log_table); - DBUG_RETURN(0); +err: + DBUG_PRINT("info",("rc = %d", rc)); + DBUG_RETURN(rc); } @@ -1050,6 +1073,8 @@ int ha_tina::rnd_init(bool scan) records_is_known= 0; chain_ptr= chain; + init_alloc_root(&blobroot, BLOB_MEMROOT_ALLOC_SIZE, 0); + DBUG_RETURN(0); } @@ -1115,7 +1140,7 @@ void ha_tina::position(const uchar *record) int ha_tina::rnd_pos(uchar * buf, uchar *pos) { DBUG_ENTER("ha_tina::rnd_pos"); - ha_statistic_increment(&SSV::ha_read_rnd_next_count); + ha_statistic_increment(&SSV::ha_read_rnd_count); current_position= (off_t)my_get_ptr(pos,ref_length); DBUG_RETURN(find_current_row(buf)); } @@ -1179,6 +1204,7 @@ int ha_tina::rnd_end() off_t file_buffer_start= 0; DBUG_ENTER("ha_tina::rnd_end"); + free_root(&blobroot, MYF(0)); records_is_known= 1; if ((chain_ptr - chain) > 0) @@ -1350,6 +1376,8 @@ int ha_tina::repair(THD* thd, HA_CHECK_OPT* check_opt) /* set current position to the beginning of the file */ current_position= next_position= 0; + init_alloc_root(&blobroot, BLOB_MEMROOT_ALLOC_SIZE, 0); + /* Read the file row-by-row. If everything is ok, repair is not needed. */ while (!(rc= find_current_row(buf))) { @@ -1358,6 +1386,8 @@ int ha_tina::repair(THD* thd, HA_CHECK_OPT* check_opt) current_position= next_position; } + free_root(&blobroot, MYF(0)); + my_free((char*)buf, MYF(0)); if (rc == HA_ERR_END_OF_FILE) @@ -1535,6 +1565,9 @@ int ha_tina::check(THD* thd, HA_CHECK_OPT* check_opt) local_saved_data_file_length= share->saved_data_file_length; /* set current position to the beginning of the file */ current_position= next_position= 0; + + init_alloc_root(&blobroot, BLOB_MEMROOT_ALLOC_SIZE, 0); + /* Read the file row-by-row. If everything is ok, repair is not needed. */ while (!(rc= find_current_row(buf))) { @@ -1542,6 +1575,8 @@ int ha_tina::check(THD* thd, HA_CHECK_OPT* check_opt) count--; current_position= next_position; } + + free_root(&blobroot, MYF(0)); my_free((char*)buf, MYF(0)); thd_proc_info(thd, old_proc_info); diff --git a/storage/csv/ha_tina.h b/storage/csv/ha_tina.h index 5ce09783b9b..5b4381396fc 100644 --- a/storage/csv/ha_tina.h +++ b/storage/csv/ha_tina.h @@ -82,6 +82,7 @@ class ha_tina: public handler uint32 chain_size; uint local_data_file_version; /* Saved version of the data file used */ bool records_is_known; + MEM_ROOT blobroot; private: bool get_write_pos(off_t *end_pos, tina_set *closest_hole); From 1804046d78a4e4c8750aed1dfbffdd1f07fc7857 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 24 Jan 2008 18:56:42 +0100 Subject: [PATCH 10/12] Bug#29182 - MyISAMCHK reports wrong character set myisamchk did always show Character set: latin1_swedish_ci (8), regardless what DEFAULT CHARSET the table had. When the server created a MyISAM table, it did not copy the characterset number into the MyISAM create info structure. Added assignment of charset number to MI_CREATE_INFO. mysql-test/r/myisam.result: Bug#29182 - MyISAMCHK reports wrong character set Added test result. mysql-test/t/myisam.test: Bug#29182 - MyISAMCHK reports wrong character set Added test. storage/myisam/ha_myisam.cc: Bug#29182 - MyISAMCHK reports wrong character set Added assignment of charset number to MI_CREATE_INFO. --- mysql-test/r/myisam.result | 19 +++++++++++++++++++ mysql-test/t/myisam.test | 14 ++++++++++++++ storage/myisam/ha_myisam.cc | 1 + 3 files changed, 34 insertions(+) diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index a18018657e0..bf57b6e1006 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -2185,4 +2185,23 @@ CHECK TABLE t1 EXTENDED; Table Op Msg_type Msg_text test.t1 check status OK DROP TABLE t1; +CREATE TABLE t1 ( +c1 VARCHAR(10) NOT NULL, +c2 CHAR(10) DEFAULT NULL, +c3 VARCHAR(10) NOT NULL, +KEY (c1), +KEY (c2) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 PACK_KEYS=0; + +MyISAM file: MYSQLTEST_VARDIR/master-data/test/t1 +Record format: Packed +Character set: utf8_general_ci (33) +Data records: 0 Deleted blocks: 0 +Recordlength: 94 + +table description: +Key Start Len Index Type +1 2 30 multip. varchar +2 33 30 multip. char NULL +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index bb2c295eac2..21ffa0683b6 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -1448,5 +1448,19 @@ CHECK TABLE t1; CHECK TABLE t1 EXTENDED; DROP TABLE t1; +# +# Bug#29182 - MyISAMCHK reports wrong character set +# +CREATE TABLE t1 ( + c1 VARCHAR(10) NOT NULL, + c2 CHAR(10) DEFAULT NULL, + c3 VARCHAR(10) NOT NULL, + KEY (c1), + KEY (c2) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 PACK_KEYS=0; +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--exec $MYISAMCHK -d $MYSQLTEST_VARDIR/master-data/test/t1 +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 0b69f9d135f..09393d58d1a 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -1859,6 +1859,7 @@ int ha_myisam::create(const char *name, register TABLE *table_arg, share->avg_row_length); create_info.data_file_name= ha_create_info->data_file_name; create_info.index_file_name= ha_create_info->index_file_name; + create_info.language= share->table_charset->number; if (ha_create_info->options & HA_LEX_CREATE_TMP_TABLE) create_flags|= HA_CREATE_TMP_TABLE; From f1042103e619330f5b1fdd11faed7d07c79df49f Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 25 Jan 2008 16:05:15 -0800 Subject: [PATCH 11/12] Bug#33358 "Plugin enum variables can't be set from command line" fix crash of LOCK_plugins mutex when loading plug-ins from command line. fix off-by-one bug when loading multiple plug-ins from the command line. initialize command line handling for ENUM and SET plugin variable types. sql/sql_plugin.cc: Bug33358 fix crash of LOCK_plugins mutex when loading plug-ins from command line. fix off-by-one bug when loading multiple plug-ins from the command line. initialize command line handling for ENUM and SET plugin variable types. mysql-test/r/plugin_load.result: New BitKeeper file ``mysql-test/r/plugin_load.result'' mysql-test/t/plugin_load-master.opt: New BitKeeper file ``mysql-test/t/plugin_load-master.opt'' mysql-test/t/plugin_load.test: New BitKeeper file ``mysql-test/t/plugin_load.test'' --- mysql-test/r/plugin_load.result | 3 ++ mysql-test/t/plugin_load-master.opt | 3 ++ mysql-test/t/plugin_load.test | 3 ++ sql/sql_plugin.cc | 66 +++++++++++++++++++++-------- 4 files changed, 57 insertions(+), 18 deletions(-) create mode 100644 mysql-test/r/plugin_load.result create mode 100644 mysql-test/t/plugin_load-master.opt create mode 100644 mysql-test/t/plugin_load.test diff --git a/mysql-test/r/plugin_load.result b/mysql-test/r/plugin_load.result new file mode 100644 index 00000000000..33116cc20ab --- /dev/null +++ b/mysql-test/r/plugin_load.result @@ -0,0 +1,3 @@ +SELECT @@global.example_enum_var = 'e2'; +@@global.example_enum_var = 'e2' +1 diff --git a/mysql-test/t/plugin_load-master.opt b/mysql-test/t/plugin_load-master.opt new file mode 100644 index 00000000000..34186aab890 --- /dev/null +++ b/mysql-test/t/plugin_load-master.opt @@ -0,0 +1,3 @@ +$EXAMPLE_PLUGIN_OPT +"--plugin-load=;EXAMPLE=ha_example.so;" +--plugin-example-enum-var=e2 diff --git a/mysql-test/t/plugin_load.test b/mysql-test/t/plugin_load.test new file mode 100644 index 00000000000..8555247dd71 --- /dev/null +++ b/mysql-test/t/plugin_load.test @@ -0,0 +1,3 @@ +--source include/have_example_plugin.inc + +SELECT @@global.example_enum_var = 'e2'; diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 2a86844c8c6..8e204eb3d51 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1412,7 +1412,11 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv, while (list) { if (p == buffer + sizeof(buffer) - 1) - break; + { + sql_print_error("plugin-load parameter too long"); + DBUG_RETURN(TRUE); + } + switch ((*(p++)= *(list++))) { case '\0': list= NULL; /* terminate the loop */ @@ -1421,10 +1425,17 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv, case ':': /* can't use this as delimiter as it may be drive letter */ #endif case ';': - name.str[name.length]= '\0'; - if (str != &dl) // load all plugins in named module + str->str[str->length]= '\0'; + if (str == &name) // load all plugins in named module { + if (!name.length) + { + p--; /* reset pointer */ + continue; + } + dl= name; + pthread_mutex_lock(&LOCK_plugin); if ((plugin_dl= plugin_dl_add(&dl, REPORT_TO_LOG))) { for (plugin= plugin_dl->plugins; plugin->info; plugin++) @@ -1434,7 +1445,10 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv, free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE)); if (plugin_add(tmp_root, &name, &dl, argc, argv, REPORT_TO_LOG)) + { + pthread_mutex_unlock(&LOCK_plugin); goto error; + } } plugin_dl_del(&dl); // reduce ref count } @@ -1442,9 +1456,14 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv, else { free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE)); + pthread_mutex_lock(&LOCK_plugin); if (plugin_add(tmp_root, &name, &dl, argc, argv, REPORT_TO_LOG)) + { + pthread_mutex_unlock(&LOCK_plugin); goto error; + } } + pthread_mutex_unlock(&LOCK_plugin); name.length= dl.length= 0; dl.str= NULL; name.str= p= buffer; str= &name; @@ -1453,6 +1472,7 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv, case '#': if (str == &name) { + name.str[name.length]= '\0'; str= &dl; str->str= p; continue; @@ -2999,7 +3019,8 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp, DBUG_RETURN(-1); } - if (opt->flags & PLUGIN_VAR_NOCMDOPT) + if ((opt->flags & (PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_THDLOCAL)) + == PLUGIN_VAR_NOCMDOPT) continue; if (!opt->name) @@ -3009,7 +3030,7 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp, DBUG_RETURN(-1); } - if (!(v= find_bookmark(name, opt->name, opt->flags))) + if (!(opt->flags & PLUGIN_VAR_THDLOCAL)) { optnamelen= strlen(opt->name); optname= (char*) alloc_root(mem_root, namelen + optnamelen + 2); @@ -3017,7 +3038,23 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp, optnamelen= namelen + optnamelen + 1; } else - optname= (char*) memdup_root(mem_root, v->key + 1, (optnamelen= v->name_len) + 1); + { + /* this should not fail because register_var should create entry */ + if (!(v= find_bookmark(name, opt->name, opt->flags))) + { + sql_print_error("Thread local variable '%s' not allocated " + "in plugin '%s'.", opt->name, plugin_name); + DBUG_RETURN(-1); + } + + *(int*)(opt + 1)= offset= v->offset; + + if (opt->flags & PLUGIN_VAR_NOCMDOPT) + continue; + + optname= (char*) memdup_root(mem_root, v->key + 1, + (optnamelen= v->name_len) + 1); + } /* convert '_' to '-' */ for (p= optname; *p; p++) @@ -3029,20 +3066,13 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp, options->app_type= opt; options->id= (options-1)->id + 1; - if (opt->flags & PLUGIN_VAR_THDLOCAL) - *(int*)(opt + 1)= offset= v->offset; - plugin_opt_set_limits(options, opt); - if ((opt->flags & PLUGIN_VAR_TYPEMASK) != PLUGIN_VAR_ENUM && - (opt->flags & PLUGIN_VAR_TYPEMASK) != PLUGIN_VAR_SET) - { - if (opt->flags & PLUGIN_VAR_THDLOCAL) - options->value= options->u_max_value= (uchar**) - (global_system_variables.dynamic_variables_ptr + offset); - else - options->value= options->u_max_value= *(uchar***) (opt + 1); - } + if (opt->flags & PLUGIN_VAR_THDLOCAL) + options->value= options->u_max_value= (uchar**) + (global_system_variables.dynamic_variables_ptr + offset); + else + options->value= options->u_max_value= *(uchar***) (opt + 1); options[1]= options[0]; options[1].name= p= (char*) alloc_root(mem_root, optnamelen + 8); From 70884e09b8d10088da4598aaf0b8ebe04e6a97b8 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 26 Jan 2008 02:13:35 -0800 Subject: [PATCH 12/12] fixes to make pushbuild tests green mysql-test/t/plugin_load-master.opt: add '--loose' modifier to allow test to be skipped if plugin is not available. sql/sql_plugin.cc: Failure to load a plugin from command line option made non-fatal as plugin load failures from plugin table is already non-fatal. --- mysql-test/t/plugin_load-master.opt | 2 +- sql/sql_plugin.cc | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/mysql-test/t/plugin_load-master.opt b/mysql-test/t/plugin_load-master.opt index 34186aab890..66637841f16 100644 --- a/mysql-test/t/plugin_load-master.opt +++ b/mysql-test/t/plugin_load-master.opt @@ -1,3 +1,3 @@ $EXAMPLE_PLUGIN_OPT "--plugin-load=;EXAMPLE=ha_example.so;" ---plugin-example-enum-var=e2 +--loose-plugin-example-enum-var=e2 diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 8e204eb3d51..bae4a85fd8a 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1181,9 +1181,8 @@ int plugin_init(int *argc, char **argv, int flags) /* Register all dynamic plugins */ if (!(flags & PLUGIN_INIT_SKIP_DYNAMIC_LOADING)) { - if (opt_plugin_load && - plugin_load_list(&tmp_root, argc, argv, opt_plugin_load)) - goto err; + if (opt_plugin_load) + plugin_load_list(&tmp_root, argc, argv, opt_plugin_load); if (!(flags & PLUGIN_INIT_SKIP_PLUGIN_TABLE)) plugin_load(&tmp_root, argc, argv); }