From 970aa54bd68ea425923248295be8d52f1f52b039 Mon Sep 17 00:00:00 2001 From: "jimw@mysql.com" <> Date: Wed, 1 Feb 2006 12:28:39 -0800 Subject: [PATCH 1/8] Fix mysqldump crash when encountering a VIEW (when used against a 5.0 or later server, obviously). (Bug #16389) --- client/mysqldump.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 7ff9504607f..64629bcf608 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -2557,8 +2557,11 @@ static const char *check_if_ignore_table(const char *table_name) mysql_free_result(res); return 0; /* assume table is ok */ } - if (strcmp(row[1], (result= "MRG_MyISAM")) && - strcmp(row[1], (result= "MRG_ISAM"))) + /* Some forward-compatibility: don't dump data from a VIEW */ + if (!row[1]) + result= "VIEW"; + else if (strcmp(row[1], (result= "MRG_MyISAM")) && + strcmp(row[1], (result= "MRG_ISAM"))) result= 0; mysql_free_result(res); return result; From 4217699e56828f5a7af66f188bcc59ed6919623d Mon Sep 17 00:00:00 2001 From: "msvensson@neptunus.(none)" <> Date: Fri, 10 Feb 2006 12:11:16 +0100 Subject: [PATCH 2/8] Bug#17280 mysqltest, --echo sometimes does not expand $variables - Evaluate all variables in the text before printing it to result file --- client/mysqltest.c | 28 +++++++++++++++------------- mysql-test/r/mysqltest.result | 19 +++++++++++++++++-- mysql-test/t/mysqltest.test | 13 +++++++++++++ 3 files changed, 45 insertions(+), 15 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 6a2a7b072de..8c712541fb5 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -1384,38 +1384,40 @@ int do_system(struct st_query *q) /* Print the content between echo and to result file. - If content is a variable, the variable value will be retrieved + Evaluate all variables in the string before printing, allow + for variable names to be escaped using \ SYNOPSIS do_echo() q called command DESCRIPTION - Usage 1: echo text Print the text after echo until end of command to result file - Usage 2: echo $ Print the content of the variable to result file + echo Some text $ + Print "Some text" plus the content of the variable to + result file + + echo Some text \$ + Print "Some text" plus $ to result file */ -int do_echo(struct st_query *q) +int do_echo(struct st_query *command) { - char *p= q->first_argument; - DYNAMIC_STRING *ds; - VAR v; - var_init(&v,0,0,0,0); + DYNAMIC_STRING *ds, ds_echo; ds= &ds_res; - eval_expr(&v, p, 0); /* NULL terminated */ - if (v.str_val_len) - dynstr_append_mem(ds, v.str_val, v.str_val_len); + init_dynamic_string(&ds_echo, "", 256, 256); + do_eval(&ds_echo, command->first_argument); + dynstr_append_mem(ds, ds_echo.str, ds_echo.length); dynstr_append_mem(ds, "\n", 1); - var_free(&v); - q->last_argument= q->end; + dynstr_free(&ds_echo); + command->last_argument= command->end; return 0; } diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index 067054510c2..53141a8d266 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -201,8 +201,14 @@ source database - world''s most -- popular open # source database -'$message' -"$message" +'# MySQL: The +- world''s most +-- popular open +# source database' +"# MySQL: The +- world''s most +-- popular open +# source database" hej hej hej @@ -222,6 +228,15 @@ mysqltest: At line 1: Missing arguments to let mysqltest: At line 1: Missing variable name in let mysqltest: At line 1: Variable name in =hi does not start with '$' mysqltest: At line 1: Missing assignment operator in let +# Execute: --echo # success: $success +# success: 1 +# Execute: echo # success: $success ; +# success: 1 +# The next two variants work fine and expand the content of $success +# Execute: --echo $success +1 +# Execute: echo $success ; +1 mysqltest: At line 1: Missing file name in source mysqltest: At line 1: Could not open file ./non_existingFile mysqltest: In included file "./var/tmp/recursive.sql": At line 1: Source directives are nesting too deep diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index 5cf49185c30..caedbfab4a6 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -539,6 +539,19 @@ echo $novar1; --error 1 --exec echo "let hi;" | $MYSQL_TEST 2>&1 +# More advanced test for bug#17280 +let $success= 1; +--echo # Execute: --echo # success: \$success +--echo # success: $success +--echo # Execute: echo # success: \$success ; +echo # success: $success ; + +--echo # The next two variants work fine and expand the content of \$success +--echo # Execute: --echo \$success +--echo $success +--echo # Execute: echo \$success ; +echo $success ; + # ---------------------------------------------------------------------------- # Test to assign let from query # let $=``; From 5000951ab48b3f995e5eb6e65a50820cc9ebd0c0 Mon Sep 17 00:00:00 2001 From: "msvensson@neptunus.(none)" <> Date: Fri, 10 Feb 2006 14:50:29 +0100 Subject: [PATCH 3/8] Bug#14013 mysql_stmt_store_result() bombs if a cursor is open - Add code to 'mysql_stmt_store_result' to allow it to be called on a prepared statement with open server side cursor. - Add tests to mysql_client_test that uses 'mysql_stmt_store_result' --- client/mysqltest.c | 40 ++++++++++++++++++++++----------------- libmysql/libmysql.c | 35 ++++++++++++++++++++++++++++++++-- tests/mysql_client_test.c | 20 +++++++++++++++++--- 3 files changed, 73 insertions(+), 22 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 24be5de8021..3851a922e13 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -3167,7 +3167,7 @@ static void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt, if (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA) die("fetch didn't end with MYSQL_NO_DATA from statement: %d %s", - mysql_stmt_error(stmt), mysql_stmt_errno(stmt)); + mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); free_replace_column(); @@ -3632,7 +3632,7 @@ static void run_query_stmt(MYSQL *mysql, struct st_query *command, if (mysql_stmt_prepare(stmt, query, query_len)) { handle_error(query, command, mysql_stmt_errno(stmt), - mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds); + mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds); goto end; } @@ -3648,29 +3648,34 @@ static void run_query_stmt(MYSQL *mysql, struct st_query *command, parameter markers. */ -#ifdef BUG14013_FIXED - /* - Use cursor when retrieving result - */ if (cursor_protocol_enabled) { + /* + Use cursor when retrieving result + */ ulong type= CURSOR_TYPE_READ_ONLY; if (mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type)) die("mysql_stmt_attr_set(STMT_ATTR_CURSOR_TYPE) failed': %d %s", - mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); + mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); } -#endif /* Execute the query - */ + */ if (mysql_stmt_execute(stmt)) { handle_error(query, command, mysql_stmt_errno(stmt), - mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds); + mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds); goto end; } + /* + When running in cursor_protocol get the warnings from execute here + and keep them in a separate string for later. + */ + if (cursor_protocol_enabled && !disable_warnings) + append_warnings(&ds_execute_warnings, mysql); + /* We instruct that we want to update the "max_length" field in mysql_stmt_store_result(), this is our only way to know how much @@ -3680,7 +3685,7 @@ static void run_query_stmt(MYSQL *mysql, struct st_query *command, my_bool one= 1; if (mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &one)) die("mysql_stmt_attr_set(STMT_ATTR_UPDATE_MAX_LENGTH) failed': %d %s", - mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); + mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); } /* @@ -3690,7 +3695,7 @@ static void run_query_stmt(MYSQL *mysql, struct st_query *command, if (mysql_stmt_store_result(stmt)) { handle_error(query, command, mysql_stmt_errno(stmt), - mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds); + mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds); goto end; } @@ -3711,10 +3716,10 @@ static void run_query_stmt(MYSQL *mysql, struct st_query *command, uint num_fields= mysql_num_fields(res); if (display_metadata) - append_metadata(ds, fields, num_fields); + append_metadata(ds, fields, num_fields); if (!display_result_vertically) - append_table_headings(ds, fields, num_fields); + append_table_headings(ds, fields, num_fields); append_stmt_result(ds, stmt, fields, num_fields); @@ -3736,10 +3741,11 @@ static void run_query_stmt(MYSQL *mysql, struct st_query *command, /* Append warnings to ds - if there are any */ if (append_warnings(&ds_execute_warnings, mysql) || - ds_prepare_warnings.length || - ds_warnings->length) + ds_execute_warnings.length || + ds_prepare_warnings.length || + ds_warnings->length) { - dynstr_append_mem(ds, "Warnings:\n", 10); + dynstr_append_mem(ds, "Warnings:\n", 10); if (ds_warnings->length) dynstr_append_mem(ds, ds_warnings->str, ds_warnings->length); diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 11ee7284cbf..30eecf809c5 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -4757,12 +4757,39 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt) if (!stmt->field_count) DBUG_RETURN(0); - if ((int) stmt->state < (int) MYSQL_STMT_EXECUTE_DONE || - mysql->status != MYSQL_STATUS_GET_RESULT) + + if ((int) stmt->state < (int) MYSQL_STMT_EXECUTE_DONE) { set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate); DBUG_RETURN(1); } + + if (mysql->status == MYSQL_STATUS_READY && + stmt->server_status & SERVER_STATUS_CURSOR_EXISTS) + { + /* + Server side cursor exist, tell server to start sending the rows + */ + NET *net= &mysql->net; + char buff[4 /* statement id */ + + 4 /* number of rows to fetch */]; + + /* Send row request to the server */ + int4store(buff, stmt->stmt_id); + int4store(buff + 4, (int)~0); /* number of rows to fetch */ + if (cli_advanced_command(mysql, COM_STMT_FETCH, buff, sizeof(buff), + NullS, 0, 1)) + { + set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate); + DBUG_RETURN(1); + } + } + else if (mysql->status != MYSQL_STATUS_GET_RESULT) + { + set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate); + DBUG_RETURN(1); + } + if (result->data) { free_root(&result->alloc, MYF(MY_KEEP_PREALLOC)); @@ -4803,6 +4830,10 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt) DBUG_RETURN(1); } + /* Assert that if there was a cursor, all rows have been fetched */ + DBUG_ASSERT(mysql->status != MYSQL_STATUS_READY || + (mysql->server_status & SERVER_STATUS_LAST_ROW_SENT)); + if (stmt->update_max_length) { MYSQL_ROWS *cur= result->data; diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 216961b3a80..25729e9f47c 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -1049,7 +1049,10 @@ void stmt_fetch_close(Stmt_fetch *fetch) reading from the rest. */ -my_bool fetch_n(const char **query_list, unsigned query_count) +enum fetch_type { USE_ROW_BY_ROW_FETCH= 0, USE_STORE_RESULT= 1 }; + +my_bool fetch_n(const char **query_list, unsigned query_count, + enum fetch_type fetch_type) { unsigned open_statements= query_count; int rc, error_count= 0; @@ -1065,6 +1068,15 @@ my_bool fetch_n(const char **query_list, unsigned query_count) query_list[fetch - fetch_array]); } + if (fetch_type == USE_STORE_RESULT) + { + for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch) + { + rc= mysql_stmt_store_result(fetch->handle); + check_execute(fetch->handle, rc); + } + } + while (open_statements) { for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch) @@ -11867,7 +11879,8 @@ static void test_basic_cursors() fill_tables(basic_tables, sizeof(basic_tables)/sizeof(*basic_tables)); - fetch_n(queries, sizeof(queries)/sizeof(*queries)); + fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH); + fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT); DBUG_VOID_RETURN; } @@ -11880,7 +11893,8 @@ static void test_cursors_with_union() "SELECT t1.id FROM t1 WHERE t1.id < 5" }; myheader("test_cursors_with_union"); - fetch_n(queries, sizeof(queries)/sizeof(*queries)); + fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH); + fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT); } /* From 7cdfacde683778c13296f148251b5e8e52593ff7 Mon Sep 17 00:00:00 2001 From: "jimw@mysql.com" <> Date: Mon, 13 Feb 2006 10:15:42 -0800 Subject: [PATCH 4/8] Bug #16775: DROP TABLE of subpartitioned table can fail if default engine used. The problem is that the actual engine was not stored in the .par file, causing confusion when the default engine was changed. Now the actual storage engine is stored for subpartitions, as was intended. --- mysql-test/r/partition.result | 8 ++++++++ mysql-test/t/partition.test | 12 ++++++++++++ sql/ha_partition.cc | 5 +++-- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index a638babc365..77efcf847e9 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -278,3 +278,11 @@ partition p1 values in (14) insert into t1 values (10,1); ERROR HY000: Table has no partition for value 11 drop table t1; +set session storage_engine= 'memory'; +create table t1 (f_int1 int(11) default null) engine = memory +partition by range (f_int1) subpartition by hash (f_int1) +(partition part1 values less than (1000) +(subpartition subpart11 engine = memory)); +set session storage_engine='myisam'; +drop table t1; +End of 5.1 tests diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index 301c1971c91..c4497443ee9 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -353,3 +353,15 @@ insert into t1 values (10,1); drop table t1; +# +# Bug #16775: Wrong engine type stored for subpartition +# +set session storage_engine= 'memory'; +create table t1 (f_int1 int(11) default null) engine = memory + partition by range (f_int1) subpartition by hash (f_int1) + (partition part1 values less than (1000) + (subpartition subpart11 engine = memory)); +set session storage_engine='myisam'; +drop table t1; + +--echo End of 5.1 tests diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 2bc4a106536..babc8a0e969 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -1937,7 +1937,8 @@ bool ha_partition::create_handler_file(const char *name) name_buffer_ptr+= name_add(name_buffer_ptr, part_name, subpart_name); - *engine_array= (uchar) ha_legacy_type(part_elem->engine_type); + *engine_array= (uchar) ha_legacy_type(subpart_elem->engine_type); + DBUG_PRINT("info", ("engine: %u", *engine_array)); engine_array++; } } @@ -1954,7 +1955,7 @@ bool ha_partition::create_handler_file(const char *name) Create and write and close file to be used at open, delete_table and rename_table */ - fn_format(file_name, name, "", ".par", MY_APPEND_EXT); + fn_format(file_name, name, "", ha_par_ext, MY_APPEND_EXT); if ((file= my_create(file_name, CREATE_MODE, O_RDWR | O_TRUNC, MYF(MY_WME))) >= 0) { From 52183ddd788c790205c24622fa87b7105ae2f9e2 Mon Sep 17 00:00:00 2001 From: "msvensson@neptunus.(none)" <> Date: Tue, 14 Feb 2006 17:15:24 +0100 Subject: [PATCH 5/8] Change from std_data to std_data_ln --- mysql-test/r/ndb_load.result | 4 ++-- mysql-test/t/ndb_load.test | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/ndb_load.result b/mysql-test/r/ndb_load.result index 76da5b2a215..416a350066b 100644 --- a/mysql-test/r/ndb_load.result +++ b/mysql-test/r/ndb_load.result @@ -1,10 +1,10 @@ DROP TABLE IF EXISTS t1; CREATE TABLE t1 (word CHAR(20) NOT NULL PRIMARY KEY) ENGINE=NDB; -LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1 ; +LOAD DATA INFILE '../std_data_ln/words.dat' INTO TABLE t1 ; ERROR 23000: Can't write; duplicate key in table 't1' DROP TABLE t1; CREATE TABLE t1 (word CHAR(20) NOT NULL) ENGINE=NDB; -LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1 ; +LOAD DATA INFILE '../std_data_ln/words.dat' INTO TABLE t1 ; SELECT * FROM t1 ORDER BY word; word Aarhus diff --git a/mysql-test/t/ndb_load.test b/mysql-test/t/ndb_load.test index 72a5b53eaad..af2df70b74e 100644 --- a/mysql-test/t/ndb_load.test +++ b/mysql-test/t/ndb_load.test @@ -12,12 +12,12 @@ DROP TABLE IF EXISTS t1; # should give duplicate key CREATE TABLE t1 (word CHAR(20) NOT NULL PRIMARY KEY) ENGINE=NDB; --error 1022 -LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1 ; +LOAD DATA INFILE '../std_data_ln/words.dat' INTO TABLE t1 ; DROP TABLE t1; # now without a primary key we should be ok CREATE TABLE t1 (word CHAR(20) NOT NULL) ENGINE=NDB; -LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1 ; +LOAD DATA INFILE '../std_data_ln/words.dat' INTO TABLE t1 ; SELECT * FROM t1 ORDER BY word; DROP TABLE t1; From dc5bb004678a1a2a0cd8ac378158f52621bef574 Mon Sep 17 00:00:00 2001 From: "msvensson@neptunus.(none)" <> Date: Tue, 14 Feb 2006 17:21:18 +0100 Subject: [PATCH 6/8] Enable ndb_load test case --- mysql-test/t/disabled.def | 1 - 1 file changed, 1 deletion(-) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 09a11578096..46f15983dc3 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -12,4 +12,3 @@ sp-goto : GOTO is currently is disabled - will be fixed in the future subselect : Bug#15706 -ndb_load : Bug #17233 From eb978186277614960d82c1924449b9806655768a Mon Sep 17 00:00:00 2001 From: "msvensson@devsrv-b.mysql.com" <> Date: Wed, 15 Feb 2006 13:45:03 +0100 Subject: [PATCH 7/8] Bug#16143 mysql_stmt_sqlstate returns an empty string instead of '00000' - Init sql_state in mysql_stmt_init --- libmysql/libmysql.c | 1 + tests/mysql_client_test.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 9825f1ecdfa..3ff4cfb4c50 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -2008,6 +2008,7 @@ mysql_stmt_init(MYSQL *mysql) stmt->mysql= mysql; stmt->read_row_func= stmt_read_row_no_result_set; stmt->prefetch_rows= DEFAULT_PREFETCH_ROWS; + strmov(stmt->sqlstate, not_error_sqlstate); /* The rest of statement members was bzeroed inside malloc */ DBUG_RETURN(stmt); diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 666c60391da..241a994d07c 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -14729,6 +14729,21 @@ static void test_bug12744() client_connect(0); } +/* Bug #16143: mysql_stmt_sqlstate returns an empty string instead of '00000' */ + +static void test_bug16143() +{ + MYSQL_STMT *stmt; + myheader("test_bug16143"); + + stmt= mysql_stmt_init(mysql); + /* Check mysql_stmt_sqlstate return "no error" */ + DIE_UNLESS(strcmp(mysql_stmt_sqlstate(stmt), "00000") == 0); + + mysql_stmt_close(stmt); +} + + /* Bug #16144: mysql_stmt_attr_get type error */ static void test_bug16144() @@ -15073,6 +15088,7 @@ static struct my_tests_st my_tests[]= { { "test_bug15510", test_bug15510 }, { "test_opt_reconnect", test_opt_reconnect }, { "test_bug12744", test_bug12744 }, + { "test_bug16143", test_bug16143 }, { "test_bug16144", test_bug16144 }, { "test_bug15613", test_bug15613 }, { 0, 0 } From e145908eb38237c2f5c9818388f1778fee6b03e8 Mon Sep 17 00:00:00 2001 From: "jimw@mysql.com" <> Date: Wed, 15 Feb 2006 11:20:57 -0800 Subject: [PATCH 8/8] Bug #16782: Partitions: crash, REPLACE .. on table with PK, DUPLICATE KEY event. Partitioning wrongly claimed to be able to handle HA_DUPP_POS when it was supported by the underlying storage engine, which resulted in a crash when handling REPLACE statements. --- mysql-test/r/partition.result | 6 ++++++ mysql-test/t/partition.test | 10 ++++++++++ sql/ha_partition.cc | 7 ++++--- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index a638babc365..04f96dd4266 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -278,3 +278,9 @@ partition p1 values in (14) insert into t1 values (10,1); ERROR HY000: Table has no partition for value 11 drop table t1; +create table t1 (f_int1 integer, f_int2 integer, primary key (f_int1)) +partition by hash(f_int1) partitions 2; +insert into t1 values (1,1),(2,2); +replace into t1 values (1,1),(2,2); +drop table t1; +End of 5.1 tests diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index 301c1971c91..a262883373e 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -353,3 +353,13 @@ insert into t1 values (10,1); drop table t1; +# +# Bug #16782: Crash using REPLACE on table with primary key +# +create table t1 (f_int1 integer, f_int2 integer, primary key (f_int1)) + partition by hash(f_int1) partitions 2; +insert into t1 values (1,1),(2,2); +replace into t1 values (1,1),(2,2); +drop table t1; + +--echo End of 5.1 tests diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 50299dffd85..a71b13bed17 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -359,7 +359,7 @@ int ha_partition::ha_initialise() other parameters are calculated on demand. HA_FILE_BASED is always set for partition handler since we use a special file for handling names of partitions, engine types. - HA_CAN_GEOMETRY, HA_CAN_FULLTEXT, HA_CAN_SQL_HANDLER, + HA_CAN_GEOMETRY, HA_CAN_FULLTEXT, HA_CAN_SQL_HANDLER, HA_DUPP_POS, HA_CAN_INSERT_DELAYED is disabled until further investigated. */ m_table_flags= m_file[0]->table_flags(); @@ -382,8 +382,8 @@ int ha_partition::ha_initialise() m_pkey_is_clustered= FALSE; m_table_flags&= file->table_flags(); } while (*(++file_array)); - m_table_flags&= ~(HA_CAN_GEOMETRY & HA_CAN_FULLTEXT & - HA_CAN_SQL_HANDLER & HA_CAN_INSERT_DELAYED); + m_table_flags&= ~(HA_CAN_GEOMETRY | HA_CAN_FULLTEXT | HA_DUPP_POS | + HA_CAN_SQL_HANDLER | HA_CAN_INSERT_DELAYED); m_table_flags|= HA_FILE_BASED | HA_REC_NOT_IN_SEQ; DBUG_RETURN(0); } @@ -4688,6 +4688,7 @@ int ha_partition::extra(enum ha_extra_function operation) case HA_EXTRA_PREPARE_FOR_UPDATE: case HA_EXTRA_PREPARE_FOR_DELETE: case HA_EXTRA_FORCE_REOPEN: + case HA_EXTRA_FLUSH_CACHE: { if (m_myisam) DBUG_RETURN(loop_extra(operation));