From: Dmitry Lenev Date: November 19 2010 8:19am Subject: bzr push into mysql-5.5-runtime branch (Dmitry.Lenev:3195) List-Archive: http://lists.mysql.com/commits/124369 Message-Id: <20101119081951.D2546E593C@mockturtle> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 3195 Dmitry Lenev 2010-11-19 [merge] Merged recent change from mysql-5.5-bugteam into mysql-5.5-runtime tree. modified: mysql-test/r/show_check.result mysql-test/t/show_check.test === modified file '.bzr-mysql/default.conf' --- a/.bzr-mysql/default.conf 2010-11-18 15:01:58 +0000 +++ b/.bzr-mysql/default.conf 2010-11-18 16:52:53 +0000 @@ -1,4 +1,4 @@ [MYSQL] post_commit_to = "commits@stripped" post_push_to = "commits@stripped" -tree_name = "mysql-5.5-bugteam" +tree_name = "mysql-5.5-runtime" === modified file 'mysql-test/r/partition_innodb.result' --- a/mysql-test/r/partition_innodb.result 2010-09-13 13:56:56 +0000 +++ b/mysql-test/r/partition_innodb.result 2010-11-19 07:26:09 +0000 @@ -489,3 +489,31 @@ Warning 1265 Data truncated for column ' Error 1067 Invalid default value for 'b' SET SESSION sql_mode = @old_mode; DROP TABLE t1; +# +# Bug#57985 "ONLINE/FAST ALTER PARTITION can fail and leave the +# table unusable". +# +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (a bigint not null, b int not null, PRIMARY KEY (a)) +ENGINE = InnoDB PARTITION BY KEY(a) PARTITIONS 2; +INSERT INTO t1 values (0,1), (1,2); +# The below ALTER should fail. It should leave the +# table in its original, non-corrupted, usable state. +ALTER TABLE t1 ADD UNIQUE KEY (b); +ERROR HY000: A UNIQUE INDEX must include all columns in the table's partitioning function +# The below statements should succeed, as ALTER should +# have left table intact. +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` bigint(20) NOT NULL, + `b` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY KEY (a) +PARTITIONS 2 */ +SELECT * FROM t1; +a b +1 2 +0 1 +DROP TABLE t1; === modified file 'mysql-test/t/partition_innodb.test' --- a/mysql-test/t/partition_innodb.test 2010-08-20 17:15:48 +0000 +++ b/mysql-test/t/partition_innodb.test 2010-11-19 07:26:09 +0000 @@ -569,3 +569,24 @@ SET SESSION sql_mode = 'NO_ZERO_DATE'; OPTIMIZE TABLE t1; SET SESSION sql_mode = @old_mode; DROP TABLE t1; + + +--echo # +--echo # Bug#57985 "ONLINE/FAST ALTER PARTITION can fail and leave the +--echo # table unusable". +--echo # +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings +CREATE TABLE t1 (a bigint not null, b int not null, PRIMARY KEY (a)) + ENGINE = InnoDB PARTITION BY KEY(a) PARTITIONS 2; +INSERT INTO t1 values (0,1), (1,2); +--echo # The below ALTER should fail. It should leave the +--echo # table in its original, non-corrupted, usable state. +--error ER_UNIQUE_KEY_NEED_ALL_FIELDS_IN_PF +ALTER TABLE t1 ADD UNIQUE KEY (b); +--echo # The below statements should succeed, as ALTER should +--echo # have left table intact. +SHOW CREATE TABLE t1; +SELECT * FROM t1; +DROP TABLE t1; === modified file 'sql/event_queue.cc' --- a/sql/event_queue.cc 2010-11-11 17:11:05 +0000 +++ b/sql/event_queue.cc 2010-11-19 07:41:09 +0000 @@ -568,8 +568,8 @@ Event_queue::get_top_for_execution_if_ti { bool ret= FALSE; *event_name= NULL; - my_time_t last_executed; - int status; + my_time_t UNINIT_VAR(last_executed); + int UNINIT_VAR(status); DBUG_ENTER("Event_queue::get_top_for_execution_if_time"); LOCK_QUEUE_DATA(); === modified file 'sql/sql_table.cc' --- a/sql/sql_table.cc 2010-11-16 10:00:12 +0000 +++ b/sql/sql_table.cc 2010-11-19 07:26:09 +0000 @@ -3815,6 +3815,46 @@ void sp_prepare_create_field(THD *thd, C (void) prepare_blob_field(thd, sql_field); } + +/** + Auxiliary function which allows to check if freshly created .FRM + file for table can be opened. + + @retval FALSE - Success. + @retval TRUE - Failure. +*/ + +static bool check_if_created_table_can_be_opened(THD *thd, + const char *path, + const char *db, + const char *table_name, + HA_CREATE_INFO *create_info, + handler *file) +{ + TABLE table; + TABLE_SHARE share; + bool result; + + /* + It is impossible to open definition of partitioned table without .par file. + */ + if (file->ha_create_handler_files(path, NULL, CHF_CREATE_FLAG, create_info)) + return TRUE; + + init_tmp_table_share(thd, &share, db, 0, table_name, path); + + result= (open_table_def(thd, &share, 0) || + open_table_from_share(thd, &share, "", 0, (uint) READ_ALL, + 0, &table, TRUE)); + if (! result) + (void) closefrm(&table, 0); + + free_table_share(&share); + (void) file->ha_create_handler_files(path, NULL, CHF_DELETE_FLAG, create_info); + return result; +} + + /* Create a table @@ -4241,6 +4281,29 @@ bool mysql_create_table_no_lock(THD *thd thd->thread_specific_used= TRUE; } +#ifdef WITH_PARTITION_STORAGE_ENGINE + else if (part_info && create_info->frm_only) + { + /* + For partitioned tables we can't find some problems with table + until table is opened. Therefore in order to disallow creation + of corrupted tables we have to try to open table as the part + of its creation process. + In cases when both .FRM and SE part of table are created table + is implicitly open in ha_create_table() call. + In cases when we create .FRM without SE part we have to open + table explicitly. + */ + if (check_if_created_table_can_be_opened(thd, path, db, table_name, + create_info, file)) + { + char frm_name[FN_REFLEN]; + strxmov(frm_name, path, reg_ext, NullS); + (void) mysql_file_delete(key_file_frm, frm_name, MYF(0)); + goto err; + } + } +#endif error= FALSE; err: No bundle (reason: useless for push emails).