From 9ecf3156794ea83ddf35dc19acce7f2288505567 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Mon, 10 Jan 2011 16:20:28 +0100 Subject: [PATCH 1/3] Bug#57924: crash when creating partitioned table with multiple columns in the partition key ndb crash if duplicate columns in the partitioning key. Backport from mysql-5.1-telco-7.0, see bug#53354. Changed from case sensitive field name comparision to non case sensitive too. --- mysql-test/r/partition_error.result | 13 +++++++++++++ mysql-test/suite/ndb/r/ndb_basic.result | 2 ++ mysql-test/suite/ndb/t/ndb_basic.test | 7 +++++++ mysql-test/t/partition_error.test | 14 ++++++++++++++ sql/sql_partition.cc | 22 ++++++++++++++++++++++ 5 files changed, 58 insertions(+) diff --git a/mysql-test/r/partition_error.result b/mysql-test/r/partition_error.result index ea74f476ceb..91eb18b3dad 100644 --- a/mysql-test/r/partition_error.result +++ b/mysql-test/r/partition_error.result @@ -1,5 +1,18 @@ drop table if exists t1; # +# Bug#57924: crash when creating partitioned table with +# multiple columns in the partition key +# +CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a,b)) +PARTITION BY KEY(a, b, a); +ERROR HY000: Field in list of fields for partition function not found in table +CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a,b)) +PARTITION BY KEY(A, b); +DROP TABLE t1; +CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a,b)) +PARTITION BY KEY(a, b, A); +ERROR HY000: Field in list of fields for partition function not found in table +# # Bug#49161: Out of memory; restart server and try again (needed 2 bytes) # CREATE TABLE t1 (a INT) PARTITION BY HASH (a); diff --git a/mysql-test/suite/ndb/r/ndb_basic.result b/mysql-test/suite/ndb/r/ndb_basic.result index 9f4f8c0755c..ee50352220e 100644 --- a/mysql-test/suite/ndb/r/ndb_basic.result +++ b/mysql-test/suite/ndb/r/ndb_basic.result @@ -585,6 +585,8 @@ c127 int, c128 int, primary key using hash(c1)) engine=ndb partition by key(c1); drop table t1; +create table `t1` (`a` int, b int, primary key (a,b)) engine=ndb partition by key(`a`,`b`,`a`); +ERROR HY000: Field in list of fields for partition function not found in table create table t1 ( a1234567890123456789012345678901234567890 int primary key, a12345678901234567890123456789a1234567890 int, diff --git a/mysql-test/suite/ndb/t/ndb_basic.test b/mysql-test/suite/ndb/t/ndb_basic.test index 2fc140288ca..5d6221d1784 100644 --- a/mysql-test/suite/ndb/t/ndb_basic.test +++ b/mysql-test/suite/ndb/t/ndb_basic.test @@ -547,6 +547,13 @@ c128 int, primary key using hash(c1)) engine=ndb partition by key(c1); drop table t1; +# +# test bug#53354 - crash when creating partitioned table with multiple columns in the partition key +# + +--error ER_FIELD_NOT_FOUND_PART_ERROR +create table `t1` (`a` int, b int, primary key (a,b)) engine=ndb partition by key(`a`,`b`,`a`); + # # test max size of attribute name and truncation # diff --git a/mysql-test/t/partition_error.test b/mysql-test/t/partition_error.test index d3f10628254..aa26fa29db9 100644 --- a/mysql-test/t/partition_error.test +++ b/mysql-test/t/partition_error.test @@ -10,6 +10,20 @@ drop table if exists t1; let $MYSQLD_DATADIR= `SELECT @@datadir`; +--echo # +--echo # Bug#57924: crash when creating partitioned table with +--echo # multiple columns in the partition key +--echo # +--error ER_FIELD_NOT_FOUND_PART_ERROR +CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a,b)) +PARTITION BY KEY(a, b, a); +CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a,b)) +PARTITION BY KEY(A, b); +DROP TABLE t1; +--error ER_FIELD_NOT_FOUND_PART_ERROR +CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a,b)) +PARTITION BY KEY(a, b, A); + --echo # --echo # Bug#49161: Out of memory; restart server and try again (needed 2 bytes) --echo # diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 44ed9e759c6..8cd43a4f60e 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -761,6 +761,9 @@ static bool handle_list_of_fields(List_iterator it, bool result; char *field_name; bool is_list_empty= TRUE; + int fields_handled = 0; + char* field_name_array[MAX_KEY]; + DBUG_ENTER("handle_list_of_fields"); while ((field_name= it++)) @@ -776,6 +779,25 @@ static bool handle_list_of_fields(List_iterator it, result= TRUE; goto end; } + + /* + Check for duplicate fields in the list. + Assuming that there are not many fields in the partition key list. + If there were, it would be better to replace the for-loop + with a more efficient algorithm. + */ + + field_name_array[fields_handled] = field_name; + for (int i = 0; i < fields_handled; ++i) + { + if (my_strcasecmp(system_charset_info, + field_name_array[i], field_name) == 0) + { + my_error(ER_FIELD_NOT_FOUND_PART_ERROR, MYF(0)); + DBUG_RETURN(TRUE); + } + } + fields_handled++; } if (is_list_empty) { From 3a0b067654aed03d078460e9e0f1bbd20d5b4457 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Mon, 10 Jan 2011 23:42:37 +0100 Subject: [PATCH 2/3] Bug#47902: partition_recover_myisam fails with --ps-protocol The problem was that the warnings was never written out when running with --ps-protocol. This was because the warnings only appeared during the prepare phase, not the execute phase. Solved by not clearing the warnings from the prepare phase if there was no other warnings. If there are warnings from the execute phase, it is very likely to be the same as from the prepare phase. My tests show that if not clearing the warnings from the prepare phase when there are warnings from the execute phase, there will be duplicated warnings in the result. --- client/mysqltest.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index a12c56c9657..cdfce036ec7 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -7241,8 +7241,12 @@ void run_query_stmt(MYSQL *mysql, struct st_command *command, mysql_free_result(res); /* Free normal result set with meta data */ - /* Clear prepare warnings */ - dynstr_set(&ds_prepare_warnings, NULL); + /* + Clear prepare warnings if there are execute warnings, + since they are probably duplicated. + */ + if (ds_execute_warnings.length || mysql->warning_count) + dynstr_set(&ds_prepare_warnings, NULL); } else { From 4eb7054598196f474bfef50318a483c20bc29b87 Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Wed, 26 Jan 2011 15:49:09 +0300 Subject: [PATCH 3/3] Bug #47811 : remove the non-default alignment specification. Fix backported from to 5.0. "Remove the alignment option, let valgrind use its default" --- mysql-test/mysql-test-run-shell.sh | 2 +- mysql-test/mysql-test-run.pl | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/mysql-test/mysql-test-run-shell.sh b/mysql-test/mysql-test-run-shell.sh index d919246f2e1..d4d31506f23 100644 --- a/mysql-test/mysql-test-run-shell.sh +++ b/mysql-test/mysql-test-run-shell.sh @@ -150,7 +150,7 @@ find_valgrind() fi # >=2.1.2 requires the --tool option, some versions write to stdout, some to stderr valgrind --help 2>&1 | grep "\-\-tool" > /dev/null && FIND_VALGRIND="$FIND_VALGRIND --tool=memcheck" - FIND_VALGRIND="$FIND_VALGRIND --alignment=8 --leak-check=yes --num-callers=16 --suppressions=$MYSQL_TEST_DIR/valgrind.supp" + FIND_VALGRIND="$FIND_VALGRIND --leak-check=yes --num-callers=16 --suppressions=$MYSQL_TEST_DIR/valgrind.supp" } # No paths below as we can't be sure where the program is! diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 2cfd689b0e7..f0100593516 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -5135,7 +5135,6 @@ sub valgrind_arguments { else { mtr_add_arg($args, "--tool=memcheck"); # From >= 2.1.2 needs this option - mtr_add_arg($args, "--alignment=8"); mtr_add_arg($args, "--leak-check=yes"); mtr_add_arg($args, "--num-callers=16"); mtr_add_arg($args, "--suppressions=%s/valgrind.supp", $glob_mysql_test_dir)