From f081188fcba9f0f6828a74e16eb4a58075ab9779 Mon Sep 17 00:00:00 2001 From: "gkodinov/kgeorge@macbook.gmz" <> Date: Mon, 4 Jun 2007 18:56:29 +0300 Subject: [PATCH] Bug #28488: Incorrect information in file: './test/t1_test#.frm' While executing ALTER TABLE ... PARTITION the server uses a temporary "shadow" table to create the updated table. This shadow table then gets renamed as the original table. The shadow table was not prefixed with the special prefix that marks temporary tables so it was picked up by SHOW TABLE STATUS. Fixed by isolating the code to create the shadow table name in a separate function and prefixing the shadow table name with the special prefix to exclude it from the list of user tables. See bug 18775 and WL1324 for details. --- mysql-test/r/partition.result | 10 ++++++++++ mysql-test/t/partition.test | 17 +++++++++++++++++ sql/mysql_priv.h | 2 ++ sql/sql_partition.cc | 9 +++------ sql/sql_table.cc | 28 ++++++++++++++++++++++++++-- 5 files changed, 58 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index de477310fe3..af90ac6c714 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -1235,4 +1235,14 @@ aaa 2 drop table t1; create table t1 (s1 bigint) partition by list (s1) (partition p1 values in (-9223372036854775808)); drop table t1; +CREATE TABLE t1(a INT NOT NULL, b TINYBLOB, KEY(a)) +PARTITION BY RANGE(a) ( PARTITION p0 VALUES LESS THAN (32)); +INSERT INTO t1 VALUES (1, REPEAT('a', 10)); +INSERT INTO t1 SELECT a + 1, b FROM t1; +INSERT INTO t1 SELECT a + 2, b FROM t1; +INSERT INTO t1 SELECT a + 4, b FROM t1; +INSERT INTO t1 SELECT a + 8, b FROM t1; +ALTER TABLE t1 ADD PARTITION (PARTITION p1 VALUES LESS THAN (64)); +ALTER TABLE t1 DROP PARTITION p1; +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index 68c13c0792a..186cf1d3e8a 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -1448,4 +1448,21 @@ drop table t1; create table t1 (s1 bigint) partition by list (s1) (partition p1 values in (-9223372036854775808)); drop table t1; +# +# Bug #28488: Incorrect information in file: './test/t1_test#.frm' +# + +CREATE TABLE t1(a INT NOT NULL, b TINYBLOB, KEY(a)) + PARTITION BY RANGE(a) ( PARTITION p0 VALUES LESS THAN (32)); +INSERT INTO t1 VALUES (1, REPEAT('a', 10)); +INSERT INTO t1 SELECT a + 1, b FROM t1; +INSERT INTO t1 SELECT a + 2, b FROM t1; +INSERT INTO t1 SELECT a + 4, b FROM t1; +INSERT INTO t1 SELECT a + 8, b FROM t1; + +ALTER TABLE t1 ADD PARTITION (PARTITION p1 VALUES LESS THAN (64)); +ALTER TABLE t1 DROP PARTITION p1; + +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 71b8cc6d361..8cad35cc693 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1934,6 +1934,8 @@ uint filename_to_tablename(const char *from, char *to, uint to_length); uint tablename_to_filename(const char *from, char *to, uint to_length); uint build_table_filename(char *buff, size_t bufflen, const char *db, const char *table, const char *ext, uint flags); +uint build_table_shadow_filename(char *buff, size_t bufflen, + ALTER_PARTITION_PARAM_TYPE *lpt); /* Flags for conversion functions. */ #define FN_FROM_IS_TMP (1 << 0) #define FN_TO_IS_TMP (1 << 1) diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 2c5fe91681e..a5d26fa700f 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -5488,8 +5488,7 @@ static bool write_log_drop_shadow_frm(ALTER_PARTITION_PARAM_TYPE *lpt) char shadow_path[FN_LEN]; DBUG_ENTER("write_log_drop_shadow_frm"); - build_table_filename(shadow_path, sizeof(shadow_path), lpt->db, - lpt->table_name, "#", 0); + build_table_shadow_filename(shadow_path, sizeof(shadow_path), lpt); pthread_mutex_lock(&LOCK_gdl); if (write_log_replace_delete_frm(lpt, 0UL, NULL, (const char*)shadow_path, FALSE)) @@ -5537,8 +5536,7 @@ static bool write_log_rename_frm(ALTER_PARTITION_PARAM_TYPE *lpt) part_info->first_log_entry= NULL; build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, "", 0); - build_table_filename(shadow_path, sizeof(shadow_path), lpt->db, - lpt->table_name, "#", 0); + build_table_shadow_filename(shadow_path, sizeof(shadow_path), lpt); pthread_mutex_lock(&LOCK_gdl); if (write_log_replace_delete_frm(lpt, 0UL, shadow_path, path, TRUE)) goto error; @@ -5703,8 +5701,7 @@ static bool write_log_final_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt) part_info->first_log_entry= NULL; build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, "", 0); - build_table_filename(shadow_path, sizeof(shadow_path), lpt->db, - lpt->table_name, "#", 0); + build_table_shadow_filename(shadow_path, sizeof(shadow_path), lpt); pthread_mutex_lock(&LOCK_gdl); if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path, lpt->alter_info->flags & ALTER_REORGANIZE_PARTITION)) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 6d5860240be..007315ce5f9 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1262,6 +1262,31 @@ void release_ddl_log() */ +/** + @brief construct a temporary shadow file name. + + @details Make a shadow file name used by ALTER TABLE to construct the + modified table (with keeping the original). The modified table is then + moved back as original table. The name must start with the temp file + prefix so it gets filtered out by table files listing routines. + + @param[out] buff buffer to receive the constructed name + @param bufflen size of buff + @param lpt alter table data structure + + @retval path length +*/ + +uint build_table_shadow_filename(char *buff, size_t bufflen, + ALTER_PARTITION_PARAM_TYPE *lpt) +{ + char tmp_name[FN_REFLEN]; + my_snprintf (tmp_name, sizeof (tmp_name), "%s-%s", tmp_file_prefix, + lpt->table_name); + return build_table_filename(buff, bufflen, lpt->db, tmp_name, "", FN_IS_TMP); +} + + /* SYNOPSIS mysql_write_frm() @@ -1302,8 +1327,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) /* Build shadow frm file name */ - build_table_filename(shadow_path, sizeof(shadow_path), lpt->db, - lpt->table_name, "#", 0); + build_table_shadow_filename(shadow_path, sizeof(shadow_path), lpt); strxmov(shadow_frm_name, shadow_path, reg_ext, NullS); if (flags & WFRM_WRITE_SHADOW) {