From a58331b1613ee0e025c41002df0c27a73756b519 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Fri, 11 Dec 2009 18:41:31 +0100 Subject: [PATCH] Bug#49477: Assertion `0' failed in ha_partition.cc:5530 with temporary table and partitions It was possible to create temporary partitioned tables via create table ... like ... (which is not allowed with create temporary table). This lead to a new HA_EXTRA flag (HA_EXTRA_MMAP) was sent to the partitioning handler, which was caught on an assert in debug builds. Solution was to check for partitioned tables when doing create table ... like ... and disallow it. --- mysql-test/r/partition_error.result | 8 ++++++++ mysql-test/t/partition_error.test | 9 +++++++++ sql/sql_table.cc | 20 +++++++++++++------- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/partition_error.result b/mysql-test/r/partition_error.result index 511806d64bd..5b7030d33fe 100644 --- a/mysql-test/r/partition_error.result +++ b/mysql-test/r/partition_error.result @@ -1,4 +1,12 @@ drop table if exists t1; +# +# Bug#49477: Assertion `0' failed in ha_partition.cc:5530 +# with temporary table and partitions +# +CREATE TABLE t1 (a INT) PARTITION BY HASH(a); +CREATE TEMPORARY TABLE tmp_t1 LIKE t1; +ERROR HY000: Cannot create temporary table with partitions +DROP TABLE t1; CREATE TABLE t1 (a INTEGER NOT NULL, PRIMARY KEY (a)); INSERT INTO t1 VALUES (1),(1); ERROR 23000: Duplicate entry '1' for key 'PRIMARY' diff --git a/mysql-test/t/partition_error.test b/mysql-test/t/partition_error.test index 49632f95dfb..5f824fefc93 100644 --- a/mysql-test/t/partition_error.test +++ b/mysql-test/t/partition_error.test @@ -8,6 +8,15 @@ drop table if exists t1; --enable_warnings +--echo # +--echo # Bug#49477: Assertion `0' failed in ha_partition.cc:5530 +--echo # with temporary table and partitions +--echo # +CREATE TABLE t1 (a INT) PARTITION BY HASH(a); +--error ER_PARTITION_NO_TEMPORARY +CREATE TEMPORARY TABLE tmp_t1 LIKE t1; +DROP TABLE t1; + # # Bug#38719: Partitioning returns a different error code for a # duplicate key error diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 869ae42c98c..6e0daefb7c1 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -5257,6 +5257,11 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, */ if (create_info->options & HA_LEX_CREATE_TMP_TABLE) { + if (src_table->table->file->ht == partition_hton) + { + my_error(ER_PARTITION_NO_TEMPORARY, MYF(0)); + goto err; + } if (find_temporary_table(thd, db, table_name)) goto table_exists; dst_path_length= build_tmptable_filename(thd, dst_path, sizeof(dst_path)); @@ -5321,14 +5326,15 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, /* For partitioned tables we need to copy the .par file as well since it is used in open_table_def to even be able to create a new handler. - There is no way to find out here if the original table is a - partitioned table so we copy the file and ignore any errors. */ - fn_format(tmp_path, dst_path, reg_ext, ".par", MYF(MY_REPLACE_EXT)); - strmov(dst_path, tmp_path); - fn_format(tmp_path, src_path, reg_ext, ".par", MYF(MY_REPLACE_EXT)); - strmov(src_path, tmp_path); - my_copy(src_path, dst_path, MYF(MY_DONT_OVERWRITE_FILE)); + if (src_table->table->file->ht == partition_hton) + { + fn_format(tmp_path, dst_path, reg_ext, ".par", MYF(MY_REPLACE_EXT)); + strmov(dst_path, tmp_path); + fn_format(tmp_path, src_path, reg_ext, ".par", MYF(MY_REPLACE_EXT)); + strmov(src_path, tmp_path); + my_copy(src_path, dst_path, MYF(MY_DONT_OVERWRITE_FILE)); + } #endif DBUG_EXECUTE_IF("sleep_create_like_before_ha_create", my_sleep(6000000););