diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index 753a2e31632..15335a59421 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -1,4 +1,20 @@ drop table if exists t1; +CREATE TABLE t1 ( +d DATE NOT NULL +) +PARTITION BY RANGE( YEAR(d) ) ( +PARTITION p0 VALUES LESS THAN (1960), +PARTITION p1 VALUES LESS THAN (1970), +PARTITION p2 VALUES LESS THAN (1980), +PARTITION p3 VALUES LESS THAN (1990) +); +ALTER TABLE t1 ADD PARTITION ( +PARTITION `p5` VALUES LESS THAN (2010) +COMMENT 'APSTART \' APEND' +); +SELECT * FROM t1 LIMIT 1; +d +DROP TABLE t1; create table t1 (id int auto_increment, s1 int, primary key (id)); insert into t1 values (null,1); insert into t1 values (null,6); diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index 929d3ecce9e..e96b966ae56 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -9,6 +9,32 @@ drop table if exists t1; --enable_warnings +# +# Bug #30695: An apostrophe ' in the comment of the ADD PARTITION causes the Server to crash. +# +# To verify the fix for crashing (on unix-type OS) +# uncomment the exec and error rows! + +CREATE TABLE t1 ( + d DATE NOT NULL +) +PARTITION BY RANGE( YEAR(d) ) ( + PARTITION p0 VALUES LESS THAN (1960), + PARTITION p1 VALUES LESS THAN (1970), + PARTITION p2 VALUES LESS THAN (1980), + PARTITION p3 VALUES LESS THAN (1990) +); + +ALTER TABLE t1 ADD PARTITION ( +PARTITION `p5` VALUES LESS THAN (2010) +COMMENT 'APSTART \' APEND' +); +#--exec sed 's/APSTART \\/APSTART /' var/master-data/test/t1.frm > tmpt1.frm && mv tmpt1.frm var/master-data/test/t1.frm +#--error 1064 +SELECT * FROM t1 LIMIT 1; + +DROP TABLE t1; + # # Bug 30878: crashing when alter an auto_increment non partitioned # table to partitioned diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 8a8a03cb4e4..3ad2cbfb284 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -1849,6 +1849,20 @@ static int add_uint(File fptr, ulonglong number) return add_string(fptr, buff); } +/* + Must escape strings in partitioned tables frm-files, + parsing it later with mysql_unpack_partition will fail otherwise. +*/ +static int add_quoted_string(File fptr, const char *quotestr) +{ + String orgstr(quotestr, system_charset_info); + String escapedstr; + int err= add_string(fptr, "'"); + err+= append_escaped(&escapedstr, &orgstr); + err+= add_string(fptr, escapedstr.c_ptr()); + return err + add_string(fptr, "'"); +} + static int add_keyword_string(File fptr, const char *keyword, bool should_use_quotes, const char *keystr) @@ -1859,10 +1873,9 @@ static int add_keyword_string(File fptr, const char *keyword, err+= add_equal(fptr); err+= add_space(fptr); if (should_use_quotes) - err+= add_string(fptr, "'"); - err+= add_string(fptr, keystr); - if (should_use_quotes) - err+= add_string(fptr, "'"); + err+= add_quoted_string(fptr, keystr); + else + err+= add_string(fptr, keystr); return err + add_space(fptr); } diff --git a/sql/table.cc b/sql/table.cc index ccddbf8134b..7cf5eeaaad6 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1782,7 +1782,8 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, outparam, is_create_table, share->default_part_db_type, &work_part_info_used); - outparam->part_info->is_auto_partitioned= share->auto_partitioned; + if (!tmp) + outparam->part_info->is_auto_partitioned= share->auto_partitioned; DBUG_PRINT("info", ("autopartitioned: %u", share->auto_partitioned)); /* we should perform the fix_partition_func in either local or caller's arena depending on work_part_info_used value