From 80c0891588dd8aef2a0e08864b00067ffd9de5ce Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 9 Apr 2013 09:58:51 +0300 Subject: [PATCH 1/7] MDEV-4326 fix. Removed "optimization" which caused preoblems on second execution of PS with string parameter in LIMIT clause. Fixed test_bug43560 to be able to skipp it if connection is UNIX socket. --- sql/sql_prepare.cc | 2 +- tests/mysql_client_test.c | 110 +++++++++++++++++++++++++++++++++++++- 2 files changed, 110 insertions(+), 2 deletions(-) diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 0c1c33dcee0..733fc00bf20 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -787,7 +787,7 @@ static bool insert_params_with_log(Prepared_statement *stmt, uchar *null_array, if (param->state == Item_param::NO_VALUE) DBUG_RETURN(1); - if (param->limit_clause_param && param->item_type != Item::INT_ITEM) + if (param->limit_clause_param) { param->set_int(param->val_int(), MY_INT64_NUM_DECIMAL_DIGITS); param->item_type= Item::INT_ITEM; diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 462575ac456..0e18ca12c42 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -16750,7 +16750,11 @@ static void test_bug43560(void) fprintf(stdout, "Skipping test_bug43560: server not DEBUG version\n"); DBUG_VOID_RETURN; } - + if (opt_unix_socket) + { + fprintf(stdout, "Skipping test_bug43560: connected via UNIX socket\n"); + DBUG_VOID_RETURN; + } /* Set up a separate connection for this test to avoid messing up the general MYSQL object used in other subtests. Use TCP protocol to avoid @@ -17541,6 +17545,109 @@ static void test_bug13001491() myquery(rc); } +static void test_mdev4326() +{ + MYSQL_STMT *stmt; + MYSQL_BIND bind; + char query[]= "SELECT * FROM mysql.user LIMIT ?"; + char str_data[]= "1"; + unsigned long length= 0; + int int_data= 1; + int rc, count; + my_bool is_null= 0; + my_bool error= 0; + myheader("test_mdev4326"); + + rc= mysql_change_user(mysql, opt_user, opt_password, "mysql"); + myquery(rc); + + rc= mysql_query(mysql, "SET GLOBAL general_log = 1"); + myquery(rc); + + stmt= mysql_stmt_init(mysql); + check_stmt(stmt); + + /* Numeric parameter test */ + + rc= mysql_stmt_prepare(stmt, query, strlen(query)); + check_execute(stmt, rc); + check_stmt(stmt); + verify_param_count(stmt, 1); + + memset((char *)&bind, 0, sizeof(bind)); + bind.buffer_type= MYSQL_TYPE_LONG; + bind.buffer= (char *)&int_data; + bind.is_null= &is_null; + bind.length= &length; + bind.error= &error; + + rc= mysql_stmt_bind_param(stmt, &bind); + check_execute(stmt, rc); + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + count= 0; + while (!(rc= mysql_stmt_fetch(stmt))) + count++; + DIE_UNLESS(count == 1); + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + count= 0; + while (!(rc= mysql_stmt_fetch(stmt))) + count++; + DIE_UNLESS(count == 1); + int_data= 0; + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + count= 0; + while (!(rc= mysql_stmt_fetch(stmt))) + count++; + DIE_UNLESS(count == 0); + rc= mysql_stmt_close(stmt); + check_execute(stmt, rc); + + /* String parameter test */ + + stmt= mysql_stmt_init(mysql); + rc= mysql_stmt_prepare(stmt, query, strlen(query)); + check_execute(stmt, rc); + check_stmt(stmt); + verify_param_count(stmt, 1); + + memset((char *)&bind, 0, sizeof(bind)); + bind.buffer_type= MYSQL_TYPE_STRING; + bind.buffer= (char *)str_data; + length= bind.buffer_length= sizeof(str_data); + bind.is_null= &is_null; + bind.length= &length; + bind.error= &error; + + rc= mysql_stmt_bind_param(stmt, &bind); + check_execute(stmt, rc); + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + count= 0; + while (!(rc= mysql_stmt_fetch(stmt))) + count++; + DIE_UNLESS(count == 1); + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + count= 0; + while (!(rc= mysql_stmt_fetch(stmt))) + count++; + DIE_UNLESS(count == 1); + str_data[0]= '0'; + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + count= 0; + while (!(rc= mysql_stmt_fetch(stmt))) + count++; + DIE_UNLESS(count == 0); + rc= mysql_stmt_close(stmt); + check_execute(stmt, rc); + + rc= mysql_change_user(mysql, opt_user, opt_password, current_db); + myquery(rc); +} static struct my_tests_st my_tests[]= { { "disable_query_logs", disable_query_logs }, @@ -17790,6 +17897,7 @@ static struct my_tests_st my_tests[]= { { "test_bug58036", test_bug58036 }, { "test_bug56976", test_bug56976 }, { "test_bug13001491", test_bug13001491 }, + { "test_mdev4326", test_mdev4326 }, { 0, 0 } }; From 4a0f2563d3d1747a4704e6241380071efbeb3882 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 8 May 2013 14:32:32 +0200 Subject: [PATCH 2/7] MDEV-4462 mysqld gets SIGFPE when mysql.user table is empty avoid divison by zero --- mysql-test/r/empty_user_table.result | 8 ++++++++ mysql-test/t/empty_user_table.test | 18 ++++++++++++++++++ sql/sql_acl.cc | 6 ++++++ 3 files changed, 32 insertions(+) create mode 100644 mysql-test/r/empty_user_table.result create mode 100644 mysql-test/t/empty_user_table.test diff --git a/mysql-test/r/empty_user_table.result b/mysql-test/r/empty_user_table.result new file mode 100644 index 00000000000..df9d803e5c0 --- /dev/null +++ b/mysql-test/r/empty_user_table.result @@ -0,0 +1,8 @@ +create table t1 as select * from mysql.user; +truncate table mysql.user; +flush privileges; +connect(localhost,u1,,test,MASTER_PORT,MASTER_SOCKET); +ERROR 28000: Access denied for user 'u1'@'localhost' (using password: NO) +insert mysql.user select * from t1; +drop table t1; +flush privileges; diff --git a/mysql-test/t/empty_user_table.test b/mysql-test/t/empty_user_table.test new file mode 100644 index 00000000000..7e672cc64f6 --- /dev/null +++ b/mysql-test/t/empty_user_table.test @@ -0,0 +1,18 @@ +# +# MDEV-4462 mysqld gets SIGFPE when mysql.user table is empty +# + +source include/not_embedded.inc; + +create table t1 as select * from mysql.user; +truncate table mysql.user; +flush privileges; + +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--error ER_ACCESS_DENIED_ERROR +connect (fail,localhost,u1); + +insert mysql.user select * from t1; +drop table t1; +flush privileges; + diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 29922aa5321..9983c52abb5 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -7367,6 +7367,12 @@ static bool find_mpvio_user(MPVIO_EXT *mpvio, Security_context *sctx) cs->coll->hash_sort(cs, (uchar*) sctx->user, strlen(sctx->user), &nr1, &nr2); pthread_mutex_lock(&acl_cache->lock); + if (!acl_users.elements) + { + pthread_mutex_unlock(&acl_cache->lock); + login_failed_error(mpvio->thd); + return 1; + } uint i= nr1 % acl_users.elements; ACL_USER *acl_user_tmp= dynamic_element(&acl_users, i, ACL_USER*); mpvio->acl_user= acl_user_tmp->copy(mpvio->thd->mem_root); From 4e9bf37f1f70ddc0c901760e4302dd4040a2730c Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Sat, 11 May 2013 15:55:11 +0300 Subject: [PATCH 3/7] MDEV-4280: Assertion `empty_size == empty_size_on_page' failure in ma_blockrec.c or ER_NOT_KEYFILE on query with DISTINCT and GROUP BY This could happen when using Aria for internal temporary files (default case) and using DISTINCT. _ma_scan_restore_block_record() didn't work correctly if there was rows inserted, updated or deleted on the handler between calls to _ma_scan_remember_block_record() and _ma_scan_restore_block_record(). The effect was that some DISTINCT queries that used remove_dup_with_compare() could fail. .bzrignore: Ignore sql_yacc.hh mysql-test/suite/maria/r/distinct.result: Test case for MDEV-4280 mysql-test/suite/maria/t/distinct.test: Test case for MDEV-4280 mysql-test/t/mysql.test: Fixed test suite (we could get error -1 in some cases) sql/sql_select.cc: Break loop if restart_rnd_next() gives an error storage/maria/ha_maria.cc: scan_restore_pos() can return disk fault error. storage/maria/ma_blockrec.c: _ma_scan_remember_block_record() did incorrectly update scan.dir instead of scan_save.dir . _ma_scan_restore_block_record() didn't work correctly if there was rows inserted,updated or deleted on the handler between calls to _ma_scan_remember_block_record() and _ma_scan_restore_block_record(). Fixed by adding counters for row changes and reading the current scan page if changes had been made. storage/maria/ma_blockrec.h: scan_restore_pos() can return disk fault error. storage/maria/ma_delete.c: Increment row_changes storage/maria/ma_scan.c: scan_restore_pos() can return disk fault error. storage/maria/ma_update.c: Increment row_changes storage/maria/ma_write.c: Increment row_changes storage/maria/maria_def.h: scan_restore_pos() can return disk fault error. --- .bzrignore | 1 + mysql-test/suite/maria/r/distinct.result | 25 +++++++++ mysql-test/suite/maria/t/distinct.test | 25 +++++++++ mysql-test/t/mysql.test | 2 +- sql/sql_select.cc | 3 +- storage/maria/ha_maria.cc | 4 +- storage/maria/ma_blockrec.c | 67 +++++++++++++++++++----- storage/maria/ma_blockrec.h | 4 +- storage/maria/ma_delete.c | 1 + storage/maria/ma_scan.c | 3 +- storage/maria/ma_update.c | 1 + storage/maria/ma_write.c | 1 + storage/maria/maria_def.h | 6 ++- 13 files changed, 121 insertions(+), 22 deletions(-) create mode 100644 mysql-test/suite/maria/r/distinct.result create mode 100644 mysql-test/suite/maria/t/distinct.test diff --git a/.bzrignore b/.bzrignore index 84ebe547912..5d89804d637 100644 --- a/.bzrignore +++ b/.bzrignore @@ -1957,3 +1957,4 @@ CPackSourceConfig.cmake win/nmake_cache.txt *.manifest *.resource.txt +sql/sql_yacc.hh diff --git a/mysql-test/suite/maria/r/distinct.result b/mysql-test/suite/maria/r/distinct.result new file mode 100644 index 00000000000..04d5e3d6a2c --- /dev/null +++ b/mysql-test/suite/maria/r/distinct.result @@ -0,0 +1,25 @@ +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (a INT, b INT) ENGINE=Aria; +INSERT t1 VALUES (3,2004),(2,2006),(1,2007),(3,2008),(2,2005),(2,2001); +SELECT GROUP_CONCAT(a) FROM t1 GROUP BY b; +GROUP_CONCAT(a) +2 +3 +2 +2 +1 +3 +SELECT DISTINCT GROUP_CONCAT(a) FROM t1 GROUP BY b; +GROUP_CONCAT(a) +2 +3 +1 +DROP TABLE t1; +CREATE TABLE t1 (a INT, b VARCHAR(1)) ENGINE=MyISAM; +INSERT INTO t1 VALUES (7,'q'),(2,NULL),(7,'g'),(6,'x'); +SELECT DISTINCT MAX( a ) FROM t1 GROUP BY b ORDER BY DES_DECRYPT( b ); +MAX( a ) +2 +7 +6 +DROP TABLE t1; diff --git a/mysql-test/suite/maria/t/distinct.test b/mysql-test/suite/maria/t/distinct.test new file mode 100644 index 00000000000..b30d97b8383 --- /dev/null +++ b/mysql-test/suite/maria/t/distinct.test @@ -0,0 +1,25 @@ +# +# MDEV-4280: +# Assertion `empty_size == empty_size_on_page' failure in ma_blockrec.c or +# ER_NOT_KEYFILE on query with DISTINCT and GROUP BY +# +# This issue was a bug in how we delete row during duplicate removal when +# we use Aria for internal temporary table. +# + +-- source include/have_maria.inc + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1 (a INT, b INT) ENGINE=Aria; +INSERT t1 VALUES (3,2004),(2,2006),(1,2007),(3,2008),(2,2005),(2,2001); +SELECT GROUP_CONCAT(a) FROM t1 GROUP BY b; +SELECT DISTINCT GROUP_CONCAT(a) FROM t1 GROUP BY b; +DROP TABLE t1; + +CREATE TABLE t1 (a INT, b VARCHAR(1)) ENGINE=MyISAM; +INSERT INTO t1 VALUES (7,'q'),(2,NULL),(7,'g'),(6,'x'); +SELECT DISTINCT MAX( a ) FROM t1 GROUP BY b ORDER BY DES_DECRYPT( b ); +DROP TABLE t1; diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index dc6c8cf9be7..4ed776f1987 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -224,7 +224,7 @@ drop table t17583; --exec $MYSQL test -e "connect test invalid_hostname" 2>&1 --echo The commands reported in the bug report ---replace_regex /\([0-9]*\)/(errno)/ +--replace_regex /\([0-9|-]*\)/(errno)/ --error 1 --exec $MYSQL test -e "\r\r\n\r\n cyril\ has\ found\ a\ bug\ :)XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" 2>&1 diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 24ca1ab0174..b76e8afac36 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -14656,7 +14656,8 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field, if (!found) break; // End of file /* Restart search on saved row */ - error=file->restart_rnd_next(record); + if ((error= file->restart_rnd_next(record))) + goto err; } file->extra(HA_EXTRA_NO_CACHE); diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 8b1fe4d05b3..ce308887516 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -2255,7 +2255,9 @@ int ha_maria::remember_rnd_pos() int ha_maria::restart_rnd_next(uchar *buf) { - (*file->s->scan_restore_pos)(file, remember_pos); + int error; + if ((error= (*file->s->scan_restore_pos)(file, remember_pos))) + return error; return rnd_next(buf); } diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c index 71bbb389ca2..73b3326fd28 100644 --- a/storage/maria/ma_blockrec.c +++ b/storage/maria/ma_blockrec.c @@ -4008,6 +4008,8 @@ static int delete_dir_entry(uchar *buff, uint block_size, uint record_number, uint length, empty_space; uchar *dir; DBUG_ENTER("delete_dir_entry"); + DBUG_PRINT("enter", ("record_number: %u number_of_records: %u", + record_number, number_of_records)); #ifdef SANITY_CHECKS if (record_number >= number_of_records || @@ -4024,7 +4026,8 @@ static int delete_dir_entry(uchar *buff, uint block_size, uint record_number, check_directory(buff, block_size, 0, (uint) -1); empty_space= uint2korr(buff + EMPTY_SPACE_OFFSET); dir= dir_entry_pos(buff, block_size, record_number); - length= uint2korr(dir + 2); + length= uint2korr(dir + 2); /* Length of entry we just deleted */ + DBUG_ASSERT(uint2korr(dir) != 0 && length < block_size); if (record_number == number_of_records - 1) { @@ -5230,11 +5233,6 @@ void _ma_scan_end_block_record(MARIA_HA *info) For the moment we can only remember one position, but this is good enough for MySQL usage - @Warning - When this function is called, we assume that the thread is not deleting - or updating the current row before ma_scan_restore_block_record() - is called! - @return @retval 0 ok @retval HA_ERR_WRONG_IN_RECORD Could not allocate memory to hold position @@ -5254,15 +5252,18 @@ int _ma_scan_remember_block_record(MARIA_HA *info, info->scan_save->bitmap_buff= ((uchar*) info->scan_save + ALIGN_SIZE(sizeof(*info->scan_save))); } - /* Point to the last read row */ - *lastpos= info->cur_row.nextpos - 1; - info->scan.dir+= DIR_ENTRY_SIZE; + /* For checking if pages have changed since we last read it */ + info->scan.row_changes= info->row_changes; /* Remember used bitmap and used head page */ bitmap_buff= info->scan_save->bitmap_buff; memcpy(info->scan_save, &info->scan, sizeof(*info->scan_save)); info->scan_save->bitmap_buff= bitmap_buff; memcpy(bitmap_buff, info->scan.bitmap_buff, info->s->block_size * 2); + + /* Point to the last read row */ + *lastpos= info->cur_row.nextpos - 1; + info->scan_save->dir+= DIR_ENTRY_SIZE; DBUG_RETURN(0); } @@ -5270,15 +5271,22 @@ int _ma_scan_remember_block_record(MARIA_HA *info, /** @brief restore scan block it's original values + @return + 0 ok + # error + @note In theory we could swap bitmap buffers instead of copy them. For the moment we don't do that because there are variables pointing inside the buffers and it's a bit of hassle to either make them relative or repoint them. + + If the data file has changed, we will re-read the new block record + to ensure that when we continue scanning we can ignore any deleted rows. */ -void _ma_scan_restore_block_record(MARIA_HA *info, - MARIA_RECORD_POS lastpos) +int _ma_scan_restore_block_record(MARIA_HA *info, + MARIA_RECORD_POS lastpos) { uchar *bitmap_buff; DBUG_ENTER("_ma_scan_restore_block_record"); @@ -5289,7 +5297,26 @@ void _ma_scan_restore_block_record(MARIA_HA *info, info->scan.bitmap_buff= bitmap_buff; memcpy(bitmap_buff, info->scan_save->bitmap_buff, info->s->block_size * 2); - DBUG_VOID_RETURN; + if (info->scan.row_changes != info->row_changes) + { + /* + Table has been changed. We have to re-read the current page block as + data may have changed on it that we have to see. + */ + if (!(pagecache_read(info->s->pagecache, + &info->dfile, + ma_recordpos_to_page(info->scan.row_base_page), + 0, info->scan.page_buff, + info->s->page_type, + PAGECACHE_LOCK_LEFT_UNLOCKED, 0))) + DBUG_RETURN(my_errno); + info->scan.number_of_rows= + (uint) (uchar) info->scan.page_buff[DIR_COUNT_OFFSET]; + info->scan.dir_end= (info->scan.page_buff + info->s->block_size - + PAGE_SUFFIX_SIZE - + info->scan.number_of_rows * DIR_ENTRY_SIZE); + } + DBUG_RETURN(0); } @@ -5316,7 +5343,7 @@ void _ma_scan_restore_block_record(MARIA_HA *info, RETURN 0 ok - # Error code + # Error code (Normally HA_ERR_END_OF_FILE) */ int _ma_scan_block_record(MARIA_HA *info, uchar *record, @@ -5336,6 +5363,12 @@ restart_record_read: uchar *data, *end_of_data; int error; + /* Ensure that scan.dir and record_pos are in sync */ + DBUG_ASSERT(info->scan.dir == dir_entry_pos(info->scan.page_buff, + share->block_size, + record_pos)); + + /* Search for a valid directory entry (not 0) */ while (!(offset= uint2korr(info->scan.dir))) { info->scan.dir-= DIR_ENTRY_SIZE; @@ -5348,13 +5381,19 @@ restart_record_read: } #endif } + /* + This should always be true as the directory should always start with + a valid entry. + */ + DBUG_ASSERT(info->scan.dir >= info->scan.dir_end); + /* found row */ info->cur_row.lastpos= info->scan.row_base_page + record_pos; info->cur_row.nextpos= record_pos + 1; data= info->scan.page_buff + offset; length= uint2korr(info->scan.dir + 2); end_of_data= data + length; - info->scan.dir-= DIR_ENTRY_SIZE; /* Point to previous row */ + info->scan.dir-= DIR_ENTRY_SIZE; /* Point to next row to process */ #ifdef SANITY_CHECKS if (end_of_data > info->scan.dir_end || offset < PAGE_HEADER_SIZE || length < share->base.min_block_length) diff --git a/storage/maria/ma_blockrec.h b/storage/maria/ma_blockrec.h index 2a323d16ffa..f6aae8d4759 100644 --- a/storage/maria/ma_blockrec.h +++ b/storage/maria/ma_blockrec.h @@ -168,8 +168,8 @@ my_bool _ma_scan_init_block_record(MARIA_HA *info); void _ma_scan_end_block_record(MARIA_HA *info); int _ma_scan_remember_block_record(MARIA_HA *info, MARIA_RECORD_POS *lastpos); -void _ma_scan_restore_block_record(MARIA_HA *info, - MARIA_RECORD_POS lastpos); +int _ma_scan_restore_block_record(MARIA_HA *info, + MARIA_RECORD_POS lastpos); MARIA_RECORD_POS _ma_write_init_block_record(MARIA_HA *info, const uchar *record); diff --git a/storage/maria/ma_delete.c b/storage/maria/ma_delete.c index ab66499ecfe..977c7c82cb7 100644 --- a/storage/maria/ma_delete.c +++ b/storage/maria/ma_delete.c @@ -112,6 +112,7 @@ int maria_delete(MARIA_HA *info,const uchar *record) info->state->checksum-= info->cur_row.checksum; info->state->records--; info->update= HA_STATE_CHANGED+HA_STATE_DELETED+HA_STATE_ROW_CHANGED; + info->row_changes++; share->state.changed|= (STATE_NOT_OPTIMIZED_ROWS | STATE_NOT_MOVABLE | STATE_NOT_ZEROFILLED); info->state->changed=1; diff --git a/storage/maria/ma_scan.c b/storage/maria/ma_scan.c index cbac463a2c8..ad526211615 100644 --- a/storage/maria/ma_scan.c +++ b/storage/maria/ma_scan.c @@ -68,7 +68,8 @@ int _ma_def_scan_remember_pos(MARIA_HA *info, MARIA_RECORD_POS *lastpos) } -void _ma_def_scan_restore_pos(MARIA_HA *info, MARIA_RECORD_POS lastpos) +int _ma_def_scan_restore_pos(MARIA_HA *info, MARIA_RECORD_POS lastpos) { info->cur_row.nextpos= lastpos; + return 0; } diff --git a/storage/maria/ma_update.c b/storage/maria/ma_update.c index abd9116a711..80b1fd86782 100644 --- a/storage/maria/ma_update.c +++ b/storage/maria/ma_update.c @@ -173,6 +173,7 @@ int maria_update(register MARIA_HA *info, const uchar *oldrec, uchar *newrec) We can't yet have HA_STATE_AKTIV here, as block_record dosn't support it */ info->update= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED | key_changed); + info->row_changes++; share->state.changed|= STATE_NOT_MOVABLE | STATE_NOT_ZEROFILLED; info->state->changed= 1; diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c index b4bf5086e0b..3c5efdc2ef0 100644 --- a/storage/maria/ma_write.c +++ b/storage/maria/ma_write.c @@ -288,6 +288,7 @@ int maria_write(MARIA_HA *info, uchar *record) info->state->records++; info->update= (HA_STATE_CHANGED | HA_STATE_AKTIV | HA_STATE_WRITTEN | HA_STATE_ROW_CHANGED); + info->row_changes++; share->state.changed|= STATE_NOT_MOVABLE | STATE_NOT_ZEROFILLED; info->state->changed= 1; diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h index 41501b8eb74..fe9bf10fe24 100644 --- a/storage/maria/maria_def.h +++ b/storage/maria/maria_def.h @@ -317,7 +317,7 @@ typedef struct st_maria_share /* End scan */ void (*scan_end)(MARIA_HA *); int (*scan_remember_pos)(MARIA_HA *, MARIA_RECORD_POS*); - void (*scan_restore_pos)(MARIA_HA *, MARIA_RECORD_POS); + int (*scan_restore_pos)(MARIA_HA *, MARIA_RECORD_POS); /* Pre-write of row (some handlers may do the actual write here) */ MARIA_RECORD_POS (*write_record_init)(MARIA_HA *, const uchar *); /* Write record (or accept write_record_init) */ @@ -492,6 +492,7 @@ typedef struct st_maria_block_scan ulonglong bits; uint number_of_rows, bit_pos; MARIA_RECORD_POS row_base_page; + ulonglong row_changes; } MARIA_BLOCK_SCAN; @@ -533,6 +534,7 @@ struct st_maria_handler int (*read_record)(MARIA_HA *, uchar*, MARIA_RECORD_POS); invalidator_by_filename invalidator; /* query cache invalidator */ ulonglong last_auto_increment; /* auto value at start of statement */ + ulonglong row_changes; /* Incremented for each change */ ulong this_unique; /* uniq filenumber or thread */ ulong last_unique; /* last unique number */ ulong this_loop; /* counter for this open */ @@ -1175,7 +1177,7 @@ my_bool _ma_check_status(void *param); void _ma_restore_status(void *param); void _ma_reset_status(MARIA_HA *maria); int _ma_def_scan_remember_pos(MARIA_HA *info, MARIA_RECORD_POS *lastpos); -void _ma_def_scan_restore_pos(MARIA_HA *info, MARIA_RECORD_POS lastpos); +int _ma_def_scan_restore_pos(MARIA_HA *info, MARIA_RECORD_POS lastpos); #include "ma_commit.h" From 4b9a6c03fafe7f4c1901ba909796a3385184c516 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Sat, 11 May 2013 18:57:06 +0300 Subject: [PATCH 4/7] Fixed compiler warning --- client/mysqldump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index b271cb8429b..ece88a51306 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1886,7 +1886,7 @@ static void print_xml_row(FILE *xml_file, const char *row_name, const char *str_create) { uint i; - my_bool body_found= 0; + my_bool body_found __attribute__((unused)) = 0; char *create_stmt_ptr= NULL; ulong create_stmt_len= 0; MYSQL_FIELD *field; From 3b3f870994299c905627c7925c4af473e948d78d Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Sat, 11 May 2013 20:23:57 +0300 Subject: [PATCH 5/7] Fixed compiler failure on solaris --- mysys/my_gethwaddr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysys/my_gethwaddr.c b/mysys/my_gethwaddr.c index c96af3f1018..95306e71650 100644 --- a/mysys/my_gethwaddr.c +++ b/mysys/my_gethwaddr.c @@ -101,7 +101,7 @@ my_bool my_gethwaddr(uchar *to) uint i; for (i= 0; res && i < ifc.ifc_len / sizeof(ifr[0]); i++) { -#ifdef SIOCGIFHWADDR +#ifdef __linux__ if (ioctl(fd, SIOCGIFHWADDR, &ifr[i]) >= 0) res= memcpy_and_test(to, (uchar *)&ifr[i].ifr_hwaddr.sa_data, ETHER_ADDR_LEN); From cbd300e7b028ab7716a4e02fa2e5067c4d8ee006 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Sun, 19 May 2013 16:22:33 +0200 Subject: [PATCH 6/7] Fix cpack error - safe_process.pl does not exist anymore. --- mysql-test/lib/My/SafeProcess/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/lib/My/SafeProcess/CMakeLists.txt b/mysql-test/lib/My/SafeProcess/CMakeLists.txt index 6edf9d45683..67755a065ea 100644 --- a/mysql-test/lib/My/SafeProcess/CMakeLists.txt +++ b/mysql-test/lib/My/SafeProcess/CMakeLists.txt @@ -26,4 +26,4 @@ ELSE() MYSQL_ADD_EXECUTABLE(my_safe_process safe_process.cc ${INSTALL_ARGS}) ENDIF() -INSTALL(FILES safe_process.pl Base.pm DESTINATION "${INSTALL_MYSQLTESTDIR}/lib/My/SafeProcess" COMPONENT Test) +INSTALL(FILES Base.pm DESTINATION "${INSTALL_MYSQLTESTDIR}/lib/My/SafeProcess" COMPONENT Test) From dc56d56ce578d32e4bfba23f01a644da97c7ccb6 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Sun, 19 May 2013 16:38:56 +0200 Subject: [PATCH 7/7] MDEV-4544 - update MSI to include HeidiSQL 8.0 --- win/packaging/heidisql.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/packaging/heidisql.cmake b/win/packaging/heidisql.cmake index f826c9a6633..124f85bb87e 100644 --- a/win/packaging/heidisql.cmake +++ b/win/packaging/heidisql.cmake @@ -1,4 +1,4 @@ -SET(HEIDISQL_BASE_NAME "HeidiSQL_7.0_Portable") +SET(HEIDISQL_BASE_NAME "HeidiSQL_8.0_Portable") SET(HEIDISQL_ZIP "${HEIDISQL_BASE_NAME}.zip") SET(HEIDISQL_URL "http://heidisql.googlecode.com/files/${HEIDISQL_ZIP}") SET(HEIDISQL_DOWNLOAD_DIR ${THIRD_PARTY_DOWNLOAD_LOCATION}/${HEIDISQL_BASE_NAME})