From da0b6d611fcbe15e18fd888e9bf3578855caca09 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 31 May 2010 19:35:40 +0300 Subject: [PATCH 001/112] Merge a change from mysql-trunk-innodb: ------------------------------------------------------------ revno: 3127 revision-id: vasil.dimov@oracle.com-20100531152341-x2d4hma644icamh1 parent: vasil.dimov@oracle.com-20100531105923-kpjwl4rbgfpfj13c committer: Vasil Dimov branch nick: mysql-trunk-innodb timestamp: Mon 2010-05-31 18:23:41 +0300 message: Fix Bug #53947 InnoDB: Assertion failure in thread 4224 in file .\sync\sync0sync.c line 324 Destroy the rw-lock object before freeing the memory it is occupying. If we do not do this, then the mutex that is contained in the rw-lock object btr_search_latch_temp->mutex gets "freed" and subsequently mutex_free() from sync_close() hits a mutex whose memory has been freed and crashes. Approved by: Heikki (via IRC) Discussed with: Calvin --- storage/innodb_plugin/btr/btr0sea.c | 1 + 1 file changed, 1 insertion(+) diff --git a/storage/innodb_plugin/btr/btr0sea.c b/storage/innodb_plugin/btr/btr0sea.c index ef7afeb1039..c91afa31bf0 100644 --- a/storage/innodb_plugin/btr/btr0sea.c +++ b/storage/innodb_plugin/btr/btr0sea.c @@ -182,6 +182,7 @@ void btr_search_sys_free(void) /*=====================*/ { + rw_lock_free(&btr_search_latch); mem_free(btr_search_latch_temp); btr_search_latch_temp = NULL; mem_heap_free(btr_search_sys->hash_index->heap); From 2caade505362cb2ab66514c64ac9424af775cbf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 1 Jun 2010 13:37:38 +0300 Subject: [PATCH 002/112] Bug#53812: assert row/row0umod.c line 660 in txn rollback after crash recovery row_undo_mod_upd_exist_sec(): Tolerate a failure to build the index entry for a DYNAMIC or COMPRESSED table during crash recovery. --- storage/innodb_plugin/row/row0umod.c | 64 ++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 17 deletions(-) diff --git a/storage/innodb_plugin/row/row0umod.c b/storage/innodb_plugin/row/row0umod.c index e7245dbee41..c497c469aae 100644 --- a/storage/innodb_plugin/row/row0umod.c +++ b/storage/innodb_plugin/row/row0umod.c @@ -657,24 +657,55 @@ row_undo_mod_upd_exist_sec( /* Build the newest version of the index entry */ entry = row_build_index_entry(node->row, node->ext, index, heap); - ut_a(entry); - /* NOTE that if we updated the fields of a - delete-marked secondary index record so that - alphabetically they stayed the same, e.g., - 'abc' -> 'aBc', we cannot return to the original - values because we do not know them. But this should - not cause problems because in row0sel.c, in queries - we always retrieve the clustered index record or an - earlier version of it, if the secondary index record - through which we do the search is delete-marked. */ + if (UNIV_UNLIKELY(!entry)) { + /* The server must have crashed in + row_upd_clust_rec_by_insert(), in + row_ins_index_entry_low() before + btr_store_big_rec_extern_fields() + has written the externally stored columns + (BLOBs) of the new clustered index entry. */ - err = row_undo_mod_del_mark_or_remove_sec(node, thr, - index, - entry); - if (err != DB_SUCCESS) { - mem_heap_free(heap); + /* The table must be in DYNAMIC or COMPRESSED + format. REDUNDANT and COMPACT formats + store a local 768-byte prefix of each + externally stored column. */ + ut_a(dict_table_get_format(index->table) + >= DICT_TF_FORMAT_ZIP); - return(err); + /* This is only legitimate when + rolling back an incomplete transaction + after crash recovery. */ + ut_a(thr_get_trx(thr)->is_recovered); + + /* The server must have crashed before + completing the insert of the new + clustered index entry and before + inserting to the secondary indexes. + Because node->row was not yet written + to this index, we can ignore it. But + we must restore node->undo_row. */ + } else { + /* NOTE that if we updated the fields of a + delete-marked secondary index record so that + alphabetically they stayed the same, e.g., + 'abc' -> 'aBc', we cannot return to the + original values because we do not know them. + But this should not cause problems because + in row0sel.c, in queries we always retrieve + the clustered index record or an earlier + version of it, if the secondary index record + through which we do the search is + delete-marked. */ + + err = row_undo_mod_del_mark_or_remove_sec( + node, thr, index, entry); + if (err != DB_SUCCESS) { + mem_heap_free(heap); + + return(err); + } + + mem_heap_empty(heap); } /* We may have to update the delete mark in the @@ -683,7 +714,6 @@ row_undo_mod_upd_exist_sec( the secondary index record if we updated its fields but alphabetically they stayed the same, e.g., 'abc' -> 'aBc'. */ - mem_heap_empty(heap); entry = row_build_index_entry(node->undo_row, node->undo_ext, index, heap); From dd201037c2f4c2c5a740c0dfc8a2deb3cfe6733b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 1 Jun 2010 15:05:21 +0300 Subject: [PATCH 003/112] Document the Bug #53812 fix. --- storage/innodb_plugin/ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 89823642957..a53f765aac6 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,9 @@ +2010-06-01 The InnoDB Team + + * row/row0umod.c: + Fix Bug#53812 assert row/row0umod.c line 660 in txn rollback + after crash recovery + 2010-05-25 The InnoDB Team * handler/ha_innodb.cc, include/row0mysql.h, row/row0mysql.c: From 90cb7fa43208d76fcc2e15caa40054f5d754dd58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 1 Jun 2010 15:07:51 +0300 Subject: [PATCH 004/112] Minor cleanup. lock_rec_unlock(): Cache first_lock and rewrite while() loops as for(). btr_cur_optimistic_update(): Use common error handling return. row_create_prebuilt(): Add Valgrind instrumentation. --- storage/innodb_plugin/btr/btr0cur.c | 10 +++---- storage/innodb_plugin/lock/lock0lock.c | 40 +++++++++++--------------- storage/innodb_plugin/row/row0mysql.c | 2 ++ 3 files changed, 23 insertions(+), 29 deletions(-) diff --git a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0cur.c index 6270aa6a727..50531ad3bd7 100644 --- a/storage/innodb_plugin/btr/btr0cur.c +++ b/storage/innodb_plugin/btr/btr0cur.c @@ -1959,9 +1959,8 @@ any_extern: err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info, thr, mtr, &roll_ptr); if (err != DB_SUCCESS) { -err_exit: - mem_heap_free(heap); - return(err); + + goto err_exit; } /* Ok, we may do the replacement. Store on the page infimum the @@ -2007,9 +2006,10 @@ err_exit: page_cur_move_to_next(page_cursor); + err = DB_SUCCESS; +err_exit: mem_heap_free(heap); - - return(DB_SUCCESS); + return(err); } /*************************************************************//** diff --git a/storage/innodb_plugin/lock/lock0lock.c b/storage/innodb_plugin/lock/lock0lock.c index 04e5fe1a65a..d6d9f6668da 100644 --- a/storage/innodb_plugin/lock/lock0lock.c +++ b/storage/innodb_plugin/lock/lock0lock.c @@ -3935,8 +3935,8 @@ lock_rec_unlock( const rec_t* rec, /*!< in: record */ enum lock_mode lock_mode)/*!< in: LOCK_S or LOCK_X */ { + lock_t* first_lock; lock_t* lock; - lock_t* release_lock = NULL; ulint heap_no; ut_ad(trx && rec); @@ -3946,48 +3946,40 @@ lock_rec_unlock( mutex_enter(&kernel_mutex); - lock = lock_rec_get_first(block, heap_no); + first_lock = lock_rec_get_first(block, heap_no); /* Find the last lock with the same lock_mode and transaction from the record. */ - while (lock != NULL) { + for (lock = first_lock; lock != NULL; + lock = lock_rec_get_next(heap_no, lock)) { if (lock->trx == trx && lock_get_mode(lock) == lock_mode) { - release_lock = lock; ut_a(!lock_get_wait(lock)); + lock_rec_reset_nth_bit(lock, heap_no); + goto released; } - - lock = lock_rec_get_next(heap_no, lock); } - /* If a record lock is found, release the record lock */ + mutex_exit(&kernel_mutex); + ut_print_timestamp(stderr); + fprintf(stderr, + " InnoDB: Error: unlock row could not" + " find a %lu mode lock on the record\n", + (ulong) lock_mode); - if (UNIV_LIKELY(release_lock != NULL)) { - lock_rec_reset_nth_bit(release_lock, heap_no); - } else { - mutex_exit(&kernel_mutex); - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Error: unlock row could not" - " find a %lu mode lock on the record\n", - (ulong) lock_mode); - - return; - } + return; +released: /* Check if we can now grant waiting lock requests */ - lock = lock_rec_get_first(block, heap_no); - - while (lock != NULL) { + for (lock = first_lock; lock != NULL; + lock = lock_rec_get_next(heap_no, lock)) { if (lock_get_wait(lock) && !lock_rec_has_to_wait_in_queue(lock)) { /* Grant the lock */ lock_grant(lock); } - - lock = lock_rec_get_next(heap_no, lock); } mutex_exit(&kernel_mutex); diff --git a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c index 8d47d0f25fc..c093925fc73 100644 --- a/storage/innodb_plugin/row/row0mysql.c +++ b/storage/innodb_plugin/row/row0mysql.c @@ -625,6 +625,8 @@ row_create_prebuilt( prebuilt->select_lock_type = LOCK_NONE; prebuilt->stored_select_lock_type = 99999999; + UNIV_MEM_INVALID(&prebuilt->stored_select_lock_type, + sizeof prebuilt->stored_select_lock_type); prebuilt->search_tuple = dtuple_create( heap, 2 * dict_table_get_n_cols(table)); From 6e569dd209bc2ca82886df6379baa1de3293b803 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 1 Jun 2010 16:43:35 +0300 Subject: [PATCH 005/112] Bug#48197: Concurrent rw_lock_free may cause assertion failure rw_lock_t: Remove magic_n unless UNIV_DEBUG is defined. rw_lock_free(): Invalidate magic_n only after removing from rw_lock_list. --- storage/innodb_plugin/include/sync0rw.h | 5 +++-- storage/innodb_plugin/sync/sync0rw.c | 24 ++++++++++-------------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/storage/innodb_plugin/include/sync0rw.h b/storage/innodb_plugin/include/sync0rw.h index 6f7e13220c1..175f3deb77c 100644 --- a/storage/innodb_plugin/include/sync0rw.h +++ b/storage/innodb_plugin/include/sync0rw.h @@ -555,11 +555,12 @@ struct rw_lock_struct { unsigned cline:14; /*!< Line where created */ unsigned last_s_line:14; /*!< Line number where last time s-locked */ unsigned last_x_line:14; /*!< Line number where last time x-locked */ +#ifdef UNIV_DEBUG ulint magic_n; /*!< RW_LOCK_MAGIC_N */ -}; - /** Value of rw_lock_struct::magic_n */ #define RW_LOCK_MAGIC_N 22643 +#endif /* UNIV_DEBUG */ +}; #ifdef UNIV_SYNC_DEBUG /** The structure for storing debug info of an rw-lock */ diff --git a/storage/innodb_plugin/sync/sync0rw.c b/storage/innodb_plugin/sync/sync0rw.c index d231b6acdf7..52eaa5d0f43 100644 --- a/storage/innodb_plugin/sync/sync0rw.c +++ b/storage/innodb_plugin/sync/sync0rw.c @@ -267,7 +267,7 @@ rw_lock_create_func( lock->level = level; #endif /* UNIV_SYNC_DEBUG */ - lock->magic_n = RW_LOCK_MAGIC_N; + ut_d(lock->magic_n = RW_LOCK_MAGIC_N); lock->cfile_name = cfile_name; lock->cline = (unsigned int) cline; @@ -282,10 +282,8 @@ rw_lock_create_func( mutex_enter(&rw_lock_list_mutex); - if (UT_LIST_GET_LEN(rw_lock_list) > 0) { - ut_a(UT_LIST_GET_FIRST(rw_lock_list)->magic_n - == RW_LOCK_MAGIC_N); - } + ut_ad(UT_LIST_GET_FIRST(rw_lock_list) == NULL + || UT_LIST_GET_FIRST(rw_lock_list)->magic_n == RW_LOCK_MAGIC_N); UT_LIST_ADD_FIRST(list, rw_lock_list, lock); @@ -305,8 +303,6 @@ rw_lock_free( ut_ad(rw_lock_validate(lock)); ut_a(lock->lock_word == X_LOCK_DECR); - lock->magic_n = 0; - #ifndef INNODB_RW_LOCKS_USE_ATOMICS mutex_free(rw_lock_get_mutex(lock)); #endif /* INNODB_RW_LOCKS_USE_ATOMICS */ @@ -316,16 +312,16 @@ rw_lock_free( os_event_free(lock->wait_ex_event); - if (UT_LIST_GET_PREV(list, lock)) { - ut_a(UT_LIST_GET_PREV(list, lock)->magic_n == RW_LOCK_MAGIC_N); - } - if (UT_LIST_GET_NEXT(list, lock)) { - ut_a(UT_LIST_GET_NEXT(list, lock)->magic_n == RW_LOCK_MAGIC_N); - } + ut_ad(UT_LIST_GET_PREV(list, lock) == NULL + || UT_LIST_GET_PREV(list, lock)->magic_n == RW_LOCK_MAGIC_N); + ut_ad(UT_LIST_GET_NEXT(list, lock) == NULL + || UT_LIST_GET_NEXT(list, lock)->magic_n == RW_LOCK_MAGIC_N); UT_LIST_REMOVE(list, rw_lock_list, lock); mutex_exit(&rw_lock_list_mutex); + + ut_d(lock->magic_n = 0); } #ifdef UNIV_DEBUG @@ -344,7 +340,7 @@ rw_lock_validate( ulint waiters = rw_lock_get_waiters(lock); lint lock_word = lock->lock_word; - ut_a(lock->magic_n == RW_LOCK_MAGIC_N); + ut_ad(lock->magic_n == RW_LOCK_MAGIC_N); ut_a(waiters == 0 || waiters == 1); ut_a(lock_word > -X_LOCK_DECR ||(-lock_word) % X_LOCK_DECR == 0); From 9f278a36822455c36e525617b5822e0061dfe9ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 1 Jun 2010 16:58:02 +0300 Subject: [PATCH 006/112] Document Bug #48197 fix --- storage/innodb_plugin/ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index a53f765aac6..c90b401f0f8 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,8 @@ +2010-06-01 The InnoDB Team + + * include/sync0rw.h, sync/sync0rw.c: + Fix Bug#48197 Concurrent rw_lock_free may cause assertion failure + 2010-06-01 The InnoDB Team * row/row0umod.c: From 742e8c2ad94f60bcb33420948025c54d442e107c Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 2 Jun 2010 11:42:37 +0300 Subject: [PATCH 007/112] changed the tree name --- .bzr-mysql/default.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 557df1b1ffe..f79c1cd6319 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] post_commit_to = "commits@lists.mysql.com" post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.0-bugteam" +tree_name = "mysql-5.0" From b55ec587016db5af04acd6800eb04c6a427527b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 2 Jun 2010 13:19:40 +0300 Subject: [PATCH 008/112] fil_print_orphaned_tablespaces(): Unused function, remove. --- storage/innodb_plugin/fil/fil0fil.c | 33 ------------------------- storage/innodb_plugin/include/fil0fil.h | 10 -------- 2 files changed, 43 deletions(-) diff --git a/storage/innodb_plugin/fil/fil0fil.c b/storage/innodb_plugin/fil/fil0fil.c index af85e14f226..219eb5f500f 100644 --- a/storage/innodb_plugin/fil/fil0fil.c +++ b/storage/innodb_plugin/fil/fil0fil.c @@ -3542,39 +3542,6 @@ next_datadir_item: return(err); } -/********************************************************************//** -If we need crash recovery, and we have called -fil_load_single_table_tablespaces() and dict_load_single_table_tablespaces(), -we can call this function to print an error message of orphaned .ibd files -for which there is not a data dictionary entry with a matching table name -and space id. */ -UNIV_INTERN -void -fil_print_orphaned_tablespaces(void) -/*================================*/ -{ - fil_space_t* space; - - mutex_enter(&fil_system->mutex); - - space = UT_LIST_GET_FIRST(fil_system->space_list); - - while (space) { - if (space->purpose == FIL_TABLESPACE && space->id != 0 - && !space->mark) { - fputs("InnoDB: Warning: tablespace ", stderr); - ut_print_filename(stderr, space->name); - fprintf(stderr, " of id %lu has no matching table in\n" - "InnoDB: the InnoDB data dictionary.\n", - (ulong) space->id); - } - - space = UT_LIST_GET_NEXT(space_list, space); - } - - mutex_exit(&fil_system->mutex); -} - /*******************************************************************//** Returns TRUE if a single-table tablespace does not exist in the memory cache, or is being deleted there. diff --git a/storage/innodb_plugin/include/fil0fil.h b/storage/innodb_plugin/include/fil0fil.h index 10c3ff025ac..c894875b352 100644 --- a/storage/innodb_plugin/include/fil0fil.h +++ b/storage/innodb_plugin/include/fil0fil.h @@ -506,16 +506,6 @@ UNIV_INTERN ulint fil_load_single_table_tablespaces(void); /*===================================*/ -/********************************************************************//** -If we need crash recovery, and we have called -fil_load_single_table_tablespaces() and dict_load_single_table_tablespaces(), -we can call this function to print an error message of orphaned .ibd files -for which there is not a data dictionary entry with a matching table name -and space id. */ -UNIV_INTERN -void -fil_print_orphaned_tablespaces(void); -/*================================*/ /*******************************************************************//** Returns TRUE if a single-table tablespace does not exist in the memory cache, or is being deleted there. From 306e1338a5c4480d057e7647943aa1eb150e4cef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 2 Jun 2010 13:26:37 +0300 Subject: [PATCH 009/112] Bug#53674: InnoDB: Error: unlock row could not find a 4 mode lock on the record In semi-consistent read, only unlock freshly locked non-matching records. Define DB_SUCCESS_LOCKED_REC for indicating a successful operation where a record lock was created. lock_rec_lock_fast(): Return LOCK_REC_SUCCESS, LOCK_REC_SUCCESS_CREATED, or LOCK_REC_FAIL instead of TRUE/FALSE. lock_sec_rec_read_check_and_lock(), lock_clust_rec_read_check_and_lock(), lock_rec_enqueue_waiting(), lock_rec_lock_slow(), lock_rec_lock(), row_ins_set_shared_rec_lock(), row_ins_set_exclusive_rec_lock(), sel_set_rec_lock(), row_sel_get_clust_rec_for_mysql(): Return DB_SUCCESS_LOCKED_REC if a new record lock was created. Adjust callers. row_unlock_for_mysql(): Correct the function documentation. row_prebuilt_t::new_rec_locks: Correct the documentation. --- .../suite/innodb/r/innodb_bug53674.result | 11 ++ .../suite/innodb/t/innodb_bug53674-master.opt | 1 + .../suite/innodb/t/innodb_bug53674.test | 8 + storage/innobase/include/db0err.h | 2 + storage/innobase/include/lock0lock.h | 12 +- storage/innobase/include/row0mysql.h | 43 +++--- storage/innobase/lock/lock0lock.c | 138 ++++++++++------- storage/innobase/row/row0ins.c | 146 +++++++++--------- storage/innobase/row/row0mysql.c | 20 ++- storage/innobase/row/row0sel.c | 124 ++++++++++----- 10 files changed, 295 insertions(+), 210 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb_bug53674.result create mode 100644 mysql-test/suite/innodb/t/innodb_bug53674-master.opt create mode 100644 mysql-test/suite/innodb/t/innodb_bug53674.test diff --git a/mysql-test/suite/innodb/r/innodb_bug53674.result b/mysql-test/suite/innodb/r/innodb_bug53674.result new file mode 100644 index 00000000000..c4021c2e7cd --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug53674.result @@ -0,0 +1,11 @@ +create table bug53674(a int)engine=innodb; +insert into bug53674 values (1),(2); +start transaction; +select * from bug53674 for update; +a +1 +2 +select * from bug53674 where a=(select a from bug53674 where a > 1); +a +2 +drop table bug53674; diff --git a/mysql-test/suite/innodb/t/innodb_bug53674-master.opt b/mysql-test/suite/innodb/t/innodb_bug53674-master.opt new file mode 100644 index 00000000000..f1cfd7ab6c7 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug53674-master.opt @@ -0,0 +1 @@ +--log-bin --innodb-locks-unsafe-for-binlog --binlog-format=mixed diff --git a/mysql-test/suite/innodb/t/innodb_bug53674.test b/mysql-test/suite/innodb/t/innodb_bug53674.test new file mode 100644 index 00000000000..47f67f109c3 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug53674.test @@ -0,0 +1,8 @@ +-- source include/have_innodb.inc + +create table bug53674(a int)engine=innodb; +insert into bug53674 values (1),(2); +start transaction; +select * from bug53674 for update; +select * from bug53674 where a=(select a from bug53674 where a > 1); +drop table bug53674; diff --git a/storage/innobase/include/db0err.h b/storage/innobase/include/db0err.h index b1461689d38..2be6005622d 100644 --- a/storage/innobase/include/db0err.h +++ b/storage/innobase/include/db0err.h @@ -10,6 +10,8 @@ Created 5/24/1996 Heikki Tuuri #define db0err_h +#define DB_SUCCESS_LOCKED_REC 9 /* like DB_SUCCESS, but a new + explicit record lock was created */ #define DB_SUCCESS 10 /* The following are error codes */ diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h index beaf17eda01..70b141eafeb 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -292,14 +292,15 @@ lock_sec_rec_modify_check_and_lock( dict_index_t* index, /* in: secondary index */ que_thr_t* thr); /* in: query thread */ /************************************************************************* -Like the counterpart for a clustered index below, but now we read a +Like lock_clust_rec_read_check_and_lock(), but reads a secondary index record. */ ulint lock_sec_rec_read_check_and_lock( /*=============================*/ - /* out: DB_SUCCESS, DB_LOCK_WAIT, - DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ + /* out: DB_SUCCESS, DB_SUCCESS_LOCKED_REC, + DB_LOCK_WAIT, DB_DEADLOCK, + or DB_QUE_THR_SUSPENDED */ ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set, does nothing */ rec_t* rec, /* in: user record or page supremum record @@ -324,8 +325,9 @@ lock on the record. */ ulint lock_clust_rec_read_check_and_lock( /*===============================*/ - /* out: DB_SUCCESS, DB_LOCK_WAIT, - DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ + /* out: DB_SUCCESS, DB_SUCCESS_LOCKED_REC, + DB_LOCK_WAIT, DB_DEADLOCK, + or DB_QUE_THR_SUSPENDED */ ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set, does nothing */ rec_t* rec, /* in: user record or page supremum record diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index 40fcdbb9548..488177791a4 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -246,22 +246,20 @@ row_update_for_mysql( row_prebuilt_t* prebuilt); /* in: prebuilt struct in MySQL handle */ /************************************************************************* -This can only be used when srv_locks_unsafe_for_binlog is TRUE or -session is using a READ COMMITTED isolation level. Before -calling this function we must use trx_reset_new_rec_lock_info() and -trx_register_new_rec_lock() to store the information which new record locks -really were set. This function removes a newly set lock under prebuilt->pcur, -and also under prebuilt->clust_pcur. Currently, this is only used and tested -in the case of an UPDATE or a DELETE statement, where the row lock is of the -LOCK_X type. -Thus, this implements a 'mini-rollback' that releases the latest record -locks we set. */ +This can only be used when srv_locks_unsafe_for_binlog is TRUE or this +session is using a READ COMMITTED or READ UNCOMMITTED isolation level. +Before calling this function row_search_for_mysql() must have +initialized prebuilt->new_rec_locks to store the information which new +record locks really were set. This function removes a newly set +clustered index record lock under prebuilt->pcur or +prebuilt->clust_pcur. Thus, this implements a 'mini-rollback' that +releases the latest clustered index record lock we set. */ int row_unlock_for_mysql( /*=================*/ /* out: error code or DB_SUCCESS */ - row_prebuilt_t* prebuilt, /* in: prebuilt struct in MySQL + row_prebuilt_t* prebuilt, /* in/out: prebuilt struct in MySQL handle */ ibool has_latches_on_recs);/* TRUE if called so that we have the latches on the records under pcur @@ -660,18 +658,17 @@ struct row_prebuilt_struct { ulint new_rec_locks; /* normally 0; if srv_locks_unsafe_for_binlog is TRUE or session is using READ - COMMITTED isolation level, in a - cursor search, if we set a new - record lock on an index, this is - incremented; this is used in - releasing the locks under the - cursors if we are performing an - UPDATE and we determine after - retrieving the row that it does - not need to be locked; thus, - these can be used to implement a - 'mini-rollback' that releases - the latest record locks */ + COMMITTED or READ UNCOMMITTED + isolation level, set in + row_search_for_mysql() if we set a new + record lock on the secondary + or clustered index; this is + used in row_unlock_for_mysql() + when releasing the lock under + the cursor if we determine + after retrieving the row that + it does not need to be locked + ('mini-rollback') */ ulint mysql_prefix_len;/* byte offset of the end of the last requested column */ ulint mysql_row_len; /* length in bytes of a row in the diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c index 7df8ea50887..04240960b3a 100644 --- a/storage/innobase/lock/lock0lock.c +++ b/storage/innobase/lock/lock0lock.c @@ -1739,11 +1739,12 @@ ulint lock_rec_enqueue_waiting( /*=====================*/ /* out: DB_LOCK_WAIT, DB_DEADLOCK, or - DB_QUE_THR_SUSPENDED, or DB_SUCCESS; - DB_SUCCESS means that there was a deadlock, - but another transaction was chosen as a - victim, and we got the lock immediately: - no need to wait then */ + DB_QUE_THR_SUSPENDED, or DB_SUCCESS_LOCKED_REC; + DB_SUCCESS_LOCKED_REC means that there + was a deadlock, but another + transaction was chosen as a victim, + and we got the lock immediately: no + need to wait then */ ulint type_mode,/* in: lock mode this transaction is requesting: LOCK_S or LOCK_X, possibly ORed with LOCK_GAP or LOCK_REC_NOT_GAP, ORed @@ -1804,7 +1805,7 @@ lock_rec_enqueue_waiting( if (trx->wait_lock == NULL) { - return(DB_SUCCESS); + return(DB_SUCCESS_LOCKED_REC); } trx->que_state = TRX_QUE_LOCK_WAIT; @@ -1903,6 +1904,16 @@ lock_rec_add_to_queue( return(lock_rec_create(type_mode, rec, index, trx)); } +/** Record locking request status */ +enum lock_rec_req_status { + /** Failed to acquire a lock */ + LOCK_REC_FAIL, + /** Succeeded in acquiring a lock (implicit or already acquired) */ + LOCK_REC_SUCCESS, + /** Explicitly created a new lock */ + LOCK_REC_SUCCESS_CREATED +}; + /************************************************************************* This is a fast routine for locking a record in the most common cases: there are no explicit locks on the page, or there is just one lock, owned @@ -1911,10 +1922,10 @@ which does NOT look at implicit locks! Checks lock compatibility within explicit locks. This function sets a normal next-key lock, or in the case of a page supremum record, a gap type lock. */ UNIV_INLINE -ibool +enum lock_rec_req_status lock_rec_lock_fast( /*===============*/ - /* out: TRUE if locking succeeded */ + /* out: whether the locking succeeded */ ibool impl, /* in: if TRUE, no lock is set if no wait is necessary: we assume that the caller will set an implicit lock */ @@ -1950,19 +1961,19 @@ lock_rec_lock_fast( lock_rec_create(mode, rec, index, trx); } - return(TRUE); + return(LOCK_REC_SUCCESS_CREATED); } if (lock_rec_get_next_on_page(lock)) { - return(FALSE); + return(LOCK_REC_FAIL); } if (lock->trx != trx || lock->type_mode != (mode | LOCK_REC) || lock_rec_get_n_bits(lock) <= heap_no) { - return(FALSE); + return(LOCK_REC_FAIL); } if (!impl) { @@ -1971,10 +1982,11 @@ lock_rec_lock_fast( if (!lock_rec_get_nth_bit(lock, heap_no)) { lock_rec_set_nth_bit(lock, heap_no); + return(LOCK_REC_SUCCESS_CREATED); } } - return(TRUE); + return(LOCK_REC_SUCCESS); } /************************************************************************* @@ -1986,8 +1998,9 @@ static ulint lock_rec_lock_slow( /*===============*/ - /* out: DB_SUCCESS, DB_LOCK_WAIT, or error - code */ + /* out: DB_SUCCESS, DB_SUCCESS_LOCKED_REC, + DB_LOCK_WAIT, DB_DEADLOCK, + or DB_QUE_THR_SUSPENDED */ ibool impl, /* in: if TRUE, no lock is set if no wait is necessary: we assume that the caller will set an implicit lock */ @@ -1998,7 +2011,6 @@ lock_rec_lock_slow( que_thr_t* thr) /* in: query thread */ { trx_t* trx; - ulint err; ut_ad(mutex_own(&kernel_mutex)); ut_ad((LOCK_MODE_MASK & mode) != LOCK_S @@ -2017,26 +2029,21 @@ lock_rec_lock_slow( /* The trx already has a strong enough lock on rec: do nothing */ - err = DB_SUCCESS; } else if (lock_rec_other_has_conflicting(mode, rec, trx)) { /* If another transaction has a non-gap conflicting request in the queue, as this transaction does not have a lock strong enough already granted on the record, we have to wait. */ - err = lock_rec_enqueue_waiting(mode, rec, index, thr); - } else { - if (!impl) { - /* Set the requested lock on the record */ + return(lock_rec_enqueue_waiting(mode, rec, index, thr)); + } else if (!impl) { + /* Set the requested lock on the record */ - lock_rec_add_to_queue(LOCK_REC | mode, rec, index, - trx); - } - - err = DB_SUCCESS; + lock_rec_add_to_queue(LOCK_REC | mode, rec, index, trx); + return(DB_SUCCESS_LOCKED_REC); } - return(err); + return(DB_SUCCESS); } /************************************************************************* @@ -2049,8 +2056,9 @@ static ulint lock_rec_lock( /*==========*/ - /* out: DB_SUCCESS, DB_LOCK_WAIT, or error - code */ + /* out: DB_SUCCESS, DB_SUCCESS_LOCKED_REC, + DB_LOCK_WAIT, DB_DEADLOCK, or + DB_QUE_THR_SUSPENDED */ ibool impl, /* in: if TRUE, no lock is set if no wait is necessary: we assume that the caller will set an implicit lock */ @@ -2060,8 +2068,6 @@ lock_rec_lock( dict_index_t* index, /* in: index of record */ que_thr_t* thr) /* in: query thread */ { - ulint err; - ut_ad(mutex_own(&kernel_mutex)); ut_ad((LOCK_MODE_MASK & mode) != LOCK_S || lock_table_has(thr_get_trx(thr), index->table, LOCK_IS)); @@ -2073,17 +2079,19 @@ lock_rec_lock( || mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP || mode - (LOCK_MODE_MASK & mode) == 0); - if (lock_rec_lock_fast(impl, mode, rec, index, thr)) { - - /* We try a simplified and faster subroutine for the most - common cases */ - - err = DB_SUCCESS; - } else { - err = lock_rec_lock_slow(impl, mode, rec, index, thr); + /* We try a simplified and faster subroutine for the most + common cases */ + switch (lock_rec_lock_fast(impl, mode, rec, index, thr)) { + case LOCK_REC_SUCCESS: + return(DB_SUCCESS); + case LOCK_REC_SUCCESS_CREATED: + return(DB_SUCCESS_LOCKED_REC); + case LOCK_REC_FAIL: + return(lock_rec_lock_slow(impl, mode, rec, index, thr)); } - return(err); + ut_error; + return(DB_ERROR); } /************************************************************************* @@ -4832,7 +4840,7 @@ lock_rec_insert_check_and_lock( lock = lock_rec_get_first(next_rec); - if (lock == NULL) { + if (UNIV_LIKELY(lock == NULL)) { /* We optimize CPU time usage in the simplest case */ lock_mutex_exit_kernel(); @@ -4840,8 +4848,7 @@ lock_rec_insert_check_and_lock( if (!(index->type & DICT_CLUSTERED)) { /* Update the page max trx id field */ - page_update_max_trx_id(buf_frame_align(rec), - thr_get_trx(thr)->id); + page_update_max_trx_id(buf_frame_align(rec), trx->id); } return(DB_SUCCESS); @@ -4873,11 +4880,16 @@ lock_rec_insert_check_and_lock( lock_mutex_exit_kernel(); - if (!(index->type & DICT_CLUSTERED) && (err == DB_SUCCESS)) { - + switch (err) { + case DB_SUCCESS_LOCKED_REC: + err = DB_SUCCESS; + /* fall through */ + case DB_SUCCESS: + if (index->type & DICT_CLUSTERED) { + break; + } /* Update the page max trx id field */ - page_update_max_trx_id(buf_frame_align(rec), - thr_get_trx(thr)->id); + page_update_max_trx_id(buf_frame_align(rec), trx->id); } #ifdef UNIV_DEBUG @@ -4984,6 +4996,10 @@ lock_clust_rec_modify_check_and_lock( ut_ad(lock_rec_queue_validate(rec, index, offsets)); + if (UNIV_UNLIKELY(err == DB_SUCCESS_LOCKED_REC)) { + err = DB_SUCCESS; + } + return(err); } @@ -5043,25 +5059,29 @@ lock_sec_rec_modify_check_and_lock( } #endif /* UNIV_DEBUG */ - if (err == DB_SUCCESS) { + if (err == DB_SUCCESS || err == DB_SUCCESS_LOCKED_REC) { /* Update the page max trx id field */ - + /* It might not be necessary to do this if + err == DB_SUCCESS (no new lock created), + but it should not cost too much performance. */ page_update_max_trx_id(buf_frame_align(rec), thr_get_trx(thr)->id); + err = DB_SUCCESS; } return(err); } /************************************************************************* -Like the counterpart for a clustered index below, but now we read a +Like lock_clust_rec_read_check_and_lock(), but reads a secondary index record. */ ulint lock_sec_rec_read_check_and_lock( /*=============================*/ - /* out: DB_SUCCESS, DB_LOCK_WAIT, - DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ + /* out: DB_SUCCESS, DB_SUCCESS_LOCKED_REC, + DB_LOCK_WAIT, DB_DEADLOCK, + or DB_QUE_THR_SUSPENDED */ ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set, does nothing */ rec_t* rec, /* in: user record or page supremum record @@ -5126,8 +5146,9 @@ lock on the record. */ ulint lock_clust_rec_read_check_and_lock( /*===============================*/ - /* out: DB_SUCCESS, DB_LOCK_WAIT, - DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ + /* out: DB_SUCCESS, DB_SUCCESS_LOCKED_REC, + DB_LOCK_WAIT, DB_DEADLOCK, + or DB_QUE_THR_SUSPENDED */ ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set, does nothing */ rec_t* rec, /* in: user record or page supremum record @@ -5206,16 +5227,21 @@ lock_clust_rec_read_check_and_lock_alt( mem_heap_t* tmp_heap = NULL; ulint offsets_[REC_OFFS_NORMAL_SIZE]; ulint* offsets = offsets_; - ulint ret; + ulint err; *offsets_ = (sizeof offsets_) / sizeof *offsets_; offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &tmp_heap); - ret = lock_clust_rec_read_check_and_lock(flags, rec, index, + err = lock_clust_rec_read_check_and_lock(flags, rec, index, offsets, mode, gap_mode, thr); if (tmp_heap) { mem_heap_free(tmp_heap); } - return(ret); + + if (UNIV_UNLIKELY(err == DB_SUCCESS_LOCKED_REC)) { + err = DB_SUCCESS; + } + + return(err); } diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c index 51c295b5098..9786f90fd39 100644 --- a/storage/innobase/row/row0ins.c +++ b/storage/innobase/row/row0ins.c @@ -1114,7 +1114,8 @@ static ulint row_ins_set_shared_rec_lock( /*========================*/ - /* out: DB_SUCCESS or error code */ + /* out: DB_SUCCESS, DB_SUCCESS_LOCKED_REC, + or error code */ ulint type, /* in: LOCK_ORDINARY, LOCK_GAP, or LOCK_REC_NOT_GAP type lock */ rec_t* rec, /* in: record */ @@ -1145,7 +1146,8 @@ static ulint row_ins_set_exclusive_rec_lock( /*===========================*/ - /* out: DB_SUCCESS or error code */ + /* out: DB_SUCCESS, DB_SUCCESS_LOCKED_REC, + or error code */ ulint type, /* in: LOCK_ORDINARY, LOCK_GAP, or LOCK_REC_NOT_GAP type lock */ rec_t* rec, /* in: record */ @@ -1195,9 +1197,7 @@ row_ins_check_foreign_constraint( dict_table_t* check_table; dict_index_t* check_index; ulint n_fields_cmp; - rec_t* rec; btr_pcur_t pcur; - ibool moved; int cmp; ulint err; ulint i; @@ -1328,12 +1328,12 @@ run_again: /* Scan index records and check if there is a matching record */ - for (;;) { - rec = btr_pcur_get_rec(&pcur); + do { + rec_t* rec = btr_pcur_get_rec(&pcur); if (page_rec_is_infimum(rec)) { - goto next_rec; + continue; } offsets = rec_get_offsets(rec, check_index, @@ -1343,12 +1343,13 @@ run_again: err = row_ins_set_shared_rec_lock( LOCK_ORDINARY, rec, check_index, offsets, thr); - if (err != DB_SUCCESS) { - - break; + switch (err) { + case DB_SUCCESS_LOCKED_REC: + case DB_SUCCESS: + continue; + default: + goto end_scan; } - - goto next_rec; } cmp = cmp_dtuple_rec(entry, rec, offsets); @@ -1359,9 +1360,12 @@ run_again: err = row_ins_set_shared_rec_lock( LOCK_ORDINARY, rec, check_index, offsets, thr); - if (err != DB_SUCCESS) { - + switch (err) { + case DB_SUCCESS_LOCKED_REC: + case DB_SUCCESS: break; + default: + goto end_scan; } } else { /* Found a matching record. Lock only @@ -1372,15 +1376,18 @@ run_again: LOCK_REC_NOT_GAP, rec, check_index, offsets, thr); - if (err != DB_SUCCESS) { - + switch (err) { + case DB_SUCCESS_LOCKED_REC: + case DB_SUCCESS: break; + default: + goto end_scan; } if (check_ref) { err = DB_SUCCESS; - break; + goto end_scan; } else if (foreign->type != 0) { /* There is an ON UPDATE or ON DELETE condition: check them in a separate @@ -1406,7 +1413,7 @@ run_again: err = DB_FOREIGN_DUPLICATE_KEY; } - break; + goto end_scan; } } else { row_ins_foreign_report_err( @@ -1414,48 +1421,39 @@ run_again: thr, foreign, rec, entry); err = DB_ROW_IS_REFERENCED; - break; + goto end_scan; } } - } + } else { + ut_a(cmp < 0); - if (cmp < 0) { err = row_ins_set_shared_rec_lock( LOCK_GAP, rec, check_index, offsets, thr); - if (err != DB_SUCCESS) { - - break; + switch (err) { + case DB_SUCCESS_LOCKED_REC: + case DB_SUCCESS: + if (check_ref) { + err = DB_NO_REFERENCED_ROW; + row_ins_foreign_report_add_err( + trx, foreign, rec, entry); + } else { + err = DB_SUCCESS; + } } - if (check_ref) { - err = DB_NO_REFERENCED_ROW; - row_ins_foreign_report_add_err( - trx, foreign, rec, entry); - } else { - err = DB_SUCCESS; - } - - break; + goto end_scan; } + } while (btr_pcur_move_to_next(&pcur, &mtr)); - ut_a(cmp == 0); -next_rec: - moved = btr_pcur_move_to_next(&pcur, &mtr); - - if (!moved) { - if (check_ref) { - rec = btr_pcur_get_rec(&pcur); - row_ins_foreign_report_add_err( - trx, foreign, rec, entry); - err = DB_NO_REFERENCED_ROW; - } else { - err = DB_SUCCESS; - } - - break; - } + if (check_ref) { + row_ins_foreign_report_add_err( + trx, foreign, btr_pcur_get_rec(&pcur), entry); + err = DB_NO_REFERENCED_ROW; + } else { + err = DB_SUCCESS; } +end_scan: btr_pcur_close(&pcur); mtr_commit(&mtr); @@ -1641,10 +1639,8 @@ row_ins_scan_sec_index_for_duplicate( ulint i; int cmp; ulint n_fields_cmp; - rec_t* rec; btr_pcur_t pcur; ulint err = DB_SUCCESS; - ibool moved; unsigned allow_duplicates; mtr_t mtr; mem_heap_t* heap = NULL; @@ -1680,12 +1676,12 @@ row_ins_scan_sec_index_for_duplicate( /* Scan index records and check if there is a duplicate */ - for (;;) { - rec = btr_pcur_get_rec(&pcur); + do { + rec_t* rec = btr_pcur_get_rec(&pcur); if (page_rec_is_infimum(rec)) { - goto next_rec; + continue; } offsets = rec_get_offsets(rec, index, offsets, @@ -1706,14 +1702,18 @@ row_ins_scan_sec_index_for_duplicate( LOCK_ORDINARY, rec, index, offsets, thr); } - if (err != DB_SUCCESS) { - + switch (err) { + case DB_SUCCESS_LOCKED_REC: + err = DB_SUCCESS; + case DB_SUCCESS: break; + default: + goto end_scan; } if (page_rec_is_supremum(rec)) { - goto next_rec; + continue; } cmp = cmp_dtuple_rec(entry, rec, offsets); @@ -1725,23 +1725,15 @@ row_ins_scan_sec_index_for_duplicate( thr_get_trx(thr)->error_info = index; - break; + goto end_scan; } + } else { + ut_a(cmp < 0); + goto end_scan; } + } while (btr_pcur_move_to_next(&pcur, &mtr)); - if (cmp < 0) { - break; - } - - ut_a(cmp == 0); -next_rec: - moved = btr_pcur_move_to_next(&pcur, &mtr); - - if (!moved) { - break; - } - } - +end_scan: if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } @@ -1837,7 +1829,11 @@ row_ins_duplicate_error_in_clust( cursor->index, offsets, thr); } - if (err != DB_SUCCESS) { + switch (err) { + case DB_SUCCESS_LOCKED_REC: + case DB_SUCCESS: + break; + default: goto func_exit; } @@ -1875,7 +1871,11 @@ row_ins_duplicate_error_in_clust( cursor->index, offsets, thr); } - if (err != DB_SUCCESS) { + switch (err) { + case DB_SUCCESS_LOCKED_REC: + case DB_SUCCESS: + break; + default: goto func_exit; } diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index b4ce31575c7..4a834c4efc2 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -1455,22 +1455,20 @@ run_again: } /************************************************************************* -This can only be used when srv_locks_unsafe_for_binlog is TRUE or -this session is using a READ COMMITTED isolation level. Before -calling this function we must use trx_reset_new_rec_lock_info() and -trx_register_new_rec_lock() to store the information which new record locks -really were set. This function removes a newly set lock under prebuilt->pcur, -and also under prebuilt->clust_pcur. Currently, this is only used and tested -in the case of an UPDATE or a DELETE statement, where the row lock is of the -LOCK_X type. -Thus, this implements a 'mini-rollback' that releases the latest record -locks we set. */ +This can only be used when srv_locks_unsafe_for_binlog is TRUE or this +session is using a READ COMMITTED or READ UNCOMMITTED isolation level. +Before calling this function row_search_for_mysql() must have +initialized prebuilt->new_rec_locks to store the information which new +record locks really were set. This function removes a newly set +clustered index record lock under prebuilt->pcur or +prebuilt->clust_pcur. Thus, this implements a 'mini-rollback' that +releases the latest clustered index record lock we set. */ int row_unlock_for_mysql( /*=================*/ /* out: error code or DB_SUCCESS */ - row_prebuilt_t* prebuilt, /* in: prebuilt struct in MySQL + row_prebuilt_t* prebuilt, /* in/out: prebuilt struct in MySQL handle */ ibool has_latches_on_recs)/* TRUE if called so that we have the latches on the records under pcur diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c index 6912a489f75..fcc95aec9af 100644 --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c @@ -754,8 +754,14 @@ row_sel_get_clust_rec( 0, clust_rec, index, offsets, node->row_lock_mode, lock_type, thr); - if (err != DB_SUCCESS) { - + switch (err) { + case DB_SUCCESS: + case DB_SUCCESS_LOCKED_REC: + /* Declare the variable uninitialized in Valgrind. + It should be set to DB_SUCCESS at func_exit. */ + UNIV_MEM_INVALID(&err, sizeof err); + break; + default: goto err_exit; } } else { @@ -826,7 +832,8 @@ UNIV_INLINE ulint sel_set_rec_lock( /*=============*/ - /* out: DB_SUCCESS or error code */ + /* out: DB_SUCCESS, DB_SUCCESS_LOCKED_REC, + or error code */ rec_t* rec, /* in: record */ dict_index_t* index, /* in: index */ const ulint* offsets,/* in: rec_get_offsets(rec, index) */ @@ -1374,11 +1381,15 @@ rec_loop: node->row_lock_mode, lock_type, thr); - if (err != DB_SUCCESS) { + switch (err) { + case DB_SUCCESS_LOCKED_REC: + err = DB_SUCCESS; + case DB_SUCCESS: + break; + default: /* Note that in this case we will store in pcur the PREDECESSOR of the record we are waiting the lock for */ - goto lock_wait_or_error; } } @@ -1429,8 +1440,12 @@ skip_lock: err = sel_set_rec_lock(rec, index, offsets, node->row_lock_mode, lock_type, thr); - if (err != DB_SUCCESS) { - + switch (err) { + case DB_SUCCESS_LOCKED_REC: + err = DB_SUCCESS; + case DB_SUCCESS: + break; + default: goto lock_wait_or_error; } } @@ -2745,7 +2760,8 @@ static ulint row_sel_get_clust_rec_for_mysql( /*============================*/ - /* out: DB_SUCCESS or error code */ + /* out: DB_SUCCESS, DB_SUCCESS_LOCKED_REC, + or error code */ row_prebuilt_t* prebuilt,/* in: prebuilt struct in the handle */ dict_index_t* sec_index,/* in: secondary index where rec resides */ rec_t* rec, /* in: record in a non-clustered index; if @@ -2826,6 +2842,7 @@ row_sel_get_clust_rec_for_mysql( clust_rec = NULL; + err = DB_SUCCESS; goto func_exit; } @@ -2840,8 +2857,11 @@ row_sel_get_clust_rec_for_mysql( err = lock_clust_rec_read_check_and_lock( 0, clust_rec, clust_index, *offsets, prebuilt->select_lock_type, LOCK_REC_NOT_GAP, thr); - if (err != DB_SUCCESS) { - + switch (err) { + case DB_SUCCESS: + case DB_SUCCESS_LOCKED_REC: + break; + default: goto err_exit; } } else { @@ -2900,6 +2920,8 @@ row_sel_get_clust_rec_for_mysql( rec, sec_index, clust_rec, clust_index)); #endif } + + err = DB_SUCCESS; } func_exit: @@ -2912,7 +2934,6 @@ func_exit: btr_pcur_store_position(prebuilt->clust_pcur, mtr); } - err = DB_SUCCESS; err_exit: return(err); } @@ -3626,8 +3647,12 @@ shortcut_fails_too_big_rec: prebuilt->select_lock_type, LOCK_GAP, thr); - if (err != DB_SUCCESS) { - + switch (err) { + case DB_SUCCESS_LOCKED_REC: + err = DB_SUCCESS; + case DB_SUCCESS: + break; + default: goto lock_wait_or_error; } } @@ -3724,8 +3749,12 @@ rec_loop: prebuilt->select_lock_type, LOCK_ORDINARY, thr); - if (err != DB_SUCCESS) { - + switch (err) { + case DB_SUCCESS_LOCKED_REC: + err = DB_SUCCESS; + case DB_SUCCESS: + break; + default: goto lock_wait_or_error; } } @@ -3856,8 +3885,11 @@ wrong_offs: prebuilt->select_lock_type, LOCK_GAP, thr); - if (err != DB_SUCCESS) { - + switch (err) { + case DB_SUCCESS_LOCKED_REC: + case DB_SUCCESS: + break; + default: goto lock_wait_or_error; } } @@ -3891,8 +3923,11 @@ wrong_offs: prebuilt->select_lock_type, LOCK_GAP, thr); - if (err != DB_SUCCESS) { - + switch (err) { + case DB_SUCCESS_LOCKED_REC: + case DB_SUCCESS: + break; + default: goto lock_wait_or_error; } } @@ -3961,15 +3996,21 @@ no_gap_lock: switch (err) { rec_t* old_vers; - case DB_SUCCESS: + case DB_SUCCESS_LOCKED_REC: if (srv_locks_unsafe_for_binlog - || trx->isolation_level <= TRX_ISO_READ_COMMITTED) { + || trx->isolation_level + <= TRX_ISO_READ_COMMITTED) { /* Note that a record of prebuilt->index was locked. */ prebuilt->new_rec_locks = 1; } + err = DB_SUCCESS; + case DB_SUCCESS: break; case DB_LOCK_WAIT: + /* Never unlock rows that were part of a conflict. */ + prebuilt->new_rec_locks = 0; + if (UNIV_LIKELY(prebuilt->row_read_type != ROW_READ_TRY_SEMI_CONSISTENT) || unique_search @@ -3999,7 +4040,6 @@ no_gap_lock: if (UNIV_LIKELY(trx->wait_lock != NULL)) { lock_cancel_waiting_and_release( trx->wait_lock); - prebuilt->new_rec_locks = 0; } else { mutex_exit(&kernel_mutex); @@ -4011,9 +4051,6 @@ no_gap_lock: ULINT_UNDEFINED, &heap); err = DB_SUCCESS; - /* Note that a record of - prebuilt->index was locked. */ - prebuilt->new_rec_locks = 1; break; } mutex_exit(&kernel_mutex); @@ -4151,27 +4188,30 @@ requires_clust_rec: err = row_sel_get_clust_rec_for_mysql(prebuilt, index, rec, thr, &clust_rec, &offsets, &heap, &mtr); - if (err != DB_SUCCESS) { + switch (err) { + case DB_SUCCESS: + if (clust_rec == NULL) { + /* The record did not exist in the read view */ + ut_ad(prebuilt->select_lock_type == LOCK_NONE); + goto next_rec; + } + break; + case DB_SUCCESS_LOCKED_REC: + ut_a(clust_rec != NULL); + if (srv_locks_unsafe_for_binlog + || trx->isolation_level + <= TRX_ISO_READ_COMMITTED) { + /* Note that the clustered index record + was locked. */ + prebuilt->new_rec_locks = 2; + } + err = DB_SUCCESS; + break; + default: goto lock_wait_or_error; } - if (clust_rec == NULL) { - /* The record did not exist in the read view */ - ut_ad(prebuilt->select_lock_type == LOCK_NONE); - - goto next_rec; - } - - if ((srv_locks_unsafe_for_binlog - || trx->isolation_level <= TRX_ISO_READ_COMMITTED) - && prebuilt->select_lock_type != LOCK_NONE) { - /* Note that both the secondary index record - and the clustered index record were locked. */ - ut_ad(prebuilt->new_rec_locks == 1); - prebuilt->new_rec_locks = 2; - } - if (UNIV_UNLIKELY(rec_get_deleted_flag(clust_rec, comp))) { /* The record is delete marked: we can skip it */ From c84c4b107c7d471588433a4d1fa1c3b8b37dccf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 2 Jun 2010 13:37:14 +0300 Subject: [PATCH 010/112] Bug#53674: InnoDB: Error: unlock row could not find a 4 mode lock on the record In semi-consistent read, only unlock freshly locked non-matching records. lock_rec_lock_fast(): Return LOCK_REC_SUCCESS, LOCK_REC_SUCCESS_CREATED, or LOCK_REC_FAIL instead of TRUE/FALSE. enum db_err: Add DB_SUCCESS_LOCKED_REC for indicating a successful operation where a record lock was created. lock_sec_rec_read_check_and_lock(), lock_clust_rec_read_check_and_lock(), lock_rec_enqueue_waiting(), lock_rec_lock_slow(), lock_rec_lock(), row_ins_set_shared_rec_lock(), row_ins_set_exclusive_rec_lock(), sel_set_rec_lock(), row_sel_get_clust_rec_for_mysql(): Return DB_SUCCESS_LOCKED_REC if a new record lock was created. Adjust callers. row_unlock_for_mysql(): Correct the function documentation. row_prebuilt_t::new_rec_locks: Correct the documentation. --- .../innodb_plugin/r/innodb_bug53674.result | 11 ++ .../t/innodb_bug53674-master.opt | 1 + .../innodb_plugin/t/innodb_bug53674.test | 8 + storage/innodb_plugin/include/db0err.h | 2 + storage/innodb_plugin/include/lock0lock.h | 12 +- storage/innodb_plugin/include/row0mysql.h | 54 ++++--- storage/innodb_plugin/lock/lock0lock.c | 138 +++++++++++------- storage/innodb_plugin/row/row0ins.c | 130 +++++++++-------- storage/innodb_plugin/row/row0mysql.c | 31 ++-- storage/innodb_plugin/row/row0sel.c | 132 +++++++++++------ 10 files changed, 308 insertions(+), 211 deletions(-) create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_bug53674.result create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug53674-master.opt create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug53674.test diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug53674.result b/mysql-test/suite/innodb_plugin/r/innodb_bug53674.result new file mode 100644 index 00000000000..c4021c2e7cd --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug53674.result @@ -0,0 +1,11 @@ +create table bug53674(a int)engine=innodb; +insert into bug53674 values (1),(2); +start transaction; +select * from bug53674 for update; +a +1 +2 +select * from bug53674 where a=(select a from bug53674 where a > 1); +a +2 +drop table bug53674; diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug53674-master.opt b/mysql-test/suite/innodb_plugin/t/innodb_bug53674-master.opt new file mode 100644 index 00000000000..f1cfd7ab6c7 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug53674-master.opt @@ -0,0 +1 @@ +--log-bin --innodb-locks-unsafe-for-binlog --binlog-format=mixed diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug53674.test b/mysql-test/suite/innodb_plugin/t/innodb_bug53674.test new file mode 100644 index 00000000000..e3cbf4466a7 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug53674.test @@ -0,0 +1,8 @@ +-- source include/have_innodb_plugin.inc + +create table bug53674(a int)engine=innodb; +insert into bug53674 values (1),(2); +start transaction; +select * from bug53674 for update; +select * from bug53674 where a=(select a from bug53674 where a > 1); +drop table bug53674; diff --git a/storage/innodb_plugin/include/db0err.h b/storage/innodb_plugin/include/db0err.h index 747e9b5364e..c841c2b4afe 100644 --- a/storage/innodb_plugin/include/db0err.h +++ b/storage/innodb_plugin/include/db0err.h @@ -28,6 +28,8 @@ Created 5/24/1996 Heikki Tuuri enum db_err { + DB_SUCCESS_LOCKED_REC = 9, /*!< like DB_SUCCESS, but a new + explicit record lock was created */ DB_SUCCESS = 10, /* The following are error codes */ diff --git a/storage/innodb_plugin/include/lock0lock.h b/storage/innodb_plugin/include/lock0lock.h index 7d76cbe3c75..b3e1e5c4537 100644 --- a/storage/innodb_plugin/include/lock0lock.h +++ b/storage/innodb_plugin/include/lock0lock.h @@ -340,11 +340,12 @@ lock_sec_rec_modify_check_and_lock( que_thr_t* thr, /*!< in: query thread */ mtr_t* mtr); /*!< in/out: mini-transaction */ /*********************************************************************//** -Like the counterpart for a clustered index below, but now we read a +Like lock_clust_rec_read_check_and_lock(), but reads a secondary index record. -@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ +@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK, +or DB_QUE_THR_SUSPENDED */ UNIV_INTERN -ulint +enum db_err lock_sec_rec_read_check_and_lock( /*=============================*/ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG @@ -371,9 +372,10 @@ if the query thread should anyway be suspended for some reason; if not, then puts the transaction and the query thread to the lock wait state and inserts a waiting request for a record lock to the lock queue. Sets the requested mode lock on the record. -@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ +@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK, +or DB_QUE_THR_SUSPENDED */ UNIV_INTERN -ulint +enum db_err lock_clust_rec_read_check_and_lock( /*===============================*/ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG diff --git a/storage/innodb_plugin/include/row0mysql.h b/storage/innodb_plugin/include/row0mysql.h index e90742abe7c..39ea240772c 100644 --- a/storage/innodb_plugin/include/row0mysql.h +++ b/storage/innodb_plugin/include/row0mysql.h @@ -264,27 +264,26 @@ row_update_for_mysql( row_prebuilt_t* prebuilt); /*!< in: prebuilt struct in MySQL handle */ /*********************************************************************//** -This can only be used when srv_locks_unsafe_for_binlog is TRUE or -session is using a READ COMMITTED isolation level. Before -calling this function we must use trx_reset_new_rec_lock_info() and -trx_register_new_rec_lock() to store the information which new record locks -really were set. This function removes a newly set lock under prebuilt->pcur, -and also under prebuilt->clust_pcur. Currently, this is only used and tested -in the case of an UPDATE or a DELETE statement, where the row lock is of the -LOCK_X type. -Thus, this implements a 'mini-rollback' that releases the latest record -locks we set. -@return error code or DB_SUCCESS */ +This can only be used when srv_locks_unsafe_for_binlog is TRUE or this +session is using a READ COMMITTED or READ UNCOMMITTED isolation level. +Before calling this function row_search_for_mysql() must have +initialized prebuilt->new_rec_locks to store the information which new +record locks really were set. This function removes a newly set +clustered index record lock under prebuilt->pcur or +prebuilt->clust_pcur. Thus, this implements a 'mini-rollback' that +releases the latest clustered index record lock we set. +@return error code or DB_SUCCESS */ UNIV_INTERN int row_unlock_for_mysql( /*=================*/ - row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in MySQL + row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct in MySQL handle */ - ibool has_latches_on_recs);/*!< TRUE if called so that we have - the latches on the records under pcur - and clust_pcur, and we do not need to - reposition the cursors. */ + ibool has_latches_on_recs);/*!< in: TRUE if called + so that we have the latches on + the records under pcur and + clust_pcur, and we do not need + to reposition the cursors. */ /*********************************************************************//** Creates an query graph node of 'update' type to be used in the MySQL interface. @@ -702,18 +701,17 @@ struct row_prebuilt_struct { ulint new_rec_locks; /*!< normally 0; if srv_locks_unsafe_for_binlog is TRUE or session is using READ - COMMITTED isolation level, in a - cursor search, if we set a new - record lock on an index, this is - incremented; this is used in - releasing the locks under the - cursors if we are performing an - UPDATE and we determine after - retrieving the row that it does - not need to be locked; thus, - these can be used to implement a - 'mini-rollback' that releases - the latest record locks */ + COMMITTED or READ UNCOMMITTED + isolation level, set in + row_search_for_mysql() if we set a new + record lock on the secondary + or clustered index; this is + used in row_unlock_for_mysql() + when releasing the lock under + the cursor if we determine + after retrieving the row that + it does not need to be locked + ('mini-rollback') */ ulint mysql_prefix_len;/*!< byte offset of the end of the last requested column */ ulint mysql_row_len; /*!< length in bytes of a row in the diff --git a/storage/innodb_plugin/lock/lock0lock.c b/storage/innodb_plugin/lock/lock0lock.c index d6d9f6668da..77d69d11a2d 100644 --- a/storage/innodb_plugin/lock/lock0lock.c +++ b/storage/innodb_plugin/lock/lock0lock.c @@ -1733,11 +1733,11 @@ lock_rec_create( Enqueues a waiting request for a lock which cannot be granted immediately. Checks for deadlocks. @return DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED, or -DB_SUCCESS; DB_SUCCESS means that there was a deadlock, but another -transaction was chosen as a victim, and we got the lock immediately: -no need to wait then */ +DB_SUCCESS_LOCKED_REC; DB_SUCCESS_LOCKED_REC means that +there was a deadlock, but another transaction was chosen as a victim, +and we got the lock immediately: no need to wait then */ static -ulint +enum db_err lock_rec_enqueue_waiting( /*=====================*/ ulint type_mode,/*!< in: lock mode this @@ -1809,7 +1809,7 @@ lock_rec_enqueue_waiting( if (trx->wait_lock == NULL) { - return(DB_SUCCESS); + return(DB_SUCCESS_LOCKED_REC); } trx->que_state = TRX_QUE_LOCK_WAIT; @@ -1925,6 +1925,16 @@ somebody_waits: return(lock_rec_create(type_mode, block, heap_no, index, trx)); } +/** Record locking request status */ +enum lock_rec_req_status { + /** Failed to acquire a lock */ + LOCK_REC_FAIL, + /** Succeeded in acquiring a lock (implicit or already acquired) */ + LOCK_REC_SUCCESS, + /** Explicitly created a new lock */ + LOCK_REC_SUCCESS_CREATED +}; + /*********************************************************************//** This is a fast routine for locking a record in the most common cases: there are no explicit locks on the page, or there is just one lock, owned @@ -1932,9 +1942,9 @@ by this transaction, and of the right type_mode. This is a low-level function which does NOT look at implicit locks! Checks lock compatibility within explicit locks. This function sets a normal next-key lock, or in the case of a page supremum record, a gap type lock. -@return TRUE if locking succeeded */ +@return whether the locking succeeded */ UNIV_INLINE -ibool +enum lock_rec_req_status lock_rec_lock_fast( /*===============*/ ibool impl, /*!< in: if TRUE, no lock is set @@ -1973,19 +1983,19 @@ lock_rec_lock_fast( lock_rec_create(mode, block, heap_no, index, trx); } - return(TRUE); + return(LOCK_REC_SUCCESS_CREATED); } if (lock_rec_get_next_on_page(lock)) { - return(FALSE); + return(LOCK_REC_FAIL); } if (lock->trx != trx || lock->type_mode != (mode | LOCK_REC) || lock_rec_get_n_bits(lock) <= heap_no) { - return(FALSE); + return(LOCK_REC_FAIL); } if (!impl) { @@ -1994,10 +2004,11 @@ lock_rec_lock_fast( if (!lock_rec_get_nth_bit(lock, heap_no)) { lock_rec_set_nth_bit(lock, heap_no); + return(LOCK_REC_SUCCESS_CREATED); } } - return(TRUE); + return(LOCK_REC_SUCCESS); } /*********************************************************************//** @@ -2005,9 +2016,10 @@ This is the general, and slower, routine for locking a record. This is a low-level function which does NOT look at implicit locks! Checks lock compatibility within explicit locks. This function sets a normal next-key lock, or in the case of a page supremum record, a gap type lock. -@return DB_SUCCESS, DB_LOCK_WAIT, or error code */ +@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK, +or DB_QUE_THR_SUSPENDED */ static -ulint +enum db_err lock_rec_lock_slow( /*===============*/ ibool impl, /*!< in: if TRUE, no lock is set @@ -2024,7 +2036,6 @@ lock_rec_lock_slow( que_thr_t* thr) /*!< in: query thread */ { trx_t* trx; - ulint err; ut_ad(mutex_own(&kernel_mutex)); ut_ad((LOCK_MODE_MASK & mode) != LOCK_S @@ -2043,27 +2054,23 @@ lock_rec_lock_slow( /* The trx already has a strong enough lock on rec: do nothing */ - err = DB_SUCCESS; } else if (lock_rec_other_has_conflicting(mode, block, heap_no, trx)) { /* If another transaction has a non-gap conflicting request in the queue, as this transaction does not have a lock strong enough already granted on the record, we have to wait. */ - err = lock_rec_enqueue_waiting(mode, block, heap_no, - index, thr); - } else { - if (!impl) { - /* Set the requested lock on the record */ + return(lock_rec_enqueue_waiting(mode, block, heap_no, + index, thr)); + } else if (!impl) { + /* Set the requested lock on the record */ - lock_rec_add_to_queue(LOCK_REC | mode, block, - heap_no, index, trx); - } - - err = DB_SUCCESS; + lock_rec_add_to_queue(LOCK_REC | mode, block, + heap_no, index, trx); + return(DB_SUCCESS_LOCKED_REC); } - return(err); + return(DB_SUCCESS); } /*********************************************************************//** @@ -2072,9 +2079,10 @@ possible, enqueues a waiting lock request. This is a low-level function which does NOT look at implicit locks! Checks lock compatibility within explicit locks. This function sets a normal next-key lock, or in the case of a page supremum record, a gap type lock. -@return DB_SUCCESS, DB_LOCK_WAIT, or error code */ +@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK, +or DB_QUE_THR_SUSPENDED */ static -ulint +enum db_err lock_rec_lock( /*==========*/ ibool impl, /*!< in: if TRUE, no lock is set @@ -2090,8 +2098,6 @@ lock_rec_lock( dict_index_t* index, /*!< in: index of record */ que_thr_t* thr) /*!< in: query thread */ { - ulint err; - ut_ad(mutex_own(&kernel_mutex)); ut_ad((LOCK_MODE_MASK & mode) != LOCK_S || lock_table_has(thr_get_trx(thr), index->table, LOCK_IS)); @@ -2103,18 +2109,20 @@ lock_rec_lock( || mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP || mode - (LOCK_MODE_MASK & mode) == 0); - if (lock_rec_lock_fast(impl, mode, block, heap_no, index, thr)) { - - /* We try a simplified and faster subroutine for the most - common cases */ - - err = DB_SUCCESS; - } else { - err = lock_rec_lock_slow(impl, mode, block, - heap_no, index, thr); + /* We try a simplified and faster subroutine for the most + common cases */ + switch (lock_rec_lock_fast(impl, mode, block, heap_no, index, thr)) { + case LOCK_REC_SUCCESS: + return(DB_SUCCESS); + case LOCK_REC_SUCCESS_CREATED: + return(DB_SUCCESS_LOCKED_REC); + case LOCK_REC_FAIL: + return(lock_rec_lock_slow(impl, mode, block, + heap_no, index, thr)); } - return(err); + ut_error; + return(DB_ERROR); } /*********************************************************************//** @@ -5072,7 +5080,14 @@ lock_rec_insert_check_and_lock( lock_mutex_exit_kernel(); - if ((err == DB_SUCCESS) && !dict_index_is_clust(index)) { + switch (err) { + case DB_SUCCESS_LOCKED_REC: + err = DB_SUCCESS; + /* fall through */ + case DB_SUCCESS: + if (dict_index_is_clust(index)) { + break; + } /* Update the page max trx id field */ page_update_max_trx_id(block, buf_block_get_page_zip(block), @@ -5195,6 +5210,10 @@ lock_clust_rec_modify_check_and_lock( ut_ad(lock_rec_queue_validate(block, rec, index, offsets)); + if (UNIV_UNLIKELY(err == DB_SUCCESS_LOCKED_REC)) { + err = DB_SUCCESS; + } + return(err); } @@ -5261,22 +5280,27 @@ lock_sec_rec_modify_check_and_lock( } #endif /* UNIV_DEBUG */ - if (err == DB_SUCCESS) { + if (err == DB_SUCCESS || err == DB_SUCCESS_LOCKED_REC) { /* Update the page max trx id field */ + /* It might not be necessary to do this if + err == DB_SUCCESS (no new lock created), + but it should not cost too much performance. */ page_update_max_trx_id(block, buf_block_get_page_zip(block), thr_get_trx(thr)->id, mtr); + err = DB_SUCCESS; } return(err); } /*********************************************************************//** -Like the counterpart for a clustered index below, but now we read a +Like lock_clust_rec_read_check_and_lock(), but reads a secondary index record. -@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ +@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK, +or DB_QUE_THR_SUSPENDED */ UNIV_INTERN -ulint +enum db_err lock_sec_rec_read_check_and_lock( /*=============================*/ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG @@ -5297,8 +5321,8 @@ lock_sec_rec_read_check_and_lock( LOCK_REC_NOT_GAP */ que_thr_t* thr) /*!< in: query thread */ { - ulint err; - ulint heap_no; + enum db_err err; + ulint heap_no; ut_ad(!dict_index_is_clust(index)); ut_ad(block->frame == page_align(rec)); @@ -5349,9 +5373,10 @@ if the query thread should anyway be suspended for some reason; if not, then puts the transaction and the query thread to the lock wait state and inserts a waiting request for a record lock to the lock queue. Sets the requested mode lock on the record. -@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ +@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK, +or DB_QUE_THR_SUSPENDED */ UNIV_INTERN -ulint +enum db_err lock_clust_rec_read_check_and_lock( /*===============================*/ ulint flags, /*!< in: if BTR_NO_LOCKING_FLAG @@ -5372,8 +5397,8 @@ lock_clust_rec_read_check_and_lock( LOCK_REC_NOT_GAP */ que_thr_t* thr) /*!< in: query thread */ { - ulint err; - ulint heap_no; + enum db_err err; + ulint heap_no; ut_ad(dict_index_is_clust(index)); ut_ad(block->frame == page_align(rec)); @@ -5444,17 +5469,22 @@ lock_clust_rec_read_check_and_lock_alt( mem_heap_t* tmp_heap = NULL; ulint offsets_[REC_OFFS_NORMAL_SIZE]; ulint* offsets = offsets_; - ulint ret; + ulint err; rec_offs_init(offsets_); offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &tmp_heap); - ret = lock_clust_rec_read_check_and_lock(flags, block, rec, index, + err = lock_clust_rec_read_check_and_lock(flags, block, rec, index, offsets, mode, gap_mode, thr); if (tmp_heap) { mem_heap_free(tmp_heap); } - return(ret); + + if (UNIV_UNLIKELY(err == DB_SUCCESS_LOCKED_REC)) { + err = DB_SUCCESS; + } + + return(err); } /*******************************************************************//** diff --git a/storage/innodb_plugin/row/row0ins.c b/storage/innodb_plugin/row/row0ins.c index 230dc45dadc..09d2ffc7431 100644 --- a/storage/innodb_plugin/row/row0ins.c +++ b/storage/innodb_plugin/row/row0ins.c @@ -1121,9 +1121,9 @@ nonstandard_exit_func: /*********************************************************************//** Sets a shared lock on a record. Used in locking possible duplicate key records and also in checking foreign key constraints. -@return DB_SUCCESS or error code */ +@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, or error code */ static -ulint +enum db_err row_ins_set_shared_rec_lock( /*========================*/ ulint type, /*!< in: LOCK_ORDINARY, LOCK_GAP, or @@ -1134,7 +1134,7 @@ row_ins_set_shared_rec_lock( const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */ que_thr_t* thr) /*!< in: query thread */ { - ulint err; + enum db_err err; ut_ad(rec_offs_validate(rec, index, offsets)); @@ -1152,9 +1152,9 @@ row_ins_set_shared_rec_lock( /*********************************************************************//** Sets a exclusive lock on a record. Used in locking possible duplicate key records -@return DB_SUCCESS or error code */ +@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, or error code */ static -ulint +enum db_err row_ins_set_exclusive_rec_lock( /*===========================*/ ulint type, /*!< in: LOCK_ORDINARY, LOCK_GAP, or @@ -1165,7 +1165,7 @@ row_ins_set_exclusive_rec_lock( const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */ que_thr_t* thr) /*!< in: query thread */ { - ulint err; + enum db_err err; ut_ad(rec_offs_validate(rec, index, offsets)); @@ -1205,7 +1205,6 @@ row_ins_check_foreign_constraint( dict_index_t* check_index; ulint n_fields_cmp; btr_pcur_t pcur; - ibool moved; int cmp; ulint err; ulint i; @@ -1336,13 +1335,13 @@ run_again: /* Scan index records and check if there is a matching record */ - for (;;) { + do { const rec_t* rec = btr_pcur_get_rec(&pcur); const buf_block_t* block = btr_pcur_get_block(&pcur); if (page_rec_is_infimum(rec)) { - goto next_rec; + continue; } offsets = rec_get_offsets(rec, check_index, @@ -1353,12 +1352,13 @@ run_again: err = row_ins_set_shared_rec_lock(LOCK_ORDINARY, block, rec, check_index, offsets, thr); - if (err != DB_SUCCESS) { - - break; + switch (err) { + case DB_SUCCESS_LOCKED_REC: + case DB_SUCCESS: + continue; + default: + goto end_scan; } - - goto next_rec; } cmp = cmp_dtuple_rec(entry, rec, offsets); @@ -1369,9 +1369,12 @@ run_again: err = row_ins_set_shared_rec_lock( LOCK_ORDINARY, block, rec, check_index, offsets, thr); - if (err != DB_SUCCESS) { - + switch (err) { + case DB_SUCCESS_LOCKED_REC: + case DB_SUCCESS: break; + default: + goto end_scan; } } else { /* Found a matching record. Lock only @@ -1382,15 +1385,18 @@ run_again: LOCK_REC_NOT_GAP, block, rec, check_index, offsets, thr); - if (err != DB_SUCCESS) { - + switch (err) { + case DB_SUCCESS_LOCKED_REC: + case DB_SUCCESS: break; + default: + goto end_scan; } if (check_ref) { err = DB_SUCCESS; - break; + goto end_scan; } else if (foreign->type != 0) { /* There is an ON UPDATE or ON DELETE condition: check them in a separate @@ -1416,7 +1422,7 @@ run_again: err = DB_FOREIGN_DUPLICATE_KEY; } - break; + goto end_scan; } /* row_ins_foreign_check_on_constraint @@ -1429,49 +1435,41 @@ run_again: thr, foreign, rec, entry); err = DB_ROW_IS_REFERENCED; - break; + goto end_scan; } } - } + } else { + ut_a(cmp < 0); - if (cmp < 0) { err = row_ins_set_shared_rec_lock( LOCK_GAP, block, rec, check_index, offsets, thr); - if (err != DB_SUCCESS) { - break; + switch (err) { + case DB_SUCCESS_LOCKED_REC: + case DB_SUCCESS: + if (check_ref) { + err = DB_NO_REFERENCED_ROW; + row_ins_foreign_report_add_err( + trx, foreign, rec, entry); + } else { + err = DB_SUCCESS; + } } - if (check_ref) { - err = DB_NO_REFERENCED_ROW; - row_ins_foreign_report_add_err( - trx, foreign, rec, entry); - } else { - err = DB_SUCCESS; - } - - break; + goto end_scan; } + } while (btr_pcur_move_to_next(&pcur, &mtr)); - ut_a(cmp == 0); -next_rec: - moved = btr_pcur_move_to_next(&pcur, &mtr); - - if (!moved) { - if (check_ref) { - rec = btr_pcur_get_rec(&pcur); - row_ins_foreign_report_add_err( - trx, foreign, rec, entry); - err = DB_NO_REFERENCED_ROW; - } else { - err = DB_SUCCESS; - } - - break; - } + if (check_ref) { + row_ins_foreign_report_add_err( + trx, foreign, btr_pcur_get_rec(&pcur), entry); + err = DB_NO_REFERENCED_ROW; + } else { + err = DB_SUCCESS; } +end_scan: btr_pcur_close(&pcur); mtr_commit(&mtr); @@ -1719,9 +1717,13 @@ row_ins_scan_sec_index_for_duplicate( rec, index, offsets, thr); } - if (err != DB_SUCCESS) { - + switch (err) { + case DB_SUCCESS_LOCKED_REC: + err = DB_SUCCESS; + case DB_SUCCESS: break; + default: + goto end_scan; } if (page_rec_is_supremum(rec)) { @@ -1738,17 +1740,15 @@ row_ins_scan_sec_index_for_duplicate( thr_get_trx(thr)->error_info = index; - break; + goto end_scan; } + } else { + ut_a(cmp < 0); + goto end_scan; } - - if (cmp < 0) { - break; - } - - ut_a(cmp == 0); } while (btr_pcur_move_to_next(&pcur, &mtr)); +end_scan: if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } @@ -1837,7 +1837,11 @@ row_ins_duplicate_error_in_clust( cursor->index, offsets, thr); } - if (err != DB_SUCCESS) { + switch (err) { + case DB_SUCCESS_LOCKED_REC: + case DB_SUCCESS: + break; + default: goto func_exit; } @@ -1877,7 +1881,11 @@ row_ins_duplicate_error_in_clust( rec, cursor->index, offsets, thr); } - if (err != DB_SUCCESS) { + switch (err) { + case DB_SUCCESS_LOCKED_REC: + case DB_SUCCESS: + break; + default: goto func_exit; } diff --git a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c index c093925fc73..feeb7fc80b7 100644 --- a/storage/innodb_plugin/row/row0mysql.c +++ b/storage/innodb_plugin/row/row0mysql.c @@ -1430,27 +1430,26 @@ run_again: } /*********************************************************************//** -This can only be used when srv_locks_unsafe_for_binlog is TRUE or -this session is using a READ COMMITTED isolation level. Before -calling this function we must use trx_reset_new_rec_lock_info() and -trx_register_new_rec_lock() to store the information which new record locks -really were set. This function removes a newly set lock under prebuilt->pcur, -and also under prebuilt->clust_pcur. Currently, this is only used and tested -in the case of an UPDATE or a DELETE statement, where the row lock is of the -LOCK_X type. -Thus, this implements a 'mini-rollback' that releases the latest record -locks we set. -@return error code or DB_SUCCESS */ +This can only be used when srv_locks_unsafe_for_binlog is TRUE or this +session is using a READ COMMITTED or READ UNCOMMITTED isolation level. +Before calling this function row_search_for_mysql() must have +initialized prebuilt->new_rec_locks to store the information which new +record locks really were set. This function removes a newly set +clustered index record lock under prebuilt->pcur or +prebuilt->clust_pcur. Thus, this implements a 'mini-rollback' that +releases the latest clustered index record lock we set. +@return error code or DB_SUCCESS */ UNIV_INTERN int row_unlock_for_mysql( /*=================*/ - row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in MySQL + row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct in MySQL handle */ - ibool has_latches_on_recs)/*!< TRUE if called so that we have - the latches on the records under pcur - and clust_pcur, and we do not need to - reposition the cursors. */ + ibool has_latches_on_recs)/*!< in: TRUE if called so + that we have the latches on + the records under pcur and + clust_pcur, and we do not need + to reposition the cursors. */ { btr_pcur_t* pcur = prebuilt->pcur; btr_pcur_t* clust_pcur = prebuilt->clust_pcur; diff --git a/storage/innodb_plugin/row/row0sel.c b/storage/innodb_plugin/row/row0sel.c index 4d19ed93a49..a5bf361661b 100644 --- a/storage/innodb_plugin/row/row0sel.c +++ b/storage/innodb_plugin/row/row0sel.c @@ -863,8 +863,14 @@ row_sel_get_clust_rec( clust_rec, index, offsets, node->row_lock_mode, lock_type, thr); - if (err != DB_SUCCESS) { - + switch (err) { + case DB_SUCCESS: + case DB_SUCCESS_LOCKED_REC: + /* Declare the variable uninitialized in Valgrind. + It should be set to DB_SUCCESS at func_exit. */ + UNIV_MEM_INVALID(&err, sizeof err); + break; + default: goto err_exit; } } else { @@ -934,9 +940,9 @@ err_exit: /*********************************************************************//** Sets a lock on a record. -@return DB_SUCCESS or error code */ +@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, or error code */ UNIV_INLINE -ulint +enum db_err sel_set_rec_lock( /*=============*/ const buf_block_t* block, /*!< in: buffer block of rec */ @@ -948,8 +954,8 @@ sel_set_rec_lock( LOC_REC_NOT_GAP */ que_thr_t* thr) /*!< in: query thread */ { - trx_t* trx; - ulint err; + trx_t* trx; + enum db_err err; trx = thr_get_trx(thr); @@ -1482,11 +1488,15 @@ rec_loop: node->row_lock_mode, lock_type, thr); - if (err != DB_SUCCESS) { + switch (err) { + case DB_SUCCESS_LOCKED_REC: + err = DB_SUCCESS; + case DB_SUCCESS: + break; + default: /* Note that in this case we will store in pcur the PREDECESSOR of the record we are waiting the lock for */ - goto lock_wait_or_error; } } @@ -1538,8 +1548,12 @@ skip_lock: rec, index, offsets, node->row_lock_mode, lock_type, thr); - if (err != DB_SUCCESS) { - + switch (err) { + case DB_SUCCESS_LOCKED_REC: + err = DB_SUCCESS; + case DB_SUCCESS: + break; + default: goto lock_wait_or_error; } } @@ -2801,9 +2815,9 @@ row_sel_build_prev_vers_for_mysql( Retrieves the clustered index record corresponding to a record in a non-clustered index. Does the necessary locking. Used in the MySQL interface. -@return DB_SUCCESS or error code */ +@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, or error code */ static -ulint +enum db_err row_sel_get_clust_rec_for_mysql( /*============================*/ row_prebuilt_t* prebuilt,/*!< in: prebuilt struct in the handle */ @@ -2830,7 +2844,7 @@ row_sel_get_clust_rec_for_mysql( dict_index_t* clust_index; const rec_t* clust_rec; rec_t* old_vers; - ulint err; + enum db_err err; trx_t* trx; *out_rec = NULL; @@ -2889,6 +2903,7 @@ row_sel_get_clust_rec_for_mysql( clust_rec = NULL; + err = DB_SUCCESS; goto func_exit; } @@ -2904,8 +2919,11 @@ row_sel_get_clust_rec_for_mysql( 0, btr_pcur_get_block(prebuilt->clust_pcur), clust_rec, clust_index, *offsets, prebuilt->select_lock_type, LOCK_REC_NOT_GAP, thr); - if (err != DB_SUCCESS) { - + switch (err) { + case DB_SUCCESS: + case DB_SUCCESS_LOCKED_REC: + break; + default: goto err_exit; } } else { @@ -2965,6 +2983,8 @@ row_sel_get_clust_rec_for_mysql( rec, sec_index, clust_rec, clust_index)); #endif } + + err = DB_SUCCESS; } func_exit: @@ -2977,7 +2997,6 @@ func_exit: btr_pcur_store_position(prebuilt->clust_pcur, mtr); } - err = DB_SUCCESS; err_exit: return(err); } @@ -3702,8 +3721,12 @@ shortcut_fails_too_big_rec: prebuilt->select_lock_type, LOCK_GAP, thr); - if (err != DB_SUCCESS) { - + switch (err) { + case DB_SUCCESS_LOCKED_REC: + err = DB_SUCCESS; + case DB_SUCCESS: + break; + default: goto lock_wait_or_error; } } @@ -3801,8 +3824,12 @@ rec_loop: prebuilt->select_lock_type, LOCK_ORDINARY, thr); - if (err != DB_SUCCESS) { - + switch (err) { + case DB_SUCCESS_LOCKED_REC: + err = DB_SUCCESS; + case DB_SUCCESS: + break; + default: goto lock_wait_or_error; } } @@ -3932,8 +3959,11 @@ wrong_offs: prebuilt->select_lock_type, LOCK_GAP, thr); - if (err != DB_SUCCESS) { - + switch (err) { + case DB_SUCCESS_LOCKED_REC: + case DB_SUCCESS: + break; + default: goto lock_wait_or_error; } } @@ -3968,8 +3998,11 @@ wrong_offs: prebuilt->select_lock_type, LOCK_GAP, thr); - if (err != DB_SUCCESS) { - + switch (err) { + case DB_SUCCESS_LOCKED_REC: + case DB_SUCCESS: + break; + default: goto lock_wait_or_error; } } @@ -4039,15 +4072,21 @@ no_gap_lock: switch (err) { const rec_t* old_vers; - case DB_SUCCESS: + case DB_SUCCESS_LOCKED_REC: if (srv_locks_unsafe_for_binlog - || trx->isolation_level <= TRX_ISO_READ_COMMITTED) { + || trx->isolation_level + <= TRX_ISO_READ_COMMITTED) { /* Note that a record of prebuilt->index was locked. */ prebuilt->new_rec_locks = 1; } + err = DB_SUCCESS; + case DB_SUCCESS: break; case DB_LOCK_WAIT: + /* Never unlock rows that were part of a conflict. */ + prebuilt->new_rec_locks = 0; + if (UNIV_LIKELY(prebuilt->row_read_type != ROW_READ_TRY_SEMI_CONSISTENT) || unique_search @@ -4077,7 +4116,6 @@ no_gap_lock: if (UNIV_LIKELY(trx->wait_lock != NULL)) { lock_cancel_waiting_and_release( trx->wait_lock); - prebuilt->new_rec_locks = 0; } else { mutex_exit(&kernel_mutex); @@ -4089,9 +4127,6 @@ no_gap_lock: ULINT_UNDEFINED, &heap); err = DB_SUCCESS; - /* Note that a record of - prebuilt->index was locked. */ - prebuilt->new_rec_locks = 1; break; } mutex_exit(&kernel_mutex); @@ -4228,27 +4263,30 @@ requires_clust_rec: err = row_sel_get_clust_rec_for_mysql(prebuilt, index, rec, thr, &clust_rec, &offsets, &heap, &mtr); - if (err != DB_SUCCESS) { + switch (err) { + case DB_SUCCESS: + if (clust_rec == NULL) { + /* The record did not exist in the read view */ + ut_ad(prebuilt->select_lock_type == LOCK_NONE); + goto next_rec; + } + break; + case DB_SUCCESS_LOCKED_REC: + ut_a(clust_rec != NULL); + if (srv_locks_unsafe_for_binlog + || trx->isolation_level + <= TRX_ISO_READ_COMMITTED) { + /* Note that the clustered index record + was locked. */ + prebuilt->new_rec_locks = 2; + } + err = DB_SUCCESS; + break; + default: goto lock_wait_or_error; } - if (clust_rec == NULL) { - /* The record did not exist in the read view */ - ut_ad(prebuilt->select_lock_type == LOCK_NONE); - - goto next_rec; - } - - if ((srv_locks_unsafe_for_binlog - || trx->isolation_level <= TRX_ISO_READ_COMMITTED) - && prebuilt->select_lock_type != LOCK_NONE) { - /* Note that both the secondary index record - and the clustered index record were locked. */ - ut_ad(prebuilt->new_rec_locks == 1); - prebuilt->new_rec_locks = 2; - } - if (UNIV_UNLIKELY(rec_get_deleted_flag(clust_rec, comp))) { /* The record is delete marked: we can skip it */ From 3ac0b6f2031fbc3cbcc79c420909d9521eb64e36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 2 Jun 2010 13:39:03 +0300 Subject: [PATCH 011/112] Document the Bug #53674 fix in the InnoDB Plugin --- storage/innodb_plugin/ChangeLog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index c90b401f0f8..20775b41ca8 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,10 @@ +2010-06-02 The InnoDB Team + + * include/db0err.h, include/lock0lock.h, include/row0mysql.h, + lock/lock0lock.c, row/row0ins.c, row/row0mysql.c, row/row0sel.c: + Fix Bug#53674 InnoDB: Error: unlock row could not find a + 4 mode lock on the record + 2010-06-01 The InnoDB Team * include/sync0rw.h, sync/sync0rw.c: From dbafe6be280113636ae647add0978c64c96985e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 3 Jun 2010 12:45:34 +0300 Subject: [PATCH 012/112] Add innodb_plugin to mysql-test-run default suites. --- mysql-test/mysql-test-run.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index a35741bebda..01d1fbfe319 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -129,7 +129,7 @@ my $path_config_file; # The generated config file, var/my.cnf # executables will be used by the test suite. our $opt_vs_config = $ENV{'MTR_VS_CONFIG'}; -my $DEFAULT_SUITES= "main,binlog,federated,rpl,rpl_ndb,ndb,innodb"; +my $DEFAULT_SUITES= "main,binlog,federated,rpl,rpl_ndb,ndb,innodb,innodb_plugin"; my $opt_suites; our $opt_verbose= 0; # Verbose output, enable with --verbose From 05bf36cbb0deccf2da84e3ef251d817db416f055 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 3 Jun 2010 12:46:37 +0300 Subject: [PATCH 013/112] Source have_innodb_plugin.inc in the plugin tests. --- mysql-test/suite/innodb_plugin/t/innodb_bug53592.test | 2 +- mysql-test/suite/innodb_plugin/t/innodb_multi_update.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug53592.test b/mysql-test/suite/innodb_plugin/t/innodb_bug53592.test index ca2bd41b137..aec331e031b 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb_bug53592.test +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug53592.test @@ -2,7 +2,7 @@ # table after fast alter table added unique key". The fix is to make # sure index number lookup should go through "index translation table". ---source include/have_innodb.inc +--source include/have_innodb_plugin.inc # Use FIC for index creation set old_alter_table=0; diff --git a/mysql-test/suite/innodb_plugin/t/innodb_multi_update.test b/mysql-test/suite/innodb_plugin/t/innodb_multi_update.test index 7ab17ccf70a..890889301e6 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb_multi_update.test +++ b/mysql-test/suite/innodb_plugin/t/innodb_multi_update.test @@ -1,4 +1,4 @@ --- source include/have_innodb.inc +-- source include/have_innodb_plugin.inc # # Test multi update with different join methods From afb7f96b068e7fcd1e1dafc53384fd98f938a46a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 3 Jun 2010 12:48:59 +0300 Subject: [PATCH 014/112] Copy built-in InnoDB tests to mysql-test/suite/innodb_plugin. --- .../r/innodb-autoinc-optimize.result | 9 + .../suite/innodb_plugin/r/innodb-ucs2.result | 314 +++ .../r/innodb_autoinc_lock_mode_zero.result | 39 + .../innodb_plugin/r/innodb_bug30919.result | 1043 ++++++++ .../innodb_plugin/r/innodb_bug42419.result | 17 + .../suite/innodb_plugin/r/innodb_gis.result | 589 ++++ .../r/innodb_lock_wait_timeout_1.result | 375 +++ .../suite/innodb_plugin/r/innodb_mysql.result | 2381 +++++++++++++++++ .../innodb_plugin/r/innodb_mysql_rbk.result | 21 + .../innodb_plugin/r/innodb_notembedded.result | 23 + .../r/innodb_timeout_rollback.result | 36 + .../t/innodb-autoinc-optimize.test | 19 + .../suite/innodb_plugin/t/innodb-ucs2.test | 230 ++ .../innodb_autoinc_lock_mode_zero-master.opt | 1 + .../t/innodb_autoinc_lock_mode_zero.test | 44 + .../t/innodb_bug30919-master.opt | 1 + .../innodb_plugin/t/innodb_bug30919.test | 68 + .../innodb_plugin/t/innodb_bug42419.test | 78 + .../suite/innodb_plugin/t/innodb_gis.test | 10 + .../t/innodb_lock_wait_timeout_1-master.opt | 1 + .../t/innodb_lock_wait_timeout_1.test | 264 ++ .../innodb_plugin/t/innodb_mysql-master.opt | 1 + .../suite/innodb_plugin/t/innodb_mysql.test | 622 +++++ .../t/innodb_mysql_rbk-master.opt | 1 + .../innodb_plugin/t/innodb_mysql_rbk.test | 35 + .../innodb_plugin/t/innodb_notembedded.test | 50 + .../t/innodb_timeout_rollback-master.opt | 1 + .../t/innodb_timeout_rollback.test | 5 + 28 files changed, 6278 insertions(+) create mode 100644 mysql-test/suite/innodb_plugin/r/innodb-autoinc-optimize.result create mode 100644 mysql-test/suite/innodb_plugin/r/innodb-ucs2.result create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_autoinc_lock_mode_zero.result create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_bug30919.result create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_bug42419.result create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_gis.result create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_lock_wait_timeout_1.result create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_mysql.result create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_mysql_rbk.result create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_notembedded.result create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_timeout_rollback.result create mode 100644 mysql-test/suite/innodb_plugin/t/innodb-autoinc-optimize.test create mode 100644 mysql-test/suite/innodb_plugin/t/innodb-ucs2.test create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_autoinc_lock_mode_zero-master.opt create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_autoinc_lock_mode_zero.test create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug30919-master.opt create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug30919.test create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug42419.test create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_gis.test create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_lock_wait_timeout_1-master.opt create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_lock_wait_timeout_1.test create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_mysql-master.opt create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_mysql.test create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_mysql_rbk-master.opt create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_mysql_rbk.test create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_notembedded.test create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_timeout_rollback-master.opt create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_timeout_rollback.test diff --git a/mysql-test/suite/innodb_plugin/r/innodb-autoinc-optimize.result b/mysql-test/suite/innodb_plugin/r/innodb-autoinc-optimize.result new file mode 100644 index 00000000000..c6da43555b2 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb-autoinc-optimize.result @@ -0,0 +1,9 @@ +drop table if exists t1; +create table t1(a int not null auto_increment primary key) engine=innodb; +insert into t1 set a = -1; +optimize table t1; +Table Op Msg_type Msg_text +test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize status OK +==== clean up ==== +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_plugin/r/innodb-ucs2.result b/mysql-test/suite/innodb_plugin/r/innodb-ucs2.result new file mode 100644 index 00000000000..b6bff7d5f42 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb-ucs2.result @@ -0,0 +1,314 @@ +drop table if exists t1, t2; +create table t1 ( +a int, b char(10), c char(10), filler char(10), primary key(a, b(2)), unique key (a, c(2)) +) character set utf8 engine = innodb; +create table t2 ( +a int, b char(10), c char(10), filler char(10), primary key(a, b(2)), unique key (a, c(2)) +) character set ucs2 engine = innodb; +insert into t1 values (1,'abcdefg','abcdefg','one'); +insert into t1 values (2,'ijkilmn','ijkilmn','two'); +insert into t1 values (3,'qrstuvw','qrstuvw','three'); +insert into t1 values (4,_utf8 0xe880bd,_utf8 0xe880bd,'four'); +insert into t1 values (4,_utf8 0x5b,_utf8 0x5b,'five'); +insert into t1 values (4,_utf8 0xe880bde880bd,_utf8 0xe880bde880bd,'six'); +insert into t1 values (4,_utf8 0xe880bdD0B1e880bd,_utf8 0xe880bdD0B1e880bd,'seven'); +insert into t1 values (4,_utf8 0xD0B1,_utf8 0xD0B1,'eight'); +insert into t2 values (1,'abcdefg','abcdefg','one'); +insert into t2 values (2,'ijkilmn','ijkilmn','two'); +insert into t2 values (3,'qrstuvw','qrstuvw','three'); +insert into t2 values (4,_ucs2 0x00e400,_ucs2 0x00e400,'four'); +insert into t2 values (4,_ucs2 0x00640065,_ucs2 0x00640065,'five'); +insert into t2 values (4,_ucs2 0x00e400e50068,_ucs2 0x00e400e50068,'six'); +insert into t2 values (4,_ucs2 0x01fc,_ucs2 0x01fc,'seven'); +insert into t2 values (4,_ucs2 0x0120,_ucs2 0x0120,'eight'); +insert into t2 values (4,_ucs2 0x0563,_ucs2 0x0563,'ten'); +insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven'); +insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point'); +insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken'); +update t1 set filler = 'boo' where a = 1; +update t2 set filler ='email' where a = 4; +select a,hex(b),hex(c),filler from t1 order by filler; +a hex(b) hex(c) filler +1 61626364656667 61626364656667 boo +4 D0B1 D0B1 eight +4 5B 5B five +4 E880BD E880BD four +4 E880BDD0B1E880BD E880BDD0B1E880BD seven +4 E880BDE880BD E880BDE880BD six +3 71727374757677 71727374757677 three +2 696A6B696C6D6E 696A6B696C6D6E two +select a,hex(b),hex(c),filler from t2 order by filler; +a hex(b) hex(c) filler +4 05630563 05630563 email +4 0563 0563 email +4 05612020 05612020 email +4 01FC 01FC email +4 0120 0120 email +4 00640065 00640065 email +4 00E400E50068 00E400E50068 email +4 0000E400 0000E400 email +4 0000563001FC0563 0000563001FC0563 email +1 0061006200630064006500660067 0061006200630064006500660067 one +3 0071007200730074007500760077 0071007200730074007500760077 three +2 0069006A006B0069006C006D006E 0069006A006B0069006C006D006E two +drop table t1; +drop table t2; +create table t1 ( +a int, b varchar(10), c varchar(10), filler varchar(10), primary key(a, b(2)), unique key (a, c(2)) +) character set utf8 engine = innodb; +create table t2 ( +a int, b varchar(10), c varchar(10), filler varchar(10), primary key(a, b(2)), unique key (a, c(2)) +) character set ucs2 engine = innodb; +insert into t1 values (1,'abcdefg','abcdefg','one'); +insert into t1 values (2,'ijkilmn','ijkilmn','two'); +insert into t1 values (3,'qrstuvw','qrstuvw','three'); +insert into t1 values (4,_utf8 0xe880bd,_utf8 0xe880bd,'four'); +insert into t1 values (4,_utf8 0x5b,_utf8 0x5b,'five'); +insert into t1 values (4,_utf8 0xe880bde880bd,_utf8 0xe880bde880bd,'six'); +insert into t1 values (4,_utf8 0xe880bdD0B1e880bd,_utf8 0xe880bdD0B1e880bd,'seven'); +insert into t1 values (4,_utf8 0xD0B1,_utf8 0xD0B1,'eight'); +insert into t2 values (1,'abcdefg','abcdefg','one'); +insert into t2 values (2,'ijkilmn','ijkilmn','two'); +insert into t2 values (3,'qrstuvw','qrstuvw','three'); +insert into t2 values (4,_ucs2 0x00e400,_ucs2 0x00e400,'four'); +insert into t2 values (4,_ucs2 0x00640065,_ucs2 0x00640065,'five'); +insert into t2 values (4,_ucs2 0x00e400e50068,_ucs2 0x00e400e50068,'six'); +insert into t2 values (4,_ucs2 0x01fc,_ucs2 0x01fc,'seven'); +insert into t2 values (4,_ucs2 0x0120,_ucs2 0x0120,'eight'); +insert into t2 values (4,_ucs2 0x0563,_ucs2 0x0563,'ten'); +insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven'); +insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point'); +insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken'); +update t1 set filler = 'boo' where a = 1; +update t2 set filler ='email' where a = 4; +select a,hex(b),hex(c),filler from t1 order by filler; +a hex(b) hex(c) filler +1 61626364656667 61626364656667 boo +4 D0B1 D0B1 eight +4 5B 5B five +4 E880BD E880BD four +4 E880BDD0B1E880BD E880BDD0B1E880BD seven +4 E880BDE880BD E880BDE880BD six +3 71727374757677 71727374757677 three +2 696A6B696C6D6E 696A6B696C6D6E two +select a,hex(b),hex(c),filler from t2 order by filler; +a hex(b) hex(c) filler +4 05630563 05630563 email +4 0563 0563 email +4 05612020 05612020 email +4 01FC 01FC email +4 0120 0120 email +4 00640065 00640065 email +4 00E400E50068 00E400E50068 email +4 0000E400 0000E400 email +4 0000563001FC0563 0000563001FC0563 email +1 0061006200630064006500660067 0061006200630064006500660067 one +3 0071007200730074007500760077 0071007200730074007500760077 three +2 0069006A006B0069006C006D006E 0069006A006B0069006C006D006E two +drop table t1; +drop table t2; +create table t1 ( +a int, b text(10), c text(10), filler text(10), primary key(a, b(2)), unique key (a, c(2)) +) character set utf8 engine = innodb; +create table t2 ( +a int, b text(10), c text(10), filler text(10), primary key(a, b(2)), unique key (a, c(2)) +) character set ucs2 engine = innodb; +insert into t1 values (1,'abcdefg','abcdefg','one'); +insert into t1 values (2,'ijkilmn','ijkilmn','two'); +insert into t1 values (3,'qrstuvw','qrstuvw','three'); +insert into t1 values (4,_utf8 0xe880bd,_utf8 0xe880bd,'four'); +insert into t1 values (4,_utf8 0x5b,_utf8 0x5b,'five'); +insert into t1 values (4,_utf8 0xe880bde880bd,_utf8 0xe880bde880bd,'six'); +insert into t1 values (4,_utf8 0xe880bdD0B1e880bd,_utf8 0xe880bdD0B1e880bd,'seven'); +insert into t1 values (4,_utf8 0xD0B1,_utf8 0xD0B1,'eight'); +insert into t2 values (1,'abcdefg','abcdefg','one'); +insert into t2 values (2,'ijkilmn','ijkilmn','two'); +insert into t2 values (3,'qrstuvw','qrstuvw','three'); +insert into t2 values (4,_ucs2 0x00e400,_ucs2 0x00e400,'four'); +insert into t2 values (4,_ucs2 0x00640065,_ucs2 0x00640065,'five'); +insert into t2 values (4,_ucs2 0x00e400e50068,_ucs2 0x00e400e50068,'six'); +insert into t2 values (4,_ucs2 0x01fc,_ucs2 0x01fc,'seven'); +insert into t2 values (4,_ucs2 0x0120,_ucs2 0x0120,'eight'); +insert into t2 values (4,_ucs2 0x0563,_ucs2 0x0563,'ten'); +insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven'); +insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point'); +insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken'); +update t1 set filler = 'boo' where a = 1; +update t2 set filler ='email' where a = 4; +select a,hex(b),hex(c),filler from t1 order by filler; +a hex(b) hex(c) filler +1 61626364656667 61626364656667 boo +4 D0B1 D0B1 eight +4 5B 5B five +4 E880BD E880BD four +4 E880BDD0B1E880BD E880BDD0B1E880BD seven +4 E880BDE880BD E880BDE880BD six +3 71727374757677 71727374757677 three +2 696A6B696C6D6E 696A6B696C6D6E two +select a,hex(b),hex(c),filler from t2 order by filler; +a hex(b) hex(c) filler +4 0120 0120 email +4 01FC 01FC email +4 0563 0563 email +4 0000563001FC0563 0000563001FC0563 email +4 0000E400 0000E400 email +4 00640065 00640065 email +4 00E400E50068 00E400E50068 email +4 05612020 05612020 email +4 05630563 05630563 email +1 0061006200630064006500660067 0061006200630064006500660067 one +3 0071007200730074007500760077 0071007200730074007500760077 three +2 0069006A006B0069006C006D006E 0069006A006B0069006C006D006E two +drop table t1; +drop table t2; +create table t1 ( +a int, b blob(10), c blob(10), filler blob(10), primary key(a, b(2)), unique key (a, c(2)) +) character set utf8 engine = innodb; +create table t2 ( +a int, b blob(10), c blob(10), filler blob(10), primary key(a, b(2)), unique key (a, c(2)) +) character set ucs2 engine = innodb; +insert into t1 values (1,'abcdefg','abcdefg','one'); +insert into t1 values (2,'ijkilmn','ijkilmn','two'); +insert into t1 values (3,'qrstuvw','qrstuvw','three'); +insert into t1 values (4,_utf8 0xe880bd,_utf8 0xe880bd,'four'); +insert into t1 values (4,_utf8 0x5b,_utf8 0x5b,'five'); +insert into t1 values (4,_utf8 0xD0B1,_utf8 0xD0B1,'eight'); +insert into t2 values (1,'abcdefg','abcdefg','one'); +insert into t2 values (2,'ijkilmn','ijkilmn','two'); +insert into t2 values (3,'qrstuvw','qrstuvw','three'); +insert into t2 values (4,_ucs2 0x00e400,_ucs2 0x00e400,'four'); +insert into t2 values (4,_ucs2 0x00640065,_ucs2 0x00640065,'five'); +insert into t2 values (4,_ucs2 0x00e400e50068,_ucs2 0x00e400e50068,'six'); +insert into t2 values (4,_ucs2 0x01fc,_ucs2 0x01fc,'seven'); +insert into t2 values (4,_ucs2 0x0120,_ucs2 0x0120,'eight'); +insert into t2 values (4,_ucs2 0x0563,_ucs2 0x0563,'ten'); +insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken'); +update t1 set filler = 'boo' where a = 1; +update t2 set filler ='email' where a = 4; +select a,hex(b),hex(c),filler from t1 order by filler; +a hex(b) hex(c) filler +1 61626364656667 61626364656667 boo +4 D0B1 D0B1 eight +4 5B 5B five +4 E880BD E880BD four +3 71727374757677 71727374757677 three +2 696A6B696C6D6E 696A6B696C6D6E two +select a,hex(b),hex(c),filler from t2 order by filler; +a hex(b) hex(c) filler +4 0000E400 0000E400 email +4 00640065 00640065 email +4 00E400E50068 00E400E50068 email +4 0120 0120 email +4 01FC 01FC email +4 05612020 05612020 email +4 0563 0563 email +1 61626364656667 61626364656667 one +3 71727374757677 71727374757677 three +2 696A6B696C6D6E 696A6B696C6D6E two +drop table t1; +drop table t2; +commit; +CREATE TABLE t1 ( +ind enum('0','1','2') NOT NULL default '0', +string1 varchar(250) NOT NULL, +PRIMARY KEY (ind) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE t2 ( +ind enum('0','1','2') NOT NULL default '0', +string1 varchar(250) NOT NULL, +PRIMARY KEY (ind) +) ENGINE=InnoDB DEFAULT CHARSET=ucs2; +INSERT INTO t1 VALUES ('1', ''),('2', ''); +INSERT INTO t2 VALUES ('1', ''),('2', ''); +SELECT hex(ind),hex(string1) FROM t1 ORDER BY string1; +hex(ind) hex(string1) +31 +32 +SELECT hex(ind),hex(string1) FROM t2 ORDER BY string1; +hex(ind) hex(string1) +0031 +0032 +drop table t1,t2; +CREATE TABLE t1 ( +ind set('0','1','2') NOT NULL default '0', +string1 varchar(250) NOT NULL, +PRIMARY KEY (ind) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE t2 ( +ind set('0','1','2') NOT NULL default '0', +string1 varchar(250) NOT NULL, +PRIMARY KEY (ind) +) ENGINE=InnoDB DEFAULT CHARSET=ucs2; +INSERT INTO t1 VALUES ('1', ''),('2', ''); +INSERT INTO t2 VALUES ('1', ''),('2', ''); +SELECT hex(ind),hex(string1) FROM t1 ORDER BY string1; +hex(ind) hex(string1) +31 +32 +SELECT hex(ind),hex(string1) FROM t2 ORDER BY string1; +hex(ind) hex(string1) +0031 +0032 +drop table t1,t2; +CREATE TABLE t1 ( +ind bit not null, +string1 varchar(250) NOT NULL, +PRIMARY KEY (ind) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE t2 ( +ind bit not null, +string1 varchar(250) NOT NULL, +PRIMARY KEY (ind) +) ENGINE=InnoDB DEFAULT CHARSET=ucs2; +insert into t1 values(0,''),(1,''); +insert into t2 values(0,''),(1,''); +select hex(ind),hex(string1) from t1 order by string1; +hex(ind) hex(string1) +0 +1 +select hex(ind),hex(string1) from t2 order by string1; +hex(ind) hex(string1) +0 +1 +drop table t1,t2; +create table t2 ( +a int, b char(10), filler char(10), primary key(a, b(2)) +) character set utf8 engine = innodb; +insert into t2 values (1,'abcdefg','one'); +insert into t2 values (2,'ijkilmn','two'); +insert into t2 values (3, 'qrstuvw','three'); +update t2 set a=5, filler='booo' where a=1; +drop table t2; +create table t2 ( +a int, b char(10), filler char(10), primary key(a, b(2)) +) character set ucs2 engine = innodb; +insert into t2 values (1,'abcdefg','one'); +insert into t2 values (2,'ijkilmn','two'); +insert into t2 values (3, 'qrstuvw','three'); +update t2 set a=5, filler='booo' where a=1; +drop table t2; +create table t1(a int not null, b char(110),primary key(a,b(100))) engine=innodb default charset=utf8; +insert into t1 values(1,'abcdefg'),(2,'defghijk'); +insert into t1 values(6,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1); +insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2); +select a,hex(b) from t1 order by b; +a hex(b) +1 61626364656667 +2 6465666768696A6B +6 D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1 +7 D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2 +update t1 set b = 'three' where a = 6; +drop table t1; +create table t1(a int not null, b text(110),primary key(a,b(100))) engine=innodb default charset=utf8; +insert into t1 values(1,'abcdefg'),(2,'defghijk'); +insert into t1 values(6,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1); +insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2); +select a,hex(b) from t1 order by b; +a hex(b) +1 61626364656667 +2 6465666768696A6B +6 D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1 +7 D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2 +update t1 set b = 'three' where a = 6; +drop table t1; +End of 5.0 tests diff --git a/mysql-test/suite/innodb_plugin/r/innodb_autoinc_lock_mode_zero.result b/mysql-test/suite/innodb_plugin/r/innodb_autoinc_lock_mode_zero.result new file mode 100644 index 00000000000..3d016684338 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_autoinc_lock_mode_zero.result @@ -0,0 +1,39 @@ +drop table if exists t1; +CREATE TABLE t1 ( +id int(11) NOT NULL auto_increment, +ggid varchar(32) binary DEFAULT '' NOT NULL, +email varchar(64) DEFAULT '' NOT NULL, +passwd varchar(32) binary DEFAULT '' NOT NULL, +PRIMARY KEY (id), +UNIQUE ggid (ggid) +) ENGINE=innodb; +insert into t1 (ggid,passwd) values ('test1','xxx'); +insert into t1 (ggid,passwd) values ('test2','yyy'); +insert into t1 (ggid,passwd) values ('test2','this will fail'); +ERROR 23000: Duplicate entry 'test2' for key 'ggid' +insert into t1 (ggid,id) values ('this will fail',1); +ERROR 23000: Duplicate entry '1' for key 'PRIMARY' +select * from t1 where ggid='test1'; +id ggid email passwd +1 test1 xxx +select * from t1 where passwd='xxx'; +id ggid email passwd +1 test1 xxx +select * from t1 where id=2; +id ggid email passwd +2 test2 yyy +replace into t1 (ggid,id) values ('this will work',1); +replace into t1 (ggid,passwd) values ('test2','this will work'); +update t1 set id=100,ggid='test2' where id=1; +ERROR 23000: Duplicate entry 'test2' for key 'ggid' +select * from t1; +id ggid email passwd +1 this will work +3 test2 this will work +select * from t1 where id=1; +id ggid email passwd +1 this will work +select * from t1 where id=999; +id ggid email passwd +drop table t1; +End of tests diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug30919.result b/mysql-test/suite/innodb_plugin/r/innodb_bug30919.result new file mode 100644 index 00000000000..42aa4ff302b --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug30919.result @@ -0,0 +1,1043 @@ +use test; +CREATE TABLE test.part_tbl(id MEDIUMINT NOT NULL AUTO_INCREMENT, +dt TIMESTAMP, user CHAR(255), uuidf LONGBLOB, +fkid MEDIUMINT, filler VARCHAR(255), +PRIMARY KEY(id)) ENGINE='innodb' +PARTITION BY RANGE(id) +SUBPARTITION BY hash(id) subpartitions 2 +(PARTITION pa3 values less than (42), +PARTITION pa6 values less than (60), +PARTITION pa7 values less than (70), +PARTITION pa8 values less than (80), +PARTITION pa9 values less than (90), +PARTITION pa10 values less than (100), +PARTITION pa11 values less than MAXVALUE); +CREATE PROCEDURE test.proc_part() +BEGIN +DECLARE ins_count INT DEFAULT 1000; +DECLARE del_count INT; +DECLARE cur_user VARCHAR(255); +DECLARE local_uuid VARCHAR(255); +DECLARE local_time TIMESTAMP; +SET local_time= NOW(); +SET cur_user= CURRENT_USER(); +SET local_uuid= UUID(); +WHILE ins_count > 0 DO +INSERT INTO test.part_tbl VALUES (NULL, NOW(), USER() , UUID(), +ins_count,'Going to test MBR for MySQL'); +SET ins_count = ins_count - 1; +END WHILE; +SELECT MAX(id) FROM test.part_tbl INTO del_count; +WHILE del_count > 0 DO +DELETE FROM test.part_tbl WHERE id = del_count; +select count(*) as internal_count, del_count -- these two lines are for +FROM test.part_tbl; -- debug to show the problem +SET del_count = del_count - 2; +END WHILE; +END| +CALL test.proc_part(); +internal_count del_count +999 1000 +internal_count del_count +998 998 +internal_count del_count +997 996 +internal_count del_count +996 994 +internal_count del_count +995 992 +internal_count del_count +994 990 +internal_count del_count +993 988 +internal_count del_count +992 986 +internal_count del_count +991 984 +internal_count del_count +990 982 +internal_count del_count +989 980 +internal_count del_count +988 978 +internal_count del_count +987 976 +internal_count del_count +986 974 +internal_count del_count +985 972 +internal_count del_count +984 970 +internal_count del_count +983 968 +internal_count del_count +982 966 +internal_count del_count +981 964 +internal_count del_count +980 962 +internal_count del_count +979 960 +internal_count del_count +978 958 +internal_count del_count +977 956 +internal_count del_count +976 954 +internal_count del_count +975 952 +internal_count del_count +974 950 +internal_count del_count +973 948 +internal_count del_count +972 946 +internal_count del_count +971 944 +internal_count del_count +970 942 +internal_count del_count +969 940 +internal_count del_count +968 938 +internal_count del_count +967 936 +internal_count del_count +966 934 +internal_count del_count +965 932 +internal_count del_count +964 930 +internal_count del_count +963 928 +internal_count del_count +962 926 +internal_count del_count +961 924 +internal_count del_count +960 922 +internal_count del_count +959 920 +internal_count del_count +958 918 +internal_count del_count +957 916 +internal_count del_count +956 914 +internal_count del_count +955 912 +internal_count del_count +954 910 +internal_count del_count +953 908 +internal_count del_count +952 906 +internal_count del_count +951 904 +internal_count del_count +950 902 +internal_count del_count +949 900 +internal_count del_count +948 898 +internal_count del_count +947 896 +internal_count del_count +946 894 +internal_count del_count +945 892 +internal_count del_count +944 890 +internal_count del_count +943 888 +internal_count del_count +942 886 +internal_count del_count +941 884 +internal_count del_count +940 882 +internal_count del_count +939 880 +internal_count del_count +938 878 +internal_count del_count +937 876 +internal_count del_count +936 874 +internal_count del_count +935 872 +internal_count del_count +934 870 +internal_count del_count +933 868 +internal_count del_count +932 866 +internal_count del_count +931 864 +internal_count del_count +930 862 +internal_count del_count +929 860 +internal_count del_count +928 858 +internal_count del_count +927 856 +internal_count del_count +926 854 +internal_count del_count +925 852 +internal_count del_count +924 850 +internal_count del_count +923 848 +internal_count del_count +922 846 +internal_count del_count +921 844 +internal_count del_count +920 842 +internal_count del_count +919 840 +internal_count del_count +918 838 +internal_count del_count +917 836 +internal_count del_count +916 834 +internal_count del_count +915 832 +internal_count del_count +914 830 +internal_count del_count +913 828 +internal_count del_count +912 826 +internal_count del_count +911 824 +internal_count del_count +910 822 +internal_count del_count +909 820 +internal_count del_count +908 818 +internal_count del_count +907 816 +internal_count del_count +906 814 +internal_count del_count +905 812 +internal_count del_count +904 810 +internal_count del_count +903 808 +internal_count del_count +902 806 +internal_count del_count +901 804 +internal_count del_count +900 802 +internal_count del_count +899 800 +internal_count del_count +898 798 +internal_count del_count +897 796 +internal_count del_count +896 794 +internal_count del_count +895 792 +internal_count del_count +894 790 +internal_count del_count +893 788 +internal_count del_count +892 786 +internal_count del_count +891 784 +internal_count del_count +890 782 +internal_count del_count +889 780 +internal_count del_count +888 778 +internal_count del_count +887 776 +internal_count del_count +886 774 +internal_count del_count +885 772 +internal_count del_count +884 770 +internal_count del_count +883 768 +internal_count del_count +882 766 +internal_count del_count +881 764 +internal_count del_count +880 762 +internal_count del_count +879 760 +internal_count del_count +878 758 +internal_count del_count +877 756 +internal_count del_count +876 754 +internal_count del_count +875 752 +internal_count del_count +874 750 +internal_count del_count +873 748 +internal_count del_count +872 746 +internal_count del_count +871 744 +internal_count del_count +870 742 +internal_count del_count +869 740 +internal_count del_count +868 738 +internal_count del_count +867 736 +internal_count del_count +866 734 +internal_count del_count +865 732 +internal_count del_count +864 730 +internal_count del_count +863 728 +internal_count del_count +862 726 +internal_count del_count +861 724 +internal_count del_count +860 722 +internal_count del_count +859 720 +internal_count del_count +858 718 +internal_count del_count +857 716 +internal_count del_count +856 714 +internal_count del_count +855 712 +internal_count del_count +854 710 +internal_count del_count +853 708 +internal_count del_count +852 706 +internal_count del_count +851 704 +internal_count del_count +850 702 +internal_count del_count +849 700 +internal_count del_count +848 698 +internal_count del_count +847 696 +internal_count del_count +846 694 +internal_count del_count +845 692 +internal_count del_count +844 690 +internal_count del_count +843 688 +internal_count del_count +842 686 +internal_count del_count +841 684 +internal_count del_count +840 682 +internal_count del_count +839 680 +internal_count del_count +838 678 +internal_count del_count +837 676 +internal_count del_count +836 674 +internal_count del_count +835 672 +internal_count del_count +834 670 +internal_count del_count +833 668 +internal_count del_count +832 666 +internal_count del_count +831 664 +internal_count del_count +830 662 +internal_count del_count +829 660 +internal_count del_count +828 658 +internal_count del_count +827 656 +internal_count del_count +826 654 +internal_count del_count +825 652 +internal_count del_count +824 650 +internal_count del_count +823 648 +internal_count del_count +822 646 +internal_count del_count +821 644 +internal_count del_count +820 642 +internal_count del_count +819 640 +internal_count del_count +818 638 +internal_count del_count +817 636 +internal_count del_count +816 634 +internal_count del_count +815 632 +internal_count del_count +814 630 +internal_count del_count +813 628 +internal_count del_count +812 626 +internal_count del_count +811 624 +internal_count del_count +810 622 +internal_count del_count +809 620 +internal_count del_count +808 618 +internal_count del_count +807 616 +internal_count del_count +806 614 +internal_count del_count +805 612 +internal_count del_count +804 610 +internal_count del_count +803 608 +internal_count del_count +802 606 +internal_count del_count +801 604 +internal_count del_count +800 602 +internal_count del_count +799 600 +internal_count del_count +798 598 +internal_count del_count +797 596 +internal_count del_count +796 594 +internal_count del_count +795 592 +internal_count del_count +794 590 +internal_count del_count +793 588 +internal_count del_count +792 586 +internal_count del_count +791 584 +internal_count del_count +790 582 +internal_count del_count +789 580 +internal_count del_count +788 578 +internal_count del_count +787 576 +internal_count del_count +786 574 +internal_count del_count +785 572 +internal_count del_count +784 570 +internal_count del_count +783 568 +internal_count del_count +782 566 +internal_count del_count +781 564 +internal_count del_count +780 562 +internal_count del_count +779 560 +internal_count del_count +778 558 +internal_count del_count +777 556 +internal_count del_count +776 554 +internal_count del_count +775 552 +internal_count del_count +774 550 +internal_count del_count +773 548 +internal_count del_count +772 546 +internal_count del_count +771 544 +internal_count del_count +770 542 +internal_count del_count +769 540 +internal_count del_count +768 538 +internal_count del_count +767 536 +internal_count del_count +766 534 +internal_count del_count +765 532 +internal_count del_count +764 530 +internal_count del_count +763 528 +internal_count del_count +762 526 +internal_count del_count +761 524 +internal_count del_count +760 522 +internal_count del_count +759 520 +internal_count del_count +758 518 +internal_count del_count +757 516 +internal_count del_count +756 514 +internal_count del_count +755 512 +internal_count del_count +754 510 +internal_count del_count +753 508 +internal_count del_count +752 506 +internal_count del_count +751 504 +internal_count del_count +750 502 +internal_count del_count +749 500 +internal_count del_count +748 498 +internal_count del_count +747 496 +internal_count del_count +746 494 +internal_count del_count +745 492 +internal_count del_count +744 490 +internal_count del_count +743 488 +internal_count del_count +742 486 +internal_count del_count +741 484 +internal_count del_count +740 482 +internal_count del_count +739 480 +internal_count del_count +738 478 +internal_count del_count +737 476 +internal_count del_count +736 474 +internal_count del_count +735 472 +internal_count del_count +734 470 +internal_count del_count +733 468 +internal_count del_count +732 466 +internal_count del_count +731 464 +internal_count del_count +730 462 +internal_count del_count +729 460 +internal_count del_count +728 458 +internal_count del_count +727 456 +internal_count del_count +726 454 +internal_count del_count +725 452 +internal_count del_count +724 450 +internal_count del_count +723 448 +internal_count del_count +722 446 +internal_count del_count +721 444 +internal_count del_count +720 442 +internal_count del_count +719 440 +internal_count del_count +718 438 +internal_count del_count +717 436 +internal_count del_count +716 434 +internal_count del_count +715 432 +internal_count del_count +714 430 +internal_count del_count +713 428 +internal_count del_count +712 426 +internal_count del_count +711 424 +internal_count del_count +710 422 +internal_count del_count +709 420 +internal_count del_count +708 418 +internal_count del_count +707 416 +internal_count del_count +706 414 +internal_count del_count +705 412 +internal_count del_count +704 410 +internal_count del_count +703 408 +internal_count del_count +702 406 +internal_count del_count +701 404 +internal_count del_count +700 402 +internal_count del_count +699 400 +internal_count del_count +698 398 +internal_count del_count +697 396 +internal_count del_count +696 394 +internal_count del_count +695 392 +internal_count del_count +694 390 +internal_count del_count +693 388 +internal_count del_count +692 386 +internal_count del_count +691 384 +internal_count del_count +690 382 +internal_count del_count +689 380 +internal_count del_count +688 378 +internal_count del_count +687 376 +internal_count del_count +686 374 +internal_count del_count +685 372 +internal_count del_count +684 370 +internal_count del_count +683 368 +internal_count del_count +682 366 +internal_count del_count +681 364 +internal_count del_count +680 362 +internal_count del_count +679 360 +internal_count del_count +678 358 +internal_count del_count +677 356 +internal_count del_count +676 354 +internal_count del_count +675 352 +internal_count del_count +674 350 +internal_count del_count +673 348 +internal_count del_count +672 346 +internal_count del_count +671 344 +internal_count del_count +670 342 +internal_count del_count +669 340 +internal_count del_count +668 338 +internal_count del_count +667 336 +internal_count del_count +666 334 +internal_count del_count +665 332 +internal_count del_count +664 330 +internal_count del_count +663 328 +internal_count del_count +662 326 +internal_count del_count +661 324 +internal_count del_count +660 322 +internal_count del_count +659 320 +internal_count del_count +658 318 +internal_count del_count +657 316 +internal_count del_count +656 314 +internal_count del_count +655 312 +internal_count del_count +654 310 +internal_count del_count +653 308 +internal_count del_count +652 306 +internal_count del_count +651 304 +internal_count del_count +650 302 +internal_count del_count +649 300 +internal_count del_count +648 298 +internal_count del_count +647 296 +internal_count del_count +646 294 +internal_count del_count +645 292 +internal_count del_count +644 290 +internal_count del_count +643 288 +internal_count del_count +642 286 +internal_count del_count +641 284 +internal_count del_count +640 282 +internal_count del_count +639 280 +internal_count del_count +638 278 +internal_count del_count +637 276 +internal_count del_count +636 274 +internal_count del_count +635 272 +internal_count del_count +634 270 +internal_count del_count +633 268 +internal_count del_count +632 266 +internal_count del_count +631 264 +internal_count del_count +630 262 +internal_count del_count +629 260 +internal_count del_count +628 258 +internal_count del_count +627 256 +internal_count del_count +626 254 +internal_count del_count +625 252 +internal_count del_count +624 250 +internal_count del_count +623 248 +internal_count del_count +622 246 +internal_count del_count +621 244 +internal_count del_count +620 242 +internal_count del_count +619 240 +internal_count del_count +618 238 +internal_count del_count +617 236 +internal_count del_count +616 234 +internal_count del_count +615 232 +internal_count del_count +614 230 +internal_count del_count +613 228 +internal_count del_count +612 226 +internal_count del_count +611 224 +internal_count del_count +610 222 +internal_count del_count +609 220 +internal_count del_count +608 218 +internal_count del_count +607 216 +internal_count del_count +606 214 +internal_count del_count +605 212 +internal_count del_count +604 210 +internal_count del_count +603 208 +internal_count del_count +602 206 +internal_count del_count +601 204 +internal_count del_count +600 202 +internal_count del_count +599 200 +internal_count del_count +598 198 +internal_count del_count +597 196 +internal_count del_count +596 194 +internal_count del_count +595 192 +internal_count del_count +594 190 +internal_count del_count +593 188 +internal_count del_count +592 186 +internal_count del_count +591 184 +internal_count del_count +590 182 +internal_count del_count +589 180 +internal_count del_count +588 178 +internal_count del_count +587 176 +internal_count del_count +586 174 +internal_count del_count +585 172 +internal_count del_count +584 170 +internal_count del_count +583 168 +internal_count del_count +582 166 +internal_count del_count +581 164 +internal_count del_count +580 162 +internal_count del_count +579 160 +internal_count del_count +578 158 +internal_count del_count +577 156 +internal_count del_count +576 154 +internal_count del_count +575 152 +internal_count del_count +574 150 +internal_count del_count +573 148 +internal_count del_count +572 146 +internal_count del_count +571 144 +internal_count del_count +570 142 +internal_count del_count +569 140 +internal_count del_count +568 138 +internal_count del_count +567 136 +internal_count del_count +566 134 +internal_count del_count +565 132 +internal_count del_count +564 130 +internal_count del_count +563 128 +internal_count del_count +562 126 +internal_count del_count +561 124 +internal_count del_count +560 122 +internal_count del_count +559 120 +internal_count del_count +558 118 +internal_count del_count +557 116 +internal_count del_count +556 114 +internal_count del_count +555 112 +internal_count del_count +554 110 +internal_count del_count +553 108 +internal_count del_count +552 106 +internal_count del_count +551 104 +internal_count del_count +550 102 +internal_count del_count +549 100 +internal_count del_count +548 98 +internal_count del_count +547 96 +internal_count del_count +546 94 +internal_count del_count +545 92 +internal_count del_count +544 90 +internal_count del_count +543 88 +internal_count del_count +542 86 +internal_count del_count +541 84 +internal_count del_count +540 82 +internal_count del_count +539 80 +internal_count del_count +538 78 +internal_count del_count +537 76 +internal_count del_count +536 74 +internal_count del_count +535 72 +internal_count del_count +534 70 +internal_count del_count +533 68 +internal_count del_count +532 66 +internal_count del_count +531 64 +internal_count del_count +530 62 +internal_count del_count +529 60 +internal_count del_count +528 58 +internal_count del_count +527 56 +internal_count del_count +526 54 +internal_count del_count +525 52 +internal_count del_count +524 50 +internal_count del_count +523 48 +internal_count del_count +522 46 +internal_count del_count +521 44 +internal_count del_count +520 42 +internal_count del_count +519 40 +internal_count del_count +518 38 +internal_count del_count +517 36 +internal_count del_count +516 34 +internal_count del_count +515 32 +internal_count del_count +514 30 +internal_count del_count +513 28 +internal_count del_count +512 26 +internal_count del_count +511 24 +internal_count del_count +510 22 +internal_count del_count +509 20 +internal_count del_count +508 18 +internal_count del_count +507 16 +internal_count del_count +506 14 +internal_count del_count +505 12 +internal_count del_count +504 10 +internal_count del_count +503 8 +internal_count del_count +502 6 +internal_count del_count +501 4 +internal_count del_count +500 2 +select count(*) as Part from test.part_tbl; +Part +500 +DROP PROCEDURE test.proc_part; +DROP TABLE test.part_tbl; diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug42419.result b/mysql-test/suite/innodb_plugin/r/innodb_bug42419.result new file mode 100644 index 00000000000..f304bb634cb --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug42419.result @@ -0,0 +1,17 @@ +CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b INT) ENGINE = InnoDB; +INSERT INTO t1 VALUES (1,1),(2,2),(3,3); +COMMIT; +SET AUTOCOMMIT = 0; +CREATE TEMPORARY TABLE t1_tmp ( b INT ); +INSERT INTO t1_tmp (b) SELECT b FROM t1 WHERE a = 3; +INSERT INTO t1_tmp (b) SELECT b FROM t1 WHERE a = 2; +SET AUTOCOMMIT = 0; +CREATE TEMPORARY TABLE t2_tmp ( a int, new_a int ); +INSERT INTO t2_tmp VALUES (1,51),(2,52),(3,53); +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 1; +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 2; +INSERT INTO t1_tmp (b) SELECT b FROM t1 WHERE a = 1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +Reap the server message for connection user2 UPDATE t1 ... +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 3; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_plugin/r/innodb_gis.result b/mysql-test/suite/innodb_plugin/r/innodb_gis.result new file mode 100644 index 00000000000..c6c775afc9f --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_gis.result @@ -0,0 +1,589 @@ +SET storage_engine=innodb; +DROP TABLE IF EXISTS t1, gis_point, gis_line, gis_polygon, gis_multi_point, gis_multi_line, gis_multi_polygon, gis_geometrycollection, gis_geometry; +CREATE TABLE gis_point (fid INTEGER PRIMARY KEY AUTO_INCREMENT, g POINT); +CREATE TABLE gis_line (fid INTEGER PRIMARY KEY AUTO_INCREMENT, g LINESTRING); +CREATE TABLE gis_polygon (fid INTEGER PRIMARY KEY AUTO_INCREMENT, g POLYGON); +CREATE TABLE gis_multi_point (fid INTEGER PRIMARY KEY AUTO_INCREMENT, g MULTIPOINT); +CREATE TABLE gis_multi_line (fid INTEGER PRIMARY KEY AUTO_INCREMENT, g MULTILINESTRING); +CREATE TABLE gis_multi_polygon (fid INTEGER PRIMARY KEY AUTO_INCREMENT, g MULTIPOLYGON); +CREATE TABLE gis_geometrycollection (fid INTEGER PRIMARY KEY AUTO_INCREMENT, g GEOMETRYCOLLECTION); +CREATE TABLE gis_geometry (fid INTEGER PRIMARY KEY AUTO_INCREMENT, g GEOMETRY); +SHOW CREATE TABLE gis_point; +Table Create Table +gis_point CREATE TABLE `gis_point` ( + `fid` int(11) NOT NULL AUTO_INCREMENT, + `g` point DEFAULT NULL, + PRIMARY KEY (`fid`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SHOW FIELDS FROM gis_point; +Field Type Null Key Default Extra +fid int(11) NO PRI NULL auto_increment +g point YES NULL +SHOW FIELDS FROM gis_line; +Field Type Null Key Default Extra +fid int(11) NO PRI NULL auto_increment +g linestring YES NULL +SHOW FIELDS FROM gis_polygon; +Field Type Null Key Default Extra +fid int(11) NO PRI NULL auto_increment +g polygon YES NULL +SHOW FIELDS FROM gis_multi_point; +Field Type Null Key Default Extra +fid int(11) NO PRI NULL auto_increment +g multipoint YES NULL +SHOW FIELDS FROM gis_multi_line; +Field Type Null Key Default Extra +fid int(11) NO PRI NULL auto_increment +g multilinestring YES NULL +SHOW FIELDS FROM gis_multi_polygon; +Field Type Null Key Default Extra +fid int(11) NO PRI NULL auto_increment +g multipolygon YES NULL +SHOW FIELDS FROM gis_geometrycollection; +Field Type Null Key Default Extra +fid int(11) NO PRI NULL auto_increment +g geometrycollection YES NULL +SHOW FIELDS FROM gis_geometry; +Field Type Null Key Default Extra +fid int(11) NO PRI NULL auto_increment +g geometry YES NULL +INSERT INTO gis_point VALUES +(101, PointFromText('POINT(10 10)')), +(102, PointFromText('POINT(20 10)')), +(103, PointFromText('POINT(20 20)')), +(104, PointFromWKB(AsWKB(PointFromText('POINT(10 20)')))); +INSERT INTO gis_line VALUES +(105, LineFromText('LINESTRING(0 0,0 10,10 0)')), +(106, LineStringFromText('LINESTRING(10 10,20 10,20 20,10 20,10 10)')), +(107, LineStringFromWKB(LineString(Point(10, 10), Point(40, 10)))); +INSERT INTO gis_polygon VALUES +(108, PolygonFromText('POLYGON((10 10,20 10,20 20,10 20,10 10))')), +(109, PolyFromText('POLYGON((0 0,50 0,50 50,0 50,0 0), (10 10,20 10,20 20,10 20,10 10))')), +(110, PolyFromWKB(Polygon(LineString(Point(0, 0), Point(30, 0), Point(30, 30), Point(0, 0))))); +INSERT INTO gis_multi_point VALUES +(111, MultiPointFromText('MULTIPOINT(0 0,10 10,10 20,20 20)')), +(112, MPointFromText('MULTIPOINT(1 1,11 11,11 21,21 21)')), +(113, MPointFromWKB(MultiPoint(Point(3, 6), Point(4, 10)))); +INSERT INTO gis_multi_line VALUES +(114, MultiLineStringFromText('MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))')), +(115, MLineFromText('MULTILINESTRING((10 48,10 21,10 0))')), +(116, MLineFromWKB(MultiLineString(LineString(Point(1, 2), Point(3, 5)), LineString(Point(2, 5), Point(5, 8), Point(21, 7))))); +INSERT INTO gis_multi_polygon VALUES +(117, MultiPolygonFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')), +(118, MPolyFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')), +(119, MPolyFromWKB(MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))))); +INSERT INTO gis_geometrycollection VALUES +(120, GeomCollFromText('GEOMETRYCOLLECTION(POINT(0 0), LINESTRING(0 0,10 10))')), +(121, GeometryFromWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9))))); +INSERT into gis_geometry SELECT * FROM gis_point; +INSERT into gis_geometry SELECT * FROM gis_line; +INSERT into gis_geometry SELECT * FROM gis_polygon; +INSERT into gis_geometry SELECT * FROM gis_multi_point; +INSERT into gis_geometry SELECT * FROM gis_multi_line; +INSERT into gis_geometry SELECT * FROM gis_multi_polygon; +INSERT into gis_geometry SELECT * FROM gis_geometrycollection; +SELECT fid, AsText(g) FROM gis_point ORDER by fid; +fid AsText(g) +101 POINT(10 10) +102 POINT(20 10) +103 POINT(20 20) +104 POINT(10 20) +SELECT fid, AsText(g) FROM gis_line ORDER by fid; +fid AsText(g) +105 LINESTRING(0 0,0 10,10 0) +106 LINESTRING(10 10,20 10,20 20,10 20,10 10) +107 LINESTRING(10 10,40 10) +SELECT fid, AsText(g) FROM gis_polygon ORDER by fid; +fid AsText(g) +108 POLYGON((10 10,20 10,20 20,10 20,10 10)) +109 POLYGON((0 0,50 0,50 50,0 50,0 0),(10 10,20 10,20 20,10 20,10 10)) +110 POLYGON((0 0,30 0,30 30,0 0)) +SELECT fid, AsText(g) FROM gis_multi_point ORDER by fid; +fid AsText(g) +111 MULTIPOINT(0 0,10 10,10 20,20 20) +112 MULTIPOINT(1 1,11 11,11 21,21 21) +113 MULTIPOINT(3 6,4 10) +SELECT fid, AsText(g) FROM gis_multi_line ORDER by fid; +fid AsText(g) +114 MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48)) +115 MULTILINESTRING((10 48,10 21,10 0)) +116 MULTILINESTRING((1 2,3 5),(2 5,5 8,21 7)) +SELECT fid, AsText(g) FROM gis_multi_polygon ORDER by fid; +fid AsText(g) +117 MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18))) +118 MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18))) +119 MULTIPOLYGON(((0 3,3 3,3 0,0 3))) +SELECT fid, AsText(g) FROM gis_geometrycollection ORDER by fid; +fid AsText(g) +120 GEOMETRYCOLLECTION(POINT(0 0),LINESTRING(0 0,10 10)) +121 GEOMETRYCOLLECTION(POINT(44 6),LINESTRING(3 6,7 9)) +SELECT fid, AsText(g) FROM gis_geometry ORDER by fid; +fid AsText(g) +101 POINT(10 10) +102 POINT(20 10) +103 POINT(20 20) +104 POINT(10 20) +105 LINESTRING(0 0,0 10,10 0) +106 LINESTRING(10 10,20 10,20 20,10 20,10 10) +107 LINESTRING(10 10,40 10) +108 POLYGON((10 10,20 10,20 20,10 20,10 10)) +109 POLYGON((0 0,50 0,50 50,0 50,0 0),(10 10,20 10,20 20,10 20,10 10)) +110 POLYGON((0 0,30 0,30 30,0 0)) +111 MULTIPOINT(0 0,10 10,10 20,20 20) +112 MULTIPOINT(1 1,11 11,11 21,21 21) +113 MULTIPOINT(3 6,4 10) +114 MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48)) +115 MULTILINESTRING((10 48,10 21,10 0)) +116 MULTILINESTRING((1 2,3 5),(2 5,5 8,21 7)) +117 MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18))) +118 MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18))) +119 MULTIPOLYGON(((0 3,3 3,3 0,0 3))) +120 GEOMETRYCOLLECTION(POINT(0 0),LINESTRING(0 0,10 10)) +121 GEOMETRYCOLLECTION(POINT(44 6),LINESTRING(3 6,7 9)) +SELECT fid, Dimension(g) FROM gis_geometry ORDER by fid; +fid Dimension(g) +101 0 +102 0 +103 0 +104 0 +105 1 +106 1 +107 1 +108 2 +109 2 +110 2 +111 0 +112 0 +113 0 +114 1 +115 1 +116 1 +117 2 +118 2 +119 2 +120 1 +121 1 +SELECT fid, GeometryType(g) FROM gis_geometry ORDER by fid; +fid GeometryType(g) +101 POINT +102 POINT +103 POINT +104 POINT +105 LINESTRING +106 LINESTRING +107 LINESTRING +108 POLYGON +109 POLYGON +110 POLYGON +111 MULTIPOINT +112 MULTIPOINT +113 MULTIPOINT +114 MULTILINESTRING +115 MULTILINESTRING +116 MULTILINESTRING +117 MULTIPOLYGON +118 MULTIPOLYGON +119 MULTIPOLYGON +120 GEOMETRYCOLLECTION +121 GEOMETRYCOLLECTION +SELECT fid, IsEmpty(g) FROM gis_geometry ORDER by fid; +fid IsEmpty(g) +101 0 +102 0 +103 0 +104 0 +105 0 +106 0 +107 0 +108 0 +109 0 +110 0 +111 0 +112 0 +113 0 +114 0 +115 0 +116 0 +117 0 +118 0 +119 0 +120 0 +121 0 +SELECT fid, AsText(Envelope(g)) FROM gis_geometry ORDER by fid; +fid AsText(Envelope(g)) +101 POLYGON((10 10,10 10,10 10,10 10,10 10)) +102 POLYGON((20 10,20 10,20 10,20 10,20 10)) +103 POLYGON((20 20,20 20,20 20,20 20,20 20)) +104 POLYGON((10 20,10 20,10 20,10 20,10 20)) +105 POLYGON((0 0,10 0,10 10,0 10,0 0)) +106 POLYGON((10 10,20 10,20 20,10 20,10 10)) +107 POLYGON((10 10,40 10,40 10,10 10,10 10)) +108 POLYGON((10 10,20 10,20 20,10 20,10 10)) +109 POLYGON((0 0,50 0,50 50,0 50,0 0)) +110 POLYGON((0 0,30 0,30 30,0 30,0 0)) +111 POLYGON((0 0,20 0,20 20,0 20,0 0)) +112 POLYGON((1 1,21 1,21 21,1 21,1 1)) +113 POLYGON((3 6,4 6,4 10,3 10,3 6)) +114 POLYGON((10 0,16 0,16 48,10 48,10 0)) +115 POLYGON((10 0,10 0,10 48,10 48,10 0)) +116 POLYGON((1 2,21 2,21 8,1 8,1 2)) +117 POLYGON((28 0,84 0,84 42,28 42,28 0)) +118 POLYGON((28 0,84 0,84 42,28 42,28 0)) +119 POLYGON((0 0,3 0,3 3,0 3,0 0)) +120 POLYGON((0 0,10 0,10 10,0 10,0 0)) +121 POLYGON((3 6,44 6,44 9,3 9,3 6)) +explain extended select Dimension(g), GeometryType(g), IsEmpty(g), AsText(Envelope(g)) from gis_geometry; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE gis_geometry ALL NULL NULL NULL NULL 21 100.00 +Warnings: +Note 1003 select dimension(`test`.`gis_geometry`.`g`) AS `Dimension(g)`,geometrytype(`test`.`gis_geometry`.`g`) AS `GeometryType(g)`,isempty(`test`.`gis_geometry`.`g`) AS `IsEmpty(g)`,astext(envelope(`test`.`gis_geometry`.`g`)) AS `AsText(Envelope(g))` from `test`.`gis_geometry` +SELECT fid, X(g) FROM gis_point ORDER by fid; +fid X(g) +101 10 +102 20 +103 20 +104 10 +SELECT fid, Y(g) FROM gis_point ORDER by fid; +fid Y(g) +101 10 +102 10 +103 20 +104 20 +explain extended select X(g),Y(g) FROM gis_point; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE gis_point ALL NULL NULL NULL NULL 4 100.00 +Warnings: +Note 1003 select x(`test`.`gis_point`.`g`) AS `X(g)`,y(`test`.`gis_point`.`g`) AS `Y(g)` from `test`.`gis_point` +SELECT fid, AsText(StartPoint(g)) FROM gis_line ORDER by fid; +fid AsText(StartPoint(g)) +105 POINT(0 0) +106 POINT(10 10) +107 POINT(10 10) +SELECT fid, AsText(EndPoint(g)) FROM gis_line ORDER by fid; +fid AsText(EndPoint(g)) +105 POINT(10 0) +106 POINT(10 10) +107 POINT(40 10) +SELECT fid, GLength(g) FROM gis_line ORDER by fid; +fid GLength(g) +105 24.142135623731 +106 40 +107 30 +SELECT fid, NumPoints(g) FROM gis_line ORDER by fid; +fid NumPoints(g) +105 3 +106 5 +107 2 +SELECT fid, AsText(PointN(g, 2)) FROM gis_line ORDER by fid; +fid AsText(PointN(g, 2)) +105 POINT(0 10) +106 POINT(20 10) +107 POINT(40 10) +SELECT fid, IsClosed(g) FROM gis_line ORDER by fid; +fid IsClosed(g) +105 0 +106 1 +107 0 +explain extended select AsText(StartPoint(g)),AsText(EndPoint(g)),GLength(g),NumPoints(g),AsText(PointN(g, 2)),IsClosed(g) FROM gis_line; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE gis_line ALL NULL NULL NULL NULL 3 100.00 +Warnings: +Note 1003 select astext(startpoint(`test`.`gis_line`.`g`)) AS `AsText(StartPoint(g))`,astext(endpoint(`test`.`gis_line`.`g`)) AS `AsText(EndPoint(g))`,glength(`test`.`gis_line`.`g`) AS `GLength(g)`,numpoints(`test`.`gis_line`.`g`) AS `NumPoints(g)`,astext(pointn(`test`.`gis_line`.`g`,2)) AS `AsText(PointN(g, 2))`,isclosed(`test`.`gis_line`.`g`) AS `IsClosed(g)` from `test`.`gis_line` +SELECT fid, AsText(Centroid(g)) FROM gis_polygon ORDER by fid; +fid AsText(Centroid(g)) +108 POINT(15 15) +109 POINT(25.4166666666667 25.4166666666667) +110 POINT(20 10) +SELECT fid, Area(g) FROM gis_polygon ORDER by fid; +fid Area(g) +108 100 +109 2400 +110 450 +SELECT fid, AsText(ExteriorRing(g)) FROM gis_polygon ORDER by fid; +fid AsText(ExteriorRing(g)) +108 LINESTRING(10 10,20 10,20 20,10 20,10 10) +109 LINESTRING(0 0,50 0,50 50,0 50,0 0) +110 LINESTRING(0 0,30 0,30 30,0 0) +SELECT fid, NumInteriorRings(g) FROM gis_polygon ORDER by fid; +fid NumInteriorRings(g) +108 0 +109 1 +110 0 +SELECT fid, AsText(InteriorRingN(g, 1)) FROM gis_polygon ORDER by fid; +fid AsText(InteriorRingN(g, 1)) +108 NULL +109 LINESTRING(10 10,20 10,20 20,10 20,10 10) +110 NULL +explain extended select AsText(Centroid(g)),Area(g),AsText(ExteriorRing(g)),NumInteriorRings(g),AsText(InteriorRingN(g, 1)) FROM gis_polygon; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE gis_polygon ALL NULL NULL NULL NULL 3 100.00 +Warnings: +Note 1003 select astext(centroid(`test`.`gis_polygon`.`g`)) AS `AsText(Centroid(g))`,area(`test`.`gis_polygon`.`g`) AS `Area(g)`,astext(exteriorring(`test`.`gis_polygon`.`g`)) AS `AsText(ExteriorRing(g))`,numinteriorrings(`test`.`gis_polygon`.`g`) AS `NumInteriorRings(g)`,astext(interiorringn(`test`.`gis_polygon`.`g`,1)) AS `AsText(InteriorRingN(g, 1))` from `test`.`gis_polygon` +SELECT fid, IsClosed(g) FROM gis_multi_line ORDER by fid; +fid IsClosed(g) +114 0 +115 0 +116 0 +SELECT fid, AsText(Centroid(g)) FROM gis_multi_polygon ORDER by fid; +fid AsText(Centroid(g)) +117 POINT(55.5885277530424 17.426536064114) +118 POINT(55.5885277530424 17.426536064114) +119 POINT(2 2) +SELECT fid, Area(g) FROM gis_multi_polygon ORDER by fid; +fid Area(g) +117 1684.5 +118 1684.5 +119 4.5 +SELECT fid, NumGeometries(g) from gis_multi_point ORDER by fid; +fid NumGeometries(g) +111 4 +112 4 +113 2 +SELECT fid, NumGeometries(g) from gis_multi_line ORDER by fid; +fid NumGeometries(g) +114 2 +115 1 +116 2 +SELECT fid, NumGeometries(g) from gis_multi_polygon ORDER by fid; +fid NumGeometries(g) +117 2 +118 2 +119 1 +SELECT fid, NumGeometries(g) from gis_geometrycollection ORDER by fid; +fid NumGeometries(g) +120 2 +121 2 +explain extended SELECT fid, NumGeometries(g) from gis_multi_point; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL 3 100.00 +Warnings: +Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,numgeometries(`test`.`gis_multi_point`.`g`) AS `NumGeometries(g)` from `test`.`gis_multi_point` +SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_point ORDER by fid; +fid AsText(GeometryN(g, 2)) +111 POINT(10 10) +112 POINT(11 11) +113 POINT(4 10) +SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_line ORDER by fid; +fid AsText(GeometryN(g, 2)) +114 LINESTRING(16 0,16 23,16 48) +115 NULL +116 LINESTRING(2 5,5 8,21 7) +SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_polygon ORDER by fid; +fid AsText(GeometryN(g, 2)) +117 POLYGON((59 18,67 18,67 13,59 13,59 18)) +118 POLYGON((59 18,67 18,67 13,59 13,59 18)) +119 NULL +SELECT fid, AsText(GeometryN(g, 2)) from gis_geometrycollection ORDER by fid; +fid AsText(GeometryN(g, 2)) +120 LINESTRING(0 0,10 10) +121 LINESTRING(3 6,7 9) +SELECT fid, AsText(GeometryN(g, 1)) from gis_geometrycollection ORDER by fid; +fid AsText(GeometryN(g, 1)) +120 POINT(0 0) +121 POINT(44 6) +explain extended SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_point; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE gis_multi_point ALL NULL NULL NULL NULL 3 100.00 +Warnings: +Note 1003 select `test`.`gis_multi_point`.`fid` AS `fid`,astext(geometryn(`test`.`gis_multi_point`.`g`,2)) AS `AsText(GeometryN(g, 2))` from `test`.`gis_multi_point` +SELECT g1.fid as first, g2.fid as second, +Within(g1.g, g2.g) as w, Contains(g1.g, g2.g) as c, Overlaps(g1.g, g2.g) as o, +Equals(g1.g, g2.g) as e, Disjoint(g1.g, g2.g) as d, Touches(g1.g, g2.g) as t, +Intersects(g1.g, g2.g) as i, Crosses(g1.g, g2.g) as r +FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second; +first second w c o e d t i r +120 120 1 1 0 1 0 0 1 0 +120 121 0 0 1 0 0 0 1 0 +121 120 0 0 1 0 0 0 1 0 +121 121 1 1 0 1 0 0 1 0 +explain extended SELECT g1.fid as first, g2.fid as second, +Within(g1.g, g2.g) as w, Contains(g1.g, g2.g) as c, Overlaps(g1.g, g2.g) as o, +Equals(g1.g, g2.g) as e, Disjoint(g1.g, g2.g) as d, Touches(g1.g, g2.g) as t, +Intersects(g1.g, g2.g) as i, Crosses(g1.g, g2.g) as r +FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE g1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort +1 SIMPLE g2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer +Warnings: +Note 1003 select `test`.`g1`.`fid` AS `first`,`test`.`g2`.`fid` AS `second`,within(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `w`,contains(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `c`,overlaps(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `o`,equals(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `e`,disjoint(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `d`,touches(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `t`,intersects(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `i`,crosses(`test`.`g1`.`g`,`test`.`g2`.`g`) AS `r` from `test`.`gis_geometrycollection` `g1` join `test`.`gis_geometrycollection` `g2` order by `test`.`g1`.`fid`,`test`.`g2`.`fid` +DROP TABLE gis_point, gis_line, gis_polygon, gis_multi_point, gis_multi_line, gis_multi_polygon, gis_geometrycollection, gis_geometry; +CREATE TABLE t1 ( +a INTEGER PRIMARY KEY AUTO_INCREMENT, +gp point, +ln linestring, +pg polygon, +mp multipoint, +mln multilinestring, +mpg multipolygon, +gc geometrycollection, +gm geometry +); +SHOW FIELDS FROM t1; +Field Type Null Key Default Extra +a int(11) NO PRI NULL auto_increment +gp point YES NULL +ln linestring YES NULL +pg polygon YES NULL +mp multipoint YES NULL +mln multilinestring YES NULL +mpg multipolygon YES NULL +gc geometrycollection YES NULL +gm geometry YES NULL +ALTER TABLE t1 ADD fid INT; +SHOW FIELDS FROM t1; +Field Type Null Key Default Extra +a int(11) NO PRI NULL auto_increment +gp point YES NULL +ln linestring YES NULL +pg polygon YES NULL +mp multipoint YES NULL +mln multilinestring YES NULL +mpg multipolygon YES NULL +gc geometrycollection YES NULL +gm geometry YES NULL +fid int(11) YES NULL +DROP TABLE t1; +create table t1 (pk integer primary key auto_increment, a geometry not null); +insert into t1 (a) values (GeomFromText('Point(1 2)')); +insert into t1 (a) values ('Garbage'); +ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field +insert IGNORE into t1 (a) values ('Garbage'); +ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field +drop table t1; +create table t1 (pk integer primary key auto_increment, fl geometry not null); +insert into t1 (fl) values (1); +ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field +insert into t1 (fl) values (1.11); +ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field +insert into t1 (fl) values ("qwerty"); +ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field +insert into t1 (fl) values (pointfromtext('point(1,1)')); +ERROR 23000: Column 'fl' cannot be null +drop table t1; +End of 4.1 tests +CREATE TABLE t1 (name VARCHAR(100), square GEOMETRY); +INSERT INTO t1 VALUES("center", GeomFromText('POLYGON (( 0 0, 0 2, 2 2, 2 0, 0 0))')); +INSERT INTO t1 VALUES("small", GeomFromText('POLYGON (( 0 0, 0 1, 1 1, 1 0, 0 0))')); +INSERT INTO t1 VALUES("big", GeomFromText('POLYGON (( 0 0, 0 3, 3 3, 3 0, 0 0))')); +INSERT INTO t1 VALUES("up", GeomFromText('POLYGON (( 0 1, 0 3, 2 3, 2 1, 0 1))')); +INSERT INTO t1 VALUES("up2", GeomFromText('POLYGON (( 0 2, 0 4, 2 4, 2 2, 0 2))')); +INSERT INTO t1 VALUES("up3", GeomFromText('POLYGON (( 0 3, 0 5, 2 5, 2 3, 0 3))')); +INSERT INTO t1 VALUES("down", GeomFromText('POLYGON (( 0 -1, 0 1, 2 1, 2 -1, 0 -1))')); +INSERT INTO t1 VALUES("down2", GeomFromText('POLYGON (( 0 -2, 0 0, 2 0, 2 -2, 0 -2))')); +INSERT INTO t1 VALUES("down3", GeomFromText('POLYGON (( 0 -3, 0 -1, 2 -1, 2 -3, 0 -3))')); +INSERT INTO t1 VALUES("right", GeomFromText('POLYGON (( 1 0, 1 2, 3 2, 3 0, 1 0))')); +INSERT INTO t1 VALUES("right2", GeomFromText('POLYGON (( 2 0, 2 2, 4 2, 4 0, 2 0))')); +INSERT INTO t1 VALUES("right3", GeomFromText('POLYGON (( 3 0, 3 2, 5 2, 5 0, 3 0))')); +INSERT INTO t1 VALUES("left", GeomFromText('POLYGON (( -1 0, -1 2, 1 2, 1 0, -1 0))')); +INSERT INTO t1 VALUES("left2", GeomFromText('POLYGON (( -2 0, -2 2, 0 2, 0 0, -2 0))')); +INSERT INTO t1 VALUES("left3", GeomFromText('POLYGON (( -3 0, -3 2, -1 2, -1 0, -3 0))')); +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrcontains FROM t1 a1 JOIN t1 a2 ON MBRContains( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrcontains +center,small +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrdisjoint FROM t1 a1 JOIN t1 a2 ON MBRDisjoint( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrdisjoint +down3,left3,right3,up3 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrequal FROM t1 a1 JOIN t1 a2 ON MBREqual( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrequal +center +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrintersect FROM t1 a1 JOIN t1 a2 ON MBRIntersects( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrintersect +big,center,down,down2,left,left2,right,right2,small,up,up2 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbroverlaps FROM t1 a1 JOIN t1 a2 ON MBROverlaps( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbroverlaps +down,left,right,up +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrtouches FROM t1 a1 JOIN t1 a2 ON MBRTouches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrtouches +down2,left2,right2,up2 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrwithin FROM t1 a1 JOIN t1 a2 ON MBRWithin( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrwithin +big,center +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS contains FROM t1 a1 JOIN t1 a2 ON Contains( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +contains +center,small +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS disjoint FROM t1 a1 JOIN t1 a2 ON Disjoint( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +disjoint +down3,left3,right3,up3 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS equals FROM t1 a1 JOIN t1 a2 ON Equals( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +equals +center +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS intersect FROM t1 a1 JOIN t1 a2 ON Intersects( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +intersect +big,center,down,down2,left,left2,right,right2,small,up,up2 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS overlaps FROM t1 a1 JOIN t1 a2 ON Overlaps( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +overlaps +down,left,right,up +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS touches FROM t1 a1 JOIN t1 a2 ON Touches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +touches +down2,left2,right2,up2 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS within FROM t1 a1 JOIN t1 a2 ON Within( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +within +big,center +SET @vert1 = GeomFromText('POLYGON ((0 -2, 0 2, 0 -2))'); +SET @horiz1 = GeomFromText('POLYGON ((-2 0, 2 0, -2 0))'); +SET @horiz2 = GeomFromText('POLYGON ((-1 0, 3 0, -1 0))'); +SET @horiz3 = GeomFromText('POLYGON ((2 0, 3 0, 2 0))'); +SET @point1 = GeomFromText('POLYGON ((0 0))'); +SET @point2 = GeomFromText('POLYGON ((-2 0))'); +SELECT GROUP_CONCAT(a1.name ORDER BY a1.name) AS overlaps FROM t1 a1 WHERE Overlaps(a1.square, @vert1) GROUP BY a1.name; +overlaps +SELECT GROUP_CONCAT(a1.name ORDER BY a1.name) AS overlaps FROM t1 a1 WHERE Overlaps(a1.square, @horiz1) GROUP BY a1.name; +overlaps +SELECT Overlaps(@horiz1, @vert1) FROM DUAL; +Overlaps(@horiz1, @vert1) +0 +SELECT Overlaps(@horiz1, @horiz2) FROM DUAL; +Overlaps(@horiz1, @horiz2) +1 +SELECT Overlaps(@horiz1, @horiz3) FROM DUAL; +Overlaps(@horiz1, @horiz3) +0 +SELECT Overlaps(@horiz1, @point1) FROM DUAL; +Overlaps(@horiz1, @point1) +0 +SELECT Overlaps(@horiz1, @point2) FROM DUAL; +Overlaps(@horiz1, @point2) +0 +DROP TABLE t1; +End of 5.0 tests +CREATE TABLE t1 (p POINT); +CREATE TABLE t2 (p POINT, INDEX(p)); +INSERT INTO t1 VALUES (POINTFROMTEXT('POINT(1 2)')); +INSERT INTO t2 VALUES (POINTFROMTEXT('POINT(1 2)')); +SELECT COUNT(*) FROM t1 WHERE p=POINTFROMTEXT('POINT(1 2)'); +COUNT(*) +1 +EXPLAIN +SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref p p 28 const 1 Using where +SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)'); +COUNT(*) +1 +INSERT INTO t1 VALUES (POINTFROMTEXT('POINT(1 2)')); +INSERT INTO t2 VALUES (POINTFROMTEXT('POINT(1 2)')); +EXPLAIN +SELECT COUNT(*) FROM t1 WHERE p=POINTFROMTEXT('POINT(1 2)'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where +SELECT COUNT(*) FROM t1 WHERE p=POINTFROMTEXT('POINT(1 2)'); +COUNT(*) +2 +EXPLAIN +SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref p p 28 const 1 Using where +SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)'); +COUNT(*) +2 +EXPLAIN +SELECT COUNT(*) FROM t2 IGNORE INDEX(p) WHERE p=POINTFROMTEXT('POINT(1 2)'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where +SELECT COUNT(*) FROM t2 IGNORE INDEX(p) WHERE p=POINTFROMTEXT('POINT(1 2)'); +COUNT(*) +2 +DROP TABLE t1, t2; +End of 5.0 tests +create table t1 (g geometry not null, spatial gk(g)) engine=innodb; +ERROR HY000: The used table type doesn't support SPATIAL indexes diff --git a/mysql-test/suite/innodb_plugin/r/innodb_lock_wait_timeout_1.result b/mysql-test/suite/innodb_plugin/r/innodb_lock_wait_timeout_1.result new file mode 100644 index 00000000000..bd8760b8f79 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_lock_wait_timeout_1.result @@ -0,0 +1,375 @@ +# +# Bug #40113: Embedded SELECT inside UPDATE or DELETE can timeout +# without error +# +CREATE TABLE t1 (a int, b int, PRIMARY KEY (a,b)) ENGINE=InnoDB; +INSERT INTO t1 (a,b) VALUES (1070109,99); +CREATE TABLE t2 (b int, a int, PRIMARY KEY (b)) ENGINE=InnoDB; +INSERT INTO t2 (b,a) VALUES (7,1070109); +SELECT * FROM t1; +a b +1070109 99 +BEGIN; +SELECT b FROM t2 WHERE b=7 FOR UPDATE; +b +7 +BEGIN; +SELECT b FROM t2 WHERE b=7 FOR UPDATE; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +INSERT INTO t1 (a) VALUES ((SELECT a FROM t2 WHERE b=7)); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE t1 SET a='7000000' WHERE a=(SELECT a FROM t2 WHERE b=7); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +DELETE FROM t1 WHERE a=(SELECT a FROM t2 WHERE b=7); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT * FROM t1; +a b +1070109 99 +DROP TABLE t2, t1; +# End of 5.0 tests +# +# Bug#46539 Various crashes on INSERT IGNORE SELECT + SELECT +# FOR UPDATE +# +drop table if exists t1; +create table t1 (a int primary key auto_increment, +b int, index(b)) engine=innodb; +insert into t1 (b) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); +set autocommit=0; +begin; +select * from t1 where b=5 for update; +a b +5 5 +insert ignore into t1 (b) select a as b from t1; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +# Cleanup +# +commit; +set autocommit=default; +drop table t1; +# +# Bug #37183 insert ignore into .. select ... hangs +# after deadlock was encountered +# +create table t1(id int primary key,v int)engine=innodb; +insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7); +create table t2 like t1; +begin; +update t1 set v=id*2 where id=1; +begin; +update t1 set v=id*2 where id=2; +update t1 set v=id*2 where id=2; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +insert ignore into t2 select * from t1 where id=1; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +rollback; +rollback; +drop table t1, t2; +# +# Bug#41756 Strange error messages about locks from InnoDB +# +drop table if exists t1; +# In the default transaction isolation mode, and/or with +# innodb_locks_unsafe_for_binlog=OFF, handler::unlock_row() +# in InnoDB does nothing. +# Thus in order to reproduce the condition that led to the +# warning, one needs to relax isolation by either +# setting a weaker tx_isolation value, or by turning on +# the unsafe replication switch. +# For testing purposes, choose to tweak the isolation level, +# since it's settable at runtime, unlike +# innodb_locks_unsafe_for_binlog, which is +# only a command-line switch. +# +set @@session.tx_isolation="read-committed"; +# Prepare data. We need a table with a unique index, +# for join_read_key to be used. The other column +# allows to control what passes WHERE clause filter. +create table t1 (a int primary key, b int) engine=innodb; +# Let's make sure t1 has sufficient amount of rows +# to exclude JT_ALL access method when reading it, +# i.e. make sure that JT_EQ_REF(a) is always preferred. +insert into t1 values (1,1), (2,null), (3,1), (4,1), +(5,1), (6,1), (7,1), (8,1), (9,1), (10,1), +(11,1), (12,1), (13,1), (14,1), (15,1), +(16,1), (17,1), (18,1), (19,1), (20,1); +# +# Demonstrate that for the SELECT statement +# used later in the test JT_EQ_REF access method is used. +# +explain +select 1 from t1 natural join (select 2 as a, 1 as b union all +select 2 as a, 2 as b) as t2 for update; +id 1 +select_type PRIMARY +table +type ALL +possible_keys NULL +key NULL +key_len NULL +ref NULL +rows 2 +Extra +id 1 +select_type PRIMARY +table t1 +type eq_ref +possible_keys PRIMARY +key PRIMARY +key_len 4 +ref t2.a +rows 1 +Extra Using where +id 2 +select_type DERIVED +table NULL +type NULL +possible_keys NULL +key NULL +key_len NULL +ref NULL +rows NULL +Extra No tables used +id 3 +select_type UNION +table NULL +type NULL +possible_keys NULL +key NULL +key_len NULL +ref NULL +rows NULL +Extra No tables used +id NULL +select_type UNION RESULT +table +type ALL +possible_keys NULL +key NULL +key_len NULL +ref NULL +rows NULL +Extra +# +# Demonstrate that the reported SELECT statement +# no longer produces warnings. +# +select 1 from t1 natural join (select 2 as a, 1 as b union all +select 2 as a, 2 as b) as t2 for update; +1 +commit; +# +# Demonstrate that due to lack of inter-sweep "reset" function, +# we keep some non-matching records locked, even though we know +# we could unlock them. +# To do that, show that if there is only one distinct value +# for a in t2 (a=2), we will keep record (2,null) in t1 locked. +# But if we add another value for "a" to t2, say 6, +# join_read_key cache will be pruned at least once, +# and thus record (2, null) in t1 will get unlocked. +# +begin; +select 1 from t1 natural join (select 2 as a, 1 as b union all +select 2 as a, 2 as b) as t2 for update; +1 +# +# Switching to connection con1 +# We should be able to delete all records from t1 except (2, null), +# since they were not locked. +begin; +# Delete in series of 3 records so that full scan +# is not used and we're not blocked on record (2,null) +delete from t1 where a in (1,3,4); +delete from t1 where a in (5,6,7); +delete from t1 where a in (8,9,10); +delete from t1 where a in (11,12,13); +delete from t1 where a in (14,15,16); +delete from t1 where a in (17,18); +delete from t1 where a in (19,20); +# +# Record (2, null) is locked. This is actually unnecessary, +# because the previous select returned no rows. +# Just demonstrate the effect. +# +delete from t1; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +rollback; +# +# Switching to connection default +# +# Show that the original contents of t1 is intact: +select * from t1; +a b +1 1 +2 NULL +3 1 +4 1 +5 1 +6 1 +7 1 +8 1 +9 1 +10 1 +11 1 +12 1 +13 1 +14 1 +15 1 +16 1 +17 1 +18 1 +19 1 +20 1 +commit; +# +# Have a one more record in t2 to show that +# if join_read_key cache is purned, the current +# row under the cursor is unlocked (provided, this row didn't +# match the partial WHERE clause, of course). +# Sic: the result of this test dependent on the order of retrieval +# of records --echo # from the derived table, if ! +# We use DELETE to disable the JOIN CACHE. This DELETE modifies no +# records. It also should leave no InnoDB row locks. +# +begin; +delete t1.* from t1 natural join (select 2 as a, 2 as b union all +select 0 as a, 0 as b) as t2; +# Demonstrate that nothing was deleted form t1 +select * from t1; +a b +1 1 +2 NULL +3 1 +4 1 +5 1 +6 1 +7 1 +8 1 +9 1 +10 1 +11 1 +12 1 +13 1 +14 1 +15 1 +16 1 +17 1 +18 1 +19 1 +20 1 +# +# Switching to connection con1 +begin; +# Since there is another distinct record in the derived table +# the previous matching record in t1 -- (2,null) -- was unlocked. +delete from t1; +# We will need the contents of the table again. +rollback; +select * from t1; +a b +1 1 +2 NULL +3 1 +4 1 +5 1 +6 1 +7 1 +8 1 +9 1 +10 1 +11 1 +12 1 +13 1 +14 1 +15 1 +16 1 +17 1 +18 1 +19 1 +20 1 +commit; +# +# Switching to connection default +rollback; +begin; +# +# Before this patch, we could wrongly unlock a record +# that was cached and later used in a join. Demonstrate that +# this is no longer the case. +# Sic: this test is also order-dependent (i.e. the +# the bug would show up only if the first record in the union +# is retreived and processed first. +# +# Verify that JT_EQ_REF is used. +explain +select 1 from t1 natural join (select 3 as a, 2 as b union all +select 3 as a, 1 as b) as t2 for update; +id 1 +select_type PRIMARY +table +type ALL +possible_keys NULL +key NULL +key_len NULL +ref NULL +rows 2 +Extra +id 1 +select_type PRIMARY +table t1 +type eq_ref +possible_keys PRIMARY +key PRIMARY +key_len 4 +ref t2.a +rows 1 +Extra Using where +id 2 +select_type DERIVED +table NULL +type NULL +possible_keys NULL +key NULL +key_len NULL +ref NULL +rows NULL +Extra No tables used +id 3 +select_type UNION +table NULL +type NULL +possible_keys NULL +key NULL +key_len NULL +ref NULL +rows NULL +Extra No tables used +id NULL +select_type UNION RESULT +table +type ALL +possible_keys NULL +key NULL +key_len NULL +ref NULL +rows NULL +Extra +# Lock the record. +select 1 from t1 natural join (select 3 as a, 2 as b union all +select 3 as a, 1 as b) as t2 for update; +1 +1 +# Switching to connection con1 +# +# We should not be able to delete record (3,1) from t1, +# (previously it was possible). +# +delete from t1 where a=3; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +# Switching to connection default +commit; +set @@session.tx_isolation=default; +drop table t1; +# +# End of 5.1 tests +# diff --git a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result new file mode 100644 index 00000000000..2bf1ef8fbf0 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result @@ -0,0 +1,2381 @@ +set global innodb_support_xa=default; +set session innodb_support_xa=default; +SET SESSION STORAGE_ENGINE = InnoDB; +drop table if exists t1,t2,t3,t1m,t1i,t2m,t2i,t4; +drop procedure if exists p1; +create table t1 ( +c_id int(11) not null default '0', +org_id int(11) default null, +unique key contacts$c_id (c_id), +key contacts$org_id (org_id) +); +insert into t1 values +(2,null),(120,null),(141,null),(218,7), (128,1), +(151,2),(234,2),(236,2),(243,2),(255,2),(259,2),(232,3),(235,3),(238,3), +(246,3),(253,3),(269,3),(285,3),(291,3),(293,3),(131,4),(230,4),(231,4); +create table t2 ( +slai_id int(11) not null default '0', +owner_tbl int(11) default null, +owner_id int(11) default null, +sla_id int(11) default null, +inc_web int(11) default null, +inc_email int(11) default null, +inc_chat int(11) default null, +inc_csr int(11) default null, +inc_total int(11) default null, +time_billed int(11) default null, +activedate timestamp null default null, +expiredate timestamp null default null, +state int(11) default null, +sla_set int(11) default null, +unique key t2$slai_id (slai_id), +key t2$owner_id (owner_id), +key t2$sla_id (sla_id) +); +insert into t2(slai_id, owner_tbl, owner_id, sla_id) values +(1,3,1,1), (3,3,10,2), (4,3,3,6), (5,3,2,5), (6,3,8,3), (7,3,9,7), +(8,3,6,8), (9,3,4,9), (10,3,5,10), (11,3,11,11), (12,3,7,12); +flush tables; +select si.slai_id +from t1 c join t2 si on +((si.owner_tbl = 3 and si.owner_id = c.org_id) or +( si.owner_tbl = 2 and si.owner_id = c.c_id)) +where +c.c_id = 218 and expiredate is null; +slai_id +12 +select * from t1 where org_id is null; +c_id org_id +2 NULL +120 NULL +141 NULL +select si.slai_id +from t1 c join t2 si on +((si.owner_tbl = 3 and si.owner_id = c.org_id) or +( si.owner_tbl = 2 and si.owner_id = c.c_id)) +where +c.c_id = 218 and expiredate is null; +slai_id +12 +drop table t1, t2; +CREATE TABLE t1 (a int, b int, KEY b (b)); +CREATE TABLE t2 (a int, b int, PRIMARY KEY (a,b)); +CREATE TABLE t3 (a int, b int, c int, PRIMARY KEY (a), +UNIQUE KEY b (b,c), KEY a (a,b,c)); +INSERT INTO t1 VALUES (1, 1); +INSERT INTO t1 SELECT a + 1, b + 1 FROM t1; +INSERT INTO t1 SELECT a + 2, b + 2 FROM t1; +INSERT INTO t2 VALUES (1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1,8); +INSERT INTO t2 SELECT a + 1, b FROM t2; +DELETE FROM t2 WHERE a = 1 AND b < 2; +INSERT INTO t3 VALUES (1,1,1),(2,1,2); +INSERT INTO t3 SELECT a + 2, a + 2, 3 FROM t3; +INSERT INTO t3 SELECT a + 4, a + 4, 3 FROM t3; +SELECT STRAIGHT_JOIN SQL_NO_CACHE t1.b, t1.a FROM t1, t3, t2 WHERE +t3.a = t2.a AND t2.b = t1.a AND t3.b = 1 AND t3.c IN (1, 2) +ORDER BY t1.b LIMIT 2; +b a +1 1 +2 2 +SELECT STRAIGHT_JOIN SQL_NO_CACHE t1.b, t1.a FROM t1, t3, t2 WHERE +t3.a = t2.a AND t2.b = t1.a AND t3.b = 1 AND t3.c IN (1, 2) +ORDER BY t1.b LIMIT 5; +b a +1 1 +2 2 +2 2 +3 3 +3 3 +DROP TABLE t1, t2, t3; +CREATE TABLE `t1` (`id1` INT) ; +INSERT INTO `t1` (`id1`) VALUES (1),(5),(2); +CREATE TABLE `t2` ( +`id1` INT, +`id2` INT NOT NULL, +`id3` INT, +`id4` INT NOT NULL, +UNIQUE (`id2`,`id4`), +KEY (`id1`) +); +INSERT INTO `t2`(`id1`,`id2`,`id3`,`id4`) VALUES +(1,1,1,0), +(1,1,2,1), +(5,1,2,2), +(6,1,2,3), +(1,2,2,2), +(1,2,1,1); +SELECT `id1` FROM `t1` WHERE `id1` NOT IN (SELECT `id1` FROM `t2` WHERE `id2` = 1 AND `id3` = 2); +id1 +2 +DROP TABLE t1, t2; +create table t1 (c1 int) engine=innodb; +handler t1 open; +handler t1 read first; +c1 +Before and after comparison +0 +drop table t1; +CREATE TABLE t1(c1 TEXT, UNIQUE (c1(1)), cnt INT DEFAULT 1) +ENGINE=INNODB CHARACTER SET UTF8; +INSERT INTO t1 (c1) VALUES ('1a'); +SELECT * FROM t1; +c1 cnt +1a 1 +INSERT INTO t1 (c1) VALUES ('1b') ON DUPLICATE KEY UPDATE cnt=cnt+1; +SELECT * FROM t1; +c1 cnt +1a 2 +DROP TABLE t1; +CREATE TABLE t1(c1 VARCHAR(2), UNIQUE (c1(1)), cnt INT DEFAULT 1) +ENGINE=INNODB CHARACTER SET UTF8; +INSERT INTO t1 (c1) VALUES ('1a'); +SELECT * FROM t1; +c1 cnt +1a 1 +INSERT INTO t1 (c1) VALUES ('1b') ON DUPLICATE KEY UPDATE cnt=cnt+1; +SELECT * FROM t1; +c1 cnt +1a 2 +DROP TABLE t1; +CREATE TABLE t1(c1 CHAR(2), UNIQUE (c1(1)), cnt INT DEFAULT 1) +ENGINE=INNODB CHARACTER SET UTF8; +INSERT INTO t1 (c1) VALUES ('1a'); +SELECT * FROM t1; +c1 cnt +1a 1 +INSERT INTO t1 (c1) VALUES ('1b') ON DUPLICATE KEY UPDATE cnt=cnt+1; +SELECT * FROM t1; +c1 cnt +1a 2 +DROP TABLE t1; +CREATE TABLE t1 ( +a1 decimal(10,0) DEFAULT NULL, +a2 blob, +a3 time DEFAULT NULL, +a4 blob, +a5 char(175) DEFAULT NULL, +a6 timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', +a7 tinyblob, +INDEX idx (a6,a7(239),a5) +) ENGINE=InnoDB; +EXPLAIN SELECT a4 FROM t1 WHERE +a6=NULL AND +a4='UNcT5pIde4I6c2SheTo4gt92OV1jgJCVkXmzyf325R1DwLURkbYHwhydANIZMbKTgdcR5xS'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +EXPLAIN SELECT t1.a4 FROM t1, t1 t WHERE +t.a6=t.a6 AND t1.a6=NULL AND +t1.a4='UNcT5pIde4I6c2SheTo4gt92OV1jgJCVkXmzyf325R1DwLURkbYHwhydANIZMbKTgdcR5xS'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +DROP TABLE t1; +create table t1m (a int) engine = MEMORY; +create table t1i (a int); +create table t2m (a int) engine = MEMORY; +create table t2i (a int); +insert into t2m values (5); +insert into t2i values (5); +select min(a) from t1i; +min(a) +NULL +select min(7) from t1i; +min(7) +NULL +select min(7) from DUAL; +min(7) +7 +explain select min(7) from t2i join t1i; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2i ALL NULL NULL NULL NULL 1 +1 SIMPLE t1i ALL NULL NULL NULL NULL 1 Using join buffer +select min(7) from t2i join t1i; +min(7) +NULL +select max(a) from t1i; +max(a) +NULL +select max(7) from t1i; +max(7) +NULL +select max(7) from DUAL; +max(7) +7 +explain select max(7) from t2i join t1i; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2i ALL NULL NULL NULL NULL 1 +1 SIMPLE t1i ALL NULL NULL NULL NULL 1 Using join buffer +select max(7) from t2i join t1i; +max(7) +NULL +select 1, min(a) from t1i where a=99; +1 min(a) +1 NULL +select 1, min(a) from t1i where 1=99; +1 min(a) +1 NULL +select 1, min(1) from t1i where a=99; +1 min(1) +1 NULL +select 1, min(1) from t1i where 1=99; +1 min(1) +1 NULL +select 1, max(a) from t1i where a=99; +1 max(a) +1 NULL +select 1, max(a) from t1i where 1=99; +1 max(a) +1 NULL +select 1, max(1) from t1i where a=99; +1 max(1) +1 NULL +select 1, max(1) from t1i where 1=99; +1 max(1) +1 NULL +explain select count(*), min(7), max(7) from t1m, t1i; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1m system NULL NULL NULL NULL 0 const row not found +1 SIMPLE t1i ALL NULL NULL NULL NULL 1 +select count(*), min(7), max(7) from t1m, t1i; +count(*) min(7) max(7) +0 NULL NULL +explain select count(*), min(7), max(7) from t1m, t2i; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1m system NULL NULL NULL NULL 0 const row not found +1 SIMPLE t2i ALL NULL NULL NULL NULL 1 +select count(*), min(7), max(7) from t1m, t2i; +count(*) min(7) max(7) +0 NULL NULL +explain select count(*), min(7), max(7) from t2m, t1i; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2m system NULL NULL NULL NULL 1 +1 SIMPLE t1i ALL NULL NULL NULL NULL 1 +select count(*), min(7), max(7) from t2m, t1i; +count(*) min(7) max(7) +0 NULL NULL +drop table t1m, t1i, t2m, t2i; +create table t1 ( +a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(64) default ' ' +) ENGINE = MEMORY; +insert into t1 (a1, a2, b, c, d) values +('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'), +('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'), +('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'), +('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'), +('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'), +('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'), +('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'), +('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'), +('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'), +('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'), +('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'), +('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'), +('d','a','a','a411','xy1'),('d','a','a','b411','xy2'),('d','a','a','c411','xy3'),('d','a','a','d411','xy4'), +('d','a','b','e412','xy1'),('d','a','b','f412','xy2'),('d','a','b','g412','xy3'),('d','a','b','h412','xy4'), +('d','b','a','i421','xy1'),('d','b','a','j421','xy2'),('d','b','a','k421','xy3'),('d','b','a','l421','xy4'), +('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4'), +('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'), +('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'), +('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'), +('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'), +('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'), +('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'), +('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'), +('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'), +('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'), +('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'), +('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'), +('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'), +('d','a','a','a411','xy1'),('d','a','a','b411','xy2'),('d','a','a','c411','xy3'),('d','a','a','d411','xy4'), +('d','a','b','e412','xy1'),('d','a','b','f412','xy2'),('d','a','b','g412','xy3'),('d','a','b','h412','xy4'), +('d','b','a','i421','xy1'),('d','b','a','j421','xy2'),('d','b','a','k421','xy3'),('d','b','a','l421','xy4'), +('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4'); +create table t4 ( +pk_col int auto_increment primary key, a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(64) default ' ' +); +insert into t4 (a1, a2, b, c, d, dummy) select * from t1; +create index idx12672_0 on t4 (a1); +create index idx12672_1 on t4 (a1,a2,b,c); +create index idx12672_2 on t4 (a1,a2,b); +analyze table t4; +Table Op Msg_type Msg_text +test.t4 analyze status OK +select distinct a1 from t4 where pk_col not in (1,2,3,4); +a1 +a +b +c +d +drop table t1,t4; +DROP TABLE IF EXISTS t2, t1; +CREATE TABLE t1 (i INT NOT NULL PRIMARY KEY) ENGINE= InnoDB; +CREATE TABLE t2 ( +i INT NOT NULL, +FOREIGN KEY (i) REFERENCES t1 (i) ON DELETE NO ACTION +) ENGINE= InnoDB; +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1); +DELETE IGNORE FROM t1 WHERE i = 1; +Warnings: +Error 1451 Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`i`) REFERENCES `t1` (`i`) ON DELETE NO ACTION) +SELECT * FROM t1, t2; +i i +1 1 +DROP TABLE t2, t1; +End of 4.1 tests. +create table t1 ( +a varchar(30), b varchar(30), primary key(a), key(b) +); +select distinct a from t1; +a +drop table t1; +create table t1(a int, key(a)); +insert into t1 values(1); +select a, count(a) from t1 group by a with rollup; +a count(a) +1 1 +NULL 1 +drop table t1; +create table t1 (f1 int, f2 char(1), primary key(f1,f2)); +insert into t1 values ( 1,"e"),(2,"a"),( 3,"c"),(4,"d"); +alter table t1 drop primary key, add primary key (f2, f1); +explain select distinct f1 a, f1 b from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL PRIMARY 5 NULL 4 Using index; Using temporary +explain select distinct f1, f2 from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range NULL PRIMARY 5 NULL 3 Using index for group-by; Using temporary +drop table t1; +CREATE TABLE t1 (id int(11) NOT NULL PRIMARY KEY, name varchar(20), +INDEX (name)); +CREATE TABLE t2 (id int(11) NOT NULL PRIMARY KEY, fkey int(11)); +ALTER TABLE t2 ADD FOREIGN KEY (fkey) REFERENCES t2(id); +INSERT INTO t1 VALUES (1,'A1'),(2,'A2'),(3,'B'); +INSERT INTO t2 VALUES (1,1),(2,2),(3,2),(4,3),(5,3); +EXPLAIN +SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id +WHERE t1.name LIKE 'A%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index PRIMARY,name name 23 NULL 3 Using where; Using index +1 SIMPLE t2 ref fkey fkey 5 test.t1.id 1 Using where; Using index +EXPLAIN +SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id +WHERE t1.name LIKE 'A%' OR FALSE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 index NULL fkey 5 NULL 5 Using index +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.fkey 1 Using where +DROP TABLE t1,t2; +CREATE TABLE t1 ( +id int NOT NULL, +name varchar(20) NOT NULL, +dept varchar(20) NOT NULL, +age tinyint(3) unsigned NOT NULL, +PRIMARY KEY (id), +INDEX (name,dept) +) ENGINE=InnoDB; +INSERT INTO t1(id, dept, age, name) VALUES +(3987, 'cs1', 10, 'rs1'), (3988, 'cs2', 20, 'rs1'), (3995, 'cs3', 10, 'rs2'), +(3996, 'cs4', 20, 'rs2'), (4003, 'cs5', 10, 'rs3'), (4004, 'cs6', 20, 'rs3'), +(4011, 'cs7', 10, 'rs4'), (4012, 'cs8', 20, 'rs4'), (4019, 'cs9', 10, 'rs5'), +(4020, 'cs10', 20, 'rs5'),(4027, 'cs11', 10, 'rs6'),(4028, 'cs12', 20, 'rs6'); +EXPLAIN SELECT DISTINCT t1.name, t1.dept FROM t1 WHERE t1.name='rs5'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range name name 44 NULL 2 Using where; Using index for group-by +SELECT DISTINCT t1.name, t1.dept FROM t1 WHERE t1.name='rs5'; +name dept +rs5 cs10 +rs5 cs9 +DELETE FROM t1; +# Masking (#) number in "rows" column of the following EXPLAIN output, as it may vary (bug#47746). +EXPLAIN SELECT DISTINCT t1.name, t1.dept FROM t1 WHERE t1.name='rs5'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range name name 44 NULL # Using where; Using index for group-by +SELECT DISTINCT t1.name, t1.dept FROM t1 WHERE t1.name='rs5'; +name dept +DROP TABLE t1; +drop table if exists t1; +show variables like 'innodb_rollback_on_timeout'; +Variable_name Value +innodb_rollback_on_timeout OFF +create table t1 (a int unsigned not null primary key) engine = innodb; +insert into t1 values (1); +commit; +begin work; +insert into t1 values (2); +select * from t1; +a +1 +2 +begin work; +insert into t1 values (5); +select * from t1; +a +1 +5 +insert into t1 values (2); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +select * from t1; +a +1 +5 +commit; +select * from t1; +a +1 +2 +commit; +select * from t1; +a +1 +2 +5 +drop table t1; +set @save_qcache_size=@@global.query_cache_size; +set @save_qcache_type=@@global.query_cache_type; +set global query_cache_size=10*1024*1024; +set global query_cache_type=1; +drop table if exists `test`; +Warnings: +Note 1051 Unknown table 'test' +CREATE TABLE `test` (`test1` varchar(3) NOT NULL, +`test2` varchar(4) NOT NULL,PRIMARY KEY (`test1`)) +ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO `test` (`test1`, `test2`) VALUES ('tes', '5678'); +select * from test; +test1 test2 +tes 5678 +INSERT INTO `test` (`test1`, `test2`) VALUES ('tes', '1234') +ON DUPLICATE KEY UPDATE `test2` = '1234'; +select * from test; +test1 test2 +tes 1234 +flush tables; +select * from test; +test1 test2 +tes 1234 +drop table test; +set global query_cache_type=@save_qcache_type; +set global query_cache_size=@save_qcache_size; +drop table if exists t1; +show variables like 'innodb_rollback_on_timeout'; +Variable_name Value +innodb_rollback_on_timeout OFF +create table t1 (a int unsigned not null primary key) engine = innodb; +insert into t1 values (1); +commit; +begin work; +insert into t1 values (2); +select * from t1; +a +1 +2 +begin work; +insert into t1 values (5); +select * from t1; +a +1 +5 +insert into t1 values (2); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +select * from t1; +a +1 +5 +commit; +select * from t1; +a +1 +2 +commit; +select * from t1; +a +1 +2 +5 +drop table t1; +create table t1( +id int auto_increment, +c char(1) not null, +counter int not null default 1, +primary key (id), +unique key (c) +) engine=innodb; +insert into t1 (id, c) values +(NULL, 'a'), +(NULL, 'a') +on duplicate key update id = values(id), counter = counter + 1; +select * from t1; +id c counter +2 a 2 +insert into t1 (id, c) values +(NULL, 'b') +on duplicate key update id = values(id), counter = counter + 1; +select * from t1; +id c counter +2 a 2 +3 b 1 +truncate table t1; +insert into t1 (id, c) values (NULL, 'a'); +select * from t1; +id c counter +1 a 1 +insert into t1 (id, c) values (NULL, 'b'), (NULL, 'b') +on duplicate key update id = values(id), c = values(c), counter = counter + 1; +select * from t1; +id c counter +1 a 1 +3 b 2 +insert into t1 (id, c) values (NULL, 'a') +on duplicate key update id = values(id), c = values(c), counter = counter + 1; +select * from t1; +id c counter +3 b 2 +4 a 2 +drop table t1; +CREATE TABLE t1( +id int AUTO_INCREMENT PRIMARY KEY, +stat_id int NOT NULL, +acct_id int DEFAULT NULL, +INDEX idx1 (stat_id, acct_id), +INDEX idx2 (acct_id) +) ENGINE=MyISAM; +CREATE TABLE t2( +id int AUTO_INCREMENT PRIMARY KEY, +stat_id int NOT NULL, +acct_id int DEFAULT NULL, +INDEX idx1 (stat_id, acct_id), +INDEX idx2 (acct_id) +) ENGINE=InnoDB; +INSERT INTO t1(stat_id,acct_id) VALUES +(1,759), (2,831), (3,785), (4,854), (1,921), +(1,553), (2,589), (3,743), (2,827), (2,545), +(4,779), (4,783), (1,597), (1,785), (4,832), +(1,741), (1,833), (3,788), (2,973), (1,907); +INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1; +INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1; +INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1; +INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1; +INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1; +INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1; +INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1; +INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1; +INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1; +INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1; +INSERT INTO t1(stat_id,acct_id) SELECT stat_id, mod(id+100000, acct_id) FROM t1; +UPDATE t1 SET acct_id=785 +WHERE MOD(stat_id,2)=0 AND MOD(id,stat_id)=MOD(acct_id,stat_id); +OPTIMIZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 optimize status OK +SELECT COUNT(*) FROM t1; +COUNT(*) +40960 +SELECT COUNT(*) FROM t1 WHERE acct_id=785; +COUNT(*) +8702 +EXPLAIN SELECT COUNT(*) FROM t1 WHERE stat_id IN (1,3) AND acct_id=785; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range idx1,idx2 idx1 9 NULL 2 Using where; Using index +INSERT INTO t2 SELECT * FROM t1; +OPTIMIZE TABLE t2; +Table Op Msg_type Msg_text +test.t2 optimize note Table does not support optimize, doing recreate + analyze instead +test.t2 optimize status OK +EXPLAIN SELECT COUNT(*) FROM t2 WHERE stat_id IN (1,3) AND acct_id=785; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 range idx1,idx2 idx1 9 NULL 2 Using where; Using index +DROP TABLE t1,t2; +create table t1(a int) engine=innodb; +alter table t1 comment '123'; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='123' +drop table t1; +CREATE TABLE t1 (a CHAR(2), KEY (a)) ENGINE = InnoDB DEFAULT CHARSET=UTF8; +INSERT INTO t1 VALUES ('uk'),('bg'); +SELECT * FROM t1 WHERE a = 'uk'; +a +uk +DELETE FROM t1 WHERE a = 'uk'; +SELECT * FROM t1 WHERE a = 'uk'; +a +UPDATE t1 SET a = 'us' WHERE a = 'uk'; +SELECT * FROM t1 WHERE a = 'uk'; +a +CREATE TABLE t2 (a CHAR(2), KEY (a)) ENGINE = InnoDB; +INSERT INTO t2 VALUES ('uk'),('bg'); +SELECT * FROM t2 WHERE a = 'uk'; +a +uk +DELETE FROM t2 WHERE a = 'uk'; +SELECT * FROM t2 WHERE a = 'uk'; +a +INSERT INTO t2 VALUES ('uk'); +UPDATE t2 SET a = 'us' WHERE a = 'uk'; +SELECT * FROM t2 WHERE a = 'uk'; +a +CREATE TABLE t3 (a CHAR(2), KEY (a)) ENGINE = MyISAM; +INSERT INTO t3 VALUES ('uk'),('bg'); +SELECT * FROM t3 WHERE a = 'uk'; +a +uk +DELETE FROM t3 WHERE a = 'uk'; +SELECT * FROM t3 WHERE a = 'uk'; +a +INSERT INTO t3 VALUES ('uk'); +UPDATE t3 SET a = 'us' WHERE a = 'uk'; +SELECT * FROM t3 WHERE a = 'uk'; +a +DROP TABLE t1,t2,t3; +create table t1 (a int) engine=innodb; +select * from bug29807; +ERROR 42S02: Table 'test.bug29807' doesn't exist +drop table t1; +drop table bug29807; +ERROR 42S02: Unknown table 'bug29807' +create table bug29807 (a int); +drop table bug29807; +CREATE TABLE t1 (a INT) ENGINE=InnoDB; +CREATE TABLE t2 (a INT) ENGINE=InnoDB; +switch to connection c1 +SET AUTOCOMMIT=0; +INSERT INTO t2 VALUES (1); +switch to connection c2 +SET AUTOCOMMIT=0; +LOCK TABLES t1 READ, t2 READ; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +switch to connection c1 +COMMIT; +INSERT INTO t1 VALUES (1); +switch to connection default +SET AUTOCOMMIT=default; +DROP TABLE t1,t2; +CREATE TABLE t1 ( +id int NOT NULL auto_increment PRIMARY KEY, +b int NOT NULL, +c datetime NOT NULL, +INDEX idx_b(b), +INDEX idx_c(c) +) ENGINE=InnoDB; +CREATE TABLE t2 ( +b int NOT NULL auto_increment PRIMARY KEY, +c datetime NOT NULL +) ENGINE= MyISAM; +INSERT INTO t2(c) VALUES ('2007-01-01'); +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t2(c) SELECT c FROM t2; +INSERT INTO t1(b,c) SELECT b,c FROM t2; +UPDATE t2 SET c='2007-01-02'; +INSERT INTO t1(b,c) SELECT b,c FROM t2; +UPDATE t2 SET c='2007-01-03'; +INSERT INTO t1(b,c) SELECT b,c FROM t2; +set @@sort_buffer_size=8192; +Warnings: +Warning 1292 Truncated incorrect sort_buffer_size value: '8192' +SELECT COUNT(*) FROM t1; +COUNT(*) +3072 +EXPLAIN +SELECT COUNT(*) FROM t1 +WHERE (c >= '2007-01-02' AND c <= '2007-01-03') OR b >= 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL idx_b,idx_c NULL NULL NULL # Using where +SELECT COUNT(*) FROM t1 +WHERE (c >= '2007-01-02' AND c <= '2007-01-03') OR b >= 1; +COUNT(*) +3072 +EXPLAIN +SELECT COUNT(*) FROM t1 FORCE INDEX(idx_b, idx_c) +WHERE (c >= '2007-01-02' AND c <= '2007-01-03') OR b >= 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge idx_b,idx_c idx_c,idx_b 8,4 NULL # Using sort_union(idx_c,idx_b); Using where +SELECT COUNT(*) FROM t1 FORCE INDEX(idx_b, idx_c) +WHERE (c >= '2007-01-02' AND c <= '2007-01-03') OR b >= 1; +COUNT(*) +3072 +set @@sort_buffer_size=default; +DROP TABLE t1,t2; +CREATE TABLE t1 (a int, b int); +insert into t1 values (1,1),(1,2); +CREATE TABLE t2 (primary key (a)) select * from t1; +ERROR 23000: Duplicate entry '1' for key 'PRIMARY' +drop table if exists t2; +Warnings: +Note 1051 Unknown table 't2' +CREATE TEMPORARY TABLE t2 (primary key (a)) select * from t1; +ERROR 23000: Duplicate entry '1' for key 'PRIMARY' +drop table if exists t2; +Warnings: +Note 1051 Unknown table 't2' +CREATE TABLE t2 (a int, b int, primary key (a)); +BEGIN; +INSERT INTO t2 values(100,100); +CREATE TABLE IF NOT EXISTS t2 (primary key (a)) select * from t1; +ERROR 23000: Duplicate entry '1' for key 'PRIMARY' +SELECT * from t2; +a b +100 100 +ROLLBACK; +SELECT * from t2; +a b +100 100 +TRUNCATE table t2; +INSERT INTO t2 select * from t1; +ERROR 23000: Duplicate entry '1' for key 'PRIMARY' +SELECT * from t2; +a b +drop table t2; +CREATE TEMPORARY TABLE t2 (a int, b int, primary key (a)); +BEGIN; +INSERT INTO t2 values(100,100); +CREATE TEMPORARY TABLE IF NOT EXISTS t2 (primary key (a)) select * from t1; +ERROR 23000: Duplicate entry '1' for key 'PRIMARY' +SELECT * from t2; +a b +100 100 +COMMIT; +BEGIN; +INSERT INTO t2 values(101,101); +CREATE TEMPORARY TABLE IF NOT EXISTS t2 (primary key (a)) select * from t1; +ERROR 23000: Duplicate entry '1' for key 'PRIMARY' +SELECT * from t2; +a b +100 100 +101 101 +ROLLBACK; +SELECT * from t2; +a b +100 100 +TRUNCATE table t2; +INSERT INTO t2 select * from t1; +ERROR 23000: Duplicate entry '1' for key 'PRIMARY' +SELECT * from t2; +a b +drop table t1,t2; +create table t1(f1 varchar(800) binary not null, key(f1)) +character set utf8 collate utf8_general_ci; +Warnings: +Warning 1071 Specified key was too long; max key length is 767 bytes +insert into t1 values('aaa'); +drop table t1; +CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c FLOAT, KEY b(b)) ENGINE = INNODB; +INSERT INTO t1 VALUES ( 1 , 1 , 1); +INSERT INTO t1 SELECT a + 1 , MOD(a + 1 , 20), 1 FROM t1; +INSERT INTO t1 SELECT a + 2 , MOD(a + 2 , 20), 1 FROM t1; +INSERT INTO t1 SELECT a + 4 , MOD(a + 4 , 20), 1 FROM t1; +INSERT INTO t1 SELECT a + 8 , MOD(a + 8 , 20), 1 FROM t1; +INSERT INTO t1 SELECT a + 16, MOD(a + 16, 20), 1 FROM t1; +INSERT INTO t1 SELECT a + 32, MOD(a + 32, 20), 1 FROM t1; +INSERT INTO t1 SELECT a + 64, MOD(a + 64, 20), 1 FROM t1; +EXPLAIN SELECT b, SUM(c) FROM t1 GROUP BY b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL b 5 NULL 128 +EXPLAIN SELECT SQL_BIG_RESULT b, SUM(c) FROM t1 GROUP BY b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 128 Using filesort +DROP TABLE t1; +drop table if exists t1; +show variables like 'innodb_rollback_on_timeout'; +Variable_name Value +innodb_rollback_on_timeout OFF +create table t1 (a int unsigned not null primary key) engine = innodb; +insert into t1 values (1); +commit; +begin work; +insert into t1 values (2); +select * from t1; +a +1 +2 +begin work; +insert into t1 values (5); +select * from t1; +a +1 +5 +insert into t1 values (2); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +select * from t1; +a +1 +5 +commit; +select * from t1; +a +1 +2 +commit; +select * from t1; +a +1 +2 +5 +drop table t1; +drop table if exists t1; +create table t1 (a int) engine=innodb; +alter table t1 alter a set default 1; +drop table t1; + +Bug#24918 drop table and lock / inconsistent between +perm and temp tables + +Check transactional tables under LOCK TABLES + +drop table if exists t24918, t24918_tmp, t24918_trans, t24918_trans_tmp, +t24918_access; +create table t24918_access (id int); +create table t24918 (id int) engine=myisam; +create temporary table t24918_tmp (id int) engine=myisam; +create table t24918_trans (id int) engine=innodb; +create temporary table t24918_trans_tmp (id int) engine=innodb; +lock table t24918 write, t24918_tmp write, t24918_trans write, t24918_trans_tmp write; +drop table t24918; +select * from t24918_access; +ERROR HY000: Table 't24918_access' was not locked with LOCK TABLES +drop table t24918_trans; +select * from t24918_access; +ERROR HY000: Table 't24918_access' was not locked with LOCK TABLES +drop table t24918_trans_tmp; +select * from t24918_access; +ERROR HY000: Table 't24918_access' was not locked with LOCK TABLES +drop table t24918_tmp; +select * from t24918_access; +ERROR HY000: Table 't24918_access' was not locked with LOCK TABLES +unlock tables; +drop table t24918_access; +CREATE TABLE t1 (a int, b int, PRIMARY KEY (a), KEY bkey (b)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,2),(3,2),(2,2),(4,2),(5,2),(6,2),(7,2),(8,2); +INSERT INTO t1 SELECT a + 8, 2 FROM t1; +INSERT INTO t1 SELECT a + 16, 1 FROM t1; +EXPLAIN SELECT * FROM t1 WHERE b=2 ORDER BY a; +id 1 +select_type SIMPLE +table t1 +type ref +possible_keys bkey +key bkey +key_len 5 +ref const +rows 16 +Extra Using where; Using index +SELECT * FROM t1 WHERE b=2 ORDER BY a; +a b +1 2 +2 2 +3 2 +4 2 +5 2 +6 2 +7 2 +8 2 +9 2 +10 2 +11 2 +12 2 +13 2 +14 2 +15 2 +16 2 +EXPLAIN SELECT * FROM t1 WHERE b BETWEEN 1 AND 2 ORDER BY a; +id 1 +select_type SIMPLE +table t1 +type range +possible_keys bkey +key bkey +key_len 5 +ref NULL +rows 16 +Extra Using where; Using index; Using filesort +SELECT * FROM t1 WHERE b BETWEEN 1 AND 2 ORDER BY a; +a b +1 2 +2 2 +3 2 +4 2 +5 2 +6 2 +7 2 +8 2 +9 2 +10 2 +11 2 +12 2 +13 2 +14 2 +15 2 +16 2 +17 1 +18 1 +19 1 +20 1 +21 1 +22 1 +23 1 +24 1 +25 1 +26 1 +27 1 +28 1 +29 1 +30 1 +31 1 +32 1 +EXPLAIN SELECT * FROM t1 WHERE b BETWEEN 1 AND 2 ORDER BY b,a; +id 1 +select_type SIMPLE +table t1 +type range +possible_keys bkey +key bkey +key_len 5 +ref NULL +rows 16 +Extra Using where; Using index +SELECT * FROM t1 WHERE b BETWEEN 1 AND 2 ORDER BY b,a; +a b +17 1 +18 1 +19 1 +20 1 +21 1 +22 1 +23 1 +24 1 +25 1 +26 1 +27 1 +28 1 +29 1 +30 1 +31 1 +32 1 +1 2 +2 2 +3 2 +4 2 +5 2 +6 2 +7 2 +8 2 +9 2 +10 2 +11 2 +12 2 +13 2 +14 2 +15 2 +16 2 +CREATE TABLE t2 (a int, b int, c int, PRIMARY KEY (a), KEY bkey (b,c)) +ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,1,1),(3,1,1),(2,1,1),(4,1,1); +INSERT INTO t2 SELECT a + 4, 1, 1 FROM t2; +INSERT INTO t2 SELECT a + 8, 1, 1 FROM t2; +EXPLAIN SELECT * FROM t2 WHERE b=1 ORDER BY a; +id 1 +select_type SIMPLE +table t2 +type ref +possible_keys bkey +key bkey +key_len 5 +ref const +rows 8 +Extra Using where; Using index; Using filesort +SELECT * FROM t2 WHERE b=1 ORDER BY a; +a b c +1 1 1 +2 1 1 +3 1 1 +4 1 1 +5 1 1 +6 1 1 +7 1 1 +8 1 1 +9 1 1 +10 1 1 +11 1 1 +12 1 1 +13 1 1 +14 1 1 +15 1 1 +16 1 1 +EXPLAIN SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY a; +id 1 +select_type SIMPLE +table t2 +type ref +possible_keys bkey +key bkey +key_len 10 +ref const,const +rows 8 +Extra Using where; Using index +SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY a; +a b c +1 1 1 +2 1 1 +3 1 1 +4 1 1 +5 1 1 +6 1 1 +7 1 1 +8 1 1 +9 1 1 +10 1 1 +11 1 1 +12 1 1 +13 1 1 +14 1 1 +15 1 1 +16 1 1 +EXPLAIN SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY b,c,a; +id 1 +select_type SIMPLE +table t2 +type ref +possible_keys bkey +key bkey +key_len 10 +ref const,const +rows 8 +Extra Using where; Using index +SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY b,c,a; +a b c +1 1 1 +2 1 1 +3 1 1 +4 1 1 +5 1 1 +6 1 1 +7 1 1 +8 1 1 +9 1 1 +10 1 1 +11 1 1 +12 1 1 +13 1 1 +14 1 1 +15 1 1 +16 1 1 +EXPLAIN SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY c,a; +id 1 +select_type SIMPLE +table t2 +type ref +possible_keys bkey +key bkey +key_len 10 +ref const,const +rows 8 +Extra Using where; Using index +SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY c,a; +a b c +1 1 1 +2 1 1 +3 1 1 +4 1 1 +5 1 1 +6 1 1 +7 1 1 +8 1 1 +9 1 1 +10 1 1 +11 1 1 +12 1 1 +13 1 1 +14 1 1 +15 1 1 +16 1 1 +DROP TABLE t1,t2; +CREATE TABLE t1 (a INT, PRIMARY KEY (a)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8); +INSERT INTO t1 SELECT a + 8 FROM t1; +INSERT INTO t1 SELECT a + 16 FROM t1; +CREATE PROCEDURE p1 () +BEGIN +DECLARE i INT DEFAULT 50; +DECLARE cnt INT; +START TRANSACTION; +ALTER TABLE t1 ENGINE=InnoDB; +COMMIT; +START TRANSACTION; +WHILE (i > 0) DO +SET i = i - 1; +SELECT COUNT(*) INTO cnt FROM t1 LOCK IN SHARE MODE; +END WHILE; +COMMIT; +END;| +CALL p1(); +CALL p1(); +CALL p1(); +DROP PROCEDURE p1; +DROP TABLE t1; +create table t1(a text) engine=innodb default charset=utf8; +insert into t1 values('aaa'); +alter table t1 add index(a(1024)); +Warnings: +Warning 1071 Specified key was too long; max key length is 767 bytes +Warning 1071 Specified key was too long; max key length is 767 bytes +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` text, + KEY `a` (`a`(255)) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 +drop table t1; +CREATE TABLE t1 ( +a INT, +b INT, +KEY (b) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,10), (2,10), (2,20), (3,30); +START TRANSACTION; +SELECT * FROM t1 WHERE b=20 FOR UPDATE; +a b +2 20 +START TRANSACTION; +SELECT * FROM t1 WHERE b=10 ORDER BY A FOR UPDATE; +a b +1 10 +2 10 +ROLLBACK; +ROLLBACK; +DROP TABLE t1; +CREATE TABLE t1( +a INT, +b INT NOT NULL, +c INT NOT NULL, +d INT, +UNIQUE KEY (c,b) +) engine=innodb; +INSERT INTO t1 VALUES (1,1,1,50), (1,2,3,40), (2,1,3,4); +EXPLAIN SELECT c,b,d FROM t1 GROUP BY c,b,d; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using filesort +SELECT c,b,d FROM t1 GROUP BY c,b,d; +c b d +1 1 50 +3 1 4 +3 2 40 +EXPLAIN SELECT c,b,d FROM t1 GROUP BY c,b,d ORDER BY NULL; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 +SELECT c,b,d FROM t1 GROUP BY c,b,d ORDER BY NULL; +c b d +1 1 50 +3 1 4 +3 2 40 +EXPLAIN SELECT c,b,d FROM t1 ORDER BY c,b,d; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using filesort +SELECT c,b,d FROM t1 ORDER BY c,b,d; +c b d +1 1 50 +3 1 4 +3 2 40 +EXPLAIN SELECT c,b,d FROM t1 GROUP BY c,b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL c 8 NULL 3 +SELECT c,b,d FROM t1 GROUP BY c,b; +c b d +1 1 50 +3 1 4 +3 2 40 +EXPLAIN SELECT c,b FROM t1 GROUP BY c,b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL c 8 NULL 3 Using index +SELECT c,b FROM t1 GROUP BY c,b; +c b +1 1 +3 1 +3 2 +DROP TABLE t1; +CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a), INDEX b (b)) ENGINE=InnoDB; +INSERT INTO t1(a,b) VALUES (1,1), (2,2), (3,2); +EXPLAIN SELECT * FROM t1 WHERE b=2 ORDER BY a ASC; +id 1 +select_type SIMPLE +table t1 +type ref +possible_keys b +key b +key_len 5 +ref const +rows 1 +Extra Using where; Using index +SELECT * FROM t1 WHERE b=2 ORDER BY a ASC; +a b +2 2 +3 2 +EXPLAIN SELECT * FROM t1 WHERE b=2 ORDER BY a DESC; +id 1 +select_type SIMPLE +table t1 +type ref +possible_keys b +key b +key_len 5 +ref const +rows 1 +Extra Using where; Using index +SELECT * FROM t1 WHERE b=2 ORDER BY a DESC; +a b +3 2 +2 2 +EXPLAIN SELECT * FROM t1 ORDER BY b ASC, a ASC; +id 1 +select_type SIMPLE +table t1 +type index +possible_keys NULL +key b +key_len 5 +ref NULL +rows 3 +Extra Using index +SELECT * FROM t1 ORDER BY b ASC, a ASC; +a b +1 1 +2 2 +3 2 +EXPLAIN SELECT * FROM t1 ORDER BY b DESC, a DESC; +id 1 +select_type SIMPLE +table t1 +type index +possible_keys NULL +key b +key_len 5 +ref NULL +rows 3 +Extra Using index +SELECT * FROM t1 ORDER BY b DESC, a DESC; +a b +3 2 +2 2 +1 1 +EXPLAIN SELECT * FROM t1 ORDER BY b ASC, a DESC; +id 1 +select_type SIMPLE +table t1 +type index +possible_keys NULL +key b +key_len 5 +ref NULL +rows 3 +Extra Using index; Using filesort +SELECT * FROM t1 ORDER BY b ASC, a DESC; +a b +1 1 +3 2 +2 2 +EXPLAIN SELECT * FROM t1 ORDER BY b DESC, a ASC; +id 1 +select_type SIMPLE +table t1 +type index +possible_keys NULL +key b +key_len 5 +ref NULL +rows 3 +Extra Using index; Using filesort +SELECT * FROM t1 ORDER BY b DESC, a ASC; +a b +2 2 +3 2 +1 1 +DROP TABLE t1; + +# +# Bug#27610: ALTER TABLE ROW_FORMAT=... does not rebuild the table. +# + +# - prepare; + +DROP TABLE IF EXISTS t1; + +CREATE TABLE t1(c INT) +ENGINE = InnoDB +ROW_FORMAT = COMPACT; + +# - initial check; + +SELECT table_schema, table_name, row_format +FROM INFORMATION_SCHEMA.TABLES +WHERE table_schema = DATABASE() AND table_name = 't1'; +table_schema table_name row_format +test t1 Compact + +# - change ROW_FORMAT and check; + +ALTER TABLE t1 ROW_FORMAT = REDUNDANT; + +SELECT table_schema, table_name, row_format +FROM INFORMATION_SCHEMA.TABLES +WHERE table_schema = DATABASE() AND table_name = 't1'; +table_schema table_name row_format +test t1 Redundant + +# - that's it, cleanup. + +DROP TABLE t1; +create table t1(a char(10) not null, unique key aa(a(1)), +b char(4) not null, unique key bb(b(4))) engine=innodb; +desc t1; +Field Type Null Key Default Extra +a char(10) NO UNI NULL +b char(4) NO PRI NULL +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(10) NOT NULL, + `b` char(4) NOT NULL, + UNIQUE KEY `bb` (`b`), + UNIQUE KEY `aa` (`a`(1)) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +drop table t1; +CREATE TABLE t1 (id int, type char(6), d int, INDEX idx(id,d)) ENGINE=InnoDB; +INSERT INTO t1 VALUES +(191, 'member', 1), (NULL, 'member', 3), (NULL, 'member', 4), (201, 'member', 2); +EXPLAIN SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL idx NULL NULL NULL 4 Using where; Using filesort +SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d; +id type d +191 member 1 +NULL member 3 +NULL member 4 +DROP TABLE t1; +set @my_innodb_autoextend_increment=@@global.innodb_autoextend_increment; +set global innodb_autoextend_increment=8; +set global innodb_autoextend_increment=@my_innodb_autoextend_increment; +set @my_innodb_commit_concurrency=@@global.innodb_commit_concurrency; +set global innodb_commit_concurrency=0; +set global innodb_commit_concurrency=@my_innodb_commit_concurrency; +CREATE TABLE t1 (a int, b int, c int, PRIMARY KEY (a), KEY t1_b (b)) +ENGINE=InnoDB; +INSERT INTO t1 (a,b,c) VALUES (1,1,1), (2,1,1), (3,1,1), (4,1,1); +INSERT INTO t1 (a,b,c) SELECT a+4,b,c FROM t1; +EXPLAIN SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index t1_b PRIMARY 4 NULL 8 Using where +SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5; +a b c +8 1 1 +7 1 1 +6 1 1 +5 1 1 +4 1 1 +DROP TABLE t1; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (a char(50)) ENGINE=InnoDB; +CREATE INDEX i1 on t1 (a(3)); +SELECT * FROM t1 WHERE a = 'abcde'; +a +DROP TABLE t1; +# +# BUG #26288: savepoint are not deleted on comit, if the transaction +# was otherwise empty +# +BEGIN; +SAVEPOINT s1; +COMMIT; +RELEASE SAVEPOINT s1; +ERROR 42000: SAVEPOINT s1 does not exist +BEGIN; +SAVEPOINT s2; +COMMIT; +ROLLBACK TO SAVEPOINT s2; +ERROR 42000: SAVEPOINT s2 does not exist +BEGIN; +SAVEPOINT s3; +ROLLBACK; +RELEASE SAVEPOINT s3; +ERROR 42000: SAVEPOINT s3 does not exist +BEGIN; +SAVEPOINT s4; +ROLLBACK; +ROLLBACK TO SAVEPOINT s4; +ERROR 42000: SAVEPOINT s4 does not exist +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY COMMENT 'My ID#', f2 INTEGER DEFAULT NULL, f3 CHAR(10) DEFAULT 'My ID#', CONSTRAINT f2_ref FOREIGN KEY (f2) REFERENCES t1 (f1)) ENGINE=INNODB; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) NOT NULL COMMENT 'My ID#', + `f2` int(11) DEFAULT NULL, + `f3` char(10) DEFAULT 'My ID#', + PRIMARY KEY (`f1`), + KEY `f2_ref` (`f2`), + CONSTRAINT `f2_ref` FOREIGN KEY (`f2`) REFERENCES `t1` (`f1`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +DROP TABLE t1; +# +# Bug #36995: valgrind error in remove_const during subquery executions +# +create table t1 (a bit(1) not null,b int) engine=myisam; +create table t2 (c int) engine=innodb; +explain +select b from t1 where a not in (select b from t1,t2 group by a) group by a; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 0 const row not found +2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 1 +DROP TABLE t1,t2; +End of 5.0 tests +CREATE TABLE `t2` ( +`k` int(11) NOT NULL auto_increment, +`a` int(11) default NULL, +`c` int(11) default NULL, +PRIMARY KEY (`k`), +UNIQUE KEY `idx_1` (`a`) +); +insert into t2 ( a ) values ( 6 ) on duplicate key update c = +ifnull( c, +0 ) + 1; +insert into t2 ( a ) values ( 7 ) on duplicate key update c = +ifnull( c, +0 ) + 1; +select last_insert_id(); +last_insert_id() +2 +select * from t2; +k a c +1 6 NULL +2 7 NULL +insert into t2 ( a ) values ( 6 ) on duplicate key update c = +ifnull( c, +0 ) + 1; +select last_insert_id(); +last_insert_id() +2 +select last_insert_id(0); +last_insert_id(0) +0 +insert into t2 ( a ) values ( 6 ) on duplicate key update c = +ifnull( c, +0 ) + 1; +select last_insert_id(); +last_insert_id() +0 +select * from t2; +k a c +1 6 2 +2 7 NULL +insert ignore into t2 values (null,6,1),(10,8,1); +select last_insert_id(); +last_insert_id() +0 +insert ignore into t2 values (null,6,1),(null,8,1),(null,15,1),(null,20,1); +select last_insert_id(); +last_insert_id() +11 +select * from t2; +k a c +1 6 2 +2 7 NULL +10 8 1 +11 15 1 +12 20 1 +insert into t2 ( a ) values ( 6 ) on duplicate key update c = +ifnull( c, +0 ) + 1, k=last_insert_id(k); +select last_insert_id(); +last_insert_id() +1 +select * from t2; +k a c +1 6 3 +2 7 NULL +10 8 1 +11 15 1 +12 20 1 +drop table t2; +drop table if exists t1, t2; +create table t1 (i int); +alter table t1 modify i int default 1; +alter table t1 modify i int default 2, rename t2; +lock table t2 write; +alter table t2 modify i int default 3; +unlock tables; +lock table t2 write; +alter table t2 modify i int default 4, rename t1; +unlock tables; +drop table t1; +drop table if exists t1; +create table t1 (i int); +insert into t1 values (); +lock table t1 write; +alter table t1 modify i int default 1; +insert into t1 values (); +select * from t1; +i +NULL +1 +alter table t1 change i c char(10) default "Two"; +insert into t1 values (); +select * from t1; +c +NULL +1 +Two +unlock tables; +select * from t1; +c +NULL +1 +Two +drop tables t1; +create table t1(f1 varchar(5) unique, f2 timestamp NOT NULL DEFAULT +CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP); +insert into t1(f1) values(1); +select @a:=f2 from t1; +@a:=f2 +# +update t1 set f1=1; +select @b:=f2 from t1; +@b:=f2 +# +select if(@a=@b,"ok","wrong"); +if(@a=@b,"ok","wrong") +ok +insert into t1(f1) values (1) on duplicate key update f1="1"; +select @b:=f2 from t1; +@b:=f2 +# +select if(@a=@b,"ok","wrong"); +if(@a=@b,"ok","wrong") +ok +insert into t1(f1) select f1 from t1 on duplicate key update f1="1"; +select @b:=f2 from t1; +@b:=f2 +# +select if(@a=@b,"ok","wrong"); +if(@a=@b,"ok","wrong") +ok +drop table t1; +SET SESSION AUTOCOMMIT = 0; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +set binlog_format=mixed; +# Switch to connection con1 +CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(256)) +ENGINE = InnoDB; +INSERT INTO t1 VALUES (1,2); +# 1. test for locking: +BEGIN; +UPDATE t1 SET b = 12 WHERE a = 1; +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +SELECT * FROM t1; +a b +1 12 +# Switch to connection con2 +UPDATE t1 SET b = 21 WHERE a = 1; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +# Switch to connection con1 +SELECT * FROM t1; +a b +1 12 +ROLLBACK; +# 2. test for serialized update: +CREATE TABLE t2 (a INT); +TRUNCATE t1; +INSERT INTO t1 VALUES (1,'init'); +CREATE PROCEDURE p1() +BEGIN +UPDATE t1 SET b = CONCAT(b, '+con2') WHERE a = 1; +INSERT INTO t2 VALUES (); +END| +BEGIN; +UPDATE t1 SET b = CONCAT(b, '+con1') WHERE a = 1; +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +SELECT * FROM t1; +a b +1 init+con1 +# Switch to connection con2 +CALL p1;; +# Switch to connection con1 +SELECT * FROM t1; +a b +1 init+con1 +COMMIT; +SELECT * FROM t1; +a b +1 init+con1 +# Switch to connection con2 +SELECT * FROM t1; +a b +1 init+con1+con2 +# Switch to connection con1 +# 3. test for updated key column: +TRUNCATE t1; +TRUNCATE t2; +INSERT INTO t1 VALUES (1,'init'); +BEGIN; +UPDATE t1 SET a = 2, b = CONCAT(b, '+con1') WHERE a = 1; +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +SELECT * FROM t1; +a b +2 init+con1 +# Switch to connection con2 +CALL p1;; +# Switch to connection con1 +SELECT * FROM t1; +a b +2 init+con1 +COMMIT; +SELECT * FROM t1; +a b +2 init+con1 +# Switch to connection con2 +SELECT * FROM t1; +a b +2 init+con1 +DROP PROCEDURE p1; +DROP TABLE t1, t2; +CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, PRIMARY KEY (a,b)) engine=innodb; +CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d), +CONSTRAINT c2 FOREIGN KEY f2 (c) REFERENCES t1 (a,b) ON UPDATE NO ACTION) engine=innodb; +ERROR 42000: Incorrect foreign key definition for 'f2': Key reference and table reference don't match +CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d), +CONSTRAINT c2 FOREIGN KEY (c) REFERENCES t1 (a,b) ON UPDATE NO ACTION) engine=innodb; +ERROR 42000: Incorrect foreign key definition for 'c2': Key reference and table reference don't match +CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d), +CONSTRAINT c1 FOREIGN KEY c2 (c) REFERENCES t1 (a) ON DELETE NO ACTION, +CONSTRAINT c2 FOREIGN KEY (c) REFERENCES t1 (a) ON UPDATE NO ACTION) engine=innodb; +ALTER TABLE t2 DROP FOREIGN KEY c2; +DROP TABLE t2; +CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d), +FOREIGN KEY (c) REFERENCES t1 (a,k) ON UPDATE NO ACTION) engine=innodb; +ERROR 42000: Incorrect foreign key definition for 'foreign key without name': Key reference and table reference don't match +CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d), +FOREIGN KEY f1 (c) REFERENCES t1 (a,k) ON UPDATE NO ACTION) engine=innodb; +ERROR 42000: Incorrect foreign key definition for 'f1': Key reference and table reference don't match +CREATE TABLE t2 (c INT NOT NULL, d INT NOT NULL, PRIMARY KEY (c,d), +CONSTRAINT c1 FOREIGN KEY f1 (c) REFERENCES t1 (a) ON DELETE NO ACTION, +CONSTRAINT c2 FOREIGN KEY (c) REFERENCES t1 (a) ON UPDATE NO ACTION, +FOREIGN KEY f3 (c) REFERENCES t1 (a) ON UPDATE NO ACTION, +FOREIGN KEY (c) REFERENCES t1 (a) ON UPDATE NO ACTION) engine=innodb; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `c` int(11) NOT NULL, + `d` int(11) NOT NULL, + PRIMARY KEY (`c`,`d`), + CONSTRAINT `c1` FOREIGN KEY (`c`) REFERENCES `t1` (`a`) ON DELETE NO ACTION, + CONSTRAINT `c2` FOREIGN KEY (`c`) REFERENCES `t1` (`a`) ON UPDATE NO ACTION, + CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`c`) REFERENCES `t1` (`a`) ON UPDATE NO ACTION, + CONSTRAINT `t2_ibfk_2` FOREIGN KEY (`c`) REFERENCES `t1` (`a`) ON UPDATE NO ACTION +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +DROP TABLE t2; +DROP TABLE t1; +create table t1 (a int auto_increment primary key) engine=innodb; +alter table t1 order by a; +Warnings: +Warning 1105 ORDER BY ignored as there is a user-defined clustered index in the table 't1' +drop table t1; +CREATE TABLE t1 +(vid integer NOT NULL, +tid integer NOT NULL, +idx integer NOT NULL, +name varchar(128) NOT NULL, +type varchar(128) NULL, +PRIMARY KEY(idx, vid, tid), +UNIQUE(vid, tid, name) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES +(1,1,1,'pk',NULL),(2,1,1,'pk',NULL),(3,1,1,'pk',NULL),(4,1,1,'c1',NULL), +(5,1,1,'pk',NULL),(1,1,2,'c1',NULL),(2,1,2,'c1',NULL),(3,1,2,'c1',NULL), +(4,1,2,'c2',NULL),(5,1,2,'c1',NULL),(2,1,3,'c2',NULL),(3,1,3,'c2',NULL), +(4,1,3,'pk',NULL),(5,1,3,'c2',NULL), +(2,1,4,'c_extra',NULL),(3,1,4,'c_extra',NULL); +EXPLAIN SELECT * FROM t1 FORCE INDEX (PRIMARY) WHERE tid = 1 AND vid = 3 ORDER BY idx DESC; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL PRIMARY 12 NULL 16 Using where +SELECT * FROM t1 FORCE INDEX (PRIMARY) WHERE tid = 1 AND vid = 3 ORDER BY idx DESC; +vid tid idx name type +3 1 4 c_extra NULL +3 1 3 c2 NULL +3 1 2 c1 NULL +3 1 1 pk NULL +DROP TABLE t1; +# +# Bug #44290: explain crashes for subquery with distinct in +# SQL_SELECT::test_quick_select +# (reproduced only with InnoDB tables) +# +CREATE TABLE t1 (c1 INT, c2 INT, c3 INT, KEY (c3), KEY (c2, c3)) +ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,1,1), (1,1,1), (1,1,2), (1,1,1), (1,1,2); +SELECT 1 FROM (SELECT COUNT(DISTINCT c1) +FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; +1 +1 +EXPLAIN +SELECT 1 FROM (SELECT COUNT(DISTINCT c1) +FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY system NULL NULL NULL NULL 1 +2 DERIVED t1 index c3,c2 c2 10 NULL 5 +DROP TABLE t1; +CREATE TABLE t1 (c1 REAL, c2 REAL, c3 REAL, KEY (c3), KEY (c2, c3)) +ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,1,1), (1,1,1), (1,1,2), (1,1,1), (1,1,2); +SELECT 1 FROM (SELECT COUNT(DISTINCT c1) +FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; +1 +1 +EXPLAIN +SELECT 1 FROM (SELECT COUNT(DISTINCT c1) +FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY system NULL NULL NULL NULL 1 +2 DERIVED t1 index c3,c2 c2 18 NULL 5 +DROP TABLE t1; +CREATE TABLE t1 (c1 DECIMAL(12,2), c2 DECIMAL(12,2), c3 DECIMAL(12,2), +KEY (c3), KEY (c2, c3)) +ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,1,1), (1,1,1), (1,1,2), (1,1,1), (1,1,2); +SELECT 1 FROM (SELECT COUNT(DISTINCT c1) +FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; +1 +1 +EXPLAIN +SELECT 1 FROM (SELECT COUNT(DISTINCT c1) +FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY system NULL NULL NULL NULL 1 +2 DERIVED t1 index c3,c2 c2 14 NULL 5 +DROP TABLE t1; +End of 5.1 tests +drop table if exists t1, t2, t3; +create table t1(a int); +insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t2 (a int, b int, pk int, key(a,b), primary key(pk)) engine=innodb; +insert into t2 select @a:=A.a+10*(B.a + 10*C.a),@a, @a from t1 A, t1 B, t1 C; +this must use key 'a', not PRIMARY: +explain select a from t2 where a=b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 index NULL a 10 NULL # Using where; Using index +drop table t1, t2; +SET SESSION BINLOG_FORMAT=STATEMENT; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +select @@session.sql_log_bin, @@session.binlog_format, @@session.tx_isolation; +@@session.sql_log_bin 1 +@@session.binlog_format STATEMENT +@@session.tx_isolation READ-COMMITTED +CREATE TABLE t1 ( a INT ) ENGINE=InnoDB; +INSERT INTO t1 VALUES(1); +DROP TABLE t1; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (a char(50)) ENGINE=InnoDB; +CREATE INDEX i1 on t1 (a(3)); +SELECT * FROM t1 WHERE a = 'abcde'; +a +DROP TABLE t1; +CREATE TABLE foo (a int, b int, c char(10), +PRIMARY KEY (c(3)), +KEY b (b) +) engine=innodb; +CREATE TABLE foo2 (a int, b int, c char(10), +PRIMARY KEY (c), +KEY b (b) +) engine=innodb; +CREATE TABLE bar (a int, b int, c char(10), +PRIMARY KEY (c(3)), +KEY b (b) +) engine=myisam; +INSERT INTO foo VALUES +(1,2,'abcdefghij'), (2,3,''), (3,4,'klmnopqrst'), +(4,5,'uvwxyz'), (5,6,'meotnsyglt'), (4,5,'asfdewe'); +INSERT INTO bar SELECT * FROM foo; +INSERT INTO foo2 SELECT * FROM foo; +EXPLAIN SELECT c FROM bar WHERE b>2;; +id 1 +select_type SIMPLE +table bar +type ALL +possible_keys b +key NULL +key_len NULL +ref NULL +rows 6 +Extra Using where +EXPLAIN SELECT c FROM foo WHERE b>2;; +id 1 +select_type SIMPLE +table foo +type ALL +possible_keys b +key NULL +key_len NULL +ref NULL +rows 6 +Extra Using where +EXPLAIN SELECT c FROM foo2 WHERE b>2;; +id 1 +select_type SIMPLE +table foo2 +type range +possible_keys b +key b +key_len 5 +ref NULL +rows 3 +Extra Using where; Using index +EXPLAIN SELECT c FROM bar WHERE c>2;; +id 1 +select_type SIMPLE +table bar +type ALL +possible_keys PRIMARY +key NULL +key_len NULL +ref NULL +rows 6 +Extra Using where +EXPLAIN SELECT c FROM foo WHERE c>2;; +id 1 +select_type SIMPLE +table foo +type ALL +possible_keys PRIMARY +key NULL +key_len NULL +ref NULL +rows 6 +Extra Using where +EXPLAIN SELECT c FROM foo2 WHERE c>2;; +id 1 +select_type SIMPLE +table foo2 +type index +possible_keys PRIMARY +key b +key_len 5 +ref NULL +rows 6 +Extra Using where; Using index +DROP TABLE foo, bar, foo2; +DROP TABLE IF EXISTS t1,t3,t2; +DROP FUNCTION IF EXISTS f1; +CREATE FUNCTION f1() RETURNS VARCHAR(250) +BEGIN +return 'hhhhhhh' ; +END| +CREATE TABLE t1 (a VARCHAR(20), b VARCHAR(20), c VARCHAR(20)) ENGINE=INNODB; +BEGIN WORK; +CREATE TEMPORARY TABLE t2 (a VARCHAR(20), b VARCHAR(20), c varchar(20)) ENGINE=INNODB; +CREATE TEMPORARY TABLE t3 LIKE t2; +INSERT INTO t1 VALUES ('a','b',NULL),('c','d',NULL),('e','f',NULL); +SET @stmt := CONCAT('INSERT INTO t2 SELECT tbl.a, tbl.b, f1()',' FROM t1 tbl'); +PREPARE stmt1 FROM @stmt; +SET @stmt := CONCAT('INSERT INTO t3', ' SELECT * FROM t2'); +PREPARE stmt3 FROM @stmt; +EXECUTE stmt1; +COMMIT; +DEALLOCATE PREPARE stmt1; +DEALLOCATE PREPARE stmt3; +DROP TABLE t1,t3,t2; +DROP FUNCTION f1; +DROP TABLE IF EXISTS t1,t2; +CREATE TABLE t1 (id INT NOT NULL, PRIMARY KEY (id)) ENGINE=INNODB; +CREATE TABLE t2 (id INT PRIMARY KEY, +t1_id INT, INDEX par_ind (t1_id), +FOREIGN KEY (t1_id) REFERENCES t1(id)) ENGINE=INNODB; +INSERT INTO t1 VALUES (1),(2); +INSERT INTO t2 VALUES (3,2); +SET AUTOCOMMIT = 0; +START TRANSACTION; +TRUNCATE TABLE t1; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`t1_id`) REFERENCES `t1` (`id`)) +SELECT * FROM t1; +id +1 +2 +COMMIT; +SELECT * FROM t1; +id +1 +2 +START TRANSACTION; +TRUNCATE TABLE t1; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`t1_id`) REFERENCES `t1` (`id`)) +SELECT * FROM t1; +id +1 +2 +ROLLBACK; +SELECT * FROM t1; +id +1 +2 +SET AUTOCOMMIT = 1; +START TRANSACTION; +SELECT * FROM t1; +id +1 +2 +COMMIT; +TRUNCATE TABLE t1; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`t1_id`) REFERENCES `t1` (`id`)) +SELECT * FROM t1; +id +1 +2 +DELETE FROM t2 WHERE id = 3; +START TRANSACTION; +SELECT * FROM t1; +id +1 +2 +TRUNCATE TABLE t1; +ROLLBACK; +SELECT * FROM t1; +id +TRUNCATE TABLE t2; +DROP TABLE t2; +DROP TABLE t1; +# +# Bug#40127 Multiple table DELETE IGNORE hangs on foreign key constraint violation on 5.0 +# +CREATE TABLE t1 ( +id INT UNSIGNED NOT NULL AUTO_INCREMENT, +PRIMARY KEY (id) +) ENGINE=InnoDB; +CREATE TABLE t2 ( +id INT UNSIGNED NOT NULL AUTO_INCREMENT, +aid INT UNSIGNED NOT NULL, +PRIMARY KEY (id), +FOREIGN KEY (aid) REFERENCES t1 (id) +) ENGINE=InnoDB; +CREATE TABLE t3 ( +bid INT UNSIGNED NOT NULL, +FOREIGN KEY (bid) REFERENCES t2 (id) +) ENGINE=InnoDB; +CREATE TABLE t4 ( +a INT +) ENGINE=InnoDB; +CREATE TABLE t5 ( +a INT +) ENGINE=InnoDB; +INSERT INTO t1 (id) VALUES (1); +INSERT INTO t2 (id, aid) VALUES (1, 1),(2,1),(3,1),(4,1); +INSERT INTO t3 (bid) VALUES (1); +INSERT INTO t4 VALUES (1),(2),(3),(4),(5); +INSERT INTO t5 VALUES (1); +DELETE t5 FROM t4 LEFT JOIN t5 ON t4.a= t5.a; +DELETE t2, t1 FROM t2 INNER JOIN t1 ON (t2.aid = t1.id) WHERE t2.id = 1; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t3`, CONSTRAINT `t3_ibfk_1` FOREIGN KEY (`bid`) REFERENCES `t2` (`id`)) +DELETE t2, t1 FROM t2 INNER JOIN t1 ON (t2.aid = t1.id) WHERE t2.id = 1; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t3`, CONSTRAINT `t3_ibfk_1` FOREIGN KEY (`bid`) REFERENCES `t2` (`id`)) +DELETE IGNORE t2, t1 FROM t2 INNER JOIN t1 ON (t2.aid = t1.id) WHERE t2.id = 1; +DROP TABLE t3; +DROP TABLE t2; +DROP TABLE t1; +DROP TABLES t4,t5; +# Bug#40127 Multiple table DELETE IGNORE hangs on foreign key constraint violation on 5.0 +# Testing for any side effects of IGNORE on AFTER DELETE triggers used with +# transactional tables. +# +CREATE TABLE t1 (i INT NOT NULL PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t2 (a VARCHAR(100)) ENGINE=InnoDB; +CREATE TABLE t3 (i INT NOT NULL PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t4 (i INT NOT NULL PRIMARY KEY, t1i INT, +FOREIGN KEY (t1i) REFERENCES t1(i)) +ENGINE=InnoDB; +CREATE TRIGGER trg AFTER DELETE ON t1 FOR EACH ROW +BEGIN +SET @b:='EXECUTED TRIGGER'; +INSERT INTO t2 VALUES (@b); +SET @a:= error_happens_here; +END|| +SET @b:=""; +SET @a:=""; +INSERT INTO t1 VALUES (1),(2),(3),(4); +INSERT INTO t3 SELECT * FROM t1; +** An error in a trigger causes rollback of the statement. +DELETE t1 FROM t3 LEFT JOIN t1 ON t1.i=t3.i; +ERROR 42S22: Unknown column 'error_happens_here' in 'field list' +SELECT @a,@b; +@a @b + EXECUTED TRIGGER +SELECT * FROM t2; +a +SELECT * FROM t1 LEFT JOIN t3 ON t1.i=t3.i; +i i +1 1 +2 2 +3 3 +4 4 +** Same happens with the IGNORE option +DELETE IGNORE t1 FROM t3 LEFT JOIN t1 ON t1.i=t3.i; +ERROR 42S22: Unknown column 'error_happens_here' in 'field list' +SELECT * FROM t2; +a +SELECT * FROM t1 LEFT JOIN t3 ON t1.i=t3.i; +i i +1 1 +2 2 +3 3 +4 4 +** +** The following is an attempt to demonstrate +** error handling inside a row iteration. +** +DROP TRIGGER trg; +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; +INSERT INTO t1 VALUES (1),(2),(3),(4); +INSERT INTO t3 VALUES (1),(2),(3),(4); +INSERT INTO t4 VALUES (3,3),(4,4); +CREATE TRIGGER trg AFTER DELETE ON t1 FOR EACH ROW +BEGIN +SET @b:= CONCAT('EXECUTED TRIGGER FOR ROW ',CAST(OLD.i AS CHAR)); +INSERT INTO t2 VALUES (@b); +END|| +** DELETE is prevented by foreign key constrains but errors are silenced. +** The AFTER trigger isn't fired. +DELETE IGNORE t1 FROM t3 LEFT JOIN t1 ON t1.i=t3.i; +** Tables are modified by best effort: +SELECT * FROM t1 LEFT JOIN t3 ON t1.i=t3.i; +i i +3 3 +4 4 +** The AFTER trigger was only executed on successful rows: +SELECT * FROM t2; +a +EXECUTED TRIGGER FOR ROW 1 +EXECUTED TRIGGER FOR ROW 2 +DROP TRIGGER trg; +** +** Induce an error midway through an AFTER-trigger +** +TRUNCATE TABLE t4; +TRUNCATE TABLE t1; +TRUNCATE TABLE t3; +INSERT INTO t1 VALUES (1),(2),(3),(4); +INSERT INTO t3 VALUES (1),(2),(3),(4); +CREATE TRIGGER trg AFTER DELETE ON t1 FOR EACH ROW +BEGIN +SET @a:= @a+1; +IF @a > 2 THEN +INSERT INTO t4 VALUES (5,5); +END IF; +END|| +SET @a:=0; +** Errors in the trigger causes the statement to abort. +DELETE IGNORE t1 FROM t3 LEFT JOIN t1 ON t1.i=t3.i; +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`t1i`) REFERENCES `t1` (`i`)) +SELECT * FROM t1 LEFT JOIN t3 ON t1.i=t3.i; +i i +1 1 +2 2 +3 3 +4 4 +SELECT * FROM t4; +i t1i +DROP TRIGGER trg; +DROP TABLE t4; +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; +CREATE TABLE t1 (a INT, b INT, KEY (a)) ENGINE = INNODB; +CREATE TABLE t2 (a INT KEY, b INT, KEY (b)) ENGINE = INNODB; +CREATE TABLE t3 (a INT, b INT KEY, KEY (a)) ENGINE = INNODB; +CREATE TABLE t4 (a INT KEY, b INT, KEY (b)) ENGINE = INNODB; +INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6); +INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5); +INSERT INTO t3 VALUES (1, 101), (2, 102), (3, 103), (4, 104), (5, 105), (6, 106); +INSERT INTO t4 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5); +UPDATE t1, t2 SET t1.a = t1.a + 100, t2.b = t1.a + 10 +WHERE t1.a BETWEEN 2 AND 4 AND t2.a = t1.b; +SELECT * FROM t2; +a b +1 1 +2 12 +3 13 +4 14 +5 5 +UPDATE t3, t4 SET t3.a = t3.a + 100, t4.b = t3.a + 10 +WHERE t3.a BETWEEN 2 AND 4 AND t4.a = t3.b - 100; +SELECT * FROM t4; +a b +1 1 +2 12 +3 13 +4 14 +5 5 +DROP TABLE t1, t2, t3, t4; +# +# Bug#44886: SIGSEGV in test_if_skip_sort_order() - +# uninitialized variable used as subscript +# +CREATE TABLE t1 (a INT, b INT, c INT, d INT, PRIMARY KEY (b), KEY (a,c)) +ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,1,1,0); +CREATE TABLE t2 (a INT, b INT, e INT, KEY (e)) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,1,2); +CREATE TABLE t3 (a INT, b INT) ENGINE=MyISAM; +INSERT INTO t3 VALUES (1, 1); +SELECT * FROM t1, t2, t3 +WHERE t1.a = t3.a AND (t1.b = t3.b OR t1.d) AND t2.b = t1.b AND t2.e = 2 +GROUP BY t1.b; +a b c d a b e a b +1 1 1 0 1 1 2 1 1 +DROP TABLE t1, t2, t3; +# +# Bug #45828: Optimizer won't use partial primary key if another +# index can prevent filesort +# +CREATE TABLE `t1` ( +c1 int NOT NULL, +c2 int NOT NULL, +c3 int NOT NULL, +PRIMARY KEY (c1,c2), +KEY (c3) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES (5,2,1246276747); +INSERT INTO t1 VALUES (2,1,1246281721); +INSERT INTO t1 VALUES (7,3,1246281756); +INSERT INTO t1 VALUES (4,2,1246282139); +INSERT INTO t1 VALUES (3,1,1246282230); +INSERT INTO t1 VALUES (1,0,1246282712); +INSERT INTO t1 VALUES (8,3,1246282765); +INSERT INTO t1 SELECT c1+10,c2+10,c3+10 FROM t1; +INSERT INTO t1 SELECT c1+100,c2+100,c3+100 from t1; +INSERT INTO t1 SELECT c1+1000,c2+1000,c3+1000 from t1; +INSERT INTO t1 SELECT c1+10000,c2+10000,c3+10000 from t1; +INSERT INTO t1 SELECT c1+100000,c2+100000,c3+100000 from t1; +INSERT INTO t1 SELECT c1+1000000,c2+1000000,c3+1000000 from t1; +SELECT * FROM t1 WHERE c1 = 99999999 AND c3 > 1 ORDER BY c3; +c1 c2 c3 +EXPLAIN SELECT * FROM t1 WHERE c1 = 99999999 AND c3 > 1 ORDER BY c3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref PRIMARY,c3 PRIMARY 4 const 1 Using where; Using filesort +EXPLAIN SELECT * FROM t1 FORCE INDEX (PRIMARY) WHERE c1 = 99999999 AND c3 > 1 ORDER BY c3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref PRIMARY PRIMARY 4 const 1 Using where; Using filesort +CREATE TABLE t2 ( +c1 int NOT NULL, +c2 int NOT NULL, +c3 int NOT NULL, +KEY (c1,c2), +KEY (c3) +) ENGINE=InnoDB; +explain SELECT * FROM t2 WHERE c1 = 99999999 AND c3 > 1 ORDER BY c3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref c1,c3 c1 4 const 1 Using where; Using filesort +DROP TABLE t1,t2; +# +# 36259: Optimizing with ORDER BY +# +CREATE TABLE t1 ( +a INT NOT NULL AUTO_INCREMENT, +b INT NOT NULL, +c INT NOT NULL, +d VARCHAR(5), +e INT NOT NULL, +PRIMARY KEY (a), KEY i2 (b,c,d) +) ENGINE=InnoDB; +INSERT INTO t1 (b,c,d,e) VALUES (1,1,'a',1), (2,2,'b',2); +INSERT INTO t1 (b,c,d,e) SELECT RAND()*10000, RAND()*10000, d, e FROM t1; +INSERT INTO t1 (b,c,d,e) SELECT RAND()*10000, RAND()*10000, d, e FROM t1; +INSERT INTO t1 (b,c,d,e) SELECT RAND()*10000, RAND()*10000, d, e FROM t1; +INSERT INTO t1 (b,c,d,e) SELECT RAND()*10000, RAND()*10000, d, e FROM t1; +INSERT INTO t1 (b,c,d,e) SELECT RAND()*10000, RAND()*10000, d, e FROM t1; +INSERT INTO t1 (b,c,d,e) SELECT RAND()*10000, RAND()*10000, d, e FROM t1; +EXPLAIN SELECT * FROM t1 WHERE b=1 AND c=1 ORDER BY a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref i2 i2 8 const,const 1 Using where; Using filesort +EXPLAIN SELECT * FROM t1 FORCE INDEX(i2) WHERE b=1 and c=1 ORDER BY a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref i2 i2 8 const,const 1 Using where; Using filesort +EXPLAIN SELECT * FROM t1 FORCE INDEX(PRIMARY) WHERE b=1 AND c=1 ORDER BY a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL PRIMARY 4 NULL 128 Using where +DROP TABLE t1; +# +# Bug #47963: Wrong results when index is used +# +CREATE TABLE t1( +a VARCHAR(5) NOT NULL, +b VARCHAR(5) NOT NULL, +c DATETIME NOT NULL, +KEY (c) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES('TEST', 'TEST', '2009-10-09 00:00:00'); +SELECT * FROM t1 WHERE a = 'TEST' AND +c >= '2009-10-09 00:00:00' AND c <= '2009-10-09 00:00:00'; +a b c +TEST TEST 2009-10-09 00:00:00 +SELECT * FROM t1 WHERE a = 'TEST' AND +c >= '2009-10-09 00:00:00.0' AND c <= '2009-10-09 00:00:00.0'; +a b c +TEST TEST 2009-10-09 00:00:00 +SELECT * FROM t1 WHERE a = 'TEST' AND +c >= '2009-10-09 00:00:00.0' AND c <= '2009-10-09 00:00:00'; +a b c +TEST TEST 2009-10-09 00:00:00 +SELECT * FROM t1 WHERE a = 'TEST' AND +c >= '2009-10-09 00:00:00' AND c <= '2009-10-09 00:00:00.0'; +a b c +TEST TEST 2009-10-09 00:00:00 +SELECT * FROM t1 WHERE a = 'TEST' AND +c >= '2009-10-09 00:00:00.000' AND c <= '2009-10-09 00:00:00.000'; +a b c +TEST TEST 2009-10-09 00:00:00 +SELECT * FROM t1 WHERE a = 'TEST' AND +c >= '2009-10-09 00:00:00.00' AND c <= '2009-10-09 00:00:00.001'; +a b c +TEST TEST 2009-10-09 00:00:00 +SELECT * FROM t1 WHERE a = 'TEST' AND +c >= '2009-10-09 00:00:00.001' AND c <= '2009-10-09 00:00:00.00'; +a b c +EXPLAIN SELECT * FROM t1 WHERE a = 'TEST' AND +c >= '2009-10-09 00:00:00.001' AND c <= '2009-10-09 00:00:00.00'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +DROP TABLE t1; +# +# Bug #46175: NULL read_view and consistent read assertion +# +CREATE TABLE t1(a CHAR(13),KEY(a)) ENGINE=innodb; +CREATE TABLE t2(b DATETIME,KEY(b)) ENGINE=innodb; +INSERT INTO t1 VALUES (),(); +INSERT INTO t2 VALUES (),(); +CREATE OR REPLACE VIEW v1 AS SELECT 1 FROM t2 +WHERE b =(SELECT a FROM t1 LIMIT 1); +CREATE PROCEDURE p1(num INT) +BEGIN +DECLARE i INT DEFAULT 0; +REPEAT +SHOW CREATE VIEW v1; +SET i:=i+1; +UNTIL i>num END REPEAT; +END| +# Should not crash +# Should not crash +DROP PROCEDURE p1; +DROP VIEW v1; +DROP TABLE t1,t2; +# +# Bug #49324: more valgrind errors in test_if_skip_sort_order +# +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb ; +#should not cause valgrind warnings +SELECT 1 FROM t1 JOIN t1 a USING(a) GROUP BY t1.a,t1.a; +1 +DROP TABLE t1; +# +# Bug#50843: Filesort used instead of clustered index led to +# performance degradation. +# +create table t1(f1 int not null primary key, f2 int) engine=innodb; +create table t2(f1 int not null, key (f1)) engine=innodb; +insert into t1 values (1,1),(2,2),(3,3); +insert into t2 values (1),(2),(3); +explain select t1.* from t1 left join t2 using(f1) group by t1.f1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL PRIMARY 4 NULL 3 +1 SIMPLE t2 ref f1 f1 4 test.t1.f1 1 Using index +drop table t1,t2; +# +# +# Bug #39653: find_shortest_key in sql_select.cc does not consider +# clustered primary keys +# +CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c INT, d INT, e INT, f INT, +KEY (b,c)) ENGINE=INNODB; +INSERT INTO t1 VALUES (1,1,1,1,1,1), (2,2,2,2,2,2), (3,3,3,3,3,3), +(4,4,4,4,4,4), (5,5,5,5,5,5), (6,6,6,6,6,6), +(7,7,7,7,7,7), (8,8,8,8,8,8), (9,9,9,9,9,9), +(11,11,11,11,11,11); +EXPLAIN SELECT COUNT(*) FROM t1; +id 1 +select_type SIMPLE +table t1 +type index +possible_keys NULL +key b +key_len 10 +ref NULL +rows 10 +Extra Using index +DROP TABLE t1; +# +# Bug #49838: DROP INDEX and ADD UNIQUE INDEX for same index may +# corrupt definition at engine +# +CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, KEY k (a,b)) +ENGINE=InnoDB; +ALTER TABLE t1 DROP INDEX k, ADD UNIQUE INDEX k (a,b); +SHOW INDEXES FROM t1;; +Table t1 +Non_unique 0 +Key_name k +Seq_in_index 1 +Column_name a +Collation A +Cardinality 0 +Sub_part NULL +Packed NULL +Null +Index_type BTREE +Comment +Table t1 +Non_unique 0 +Key_name k +Seq_in_index 2 +Column_name b +Collation A +Cardinality 0 +Sub_part NULL +Packed NULL +Null +Index_type BTREE +Comment +DROP TABLE t1; +# +# Bug #47453: InnoDB incorrectly changes TIMESTAMP columns when +# JOINed during an UPDATE +# +CREATE TABLE t1 (d INT) ENGINE=InnoDB; +CREATE TABLE t2 (a INT, b INT, +c TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +ON UPDATE CURRENT_TIMESTAMP) ENGINE=InnoDB; +set up our data elements +INSERT INTO t1 (d) VALUES (1); +INSERT INTO t2 (a,b) VALUES (1,1); +SELECT SECOND(c) INTO @bug47453 FROM t2; +SELECT SECOND(c)-@bug47453 FROM t1 JOIN t2 ON d=a; +SECOND(c)-@bug47453 +0 +UPDATE t1 JOIN t2 ON d=a SET b=1 WHERE a=1; +SELECT SECOND(c)-@bug47453 FROM t1 JOIN t2 ON d=a; +SECOND(c)-@bug47453 +0 +SELECT SLEEP(1); +SLEEP(1) +0 +UPDATE t1 JOIN t2 ON d=a SET b=1 WHERE a=1; +#should be 0 +SELECT SECOND(c)-@bug47453 FROM t1 JOIN t2 ON d=a; +SECOND(c)-@bug47453 +0 +DROP TABLE t1, t2; +End of 5.1 tests diff --git a/mysql-test/suite/innodb_plugin/r/innodb_mysql_rbk.result b/mysql-test/suite/innodb_plugin/r/innodb_mysql_rbk.result new file mode 100644 index 00000000000..21ac4295325 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_mysql_rbk.result @@ -0,0 +1,21 @@ +CREATE TABLE t1(a INT, b INT NOT NULL, PRIMARY KEY (a)) ENGINE=innodb +DEFAULT CHARSET=latin1; +INSERT INTO t1 VALUES (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7); +START TRANSACTION; +SELECT * FROM t1 WHERE b=3 LIMIT 1 FOR UPDATE; +a b +3 3 +START TRANSACTION; +UPDATE t1 SET b=b+12 WHERE a > 2 ORDER BY a; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +ROLLBACK; +START TRANSACTION; +SELECT * FROM t1 WHERE b=3 LIMIT 1 FOR UPDATE; +a b +3 3 +START TRANSACTION; +UPDATE t1 SET b=10 WHERE a > 1 ORDER BY a; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT * FROM t1 WHERE b = 10; +a b +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_plugin/r/innodb_notembedded.result b/mysql-test/suite/innodb_plugin/r/innodb_notembedded.result new file mode 100644 index 00000000000..af332aba38a --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_notembedded.result @@ -0,0 +1,23 @@ +drop table if exists t1; +SET @old_log_bin_trust_function_creators= @@global.log_bin_trust_function_creators; +SET GLOBAL log_bin_trust_function_creators = 1; +create table t1 (col1 integer primary key, col2 integer) engine=innodb; +insert t1 values (1,100); +create function f1 () returns integer begin +declare var1 int; +select col2 into var1 from t1 where col1=1 for update; +return var1; +end| +start transaction; +select f1(); +f1() +100 +update t1 set col2=0 where col1=1; +select * from t1; +col1 col2 +1 100 +rollback; +rollback; +drop table t1; +drop function f1; +SET @@global.log_bin_trust_function_creators= @old_log_bin_trust_function_creators; diff --git a/mysql-test/suite/innodb_plugin/r/innodb_timeout_rollback.result b/mysql-test/suite/innodb_plugin/r/innodb_timeout_rollback.result new file mode 100644 index 00000000000..e2da6ba8af7 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_timeout_rollback.result @@ -0,0 +1,36 @@ +drop table if exists t1; +show variables like 'innodb_rollback_on_timeout'; +Variable_name Value +innodb_rollback_on_timeout ON +create table t1 (a int unsigned not null primary key) engine = innodb; +insert into t1 values (1); +commit; +begin work; +insert into t1 values (2); +select * from t1; +a +1 +2 +begin work; +insert into t1 values (5); +select * from t1; +a +1 +5 +insert into t1 values (2); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +select * from t1; +a +1 +commit; +select * from t1; +a +1 +2 +commit; +select * from t1; +a +1 +2 +drop table t1; +End of 5.0 tests diff --git a/mysql-test/suite/innodb_plugin/t/innodb-autoinc-optimize.test b/mysql-test/suite/innodb_plugin/t/innodb-autoinc-optimize.test new file mode 100644 index 00000000000..b359980768c --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb-autoinc-optimize.test @@ -0,0 +1,19 @@ +-- source include/have_innodb_plugin.inc +# embedded server ignores 'delayed', so skip this +-- source include/not_embedded.inc + +--disable_warnings +drop table if exists t1; +--enable_warnings + +# +# Bug 34286 +# +create table t1(a int not null auto_increment primary key) engine=innodb; +insert into t1 set a = -1; +# NOTE: The database needs to be shutdown and restarted (here) for +# the test to work. It's included for reference only. +optimize table t1; + +--echo ==== clean up ==== +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_plugin/t/innodb-ucs2.test b/mysql-test/suite/innodb_plugin/t/innodb-ucs2.test new file mode 100644 index 00000000000..050a05675e7 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb-ucs2.test @@ -0,0 +1,230 @@ +-- source include/have_innodb_plugin.inc +-- source include/have_ucs2.inc + +--disable_warnings +drop table if exists t1, t2; +--enable_warnings + +# +# BUG 14056 Column prefix index on UTF-8 primary key column causes: Can't find record.. +# + +create table t1 ( + a int, b char(10), c char(10), filler char(10), primary key(a, b(2)), unique key (a, c(2)) +) character set utf8 engine = innodb; +create table t2 ( + a int, b char(10), c char(10), filler char(10), primary key(a, b(2)), unique key (a, c(2)) +) character set ucs2 engine = innodb; +insert into t1 values (1,'abcdefg','abcdefg','one'); +insert into t1 values (2,'ijkilmn','ijkilmn','two'); +insert into t1 values (3,'qrstuvw','qrstuvw','three'); +insert into t1 values (4,_utf8 0xe880bd,_utf8 0xe880bd,'four'); +insert into t1 values (4,_utf8 0x5b,_utf8 0x5b,'five'); +insert into t1 values (4,_utf8 0xe880bde880bd,_utf8 0xe880bde880bd,'six'); +insert into t1 values (4,_utf8 0xe880bdD0B1e880bd,_utf8 0xe880bdD0B1e880bd,'seven'); +insert into t1 values (4,_utf8 0xD0B1,_utf8 0xD0B1,'eight'); +insert into t2 values (1,'abcdefg','abcdefg','one'); +insert into t2 values (2,'ijkilmn','ijkilmn','two'); +insert into t2 values (3,'qrstuvw','qrstuvw','three'); +insert into t2 values (4,_ucs2 0x00e400,_ucs2 0x00e400,'four'); +insert into t2 values (4,_ucs2 0x00640065,_ucs2 0x00640065,'five'); +insert into t2 values (4,_ucs2 0x00e400e50068,_ucs2 0x00e400e50068,'six'); +insert into t2 values (4,_ucs2 0x01fc,_ucs2 0x01fc,'seven'); +insert into t2 values (4,_ucs2 0x0120,_ucs2 0x0120,'eight'); +insert into t2 values (4,_ucs2 0x0563,_ucs2 0x0563,'ten'); +insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven'); +insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point'); +insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken'); +update t1 set filler = 'boo' where a = 1; +update t2 set filler ='email' where a = 4; +select a,hex(b),hex(c),filler from t1 order by filler; +select a,hex(b),hex(c),filler from t2 order by filler; +drop table t1; +drop table t2; + +create table t1 ( + a int, b varchar(10), c varchar(10), filler varchar(10), primary key(a, b(2)), unique key (a, c(2)) +) character set utf8 engine = innodb; +create table t2 ( + a int, b varchar(10), c varchar(10), filler varchar(10), primary key(a, b(2)), unique key (a, c(2)) +) character set ucs2 engine = innodb; +insert into t1 values (1,'abcdefg','abcdefg','one'); +insert into t1 values (2,'ijkilmn','ijkilmn','two'); +insert into t1 values (3,'qrstuvw','qrstuvw','three'); +insert into t1 values (4,_utf8 0xe880bd,_utf8 0xe880bd,'four'); +insert into t1 values (4,_utf8 0x5b,_utf8 0x5b,'five'); +insert into t1 values (4,_utf8 0xe880bde880bd,_utf8 0xe880bde880bd,'six'); +insert into t1 values (4,_utf8 0xe880bdD0B1e880bd,_utf8 0xe880bdD0B1e880bd,'seven'); +insert into t1 values (4,_utf8 0xD0B1,_utf8 0xD0B1,'eight'); +insert into t2 values (1,'abcdefg','abcdefg','one'); +insert into t2 values (2,'ijkilmn','ijkilmn','two'); +insert into t2 values (3,'qrstuvw','qrstuvw','three'); +insert into t2 values (4,_ucs2 0x00e400,_ucs2 0x00e400,'four'); +insert into t2 values (4,_ucs2 0x00640065,_ucs2 0x00640065,'five'); +insert into t2 values (4,_ucs2 0x00e400e50068,_ucs2 0x00e400e50068,'six'); +insert into t2 values (4,_ucs2 0x01fc,_ucs2 0x01fc,'seven'); +insert into t2 values (4,_ucs2 0x0120,_ucs2 0x0120,'eight'); +insert into t2 values (4,_ucs2 0x0563,_ucs2 0x0563,'ten'); +insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven'); +insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point'); +insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken'); +update t1 set filler = 'boo' where a = 1; +update t2 set filler ='email' where a = 4; +select a,hex(b),hex(c),filler from t1 order by filler; +select a,hex(b),hex(c),filler from t2 order by filler; +drop table t1; +drop table t2; + +create table t1 ( + a int, b text(10), c text(10), filler text(10), primary key(a, b(2)), unique key (a, c(2)) +) character set utf8 engine = innodb; +create table t2 ( + a int, b text(10), c text(10), filler text(10), primary key(a, b(2)), unique key (a, c(2)) +) character set ucs2 engine = innodb; +insert into t1 values (1,'abcdefg','abcdefg','one'); +insert into t1 values (2,'ijkilmn','ijkilmn','two'); +insert into t1 values (3,'qrstuvw','qrstuvw','three'); +insert into t1 values (4,_utf8 0xe880bd,_utf8 0xe880bd,'four'); +insert into t1 values (4,_utf8 0x5b,_utf8 0x5b,'five'); +insert into t1 values (4,_utf8 0xe880bde880bd,_utf8 0xe880bde880bd,'six'); +insert into t1 values (4,_utf8 0xe880bdD0B1e880bd,_utf8 0xe880bdD0B1e880bd,'seven'); +insert into t1 values (4,_utf8 0xD0B1,_utf8 0xD0B1,'eight'); +insert into t2 values (1,'abcdefg','abcdefg','one'); +insert into t2 values (2,'ijkilmn','ijkilmn','two'); +insert into t2 values (3,'qrstuvw','qrstuvw','three'); +insert into t2 values (4,_ucs2 0x00e400,_ucs2 0x00e400,'four'); +insert into t2 values (4,_ucs2 0x00640065,_ucs2 0x00640065,'five'); +insert into t2 values (4,_ucs2 0x00e400e50068,_ucs2 0x00e400e50068,'six'); +insert into t2 values (4,_ucs2 0x01fc,_ucs2 0x01fc,'seven'); +insert into t2 values (4,_ucs2 0x0120,_ucs2 0x0120,'eight'); +insert into t2 values (4,_ucs2 0x0563,_ucs2 0x0563,'ten'); +insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven'); +insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point'); +insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken'); +update t1 set filler = 'boo' where a = 1; +update t2 set filler ='email' where a = 4; +select a,hex(b),hex(c),filler from t1 order by filler; +select a,hex(b),hex(c),filler from t2 order by filler; +drop table t1; +drop table t2; + +create table t1 ( + a int, b blob(10), c blob(10), filler blob(10), primary key(a, b(2)), unique key (a, c(2)) +) character set utf8 engine = innodb; +create table t2 ( + a int, b blob(10), c blob(10), filler blob(10), primary key(a, b(2)), unique key (a, c(2)) +) character set ucs2 engine = innodb; +insert into t1 values (1,'abcdefg','abcdefg','one'); +insert into t1 values (2,'ijkilmn','ijkilmn','two'); +insert into t1 values (3,'qrstuvw','qrstuvw','three'); +insert into t1 values (4,_utf8 0xe880bd,_utf8 0xe880bd,'four'); +insert into t1 values (4,_utf8 0x5b,_utf8 0x5b,'five'); +insert into t1 values (4,_utf8 0xD0B1,_utf8 0xD0B1,'eight'); +insert into t2 values (1,'abcdefg','abcdefg','one'); +insert into t2 values (2,'ijkilmn','ijkilmn','two'); +insert into t2 values (3,'qrstuvw','qrstuvw','three'); +insert into t2 values (4,_ucs2 0x00e400,_ucs2 0x00e400,'four'); +insert into t2 values (4,_ucs2 0x00640065,_ucs2 0x00640065,'five'); +insert into t2 values (4,_ucs2 0x00e400e50068,_ucs2 0x00e400e50068,'six'); +insert into t2 values (4,_ucs2 0x01fc,_ucs2 0x01fc,'seven'); +insert into t2 values (4,_ucs2 0x0120,_ucs2 0x0120,'eight'); +insert into t2 values (4,_ucs2 0x0563,_ucs2 0x0563,'ten'); +insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken'); +update t1 set filler = 'boo' where a = 1; +update t2 set filler ='email' where a = 4; +select a,hex(b),hex(c),filler from t1 order by filler; +select a,hex(b),hex(c),filler from t2 order by filler; +drop table t1; +drop table t2; +commit; + +# +# Test cases for bug #15308 Problem of Order with Enum Column in Primary Key +# +CREATE TABLE t1 ( + ind enum('0','1','2') NOT NULL default '0', + string1 varchar(250) NOT NULL, + PRIMARY KEY (ind) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE t2 ( + ind enum('0','1','2') NOT NULL default '0', + string1 varchar(250) NOT NULL, + PRIMARY KEY (ind) +) ENGINE=InnoDB DEFAULT CHARSET=ucs2; + +INSERT INTO t1 VALUES ('1', ''),('2', ''); +INSERT INTO t2 VALUES ('1', ''),('2', ''); +SELECT hex(ind),hex(string1) FROM t1 ORDER BY string1; +SELECT hex(ind),hex(string1) FROM t2 ORDER BY string1; +drop table t1,t2; + +CREATE TABLE t1 ( + ind set('0','1','2') NOT NULL default '0', + string1 varchar(250) NOT NULL, + PRIMARY KEY (ind) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE t2 ( + ind set('0','1','2') NOT NULL default '0', + string1 varchar(250) NOT NULL, + PRIMARY KEY (ind) +) ENGINE=InnoDB DEFAULT CHARSET=ucs2; + +INSERT INTO t1 VALUES ('1', ''),('2', ''); +INSERT INTO t2 VALUES ('1', ''),('2', ''); +SELECT hex(ind),hex(string1) FROM t1 ORDER BY string1; +SELECT hex(ind),hex(string1) FROM t2 ORDER BY string1; +drop table t1,t2; + +CREATE TABLE t1 ( + ind bit not null, + string1 varchar(250) NOT NULL, + PRIMARY KEY (ind) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE t2 ( + ind bit not null, + string1 varchar(250) NOT NULL, + PRIMARY KEY (ind) +) ENGINE=InnoDB DEFAULT CHARSET=ucs2; +insert into t1 values(0,''),(1,''); +insert into t2 values(0,''),(1,''); +select hex(ind),hex(string1) from t1 order by string1; +select hex(ind),hex(string1) from t2 order by string1; +drop table t1,t2; + +# tests for bug #14056 Column prefix index on UTF-8 primary key column causes 'Can't find record..' + +create table t2 ( + a int, b char(10), filler char(10), primary key(a, b(2)) +) character set utf8 engine = innodb; + +insert into t2 values (1,'abcdefg','one'); +insert into t2 values (2,'ijkilmn','two'); +insert into t2 values (3, 'qrstuvw','three'); +update t2 set a=5, filler='booo' where a=1; +drop table t2; +create table t2 ( + a int, b char(10), filler char(10), primary key(a, b(2)) +) character set ucs2 engine = innodb; + +insert into t2 values (1,'abcdefg','one'); +insert into t2 values (2,'ijkilmn','two'); +insert into t2 values (3, 'qrstuvw','three'); +update t2 set a=5, filler='booo' where a=1; +drop table t2; + +create table t1(a int not null, b char(110),primary key(a,b(100))) engine=innodb default charset=utf8; +insert into t1 values(1,'abcdefg'),(2,'defghijk'); +insert into t1 values(6,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1); +insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2); +select a,hex(b) from t1 order by b; +update t1 set b = 'three' where a = 6; +drop table t1; +create table t1(a int not null, b text(110),primary key(a,b(100))) engine=innodb default charset=utf8; +insert into t1 values(1,'abcdefg'),(2,'defghijk'); +insert into t1 values(6,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1); +insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2); +select a,hex(b) from t1 order by b; +update t1 set b = 'three' where a = 6; +drop table t1; + +--echo End of 5.0 tests diff --git a/mysql-test/suite/innodb_plugin/t/innodb_autoinc_lock_mode_zero-master.opt b/mysql-test/suite/innodb_plugin/t/innodb_autoinc_lock_mode_zero-master.opt new file mode 100644 index 00000000000..fad0da2ac2e --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_autoinc_lock_mode_zero-master.opt @@ -0,0 +1 @@ +--innodb-autoinc-lock-mode=0 diff --git a/mysql-test/suite/innodb_plugin/t/innodb_autoinc_lock_mode_zero.test b/mysql-test/suite/innodb_plugin/t/innodb_autoinc_lock_mode_zero.test new file mode 100644 index 00000000000..5a0cd5fa766 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_autoinc_lock_mode_zero.test @@ -0,0 +1,44 @@ +# This test runs with old-style locking, as: +# --innodb-autoinc-lock-mode=0 + +-- source include/have_innodb_plugin.inc + +--disable_warnings +drop table if exists t1; +--enable_warnings + + +# +# Search on unique key +# + +CREATE TABLE t1 ( + id int(11) NOT NULL auto_increment, + ggid varchar(32) binary DEFAULT '' NOT NULL, + email varchar(64) DEFAULT '' NOT NULL, + passwd varchar(32) binary DEFAULT '' NOT NULL, + PRIMARY KEY (id), + UNIQUE ggid (ggid) +) ENGINE=innodb; + +insert into t1 (ggid,passwd) values ('test1','xxx'); +insert into t1 (ggid,passwd) values ('test2','yyy'); +-- error ER_DUP_ENTRY +insert into t1 (ggid,passwd) values ('test2','this will fail'); +-- error ER_DUP_ENTRY +insert into t1 (ggid,id) values ('this will fail',1); + +select * from t1 where ggid='test1'; +select * from t1 where passwd='xxx'; +select * from t1 where id=2; + +replace into t1 (ggid,id) values ('this will work',1); +replace into t1 (ggid,passwd) values ('test2','this will work'); +-- error ER_DUP_ENTRY +update t1 set id=100,ggid='test2' where id=1; +select * from t1; +select * from t1 where id=1; +select * from t1 where id=999; +drop table t1; + +--echo End of tests diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug30919-master.opt b/mysql-test/suite/innodb_plugin/t/innodb_bug30919-master.opt new file mode 100644 index 00000000000..8636d2d8734 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug30919-master.opt @@ -0,0 +1 @@ +--innodb --innodb_autoinc_lock_mode=0 diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug30919.test b/mysql-test/suite/innodb_plugin/t/innodb_bug30919.test new file mode 100644 index 00000000000..cc1358294e1 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug30919.test @@ -0,0 +1,68 @@ +--source include/have_innodb_plugin.inc +--source include/have_partition.inc +--vertical_results +let $engine_type= 'innodb'; + +######## Creat Table Section ######### +use test; + +eval CREATE TABLE test.part_tbl(id MEDIUMINT NOT NULL AUTO_INCREMENT, + dt TIMESTAMP, user CHAR(255), uuidf LONGBLOB, + fkid MEDIUMINT, filler VARCHAR(255), + PRIMARY KEY(id)) ENGINE=$engine_type + PARTITION BY RANGE(id) + SUBPARTITION BY hash(id) subpartitions 2 + (PARTITION pa3 values less than (42), + PARTITION pa6 values less than (60), + PARTITION pa7 values less than (70), + PARTITION pa8 values less than (80), + PARTITION pa9 values less than (90), + PARTITION pa10 values less than (100), + PARTITION pa11 values less than MAXVALUE); + +######## Create SPs, Functions, Views and Triggers Section ############## + +delimiter |; + +CREATE PROCEDURE test.proc_part() +BEGIN + DECLARE ins_count INT DEFAULT 1000; + DECLARE del_count INT; + DECLARE cur_user VARCHAR(255); + DECLARE local_uuid VARCHAR(255); + DECLARE local_time TIMESTAMP; + + SET local_time= NOW(); + SET cur_user= CURRENT_USER(); + SET local_uuid= UUID(); + + WHILE ins_count > 0 DO + INSERT INTO test.part_tbl VALUES (NULL, NOW(), USER() , UUID(), + ins_count,'Going to test MBR for MySQL'); + SET ins_count = ins_count - 1; + END WHILE; + SELECT MAX(id) FROM test.part_tbl INTO del_count; + WHILE del_count > 0 DO + DELETE FROM test.part_tbl WHERE id = del_count; + select count(*) as internal_count, del_count -- these two lines are for + FROM test.part_tbl; -- debug to show the problem + SET del_count = del_count - 2; + END WHILE; +END| + +delimiter ;| + +############ Finish Setup Section ################### + +############ Test Section ################### +--horizontal_results + +CALL test.proc_part(); + +select count(*) as Part from test.part_tbl; + +###### CLEAN UP SECTION ############## + +DROP PROCEDURE test.proc_part; +DROP TABLE test.part_tbl; + diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug42419.test b/mysql-test/suite/innodb_plugin/t/innodb_bug42419.test new file mode 100644 index 00000000000..2302e3c2233 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug42419.test @@ -0,0 +1,78 @@ +# +# Testcase for InnoDB +# Bug#42419 Server crash with "Pure virtual method called" on two concurrent connections +# + +--source include/not_embedded.inc +--source include/have_innodb_plugin.inc + +let $innodb_lock_wait_timeout= query_get_value(SHOW VARIABLES LIKE 'innodb_lock_wait_timeout%', Value, 1); +if (`SELECT $innodb_lock_wait_timeout < 10`) +{ + --echo # innodb_lock_wait_timeout must be >= 10 seconds + --echo # so that this test can work all time fine on an overloaded testing box + SHOW VARIABLES LIKE 'innodb_lock_wait_timeout'; + exit; +} + +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + +# First session +connection default; + + +--enable_warnings +CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b INT) ENGINE = InnoDB; + +INSERT INTO t1 VALUES (1,1),(2,2),(3,3); +COMMIT; +SET AUTOCOMMIT = 0; + +CREATE TEMPORARY TABLE t1_tmp ( b INT ); + +INSERT INTO t1_tmp (b) SELECT b FROM t1 WHERE a = 3; +INSERT INTO t1_tmp (b) SELECT b FROM t1 WHERE a = 2; + +# Second session +connect (user2,localhost,root,,,$MASTER_MYPORT,$MASTER_MYSOCK); + +SET AUTOCOMMIT = 0; + +CREATE TEMPORARY TABLE t2_tmp ( a int, new_a int ); +INSERT INTO t2_tmp VALUES (1,51),(2,52),(3,53); + +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 1; +send +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 2; + +# The last update will wait for a lock held by the first session + +# First session +connection default; + +# Poll till the UPDATE of the second session waits for lock +let $show_statement= SHOW PROCESSLIST; +let $field= State; +let $condition= = 'Updating'; +--source include/wait_show_condition.inc + +# If the testing box is overloadeded and innodb_lock_wait_timeout is too small +# we might get here ER_LOCK_WAIT_TIMEOUT. +--error ER_LOCK_DEADLOCK +INSERT INTO t1_tmp (b) SELECT b FROM t1 WHERE a = 1; + +# Second session +connection user2; +--echo Reap the server message for connection user2 UPDATE t1 ... +reap; + +# The server crashed when executing this UPDATE or the succeeding SQL command. +UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 3; + +connection default; +disconnect user2; +DROP TABLE t1; + +# Wait till all disconnects are completed +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/innodb_plugin/t/innodb_gis.test b/mysql-test/suite/innodb_plugin/t/innodb_gis.test new file mode 100644 index 00000000000..ad1d081f29c --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_gis.test @@ -0,0 +1,10 @@ +--source include/have_innodb_plugin.inc +SET storage_engine=innodb; +--source include/gis_generic.inc +--source include/gis_keys.inc + +# +# Bug #15680 (SPATIAL key in innodb) +# +--error ER_TABLE_CANT_HANDLE_SPKEYS +create table t1 (g geometry not null, spatial gk(g)) engine=innodb; diff --git a/mysql-test/suite/innodb_plugin/t/innodb_lock_wait_timeout_1-master.opt b/mysql-test/suite/innodb_plugin/t/innodb_lock_wait_timeout_1-master.opt new file mode 100644 index 00000000000..462f8fbe828 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_lock_wait_timeout_1-master.opt @@ -0,0 +1 @@ +--innodb_lock_wait_timeout=1 diff --git a/mysql-test/suite/innodb_plugin/t/innodb_lock_wait_timeout_1.test b/mysql-test/suite/innodb_plugin/t/innodb_lock_wait_timeout_1.test new file mode 100644 index 00000000000..d7272779bdd --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_lock_wait_timeout_1.test @@ -0,0 +1,264 @@ +--source include/have_innodb_plugin.inc + +--echo # +--echo # Bug #40113: Embedded SELECT inside UPDATE or DELETE can timeout +--echo # without error +--echo # + +CREATE TABLE t1 (a int, b int, PRIMARY KEY (a,b)) ENGINE=InnoDB; + +INSERT INTO t1 (a,b) VALUES (1070109,99); + +CREATE TABLE t2 (b int, a int, PRIMARY KEY (b)) ENGINE=InnoDB; + +INSERT INTO t2 (b,a) VALUES (7,1070109); + +SELECT * FROM t1; + +BEGIN; + +SELECT b FROM t2 WHERE b=7 FOR UPDATE; + +CONNECT (addconroot, localhost, root,,); +CONNECTION addconroot; + +BEGIN; + +--error ER_LOCK_WAIT_TIMEOUT +SELECT b FROM t2 WHERE b=7 FOR UPDATE; + +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t1 (a) VALUES ((SELECT a FROM t2 WHERE b=7)); + +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t1 SET a='7000000' WHERE a=(SELECT a FROM t2 WHERE b=7); + +--error ER_LOCK_WAIT_TIMEOUT +DELETE FROM t1 WHERE a=(SELECT a FROM t2 WHERE b=7); + +SELECT * FROM t1; + +CONNECTION default; +DISCONNECT addconroot; + +DROP TABLE t2, t1; + +--echo # End of 5.0 tests + +--echo # +--echo # Bug#46539 Various crashes on INSERT IGNORE SELECT + SELECT +--echo # FOR UPDATE +--echo # +--disable_warnings +drop table if exists t1; +--enable_warnings +create table t1 (a int primary key auto_increment, + b int, index(b)) engine=innodb; +insert into t1 (b) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); +set autocommit=0; +begin; +select * from t1 where b=5 for update; +connect (con1, localhost, root,,); +connection con1; +--error ER_LOCK_WAIT_TIMEOUT +insert ignore into t1 (b) select a as b from t1; +connection default; +--echo # Cleanup +--echo # +disconnect con1; +commit; +set autocommit=default; +drop table t1; + +--echo # +--echo # Bug #37183 insert ignore into .. select ... hangs +--echo # after deadlock was encountered +--echo # +connect (con1,localhost,root,,); +create table t1(id int primary key,v int)engine=innodb; +insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7); +create table t2 like t1; + +--connection con1 +begin; +update t1 set v=id*2 where id=1; + +--connection default +begin; +update t1 set v=id*2 where id=2; + +--connection con1 +--error 1205 +update t1 set v=id*2 where id=2; + +--connection default +--error 1205 +insert ignore into t2 select * from t1 where id=1; +rollback; + +--connection con1 +rollback; + +--connection default +disconnect con1; +drop table t1, t2; + + +--echo # +--echo # Bug#41756 Strange error messages about locks from InnoDB +--echo # +--disable_warnings +drop table if exists t1; +--enable_warnings +--echo # In the default transaction isolation mode, and/or with +--echo # innodb_locks_unsafe_for_binlog=OFF, handler::unlock_row() +--echo # in InnoDB does nothing. +--echo # Thus in order to reproduce the condition that led to the +--echo # warning, one needs to relax isolation by either +--echo # setting a weaker tx_isolation value, or by turning on +--echo # the unsafe replication switch. +--echo # For testing purposes, choose to tweak the isolation level, +--echo # since it's settable at runtime, unlike +--echo # innodb_locks_unsafe_for_binlog, which is +--echo # only a command-line switch. +--echo # +set @@session.tx_isolation="read-committed"; + +--echo # Prepare data. We need a table with a unique index, +--echo # for join_read_key to be used. The other column +--echo # allows to control what passes WHERE clause filter. +create table t1 (a int primary key, b int) engine=innodb; +--echo # Let's make sure t1 has sufficient amount of rows +--echo # to exclude JT_ALL access method when reading it, +--echo # i.e. make sure that JT_EQ_REF(a) is always preferred. +insert into t1 values (1,1), (2,null), (3,1), (4,1), + (5,1), (6,1), (7,1), (8,1), (9,1), (10,1), + (11,1), (12,1), (13,1), (14,1), (15,1), + (16,1), (17,1), (18,1), (19,1), (20,1); +--echo # +--echo # Demonstrate that for the SELECT statement +--echo # used later in the test JT_EQ_REF access method is used. +--echo # +--vertical_results +explain +select 1 from t1 natural join (select 2 as a, 1 as b union all + select 2 as a, 2 as b) as t2 for update; +--horizontal_results +--echo # +--echo # Demonstrate that the reported SELECT statement +--echo # no longer produces warnings. +--echo # +select 1 from t1 natural join (select 2 as a, 1 as b union all + select 2 as a, 2 as b) as t2 for update; +commit; +--echo # +--echo # Demonstrate that due to lack of inter-sweep "reset" function, +--echo # we keep some non-matching records locked, even though we know +--echo # we could unlock them. +--echo # To do that, show that if there is only one distinct value +--echo # for a in t2 (a=2), we will keep record (2,null) in t1 locked. +--echo # But if we add another value for "a" to t2, say 6, +--echo # join_read_key cache will be pruned at least once, +--echo # and thus record (2, null) in t1 will get unlocked. +--echo # +begin; +select 1 from t1 natural join (select 2 as a, 1 as b union all + select 2 as a, 2 as b) as t2 for update; +connect (con1,localhost,root,,); +--echo # +--echo # Switching to connection con1 +connection con1; +--echo # We should be able to delete all records from t1 except (2, null), +--echo # since they were not locked. +begin; +--echo # Delete in series of 3 records so that full scan +--echo # is not used and we're not blocked on record (2,null) +delete from t1 where a in (1,3,4); +delete from t1 where a in (5,6,7); +delete from t1 where a in (8,9,10); +delete from t1 where a in (11,12,13); +delete from t1 where a in (14,15,16); +delete from t1 where a in (17,18); +delete from t1 where a in (19,20); +--echo # +--echo # Record (2, null) is locked. This is actually unnecessary, +--echo # because the previous select returned no rows. +--echo # Just demonstrate the effect. +--echo # +--error ER_LOCK_WAIT_TIMEOUT +delete from t1; +rollback; +--echo # +--echo # Switching to connection default +connection default; +--echo # +--echo # Show that the original contents of t1 is intact: +select * from t1; +commit; +--echo # +--echo # Have a one more record in t2 to show that +--echo # if join_read_key cache is purned, the current +--echo # row under the cursor is unlocked (provided, this row didn't +--echo # match the partial WHERE clause, of course). +--echo # Sic: the result of this test dependent on the order of retrieval +--echo # of records --echo # from the derived table, if ! +--echo # We use DELETE to disable the JOIN CACHE. This DELETE modifies no +--echo # records. It also should leave no InnoDB row locks. +--echo # +begin; +delete t1.* from t1 natural join (select 2 as a, 2 as b union all + select 0 as a, 0 as b) as t2; +--echo # Demonstrate that nothing was deleted form t1 +select * from t1; +--echo # +--echo # Switching to connection con1 +connection con1; +begin; +--echo # Since there is another distinct record in the derived table +--echo # the previous matching record in t1 -- (2,null) -- was unlocked. +delete from t1; +--echo # We will need the contents of the table again. +rollback; +select * from t1; +commit; +--echo # +--echo # Switching to connection default +connection default; +rollback; +begin; +--echo # +--echo # Before this patch, we could wrongly unlock a record +--echo # that was cached and later used in a join. Demonstrate that +--echo # this is no longer the case. +--echo # Sic: this test is also order-dependent (i.e. the +--echo # the bug would show up only if the first record in the union +--echo # is retreived and processed first. +--echo # +--echo # Verify that JT_EQ_REF is used. +--vertical_results +explain +select 1 from t1 natural join (select 3 as a, 2 as b union all + select 3 as a, 1 as b) as t2 for update; +--horizontal_results +--echo # Lock the record. +select 1 from t1 natural join (select 3 as a, 2 as b union all + select 3 as a, 1 as b) as t2 for update; +--echo # Switching to connection con1 +connection con1; +--echo # +--echo # We should not be able to delete record (3,1) from t1, +--echo # (previously it was possible). +--echo # +--error ER_LOCK_WAIT_TIMEOUT +delete from t1 where a=3; +--echo # Switching to connection default +connection default; +commit; + +disconnect con1; +set @@session.tx_isolation=default; +drop table t1; + +--echo # +--echo # End of 5.1 tests +--echo # diff --git a/mysql-test/suite/innodb_plugin/t/innodb_mysql-master.opt b/mysql-test/suite/innodb_plugin/t/innodb_mysql-master.opt new file mode 100644 index 00000000000..205c733455d --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_mysql-master.opt @@ -0,0 +1 @@ +--innodb-lock-wait-timeout=2 diff --git a/mysql-test/suite/innodb_plugin/t/innodb_mysql.test b/mysql-test/suite/innodb_plugin/t/innodb_mysql.test new file mode 100644 index 00000000000..c80db7088ab --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_mysql.test @@ -0,0 +1,622 @@ +# t/innodb_mysql.test +# +# Last update: +# 2006-07-26 ML test refactored (MySQL 5.1) +# main testing code t/innodb_mysql.test -> include/mix1.inc +# + +-- source include/have_innodb_plugin.inc +let $engine_type= InnoDB; +let $other_engine_type= MEMORY; +# InnoDB does support FOREIGN KEYFOREIGN KEYs +let $test_foreign_keys= 1; +set global innodb_support_xa=default; +set session innodb_support_xa=default; +--source include/mix1.inc + +--disable_warnings +drop table if exists t1, t2, t3; +--enable_warnings +# +# BUG#35850: Performance regression in 5.1.23/5.1.24 +# +create table t1(a int); +insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t2 (a int, b int, pk int, key(a,b), primary key(pk)) engine=innodb; +insert into t2 select @a:=A.a+10*(B.a + 10*C.a),@a, @a from t1 A, t1 B, t1 C; +--echo this must use key 'a', not PRIMARY: +--replace_column 9 # +explain select a from t2 where a=b; +drop table t1, t2; + +# +# Bug #40360: Binlog related errors with binlog off +# +# This bug is triggered when the binlog format is STATEMENT and the +# binary log is turned off. In this case, no error should be shown for +# the statement since there are no replication issues. + +SET SESSION BINLOG_FORMAT=STATEMENT; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +query_vertical select @@session.sql_log_bin, @@session.binlog_format, @@session.tx_isolation; +CREATE TABLE t1 ( a INT ) ENGINE=InnoDB; +INSERT INTO t1 VALUES(1); +DROP TABLE t1; + +# +# Bug#37284 Crash in Field_string::type() +# +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings +CREATE TABLE t1 (a char(50)) ENGINE=InnoDB; +CREATE INDEX i1 on t1 (a(3)); +SELECT * FROM t1 WHERE a = 'abcde'; +DROP TABLE t1; + +# +# Bug #37742: HA_EXTRA_KEYREAD flag is set when key contains only prefix of +# requested column +# + +CREATE TABLE foo (a int, b int, c char(10), + PRIMARY KEY (c(3)), + KEY b (b) +) engine=innodb; + +CREATE TABLE foo2 (a int, b int, c char(10), + PRIMARY KEY (c), + KEY b (b) +) engine=innodb; + +CREATE TABLE bar (a int, b int, c char(10), + PRIMARY KEY (c(3)), + KEY b (b) +) engine=myisam; + +INSERT INTO foo VALUES + (1,2,'abcdefghij'), (2,3,''), (3,4,'klmnopqrst'), + (4,5,'uvwxyz'), (5,6,'meotnsyglt'), (4,5,'asfdewe'); + +INSERT INTO bar SELECT * FROM foo; +INSERT INTO foo2 SELECT * FROM foo; + +--query_vertical EXPLAIN SELECT c FROM bar WHERE b>2; +--query_vertical EXPLAIN SELECT c FROM foo WHERE b>2; +--query_vertical EXPLAIN SELECT c FROM foo2 WHERE b>2; + +--query_vertical EXPLAIN SELECT c FROM bar WHERE c>2; +--query_vertical EXPLAIN SELECT c FROM foo WHERE c>2; +--query_vertical EXPLAIN SELECT c FROM foo2 WHERE c>2; + +DROP TABLE foo, bar, foo2; + + +# +# Bug#41348: INSERT INTO tbl SELECT * FROM temp_tbl overwrites locking type of temp table +# + +--disable_warnings +DROP TABLE IF EXISTS t1,t3,t2; +DROP FUNCTION IF EXISTS f1; +--enable_warnings + +DELIMITER |; +CREATE FUNCTION f1() RETURNS VARCHAR(250) + BEGIN + return 'hhhhhhh' ; + END| +DELIMITER ;| + +CREATE TABLE t1 (a VARCHAR(20), b VARCHAR(20), c VARCHAR(20)) ENGINE=INNODB; + +BEGIN WORK; + +CREATE TEMPORARY TABLE t2 (a VARCHAR(20), b VARCHAR(20), c varchar(20)) ENGINE=INNODB; +CREATE TEMPORARY TABLE t3 LIKE t2; + +INSERT INTO t1 VALUES ('a','b',NULL),('c','d',NULL),('e','f',NULL); + +SET @stmt := CONCAT('INSERT INTO t2 SELECT tbl.a, tbl.b, f1()',' FROM t1 tbl'); +PREPARE stmt1 FROM @stmt; + +SET @stmt := CONCAT('INSERT INTO t3', ' SELECT * FROM t2'); +PREPARE stmt3 FROM @stmt; + +EXECUTE stmt1; + +COMMIT; + +DEALLOCATE PREPARE stmt1; +DEALLOCATE PREPARE stmt3; + +DROP TABLE t1,t3,t2; +DROP FUNCTION f1; + +# +# Bug#37016: TRUNCATE TABLE removes some rows but not all +# + +--disable_warnings +DROP TABLE IF EXISTS t1,t2; +--enable_warnings + +CREATE TABLE t1 (id INT NOT NULL, PRIMARY KEY (id)) ENGINE=INNODB; +CREATE TABLE t2 (id INT PRIMARY KEY, + t1_id INT, INDEX par_ind (t1_id), + FOREIGN KEY (t1_id) REFERENCES t1(id)) ENGINE=INNODB; +INSERT INTO t1 VALUES (1),(2); +INSERT INTO t2 VALUES (3,2); + +SET AUTOCOMMIT = 0; + +START TRANSACTION; +--error ER_ROW_IS_REFERENCED_2 +TRUNCATE TABLE t1; +SELECT * FROM t1; +COMMIT; +SELECT * FROM t1; + +START TRANSACTION; +--error ER_ROW_IS_REFERENCED_2 +TRUNCATE TABLE t1; +SELECT * FROM t1; +ROLLBACK; +SELECT * FROM t1; + +SET AUTOCOMMIT = 1; + +START TRANSACTION; +SELECT * FROM t1; +COMMIT; + +--error ER_ROW_IS_REFERENCED_2 +TRUNCATE TABLE t1; +SELECT * FROM t1; +DELETE FROM t2 WHERE id = 3; + +START TRANSACTION; +SELECT * FROM t1; +TRUNCATE TABLE t1; +ROLLBACK; +SELECT * FROM t1; +TRUNCATE TABLE t2; + +DROP TABLE t2; +DROP TABLE t1; + +--echo # +--echo # Bug#40127 Multiple table DELETE IGNORE hangs on foreign key constraint violation on 5.0 +--echo # +CREATE TABLE t1 ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT, + PRIMARY KEY (id) +) ENGINE=InnoDB; + +CREATE TABLE t2 ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT, + aid INT UNSIGNED NOT NULL, + PRIMARY KEY (id), + FOREIGN KEY (aid) REFERENCES t1 (id) +) ENGINE=InnoDB; + +CREATE TABLE t3 ( + bid INT UNSIGNED NOT NULL, + FOREIGN KEY (bid) REFERENCES t2 (id) +) ENGINE=InnoDB; + +CREATE TABLE t4 ( + a INT +) ENGINE=InnoDB; + +CREATE TABLE t5 ( + a INT +) ENGINE=InnoDB; + +INSERT INTO t1 (id) VALUES (1); +INSERT INTO t2 (id, aid) VALUES (1, 1),(2,1),(3,1),(4,1); +INSERT INTO t3 (bid) VALUES (1); + +INSERT INTO t4 VALUES (1),(2),(3),(4),(5); +INSERT INTO t5 VALUES (1); + +DELETE t5 FROM t4 LEFT JOIN t5 ON t4.a= t5.a; + +--error ER_ROW_IS_REFERENCED_2 +DELETE t2, t1 FROM t2 INNER JOIN t1 ON (t2.aid = t1.id) WHERE t2.id = 1; +--error ER_ROW_IS_REFERENCED_2 +DELETE t2, t1 FROM t2 INNER JOIN t1 ON (t2.aid = t1.id) WHERE t2.id = 1; + +DELETE IGNORE t2, t1 FROM t2 INNER JOIN t1 ON (t2.aid = t1.id) WHERE t2.id = 1; + +DROP TABLE t3; +DROP TABLE t2; +DROP TABLE t1; +DROP TABLES t4,t5; + +--echo # Bug#40127 Multiple table DELETE IGNORE hangs on foreign key constraint violation on 5.0 +--echo # Testing for any side effects of IGNORE on AFTER DELETE triggers used with +--echo # transactional tables. +--echo # +CREATE TABLE t1 (i INT NOT NULL PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t2 (a VARCHAR(100)) ENGINE=InnoDB; +CREATE TABLE t3 (i INT NOT NULL PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t4 (i INT NOT NULL PRIMARY KEY, t1i INT, + FOREIGN KEY (t1i) REFERENCES t1(i)) + ENGINE=InnoDB; +delimiter ||; +CREATE TRIGGER trg AFTER DELETE ON t1 FOR EACH ROW +BEGIN + SET @b:='EXECUTED TRIGGER'; + INSERT INTO t2 VALUES (@b); + SET @a:= error_happens_here; +END|| +delimiter ;|| + +SET @b:=""; +SET @a:=""; +INSERT INTO t1 VALUES (1),(2),(3),(4); +INSERT INTO t3 SELECT * FROM t1; +--echo ** An error in a trigger causes rollback of the statement. +--error ER_BAD_FIELD_ERROR +DELETE t1 FROM t3 LEFT JOIN t1 ON t1.i=t3.i; +SELECT @a,@b; +SELECT * FROM t2; +SELECT * FROM t1 LEFT JOIN t3 ON t1.i=t3.i; + +--echo ** Same happens with the IGNORE option +--error ER_BAD_FIELD_ERROR +DELETE IGNORE t1 FROM t3 LEFT JOIN t1 ON t1.i=t3.i; +SELECT * FROM t2; +SELECT * FROM t1 LEFT JOIN t3 ON t1.i=t3.i; + +--echo ** +--echo ** The following is an attempt to demonstrate +--echo ** error handling inside a row iteration. +--echo ** +DROP TRIGGER trg; +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +TRUNCATE TABLE t3; + +INSERT INTO t1 VALUES (1),(2),(3),(4); +INSERT INTO t3 VALUES (1),(2),(3),(4); +INSERT INTO t4 VALUES (3,3),(4,4); + +delimiter ||; +CREATE TRIGGER trg AFTER DELETE ON t1 FOR EACH ROW +BEGIN + SET @b:= CONCAT('EXECUTED TRIGGER FOR ROW ',CAST(OLD.i AS CHAR)); + INSERT INTO t2 VALUES (@b); +END|| +delimiter ;|| + +--echo ** DELETE is prevented by foreign key constrains but errors are silenced. +--echo ** The AFTER trigger isn't fired. +DELETE IGNORE t1 FROM t3 LEFT JOIN t1 ON t1.i=t3.i; +--echo ** Tables are modified by best effort: +SELECT * FROM t1 LEFT JOIN t3 ON t1.i=t3.i; +--echo ** The AFTER trigger was only executed on successful rows: +SELECT * FROM t2; + +DROP TRIGGER trg; + +--echo ** +--echo ** Induce an error midway through an AFTER-trigger +--echo ** +TRUNCATE TABLE t4; +TRUNCATE TABLE t1; +TRUNCATE TABLE t3; +INSERT INTO t1 VALUES (1),(2),(3),(4); +INSERT INTO t3 VALUES (1),(2),(3),(4); +delimiter ||; +CREATE TRIGGER trg AFTER DELETE ON t1 FOR EACH ROW +BEGIN + SET @a:= @a+1; + IF @a > 2 THEN + INSERT INTO t4 VALUES (5,5); + END IF; +END|| +delimiter ;|| + +SET @a:=0; +--echo ** Errors in the trigger causes the statement to abort. +--error ER_NO_REFERENCED_ROW_2 +DELETE IGNORE t1 FROM t3 LEFT JOIN t1 ON t1.i=t3.i; +SELECT * FROM t1 LEFT JOIN t3 ON t1.i=t3.i; +SELECT * FROM t4; + +DROP TRIGGER trg; +DROP TABLE t4; +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; + +# +# Bug#43580: Issue with Innodb on multi-table update +# +CREATE TABLE t1 (a INT, b INT, KEY (a)) ENGINE = INNODB; +CREATE TABLE t2 (a INT KEY, b INT, KEY (b)) ENGINE = INNODB; + +CREATE TABLE t3 (a INT, b INT KEY, KEY (a)) ENGINE = INNODB; +CREATE TABLE t4 (a INT KEY, b INT, KEY (b)) ENGINE = INNODB; + +INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6); +INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5); + +INSERT INTO t3 VALUES (1, 101), (2, 102), (3, 103), (4, 104), (5, 105), (6, 106); +INSERT INTO t4 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5); + +UPDATE t1, t2 SET t1.a = t1.a + 100, t2.b = t1.a + 10 +WHERE t1.a BETWEEN 2 AND 4 AND t2.a = t1.b; +--sorted_result +SELECT * FROM t2; + +UPDATE t3, t4 SET t3.a = t3.a + 100, t4.b = t3.a + 10 +WHERE t3.a BETWEEN 2 AND 4 AND t4.a = t3.b - 100; +--sorted_result +SELECT * FROM t4; + +DROP TABLE t1, t2, t3, t4; + +--echo # +--echo # Bug#44886: SIGSEGV in test_if_skip_sort_order() - +--echo # uninitialized variable used as subscript +--echo # + +CREATE TABLE t1 (a INT, b INT, c INT, d INT, PRIMARY KEY (b), KEY (a,c)) + ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,1,1,0); + +CREATE TABLE t2 (a INT, b INT, e INT, KEY (e)) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,1,2); + +CREATE TABLE t3 (a INT, b INT) ENGINE=MyISAM; +INSERT INTO t3 VALUES (1, 1); + +SELECT * FROM t1, t2, t3 + WHERE t1.a = t3.a AND (t1.b = t3.b OR t1.d) AND t2.b = t1.b AND t2.e = 2 + GROUP BY t1.b; + +DROP TABLE t1, t2, t3; + +--echo # +--echo # Bug #45828: Optimizer won't use partial primary key if another +--echo # index can prevent filesort +--echo # + +# Create the table +CREATE TABLE `t1` ( + c1 int NOT NULL, + c2 int NOT NULL, + c3 int NOT NULL, + PRIMARY KEY (c1,c2), + KEY (c3) +) ENGINE=InnoDB; + +# populate with data +INSERT INTO t1 VALUES (5,2,1246276747); +INSERT INTO t1 VALUES (2,1,1246281721); +INSERT INTO t1 VALUES (7,3,1246281756); +INSERT INTO t1 VALUES (4,2,1246282139); +INSERT INTO t1 VALUES (3,1,1246282230); +INSERT INTO t1 VALUES (1,0,1246282712); +INSERT INTO t1 VALUES (8,3,1246282765); +INSERT INTO t1 SELECT c1+10,c2+10,c3+10 FROM t1; +INSERT INTO t1 SELECT c1+100,c2+100,c3+100 from t1; +INSERT INTO t1 SELECT c1+1000,c2+1000,c3+1000 from t1; +INSERT INTO t1 SELECT c1+10000,c2+10000,c3+10000 from t1; +INSERT INTO t1 SELECT c1+100000,c2+100000,c3+100000 from t1; +INSERT INTO t1 SELECT c1+1000000,c2+1000000,c3+1000000 from t1; + +# query and no rows will match the c1 condition, whereas all will match c3 +SELECT * FROM t1 WHERE c1 = 99999999 AND c3 > 1 ORDER BY c3; + +# SHOULD use the pk. +# index on c3 will be used instead of primary key +EXPLAIN SELECT * FROM t1 WHERE c1 = 99999999 AND c3 > 1 ORDER BY c3; + +# if we force the primary key, we can see the estimate is 1 +EXPLAIN SELECT * FROM t1 FORCE INDEX (PRIMARY) WHERE c1 = 99999999 AND c3 > 1 ORDER BY c3; + + +CREATE TABLE t2 ( + c1 int NOT NULL, + c2 int NOT NULL, + c3 int NOT NULL, + KEY (c1,c2), + KEY (c3) +) ENGINE=InnoDB; + +# SHOULD use the pk. +# if we switch it from a primary key to a regular index, it works correctly as well +explain SELECT * FROM t2 WHERE c1 = 99999999 AND c3 > 1 ORDER BY c3; + +DROP TABLE t1,t2; + + +--echo # +--echo # 36259: Optimizing with ORDER BY +--echo # + +CREATE TABLE t1 ( + a INT NOT NULL AUTO_INCREMENT, + b INT NOT NULL, + c INT NOT NULL, + d VARCHAR(5), + e INT NOT NULL, + PRIMARY KEY (a), KEY i2 (b,c,d) +) ENGINE=InnoDB; + +INSERT INTO t1 (b,c,d,e) VALUES (1,1,'a',1), (2,2,'b',2); +INSERT INTO t1 (b,c,d,e) SELECT RAND()*10000, RAND()*10000, d, e FROM t1; +INSERT INTO t1 (b,c,d,e) SELECT RAND()*10000, RAND()*10000, d, e FROM t1; +INSERT INTO t1 (b,c,d,e) SELECT RAND()*10000, RAND()*10000, d, e FROM t1; +INSERT INTO t1 (b,c,d,e) SELECT RAND()*10000, RAND()*10000, d, e FROM t1; +INSERT INTO t1 (b,c,d,e) SELECT RAND()*10000, RAND()*10000, d, e FROM t1; +INSERT INTO t1 (b,c,d,e) SELECT RAND()*10000, RAND()*10000, d, e FROM t1; +EXPLAIN SELECT * FROM t1 WHERE b=1 AND c=1 ORDER BY a; +EXPLAIN SELECT * FROM t1 FORCE INDEX(i2) WHERE b=1 and c=1 ORDER BY a; +EXPLAIN SELECT * FROM t1 FORCE INDEX(PRIMARY) WHERE b=1 AND c=1 ORDER BY a; + +DROP TABLE t1; + +--echo # +--echo # Bug #47963: Wrong results when index is used +--echo # +CREATE TABLE t1( + a VARCHAR(5) NOT NULL, + b VARCHAR(5) NOT NULL, + c DATETIME NOT NULL, + KEY (c) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES('TEST', 'TEST', '2009-10-09 00:00:00'); +SELECT * FROM t1 WHERE a = 'TEST' AND + c >= '2009-10-09 00:00:00' AND c <= '2009-10-09 00:00:00'; +SELECT * FROM t1 WHERE a = 'TEST' AND + c >= '2009-10-09 00:00:00.0' AND c <= '2009-10-09 00:00:00.0'; +SELECT * FROM t1 WHERE a = 'TEST' AND + c >= '2009-10-09 00:00:00.0' AND c <= '2009-10-09 00:00:00'; +SELECT * FROM t1 WHERE a = 'TEST' AND + c >= '2009-10-09 00:00:00' AND c <= '2009-10-09 00:00:00.0'; +SELECT * FROM t1 WHERE a = 'TEST' AND + c >= '2009-10-09 00:00:00.000' AND c <= '2009-10-09 00:00:00.000'; +SELECT * FROM t1 WHERE a = 'TEST' AND + c >= '2009-10-09 00:00:00.00' AND c <= '2009-10-09 00:00:00.001'; +SELECT * FROM t1 WHERE a = 'TEST' AND + c >= '2009-10-09 00:00:00.001' AND c <= '2009-10-09 00:00:00.00'; +EXPLAIN SELECT * FROM t1 WHERE a = 'TEST' AND + c >= '2009-10-09 00:00:00.001' AND c <= '2009-10-09 00:00:00.00'; +DROP TABLE t1; + +--echo # +--echo # Bug #46175: NULL read_view and consistent read assertion +--echo # + +CREATE TABLE t1(a CHAR(13),KEY(a)) ENGINE=innodb; +CREATE TABLE t2(b DATETIME,KEY(b)) ENGINE=innodb; +INSERT INTO t1 VALUES (),(); +INSERT INTO t2 VALUES (),(); +CREATE OR REPLACE VIEW v1 AS SELECT 1 FROM t2 + WHERE b =(SELECT a FROM t1 LIMIT 1); + +--disable_query_log +--disable_result_log +CONNECT (con1, localhost, root,,); +--enable_query_log +--enable_result_log +CONNECTION default; + +DELIMITER |; +CREATE PROCEDURE p1(num INT) +BEGIN + DECLARE i INT DEFAULT 0; + REPEAT + SHOW CREATE VIEW v1; + SET i:=i+1; + UNTIL i>num END REPEAT; +END| +DELIMITER ;| + +--echo # Should not crash +--disable_query_log +--disable_result_log +--send CALL p1(1000) +CONNECTION con1; +--echo # Should not crash +CALL p1(1000); + +CONNECTION default; +--reap +--enable_query_log +--enable_result_log + +DISCONNECT con1; +DROP PROCEDURE p1; +DROP VIEW v1; +DROP TABLE t1,t2; + + +--echo # +--echo # Bug #49324: more valgrind errors in test_if_skip_sort_order +--echo # +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb ; +--echo #should not cause valgrind warnings +SELECT 1 FROM t1 JOIN t1 a USING(a) GROUP BY t1.a,t1.a; +DROP TABLE t1; + +--echo # +--echo # Bug#50843: Filesort used instead of clustered index led to +--echo # performance degradation. +--echo # +create table t1(f1 int not null primary key, f2 int) engine=innodb; +create table t2(f1 int not null, key (f1)) engine=innodb; +insert into t1 values (1,1),(2,2),(3,3); +insert into t2 values (1),(2),(3); +explain select t1.* from t1 left join t2 using(f1) group by t1.f1; +drop table t1,t2; +--echo # + + +--echo # +--echo # Bug #39653: find_shortest_key in sql_select.cc does not consider +--echo # clustered primary keys +--echo # + +CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c INT, d INT, e INT, f INT, + KEY (b,c)) ENGINE=INNODB; + +INSERT INTO t1 VALUES (1,1,1,1,1,1), (2,2,2,2,2,2), (3,3,3,3,3,3), + (4,4,4,4,4,4), (5,5,5,5,5,5), (6,6,6,6,6,6), + (7,7,7,7,7,7), (8,8,8,8,8,8), (9,9,9,9,9,9), + (11,11,11,11,11,11); + +--query_vertical EXPLAIN SELECT COUNT(*) FROM t1 + +DROP TABLE t1; + +--echo # +--echo # Bug #49838: DROP INDEX and ADD UNIQUE INDEX for same index may +--echo # corrupt definition at engine +--echo # + +CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, KEY k (a,b)) + ENGINE=InnoDB; + +ALTER TABLE t1 DROP INDEX k, ADD UNIQUE INDEX k (a,b); + +--query_vertical SHOW INDEXES FROM t1; + +DROP TABLE t1; + + +--echo # +--echo # Bug #47453: InnoDB incorrectly changes TIMESTAMP columns when +--echo # JOINed during an UPDATE +--echo # + +CREATE TABLE t1 (d INT) ENGINE=InnoDB; +CREATE TABLE t2 (a INT, b INT, + c TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP + ON UPDATE CURRENT_TIMESTAMP) ENGINE=InnoDB; + +--echo set up our data elements +INSERT INTO t1 (d) VALUES (1); +INSERT INTO t2 (a,b) VALUES (1,1); +SELECT SECOND(c) INTO @bug47453 FROM t2; + +SELECT SECOND(c)-@bug47453 FROM t1 JOIN t2 ON d=a; +UPDATE t1 JOIN t2 ON d=a SET b=1 WHERE a=1; +SELECT SECOND(c)-@bug47453 FROM t1 JOIN t2 ON d=a; + +SELECT SLEEP(1); + +UPDATE t1 JOIN t2 ON d=a SET b=1 WHERE a=1; + +--echo #should be 0 +SELECT SECOND(c)-@bug47453 FROM t1 JOIN t2 ON d=a; + +DROP TABLE t1, t2; + + +--echo End of 5.1 tests diff --git a/mysql-test/suite/innodb_plugin/t/innodb_mysql_rbk-master.opt b/mysql-test/suite/innodb_plugin/t/innodb_mysql_rbk-master.opt new file mode 100644 index 00000000000..0e400f9c36b --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_mysql_rbk-master.opt @@ -0,0 +1 @@ +--innodb_lock_wait_timeout=1 --innodb_rollback_on_timeout=1 diff --git a/mysql-test/suite/innodb_plugin/t/innodb_mysql_rbk.test b/mysql-test/suite/innodb_plugin/t/innodb_mysql_rbk.test new file mode 100644 index 00000000000..d8d56adc448 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_mysql_rbk.test @@ -0,0 +1,35 @@ +-- source include/have_innodb_plugin.inc + +# +# Bug #41453: Assertion `m_status == DA_ERROR' failed in +# Diagnostics_area::sql_errno +# + +CREATE TABLE t1(a INT, b INT NOT NULL, PRIMARY KEY (a)) ENGINE=innodb +DEFAULT CHARSET=latin1; +INSERT INTO t1 VALUES (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7); +CONNECT (con1,localhost,root,,); +CONNECT (con2,localhost,root,,); + +CONNECTION con1; +START TRANSACTION; +SELECT * FROM t1 WHERE b=3 LIMIT 1 FOR UPDATE; +CONNECTION con2; +START TRANSACTION; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t1 SET b=b+12 WHERE a > 2 ORDER BY a; +ROLLBACK; + +CONNECTION con1; +START TRANSACTION; +SELECT * FROM t1 WHERE b=3 LIMIT 1 FOR UPDATE; +CONNECTION con2; +START TRANSACTION; +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t1 SET b=10 WHERE a > 1 ORDER BY a; +SELECT * FROM t1 WHERE b = 10; + +CONNECTION default; +DISCONNECT con1; +DISCONNECT con2; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_plugin/t/innodb_notembedded.test b/mysql-test/suite/innodb_plugin/t/innodb_notembedded.test new file mode 100644 index 00000000000..2afe9079ba8 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_notembedded.test @@ -0,0 +1,50 @@ +-- source include/not_embedded.inc +-- source include/have_innodb_plugin.inc + +--disable_warnings +drop table if exists t1; +--enable_warnings + +SET @old_log_bin_trust_function_creators= @@global.log_bin_trust_function_creators; + +connect (a,localhost,root,,); +connect (b,localhost,root,,); + + +# +# BUG#11238 - in prelocking mode SELECT .. FOR UPDATE is changed to +# non-blocking SELECT +# +SET GLOBAL log_bin_trust_function_creators = 1; +create table t1 (col1 integer primary key, col2 integer) engine=innodb; +insert t1 values (1,100); +delimiter |; +create function f1 () returns integer begin +declare var1 int; +select col2 into var1 from t1 where col1=1 for update; +return var1; +end| +delimiter ;| +start transaction; +select f1(); +connection b; +send update t1 set col2=0 where col1=1; +connection default; +select * from t1; +connection a; +rollback; +connection b; +reap; +rollback; + +# Cleanup +connection a; +disconnect a; +--source include/wait_until_disconnected.inc +connection b; +disconnect b; +--source include/wait_until_disconnected.inc +connection default; +drop table t1; +drop function f1; +SET @@global.log_bin_trust_function_creators= @old_log_bin_trust_function_creators; diff --git a/mysql-test/suite/innodb_plugin/t/innodb_timeout_rollback-master.opt b/mysql-test/suite/innodb_plugin/t/innodb_timeout_rollback-master.opt new file mode 100644 index 00000000000..50921bb4df0 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_timeout_rollback-master.opt @@ -0,0 +1 @@ +--innodb_lock_wait_timeout=2 --innodb_rollback_on_timeout diff --git a/mysql-test/suite/innodb_plugin/t/innodb_timeout_rollback.test b/mysql-test/suite/innodb_plugin/t/innodb_timeout_rollback.test new file mode 100644 index 00000000000..cc7ab9ee0bd --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_timeout_rollback.test @@ -0,0 +1,5 @@ +-- source include/have_innodb_plugin.inc + +--source include/innodb_rollback_on_timeout.inc + +--echo End of 5.0 tests From 60845867e331284d8ef11a2642a3c7c1c8efcd95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 3 Jun 2010 12:50:32 +0300 Subject: [PATCH 015/112] Move some InnoDB tests to mysql-test/suite/innodb. --- mysql-test/{ => suite/innodb}/r/innodb-autoinc-optimize.result | 0 mysql-test/{ => suite/innodb}/r/innodb-ucs2.result | 0 .../{ => suite/innodb}/r/innodb_autoinc_lock_mode_zero.result | 0 mysql-test/{ => suite/innodb}/r/innodb_bug30919.result | 0 mysql-test/{ => suite/innodb}/r/innodb_bug42419.result | 0 mysql-test/{ => suite/innodb}/r/innodb_gis.result | 0 mysql-test/{ => suite/innodb}/r/innodb_lock_wait_timeout_1.result | 0 mysql-test/{ => suite/innodb}/r/innodb_mysql.result | 0 mysql-test/{ => suite/innodb}/r/innodb_mysql_rbk.result | 0 mysql-test/{ => suite/innodb}/r/innodb_notembedded.result | 0 mysql-test/{ => suite/innodb}/r/innodb_timeout_rollback.result | 0 mysql-test/{ => suite/innodb}/t/innodb-autoinc-optimize.test | 0 mysql-test/{ => suite/innodb}/t/innodb-ucs2.test | 0 .../{ => suite/innodb}/t/innodb_autoinc_lock_mode_zero-master.opt | 0 .../{ => suite/innodb}/t/innodb_autoinc_lock_mode_zero.test | 0 mysql-test/{ => suite/innodb}/t/innodb_bug30919-master.opt | 0 mysql-test/{ => suite/innodb}/t/innodb_bug30919.test | 0 mysql-test/{ => suite/innodb}/t/innodb_bug42419.test | 0 mysql-test/{ => suite/innodb}/t/innodb_gis.test | 0 .../{ => suite/innodb}/t/innodb_lock_wait_timeout_1-master.opt | 0 mysql-test/{ => suite/innodb}/t/innodb_lock_wait_timeout_1.test | 0 mysql-test/{ => suite/innodb}/t/innodb_mysql-master.opt | 0 mysql-test/{ => suite/innodb}/t/innodb_mysql.test | 0 mysql-test/{ => suite/innodb}/t/innodb_mysql_rbk-master.opt | 0 mysql-test/{ => suite/innodb}/t/innodb_mysql_rbk.test | 0 mysql-test/{ => suite/innodb}/t/innodb_notembedded.test | 0 .../{ => suite/innodb}/t/innodb_timeout_rollback-master.opt | 0 mysql-test/{ => suite/innodb}/t/innodb_timeout_rollback.test | 0 28 files changed, 0 insertions(+), 0 deletions(-) rename mysql-test/{ => suite/innodb}/r/innodb-autoinc-optimize.result (100%) rename mysql-test/{ => suite/innodb}/r/innodb-ucs2.result (100%) rename mysql-test/{ => suite/innodb}/r/innodb_autoinc_lock_mode_zero.result (100%) rename mysql-test/{ => suite/innodb}/r/innodb_bug30919.result (100%) rename mysql-test/{ => suite/innodb}/r/innodb_bug42419.result (100%) rename mysql-test/{ => suite/innodb}/r/innodb_gis.result (100%) rename mysql-test/{ => suite/innodb}/r/innodb_lock_wait_timeout_1.result (100%) rename mysql-test/{ => suite/innodb}/r/innodb_mysql.result (100%) rename mysql-test/{ => suite/innodb}/r/innodb_mysql_rbk.result (100%) rename mysql-test/{ => suite/innodb}/r/innodb_notembedded.result (100%) rename mysql-test/{ => suite/innodb}/r/innodb_timeout_rollback.result (100%) rename mysql-test/{ => suite/innodb}/t/innodb-autoinc-optimize.test (100%) rename mysql-test/{ => suite/innodb}/t/innodb-ucs2.test (100%) rename mysql-test/{ => suite/innodb}/t/innodb_autoinc_lock_mode_zero-master.opt (100%) rename mysql-test/{ => suite/innodb}/t/innodb_autoinc_lock_mode_zero.test (100%) rename mysql-test/{ => suite/innodb}/t/innodb_bug30919-master.opt (100%) rename mysql-test/{ => suite/innodb}/t/innodb_bug30919.test (100%) rename mysql-test/{ => suite/innodb}/t/innodb_bug42419.test (100%) rename mysql-test/{ => suite/innodb}/t/innodb_gis.test (100%) rename mysql-test/{ => suite/innodb}/t/innodb_lock_wait_timeout_1-master.opt (100%) rename mysql-test/{ => suite/innodb}/t/innodb_lock_wait_timeout_1.test (100%) rename mysql-test/{ => suite/innodb}/t/innodb_mysql-master.opt (100%) rename mysql-test/{ => suite/innodb}/t/innodb_mysql.test (100%) rename mysql-test/{ => suite/innodb}/t/innodb_mysql_rbk-master.opt (100%) rename mysql-test/{ => suite/innodb}/t/innodb_mysql_rbk.test (100%) rename mysql-test/{ => suite/innodb}/t/innodb_notembedded.test (100%) rename mysql-test/{ => suite/innodb}/t/innodb_timeout_rollback-master.opt (100%) rename mysql-test/{ => suite/innodb}/t/innodb_timeout_rollback.test (100%) diff --git a/mysql-test/r/innodb-autoinc-optimize.result b/mysql-test/suite/innodb/r/innodb-autoinc-optimize.result similarity index 100% rename from mysql-test/r/innodb-autoinc-optimize.result rename to mysql-test/suite/innodb/r/innodb-autoinc-optimize.result diff --git a/mysql-test/r/innodb-ucs2.result b/mysql-test/suite/innodb/r/innodb-ucs2.result similarity index 100% rename from mysql-test/r/innodb-ucs2.result rename to mysql-test/suite/innodb/r/innodb-ucs2.result diff --git a/mysql-test/r/innodb_autoinc_lock_mode_zero.result b/mysql-test/suite/innodb/r/innodb_autoinc_lock_mode_zero.result similarity index 100% rename from mysql-test/r/innodb_autoinc_lock_mode_zero.result rename to mysql-test/suite/innodb/r/innodb_autoinc_lock_mode_zero.result diff --git a/mysql-test/r/innodb_bug30919.result b/mysql-test/suite/innodb/r/innodb_bug30919.result similarity index 100% rename from mysql-test/r/innodb_bug30919.result rename to mysql-test/suite/innodb/r/innodb_bug30919.result diff --git a/mysql-test/r/innodb_bug42419.result b/mysql-test/suite/innodb/r/innodb_bug42419.result similarity index 100% rename from mysql-test/r/innodb_bug42419.result rename to mysql-test/suite/innodb/r/innodb_bug42419.result diff --git a/mysql-test/r/innodb_gis.result b/mysql-test/suite/innodb/r/innodb_gis.result similarity index 100% rename from mysql-test/r/innodb_gis.result rename to mysql-test/suite/innodb/r/innodb_gis.result diff --git a/mysql-test/r/innodb_lock_wait_timeout_1.result b/mysql-test/suite/innodb/r/innodb_lock_wait_timeout_1.result similarity index 100% rename from mysql-test/r/innodb_lock_wait_timeout_1.result rename to mysql-test/suite/innodb/r/innodb_lock_wait_timeout_1.result diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result similarity index 100% rename from mysql-test/r/innodb_mysql.result rename to mysql-test/suite/innodb/r/innodb_mysql.result diff --git a/mysql-test/r/innodb_mysql_rbk.result b/mysql-test/suite/innodb/r/innodb_mysql_rbk.result similarity index 100% rename from mysql-test/r/innodb_mysql_rbk.result rename to mysql-test/suite/innodb/r/innodb_mysql_rbk.result diff --git a/mysql-test/r/innodb_notembedded.result b/mysql-test/suite/innodb/r/innodb_notembedded.result similarity index 100% rename from mysql-test/r/innodb_notembedded.result rename to mysql-test/suite/innodb/r/innodb_notembedded.result diff --git a/mysql-test/r/innodb_timeout_rollback.result b/mysql-test/suite/innodb/r/innodb_timeout_rollback.result similarity index 100% rename from mysql-test/r/innodb_timeout_rollback.result rename to mysql-test/suite/innodb/r/innodb_timeout_rollback.result diff --git a/mysql-test/t/innodb-autoinc-optimize.test b/mysql-test/suite/innodb/t/innodb-autoinc-optimize.test similarity index 100% rename from mysql-test/t/innodb-autoinc-optimize.test rename to mysql-test/suite/innodb/t/innodb-autoinc-optimize.test diff --git a/mysql-test/t/innodb-ucs2.test b/mysql-test/suite/innodb/t/innodb-ucs2.test similarity index 100% rename from mysql-test/t/innodb-ucs2.test rename to mysql-test/suite/innodb/t/innodb-ucs2.test diff --git a/mysql-test/t/innodb_autoinc_lock_mode_zero-master.opt b/mysql-test/suite/innodb/t/innodb_autoinc_lock_mode_zero-master.opt similarity index 100% rename from mysql-test/t/innodb_autoinc_lock_mode_zero-master.opt rename to mysql-test/suite/innodb/t/innodb_autoinc_lock_mode_zero-master.opt diff --git a/mysql-test/t/innodb_autoinc_lock_mode_zero.test b/mysql-test/suite/innodb/t/innodb_autoinc_lock_mode_zero.test similarity index 100% rename from mysql-test/t/innodb_autoinc_lock_mode_zero.test rename to mysql-test/suite/innodb/t/innodb_autoinc_lock_mode_zero.test diff --git a/mysql-test/t/innodb_bug30919-master.opt b/mysql-test/suite/innodb/t/innodb_bug30919-master.opt similarity index 100% rename from mysql-test/t/innodb_bug30919-master.opt rename to mysql-test/suite/innodb/t/innodb_bug30919-master.opt diff --git a/mysql-test/t/innodb_bug30919.test b/mysql-test/suite/innodb/t/innodb_bug30919.test similarity index 100% rename from mysql-test/t/innodb_bug30919.test rename to mysql-test/suite/innodb/t/innodb_bug30919.test diff --git a/mysql-test/t/innodb_bug42419.test b/mysql-test/suite/innodb/t/innodb_bug42419.test similarity index 100% rename from mysql-test/t/innodb_bug42419.test rename to mysql-test/suite/innodb/t/innodb_bug42419.test diff --git a/mysql-test/t/innodb_gis.test b/mysql-test/suite/innodb/t/innodb_gis.test similarity index 100% rename from mysql-test/t/innodb_gis.test rename to mysql-test/suite/innodb/t/innodb_gis.test diff --git a/mysql-test/t/innodb_lock_wait_timeout_1-master.opt b/mysql-test/suite/innodb/t/innodb_lock_wait_timeout_1-master.opt similarity index 100% rename from mysql-test/t/innodb_lock_wait_timeout_1-master.opt rename to mysql-test/suite/innodb/t/innodb_lock_wait_timeout_1-master.opt diff --git a/mysql-test/t/innodb_lock_wait_timeout_1.test b/mysql-test/suite/innodb/t/innodb_lock_wait_timeout_1.test similarity index 100% rename from mysql-test/t/innodb_lock_wait_timeout_1.test rename to mysql-test/suite/innodb/t/innodb_lock_wait_timeout_1.test diff --git a/mysql-test/t/innodb_mysql-master.opt b/mysql-test/suite/innodb/t/innodb_mysql-master.opt similarity index 100% rename from mysql-test/t/innodb_mysql-master.opt rename to mysql-test/suite/innodb/t/innodb_mysql-master.opt diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/suite/innodb/t/innodb_mysql.test similarity index 100% rename from mysql-test/t/innodb_mysql.test rename to mysql-test/suite/innodb/t/innodb_mysql.test diff --git a/mysql-test/t/innodb_mysql_rbk-master.opt b/mysql-test/suite/innodb/t/innodb_mysql_rbk-master.opt similarity index 100% rename from mysql-test/t/innodb_mysql_rbk-master.opt rename to mysql-test/suite/innodb/t/innodb_mysql_rbk-master.opt diff --git a/mysql-test/t/innodb_mysql_rbk.test b/mysql-test/suite/innodb/t/innodb_mysql_rbk.test similarity index 100% rename from mysql-test/t/innodb_mysql_rbk.test rename to mysql-test/suite/innodb/t/innodb_mysql_rbk.test diff --git a/mysql-test/t/innodb_notembedded.test b/mysql-test/suite/innodb/t/innodb_notembedded.test similarity index 100% rename from mysql-test/t/innodb_notembedded.test rename to mysql-test/suite/innodb/t/innodb_notembedded.test diff --git a/mysql-test/t/innodb_timeout_rollback-master.opt b/mysql-test/suite/innodb/t/innodb_timeout_rollback-master.opt similarity index 100% rename from mysql-test/t/innodb_timeout_rollback-master.opt rename to mysql-test/suite/innodb/t/innodb_timeout_rollback-master.opt diff --git a/mysql-test/t/innodb_timeout_rollback.test b/mysql-test/suite/innodb/t/innodb_timeout_rollback.test similarity index 100% rename from mysql-test/t/innodb_timeout_rollback.test rename to mysql-test/suite/innodb/t/innodb_timeout_rollback.test From d80f8c07d648ffa5099554da354f43add058d8e4 Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Thu, 3 Jun 2010 06:44:48 -0700 Subject: [PATCH 016/112] Remove unncessary name comapre in innobase_get_mysql_key_number_for_index() introduced in bug fix #53592, since dict_table_t can sufficiently unique identify the the table. --- storage/innodb_plugin/handler/ha_innodb.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index c65ba3163fc..34249b7718a 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -7420,8 +7420,7 @@ innobase_get_mysql_key_number_for_index( /* If index does not belong to the table of share structure. Search index->table instead */ - if (index->table != ib_table - && strcmp(index->table->name, share->table_name)) { + if (index->table != ib_table) { i = 0; ind = dict_table_get_first_index(index->table); From 5bc84421f2ae5339914f4563f156877f8d50ca31 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Jun 2010 16:03:17 +0200 Subject: [PATCH 017/112] Raise version number after cloning 5.1.48 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index a2a3a6196fc..27b6617f6bc 100644 --- a/configure.in +++ b/configure.in @@ -12,7 +12,7 @@ dnl dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MySQL Server], [5.1.48], [], [mysql]) +AC_INIT([MySQL Server], [5.1.49], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM From 55acf60c93d61b0382093b4d0ad6f8a1e9cbe57a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 8 Jun 2010 14:40:55 +0300 Subject: [PATCH 018/112] buf_page_get_gen(): Pass file,line to rw_lock_x_lock(). --- storage/innodb_plugin/buf/buf0buf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0buf.c index bc5e9814099..660686bac1e 100644 --- a/storage/innodb_plugin/buf/buf0buf.c +++ b/storage/innodb_plugin/buf/buf0buf.c @@ -2236,7 +2236,7 @@ wait_until_unfixed: block->page.buf_fix_count = 1; buf_block_set_io_fix(block, BUF_IO_READ); - rw_lock_x_lock(&block->lock); + rw_lock_x_lock_func(&block->lock, 0, file, line); UNIV_MEM_INVALID(bpage, sizeof *bpage); From 627c14d9e886d0bbef425d4f483cd697c6710bbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 8 Jun 2010 15:10:41 +0300 Subject: [PATCH 019/112] Bug#54009: Server crashes when data is selected from non backed up table for InnoDB plugin dict_load_table(): Pass the correct tablespace flags to fil_open_single_table_tablespace(). For ROW_FORMAT=COMPACT and REDUNDANT, the tablespace flags are 0. The table flags would be 0 or DICT_TF_COMPACT. --- storage/innodb_plugin/dict/dict0load.c | 1 + 1 file changed, 1 insertion(+) diff --git a/storage/innodb_plugin/dict/dict0load.c b/storage/innodb_plugin/dict/dict0load.c index 377818308c5..f86aa0848bd 100644 --- a/storage/innodb_plugin/dict/dict0load.c +++ b/storage/innodb_plugin/dict/dict0load.c @@ -973,6 +973,7 @@ err_exit: /* Try to open the tablespace */ if (!fil_open_single_table_tablespace( TRUE, space, + flags == DICT_TF_COMPACT ? 0 : flags & ~(~0 << DICT_TF_BITS), name)) { /* We failed to find a sensible tablespace file */ From 76a7cda35c2058c90fed090c4d577b0c49f3203f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 8 Jun 2010 15:12:15 +0300 Subject: [PATCH 020/112] Document Bug#54009 in the InnoDB Plugin ChangeLog. --- storage/innodb_plugin/ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 20775b41ca8..fb577a04221 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,9 @@ +2010-06-08 The InnoDB Team + + * dict/dict0load.c: + Fix Bug#54009 Server crashes when data is selected from non backed + up table for InnoDB plugin + 2010-06-02 The InnoDB Team * include/db0err.h, include/lock0lock.h, include/row0mysql.h, From 28187edf33629cd72b3f8fafbc3421b3aaa0e4d7 Mon Sep 17 00:00:00 2001 From: Inaam Rana Date: Tue, 8 Jun 2010 14:14:08 -0400 Subject: [PATCH 021/112] Add call to log_free_check() in the DML code paths that were missing this before. --- storage/innodb_plugin/row/row0ins.c | 9 +++++++++ storage/innodb_plugin/row/row0purge.c | 11 +++++++++++ storage/innodb_plugin/row/row0uins.c | 13 ++++++++++++- storage/innodb_plugin/row/row0umod.c | 14 +++++++++++++- storage/innodb_plugin/row/row0upd.c | 16 ++++++++++++++-- 5 files changed, 59 insertions(+), 4 deletions(-) diff --git a/storage/innodb_plugin/row/row0ins.c b/storage/innodb_plugin/row/row0ins.c index 09d2ffc7431..b70e77c7b7a 100644 --- a/storage/innodb_plugin/row/row0ins.c +++ b/storage/innodb_plugin/row/row0ins.c @@ -51,6 +51,15 @@ Created 4/20/1996 Heikki Tuuri #define ROW_INS_PREV 1 #define ROW_INS_NEXT 2 +/*********************************************************************//** +IMPORTANT NOTE: Any operation that generates redo MUST check that there +is enough space in the redo log before for that operation. This is +done by calling log_free_check(). The reason for checking the +availability of the redo log space before the start of the operation is +that we MUST not hold any synchonization objects when performing the +check. +If you make a change in this module make sure that no codepath is +introduced where a call to log_free_check() is bypassed. */ /*********************************************************************//** Creates an insert node struct. diff --git a/storage/innodb_plugin/row/row0purge.c b/storage/innodb_plugin/row/row0purge.c index 500ebe571ab..0b470f12fc6 100644 --- a/storage/innodb_plugin/row/row0purge.c +++ b/storage/innodb_plugin/row/row0purge.c @@ -44,6 +44,16 @@ Created 3/14/1997 Heikki Tuuri #include "row0mysql.h" #include "log0log.h" +/*********************************************************************//** +IMPORTANT NOTE: Any operation that generates redo MUST check that there +is enough space in the redo log before for that operation. This is +done by calling log_free_check(). The reason for checking the +availability of the redo log space before the start of the operation is +that we MUST not hold any synchonization objects when performing the +check. +If you make a change in this module make sure that no codepath is +introduced where a call to log_free_check() is bypassed. */ + /********************************************************************//** Creates a purge node to a query graph. @return own: purge node */ @@ -126,6 +136,7 @@ row_purge_remove_clust_if_poss_low( pcur = &(node->pcur); btr_cur = btr_pcur_get_btr_cur(pcur); + log_free_check(); mtr_start(&mtr); success = row_purge_reposition_pcur(mode, node, &mtr); diff --git a/storage/innodb_plugin/row/row0uins.c b/storage/innodb_plugin/row/row0uins.c index 9f9c814f1a5..2c5da6a81ca 100644 --- a/storage/innodb_plugin/row/row0uins.c +++ b/storage/innodb_plugin/row/row0uins.c @@ -46,6 +46,16 @@ Created 2/25/1997 Heikki Tuuri #include "ibuf0ibuf.h" #include "log0log.h" +/*********************************************************************//** +IMPORTANT NOTE: Any operation that generates redo MUST check that there +is enough space in the redo log before for that operation. This is +done by calling log_free_check(). The reason for checking the +availability of the redo log space before the start of the operation is +that we MUST not hold any synchonization objects when performing the +check. +If you make a change in this module make sure that no codepath is +introduced where a call to log_free_check() is bypassed. */ + /***************************************************************//** Removes a clustered index record. The pcur in node was positioned on the record, now it is detached. @@ -152,7 +162,6 @@ row_undo_ins_remove_sec_low( ulint err; mtr_t mtr; - log_free_check(); mtr_start(&mtr); found = row_search_index_entry(index, entry, mode, &pcur, &mtr); @@ -335,6 +344,7 @@ row_undo_ins( transactions. */ ut_a(trx_is_recv(node->trx)); } else { + log_free_check(); err = row_undo_ins_remove_sec(node->index, entry); if (err != DB_SUCCESS) { @@ -346,5 +356,6 @@ row_undo_ins( node->index = dict_table_get_next_index(node->index); } + log_free_check(); return(row_undo_ins_remove_clust_rec(node)); } diff --git a/storage/innodb_plugin/row/row0umod.c b/storage/innodb_plugin/row/row0umod.c index c497c469aae..fd10b718b4f 100644 --- a/storage/innodb_plugin/row/row0umod.c +++ b/storage/innodb_plugin/row/row0umod.c @@ -58,12 +58,22 @@ delete marked clustered index record was delete unmarked and possibly also some of its fields were changed. Now, it is possible that the delete marked version has become obsolete at the time the undo is started. */ +/*********************************************************************//** +IMPORTANT NOTE: Any operation that generates redo MUST check that there +is enough space in the redo log before for that operation. This is +done by calling log_free_check(). The reason for checking the +availability of the redo log space before the start of the operation is +that we MUST not hold any synchonization objects when performing the +check. +If you make a change in this module make sure that no codepath is +introduced where a call to log_free_check() is bypassed. */ + /***********************************************************//** Checks if also the previous version of the clustered index record was modified or inserted by the same transaction, and its undo number is such that it should be undone in the same rollback. @return TRUE if also previous modify or insert of this row should be undone */ -UNIV_INLINE +static ibool row_undo_mod_undo_also_prev_vers( /*=============================*/ @@ -231,6 +241,8 @@ row_undo_mod_clust( ut_ad(node && thr); + log_free_check(); + /* Check if also the previous version of the clustered index record should be undone in this same rollback operation */ diff --git a/storage/innodb_plugin/row/row0upd.c b/storage/innodb_plugin/row/row0upd.c index 95d1d00aeef..efc27a3cacd 100644 --- a/storage/innodb_plugin/row/row0upd.c +++ b/storage/innodb_plugin/row/row0upd.c @@ -92,6 +92,16 @@ the x-latch freed? The most efficient way for performing a searched delete is obviously to keep the x-latch for several steps of query graph execution. */ +/*********************************************************************//** +IMPORTANT NOTE: Any operation that generates redo MUST check that there +is enough space in the redo log before for that operation. This is +done by calling log_free_check(). The reason for checking the +availability of the redo log space before the start of the operation is +that we MUST not hold any synchonization objects when performing the +check. +If you make a change in this module make sure that no codepath is +introduced where a call to log_free_check() is bypassed. */ + /***********************************************************//** Checks if an update vector changes some of the first ordering fields of an index record. This is only used in foreign key checks and we can assume @@ -1453,7 +1463,6 @@ row_upd_sec_index_entry( entry = row_build_index_entry(node->row, node->ext, index, heap); ut_a(entry); - log_free_check(); mtr_start(&mtr); found = row_search_index_entry(index, entry, BTR_MODIFY_LEAF, &pcur, @@ -1529,7 +1538,7 @@ Updates the secondary index record if it is changed in the row update or deletes it if this is a delete. @return DB_SUCCESS if operation successfully completed, else error code or DB_LOCK_WAIT */ -UNIV_INLINE +static ulint row_upd_sec_step( /*=============*/ @@ -2015,6 +2024,7 @@ row_upd( if (node->state == UPD_NODE_UPDATE_CLUSTERED || node->state == UPD_NODE_INSERT_CLUSTERED) { + log_free_check(); err = row_upd_clust_step(node, thr); if (err != DB_SUCCESS) { @@ -2029,6 +2039,8 @@ row_upd( } while (node->index != NULL) { + + log_free_check(); err = row_upd_sec_step(node, thr); if (err != DB_SUCCESS) { From 60a66c451a863986d36dde676ce99eca3edc55f3 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Wed, 9 Jun 2010 16:07:34 +0400 Subject: [PATCH 022/112] Bug#38999 valgrind warnings for update statement in function compare_record() Valgrind warning happpens because of uninitialized null bytes. In row_sel_push_cache_row_for_mysql() function we fill fetch cache with necessary field values, row_sel_store_mysql_rec() is called for this and leaves null bytes untouched. Later row_sel_pop_cached_row_for_mysql() rewrites table record buffer with uninited null bytes. We can see the problem from the test case: At 'SELECT...' we call row_sel_push...->row_sel_store...->row_sel_pop_cached... chain which rewrites table->record[0] buffer with uninitialized null bytes. When we call 'UPDATE...' statement, compare_record uses this buffer and valgrind warning occurs. The fix is to init null bytes with default values. mysql-test/suite/innodb/r/innodb_mysql.result: test case mysql-test/suite/innodb/t/innodb_mysql.test: test case mysql-test/t/ps_3innodb.test: enable valgrind testing storage/innobase/row/row0sel.c: init null bytes with default values as they might be left uninitialized in some cases and these uninited bytes might be copied into mysql record buffer that leads to valgrind warnings on next use of the buffer. --- mysql-test/suite/innodb/r/innodb_mysql.result | 12 ++++++++++++ mysql-test/suite/innodb/t/innodb_mysql.test | 13 +++++++++++++ mysql-test/t/ps_3innodb.test | 4 ---- storage/innobase/row/row0sel.c | 6 ++++++ 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index 2bf1ef8fbf0..b4ac88fc1c3 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -2378,4 +2378,16 @@ SELECT SECOND(c)-@bug47453 FROM t1 JOIN t2 ON d=a; SECOND(c)-@bug47453 0 DROP TABLE t1, t2; +# +# Bug#38999 valgrind warnings for update statement in function compare_record() +# +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 values (1),(2),(3),(4),(5); +INSERT INTO t2 values (1); +SELECT * FROM t1 WHERE a = 2; +a +2 +UPDATE t1,t2 SET t1.a = t1.a + 100 WHERE t1.a = 1; +DROP TABLE t1,t2; End of 5.1 tests diff --git a/mysql-test/suite/innodb/t/innodb_mysql.test b/mysql-test/suite/innodb/t/innodb_mysql.test index 9564d3b41fb..5a3a72c09bf 100644 --- a/mysql-test/suite/innodb/t/innodb_mysql.test +++ b/mysql-test/suite/innodb/t/innodb_mysql.test @@ -618,5 +618,18 @@ SELECT SECOND(c)-@bug47453 FROM t1 JOIN t2 ON d=a; DROP TABLE t1, t2; +--echo # +--echo # Bug#38999 valgrind warnings for update statement in function compare_record() +--echo # + +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 values (1),(2),(3),(4),(5); +INSERT INTO t2 values (1); + +SELECT * FROM t1 WHERE a = 2; +UPDATE t1,t2 SET t1.a = t1.a + 100 WHERE t1.a = 1; + +DROP TABLE t1,t2; --echo End of 5.1 tests diff --git a/mysql-test/t/ps_3innodb.test b/mysql-test/t/ps_3innodb.test index 10d2e7a9ae5..e25a8b1f469 100644 --- a/mysql-test/t/ps_3innodb.test +++ b/mysql-test/t/ps_3innodb.test @@ -8,10 +8,6 @@ # NOTE: PLEASE SEE ps_1general.test (bottom) # BEFORE ADDING NEW TEST CASES HERE !!! -# See Bug#38999 valgrind warnings for update statement in function -# compare_record() --- source include/not_valgrind.inc - use test; -- source include/have_innodb.inc diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c index fcc95aec9af..06a19ba7979 100644 --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c @@ -2621,6 +2621,12 @@ row_sel_store_mysql_rec( prebuilt->blob_heap = NULL; } + /* init null bytes with default values as they might be + left uninitialized in some cases and this uninited bytes + might be copied into mysql record buffer that leads to + valgrind warnings */ + memcpy(mysql_rec, prebuilt->default_rec, prebuilt->null_bitmap_len); + for (i = 0; i < prebuilt->n_template; i++) { templ = prebuilt->mysql_template + i; From 022e2ef800a333cb37eb783f83c480770587f57b Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Wed, 9 Jun 2010 16:17:18 +0400 Subject: [PATCH 023/112] Bug#38999 valgrind warnings for update statement in function compare_record() (InnoDB plugin branch) mysql-test/suite/innodb_plugin/r/innodb_mysql.result: test case mysql-test/suite/innodb_plugin/t/innodb_mysql.test: test case storage/innodb_plugin/row/row0sel.c: init null bytes with default values as they might be left uninitialized in some cases and these uninited bytes might be copied into mysql record buffer that leads to valgrind warnings on next use of the buffer. --- .../suite/innodb_plugin/r/innodb_mysql.result | 12 ++++++++++++ mysql-test/suite/innodb_plugin/t/innodb_mysql.test | 13 +++++++++++++ storage/innodb_plugin/row/row0sel.c | 6 ++++++ 3 files changed, 31 insertions(+) diff --git a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result index 2bf1ef8fbf0..b4ac88fc1c3 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result +++ b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result @@ -2378,4 +2378,16 @@ SELECT SECOND(c)-@bug47453 FROM t1 JOIN t2 ON d=a; SECOND(c)-@bug47453 0 DROP TABLE t1, t2; +# +# Bug#38999 valgrind warnings for update statement in function compare_record() +# +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 values (1),(2),(3),(4),(5); +INSERT INTO t2 values (1); +SELECT * FROM t1 WHERE a = 2; +a +2 +UPDATE t1,t2 SET t1.a = t1.a + 100 WHERE t1.a = 1; +DROP TABLE t1,t2; End of 5.1 tests diff --git a/mysql-test/suite/innodb_plugin/t/innodb_mysql.test b/mysql-test/suite/innodb_plugin/t/innodb_mysql.test index c80db7088ab..3f6d9d96bb8 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb_mysql.test +++ b/mysql-test/suite/innodb_plugin/t/innodb_mysql.test @@ -618,5 +618,18 @@ SELECT SECOND(c)-@bug47453 FROM t1 JOIN t2 ON d=a; DROP TABLE t1, t2; +--echo # +--echo # Bug#38999 valgrind warnings for update statement in function compare_record() +--echo # + +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 values (1),(2),(3),(4),(5); +INSERT INTO t2 values (1); + +SELECT * FROM t1 WHERE a = 2; +UPDATE t1,t2 SET t1.a = t1.a + 100 WHERE t1.a = 1; + +DROP TABLE t1,t2; --echo End of 5.1 tests diff --git a/storage/innodb_plugin/row/row0sel.c b/storage/innodb_plugin/row/row0sel.c index a5bf361661b..2861235a995 100644 --- a/storage/innodb_plugin/row/row0sel.c +++ b/storage/innodb_plugin/row/row0sel.c @@ -2678,6 +2678,12 @@ row_sel_store_mysql_rec( prebuilt->blob_heap = NULL; } + /* init null bytes with default values as they might be + left uninitialized in some cases and these uninited bytes + might be copied into mysql record buffer that leads to + valgrind warnings */ + memcpy(mysql_rec, prebuilt->default_rec, prebuilt->null_bitmap_len); + for (i = 0; i < prebuilt->n_template; i++) { templ = prebuilt->mysql_template + i; From 50d0cd72485ad3c069a7fbb07473fc08b28301c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 10 Jun 2010 15:56:23 +0300 Subject: [PATCH 024/112] Bug #38999: Re-enable innodb_multi_update.test --- mysql-test/suite/innodb/t/disabled.def | 1 - mysql-test/suite/innodb_plugin/t/disabled.def | 1 - 2 files changed, 2 deletions(-) diff --git a/mysql-test/suite/innodb/t/disabled.def b/mysql-test/suite/innodb/t/disabled.def index da04138fd0a..888298bbb09 100644 --- a/mysql-test/suite/innodb/t/disabled.def +++ b/mysql-test/suite/innodb/t/disabled.def @@ -9,4 +9,3 @@ # Do not use any TAB characters for whitespace. # ############################################################################## -innodb_multi_update: Bug #38999 2010-05-05 mmakela Valgrind warnings diff --git a/mysql-test/suite/innodb_plugin/t/disabled.def b/mysql-test/suite/innodb_plugin/t/disabled.def index da04138fd0a..888298bbb09 100644 --- a/mysql-test/suite/innodb_plugin/t/disabled.def +++ b/mysql-test/suite/innodb_plugin/t/disabled.def @@ -9,4 +9,3 @@ # Do not use any TAB characters for whitespace. # ############################################################################## -innodb_multi_update: Bug #38999 2010-05-05 mmakela Valgrind warnings From e40c3b97630a0885a1a328d1133f21b65c69298c Mon Sep 17 00:00:00 2001 From: Inaam Rana Date: Thu, 10 Jun 2010 09:58:11 -0400 Subject: [PATCH 025/112] Formatting changes --- storage/innodb_plugin/row/row0ins.c | 2 +- storage/innodb_plugin/row/row0purge.c | 2 +- storage/innodb_plugin/row/row0uins.c | 2 +- storage/innodb_plugin/row/row0umod.c | 2 +- storage/innodb_plugin/row/row0upd.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/storage/innodb_plugin/row/row0ins.c b/storage/innodb_plugin/row/row0ins.c index b70e77c7b7a..a193bf21f7c 100644 --- a/storage/innodb_plugin/row/row0ins.c +++ b/storage/innodb_plugin/row/row0ins.c @@ -51,7 +51,7 @@ Created 4/20/1996 Heikki Tuuri #define ROW_INS_PREV 1 #define ROW_INS_NEXT 2 -/*********************************************************************//** +/************************************************************************* IMPORTANT NOTE: Any operation that generates redo MUST check that there is enough space in the redo log before for that operation. This is done by calling log_free_check(). The reason for checking the diff --git a/storage/innodb_plugin/row/row0purge.c b/storage/innodb_plugin/row/row0purge.c index 0b470f12fc6..835af990672 100644 --- a/storage/innodb_plugin/row/row0purge.c +++ b/storage/innodb_plugin/row/row0purge.c @@ -44,7 +44,7 @@ Created 3/14/1997 Heikki Tuuri #include "row0mysql.h" #include "log0log.h" -/*********************************************************************//** +/************************************************************************* IMPORTANT NOTE: Any operation that generates redo MUST check that there is enough space in the redo log before for that operation. This is done by calling log_free_check(). The reason for checking the diff --git a/storage/innodb_plugin/row/row0uins.c b/storage/innodb_plugin/row/row0uins.c index 2c5da6a81ca..930a5cf13b6 100644 --- a/storage/innodb_plugin/row/row0uins.c +++ b/storage/innodb_plugin/row/row0uins.c @@ -46,7 +46,7 @@ Created 2/25/1997 Heikki Tuuri #include "ibuf0ibuf.h" #include "log0log.h" -/*********************************************************************//** +/************************************************************************* IMPORTANT NOTE: Any operation that generates redo MUST check that there is enough space in the redo log before for that operation. This is done by calling log_free_check(). The reason for checking the diff --git a/storage/innodb_plugin/row/row0umod.c b/storage/innodb_plugin/row/row0umod.c index fd10b718b4f..8464b0f95cc 100644 --- a/storage/innodb_plugin/row/row0umod.c +++ b/storage/innodb_plugin/row/row0umod.c @@ -58,7 +58,7 @@ delete marked clustered index record was delete unmarked and possibly also some of its fields were changed. Now, it is possible that the delete marked version has become obsolete at the time the undo is started. */ -/*********************************************************************//** +/************************************************************************* IMPORTANT NOTE: Any operation that generates redo MUST check that there is enough space in the redo log before for that operation. This is done by calling log_free_check(). The reason for checking the diff --git a/storage/innodb_plugin/row/row0upd.c b/storage/innodb_plugin/row/row0upd.c index efc27a3cacd..d0aaecd3dae 100644 --- a/storage/innodb_plugin/row/row0upd.c +++ b/storage/innodb_plugin/row/row0upd.c @@ -92,7 +92,7 @@ the x-latch freed? The most efficient way for performing a searched delete is obviously to keep the x-latch for several steps of query graph execution. */ -/*********************************************************************//** +/************************************************************************* IMPORTANT NOTE: Any operation that generates redo MUST check that there is enough space in the redo log before for that operation. This is done by calling log_free_check(). The reason for checking the From e7c672cbd98a62ddeeed0bb3c9c5cb4192846fc3 Mon Sep 17 00:00:00 2001 From: Inaam Rana Date: Thu, 10 Jun 2010 10:31:28 -0400 Subject: [PATCH 026/112] Add a debug assertion. --- storage/innodb_plugin/include/log0log.ic | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/storage/innodb_plugin/include/log0log.ic b/storage/innodb_plugin/include/log0log.ic index 139f4041a36..1ce00fd7313 100644 --- a/storage/innodb_plugin/include/log0log.ic +++ b/storage/innodb_plugin/include/log0log.ic @@ -433,7 +433,10 @@ void log_free_check(void) /*================*/ { - /* ut_ad(sync_thread_levels_empty()); */ + +#ifdef UNIV_SYNC_DEBUG + ut_ad(sync_thread_levels_empty_gen(TRUE)); +#endif /* UNIV_SYNC_DEBUG */ if (log_sys->check_flush_or_checkpoint) { From 3170aa677de12d5b779165fb96b306fa840ab89d Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 14 Jun 2010 13:35:15 +0300 Subject: [PATCH 027/112] Adjust suite/innodb/r/innodb_mysql.result after the merge --- mysql-test/suite/innodb/r/innodb_mysql.result | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index 497a98c8121..92699cb4481 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -2379,3 +2379,54 @@ SECOND(c)-@bug47453 0 DROP TABLE t1, t2; # +# Bug#38999 valgrind warnings for update statement in function compare_record() +# +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 values (1),(2),(3),(4),(5); +INSERT INTO t2 values (1); +SELECT * FROM t1 WHERE a = 2; +a +2 +UPDATE t1,t2 SET t1.a = t1.a + 100 WHERE t1.a = 1; +DROP TABLE t1,t2; +# +# Bug #53334: wrong result for outer join with impossible ON condition +# (see the same test case for MyISAM in join.test) +# +CREATE TABLE t1 (id INT PRIMARY KEY); +CREATE TABLE t2 (id INT); +INSERT INTO t1 VALUES (75); +INSERT INTO t1 VALUES (79); +INSERT INTO t1 VALUES (78); +INSERT INTO t1 VALUES (77); +REPLACE INTO t1 VALUES (76); +REPLACE INTO t1 VALUES (76); +INSERT INTO t1 VALUES (104); +INSERT INTO t1 VALUES (103); +INSERT INTO t1 VALUES (102); +INSERT INTO t1 VALUES (101); +INSERT INTO t1 VALUES (105); +INSERT INTO t1 VALUES (106); +INSERT INTO t1 VALUES (107); +INSERT INTO t2 VALUES (107),(75),(1000); +SELECT t1.id,t2.id FROM t2 LEFT JOIN t1 ON t1.id>=74 AND t1.id<=0 +WHERE t2.id=75 AND t1.id IS NULL; +id id +NULL 75 +EXPLAIN SELECT t1.id,t2.id FROM t2 LEFT JOIN t1 ON t1.id>=74 AND t1.id<=0 +WHERE t2.id=75 AND t1.id IS NULL; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY NULL NULL NULL 1 Impossible ON condition +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where +DROP TABLE t1,t2; +# +# Bug #53830: !table || (!table->read_set || bitmap_is_set(table->read_set, field_index)) +# +CREATE TABLE t1 (a INT, b INT, c INT, d INT, +PRIMARY KEY(a,b,c), KEY(b,d)) +ENGINE=InnoDB; +INSERT INTO t1 VALUES (0, 77, 1, 3); +UPDATE t1 SET d = 0 WHERE b = 77 AND c = 25; +DROP TABLE t1; +End of 5.1 tests From 8e7ce2e9d86d9a216123fa424c50846944c8fbe8 Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Tue, 15 Jun 2010 02:33:26 -0700 Subject: [PATCH 028/112] Add checkin description for bug #47622 to ChangeLog. --- storage/innodb_plugin/ChangeLog | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index fb577a04221..971de4a9d27 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -275,6 +275,14 @@ Fix Bug#49497 Error 1467 (ER_AUTOINC_READ_FAILED) on inserting a negative value +2010-01-28 The InnoDB Team + * handler/ha_innodb.h, handler/ha_innodb.cc, + handler/handler0alter.cc, + mysql-test/innodb_bug47622.test, + mysql-test/innodb_bug47622.result: + Fix Bug#47622 the new index is added before the existing ones + in MySQL, but after one in SE + 2010-01-27 The InnoDB Team * include/row0mysql.h, log/log0recv.c, row/row0mysql.c: From 3c0be2c7b3faf98cb0e09994f4c992160c5a62ab Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Wed, 16 Jun 2010 19:12:04 -0700 Subject: [PATCH 029/112] Fix Bug #54330 Broken fast index creation. Add additional array to account for each merge run's start offset, so correct offsets are paired up for multiple merge runs. rb://377 approved by Marko --- storage/innodb_plugin/ChangeLog | 5 ++ storage/innodb_plugin/row/row0merge.c | 87 +++++++++++++++++---------- 2 files changed, 61 insertions(+), 31 deletions(-) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 971de4a9d27..a76329c85eb 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,8 @@ +2010-06-16 The InnoDB Team + + * row/row0merge.c: + Fix Bug#54330 Broken fast index creation + 2010-06-08 The InnoDB Team * dict/dict0load.c: diff --git a/storage/innodb_plugin/row/row0merge.c b/storage/innodb_plugin/row/row0merge.c index 1f6851bf63c..f7bc0299b70 100644 --- a/storage/innodb_plugin/row/row0merge.c +++ b/storage/innodb_plugin/row/row0merge.c @@ -1578,22 +1578,28 @@ row_merge( const dict_index_t* index, /*!< in: index being created */ merge_file_t* file, /*!< in/out: file containing index entries */ - ulint* half, /*!< in/out: half the file */ row_merge_block_t* block, /*!< in/out: 3 buffers */ int* tmpfd, /*!< in/out: temporary file handle */ - TABLE* table) /*!< in/out: MySQL table, for + TABLE* table, /*!< in/out: MySQL table, for reporting erroneous key value if applicable */ + ulint* num_run,/*!< in/out: Number of runs remain + to be merged */ + ulint* run_offset) /*!< in/out: Array contains the + first offset number for each merge + run */ { ulint foffs0; /*!< first input offset */ ulint foffs1; /*!< second input offset */ ulint error; /*!< error code */ merge_file_t of; /*!< output file */ - const ulint ihalf = *half; + const ulint ihalf = run_offset[*num_run / 2]; /*!< half the input file */ - ulint ohalf; /*!< half the output file */ + ulint n_run = 0; + /*!< num of runs generated from this merge */ UNIV_MEM_ASSERT_W(block[0], 3 * sizeof block[0]); + ut_ad(ihalf < file->offset); of.fd = *tmpfd; @@ -1601,17 +1607,20 @@ row_merge( of.n_rec = 0; /* Merge blocks to the output file. */ - ohalf = 0; foffs0 = 0; foffs1 = ihalf; + UNIV_MEM_INVALID(run_offset, *num_run * sizeof *run_offset); + for (; foffs0 < ihalf && foffs1 < file->offset; foffs0++, foffs1++) { - ulint ahalf; /*!< arithmetic half the input file */ if (UNIV_UNLIKELY(trx_is_interrupted(trx))) { return(DB_INTERRUPTED); } + /* Remember the offset number for this run */ + run_offset[n_run++] = of.offset; + error = row_merge_blocks(index, file, block, &foffs0, &foffs1, &of, table); @@ -1619,21 +1628,6 @@ row_merge( return(error); } - /* Record the offset of the output file when - approximately half the output has been generated. In - this way, the next invocation of row_merge() will - spend most of the time in this loop. The initial - estimate is ohalf==0. */ - ahalf = file->offset / 2; - ut_ad(ohalf <= of.offset); - - /* Improve the estimate until reaching half the input - file size, or we can not get any closer to it. All - comparands should be non-negative when !(ohalf < ahalf) - because ohalf <= of.offset. */ - if (ohalf < ahalf || of.offset - ahalf < ohalf - ahalf) { - ohalf = of.offset; - } } /* Copy the last blocks, if there are any. */ @@ -1643,6 +1637,9 @@ row_merge( return(DB_INTERRUPTED); } + /* Remember the offset number for this run */ + run_offset[n_run++] = of.offset; + if (!row_merge_blocks_copy(index, file, block, &foffs0, &of)) { return(DB_CORRUPTION); } @@ -1655,6 +1652,9 @@ row_merge( return(DB_INTERRUPTED); } + /* Remember the offset number for this run */ + run_offset[n_run++] = of.offset; + if (!row_merge_blocks_copy(index, file, block, &foffs1, &of)) { return(DB_CORRUPTION); } @@ -1666,10 +1666,23 @@ row_merge( return(DB_CORRUPTION); } + ut_ad(n_run < *num_run); + + *num_run = n_run; + + /* Each run can contain one or more offsets. As merge goes on, + the number of runs (to merge) will reduce until we have one + single run. So the number of runs will always be smaller than + the number of offsets in file */ + ut_ad((*num_run) <= file->offset); + + /* The number of offsets in output file is always equal or + smaller than input file */ + ut_ad(of.offset <= file->offset); + /* Swap file descriptors for the next pass. */ *tmpfd = file->fd; *file = of; - *half = ohalf; UNIV_MEM_INVALID(block[0], 3 * sizeof block[0]); @@ -1694,27 +1707,39 @@ row_merge_sort( if applicable */ { ulint half = file->offset / 2; + ulint num_runs; + ulint* run_offset; + ulint error = DB_SUCCESS; + + /* Record the number of merge runs we need to perform */ + num_runs = file->offset; + + /* "run_offset" records each run's first offset number */ + run_offset = (ulint*) mem_alloc(file->offset * sizeof(ulint)); + + /* This tells row_merge() where to start for the first round + of merge. */ + run_offset[half] = half; /* The file should always contain at least one byte (the end of file marker). Thus, it must be at least one block. */ ut_ad(file->offset > 0); + /* Merge the runs until we have one big run */ do { - ulint error; + error = row_merge(trx, index, file, block, tmpfd, + table, &num_runs, run_offset); - error = row_merge(trx, index, file, &half, - block, tmpfd, table); + UNIV_MEM_ASSERT_RW(run_offset, num_runs * sizeof *run_offset); if (error != DB_SUCCESS) { - return(error); + break; } + } while (num_runs > 1); - /* half > 0 should hold except when the file consists - of one block. No need to merge further then. */ - ut_ad(half > 0 || file->offset == 1); - } while (half < file->offset && half > 0); + mem_free(run_offset); - return(DB_SUCCESS); + return(error); } /*************************************************************//** From 69bc6dd01ce962932a1083f162b29cffc0fda834 Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Thu, 17 Jun 2010 10:33:03 -0700 Subject: [PATCH 030/112] Fix an overly asserted assertion during previous checkin for bug #54330. --- storage/innodb_plugin/row/row0merge.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/storage/innodb_plugin/row/row0merge.c b/storage/innodb_plugin/row/row0merge.c index f7bc0299b70..28e7faed1f8 100644 --- a/storage/innodb_plugin/row/row0merge.c +++ b/storage/innodb_plugin/row/row0merge.c @@ -1666,7 +1666,7 @@ row_merge( return(DB_CORRUPTION); } - ut_ad(n_run < *num_run); + ut_ad(n_run <= *num_run); *num_run = n_run; @@ -1714,6 +1714,11 @@ row_merge_sort( /* Record the number of merge runs we need to perform */ num_runs = file->offset; + /* If num_runs are less than 1, nothing to merge */ + if (num_runs <= 1) { + return(error); + } + /* "run_offset" records each run's first offset number */ run_offset = (ulint*) mem_alloc(file->offset * sizeof(ulint)); From 4d446d4c104925d866d0b28cd99111218abf22cb Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Thu, 17 Jun 2010 22:38:22 -0700 Subject: [PATCH 031/112] Check in fix for Bug #52814 InnoDB: Use the new ha_data interfaces rb://290, approved by Sunny --- storage/innobase/handler/ha_innodb.cc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index cf7ec4d6e6f..9990d7c28f0 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -583,13 +583,13 @@ thd_is_select( /************************************************************************ Obtain the InnoDB transaction of a MySQL thread. */ inline -trx_t*& +trx_t* thd_to_trx( /*=======*/ /* out: reference to transaction pointer */ THD* thd) /* in: MySQL thread */ { - return(*(trx_t**) thd_ha_data(thd, innodb_hton_ptr)); + return((trx_t*) thd_get_ha_data(thd, innodb_hton_ptr)); } /************************************************************************ @@ -1164,7 +1164,7 @@ check_trx_exists( /* out: InnoDB transaction handle */ THD* thd) /* in: user thread handle */ { - trx_t*& trx = thd_to_trx(thd); + trx_t* trx = thd_to_trx(thd); ut_ad(thd == current_thd); @@ -1178,6 +1178,9 @@ check_trx_exists( /* Update the info whether we should skip XA steps that eat CPU time */ trx->support_xa = THDVAR(thd, support_xa); + + /* We have a new trx, register with the thread handle */ + thd_set_ha_data(thd, innodb_hton_ptr, trx); } else { if (trx->magic_n != TRX_MAGIC_N) { mem_analyze_corruption(trx); @@ -2482,6 +2485,9 @@ innobase_close_connection( innobase_rollback_trx(trx); + /* Release the lock in thread handler */ + thd_set_ha_data(thd, hton, NULL); + thr_local_free(trx->mysql_thread_id); trx_free_for_mysql(trx); From 40c13ca9bd2dfd439bb9b4fc7ed840867d878398 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Fri, 18 Jun 2010 10:00:01 +0300 Subject: [PATCH 032/112] Increment InnoDB Plugin version from 1.0.9 to 1.0.10, after 1.0.9 has been released with MySQL 5.1.48. --- storage/innodb_plugin/include/univ.i | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innodb_plugin/include/univ.i b/storage/innodb_plugin/include/univ.i index 018fd157a25..9da08c894cd 100644 --- a/storage/innodb_plugin/include/univ.i +++ b/storage/innodb_plugin/include/univ.i @@ -46,7 +46,7 @@ Created 1/20/1994 Heikki Tuuri #define INNODB_VERSION_MAJOR 1 #define INNODB_VERSION_MINOR 0 -#define INNODB_VERSION_BUGFIX 9 +#define INNODB_VERSION_BUGFIX 10 /* The following is the InnoDB version as shown in SELECT plugin_version FROM information_schema.plugins; From aebf6c06c4a02d44e76efbd3d9e4cabba0b6d43d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 21 Jun 2010 12:40:08 +0300 Subject: [PATCH 033/112] Bug #54658: InnoDB: Warning: allocated tablespace %lu, old maximum was 0 dict_check_tablespaces_and_store_max_id(): Initialize max_space_id and fil_system->max_assigned_id from DICT_HDR_MAX_SPACE_ID. fil_space_create(): Suppress the warning unless !recv_recovery_on (do not complain while applying the redo log). --- storage/innodb_plugin/dict/dict0load.c | 7 ++++++- storage/innodb_plugin/fil/fil0fil.c | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/storage/innodb_plugin/dict/dict0load.c b/storage/innodb_plugin/dict/dict0load.c index f86aa0848bd..3c495d21786 100644 --- a/storage/innodb_plugin/dict/dict0load.c +++ b/storage/innodb_plugin/dict/dict0load.c @@ -316,7 +316,7 @@ dict_check_tablespaces_and_store_max_id( dict_index_t* sys_index; btr_pcur_t pcur; const rec_t* rec; - ulint max_space_id = 0; + ulint max_space_id; mtr_t mtr; mutex_enter(&(dict_sys->mutex)); @@ -327,6 +327,11 @@ dict_check_tablespaces_and_store_max_id( sys_index = UT_LIST_GET_FIRST(sys_tables->indexes); ut_a(!dict_table_is_comp(sys_tables)); + max_space_id = mtr_read_ulint(dict_hdr_get(&mtr) + + DICT_HDR_MAX_SPACE_ID, + MLOG_4BYTES, &mtr); + fil_set_max_space_id_if_bigger(max_space_id); + btr_pcur_open_at_index_side(TRUE, sys_index, BTR_SEARCH_LEAF, &pcur, TRUE, &mtr); loop: diff --git a/storage/innodb_plugin/fil/fil0fil.c b/storage/innodb_plugin/fil/fil0fil.c index 219eb5f500f..796fe921a7e 100644 --- a/storage/innodb_plugin/fil/fil0fil.c +++ b/storage/innodb_plugin/fil/fil0fil.c @@ -1197,7 +1197,7 @@ try_again: space->tablespace_version = fil_system->tablespace_version; space->mark = FALSE; - if (UNIV_LIKELY(purpose == FIL_TABLESPACE) + if (UNIV_LIKELY(purpose == FIL_TABLESPACE && !recv_recovery_on) && UNIV_UNLIKELY(id > fil_system->max_assigned_id)) { if (!fil_system->space_id_reuse_warned) { fil_system->space_id_reuse_warned = TRUE; From a6c1d93e02e2b3fffe6e80b219e571262ffc2fd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 21 Jun 2010 12:51:48 +0300 Subject: [PATCH 034/112] Bug#54658: Add ChangeLog entry --- storage/innodb_plugin/ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index a76329c85eb..3be5373f3af 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,9 @@ +2010-06-21 The InnoDB Team + + * dict/dict0load.c, fil/fil0fil.c: + Fix Bug#54658: InnoDB: Warning: allocated tablespace %lu, + old maximum was 0 (introduced in Bug #53578 fix) + 2010-06-16 The InnoDB Team * row/row0merge.c: From 0251b868ac09a12d5231adf92276aaaf77602432 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 21 Jun 2010 14:06:14 +0300 Subject: [PATCH 035/112] Switched the mailing lists --- .bzr-mysql/default.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 557df1b1ffe..d0ddf92f211 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] -post_commit_to = "commits@lists.mysql.com" -post_push_to = "commits@lists.mysql.com" +post_commit_to = "dbg_mysql_security@sun.com" +post_push_to = "dbg_mysql_security@sun.com" tree_name = "mysql-5.0-bugteam" From 5e22f73ad37236bf214b0daf487e112fca88e5ab Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 21 Jun 2010 14:09:23 +0300 Subject: [PATCH 036/112] tree name change --- .bzr-mysql/default.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index d0ddf92f211..4b2affc1529 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] post_commit_to = "dbg_mysql_security@sun.com" post_push_to = "dbg_mysql_security@sun.com" -tree_name = "mysql-5.0-bugteam" +tree_name = "mysql-5.0-security" From a1ac083fc324d729d3347d7e7c418a08f11cae9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 22 Jun 2010 14:52:15 +0300 Subject: [PATCH 037/112] Bug#54686 "field->col->mtype == type" assertion error at row/row0sel.c ha_innobase::index_read(), ha_innobase::records_in_range(): Check that the index is useable before invoking row_sel_convert_mysql_key_to_innobase(). This fix is based on a suggestion by Yasufumi Kinoshita. --- storage/innodb_plugin/handler/ha_innodb.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index 34249b7718a..3f8dc97e4b5 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -5379,6 +5379,9 @@ ha_innobase::index_read( prebuilt->index_usable = FALSE; DBUG_RETURN(HA_ERR_CRASHED); } + if (UNIV_UNLIKELY(!prebuilt->index_usable)) { + DBUG_RETURN(HA_ERR_TABLE_DEF_CHANGED); + } /* Note that if the index for which the search template is built is not necessarily prebuilt->index, but can also be the clustered index */ @@ -7221,6 +7224,10 @@ ha_innobase::records_in_range( n_rows = HA_POS_ERROR; goto func_exit; } + if (UNIV_UNLIKELY(!row_merge_is_index_usable(prebuilt->trx, index))) { + n_rows = HA_ERR_TABLE_DEF_CHANGED; + goto func_exit; + } heap = mem_heap_create(2 * (key->key_parts * sizeof(dfield_t) + sizeof(dtuple_t))); From 31939e0d14efb4d0c2aa02cb4805aab398c1db73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 22 Jun 2010 14:59:49 +0300 Subject: [PATCH 038/112] ChangeLog for Bug#54686 "field->col->mtype == type" assertion error at row/row0sel.c --- storage/innodb_plugin/ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 3be5373f3af..085edd8ad83 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,9 @@ +2010-06-22 The InnoDB Team + + * handler/ha_innodb.cc: + Fix Bug#54686: "field->col->mtype == type" assertion error at + row/row0sel.c + 2010-06-21 The InnoDB Team * dict/dict0load.c, fil/fil0fil.c: From ba04d5382614214104c33145474bab7b7f3a66d1 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 22 Jun 2010 19:30:43 +0300 Subject: [PATCH 039/112] Fix Bug#47991 InnoDB Dictionary Cache memory usage increases indefinitely when renaming tables Allocate the table name using ut_malloc() instead of table->heap because the latter cannot be freed. Adjust dict_sys->size calculations all over the code. Change dict_table_t::name from const char* to char* because we need to ut_malloc()/ut_free() it. Reviewed by: Inaam, Marko, Heikki (rb://384) Approved by: Heikki (rb://384) --- storage/innodb_plugin/dict/dict0dict.c | 34 ++++++++++++++++++------ storage/innodb_plugin/dict/dict0mem.c | 4 ++- storage/innodb_plugin/include/dict0mem.h | 2 +- storage/innodb_plugin/include/univ.i | 6 +++++ storage/innodb_plugin/page/page0zip.c | 1 + storage/innodb_plugin/row/row0merge.c | 13 ++++++++- 6 files changed, 49 insertions(+), 11 deletions(-) diff --git a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/dict0dict.c index 61f70c72720..8be5b7acac5 100644 --- a/storage/innodb_plugin/dict/dict0dict.c +++ b/storage/innodb_plugin/dict/dict0dict.c @@ -850,7 +850,8 @@ dict_table_add_to_cache( /* Add table to LRU list of tables */ UT_LIST_ADD_FIRST(table_LRU, dict_sys->table_LRU, table); - dict_sys->size += mem_heap_get_size(table->heap); + dict_sys->size += mem_heap_get_size(table->heap) + + strlen(table->name) + 1; } /**********************************************************************//** @@ -904,14 +905,21 @@ dict_table_rename_in_cache( dict_foreign_t* foreign; dict_index_t* index; ulint fold; - ulint old_size; - const char* old_name; + char old_name[MAX_TABLE_NAME_LEN + 1]; ut_ad(table); ut_ad(mutex_own(&(dict_sys->mutex))); - old_size = mem_heap_get_size(table->heap); - old_name = table->name; + /* store the old/current name to an automatic variable */ + if (strlen(table->name) + 1 <= sizeof(old_name)) { + memcpy(old_name, table->name, strlen(table->name) + 1); + } else { + ut_print_timestamp(stderr); + fprintf(stderr, "InnoDB: too long table name: '%s', " + "max length is %d\n", table->name, + MAX_TABLE_NAME_LEN); + ut_error; + } fold = ut_fold_string(new_name); @@ -957,12 +965,22 @@ dict_table_rename_in_cache( /* Remove table from the hash tables of tables */ HASH_DELETE(dict_table_t, name_hash, dict_sys->table_hash, ut_fold_string(old_name), table); - table->name = mem_heap_strdup(table->heap, new_name); + + if (strlen(new_name) > strlen(table->name)) { + /* We allocate MAX_TABLE_NAME_LEN+1 bytes here to avoid + memory fragmentation, we assume a repeated calls of + ut_realloc() with the same size do not cause fragmentation */ + ut_a(strlen(new_name) <= MAX_TABLE_NAME_LEN); + table->name = ut_realloc(table->name, MAX_TABLE_NAME_LEN + 1); + } + memcpy(table->name, new_name, strlen(new_name) + 1); /* Add table to hash table of tables */ HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold, table); - dict_sys->size += (mem_heap_get_size(table->heap) - old_size); + + dict_sys->size += strlen(new_name) - strlen(old_name); + ut_a(dict_sys->size > 0); /* Update the table_name field in indexes */ index = dict_table_get_first_index(table); @@ -1187,7 +1205,7 @@ dict_table_remove_from_cache( /* Remove table from LRU list of tables */ UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table); - size = mem_heap_get_size(table->heap); + size = mem_heap_get_size(table->heap) + strlen(table->name) + 1; ut_ad(dict_sys->size >= size); diff --git a/storage/innodb_plugin/dict/dict0mem.c b/storage/innodb_plugin/dict/dict0mem.c index 66b4b43f296..3287247029f 100644 --- a/storage/innodb_plugin/dict/dict0mem.c +++ b/storage/innodb_plugin/dict/dict0mem.c @@ -68,7 +68,8 @@ dict_mem_table_create( table->heap = heap; table->flags = (unsigned int) flags; - table->name = mem_heap_strdup(heap, name); + table->name = ut_malloc(strlen(name) + 1); + memcpy(table->name, name, strlen(name) + 1); table->space = (unsigned int) space; table->n_cols = (unsigned int) (n_cols + DATA_N_SYS_COLS); @@ -106,6 +107,7 @@ dict_mem_table_free( #ifndef UNIV_HOTBACKUP mutex_free(&(table->autoinc_mutex)); #endif /* UNIV_HOTBACKUP */ + ut_free(table->name); mem_heap_free(table->heap); } diff --git a/storage/innodb_plugin/include/dict0mem.h b/storage/innodb_plugin/include/dict0mem.h index 9996fb59a75..2fce1e00927 100644 --- a/storage/innodb_plugin/include/dict0mem.h +++ b/storage/innodb_plugin/include/dict0mem.h @@ -382,7 +382,7 @@ initialized to 0, NULL or FALSE in dict_mem_table_create(). */ struct dict_table_struct{ dulint id; /*!< id of the table */ mem_heap_t* heap; /*!< memory heap */ - const char* name; /*!< table name */ + char* name; /*!< table name */ const char* dir_path_of_temp_table;/*!< NULL or the directory path where a TEMPORARY table that was explicitly created by a user should be placed if diff --git a/storage/innodb_plugin/include/univ.i b/storage/innodb_plugin/include/univ.i index 9da08c894cd..b8e595161b9 100644 --- a/storage/innodb_plugin/include/univ.i +++ b/storage/innodb_plugin/include/univ.i @@ -290,6 +290,12 @@ management to ensure correct alignment for doubles etc. */ /* Maximum number of parallel threads in a parallelized operation */ #define UNIV_MAX_PARALLELISM 32 +/* The maximum length of a table name. This is the MySQL limit and is +defined in mysql_com.h like NAME_CHAR_LEN*SYSTEM_CHARSET_MBMAXLEN, the +number does not include a terminating '\0'. InnoDB probably can handle +longer names internally */ +#define MAX_TABLE_NAME_LEN 192 + /* UNIVERSAL TYPE DEFINITIONS ========================== diff --git a/storage/innodb_plugin/page/page0zip.c b/storage/innodb_plugin/page/page0zip.c index 8d9632a3548..d3b1edefc6b 100644 --- a/storage/innodb_plugin/page/page0zip.c +++ b/storage/innodb_plugin/page/page0zip.c @@ -1464,6 +1464,7 @@ page_zip_fields_free( dict_table_t* table = index->table; mem_heap_free(index->heap); mutex_free(&(table->autoinc_mutex)); + ut_free(table->name); mem_heap_free(table->heap); } } diff --git a/storage/innodb_plugin/row/row0merge.c b/storage/innodb_plugin/row/row0merge.c index 28e7faed1f8..70cc7912fad 100644 --- a/storage/innodb_plugin/row/row0merge.c +++ b/storage/innodb_plugin/row/row0merge.c @@ -2336,7 +2336,7 @@ row_merge_rename_tables( { ulint err = DB_ERROR; pars_info_t* info; - const char* old_name= old_table->name; + char old_name[MAX_TABLE_NAME_LEN + 1]; ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); ut_ad(old_table != new_table); @@ -2344,6 +2344,17 @@ row_merge_rename_tables( ut_a(trx->dict_operation_lock_mode == RW_X_LATCH); + /* store the old/current name to an automatic variable */ + if (strlen(old_table->name) + 1 <= sizeof(old_name)) { + memcpy(old_name, old_table->name, strlen(old_table->name) + 1); + } else { + ut_print_timestamp(stderr); + fprintf(stderr, "InnoDB: too long table name: '%s', " + "max length is %d\n", old_table->name, + MAX_TABLE_NAME_LEN); + ut_error; + } + trx->op_info = "renaming tables"; /* We use the private SQL parser of Innobase to generate the query From e42ab1af8d6d0eb3a612a92379e03cb4b2eed0b0 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 22 Jun 2010 20:04:54 +0300 Subject: [PATCH 040/112] Add ChangeLog entry for the fix of Bug#47991 --- storage/innodb_plugin/ChangeLog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 3be5373f3af..d17c6e058d4 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,10 @@ +2010-06-22 The InnoDB Team + + * dict/dict0dict.c, dict/dict0mem.c, include/dict0mem.h, + include/univ.i, page/page0zip.c, row/row0merge.c: + Fix Bug#47991 InnoDB Dictionary Cache memory usage increases + indefinitely when renaming tables + 2010-06-21 The InnoDB Team * dict/dict0load.c, fil/fil0fil.c: From ebdd52838299fbb036b8399b53dd347400644a8d Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 22 Jun 2010 19:21:25 +0200 Subject: [PATCH 041/112] Set version number for mysql-5.1.46sp1 release --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 904c54abb5f..9098ed1f3cb 100644 --- a/configure.in +++ b/configure.in @@ -12,7 +12,7 @@ dnl dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MySQL Server], [5.1.46], [], [mysql]) +AC_INIT([MySQL Server], [5.1.46sp1], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM From eea50ea20dcdae7fe8c3bb182d030cdb79e8c1e0 Mon Sep 17 00:00:00 2001 From: MySQL Build Team Date: Tue, 22 Jun 2010 21:42:14 +0200 Subject: [PATCH 042/112] Backport into build-201006221614-5.1.46sp1 > ------------------------------------------------------------ > revno: 3362 > revision-id: davi.arnaut@sun.com-20100401131522-895y8uzvv8ag44gs > parent: ramil@mysql.com-20100429045409-r7r5lcyiruis15v7 > committer: Davi Arnaut > branch nick: 50755-5.1 > timestamp: Thu 2010-04-01 10:15:22 -0300 > message: > Bug#50755: Crash if stored routine def contains version comments > > The problem was that a syntactically invalid trigger could cause > the server to crash when trying to list triggers. The crash would > happen due to a mishap in the backup/restore procedure that should > protect parser items which are not associated with the trigger. The > backup/restore is used to isolate the parse tree (and context) of > a statement from the load (and parsing) of a trigger. In this case, > a error during the parsing of a trigger could cause the improper > backup/restore sequence. > > The solution is to properly restore the original statement context > before the parser is exited due to syntax errors in the trigger body. --- mysql-test/r/trigger.result | 23 +++++++++++++++++++++++ mysql-test/t/trigger.test | 31 +++++++++++++++++++++++++++++++ sql/sp_head.cc | 36 ++++++++++++++---------------------- sql/sp_head.h | 4 ---- sql/sql_lex.cc | 1 + 5 files changed, 69 insertions(+), 26 deletions(-) diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result index 3446babbb52..e3c0b0e1dd9 100644 --- a/mysql-test/r/trigger.result +++ b/mysql-test/r/trigger.result @@ -2128,4 +2128,27 @@ Warning 1048 Column 'id' cannot be null Warning 1048 Column 'id' cannot be null DROP TRIGGER t1_bu; DROP TABLE t1,t2; +# +# Bug#50755: Crash if stored routine def contains version comments +# +DROP DATABASE IF EXISTS db1; +DROP TRIGGER IF EXISTS trg1; +DROP TABLE IF EXISTS t1, t2; +CREATE DATABASE db1; +USE db1; +CREATE TABLE t1 (b INT); +CREATE TABLE t2 (a INT); +CREATE TRIGGER trg1 BEFORE INSERT ON t2 FOR EACH ROW INSERT/*!INTO*/t1 VALUES (1); +# Used to crash +SHOW TRIGGERS IN db1; +Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +Warnings: +Warning 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'VALUES (1)' at line 1 +INSERT INTO t2 VALUES (1); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'VALUES (1)' at line 1 +SELECT * FROM t1; +b +# Work around Bug#45235 +DROP DATABASE db1; +USE test; End of 5.1 tests. diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test index 368271f1fb2..bcbca4d2139 100644 --- a/mysql-test/t/trigger.test +++ b/mysql-test/t/trigger.test @@ -2439,4 +2439,35 @@ UPDATE t1 SET id=NULL; DROP TRIGGER t1_bu; DROP TABLE t1,t2; +--echo # +--echo # Bug#50755: Crash if stored routine def contains version comments +--echo # + +--disable_warnings +DROP DATABASE IF EXISTS db1; +DROP TRIGGER IF EXISTS trg1; +DROP TABLE IF EXISTS t1, t2; +--enable_warnings + +CREATE DATABASE db1; +USE db1; + +CREATE TABLE t1 (b INT); +CREATE TABLE t2 (a INT); + +CREATE TRIGGER trg1 BEFORE INSERT ON t2 FOR EACH ROW INSERT/*!INTO*/t1 VALUES (1); +--echo # Used to crash +SHOW TRIGGERS IN db1; +--error ER_PARSE_ERROR +INSERT INTO t2 VALUES (1); +SELECT * FROM t1; + +--echo # Work around Bug#45235 +let $MYSQLD_DATADIR = `select @@datadir`; +--remove_file $MYSQLD_DATADIR/db1/t2.TRG +--remove_file $MYSQLD_DATADIR/db1/trg1.TRN + +DROP DATABASE db1; +USE test; + --echo End of 5.1 tests. diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 11d5e5f830b..cadda38053c 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -745,21 +745,12 @@ sp_head::create(THD *thd) sp_head::~sp_head() { - DBUG_ENTER("sp_head::~sp_head"); - destroy(); - delete m_next_cached_sp; - if (m_thd) - restore_thd_mem_root(m_thd); - DBUG_VOID_RETURN; -} - -void -sp_head::destroy() -{ - sp_instr *i; LEX *lex; - DBUG_ENTER("sp_head::destroy"); - DBUG_PRINT("info", ("name: %s", m_name.str)); + sp_instr *i; + DBUG_ENTER("sp_head::~sp_head"); + + /* sp_head::restore_thd_mem_root() must already have been called. */ + DBUG_ASSERT(m_thd == NULL); for (uint ip = 0 ; (i = get_instr(ip)) ; ip++) delete i; @@ -770,21 +761,22 @@ sp_head::destroy() /* If we have non-empty LEX stack then we just came out of parser with error. Now we should delete all auxilary LEXes and restore original - THD::lex (In this case sp_head::restore_thd_mem_root() was not called - too, so m_thd points to the current thread context). - It is safe to not update LEX::ptr because further query string parsing - and execution will be stopped anyway. + THD::lex. It is safe to not update LEX::ptr because further query + string parsing and execution will be stopped anyway. */ - DBUG_ASSERT(m_lex.is_empty() || m_thd); while ((lex= (LEX *)m_lex.pop())) { - lex_end(m_thd->lex); - delete m_thd->lex; - m_thd->lex= lex; + THD *thd= lex->thd; + lex_end(thd->lex); + delete thd->lex; + thd->lex= lex; } hash_free(&m_sptabs); hash_free(&m_sroutines); + + delete m_next_cached_sp; + DBUG_VOID_RETURN; } diff --git a/sql/sp_head.h b/sql/sp_head.h index 00c96d44f70..d422adc8927 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -289,10 +289,6 @@ public: virtual ~sp_head(); - /// Free memory - void - destroy(); - bool execute_trigger(THD *thd, const LEX_STRING *db_name, diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 5097ca2ad5b..a3776f59241 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2106,6 +2106,7 @@ void st_lex::cleanup_lex_after_parse_error(THD *thd) */ if (thd->lex->sphead) { + thd->lex->sphead->restore_thd_mem_root(thd); delete thd->lex->sphead; thd->lex->sphead= NULL; } From d2c104fd129c648b6b89d612d9144b4594525732 Mon Sep 17 00:00:00 2001 From: MySQL Build Team Date: Tue, 22 Jun 2010 21:50:47 +0200 Subject: [PATCH 043/112] Backport into build-201006221614-5.1.46sp1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit > ------------------------------------------------------------ > revno: 3351.14.50 > revision-id: marko.makela@oracle.com-20100421185359-8qaxoa2yyrpzwdd7 > parent: marko.makela@oracle.com-20100421102723-0i80uezbyu0ekj5d > committer: Marko Mäkelä > branch nick: 5.1-innodb > timestamp: Wed 2010-04-21 21:53:59 +0300 > message: > btr_page_split_and_insert(): Avoid an infinite loop. (Bug #52964) > > btr_page_tuple_smaller(): New function, refactored from > btr_page_split_and_insert(). > > btr_page_get_split_rec(): Renamed from btr_page_get_sure_split_rec(). > Note that a NULL return may mean that the tuple is to be inserted into > either the lower or upper page, to be determined by btr_page_tuple_smaller(). > > btr_page_split_and_insert(): When btr_page_get_split_rec() returns NULL, > invoke btr_page_tuple_smaller() to determine which half-page the tuple > belongs to. > > Reviewed by Sunny Bains --- storage/innodb_plugin/btr/btr0btr.c | 91 +++++++++++++++++++---------- 1 file changed, 59 insertions(+), 32 deletions(-) diff --git a/storage/innodb_plugin/btr/btr0btr.c b/storage/innodb_plugin/btr/btr0btr.c index fa4fc05d96b..cd8f42b3818 100644 --- a/storage/innodb_plugin/btr/btr0btr.c +++ b/storage/innodb_plugin/btr/btr0btr.c @@ -1451,11 +1451,11 @@ Calculates a split record such that the tuple will certainly fit on its half-page when the split is performed. We assume in this function only that the cursor page has at least one user record. @return split record, or NULL if tuple will be the first record on -upper half-page */ +the lower or upper half-page (determined by btr_page_tuple_smaller()) */ static rec_t* -btr_page_get_sure_split_rec( -/*========================*/ +btr_page_get_split_rec( +/*===================*/ btr_cur_t* cursor, /*!< in: cursor at which insert should be made */ const dtuple_t* tuple, /*!< in: tuple to insert */ ulint n_ext) /*!< in: number of externally stored columns */ @@ -1831,6 +1831,37 @@ btr_attach_half_pages( btr_page_set_next(upper_page, upper_page_zip, next_page_no, mtr); } +/*************************************************************//** +Determine if a tuple is smaller than any record on the page. +@return TRUE if smaller */ +static +ibool +btr_page_tuple_smaller( +/*===================*/ + btr_cur_t* cursor, /*!< in: b-tree cursor */ + const dtuple_t* tuple, /*!< in: tuple to consider */ + ulint* offsets,/*!< in/out: temporary storage */ + ulint n_uniq, /*!< in: number of unique fields + in the index page records */ + mem_heap_t** heap) /*!< in/out: heap for offsets */ +{ + buf_block_t* block; + const rec_t* first_rec; + page_cur_t pcur; + + /* Read the first user record in the page. */ + block = btr_cur_get_block(cursor); + page_cur_set_before_first(block, &pcur); + page_cur_move_to_next(&pcur); + first_rec = page_cur_get_rec(&pcur); + + offsets = rec_get_offsets( + first_rec, cursor->index, offsets, + n_uniq, heap); + + return(cmp_dtuple_rec(tuple, first_rec, offsets) < 0); +} + /*************************************************************//** Splits an index page to halves and inserts the tuple. It is assumed that mtr holds an x-latch to the index tree. NOTE: the tree x-latch is @@ -1905,49 +1936,45 @@ func_start: if (n_iterations > 0) { direction = FSP_UP; hint_page_no = page_no + 1; - split_rec = btr_page_get_sure_split_rec(cursor, tuple, n_ext); + split_rec = btr_page_get_split_rec(cursor, tuple, n_ext); + if (UNIV_UNLIKELY(split_rec == NULL)) { + insert_left = btr_page_tuple_smaller( + cursor, tuple, offsets, n_uniq, &heap); + } } else if (btr_page_get_split_rec_to_right(cursor, &split_rec)) { direction = FSP_UP; hint_page_no = page_no + 1; + insert_left = FALSE; } else if (btr_page_get_split_rec_to_left(cursor, &split_rec)) { direction = FSP_DOWN; hint_page_no = page_no - 1; + ut_ad(split_rec); } else { direction = FSP_UP; hint_page_no = page_no + 1; - if (page_get_n_recs(page) == 1) { - page_cur_t pcur; + /* If there is only one record in the index page, we + can't split the node in the middle by default. We need + to determine whether the new record will be inserted + to the left or right. */ - /* There is only one record in the index page - therefore we can't split the node in the middle - by default. We need to determine whether the - new record will be inserted to the left or right. */ - - /* Read the first (and only) record in the page. */ - page_cur_set_before_first(block, &pcur); - page_cur_move_to_next(&pcur); - first_rec = page_cur_get_rec(&pcur); - - offsets = rec_get_offsets( - first_rec, cursor->index, offsets, - n_uniq, &heap); - - /* If the new record is less than the existing record - the split in the middle will copy the existing - record to the new node. */ - if (cmp_dtuple_rec(tuple, first_rec, offsets) < 0) { - split_rec = page_get_middle_rec(page); - } else { - split_rec = NULL; - } - } else { + if (page_get_n_recs(page) > 1) { split_rec = page_get_middle_rec(page); + } else if (btr_page_tuple_smaller(cursor, tuple, + offsets, n_uniq, &heap)) { + split_rec = page_rec_get_next( + page_get_infimum_rec(page)); + } else { + split_rec = NULL; + insert_left = FALSE; } } + /* At this point, insert_left is initialized if split_rec == NULL + and may be uninitialized otherwise. */ + /* 2. Allocate a new page to the index */ new_block = btr_page_alloc(cursor->index, hint_page_no, direction, btr_page_get_level(page, mtr), mtr); @@ -1974,11 +2001,11 @@ func_start: avoid further splits by inserting the record to an empty page. */ split_rec = NULL; - goto insert_right; + goto insert_empty; } } else { -insert_right: - insert_left = FALSE; +insert_empty: + ut_ad(!split_rec); buf = mem_alloc(rec_get_converted_size(cursor->index, tuple, n_ext)); From 65379cccc84bb5324413dfd6d3fd09b496612361 Mon Sep 17 00:00:00 2001 From: MySQL Build Team Date: Tue, 22 Jun 2010 21:52:43 +0200 Subject: [PATCH 044/112] Backport into build-201006221614-5.1.46sp1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit > ------------------------------------------------------------ > revno: 3351.14.74 > revision-id: marko.makela@oracle.com-20100504093128-44v6glupe1dsh0ug > parent: marko.makela@oracle.com-20100503122859-k73bl51re93o0mt4 > committer: Marko Mäkelä > branch nick: 5.1-innodb > timestamp: Tue 2010-05-04 12:31:28 +0300 > message: > btr_page_split_and_insert(): Correct the fix of Bug #52964. > When split_rec==NULL, choose the correct node pointer key (first_rec). --- storage/innodb_plugin/btr/btr0btr.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/storage/innodb_plugin/btr/btr0btr.c b/storage/innodb_plugin/btr/btr0btr.c index cd8f42b3818..1d6b4f5a0e6 100644 --- a/storage/innodb_plugin/btr/btr0btr.c +++ b/storage/innodb_plugin/btr/btr0btr.c @@ -2003,9 +2003,13 @@ func_start: split_rec = NULL; goto insert_empty; } + } else if (UNIV_UNLIKELY(insert_left)) { + first_rec = page_rec_get_next(page_get_infimum_rec(page)); + move_limit = page_rec_get_next(btr_cur_get_rec(cursor)); } else { insert_empty: ut_ad(!split_rec); + ut_ad(!insert_left); buf = mem_alloc(rec_get_converted_size(cursor->index, tuple, n_ext)); @@ -2029,7 +2033,11 @@ insert_empty: && btr_page_insert_fits(cursor, split_rec, offsets, tuple, n_ext, heap); } else { - mem_free(buf); + if (!insert_left) { + mem_free(buf); + buf = NULL; + } + insert_will_fit = !new_page_zip && btr_page_insert_fits(cursor, NULL, NULL, tuple, n_ext, heap); From 1cab479221f6d9fbe0fc44414b5b6a9bc7c9f009 Mon Sep 17 00:00:00 2001 From: MySQL Build Team Date: Tue, 22 Jun 2010 21:54:41 +0200 Subject: [PATCH 045/112] Backport into build-201006221614-5.1.46sp1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit > ------------------------------------------------------------ > revno: 3351.47.1 > revision-id: marko.makela@oracle.com-20100511104500-c6kzd0bg5s42p8e9 > parent: vasil.dimov@oracle.com-20100510132852-cz457uqvj8iiy9mm > committer: Marko Mäkelä > branch nick: mysql-5.1-innodb2 > timestamp: Tue 2010-05-11 13:45:00 +0300 > message: > Remove a stray expression. Spotted by Sunny Bains. --- storage/innodb_plugin/page/page0zip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innodb_plugin/page/page0zip.c b/storage/innodb_plugin/page/page0zip.c index aa5e39ff04a..a64a41ea518 100644 --- a/storage/innodb_plugin/page/page0zip.c +++ b/storage/innodb_plugin/page/page0zip.c @@ -571,7 +571,7 @@ page_zip_dir_encode( /* Traverse the list of stored records in the collation order, starting from the first user record. */ - rec = page + PAGE_NEW_INFIMUM, TRUE; + rec = page + PAGE_NEW_INFIMUM; i = 0; From e87a2d917b39043ce7124aae8788e8247e611211 Mon Sep 17 00:00:00 2001 From: MySQL Build Team Date: Tue, 22 Jun 2010 21:56:18 +0200 Subject: [PATCH 046/112] Backport into build-201006221614-5.1.46sp1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit > ------------------------------------------------------------ > revno: 3351.47.2 > revision-id: marko.makela@oracle.com-20100511104910-nim8kgguawpis7zo > parent: marko.makela@oracle.com-20100511104500-c6kzd0bg5s42p8e9 > committer: Marko Mäkelä > branch nick: mysql-5.1-innodb2 > timestamp: Tue 2010-05-11 13:49:10 +0300 > message: > btr_page_split_and_insert(): Add an assertion > suggested by Sunny Bains when reviewing Bug #52964. --- storage/innodb_plugin/btr/btr0btr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/storage/innodb_plugin/btr/btr0btr.c b/storage/innodb_plugin/btr/btr0btr.c index 1d6b4f5a0e6..0fd209e0216 100644 --- a/storage/innodb_plugin/btr/btr0btr.c +++ b/storage/innodb_plugin/btr/btr0btr.c @@ -2004,6 +2004,7 @@ func_start: goto insert_empty; } } else if (UNIV_UNLIKELY(insert_left)) { + ut_a(n_iterations > 0); first_rec = page_rec_get_next(page_get_infimum_rec(page)); move_limit = page_rec_get_next(btr_cur_get_rec(cursor)); } else { From f5a0316a3962ce34f3586574be5598d2bacd5ccb Mon Sep 17 00:00:00 2001 From: MySQL Build Team Date: Tue, 22 Jun 2010 21:59:35 +0200 Subject: [PATCH 047/112] Backport into build-201006221614-5.1.46sp1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit > ------------------------------------------------------------ > revno: 3351.14.47 > revision-id: marko.makela@oracle.com-20100421095033-0acvzxb8um8cms0a > parent: marko.makela@oracle.com-20100421094032-ir4glqk46qvg2ywn > committer: Marko Mäkelä > branch nick: 5.1-innodb > timestamp: Wed 2010-04-21 12:50:33 +0300 > message: > dtuple_convert_big_rec(): Store locally any fields whose maximum length > is less than 256 bytes. (Bug #52745) > Add related comments and debug assertions to the "offsets" > functions in rem0rec.c. > Approved by Sunny Bains --- storage/innodb_plugin/data/data0data.c | 15 +++++++ storage/innodb_plugin/rem/rem0rec.c | 59 +++++++++++++++++++++++++- 2 files changed, 72 insertions(+), 2 deletions(-) diff --git a/storage/innodb_plugin/data/data0data.c b/storage/innodb_plugin/data/data0data.c index e3c1f1b4f23..0715b49bf9c 100644 --- a/storage/innodb_plugin/data/data0data.c +++ b/storage/innodb_plugin/data/data0data.c @@ -666,6 +666,21 @@ dtuple_convert_big_rec( goto skip_field; } + /* In DYNAMIC and COMPRESSED format, store + locally any non-BLOB columns whose maximum + length does not exceed 256 bytes. This is + because there is no room for the "external + storage" flag when the maximum length is 255 + bytes or less. This restriction trivially + holds in REDUNDANT and COMPACT format, because + there we always store locally columns whose + length is up to local_len == 788 bytes. + @see rec_init_offsets_comp_ordinary */ + if (ifield->col->mtype != DATA_BLOB + && ifield->col->len < 256) { + goto skip_field; + } + longest_i = i; longest = savings; diff --git a/storage/innodb_plugin/rem/rem0rec.c b/storage/innodb_plugin/rem/rem0rec.c index 27c11dacc8c..59cf6e887d1 100644 --- a/storage/innodb_plugin/rem/rem0rec.c +++ b/storage/innodb_plugin/rem/rem0rec.c @@ -212,6 +212,13 @@ rec_get_n_extern_new( const dict_col_t* col = dict_field_get_col(field); len = *lens--; + /* If the maximum length of the field is up + to 255 bytes, the actual length is always + stored in one byte. If the maximum length is + more than 255 bytes, the actual length is + stored in one byte for 0..127. The length + will be encoded in two bytes when it is 128 or + more, or when the field is stored externally. */ if (UNIV_UNLIKELY(col->len > 255) || UNIV_UNLIKELY(col->mtype == DATA_BLOB)) { if (len & 0x80) { @@ -294,6 +301,13 @@ rec_init_offsets_comp_ordinary( const dict_col_t* col = dict_field_get_col(field); len = *lens--; + /* If the maximum length of the field is up + to 255 bytes, the actual length is always + stored in one byte. If the maximum length is + more than 255 bytes, the actual length is + stored in one byte for 0..127. The length + will be encoded in two bytes when it is 128 or + more, or when the field is stored externally. */ if (UNIV_UNLIKELY(col->len > 255) || UNIV_UNLIKELY(col->mtype == DATA_BLOB)) { @@ -425,6 +439,15 @@ rec_init_offsets( const dict_col_t* col = dict_field_get_col(field); len = *lens--; + /* If the maximum length of the field + is up to 255 bytes, the actual length + is always stored in one byte. If the + maximum length is more than 255 bytes, + the actual length is stored in one + byte for 0..127. The length will be + encoded in two bytes when it is 128 or + more, or when the field is stored + externally. */ if (UNIV_UNLIKELY(col->len > 255) || UNIV_UNLIKELY(col->mtype == DATA_BLOB)) { @@ -647,6 +670,13 @@ rec_get_offsets_reverse( const dict_col_t* col = dict_field_get_col(field); len = *lens++; + /* If the maximum length of the field is up + to 255 bytes, the actual length is always + stored in one byte. If the maximum length is + more than 255 bytes, the actual length is + stored in one byte for 0..127. The length + will be encoded in two bytes when it is 128 or + more, or when the field is stored externally. */ if (UNIV_UNLIKELY(col->len > 255) || UNIV_UNLIKELY(col->mtype == DATA_BLOB)) { if (len & 0x80) { @@ -781,12 +811,20 @@ rec_get_converted_size_comp_prefix( ut_ad(len <= col->len || col->mtype == DATA_BLOB); + /* If the maximum length of a variable-length field + is up to 255 bytes, the actual length is always stored + in one byte. If the maximum length is more than 255 + bytes, the actual length is stored in one byte for + 0..127. The length will be encoded in two bytes when + it is 128 or more, or when the field is stored externally. */ + if (field->fixed_len) { ut_ad(len == field->fixed_len); /* dict_index_add_col() should guarantee this */ ut_ad(!field->prefix_len || field->fixed_len == field->prefix_len); } else if (dfield_is_ext(&fields[i])) { + ut_ad(col->len >= 256 || col->mtype == DATA_BLOB); extra_size += 2; } else if (len < 128 || (col->len < 256 && col->mtype != DATA_BLOB)) { @@ -1086,6 +1124,8 @@ rec_convert_dtuple_to_rec_comp( /* Store the data and the offsets */ for (i = 0, field = fields; i < n_fields; i++, field++) { + const dict_field_t* ifield; + type = dfield_get_type(field); len = dfield_get_len(field); @@ -1120,12 +1160,20 @@ rec_convert_dtuple_to_rec_comp( /* only nullable fields can be null */ ut_ad(!dfield_is_null(field)); - fixed_len = dict_index_get_nth_field(index, i)->fixed_len; - + ifield = dict_index_get_nth_field(index, i); + fixed_len = ifield->fixed_len; + /* If the maximum length of a variable-length field + is up to 255 bytes, the actual length is always stored + in one byte. If the maximum length is more than 255 + bytes, the actual length is stored in one byte for + 0..127. The length will be encoded in two bytes when + it is 128 or more, or when the field is stored externally. */ if (fixed_len) { ut_ad(len == fixed_len); ut_ad(!dfield_is_ext(field)); } else if (dfield_is_ext(field)) { + ut_ad(ifield->col->len >= 256 + || ifield->col->mtype == DATA_BLOB); ut_ad(len <= REC_MAX_INDEX_COL_LEN + BTR_EXTERN_FIELD_REF_SIZE); *lens-- = (byte) (len >> 8) | 0xc0; @@ -1402,6 +1450,13 @@ rec_copy_prefix_to_buf( prefix_len += field->fixed_len; } else { ulint len = *lens--; + /* If the maximum length of the column is up + to 255 bytes, the actual length is always + stored in one byte. If the maximum length is + more than 255 bytes, the actual length is + stored in one byte for 0..127. The length + will be encoded in two bytes when it is 128 or + more, or when the column is stored externally. */ if (col->len > 255 || col->mtype == DATA_BLOB) { if (len & 0x80) { /* 1exxxxxx */ From 4f066e52694cb41ed950ed0a92d4518de9cd89bf Mon Sep 17 00:00:00 2001 From: MySQL Build Team Date: Tue, 22 Jun 2010 22:09:31 +0200 Subject: [PATCH 048/112] Backport into 5.1.46sp1: > revno: 3351.14.56 > committer: Marko Mdkeld > branch nick: 5.1-innodb > timestamp: Mon 2010-04-26 14:08:56 +0300 > message: > Add a test case for Bug #52745. --- .../innodb_plugin/r/innodb_bug52745.result | 130 ++++++++++++++++++ .../innodb_plugin/t/innodb_bug52745.test | 109 +++++++++++++++ 2 files changed, 239 insertions(+) create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_bug52745.result create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug52745.test diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug52745.result b/mysql-test/suite/innodb_plugin/r/innodb_bug52745.result new file mode 100644 index 00000000000..254c6525257 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug52745.result @@ -0,0 +1,130 @@ +SET GLOBAL innodb_file_format='Barracuda'; +SET GLOBAL innodb_file_per_table=on; +CREATE TABLE bug52745 ( +a2 int(10) unsigned DEFAULT NULL, +col37 time DEFAULT NULL, +col38 char(229) CHARACTER SET utf8 DEFAULT NULL, +col39 text, +col40 timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, +col41 int(10) unsigned DEFAULT NULL, +col42 varchar(248) CHARACTER SET utf8 DEFAULT NULL, +col43 smallint(5) unsigned zerofill DEFAULT NULL, +col44 varchar(150) CHARACTER SET utf8 DEFAULT NULL, +col45 float unsigned zerofill DEFAULT NULL, +col46 binary(1) DEFAULT NULL, +col47 tinyint(4) DEFAULT NULL, +col48 tinyint(1) DEFAULT NULL, +col49 timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', +col50 binary(1) DEFAULT NULL, +col51 double unsigned zerofill DEFAULT NULL, +col52 int(10) unsigned DEFAULT NULL, +col53 time DEFAULT NULL, +col54 double unsigned DEFAULT NULL, +col55 time DEFAULT NULL, +col56 mediumtext CHARACTER SET latin2, +col57 blob, +col58 decimal(52,16) unsigned zerofill NOT NULL DEFAULT '000000000000000000000000000000000000.0000000000000000', +col59 binary(1) DEFAULT NULL, +col60 longblob, +col61 time DEFAULT NULL, +col62 longtext CHARACTER SET utf8 COLLATE utf8_persian_ci, +col63 timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', +col64 int(10) unsigned DEFAULT NULL, +col65 date DEFAULT NULL, +col66 timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', +col67 binary(1) DEFAULT NULL, +col68 tinyblob, +col69 date DEFAULT NULL, +col70 tinyint(3) unsigned zerofill DEFAULT NULL, +col71 varchar(44) CHARACTER SET utf8 DEFAULT NULL, +col72 datetime DEFAULT NULL, +col73 smallint(5) unsigned zerofill DEFAULT NULL, +col74 longblob, +col75 bit(34) DEFAULT NULL, +col76 float unsigned zerofill DEFAULT NULL, +col77 year(2) DEFAULT NULL, +col78 tinyint(3) unsigned DEFAULT NULL, +col79 set('msfheowh','tbpxbgf','by','wahnrjw','myqfasxz','rsokyumrt') CHARACTER SET latin2 DEFAULT NULL, +col80 datetime DEFAULT NULL, +col81 smallint(6) DEFAULT NULL, +col82 enum('xtaurnqfqz','rifrse','kuzwpbvb','niisabk','zxavro','rbvasv','','uulrfaove','','') DEFAULT NULL, +col83 bigint(20) unsigned zerofill DEFAULT NULL, +col84 float unsigned zerofill DEFAULT NULL, +col85 double DEFAULT NULL, +col86 enum('ylannv','','vlkhycqc','snke','cxifustp','xiaxaswzp','oxl') CHARACTER SET latin1 COLLATE latin1_german2_ci DEFAULT NULL, +col87 varbinary(221) DEFAULT NULL, +col88 double unsigned DEFAULT NULL, +col89 float unsigned zerofill DEFAULT NULL, +col90 tinyblob +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; +Warnings: +Note 1291 Column 'col82' has duplicated value '' in ENUM +Note 1291 Column 'col82' has duplicated value '' in ENUM +INSERT INTO bug52745 SET +col40='0000-00-00 00:00:00', +col51=16547, +col53='7711484', +col54=-28604, +col55='7112612', +col56='wakefulness\'', +col57=repeat('absorbefacient\'',106), +col58=11027, +col59='AM09gW7', +col60=repeat('Noelani\'',16), +col61='2520576', +col62='substitutiv', +col63='19950106155112', +col64=-12038, +col65='86238806', +col66='19600719080256', +col68=repeat('Sagittarius\'',54), +col69='38943902', +col70=1232, +col71='Elora\'', +col74=repeat('zipp',11), +col75='0', +col76=23254, +col78=13247, +col79='56219', +col80='20500609035724', +col81=11632, +col82=7, +col84=-23863, +col85=6341, +col87='HZdkf.4 s7t,5Rmq 8so fmr,ruGLUG25TrtI.yQ 2SuHq0ML7rw7.4 b2yf2E5TJxOtBBZImezDnzpj,uPYfznnEUDN1e9aQoO 2DsplB7TFWy oQJ br HLF :F,eQ p4i1oWsr lL3PG,hjCz6hYqN h1QTjLCjrv:QCdSzpYBibJAtZCxLOk3l6Blsh.W', +col88=16894, +col89=6161, +col90=repeat('gale',48); +Warnings: +Warning 1265 Data truncated for column 'col53' at row 1 +Warning 1264 Out of range value for column 'col54' at row 1 +Warning 1265 Data truncated for column 'col59' at row 1 +Warning 1265 Data truncated for column 'col61' at row 1 +Warning 1264 Out of range value for column 'col64' at row 1 +Warning 1265 Data truncated for column 'col65' at row 1 +Warning 1264 Out of range value for column 'col66' at row 1 +Warning 1265 Data truncated for column 'col68' at row 1 +Warning 1265 Data truncated for column 'col69' at row 1 +Warning 1264 Out of range value for column 'col70' at row 1 +Warning 1264 Out of range value for column 'col78' at row 1 +Warning 1265 Data truncated for column 'col79' at row 1 +Warning 1264 Out of range value for column 'col84' at row 1 +SHOW WARNINGS; +Level Code Message +Warning 1265 Data truncated for column 'col53' at row 1 +Warning 1264 Out of range value for column 'col54' at row 1 +Warning 1265 Data truncated for column 'col59' at row 1 +Warning 1265 Data truncated for column 'col61' at row 1 +Warning 1264 Out of range value for column 'col64' at row 1 +Warning 1265 Data truncated for column 'col65' at row 1 +Warning 1264 Out of range value for column 'col66' at row 1 +Warning 1265 Data truncated for column 'col68' at row 1 +Warning 1265 Data truncated for column 'col69' at row 1 +Warning 1264 Out of range value for column 'col70' at row 1 +Warning 1264 Out of range value for column 'col78' at row 1 +Warning 1265 Data truncated for column 'col79' at row 1 +Warning 1264 Out of range value for column 'col84' at row 1 +DROP TABLE bug52745; +SET GLOBAL innodb_file_format=Antelope; +SET GLOBAL innodb_file_format_check=Antelope; +SET GLOBAL innodb_file_per_table=0; diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug52745.test b/mysql-test/suite/innodb_plugin/t/innodb_bug52745.test new file mode 100644 index 00000000000..b20a993a2d1 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug52745.test @@ -0,0 +1,109 @@ +-- source include/have_innodb_plugin.inc + +let $file_format=`select @@innodb_file_format`; +let $file_format_check=`select @@innodb_file_format_check`; +let $file_per_table=`select @@innodb_file_per_table`; +SET GLOBAL innodb_file_format='Barracuda'; +SET GLOBAL innodb_file_per_table=on; + +CREATE TABLE bug52745 ( + a2 int(10) unsigned DEFAULT NULL, + col37 time DEFAULT NULL, + col38 char(229) CHARACTER SET utf8 DEFAULT NULL, + col39 text, + col40 timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + col41 int(10) unsigned DEFAULT NULL, + col42 varchar(248) CHARACTER SET utf8 DEFAULT NULL, + col43 smallint(5) unsigned zerofill DEFAULT NULL, + col44 varchar(150) CHARACTER SET utf8 DEFAULT NULL, + col45 float unsigned zerofill DEFAULT NULL, + col46 binary(1) DEFAULT NULL, + col47 tinyint(4) DEFAULT NULL, + col48 tinyint(1) DEFAULT NULL, + col49 timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + col50 binary(1) DEFAULT NULL, + col51 double unsigned zerofill DEFAULT NULL, + col52 int(10) unsigned DEFAULT NULL, + col53 time DEFAULT NULL, + col54 double unsigned DEFAULT NULL, + col55 time DEFAULT NULL, + col56 mediumtext CHARACTER SET latin2, + col57 blob, + col58 decimal(52,16) unsigned zerofill NOT NULL DEFAULT '000000000000000000000000000000000000.0000000000000000', + col59 binary(1) DEFAULT NULL, + col60 longblob, + col61 time DEFAULT NULL, + col62 longtext CHARACTER SET utf8 COLLATE utf8_persian_ci, + col63 timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + col64 int(10) unsigned DEFAULT NULL, + col65 date DEFAULT NULL, + col66 timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + col67 binary(1) DEFAULT NULL, + col68 tinyblob, + col69 date DEFAULT NULL, + col70 tinyint(3) unsigned zerofill DEFAULT NULL, + col71 varchar(44) CHARACTER SET utf8 DEFAULT NULL, + col72 datetime DEFAULT NULL, + col73 smallint(5) unsigned zerofill DEFAULT NULL, + col74 longblob, + col75 bit(34) DEFAULT NULL, + col76 float unsigned zerofill DEFAULT NULL, + col77 year(2) DEFAULT NULL, + col78 tinyint(3) unsigned DEFAULT NULL, + col79 set('msfheowh','tbpxbgf','by','wahnrjw','myqfasxz','rsokyumrt') CHARACTER SET latin2 DEFAULT NULL, + col80 datetime DEFAULT NULL, + col81 smallint(6) DEFAULT NULL, + col82 enum('xtaurnqfqz','rifrse','kuzwpbvb','niisabk','zxavro','rbvasv','','uulrfaove','','') DEFAULT NULL, + col83 bigint(20) unsigned zerofill DEFAULT NULL, + col84 float unsigned zerofill DEFAULT NULL, + col85 double DEFAULT NULL, + col86 enum('ylannv','','vlkhycqc','snke','cxifustp','xiaxaswzp','oxl') CHARACTER SET latin1 COLLATE latin1_german2_ci DEFAULT NULL, + col87 varbinary(221) DEFAULT NULL, + col88 double unsigned DEFAULT NULL, + col89 float unsigned zerofill DEFAULT NULL, + col90 tinyblob +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; + +INSERT INTO bug52745 SET +col40='0000-00-00 00:00:00', +col51=16547, +col53='7711484', +col54=-28604, +col55='7112612', +col56='wakefulness\'', +col57=repeat('absorbefacient\'',106), +col58=11027, +col59='AM09gW7', +col60=repeat('Noelani\'',16), +col61='2520576', +col62='substitutiv', +col63='19950106155112', +col64=-12038, +col65='86238806', +col66='19600719080256', +col68=repeat('Sagittarius\'',54), +col69='38943902', +col70=1232, +col71='Elora\'', +col74=repeat('zipp',11), +col75='0', +col76=23254, +col78=13247, +col79='56219', +col80='20500609035724', +col81=11632, +col82=7, +col84=-23863, +col85=6341, +col87='HZdkf.4 s7t,5Rmq 8so fmr,ruGLUG25TrtI.yQ 2SuHq0ML7rw7.4 b2yf2E5TJxOtBBZImezDnzpj,uPYfznnEUDN1e9aQoO 2DsplB7TFWy oQJ br HLF :F,eQ p4i1oWsr lL3PG,hjCz6hYqN h1QTjLCjrv:QCdSzpYBibJAtZCxLOk3l6Blsh.W', +col88=16894, +col89=6161, +col90=repeat('gale',48); + +SHOW WARNINGS; + +DROP TABLE bug52745; + +EVAL SET GLOBAL innodb_file_format=$file_format; +EVAL SET GLOBAL innodb_file_format_check=$file_format_check; +EVAL SET GLOBAL innodb_file_per_table=$file_per_table; From 01490413d26cd31f319928e30724bd5a28e82e42 Mon Sep 17 00:00:00 2001 From: MySQL Build Team Date: Tue, 22 Jun 2010 22:34:48 +0200 Subject: [PATCH 049/112] Backport into build-201006221614-5.1.46sp1 > ------------------------------------------------------------ > revno: 1810.3987.13 > revision-id: ramil@mysql.com-20100429044232-f0pkyx8fnpszf142 > parent: alexey.kopytov@sun.com-20100426200600-op06qy98llzpzgl1 > committer: Ramil Kalimullin > branch nick: b53237-5.0-bugteam > timestamp: Thu 2010-04-29 08:42:32 +0400 > message: > Fix for bug #53237: mysql_list_fields/COM_FIELD_LIST stack smashing > > Problem: "COM_FIELD_LIST is an old command of the MySQL server, before there was real move to only > SQL. Seems that the data sent to COM_FIELD_LIST( mysql_list_fields() function) is not > checked for sanity. By sending long data for the table a buffer is overflown, which can > be used deliberately to include code that harms". > > Fix: check incoming data length. The patch did not apply cleanly: - Line numbers are completely off, roughly it is 2030 -> 1313 - What is called "pend" in the patch, is "arg_end" in the source. --- sql/sql_parse.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 5228a37f490..11481933c8a 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1300,8 +1300,16 @@ bool dispatch_command(enum enum_server_command command, THD *thd, We have name + wildcard in packet, separated by endzero */ arg_end= strend(packet); + uint arg_length= arg_end - packet; + + /* Check given table name length. */ + if (arg_length >= packet_length || arg_length > NAME_LEN) + { + my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0)); + break; + } thd->convert_string(&conv_name, system_charset_info, - packet, (uint) (arg_end - packet), thd->charset()); + packet, arg_length, thd->charset()); table_list.alias= table_list.table_name= conv_name.str; packet= arg_end + 1; From fb8791e2bc36c3da93540b68d86ff1f2c3ddb2b2 Mon Sep 17 00:00:00 2001 From: MySQL Build Team Date: Tue, 22 Jun 2010 22:51:35 +0200 Subject: [PATCH 050/112] Backport into build-201006221614-5.1.46sp1 > ------------------------------------------------------------ > revno: 1810.3987.14 > revision-id: davi.arnaut@sun.com-20100429132816-ictyul6d75itek22 > parent: ramil@mysql.com-20100429044232-f0pkyx8fnpszf142 > committer: Davi Arnaut > branch nick: 50974-5.0 > timestamp: Thu 2010-04-29 10:28:16 -0300 > message: > Bug#50974: Server keeps receiving big (> max_allowed_packet) packets indefinitely. > > The server could be tricked to read packets indefinitely if it > received a packet larger than the maximum size of one packet. > This problem is aggravated by the fact that it can be triggered > before authentication. > > The solution is to no skip big packets for non-authenticated > sessions. If a big packet is sent before a session is authen- > ticated, a error is returned and the connection is closed. > ------------------------------------------------------------ > revno: 3363 [merge] > revision-id: davi.arnaut@sun.com-20100429231819-i3anwzrdasjmezvt > parent: davi.arnaut@sun.com-20100401131522-895y8uzvv8ag44gs > parent: davi.arnaut@sun.com-20100429132816-ictyul6d75itek22 > committer: Davi Arnaut > branch nick: mysql-5.1-bugteam > timestamp: Thu 2010-04-29 20:18:19 -0300 > message: > Manual merge. > ------------------------------------------------------------ > Use --include-merges or -n0 to see merged revisions. --- include/mysql_com.h | 10 ++++++++++ sql/net_serv.cc | 4 ++++ sql/sql_connect.cc | 7 +++++++ 3 files changed, 21 insertions(+) diff --git a/include/mysql_com.h b/include/mysql_com.h index db5a5eb8741..7d3dd3d4f34 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -277,6 +277,16 @@ typedef struct st_net { /** Client library sqlstate buffer. Set along with the error message. */ char sqlstate[SQLSTATE_LENGTH+1]; void *extension; +#if defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY) + /* + Controls whether a big packet should be skipped. + + Initially set to FALSE by default. Unauthenticated sessions must have + this set to FALSE so that the server can't be tricked to read packets + indefinitely. + */ + my_bool skip_big_packet; +#endif } NET; diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 73892f31ccf..15c0c581108 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -136,6 +136,9 @@ my_bool my_net_init(NET *net, Vio* vio) #else net->query_cache_query= 0; #endif +#if defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY) + net->skip_big_packet= FALSE; +#endif if (vio != 0) /* If real connection */ { @@ -949,6 +952,7 @@ my_real_read(NET *net, size_t *complen) { #if defined(MYSQL_SERVER) && !defined(NO_ALARM) if (!net->compress && + net->skip_big_packet && !my_net_skip_rest(net, (uint32) len, &alarmed, &alarm_buff)) net->error= 3; /* Successfully skiped packet */ #endif diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 16f11fe22c4..2039c7f7449 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -471,6 +471,13 @@ check_user(THD *thd, enum enum_server_command command, } my_ok(thd); thd->password= test(passwd_len); // remember for error messages + /* + Allow the network layer to skip big packets. Although a malicious + authenticated session might use this to trick the server to read + big packets indefinitely, this is a previously established behavior + that needs to be preserved as to not break backwards compatibility. + */ + thd->net.skip_big_packet= TRUE; /* Ready to handle queries */ DBUG_RETURN(0); } From a0a850318b964ca92b660e0127c35061ad8f7a54 Mon Sep 17 00:00:00 2001 From: MySQL Build Team Date: Tue, 22 Jun 2010 22:53:01 +0200 Subject: [PATCH 051/112] Backport into build-201006221614-5.1.46sp1 > ------------------------------------------------------------ > revno: 3351.41.1 > revision-id: alexey.kopytov@sun.com-20100430111048-jdls6ofn4kkmpt09 > parent: sergey.glukhov@sun.com-20100329134249-03wyhzp5k92dzhcb > committer: Alexey Kopytov > branch nick: my51-bug48419 > timestamp: Fri 2010-04-30 15:10:48 +0400 > message: > Bug #48419: another explain crash.. > > WHERE predicates containing references to empty tables in a > subquery were handled incorrectly by the optimizer when > executing EXPLAIN. As a result, the optimizer could try to > evaluate such predicates rather than just stop with > "Impossible WHERE noticed after reading const tables" as > it would do in a non-subquery case. This led to valgrind > errors and crashes. > > Fixed the code checking the above condition so that subqueries > are not excluded and hence are handled in the same way as top > level SELECTs. --- mysql-test/r/explain.result | 12 ++++++++++++ mysql-test/r/ps.result | 12 ++++++------ mysql-test/t/explain.test | 15 +++++++++++++++ sql/sql_select.cc | 3 +-- 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/explain.result b/mysql-test/r/explain.result index b8db8b53e06..8f2d704b312 100644 --- a/mysql-test/r/explain.result +++ b/mysql-test/r/explain.result @@ -226,4 +226,16 @@ Warnings: Note 1276 Field or reference 'test.t1.c' of SELECT #2 was resolved in SELECT #1 Note 1003 select (select 1 from `test`.`t2` where (`test`.`t2`.`d` = NULL)) AS `(SELECT 1 FROM t2 WHERE d = c)` from `test`.`t1` DROP TABLE t1, t2; +# +# Bug #48419: another explain crash.. +# +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (b BLOB, KEY b(b(100))); +INSERT INTO t2 VALUES ('1'), ('2'), ('3'); +FLUSH TABLES; +EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT 1 FROM t1 t JOIN t2 WHERE b <= 1 AND t.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +DROP TABLE t1, t2; End of 5.1 tests. diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index cf08d763e5c..84b9cdf930c 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -155,24 +155,24 @@ execute stmt1 ; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 6 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table -5 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found -4 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found +5 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables execute stmt1 ; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 6 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table -5 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found -4 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found +5 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 6 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table -5 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found -4 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found +5 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables deallocate prepare stmt1; diff --git a/mysql-test/t/explain.test b/mysql-test/t/explain.test index 3c2f7bbbe96..ba6be72dbdc 100644 --- a/mysql-test/t/explain.test +++ b/mysql-test/t/explain.test @@ -198,4 +198,19 @@ INSERT INTO t2 VALUES (NULL), (0); EXPLAIN EXTENDED SELECT (SELECT 1 FROM t2 WHERE d = c) FROM t1; DROP TABLE t1, t2; + +--echo # +--echo # Bug #48419: another explain crash.. +--echo # + +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (b BLOB, KEY b(b(100))); +INSERT INTO t2 VALUES ('1'), ('2'), ('3'); + +FLUSH TABLES; + +EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT 1 FROM t1 t JOIN t2 WHERE b <= 1 AND t.a); + +DROP TABLE t1, t2; + --echo End of 5.1 tests. diff --git a/sql/sql_select.cc b/sql/sql_select.cc index a426f4b68a1..291432c2bb6 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1107,8 +1107,7 @@ JOIN::optimize() } if (conds && const_table_map != found_const_table_map && - (select_options & SELECT_DESCRIBE) && - select_lex->master_unit() == &thd->lex->unit) // upper level SELECT + (select_options & SELECT_DESCRIBE)) { conds=new Item_int((longlong) 0,1); // Always false } From 1ac84a45dfa6f4140ad97b3e026bf756cee6f1cc Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Tue, 22 Jun 2010 19:04:31 -0700 Subject: [PATCH 052/112] Fix bug #54044, Create temporary tables and using innodb crashes. Screen out NULL type columns, and return without creating the table. rb://378 approved by Marko --- .../suite/innodb/r/innodb_bug54044.result | 3 +++ .../suite/innodb/t/innodb_bug54044.test | 11 +++++++++ storage/innobase/handler/ha_innodb.cc | 24 +++++++++++++++++-- 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb_bug54044.result create mode 100644 mysql-test/suite/innodb/t/innodb_bug54044.test diff --git a/mysql-test/suite/innodb/r/innodb_bug54044.result b/mysql-test/suite/innodb/r/innodb_bug54044.result new file mode 100644 index 00000000000..9574381d8e1 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug54044.result @@ -0,0 +1,3 @@ +CREATE TEMPORARY TABLE TABLE_54044 ENGINE = INNODB +AS SELECT IF(NULL IS NOT NULL, NULL, NULL); +ERROR HY000: Can't create table 'test.TABLE_54044' (errno: -1) diff --git a/mysql-test/suite/innodb/t/innodb_bug54044.test b/mysql-test/suite/innodb/t/innodb_bug54044.test new file mode 100644 index 00000000000..824450ae1a6 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug54044.test @@ -0,0 +1,11 @@ +# This is the test for bug #54044. Special handle MYSQL_TYPE_NULL type +# during create table, so it will not trigger assertion failure. + +--source include/have_innodb.inc + +# This 'create table' operation should fail because of +# using NULL datatype +--error ER_CANT_CREATE_TABLE +CREATE TEMPORARY TABLE TABLE_54044 ENGINE = INNODB + AS SELECT IF(NULL IS NOT NULL, NULL, NULL); + diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 9990d7c28f0..d10fcb8d31e 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -3242,6 +3242,11 @@ get_innobase_type_from_mysql_type( case MYSQL_TYPE_BLOB: case MYSQL_TYPE_LONG_BLOB: return(DATA_BLOB); + case MYSQL_TYPE_NULL: + /* MySQL currently accepts "NULL" datatype, but will + reject such datatype in the next release. We will cope + with it and not trigger assertion failure in 5.1 */ + break; default: assert(0); } @@ -5263,7 +5268,22 @@ create_table_def( field = form->field[i]; col_type = get_innobase_type_from_mysql_type(&unsigned_type, - field); + field); + + if (!col_type) { + push_warning_printf( + (THD*) trx->mysql_thd, + MYSQL_ERROR::WARN_LEVEL_WARN, + ER_CANT_CREATE_TABLE, + "Error creating table '%s' with " + "column '%s'. Please check its " + "column type and try to re-create " + "the table with an appropriate " + "column type.", + table->name, (char*) field->field_name); + goto err_col; + } + if (field->null_ptr) { nulls_allowed = 0; } else { @@ -5320,7 +5340,7 @@ create_table_def( "different column name.", table->name, (char*) field->field_name, (char*) field->field_name); - +err_col: dict_mem_table_free(table); trx_commit_for_mysql(trx); From 95586f2c83e9ec1e7f7430546b187ee476be71c4 Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Tue, 22 Jun 2010 19:39:20 -0700 Subject: [PATCH 053/112] Port fix for "bug #54044 Create temporary tables and using innodb crashes" to 5.1 plugin codeline. rb://378, approved by Marko --- .../innodb_plugin/r/innodb_bug54044.result | 3 +++ .../innodb_plugin/t/innodb_bug54044.test | 11 +++++++++ storage/innodb_plugin/ChangeLog | 5 ++++ storage/innodb_plugin/handler/ha_innodb.cc | 24 +++++++++++++++++-- 4 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_bug54044.result create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug54044.test diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug54044.result b/mysql-test/suite/innodb_plugin/r/innodb_bug54044.result new file mode 100644 index 00000000000..9574381d8e1 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug54044.result @@ -0,0 +1,3 @@ +CREATE TEMPORARY TABLE TABLE_54044 ENGINE = INNODB +AS SELECT IF(NULL IS NOT NULL, NULL, NULL); +ERROR HY000: Can't create table 'test.TABLE_54044' (errno: -1) diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug54044.test b/mysql-test/suite/innodb_plugin/t/innodb_bug54044.test new file mode 100644 index 00000000000..824450ae1a6 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug54044.test @@ -0,0 +1,11 @@ +# This is the test for bug #54044. Special handle MYSQL_TYPE_NULL type +# during create table, so it will not trigger assertion failure. + +--source include/have_innodb.inc + +# This 'create table' operation should fail because of +# using NULL datatype +--error ER_CANT_CREATE_TABLE +CREATE TEMPORARY TABLE TABLE_54044 ENGINE = INNODB + AS SELECT IF(NULL IS NOT NULL, NULL, NULL); + diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 36bc5551a2b..d1d36bf812b 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,8 @@ +2010-06-22 The InnoDB Team + + * handler/ha_innodb.cc, innodb_bug54044.test, innodb_bug54044.result + Fix Bug#54044, Create temporary tables and using innodb crashes. + 2010-06-22 The InnoDB Team * dict/dict0dict.c, dict/dict0mem.c, include/dict0mem.h, diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index 3f8dc97e4b5..7d918a033ee 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -3950,6 +3950,11 @@ get_innobase_type_from_mysql_type( case MYSQL_TYPE_BLOB: case MYSQL_TYPE_LONG_BLOB: return(DATA_BLOB); + case MYSQL_TYPE_NULL: + /* MySQL currently accepts "NULL" datatype, but will + reject such datatype in the next release. We will cope + with it and not trigger assertion failure in 5.1 */ + break; default: ut_error; } @@ -6000,7 +6005,22 @@ create_table_def( field = form->field[i]; col_type = get_innobase_type_from_mysql_type(&unsigned_type, - field); + field); + + if (!col_type) { + push_warning_printf( + (THD*) trx->mysql_thd, + MYSQL_ERROR::WARN_LEVEL_WARN, + ER_CANT_CREATE_TABLE, + "Error creating table '%s' with " + "column '%s'. Please check its " + "column type and try to re-create " + "the table with an appropriate " + "column type.", + table->name, (char*) field->field_name); + goto err_col; + } + if (field->null_ptr) { nulls_allowed = 0; } else { @@ -6058,7 +6078,7 @@ create_table_def( if (dict_col_name_is_reserved(field->field_name)){ my_error(ER_WRONG_COLUMN_NAME, MYF(0), field->field_name); - +err_col: dict_mem_table_free(table); trx_commit_for_mysql(trx); From c658c3ed34b99e8fef0c41898ad295b1223071f3 Mon Sep 17 00:00:00 2001 From: sunanda Date: Wed, 23 Jun 2010 12:03:22 +0200 Subject: [PATCH 054/112] Backport into build-201006221614-5.1.46sp1 > ------------------------------------------------------------ > revno: 3367 [merge] > revision-id: joro@sun.com-20100504140328-srxf3c088j2twnq6 > parent: kristofer.pettersson@sun.com-20100503172109-f9hracq5pqsaomb1 > parent: joro@sun.com-20100503151651-nakknn8amrapmdp7 > committer: Georgi Kodinov > branch nick: B53371-5.1-bugteam > timestamp: Tue 2010-05-04 17:03:28 +0300 > message: > Bug #53371: COM_FIELD_LIST can be abused to bypass table level grants. > > This is the 5.1 merge and extension of the fix. > The server was happily accepting paths in table name in all places a table > name is accepted (e.g. a SELECT). This allowed all users that have some > privilege over some database to read all tables in all databases in all > mysql server instances that the server file system has access to. > Fixed by : > 1. making sure no path elements are allowed in quoted table name when > constructing the path (note that the path symbols are still valid in table names > when they're properly escaped by the server). > 2. checking the #mysql50# prefixed names the same way they're checked for > path elements in mysql-5.0. > ------------------------------------------------------------ > Use --include-merges or -n0 to see merged revisions. --- mysql-test/r/grant.result | 16 ++++++++++++++ mysql-test/t/grant.test | 25 ++++++++++++++++++++++ sql/mysql_priv.h | 2 +- sql/partition_info.cc | 4 ++-- sql/sql_parse.cc | 9 +++++++- sql/sql_table.cc | 14 ++++++++++++ sql/sql_yacc.yy | 2 +- sql/table.cc | 29 ++++++++++++++++++++++--- tests/mysql_client_test.c | 45 +++++++++++++++++++++++++++++++++++++++ 9 files changed, 138 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index 92beccd2a9e..6831ef6183d 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -1413,3 +1413,19 @@ DROP USER 'user1'; DROP USER 'user1'@'localhost'; DROP USER 'user2'; DROP DATABASE db1; +CREATE DATABASE db1; +CREATE DATABASE db2; +GRANT SELECT ON db1.* to 'testbug'@localhost; +USE db2; +CREATE TABLE t1 (a INT); +USE test; +SELECT * FROM `../db2/tb2`; +ERROR 42S02: Table 'db1.../db2/tb2' doesn't exist +SELECT * FROM `../db2`.tb2; +ERROR 42000: SELECT command denied to user 'testbug'@'localhost' for table 'tb2' +SELECT * FROM `#mysql50#/../db2/tb2`; +ERROR 42S02: Table 'db1.#mysql50#/../db2/tb2' doesn't exist +DROP USER 'testbug'@localhost; +DROP TABLE db2.t1; +DROP DATABASE db1; +DROP DATABASE db2; diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index bcd393bd6ab..cb8d3c63be8 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -1525,5 +1525,30 @@ DROP USER 'user1'@'localhost'; DROP USER 'user2'; DROP DATABASE db1; + +# +# Bug #53371: COM_FIELD_LIST can be abused to bypass table level grants. +# + +CREATE DATABASE db1; +CREATE DATABASE db2; +GRANT SELECT ON db1.* to 'testbug'@localhost; +USE db2; +CREATE TABLE t1 (a INT); +USE test; +connect (con1,localhost,testbug,,db1); +--error ER_NO_SUCH_TABLE +SELECT * FROM `../db2/tb2`; +--error ER_TABLEACCESS_DENIED_ERROR +SELECT * FROM `../db2`.tb2; +--error ER_NO_SUCH_TABLE +SELECT * FROM `#mysql50#/../db2/tb2`; +connection default; +disconnect con1; +DROP USER 'testbug'@localhost; +DROP TABLE db2.t1; +DROP DATABASE db1; +DROP DATABASE db2; + # Wait till we reached the initial number of concurrent sessions --source include/wait_until_count_sessions.inc diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 56175d069c5..3ecbef4d456 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -2263,7 +2263,7 @@ void update_create_info_from_table(HA_CREATE_INFO *info, TABLE *form); int rename_file_ext(const char * from,const char * to,const char * ext); bool check_db_name(LEX_STRING *db); bool check_column_name(const char *name); -bool check_table_name(const char *name, uint length); +bool check_table_name(const char *name, uint length, bool check_for_path_chars); char *get_field(MEM_ROOT *mem, Field *field); bool get_field(MEM_ROOT *mem, Field *field, class String *res); int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr); diff --git a/sql/partition_info.cc b/sql/partition_info.cc index ba9ea0e876e..6e2f7dfad26 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -972,7 +972,7 @@ bool partition_info::check_partition_info(THD *thd, handlerton **eng_type, part_elem->engine_type= default_engine_type; } if (check_table_name(part_elem->partition_name, - strlen(part_elem->partition_name))) + strlen(part_elem->partition_name), FALSE)) { my_error(ER_WRONG_PARTITION_NAME, MYF(0)); goto end; @@ -990,7 +990,7 @@ bool partition_info::check_partition_info(THD *thd, handlerton **eng_type, { sub_elem= sub_it++; if (check_table_name(sub_elem->partition_name, - strlen(sub_elem->partition_name))) + strlen(sub_elem->partition_name), FALSE)) { my_error(ER_WRONG_PARTITION_NAME, MYF(0)); goto end; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 11481933c8a..93d80164ffb 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1310,6 +1310,13 @@ bool dispatch_command(enum enum_server_command command, THD *thd, } thd->convert_string(&conv_name, system_charset_info, packet, arg_length, thd->charset()); + if (check_table_name(conv_name.str, conv_name.length, FALSE)) + { + /* this is OK due to convert_string() null-terminating the string */ + my_error(ER_WRONG_TABLE_NAME, MYF(0), conv_name.str); + break; + } + table_list.alias= table_list.table_name= conv_name.str; packet= arg_end + 1; @@ -6233,7 +6240,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, DBUG_RETURN(0); // End of memory alias_str= alias ? alias->str : table->table.str; if (!test(table_options & TL_OPTION_ALIAS) && - check_table_name(table->table.str, table->table.length)) + check_table_name(table->table.str, table->table.length, FALSE)) { my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str); DBUG_RETURN(0); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index ad72cab664e..84e6c721d72 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -435,7 +435,21 @@ uint tablename_to_filename(const char *from, char *to, uint to_length) DBUG_PRINT("enter", ("from '%s'", from)); if ((length= check_n_cut_mysql50_prefix(from, to, to_length))) + { + /* + Check if the name supplied is a valid mysql 5.0 name and + make the name a zero length string if it's not. + Note that just returning zero length is not enough : + a lot of places don't check the return value and expect + a zero terminated string. + */ + if (check_table_name(to, length, TRUE)) + { + to[0]= 0; + length= 0; + } DBUG_RETURN(length); + } length= strconvert(system_charset_info, from, &my_charset_filename, to, to_length, &errors); if (check_if_legal_tablename(to) && diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 4f43ab8bebd..f815da006b1 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -6133,7 +6133,7 @@ alter_list_item: { MYSQL_YYABORT; } - if (check_table_name($3->table.str,$3->table.length) || + if (check_table_name($3->table.str,$3->table.length, FALSE) || ($3->db.str && check_db_name(&$3->db))) { my_error(ER_WRONG_TABLE_NAME, MYF(0), $3->table.str); diff --git a/sql/table.cc b/sql/table.cc index a4e2c59fb87..04d7b3a8d0a 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -494,6 +494,26 @@ inline bool is_system_table_name(const char *name, uint length) } +/** + Check if a string contains path elements +*/ + +static inline bool has_disabled_path_chars(const char *str) +{ + for (; *str; str++) + switch (*str) + { + case FN_EXTCHAR: + case '/': + case '\\': + case '~': + case '@': + return TRUE; + } + return FALSE; +} + + /* Read table definition from a binary / text based .frm file @@ -549,7 +569,8 @@ int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags) This kind of tables must have been opened only by the my_open() above. */ - if (strchr(share->table_name.str, '@') || + if (has_disabled_path_chars(share->table_name.str) || + has_disabled_path_chars(share->db.str) || !strncmp(share->db.str, MYSQL50_TABLE_NAME_PREFIX, MYSQL50_TABLE_NAME_PREFIX_LENGTH) || !strncmp(share->table_name.str, MYSQL50_TABLE_NAME_PREFIX, @@ -2711,7 +2732,6 @@ bool check_db_name(LEX_STRING *org_name) (name_length > NAME_CHAR_LEN)); /* purecov: inspected */ } - /* Allow anything as a table name, as long as it doesn't contain an ' ' at the end @@ -2719,7 +2739,7 @@ bool check_db_name(LEX_STRING *org_name) */ -bool check_table_name(const char *name, uint length) +bool check_table_name(const char *name, uint length, bool check_for_path_chars) { uint name_length= 0; // name length in symbols const char *end= name+length; @@ -2746,6 +2766,9 @@ bool check_table_name(const char *name, uint length) continue; } } + if (check_for_path_chars && + (*name == '/' || *name == '\\' || *name == '~' || *name == FN_EXTCHAR)) + return 1; #endif name++; name_length++; diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index f65e549fd96..b99461ecd06 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -18049,6 +18049,50 @@ static void test_bug44495() DBUG_VOID_RETURN; } +static void test_bug53371() +{ + int rc; + MYSQL_RES *result; + + myheader("test_bug53371"); + + rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1"); + myquery(rc); + rc= mysql_query(mysql, "DROP DATABASE IF EXISTS bug53371"); + myquery(rc); + rc= mysql_query(mysql, "DROP USER 'testbug'@localhost"); + + rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)"); + myquery(rc); + rc= mysql_query(mysql, "CREATE DATABASE bug53371"); + myquery(rc); + rc= mysql_query(mysql, "GRANT SELECT ON bug53371.* to 'testbug'@localhost"); + myquery(rc); + + rc= mysql_change_user(mysql, "testbug", NULL, "bug53371"); + myquery(rc); + + rc= mysql_query(mysql, "SHOW COLUMNS FROM client_test_db.t1"); + DIE_UNLESS(rc); + DIE_UNLESS(mysql_errno(mysql) == 1142); + + result= mysql_list_fields(mysql, "../client_test_db/t1", NULL); + DIE_IF(result); + + result= mysql_list_fields(mysql, "#mysql50#/../client_test_db/t1", NULL); + DIE_IF(result); + + rc= mysql_change_user(mysql, opt_user, opt_password, current_db); + myquery(rc); + rc= mysql_query(mysql, "DROP TABLE t1"); + myquery(rc); + rc= mysql_query(mysql, "DROP DATABASE bug53371"); + myquery(rc); + rc= mysql_query(mysql, "DROP USER 'testbug'@localhost"); + myquery(rc); +} + + /* Read and parse arguments and MySQL options from my.cnf */ @@ -18358,6 +18402,7 @@ static struct my_tests_st my_tests[]= { { "test_bug30472", test_bug30472 }, { "test_bug20023", test_bug20023 }, { "test_bug45010", test_bug45010 }, + { "test_bug53371", test_bug53371 }, { "test_bug31418", test_bug31418 }, { "test_bug31669", test_bug31669 }, { "test_bug28386", test_bug28386 }, From 12c4c7a0ee06685e727d1fb0b8d6d5560a732816 Mon Sep 17 00:00:00 2001 From: sunanda Date: Wed, 23 Jun 2010 12:14:23 +0200 Subject: [PATCH 055/112] Backport into build-201006221614-5.1.46sp1 > ------------------------------------------------------------ > revno: 3386 > revision-id: sergey.glukhov@sun.com-20100518082821-yajhvbv1ghmlpu1n > parent: aelkin@mysql.com-20100516170332-x8priwrdjwolc065 > committer: Sergey Glukhov > branch nick: mysql-5.1-bugteam > timestamp: Tue 2010-05-18 13:28:21 +0500 > message: > Bug#48729 SELECT ... FROM INFORMATION_SCHEMA.ROUTINES causes memory to grow > Analysis showed that in case of accessing I_S table > ROUTINES we perform unnecessary allocations > with get_field() function for every processed row that > in their turn causes significant memory growth. > the fix is to avoid use of get_field(). --- sql/sql_show.cc | 74 ++++++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index cb60027842d..b4881125b14 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4180,24 +4180,37 @@ int fill_schema_coll_charset_app(THD *thd, TABLE_LIST *tables, COND *cond) } +static inline void copy_field_as_string(Field *to_field, Field *from_field) +{ + char buff[MAX_FIELD_WIDTH]; + String tmp_str(buff, sizeof(buff), system_charset_info); + from_field->val_str(&tmp_str); + to_field->store(tmp_str.ptr(), tmp_str.length(), system_charset_info); +} + + bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table, const char *wild, bool full_access, const char *sp_user) { - String tmp_string; - String sp_db, sp_name, definer; MYSQL_TIME time; LEX *lex= thd->lex; CHARSET_INFO *cs= system_charset_info; - get_field(thd->mem_root, proc_table->field[0], &sp_db); - get_field(thd->mem_root, proc_table->field[1], &sp_name); - get_field(thd->mem_root, proc_table->field[11], &definer); + char sp_db_buff[NAME_LEN + 1], sp_name_buff[NAME_LEN + 1], + definer_buff[USERNAME_LENGTH + HOSTNAME_LENGTH + 2]; + String sp_db(sp_db_buff, sizeof(sp_db_buff), cs); + String sp_name(sp_name_buff, sizeof(sp_name_buff), cs); + String definer(definer_buff, sizeof(definer_buff), cs); + + proc_table->field[0]->val_str(&sp_db); + proc_table->field[1]->val_str(&sp_name); + proc_table->field[11]->val_str(&definer); + if (!full_access) - full_access= !strcmp(sp_user, definer.ptr()); - if (!full_access && check_some_routine_access(thd, sp_db.ptr(), - sp_name.ptr(), - proc_table->field[2]-> - val_int() == - TYPE_ENUM_PROCEDURE)) + full_access= !strcmp(sp_user, definer.c_ptr_safe()); + if (!full_access && + check_some_routine_access(thd, sp_db.c_ptr_safe(), sp_name.c_ptr_safe(), + proc_table->field[2]->val_int() == + TYPE_ENUM_PROCEDURE)) return 0; if ((lex->sql_command == SQLCOM_SHOW_STATUS_PROC && @@ -4207,55 +4220,42 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table, (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0) { restore_record(table, s->default_values); - if (!wild || !wild[0] || !wild_compare(sp_name.ptr(), wild, 0)) + if (!wild || !wild[0] || !wild_compare(sp_name.c_ptr_safe(), wild, 0)) { int enum_idx= (int) proc_table->field[5]->val_int(); table->field[3]->store(sp_name.ptr(), sp_name.length(), cs); - get_field(thd->mem_root, proc_table->field[3], &tmp_string); - table->field[0]->store(tmp_string.ptr(), tmp_string.length(), cs); + copy_field_as_string(table->field[0], proc_table->field[3]); table->field[2]->store(sp_db.ptr(), sp_db.length(), cs); - get_field(thd->mem_root, proc_table->field[2], &tmp_string); - table->field[4]->store(tmp_string.ptr(), tmp_string.length(), cs); + copy_field_as_string(table->field[4], proc_table->field[2]); if (proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION) { - get_field(thd->mem_root, proc_table->field[9], &tmp_string); - table->field[5]->store(tmp_string.ptr(), tmp_string.length(), cs); + copy_field_as_string(table->field[5], proc_table->field[9]); table->field[5]->set_notnull(); } if (full_access) { - get_field(thd->mem_root, proc_table->field[19], &tmp_string); - table->field[7]->store(tmp_string.ptr(), tmp_string.length(), cs); + copy_field_as_string(table->field[7], proc_table->field[19]); table->field[7]->set_notnull(); } table->field[6]->store(STRING_WITH_LEN("SQL"), cs); table->field[10]->store(STRING_WITH_LEN("SQL"), cs); - get_field(thd->mem_root, proc_table->field[6], &tmp_string); - table->field[11]->store(tmp_string.ptr(), tmp_string.length(), cs); + copy_field_as_string(table->field[11], proc_table->field[6]); table->field[12]->store(sp_data_access_name[enum_idx].str, sp_data_access_name[enum_idx].length , cs); - get_field(thd->mem_root, proc_table->field[7], &tmp_string); - table->field[14]->store(tmp_string.ptr(), tmp_string.length(), cs); + copy_field_as_string(table->field[14], proc_table->field[7]); + bzero((char *)&time, sizeof(time)); ((Field_timestamp *) proc_table->field[12])->get_time(&time); table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); bzero((char *)&time, sizeof(time)); ((Field_timestamp *) proc_table->field[13])->get_time(&time); table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); - get_field(thd->mem_root, proc_table->field[14], &tmp_string); - table->field[17]->store(tmp_string.ptr(), tmp_string.length(), cs); - get_field(thd->mem_root, proc_table->field[15], &tmp_string); - table->field[18]->store(tmp_string.ptr(), tmp_string.length(), cs); + copy_field_as_string(table->field[17], proc_table->field[14]); + copy_field_as_string(table->field[18], proc_table->field[15]); table->field[19]->store(definer.ptr(), definer.length(), cs); - - get_field(thd->mem_root, proc_table->field[16], &tmp_string); - table->field[20]->store(tmp_string.ptr(), tmp_string.length(), cs); - - get_field(thd->mem_root, proc_table->field[17], &tmp_string); - table->field[21]->store(tmp_string.ptr(), tmp_string.length(), cs); - - get_field(thd->mem_root, proc_table->field[18], &tmp_string); - table->field[22]->store(tmp_string.ptr(), tmp_string.length(), cs); + copy_field_as_string(table->field[20], proc_table->field[16]); + copy_field_as_string(table->field[21], proc_table->field[17]); + copy_field_as_string(table->field[22], proc_table->field[18]); return schema_table_store_record(thd, table); } From 1c87c8b1eeaf06e77a2651bbff80ec1a0170547d Mon Sep 17 00:00:00 2001 From: sunanda Date: Wed, 23 Jun 2010 12:22:05 +0200 Subject: [PATCH 056/112] Backport into build-201006221614-5.1.46sp1 > ------------------------------------------------------------ > revno: 3392.1.1 > revision-id: gshchepa@mysql.com-20100521184732-0jvpzinv0uwyvr2d > parent: sven.sandberg@sun.com-20100520153801-yyhujm1qqa4eyfn0 > committer: Gleb Shchepa > branch nick: 53804-5.1 > timestamp: Fri 2010-05-21 22:47:32 +0400 > message: > Bug #53804: serious flaws in the alter database .. upgrade > data directory name command > > The check_db_name function has been modified to validate tails of > #mysql50#-prefixed database names for compliance with MySQL 5.0 > database name encoding rules (the check_table_name function call > has been reused). --- mysql-test/r/renamedb.result | 2 +- mysql-test/r/upgrade.result | 28 ++++++++++++++++++++++++++++ mysql-test/t/renamedb.test | 2 +- mysql-test/t/upgrade.test | 34 ++++++++++++++++++++++++++++++++++ sql/mysql_priv.h | 1 + sql/sql_table.cc | 23 ++++++++++++++++++++--- sql/table.cc | 34 ++++++++++------------------------ 7 files changed, 95 insertions(+), 29 deletions(-) diff --git a/mysql-test/r/renamedb.result b/mysql-test/r/renamedb.result index ff8f89592fc..e77aca0d0b7 100644 --- a/mysql-test/r/renamedb.result +++ b/mysql-test/r/renamedb.result @@ -7,6 +7,6 @@ ERROR HY000: Incorrect usage of ALTER DATABASE UPGRADE DATA DIRECTORY NAME and n ALTER DATABASE `#mysql51#not-yet` UPGRADE DATA DIRECTORY NAME; ERROR HY000: Incorrect usage of ALTER DATABASE UPGRADE DATA DIRECTORY NAME and name ALTER DATABASE `#mysql50#` UPGRADE DATA DIRECTORY NAME; -ERROR HY000: Incorrect usage of ALTER DATABASE UPGRADE DATA DIRECTORY NAME and name +ERROR 42000: Incorrect database name '#mysql50#' ALTER DATABASE `#mysql50#upgrade-me` UPGRADE DATA DIRECTORY NAME; ERROR 42000: Unknown database '#mysql50#upgrade-me' diff --git a/mysql-test/r/upgrade.result b/mysql-test/r/upgrade.result index 034242079b1..da2f55b5bb1 100644 --- a/mysql-test/r/upgrade.result +++ b/mysql-test/r/upgrade.result @@ -112,3 +112,31 @@ select * from `a-b-c`.v1; f1 drop database `a-b-c`; use test; +# End of 5.0 tests +# +# Bug #53804: serious flaws in the alter database .. upgrade data +# directory name command +# +ALTER DATABASE `#mysql50#:` UPGRADE DATA DIRECTORY NAME; +ERROR 42000: Unknown database '#mysql50#:' +ALTER DATABASE `#mysql50#.` UPGRADE DATA DIRECTORY NAME; +ERROR 42000: Incorrect database name '#mysql50#.' +ALTER DATABASE `#mysql50#../` UPGRADE DATA DIRECTORY NAME; +ERROR 42000: Incorrect database name '#mysql50#../' +ALTER DATABASE `#mysql50#../..` UPGRADE DATA DIRECTORY NAME; +ERROR 42000: Incorrect database name '#mysql50#../..' +ALTER DATABASE `#mysql50#../../` UPGRADE DATA DIRECTORY NAME; +ERROR 42000: Incorrect database name '#mysql50#../../' +ALTER DATABASE `#mysql50#./blablabla` UPGRADE DATA DIRECTORY NAME; +ERROR 42000: Incorrect database name '#mysql50#./blablabla' +ALTER DATABASE `#mysql50#../blablabla` UPGRADE DATA DIRECTORY NAME; +ERROR 42000: Incorrect database name '#mysql50#../blablabla' +ALTER DATABASE `#mysql50#/` UPGRADE DATA DIRECTORY NAME; +ERROR 42000: Incorrect database name '#mysql50#/' +ALTER DATABASE `#mysql50#/.` UPGRADE DATA DIRECTORY NAME; +ERROR 42000: Incorrect database name '#mysql50#/.' +USE `#mysql50#.`; +ERROR 42000: Incorrect database name '#mysql50#.' +USE `#mysql50#../blablabla`; +ERROR 42000: Incorrect database name '#mysql50#../blablabla' +# End of 5.1 tests diff --git a/mysql-test/t/renamedb.test b/mysql-test/t/renamedb.test index 84315090b7a..71d0c127058 100644 --- a/mysql-test/t/renamedb.test +++ b/mysql-test/t/renamedb.test @@ -44,7 +44,7 @@ ALTER DATABASE `#mysql41#not-supported` UPGRADE DATA DIRECTORY NAME; --error ER_WRONG_USAGE ALTER DATABASE `#mysql51#not-yet` UPGRADE DATA DIRECTORY NAME; ---error ER_WRONG_USAGE +--error ER_WRONG_DB_NAME ALTER DATABASE `#mysql50#` UPGRADE DATA DIRECTORY NAME; --error ER_BAD_DB_ERROR diff --git a/mysql-test/t/upgrade.test b/mysql-test/t/upgrade.test index e390e8a1253..a7b9a1531ff 100644 --- a/mysql-test/t/upgrade.test +++ b/mysql-test/t/upgrade.test @@ -137,3 +137,37 @@ select * from `a-b-c`.v1; --enable_ps_protocol drop database `a-b-c`; use test; + +--echo # End of 5.0 tests + +--echo # +--echo # Bug #53804: serious flaws in the alter database .. upgrade data +--echo # directory name command +--echo # + +--error ER_BAD_DB_ERROR +ALTER DATABASE `#mysql50#:` UPGRADE DATA DIRECTORY NAME; +--error ER_WRONG_DB_NAME +ALTER DATABASE `#mysql50#.` UPGRADE DATA DIRECTORY NAME; +--error ER_WRONG_DB_NAME +ALTER DATABASE `#mysql50#../` UPGRADE DATA DIRECTORY NAME; +--error ER_WRONG_DB_NAME +ALTER DATABASE `#mysql50#../..` UPGRADE DATA DIRECTORY NAME; +--error ER_WRONG_DB_NAME +ALTER DATABASE `#mysql50#../../` UPGRADE DATA DIRECTORY NAME; +--error ER_WRONG_DB_NAME +ALTER DATABASE `#mysql50#./blablabla` UPGRADE DATA DIRECTORY NAME; +--error ER_WRONG_DB_NAME +ALTER DATABASE `#mysql50#../blablabla` UPGRADE DATA DIRECTORY NAME; +--error ER_WRONG_DB_NAME +ALTER DATABASE `#mysql50#/` UPGRADE DATA DIRECTORY NAME; +--error ER_WRONG_DB_NAME +ALTER DATABASE `#mysql50#/.` UPGRADE DATA DIRECTORY NAME; + +--error ER_WRONG_DB_NAME +USE `#mysql50#.`; +--error ER_WRONG_DB_NAME +USE `#mysql50#../blablabla`; + +--echo # End of 5.1 tests + diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 3ecbef4d456..30f3a1af437 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -2287,6 +2287,7 @@ uint explain_filename(THD* thd, const char *from, char *to, uint to_length, uint filename_to_tablename(const char *from, char *to, uint to_length); uint tablename_to_filename(const char *from, char *to, uint to_length); uint check_n_cut_mysql50_prefix(const char *from, char *to, uint to_length); +bool check_mysql50_prefix(const char *name); #endif /* MYSQL_SERVER || INNODB_COMPATIBILITY_HOOKS */ #ifdef MYSQL_SERVER uint build_table_filename(char *buff, size_t bufflen, const char *db, diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 84e6c721d72..babc025db87 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -391,6 +391,25 @@ uint filename_to_tablename(const char *from, char *to, uint to_length) } +/** + Check if given string begins with "#mysql50#" prefix + + @param name string to check cut + + @retval + FALSE no prefix found + @retval + TRUE prefix found +*/ + +bool check_mysql50_prefix(const char *name) +{ + return (name[0] == '#' && + !strncmp(name, MYSQL50_TABLE_NAME_PREFIX, + MYSQL50_TABLE_NAME_PREFIX_LENGTH)); +} + + /** Check if given string begins with "#mysql50#" prefix, cut it if so. @@ -406,9 +425,7 @@ uint filename_to_tablename(const char *from, char *to, uint to_length) uint check_n_cut_mysql50_prefix(const char *from, char *to, uint to_length) { - if (from[0] == '#' && - !strncmp(from, MYSQL50_TABLE_NAME_PREFIX, - MYSQL50_TABLE_NAME_PREFIX_LENGTH)) + if (check_mysql50_prefix(from)) return (uint) (strmake(to, from + MYSQL50_TABLE_NAME_PREFIX_LENGTH, to_length - 1) - to); return 0; diff --git a/sql/table.cc b/sql/table.cc index 04d7b3a8d0a..23d41760495 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2701,44 +2701,30 @@ bool check_db_name(LEX_STRING *org_name) { char *name= org_name->str; uint name_length= org_name->length; + bool check_for_path_chars; if (!name_length || name_length > NAME_LEN) return 1; + if ((check_for_path_chars= check_mysql50_prefix(name))) + { + name+= MYSQL50_TABLE_NAME_PREFIX_LENGTH; + name_length-= MYSQL50_TABLE_NAME_PREFIX_LENGTH; + } + if (lower_case_table_names && name != any_db) my_casedn_str(files_charset_info, name); -#if defined(USE_MB) && defined(USE_MB_IDENT) - if (use_mb(system_charset_info)) - { - name_length= 0; - bool last_char_is_space= TRUE; - char *end= name + org_name->length; - while (name < end) - { - int len; - last_char_is_space= my_isspace(system_charset_info, *name); - len= my_ismbchar(system_charset_info, name, end); - if (!len) - len= 1; - name+= len; - name_length++; - } - return (last_char_is_space || name_length > NAME_CHAR_LEN); - } - else -#endif - return ((org_name->str[org_name->length - 1] != ' ') || - (name_length > NAME_CHAR_LEN)); /* purecov: inspected */ + return check_table_name(name, name_length, check_for_path_chars); } + /* Allow anything as a table name, as long as it doesn't contain an ' ' at the end returns 1 on error */ - bool check_table_name(const char *name, uint length, bool check_for_path_chars) { uint name_length= 0; // name length in symbols @@ -2766,10 +2752,10 @@ bool check_table_name(const char *name, uint length, bool check_for_path_chars) continue; } } +#endif if (check_for_path_chars && (*name == '/' || *name == '\\' || *name == '~' || *name == FN_EXTCHAR)) return 1; -#endif name++; name_length++; } From f801ca68c65167a82f0dc2619540ef1c83e7826b Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 9 Jul 2010 16:37:52 -0300 Subject: [PATCH 057/112] Use UNINIT_VAR workaround instead of LINT_INIT. --- client/mysqlshow.c | 3 +-- regex/regcomp.c | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/client/mysqlshow.c b/client/mysqlshow.c index 2f5582cb668..8c64d61ded2 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -669,8 +669,7 @@ list_fields(MYSQL *mysql,const char *db,const char *table, char query[1024],*end; MYSQL_RES *result; MYSQL_ROW row; - ulong rows; - LINT_INIT(rows); + ulong UNINIT_VAR(rows); if (mysql_select_db(mysql,db)) { diff --git a/regex/regcomp.c b/regex/regcomp.c index 8280fbfd6c8..81c435ed552 100644 --- a/regex/regcomp.c +++ b/regex/regcomp.c @@ -1563,13 +1563,13 @@ struct parse *p; register struct re_guts *g; { register sop *scan; - sop *start; - register sop *newstart; + sop *UNINIT_VAR(start); + register sop *UNINIT_VAR(newstart); register sopno newlen; register sop s; register char *cp; register sopno i; - LINT_INIT(start); LINT_INIT(newstart); + /* avoid making error situations worse */ if (p->error != 0) return; From 266ca421da5903a97a7a52fed2032afab5df74d6 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 9 Jul 2010 14:11:12 +0300 Subject: [PATCH 058/112] Bug #52274 : Missing path to mysql in mysql_secure_installation Added some code to try to find the mysql command line in the most common places and stop if it's not there. --- scripts/mysql_secure_installation.sh | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/scripts/mysql_secure_installation.sh b/scripts/mysql_secure_installation.sh index 25d6343ee2c..188cd030dba 100644 --- a/scripts/mysql_secure_installation.sh +++ b/scripts/mysql_secure_installation.sh @@ -17,6 +17,7 @@ config=".my.cnf.$$" command=".mysql.$$" +mysql_client="" trap "interrupt" 2 @@ -37,10 +38,26 @@ prepare() { chmod 600 $config $command } +find_mysql_client() +{ + for n in ./bin/mysql mysql + do + $n --no-defaults --help > /dev/null 2>&1 + status=$? + if test $status -eq 0 + then + mysql_client=$n + return + fi + done + echo "Can't find a 'mysql' client in PATH or ./bin" + exit 1 +} + do_query() { echo "$1" >$command #sed 's,^,> ,' < $command # Debugging - mysql --defaults-file=$config <$command + $mysql_client --defaults-file=$config <$command return $? } @@ -204,6 +221,7 @@ cleanup() { # The actual script starts here prepare +find_mysql_client set_echo_compat echo From 1919414fbea08e73d326b92356b89133ed447e1d Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 14 Jul 2010 13:53:49 +0300 Subject: [PATCH 059/112] Bug #54004 : mysql_secure_installation identifies "local host" incorrectly The removal of non-local root users is overzealous in mysql_secure_installation. (Bug #54004) --- scripts/mysql_secure_installation.pl.in | 2 +- scripts/mysql_secure_installation.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/mysql_secure_installation.pl.in b/scripts/mysql_secure_installation.pl.in index 25339f9b916..0cd99267cdb 100755 --- a/scripts/mysql_secure_installation.pl.in +++ b/scripts/mysql_secure_installation.pl.in @@ -208,7 +208,7 @@ sub remove_anonymous_users { } sub remove_remote_root { - if (do_query("DELETE FROM mysql.user WHERE User='root' AND Host!='localhost';")) { + if (do_query("DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');")) { print " ... Success!\n"; } else { print " ... Failed!\n"; diff --git a/scripts/mysql_secure_installation.sh b/scripts/mysql_secure_installation.sh index 188cd030dba..ed789677bf0 100644 --- a/scripts/mysql_secure_installation.sh +++ b/scripts/mysql_secure_installation.sh @@ -164,7 +164,7 @@ remove_anonymous_users() { } remove_remote_root() { - do_query "DELETE FROM mysql.user WHERE User='root' AND Host!='localhost';" + do_query "DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');" if [ $? -eq 0 ]; then echo " ... Success!" else From 678640019debce6c77109dc5f52e323eaee45a9f Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 14 Jul 2010 11:50:17 +0300 Subject: [PATCH 060/112] Bug #53493 : add_to_status does not handle the longlong fields in STATUS_VAR bytes_received/bytes_sent are ulonglong so they cannot be handled by the ulong handling code in add_to_status/add_diff_to_status(). Fixed by adding code to handle these two variables in add_to_status()/add_diff_to_status() and making sure they are not a subject to the ulong handling code. --- sql/sql_class.cc | 6 ++++++ sql/sql_class.h | 17 ++++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 2ce03708a9a..1028a9fccf4 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1063,6 +1063,9 @@ void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var) while (to != end) *(to++)+= *(from++); + + to_var->bytes_received+= from_var->bytes_received; + to_var->bytes_sent+= from_var->bytes_sent; } /* @@ -1088,6 +1091,9 @@ void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var, while (to != end) *(to++)+= *(from++) - *(dec++); + + to_var->bytes_received+= from_var->bytes_received - dec_var->bytes_received;; + to_var->bytes_sent+= from_var->bytes_sent - dec_var->bytes_sent; } diff --git a/sql/sql_class.h b/sql/sql_class.h index 5155ffe0603..1627b6ec02d 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -405,12 +405,14 @@ struct system_variables }; -/* per thread status variables */ +/** + Per thread status variables. + Must be long/ulong up to last_system_status_var so that + add_to_status/add_diff_to_status can work. +*/ typedef struct system_status_var { - ulonglong bytes_received; - ulonglong bytes_sent; ulong com_other; ulong com_stat[(uint) SQLCOM_END]; ulong created_tmp_disk_tables; @@ -466,13 +468,14 @@ typedef struct system_status_var Number of statements sent from the client */ ulong questions; + + ulonglong bytes_received; + ulonglong bytes_sent; /* IMPORTANT! SEE last_system_status_var DEFINITION BELOW. - Below 'last_system_status_var' are all variables which doesn't make any - sense to add to the /global/ status variable counter. - Status variables which it does not make sense to add to - global status variable counter + Below 'last_system_status_var' are all variables that cannot be handled + automatically by add_to_status()/add_diff_to_status(). */ double last_query_cost; } STATUS_VAR; From dbb643d64e0981f56b6c7b35586f430b08091834 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 14 Jul 2010 14:54:51 +0300 Subject: [PATCH 061/112] Bug #51876: crash/memory underrun when loading data with ucs2 and reverse() function 3 problems fixed : 1. The reported problem : caused by incorrect parsing of the file as ucs data resulting in wrong length of the parsed string. Fixed by truncating the invalid trailing bytes (non-complete multibyte characters) when reading from the file 2. LOAD DATA when reading from a proper UCS2 file wasn't recognizing the new line characters. Fixed by first looking if a byte is a new line (or any other special) character before reading it as a part of a multibyte character. 3. When using user variables to hold the column data in LOAD DATA the character set of the user variable was set incorrectly to the database charset. Fixed by setting it to the charset specified by LOAD DATA (if any). --- mysql-test/r/loaddata.result | 29 +++++++++++++++++++ mysql-test/t/loaddata.test | 32 +++++++++++++++++++++ sql/item_func.cc | 5 +++- sql/sql_load.cc | 56 +++++++++++++++++++++--------------- 4 files changed, 98 insertions(+), 24 deletions(-) diff --git a/mysql-test/r/loaddata.result b/mysql-test/r/loaddata.result index 665e80b8ba2..40c278380b1 100644 --- a/mysql-test/r/loaddata.result +++ b/mysql-test/r/loaddata.result @@ -503,4 +503,33 @@ DROP TABLE t1; CREATE TABLE t1 (id INT NOT NULL); LOAD DATA LOCAL INFILE 'tb.txt' INTO TABLE t1; DROP TABLE t1; +# +# Bug #51876 : crash/memory underrun when loading data with ucs2 +# and reverse() function +# +# Problem # 1 (original report): wrong parsing of ucs2 data +SELECT '00' UNION SELECT '10' INTO OUTFILE 'tmpp.txt'; +CREATE TABLE t1(a INT); +LOAD DATA INFILE 'tmpp.txt' INTO TABLE t1 CHARACTER SET ucs2 +(@b) SET a=REVERSE(@b); +Warnings: +Warning 1366 Incorrect integer value: '00' for column 'a' at row 1 +Warning 1366 Incorrect integer value: '10' for column 'a' at row 2 +# should return 2 zeroes (as the value is truncated) +SELECT * FROM t1; +a +0 +0 +DROP TABLE t1; +# Problem # 2 : if you write and read ucs2 data to a file they're lost +SELECT '00' UNION SELECT '10' INTO OUTFILE 'tmpp2.txt' CHARACTER SET ucs2; +CREATE TABLE t1(a INT); +LOAD DATA INFILE 'tmpp2.txt' INTO TABLE t1 CHARACTER SET ucs2 +(@b) SET a=REVERSE(@b); +# should return 0 and 1 (10 reversed) +SELECT * FROM t1; +a +0 +1 +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/t/loaddata.test b/mysql-test/t/loaddata.test index e24f0b16705..821453777f5 100644 --- a/mysql-test/t/loaddata.test +++ b/mysql-test/t/loaddata.test @@ -580,4 +580,36 @@ DROP TABLE t1; connection default; disconnect con1; + +--echo # +--echo # Bug #51876 : crash/memory underrun when loading data with ucs2 +--echo # and reverse() function +--echo # + +--echo # Problem # 1 (original report): wrong parsing of ucs2 data +SELECT '00' UNION SELECT '10' INTO OUTFILE 'tmpp.txt'; +CREATE TABLE t1(a INT); +LOAD DATA INFILE 'tmpp.txt' INTO TABLE t1 CHARACTER SET ucs2 +(@b) SET a=REVERSE(@b); +--echo # should return 2 zeroes (as the value is truncated) +SELECT * FROM t1; + +DROP TABLE t1; +let $MYSQLD_DATADIR= `select @@datadir`; +remove_file $MYSQLD_DATADIR/test/tmpp.txt; + + +--echo # Problem # 2 : if you write and read ucs2 data to a file they're lost +SELECT '00' UNION SELECT '10' INTO OUTFILE 'tmpp2.txt' CHARACTER SET ucs2; +CREATE TABLE t1(a INT); +LOAD DATA INFILE 'tmpp2.txt' INTO TABLE t1 CHARACTER SET ucs2 +(@b) SET a=REVERSE(@b); +--echo # should return 0 and 1 (10 reversed) +SELECT * FROM t1; + +DROP TABLE t1; +let $MYSQLD_DATADIR= `select @@datadir`; +remove_file $MYSQLD_DATADIR/test/tmpp2.txt; + + --echo End of 5.1 tests diff --git a/sql/item_func.cc b/sql/item_func.cc index 1e31755179b..1bec4700bff 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4715,6 +4715,7 @@ bool Item_func_get_user_var::set_value(THD *thd, bool Item_user_var_as_out_param::fix_fields(THD *thd, Item **ref) { DBUG_ASSERT(fixed == 0); + DBUG_ASSERT(thd->lex->exchange); if (Item::fix_fields(thd, ref) || !(entry= get_variable(&thd->user_vars, name, 1))) return TRUE; @@ -4724,7 +4725,9 @@ bool Item_user_var_as_out_param::fix_fields(THD *thd, Item **ref) of fields in LOAD DATA INFILE. (Since Item_user_var_as_out_param is used only there). */ - entry->collation.set(thd->variables.collation_database); + entry->collation.set(thd->lex->exchange->cs ? + thd->lex->exchange->cs : + thd->variables.collation_database); entry->update_query_id= thd->query_id; return FALSE; } diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 552473e4fc2..ee7481234a4 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -1208,29 +1208,6 @@ int READ_INFO::read_field() while ( to < end_of_buff) { chr = GET; -#ifdef USE_MB - if ((my_mbcharlen(read_charset, chr) > 1) && - to+my_mbcharlen(read_charset, chr) <= end_of_buff) - { - uchar* p = (uchar*)to; - *to++ = chr; - int ml = my_mbcharlen(read_charset, chr); - int i; - for (i=1; i 1 && + to + my_mbcharlen(read_charset, chr) <= end_of_buff) + { + uchar* p= (uchar*) to; + int ml, i; + *to++ = chr; + + ml= my_mbcharlen(read_charset, chr); + + for (i= 1; i < ml; i++) + { + chr= GET; + if (chr == my_b_EOF) + { + /* + Need to back up the bytes already ready from illformed + multi-byte char + */ + to-= i; + goto found_eof; + } + *to++ = chr; + } + if (my_ismbchar(read_charset, + (const char *)p, + (const char *)to)) + continue; + for (i= 0; i < ml; i++) + PUSH((uchar) *--to); + chr= GET; + } +#endif *to++ = (uchar) chr; } /* From ce78970202c076b5c9967ea4e31e5add94c73d82 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Wed, 14 Jul 2010 10:10:12 -0300 Subject: [PATCH 062/112] Bug#48327: Some crashes specific to FreeBSD ("embedded") Backport fixes from ndb: Rework the constructors of some static object's to not call dbug functions since the constructors will be called before main, and consequently, before the dbug library is initialized. --- storage/ndb/src/common/portlib/NdbMutex.c | 21 ++++++--------- storage/ndb/src/ndbapi/DictCache.cpp | 32 ++++++++++++++++++----- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/storage/ndb/src/common/portlib/NdbMutex.c b/storage/ndb/src/common/portlib/NdbMutex.c index c9184e5d1f2..5595baba7c4 100644 --- a/storage/ndb/src/common/portlib/NdbMutex.c +++ b/storage/ndb/src/common/portlib/NdbMutex.c @@ -24,36 +24,31 @@ NdbMutex* NdbMutex_Create(void) { NdbMutex* pNdbMutex; int result; - DBUG_ENTER("NdbMutex_Create"); - + pNdbMutex = (NdbMutex*)NdbMem_Allocate(sizeof(NdbMutex)); - DBUG_PRINT("info",("NdbMem_Allocate 0x%lx", (long) pNdbMutex)); - + if (pNdbMutex == NULL) - DBUG_RETURN(NULL); - + return NULL; + result = pthread_mutex_init(pNdbMutex, NULL); assert(result == 0); - - DBUG_RETURN(pNdbMutex); + + return pNdbMutex; } int NdbMutex_Destroy(NdbMutex* p_mutex) { int result; - DBUG_ENTER("NdbMutex_Destroy"); if (p_mutex == NULL) - DBUG_RETURN(-1); + return -1; result = pthread_mutex_destroy(p_mutex); - DBUG_PRINT("info",("NdbMem_Free 0x%lx", (long) p_mutex)); NdbMem_Free(p_mutex); - - DBUG_RETURN(result); + return result; } diff --git a/storage/ndb/src/ndbapi/DictCache.cpp b/storage/ndb/src/ndbapi/DictCache.cpp index 04be3711847..9c66b2be9d2 100644 --- a/storage/ndb/src/ndbapi/DictCache.cpp +++ b/storage/ndb/src/ndbapi/DictCache.cpp @@ -20,8 +20,10 @@ #include #include -static NdbTableImpl f_invalid_table; -static NdbTableImpl f_altered_table; +static NdbTableImpl * f_invalid_table = 0; +static NdbTableImpl * f_altered_table = 0; + +static int ndb_dict_cache_count = 0; Ndb_local_table_info * Ndb_local_table_info::create(NdbTableImpl *table_impl, Uint32 sz) @@ -93,11 +95,29 @@ GlobalDictCache::GlobalDictCache(){ DBUG_ENTER("GlobalDictCache::GlobalDictCache"); m_tableHash.createHashTable(); m_waitForTableCondition = NdbCondition_Create(); + if (f_invalid_table == NULL) + f_invalid_table = new NdbTableImpl(); + if (f_altered_table == NULL) + f_altered_table = new NdbTableImpl(); + ndb_dict_cache_count++; DBUG_VOID_RETURN; } GlobalDictCache::~GlobalDictCache(){ DBUG_ENTER("GlobalDictCache::~GlobalDictCache"); + if (--ndb_dict_cache_count == 0) + { + if (f_invalid_table) + { + delete f_invalid_table; + f_invalid_table = 0; + } + if (f_altered_table) + { + delete f_altered_table; + f_altered_table = 0; + } + } NdbElement_t > * curr = m_tableHash.getNext(0); while(curr != 0){ Vector * vers = curr->theData; @@ -254,7 +274,7 @@ GlobalDictCache::put(const char * name, NdbTableImpl * tab) TableVersion & ver = vers->back(); if(ver.m_status != RETREIVING || !(ver.m_impl == 0 || - ver.m_impl == &f_invalid_table || ver.m_impl == &f_altered_table) || + ver.m_impl == f_invalid_table || ver.m_impl == f_altered_table) || ver.m_version != 0 || ver.m_refCount == 0){ abort(); @@ -271,7 +291,7 @@ GlobalDictCache::put(const char * name, NdbTableImpl * tab) ver.m_version = tab->m_version; ver.m_status = OK; } - else if (ver.m_impl == &f_invalid_table) + else if (ver.m_impl == f_invalid_table) { DBUG_PRINT("info", ("Table DROPPED invalid")); ver.m_impl = tab; @@ -279,7 +299,7 @@ GlobalDictCache::put(const char * name, NdbTableImpl * tab) ver.m_status = DROPPED; ver.m_impl->m_status = NdbDictionary::Object::Invalid; } - else if(ver.m_impl == &f_altered_table) + else if(ver.m_impl == f_altered_table) { DBUG_PRINT("info", ("Table DROPPED altered")); ver.m_impl = tab; @@ -440,7 +460,7 @@ GlobalDictCache::alter_table_rep(const char * name, if(i == sz - 1 && ver.m_status == RETREIVING) { - ver.m_impl = altered ? &f_altered_table : &f_invalid_table; + ver.m_impl = altered ? f_altered_table : f_invalid_table; DBUG_VOID_RETURN; } } From f317d3a6fb413cfc04c1ed005df8e859664e41d5 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Wed, 14 Jul 2010 09:27:13 -0300 Subject: [PATCH 063/112] Bug#42733: Type-punning warnings when compiling MySQL -- strict aliasing violations. Another rather noisy violation of strict aliasing rules is the spatial code which makes use of stack-based memory (of type Geometry_buffer) to provide placement for Geometry objects. Although a placement new is allowed to dynamically change the type of a object, the object returned by the new placement was being ignored and the original stack-based object was being casted to the new type, thus violating strict aliasing rules. The solution is to reorganize the code so that the object returned by the new placement is used instead of casting the original object. Also, to ensure that the stack-based object is properly aligned with respect to the objects it provides placement for, a set of compiler-dependent macros and types are introduced so that the alignment of objects can be inquired and specified. include/Makefile.am: Add new header. include/my_compiler.h: Add new header. include/my_global.h: Remove now-unnecessary macros. sql/spatial.cc: Make object creation functions return the object whose type was dynamically changed by the new placement. Move static method from the header in order to avoid having to access a forward declaration. sql/spatial.h: Object creation callbacks now take a array of chars as the storage area. Move create_by_typeid to a source file as to not access the forward declaration of Geometry_buffer. Ensure that Geometry_buffer is properly aligned. sql/sql_show.cc: Use newly added aligned storage helper. --- include/Makefile.am | 2 +- include/my_compiler.h | 127 ++++++++++++++++++++++++++++++++++++++++++ include/my_global.h | 3 - sql/spatial.cc | 43 ++++++++------ sql/spatial.h | 28 ++++------ sql/sql_show.cc | 4 +- 6 files changed, 166 insertions(+), 41 deletions(-) create mode 100644 include/my_compiler.h diff --git a/include/Makefile.am b/include/Makefile.am index 130517a405e..182011c25a3 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -37,7 +37,7 @@ noinst_HEADERS = config-win.h config-netware.h my_bit.h \ my_aes.h my_tree.h my_trie.h hash.h thr_alarm.h \ thr_lock.h t_ctype.h violite.h my_md5.h base64.h \ my_handler.h my_time.h my_vle.h my_user.h \ - my_libwrap.h my_stacktrace.h + my_libwrap.h my_stacktrace.h my_compiler.h EXTRA_DIST = mysql.h.pp mysql/plugin.h.pp diff --git a/include/my_compiler.h b/include/my_compiler.h new file mode 100644 index 00000000000..0a83c6587a5 --- /dev/null +++ b/include/my_compiler.h @@ -0,0 +1,127 @@ +#ifndef MY_COMPILER_INCLUDED +#define MY_COMPILER_INCLUDED + +/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +/** + Header for compiler-dependent features. + + Intended to contain a set of reusable wrappers for preprocessor + macros, attributes, pragmas, and any other features that are + specific to a target compiler. +*/ + +#include /* stddef.h offsetof */ + +/** + Compiler-dependent internal convenience macros. +*/ + +/* GNU C/C++ */ +#if defined __GNUC__ +/* Any after 2.95... */ +# define MY_ALIGN_EXT + +/* Microsoft Visual C++ */ +#elif defined _MSC_VER +# define MY_ALIGNOF(type) __alignof(type) +# define MY_ALIGNED(n) __declspec(align(n)) + +/* Oracle Solaris Studio */ +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) +# if (__SUNPRO_C >= 0x590) || (__SUNPRO_CC >= 0x590) +# define MY_ALIGN_EXT +# endif + +/* IBM XL C/C++ */ +#elif defined __xlC__ +# if __xlC__ >= 0x0600 +# define MY_ALIGN_EXT +# endif + +/* HP aCC */ +#elif defined(__HP_aCC) || defined(__HP_cc) +# if (__HP_aCC >= 60000) || (__HP_cc >= 60000) +# define MY_ALIGN_EXT +# endif +#endif + +#ifdef MY_ALIGN_EXT +/** Specifies the minimum alignment of a type. */ +# define MY_ALIGNOF(type) __alignof__(type) +/** Determine the alignment requirement of a type. */ +# define MY_ALIGNED(n) __attribute__((__aligned__((n)))) +#endif + +/** + Generic compiler-dependent features. +*/ +#ifndef MY_ALIGNOF +# ifdef __cplusplus + template struct my_alignof_helper { char m1; type m2; }; + /* Invalid for non-POD types, but most compilers give the right answer. */ +# define MY_ALIGNOF(type) offsetof(my_alignof_helper, m2) +# else +# define MY_ALIGNOF(type) offsetof(struct { char m1; type m2; }, m2) +# endif +#endif + +/** + C++ Type Traits +*/ + +#ifdef __cplusplus + +/** + Opaque storage with a particular alignment. +*/ +# if defined(MY_ALIGNED) +/* Partial specialization used due to MSVC++. */ +template struct my_alignment_imp; +template<> struct MY_ALIGNED(1) my_alignment_imp<1> {}; +template<> struct MY_ALIGNED(2) my_alignment_imp<2> {}; +template<> struct MY_ALIGNED(4) my_alignment_imp<4> {}; +template<> struct MY_ALIGNED(8) my_alignment_imp<8> {}; +template<> struct MY_ALIGNED(16) my_alignment_imp<16> {}; +/* ... expand as necessary. */ +# else +template +struct my_alignment_imp { double m1; }; +# endif + +/** + A POD type with a given size and alignment. + + @remark If the compiler does not support a alignment attribute + (MY_ALIGN macro), the default alignment of a double is + used instead. + + @tparam size The minimum size. + @tparam alignment The desired alignment: 1, 2, 4, 8 or 16. +*/ +template +struct my_aligned_storage +{ + union + { + char data[size]; + my_alignment_imp align; + }; +}; + +#endif /* __cplusplus */ + +#endif /* MY_COMPILER_INCLUDED */ diff --git a/include/my_global.h b/include/my_global.h index f03ed665d5a..6723267ae50 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -941,9 +941,6 @@ typedef long long my_ptrdiff_t; #define ADD_TO_PTR(ptr,size,type) (type) ((uchar*) (ptr)+size) #define PTR_BYTE_DIFF(A,B) (my_ptrdiff_t) ((uchar*) (A) - (uchar*) (B)) -#define MY_DIV_UP(A, B) (((A) + (B) - 1) / (B)) -#define MY_ALIGNED_BYTE_ARRAY(N, S, T) T N[MY_DIV_UP(S, sizeof(T))] - /* Custom version of standard offsetof() macro which can be used to get offsets of members in class for non-POD types (according to the current diff --git a/sql/spatial.cc b/sql/spatial.cc index 9114c81514d..11df6c00dc5 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -53,7 +53,7 @@ static Geometry::Class_info **ci_collection_end= Geometry::ci_collection+Geometry::wkb_last + 1; Geometry::Class_info::Class_info(const char *name, int type_id, - void(*create_func)(void *)): + create_geom_t create_func): m_type_id(type_id), m_create_func(create_func) { m_name.str= (char *) name; @@ -62,39 +62,39 @@ Geometry::Class_info::Class_info(const char *name, int type_id, ci_collection[type_id]= this; } -static void create_point(void *buffer) +static Geometry *create_point(char *buffer) { - new(buffer) Gis_point; + return new (buffer) Gis_point; } -static void create_linestring(void *buffer) +static Geometry *create_linestring(char *buffer) { - new(buffer) Gis_line_string; + return new (buffer) Gis_line_string; } -static void create_polygon(void *buffer) +static Geometry *create_polygon(char *buffer) { - new(buffer) Gis_polygon; + return new (buffer) Gis_polygon; } -static void create_multipoint(void *buffer) +static Geometry *create_multipoint(char *buffer) { - new(buffer) Gis_multi_point; + return new (buffer) Gis_multi_point; } -static void create_multipolygon(void *buffer) +static Geometry *create_multipolygon(char *buffer) { - new(buffer) Gis_multi_polygon; + return new (buffer) Gis_multi_polygon; } -static void create_multilinestring(void *buffer) +static Geometry *create_multilinestring(char *buffer) { - new(buffer) Gis_multi_line_string; + return new (buffer) Gis_multi_line_string; } -static void create_geometrycollection(void *buffer) +static Geometry *create_geometrycollection(char *buffer) { - new(buffer) Gis_geometry_collection; + return new (buffer) Gis_geometry_collection; } @@ -145,6 +145,15 @@ Geometry::Class_info *Geometry::find_class(const char *name, uint32 len) } +Geometry *Geometry::create_by_typeid(Geometry_buffer *buffer, int type_id) +{ + Class_info *ci; + if (!(ci= find_class(type_id))) + return NULL; + return (*ci->m_create_func)(buffer->data); +} + + Geometry *Geometry::construct(Geometry_buffer *buffer, const char *data, uint32 data_len) { @@ -179,9 +188,7 @@ Geometry *Geometry::create_from_wkt(Geometry_buffer *buffer, if (!(ci= find_class(name.str, name.length)) || wkt->reserve(1 + 4, 512)) return NULL; - (*ci->m_create_func)((void *)buffer); - Geometry *result= (Geometry *)buffer; - + Geometry *result= (*ci->m_create_func)(buffer->data); wkt->q_append((char) wkb_ndr); wkt->q_append((uint32) result->get_class_info()->m_type_id); if (trs->check_next_symbol('(') || diff --git a/sql/spatial.h b/sql/spatial.h index 86c2ed8c197..67edc077e04 100644 --- a/sql/spatial.h +++ b/sql/spatial.h @@ -16,6 +16,8 @@ #ifndef _spatial_h #define _spatial_h +#include + #ifdef HAVE_SPATIAL const uint SRID_SIZE= 4; @@ -225,15 +227,18 @@ public: { wkb_xdr= 0, /* Big Endian */ wkb_ndr= 1 /* Little Endian */ - }; + }; + + /** Callback which creates Geometry objects on top of a given placement. */ + typedef Geometry *(*create_geom_t)(char *); class Class_info { public: LEX_STRING m_name; int m_type_id; - void (*m_create_func)(void *); - Class_info(const char *name, int type_id, void(*create_func)(void *)); + create_geom_t m_create_func; + Class_info(const char *name, int type_id, create_geom_t create_func); }; virtual const Class_info *get_class_info() const=0; @@ -263,15 +268,7 @@ public: virtual int geometry_n(uint32 num, String *result) const { return -1; } public: - static Geometry *create_by_typeid(Geometry_buffer *buffer, int type_id) - { - Class_info *ci; - if (!(ci= find_class((int) type_id))) - return NULL; - (*ci->m_create_func)((void *)buffer); - return my_reinterpret_cast(Geometry *)(buffer); - } - + static Geometry *create_by_typeid(Geometry_buffer *buffer, int type_id); static Geometry *construct(Geometry_buffer *buffer, const char *data, uint32 data_len); static Geometry *create_from_wkt(Geometry_buffer *buffer, @@ -528,11 +525,8 @@ public: const Class_info *get_class_info() const; }; -const int geometry_buffer_size= sizeof(Gis_point); -struct Geometry_buffer -{ - void *arr[(geometry_buffer_size - 1)/sizeof(void *) + 1]; -}; +struct Geometry_buffer : public + my_aligned_storage {}; #endif /*HAVE_SPATAIAL*/ #endif diff --git a/sql/sql_show.cc b/sql/sql_show.cc index ca0d16697cd..091bd09aa25 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2202,8 +2202,8 @@ static bool show_status_array(THD *thd, const char *wild, bool ucase_names, COND *cond) { - MY_ALIGNED_BYTE_ARRAY(buff_data, SHOW_VAR_FUNC_BUFF_SIZE, long); - char * const buff= (char *) &buff_data; + my_aligned_storage buffer; + char * const buff= buffer.data; char *prefix_end; /* the variable name should not be longer than 64 characters */ char name_buffer[64]; From d7944b621e895383482792df3b8aa3eed6ee5f6d Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Wed, 14 Jul 2010 16:39:40 -0300 Subject: [PATCH 064/112] Bug#42733: Type-punning warnings when compiling MySQL -- strict aliasing violations. Post-merge fix: include my_compiler.h before my_attribute.h as the latter will undef __attribute__ if the compiler is not GCC. Based on the compiler version, in my_compiler.h we know for sure whether the aligned attribute is supported. Furthermore, undefining attribute might cause bugs if some system header uses it. include/my_compiler.h: Drop aligned attribute support from Sun Studio C++ compiler as its not clear exactly which version of it supports the attribute. --- include/my_compiler.h | 4 +++- include/my_global.h | 2 +- sql/spatial.h | 2 -- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/my_compiler.h b/include/my_compiler.h index 0a83c6587a5..1cd46ff4260 100644 --- a/include/my_compiler.h +++ b/include/my_compiler.h @@ -42,7 +42,7 @@ /* Oracle Solaris Studio */ #elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) -# if (__SUNPRO_C >= 0x590) || (__SUNPRO_CC >= 0x590) +# if __SUNPRO_C >= 0x590 # define MY_ALIGN_EXT # endif @@ -124,4 +124,6 @@ struct my_aligned_storage #endif /* __cplusplus */ +#include + #endif /* MY_COMPILER_INCLUDED */ diff --git a/include/my_global.h b/include/my_global.h index 6723267ae50..ec22a57329b 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -623,7 +623,7 @@ typedef unsigned short ushort; #define my_const_cast(A) (A) #endif -#include +#include /* Wen using the embedded library, users might run into link problems, diff --git a/sql/spatial.h b/sql/spatial.h index 67edc077e04..f778acd6c34 100644 --- a/sql/spatial.h +++ b/sql/spatial.h @@ -16,8 +16,6 @@ #ifndef _spatial_h #define _spatial_h -#include - #ifdef HAVE_SPATIAL const uint SRID_SIZE= 4; From 25bfbf684c0fefe658f6244e1f2cf23dd0246eae Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 23 Jun 2010 19:25:31 +0300 Subject: [PATCH 065/112] Bug #53814: NUMERIC_PRECISION for unsigned bigint field is 19, should be 20 Fixed the numeric precision of the unsigned BIGINT column to be 20 instead of 19. --- mysql-test/r/information_schema.result | 17 +++++++++++++++++ mysql-test/t/information_schema.test | 16 ++++++++++++++++ sql/sql_show.cc | 5 ++++- 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index b7b65598c6d..0da9ed40b9a 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -1757,4 +1757,21 @@ WHERE INFORMATION_SCHEMA.COLUMNS.TABLE_NAME = 'variables'; COLUMN_DEFAULT TABLE_NAME NULL variables DROP TABLE variables; +# +# Bug #53814: NUMERIC_PRECISION for unsigned bigint field is 19, +# should be 20 +# +CREATE TABLE ubig (a BIGINT, b BIGINT UNSIGNED); +SELECT TABLE_NAME, COLUMN_NAME, NUMERIC_PRECISION +FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='ubig'; +TABLE_NAME COLUMN_NAME NUMERIC_PRECISION +ubig a 19 +ubig b 20 +INSERT INTO ubig VALUES (0xFFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFFF); +Warnings: +Warning 1264 Out of range value for column 'a' at row 1 +SELECT length(CAST(b AS CHAR)) FROM ubig; +length(CAST(b AS CHAR)) +20 +DROP TABLE ubig; End of 5.1 tests. diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index fa4b880aead..1fa4d6da600 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -1455,6 +1455,22 @@ FROM INFORMATION_SCHEMA.COLUMNS WHERE INFORMATION_SCHEMA.COLUMNS.TABLE_NAME = 'variables'; DROP TABLE variables; +--echo # +--echo # Bug #53814: NUMERIC_PRECISION for unsigned bigint field is 19, +--echo # should be 20 +--echo # + +CREATE TABLE ubig (a BIGINT, b BIGINT UNSIGNED); + +SELECT TABLE_NAME, COLUMN_NAME, NUMERIC_PRECISION + FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='ubig'; + +INSERT INTO ubig VALUES (0xFFFFFFFFFFFFFFFF,0xFFFFFFFFFFFFFFFF); +SELECT length(CAST(b AS CHAR)) FROM ubig; + +DROP TABLE ubig; + + --echo End of 5.1 tests. # Wait till all disconnects are completed diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 091bd09aa25..d0e76e501e2 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -3965,10 +3965,13 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, case MYSQL_TYPE_TINY: case MYSQL_TYPE_SHORT: case MYSQL_TYPE_LONG: - case MYSQL_TYPE_LONGLONG: case MYSQL_TYPE_INT24: field_length= field->max_display_length() - 1; break; + case MYSQL_TYPE_LONGLONG: + field_length= field->max_display_length() - + ((field->flags & UNSIGNED_FLAG) ? 0 : 1); + break; case MYSQL_TYPE_BIT: field_length= field->max_display_length(); decimals= -1; // return NULL From 08a801e40968c15a48bca5a6010b02bf0a87eb32 Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Wed, 23 Jun 2010 19:10:10 -0700 Subject: [PATCH 066/112] Move the fix for bug #54044 to security branch, and revert commit -r3520:3521. --- .../suite/innodb/r/innodb_bug54044.result | 3 --- .../suite/innodb/t/innodb_bug54044.test | 11 --------- .../innodb_plugin/r/innodb_bug54044.result | 3 --- .../innodb_plugin/t/innodb_bug54044.test | 11 --------- storage/innobase/handler/ha_innodb.cc | 24 ++----------------- storage/innodb_plugin/ChangeLog | 5 ---- storage/innodb_plugin/handler/ha_innodb.cc | 24 ++----------------- 7 files changed, 4 insertions(+), 77 deletions(-) delete mode 100644 mysql-test/suite/innodb/r/innodb_bug54044.result delete mode 100644 mysql-test/suite/innodb/t/innodb_bug54044.test delete mode 100644 mysql-test/suite/innodb_plugin/r/innodb_bug54044.result delete mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug54044.test diff --git a/mysql-test/suite/innodb/r/innodb_bug54044.result b/mysql-test/suite/innodb/r/innodb_bug54044.result deleted file mode 100644 index 9574381d8e1..00000000000 --- a/mysql-test/suite/innodb/r/innodb_bug54044.result +++ /dev/null @@ -1,3 +0,0 @@ -CREATE TEMPORARY TABLE TABLE_54044 ENGINE = INNODB -AS SELECT IF(NULL IS NOT NULL, NULL, NULL); -ERROR HY000: Can't create table 'test.TABLE_54044' (errno: -1) diff --git a/mysql-test/suite/innodb/t/innodb_bug54044.test b/mysql-test/suite/innodb/t/innodb_bug54044.test deleted file mode 100644 index 824450ae1a6..00000000000 --- a/mysql-test/suite/innodb/t/innodb_bug54044.test +++ /dev/null @@ -1,11 +0,0 @@ -# This is the test for bug #54044. Special handle MYSQL_TYPE_NULL type -# during create table, so it will not trigger assertion failure. - ---source include/have_innodb.inc - -# This 'create table' operation should fail because of -# using NULL datatype ---error ER_CANT_CREATE_TABLE -CREATE TEMPORARY TABLE TABLE_54044 ENGINE = INNODB - AS SELECT IF(NULL IS NOT NULL, NULL, NULL); - diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug54044.result b/mysql-test/suite/innodb_plugin/r/innodb_bug54044.result deleted file mode 100644 index 9574381d8e1..00000000000 --- a/mysql-test/suite/innodb_plugin/r/innodb_bug54044.result +++ /dev/null @@ -1,3 +0,0 @@ -CREATE TEMPORARY TABLE TABLE_54044 ENGINE = INNODB -AS SELECT IF(NULL IS NOT NULL, NULL, NULL); -ERROR HY000: Can't create table 'test.TABLE_54044' (errno: -1) diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug54044.test b/mysql-test/suite/innodb_plugin/t/innodb_bug54044.test deleted file mode 100644 index 824450ae1a6..00000000000 --- a/mysql-test/suite/innodb_plugin/t/innodb_bug54044.test +++ /dev/null @@ -1,11 +0,0 @@ -# This is the test for bug #54044. Special handle MYSQL_TYPE_NULL type -# during create table, so it will not trigger assertion failure. - ---source include/have_innodb.inc - -# This 'create table' operation should fail because of -# using NULL datatype ---error ER_CANT_CREATE_TABLE -CREATE TEMPORARY TABLE TABLE_54044 ENGINE = INNODB - AS SELECT IF(NULL IS NOT NULL, NULL, NULL); - diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index d10fcb8d31e..9990d7c28f0 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -3242,11 +3242,6 @@ get_innobase_type_from_mysql_type( case MYSQL_TYPE_BLOB: case MYSQL_TYPE_LONG_BLOB: return(DATA_BLOB); - case MYSQL_TYPE_NULL: - /* MySQL currently accepts "NULL" datatype, but will - reject such datatype in the next release. We will cope - with it and not trigger assertion failure in 5.1 */ - break; default: assert(0); } @@ -5268,22 +5263,7 @@ create_table_def( field = form->field[i]; col_type = get_innobase_type_from_mysql_type(&unsigned_type, - field); - - if (!col_type) { - push_warning_printf( - (THD*) trx->mysql_thd, - MYSQL_ERROR::WARN_LEVEL_WARN, - ER_CANT_CREATE_TABLE, - "Error creating table '%s' with " - "column '%s'. Please check its " - "column type and try to re-create " - "the table with an appropriate " - "column type.", - table->name, (char*) field->field_name); - goto err_col; - } - + field); if (field->null_ptr) { nulls_allowed = 0; } else { @@ -5340,7 +5320,7 @@ create_table_def( "different column name.", table->name, (char*) field->field_name, (char*) field->field_name); -err_col: + dict_mem_table_free(table); trx_commit_for_mysql(trx); diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index d1d36bf812b..36bc5551a2b 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,8 +1,3 @@ -2010-06-22 The InnoDB Team - - * handler/ha_innodb.cc, innodb_bug54044.test, innodb_bug54044.result - Fix Bug#54044, Create temporary tables and using innodb crashes. - 2010-06-22 The InnoDB Team * dict/dict0dict.c, dict/dict0mem.c, include/dict0mem.h, diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index 7d918a033ee..3f8dc97e4b5 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -3950,11 +3950,6 @@ get_innobase_type_from_mysql_type( case MYSQL_TYPE_BLOB: case MYSQL_TYPE_LONG_BLOB: return(DATA_BLOB); - case MYSQL_TYPE_NULL: - /* MySQL currently accepts "NULL" datatype, but will - reject such datatype in the next release. We will cope - with it and not trigger assertion failure in 5.1 */ - break; default: ut_error; } @@ -6005,22 +6000,7 @@ create_table_def( field = form->field[i]; col_type = get_innobase_type_from_mysql_type(&unsigned_type, - field); - - if (!col_type) { - push_warning_printf( - (THD*) trx->mysql_thd, - MYSQL_ERROR::WARN_LEVEL_WARN, - ER_CANT_CREATE_TABLE, - "Error creating table '%s' with " - "column '%s'. Please check its " - "column type and try to re-create " - "the table with an appropriate " - "column type.", - table->name, (char*) field->field_name); - goto err_col; - } - + field); if (field->null_ptr) { nulls_allowed = 0; } else { @@ -6078,7 +6058,7 @@ create_table_def( if (dict_col_name_is_reserved(field->field_name)){ my_error(ER_WRONG_COLUMN_NAME, MYF(0), field->field_name); -err_col: + dict_mem_table_free(table); trx_commit_for_mysql(trx); From f2dfe5e8a57ff48fb39e257ed5c516d8bc8e1863 Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Thu, 24 Jun 2010 01:20:25 -0700 Subject: [PATCH 067/112] Fix Bug #54044 Create temporary tables and using innodb crashes. --- .../suite/innodb/r/innodb_bug54044.result | 3 +++ .../suite/innodb/t/innodb_bug54044.test | 11 +++++++++ .../innodb_plugin/r/innodb_bug54044.result | 3 +++ .../innodb_plugin/t/innodb_bug54044.test | 11 +++++++++ storage/innobase/handler/ha_innodb.cc | 24 +++++++++++++++++-- storage/innodb_plugin/ChangeLog | 5 ++++ storage/innodb_plugin/handler/ha_innodb.cc | 24 +++++++++++++++++-- 7 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb_bug54044.result create mode 100644 mysql-test/suite/innodb/t/innodb_bug54044.test create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_bug54044.result create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug54044.test diff --git a/mysql-test/suite/innodb/r/innodb_bug54044.result b/mysql-test/suite/innodb/r/innodb_bug54044.result new file mode 100644 index 00000000000..9574381d8e1 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug54044.result @@ -0,0 +1,3 @@ +CREATE TEMPORARY TABLE TABLE_54044 ENGINE = INNODB +AS SELECT IF(NULL IS NOT NULL, NULL, NULL); +ERROR HY000: Can't create table 'test.TABLE_54044' (errno: -1) diff --git a/mysql-test/suite/innodb/t/innodb_bug54044.test b/mysql-test/suite/innodb/t/innodb_bug54044.test new file mode 100644 index 00000000000..824450ae1a6 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug54044.test @@ -0,0 +1,11 @@ +# This is the test for bug #54044. Special handle MYSQL_TYPE_NULL type +# during create table, so it will not trigger assertion failure. + +--source include/have_innodb.inc + +# This 'create table' operation should fail because of +# using NULL datatype +--error ER_CANT_CREATE_TABLE +CREATE TEMPORARY TABLE TABLE_54044 ENGINE = INNODB + AS SELECT IF(NULL IS NOT NULL, NULL, NULL); + diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug54044.result b/mysql-test/suite/innodb_plugin/r/innodb_bug54044.result new file mode 100644 index 00000000000..9574381d8e1 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug54044.result @@ -0,0 +1,3 @@ +CREATE TEMPORARY TABLE TABLE_54044 ENGINE = INNODB +AS SELECT IF(NULL IS NOT NULL, NULL, NULL); +ERROR HY000: Can't create table 'test.TABLE_54044' (errno: -1) diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug54044.test b/mysql-test/suite/innodb_plugin/t/innodb_bug54044.test new file mode 100644 index 00000000000..8958dba1c9b --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug54044.test @@ -0,0 +1,11 @@ +# This is the test for bug #54044. Special handle MYSQL_TYPE_NULL type +# during create table, so it will not trigger assertion failure. + +--source include/have_innodb_plugin.inc + +# This 'create table' operation should fail because of +# using NULL datatype +--error ER_CANT_CREATE_TABLE +CREATE TEMPORARY TABLE TABLE_54044 ENGINE = INNODB + AS SELECT IF(NULL IS NOT NULL, NULL, NULL); + diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index cf7ec4d6e6f..49fa3907bc4 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -3236,6 +3236,11 @@ get_innobase_type_from_mysql_type( case MYSQL_TYPE_BLOB: case MYSQL_TYPE_LONG_BLOB: return(DATA_BLOB); + case MYSQL_TYPE_NULL: + /* MySQL currently accepts "NULL" datatype, but will + reject such datatype in the next release. We will cope + with it and not trigger assertion failure in 5.1 */ + break; default: assert(0); } @@ -5257,7 +5262,22 @@ create_table_def( field = form->field[i]; col_type = get_innobase_type_from_mysql_type(&unsigned_type, - field); + field); + + if (!col_type) { + push_warning_printf( + (THD*) trx->mysql_thd, + MYSQL_ERROR::WARN_LEVEL_WARN, + ER_CANT_CREATE_TABLE, + "Error creating table '%s' with " + "column '%s'. Please check its " + "column type and try to re-create " + "the table with an appropriate " + "column type.", + table->name, (char*) field->field_name); + goto err_col; + } + if (field->null_ptr) { nulls_allowed = 0; } else { @@ -5314,7 +5334,7 @@ create_table_def( "different column name.", table->name, (char*) field->field_name, (char*) field->field_name); - +err_col: dict_mem_table_free(table); trx_commit_for_mysql(trx); diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 89823642957..9ea9d2cd153 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,8 @@ +2010-06-22 The InnoDB Team + + * handler/ha_innodb.cc, innodb_bug54044.test, innodb_bug54044.result + Fix Bug#54044, Create temporary tables and using innodb crashes. + 2010-05-25 The InnoDB Team * handler/ha_innodb.cc, include/row0mysql.h, row/row0mysql.c: diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index c65ba3163fc..e5327863db4 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -3950,6 +3950,11 @@ get_innobase_type_from_mysql_type( case MYSQL_TYPE_BLOB: case MYSQL_TYPE_LONG_BLOB: return(DATA_BLOB); + case MYSQL_TYPE_NULL: + /* MySQL currently accepts "NULL" datatype, but will + reject such datatype in the next release. We will cope + with it and not trigger assertion failure in 5.1 */ + break; default: ut_error; } @@ -5997,7 +6002,22 @@ create_table_def( field = form->field[i]; col_type = get_innobase_type_from_mysql_type(&unsigned_type, - field); + field); + + if (!col_type) { + push_warning_printf( + (THD*) trx->mysql_thd, + MYSQL_ERROR::WARN_LEVEL_WARN, + ER_CANT_CREATE_TABLE, + "Error creating table '%s' with " + "column '%s'. Please check its " + "column type and try to re-create " + "the table with an appropriate " + "column type.", + table->name, (char*) field->field_name); + goto err_col; + } + if (field->null_ptr) { nulls_allowed = 0; } else { @@ -6055,7 +6075,7 @@ create_table_def( if (dict_col_name_is_reserved(field->field_name)){ my_error(ER_WRONG_COLUMN_NAME, MYF(0), field->field_name); - +err_col: dict_mem_table_free(table); trx_commit_for_mysql(trx); From 42011fb716a751f3e71ce47191a93c6ac6d69d32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 24 Jun 2010 13:46:20 +0300 Subject: [PATCH 068/112] Bug#54679: alter table causes compressed row_format to revert to compact ha_innobase::create(): Add the local variable row_type = form->s->row_type. Adjust it to ROW_TYPE_COMPRESSED when ROW_FORMAT is not specified or inherited but KEY_BLOCK_SIZE is. Observe the inherited ROW_FORMAT even when it is not explicitly specified. innodb_bug54679.test: New test, to test the bug and to ensure that there are no regressions. (The only difference in the test result without the patch applied is that the first ALTER TABLE changes ROW_FORMAT to Compact.) --- .../innodb_plugin/r/innodb_bug54679.result | 91 ++++++++++ .../innodb_plugin/t/innodb_bug54679.test | 97 +++++++++++ storage/innodb_plugin/handler/ha_innodb.cc | 159 +++++++++--------- 3 files changed, 268 insertions(+), 79 deletions(-) create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_bug54679.result create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug54679.test diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug54679.result b/mysql-test/suite/innodb_plugin/r/innodb_bug54679.result new file mode 100644 index 00000000000..14fd32ca469 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug54679.result @@ -0,0 +1,91 @@ +SET GLOBAL innodb_file_format='Barracuda'; +SET GLOBAL innodb_file_per_table=ON; +SET innodb_strict_mode=ON; +CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables +WHERE TABLE_NAME='bug54679'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug54679 Compressed row_format=COMPRESSED +ALTER TABLE bug54679 ADD COLUMN b INT; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables +WHERE TABLE_NAME='bug54679'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug54679 Compressed row_format=COMPRESSED +DROP TABLE bug54679; +CREATE TABLE bug54679 (a INT) ENGINE=InnoDB; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables +WHERE TABLE_NAME='bug54679'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug54679 Compact +ALTER TABLE bug54679 KEY_BLOCK_SIZE=1; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables +WHERE TABLE_NAME='bug54679'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug54679 Compressed KEY_BLOCK_SIZE=1 +ALTER TABLE bug54679 ROW_FORMAT=REDUNDANT; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +DROP TABLE bug54679; +CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=REDUNDANT; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables +WHERE TABLE_NAME='bug54679'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug54679 Redundant row_format=REDUNDANT +ALTER TABLE bug54679 KEY_BLOCK_SIZE=2; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables +WHERE TABLE_NAME='bug54679'; +TABLE_NAME ROW_FORMAT CREATE_OPTIONS +bug54679 Compressed row_format=REDUNDANT KEY_BLOCK_SIZE=2 +SET GLOBAL innodb_file_format=Antelope; +ALTER TABLE bug54679 KEY_BLOCK_SIZE=4; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE bug54679 ROW_FORMAT=DYNAMIC; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. +Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope. +Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +DROP TABLE bug54679; +CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +ERROR HY000: Can't create table 'test.bug54679' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope. +Error 1005 Can't create table 'test.bug54679' (errno: 1478) +CREATE TABLE bug54679 (a INT) ENGINE=InnoDB; +SET GLOBAL innodb_file_format=Barracuda; +SET GLOBAL innodb_file_per_table=OFF; +ALTER TABLE bug54679 KEY_BLOCK_SIZE=4; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +ALTER TABLE bug54679 ROW_FORMAT=DYNAMIC; +ERROR HY000: Can't create table '#sql-temporary' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table. +Error 1005 Can't create table '#sql-temporary' (errno: 1478) +DROP TABLE bug54679; +CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +ERROR HY000: Can't create table 'test.bug54679' (errno: 1478) +SHOW WARNINGS; +Level Code Message +Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table. +Error 1005 Can't create table 'test.bug54679' (errno: 1478) +SET GLOBAL innodb_file_per_table=ON; +CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +DROP TABLE bug54679; +SET GLOBAL innodb_file_format=Antelope; +SET GLOBAL innodb_file_format_check=Antelope; +SET GLOBAL innodb_file_per_table=0; diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug54679.test b/mysql-test/suite/innodb_plugin/t/innodb_bug54679.test new file mode 100644 index 00000000000..863d9847ac1 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug54679.test @@ -0,0 +1,97 @@ +# Test Bug #54679 alter table causes compressed row_format to revert to compact + +--source include/have_innodb_plugin.inc + +let $file_format=`select @@innodb_file_format`; +let $file_format_check=`select @@innodb_file_format_check`; +let $file_per_table=`select @@innodb_file_per_table`; +SET GLOBAL innodb_file_format='Barracuda'; +SET GLOBAL innodb_file_per_table=ON; +SET innodb_strict_mode=ON; + +CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables +WHERE TABLE_NAME='bug54679'; + +# The ROW_FORMAT of the table should be preserved when it is not specified +# in ALTER TABLE. +ALTER TABLE bug54679 ADD COLUMN b INT; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables +WHERE TABLE_NAME='bug54679'; + +DROP TABLE bug54679; + +# Check that the ROW_FORMAT conversion to/from COMPRESSED works. + +CREATE TABLE bug54679 (a INT) ENGINE=InnoDB; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables +WHERE TABLE_NAME='bug54679'; + +# KEY_BLOCK_SIZE implies COMPRESSED. +ALTER TABLE bug54679 KEY_BLOCK_SIZE=1; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables +WHERE TABLE_NAME='bug54679'; + +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE bug54679 ROW_FORMAT=REDUNDANT; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +DROP TABLE bug54679; +CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=REDUNDANT; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables +WHERE TABLE_NAME='bug54679'; + +ALTER TABLE bug54679 KEY_BLOCK_SIZE=2; +SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables +WHERE TABLE_NAME='bug54679'; + +# This prevents other than REDUNDANT or COMPACT ROW_FORMAT for new tables. +SET GLOBAL innodb_file_format=Antelope; + +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE bug54679 KEY_BLOCK_SIZE=4; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE bug54679 ROW_FORMAT=DYNAMIC; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +DROP TABLE bug54679; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +CREATE TABLE bug54679 (a INT) ENGINE=InnoDB; + +SET GLOBAL innodb_file_format=Barracuda; +# This will prevent ROW_FORMAT=COMPRESSED, because the system tablespace +# cannot be compressed. +SET GLOBAL innodb_file_per_table=OFF; + +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE bug54679 KEY_BLOCK_SIZE=4; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +ALTER TABLE bug54679 ROW_FORMAT=DYNAMIC; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +DROP TABLE bug54679; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error ER_CANT_CREATE_TABLE +CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +SHOW WARNINGS; +SET GLOBAL innodb_file_per_table=ON; +CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +DROP TABLE bug54679; + +EVAL SET GLOBAL innodb_file_format=$file_format; +EVAL SET GLOBAL innodb_file_format_check=$file_format_check; +EVAL SET GLOBAL innodb_file_per_table=$file_per_table; diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index 3f8dc97e4b5..aa80814dbe0 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -6460,6 +6460,7 @@ ha_innobase::create( const ulint file_format = srv_file_format; const char* stmt; size_t stmt_len; + enum row_type row_type; DBUG_ENTER("ha_innobase::create"); @@ -6580,94 +6581,94 @@ ha_innobase::create( } } - if (create_info->used_fields & HA_CREATE_USED_ROW_FORMAT) { - if (flags) { - /* KEY_BLOCK_SIZE was specified. */ - if (form->s->row_type != ROW_TYPE_COMPRESSED) { - /* ROW_FORMAT other than COMPRESSED - ignores KEY_BLOCK_SIZE. It does not - make sense to reject conflicting - KEY_BLOCK_SIZE and ROW_FORMAT, because - such combinations can be obtained - with ALTER TABLE anyway. */ - push_warning_printf( - thd, - MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: ignoring KEY_BLOCK_SIZE=%lu" - " unless ROW_FORMAT=COMPRESSED.", - create_info->key_block_size); - flags = 0; - } - } else { - /* No KEY_BLOCK_SIZE */ - if (form->s->row_type == ROW_TYPE_COMPRESSED) { - /* ROW_FORMAT=COMPRESSED without - KEY_BLOCK_SIZE implies half the - maximum KEY_BLOCK_SIZE. */ - flags = (DICT_TF_ZSSIZE_MAX - 1) - << DICT_TF_ZSSIZE_SHIFT - | DICT_TF_COMPACT - | DICT_TF_FORMAT_ZIP - << DICT_TF_FORMAT_SHIFT; + row_type = form->s->row_type; + + if (flags) { + /* KEY_BLOCK_SIZE was specified. */ + if (!(create_info->used_fields & HA_CREATE_USED_ROW_FORMAT)) { + /* ROW_FORMAT was not specified; + default to ROW_FORMAT=COMPRESSED */ + row_type = ROW_TYPE_COMPRESSED; + } else if (row_type != ROW_TYPE_COMPRESSED) { + /* ROW_FORMAT other than COMPRESSED + ignores KEY_BLOCK_SIZE. It does not + make sense to reject conflicting + KEY_BLOCK_SIZE and ROW_FORMAT, because + such combinations can be obtained + with ALTER TABLE anyway. */ + push_warning_printf( + thd, + MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: ignoring KEY_BLOCK_SIZE=%lu" + " unless ROW_FORMAT=COMPRESSED.", + create_info->key_block_size); + flags = 0; + } + } else { + /* No KEY_BLOCK_SIZE */ + if (row_type == ROW_TYPE_COMPRESSED) { + /* ROW_FORMAT=COMPRESSED without + KEY_BLOCK_SIZE implies half the + maximum KEY_BLOCK_SIZE. */ + flags = (DICT_TF_ZSSIZE_MAX - 1) + << DICT_TF_ZSSIZE_SHIFT + | DICT_TF_COMPACT + | DICT_TF_FORMAT_ZIP + << DICT_TF_FORMAT_SHIFT; #if DICT_TF_ZSSIZE_MAX < 1 # error "DICT_TF_ZSSIZE_MAX < 1" #endif - } } + } - switch (form->s->row_type) { - const char* row_format_name; - case ROW_TYPE_REDUNDANT: - break; - case ROW_TYPE_COMPRESSED: - case ROW_TYPE_DYNAMIC: - row_format_name - = form->s->row_type == ROW_TYPE_COMPRESSED - ? "COMPRESSED" - : "DYNAMIC"; + switch (row_type) { + const char* row_format_name; + case ROW_TYPE_REDUNDANT: + break; + case ROW_TYPE_COMPRESSED: + case ROW_TYPE_DYNAMIC: + row_format_name + = row_type == ROW_TYPE_COMPRESSED + ? "COMPRESSED" + : "DYNAMIC"; - if (!srv_file_per_table) { - push_warning_printf( - thd, - MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: ROW_FORMAT=%s" - " requires innodb_file_per_table.", - row_format_name); - } else if (file_format < DICT_TF_FORMAT_ZIP) { - push_warning_printf( - thd, - MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: ROW_FORMAT=%s" - " requires innodb_file_format >" - " Antelope.", - row_format_name); - } else { - flags |= DICT_TF_COMPACT - | (DICT_TF_FORMAT_ZIP - << DICT_TF_FORMAT_SHIFT); - break; - } - - /* fall through */ - case ROW_TYPE_NOT_USED: - case ROW_TYPE_FIXED: - default: - push_warning(thd, - MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA_CREATE_OPTION, - "InnoDB: assuming ROW_FORMAT=COMPACT."); - case ROW_TYPE_DEFAULT: - case ROW_TYPE_COMPACT: - flags = DICT_TF_COMPACT; + if (!srv_file_per_table) { + push_warning_printf( + thd, + MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: ROW_FORMAT=%s" + " requires innodb_file_per_table.", + row_format_name); + } else if (file_format < DICT_TF_FORMAT_ZIP) { + push_warning_printf( + thd, + MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: ROW_FORMAT=%s" + " requires innodb_file_format >" + " Antelope.", + row_format_name); + } else { + flags |= DICT_TF_COMPACT + | (DICT_TF_FORMAT_ZIP + << DICT_TF_FORMAT_SHIFT); break; } - } else if (!flags) { - /* No KEY_BLOCK_SIZE or ROW_FORMAT specified: - use ROW_FORMAT=COMPACT by default. */ + + /* fall through */ + case ROW_TYPE_NOT_USED: + case ROW_TYPE_FIXED: + default: + push_warning(thd, + MYSQL_ERROR::WARN_LEVEL_WARN, + ER_ILLEGAL_HA_CREATE_OPTION, + "InnoDB: assuming ROW_FORMAT=COMPACT."); + case ROW_TYPE_DEFAULT: + case ROW_TYPE_COMPACT: flags = DICT_TF_COMPACT; + break; } /* Look for a primary key */ From 79f71e1915f1337e3d866fb9e874f0df0bdf1fa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 24 Jun 2010 13:48:20 +0300 Subject: [PATCH 069/112] Add ChangeLog entry for Bug#54679 --- storage/innodb_plugin/ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 36bc5551a2b..5103538cb69 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,9 @@ +2010-06-24 The InnoDB Team + + * handler/ha_innodb.cc: + Fix Bug#54679 alter table causes compressed row_format to revert + to compact + 2010-06-22 The InnoDB Team * dict/dict0dict.c, dict/dict0mem.c, include/dict0mem.h, From 4cf3e93339dbd16ab0901900ce64ecb4a6362a3f Mon Sep 17 00:00:00 2001 From: Inaam Rana Date: Thu, 24 Jun 2010 08:44:50 -0400 Subject: [PATCH 070/112] Add ChangeLog for bug#39168 --- storage/innodb_plugin/ChangeLog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 971de4a9d27..cc794fab33a 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,10 @@ +2010-06-10 The InnoDB Team + + * include/log0log.ic, row/row0ins.c, row/row0purge.c, + row/row0uins.c, row/row0umod.c, row/row0upd.c: + Fix Bug#39168 ERROR: the age of the last checkpoint ... exceeds + the log group capacity + 2010-06-08 The InnoDB Team * dict/dict0load.c: From 7299858763289eab8c9fbe8048f86abebdf4d50d Mon Sep 17 00:00:00 2001 From: Sunny Bains Date: Fri, 25 Jun 2010 18:18:41 +1000 Subject: [PATCH 071/112] Fix bug#54583. This change reverses rsvn:1350 by getting rid of a bogus assertion and clarifies the invariant in dict_table_get_on_id(). In Mar 2007 Marko observed a crash during recovery, the crash resulted from an UNDO operation on a system table. His solution was to acquire an X lock on the data dictionary, this in hindsight was an overkill. It is unclear what caused the crash, current hypothesis is that it was a memory corruption. The X lock results in performance issues by when undoing changes due to rollback during normal operation on regular tables. Why the change is safe: ====================== The InnoDB code has changed since the original X lock change was made. In the new code we always lock the data dictionary in X mode during startup when UNDOing operations on the system tables (this is a given). This ensures that the crash Marko observed cannot happen as long as all transactions that update the system tables follow the standard rules by setting the appropriate DICT_OP flag when writing the log records when they make the changes. If transactions violate the above mentioned rule then during recovery (at startup) the rollback code (see trx0roll.c) will not acquire the X lock and we will see the crash again. This will however be a different bug. --- storage/innobase/dict/dict0dict.c | 10 ++++------ storage/innobase/include/sync0sync.h | 2 +- storage/innobase/row/row0undo.c | 4 ++-- storage/innodb_plugin/dict/dict0dict.c | 10 ++++------ storage/innodb_plugin/include/sync0sync.h | 2 +- storage/innodb_plugin/row/row0undo.c | 4 ++-- 6 files changed, 14 insertions(+), 18 deletions(-) diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c index d3b277d2d7a..d2b59469cdc 100644 --- a/storage/innobase/dict/dict0dict.c +++ b/storage/innobase/dict/dict0dict.c @@ -618,13 +618,11 @@ dict_table_get_on_id( if (ut_dulint_cmp(table_id, DICT_FIELDS_ID) <= 0 || trx->dict_operation_lock_mode == RW_X_LATCH) { - /* It is a system table which will always exist in the table - cache: we avoid acquiring the dictionary mutex, because - if we are doing a rollback to handle an error in TABLE - CREATE, for example, we already have the mutex! */ - ut_ad(mutex_own(&(dict_sys->mutex)) - || trx->dict_operation_lock_mode == RW_X_LATCH); + /* Note: An X latch implies that the transaction + already owns the dictionary mutex. */ + + ut_ad(mutex_own(&dict_sys->mutex)); return(dict_table_get_on_id_low(table_id)); } diff --git a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h index 6a61330f97e..9430d4cb723 100644 --- a/storage/innobase/include/sync0sync.h +++ b/storage/innobase/include/sync0sync.h @@ -401,7 +401,7 @@ or row lock! */ locked; see e.g. ibuf_bitmap_get_map_page(). */ #define SYNC_DICT_OPERATION 1001 /* table create, drop, etc. reserve - this in X-mode, implicit or backround + this in X-mode; implicit or backround operations purge, rollback, foreign key checks reserve this in S-mode */ #define SYNC_DICT 1000 diff --git a/storage/innobase/row/row0undo.c b/storage/innobase/row/row0undo.c index f03f84ed1b0..7f31fd0060c 100644 --- a/storage/innobase/row/row0undo.c +++ b/storage/innobase/row/row0undo.c @@ -272,7 +272,7 @@ row_undo( if (locked_data_dict) { - row_mysql_lock_data_dictionary(trx); + row_mysql_freeze_data_dictionary(trx); } if (node->state == UNDO_NODE_INSERT) { @@ -287,7 +287,7 @@ row_undo( if (locked_data_dict) { - row_mysql_unlock_data_dictionary(trx); + row_mysql_unfreeze_data_dictionary(trx); } /* Do some cleanup */ diff --git a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/dict0dict.c index 8be5b7acac5..fe4e058e122 100644 --- a/storage/innodb_plugin/dict/dict0dict.c +++ b/storage/innodb_plugin/dict/dict0dict.c @@ -570,13 +570,11 @@ dict_table_get_on_id( if (ut_dulint_cmp(table_id, DICT_FIELDS_ID) <= 0 || trx->dict_operation_lock_mode == RW_X_LATCH) { - /* It is a system table which will always exist in the table - cache: we avoid acquiring the dictionary mutex, because - if we are doing a rollback to handle an error in TABLE - CREATE, for example, we already have the mutex! */ - ut_ad(mutex_own(&(dict_sys->mutex)) - || trx->dict_operation_lock_mode == RW_X_LATCH); + /* Note: An X latch implies that the transaction + already owns the dictionary mutex. */ + + ut_ad(mutex_own(&dict_sys->mutex)); return(dict_table_get_on_id_low(table_id)); } diff --git a/storage/innodb_plugin/include/sync0sync.h b/storage/innodb_plugin/include/sync0sync.h index d470b823fc3..71c9920a10b 100644 --- a/storage/innodb_plugin/include/sync0sync.h +++ b/storage/innodb_plugin/include/sync0sync.h @@ -438,7 +438,7 @@ or row lock! */ #define SYNC_FILE_FORMAT_TAG 1200 /* Used to serialize access to the file format tag */ #define SYNC_DICT_OPERATION 1001 /* table create, drop, etc. reserve - this in X-mode, implicit or backround + this in X-mode; implicit or backround operations purge, rollback, foreign key checks reserve this in S-mode */ #define SYNC_DICT 1000 diff --git a/storage/innodb_plugin/row/row0undo.c b/storage/innodb_plugin/row/row0undo.c index 3d739c9689a..9ef842b5114 100644 --- a/storage/innodb_plugin/row/row0undo.c +++ b/storage/innodb_plugin/row/row0undo.c @@ -297,7 +297,7 @@ row_undo( if (locked_data_dict) { - row_mysql_lock_data_dictionary(trx); + row_mysql_freeze_data_dictionary(trx); } if (node->state == UNDO_NODE_INSERT) { @@ -312,7 +312,7 @@ row_undo( if (locked_data_dict) { - row_mysql_unlock_data_dictionary(trx); + row_mysql_unfreeze_data_dictionary(trx); } /* Do some cleanup */ From 0eb26fdfa83d2ddd5f3dc3f8cf6e372a55b4c270 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 2 Jul 2010 15:30:47 -0300 Subject: [PATCH 072/112] Bug#53445: Build with -Wall and fix warnings that it generates Apart strict-aliasing warnings, fix the remaining warnings generated by GCC 4.4.4 -Wall and -Wextra flags. One major source of warnings was the in-house function my_bcmp which (unconventionally) took pointers to unsigned characters as the byte sequences to be compared. Since my_bcmp and bcmp are deprecated functions whose only difference with memcmp is the return value, every use of the function is replaced with memcmp as the special return value wasn't actually being used by any caller. There were also various other warnings, mostly due to type mismatches, missing return values, missing prototypes, dead code (unreachable) and ignored return values. BUILD/SETUP.sh: Remove flags that are implied by -Wall and -Wextra. Do not warn about unused parameters in C++. BUILD/check-cpu: Print only the compiler version instead of verbose banner. Although the option is gcc specific, the check was only being used for GCC specific checks anyway. client/mysql.cc: bcmp is no longer defined. client/mysqltest.cc: Pass a string to function expecting a format string. Replace use of bcmp with memcmp. cmd-line-utils/readline/Makefile.am: Always define _GNU_SOURCE when compiling GNU readline. Required to make certain prototypes visible. cmd-line-utils/readline/input.c: Condition for the code to be meaningful. configure.in: Remove check for bcmp. extra/comp_err.c: Use appropriate type. extra/replace.c: Replace use of bcmp with memcmp. extra/yassl/src/crypto_wrapper.cpp: Do not ignore the return value of fgets. Retrieve the file position if fgets succeed -- if it fails, the function will bail out and return a error. extra/yassl/taocrypt/include/blowfish.hpp: Use a single array instead of accessing positions of the sbox_ through a subscript to pbox_. extra/yassl/taocrypt/include/runtime.hpp: One definition of such functions is enough. extra/yassl/taocrypt/src/aes.cpp: Avoid potentially ambiguous conditions. extra/yassl/taocrypt/src/algebra.cpp: Rename arguments to avoid shadowing related warnings. extra/yassl/taocrypt/src/blowfish.cpp: Avoid potentially ambiguous conditions. extra/yassl/taocrypt/src/integer.cpp: Do not define type within a anonymous union. Use a variable to return a value instead of leaving the result in a register -- compiler does not know the logic inside the asm. extra/yassl/taocrypt/src/misc.cpp: Define handler for pure virtual functions. Remove unused code. extra/yassl/taocrypt/src/twofish.cpp: Avoid potentially ambiguous conditions. extra/yassl/testsuite/test.hpp: Function must have C language linkage. include/m_string.h: Remove check which relied on bcmp being defined -- they weren't being used as bcmp is only visible when _BSD_SOURCE is defined. include/my_bitmap.h: Remove bogus helpers which were used only in a few files and were causing warnings about dead code. include/my_global.h: Due to G++ bug, always silence false-positive uninitialized variables warnings when compiling C++ code with G++. Remove bogus helper. libmysql/Makefile.shared: Remove built-in implementation of bcmp. mysql-test/lib/My/SafeProcess/safe_process.cc: Cast pid to largest possible type for a process identifier. mysys/mf_loadpath.c: Leave space of the ending nul. mysys/mf_pack.c: Replace bcmp with memcmp. mysys/my_bitmap.c: Dead code removal. mysys/my_gethwaddr.c: Remove unused variable. mysys/my_getopt.c: Silence bogus uninitialized variable warning. Do not cast away the constant qualifier. mysys/safemalloc.c: Cast to expected type. mysys/thr_lock.c: Silence bogus uninitialized variable warning. sql/field.cc: Replace bogus helper with a more appropriate logic which is used throughout the code. sql/item.cc: Remove bogus logical condition which always evaluates to TRUE. sql/item_create.cc: Simplify code to avoid signedness related warnings. sql/log_event.cc: Replace use of bcmp with memcmp. No need to use helpers for simple bit operations. sql/log_event_old.cc: Replace bmove_align with memcpy. sql/mysqld.cc: Move use declaration of variable to the ifdef block where it is used. Remove now-unnecessary casts and arguments. sql/set_var.cc: Replace bogus helpers with simple and classic bit operations. sql/slave.cc: Cast to expected type and silence bogus warning. sql/sql_class.h: Don't use enum values as bit flags, the supposed type safety is bogus as the combined bit flags are not a value in the enumeration. sql/udf_example.c: Only declare variable when necessary. sql/unireg.h: Replace use of bmove_align with memcpy. storage/innobase/os/os0file.c: Silence bogus warning. storage/myisam/mi_open.c: Remove bogus cast, DBUG_DUMP expects a pointer to unsigned char. storage/myisam/mi_page.c: Remove bogus cast, DBUG_DUMP expects a pointer to unsigned char. strings/bcmp.c: Remove built-in bcmp. strings/ctype-ucs2.c: Silence bogus warning. tests/mysql_client_test.c: Use a appropriate type as expected by simple_command(). --- BUILD/SETUP.sh | 13 ++-- BUILD/check-cpu | 23 ++++--- client/mysql.cc | 1 - client/mysqltest.cc | 21 +++--- cmd-line-utils/readline/Makefile.am | 2 +- cmd-line-utils/readline/input.c | 2 + configure.in | 2 +- extra/comp_err.c | 6 +- extra/replace.c | 12 ++-- extra/yassl/src/crypto_wrapper.cpp | 5 +- extra/yassl/taocrypt/include/blowfish.hpp | 6 +- extra/yassl/taocrypt/include/runtime.hpp | 16 +---- extra/yassl/taocrypt/src/aes.cpp | 3 +- extra/yassl/taocrypt/src/algebra.cpp | 6 +- extra/yassl/taocrypt/src/blowfish.cpp | 3 +- extra/yassl/taocrypt/src/integer.cpp | 32 +++++---- extra/yassl/taocrypt/src/misc.cpp | 23 ++++--- extra/yassl/taocrypt/src/twofish.cpp | 3 +- extra/yassl/testsuite/test.hpp | 5 ++ include/m_string.h | 21 ------ include/my_bitmap.h | 16 ----- include/my_global.h | 21 ++++-- libmysql/Makefile.shared | 2 +- libmysql/libmysql.c | 1 - mysql-test/lib/My/SafeProcess/safe_process.cc | 2 +- mysys/mf_loadpath.c | 2 +- mysys/mf_pack.c | 12 ++-- mysys/my_bitmap.c | 6 +- mysys/my_gethwaddr.c | 2 +- mysys/my_getopt.c | 14 ++-- mysys/my_handler.c | 1 - mysys/safemalloc.c | 2 +- mysys/thr_lock.c | 3 +- regex/regcomp.c | 1 - sql/field.cc | 8 ++- sql/item.cc | 3 +- sql/item_create.cc | 26 +++----- sql/log.cc | 2 +- sql/log_event.cc | 21 +++--- sql/log_event_old.cc | 6 +- sql/mysqld.cc | 31 +++++---- sql/rpl_rli.cc | 3 +- sql/set_var.cc | 35 +++++----- sql/set_var.h | 2 +- sql/slave.cc | 6 +- sql/sql_base.cc | 6 +- sql/sql_class.h | 15 +++-- sql/sql_repl.cc | 3 +- sql/udf_example.c | 2 + sql/unireg.h | 4 +- storage/heap/hp_hash.c | 4 +- storage/heap/hp_test2.c | 4 +- storage/innobase/os/os0file.c | 3 + storage/myisam/mi_open.c | 2 +- storage/myisam/mi_page.c | 2 +- storage/myisam/mi_search.c | 6 +- storage/myisam/mi_test2.c | 22 +++---- storage/myisam/mi_unique.c | 2 +- storage/myisammrg/ha_myisammrg.cc | 7 +- strings/CMakeLists.txt | 2 +- strings/Makefile.am | 8 +-- strings/bcmp.c | 66 ------------------- strings/ctype-ucs2.c | 6 +- strings/make-ccc | 2 +- strings/str_test.c | 10 +-- strings/xml.c | 8 +-- tests/mysql_client_test.c | 2 +- 67 files changed, 257 insertions(+), 362 deletions(-) delete mode 100644 strings/bcmp.c diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index 626f932e045..08ae4de2e23 100755 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -90,22 +90,19 @@ SSL_LIBRARY=--with-ssl if [ "x$warning_mode" != "xpedantic" ]; then # Both C and C++ warnings - warnings="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W" - warnings="$warnings -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare" - warnings="$warnings -Wwrite-strings -Wunused-function -Wunused-label -Wunused-value -Wunused-variable" + warnings="-Wall -Wextra -Wunused -Wwrite-strings" # For more warnings, uncomment the following line -# warnings="$global_warnings -Wshadow" +# warnings="$warnings -Wshadow" # C warnings - c_warnings="$warnings -Wunused-parameter" + c_warnings="$warnings" # C++ warnings - cxx_warnings="$warnings" + cxx_warnings="$warnings -Wno-unused-parameter" # cxx_warnings="$cxx_warnings -Woverloaded-virtual -Wsign-promo" - cxx_warnings="$cxx_warnings -Wreorder" cxx_warnings="$cxx_warnings -Wctor-dtor-privacy -Wnon-virtual-dtor" # Added unless --with-debug=full - debug_extra_cflags="-O0 -g3 -gdwarf-2" #1 -Wuninitialized" + debug_extra_cflags="-O0 -g3 -gdwarf-2" else warnings="-W -Wall -ansi -pedantic -Wno-long-long -Wno-unused -D_POSIX_SOURCE" c_warnings="$warnings" diff --git a/BUILD/check-cpu b/BUILD/check-cpu index c0e87a675cb..390ba545405 100755 --- a/BUILD/check-cpu +++ b/BUILD/check-cpu @@ -181,14 +181,17 @@ check_cpu () { cc=$CC fi - cc_ver=`$cc --version | sed 1q` - cc_verno=`echo $cc_ver | sed -e 's/^.*(GCC)//g; s/[^0-9. ]//g; s/^ *//g; s/ .*//g'` - set -- `echo $cc_verno | tr '.' ' '` - cc_major=$1 - cc_minor=$2 - cc_patch=$3 - cc_comp=`expr $cc_major '*' 100 '+' $cc_minor` - + # check if compiler is gcc and dump its version + cc_verno=`$cc -dumpversion 2>/dev/null` + if test "x$?" = "x0" ; then + set -- `echo $cc_verno | tr '.' ' '` + cc_ver="GCC" + cc_major=$1 + cc_minor=$2 + cc_patch=$3 + cc_comp=`expr $cc_major '*' 100 '+' $cc_minor` + fi + case "$cc_ver--$cc_verno" in *GCC*) # different gcc backends (and versions) have different CPU flags @@ -229,7 +232,7 @@ check_cpu () { fi while [ "$cpu_arg" ] ; do printf "testing $cpu_arg ... " >&2 - + # compile check eval "$cc -c $check_cpu_cflags __test.c" 2>/dev/null if test "x$?" = "x0" ; then @@ -243,5 +246,5 @@ check_cpu () { done rm __test.* } - + check_cpu diff --git a/client/mysql.cc b/client/mysql.cc index 14a6ceed51d..edcc72b60bf 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -93,7 +93,6 @@ extern "C" { #endif #endif -#undef bcmp // Fix problem with new readline #if defined(__WIN__) #include #elif !defined(__NETWARE__) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 359de9880e7..6a8d119a7c4 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -5780,7 +5780,7 @@ int read_command(struct st_command** command_ptr) (struct st_command*) my_malloc(sizeof(*command), MYF(MY_WME|MY_ZEROFILL))) || insert_dynamic(&q_lines, (uchar*) &command)) - die(NullS); + die("Out of memory"); command->type= Q_UNKNOWN; read_command_buf[0]= 0; @@ -6260,7 +6260,7 @@ void init_win_path_patterns() } if (insert_dynamic(&patterns, (uchar*) &p)) - die(NullS); + die("Out of memory"); DBUG_PRINT("info", ("p: %s", p)); while (*p) @@ -9331,8 +9331,7 @@ REPLACE *init_replace(char * *from, char * *to,uint count, for (i=1 ; i <= found_sets ; i++) { pos=from[found_set[i-1].table_offset]; - rep_str[i].found= !bcmp((const uchar*) pos, - (const uchar*) "\\^", 3) ? 2 : 1; + rep_str[i].found= !memcmp(pos, "\\^", 3) ? 2 : 1; rep_str[i].replace_string=to_array[found_set[i-1].table_offset]; rep_str[i].to_offset=found_set[i-1].found_offset-start_at_word(pos); rep_str[i].from_offset=found_set[i-1].found_offset-replace_len(pos)+ @@ -9460,8 +9459,8 @@ void copy_bits(REP_SET *to,REP_SET *from) int cmp_bits(REP_SET *set1,REP_SET *set2) { - return bcmp((uchar*) set1->bits,(uchar*) set2->bits, - sizeof(uint) * set1->size_of_bits); + return memcmp(set1->bits, set2->bits, + sizeof(uint) * set1->size_of_bits); } @@ -9530,17 +9529,15 @@ int find_found(FOUND_SET *found_set,uint table_offset, int found_offset) uint start_at_word(char * pos) { - return (((!bcmp((const uchar*) pos, (const uchar*) "\\b",2) && pos[2]) || - !bcmp((const uchar*) pos, (const uchar*) "\\^", 2)) ? 1 : 0); + return (((!memcmp(pos, "\\b",2) && pos[2]) || + !memcmp(pos, "\\^", 2)) ? 1 : 0); } uint end_of_word(char * pos) { char * end=strend(pos); - return ((end > pos+2 && !bcmp((const uchar*) end-2, - (const uchar*) "\\b", 2)) || - (end >= pos+2 && !bcmp((const uchar*) end-2, - (const uchar*) "\\$",2))) ? 1 : 0; + return ((end > pos+2 && !memcmp(end-2, "\\b", 2)) || + (end >= pos+2 && !memcmp(end-2, "\\$",2))) ? 1 : 0; } /**************************************************************************** diff --git a/cmd-line-utils/readline/Makefile.am b/cmd-line-utils/readline/Makefile.am index e5f5717858d..e1e9645e238 100644 --- a/cmd-line-utils/readline/Makefile.am +++ b/cmd-line-utils/readline/Makefile.am @@ -31,7 +31,7 @@ noinst_HEADERS = readline.h chardefs.h keymaps.h \ EXTRA_DIST= emacs_keymap.c vi_keymap.c -DEFS = -DMYSQL_CLIENT_NO_THREADS -DHAVE_CONFIG_H -DNO_KILL_INTR +DEFS = -DMYSQL_CLIENT_NO_THREADS -DHAVE_CONFIG_H -DNO_KILL_INTR -D_GNU_SOURCE=1 # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/cmd-line-utils/readline/input.c b/cmd-line-utils/readline/input.c index 84c0422059a..af81d9cd3b0 100644 --- a/cmd-line-utils/readline/input.c +++ b/cmd-line-utils/readline/input.c @@ -318,7 +318,9 @@ _rl_input_available () return (_kbhit ()); #endif +#if !defined (HAVE_SELECT) return 0; +#endif } int diff --git a/configure.in b/configure.in index 74e575fad8c..539d597fd07 100644 --- a/configure.in +++ b/configure.in @@ -2102,7 +2102,7 @@ MYSQL_TYPE_QSORT AC_FUNC_UTIME_NULL AC_FUNC_VPRINTF -AC_CHECK_FUNCS(alarm bcmp bfill bmove bsearch bzero \ +AC_CHECK_FUNCS(alarm bfill bmove bsearch bzero \ chsize cuserid fchmod fcntl \ fconvert fdatasync fesetround finite fpresetsticky fpsetmask fsync ftruncate \ getcwd gethostbyaddr_r gethostbyname_r getpass getpassphrase getpwnam \ diff --git a/extra/comp_err.c b/extra/comp_err.c index bd03f20a755..c02c7ca3d2a 100644 --- a/extra/comp_err.c +++ b/extra/comp_err.c @@ -639,9 +639,9 @@ static struct message *find_message(struct errors *err, const char *lang, static ha_checksum checksum_format_specifier(const char* msg) { ha_checksum chksum= 0; - const char* p= msg; - const char* start= 0; - int num_format_specifiers= 0; + const uchar* p= (const uchar*) msg; + const uchar* start= NULL; + uint32 num_format_specifiers= 0; while (*p) { diff --git a/extra/replace.c b/extra/replace.c index 9b7695eddcb..fd2d860c212 100644 --- a/extra/replace.c +++ b/extra/replace.c @@ -648,7 +648,7 @@ static REPLACE *init_replace(char * *from, char * *to,uint count, for (i=1 ; i <= found_sets ; i++) { pos=from[found_set[i-1].table_offset]; - rep_str[i].found= (my_bool) (!bcmp(pos,"\\^",3) ? 2 : 1); + rep_str[i].found= (my_bool) (!memcmp(pos,"\\^",3) ? 2 : 1); rep_str[i].replace_string=to_array[found_set[i-1].table_offset]; rep_str[i].to_offset=found_set[i-1].found_offset-start_at_word(pos); rep_str[i].from_offset=found_set[i-1].found_offset-replace_len(pos)+ @@ -776,8 +776,8 @@ static void copy_bits(REP_SET *to,REP_SET *from) static int cmp_bits(REP_SET *set1,REP_SET *set2) { - return bcmp((uchar*) set1->bits,(uchar*) set2->bits, - sizeof(uint) * set1->size_of_bits); + return memcmp(set1->bits, set2->bits, + sizeof(uint) * set1->size_of_bits); } @@ -849,14 +849,14 @@ static short find_found(FOUND_SET *found_set,uint table_offset, static uint start_at_word(char * pos) { - return (((!bcmp(pos,"\\b",2) && pos[2]) || !bcmp(pos,"\\^",2)) ? 1 : 0); + return (((!memcmp(pos,"\\b",2) && pos[2]) || !memcmp(pos,"\\^",2)) ? 1 : 0); } static uint end_of_word(char * pos) { char * end=strend(pos); - return ((end > pos+2 && !bcmp(end-2,"\\b",2)) || - (end >= pos+2 && !bcmp(end-2,"\\$",2))) ? + return ((end > pos+2 && !memcmp(end-2,"\\b",2)) || + (end >= pos+2 && !memcmp(end-2,"\\$",2))) ? 1 : 0; } diff --git a/extra/yassl/src/crypto_wrapper.cpp b/extra/yassl/src/crypto_wrapper.cpp index 28d7f1b5693..b968ec1e6c3 100644 --- a/extra/yassl/src/crypto_wrapper.cpp +++ b/extra/yassl/src/crypto_wrapper.cpp @@ -953,8 +953,9 @@ x509* PemToDer(FILE* file, CertType type, EncryptedInfo* info) info->set = true; } } - fgets(line,sizeof(line), file); // get blank line - begin = ftell(file); + // get blank line + if (fgets(line, sizeof(line), file)) + begin = ftell(file); } } diff --git a/extra/yassl/taocrypt/include/blowfish.hpp b/extra/yassl/taocrypt/include/blowfish.hpp index 90d2c014b4c..94bbab7aea8 100644 --- a/extra/yassl/taocrypt/include/blowfish.hpp +++ b/extra/yassl/taocrypt/include/blowfish.hpp @@ -51,7 +51,7 @@ public: enum { BLOCK_SIZE = BLOWFISH_BLOCK_SIZE, ROUNDS = 16 }; Blowfish(CipherDir DIR, Mode MODE) - : Mode_BASE(BLOCK_SIZE, DIR, MODE) {} + : Mode_BASE(BLOCK_SIZE, DIR, MODE), sbox_(pbox_ + ROUNDS + 2) {} #ifdef DO_BLOWFISH_ASM void Process(byte*, const byte*, word32); @@ -62,8 +62,8 @@ private: static const word32 p_init_[ROUNDS + 2]; static const word32 s_init_[4 * 256]; - word32 pbox_[ROUNDS + 2]; - word32 sbox_[4 * 256]; + word32 pbox_[ROUNDS + 2 + 4 * 256]; + word32* sbox_; void crypt_block(const word32 in[2], word32 out[2]) const; void AsmProcess(const byte* in, byte* out) const; diff --git a/extra/yassl/taocrypt/include/runtime.hpp b/extra/yassl/taocrypt/include/runtime.hpp index 99bbe3ac8a3..9d12b253dd6 100644 --- a/extra/yassl/taocrypt/include/runtime.hpp +++ b/extra/yassl/taocrypt/include/runtime.hpp @@ -35,10 +35,7 @@ // Handler for pure virtual functions namespace __Crun { - static void pure_error(void) - { - assert("Pure virtual method called." == "Aborted"); - } + void pure_error(void); } // namespace __Crun #endif // __sun @@ -54,16 +51,7 @@ extern "C" { #else #include "kernelc.hpp" #endif - -/* Disallow inline __cxa_pure_virtual() */ -static int __cxa_pure_virtual() __attribute__((noinline, used)); -static int __cxa_pure_virtual() -{ - // oops, pure virtual called! - assert("Pure virtual method called." == "Aborted"); - return 0; -} - + int __cxa_pure_virtual () __attribute__ ((weak)); } // extern "C" #endif // __GNUC__ > 2 diff --git a/extra/yassl/taocrypt/src/aes.cpp b/extra/yassl/taocrypt/src/aes.cpp index b2b42d3dcf0..63eff1d91fc 100644 --- a/extra/yassl/taocrypt/src/aes.cpp +++ b/extra/yassl/taocrypt/src/aes.cpp @@ -51,7 +51,7 @@ void AES::Process(byte* out, const byte* in, word32 sz) out += BLOCK_SIZE; in += BLOCK_SIZE; } - else if (mode_ == CBC) + else if (mode_ == CBC) { if (dir_ == ENCRYPTION) while (blocks--) { r_[0] ^= *(word32*)in; @@ -78,6 +78,7 @@ void AES::Process(byte* out, const byte* in, word32 sz) out += BLOCK_SIZE; in += BLOCK_SIZE; } + } } #endif // DO_AES_ASM diff --git a/extra/yassl/taocrypt/src/algebra.cpp b/extra/yassl/taocrypt/src/algebra.cpp index c221ce3d6cb..47a660d5c96 100644 --- a/extra/yassl/taocrypt/src/algebra.cpp +++ b/extra/yassl/taocrypt/src/algebra.cpp @@ -186,10 +186,10 @@ Integer AbstractGroup::CascadeScalarMultiply(const Element &x, struct WindowSlider { - WindowSlider(const Integer &exp, bool fastNegate, + WindowSlider(const Integer &expIn, bool fastNegateIn, unsigned int windowSizeIn=0) - : exp(exp), windowModulus(Integer::One()), windowSize(windowSizeIn), - windowBegin(0), fastNegate(fastNegate), firstTime(true), + : exp(expIn), windowModulus(Integer::One()), windowSize(windowSizeIn), + windowBegin(0), fastNegate(fastNegateIn), firstTime(true), finished(false) { if (windowSize == 0) diff --git a/extra/yassl/taocrypt/src/blowfish.cpp b/extra/yassl/taocrypt/src/blowfish.cpp index 66ff4d829d7..2097b045278 100644 --- a/extra/yassl/taocrypt/src/blowfish.cpp +++ b/extra/yassl/taocrypt/src/blowfish.cpp @@ -53,7 +53,7 @@ void Blowfish::Process(byte* out, const byte* in, word32 sz) out += BLOCK_SIZE; in += BLOCK_SIZE; } - else if (mode_ == CBC) + else if (mode_ == CBC) { if (dir_ == ENCRYPTION) while (blocks--) { r_[0] ^= *(word32*)in; @@ -78,6 +78,7 @@ void Blowfish::Process(byte* out, const byte* in, word32 sz) out += BLOCK_SIZE; in += BLOCK_SIZE; } + } } #endif // DO_BLOWFISH_ASM diff --git a/extra/yassl/taocrypt/src/integer.cpp b/extra/yassl/taocrypt/src/integer.cpp index 85733b88aa9..b054e98bef4 100644 --- a/extra/yassl/taocrypt/src/integer.cpp +++ b/extra/yassl/taocrypt/src/integer.cpp @@ -283,21 +283,23 @@ DWord() {} word GetHighHalfAsBorrow() const {return 0-halfs_.high;} private: + struct dword_struct + { + #ifdef LITTLE_ENDIAN_ORDER + word low; + word high; + #else + word high; + word low; + #endif + }; + union { #ifdef TAOCRYPT_NATIVE_DWORD_AVAILABLE dword whole_; #endif - struct - { - #ifdef LITTLE_ENDIAN_ORDER - word low; - word high; - #else - word high; - word low; - #endif - } halfs_; + struct dword_struct halfs_; }; }; @@ -1214,20 +1216,24 @@ public: #define AS1(x) #x ";" #define AS2(x, y) #x ", " #y ";" #define AddPrologue \ + word res; \ __asm__ __volatile__ \ ( \ "push %%ebx;" /* save this manually, in case of -fPIC */ \ - "mov %2, %%ebx;" \ + "mov %3, %%ebx;" \ ".intel_syntax noprefix;" \ "push ebp;" #define AddEpilogue \ "pop ebp;" \ ".att_syntax prefix;" \ "pop %%ebx;" \ - : \ + "mov %%eax, %0;" \ + : "=g" (res) \ : "c" (C), "d" (A), "m" (B), "S" (N) \ : "%edi", "memory", "cc" \ - ); + ); \ + return res; + #define MulPrologue \ __asm__ __volatile__ \ ( \ diff --git a/extra/yassl/taocrypt/src/misc.cpp b/extra/yassl/taocrypt/src/misc.cpp index 402645c93fd..11dd4dc6d66 100644 --- a/extra/yassl/taocrypt/src/misc.cpp +++ b/extra/yassl/taocrypt/src/misc.cpp @@ -84,12 +84,23 @@ namespace STL = STL_NAMESPACE; } -#if defined(__ICC) || defined(__INTEL_COMPILER) +#ifdef __sun + +// Handler for pure virtual functions +namespace __Crun { + void pure_error() { + assert(!"Aborted: pure virtual method called."); + } +} + +#endif + +#if defined(__ICC) || defined(__INTEL_COMPILER) || (__GNUC__ > 2) extern "C" { int __cxa_pure_virtual() { - assert("Pure virtual method called." == "Aborted"); + assert(!"Aborted: pure virtual method called."); return 0; } @@ -166,14 +177,6 @@ word Crop(word value, unsigned int size) #ifdef TAOCRYPT_X86ASM_AVAILABLE -#ifndef _MSC_VER - static jmp_buf s_env; - static void SigIllHandler(int) - { - longjmp(s_env, 1); - } -#endif - bool HaveCpuId() { diff --git a/extra/yassl/taocrypt/src/twofish.cpp b/extra/yassl/taocrypt/src/twofish.cpp index 84dd35f9191..71601c08162 100644 --- a/extra/yassl/taocrypt/src/twofish.cpp +++ b/extra/yassl/taocrypt/src/twofish.cpp @@ -54,7 +54,7 @@ void Twofish::Process(byte* out, const byte* in, word32 sz) out += BLOCK_SIZE; in += BLOCK_SIZE; } - else if (mode_ == CBC) + else if (mode_ == CBC) { if (dir_ == ENCRYPTION) while (blocks--) { r_[0] ^= *(word32*)in; @@ -82,6 +82,7 @@ void Twofish::Process(byte* out, const byte* in, word32 sz) out += BLOCK_SIZE; in += BLOCK_SIZE; } + } } #endif // DO_TWOFISH_ASM diff --git a/extra/yassl/testsuite/test.hpp b/extra/yassl/testsuite/test.hpp index c921f8f9c69..970ba5bf367 100644 --- a/extra/yassl/testsuite/test.hpp +++ b/extra/yassl/testsuite/test.hpp @@ -160,6 +160,11 @@ inline void err_sys(const char* msg) } +extern "C" { + static int PasswordCallBack(char*, int, int, void*); +} + + static int PasswordCallBack(char* passwd, int sz, int rw, void* userdata) { strncpy(passwd, "12345678", sz); diff --git a/include/m_string.h b/include/m_string.h index b2a1d9ff2f4..d027047f501 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -33,10 +33,6 @@ /* need by my_vsnprintf */ #include -#ifdef _AIX -#undef HAVE_BCMP -#endif - /* This is needed for the definitions of bzero... on solaris */ #if defined(HAVE_STRINGS_H) #include @@ -60,14 +56,6 @@ /* Unixware 7 */ #if !defined(HAVE_BFILL) # define bfill(A,B,C) memset((A),(C),(B)) -# define bmove_align(A,B,C) memcpy((A),(B),(C)) -#endif - -#if !defined(HAVE_BCMP) -# define bcopy(s, d, n) memcpy((d), (s), (n)) -# define bcmp(A,B,C) memcmp((A),(B),(C)) -# define bzero(A,B) memset((A),0,(B)) -# define bmove_align(A,B,C) memcpy((A),(B),(C)) #endif #if defined(__cplusplus) @@ -120,15 +108,6 @@ extern void bfill(uchar *dst,size_t len,pchar fill); extern void bzero(uchar * dst,size_t len); #endif -#if !defined(bcmp) && !defined(HAVE_BCMP) -extern size_t bcmp(const uchar *s1,const uchar *s2,size_t len); -#endif -#ifdef HAVE_purify -extern size_t my_bcmp(const uchar *s1,const uchar *s2,size_t len); -#undef bcmp -#define bcmp(A,B,C) my_bcmp((A),(B),(C)) -#endif /* HAVE_purify */ - #ifndef bmove512 extern void bmove512(uchar *dst,const uchar *src,size_t len); #endif diff --git a/include/my_bitmap.h b/include/my_bitmap.h index 78642df3362..ab69b2d671d 100644 --- a/include/my_bitmap.h +++ b/include/my_bitmap.h @@ -159,22 +159,6 @@ static inline my_bool bitmap_cmp(const MY_BITMAP *map1, const MY_BITMAP *map2) #define bitmap_set_all(MAP) \ (memset((MAP)->bitmap, 0xFF, 4*no_words_in_map((MAP)))) -/** - check, set and clear a bit of interest of an integer. - - If the bit is out of range @retval -1. Otherwise - bit_is_set @return 0 or 1 reflecting the bit is set or not; - bit_do_set @return 1 (bit is set 1) - bit_do_clear @return 0 (bit is cleared to 0) -*/ - -#define bit_is_set(I,B) (sizeof(I) * CHAR_BIT > (B) ? \ - (((I) & (ULL(1) << (B))) == 0 ? 0 : 1) : -1) -#define bit_do_set(I,B) (sizeof(I) * CHAR_BIT > (B) ? \ - ((I) |= (ULL(1) << (B)), 1) : -1) -#define bit_do_clear(I,B) (sizeof(I) * CHAR_BIT > (B) ? \ - ((I) &= ~(ULL(1) << (B)), 0) : -1) - #ifdef __cplusplus } #endif diff --git a/include/my_global.h b/include/my_global.h index e13c7c37b62..572df6a584d 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -556,22 +556,30 @@ int __void__; #endif #endif /* DONT_DEFINE_VOID */ -#if defined(_lint) || defined(FORCE_INIT_OF_VARS) -#define LINT_INIT(var) var=0 /* No uninitialize-warning */ +/* + Deprecated workaround for false-positive uninitialized variables + warnings. Those should be silenced using tool-specific heuristics. + + Enabled by default for g++ due to the bug referenced below. +*/ +#if defined(_lint) || defined(FORCE_INIT_OF_VARS) || \ + (defined(__GNUC__) && defined(__cplusplus)) +#define LINT_INIT(var) var= 0 #else #define LINT_INIT(var) #endif -/* +/* Suppress uninitialized variable warning without generating code. The _cplusplus is a temporary workaround for C++ code pending a fix - for a g++ bug (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34772). + for a g++ bug (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34772). */ -#if defined(_lint) || defined(FORCE_INIT_OF_VARS) || defined(__cplusplus) || \ - !defined(__GNUC__) +#if defined(_lint) || defined(FORCE_INIT_OF_VARS) || \ + defined(__cplusplus) || !defined(__GNUC__) #define UNINIT_VAR(x) x= 0 #else +/* GCC specific self-initialization which inhibits the warning. */ #define UNINIT_VAR(x) x= x #endif @@ -595,7 +603,6 @@ typedef unsigned short ushort; #define set_if_bigger(a,b) do { if ((a) < (b)) (a)=(b); } while(0) #define set_if_smaller(a,b) do { if ((a) > (b)) (a)=(b); } while(0) #define test_all_bits(a,b) (((a) & (b)) == (b)) -#define set_bits(type, bit_count) (sizeof(type)*8 <= (bit_count) ? ~(type) 0 : ((((type) 1) << (bit_count)) - (type) 1)) #define array_elements(A) ((uint) (sizeof(A)/sizeof(A[0]))) /* Define some general constants */ diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared index 3e93b7daf84..39c1975888a 100644 --- a/libmysql/Makefile.shared +++ b/libmysql/Makefile.shared @@ -38,7 +38,7 @@ mystringsobjects = strmov.lo strxmov.lo strxnmov.lo strnmov.lo \ strmake.lo strend.lo strtod.lo \ strnlen.lo strfill.lo is_prefix.lo \ int2str.lo str2int.lo strinstr.lo strcont.lo \ - strcend.lo bcmp.lo ctype-latin1.lo \ + strcend.lo ctype-latin1.lo \ bchange.lo bmove.lo bmove_upp.lo longlong2str.lo \ strtoull.lo strtoll.lo llstr.lo my_vsnprintf.lo \ ctype.lo ctype-simple.lo ctype-bin.lo ctype-mb.lo \ diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 21cbfaf6dbb..e0cc119bd16 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -4425,7 +4425,6 @@ static my_bool setup_one_fetch_function(MYSQL_BIND *param, MYSQL_FIELD *field) field->max_length= 10; /* 2003-11-11 */ param->skip_result= skip_result_with_length; break; - break; case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_TIMESTAMP: param->skip_result= skip_result_with_length; diff --git a/mysql-test/lib/My/SafeProcess/safe_process.cc b/mysql-test/lib/My/SafeProcess/safe_process.cc index 50c433b9b39..1c778362975 100644 --- a/mysql-test/lib/My/SafeProcess/safe_process.cc +++ b/mysql-test/lib/My/SafeProcess/safe_process.cc @@ -159,7 +159,7 @@ int main(int argc, char* const argv[] ) signal(SIGCHLD, handle_signal); signal(SIGABRT, handle_abort); - sprintf(safe_process_name, "safe_process[%d]", own_pid); + sprintf(safe_process_name, "safe_process[%ld]", (long) own_pid); message("Started"); diff --git a/mysys/mf_loadpath.c b/mysys/mf_loadpath.c index 1df613a1733..b329d103d94 100644 --- a/mysys/mf_loadpath.c +++ b/mysys/mf_loadpath.c @@ -42,7 +42,7 @@ char * my_load_path(char * to, const char *path, if (is_cur) is_cur=2; /* Remove current dir */ if (! my_getwd(buff,(uint) (FN_REFLEN-strlen(path)+is_cur),MYF(0))) - VOID(strncat(buff, path+is_cur, FN_REFLEN)); + VOID(strncat(buff, path+is_cur, FN_REFLEN-1)); else VOID(strnmov(buff, path, FN_REFLEN)); /* Return org file name */ } diff --git a/mysys/mf_pack.c b/mysys/mf_pack.c index 4f7cd90e8aa..86fd61537e7 100644 --- a/mysys/mf_pack.c +++ b/mysys/mf_pack.c @@ -52,7 +52,7 @@ void pack_dirname(char * to, const char *from) buff_length= strlen(buff); d_length= (size_t) (start-to); if ((start == to || - (buff_length == d_length && !bcmp(buff,start,d_length))) && + (buff_length == d_length && !memcmp(buff,start,d_length))) && *start != FN_LIBCHAR && *start) { /* Put current dir before */ bchange((uchar*) to, d_length, (uchar*) buff, buff_length, strlen(to)+1); @@ -70,7 +70,7 @@ void pack_dirname(char * to, const char *from) } if (length > 1 && length < d_length) { /* test if /xx/yy -> ~/yy */ - if (bcmp(to,home_dir,length) == 0 && to[length] == FN_LIBCHAR) + if (memcmp(to,home_dir,length) == 0 && to[length] == FN_LIBCHAR) { to[0]=FN_HOMELIB; /* Filename begins with ~ */ (void) strmov_overlapp(to+1,to+length); @@ -80,7 +80,7 @@ void pack_dirname(char * to, const char *from) { /* Test if cwd is ~/... */ if (length > 1 && length < buff_length) { - if (bcmp(buff,home_dir,length) == 0 && buff[length] == FN_LIBCHAR) + if (memcmp(buff,home_dir,length) == 0 && buff[length] == FN_LIBCHAR) { buff[0]=FN_HOMELIB; (void) strmov_overlapp(buff+1,buff+length); @@ -166,7 +166,7 @@ size_t cleanup_dirname(register char *to, const char *from) *pos = FN_LIBCHAR; if (*pos == FN_LIBCHAR) { - if ((size_t) (pos-start) > length && bcmp(pos-length,parent,length) == 0) + if ((size_t) (pos-start) > length && memcmp(pos-length,parent,length) == 0) { /* If .../../; skip prev */ pos-=length; if (pos != start) @@ -197,7 +197,7 @@ size_t cleanup_dirname(register char *to, const char *from) end_parentdir=pos; while (pos >= start && *pos != FN_LIBCHAR) /* remove prev dir */ pos--; - if (pos[1] == FN_HOMELIB || bcmp(pos,parent,length) == 0) + if (pos[1] == FN_HOMELIB || memcmp(pos,parent,length) == 0) { /* Don't remove ~user/ */ pos=strmov(end_parentdir+1,parent); *pos=FN_LIBCHAR; @@ -206,7 +206,7 @@ size_t cleanup_dirname(register char *to, const char *from) } } else if ((size_t) (pos-start) == length-1 && - !bcmp(start,parent+1,length-1)) + !memcmp(start,parent+1,length-1)) start=pos; /* Starts with "../" */ else if (pos-start > 0 && pos[-1] == FN_LIBCHAR) { diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c index e127b2584ae..b7258080337 100644 --- a/mysys/my_bitmap.c +++ b/mysys/my_bitmap.c @@ -508,10 +508,8 @@ uint bitmap_get_first_set(const MY_BITMAP *map) if (*byte_ptr & (1 << k)) return (i*32) + (j*8) + k; } - DBUG_ASSERT(0); } } - DBUG_ASSERT(0); } } return MY_BIT_NONE; @@ -534,7 +532,7 @@ uint bitmap_get_first(const MY_BITMAP *map) { byte_ptr= (uchar*)data_ptr; for (j=0; ; j++, byte_ptr++) - { + { if (*byte_ptr != 0xFF) { for (k=0; ; k++) @@ -542,10 +540,8 @@ uint bitmap_get_first(const MY_BITMAP *map) if (!(*byte_ptr & (1 << k))) return (i*32) + (j*8) + k; } - DBUG_ASSERT(0); } } - DBUG_ASSERT(0); } } return MY_BIT_NONE; diff --git a/mysys/my_gethwaddr.c b/mysys/my_gethwaddr.c index c7f138c7337..00e0e90f1e4 100644 --- a/mysys/my_gethwaddr.c +++ b/mysys/my_gethwaddr.c @@ -47,7 +47,7 @@ my_bool my_gethwaddr(uchar *to) uchar *buf, *next, *end, *addr; struct if_msghdr *ifm; struct sockaddr_dl *sdl; - int i, res=1, mib[6]={CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0}; + int res=1, mib[6]={CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0}; if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1) goto err; diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 26b1cc75af0..b0e7175d0b9 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -30,7 +30,7 @@ my_error_reporter my_getopt_error_reporter= &default_reporter; static int findopt(char *optpat, uint length, const struct my_option **opt_res, - char **ffname); + const char **ffname); my_bool getopt_compare_strings(const char *s, const char *t, uint length); @@ -115,8 +115,8 @@ int handle_options(int *argc, char ***argv, uint opt_found, argvpos= 0, length; my_bool end_of_options= 0, must_be_var, set_maximum_value, option_is_loose; - char **pos, **pos_end, *optend, *UNINIT_VAR(prev_found), - *opt_str, key_name[FN_REFLEN]; + char **pos, **pos_end, *optend, *opt_str, key_name[FN_REFLEN]; + const char *UNINIT_VAR(prev_found); const struct my_option *optp; void *value; int error, i; @@ -225,7 +225,6 @@ int handle_options(int *argc, char ***argv, Find first the right option. Return error in case of an ambiguous, or unknown option */ - LINT_INIT(prev_found); optp= longopts; if (!(opt_found= findopt(opt_str, length, &optp, &prev_found))) { @@ -709,10 +708,10 @@ static int setval(const struct my_option *opts, void *value, char *argument, static int findopt(char *optpat, uint length, const struct my_option **opt_res, - char **ffname) + const char **ffname) { uint count; - struct my_option *opt= (struct my_option *) *opt_res; + const struct my_option *opt= *opt_res; for (count= 0; opt->name; opt++) { @@ -723,8 +722,9 @@ static int findopt(char *optpat, uint length, return 1; if (!count) { + /* We only need to know one prev */ count= 1; - *ffname= (char *) opt->name; /* We only need to know one prev */ + *ffname= opt->name; } else if (strcmp(*ffname, opt->name)) { diff --git a/mysys/my_handler.c b/mysys/my_handler.c index 3bc27b622cb..7aa8177040d 100644 --- a/mysys/my_handler.c +++ b/mysys/my_handler.c @@ -269,7 +269,6 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); a+=a_length; b+=b_length; - break; } break; case HA_KEYTYPE_INT8: diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c index 2c72026ab5a..76faa33e804 100644 --- a/mysys/safemalloc.c +++ b/mysys/safemalloc.c @@ -163,7 +163,7 @@ void *_mymalloc(size_t size, const char *filename, uint lineno, myf MyFlags) my_message(EE_OUTOFMEMORY, buff, MYF(ME_BELL+ME_WAITTANG+ME_NOREFRESH)); } DBUG_PRINT("error",("Out of memory, in use: %ld at line %d, '%s'", - sf_malloc_max_memory,lineno, filename)); + (ulong) sf_malloc_max_memory, lineno, filename)); DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_SET("-d,simulate_out_of_memory");); if (MyFlags & MY_FAE) diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index 0e0e93cf220..b925c5588be 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -125,8 +125,7 @@ static int check_lock(struct st_lock_list *list, const char* lock_type, { THR_LOCK_DATA *data,**prev; uint count=0; - THR_LOCK_OWNER *first_owner; - LINT_INIT(first_owner); + THR_LOCK_OWNER *UNINIT_VAR(first_owner); prev= &list->data; if (list->data) diff --git a/regex/regcomp.c b/regex/regcomp.c index b203d4941e1..8280fbfd6c8 100644 --- a/regex/regcomp.c +++ b/regex/regcomp.c @@ -690,7 +690,6 @@ register cset *cs; case '-': SETERROR(REG_ERANGE); return; /* NOTE RETURN */ - break; default: c = '\0'; break; diff --git a/sql/field.cc b/sql/field.cc index 7360a013ffb..2229bc19b3c 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -8691,7 +8691,13 @@ int Field_set::store(longlong nr, bool unsigned_val) { ASSERT_COLUMN_MARKED_FOR_WRITE; int error= 0; - ulonglong max_nr= set_bits(ulonglong, typelib->count); + ulonglong max_nr; + + if (sizeof(ulonglong)*8 <= typelib->count) + max_nr= ULONGLONG_MAX; + else + max_nr= (ULL(1) << typelib->count) - 1; + if ((ulonglong) nr > max_nr) { nr&= max_nr; diff --git a/sql/item.cc b/sql/item.cc index 5f0ca4374df..db2c4c0974b 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -4130,8 +4130,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) context->first_name_resolution_table, context->last_name_resolution_table, reference, REPORT_ALL_ERRORS, - !any_privileges && - TRUE, TRUE); + !any_privileges, TRUE); } return -1; } diff --git a/sql/item_create.cc b/sql/item_create.cc index fd8f13d6dc5..5726e987ef6 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -5051,8 +5051,6 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type, CHARSET_INFO *cs) { Item *UNINIT_VAR(res); - ulong len; - uint dec; switch (cast_type) { case ITEM_CAST_BINARY: @@ -5075,11 +5073,10 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type, break; case ITEM_CAST_DECIMAL: { - if (c_len == NULL) - { - len= 0; - } - else + ulong len= 0; + uint dec= 0; + + if (c_len) { ulong decoded_size; errno= 0; @@ -5093,11 +5090,7 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type, len= decoded_size; } - if (c_dec == NULL) - { - dec= 0; - } - else + if (c_dec) { ulong decoded_size; errno= 0; @@ -5133,12 +5126,9 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type, } case ITEM_CAST_CHAR: { + int len= -1; CHARSET_INFO *real_cs= (cs ? cs : thd->variables.collation_connection); - if (c_len == NULL) - { - len= LL(-1); - } - else + if (c_len) { ulong decoded_size; errno= 0; @@ -5148,7 +5138,7 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type, my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), "cast as char", MAX_FIELD_BLOBLENGTH); return NULL; } - len= decoded_size; + len= (int) decoded_size; } res= new (thd->mem_root) Item_char_typecast(a, len, real_cs); break; diff --git a/sql/log.cc b/sql/log.cc index b3554d2a068..d8d5f6fa418 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1862,7 +1862,7 @@ static int find_uniq_filename(char *name) file_info= dir_info->dir_entry; for (i=dir_info->number_off_files ; i-- ; file_info++) { - if (bcmp((uchar*) file_info->name, (uchar*) start, length) == 0 && + if (memcmp(file_info->name, start, length) == 0 && test_if_number(file_info->name+length, &number,0)) { set_if_bigger(max_found,(ulong) number); diff --git a/sql/log_event.cc b/sql/log_event.cc index 5ff4b50c6df..d53f13e0b6b 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2905,7 +2905,7 @@ void Query_log_event::print_query_header(IO_CACHE* file, if (likely(charset_inited) && (unlikely(!print_event_info->charset_inited || - bcmp((uchar*) print_event_info->charset, (uchar*) charset, 6)))) + memcmp(print_event_info->charset, charset, 6)))) { CHARSET_INFO *cs_info= get_charset(uint2korr(charset), MYF(MY_WME)); if (cs_info) @@ -2928,8 +2928,8 @@ void Query_log_event::print_query_header(IO_CACHE* file, } if (time_zone_len) { - if (bcmp((uchar*) print_event_info->time_zone_str, - (uchar*) time_zone_str, time_zone_len+1)) + if (memcmp(print_event_info->time_zone_str, + time_zone_str, time_zone_len+1)) { my_b_printf(file,"SET @@session.time_zone='%s'%s\n", time_zone_str, print_event_info->delimiter); @@ -7503,8 +7503,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) { int actual_error= convert_handler_error(error, thd, table); bool idempotent_error= (idempotent_error_code(error) && - ((bit_is_set(slave_exec_mode, - SLAVE_EXEC_MODE_IDEMPOTENT)) == 1)); + (slave_exec_mode & SLAVE_EXEC_MODE_IDEMPOTENT)); bool ignored_error= (idempotent_error == 0 ? ignored_error_code(actual_error) : 0); @@ -8332,7 +8331,7 @@ Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability todo: to introduce a property for the event (handler?) which forces applying the event in the replace (idempotent) fashion. */ - if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1 || + if ((slave_exec_mode & SLAVE_EXEC_MODE_IDEMPOTENT) || m_table->s->db_type()->db_type == DB_TYPE_NDBCLUSTER) { /* @@ -8411,7 +8410,7 @@ Write_rows_log_event::do_after_row_operations(const Slave_reporting_capability * int local_error= 0; m_table->next_number_field=0; m_table->auto_increment_field_not_null= FALSE; - if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1 || + if ((slave_exec_mode & SLAVE_EXEC_MODE_IDEMPOTENT) || m_table->s->db_type()->db_type == DB_TYPE_NDBCLUSTER) { m_table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); @@ -8514,7 +8513,7 @@ Rows_log_event::write_row(const Relay_log_info *const rli, TABLE *table= m_table; // pointer to event's table int error; - int keynum; + int UNINIT_VAR(keynum); auto_afree_ptr key(NULL); /* fill table->record[0] with default values */ @@ -8712,10 +8711,8 @@ int Write_rows_log_event::do_exec_row(const Relay_log_info *const rli) { DBUG_ASSERT(m_table != NULL); - int error= - write_row(rli, /* if 1 then overwrite */ - bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1); - + int error= write_row(rli, (slave_exec_mode & SLAVE_EXEC_MODE_IDEMPOTENT)); + if (error && !thd->is_error()) { DBUG_ASSERT(0); diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index 202b81989a8..e901f44286c 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -441,7 +441,7 @@ copy_extra_record_fields(TABLE *table, DBUG_ASSERT(master_reclength <= table->s->reclength); if (master_reclength < table->s->reclength) - bmove_align(table->record[0] + master_reclength, + memcpy(table->record[0] + master_reclength, table->record[1] + master_reclength, table->s->reclength - master_reclength); @@ -720,7 +720,7 @@ static int find_and_fetch_row(TABLE *table, uchar *key) rnd_pos() returns the record in table->record[0], so we have to move it to table->record[1]. */ - bmove_align(table->record[1], table->record[0], table->s->reclength); + memcpy(table->record[1], table->record[0], table->s->reclength); DBUG_RETURN(error); } @@ -1213,7 +1213,7 @@ int Update_rows_log_event_old::do_exec_row(TABLE *table) overwriting the default values that where put there by the unpack_row() function. */ - bmove_align(table->record[0], m_after_image, table->s->reclength); + memcpy(table->record[0], m_after_image, table->s->reclength); copy_extra_record_fields(table, m_master_reclength, m_width); /* diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 5514c356bd1..99f16b36dfa 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -559,7 +559,7 @@ ulong query_buff_size, slow_launch_time, slave_open_temp_tables; ulong open_files_limit, max_binlog_size, max_relay_log_size; ulong slave_net_timeout, slave_trans_retries; ulong slave_exec_mode_options; -const char *slave_exec_mode_str= "STRICT"; +static const char *slave_exec_mode_str= "STRICT"; ulong thread_cache_size=0, thread_pool_size= 0; ulong binlog_cache_size=0; ulonglong max_binlog_cache_size=0; @@ -2464,7 +2464,6 @@ extern "C" sig_handler handle_segfault(int sig) { time_t curr_time; struct tm tm; - THD *thd=current_thd; /* Strictly speaking, one needs a mutex here @@ -2523,13 +2522,15 @@ the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n", #endif /* HAVE_LINUXTHREADS */ #ifdef HAVE_STACKTRACE + THD *thd=current_thd; + if (!(test_flags & TEST_NO_STACKTRACE)) { - fprintf(stderr,"thd: 0x%lx\n",(long) thd); - fprintf(stderr,"\ -Attempting backtrace. You can use the following information to find out\n\ -where mysqld died. If you see no messages after this, something went\n\ -terribly wrong...\n"); + fprintf(stderr, "thd: 0x%lx\n",(long) thd); + fprintf(stderr, "Attempting backtrace. You can use the following " + "information to find out\nwhere mysqld died. If " + "you see no messages after this, something went\n" + "terribly wrong...\n"); my_print_stacktrace(thd ? (uchar*) thd->thread_stack : NULL, my_thread_stack_size); } @@ -7879,10 +7880,11 @@ static int mysql_init_variables(void) /* Things with default values that are not zero */ delay_key_write_options= (uint) DELAY_KEY_WRITE_ON; - slave_exec_mode_options= 0; - slave_exec_mode_options= (uint) - find_bit_type_or_exit(slave_exec_mode_str, &slave_exec_mode_typelib, NULL, - &error); + slave_exec_mode_options= find_bit_type_or_exit(slave_exec_mode_str, + &slave_exec_mode_typelib, + NULL, &error); + /* Default mode string must not yield a error. */ + DBUG_ASSERT(!error); if (error) return 1; opt_specialflag= SPECIAL_ENGLISH; @@ -8118,8 +8120,9 @@ mysqld_get_one_option(int optid, init_slave_skip_errors(argument); break; case OPT_SLAVE_EXEC_MODE: - slave_exec_mode_options= (uint) - find_bit_type_or_exit(argument, &slave_exec_mode_typelib, "", &error); + slave_exec_mode_options= find_bit_type_or_exit(argument, + &slave_exec_mode_typelib, + "", &error); if (error) return 1; break; @@ -8773,7 +8776,7 @@ static int get_options(int *argc,char **argv) /* Set global MyISAM variables from delay_key_write_options */ fix_delay_key_write((THD*) 0, OPT_GLOBAL); /* Set global slave_exec_mode from its option */ - fix_slave_exec_mode(OPT_GLOBAL); + fix_slave_exec_mode(); #ifndef EMBEDDED_LIBRARY if (mysqld_chroot) diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 316e26f7e40..99a42bbe818 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -1120,8 +1120,7 @@ bool Relay_log_info::cached_charset_compare(char *charset) const { DBUG_ENTER("Relay_log_info::cached_charset_compare"); - if (bcmp((uchar*) cached_charset, (uchar*) charset, - sizeof(cached_charset))) + if (memcmp(cached_charset, charset, sizeof(cached_charset))) { memcpy(const_cast(cached_charset), charset, sizeof(cached_charset)); DBUG_RETURN(1); diff --git a/sql/set_var.cc b/sql/set_var.cc index 241126e1e6f..c5517da92f8 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -92,14 +92,13 @@ TYPELIB delay_key_write_typelib= delay_key_write_type_names, NULL }; -const char *slave_exec_mode_names[]= -{ "STRICT", "IDEMPOTENT", NullS }; -static const unsigned int slave_exec_mode_names_len[]= -{ sizeof("STRICT") - 1, sizeof("IDEMPOTENT") - 1, 0 }; +static const char *slave_exec_mode_names[]= { "STRICT", "IDEMPOTENT", NullS }; +static unsigned int slave_exec_mode_names_len[]= { sizeof("STRICT") - 1, + sizeof("IDEMPOTENT") - 1, 0 }; TYPELIB slave_exec_mode_typelib= { array_elements(slave_exec_mode_names)-1, "", - slave_exec_mode_names, (unsigned int *) slave_exec_mode_names_len + slave_exec_mode_names, slave_exec_mode_names_len }; static int sys_check_ftb_syntax(THD *thd, set_var *var); @@ -1215,16 +1214,14 @@ uchar *sys_var_set::value_ptr(THD *thd, enum_var_type type, void sys_var_set_slave_mode::set_default(THD *thd, enum_var_type type) { - slave_exec_mode_options= 0; - bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT); + slave_exec_mode_options= SLAVE_EXEC_MODE_STRICT; } bool sys_var_set_slave_mode::check(THD *thd, set_var *var) { bool rc= sys_var_set::check(thd, var); - if (!rc && - bit_is_set(var->save_result.ulong_value, SLAVE_EXEC_MODE_STRICT) == 1 && - bit_is_set(var->save_result.ulong_value, SLAVE_EXEC_MODE_IDEMPOTENT) == 1) + if (!rc && (var->save_result.ulong_value & SLAVE_EXEC_MODE_STRICT) && + (var->save_result.ulong_value & SLAVE_EXEC_MODE_IDEMPOTENT)) { rc= true; my_error(ER_SLAVE_AMBIGOUS_EXEC_MODE, MYF(0), ""); @@ -1241,20 +1238,18 @@ bool sys_var_set_slave_mode::update(THD *thd, set_var *var) return rc; } -void fix_slave_exec_mode(enum_var_type type) +void fix_slave_exec_mode(void) { DBUG_ENTER("fix_slave_exec_mode"); - compile_time_assert(sizeof(slave_exec_mode_options) * CHAR_BIT - > SLAVE_EXEC_MODE_LAST_BIT - 1); - if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT) == 1 && - bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 1) + + if ((slave_exec_mode_options & SLAVE_EXEC_MODE_STRICT) && + (slave_exec_mode_options & SLAVE_EXEC_MODE_IDEMPOTENT)) { - sql_print_error("Ambiguous slave modes combination." - " STRICT will be used"); - bit_do_clear(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT); + sql_print_error("Ambiguous slave modes combination. STRICT will be used"); + slave_exec_mode_options&= ~SLAVE_EXEC_MODE_IDEMPOTENT; } - if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 0) - bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT); + if (!(slave_exec_mode_options & SLAVE_EXEC_MODE_IDEMPOTENT)) + slave_exec_mode_options|= SLAVE_EXEC_MODE_STRICT; DBUG_VOID_RETURN; } diff --git a/sql/set_var.h b/sql/set_var.h index bc94c6b85c4..68cd94a5670 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -1446,7 +1446,7 @@ sys_var *find_sys_var(THD *thd, const char *str, uint length=0); int sql_set_variables(THD *thd, List *var_list); bool not_all_support_one_shot(List *var_list); void fix_delay_key_write(THD *thd, enum_var_type type); -void fix_slave_exec_mode(enum_var_type type); +void fix_slave_exec_mode(void); ulong fix_sql_mode(ulong sql_mode); extern sys_var_const_str sys_charset_system; extern sys_var_str sys_init_connect; diff --git a/sql/slave.cc b/sql/slave.cc index af53bc65c0e..795bc481071 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2113,7 +2113,7 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli) DBUG_PRINT("info", ("thd->options: %s%s; rli->last_event_start_time: %lu", FLAGSTR(thd->options, OPTION_NOT_AUTOCOMMIT), FLAGSTR(thd->options, OPTION_BEGIN), - rli->last_event_start_time)); + (ulong) rli->last_event_start_time)); /* Execute the event to change the database and update the binary @@ -2885,8 +2885,8 @@ pthread_handler_t handle_slave_sql(void *arg) char llbuff[22],llbuff1[22]; char saved_log_name[FN_REFLEN]; char saved_master_log_name[FN_REFLEN]; - my_off_t saved_log_pos; - my_off_t saved_master_log_pos; + my_off_t UNINIT_VAR(saved_log_pos); + my_off_t UNINIT_VAR(saved_master_log_pos); my_off_t saved_skip= 0; Relay_log_info* rli = &((Master_info*)arg)->rli; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 3a51b5c5610..d2392bdd9b1 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -8403,15 +8403,15 @@ my_bool mysql_rm_tmp_tables(void) (file->name[1] == '.' && !file->name[2]))) continue; - if (!bcmp((uchar*) file->name, (uchar*) tmp_file_prefix, - tmp_file_prefix_length)) + if (!memcmp(file->name, tmp_file_prefix, + tmp_file_prefix_length)) { char *ext= fn_ext(file->name); uint ext_len= strlen(ext); uint filePath_len= my_snprintf(filePath, sizeof(filePath), "%s%c%s", tmpdir, FN_LIBCHAR, file->name); - if (!bcmp((uchar*) reg_ext, (uchar*) ext, ext_len)) + if (!memcmp(reg_ext, ext, ext_len)) { handler *handler_file= 0; /* We should cut file extention before deleting of table */ diff --git a/sql/sql_class.h b/sql/sql_class.h index 4c1d4a98db0..023367cb747 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -83,9 +83,10 @@ enum enum_ha_read_modes { RFIRST, RNEXT, RPREV, RLAST, RKEY, RNEXT_SAME }; enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_UPDATE }; enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON, DELAY_KEY_WRITE_ALL }; -enum enum_slave_exec_mode { SLAVE_EXEC_MODE_STRICT, - SLAVE_EXEC_MODE_IDEMPOTENT, - SLAVE_EXEC_MODE_LAST_BIT}; + +#define SLAVE_EXEC_MODE_STRICT (1U << 0) +#define SLAVE_EXEC_MODE_IDEMPOTENT (1U << 1) + enum enum_mark_columns { MARK_COLUMNS_NONE, MARK_COLUMNS_READ, MARK_COLUMNS_WRITE}; @@ -2418,7 +2419,7 @@ class select_result :public Sql_alloc { protected: THD *thd; SELECT_LEX_UNIT *unit; - uint nest_level; + int nest_level; public: select_result(); virtual ~select_result() {}; @@ -2559,7 +2560,7 @@ public: Creates a select_export to represent INTO OUTFILE with a defined level of subquery nesting. */ - select_export(sql_exchange *ex, uint nest_level_arg) :select_to_file(ex) + select_export(sql_exchange *ex, int nest_level_arg) :select_to_file(ex) { nest_level= nest_level_arg; } @@ -2576,7 +2577,7 @@ public: Creates a select_export to represent INTO DUMPFILE with a defined level of subquery nesting. */ - select_dump(sql_exchange *ex, uint nest_level_arg) : + select_dump(sql_exchange *ex, int nest_level_arg) : select_to_file(ex) { nest_level= nest_level_arg; @@ -3046,7 +3047,7 @@ public: Creates a select_dumpvar to represent INTO with a defined level of subquery nesting. */ - select_dumpvar(uint nest_level_arg) + select_dumpvar(int nest_level_arg) { var_list.empty(); row_count= 0; diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 75a738a0073..f6045e4704e 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -218,8 +218,7 @@ bool log_in_use(const char* log_name) if ((linfo = tmp->current_linfo)) { pthread_mutex_lock(&linfo->lock); - result = !bcmp((uchar*) log_name, (uchar*) linfo->log_file_name, - log_name_len); + result = !memcmp(log_name, linfo->log_file_name, log_name_len); pthread_mutex_unlock(&linfo->lock); if (result) break; diff --git a/sql/udf_example.c b/sql/udf_example.c index 82af58ec502..637293209e0 100644 --- a/sql/udf_example.c +++ b/sql/udf_example.c @@ -141,7 +141,9 @@ typedef long long longlong; #ifdef HAVE_DLOPEN +#if !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_SOLARIS_STYLE_GETHOST) static pthread_mutex_t LOCK_hostname; +#endif /* These must be right or mysqld will not find the symbol! */ diff --git a/sql/unireg.h b/sql/unireg.h index 3ff7f058e3c..4f6b647964d 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -129,8 +129,8 @@ #define SPECIAL_LOG_QUERIES_NOT_USING_INDEXES 4096 /* Obsolete */ /* Extern defines */ -#define store_record(A,B) bmove_align((A)->B,(A)->record[0],(size_t) (A)->s->reclength) -#define restore_record(A,B) bmove_align((A)->record[0],(A)->B,(size_t) (A)->s->reclength) +#define store_record(A,B) memcpy((A)->B,(A)->record[0],(size_t) (A)->s->reclength) +#define restore_record(A,B) memcpy((A)->record[0],(A)->B,(size_t) (A)->s->reclength) #define cmp_record(A,B) memcmp((A)->record[0],(A)->B,(size_t) (A)->s->reclength) #define empty_record(A) { \ restore_record((A),s->default_values); \ diff --git a/storage/heap/hp_hash.c b/storage/heap/hp_hash.c index aaaa0fe833f..f56df42aab3 100644 --- a/storage/heap/hp_hash.c +++ b/storage/heap/hp_hash.c @@ -577,7 +577,7 @@ int hp_rec_key_cmp(HP_KEYDEF *keydef, const uchar *rec1, const uchar *rec2, } else { - if (bcmp(rec1+seg->start,rec2+seg->start,seg->length)) + if (memcmp(rec1+seg->start,rec2+seg->start,seg->length)) return 1; } } @@ -660,7 +660,7 @@ int hp_key_cmp(HP_KEYDEF *keydef, const uchar *rec, const uchar *key) } else { - if (bcmp(rec+seg->start,key,seg->length)) + if (memcmp(rec+seg->start,key,seg->length)) return 1; } } diff --git a/storage/heap/hp_test2.c b/storage/heap/hp_test2.c index 5c548b6be74..bf06cf03035 100644 --- a/storage/heap/hp_test2.c +++ b/storage/heap/hp_test2.c @@ -406,7 +406,7 @@ int main(int argc, char *argv[]) bmove(record2,record,reclength); if (heap_rsame(file,record,-1) || heap_rsame(file,record2,2)) goto err; - if (bcmp(record2,record,reclength)) + if (memcmp(record2,record,reclength)) { puts("heap_rsame didn't find right record"); goto end; @@ -415,7 +415,7 @@ int main(int argc, char *argv[]) puts("- Test of read through position"); if (heap_rrnd(file,record,position)) goto err; - if (bcmp(record3,record,reclength)) + if (memcmp(record3,record,reclength)) { puts("heap_frnd didn't find right record"); goto end; diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c index 7373a97cfb0..3396d1adf2f 100644 --- a/storage/innobase/os/os0file.c +++ b/storage/innobase/os/os0file.c @@ -3974,6 +3974,9 @@ os_aio_simulated_handle( ulint n; ulint i; + /* Fix compiler warning */ + *consecutive_ios = NULL; + segment = os_aio_get_array_and_local_segment(&array, global_segment); restart: diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c index f2f390862bd..8ecb07d75e8 100644 --- a/storage/myisam/mi_open.c +++ b/storage/myisam/mi_open.c @@ -139,7 +139,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) (uchar*) myisam_file_magic, 4)) { DBUG_PRINT("error",("Wrong header in %s",name_buff)); - DBUG_DUMP("error_dump",(char*) share->state.header.file_version, + DBUG_DUMP("error_dump", share->state.header.file_version, head_length); my_errno=HA_ERR_NOT_A_TABLE; goto err; diff --git a/storage/myisam/mi_page.c b/storage/myisam/mi_page.c index 76fac8688a7..90e31e72532 100644 --- a/storage/myisam/mi_page.c +++ b/storage/myisam/mi_page.c @@ -49,7 +49,7 @@ uchar *_mi_fetch_keypage(register MI_INFO *info, MI_KEYDEF *keyinfo, { DBUG_PRINT("error",("page %lu had wrong page length: %u", (ulong) page, page_size)); - DBUG_DUMP("page", (char*) tmp, keyinfo->block_length); + DBUG_DUMP("page", tmp, keyinfo->block_length); info->last_keypage = HA_OFFSET_ERROR; mi_print_error(info->s, HA_ERR_CRASHED); my_errno = HA_ERR_CRASHED; diff --git a/storage/myisam/mi_search.c b/storage/myisam/mi_search.c index 95f817e47aa..9c842fba544 100644 --- a/storage/myisam/mi_search.c +++ b/storage/myisam/mi_search.c @@ -819,7 +819,7 @@ uint _mi_get_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag, DBUG_PRINT("error", ("Found too long null packed key: %u of %u at 0x%lx", length, keyseg->length, (long) *page_pos)); - DBUG_DUMP("key",(char*) *page_pos,16); + DBUG_DUMP("key", *page_pos, 16); mi_print_error(keyinfo->share, HA_ERR_CRASHED); my_errno=HA_ERR_CRASHED; return 0; @@ -876,7 +876,7 @@ uint _mi_get_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag, { DBUG_PRINT("error",("Found too long packed key: %u of %u at 0x%lx", length, keyseg->length, (long) *page_pos)); - DBUG_DUMP("key",(char*) *page_pos,16); + DBUG_DUMP("key", *page_pos, 16); mi_print_error(keyinfo->share, HA_ERR_CRASHED); my_errno=HA_ERR_CRASHED; return 0; /* Error */ @@ -948,7 +948,7 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag, DBUG_PRINT("error", ("Found too long binary packed key: %u of %u at 0x%lx", length, keyinfo->maxlength, (long) *page_pos)); - DBUG_DUMP("key",(char*) *page_pos,16); + DBUG_DUMP("key", *page_pos, 16); mi_print_error(keyinfo->share, HA_ERR_CRASHED); my_errno=HA_ERR_CRASHED; DBUG_RETURN(0); /* Wrong key */ diff --git a/storage/myisam/mi_test2.c b/storage/myisam/mi_test2.c index 23c58638166..d7c168d01b0 100644 --- a/storage/myisam/mi_test2.c +++ b/storage/myisam/mi_test2.c @@ -415,7 +415,7 @@ int main(int argc, char *argv[]) } ant=0; while (mi_rprev(file,read_record3,0) == 0 && - bcmp(read_record3+start,key,length) == 0) ant++; + memcmp(read_record3+start,key,length) == 0) ant++; if (ant != dupp_keys) { printf("prev: Found: %d records of %d\n",ant,dupp_keys); @@ -453,7 +453,7 @@ int main(int argc, char *argv[]) goto end; } if (mi_rlast(file,read_record2,0) || - bcmp(read_record2,read_record3,reclength)) + memcmp(read_record2,read_record3,reclength)) { printf("Can't find last record\n"); DBUG_DUMP("record2",(uchar*) read_record2,reclength); @@ -468,7 +468,7 @@ int main(int argc, char *argv[]) printf("prev: I found: %d records of %d\n",ant,write_count); goto end; } - if (bcmp(read_record,read_record3,reclength)) + if (memcmp(read_record,read_record3,reclength)) { printf("Can't find first record\n"); goto end; @@ -483,7 +483,7 @@ int main(int argc, char *argv[]) mi_rprev(file,read_record3,0) == 0 || mi_rnext(file,read_record3,0)) goto err; - if (bcmp(read_record,read_record3,reclength) != 0) + if (memcmp(read_record,read_record3,reclength) != 0) printf("Can't find first record\n"); if (!silent) @@ -495,7 +495,7 @@ int main(int argc, char *argv[]) mi_rnext(file,read_record3,0) == 0 || mi_rprev(file,read_record3,0)) goto err; - if (bcmp(read_record2,read_record3,reclength)) + if (memcmp(read_record2,read_record3,reclength)) printf("Can't find last record\n"); #ifdef NOT_ANYMORE if (!silent) @@ -509,7 +509,7 @@ int main(int argc, char *argv[]) bzero((char*) file->lastkey,file->s->base.max_key_length*2); if (mi_rkey(file,read_record,0,key2,(uint) i,HA_READ_PREFIX)) goto err; - if (bcmp(read_record+start,key,(uint) i)) + if (memcmp(read_record+start,key,(uint) i)) { puts("Didn't find right record"); goto end; @@ -528,7 +528,7 @@ int main(int argc, char *argv[]) opt_delete++; ant=1; while (mi_rnext(file,read_record3,0) == 0 && - bcmp(read_record3+start,key,length) == 0) ant++; + memcmp(read_record3+start,key,length) == 0) ant++; if (ant != dupp_keys-1) { printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-1); @@ -546,7 +546,7 @@ int main(int argc, char *argv[]) opt_delete++; ant=1; while (mi_rprev(file,read_record3,0) == 0 && - bcmp(read_record3+start,key,length) == 0) ant++; + memcmp(read_record3+start,key,length) == 0) ant++; if (ant != dupp_keys-2) { printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-2); @@ -566,7 +566,7 @@ int main(int argc, char *argv[]) if (mi_rnext(file,read_record,0)) goto err; /* Skall finnas poster */ while (mi_rnext(file,read_record3,0) == 0 && - bcmp(read_record3+start,key,length) == 0) ant++; + memcmp(read_record3+start,key,length) == 0) ant++; if (ant != dupp_keys-3) { printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-3); @@ -581,7 +581,7 @@ int main(int argc, char *argv[]) opt_delete++; ant=0; while (mi_rprev(file,read_record3,0) == 0 && - bcmp(read_record3+start,key,length) == 0) ant++; + memcmp(read_record3+start,key,length) == 0) ant++; if (ant != dupp_keys-4) { printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-4); @@ -604,7 +604,7 @@ int main(int argc, char *argv[]) for (i=min(2,keys) ; i-- > 0 ;) { if (mi_rsame(file,read_record2,(int) i)) goto err; - if (bcmp(read_record,read_record2,reclength) != 0) + if (memcmp(read_record,read_record2,reclength) != 0) { printf("is_rsame didn't find same record\n"); goto end; diff --git a/storage/myisam/mi_unique.c b/storage/myisam/mi_unique.c index 02fcd9289dd..fdba84a2e67 100644 --- a/storage/myisam/mi_unique.c +++ b/storage/myisam/mi_unique.c @@ -56,7 +56,7 @@ my_bool mi_check_unique(MI_INFO *info, MI_UNIQUEDEF *def, uchar *record, if (_mi_search_next(info,info->s->keyinfo+def->key, info->lastkey, MI_UNIQUE_HASH_LENGTH, SEARCH_BIGGER, info->s->state.key_root[def->key]) || - bcmp((char*) info->lastkey, (char*) key_buff, MI_UNIQUE_HASH_LENGTH)) + memcmp(info->lastkey, key_buff, MI_UNIQUE_HASH_LENGTH)) { info->page_changed=1; /* Can't optimize read next */ info->lastpos=lastpos; diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index 7886cc2a5a2..8e18924c5b8 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -293,8 +293,9 @@ static int myisammrg_parent_open_callback(void *callback_param, } } - DBUG_PRINT("myrg", ("open: '%.*s'.'%.*s'", child_l->db_length, child_l->db, - child_l->table_name_length, child_l->table_name)); + DBUG_PRINT("myrg", ("open: '%.*s'.'%.*s'", (int) child_l->db_length, + child_l->db, (int) child_l->table_name_length, + child_l->table_name)); /* Convert to lowercase if required. */ if (lower_case_table_names && child_l->table_name_length) @@ -341,7 +342,7 @@ static MI_INFO *myisammrg_attach_children_callback(void *callback_param) TABLE *parent; TABLE *child; TABLE_LIST *child_l; - MI_INFO *myisam; + MI_INFO *UNINIT_VAR(myisam); DBUG_ENTER("myisammrg_attach_children_callback"); my_errno= 0; diff --git a/strings/CMakeLists.txt b/strings/CMakeLists.txt index 3d9de566670..67e8ad22783 100755 --- a/strings/CMakeLists.txt +++ b/strings/CMakeLists.txt @@ -18,7 +18,7 @@ SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG -DSAFEMALLOC -DSAFE_MUT INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) -SET(STRINGS_SOURCES bchange.c bcmp.c bfill.c bmove512.c bmove_upp.c ctype-big5.c ctype-bin.c ctype-cp932.c +SET(STRINGS_SOURCES bchange.c bfill.c bmove512.c bmove_upp.c ctype-big5.c ctype-bin.c ctype-cp932.c ctype-czech.c ctype-euc_kr.c ctype-eucjpms.c ctype-extra.c ctype-gb2312.c ctype-gbk.c ctype-latin1.c ctype-mb.c ctype-simple.c ctype-sjis.c ctype-tis620.c ctype-uca.c ctype-ucs2.c ctype-ujis.c ctype-utf8.c ctype-win1250ch.c ctype.c decimal.c int2str.c diff --git a/strings/Makefile.am b/strings/Makefile.am index db9016b7148..1303af91820 100644 --- a/strings/Makefile.am +++ b/strings/Makefile.am @@ -21,19 +21,19 @@ pkglib_LIBRARIES = libmystrings.a # Exact one of ASSEMBLER_X if ASSEMBLER_x86 ASRCS = strings-x86.s longlong2str-x86.s my_strtoll10-x86.s -CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c str_alloc.c longlong2str_asm.c my_strchr.c strmov.c +CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c str_alloc.c longlong2str_asm.c my_strchr.c strmov.c else if ASSEMBLER_sparc32 # These file MUST all be on the same line!! Otherwise automake # generats a very broken makefile ASRCS = bmove_upp-sparc.s strappend-sparc.s strend-sparc.s strinstr-sparc.s strmake-sparc.s strmov-sparc.s strnmov-sparc.s strstr-sparc.s -CSRCS = strcont.c strfill.c strcend.c is_prefix.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c strxmov.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c my_strtoll10.c str_alloc.c my_strchr.c strmov.c +CSRCS = strcont.c strfill.c strcend.c is_prefix.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c strxmov.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c my_strtoll10.c str_alloc.c my_strchr.c strmov.c else #no assembler ASRCS = # These file MUST all be on the same line!! Otherwise automake # generats a very broken makefile -CSRCS = strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c strstr.c strinstr.c strmake.c strnmov.c strmov.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c my_strtoll10.c str_alloc.c my_strchr.c +CSRCS = strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c strstr.c strinstr.c strmake.c strnmov.c strmov.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c my_strtoll10.c str_alloc.c my_strchr.c endif endif @@ -57,7 +57,7 @@ EXTRA_DIST = ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc CHARSET_INFO.txt libmystrings_a_LIBADD= -conf_to_src_SOURCES = conf_to_src.c xml.c ctype.c bcmp.c +conf_to_src_SOURCES = conf_to_src.c xml.c ctype.c conf_to_src_LDADD= #force static linking of conf_to_src - essential when linking against #custom installation of libc diff --git a/strings/bcmp.c b/strings/bcmp.c deleted file mode 100644 index 1b6ed22fc22..00000000000 --- a/strings/bcmp.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (C) 2000 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* - bcmp(s1, s2, len) returns 0 if the "len" bytes starting at "s1" are - identical to the "len" bytes starting at "s2", non-zero if they are - different. - Now only used with purify because purify gives wrong warnings when - comparing a shorter string with bcmp. -*/ - -#include -#include "m_string.h" - -#ifdef HAVE_purify -#undef bcmp -#undef HAVE_BCMP -#endif - -#if !defined(bcmp) && !defined(HAVE_BCMP) - -#if defined(MC68000) && defined(DS90) - -int bcmp(s1,s2, len) -const char *s1; -const char *s2; -uint len; /* 0 <= len <= 65535 */ -{ - asm(" movl 12(a7),d0 "); - asm(" subqw #1,d0 "); - asm(" blt .L5 "); - asm(" movl 4(a7),a1 "); - asm(" movl 8(a7),a0 "); - asm(".L4: cmpmb (a0)+,(a1)+ "); - asm(" dbne d0,.L4 "); - asm(".L5: addqw #1,d0 "); -} - -#else - -#ifndef HAVE_purify -size_t bcmp(register const uchar *s1,register const uchar *s2, - register size_t len) -#else -size_t my_bcmp(register const uchar *s1,register const uchar *s2, - register size_t len) -#endif -{ - while (len-- != 0 && *s1++ == *s2++) ; - return len+1; -} - -#endif -#endif /* BSD_FUNCS */ diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index cead55f8a0a..865a19b0828 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -203,7 +203,7 @@ static int my_strnncoll_ucs2(CHARSET_INFO *cs, my_bool t_is_prefix) { int s_res,t_res; - my_wc_t UNINIT_VAR(s_wc),t_wc; + my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc); const uchar *se=s+slen; const uchar *te=t+tlen; MY_UNICASE_INFO **uni_plane= cs->caseinfo; @@ -317,7 +317,7 @@ static int my_strncasecmp_ucs2(CHARSET_INFO *cs, const char *s, const char *t, size_t len) { int s_res,t_res; - my_wc_t UNINIT_VAR(s_wc),t_wc; + my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc); const char *se=s+len; const char *te=t+len; MY_UNICASE_INFO **uni_plane= cs->caseinfo; @@ -1384,7 +1384,7 @@ int my_strnncoll_ucs2_bin(CHARSET_INFO *cs, my_bool t_is_prefix) { int s_res,t_res; - my_wc_t UNINIT_VAR(s_wc),t_wc; + my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc); const uchar *se=s+slen; const uchar *te=t+tlen; diff --git a/strings/make-ccc b/strings/make-ccc index 78d5ad1ce42..93be2bbf862 100755 --- a/strings/make-ccc +++ b/strings/make-ccc @@ -1,3 +1,3 @@ -ccc -DHAVE_CONFIG_H -I. -I. -I.. -I./../include -I../include -O -DDBUG_OFF -fast -O3 -fomit-frame-pointer -c atof.c bchange.c bcmp.c bfill.c bmove.c bmove512.c bmove_upp.c ct_init.c ctype-latin1.c int2str.c is_prefix.c llstr.c longlong2str.c r_strinstr.c str2int.c strappend.c strcend.c strcont.c strend.c strfill.c strinstr.c strmake.c strmov.c strnmov.c strstr.c strtol.c strtoll.c strtoul.c strtoull.c strxmov.c strxnmov.c +ccc -DHAVE_CONFIG_H -I. -I. -I.. -I./../include -I../include -O -DDBUG_OFF -fast -O3 -fomit-frame-pointer -c atof.c bchange.c bfill.c bmove.c bmove512.c bmove_upp.c ct_init.c ctype-latin1.c int2str.c is_prefix.c llstr.c longlong2str.c r_strinstr.c str2int.c strappend.c strcend.c strcont.c strend.c strfill.c strinstr.c strmake.c strmov.c strnmov.c strstr.c strtol.c strtoll.c strtoul.c strtoull.c strxmov.c strxnmov.c rm libmystrings.a ar -cr libmystrings.a atof.o diff --git a/strings/str_test.c b/strings/str_test.c index 3ddfca39419..a476809e22d 100644 --- a/strings/str_test.c +++ b/strings/str_test.c @@ -50,10 +50,10 @@ int main(void) errors=tests=0; init_strings(); - test_arg("bcmp(from,to,5)",(long) my_test(bcmp(from,to,5)),1L); - test_arg("bcmp(from,from,5)",(long) bcmp(from,from,5),0L); + test_arg("memcmp(from,to,5)",(long) my_test(memcmp(from,to,5)),1L); + test_arg("memcmp(from,from,5)",(long) memcmp(from,from,5),0L); - test_arg("bcmp(from,to,0)",(long) bcmp(from,to,0),0L); + test_arg("memcmp(from,to,0)",(long) memcmp(from,to,0),0L); test_arg("strend(from)",(long) strend(from),(long) from+F_LEN); test_arg("strchr(v1,'M')",(long) strchr(v1,'M'),(long) v1); test_arg("strchr(v1,'y')",(long) strchr(v1,'y'),(long) v1+4); @@ -93,7 +93,7 @@ int main(void) test_strarg("bmove_upp(to+6,from+6,3)",(bmove_upp(to+6,from+6,3),0L),INT_MAX32, 3,T_CHAR,3,F_CHAR,0,0); test_strarg("bmove_upp(to,from,0)",(bmove_upp(to,from,0),0L),INT_MAX32,0,0); - test_strarg("bmove_align(to,from,8)",(bmove_align(to,from,8),0L),INT_MAX32, + test_strarg("memcpy(to,from,8)",(memcpy(to,from,8),0L),INT_MAX32, 8,F_CHAR,0,0); test_strarg("strappend(to,3,' ')",(strappend(to,3,' '),0L),INT_MAX32, 3,T_CHAR,1,0,T_LEN-4,T_CHAR,1,0,0,0); @@ -233,7 +233,7 @@ int compare_buff(const char *message, char * b1, char * b2, int length, { int i,error=0; - if (bcmp(b1,b2,length)) + if (memcmp(b1,b2,length)) { errors++; printf("func: '%s' Buffers differ\nIs: ",message); diff --git a/strings/xml.c b/strings/xml.c index 1b697ec6b26..f3cfaad54fa 100644 --- a/strings/xml.c +++ b/strings/xml.c @@ -123,16 +123,16 @@ static int my_xml_scan(MY_XML_PARSER *p,MY_XML_ATTR *a) a->beg=p->cur; a->end=p->cur; - if ((p->end - p->cur > 3) && !bcmp(p->cur,"", 3); p->cur++) + for (; (p->cur < p->end) && memcmp(p->cur, "-->", 3); p->cur++) {} - if (!bcmp(p->cur, "-->", 3)) + if (!memcmp(p->cur, "-->", 3)) p->cur+=3; a->end=p->cur; lex=MY_XML_COMMENT; } - else if (!bcmp(p->cur, "cur, "cur+= 9; for (; p->cur < p->end - 2 ; p->cur++) diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 97d146ff9ef..c492db723b0 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -18096,7 +18096,7 @@ static void test_bug53371() static void test_bug53907() { int rc; - char buf[] = "\x4test\x14../client_test_db/t1"; + uchar buf[] = "\x4test\x14../client_test_db/t1"; myheader("test_bug53907"); From 0300935ff3f6b422cff4c383d74ce0124dfd7f1f Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 2 Jul 2010 18:42:32 -0300 Subject: [PATCH 073/112] Bug#53445: Build with -Wall and fix warnings that it generates If bzero is not available, resort to memset. Also, remove dead bzero.c --- include/m_string.h | 8 ++--- strings/bzero.c | 82 ---------------------------------------------- 2 files changed, 4 insertions(+), 86 deletions(-) delete mode 100644 strings/bzero.c diff --git a/include/m_string.h b/include/m_string.h index d027047f501..3e5cd063b7b 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -58,6 +58,10 @@ # define bfill(A,B,C) memset((A),(C),(B)) #endif +#if !defined(bzero) && !defined(HAVE_BZERO) +# define bzero(A,B) memset((A),0,(B)) +#endif + #if defined(__cplusplus) extern "C" { #endif @@ -104,10 +108,6 @@ extern const double log_10[309]; extern void bfill(uchar *dst,size_t len,pchar fill); #endif -#if !defined(bzero) && !defined(HAVE_BZERO) -extern void bzero(uchar * dst,size_t len); -#endif - #ifndef bmove512 extern void bmove512(uchar *dst,const uchar *src,size_t len); #endif diff --git a/strings/bzero.c b/strings/bzero.c deleted file mode 100644 index b720de65eed..00000000000 --- a/strings/bzero.c +++ /dev/null @@ -1,82 +0,0 @@ -/* Copyright (C) 2000 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* File : bzero.c - Author : Richard A. O'Keefe. - Michael Widenius; ifdef MC68000 - Updated: 23 April 1984 - Defines: bzero() - - bzero(dst, len) moves "len" 0 bytes to "dst". - Thus to clear a disc buffer to 0s do bzero(buffer, BUFSIZ). - - Note: the "b" routines are there to exploit certain VAX order codes, - The asm code is presented for your interest and amusement. -*/ - -#ifndef BSD_FUNCS -#include "strings.h" - -#ifdef bzero -#undef bzero /* remove macro */ -#endif - -#if VaxAsm - -static void _bzero64 _A((char *dst,int len)); - -void bzero(dst, len) -char *dst; -uint len; -{ - while ((int) len >= 64*K) - { - _bzero64(dst, 64*K-1); - dst += 64*K-1; - len -= 64*K-1; - } - _bzero64(dst, len); -} - -_bzero64(dst, len) -char *dst; -int len; -{ - asm("movc5 $0,*4(ap),$0,8(ap),*4(ap)"); -} - -#else - -#if defined(MC68000) && defined(DS90) - -void bzero(dst, len) -char *dst; -uint len; -{ - bfill(dst,len,0); /* This is very optimized ! */ -} /* bzero */ - -#else - -void bzero(dst, len) -register char *dst; -register uint len; -{ - while (len-- != 0) *dst++ = 0; -} /* bzero */ - -#endif -#endif -#endif /* BSD_FUNCS */ From 85d281737f0feccbd43d7f025658d260d340dd84 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Sat, 3 Jul 2010 10:20:05 -0300 Subject: [PATCH 074/112] Fix somewhat bogus GCC warning. Although needless as the base class is mostly empty, initialize the base class explicitly in the copy constructor. --- sql/sql_list.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_list.h b/sql/sql_list.h index 3e0ba2b2ede..c61846c22cd 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -74,7 +74,7 @@ public: SQL_I_List() { empty(); } - SQL_I_List(const SQL_I_List &tmp) + SQL_I_List(const SQL_I_List &tmp) : Sql_alloc() { elements= tmp.elements; first= tmp.first; From 1a17d7e8079b4cbda51c311eceaea38b407556f3 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 4 Jul 2010 12:02:49 +0800 Subject: [PATCH 075/112] The following statements support the CURRENT_USER() where a user is needed. DROP USER RENAME USER CURRENT_USER() ... GRANT ... TO CURRENT_USER() REVOKE ... FROM CURRENT_USER() ALTER DEFINER = CURRENT_USER() EVENTbut, When these statements are binlogged, CURRENT_USER() just is binlogged as 'CURRENT_USER()', it is not expanded to the real user name. When slave executes the log event, 'CURRENT_USER()' is expand to the user of slave SQL thread, but SQL thread's user name always NULL. This breaks the replication. After this patch, session's user will be written into query log events if these statements call CURREN_USER() or 'ALTER EVENT' does not assign a definer. mysql-test/include/diff_tables.inc: Expend its abilities. Now it can diff not only in sessions of 'master' and 'slave', but other sessions as well. sql/log_event.cc: session's user will be written into Query_log_event, if is_current_user_used() is TRUE. On slave SQL thread, Only thd->invoker is written into Query_log_event, if it exists. sql/sql_acl.cc: On slave SQL thread, grantor should copy from thd->invoker, if it exists sql/sql_class.h: On slave SQL thread, thd->invoker is used to store the applying event's invoker. --- mysql-test/include/diff_tables.inc | 18 +- mysql-test/include/rpl_diff_tables.inc | 35 +++ .../suite/rpl/r/rpl_current_user.result | 205 +++++++++++++++ .../suite/rpl/r/rpl_innodb_mixed_dml.result | 2 +- mysql-test/suite/rpl/t/rpl_current_user.cnf | 9 + mysql-test/suite/rpl/t/rpl_current_user.test | 238 ++++++++++++++++++ sql/log_event.cc | 65 ++++- sql/log_event.h | 7 +- sql/sql_acl.cc | 23 +- sql/sql_class.cc | 20 ++ sql/sql_class.h | 31 +++ sql/sql_parse.cc | 2 +- 12 files changed, 634 insertions(+), 21 deletions(-) create mode 100644 mysql-test/include/rpl_diff_tables.inc create mode 100644 mysql-test/suite/rpl/r/rpl_current_user.result create mode 100644 mysql-test/suite/rpl/t/rpl_current_user.cnf create mode 100644 mysql-test/suite/rpl/t/rpl_current_user.test diff --git a/mysql-test/include/diff_tables.inc b/mysql-test/include/diff_tables.inc index d15dd56b35d..e11e69b3023 100644 --- a/mysql-test/include/diff_tables.inc +++ b/mysql-test/include/diff_tables.inc @@ -64,17 +64,13 @@ let $_diff_table=$diff_table_2; let $_diff_i=2; while ($_diff_i) { - # Parse out any leading "master:" or "slave:" from the table - # specification and connect the appropriate server. - let $_diff_conn_master=`SELECT SUBSTR('$_diff_table', 1, 7) = 'master:'`; - if ($_diff_conn_master) { - let $_diff_table=`SELECT SUBSTR('$_diff_table', 8)`; - connection master; - } - let $_diff_conn_slave=`SELECT SUBSTR('$_diff_table', 1, 6) = 'slave:'`; - if ($_diff_conn_slave) { - let $_diff_table=`SELECT SUBSTR('$_diff_table', 7)`; - connection slave; + # Parse out any leading "master:" or "slave:" from the table specification +# and connect the appropriate server. + let $_pos= `SELECT LOCATE(':', '$_diff_table')`; + let $_diff_conn=`SELECT SUBSTR('$_diff_table', 1, $_pos-1)`; + if (`SELECT "XX$_diff_conn" <> "XX"`) { + let $_diff_table=`SELECT SUBSTR('$_diff_table', $_pos+1)`; + connection $_diff_conn; } # Sanity-check the input. diff --git a/mysql-test/include/rpl_diff_tables.inc b/mysql-test/include/rpl_diff_tables.inc new file mode 100644 index 00000000000..c3a45578a79 --- /dev/null +++ b/mysql-test/include/rpl_diff_tables.inc @@ -0,0 +1,35 @@ +# ############################################################################# +# Check whether the given table is consistent between different master and +# slaves +# +# Usage: +# --let $diff_table= test.t1 +# --let $diff_server_list= master, slave, slave2 +# --source include/rpl_diff_tables.inc +# ############################################################################# + +if (`SELECT "XX$diff_table" = "XX"`) +{ + --die diff_table is null. +} + +--let $_servers= master, slave +if (`SELECT "XX$diff_server_list" <> "XX"`) +{ + --let $_servers= $diff_server_list +} + +--let $_master= `SELECT SUBSTRING_INDEX('$_servers', ',', 1)` +--let $_servers= `SELECT LTRIM(SUBSTRING('$_servers', LENGTH('$_master') + 2))` +connection $_master; +while (`SELECT "XX$_servers" <> "XX"`) +{ + --let $_slave= `SELECT SUBSTRING_INDEX('$_servers', ',', 1)` + --let $_servers= `SELECT LTRIM(SUBSTRING('$_servers', LENGTH('$_slave') + 2))` + + --sync_slave_with_master $_slave + --let $diff_table_1= $_master:$diff_table + --let $diff_table_2= $_slave:$diff_table + --source include/diff_tables.inc + connection $_slave; +} diff --git a/mysql-test/suite/rpl/r/rpl_current_user.result b/mysql-test/suite/rpl/r/rpl_current_user.result new file mode 100644 index 00000000000..85490c2571c --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_current_user.result @@ -0,0 +1,205 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; + +# On slave2 +# Connect slave2 to slave +CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=SLAVE_MYPORT;, +MASTER_LOG_FILE='slave-bin.000001', MASTER_USER='root'; +START SLAVE; + +# [On master] +DROP VIEW IF EXISTS v_user; +DROP VIEW IF EXISTS v_tables_priv; +DROP VIEW IF EXISTS v_procs_priv; +DROP PROCEDURE IF EXISTS p1; +DROP PROCEDURE IF EXISTS my_grant; +DROP PROCEDURE IF EXISTS my_revoke; +DROP FUNCTION IF EXISTS my_user; +DROP EVENT IF EXISTS e1; +CREATE TABLE t1(c1 char(100)); +CREATE VIEW test.v_user AS SELECT * FROM mysql.user WHERE User LIKE 'bug48321%'; +CREATE VIEW test.v_tables_priv AS SELECT * FROM mysql.tables_priv WHERE User LIKE 'bug48321%'; +CREATE VIEW test.v_procs_priv AS SELECT * FROM mysql.procs_priv WHERE User LIKE 'bug48321%'; +CREATE VIEW test.v_event AS SELECT definer FROM mysql.event WHERE name = 'e1'; +CREATE PROCEDURE p1() SELECT 1; +# bug48321_1-01234 has the max length(16) of user. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1-01234'@'localhost' WITH GRANT OPTION; + +# Make sure the max lengths of user and host +# the user name is too lengh +GRANT CREATE USER ON *.* TO '01234567890123456'@'fakehost'; +ERROR HY000: String '01234567890123456' is too long for user name (should be no longer than 16) +# the host name is too lengh +GRANT CREATE USER ON *.* TO 'fakename'@'0123456789012345678901234567890123456789012345678901234567890'; +ERROR HY000: String '0123456789012345678901234567890123456789012345678901234567890' is too long for host name (should be no longer than 60) + +# User 'bug48321_1-01234' connects to master by conn1 +# [On conn1] +# Verify 'REVOKE ALL' statement +REVOKE ALL PRIVILEGES, GRANT OPTION FROM CURRENT_USER(); +Comparing tables master:test.v_user and slave:test.v_user +Comparing tables master:test.v_user and slave2:test.v_user + +# Verify 'GRANT ... ON TABLE ...' statement +GRANT CREATE, INSERT, SELECT ON TABLE test.t1 TO CURRENT_USER(); +Comparing tables master:test.v_tables_priv and slave:test.v_tables_priv +Comparing tables master:test.v_tables_priv and slave2:test.v_tables_priv + +# Verify 'GRANT ... ON PROCEDURE...' statement +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO CURRENT_USER(); +Comparing tables master:test.v_procs_priv and slave:test.v_procs_priv +Comparing tables master:test.v_procs_priv and slave2:test.v_procs_priv + +# Verify 'GRANT ... ON *.* ...' statement +GRANT ALL PRIVILEGES ON *.* TO CURRENT_USER() WITH GRANT OPTION; +Comparing tables master:test.v_procs_priv and slave:test.v_procs_priv +Comparing tables master:test.v_procs_priv and slave2:test.v_procs_priv + +# Verify 'REVOKE ... ON TABLE ...' statement +REVOKE CREATE, INSERT, SELECT ON TABLE t1 FROM CURRENT_USER(); +Comparing tables master:test.v_tables_priv and slave:test.v_tables_priv +Comparing tables master:test.v_tables_priv and slave2:test.v_tables_priv + +# Verify 'REVOKE ... ON PROCEDURE...' statement +REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM CURRENT_USER(); +Comparing tables master:test.v_procs_priv and slave:test.v_procs_priv +Comparing tables master:test.v_procs_priv and slave2:test.v_procs_priv + +# Verify 'REVOKE ... ON *.* ...' statement +REVOKE ALL PRIVILEGES ON *.* FROM CURRENT_USER(); +Comparing tables master:test.v_user and slave:test.v_user +Comparing tables master:test.v_user and slave2:test.v_user + +# Verify 'GRANT ...' statement in the procedure +CREATE PROCEDURE my_grant() +GRANT CREATE, INSERT, SELECT ON TABLE test.t1 TO CURRENT_USER(); +call my_grant; +Comparing tables master:test.v_tables_priv and slave:test.v_tables_priv +Comparing tables master:test.v_tables_priv and slave2:test.v_tables_priv + +# Verify 'REVOKE ... ON TABLE ...' statement in the procedure +CREATE PROCEDURE my_revoke() +REVOKE CREATE, INSERT, SELECT ON TABLE t1 FROM CURRENT_USER(); +call my_revoke; +Comparing tables master:test.v_tables_priv and slave:test.v_tables_priv +Comparing tables master:test.v_tables_priv and slave2:test.v_tables_priv + +# Verify 'RENAME USER ...' statement +RENAME USER CURRENT_USER TO 'bug48321_2'@'localhost'; +Comparing tables master:test.v_user and slave:test.v_user +Comparing tables master:test.v_user and slave2:test.v_user + +# Verify 'DROP USER ...' statement +GRANT CREATE USER ON *.* TO 'bug48321_2'@'localhost'; +DROP USER CURRENT_USER(); +Comparing tables master:test.v_user and slave:test.v_user +Comparing tables master:test.v_user and slave2:test.v_user + +# Verify 'ALTER EVENT...' statement +CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT * FROM t1; +# Explicitly assign CURRENT_USER() to definer +ALTER DEFINER=CURRENT_USER() EVENT e1 ENABLE; +Comparing tables master:test.v_event and slave:test.v_event +Comparing tables master:test.v_event and slave2:test.v_event + +# Session user will be set as definer, if the statement does not assign +# a definer +ALTER EVENT e1 ENABLE; +Comparing tables master:test.v_event and slave:test.v_event +Comparing tables master:test.v_event and slave2:test.v_event + +# Verify that this patch does not affect the calling of CURRENT_USER() +# in the other statements +# [On master] +INSERT INTO t1 VALUES(CURRENT_USER()), ('1234'); +Warnings: +Note 1592 Statement may not be safe to log in statement format. +SELECT * FROM t1; +c1 +root@localhost +1234 +# [On slave] +SELECT * FROM t1; +c1 +@ +1234 +# [On slave2] +SELECT * FROM t1; +c1 +@ +1234 +# [On master] +UPDATE t1 SET c1=CURRENT_USER() WHERE c1='1234'; +Warnings: +Note 1592 Statement may not be safe to log in statement format. +SELECT * FROM t1; +c1 +root@localhost +root@localhost +# [On slave] +SELECT * FROM t1; +c1 +@ +@ +# [On slave2] +SELECT * FROM t1; +c1 +@ +@ +# [On master] +DELETE FROM t1 WHERE c1=CURRENT_USER(); +Warnings: +Note 1592 Statement may not be safe to log in statement format. +SELECT * FROM t1; +c1 +# [On slave] +SELECT * FROM t1; +c1 +# [On slave2] +SELECT * FROM t1; +c1 +# [On master] +CREATE TABLE t2(c1 char(100)); +CREATE FUNCTION my_user() RETURNS VARCHAR(64) +SQL SECURITY INVOKER +BEGIN +INSERT INTO t2 VALUES(CURRENT_USER()); +RETURN CURRENT_USER(); +END | +INSERT INTO t1 VALUES(my_user()); +Warnings: +Note 1592 Statement may not be safe to log in statement format. +Note 1592 Statement may not be safe to log in statement format. +SELECT * FROM t1; +c1 +root@localhost +SELECT * FROM t2; +c1 +root@localhost +# [On slave] +SELECT * FROM t1; +c1 +@ +SELECT * FROM t2; +c1 +@ +# [On slave2] +SELECT * FROM t1; +c1 +@ +SELECT * FROM t2; +c1 +@ + +# END +DROP TABLE t1, t2; +DROP VIEW v_user, v_tables_priv, v_procs_priv, v_event; +DROP PROCEDURE p1; +DROP PROCEDURE my_grant; +DROP PROCEDURE my_revoke; +DROP FUNCTION my_user; +DROP EVENT e1; diff --git a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result index 26f2545dd72..35f4cd3ecbb 100644 --- a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result +++ b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result @@ -750,7 +750,7 @@ test_rpl e2 root@localhost SYSTEM RECURRING NULL 1 # # NULL ENABLED 1 latin1 lat USE test_rpl; SHOW EVENTS; Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation -test_rpl e2 @ SYSTEM RECURRING NULL 1 # # NULL SLAVESIDE_DISABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci +test_rpl e2 root@localhost SYSTEM RECURRING NULL 1 # # NULL SLAVESIDE_DISABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci ==========MASTER========== SELECT COUNT(*) FROM t1; COUNT(*) diff --git a/mysql-test/suite/rpl/t/rpl_current_user.cnf b/mysql-test/suite/rpl/t/rpl_current_user.cnf new file mode 100644 index 00000000000..999ee727a88 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_current_user.cnf @@ -0,0 +1,9 @@ +!include ../my.cnf + +[mysqld.3] +server-id=3 +log-bin=slave-bin + +[ENV] +SLAVE_MYPORT1= @mysqld.3.port +SLAVE_MYSOCK1= @mysqld.3.socket diff --git a/mysql-test/suite/rpl/t/rpl_current_user.test b/mysql-test/suite/rpl/t/rpl_current_user.test new file mode 100644 index 00000000000..72581ed7049 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_current_user.test @@ -0,0 +1,238 @@ +############################################################################## +# BUG#48321 CURRENT_USER() incorrectly replicated for DROP/RENAME USER, +# REVOKE, GRANT, ALTER EVENT +# +# Calling CURRENT_USER() results into inconsistency between slave and master, +# as the slave SQL thread has different user with common users. +# +# After the patch for bug#48321, session's user will be written into query log +# event if CURRENT_USER() is called in 'DROP/RENAME USER', 'REVOKE', 'GRANT', +# 'ALTER EVENT'. +# +############################################################################## +source include/master-slave.inc; +source include/have_binlog_format_statement.inc; + +--echo +--echo # On slave2 +connect (slave2,127.0.0.1,root,,test,$SLAVE_MYPORT1,); +connection slave2; + +--echo # Connect slave2 to slave +--replace_result $SLAVE_MYPORT SLAVE_MYPORT; +eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$SLAVE_MYPORT, + MASTER_LOG_FILE='slave-bin.000001', MASTER_USER='root'; +START SLAVE; +source include/wait_for_slave_to_start.inc; + +--echo +--echo # [On master] +connection master; +--disable_warnings +DROP VIEW IF EXISTS v_user; +DROP VIEW IF EXISTS v_tables_priv; +DROP VIEW IF EXISTS v_procs_priv; +DROP PROCEDURE IF EXISTS p1; +DROP PROCEDURE IF EXISTS my_grant; +DROP PROCEDURE IF EXISTS my_revoke; +DROP FUNCTION IF EXISTS my_user; +DROP EVENT IF EXISTS e1; +--enable_warnings +CREATE TABLE t1(c1 char(100)); +CREATE VIEW test.v_user AS SELECT * FROM mysql.user WHERE User LIKE 'bug48321%'; +CREATE VIEW test.v_tables_priv AS SELECT * FROM mysql.tables_priv WHERE User LIKE 'bug48321%'; +CREATE VIEW test.v_procs_priv AS SELECT * FROM mysql.procs_priv WHERE User LIKE 'bug48321%'; +CREATE VIEW test.v_event AS SELECT definer FROM mysql.event WHERE name = 'e1'; +CREATE PROCEDURE p1() SELECT 1; +--echo # bug48321_1-01234 has the max length(16) of user. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1-01234'@'localhost' WITH GRANT OPTION; + +--echo +--echo # Make sure the max lengths of user and host +--echo # the user name is too lengh +--error 1470 +GRANT CREATE USER ON *.* TO '01234567890123456'@'fakehost'; +--echo # the host name is too lengh +--error 1470 +GRANT CREATE USER ON *.* TO 'fakename'@'0123456789012345678901234567890123456789012345678901234567890'; + +--echo +--echo # User 'bug48321_1-01234' connects to master by conn1 +connect (conn1, 127.0.0.1, 'bug48321_1-01234'@'localhost',,); +connection conn1; +--echo # [On conn1] +--echo # Verify 'REVOKE ALL' statement +REVOKE ALL PRIVILEGES, GRANT OPTION FROM CURRENT_USER(); +let $diff_table= test.v_user; +let $diff_server_list= master, slave, slave2; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'GRANT ... ON TABLE ...' statement +connection conn1; +GRANT CREATE, INSERT, SELECT ON TABLE test.t1 TO CURRENT_USER(); +let $diff_table= test.v_tables_priv; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'GRANT ... ON PROCEDURE...' statement +connection conn1; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO CURRENT_USER(); +let $diff_table= test.v_procs_priv; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'GRANT ... ON *.* ...' statement +connection conn1; +GRANT ALL PRIVILEGES ON *.* TO CURRENT_USER() WITH GRANT OPTION; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'REVOKE ... ON TABLE ...' statement +connection conn1; +REVOKE CREATE, INSERT, SELECT ON TABLE t1 FROM CURRENT_USER(); +let $diff_table= test.v_tables_priv; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'REVOKE ... ON PROCEDURE...' statement +connection conn1; +REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM CURRENT_USER(); +let $diff_table= test.v_procs_priv; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'REVOKE ... ON *.* ...' statement +connection conn1; +REVOKE ALL PRIVILEGES ON *.* FROM CURRENT_USER(); +let $diff_table= test.v_user; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'GRANT ...' statement in the procedure +connection conn1; +CREATE PROCEDURE my_grant() + GRANT CREATE, INSERT, SELECT ON TABLE test.t1 TO CURRENT_USER(); +call my_grant; +let $diff_table= test.v_tables_priv; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'REVOKE ... ON TABLE ...' statement in the procedure +connection conn1; +CREATE PROCEDURE my_revoke() + REVOKE CREATE, INSERT, SELECT ON TABLE t1 FROM CURRENT_USER(); +call my_revoke; +let $diff_table= test.v_tables_priv; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'RENAME USER ...' statement +connection conn1; +RENAME USER CURRENT_USER TO 'bug48321_2'@'localhost'; +let $diff_table= test.v_user; +source include/rpl_diff_tables.inc; + +disconnect conn1; + +--echo +--echo # Verify 'DROP USER ...' statement +connection master; +GRANT CREATE USER ON *.* TO 'bug48321_2'@'localhost'; +connect (conn1, 127.0.0.1, 'bug48321_2'@'localhost',,); +connection conn1; +DROP USER CURRENT_USER(); +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify 'ALTER EVENT...' statement +connection master; +CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT * FROM t1; + +--echo # Explicitly assign CURRENT_USER() to definer +ALTER DEFINER=CURRENT_USER() EVENT e1 ENABLE; +let $diff_table= test.v_event; +source include/rpl_diff_tables.inc; + +connection master; +--echo +--echo # Session user will be set as definer, if the statement does not assign +--echo # a definer +ALTER EVENT e1 ENABLE; +sync_slave_with_master; +source include/rpl_diff_tables.inc; + +--echo +--echo # Verify that this patch does not affect the calling of CURRENT_USER() +--echo # in the other statements +connection master; +--echo # [On master] +INSERT INTO t1 VALUES(CURRENT_USER()), ('1234'); +SELECT * FROM t1; +sync_slave_with_master; +--echo # [On slave] +SELECT * FROM t1; +--echo # [On slave2] +sync_slave_with_master slave2; +SELECT * FROM t1; + +connection master; +--echo # [On master] +UPDATE t1 SET c1=CURRENT_USER() WHERE c1='1234'; +SELECT * FROM t1; +sync_slave_with_master; +--echo # [On slave] +SELECT * FROM t1; +sync_slave_with_master slave2; +--echo # [On slave2] +SELECT * FROM t1; + +connection master; +--echo # [On master] +DELETE FROM t1 WHERE c1=CURRENT_USER(); +SELECT * FROM t1; +sync_slave_with_master; +--echo # [On slave] +SELECT * FROM t1; +sync_slave_with_master slave2; +--echo # [On slave2] +SELECT * FROM t1; + +connection master; +--echo # [On master] +CREATE TABLE t2(c1 char(100)); + +DELIMITER |; +CREATE FUNCTION my_user() RETURNS VARCHAR(64) + SQL SECURITY INVOKER +BEGIN + INSERT INTO t2 VALUES(CURRENT_USER()); + RETURN CURRENT_USER(); +END | +DELIMITER ;| + +INSERT INTO t1 VALUES(my_user()); +SELECT * FROM t1; +SELECT * FROM t2; +sync_slave_with_master; +--echo # [On slave] +SELECT * FROM t1; +SELECT * FROM t2; +sync_slave_with_master slave2; +--echo # [On slave2] +SELECT * FROM t1; +SELECT * FROM t2; + +--echo +--echo # END +connection master; +DROP TABLE t1, t2; +DROP VIEW v_user, v_tables_priv, v_procs_priv, v_event; +DROP PROCEDURE p1; +DROP PROCEDURE my_grant; +DROP PROCEDURE my_revoke; +DROP FUNCTION my_user; +DROP EVENT e1; +sync_slave_with_master; +sync_slave_with_master slave2; +source include/master-slave-end.inc; diff --git a/sql/log_event.cc b/sql/log_event.cc index d53f13e0b6b..0e4d4bd512b 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2307,6 +2307,53 @@ bool Query_log_event::write(IO_CACHE* file) start+= 4; } + if (thd && thd->is_current_user_used()) + { + LEX_STRING user; + LEX_STRING host; + memset(&user, 0, sizeof(user)); + memset(&host, 0, sizeof(host)); + + if (thd->slave_thread && thd->has_invoker()) + { + /* user will be null, if master is older than this patch */ + user= thd->get_invoker_user(); + host= thd->get_invoker_host(); + } + else if (thd->security_ctx->priv_user) + { + Security_context *ctx= thd->security_ctx; + + user.length= strlen(ctx->priv_user); + user.str= ctx->priv_user; + if (ctx->priv_host[0] != '\0') + { + host.str= ctx->priv_host; + host.length= strlen(ctx->priv_host); + } + } + + if (user.length > 0) + { + *start++= Q_INVOKER; + + /* + Store user length and user. The max length of use is 16, so 1 byte is + enough to store the user's length. + */ + *start++= (uchar)user.length; + memcpy(start, user.str, user.length); + start+= user.length; + + /* + Store host length and host. The max length of host is 60, so 1 byte is + enough to store the host's length. + */ + *start++= (uchar)host.length; + memcpy(start, host.str, host.length); + start+= host.length; + } + } /* NOTE: When adding new status vars, please don't forget to update the MAX_SIZE_LOG_EVENT_STATUS in log_event.h and update the function @@ -2575,6 +2622,8 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, bool catalog_nz= 1; DBUG_ENTER("Query_log_event::Query_log_event(char*,...)"); + memset(&user, 0, sizeof(user)); + memset(&host, 0, sizeof(host)); common_header_len= description_event->common_header_len; post_header_len= description_event->post_header_len[event_type-1]; DBUG_PRINT("info",("event_len: %u common_header_len: %d post_header_len: %d", @@ -2729,6 +2778,20 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, data_written= master_data_written= uint4korr(pos); pos+= 4; break; + case Q_INVOKER: + { + CHECK_SPACE(pos, end, 1); + user.length= *pos++; + CHECK_SPACE(pos, end, user.length); + user.str= my_strndup((const char *)pos, user.length, MYF(0)); + pos+= user.length; + + CHECK_SPACE(pos, end, 1); + host.length= *pos++; + CHECK_SPACE(pos, end, host.length); + host.str= my_strndup((const char *)pos, host.length, MYF(0)); + pos+= host.length; + } default: /* That's why you must write status vars in growing order of code */ DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\ @@ -3178,7 +3241,7 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli, thd->variables.collation_database= thd->db_charset; thd->table_map_for_update= (table_map)table_map_for_update; - + thd->set_invoker(&user, &host); /* Execute the query (note that we bypass dispatch_command()) */ const char* found_semicolon= NULL; mysql_parse(thd, thd->query(), thd->query_length(), &found_semicolon); diff --git a/sql/log_event.h b/sql/log_event.h index e3ca4ca3321..816a241e55d 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -264,7 +264,8 @@ struct sql_ex_info 1 + 2 /* type, lc_time_names_number */ + \ 1 + 2 /* type, charset_database_number */ + \ 1 + 8 /* type, table_map_for_update */ + \ - 1 + 4 /* type, master_data_written */) + 1 + 4 /* type, master_data_written */ + \ + 1 + 16 + 1 + 60/* type, user_len, user, host_len, host */) #define MAX_LOG_EVENT_HEADER ( /* in order of Query_log_event::write */ \ LOG_EVENT_HEADER_LEN + /* write_header */ \ QUERY_HEADER_LEN + /* write_data */ \ @@ -333,6 +334,8 @@ struct sql_ex_info #define Q_MASTER_DATA_WRITTEN_CODE 10 +#define Q_INVOKER 11 + /* Intvar event post-header */ /* Intvar event data */ @@ -1546,6 +1549,8 @@ protected: */ class Query_log_event: public Log_event { + LEX_STRING user; + LEX_STRING host; protected: Log_event::Byte* data_buf; public: diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index dd256c70ecb..9640b8db1b2 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -194,6 +194,7 @@ static bool compare_hostname(const acl_host_and_ip *host,const char *hostname, const char *ip); static my_bool acl_load(THD *thd, TABLE_LIST *tables); static my_bool grant_load(THD *thd, TABLE_LIST *tables); +static inline void get_grantor(THD *thd, char* grantor); /* Convert scrambled password to binary form, according to scramble type, @@ -2704,6 +2705,20 @@ end: DBUG_RETURN(result); } +static inline void get_grantor(THD *thd, char *grantor) +{ + const char *user= thd->security_ctx->user; + const char *host= thd->security_ctx->host_or_ip; + +#if defined(HAVE_REPLICATION) + if (thd->slave_thread && thd->has_invoker()) + { + user= thd->get_invoker_user().str; + host= thd->get_invoker_host().str; + } +#endif + strxmov(grantor, user, "@", host, NullS); +} static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, TABLE *table, const LEX_USER &combo, @@ -2718,9 +2733,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, uchar user_key[MAX_KEY_LENGTH]; DBUG_ENTER("replace_table_table"); - strxmov(grantor, thd->security_ctx->user, "@", - thd->security_ctx->host_or_ip, NullS); - + get_grantor(thd, grantor); /* The following should always succeed as new users are created before this function is called! @@ -2850,9 +2863,7 @@ static int replace_routine_table(THD *thd, GRANT_NAME *grant_name, DBUG_RETURN(-1); } - strxmov(grantor, thd->security_ctx->user, "@", - thd->security_ctx->host_or_ip, NullS); - + get_grantor(thd, grantor); /* New users are created before this function is called. diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 93aa6a8268c..2ce03708a9a 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -736,6 +736,9 @@ THD::THD() thr_lock_owner_init(&main_lock_id, &lock_info); m_internal_handler= NULL; + current_user_used= FALSE; + memset(&invoker_user, 0, sizeof(invoker_user)); + memset(&invoker_host, 0, sizeof(invoker_host)); } @@ -1236,6 +1239,7 @@ void THD::cleanup_after_query() where= THD::DEFAULT_WHERE; /* reset table map for multi-table update */ table_map_for_update= 0; + clean_current_user_used(); } @@ -3267,6 +3271,22 @@ void THD::set_query(char *query_arg, uint32 query_length_arg) pthread_mutex_unlock(&LOCK_thd_data); } +void THD::get_definer(LEX_USER *definer) +{ + set_current_user_used(); +#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) + if (slave_thread && has_invoker()) + { + definer->user = invoker_user; + definer->host= invoker_host; + definer->password.str= NULL; + definer->password.length= 0; + } + else +#endif + get_default_definer(this, definer); +} + /** Mark transaction to rollback and mark error as fatal to a sub-statement. diff --git a/sql/sql_class.h b/sql/sql_class.h index 023367cb747..5155ffe0603 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2341,6 +2341,18 @@ public: Protected with LOCK_thd_data mutex. */ void set_query(char *query_arg, uint32 query_length_arg); + void set_current_user_used() { current_user_used= TRUE; } + bool is_current_user_used() { return current_user_used; } + void clean_current_user_used() { current_user_used= FALSE; } + void get_definer(LEX_USER *definer); + void set_invoker(const LEX_STRING *user, const LEX_STRING *host) + { + invoker_user= *user; + invoker_host= *host; + } + LEX_STRING get_invoker_user() { return invoker_user; } + LEX_STRING get_invoker_host() { return invoker_host; } + bool has_invoker() { return invoker_user.length > 0; } private: /** The current internal error handler for this thread, or NULL. */ Internal_error_handler *m_internal_handler; @@ -2360,6 +2372,25 @@ private: tree itself is reused between executions and thus is stored elsewhere. */ MEM_ROOT main_mem_root; + + /** + It will be set TURE if CURRENT_USER() is called in account management + statements or default definer is set in CREATE/ALTER SP, SF, Event, + TRIGGER or VIEW statements. + + Current user will be binlogged into Query_log_event if current_user_used + is TRUE; It will be stored into invoker_host and invoker_user by SQL thread. + */ + bool current_user_used; + + /** + It points to the invoker in the Query_log_event. + SQL thread use it as the default definer in CREATE/ALTER SP, SF, Event, + TRIGGER or VIEW statements or current user in account management + statements if it is not NULL. + */ + LEX_STRING invoker_user; + LEX_STRING invoker_host; }; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index ed2c76fdcb8..1f3d29ffec0 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -7654,7 +7654,7 @@ LEX_USER *create_default_definer(THD *thd) if (! (definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER)))) return 0; - get_default_definer(thd, definer); + thd->get_definer(definer); return definer; } From fd0eb0c1b02879b527471f4304f4a443fdd96fa9 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 4 Jul 2010 16:17:53 +0800 Subject: [PATCH 076/112] Postfix for bug#48321 Some test cases set ANSI_QUOTES in sql_mode. So we have to use single quotes to quote literal strings. --- mysql-test/include/diff_tables.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/include/diff_tables.inc b/mysql-test/include/diff_tables.inc index e11e69b3023..81362e8643b 100644 --- a/mysql-test/include/diff_tables.inc +++ b/mysql-test/include/diff_tables.inc @@ -68,7 +68,7 @@ while ($_diff_i) { # and connect the appropriate server. let $_pos= `SELECT LOCATE(':', '$_diff_table')`; let $_diff_conn=`SELECT SUBSTR('$_diff_table', 1, $_pos-1)`; - if (`SELECT "XX$_diff_conn" <> "XX"`) { + if (`SELECT 'XX$_diff_conn' <> 'XX'`) { let $_diff_table=`SELECT SUBSTR('$_diff_table', $_pos+1)`; connection $_diff_conn; } From 3e1a47070518a1995cc48e28c36b7c817d5f6008 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 25 Jun 2010 15:59:44 +0300 Subject: [PATCH 077/112] Bug #53095: SELECT column_name FROM INFORMATION_SCHEMA.STATISTICS returns nothing When looking for table or database names inside INFORMATION_SCHEMA we must convert the table and database names to lowercase (just as it's done in the rest of the server) when lowercase_table_names is non-zero. This will allow us to find the same tables that we would find if there is no condition. Fixed by converting to lower case when extracting the database and table name conditions. Test case added. --- mysql-test/r/lowercase_view.result | 17 ++++++++++++++ mysql-test/t/lowercase_view.test | 22 ++++++++++++++++++ sql/sql_show.cc | 37 ++++++++++++++++++++++-------- 3 files changed, 67 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/lowercase_view.result b/mysql-test/r/lowercase_view.result index c37dc41c495..33c87ec101c 100644 --- a/mysql-test/r/lowercase_view.result +++ b/mysql-test/r/lowercase_view.result @@ -148,3 +148,20 @@ a DROP VIEW v1; DROP TABLE t1; End of 5.0 tests. +# +# Bug #53095: SELECT column_name FROM INFORMATION_SCHEMA.STATISTICS +# returns nothing +# +CREATE TABLE `ttt` ( +`f1` char(3) NOT NULL, +PRIMARY KEY (`f1`) +) ENGINE=myisam DEFAULT CHARSET=latin1; +SELECT count(COLUMN_NAME) FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = +'TTT'; +count(COLUMN_NAME) +1 +SELECT count(*) FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 'TTT'; +count(*) +1 +DROP TABLE `ttt`; +End of 5.0 tests. diff --git a/mysql-test/t/lowercase_view.test b/mysql-test/t/lowercase_view.test index d6612b3e6b9..52be911cde0 100644 --- a/mysql-test/t/lowercase_view.test +++ b/mysql-test/t/lowercase_view.test @@ -160,4 +160,26 @@ SELECT * FROM v1; DROP VIEW v1; DROP TABLE t1; + --echo End of 5.0 tests. + + +--echo # +--echo # Bug #53095: SELECT column_name FROM INFORMATION_SCHEMA.STATISTICS +--echo # returns nothing +--echo # + +CREATE TABLE `ttt` ( + `f1` char(3) NOT NULL, + PRIMARY KEY (`f1`) +) ENGINE=myisam DEFAULT CHARSET=latin1; + +SELECT count(COLUMN_NAME) FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = +'TTT'; +SELECT count(*) FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 'TTT'; + +DROP TABLE `ttt`; + + +--echo End of 5.0 tests. + diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 33abf356718..0eeb333f278 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2690,36 +2690,54 @@ bool get_lookup_field_values(THD *thd, COND *cond, TABLE_LIST *tables, { LEX *lex= thd->lex; const char *wild= lex->wild ? lex->wild->ptr() : NullS; + bool rc= 0; + bzero((char*) lookup_field_values, sizeof(LOOKUP_FIELD_VALUES)); switch (lex->sql_command) { case SQLCOM_SHOW_DATABASES: if (wild) { - lookup_field_values->db_value.str= (char*) wild; - lookup_field_values->db_value.length= strlen(wild); + thd->make_lex_string(&lookup_field_values->db_value, + wild, strlen(wild), 0); lookup_field_values->wild_db_value= 1; } - return 0; + break; case SQLCOM_SHOW_TABLES: case SQLCOM_SHOW_TABLE_STATUS: case SQLCOM_SHOW_TRIGGERS: case SQLCOM_SHOW_EVENTS: - lookup_field_values->db_value.str= lex->select_lex.db; - lookup_field_values->db_value.length=strlen(lex->select_lex.db); + thd->make_lex_string(&lookup_field_values->db_value, + lex->select_lex.db, strlen(lex->select_lex.db), 0); if (wild) { - lookup_field_values->table_value.str= (char*)wild; - lookup_field_values->table_value.length= strlen(wild); + thd->make_lex_string(&lookup_field_values->table_value, + wild, strlen(wild), 0); lookup_field_values->wild_table_value= 1; } - return 0; + break; default: /* The "default" is for queries over I_S. All previous cases handle SHOW commands. */ - return calc_lookup_values_from_cond(thd, cond, tables, lookup_field_values); + rc= calc_lookup_values_from_cond(thd, cond, tables, lookup_field_values); + break; } + + if (lower_case_table_names && !rc) + { + /* + We can safely do in-place upgrades here since all of the above cases + are allocating a new memory buffer for these strings. + */ + if (lookup_field_values->db_value.str && lookup_field_values->db_value.str[0]) + my_casedn_str(system_charset_info, lookup_field_values->db_value.str); + if (lookup_field_values->table_value.str && + lookup_field_values->table_value.str[0]) + my_casedn_str(system_charset_info, lookup_field_values->table_value.str); + } + + return rc; } @@ -3324,6 +3342,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) error= 0; goto err; } + DBUG_PRINT("INDEX VALUES",("db_name='%s', table_name='%s'", STR_OR_NIL(lookup_field_vals.db_value.str), STR_OR_NIL(lookup_field_vals.table_value.str))); From 5bbdeada810ae838981c7bbecfeddda64076d7e4 Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Tue, 29 Jun 2010 00:13:18 -0700 Subject: [PATCH 078/112] Change the table name in innodb_bug54044 to lower case to avoid platform dependent diffs. --- mysql-test/suite/innodb/r/innodb_bug54044.result | 4 ++-- mysql-test/suite/innodb/t/innodb_bug54044.test | 2 +- mysql-test/suite/innodb_plugin/r/innodb_bug54044.result | 4 ++-- mysql-test/suite/innodb_plugin/t/innodb_bug54044.test | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb_bug54044.result b/mysql-test/suite/innodb/r/innodb_bug54044.result index 9574381d8e1..90ab812f2ae 100644 --- a/mysql-test/suite/innodb/r/innodb_bug54044.result +++ b/mysql-test/suite/innodb/r/innodb_bug54044.result @@ -1,3 +1,3 @@ -CREATE TEMPORARY TABLE TABLE_54044 ENGINE = INNODB +CREATE TEMPORARY TABLE table_54044 ENGINE = INNODB AS SELECT IF(NULL IS NOT NULL, NULL, NULL); -ERROR HY000: Can't create table 'test.TABLE_54044' (errno: -1) +ERROR HY000: Can't create table 'test.table_54044' (errno: -1) diff --git a/mysql-test/suite/innodb/t/innodb_bug54044.test b/mysql-test/suite/innodb/t/innodb_bug54044.test index 824450ae1a6..a6722ed6399 100644 --- a/mysql-test/suite/innodb/t/innodb_bug54044.test +++ b/mysql-test/suite/innodb/t/innodb_bug54044.test @@ -6,6 +6,6 @@ # This 'create table' operation should fail because of # using NULL datatype --error ER_CANT_CREATE_TABLE -CREATE TEMPORARY TABLE TABLE_54044 ENGINE = INNODB +CREATE TEMPORARY TABLE table_54044 ENGINE = INNODB AS SELECT IF(NULL IS NOT NULL, NULL, NULL); diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug54044.result b/mysql-test/suite/innodb_plugin/r/innodb_bug54044.result index 9574381d8e1..90ab812f2ae 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb_bug54044.result +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug54044.result @@ -1,3 +1,3 @@ -CREATE TEMPORARY TABLE TABLE_54044 ENGINE = INNODB +CREATE TEMPORARY TABLE table_54044 ENGINE = INNODB AS SELECT IF(NULL IS NOT NULL, NULL, NULL); -ERROR HY000: Can't create table 'test.TABLE_54044' (errno: -1) +ERROR HY000: Can't create table 'test.table_54044' (errno: -1) diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug54044.test b/mysql-test/suite/innodb_plugin/t/innodb_bug54044.test index 8958dba1c9b..58f60a54130 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb_bug54044.test +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug54044.test @@ -6,6 +6,6 @@ # This 'create table' operation should fail because of # using NULL datatype --error ER_CANT_CREATE_TABLE -CREATE TEMPORARY TABLE TABLE_54044 ENGINE = INNODB +CREATE TEMPORARY TABLE table_54044 ENGINE = INNODB AS SELECT IF(NULL IS NOT NULL, NULL, NULL); From 18388d2105efe47f59e7a201154907ec9d7508df Mon Sep 17 00:00:00 2001 From: Staale Smedseng Date: Wed, 30 Jun 2010 11:16:06 +0200 Subject: [PATCH 079/112] Bug #53899 Wrong mysql_stmt_errno() after connection loss with automatic reconnect A client with automatic reconnect enabled will see the error message "Lost connection to MySQL server during query" if the connection is lost between mysql_stmt_prepare() and mysql_stmt_execute(). The mysql_stmt_errno() number, however, is 0 -- not the corresponding value 2013. This patch checks for the case where the prepared statement has been pruned due to a connection loss (i.e., stmt->mysql has been set to NULL) during a call to cli_advanced_command(), and avoids changing the last_errno to the result of the last reconnect attempt. --- libmysql/libmysql.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 6ea777a0702..0ba85c1ac07 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -2495,7 +2495,12 @@ static my_bool execute(MYSQL_STMT *stmt, char *packet, ulong length) stmt->insert_id= mysql->insert_id; if (res) { - set_stmt_errmsg(stmt, net); + /* + Don't set stmt error if stmt->mysql is NULL, as the error in this case + has already been set by mysql_prune_stmt_list(). + */ + if (stmt->mysql) + set_stmt_errmsg(stmt, net); DBUG_RETURN(1); } DBUG_RETURN(0); @@ -2706,7 +2711,12 @@ stmt_read_row_from_cursor(MYSQL_STMT *stmt, unsigned char **row) buff, sizeof(buff), (uchar*) 0, 0, 1, stmt)) { - set_stmt_errmsg(stmt, net); + /* + Don't set stmt error if stmt->mysql is NULL, as the error in this case + has already been set by mysql_prune_stmt_list(). + */ + if (stmt->mysql) + set_stmt_errmsg(stmt, net); return 1; } if ((*mysql->methods->read_rows_from_cursor)(stmt)) @@ -3387,7 +3397,12 @@ mysql_stmt_send_long_data(MYSQL_STMT *stmt, uint param_number, buff, sizeof(buff), (uchar*) data, length, 1, stmt)) { - set_stmt_errmsg(stmt, &mysql->net); + /* + Don't set stmt error if stmt->mysql is NULL, as the error in this case + has already been set by mysql_prune_stmt_list(). + */ + if (stmt->mysql) + set_stmt_errmsg(stmt, &mysql->net); DBUG_RETURN(1); } } @@ -4823,7 +4838,12 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt) if (cli_advanced_command(mysql, COM_STMT_FETCH, buff, sizeof(buff), (uchar*) 0, 0, 1, stmt)) { - set_stmt_errmsg(stmt, net); + /* + Don't set stmt error if stmt->mysql is NULL, as the error in this case + has already been set by mysql_prune_stmt_list(). + */ + if (stmt->mysql) + set_stmt_errmsg(stmt, net); DBUG_RETURN(1); } } From 1c5388765fc121ca8e5458df80c955bc209841db Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Wed, 30 Jun 2010 17:06:25 +0400 Subject: [PATCH 080/112] Bug#51431 Wrong sort order after import of dump file The problem is that QUICK_SELECT_DESC behaviour depends on used_key_parts value which can be bigger than selected best_key_parts value if an engine supports clustered key. But used_key_parts is overwritten with best_key_parts value that prevents from correct selection of index access method. The fix is to preserve used_key_parts value for further use in QUICK_SELECT_DESC. mysql-test/r/innodb_mysql.result: test case mysql-test/t/innodb_mysql.test: test case sql/sql_select.cc: preserve used_key_parts value for further use in QUICK_SELECT_DESC --- mysql-test/r/innodb_mysql.result | 32 ++++++++++++++++++++++++++++++++ mysql-test/t/innodb_mysql.test | 30 ++++++++++++++++++++++++++++++ sql/sql_select.cc | 11 ++++++++++- 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index 2af3db75adc..e2f28b96f7e 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -2455,4 +2455,36 @@ AND f5 = 'abcdefghijklmnopwrst' AND f2 = 1221457 AND f4 = 0 ; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge PRIMARY,idx1,idx2 idx2,idx1,PRIMARY 7,60,4 NULL 1 Using intersect(idx2,idx1,PRIMARY); Using where DROP TABLE t1; +# +# Bug#51431 Wrong sort order after import of dump file +# +CREATE TABLE t1 ( +f1 INT(11) NOT NULL, +f2 int(11) NOT NULL, +f3 int(11) NOT NULL, +f4 tinyint(1) NOT NULL, +PRIMARY KEY (f1), +UNIQUE KEY (f2, f3), +KEY (f4) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES +(1,1,991,1), (2,1,992,1), (3,1,993,1), (4,1,994,1), (5,1,995,1), +(6,1,996,1), (7,1,997,1), (8,1,998,1), (10,1,999,1), (11,1,9910,1), +(16,1,9911,1), (17,1,9912,1), (18,1,9913,1), (19,1,9914,1), (20,1,9915,1), +(21,1,9916,1), (22,1,9917,1), (23,1,9918,1), (24,1,9919,1), (25,1,9920,1), +(26,1,9921,1), (27,1,9922,1); +FLUSH TABLES; +SELECT * FROM t1 WHERE f2 = 1 AND f4 = TRUE +ORDER BY f1 DESC LIMIT 5; +f1 f2 f3 f4 +27 1 9922 1 +26 1 9921 1 +25 1 9920 1 +24 1 9919 1 +23 1 9918 1 +EXPLAIN SELECT * FROM t1 WHERE f2 = 1 AND f4 = TRUE +ORDER BY f1 DESC LIMIT 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range f2,f4 f4 1 NULL 11 Using where +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index 47135578697..72795392e50 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -694,4 +694,34 @@ AND f5 = 'abcdefghijklmnopwrst' AND f2 = 1221457 AND f4 = 0 ; DROP TABLE t1; +--echo # +--echo # Bug#51431 Wrong sort order after import of dump file +--echo # + +CREATE TABLE t1 ( + f1 INT(11) NOT NULL, + f2 int(11) NOT NULL, + f3 int(11) NOT NULL, + f4 tinyint(1) NOT NULL, + PRIMARY KEY (f1), + UNIQUE KEY (f2, f3), + KEY (f4) +) ENGINE=InnoDB; + +INSERT INTO t1 VALUES +(1,1,991,1), (2,1,992,1), (3,1,993,1), (4,1,994,1), (5,1,995,1), +(6,1,996,1), (7,1,997,1), (8,1,998,1), (10,1,999,1), (11,1,9910,1), +(16,1,9911,1), (17,1,9912,1), (18,1,9913,1), (19,1,9914,1), (20,1,9915,1), +(21,1,9916,1), (22,1,9917,1), (23,1,9918,1), (24,1,9919,1), (25,1,9920,1), +(26,1,9921,1), (27,1,9922,1); + +FLUSH TABLES; + +SELECT * FROM t1 WHERE f2 = 1 AND f4 = TRUE +ORDER BY f1 DESC LIMIT 5; +EXPLAIN SELECT * FROM t1 WHERE f2 = 1 AND f4 = TRUE +ORDER BY f1 DESC LIMIT 5; + +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b61f7d1eb37..b20726fc151 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -13419,6 +13419,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, uint nr; key_map keys; uint best_key_parts= 0; + uint saved_best_key_parts= 0; int best_key_direction= 0; ha_rows best_records= 0; double read_time; @@ -13579,6 +13580,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, { best_key= nr; best_key_parts= keyinfo->key_parts; + saved_best_key_parts= used_key_parts; best_records= quick_records; is_best_covering= is_covering; best_key_direction= direction; @@ -13665,8 +13667,15 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, */ } } - used_key_parts= best_key_parts; order_direction= best_key_direction; + /* + saved_best_key_parts is actual number of used keyparts found by the + test_if_order_by_key function. It could differ from keyinfo->key_parts, + thus we have to restore it in case of desc order as it affects + QUICK_SELECT_DESC behaviour. + */ + used_key_parts= (order_direction == -1) ? + saved_best_key_parts : best_key_parts; } else DBUG_RETURN(0); From f3ccf5061fdf7110be6e6f1dd98fe696842081d1 Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Thu, 1 Jul 2010 12:02:00 +0400 Subject: [PATCH 081/112] Bug#54667: Unnecessary signal handler redefinition POSIX requires that a signal handler defined with sigaction() is not reset on delivering a signal unless SA_NODEFER or SA_RESETHAND is set. It is therefore unnecessary to redefine the handler on signal delivery on platforms where sigaction() is used without those flags. include/my_alarm.h: Renamed DONT_REMEMBER_SIGNAL -> SIGNAL_HANDLER_RESET_ON_DELIVERY. include/my_global.h: Renamed DONT_REMEMBER_SIGNAL -> SIGNAL_HANDLER_RESET_ON_DELIVERY. The latter is now defined only on non-BSD platforms missing the POSIX sigaction() function. libmysql/libmysql.c: Renamed DONT_REMEMBER_SIGNAL -> SIGNAL_HANDLER_RESET_ON_DELIVERY mysys/thr_alarm.c: Renamed DONT_REMEMBER_SIGNAL -> SIGNAL_HANDLER_RESET_ON_DELIVERY sql/mysqld.cc: Renamed DONT_REMEMBER_SIGNAL -> SIGNAL_HANDLER_RESET_ON_DELIVERY --- include/my_alarm.h | 4 ++-- include/my_global.h | 4 ++-- libmysql/libmysql.c | 2 +- mysys/thr_alarm.c | 10 +++++----- sql/mysqld.cc | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/include/my_alarm.h b/include/my_alarm.h index 750135d64ed..c41c1d65e27 100644 --- a/include/my_alarm.h +++ b/include/my_alarm.h @@ -36,14 +36,14 @@ extern ulong my_time_to_wait_for_lock; #define ALARM_END VOID(signal(SIGALRM,alarm_signal)); \ VOID(alarm(alarm_old)); #define ALARM_TEST my_have_got_alarm -#ifdef DONT_REMEMBER_SIGNAL +#ifdef SIGNAL_HANDLER_RESET_ON_DELIVERY #define ALARM_REINIT VOID(alarm(MY_HOW_OFTEN_TO_ALARM)); \ VOID(signal(SIGALRM,my_set_alarm_variable));\ my_have_got_alarm=0; #else #define ALARM_REINIT VOID(alarm((uint) MY_HOW_OFTEN_TO_ALARM)); \ my_have_got_alarm=0; -#endif /* DONT_REMEMBER_SIGNAL */ +#endif /* SIGNAL_HANDLER_RESET_ON_DELIVERY */ #else #define ALARM_VARIABLES long alarm_pos=0,alarm_end_pos=MY_HOW_OFTEN_TO_WRITE-1 #define ALARM_INIT diff --git a/include/my_global.h b/include/my_global.h index e284acce186..e13c7c37b62 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -541,8 +541,8 @@ extern "C" int madvise(void *addr, size_t len, int behav); #endif /* Does the system remember a signal handler after a signal ? */ -#ifndef HAVE_BSD_SIGNALS -#define DONT_REMEMBER_SIGNAL +#if !defined(HAVE_BSD_SIGNALS) && !defined(HAVE_SIGACTION) +#define SIGNAL_HANDLER_RESET_ON_DELIVERY #endif /* Define void to stop lint from generating "null effekt" comments */ diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 6ea777a0702..cfbeb99508f 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -328,7 +328,7 @@ sig_handler my_pipe_sig_handler(int sig __attribute__((unused))) { DBUG_PRINT("info",("Hit by signal %d",sig)); -#ifdef DONT_REMEMBER_SIGNAL +#ifdef SIGNAL_HANDLER_RESET_ON_DELIVERY (void) signal(SIGPIPE, my_pipe_sig_handler); #endif } diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c index b710a7eee39..386691be4de 100644 --- a/mysys/thr_alarm.c +++ b/mysys/thr_alarm.c @@ -306,7 +306,7 @@ sig_handler process_alarm(int sig __attribute__((unused))) #if defined(MAIN) && !defined(__bsdi__) printf("thread_alarm in process_alarm\n"); fflush(stdout); #endif -#ifdef DONT_REMEMBER_SIGNAL +#ifdef SIGNAL_HANDLER_RESET_ON_DELIVERY my_sigset(thr_client_alarm, process_alarm); /* int. thread system calls */ #endif return; @@ -325,7 +325,7 @@ sig_handler process_alarm(int sig __attribute__((unused))) #endif process_alarm_part2(sig); #ifndef USE_ALARM_THREAD -#if defined(DONT_REMEMBER_SIGNAL) && !defined(USE_ONE_SIGNAL_HAND) +#if defined(SIGNAL_HANDLER_RESET_ON_DELIVERY) && !defined(USE_ONE_SIGNAL_HAND) my_sigset(THR_SERVER_ALARM,process_alarm); #endif pthread_mutex_unlock(&LOCK_alarm); @@ -523,12 +523,12 @@ void thr_alarm_info(ALARM_INFO *info) */ -static sig_handler thread_alarm(int sig) +static sig_handler thread_alarm(int sig __attribute__((unused))) { #ifdef MAIN printf("thread_alarm\n"); fflush(stdout); #endif -#ifdef DONT_REMEMBER_SIGNAL +#ifdef SIGNAL_HANDLER_RESET_ON_DELIVERY my_sigset(sig,thread_alarm); /* int. thread system calls */ #endif } @@ -797,7 +797,7 @@ static sig_handler print_signal_warning(int sig) { printf("Warning: Got signal %d from thread %s\n",sig,my_thread_name()); fflush(stdout); -#ifdef DONT_REMEMBER_SIGNAL +#ifdef SIGNAL_HANDLER_RESET_ON_DELIVERY my_sigset(sig,print_signal_warning); /* int. thread system calls */ #endif if (sig == SIGALRM) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index daa1bbe8ccc..cac17889638 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1232,7 +1232,7 @@ extern "C" sig_handler print_signal_warning(int sig) { if (global_system_variables.log_warnings) sql_print_warning("Got signal %d from thread %ld", sig,my_thread_id()); -#ifdef DONT_REMEMBER_SIGNAL +#ifdef SIGNAL_HANDLER_RESET_ON_DELIVERY my_sigset(sig,print_signal_warning); /* int. thread system calls */ #endif #if !defined(__WIN__) && !defined(__NETWARE__) From 279b3adfc78ae93f976eb8797f41c64f3bc6b4bb Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Thu, 1 Jul 2010 12:05:09 +0300 Subject: [PATCH 082/112] Bug #53613: mysql_upgrade incorrectly revokes TRIGGER privilege on given table Fixed an incomplete historical ALTER TABLE MODIFY trimming the trigger privilege bit from mysql.tables_priv.Table_priv column. Removed the duplicate ALTER TABLE MODIFY. Test suite added. --- mysql-test/r/mysql_upgrade.result | 42 +++++++++++++++++++++++++++++ mysql-test/t/mysql_upgrade.test | 16 +++++++++++ scripts/mysql_system_tables_fix.sql | 4 +-- 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/mysql_upgrade.result b/mysql-test/r/mysql_upgrade.result index 821ad31871f..4541763c7c5 100644 --- a/mysql-test/r/mysql_upgrade.result +++ b/mysql-test/r/mysql_upgrade.result @@ -169,3 +169,45 @@ DROP PROCEDURE testproc; WARNING: NULL values of the 'character_set_client' column ('mysql.proc' table) have been updated with a default value (latin1). Please verify if necessary. WARNING: NULL values of the 'collation_connection' column ('mysql.proc' table) have been updated with a default value (latin1_swedish_ci). Please verify if necessary. WARNING: NULL values of the 'db_collation' column ('mysql.proc' table) have been updated with default values. Please verify if necessary. +# +# Bug #53613: mysql_upgrade incorrectly revokes +# TRIGGER privilege on given table +# +GRANT USAGE ON *.* TO 'user3'@'%'; +GRANT ALL PRIVILEGES ON `roelt`.`test2` TO 'user3'@'%'; +Run mysql_upgrade with all privileges on a user +mtr.global_suppressions OK +mtr.test_suppressions OK +mysql.columns_priv OK +mysql.db OK +mysql.event OK +mysql.func OK +mysql.general_log +Error : You can't use locks with log tables. +status : OK +mysql.help_category OK +mysql.help_keyword OK +mysql.help_relation OK +mysql.help_topic OK +mysql.host OK +mysql.ndb_binlog_index OK +mysql.plugin OK +mysql.proc OK +mysql.procs_priv OK +mysql.servers OK +mysql.slow_log +Error : You can't use locks with log tables. +status : OK +mysql.tables_priv OK +mysql.time_zone OK +mysql.time_zone_leap_second OK +mysql.time_zone_name OK +mysql.time_zone_transition OK +mysql.time_zone_transition_type OK +mysql.user OK +SHOW GRANTS FOR 'user3'@'%'; +Grants for user3@% +GRANT USAGE ON *.* TO 'user3'@'%' +GRANT ALL PRIVILEGES ON `roelt`.`test2` TO 'user3'@'%' +DROP USER 'user3'@'%'; +End of 5.1 tests diff --git a/mysql-test/t/mysql_upgrade.test b/mysql-test/t/mysql_upgrade.test index 6c01f3b2027..5f3ff9c7bb8 100644 --- a/mysql-test/t/mysql_upgrade.test +++ b/mysql-test/t/mysql_upgrade.test @@ -108,3 +108,19 @@ CALL testproc(); DROP PROCEDURE testproc; --cat_file $MYSQLTEST_VARDIR/tmp/41569.txt --remove_file $MYSQLTEST_VARDIR/tmp/41569.txt + + +--echo # +--echo # Bug #53613: mysql_upgrade incorrectly revokes +--echo # TRIGGER privilege on given table +--echo # + +GRANT USAGE ON *.* TO 'user3'@'%'; +GRANT ALL PRIVILEGES ON `roelt`.`test2` TO 'user3'@'%'; +--echo Run mysql_upgrade with all privileges on a user +--exec $MYSQL_UPGRADE --skip-verbose --force 2>&1 +SHOW GRANTS FOR 'user3'@'%'; + +DROP USER 'user3'@'%'; + +--echo End of 5.1 tests diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql index deeb4d4de82..90bdbdae338 100644 --- a/scripts/mysql_system_tables_fix.sql +++ b/scripts/mysql_system_tables_fix.sql @@ -58,7 +58,7 @@ ALTER TABLE tables_priv COLLATE utf8_general_ci DEFAULT '' NOT NULL, MODIFY Table_priv set('Select','Insert','Update','Delete','Create', 'Drop','Grant','References','Index','Alter', - 'Create View','Show view') + 'Create View','Show view','Trigger') COLLATE utf8_general_ci DEFAULT '' NOT NULL, COMMENT='Table privileges'; @@ -584,8 +584,6 @@ ALTER TABLE host MODIFY Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAU ALTER TABLE db ADD Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; ALTER TABLE db MODIFY Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; -ALTER TABLE tables_priv MODIFY Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger') COLLATE utf8_general_ci DEFAULT '' NOT NULL; - UPDATE user SET Trigger_priv=Super_priv WHERE @hadTriggerPriv = 0; # Activate the new, possible modified privilege tables From 1bfb6949bc867f20fe86c55b649188ab2297a357 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 2 Jul 2010 14:31:16 +0300 Subject: [PATCH 083/112] merge --- .bzr-mysql/default.conf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index e613cefc614..77df77c6021 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] -post_commit_to = "commits@lists.mysql.com" -post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.1-bugteam" +post_commit_to = "dbg_mysql_security@sun.com" +post_push_to = "dbg_mysql_security@sun.com" +tree_name = "mysql-5.1-security" From 0f5fed201fee686ddafb3221e3a055aa8fc194e6 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 2 Jul 2010 14:33:17 +0300 Subject: [PATCH 084/112] merge --- .bzr-mysql/default.conf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 557df1b1ffe..4b2affc1529 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] -post_commit_to = "commits@lists.mysql.com" -post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.0-bugteam" +post_commit_to = "dbg_mysql_security@sun.com" +post_push_to = "dbg_mysql_security@sun.com" +tree_name = "mysql-5.0-security" From cd41cd953d9d76b4b9c13fd745856d5023f12d71 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Mon, 5 Jul 2010 09:00:39 -0300 Subject: [PATCH 085/112] Bug#22320: my_atomic-t unit test fails The atomic operations implementation on 5.1 has a few problems, which might cause tests to abort randomly. Since no code in 5.1 uses atomic operations, simply remove the code. --- include/Makefile.am | 6 +- include/atomic/gcc_builtins.h | 33 ------ include/atomic/nolock.h | 44 -------- include/atomic/rwlock.h | 48 -------- include/atomic/x86-gcc.h | 58 ---------- include/atomic/x86-msvc.h | 96 ---------------- include/my_atomic.h | 142 ----------------------- include/my_pthread.h | 2 +- mysys/Makefile.am | 3 +- mysys/my_atomic.c | 45 -------- storage/ibmdb2i/db2i_file.h | 1 - unittest/mysys/Makefile.am | 7 -- unittest/mysys/my_atomic-t.c | 205 ---------------------------------- 13 files changed, 4 insertions(+), 686 deletions(-) delete mode 100644 include/atomic/gcc_builtins.h delete mode 100644 include/atomic/nolock.h delete mode 100644 include/atomic/rwlock.h delete mode 100644 include/atomic/x86-gcc.h delete mode 100644 include/atomic/x86-msvc.h delete mode 100644 include/my_atomic.h delete mode 100644 mysys/my_atomic.c delete mode 100644 unittest/mysys/my_atomic-t.c diff --git a/include/Makefile.am b/include/Makefile.am index 64f73af8606..130517a405e 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -36,10 +36,8 @@ noinst_HEADERS = config-win.h config-netware.h my_bit.h \ my_nosys.h my_alarm.h queues.h rijndael.h sha1.h \ my_aes.h my_tree.h my_trie.h hash.h thr_alarm.h \ thr_lock.h t_ctype.h violite.h my_md5.h base64.h \ - my_handler.h my_time.h \ - my_vle.h my_user.h my_atomic.h atomic/nolock.h \ - atomic/rwlock.h atomic/x86-gcc.h atomic/x86-msvc.h \ - atomic/gcc_builtins.h my_libwrap.h my_stacktrace.h + my_handler.h my_time.h my_vle.h my_user.h \ + my_libwrap.h my_stacktrace.h EXTRA_DIST = mysql.h.pp mysql/plugin.h.pp diff --git a/include/atomic/gcc_builtins.h b/include/atomic/gcc_builtins.h deleted file mode 100644 index 509701b30a5..00000000000 --- a/include/atomic/gcc_builtins.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2008 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#define make_atomic_add_body(S) \ - v= __sync_fetch_and_add(a, v); -#define make_atomic_swap_body(S) \ - v= __sync_lock_test_and_set(a, v); -#define make_atomic_cas_body(S) \ - int ## S sav; \ - sav= __sync_val_compare_and_swap(a, *cmp, set); \ - if (!(ret= (sav == *cmp))) *cmp= sav; - -#ifdef MY_ATOMIC_MODE_DUMMY -#define make_atomic_load_body(S) ret= *a -#define make_atomic_store_body(S) *a= v -#else -#define make_atomic_load_body(S) \ - ret= __sync_fetch_and_or(a, 0); -#define make_atomic_store_body(S) \ - (void) __sync_lock_test_and_set(a, v); -#endif diff --git a/include/atomic/nolock.h b/include/atomic/nolock.h deleted file mode 100644 index 10ac17884b6..00000000000 --- a/include/atomic/nolock.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (C) 2006 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#if defined(__i386__) || defined(_M_IX86) || defined(HAVE_GCC_ATOMIC_BUILTINS) - -#ifdef MY_ATOMIC_MODE_DUMMY -# define LOCK "" -#else -# define LOCK "lock" -#endif - -#ifdef HAVE_GCC_ATOMIC_BUILTINS -#include "gcc_builtins.h" -#elif __GNUC__ -#include "x86-gcc.h" -#elif defined(_MSC_VER) -#include "x86-msvc.h" -#endif -#endif - -#ifdef make_atomic_cas_body - -typedef struct { } my_atomic_rwlock_t; -#define my_atomic_rwlock_destroy(name) -#define my_atomic_rwlock_init(name) -#define my_atomic_rwlock_rdlock(name) -#define my_atomic_rwlock_wrlock(name) -#define my_atomic_rwlock_rdunlock(name) -#define my_atomic_rwlock_wrunlock(name) - -#endif - diff --git a/include/atomic/rwlock.h b/include/atomic/rwlock.h deleted file mode 100644 index 18b77e93d80..00000000000 --- a/include/atomic/rwlock.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (C) 2006 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -typedef struct {pthread_rwlock_t rw;} my_atomic_rwlock_t; - -#ifdef MY_ATOMIC_MODE_DUMMY -/* - the following can never be enabled by ./configure, one need to put #define in - a source to trigger the following warning. The resulting code will be broken, - it only makes sense to do it to see now test_atomic detects broken - implementations (another way is to run a UP build on an SMP box). -*/ -#warning MY_ATOMIC_MODE_DUMMY and MY_ATOMIC_MODE_RWLOCKS are incompatible -#define my_atomic_rwlock_destroy(name) -#define my_atomic_rwlock_init(name) -#define my_atomic_rwlock_rdlock(name) -#define my_atomic_rwlock_wrlock(name) -#define my_atomic_rwlock_rdunlock(name) -#define my_atomic_rwlock_wrunlock(name) -#define MY_ATOMIC_MODE "dummy (non-atomic)" -#else -#define my_atomic_rwlock_destroy(name) pthread_rwlock_destroy(& (name)->rw) -#define my_atomic_rwlock_init(name) pthread_rwlock_init(& (name)->rw, 0) -#define my_atomic_rwlock_rdlock(name) pthread_rwlock_rdlock(& (name)->rw) -#define my_atomic_rwlock_wrlock(name) pthread_rwlock_wrlock(& (name)->rw) -#define my_atomic_rwlock_rdunlock(name) pthread_rwlock_unlock(& (name)->rw) -#define my_atomic_rwlock_wrunlock(name) pthread_rwlock_unlock(& (name)->rw) -#define MY_ATOMIC_MODE "rwlocks" -#endif - -#define make_atomic_add_body(S) int ## S sav; sav= *a; *a+= v; v=sav; -#define make_atomic_swap_body(S) int ## S sav; sav= *a; *a= v; v=sav; -#define make_atomic_cas_body(S) if ((ret= (*a == *cmp))) *a= set; else *cmp=*a; -#define make_atomic_load_body(S) ret= *a; -#define make_atomic_store_body(S) *a= v; - diff --git a/include/atomic/x86-gcc.h b/include/atomic/x86-gcc.h deleted file mode 100644 index d79dadbf05e..00000000000 --- a/include/atomic/x86-gcc.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (C) 2006 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* - XXX 64-bit atomic operations can be implemented using - cmpxchg8b, if necessary. Though I've heard that not all 64-bit - architectures support double-word (128-bit) cas. -*/ - -#ifdef MY_ATOMIC_NO_XADD -#define MY_ATOMIC_MODE "gcc-x86" LOCK "-no-xadd" -#else -#define MY_ATOMIC_MODE "gcc-x86" LOCK -#endif - -/* fix -ansi errors while maintaining readability */ -#ifndef asm -#define asm __asm__ -#endif - -#ifndef MY_ATOMIC_NO_XADD -#define make_atomic_add_body(S) \ - asm volatile (LOCK "; xadd %0, %1;" : "+r" (v) , "+m" (*a)) -#endif -#define make_atomic_swap_body(S) \ - asm volatile ("; xchg %0, %1;" : "+r" (v) , "+m" (*a)) -#define make_atomic_cas_body(S) \ - asm volatile (LOCK "; cmpxchg %3, %0; setz %2;" \ - : "+m" (*a), "+a" (*cmp), "=q" (ret): "r" (set)) - -#ifdef MY_ATOMIC_MODE_DUMMY -#define make_atomic_load_body(S) ret=*a -#define make_atomic_store_body(S) *a=v -#else -/* - Actually 32-bit reads/writes are always atomic on x86 - But we add LOCK here anyway to force memory barriers -*/ -#define make_atomic_load_body(S) \ - ret=0; \ - asm volatile (LOCK "; cmpxchg %2, %0" \ - : "+m" (*a), "+a" (ret): "r" (ret)) -#define make_atomic_store_body(S) \ - asm volatile ("; xchg %0, %1;" : "+m" (*a) : "r" (v)) -#endif - diff --git a/include/atomic/x86-msvc.h b/include/atomic/x86-msvc.h deleted file mode 100644 index c4885bb8451..00000000000 --- a/include/atomic/x86-msvc.h +++ /dev/null @@ -1,96 +0,0 @@ -/* Copyright (C) 2006 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* - XXX 64-bit atomic operations can be implemented using - cmpxchg8b, if necessary -*/ - -// Would it be better to use intrinsics ? -// (InterlockedCompareExchange, InterlockedCompareExchange16 -// InterlockedExchangeAdd, InterlockedExchange) - -#ifndef _atomic_h_cleanup_ -#define _atomic_h_cleanup_ "atomic/x86-msvc.h" - -#define MY_ATOMIC_MODE "msvc-x86" LOCK - -#define make_atomic_add_body(S) \ - _asm { \ - _asm mov reg_ ## S, v \ - _asm LOCK xadd *a, reg_ ## S \ - _asm movzx v, reg_ ## S \ - } -#define make_atomic_cas_body(S) \ - _asm { \ - _asm mov areg_ ## S, *cmp \ - _asm mov reg2_ ## S, set \ - _asm LOCK cmpxchg *a, reg2_ ## S \ - _asm mov *cmp, areg_ ## S \ - _asm setz al \ - _asm movzx ret, al \ - } -#define make_atomic_swap_body(S) \ - _asm { \ - _asm mov reg_ ## S, v \ - _asm xchg *a, reg_ ## S \ - _asm mov v, reg_ ## S \ - } - -#ifdef MY_ATOMIC_MODE_DUMMY -#define make_atomic_load_body(S) ret=*a -#define make_atomic_store_body(S) *a=v -#else -/* - Actually 32-bit reads/writes are always atomic on x86 - But we add LOCK here anyway to force memory barriers -*/ -#define make_atomic_load_body(S) \ - _asm { \ - _asm mov areg_ ## S, 0 \ - _asm mov reg2_ ## S, areg_ ## S \ - _asm LOCK cmpxchg *a, reg2_ ## S \ - _asm mov ret, areg_ ## S \ - } -#define make_atomic_store_body(S) \ - _asm { \ - _asm mov reg_ ## S, v \ - _asm xchg *a, reg_ ## S \ - } -#endif - -#define reg_8 al -#define reg_16 ax -#define reg_32 eax -#define areg_8 al -#define areg_16 ax -#define areg_32 eax -#define reg2_8 bl -#define reg2_16 bx -#define reg2_32 ebx - -#else /* cleanup */ - -#undef reg_8 -#undef reg_16 -#undef reg_32 -#undef areg_8 -#undef areg_16 -#undef areg_32 -#undef reg2_8 -#undef reg2_16 -#undef reg2_32 -#endif - diff --git a/include/my_atomic.h b/include/my_atomic.h deleted file mode 100644 index ed439e5fe87..00000000000 --- a/include/my_atomic.h +++ /dev/null @@ -1,142 +0,0 @@ -/* Copyright (C) 2006 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#ifndef my_atomic_rwlock_init - -#define intptr void * - -#ifndef MY_ATOMIC_MODE_RWLOCKS -#include "atomic/nolock.h" -#endif - -#ifndef make_atomic_cas_body -#include "atomic/rwlock.h" -#endif - -#ifndef make_atomic_add_body -#define make_atomic_add_body(S) \ - int ## S tmp=*a; \ - while (!my_atomic_cas ## S(a, &tmp, tmp+v)); \ - v=tmp; -#endif - -#ifdef HAVE_INLINE - -#define make_atomic_add(S) \ -STATIC_INLINE int ## S my_atomic_add ## S( \ - int ## S volatile *a, int ## S v) \ -{ \ - make_atomic_add_body(S); \ - return v; \ -} - -#define make_atomic_swap(S) \ -STATIC_INLINE int ## S my_atomic_swap ## S( \ - int ## S volatile *a, int ## S v) \ -{ \ - make_atomic_swap_body(S); \ - return v; \ -} - -#define make_atomic_cas(S) \ -STATIC_INLINE int my_atomic_cas ## S(int ## S volatile *a, \ - int ## S *cmp, int ## S set) \ -{ \ - int8 ret; \ - make_atomic_cas_body(S); \ - return ret; \ -} - -#define make_atomic_load(S) \ -STATIC_INLINE int ## S my_atomic_load ## S(int ## S volatile *a) \ -{ \ - int ## S ret; \ - make_atomic_load_body(S); \ - return ret; \ -} - -#define make_atomic_store(S) \ -STATIC_INLINE void my_atomic_store ## S( \ - int ## S volatile *a, int ## S v) \ -{ \ - make_atomic_store_body(S); \ -} - -#else /* no inline functions */ - -#define make_atomic_add(S) \ -extern int ## S my_atomic_add ## S(int ## S volatile *a, int ## S v); - -#define make_atomic_swap(S) \ -extern int ## S my_atomic_swap ## S(int ## S volatile *a, int ## S v); - -#define make_atomic_cas(S) \ -extern int my_atomic_cas ## S(int ## S volatile *a, int ## S *cmp, int ## S set); - -#define make_atomic_load(S) \ -extern int ## S my_atomic_load ## S(int ## S volatile *a); - -#define make_atomic_store(S) \ -extern void my_atomic_store ## S(int ## S volatile *a, int ## S v); - -#endif - -make_atomic_cas( 8) -make_atomic_cas(16) -make_atomic_cas(32) -make_atomic_cas(ptr) - -make_atomic_add( 8) -make_atomic_add(16) -make_atomic_add(32) - -make_atomic_load( 8) -make_atomic_load(16) -make_atomic_load(32) -make_atomic_load(ptr) - -make_atomic_store( 8) -make_atomic_store(16) -make_atomic_store(32) -make_atomic_store(ptr) - -make_atomic_swap( 8) -make_atomic_swap(16) -make_atomic_swap(32) -make_atomic_swap(ptr) - -#undef make_atomic_add -#undef make_atomic_cas -#undef make_atomic_load -#undef make_atomic_store -#undef make_atomic_swap -#undef make_atomic_add_body -#undef make_atomic_cas_body -#undef make_atomic_load_body -#undef make_atomic_store_body -#undef make_atomic_swap_body -#undef intptr - -#ifdef _atomic_h_cleanup_ -#include _atomic_h_cleanup_ -#undef _atomic_h_cleanup_ -#endif - -#define MY_ATOMIC_OK 0 -#define MY_ATOMIC_NOT_1CPU 1 -extern int my_atomic_initialize(); - -#endif - diff --git a/include/my_pthread.h b/include/my_pthread.h index e9256610ea7..eff6a677192 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -715,7 +715,7 @@ extern uint thd_lib_detected; The implementation is guaranteed to be thread safe, on all platforms. Note that the calling code should *not* assume the counter is protected by the mutex given, as the implementation of these helpers may change - to use my_atomic operations instead. + to use atomic operations instead. */ /* diff --git a/mysys/Makefile.am b/mysys/Makefile.am index 19017330654..e4c71f66079 100644 --- a/mysys/Makefile.am +++ b/mysys/Makefile.am @@ -30,8 +30,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \ mf_tempdir.c my_lock.c mf_brkhant.c my_alarm.c \ my_malloc.c my_realloc.c my_once.c mulalloc.c \ my_alloc.c safemalloc.c my_new.cc \ - my_vle.c my_atomic.c \ - my_fopen.c my_fstream.c my_getsystime.c \ + my_vle.c my_fopen.c my_fstream.c my_getsystime.c \ my_error.c errors.c my_div.c my_messnc.c \ mf_format.c mf_same.c mf_dirname.c mf_fn_ext.c \ my_symlink.c my_symlink2.c \ diff --git a/mysys/my_atomic.c b/mysys/my_atomic.c deleted file mode 100644 index aa04d55f624..00000000000 --- a/mysys/my_atomic.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (C) 2006 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include -#include - -#ifndef HAVE_INLINE -/* the following will cause all inline functions to be instantiated */ -#define HAVE_INLINE -#undef STATIC_INLINE -#define STATIC_INLINE extern -#endif - -#include - -/* - checks that the current build of atomic ops - can run on this machine - - RETURN - ATOMIC_xxx values, see my_atomic.h -*/ -int my_atomic_initialize() -{ - compile_time_assert(sizeof(intptr) == sizeof(void *)); - /* currently the only thing worth checking is SMP/UP issue */ -#ifdef MY_ATOMIC_MODE_DUMMY - return my_getncpus() == 1 ? MY_ATOMIC_OK : MY_ATOMIC_NOT_1CPU; -#else - return MY_ATOMIC_OK; -#endif -} - diff --git a/storage/ibmdb2i/db2i_file.h b/storage/ibmdb2i/db2i_file.h index ff35a473b05..7b63b18c315 100644 --- a/storage/ibmdb2i/db2i_file.h +++ b/storage/ibmdb2i/db2i_file.h @@ -40,7 +40,6 @@ OF SUCH DAMAGE. #include "db2i_global.h" #include "db2i_ileBridge.h" #include "db2i_validatedPointer.h" -#include "my_atomic.h" #include "db2i_iconv.h" #include "db2i_charsetSupport.h" diff --git a/unittest/mysys/Makefile.am b/unittest/mysys/Makefile.am index f0ffc7a6720..b195017e914 100644 --- a/unittest/mysys/Makefile.am +++ b/unittest/mysys/Makefile.am @@ -23,12 +23,5 @@ LDADD = $(top_builddir)/unittest/mytap/libmytap.a \ noinst_PROGRAMS = bitmap-t base64-t -if NEED_THREAD -# my_atomic-t is used to check thread functions, so it is safe to -# ignore the file in non-threaded builds. -# In fact, it will not compile without thread support. -noinst_PROGRAMS += my_atomic-t -endif - # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/unittest/mysys/my_atomic-t.c b/unittest/mysys/my_atomic-t.c deleted file mode 100644 index f2bcd360508..00000000000 --- a/unittest/mysys/my_atomic-t.c +++ /dev/null @@ -1,205 +0,0 @@ -/* Copyright (C) 2006 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include -#include -#include -#include - -/* at least gcc 3.4.5 and 3.4.6 (but not 3.2.3) on RHEL */ -#if __GNUC__ == 3 && __GNUC_MINOR__ == 4 -#define GCC_BUG_WORKAROUND volatile -#else -#define GCC_BUG_WORKAROUND -#endif - -int32 a32,b32,c32; -my_atomic_rwlock_t rwl; - -pthread_attr_t thr_attr; -pthread_mutex_t mutex; -pthread_cond_t cond; -int N; - -/* add and sub a random number in a loop. Must get 0 at the end */ -pthread_handler_t test_atomic_add_handler(void *arg) -{ - int m=*(int *)arg; - GCC_BUG_WORKAROUND int32 x; - for (x=((int)((long)(&m))); m ; m--) - { - x=x*m+0x87654321; - my_atomic_rwlock_wrlock(&rwl); - my_atomic_add32(&a32, x); - my_atomic_rwlock_wrunlock(&rwl); - - my_atomic_rwlock_wrlock(&rwl); - my_atomic_add32(&a32, -x); - my_atomic_rwlock_wrunlock(&rwl); - } - pthread_mutex_lock(&mutex); - N--; - if (!N) pthread_cond_signal(&cond); - pthread_mutex_unlock(&mutex); - return 0; -} - -/* - 1. generate thread number 0..N-1 from b32 - 2. add it to a32 - 3. swap thread numbers in c32 - 4. (optionally) one more swap to avoid 0 as a result - 5. subtract result from a32 - must get 0 in a32 at the end -*/ -pthread_handler_t test_atomic_swap_handler(void *arg) -{ - int m=*(int *)arg; - int32 x; - - my_atomic_rwlock_wrlock(&rwl); - x=my_atomic_add32(&b32, 1); - my_atomic_rwlock_wrunlock(&rwl); - - my_atomic_rwlock_wrlock(&rwl); - my_atomic_add32(&a32, x); - my_atomic_rwlock_wrunlock(&rwl); - - for (; m ; m--) - { - my_atomic_rwlock_wrlock(&rwl); - x=my_atomic_swap32(&c32, x); - my_atomic_rwlock_wrunlock(&rwl); - } - - if (!x) - { - my_atomic_rwlock_wrlock(&rwl); - x=my_atomic_swap32(&c32, x); - my_atomic_rwlock_wrunlock(&rwl); - } - - my_atomic_rwlock_wrlock(&rwl); - my_atomic_add32(&a32, -x); - my_atomic_rwlock_wrunlock(&rwl); - - pthread_mutex_lock(&mutex); - N--; - if (!N) pthread_cond_signal(&cond); - pthread_mutex_unlock(&mutex); - return 0; -} - -/* - same as test_atomic_add_handler, but my_atomic_add32 is emulated with - (slower) my_atomic_cas32 -*/ -pthread_handler_t test_atomic_cas_handler(void *arg) -{ - int m=*(int *)arg, ok; - GCC_BUG_WORKAROUND int32 x,y; - for (x=((int)((long)(&m))); m ; m--) - { - my_atomic_rwlock_wrlock(&rwl); - y=my_atomic_load32(&a32); - my_atomic_rwlock_wrunlock(&rwl); - - x=x*m+0x87654321; - do { - my_atomic_rwlock_wrlock(&rwl); - ok=my_atomic_cas32(&a32, &y, y+x); - my_atomic_rwlock_wrunlock(&rwl); - } while (!ok); - do { - my_atomic_rwlock_wrlock(&rwl); - ok=my_atomic_cas32(&a32, &y, y-x); - my_atomic_rwlock_wrunlock(&rwl); - } while (!ok); - } - pthread_mutex_lock(&mutex); - N--; - if (!N) pthread_cond_signal(&cond); - pthread_mutex_unlock(&mutex); - return 0; -} - -void test_atomic(const char *test, pthread_handler handler, int n, int m) -{ - pthread_t t; - ulonglong now=my_getsystime(); - - a32= 0; - b32= 0; - c32= 0; - - diag("Testing %s with %d threads, %d iterations... ", test, n, m); - for (N=n ; n ; n--) - { - if (pthread_create(&t, &thr_attr, handler, &m) != 0) - { - diag("Could not create thread"); - a32= 1; - goto err; - } - } - - pthread_mutex_lock(&mutex); - while (N) - pthread_cond_wait(&cond, &mutex); - pthread_mutex_unlock(&mutex); - now=my_getsystime()-now; -err: - ok(a32 == 0, "tested %s in %g secs", test, ((double)now)/1e7); -} - -int main() -{ - int err; - MY_INIT("my_atomic-t.c"); - - diag("N CPUs: %d", my_getncpus()); - err= my_atomic_initialize(); - - plan(4); - ok(err == 0, "my_atomic_initialize() returned %d", err); - - pthread_attr_init(&thr_attr); - pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED); - pthread_mutex_init(&mutex, 0); - pthread_cond_init(&cond, 0); - my_atomic_rwlock_init(&rwl); - -#ifdef HPUX11 -#define CYCLES 1000 -#else -#define CYCLES 10000 -#endif -#define THREADS 100 - test_atomic("my_atomic_add32", test_atomic_add_handler, THREADS, CYCLES); - test_atomic("my_atomic_swap32", test_atomic_swap_handler, THREADS, CYCLES); - test_atomic("my_atomic_cas32", test_atomic_cas_handler, THREADS, CYCLES); - /* - workaround until we know why it crashes randomly on some machine - (BUG#22320). - */ - sleep(2); - - pthread_mutex_destroy(&mutex); - pthread_cond_destroy(&cond); - pthread_attr_destroy(&thr_attr); - my_atomic_rwlock_destroy(&rwl); - return exit_status(); -} - From 9dba6ddfac25088c5b187f15370d949eb4a40896 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 6 Jul 2010 16:01:02 +0200 Subject: [PATCH 086/112] Raise version number after cloning 5.1.49 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 74e575fad8c..a475185d880 100644 --- a/configure.in +++ b/configure.in @@ -12,7 +12,7 @@ dnl dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MySQL Server], [5.1.49], [], [mysql]) +AC_INIT([MySQL Server], [5.1.50], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM From 04dd8ed0eb5f06f670f6e455b06c1173988a8f11 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 6 Jul 2010 15:36:31 -0300 Subject: [PATCH 087/112] Bug#52514: mysql 5.1 do_abi_check does not compile w/ gcc4.5 due to GCC preprocessor change Temporary workaround: disable abi_check if GCC >= 4.5 --- configure.in | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 539d597fd07..d47bf975fdd 100644 --- a/configure.in +++ b/configure.in @@ -475,7 +475,16 @@ if test "$GCC" != "yes" || expr "$CC" : ".*icc.*" then ABI_CHECK="" else - ABI_CHECK="abi_check" + # Workaround GCC >= 4.5 - See Bug#52514 + case `$CC -dumpversion` in + [[4-9]].[[5-9]]*) + AC_MSG_WARN([ABI check disabled (GCC >= 4.5)]) + ABI_CHECK="" + ;; + *) + ABI_CHECK="abi_check" + ;; + esac fi AC_SUBST(ABI_CHECK) From 6652fc78b7b5e1093a0670c3271fec7d626bb222 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 6 Jul 2010 19:31:54 -0300 Subject: [PATCH 088/112] Fix what is probably the result of a bad merge. No functional change. --- libmysql/libmysql.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index e0cc119bd16..362ad5de6c4 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -4421,6 +4421,7 @@ static my_bool setup_one_fetch_function(MYSQL_BIND *param, MYSQL_FIELD *field) case MYSQL_TYPE_TIME: field->max_length= 15; /* 19:23:48.123456 */ param->skip_result= skip_result_with_length; + break; case MYSQL_TYPE_DATE: field->max_length= 10; /* 2003-11-11 */ param->skip_result= skip_result_with_length; From d9e7c4efb6bfebf625af629b3ca878f1d0dc7e02 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 7 Jul 2010 12:15:58 +0300 Subject: [PATCH 089/112] Addendum to the fix for bug #53095 (failing information_schema.test on windows) Since the original fix for this bug lowercases the search pattern it's not a good idea to copy the search pattern to the output instead of the real table name found (since, depending on the case mode these two names may differ in case). Fixed the infrmation_schema.test failure by making sure the actual table name of an inoformation schema table is passed instead of the lookup pattern even when the pattern doesn't contain wildcards. --- sql/sql_show.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 0eeb333f278..17fbf62b097 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2939,11 +2939,15 @@ make_table_name_list(THD *thd, List *table_names, LEX *lex, { if (with_i_schema) { + LEX_STRING *name; ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, lookup_field_vals->table_value.str); if (schema_table && !schema_table->hidden) { - if (table_names->push_back(&lookup_field_vals->table_value)) + if (!(name= + thd->make_lex_string(NULL, schema_table->table_name, + strlen(schema_table->table_name), TRUE)) || + table_names->push_back(name)) return 1; } } From b2318bce9e8ed93d4566896c05806c6bf547b54f Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 7 Jul 2010 20:13:53 +0300 Subject: [PATCH 090/112] Merge the fix for Bug#49238 from SVN (without the unrelated whitespace changes): ------------------------------------------------------------------------ r7009 | jyang | 2010-04-29 20:44:56 +0300 (Thu, 29 Apr 2010) | 6 lines branches/5.0: Port fix for bug #49238 (Creating/Dropping a temporary table while at 1023 transactions will cause assert) from 5.1 to branches/5.1. Separate action for return value DB_TOO_MANY_CONCURRENT_TRXS from that of DB_MUST_GET_MORE_FILE_SPACE in row_drop_table_for_mysql(). ------------------------------------------------------------------------ --- innobase/row/row0mysql.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 75c54cec4b3..f636b505b6b 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -3335,20 +3335,13 @@ fputs(" InnoDB: You are trying to drop table ", stderr); err = trx->error_state; - if (err != DB_SUCCESS) { - ut_a(err == DB_OUT_OF_FILE_SPACE); - - err = DB_MUST_GET_MORE_FILE_SPACE; - - row_mysql_handle_errors(&err, trx, thr, NULL); - - ut_error; - } else { + switch (err) { ibool is_path; const char* name_or_path; + case DB_SUCCESS: space_id = table->space; - + if (table->dir_path_of_temp_table != NULL) { dir_path_of_temp_table = mem_strdup(table->dir_path_of_temp_table); @@ -3407,7 +3400,27 @@ fputs(" InnoDB: You are trying to drop table ", stderr); err = DB_ERROR; } } + break; + + case DB_TOO_MANY_CONCURRENT_TRXS: + /* Cannot even find a free slot for the + the undo log. We can directly exit here + and return the DB_TOO_MANY_CONCURRENT_TRXS + error. */ + break; + + case DB_OUT_OF_FILE_SPACE: + err = DB_MUST_GET_MORE_FILE_SPACE; + + row_mysql_handle_errors(&err, trx, thr, NULL); + + /* Fall through to raise error */ + + default: + /* No other possible error returns */ + ut_error; } + funct_exit: trx_commit_for_mysql(trx); From 2f570f7ce3a41d5bb99ce454c88e3e321751fc49 Mon Sep 17 00:00:00 2001 From: sunanda Date: Wed, 7 Jul 2010 20:34:50 +0200 Subject: [PATCH 091/112] rko Mdkeld change, revision 3351.14.134 add innodb_plugin to mysql-test-run default suites was not complete. Bootstrap failed to pick up necessary files needed by test and hence all tests failed. --- mysql-test/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index 06aea68b52d..066c8d53c14 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -100,6 +100,7 @@ TEST_DIRS = t r include std_data std_data/parts collections \ suite/rpl_ndb suite/rpl_ndb/t suite/rpl_ndb/r \ suite/parts suite/parts/t suite/parts/r suite/parts/inc \ suite/innodb suite/innodb/t suite/innodb/r suite/innodb/include \ + suite/innodb_plugin suite/innodb_plugin/t suite/innodb_plugin/r suite/innodb_plugin/include \ suite/engines suite/engines/funcs suite/engines/iuds suite/engines/rr_trx \ suite/engines/funcs/r suite/engines/funcs/t suite/engines/iuds/r \ suite/engines/iuds/t suite/engines/rr_trx/include suite/engines/rr_trx/r \ From 625ae7185abcfc7042be225d4f8ef77806fc0803 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 8 Jul 2010 10:44:26 +0800 Subject: [PATCH 092/112] Postfix bug#48321 Fix the memory leak --- sql/log_event.cc | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index 0e4d4bd512b..93d170e1510 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2396,6 +2396,8 @@ bool Query_log_event::write(IO_CACHE* file) Query_log_event::Query_log_event() :Log_event(), data_buf(0) { + memset(&user, 0, sizeof(user)); + memset(&host, 0, sizeof(host)); } @@ -2438,6 +2440,9 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, { time_t end_time; + memset(&user, 0, sizeof(user)); + memset(&host, 0, sizeof(host)); + error_code= errcode; time(&end_time); @@ -2783,13 +2788,13 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, CHECK_SPACE(pos, end, 1); user.length= *pos++; CHECK_SPACE(pos, end, user.length); - user.str= my_strndup((const char *)pos, user.length, MYF(0)); + user.str= (char *)pos; pos+= user.length; CHECK_SPACE(pos, end, 1); host.length= *pos++; CHECK_SPACE(pos, end, host.length); - host.str= my_strndup((const char *)pos, host.length, MYF(0)); + host.str= (char *)pos; pos+= host.length; } default: @@ -2805,12 +2810,16 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, time_zone_len + 1 + data_len + 1 + QUERY_CACHE_FLAGS_SIZE + + user.length + 1 + + host.length + 1 + db_len + 1, MYF(MY_WME)))) #else if (!(start= data_buf = (Log_event::Byte*) my_malloc(catalog_len + 1 + time_zone_len + 1 + - data_len + 1, + data_len + 1 + + user.length + 1 + + host.length + 1, MYF(MY_WME)))) #endif DBUG_VOID_RETURN; @@ -2833,6 +2842,11 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, if (time_zone_len) copy_str_and_move(&time_zone_str, &start, time_zone_len); + if (user.length > 0) + copy_str_and_move((const char **)&(user.str), &start, user.length); + if (host.length > 0) + copy_str_and_move((const char **)&(host.str), &start, host.length); + /** if time_zone_len or catalog_len are 0, then time_zone and catalog are uninitialized at this point. shouldn't they point to the From 9edde02ebb908497a7ad12a2c9e28380d1e30531 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Fri, 9 Jul 2010 01:09:31 +0200 Subject: [PATCH 093/112] Bug#52455: Subpar INSERT ON DUPLICATE KEY UPDATE performance with many partitions The handler function for reading one row from a specific index was not optimized in the partitioning handler since it used the default implementation. No test case since it is performance only, verified by hand. sql/ha_partition.cc: Implemented a optimized version of index_read_idx_map for the case when find flag == HA_READ_KEY_EXACT, which is the common case. sql/ha_partition.h: Declared ha_partition::index_read_idx_map --- sql/ha_partition.cc | 52 +++++++++++++++++++++++++++++++++++++++++++++ sql/ha_partition.h | 9 ++++++++ 2 files changed, 61 insertions(+) diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 60722f0100e..a87c7fbf7b8 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -4219,6 +4219,58 @@ int ha_partition::index_read_last_map(uchar *buf, const uchar *key, } +/* + Optimization of the default implementation to take advantage of dynamic + partition pruning. +*/ +int ha_partition::index_read_idx_map(uchar *buf, uint index, + const uchar *key, + key_part_map keypart_map, + enum ha_rkey_function find_flag) +{ + int error= HA_ERR_KEY_NOT_FOUND; + DBUG_ENTER("ha_partition::index_read_idx_map"); + + if (find_flag == HA_READ_KEY_EXACT) + { + uint part; + m_start_key.key= key; + m_start_key.keypart_map= keypart_map; + m_start_key.flag= find_flag; + m_start_key.length= calculate_key_len(table, index, m_start_key.key, + m_start_key.keypart_map); + + get_partition_set(table, buf, index, &m_start_key, &m_part_spec); + + /* How can it be more than one partition with the current use? */ + DBUG_ASSERT(m_part_spec.start_part == m_part_spec.end_part); + + for (part= m_part_spec.start_part; part <= m_part_spec.end_part; part++) + { + if (bitmap_is_set(&(m_part_info->used_partitions), part)) + { + error= m_file[part]->index_read_idx_map(buf, index, key, + keypart_map, find_flag); + if (error != HA_ERR_KEY_NOT_FOUND && + error != HA_ERR_END_OF_FILE) + break; + } + } + } + else + { + /* + If not only used with READ_EXACT, we should investigate if possible + to optimize for other find_flag's as well. + */ + DBUG_ASSERT(0); + /* fall back on the default implementation */ + error= handler::index_read_idx_map(buf, index, key, keypart_map, find_flag); + } + DBUG_RETURN(error); +} + + /* Read next record in a forward index scan diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 9f6d9e0a5ba..d8872d37a09 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -448,6 +448,15 @@ public: virtual int index_init(uint idx, bool sorted); virtual int index_end(); + /** + @breif + Positions an index cursor to the index specified in the hanlde. Fetches the + row if available. If the key value is null, begin at first key of the + index. + */ + virtual int index_read_idx_map(uchar *buf, uint index, const uchar *key, + key_part_map keypart_map, + enum ha_rkey_function find_flag); /* These methods are used to jump to next or previous entry in the index scan. There are also methods to jump to first and last entry. From 013136364c95b7bcc5a987dd301b042f31dab1f9 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Fri, 9 Jul 2010 14:39:47 +0400 Subject: [PATCH 094/112] Bug#54416 MAX from JOIN with HAVING returning NULL with 5.1 and Empty set The problem there is that HAVING condition evaluates const parts of condition despite the condition has references on aggregate functions. Table t1 became const tables after make_join_statistics and table1.pk = 1, HAVING is transformed into MAX(1) < 7 and taken away from HAVING. The fix is to skip evaluation of HAVING conts parts if HAVING condition has references on aggregate functions. mysql-test/r/having.result: test case mysql-test/t/having.test: test case sql/sql_select.cc: skip evaluation of HAVING conts parts if HAVING condition has references on aggregate functions. --- mysql-test/r/having.result | 16 ++++++++++++++++ mysql-test/t/having.test | 21 +++++++++++++++++++++ sql/sql_select.cc | 2 +- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result index 54293e9d02e..cd1b4ae0218 100644 --- a/mysql-test/r/having.result +++ b/mysql-test/r/having.result @@ -530,3 +530,19 @@ MAX(t2.f2) NULL DROP TABLE t1,t2; End of 5.0 tests +# +# Bug#54416 MAX from JOIN with HAVING returning NULL with 5.1 and Empty set +# +CREATE TABLE t1 (f1 INT(11), f2 VARCHAR(1), PRIMARY KEY (f1)); +INSERT INTO t1 VALUES (1,'f'); +CREATE TABLE t2 (f1 INT(11), f2 VARCHAR(1)); +INSERT INTO t2 VALUES (2,'m'); +INSERT INTO t2 VALUES (3,'m'); +INSERT INTO t2 VALUES (11,NULL); +INSERT INTO t2 VALUES (12,'k'); +SELECT MAX(t1.f1) field1 +FROM t1 JOIN t2 ON t2.f2 LIKE 'x' +HAVING field1 < 7; +field1 +DROP TABLE t1,t2; +End of 5.1 tests diff --git a/mysql-test/t/having.test b/mysql-test/t/having.test index 65bf9518a5c..c808e747523 100644 --- a/mysql-test/t/having.test +++ b/mysql-test/t/having.test @@ -544,3 +544,24 @@ ORDER BY t1.f2; DROP TABLE t1,t2; --echo End of 5.0 tests + +--echo # +--echo # Bug#54416 MAX from JOIN with HAVING returning NULL with 5.1 and Empty set +--echo # + +CREATE TABLE t1 (f1 INT(11), f2 VARCHAR(1), PRIMARY KEY (f1)); +INSERT INTO t1 VALUES (1,'f'); + +CREATE TABLE t2 (f1 INT(11), f2 VARCHAR(1)); +INSERT INTO t2 VALUES (2,'m'); +INSERT INTO t2 VALUES (3,'m'); +INSERT INTO t2 VALUES (11,NULL); +INSERT INTO t2 VALUES (12,'k'); + +SELECT MAX(t1.f1) field1 +FROM t1 JOIN t2 ON t2.f2 LIKE 'x' +HAVING field1 < 7; + +DROP TABLE t1,t2; + +--echo End of 5.1 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b20726fc151..fe391b50bb9 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1132,7 +1132,7 @@ JOIN::optimize() elements may be lost during further having condition transformation in JOIN::exec. */ - if (having && const_table_map) + if (having && const_table_map && !having->with_sum_func) { having->update_used_tables(); having= remove_eq_conds(thd, having, &having_value); From 70b02d3aedb5c7ddf84720d0dd54e6f74c797788 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Fri, 9 Jul 2010 13:15:26 +0200 Subject: [PATCH 095/112] Bug#52517: Regression in ROW level replication performance with partitions In bug-28430 HA_PRIMARY_KEY_REQUIRED_FOR_POSITION was disabled in the partitioning engine in the first patch, That bug was later fixed a second time, but that flag was not removed. No need to disable this flag, as it leads to bad choise in row replication. sql/ha_partition.h: Not disabling HA_PRIMARY_KEY_REQUIRED_FOR_POSITION flag. Updated comment (has nothing to do with hidden key. sql/handler.h: Updated comments to about HA_PRIMARY_KEY_REQUIRED_FOR_POSITION. --- sql/ha_partition.h | 6 +----- sql/handler.h | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 9f6d9e0a5ba..351d3d6b247 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -53,8 +53,7 @@ typedef struct st_ha_data_partition HA_CAN_FULLTEXT | \ HA_DUPLICATE_POS | \ HA_CAN_SQL_HANDLER | \ - HA_CAN_INSERT_DELAYED | \ - HA_PRIMARY_KEY_REQUIRED_FOR_POSITION) + HA_CAN_INSERT_DELAYED) class ha_partition :public handler { private: @@ -766,9 +765,6 @@ public: HA_PRIMARY_KEY_REQUIRED_FOR_POSITION: Does the storage engine need a PK for position? - Used with hidden primary key in InnoDB. - Hidden primary keys cannot be supported by partitioning, since the - partitioning expressions columns must be a part of the primary key. (InnoDB) HA_FILE_BASED is always set for partition handler since we use a diff --git a/sql/handler.h b/sql/handler.h index d9dfd4f0707..3c7cba747fa 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -93,7 +93,10 @@ #define HA_PRIMARY_KEY_IN_READ_INDEX (1 << 15) /* If HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is set, it means that to position() - uses a primary key. Without primary key, we can't call position(). + uses a primary key given by the record argument. + Without primary key, we can't call position(). + If not set, the position is returned as the current rows position + regardless of what argument is given. */ #define HA_PRIMARY_KEY_REQUIRED_FOR_POSITION (1 << 16) #define HA_CAN_RTREEKEYS (1 << 17) @@ -1446,10 +1449,9 @@ public: virtual int rnd_next(uchar *buf)=0; virtual int rnd_pos(uchar * buf, uchar *pos)=0; /** - One has to use this method when to find - random position by record as the plain - position() call doesn't work for some - handlers for random position. + This function only works for handlers having + HA_PRIMARY_KEY_REQUIRED_FOR_POSITION set. + It will return the row with the PK given in the record argument. */ virtual int rnd_pos_by_record(uchar *record) { @@ -1467,6 +1469,12 @@ public: { return HA_ERR_WRONG_COMMAND; } virtual ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key) { return (ha_rows) 10; } + /* + If HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is set, then it sets ref + (reference to the row, aka position, with the primary key given in + the record). + Otherwise it set ref to the current row. + */ virtual void position(const uchar *record)=0; virtual int info(uint)=0; // see my_base.h for full description virtual void get_dynamic_partition_info(PARTITION_INFO *stat_info, From cd37b73fe5107098c669fcbf569e9f20de013141 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 9 Jul 2010 08:37:51 -0300 Subject: [PATCH 096/112] Bug#53445: Build with -Wall and fix warnings that it generates Introduce a MySQL maintainer/developer mode that enables a set of warning options for the C/C++ compiler. This mode is intended to help improve the overall quality of the code. The warning options are: C_WARNINGS="-Wall -Wextra -Wunused -Wwrite-strings -Werror" CXX_WARNINGS="$C_WARNINGS -Wno-unused-parameter" Since -Wall is essentially a moving target, autoconf checks are not run with warning options enabled, in particualr -Werror. This decision might be revisited in the future. The patch also fixes a mistake in the makefiles, where automake CXXFLAGS would be set to CFLAGS. config/ac-macros/maintainer.m4: Add a set of default compiler flags used when in maintainer mode. configure.in: Hook into the maintainer mode. Disabled by default. --- config/ac-macros/maintainer.m4 | 66 +++++++++++++++++++++++++++++++ configure.in | 9 +++++ plugin/daemon_example/Makefile.am | 4 +- storage/archive/Makefile.am | 4 +- storage/blackhole/Makefile.am | 4 +- storage/csv/Makefile.am | 4 +- storage/example/Makefile.am | 4 +- storage/federated/Makefile.am | 4 +- storage/ibmdb2i/Makefile.am | 4 +- storage/innobase/Makefile.am | 4 +- storage/innodb_plugin/Makefile.am | 4 +- 11 files changed, 93 insertions(+), 18 deletions(-) create mode 100644 config/ac-macros/maintainer.m4 diff --git a/config/ac-macros/maintainer.m4 b/config/ac-macros/maintainer.m4 new file mode 100644 index 00000000000..6aa1d166f2a --- /dev/null +++ b/config/ac-macros/maintainer.m4 @@ -0,0 +1,66 @@ +# +# Control aspects of the development environment which are +# specific to MySQL maintainers and developers. +# +AC_DEFUN([MY_MAINTAINER_MODE], [ + AC_MSG_CHECKING([whether to enable the maintainer-specific development environment]) + AC_ARG_ENABLE([mysql-maintainer-mode], + [AS_HELP_STRING([--enable-mysql-maintainer-mode], + [Enable a MySQL maintainer-specific development environment])], + [USE_MYSQL_MAINTAINER_MODE=$enableval], + [USE_MYSQL_MAINTAINER_MODE=no]) + AC_MSG_RESULT([$USE_MYSQL_MAINTAINER_MODE]) +]) + +# Set warning options required under maintainer mode. +AC_DEFUN([MY_MAINTAINER_MODE_WARNINGS], [ + # Setup GCC warning options. + AS_IF([test "$GCC" = "yes"], [ + C_WARNINGS="-Wall -Wextra -Wunused -Wwrite-strings -Werror" + CXX_WARNINGS="${C_WARNINGS} -Wno-unused-parameter" + ]) + + # Test whether the warning options work. + # Test C options + AS_IF([test -n "$C_WARNINGS"], [ + save_CFLAGS="$CFLAGS" + AC_MSG_CHECKING([whether to use C warning options ${C_WARNINGS}]) + AC_LANG_PUSH(C) + CFLAGS="$CFLAGS ${C_WARNINGS}" + AC_LANG_WERROR + AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], [myac_c_warning_flags=yes], + [myac_c_warning_flags=no]) + AC_LANG_POP() + AC_MSG_RESULT([$myac_c_warning_flags]) + CFLAGS="$save_CFLAGS" + ]) + + # Test C++ options + AS_IF([test -n "$CXX_WARNINGS"], [ + save_CXXFLAGS="$CXXFLAGS" + AC_MSG_CHECKING([whether to use C++ warning options ${CXX_WARNINGS}]) + AC_LANG_PUSH(C++) + CXXFLAGS="$CXXFLAGS ${CXX_WARNINGS}" + AC_LANG_WERROR + AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], [myac_cxx_warning_flags=yes], + [myac_cxx_warning_flags=no]) + AC_LANG_POP() + AC_MSG_RESULT([$myac_cxx_warning_flags]) + CXXFLAGS="$save_CXXFLAGS" + ]) + + # Set compile flag variables. + AS_IF([test "$myac_c_warning_flags" = "yes"], [ + AM_CFLAGS="${AM_CFLAGS} ${C_WARNINGS}" + AC_SUBST([AM_CFLAGS])]) + AS_IF([test "$myac_cxx_warning_flags" = "yes"], [ + AM_CXXFLAGS="${AM_CXXFLAGS} ${CXX_WARNINGS}" + AC_SUBST([AM_CXXFLAGS])]) +]) + + +# Set compiler flags required under maintainer mode. +AC_DEFUN([MY_MAINTAINER_MODE_SETUP], [ + AS_IF([test "$USE_MYSQL_MAINTAINER_MODE" = "yes"], + [MY_MAINTAINER_MODE_WARNINGS]) +]) diff --git a/configure.in b/configure.in index d47bf975fdd..bc1d7df6703 100644 --- a/configure.in +++ b/configure.in @@ -65,6 +65,7 @@ MYSQL_TCP_PORT_DEFAULT=3306 MYSQL_UNIX_ADDR_DEFAULT="/tmp/mysql.sock" dnl Include m4 +sinclude(config/ac-macros/maintainer.m4) sinclude(config/ac-macros/alloca.m4) sinclude(config/ac-macros/check_cpu.m4) sinclude(config/ac-macros/character_sets.m4) @@ -102,6 +103,8 @@ AC_SUBST(SHARED_LIB_MAJOR_VERSION) AC_SUBST(SHARED_LIB_VERSION) AC_SUBST(AVAILABLE_LANGUAGES) +# Whether the maintainer mode should be enabled. +MY_MAINTAINER_MODE # Canonicalize the configuration name. @@ -2889,6 +2892,12 @@ do done AC_SUBST(sql_union_dirs) +# +# Setup maintainer mode options by the end to not disturb +# system and other checks. +# +MY_MAINTAINER_MODE_SETUP + # Some usefull subst AC_SUBST(CC) AC_SUBST(GXX) diff --git a/plugin/daemon_example/Makefile.am b/plugin/daemon_example/Makefile.am index c5414cd46c7..02310699396 100644 --- a/plugin/daemon_example/Makefile.am +++ b/plugin/daemon_example/Makefile.am @@ -27,14 +27,14 @@ INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \ EXTRA_LTLIBRARIES = libdaemon_example.la pkgplugin_LTLIBRARIES = @plugin_daemon_example_shared_target@ libdaemon_example_la_LDFLAGS = -module -rpath $(pkgplugindir) -libdaemon_example_la_CXXFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN +libdaemon_example_la_CXXFLAGS= $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN libdaemon_example_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN libdaemon_example_la_SOURCES = daemon_example.cc EXTRA_LIBRARIES = libdaemon_example.a noinst_LIBRARIES = @plugin_daemon_example_static_target@ -libdaemon_example_a_CXXFLAGS = $(AM_CFLAGS) +libdaemon_example_a_CXXFLAGS = $(AM_CXXFLAGS) libdaemon_example_a_CFLAGS = $(AM_CFLAGS) libdaemon_example_a_SOURCES= daemon_example.cc diff --git a/storage/archive/Makefile.am b/storage/archive/Makefile.am index d092f091798..94e98c468ad 100644 --- a/storage/archive/Makefile.am +++ b/storage/archive/Makefile.am @@ -36,14 +36,14 @@ noinst_PROGRAMS = archive_test archive_reader EXTRA_LTLIBRARIES = ha_archive.la pkgplugin_LTLIBRARIES = @plugin_archive_shared_target@ ha_archive_la_LDFLAGS = -module -rpath $(pkgplugindir) -ha_archive_la_CXXFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN +ha_archive_la_CXXFLAGS= $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN ha_archive_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN ha_archive_la_SOURCES = ha_archive.cc azio.c EXTRA_LIBRARIES = libarchive.a noinst_LIBRARIES = @plugin_archive_static_target@ -libarchive_a_CXXFLAGS = $(AM_CFLAGS) +libarchive_a_CXXFLAGS = $(AM_CXXFLAGS) libarchive_a_CFLAGS = $(AM_CFLAGS) libarchive_a_SOURCES = ha_archive.cc azio.c diff --git a/storage/blackhole/Makefile.am b/storage/blackhole/Makefile.am index db4f67cf847..2d27261b671 100644 --- a/storage/blackhole/Makefile.am +++ b/storage/blackhole/Makefile.am @@ -35,14 +35,14 @@ noinst_HEADERS = ha_blackhole.h EXTRA_LTLIBRARIES = ha_blackhole.la pkgplugin_LTLIBRARIES = @plugin_blackhole_shared_target@ ha_blackhole_la_LDFLAGS=-module -rpath $(pkgplugindir) -ha_blackhole_la_CXXFLAGS=$(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN +ha_blackhole_la_CXXFLAGS=$(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN ha_blackhole_la_CFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN ha_blackhole_la_SOURCES=ha_blackhole.cc EXTRA_LIBRARIES = libblackhole.a noinst_LIBRARIES = @plugin_blackhole_static_target@ -libblackhole_a_CXXFLAGS=$(AM_CFLAGS) +libblackhole_a_CXXFLAGS=$(AM_CXXFLAGS) libblackhole_a_CFLAGS = $(AM_CFLAGS) libblackhole_a_SOURCES= ha_blackhole.cc diff --git a/storage/csv/Makefile.am b/storage/csv/Makefile.am index 07ffac88a96..3a00ae85e20 100644 --- a/storage/csv/Makefile.am +++ b/storage/csv/Makefile.am @@ -32,12 +32,12 @@ noinst_HEADERS = ha_tina.h transparent_file.h EXTRA_LTLIBRARIES = ha_csv.la pkglib_LTLIBRARIES = @plugin_csv_shared_target@ ha_csv_la_LDFLAGS = -module -rpath $(MYSQLLIBdir) -ha_csv_la_CXXFLAGS = $(AM_CFLAGS) -DMYSQL_PLUGIN +ha_csv_la_CXXFLAGS = $(AM_CXXFLAGS) -DMYSQL_PLUGIN ha_csv_la_SOURCES = transparent_file.cc ha_tina.cc EXTRA_LIBRARIES = libcsv.a noinst_LIBRARIES = @plugin_csv_static_target@ -libcsv_a_CXXFLAGS = $(AM_CFLAGS) +libcsv_a_CXXFLAGS = $(AM_CXXFLAGS) libcsv_a_SOURCES = transparent_file.cc ha_tina.cc EXTRA_DIST = CMakeLists.txt plug.in diff --git a/storage/example/Makefile.am b/storage/example/Makefile.am index 4b2f165377c..1c87adbbb4c 100644 --- a/storage/example/Makefile.am +++ b/storage/example/Makefile.am @@ -35,14 +35,14 @@ noinst_HEADERS = ha_example.h EXTRA_LTLIBRARIES = ha_example.la pkgplugin_LTLIBRARIES = @plugin_example_shared_target@ ha_example_la_LDFLAGS = -module -rpath $(pkgplugindir) -ha_example_la_CXXFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN +ha_example_la_CXXFLAGS= $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN ha_example_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN ha_example_la_SOURCES = ha_example.cc EXTRA_LIBRARIES = libexample.a noinst_LIBRARIES = @plugin_example_static_target@ -libexample_a_CXXFLAGS = $(AM_CFLAGS) +libexample_a_CXXFLAGS = $(AM_CXXFLAGS) libexample_a_CFLAGS = $(AM_CFLAGS) libexample_a_SOURCES= ha_example.cc diff --git a/storage/federated/Makefile.am b/storage/federated/Makefile.am index 64ea0207017..eab8c0c3929 100644 --- a/storage/federated/Makefile.am +++ b/storage/federated/Makefile.am @@ -35,14 +35,14 @@ noinst_HEADERS = ha_federated.h EXTRA_LTLIBRARIES = ha_federated.la pkgplugin_LTLIBRARIES = @plugin_federated_shared_target@ ha_federated_la_LDFLAGS = -module -rpath $(pkgplugindir) -ha_federated_la_CXXFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN +ha_federated_la_CXXFLAGS= $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN ha_federated_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN ha_federated_la_SOURCES = ha_federated.cc EXTRA_LIBRARIES = libfederated.a noinst_LIBRARIES = @plugin_federated_static_target@ -libfederated_a_CXXFLAGS = $(AM_CFLAGS) +libfederated_a_CXXFLAGS = $(AM_CXXFLAGS) libfederated_a_CFLAGS = $(AM_CFLAGS) libfederated_a_SOURCES= ha_federated.cc diff --git a/storage/ibmdb2i/Makefile.am b/storage/ibmdb2i/Makefile.am index 768ca15f4cf..b9602e392e0 100644 --- a/storage/ibmdb2i/Makefile.am +++ b/storage/ibmdb2i/Makefile.am @@ -34,7 +34,7 @@ EXTRA_LTLIBRARIES = ha_ibmdb2i.la pkgplugin_LTLIBRARIES = @plugin_ibmdb2i_shared_target@ ha_ibmdb2i_la_LIBADD = -liconv ha_ibmdb2i_la_LDFLAGS = -module -rpath $(MYSQLLIBdir) -ha_ibmdb2i_la_CXXFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN +ha_ibmdb2i_la_CXXFLAGS= $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN ha_ibmdb2i_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN ha_ibmdb2i_la_SOURCES = ha_ibmdb2i.cc db2i_ileBridge.cc db2i_conversion.cc \ db2i_blobCollection.cc db2i_file.cc db2i_charsetSupport.cc \ @@ -44,7 +44,7 @@ ha_ibmdb2i_la_SOURCES = ha_ibmdb2i.cc db2i_ileBridge.cc db2i_conversion.cc \ EXTRA_LIBRARIES = libibmdb2i.a noinst_LIBRARIES = @plugin_ibmdb2i_static_target@ -libibmdb2i_a_CXXFLAGS = $(AM_CFLAGS) +libibmdb2i_a_CXXFLAGS = $(AM_CXXFLAGS) libibmdb2i_a_CFLAGS = $(AM_CFLAGS) libibmdb2i_a_SOURCES= $(ha_ibmdb2i_la_SOURCES) diff --git a/storage/innobase/Makefile.am b/storage/innobase/Makefile.am index a597e3c24e4..2c93a3a409a 100644 --- a/storage/innobase/Makefile.am +++ b/storage/innobase/Makefile.am @@ -156,14 +156,14 @@ libinnobase_a_SOURCES= btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c \ ut/ut0ut.c ut/ut0vec.c ut/ut0wqueue.c \ handler/ha_innodb.cc -libinnobase_a_CXXFLAGS= $(AM_CFLAGS) +libinnobase_a_CXXFLAGS= $(AM_CXXFLAGS) libinnobase_a_CFLAGS= $(AM_CFLAGS) EXTRA_LTLIBRARIES= ha_innodb.la pkgplugin_LTLIBRARIES= @plugin_innobase_shared_target@ ha_innodb_la_LDFLAGS= -module -rpath $(pkgplugindir) -ha_innodb_la_CXXFLAGS= $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS) +ha_innodb_la_CXXFLAGS= $(AM_CXXFLAGS) $(INNODB_DYNAMIC_CFLAGS) ha_innodb_la_CFLAGS= $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS) ha_innodb_la_SOURCES= $(libinnobase_a_SOURCES) diff --git a/storage/innodb_plugin/Makefile.am b/storage/innodb_plugin/Makefile.am index 1d0dd936895..f11e5db01f4 100644 --- a/storage/innodb_plugin/Makefile.am +++ b/storage/innodb_plugin/Makefile.am @@ -325,14 +325,14 @@ libinnobase_a_SOURCES= \ ut/ut0vec.c \ ut/ut0wqueue.c -libinnobase_a_CXXFLAGS= $(AM_CFLAGS) +libinnobase_a_CXXFLAGS= $(AM_CXXFLAGS) libinnobase_a_CFLAGS= $(AM_CFLAGS) EXTRA_LTLIBRARIES= ha_innodb_plugin.la pkgplugin_LTLIBRARIES= @plugin_innodb_plugin_shared_target@ ha_innodb_plugin_la_LDFLAGS= -module -rpath $(pkgplugindir) -ha_innodb_plugin_la_CXXFLAGS= $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS) +ha_innodb_plugin_la_CXXFLAGS= $(AM_CXXFLAGS) $(INNODB_DYNAMIC_CFLAGS) ha_innodb_plugin_la_CFLAGS= $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS) ha_innodb_plugin_la_SOURCES= $(libinnobase_a_SOURCES) From 11fae04527098cb6c266eae41188504bd22a5b52 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 9 Jul 2010 09:00:17 -0300 Subject: [PATCH 097/112] Bug#45288: pb2 returns a lot of compilation warnings on linux Although the C standard mandates that sprintf return the number of bytes written, some very ancient systems (i.e. SunOS 4) returned a pointer to the buffer instead. Since these systems are not supported anymore and are hopefully long dead by now, simply remove the portability wrapper that dealt with this discrepancy. The autoconf check was causing trouble with GCC. --- client/mysqlbinlog.cc | 2 +- client/mysqlcheck.c | 3 +-- client/sql_string.cc | 5 +++-- configure.in | 34 ------------------------------- include/my_global.h | 11 ---------- sql-common/my_time.c | 23 +++++++-------------- sql/field.cc | 10 ++++----- sql/item_timefunc.cc | 24 ++++++++-------------- sql/log_event.cc | 32 ++++++++++++++--------------- sql/my_decimal.cc | 8 ++++---- sql/partition_info.cc | 6 +++--- sql/protocol.cc | 24 ++++++++-------------- sql/sql_acl.cc | 10 ++++----- sql/sql_analyse.cc | 10 ++++----- sql/sql_show.cc | 2 +- sql/sql_string.cc | 5 +++-- storage/federated/ha_federated.cc | 17 ++++++---------- strings/decimal.c | 2 +- tests/mysql_client_test.c | 26 +++++++++++------------ 19 files changed, 90 insertions(+), 164 deletions(-) diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 30bdb58153f..dec3f142798 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -437,7 +437,7 @@ Exit_status Load_log_processor::process_first_event(const char *bname, ptr= fname + target_dir_name_len; memcpy(ptr,bname,blen); ptr+= blen; - ptr+= my_sprintf(ptr, (ptr, "-%x", file_id)); + ptr+= sprintf(ptr, "-%x", file_id); if ((file= create_unique_file(fname,ptr)) < 0) { diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 4183ab1dd5e..78c4b79085e 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -703,8 +703,7 @@ static int handle_request_for_tables(char *tables, uint length) if (opt_all_in_1) { /* No backticks here as we added them before */ - query_length= my_sprintf(query, - (query, "%s TABLE %s %s", op, tables, options)); + query_length= sprintf(query, "%s TABLE %s %s", op, tables, options); } else { diff --git a/client/sql_string.cc b/client/sql_string.cc index dc6147b563f..50fb4a5b777 100644 --- a/client/sql_string.cc +++ b/client/sql_string.cc @@ -122,7 +122,8 @@ bool String::set(double num,uint decimals, CHARSET_INFO *cs) str_charset=cs; if (decimals >= NOT_FIXED_DEC) { - uint32 len= my_sprintf(buff,(buff, "%.15g",num));// Enough for a DATETIME + // Enough for a DATETIME + uint32 len= sprintf(buff, "%.15g", num); return copy(buff, len, &my_charset_latin1, cs, &dummy_errors); } #ifdef HAVE_FCONVERT @@ -674,7 +675,7 @@ void String::qs_append(const char *str, uint32 len) void String::qs_append(double d) { char *buff = Ptr + str_length; - str_length+= my_sprintf(buff, (buff, "%.15g", d)); + str_length+= sprintf(buff, buff, "%.15g", d); } void String::qs_append(double *d) diff --git a/configure.in b/configure.in index bc1d7df6703..0264c351b07 100644 --- a/configure.in +++ b/configure.in @@ -278,40 +278,6 @@ AC_CHECK_PROGS(YACC, ['bison -y -p MYSQL']) AC_CHECK_PROG(PDFMANUAL, pdftex, manual.pdf) AC_CHECK_PROG(DVIS, tex, manual.dvi) -#check the return type of sprintf -AC_MSG_CHECKING("return type of sprintf") -AC_TRY_RUN([ - int main() - { - char* s = "hello"; - char buf[6]; - if((int)sprintf(buf, s) == strlen(s)) - return 0; - - return -1; - } - ], - [AC_DEFINE(SPRINTF_RETURNS_INT, [1], [POSIX sprintf]) - AC_MSG_RESULT("int")], - [AC_TRY_RUN([ - int main() - { - char* s = "hello"; - char buf[6]; - if((char*)sprintf(buf,s) == buf + strlen(s)) - return 0; - return -1; - } ], - [AC_DEFINE(SPRINTF_RETURNS_PTR, [1], [Broken sprintf]) - AC_MSG_RESULT("ptr")], - [AC_DEFINE(SPRINTF_RETURNS_GARBAGE, [1], [Broken sprintf]) - AC_MSG_RESULT("garbage")] - )], - # Cross compile, assume POSIX - [AC_DEFINE(SPRINTF_RETURNS_INT, [1], [POSIX sprintf]) - AC_MSG_RESULT("int (we assume)")] -) - AC_PATH_PROG(uname_prog, uname, no) # We should go through this and put all the explictly system dependent diff --git a/include/my_global.h b/include/my_global.h index 572df6a584d..f03ed665d5a 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -1467,17 +1467,6 @@ do { doubleget_union _tmp; \ #endif /* WORDS_BIGENDIAN */ -/* sprintf does not always return the number of bytes :- */ -#ifdef SPRINTF_RETURNS_INT -#define my_sprintf(buff,args) sprintf args -#else -#ifdef SPRINTF_RETURNS_PTR -#define my_sprintf(buff,args) ((int)(sprintf args - buff)) -#else -#define my_sprintf(buff,args) ((ulong) sprintf args, (ulong) strlen(buff)) -#endif -#endif - #ifndef THREAD #define thread_safe_increment(V,L) (V)++ #define thread_safe_decrement(V,L) (V)-- diff --git a/sql-common/my_time.c b/sql-common/my_time.c index 95078a50097..c4e917801d5 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -1024,30 +1024,21 @@ void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type) int my_time_to_str(const MYSQL_TIME *l_time, char *to) { uint extra_hours= 0; - return my_sprintf(to, (to, "%s%02u:%02u:%02u", - (l_time->neg ? "-" : ""), - extra_hours+ l_time->hour, - l_time->minute, - l_time->second)); + return sprintf(to, "%s%02u:%02u:%02u", (l_time->neg ? "-" : ""), + extra_hours+ l_time->hour, l_time->minute, l_time->second); } int my_date_to_str(const MYSQL_TIME *l_time, char *to) { - return my_sprintf(to, (to, "%04u-%02u-%02u", - l_time->year, - l_time->month, - l_time->day)); + return sprintf(to, "%04u-%02u-%02u", + l_time->year, l_time->month, l_time->day); } int my_datetime_to_str(const MYSQL_TIME *l_time, char *to) { - return my_sprintf(to, (to, "%04u-%02u-%02u %02u:%02u:%02u", - l_time->year, - l_time->month, - l_time->day, - l_time->hour, - l_time->minute, - l_time->second)); + return sprintf(to, "%04u-%02u-%02u %02u:%02u:%02u", + l_time->year, l_time->month, l_time->day, + l_time->hour, l_time->minute, l_time->second); } diff --git a/sql/field.cc b/sql/field.cc index 2229bc19b3c..c648b53e139 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2277,7 +2277,7 @@ int Field_decimal::store(double nr) snprintf(buff,sizeof(buff)-1, "%.*f",(int) dec,nr); length= strlen(buff); #else - length= my_sprintf(buff,(buff,"%.*f",dec,nr)); + length= sprintf(buff, "%.*f", dec, nr); #endif if (length > field_length) @@ -4259,7 +4259,7 @@ String *Field_float::val_str(String *val_buffer, snprintf(to,to_length-1,"%.*f",dec,nr); to=strend(to); #else - to+= my_sprintf(to,(to,"%.*f",dec,nr)); + to+= sprintf(to, "%.*f", dec, nr); #endif #endif } @@ -4617,7 +4617,7 @@ String *Field_double::val_str(String *val_buffer, snprintf(to,to_length-1,"%.*f",dec,nr); to=strend(to); #else - to+= my_sprintf(to,(to,"%.*f",dec,nr)); + to+= sprintf(to, "%.*f", dec, nr); #endif #endif } @@ -6461,7 +6461,7 @@ int Field_str::store(double nr) /* Limit precision to DBL_DIG to avoid garbage past significant digits */ set_if_smaller(digits, DBL_DIG); - length= (uint) my_sprintf(buff, (buff, "%-.*g", digits, nr)); + length= (uint) sprintf(buff, "%-.*g", digits, nr); #ifdef __WIN__ /* @@ -10419,7 +10419,7 @@ Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level, uint code, { /* DBL_DIG is enough to print '-[digits].E+###' */ char str_nr[DBL_DIG + 8]; - uint str_len= my_sprintf(str_nr, (str_nr, "%g", nr)); + uint str_len= sprintf(str_nr, "%g", nr); make_truncated_value_warning(thd, level, str_nr, str_len, ts_type, field_name); } diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 4248c2e6b4f..dff4d20f347 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -754,13 +754,11 @@ bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time, str->append(hours_i < 12 ? "AM" : "PM",2); break; case 'r': - length= my_sprintf(intbuff, - (intbuff, - ((l_time->hour % 24) < 12) ? - "%02d:%02d:%02d AM" : "%02d:%02d:%02d PM", - (l_time->hour+11)%12+1, - l_time->minute, - l_time->second)); + length= sprintf(intbuff, ((l_time->hour % 24) < 12) ? + "%02d:%02d:%02d AM" : "%02d:%02d:%02d PM", + (l_time->hour+11)%12+1, + l_time->minute, + l_time->second); str->append(intbuff, length); break; case 'S': @@ -769,12 +767,8 @@ bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time, str->append_with_prefill(intbuff, length, 2, '0'); break; case 'T': - length= my_sprintf(intbuff, - (intbuff, - "%02d:%02d:%02d", - l_time->hour, - l_time->minute, - l_time->second)); + length= sprintf(intbuff, "%02d:%02d:%02d", + l_time->hour, l_time->minute, l_time->second); str->append(intbuff, length); break; case 'U': @@ -2985,12 +2979,12 @@ String *Item_func_maketime::val_str(String *str) char buf[28]; char *ptr= longlong10_to_str(hour, buf, args[0]->unsigned_flag ? 10 : -10); int len = (int)(ptr - buf) + - my_sprintf(ptr, (ptr, ":%02u:%02u", (uint)minute, (uint)second)); + sprintf(ptr, ":%02u:%02u", (uint) minute, (uint) second); make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, buf, len, MYSQL_TIMESTAMP_TIME, NullS); } - + if (make_time_with_warn((DATE_TIME_FORMAT *) 0, <ime, str)) { null_value= 1; diff --git a/sql/log_event.cc b/sql/log_event.cc index 93d170e1510..7becdf51747 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1664,17 +1664,17 @@ beg: int i, end; char buff[512], *pos; pos= buff; - pos+= my_sprintf(buff, (buff, "%s", dec.sign() ? "-" : "")); + pos+= sprintf(buff, "%s", dec.sign() ? "-" : ""); end= ROUND_UP(dec.frac) + ROUND_UP(dec.intg)-1; for (i=0; i < end; i++) - pos+= my_sprintf(pos, (pos, "%09d.", dec.buf[i])); - pos+= my_sprintf(pos, (pos, "%09d", dec.buf[i])); + pos+= sprintf(pos, "%09d.", dec.buf[i]); + pos+= sprintf(pos, "%09d", dec.buf[i]); my_b_printf(file, "%s", buff); my_snprintf(typestr, typestr_length, "DECIMAL(%d,%d)", precision, decimals); return bin_size; } - + case MYSQL_TYPE_FLOAT: { float fl; @@ -5481,8 +5481,7 @@ void User_var_log_event::pack_info(Protocol* protocol) if (!(buf= (char*) my_malloc(val_offset + FLOATING_POINT_BUFFER, MYF(MY_WME)))) return; - event_len+= my_sprintf(buf + val_offset, - (buf + val_offset, "%.14g", real_val)); + event_len+= sprintf(buf + val_offset, "%.14g", real_val); break; case INT_RESULT: if (!(buf= (char*) my_malloc(val_offset + 22, MYF(MY_WME)))) @@ -5664,7 +5663,7 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info) double real_val; char real_buf[FMT_G_BUFSIZE(14)]; float8get(real_val, val); - my_sprintf(real_buf, (real_buf, "%.14g", real_val)); + sprintf(real_buf, "%.14g", real_val); my_b_printf(&cache, ":=%s%s\n", real_buf, print_event_info->delimiter); break; case INT_RESULT: @@ -6414,10 +6413,9 @@ void Append_block_log_event::print(FILE* file, void Append_block_log_event::pack_info(Protocol *protocol) { char buf[256]; - uint length; - length= (uint) my_sprintf(buf, - (buf, ";file_id=%u;block_len=%u", file_id, - block_len)); + size_t length; + length= my_snprintf(buf, sizeof(buf), ";file_id=%u;block_len=%u", + file_id, block_len); protocol->store(buf, length, &my_charset_bin); } @@ -6566,9 +6564,9 @@ void Delete_file_log_event::print(FILE* file, void Delete_file_log_event::pack_info(Protocol *protocol) { char buf[64]; - uint length; - length= (uint) my_sprintf(buf, (buf, ";file_id=%u", (uint) file_id)); - protocol->store(buf, (int32) length, &my_charset_bin); + size_t length; + length= my_snprintf(buf, sizeof(buf), ";file_id=%u", (uint) file_id); + protocol->store(buf, length, &my_charset_bin); } #endif @@ -6664,9 +6662,9 @@ void Execute_load_log_event::print(FILE* file, void Execute_load_log_event::pack_info(Protocol *protocol) { char buf[64]; - uint length; - length= (uint) my_sprintf(buf, (buf, ";file_id=%u", (uint) file_id)); - protocol->store(buf, (int32) length, &my_charset_bin); + size_t length; + length= my_snprintf(buf, sizeof(buf), ";file_id=%u", (uint) file_id); + protocol->store(buf, length, &my_charset_bin); } diff --git a/sql/my_decimal.cc b/sql/my_decimal.cc index 208ddefb890..3aa01880b83 100644 --- a/sql/my_decimal.cc +++ b/sql/my_decimal.cc @@ -249,12 +249,12 @@ print_decimal(const my_decimal *dec) int i, end; char buff[512], *pos; pos= buff; - pos+= my_sprintf(buff, (buff, "Decimal: sign: %d intg: %d frac: %d { ", - dec->sign(), dec->intg, dec->frac)); + pos+= sprintf(buff, "Decimal: sign: %d intg: %d frac: %d { ", + dec->sign(), dec->intg, dec->frac); end= ROUND_UP(dec->frac)+ROUND_UP(dec->intg)-1; for (i=0; i < end; i++) - pos+= my_sprintf(pos, (pos, "%09d, ", dec->buf[i])); - pos+= my_sprintf(pos, (pos, "%09d }\n", dec->buf[i])); + pos+= sprintf(pos, "%09d, ", dec->buf[i]); + pos+= sprintf(pos, "%09d }\n", dec->buf[i]); fputs(buff, DBUG_FILE); } diff --git a/sql/partition_info.cc b/sql/partition_info.cc index 6e2f7dfad26..d85888e295c 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -103,8 +103,8 @@ char *partition_info::create_default_partition_names(uint part_no, { do { - my_sprintf(move_ptr, (move_ptr,"p%u", (start_no + i))); - move_ptr+=MAX_PART_NAME_SIZE; + sprintf(move_ptr, "p%u", (start_no + i)); + move_ptr+= MAX_PART_NAME_SIZE; } while (++i < no_parts_arg); } else @@ -135,7 +135,7 @@ char *partition_info::create_subpartition_name(uint subpart_no, if (likely(ptr != NULL)) { - my_sprintf(ptr, (ptr, "%ssp%u", part_name, subpart_no)); + my_snprintf(ptr, size_alloc, "%ssp%u", part_name, subpart_no); } else { diff --git a/sql/protocol.cc b/sql/protocol.cc index dc53e029647..eaf01ecd550 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -1003,16 +1003,12 @@ bool Protocol_text::store(MYSQL_TIME *tm) #endif char buff[40]; uint length; - length= my_sprintf(buff,(buff, "%04d-%02d-%02d %02d:%02d:%02d", - (int) tm->year, - (int) tm->month, - (int) tm->day, - (int) tm->hour, - (int) tm->minute, - (int) tm->second)); + length= sprintf(buff, "%04d-%02d-%02d %02d:%02d:%02d", + (int) tm->year, (int) tm->month, + (int) tm->day, (int) tm->hour, + (int) tm->minute, (int) tm->second); if (tm->second_part) - length+= my_sprintf(buff+length,(buff+length, ".%06d", - (int)tm->second_part)); + length+= sprintf(buff+length, ".%06d", (int) tm->second_part); return net_store_data((uchar*) buff, length); } @@ -1046,13 +1042,11 @@ bool Protocol_text::store_time(MYSQL_TIME *tm) char buff[40]; uint length; uint day= (tm->year || tm->month) ? 0 : tm->day; - length= my_sprintf(buff,(buff, "%s%02ld:%02d:%02d", - tm->neg ? "-" : "", - (long) day*24L+(long) tm->hour, - (int) tm->minute, - (int) tm->second)); + length= sprintf(buff, "%s%02ld:%02d:%02d", tm->neg ? "-" : "", + (long) day*24L+(long) tm->hour, (int) tm->minute, + (int) tm->second); if (tm->second_part) - length+= my_sprintf(buff+length,(buff+length, ".%06d", (int)tm->second_part)); + length+= sprintf(buff+length, ".%06d", (int) tm->second_part); return net_store_data((uchar*) buff, length); } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 9640b8db1b2..90eef872115 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1653,12 +1653,10 @@ bool change_password(THD *thd, const char *host, const char *user, result= 0; if (mysql_bin_log.is_open()) { - query_length= - my_sprintf(buff, - (buff,"SET PASSWORD FOR '%-.120s'@'%-.120s'='%-.120s'", - acl_user->user ? acl_user->user : "", - acl_user->host.hostname ? acl_user->host.hostname : "", - new_password)); + query_length= sprintf(buff, "SET PASSWORD FOR '%-.120s'@'%-.120s'='%-.120s'", + acl_user->user ? acl_user->user : "", + acl_user->host.hostname ? acl_user->host.hostname : "", + new_password); thd->clear_error(); result= thd->binlog_query(THD::MYSQL_QUERY_TYPE, buff, query_length, FALSE, FALSE, 0); diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index d273b3319ee..29ba956bf6c 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -408,7 +408,7 @@ void field_real::add() if ((decs = decimals()) == NOT_FIXED_DEC) { - length= my_sprintf(buff, (buff, "%g", num)); + length= sprintf(buff, "%g", num); if (rint(num) != num) max_notzero_dec_len = 1; } @@ -419,7 +419,7 @@ void field_real::add() snprintf(buff, sizeof(buff)-1, "%-.*f", (int) decs, num); length = (uint) strlen(buff); #else - length= my_sprintf(buff, (buff, "%-.*f", (int) decs, num)); + length= sprintf(buff, "%-.*f", (int) decs, num); #endif // We never need to check further than this @@ -1006,9 +1006,9 @@ void field_decimal::get_opt_type(String *answer, my_decimal_set_zero(&zero); my_bool is_unsigned= (my_decimal_cmp(&zero, &min_arg) >= 0); - length= my_sprintf(buff, (buff, "DECIMAL(%d, %d)", - (int) (max_length - (item->decimals ? 1 : 0)), - item->decimals)); + length= my_snprintf(buff, sizeof(buff), "DECIMAL(%d, %d)", + (int) (max_length - (item->decimals ? 1 : 0)), + item->decimals); if (is_unsigned) length= (uint) (strmov(buff+length, " UNSIGNED")- buff); answer->append(buff, length); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 17fbf62b097..ca0d16697cd 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2278,7 +2278,7 @@ static bool show_status_array(THD *thd, const char *wild, value= ((char *) status_var + (ulong) value); /* fall through */ case SHOW_DOUBLE: - end= buff + my_sprintf(buff, (buff, "%f", *(double*) value)); + end= buff + sprintf(buff, "%f", *(double*) value); break; case SHOW_LONG_STATUS: value= ((char *) status_var + (ulong) value); diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 7c9793b273b..a41f4d52101 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -112,7 +112,8 @@ bool String::set_real(double num,uint decimals, CHARSET_INFO *cs) str_charset=cs; if (decimals >= NOT_FIXED_DEC) { - uint32 len= my_sprintf(buff,(buff, "%.15g",num));// Enough for a DATETIME + // Enough for a DATETIME + uint32 len= sprintf(buff, "%.15g", num); return copy(buff, len, &my_charset_latin1, cs, &dummy_errors); } #ifdef HAVE_FCONVERT @@ -676,7 +677,7 @@ void String::qs_append(const char *str, uint32 len) void String::qs_append(double d) { char *buff = Ptr + str_length; - str_length+= my_sprintf(buff, (buff, "%.15g", d)); + str_length+= sprintf(buff, "%.15g", d); } void String::qs_append(double *d) diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc index 955c35ad71b..e881b253274 100644 --- a/storage/federated/ha_federated.cc +++ b/storage/federated/ha_federated.cc @@ -561,7 +561,6 @@ static int parse_url_error(FEDERATED_SHARE *share, TABLE *table, int error_num) int get_connection(MEM_ROOT *mem_root, FEDERATED_SHARE *share) { int error_num= ER_FOREIGN_SERVER_DOESNT_EXIST; - char error_buffer[FEDERATED_QUERY_BUFFER_SIZE]; FOREIGN_SERVER *server, server_buffer; DBUG_ENTER("ha_federated::get_connection"); @@ -613,10 +612,8 @@ int get_connection(MEM_ROOT *mem_root, FEDERATED_SHARE *share) DBUG_RETURN(0); error: - my_sprintf(error_buffer, - (error_buffer, "server name: '%s' doesn't exist!", - share->connection_string)); - my_error(error_num, MYF(0), error_buffer); + my_printf_error(error_num, "server name: '%s' doesn't exist!", + MYF(0), share->connection_string); DBUG_RETURN(error_num); } @@ -2405,8 +2402,8 @@ int ha_federated::index_read_idx_with_result_set(uchar *buf, uint index, if (real_query(sql_query.ptr(), sql_query.length())) { - my_sprintf(error_buffer, (error_buffer, "error: %d '%s'", - mysql_errno(mysql), mysql_error(mysql))); + sprintf(error_buffer, "error: %d '%s'", + mysql_errno(mysql), mysql_error(mysql)); retval= ER_QUERY_ON_FOREIGN_DATA_SOURCE; goto error; } @@ -2775,7 +2772,6 @@ int ha_federated::rnd_pos(uchar *buf, uchar *pos) int ha_federated::info(uint flag) { - char error_buffer[FEDERATED_QUERY_BUFFER_SIZE]; char status_buf[FEDERATED_QUERY_BUFFER_SIZE]; int error; uint error_code; @@ -2859,9 +2855,8 @@ error: mysql_free_result(result); if (mysql) { - my_sprintf(error_buffer, (error_buffer, ": %d : %s", - mysql_errno(mysql), mysql_error(mysql))); - my_error(error_code, MYF(0), error_buffer); + my_printf_error(error_code, ": %d : %s", MYF(0), + mysql_errno(mysql), mysql_error(mysql)); } else if (remote_error_number != -1 /* error already reported */) diff --git a/strings/decimal.c b/strings/decimal.c index d6c33baf713..4403fc9fd6b 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -994,7 +994,7 @@ int double2decimal(double from, decimal_t *to) char buff[400], *end; int length, res; DBUG_ENTER("double2decimal"); - length= my_sprintf(buff, (buff, "%.16G", from)); + length= sprintf(buff, "%.16G", from); DBUG_PRINT("info",("from: %g from_as_str: %s", from, buff)); end= buff+length; res= string2decimal(buff, to, &end); diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index c492db723b0..00389d431fa 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -1685,7 +1685,7 @@ static void test_prepare() /* now, execute the prepared statement to insert 10 records.. */ for (tiny_data= 0; tiny_data < 100; tiny_data++) { - length[1]= my_sprintf(str_data, (str_data, "MySQL%d", int_data)); + length[1]= sprintf(str_data, "MySQL%d", int_data); rc= mysql_stmt_execute(stmt); check_execute(stmt, rc); int_data += 25; @@ -1724,7 +1724,7 @@ static void test_prepare() /* now, execute the prepared statement to insert 10 records.. */ for (o_tiny_data= 0; o_tiny_data < 100; o_tiny_data++) { - len= my_sprintf(data, (data, "MySQL%d", o_int_data)); + len= sprintf(data, "MySQL%d", o_int_data); rc= mysql_stmt_fetch(stmt); check_execute(stmt, rc); @@ -3090,7 +3090,7 @@ static void test_simple_update() my_bind[0].buffer= szData; /* string data */ my_bind[0].buffer_length= sizeof(szData); my_bind[0].length= &length[0]; - length[0]= my_sprintf(szData, (szData, "updated-data")); + length[0]= sprintf(szData, "updated-data"); my_bind[1].buffer= (void *) &nData; my_bind[1].buffer_type= MYSQL_TYPE_LONG; @@ -3286,7 +3286,7 @@ static void test_long_data_str() DIE_UNLESS(rc == 1); mysql_free_result(result); - my_sprintf(data, (data, "%d", i*5)); + sprintf(data, "%d", i*5); verify_col_data("test_long_data_str", "LENGTH(longstr)", data); data[0]= '\0'; while (i--) @@ -3344,7 +3344,7 @@ static void test_long_data_str1() rc= mysql_stmt_bind_param(stmt, my_bind); check_execute(stmt, rc); - length= my_sprintf(data, (data, "MySQL AB")); + length= sprintf(data, "MySQL AB"); /* supply data in pieces */ for (i= 0; i < 3; i++) @@ -3384,10 +3384,10 @@ static void test_long_data_str1() DIE_UNLESS(rc == 1); mysql_free_result(result); - my_sprintf(data, (data, "%ld", (long)i*length)); + sprintf(data, "%ld", (long)i*length); verify_col_data("test_long_data_str", "length(longstr)", data); - my_sprintf(data, (data, "%d", i*2)); + sprintf(data, "%d", i*2); verify_col_data("test_long_data_str", "length(blb)", data); /* Test length of field->max_length */ @@ -3659,7 +3659,7 @@ static void test_update() my_bind[0].buffer= szData; my_bind[0].buffer_length= sizeof(szData); my_bind[0].length= &length[0]; - length[0]= my_sprintf(szData, (szData, "inserted-data")); + length[0]= sprintf(szData, "inserted-data"); my_bind[1].buffer= (void *)&nData; my_bind[1].buffer_type= MYSQL_TYPE_LONG; @@ -3688,7 +3688,7 @@ static void test_update() my_bind[0].buffer= szData; my_bind[0].buffer_length= sizeof(szData); my_bind[0].length= &length[0]; - length[0]= my_sprintf(szData, (szData, "updated-data")); + length[0]= sprintf(szData, "updated-data"); my_bind[1].buffer= (void *)&nData; my_bind[1].buffer_type= MYSQL_TYPE_LONG; @@ -4257,7 +4257,7 @@ static void bind_fetch(int row_count) /* CHAR */ { char buff[20]; - long len= my_sprintf(buff, (buff, "%d", rc)); + long len= sprintf(buff, "%d", rc); DIE_UNLESS(strcmp(s_data, buff) == 0); DIE_UNLESS(length[6] == (ulong) len); } @@ -4850,7 +4850,7 @@ static void test_insert() /* now, execute the prepared statement to insert 10 records.. */ for (tiny_data= 0; tiny_data < 3; tiny_data++) { - length= my_sprintf(str_data, (str_data, "MySQL%d", tiny_data)); + length= sprintf(str_data, "MySQL%d", tiny_data); rc= mysql_stmt_execute(stmt); check_execute(stmt, rc); } @@ -17512,7 +17512,7 @@ static void test_wl4166_1() /* now, execute the prepared statement to insert 10 records.. */ for (tiny_data= 0; tiny_data < 10; tiny_data++) { - length[1]= my_sprintf(str_data, (str_data, "MySQL%d", int_data)); + length[1]= sprintf(str_data, "MySQL%d", int_data); rc= mysql_stmt_execute(stmt); check_execute(stmt, rc); int_data += 25; @@ -17535,7 +17535,7 @@ static void test_wl4166_1() for (tiny_data= 50; tiny_data < 60; tiny_data++) { - length[1]= my_sprintf(str_data, (str_data, "MySQL%d", int_data)); + length[1]= sprintf(str_data, "MySQL%d", int_data); rc= mysql_stmt_execute(stmt); check_execute(stmt, rc); int_data += 25; From 51ada4dcb05da577fcd26d11b66b8ac2557b3967 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 9 Jul 2010 15:17:47 +0300 Subject: [PATCH 098/112] Addendum #2 to bug #53095 : fixed a bad testcase result. --- mysql-test/suite/funcs_1/r/is_basics_mixed.result | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/suite/funcs_1/r/is_basics_mixed.result b/mysql-test/suite/funcs_1/r/is_basics_mixed.result index 2ae4f96c400..d20e5750403 100644 --- a/mysql-test/suite/funcs_1/r/is_basics_mixed.result +++ b/mysql-test/suite/funcs_1/r/is_basics_mixed.result @@ -328,7 +328,7 @@ ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_ SELECT table_schema,table_name FROM information_schema.tables WHERE table_schema = 'information_schema' AND table_name = 'tables'; table_schema table_name -information_schema tables +information_schema TABLES SELECT * FROM information_schema.table_privileges WHERE table_schema = 'information_schema'; GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE From 6ad06b15222300e4eed4fe3972d1ad249c4c42a2 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 9 Jul 2010 14:23:48 +0200 Subject: [PATCH 099/112] Fix bug #55039 Failing assertion: space_id > 0 in fil0fil.c. --- storage/innodb_plugin/dict/dict0crea.c | 18 +++++++++++++++--- storage/innodb_plugin/os/os0file.c | 12 ++++++++++-- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/storage/innodb_plugin/dict/dict0crea.c b/storage/innodb_plugin/dict/dict0crea.c index f185371bfca..09353c45c8c 100644 --- a/storage/innodb_plugin/dict/dict0crea.c +++ b/storage/innodb_plugin/dict/dict0crea.c @@ -240,17 +240,29 @@ dict_build_table_def_step( ibool is_path; mtr_t mtr; ulint space = 0; + ibool file_per_table; ut_ad(mutex_own(&(dict_sys->mutex))); table = node->table; - dict_hdr_get_new_id(&table->id, NULL, - srv_file_per_table ? &space : NULL); + /* Cache the global variable "srv_file_per_table" to + a local variable before using it. Please note + "srv_file_per_table" is not under dict_sys mutex + protection, and could be changed while executing + this function. So better to cache the current value + to a local variable, and all future reference to + "srv_file_per_table" should use this local variable. */ + file_per_table = srv_file_per_table; + + dict_hdr_get_new_id(&table->id, NULL, NULL); thr_get_trx(thr)->table_id = table->id; - if (srv_file_per_table) { + if (file_per_table) { + /* Get a new space id if srv_file_per_table is set */ + dict_hdr_get_new_id(NULL, NULL, &space); + if (UNIV_UNLIKELY(space == ULINT_UNDEFINED)) { return(DB_ERROR); } diff --git a/storage/innodb_plugin/os/os0file.c b/storage/innodb_plugin/os/os0file.c index b244e3974b3..9f937b9def2 100644 --- a/storage/innodb_plugin/os/os0file.c +++ b/storage/innodb_plugin/os/os0file.c @@ -1339,7 +1339,11 @@ try_again: /* When srv_file_per_table is on, file creation failure may not be critical to the whole instance. Do not crash the server in - case of unknown errors. */ + case of unknown errors. + Please note "srv_file_per_table" is a global variable with + no explicit synchronization protection. It could be + changed during this execution path. It might not have the + same value as the one when building the table definition */ if (srv_file_per_table) { retry = os_file_handle_error_no_exit(name, create_mode == OS_FILE_CREATE ? @@ -1426,7 +1430,11 @@ try_again: /* When srv_file_per_table is on, file creation failure may not be critical to the whole instance. Do not crash the server in - case of unknown errors. */ + case of unknown errors. + Please note "srv_file_per_table" is a global variable with + no explicit synchronization protection. It could be + changed during this execution path. It might not have the + same value as the one when building the table definition */ if (srv_file_per_table) { retry = os_file_handle_error_no_exit(name, create_mode == OS_FILE_CREATE ? From 72e404be34096c2b750345f7d23f6be08a95a78d Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 9 Jul 2010 09:51:21 -0300 Subject: [PATCH 100/112] Remove AC_LANG_WERROR, it causes trouble earlier versions of autoconf and is not strictly needed for now. --- config/ac-macros/maintainer.m4 | 2 -- 1 file changed, 2 deletions(-) diff --git a/config/ac-macros/maintainer.m4 b/config/ac-macros/maintainer.m4 index 6aa1d166f2a..1b7df75d6f7 100644 --- a/config/ac-macros/maintainer.m4 +++ b/config/ac-macros/maintainer.m4 @@ -27,7 +27,6 @@ AC_DEFUN([MY_MAINTAINER_MODE_WARNINGS], [ AC_MSG_CHECKING([whether to use C warning options ${C_WARNINGS}]) AC_LANG_PUSH(C) CFLAGS="$CFLAGS ${C_WARNINGS}" - AC_LANG_WERROR AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], [myac_c_warning_flags=yes], [myac_c_warning_flags=no]) AC_LANG_POP() @@ -41,7 +40,6 @@ AC_DEFUN([MY_MAINTAINER_MODE_WARNINGS], [ AC_MSG_CHECKING([whether to use C++ warning options ${CXX_WARNINGS}]) AC_LANG_PUSH(C++) CXXFLAGS="$CXXFLAGS ${CXX_WARNINGS}" - AC_LANG_WERROR AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], [myac_cxx_warning_flags=yes], [myac_cxx_warning_flags=no]) AC_LANG_POP() From e98169d52c8610efa523040d4409054e352f92df Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Mon, 12 Jul 2010 18:58:55 +0400 Subject: [PATCH 101/112] Bug#55061: Build failing on sol 8 x86 - assembler code vs compiler problem GCC-style inline assembly is not supported by the Sun Studio compilers prior to version 12. Added a check for the Sun Studio version to avoid using _FPU_GETCW() / _FPU_SETCW() when inline assembly is unsupported. This can lead to some differences in floating point calculations on Solaris 8/x86 which, however, is not worth bothering with Sun-style assembly .il templates. --- sql/mysqld.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 99f16b36dfa..598db8d993c 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -190,7 +190,7 @@ typedef fp_except fp_except_t; # define fpu_control_t unsigned int # define _FPU_EXTENDED 0x300 # define _FPU_DOUBLE 0x200 -# if defined(__GNUC__) || defined(__SUNPRO_CC) +# if defined(__GNUC__) || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x590) # define _FPU_GETCW(cw) asm volatile ("fnstcw %0" : "=m" (*&cw)) # define _FPU_SETCW(cw) asm volatile ("fldcw %0" : : "m" (*&cw)) # else From 4c28b6776884b3890cc82c251eb4b54fe5dd81d4 Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Thu, 15 Jul 2010 10:10:16 +0400 Subject: [PATCH 102/112] Backport of the fix for bug#25421 to 5.0. Calculating the estimated number of records for a range scan may take a significant time, and it was impossible for a user to interrupt that process by killing the connection or the query. Fixed by checking the thread's 'killed' status in check_quick_keys() and interrupting the calculation process if it is set to a non-zero value. --- sql/opt_range.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 84519c091b9..35d1216387c 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -6066,6 +6066,9 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree, tmp_max_flag=max_key_flag | key_tree->max_flag; } + if (unlikely(param->thd->killed != 0)) + return HA_POS_ERROR; + keynr=param->real_keynr[idx]; param->range_count++; if (!tmp_min_flag && ! tmp_max_flag && From 37c97fd472846fcb35575a51ab2937c0b82b9c5a Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Fri, 16 Jul 2010 11:15:22 +0400 Subject: [PATCH 103/112] Fix for bug #50667: The InnoDB plugin prevents initialization of the "embedded" server Problem: mysqltest_embedded failed to load ha_innodb_plugin library on some platforms (due to some unresolved references). Fix: on FreeBSD use -export-dynamic flag building mysqltest_embedded. That allows to use its global symbols to resolve references in the dynamically loaded plugin library. libmysqld/examples/Makefile.am: Fix for bug #50667: The InnoDB plugin prevents initialization of the "embedded" server - use -export-dynamic (on FreeBSD/DragonFly) building mysqltest_embedded to allow using its global symbols to resolve references in the dynamically loaded plugin libraries. --- libmysqld/examples/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libmysqld/examples/Makefile.am b/libmysqld/examples/Makefile.am index 109d33a85ae..fd37f362960 100644 --- a/libmysqld/examples/Makefile.am +++ b/libmysqld/examples/Makefile.am @@ -42,7 +42,8 @@ LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysqld.a @LIBDL@ $(CXXLDFLAGS) \ mysqltest_embedded_LINK = $(CXXLINK) nodist_mysqltest_embedded_SOURCES = mysqltest.cc -mysqltest_embedded_LDADD = $(LDADD) $(top_builddir)/regex/libregex.a +mysqltest_embedded_LDADD = $(LDADD) $(top_builddir)/regex/libregex.a \ + @MYSQLD_EXTRA_LDFLAGS@ nodist_mysql_SOURCES = mysql.cc readline.cc completion_hash.cc \ my_readline.h sql_string.h completion_hash.h From dcaef2424e56f714068411baa52f3b488210b5b0 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 16 Jul 2010 16:56:33 +0300 Subject: [PATCH 104/112] Addendum to bug #53814 : test results updates --- .../suite/funcs_1/r/is_columns_innodb.result | 12 ++-- .../suite/funcs_1/r/is_columns_is.result | 68 +++++++++---------- .../suite/funcs_1/r/is_columns_memory.result | 12 ++-- .../suite/funcs_1/r/is_columns_myisam.result | 12 ++-- .../suite/funcs_1/r/is_columns_mysql.result | 12 ++-- 5 files changed, 58 insertions(+), 58 deletions(-) diff --git a/mysql-test/suite/funcs_1/r/is_columns_innodb.result b/mysql-test/suite/funcs_1/r/is_columns_innodb.result index 73a74e4d7a2..61079b06666 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_innodb.result +++ b/mysql-test/suite/funcs_1/r/is_columns_innodb.result @@ -450,9 +450,9 @@ NULL test tb1 f27 27 NULL YES int NULL NULL 10 0 NULL NULL int(10) unsigned zero NULL test tb1 f28 28 NULL YES int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references NULL test tb1 f29 29 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(20) select,insert,update,references NULL test tb1 f3 3 NULL YES char 0 0 NULL NULL latin1 latin1_swedish_ci char(0) select,insert,update,references -NULL test tb1 f30 30 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned select,insert,update,references -NULL test tb1 f31 31 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references -NULL test tb1 f32 32 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references +NULL test tb1 f30 30 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references +NULL test tb1 f31 31 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references +NULL test tb1 f32 32 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references NULL test tb1 f33 33 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references NULL test tb1 f34 34 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references NULL test tb1 f35 35 NULL YES decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references @@ -565,9 +565,9 @@ NULL test tb3 f143 26 99999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned s NULL test tb3 f144 27 0000099999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references NULL test tb3 f145 28 0000099999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references NULL test tb3 f146 29 999999 NO bigint NULL NULL 19 0 NULL NULL bigint(20) select,insert,update,references -NULL test tb3 f147 30 999999 NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned select,insert,update,references -NULL test tb3 f148 31 00000000000000999999 NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references -NULL test tb3 f149 32 00000000000000999999 NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references +NULL test tb3 f147 30 999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references +NULL test tb3 f148 31 00000000000000999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references +NULL test tb3 f149 32 00000000000000999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references NULL test tb3 f150 33 1000 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references NULL test tb3 f151 34 999 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references NULL test tb3 f152 35 0000001000 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references diff --git a/mysql-test/suite/funcs_1/r/is_columns_is.result b/mysql-test/suite/funcs_1/r/is_columns_is.result index ccb94c63d46..0bed3753165 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is.result @@ -15,8 +15,8 @@ NULL information_schema COLLATIONS IS_DEFAULT 4 NO varchar 3 9 NULL NULL utf8 u NULL information_schema COLLATIONS SORTLEN 6 0 NO bigint NULL NULL 19 0 NULL NULL bigint(3) select NULL information_schema COLLATION_CHARACTER_SET_APPLICABILITY CHARACTER_SET_NAME 2 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select NULL information_schema COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME 1 NO varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select -NULL information_schema COLUMNS CHARACTER_MAXIMUM_LENGTH 9 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select -NULL information_schema COLUMNS CHARACTER_OCTET_LENGTH 10 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select +NULL information_schema COLUMNS CHARACTER_MAXIMUM_LENGTH 9 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select +NULL information_schema COLUMNS CHARACTER_OCTET_LENGTH 10 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select NULL information_schema COLUMNS CHARACTER_SET_NAME 13 NULL YES varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select NULL information_schema COLUMNS COLLATION_NAME 14 NULL YES varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select NULL information_schema COLUMNS COLUMN_COMMENT 19 NO varchar 255 765 NULL NULL utf8 utf8_general_ci varchar(255) select @@ -27,9 +27,9 @@ NULL information_schema COLUMNS COLUMN_TYPE 15 NULL NO longtext 4294967295 42949 NULL information_schema COLUMNS DATA_TYPE 8 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select NULL information_schema COLUMNS EXTRA 17 NO varchar 27 81 NULL NULL utf8 utf8_general_ci varchar(27) select NULL information_schema COLUMNS IS_NULLABLE 7 NO varchar 3 9 NULL NULL utf8 utf8_general_ci varchar(3) select -NULL information_schema COLUMNS NUMERIC_PRECISION 11 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select -NULL information_schema COLUMNS NUMERIC_SCALE 12 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select -NULL information_schema COLUMNS ORDINAL_POSITION 5 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select +NULL information_schema COLUMNS NUMERIC_PRECISION 11 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select +NULL information_schema COLUMNS NUMERIC_SCALE 12 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select +NULL information_schema COLUMNS ORDINAL_POSITION 5 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select NULL information_schema COLUMNS PRIVILEGES 18 NO varchar 80 240 NULL NULL utf8 utf8_general_ci varchar(80) select NULL information_schema COLUMNS TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select NULL information_schema COLUMNS TABLE_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select @@ -71,14 +71,14 @@ NULL information_schema EVENTS SQL_MODE 12 NO varchar 8192 24576 NULL NULL utf8 NULL information_schema EVENTS STARTS 13 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select NULL information_schema EVENTS STATUS 15 NO varchar 18 54 NULL NULL utf8 utf8_general_ci varchar(18) select NULL information_schema EVENTS TIME_ZONE 5 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select -NULL information_schema FILES AUTOEXTEND_SIZE 19 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select -NULL information_schema FILES AVG_ROW_LENGTH 28 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select -NULL information_schema FILES CHECKSUM 36 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select +NULL information_schema FILES AUTOEXTEND_SIZE 19 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select +NULL information_schema FILES AVG_ROW_LENGTH 28 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select +NULL information_schema FILES CHECKSUM 36 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select NULL information_schema FILES CHECK_TIME 35 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select NULL information_schema FILES CREATE_TIME 33 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select NULL information_schema FILES CREATION_TIME 20 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select -NULL information_schema FILES DATA_FREE 32 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select -NULL information_schema FILES DATA_LENGTH 29 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select +NULL information_schema FILES DATA_FREE 32 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select +NULL information_schema FILES DATA_LENGTH 29 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select NULL information_schema FILES DELETED_ROWS 12 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(4) select NULL information_schema FILES ENGINE 10 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select NULL information_schema FILES EXTENT_SIZE 16 0 NO bigint NULL NULL 19 0 NULL NULL bigint(4) select @@ -88,27 +88,27 @@ NULL information_schema FILES FILE_NAME 2 NULL YES varchar 64 192 NULL NULL utf8 NULL information_schema FILES FILE_TYPE 3 NO varchar 20 60 NULL NULL utf8 utf8_general_ci varchar(20) select NULL information_schema FILES FREE_EXTENTS 14 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(4) select NULL information_schema FILES FULLTEXT_KEYS 11 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select -NULL information_schema FILES INDEX_LENGTH 31 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select -NULL information_schema FILES INITIAL_SIZE 17 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select +NULL information_schema FILES INDEX_LENGTH 31 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select +NULL information_schema FILES INITIAL_SIZE 17 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select NULL information_schema FILES LAST_ACCESS_TIME 22 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select NULL information_schema FILES LAST_UPDATE_TIME 21 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select NULL information_schema FILES LOGFILE_GROUP_NAME 8 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select NULL information_schema FILES LOGFILE_GROUP_NUMBER 9 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(4) select -NULL information_schema FILES MAXIMUM_SIZE 18 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select -NULL information_schema FILES MAX_DATA_LENGTH 30 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select +NULL information_schema FILES MAXIMUM_SIZE 18 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select +NULL information_schema FILES MAX_DATA_LENGTH 30 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select NULL information_schema FILES RECOVER_TIME 23 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(4) select NULL information_schema FILES ROW_FORMAT 26 NULL YES varchar 10 30 NULL NULL utf8 utf8_general_ci varchar(10) select NULL information_schema FILES STATUS 37 NO varchar 20 60 NULL NULL utf8 utf8_general_ci varchar(20) select NULL information_schema FILES TABLESPACE_NAME 4 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select NULL information_schema FILES TABLE_CATALOG 5 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select NULL information_schema FILES TABLE_NAME 7 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select -NULL information_schema FILES TABLE_ROWS 27 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select +NULL information_schema FILES TABLE_ROWS 27 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select NULL information_schema FILES TABLE_SCHEMA 6 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select NULL information_schema FILES TOTAL_EXTENTS 15 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(4) select NULL information_schema FILES TRANSACTION_COUNTER 24 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(4) select NULL information_schema FILES UPDATE_COUNT 13 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(4) select NULL information_schema FILES UPDATE_TIME 34 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select -NULL information_schema FILES VERSION 25 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select +NULL information_schema FILES VERSION 25 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select NULL information_schema GLOBAL_STATUS VARIABLE_NAME 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select NULL information_schema GLOBAL_STATUS VARIABLE_VALUE 2 NULL YES varchar 1024 3072 NULL NULL utf8 utf8_general_ci varchar(1024) select NULL information_schema GLOBAL_VARIABLES VARIABLE_NAME 1 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select @@ -125,29 +125,29 @@ NULL information_schema KEY_COLUMN_USAGE REFERENCED_TABLE_SCHEMA 10 NULL YES var NULL information_schema KEY_COLUMN_USAGE TABLE_CATALOG 4 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select NULL information_schema KEY_COLUMN_USAGE TABLE_NAME 6 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select NULL information_schema KEY_COLUMN_USAGE TABLE_SCHEMA 5 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select -NULL information_schema PARTITIONS AVG_ROW_LENGTH 14 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select -NULL information_schema PARTITIONS CHECKSUM 22 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select +NULL information_schema PARTITIONS AVG_ROW_LENGTH 14 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select +NULL information_schema PARTITIONS CHECKSUM 22 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select NULL information_schema PARTITIONS CHECK_TIME 21 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select NULL information_schema PARTITIONS CREATE_TIME 19 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select -NULL information_schema PARTITIONS DATA_FREE 18 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select -NULL information_schema PARTITIONS DATA_LENGTH 15 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select -NULL information_schema PARTITIONS INDEX_LENGTH 17 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select -NULL information_schema PARTITIONS MAX_DATA_LENGTH 16 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select +NULL information_schema PARTITIONS DATA_FREE 18 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select +NULL information_schema PARTITIONS DATA_LENGTH 15 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select +NULL information_schema PARTITIONS INDEX_LENGTH 17 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select +NULL information_schema PARTITIONS MAX_DATA_LENGTH 16 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select NULL information_schema PARTITIONS NODEGROUP 24 NO varchar 12 36 NULL NULL utf8 utf8_general_ci varchar(12) select NULL information_schema PARTITIONS PARTITION_COMMENT 23 NO varchar 80 240 NULL NULL utf8 utf8_general_ci varchar(80) select NULL information_schema PARTITIONS PARTITION_DESCRIPTION 12 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select NULL information_schema PARTITIONS PARTITION_EXPRESSION 10 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select NULL information_schema PARTITIONS PARTITION_METHOD 8 NULL YES varchar 12 36 NULL NULL utf8 utf8_general_ci varchar(12) select NULL information_schema PARTITIONS PARTITION_NAME 4 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select -NULL information_schema PARTITIONS PARTITION_ORDINAL_POSITION 6 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select +NULL information_schema PARTITIONS PARTITION_ORDINAL_POSITION 6 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select NULL information_schema PARTITIONS SUBPARTITION_EXPRESSION 11 NULL YES longtext 4294967295 4294967295 NULL NULL utf8 utf8_general_ci longtext select NULL information_schema PARTITIONS SUBPARTITION_METHOD 9 NULL YES varchar 12 36 NULL NULL utf8 utf8_general_ci varchar(12) select NULL information_schema PARTITIONS SUBPARTITION_NAME 5 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select -NULL information_schema PARTITIONS SUBPARTITION_ORDINAL_POSITION 7 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select +NULL information_schema PARTITIONS SUBPARTITION_ORDINAL_POSITION 7 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select NULL information_schema PARTITIONS TABLESPACE_NAME 25 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select NULL information_schema PARTITIONS TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select NULL information_schema PARTITIONS TABLE_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select -NULL information_schema PARTITIONS TABLE_ROWS 13 0 NO bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select +NULL information_schema PARTITIONS TABLE_ROWS 13 0 NO bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select NULL information_schema PARTITIONS TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select NULL information_schema PARTITIONS UPDATE_TIME 20 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select NULL information_schema PLUGINS PLUGIN_AUTHOR 8 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select @@ -231,27 +231,27 @@ NULL information_schema STATISTICS SUB_PART 11 NULL YES bigint NULL NULL 19 0 NU NULL information_schema STATISTICS TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select NULL information_schema STATISTICS TABLE_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select NULL information_schema STATISTICS TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select -NULL information_schema TABLES AUTO_INCREMENT 14 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select -NULL information_schema TABLES AVG_ROW_LENGTH 9 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select -NULL information_schema TABLES CHECKSUM 19 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select +NULL information_schema TABLES AUTO_INCREMENT 14 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select +NULL information_schema TABLES AVG_ROW_LENGTH 9 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select +NULL information_schema TABLES CHECKSUM 19 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select NULL information_schema TABLES CHECK_TIME 17 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select NULL information_schema TABLES CREATE_OPTIONS 20 NULL YES varchar 255 765 NULL NULL utf8 utf8_general_ci varchar(255) select NULL information_schema TABLES CREATE_TIME 15 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select -NULL information_schema TABLES DATA_FREE 13 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select -NULL information_schema TABLES DATA_LENGTH 10 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select +NULL information_schema TABLES DATA_FREE 13 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select +NULL information_schema TABLES DATA_LENGTH 10 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select NULL information_schema TABLES ENGINE 5 NULL YES varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select -NULL information_schema TABLES INDEX_LENGTH 12 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select -NULL information_schema TABLES MAX_DATA_LENGTH 11 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select +NULL information_schema TABLES INDEX_LENGTH 12 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select +NULL information_schema TABLES MAX_DATA_LENGTH 11 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select NULL information_schema TABLES ROW_FORMAT 7 NULL YES varchar 10 30 NULL NULL utf8 utf8_general_ci varchar(10) select NULL information_schema TABLES TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select NULL information_schema TABLES TABLE_COLLATION 18 NULL YES varchar 32 96 NULL NULL utf8 utf8_general_ci varchar(32) select NULL information_schema TABLES TABLE_COMMENT 21 NO varchar 80 240 NULL NULL utf8 utf8_general_ci varchar(80) select NULL information_schema TABLES TABLE_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select -NULL information_schema TABLES TABLE_ROWS 8 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select +NULL information_schema TABLES TABLE_ROWS 8 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select NULL information_schema TABLES TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select NULL information_schema TABLES TABLE_TYPE 4 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select NULL information_schema TABLES UPDATE_TIME 16 NULL YES datetime NULL NULL NULL NULL NULL NULL datetime select -NULL information_schema TABLES VERSION 6 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(21) unsigned select +NULL information_schema TABLES VERSION 6 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(21) unsigned select NULL information_schema TABLE_CONSTRAINTS CONSTRAINT_CATALOG 1 NULL YES varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512) select NULL information_schema TABLE_CONSTRAINTS CONSTRAINT_NAME 3 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select NULL information_schema TABLE_CONSTRAINTS CONSTRAINT_SCHEMA 2 NO varchar 64 192 NULL NULL utf8 utf8_general_ci varchar(64) select diff --git a/mysql-test/suite/funcs_1/r/is_columns_memory.result b/mysql-test/suite/funcs_1/r/is_columns_memory.result index 513d7bdfac6..60dea25e0e3 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_memory.result +++ b/mysql-test/suite/funcs_1/r/is_columns_memory.result @@ -437,9 +437,9 @@ NULL test tb1 f27 19 NULL YES int NULL NULL 10 0 NULL NULL int(10) unsigned zero NULL test tb1 f28 20 NULL YES int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references NULL test tb1 f29 21 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(20) select,insert,update,references NULL test tb1 f3 3 NULL YES char 1 1 NULL NULL latin1 latin1_swedish_ci char(1) select,insert,update,references -NULL test tb1 f30 22 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned select,insert,update,references -NULL test tb1 f31 23 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references -NULL test tb1 f32 24 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references +NULL test tb1 f30 22 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references +NULL test tb1 f31 23 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references +NULL test tb1 f32 24 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references NULL test tb1 f33 25 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references NULL test tb1 f34 26 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references NULL test tb1 f35 27 0000000010 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references @@ -540,9 +540,9 @@ NULL test tb3 f143 20 99999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned s NULL test tb3 f144 21 0000099999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references NULL test tb3 f145 22 0000099999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references NULL test tb3 f146 23 999999 NO bigint NULL NULL 19 0 NULL NULL bigint(20) select,insert,update,references -NULL test tb3 f147 24 999999 NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned select,insert,update,references -NULL test tb3 f148 25 00000000000000999999 NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references -NULL test tb3 f149 26 00000000000000999999 NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references +NULL test tb3 f147 24 999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references +NULL test tb3 f148 25 00000000000000999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references +NULL test tb3 f149 26 00000000000000999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references NULL test tb3 f150 27 1000 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references NULL test tb3 f151 28 999 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references NULL test tb3 f152 29 0000001000 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references diff --git a/mysql-test/suite/funcs_1/r/is_columns_myisam.result b/mysql-test/suite/funcs_1/r/is_columns_myisam.result index a95ca4f0ebf..6d0a44d2223 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_myisam.result +++ b/mysql-test/suite/funcs_1/r/is_columns_myisam.result @@ -479,9 +479,9 @@ NULL test tb1 f27 27 NULL YES int NULL NULL 10 0 NULL NULL int(10) unsigned zero NULL test tb1 f28 28 NULL YES int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references NULL test tb1 f29 29 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(20) select,insert,update,references NULL test tb1 f3 3 NULL YES char 1 1 NULL NULL latin1 latin1_swedish_ci char(1) select,insert,update,references -NULL test tb1 f30 30 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned select,insert,update,references -NULL test tb1 f31 31 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references -NULL test tb1 f32 32 NULL YES bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references +NULL test tb1 f30 30 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references +NULL test tb1 f31 31 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references +NULL test tb1 f32 32 NULL YES bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references NULL test tb1 f33 33 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references NULL test tb1 f34 34 10 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references NULL test tb1 f35 35 0000000010 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references @@ -602,9 +602,9 @@ NULL test tb3 f143 26 99999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned s NULL test tb3 f144 27 0000099999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references NULL test tb3 f145 28 0000099999 NO int NULL NULL 10 0 NULL NULL int(10) unsigned zerofill select,insert,update,references NULL test tb3 f146 29 999999 NO bigint NULL NULL 19 0 NULL NULL bigint(20) select,insert,update,references -NULL test tb3 f147 30 999999 NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned select,insert,update,references -NULL test tb3 f148 31 00000000000000999999 NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references -NULL test tb3 f149 32 00000000000000999999 NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references +NULL test tb3 f147 30 999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references +NULL test tb3 f148 31 00000000000000999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references +NULL test tb3 f149 32 00000000000000999999 NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned zerofill select,insert,update,references NULL test tb3 f150 33 1000 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) select,insert,update,references NULL test tb3 f151 34 999 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned select,insert,update,references NULL test tb3 f152 35 0000001000 NO decimal NULL NULL 10 0 NULL NULL decimal(10,0) unsigned zerofill select,insert,update,references diff --git a/mysql-test/suite/funcs_1/r/is_columns_mysql.result b/mysql-test/suite/funcs_1/r/is_columns_mysql.result index 98eeacdb74c..2b285d7cc56 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_mysql.result +++ b/mysql-test/suite/funcs_1/r/is_columns_mysql.result @@ -97,13 +97,13 @@ NULL mysql host Select_priv 3 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum( NULL mysql host Show_view_priv 16 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NULL mysql host Trigger_priv 20 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references NULL mysql host Update_priv 5 N NO enum 1 3 NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references -NULL mysql ndb_binlog_index deletes 6 NULL NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned select,insert,update,references -NULL mysql ndb_binlog_index epoch 3 NULL NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned PRI select,insert,update,references +NULL mysql ndb_binlog_index deletes 6 NULL NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references +NULL mysql ndb_binlog_index epoch 3 NULL NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned PRI select,insert,update,references NULL mysql ndb_binlog_index File 2 NULL NO varchar 255 255 NULL NULL latin1 latin1_swedish_ci varchar(255) select,insert,update,references -NULL mysql ndb_binlog_index inserts 4 NULL NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned select,insert,update,references -NULL mysql ndb_binlog_index Position 1 NULL NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned select,insert,update,references -NULL mysql ndb_binlog_index schemaops 7 NULL NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned select,insert,update,references -NULL mysql ndb_binlog_index updates 5 NULL NO bigint NULL NULL 19 0 NULL NULL bigint(20) unsigned select,insert,update,references +NULL mysql ndb_binlog_index inserts 4 NULL NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references +NULL mysql ndb_binlog_index Position 1 NULL NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references +NULL mysql ndb_binlog_index schemaops 7 NULL NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references +NULL mysql ndb_binlog_index updates 5 NULL NO bigint NULL NULL 20 0 NULL NULL bigint(20) unsigned select,insert,update,references NULL mysql plugin dl 2 NO char 128 384 NULL NULL utf8 utf8_bin char(128) select,insert,update,references NULL mysql plugin name 1 NO char 64 192 NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references NULL mysql proc body 11 NULL NO longblob 4294967295 4294967295 NULL NULL NULL NULL longblob select,insert,update,references From 92f3fc92f3310cb19d48f69ab6f5d23789a90570 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 16 Jul 2010 14:33:35 -0300 Subject: [PATCH 105/112] Bug#48327: Some crashes specific to FreeBSD ("embedded") Bug#47139: Test "merge" crashes in "embedded" run Backport patch for Bug#47139 --- storage/myisam/mi_dynrec.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/storage/myisam/mi_dynrec.c b/storage/myisam/mi_dynrec.c index 09152f8d013..4153f55aa3c 100644 --- a/storage/myisam/mi_dynrec.c +++ b/storage/myisam/mi_dynrec.c @@ -66,9 +66,12 @@ static int _mi_cmp_buffer(File file, const uchar *buff, my_off_t filepos, my_bool mi_dynmap_file(MI_INFO *info, my_off_t size) { DBUG_ENTER("mi_dynmap_file"); - if (size > (my_off_t) (~((size_t) 0))) + if (size == 0 || size > (my_off_t) (~((size_t) 0))) { - DBUG_PRINT("warning", ("File is too large for mmap")); + if (size) + DBUG_PRINT("warning", ("File is too large for mmap")); + else + DBUG_PRINT("warning", ("Do not mmap zero-length")); DBUG_RETURN(1); } /* From 85e5ce0ba06b6a79e4bd7521ab0e44c1e63a3e77 Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Mon, 19 Jul 2010 11:03:52 +0200 Subject: [PATCH 106/112] Bug #54734 assert in Diagnostics_area::set_ok_status This assert checks that the server does not try to send OK to the client if there has been some error during processing. This is done to make sure that the error is in fact sent to the client. The problem was that view errors during processing of WHERE conditions in UPDATE statements where not detected by the update code. It therefore tried to send OK to the client, triggering the assert. The bug was only noticeable in debug builds. This patch fixes the problem by making sure that the update code checks for errors during condition processing and acts accordingly. --- mysql-test/r/update.result | 14 ++++++++++++++ mysql-test/t/update.test | 20 ++++++++++++++++++++ sql/filesort.cc | 4 +++- sql/opt_range.h | 6 +++++- sql/sql_delete.cc | 3 ++- sql/sql_select.cc | 32 ++++++++++++-------------------- sql/sql_update.cc | 12 ++++++++++-- 7 files changed, 66 insertions(+), 25 deletions(-) diff --git a/mysql-test/r/update.result b/mysql-test/r/update.result index 006eaba4e69..63baf639487 100644 --- a/mysql-test/r/update.result +++ b/mysql-test/r/update.result @@ -527,3 +527,17 @@ ERROR HY000: You are using safe update mode and you tried to update a table with SET SESSION sql_safe_updates = DEFAULT; DROP TABLE t1; DROP VIEW v1; +# +# Bug#54734 assert in Diagnostics_area::set_ok_status +# +DROP TABLE IF EXISTS t1, not_exists; +DROP FUNCTION IF EXISTS f1; +DROP VIEW IF EXISTS v1; +CREATE TABLE t1 (PRIMARY KEY(pk)) AS SELECT 1 AS pk; +CREATE FUNCTION f1() RETURNS INTEGER RETURN (SELECT 1 FROM not_exists); +CREATE VIEW v1 AS SELECT pk FROM t1 WHERE f1() = 13; +UPDATE v1 SET pk = 7 WHERE pk > 0; +ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +DROP VIEW v1; +DROP FUNCTION f1; +DROP TABLE t1; diff --git a/mysql-test/t/update.test b/mysql-test/t/update.test index f6708828a6b..c515f8873d8 100644 --- a/mysql-test/t/update.test +++ b/mysql-test/t/update.test @@ -483,3 +483,23 @@ UPDATE IGNORE v1 SET a = 1; SET SESSION sql_safe_updates = DEFAULT; DROP TABLE t1; DROP VIEW v1; + +--echo # +--echo # Bug#54734 assert in Diagnostics_area::set_ok_status +--echo # + +--disable_warnings +DROP TABLE IF EXISTS t1, not_exists; +DROP FUNCTION IF EXISTS f1; +DROP VIEW IF EXISTS v1; +--enable_warnings + +CREATE TABLE t1 (PRIMARY KEY(pk)) AS SELECT 1 AS pk; +CREATE FUNCTION f1() RETURNS INTEGER RETURN (SELECT 1 FROM not_exists); +CREATE VIEW v1 AS SELECT pk FROM t1 WHERE f1() = 13; +--error ER_VIEW_INVALID +UPDATE v1 SET pk = 7 WHERE pk > 0; + +DROP VIEW v1; +DROP FUNCTION f1; +DROP TABLE t1; diff --git a/sql/filesort.cc b/sql/filesort.cc index 7b584b39516..021cbdd2aad 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -514,6 +514,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select, volatile THD::killed_state *killed= &thd->killed; handler *file; MY_BITMAP *save_read_set, *save_write_set; + bool skip_record; DBUG_ENTER("find_all_keys"); DBUG_PRINT("info",("using: %s", (select ? select->quick ? "ranges" : "where": @@ -606,7 +607,8 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select, } if (error == 0) param->examined_rows++; - if (error == 0 && (!select || select->skip_record() == 0)) + if (!error && (!select || + (!select->skip_record(thd, &skip_record) && !skip_record))) { if (idx == param->keys) { diff --git a/sql/opt_range.h b/sql/opt_range.h index edae1e4114a..c6e488cf14c 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -788,7 +788,11 @@ class SQL_SELECT :public Sql_alloc { tmp.set_all(); return test_quick_select(thd, tmp, 0, limit, force_quick_range) < 0; } - inline bool skip_record() { return cond ? cond->val_int() == 0 : 0; } + inline bool skip_record(THD *thd, bool *skip_record) + { + *skip_record= cond ? cond->val_int() == FALSE : FALSE; + return thd->is_error(); + } int test_quick_select(THD *thd, key_map keys, table_map prev_tables, ha_rows limit, bool force_quick_range); }; diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index eb0fd4b5332..6a87eb4e572 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -51,6 +51,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, THD::killed_state killed_status= THD::NOT_KILLED; DBUG_ENTER("mysql_delete"); bool save_binlog_row_based; + bool skip_record; THD::enum_binlog_query_type query_type= thd->lex->sql_command == SQLCOM_TRUNCATE ? @@ -307,7 +308,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, { thd->examined_row_count++; // thd->is_error() is tested to disallow delete row on error - if (!(select && select->skip_record())&& ! thd->is_error() ) + if (!select || (!select->skip_record(thd, &skip_record) && !skip_record)) { if (triggers_applicable && diff --git a/sql/sql_select.cc b/sql/sql_select.cc index fe391b50bb9..2fc287bbe66 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -11657,38 +11657,30 @@ flush_cached_records(JOIN *join,JOIN_TAB *join_tab,bool skip_last) SQL_SELECT *select=join_tab->select; if (rc == NESTED_LOOP_OK) { - bool consider_record= !join_tab->cache.select || - !join_tab->cache.select->skip_record(); - - /* - Check for error: skip_record() can execute code by calling - Item_subselect::val_*. We need to check for errors (if any) - after such call. - */ - if (join->thd->is_error()) + bool skip_record= FALSE; + if (join_tab->cache.select && + join_tab->cache.select->skip_record(join->thd, &skip_record)) { reset_cache_write(&join_tab->cache); return NESTED_LOOP_ERROR; } - if (consider_record) + if (!skip_record) { uint i; reset_cache_read(&join_tab->cache); for (i=(join_tab->cache.records- (skip_last ? 1 : 0)) ; i-- > 0 ;) { read_cached_record(join_tab); - if (!select || !select->skip_record()) + skip_record= FALSE; + if (select && select->skip_record(join->thd, &skip_record)) { - /* - Check for error: skip_record() can execute code by calling - Item_subselect::val_*. We need to check for errors (if any) - after such call. - */ - if (join->thd->is_error()) - rc= NESTED_LOOP_ERROR; - else - rc= (join_tab->next_select)(join,join_tab+1,0); + reset_cache_write(&join_tab->cache); + return NESTED_LOOP_ERROR; + } + if (!skip_record) + { + rc= (join_tab->next_select)(join,join_tab+1,0); if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS) { reset_cache_write(&join_tab->cache); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 3cdbb97b90b..17fac877fbc 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -473,7 +473,14 @@ int mysql_update(THD *thd, while (!(error=info.read_record(&info)) && !thd->killed) { thd->examined_row_count++; - if (!(select && select->skip_record())) + bool skip_record= FALSE; + if (select && select->skip_record(thd, &skip_record)) + { + error= 1; + table->file->unlock_row(); + break; + } + if (!skip_record) { if (table->file->was_semi_consistent_read()) continue; /* repeat the read of the same row if it still exists */ @@ -580,7 +587,8 @@ int mysql_update(THD *thd, while (!(error=info.read_record(&info)) && !thd->killed) { thd->examined_row_count++; - if (!(select && select->skip_record())) + bool skip_record; + if (!select || (!select->skip_record(thd, &skip_record) && !skip_record)) { if (table->file->was_semi_consistent_read()) continue; /* repeat the read of the same row if it still exists */ From d79e6c2e4594dc506d4d30cdc53545321b475ada Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 19 Jul 2010 17:47:17 +0300 Subject: [PATCH 107/112] fix tree names --- .bzr-mysql/default.conf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 77df77c6021..f044f8e62da 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] -post_commit_to = "dbg_mysql_security@sun.com" -post_push_to = "dbg_mysql_security@sun.com" -tree_name = "mysql-5.1-security" +post_commit_to = "commits@lists.mysql.com" +post_push_to = "commits@lists.mysql.com" +tree_name = "mysql-5.1" From b0035c76d46caf25d6b52f4e1552c1e83f7f0911 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 20 Jul 2010 14:36:15 -0300 Subject: [PATCH 108/112] Bug#54453: Failing assertion: trx->active_trans when renaming a table with active trx Essentially, the problem is that InnoDB does a implicit commit when a cursor (table handler) is unlocked/closed, creating a dissonance between the transaction state within the server layer and the storage engine layer. Theoretically, a statement transaction can encompass several table instances in a similar manner to a multiple statement transaction, hence it does not make sense to limit a statement transaction to the lifetime of the table instances (cursors) used within it. Since this particular instance of the problem is only triggerable on 5.1 and is masked on 5.5 due 2PC being skipped (assertion is in the prepare phase of a 2PC), the solution (which is less risky) is to explicitly end the transaction before the cached table is unlock on rename table. The patch is to be null merged into trunk. mysql-test/include/commit.inc: Fix counters, the binlog engine does not get involved anymore. mysql-test/suite/innodb_plugin/r/innodb_bug54453.result: Add test case result for Bug#54453 mysql-test/suite/innodb_plugin/t/innodb_bug54453.test: Add test case for Bug#54453 sql/sql_table.cc: End transaction as otherwise InnoDB will end it behind our backs. --- mysql-test/include/commit.inc | 4 ++-- mysql-test/r/commit_1innodb.result | 4 ++-- .../suite/innodb_plugin/r/innodb_bug54453.result | 9 +++++++++ .../suite/innodb_plugin/t/innodb_bug54453.test | 15 +++++++++++++++ sql/sql_table.cc | 8 ++++++++ 5 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_bug54453.result create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug54453.test diff --git a/mysql-test/include/commit.inc b/mysql-test/include/commit.inc index d91ba8291fd..d412eae8364 100644 --- a/mysql-test/include/commit.inc +++ b/mysql-test/include/commit.inc @@ -725,9 +725,9 @@ call p_verify_status_increment(4, 4, 4, 4); alter table t3 add column (b int); call p_verify_status_increment(2, 0, 2, 0); alter table t3 rename t4; -call p_verify_status_increment(2, 2, 2, 2); +call p_verify_status_increment(1, 0, 1, 0); rename table t4 to t3; -call p_verify_status_increment(2, 2, 2, 2); +call p_verify_status_increment(1, 0, 1, 0); truncate table t3; call p_verify_status_increment(4, 4, 4, 4); create view v1 as select * from t2; diff --git a/mysql-test/r/commit_1innodb.result b/mysql-test/r/commit_1innodb.result index 51c4ac3002c..1f0b2c8019b 100644 --- a/mysql-test/r/commit_1innodb.result +++ b/mysql-test/r/commit_1innodb.result @@ -841,11 +841,11 @@ call p_verify_status_increment(2, 0, 2, 0); SUCCESS alter table t3 rename t4; -call p_verify_status_increment(2, 2, 2, 2); +call p_verify_status_increment(1, 0, 1, 0); SUCCESS rename table t4 to t3; -call p_verify_status_increment(2, 2, 2, 2); +call p_verify_status_increment(1, 0, 1, 0); SUCCESS truncate table t3; diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug54453.result b/mysql-test/suite/innodb_plugin/r/innodb_bug54453.result new file mode 100644 index 00000000000..e623989a9d4 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug54453.result @@ -0,0 +1,9 @@ +# +# Bug#54453: Failing assertion: trx->active_trans when renaming a table with active trx +# +DROP TABLE IF EXISTS bug54453; +CREATE TABLE bug54453(a INT) ENGINE=InnoDB; +ALTER TABLE bug54453 RENAME TO bug54453_2; +SELECT * FROM bug54453_2; +a +DROP TABLE bug54453_2; diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug54453.test b/mysql-test/suite/innodb_plugin/t/innodb_bug54453.test new file mode 100644 index 00000000000..486695d326d --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug54453.test @@ -0,0 +1,15 @@ +--source include/have_innodb_plugin.inc +--source include/have_log_bin.inc + +--echo # +--echo # Bug#54453: Failing assertion: trx->active_trans when renaming a table with active trx +--echo # + +--disable_warnings +DROP TABLE IF EXISTS bug54453; +--enable_warnings + +CREATE TABLE bug54453(a INT) ENGINE=InnoDB; +ALTER TABLE bug54453 RENAME TO bug54453_2; +SELECT * FROM bug54453_2; +DROP TABLE bug54453_2; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 50045ec6d90..47b91fcca0e 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -6848,6 +6848,14 @@ view_err: if (!error && (new_name != table_name || new_db != db)) { thd_proc_info(thd, "rename"); + + /* + Workaround InnoDB ending the transaction when the table instance + is unlocked/closed (close_cached_table below), otherwise the trx + state will differ between the server and storage engine layers. + */ + ha_autocommit_or_rollback(thd, 0); + /* Then do a 'simple' rename of the table. First we need to close all instances of 'source' table. From c36fee08f6fa7974324438572a260101335cb4b4 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 20 Jul 2010 14:44:29 -0300 Subject: [PATCH 109/112] Bug#52514: mysql 5.1 do_abi_check does not compile w/ gcc4.5 due to GCC preprocessor change The problem is that newer GCC versions treats missing headers as fatal errors. The solution is to use a guard macro to prevent the inclusion of system headers when checking the ABI with the C Preprocessor. Reference: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15638 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44836 Makefile.am: Define guard macro. configure.in: Remove workaround. include/mysql.h: Guard the header inclusion. include/mysql.h.pp: Header is not included anymore. --- Makefile.am | 2 +- configure.in | 11 +---------- include/mysql.h | 2 ++ include/mysql.h.pp | 1 - 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/Makefile.am b/Makefile.am index 7953b81fb7b..4ce753ad8aa 100644 --- a/Makefile.am +++ b/Makefile.am @@ -314,7 +314,7 @@ abi_check_all: $(TEST_PREPROCESSOR_HEADER) do_abi_check: set -ex; \ for file in $(abi_headers); do \ - @CC@ -E -nostdinc -dI \ + @CC@ -E -nostdinc -dI -DMYSQL_ABI_CHECK \ -I$(top_srcdir)/include \ -I$(top_srcdir)/include/mysql \ -I$(top_srcdir)/sql \ diff --git a/configure.in b/configure.in index 0264c351b07..8dcdecf8ea2 100644 --- a/configure.in +++ b/configure.in @@ -444,16 +444,7 @@ if test "$GCC" != "yes" || expr "$CC" : ".*icc.*" then ABI_CHECK="" else - # Workaround GCC >= 4.5 - See Bug#52514 - case `$CC -dumpversion` in - [[4-9]].[[5-9]]*) - AC_MSG_WARN([ABI check disabled (GCC >= 4.5)]) - ABI_CHECK="" - ;; - *) - ABI_CHECK="abi_check" - ;; - esac + ABI_CHECK="abi_check" fi AC_SUBST(ABI_CHECK) diff --git a/include/mysql.h b/include/mysql.h index d114afb6c93..dcf3e167e6a 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -44,7 +44,9 @@ extern "C" { #endif #ifndef _global_h /* If not standard header */ +#ifndef MYSQL_ABI_CHECK #include +#endif #ifdef __LCC__ #include /* For windows */ #endif diff --git a/include/mysql.h.pp b/include/mysql.h.pp index 633cde41130..0a397863022 100644 --- a/include/mysql.h.pp +++ b/include/mysql.h.pp @@ -1,4 +1,3 @@ -#include typedef char my_bool; typedef int my_socket; #include "mysql_version.h" From 9a5fa17fd3c4885262e31bf14cf495d02e5f6b27 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 20 Jul 2010 15:07:36 -0300 Subject: [PATCH 110/112] Bug#45288: pb2 returns a lot of compilation warnings on linux Fix warnings flagged by the new warning option -Wunused-but-set-variable that was added to GCC 4.6 and that is enabled by -Wunused and -Wall. The option causes a warning whenever a local variable is assigned to but is later unused. It also warns about meaningless pointer dereferences. client/mysql.cc: Meaningless pointer dereferences. client/mysql_upgrade.c: Check whether reading from the file succeeded. extra/comp_err.c: Unused. extra/yassl/src/yassl_imp.cpp: Skip instead of reading data that is discarded. include/my_pthread.h: Variable is only used in debug builds. include/mysys_err.h: Add new error messages. mysys/errors.c: Add new error message for permission related functions. mysys/mf_iocache.c: Variable is only checked under THREAD. mysys/my_copy.c: Raise a error if chmod or chown fails. mysys/my_redel.c: Raise a error if chmod or chown fails. regex/engine.c: Use a equivalent variable for the assert. server-tools/instance-manager/instance_options.cc: Unused. sql/field.cc: Unused. sql/item.cc: Unused. sql/log.cc: Do not ignore the return value of freopen: only set buffer if reopening succeeds. Adjust doxygen comment to the right function. Pass message lenght to log function. sql/mysqld.cc: Do not ignore the return value of freopen: only set buffer if reopening succeeds. sql/partition_info.cc: Unused. sql/slave.cc: No need to set pointer to the address of '\0'. sql/spatial.cc: Unused. Left for historical purposes. sql/sql_acl.cc: Unused. sql/sql_base.cc: Pointers are always set to the same variables. sql/sql_parse.cc: End statement if reading fails. Store the buffer after it has actually been updated. sql/sql_repl.cc: No need to set pointer to the address of '\0'. sql/sql_show.cc: Put variable under the same ifdef block. sql/udf_example.c: Set null pointer flag appropriately. storage/csv/ha_tina.cc: Meaningless dereferences. storage/example/ha_example.cc: Return the error since it's available. storage/myisam/mi_locking.c: Remove unused and dead code. --- client/mysql.cc | 4 +- client/mysql_upgrade.c | 5 +- extra/comp_err.c | 2 - extra/yassl/src/yassl_imp.cpp | 24 ++---- include/my_pthread.h | 5 +- include/mysys_err.h | 4 +- mysys/errors.c | 6 +- mysys/mf_iocache.c | 11 ++- mysys/my_copy.c | 20 ++++- mysys/my_redel.c | 24 ++++-- regex/engine.c | 17 ++--- .../instance-manager/instance_options.cc | 3 - sql/field.cc | 2 - sql/item.cc | 7 +- sql/log.cc | 73 ++++++++++--------- sql/mysqld.cc | 7 +- sql/partition_info.cc | 2 - sql/slave.cc | 7 +- sql/spatial.cc | 3 +- sql/sql_acl.cc | 2 - sql/sql_base.cc | 14 +--- sql/sql_load.cc | 13 ++-- sql/sql_parse.cc | 17 +++-- sql/sql_repl.cc | 7 +- sql/sql_show.cc | 4 +- sql/sql_table.cc | 2 - sql/table.cc | 3 +- sql/udf_example.c | 2 +- storage/csv/ha_tina.cc | 12 +-- storage/example/ha_example.cc | 2 +- storage/myisam/mi_locking.c | 14 +--- storage/myisam/rt_split.c | 3 - storage/myisammrg/myrg_open.c | 5 -- strings/decimal.c | 3 +- 34 files changed, 155 insertions(+), 174 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index edcc72b60bf..5b90f318629 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -3639,7 +3639,7 @@ xmlencode_print(const char *src, uint length) tee_fputs("NULL", PAGER); else { - for (const char *p = src; length; *p++, length--) + for (const char *p = src; length; p++, length--) { const char *t; if ((t = array_value(xmlmeta, *p))) @@ -4726,7 +4726,7 @@ static const char* construct_prompt() struct tm *t = localtime(&lclock); /* parse thru the settings for the prompt */ - for (char *c = current_prompt; *c ; *c++) + for (char *c = current_prompt; *c ; c++) { if (*c != PROMPT_CHAR) processed_prompt.append(*c); diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 0b8b43775ed..3122cc25731 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -595,7 +595,10 @@ static int upgrade_already_done(void) my_fclose(in, MYF(0)); - return (strncmp(buf, MYSQL_SERVER_VERSION, + if (!res) + return 0; /* Could not read from file => not sure */ + + return (strncmp(res, MYSQL_SERVER_VERSION, sizeof(MYSQL_SERVER_VERSION)-1)==0); } diff --git a/extra/comp_err.c b/extra/comp_err.c index c02c7ca3d2a..7e0b47a7dc7 100644 --- a/extra/comp_err.c +++ b/extra/comp_err.c @@ -831,7 +831,6 @@ static struct message *parse_message_string(struct message *new_message, static struct errors *parse_error_string(char *str, int er_count) { struct errors *new_error; - char *start; DBUG_ENTER("parse_error_string"); DBUG_PRINT("enter", ("str: %s", str)); @@ -842,7 +841,6 @@ static struct errors *parse_error_string(char *str, int er_count) DBUG_RETURN(0); /* OOM: Fatal error */ /* getting the error name */ - start= str; str= skip_delimiters(str); if (!(new_error->er_name= get_word(&str))) diff --git a/extra/yassl/src/yassl_imp.cpp b/extra/yassl/src/yassl_imp.cpp index f079df8c7ce..86799f961ae 100644 --- a/extra/yassl/src/yassl_imp.cpp +++ b/extra/yassl/src/yassl_imp.cpp @@ -884,21 +884,19 @@ void Alert::Process(input_buffer& input, SSL& ssl) else hmac(ssl, verify, data, aSz, alert, true); - // read mac and fill + // read mac and skip fill int digestSz = ssl.getCrypto().get_digest().get_digestSize(); opaque mac[SHA_LEN]; input.read(mac, digestSz); if (ssl.getSecurity().get_parms().cipher_type_ == block) { int ivExtra = 0; - opaque fill; if (ssl.isTLSv1_1()) ivExtra = ssl.getCrypto().get_cipher().get_blockSize(); int padSz = ssl.getSecurity().get_parms().encrypt_size_ - ivExtra - aSz - digestSz; - for (int i = 0; i < padSz; i++) - fill = input[AUTO]; + input.set_current(input.get_current() + padSz); } // verify @@ -981,17 +979,17 @@ output_buffer& operator<<(output_buffer& output, const Data& data) void Data::Process(input_buffer& input, SSL& ssl) { int msgSz = ssl.getSecurity().get_parms().encrypt_size_; - int pad = 0, padByte = 0; + int pad = 0, padSz = 0; int ivExtra = 0; if (ssl.getSecurity().get_parms().cipher_type_ == block) { if (ssl.isTLSv1_1()) // IV ivExtra = ssl.getCrypto().get_cipher().get_blockSize(); pad = *(input.get_buffer() + input.get_current() + msgSz -ivExtra - 1); - padByte = 1; + padSz = 1; } int digestSz = ssl.getCrypto().get_digest().get_digestSize(); - int dataSz = msgSz - ivExtra - digestSz - pad - padByte; + int dataSz = msgSz - ivExtra - digestSz - pad - padSz; opaque verify[SHA_LEN]; const byte* rawData = input.get_buffer() + input.get_current(); @@ -1020,14 +1018,10 @@ void Data::Process(input_buffer& input, SSL& ssl) hmac(ssl, verify, rawData, dataSz, application_data, true); } - // read mac and fill + // read mac and skip fill opaque mac[SHA_LEN]; - opaque fill; input.read(mac, digestSz); - for (int i = 0; i < pad; i++) - fill = input[AUTO]; - if (padByte) - fill = input[AUTO]; + input.set_current(input.get_current() + pad + padSz); // verify if (dataSz) { @@ -2073,11 +2067,9 @@ void Finished::Process(input_buffer& input, SSL& ssl) if (ssl.isTLSv1_1()) ivExtra = ssl.getCrypto().get_cipher().get_blockSize(); - opaque fill; int padSz = ssl.getSecurity().get_parms().encrypt_size_ - ivExtra - HANDSHAKE_HEADER - finishedSz - digestSz; - for (int i = 0; i < padSz; i++) - fill = input[AUTO]; + input.set_current(input.get_current() + padSz); // verify mac if (memcmp(mac, verifyMAC, digestSz)) { diff --git a/include/my_pthread.h b/include/my_pthread.h index eff6a677192..fec7c972a7b 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -269,13 +269,14 @@ int sigwait(sigset_t *setp, int *sigp); /* Use our implemention */ we want to make sure that no such flags are set. */ #if defined(HAVE_SIGACTION) && !defined(my_sigset) -#define my_sigset(A,B) do { struct sigaction l_s; sigset_t l_set; int l_rc; \ +#define my_sigset(A,B) do { struct sigaction l_s; sigset_t l_set; \ + IF_DBUG(int l_rc); \ DBUG_ASSERT((A) != 0); \ sigemptyset(&l_set); \ l_s.sa_handler = (B); \ l_s.sa_mask = l_set; \ l_s.sa_flags = 0; \ - l_rc= sigaction((A), &l_s, (struct sigaction *) NULL);\ + IF_DBUG(l_rc=) sigaction((A), &l_s, NULL); \ DBUG_ASSERT(l_rc == 0); \ } while (0) #elif defined(HAVE_SIGSET) && !defined(my_sigset) diff --git a/include/mysys_err.h b/include/mysys_err.h index 09e77248c17..6294b37f773 100644 --- a/include/mysys_err.h +++ b/include/mysys_err.h @@ -62,7 +62,9 @@ extern const char * NEAR globerrs[]; /* my_error_messages is here */ #define EE_UNKNOWN_COLLATION 28 #define EE_FILENOTFOUND 29 #define EE_FILE_NOT_CLOSED 30 -#define EE_ERROR_LAST 30 /* Copy last error nr */ +#define EE_CHANGE_OWNERSHIP 31 +#define EE_CHANGE_PERMISSIONS 32 +#define EE_ERROR_LAST 32 /* Copy last error nr */ /* Add error numbers before EE_ERROR_LAST and change it accordingly. */ /* exit codes for all MySQL programs */ diff --git a/mysys/errors.c b/mysys/errors.c index 8d3303cac9f..a5ad4a956ab 100644 --- a/mysys/errors.c +++ b/mysys/errors.c @@ -49,7 +49,9 @@ const char * NEAR globerrs[GLOBERRS]= "Can't sync file '%s' to disk (Errcode: %d)", "Collation '%s' is not a compiled collation and is not specified in the '%s' file", "File '%s' not found (Errcode: %d)", - "File '%s' (fileno: %d) was not closed" + "File '%s' (fileno: %d) was not closed", + "Can't change ownership of the file '%s' (Errcode: %d)", + "Can't change permissions of the file '%s' (Errcode: %d)", }; void init_glob_errs(void) @@ -90,6 +92,8 @@ void init_glob_errs() EE(EE_UNKNOWN_COLLATION)= "Collation '%s' is not a compiled collation and is not specified in the %s file"; EE(EE_FILENOTFOUND) = "File '%s' not found (Errcode: %d)"; EE(EE_FILE_NOT_CLOSED) = "File '%s' (fileno: %d) was not closed"; + EE(EE_CHANGE_OWNERSHIP) = "Can't change ownership of the file '%s' (Errcode: %d)"; + EE(EE_CHANGE_PERMISSIONS) = "Can't change permissions of the file '%s' (Errcode: %d)"; } #endif diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index 1a47982b221..e9b947b04a6 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -1701,16 +1701,19 @@ int my_block_write(register IO_CACHE *info, const uchar *Buffer, size_t Count, #endif -int my_b_flush_io_cache(IO_CACHE *info, int need_append_buffer_lock) +int my_b_flush_io_cache(IO_CACHE *info, + int need_append_buffer_lock __attribute__((unused))) { size_t length; - my_bool append_cache; my_off_t pos_in_file; + my_bool append_cache= (info->type == SEQ_READ_APPEND); DBUG_ENTER("my_b_flush_io_cache"); DBUG_PRINT("enter", ("cache: 0x%lx", (long) info)); - if (!(append_cache = (info->type == SEQ_READ_APPEND))) - need_append_buffer_lock=0; +#ifdef THREAD + if (!append_cache) + need_append_buffer_lock= 0; +#endif if (info->type == WRITE_CACHE || append_cache) { diff --git a/mysys/my_copy.c b/mysys/my_copy.c index 418e2b6f8a2..d0c1fc29229 100644 --- a/mysys/my_copy.c +++ b/mysys/my_copy.c @@ -16,6 +16,7 @@ #include "mysys_priv.h" #include /* for stat */ #include +#include "mysys_err.h" #if defined(HAVE_UTIME_H) #include #elif defined(HAVE_SYS_UTIME_H) @@ -56,7 +57,6 @@ int my_copy(const char *from, const char *to, myf MyFlags) File from_file,to_file; uchar buff[IO_SIZE]; MY_STAT stat_buff,new_stat_buff; - int res; DBUG_ENTER("my_copy"); DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags)); @@ -102,9 +102,23 @@ int my_copy(const char *from, const char *to, myf MyFlags) if (MyFlags & MY_HOLD_ORIGINAL_MODES && !new_file_stat) DBUG_RETURN(0); /* File copyed but not stat */ - res= chmod(to, stat_buff.st_mode & 07777); /* Copy modes */ + /* Copy modes */ + if (chmod(to, stat_buff.st_mode & 07777)) + { + my_errno= errno; + if (MyFlags & (MY_FAE+MY_WME)) + my_error(EE_CHANGE_PERMISSIONS, MYF(ME_BELL+ME_WAITTANG), from, errno); + goto err; + } #if !defined(__WIN__) && !defined(__NETWARE__) - res= chown(to, stat_buff.st_uid,stat_buff.st_gid); /* Copy ownership */ + /* Copy ownership */ + if (chown(to, stat_buff.st_uid,stat_buff.st_gid)) + { + my_errno= errno; + if (MyFlags & (MY_FAE+MY_WME)) + my_error(EE_CHANGE_OWNERSHIP, MYF(ME_BELL+ME_WAITTANG), from, errno); + goto err; + } #endif #if !defined(VMS) && !defined(__ZTC__) if (MyFlags & MY_COPYTIME) diff --git a/mysys/my_redel.c b/mysys/my_redel.c index 6521253f949..4013c5c8323 100644 --- a/mysys/my_redel.c +++ b/mysys/my_redel.c @@ -76,11 +76,8 @@ end: int my_copystat(const char *from, const char *to, int MyFlags) { struct stat statbuf; -#if !defined(__WIN__) && !defined(__NETWARE__) - int res; -#endif - if (stat((char*) from, &statbuf)) + if (stat(from, &statbuf)) { my_errno=errno; if (MyFlags & (MY_FAE+MY_WME)) @@ -89,7 +86,15 @@ int my_copystat(const char *from, const char *to, int MyFlags) } if ((statbuf.st_mode & S_IFMT) != S_IFREG) return 1; - VOID(chmod(to, statbuf.st_mode & 07777)); /* Copy modes */ + + /* Copy modes */ + if (chmod(to, statbuf.st_mode & 07777)) + { + my_errno= errno; + if (MyFlags & (MY_FAE+MY_WME)) + my_error(EE_CHANGE_PERMISSIONS, MYF(ME_BELL+ME_WAITTANG), from, errno); + return -1; + } #if !defined(__WIN__) && !defined(__NETWARE__) if (statbuf.st_nlink > 1 && MyFlags & MY_LINK_WARNING) @@ -97,7 +102,14 @@ int my_copystat(const char *from, const char *to, int MyFlags) if (MyFlags & MY_LINK_WARNING) my_error(EE_LINK_WARNING,MYF(ME_BELL+ME_WAITTANG),from,statbuf.st_nlink); } - res= chown(to, statbuf.st_uid, statbuf.st_gid); /* Copy ownership */ + /* Copy ownership */ + if (chown(to, statbuf.st_uid, statbuf.st_gid)) + { + my_errno= errno; + if (MyFlags & (MY_FAE+MY_WME)) + my_error(EE_CHANGE_OWNERSHIP, MYF(ME_BELL+ME_WAITTANG), from, errno); + return -1; + } #endif /* !__WIN__ && !__NETWARE__ */ #ifndef VMS diff --git a/regex/engine.c b/regex/engine.c index 1968ca61a96..be08adf8601 100644 --- a/regex/engine.c +++ b/regex/engine.c @@ -256,7 +256,6 @@ sopno stopst; register char *ssp; /* start of string matched by subsubRE */ register char *sep; /* end of string matched by subsubRE */ register char *oldssp; /* previous ssp */ - register char *dp; /* used in debug mode to check asserts */ AT("diss", start, stop, startst, stopst); sp = start; @@ -314,11 +313,9 @@ sopno stopst; ssub = ss + 1; esub = es - 1; /* did innards match? */ - if (slow(charset, m, sp, rest, ssub, esub) != NULL) { - dp = dissect(charset, m, sp, rest, ssub, esub); - assert(dp == rest); - } else /* no */ - assert(sp == rest); + if (slow(charset, m, sp, rest, ssub, esub) != NULL) + sp = dissect(charset, m, sp, rest, ssub, esub); + assert(sp == rest); sp = rest; break; case OPLUS_: @@ -353,8 +350,8 @@ sopno stopst; } assert(sep == rest); /* must exhaust substring */ assert(slow(charset, m, ssp, sep, ssub, esub) == rest); - dp = dissect(charset, m, ssp, sep, ssub, esub); - assert(dp == sep); + sp = dissect(charset, m, ssp, sep, ssub, esub); + assert(sp == sep); sp = rest; break; case OCH_: @@ -388,8 +385,8 @@ sopno stopst; else assert(OP(m->g->strip[esub]) == O_CH); } - dp = dissect(charset, m, sp, rest, ssub, esub); - assert(dp == rest); + sp = dissect(charset, m, sp, rest, ssub, esub); + assert(sp == rest); sp = rest; break; case O_PLUS: diff --git a/server-tools/instance-manager/instance_options.cc b/server-tools/instance-manager/instance_options.cc index 8b96d6f0f96..725089e2f42 100644 --- a/server-tools/instance-manager/instance_options.cc +++ b/server-tools/instance-manager/instance_options.cc @@ -303,7 +303,6 @@ bool Instance_options::fill_log_options() enum { MAX_LOG_OPTION_LENGTH= 256 }; char datadir[MAX_LOG_OPTION_LENGTH]; char hostname[MAX_LOG_OPTION_LENGTH]; - uint hostname_length; struct log_files_st { const char *name; @@ -335,8 +334,6 @@ bool Instance_options::fill_log_options() strmov(hostname, "mysql"); hostname[MAX_LOG_OPTION_LENGTH - 1]= 0; /* Safety */ - hostname_length= strlen(hostname); - for (log_files= logs_st; log_files->name; log_files++) { diff --git a/sql/field.cc b/sql/field.cc index c648b53e139..c887a5f1c9b 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -5541,7 +5541,6 @@ int Field_date::store(const char *from, uint len,CHARSET_INFO *cs) int Field_date::store(double nr) { longlong tmp; - int error= 0; if (nr >= 19000000000000.0 && nr <= 99991231235959.0) nr=floor(nr/1000000.0); // Timestamp to date if (nr < 0.0 || nr > 99991231.0) @@ -5550,7 +5549,6 @@ int Field_date::store(double nr) set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_DATE); - error= 1; } else tmp= (longlong) rint(nr); diff --git a/sql/item.cc b/sql/item.cc index db2c4c0974b..66c5314c16e 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -255,11 +255,10 @@ my_decimal *Item::val_decimal_from_int(my_decimal *decimal_value) my_decimal *Item::val_decimal_from_string(my_decimal *decimal_value) { String *res; - char *end_ptr; - if (!(res= val_str(&str_value))) - return 0; // NULL or EOM - end_ptr= (char*) res->ptr()+ res->length(); + if (!(res= val_str(&str_value))) + return NULL; + if (str2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_BAD_NUM, res->ptr(), res->length(), res->charset(), decimal_value) & E_DEC_BAD_NUM) diff --git a/sql/log.cc b/sql/log.cc index d8d5f6fa418..614a07e6b63 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -5050,6 +5050,22 @@ void sql_perror(const char *message) } +/* + Unfortunately, there seems to be no good way + to restore the original streams upon failure. +*/ +static bool redirect_std_streams(const char *file) +{ + if (freopen(file, "a+", stdout) && freopen(file, "a+", stderr)) + { + setbuf(stderr, NULL); + return FALSE; + } + + return TRUE; +} + + bool flush_error_log() { bool result=0; @@ -5077,11 +5093,7 @@ bool flush_error_log() setbuf(stderr, NULL); (void) my_delete(err_renamed, MYF(0)); my_rename(log_error_file,err_renamed,MYF(0)); - if (freopen(log_error_file,"a+",stdout)) - { - freopen(log_error_file,"a+",stderr); - setbuf(stderr, NULL); - } + redirect_std_streams(log_error_file); if ((fd = my_open(err_temp, O_RDONLY, MYF(0))) >= 0) { @@ -5096,13 +5108,7 @@ bool flush_error_log() result= 1; #else my_rename(log_error_file,err_renamed,MYF(0)); - if (freopen(log_error_file,"a+",stdout)) - { - FILE *reopen; - reopen= freopen(log_error_file,"a+",stderr); - setbuf(stderr, NULL); - } - else + if (redirect_std_streams(log_error_file)) result= 1; #endif VOID(pthread_mutex_unlock(&LOCK_error_log)); @@ -5153,25 +5159,9 @@ static void print_buffer_to_nt_eventlog(enum loglevel level, char *buff, #endif /* __NT__ */ -/** - Prints a printf style message to the error log and, under NT, to the - Windows event log. - - This function prints the message into a buffer and then sends that buffer - to other functions to write that message to other logging sources. - - @param event_type Type of event to write (Error, Warning, or Info) - @param format Printf style format of message - @param args va_list list of arguments for the message - - @returns - The function always returns 0. The return value is present in the - signature to be compatible with other logging routines, which could - return an error (e.g. logging to the log tables) -*/ - #ifndef EMBEDDED_LIBRARY -static void print_buffer_to_file(enum loglevel level, const char *buffer) +static void print_buffer_to_file(enum loglevel level, const char *buffer, + size_t length) { time_t skr; struct tm tm_tmp; @@ -5185,7 +5175,7 @@ static void print_buffer_to_file(enum loglevel level, const char *buffer) localtime_r(&skr, &tm_tmp); start=&tm_tmp; - fprintf(stderr, "%02d%02d%02d %2d:%02d:%02d [%s] %s\n", + fprintf(stderr, "%02d%02d%02d %2d:%02d:%02d [%s] %.*s\n", start->tm_year % 100, start->tm_mon+1, start->tm_mday, @@ -5194,7 +5184,7 @@ static void print_buffer_to_file(enum loglevel level, const char *buffer) start->tm_sec, (level == ERROR_LEVEL ? "ERROR" : level == WARNING_LEVEL ? "Warning" : "Note"), - buffer); + (int) length, buffer); fflush(stderr); @@ -5202,7 +5192,22 @@ static void print_buffer_to_file(enum loglevel level, const char *buffer) DBUG_VOID_RETURN; } +/** + Prints a printf style message to the error log and, under NT, to the + Windows event log. + This function prints the message into a buffer and then sends that buffer + to other functions to write that message to other logging sources. + + @param level The level of the msg significance + @param format Printf style format of message + @param args va_list list of arguments for the message + + @returns + The function always returns 0. The return value is present in the + signature to be compatible with other logging routines, which could + return an error (e.g. logging to the log tables) +*/ int vprint_msg_to_log(enum loglevel level, const char *format, va_list args) { char buff[1024]; @@ -5210,7 +5215,7 @@ int vprint_msg_to_log(enum loglevel level, const char *format, va_list args) DBUG_ENTER("vprint_msg_to_log"); length= my_vsnprintf(buff, sizeof(buff), format, args); - print_buffer_to_file(level, buff); + print_buffer_to_file(level, buff, length); #ifdef __NT__ print_buffer_to_nt_eventlog(level, buff, length, sizeof(buff)); @@ -5218,7 +5223,7 @@ int vprint_msg_to_log(enum loglevel level, const char *format, va_list args) DBUG_RETURN(0); } -#endif /*EMBEDDED_LIBRARY*/ +#endif /* EMBEDDED_LIBRARY */ void sql_print_error(const char *format, ...) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 99f16b36dfa..fda64e5a1ea 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3783,7 +3783,6 @@ static void end_ssl() static int init_server_components() { - FILE* reopen; DBUG_ENTER("init_server_components"); /* We need to call each of these following functions to ensure that @@ -3826,8 +3825,8 @@ static int init_server_components() if (freopen(log_error_file, "a+", stdout)) #endif { - reopen= freopen(log_error_file, "a+", stderr); - setbuf(stderr, NULL); + if (freopen(log_error_file, "a+", stderr)) + setbuf(stderr, NULL); } } } @@ -8222,7 +8221,7 @@ mysqld_get_one_option(int optid, *val= 0; val+= 2; while (*val && my_isspace(mysqld_charset, *val)) - *val++; + val++; if (!*val) { sql_print_error("Bad syntax in replicate-rewrite-db - empty TO db!\n"); diff --git a/sql/partition_info.cc b/sql/partition_info.cc index d85888e295c..f37151ea51d 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -1206,13 +1206,11 @@ bool partition_info::set_up_charset_field_preps() i= 0; while ((field= *(ptr++))) { - CHARSET_INFO *cs; uchar *field_buf; LINT_INIT(field_buf); if (!field_is_partition_charset(field)) continue; - cs= ((Field_str*)field)->charset(); size= field->pack_length(); if (!(field_buf= (uchar*) sql_calloc(size))) goto error; diff --git a/sql/slave.cc b/sql/slave.cc index 795bc481071..f1e0962e7e8 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -3035,11 +3035,8 @@ log '%s' at position %s, relay log '%s' position: %s", RPL_LOG_NAME, pthread_mutex_lock(&rli->data_lock); if (rli->slave_skip_counter) { - char *pos; - pos= strmake(saved_log_name, rli->group_relay_log_name, FN_REFLEN - 1); - pos= '\0'; - pos= strmake(saved_master_log_name, rli->group_master_log_name, FN_REFLEN - 1); - pos= '\0'; + strmake(saved_log_name, rli->group_relay_log_name, FN_REFLEN - 1); + strmake(saved_master_log_name, rli->group_master_log_name, FN_REFLEN - 1); saved_log_pos= rli->group_relay_log_pos; saved_master_log_pos= rli->group_master_log_pos; saved_skip= rli->slave_skip_counter; diff --git a/sql/spatial.cc b/sql/spatial.cc index 11df6c00dc5..2305a8eb97d 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -159,11 +159,10 @@ Geometry *Geometry::construct(Geometry_buffer *buffer, { uint32 geom_type; Geometry *result; - char byte_order; if (data_len < SRID_SIZE + WKB_HEADER_SIZE) // < 4 + (1 + 4) return NULL; - byte_order= data[SRID_SIZE]; + /* + 1 to skip the byte order (stored in position SRID_SIZE). */ geom_type= uint4korr(data + SRID_SIZE + 1); if (!(result= create_by_typeid(buffer, (int) geom_type))) return NULL; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 90eef872115..b507b70d1fb 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -5701,7 +5701,6 @@ bool mysql_create_user(THD *thd, List &list) { int result; String wrong_users; - ulong sql_mode; LEX_USER *user_name, *tmp_user_name; List_iterator user_list(list); TABLE_LIST tables[GRANT_TABLES]; @@ -5748,7 +5747,6 @@ bool mysql_create_user(THD *thd, List &list) } some_users_created= TRUE; - sql_mode= thd->variables.sql_mode; if (replace_user_table(thd, tables[0].table, *user_name, 0, 0, 1, 0)) { append_user(&wrong_users, user_name); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index d2392bdd9b1..c38526a6d0b 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5674,7 +5674,7 @@ static void update_field_dependencies(THD *thd, Field *field, TABLE *table) DBUG_ENTER("update_field_dependencies"); if (thd->mark_used_columns != MARK_COLUMNS_NONE) { - MY_BITMAP *current_bitmap, *other_bitmap; + MY_BITMAP *bitmap; /* We always want to register the used keys, as the column bitmap may have @@ -5685,15 +5685,9 @@ static void update_field_dependencies(THD *thd, Field *field, TABLE *table) table->merge_keys.merge(field->part_of_key); if (thd->mark_used_columns == MARK_COLUMNS_READ) - { - current_bitmap= table->read_set; - other_bitmap= table->write_set; - } + bitmap= table->read_set; else - { - current_bitmap= table->write_set; - other_bitmap= table->read_set; - } + bitmap= table->write_set; /* The test-and-set mechanism in the bitmap is not reliable during @@ -5702,7 +5696,7 @@ static void update_field_dependencies(THD *thd, Field *field, TABLE *table) only those columns that are used in the SET clause. I.e they are being set here. See multi_update::prepare() */ - if (bitmap_fast_test_and_set(current_bitmap, field->field_index)) + if (bitmap_fast_test_and_set(bitmap, field->field_index)) { if (thd->mark_used_columns == MARK_COLUMNS_WRITE) { diff --git a/sql/sql_load.cc b/sql/sql_load.cc index ee7481234a4..a4cf46b35e8 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -128,6 +128,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, bool is_fifo=0; #ifndef EMBEDDED_LIBRARY LOAD_FILE_INFO lf_info; + THD::killed_state killed_status; #endif char *db = table_list->db; // This is never null /* @@ -138,7 +139,6 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, char *tdb= thd->db ? thd->db : db; // Result is never null ulong skip_lines= ex->skip_lines; bool transactional_table; - THD::killed_state killed_status= THD::NOT_KILLED; DBUG_ENTER("mysql_load"); #ifdef EMBEDDED_LIBRARY @@ -455,7 +455,11 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, error=1; thd->killed= THD::KILL_QUERY; };); - killed_status= (error == 0)? THD::NOT_KILLED : thd->killed; + +#ifndef EMBEDDED_LIBRARY + killed_status= (error == 0) ? THD::NOT_KILLED : thd->killed; +#endif + /* We must invalidate the table in query cache before binlog writing and ha_autocommit_... @@ -708,12 +712,9 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, List_iterator_fast it(fields_vars); Item_field *sql_field; TABLE *table= table_list->table; - ulonglong id; bool err; DBUG_ENTER("read_fixed_length"); - id= 0; - while (!read_info.read_fixed_length()) { if (thd->killed) @@ -839,12 +840,10 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, Item *item; TABLE *table= table_list->table; uint enclosed_length; - ulonglong id; bool err; DBUG_ENTER("read_sep_field"); enclosed_length=enclosed.length(); - id= 0; for (;;it.rewind()) { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1f3d29ffec0..134517e5bf7 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -465,6 +465,12 @@ static void handle_bootstrap_impl(THD *thd) } buff= (char*) thd->net.buff; res= fgets(buff + length, thd->net.max_packet - length, file); + if (!res && !feof(file)) + { + net_end_statement(thd); + bootstrap_error= 1; + break; + } length+= (ulong) strlen(buff + length); /* purecov: end */ } @@ -1535,7 +1541,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, { STATUS_VAR current_global_status_var; ulong uptime; - uint length; + uint length __attribute__((unused)); ulonglong queries_per_second1000; char buff[250]; uint buff_len= sizeof(buff); @@ -1548,7 +1554,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, else queries_per_second1000= thd->query_id * LL(1000) / uptime; - length= my_snprintf((char*) buff, buff_len - 1, + length= my_snprintf(buff, buff_len - 1, "Uptime: %lu Threads: %d Questions: %lu " "Slow queries: %lu Opens: %lu Flush tables: %lu " "Open tables: %u Queries per second avg: %u.%u", @@ -1560,10 +1566,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd, cached_open_tables(), (uint) (queries_per_second1000 / 1000), (uint) (queries_per_second1000 % 1000)); -#ifdef EMBEDDED_LIBRARY - /* Store the buffer in permanent memory */ - my_ok(thd, 0, 0, buff); -#endif #ifdef SAFEMALLOC if (sf_malloc_cur_memory) // Using SAFEMALLOC { @@ -1578,6 +1580,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd, VOID(my_net_write(net, (uchar*) buff, length)); VOID(net_flush(net)); thd->main_da.disable_status(); +#else + /* Store the buffer in permanent memory */ + my_ok(thd, 0, 0, buff); #endif break; } diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index f6045e4704e..d7dd3eb63f2 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1168,12 +1168,9 @@ bool change_master(THD* thd, Master_info* mi) /* Before processing the command, save the previous state. */ - char *pos; - pos= strmake(saved_host, mi->host, HOSTNAME_LENGTH); - pos= '\0'; + strmake(saved_host, mi->host, HOSTNAME_LENGTH); saved_port= mi->port; - pos= strmake(saved_log_name, mi->master_log_name, FN_REFLEN - 1); - pos= '\0'; + strmake(saved_log_name, mi->master_log_name, FN_REFLEN - 1); saved_log_pos= mi->master_log_pos; /* diff --git a/sql/sql_show.cc b/sql/sql_show.cc index d0e76e501e2..eb5d3a1965d 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -3868,7 +3868,6 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, uint flags=field->flags; char tmp[MAX_FIELD_WIDTH]; String type(tmp,sizeof(tmp), system_charset_info); - char *end; int decimals, field_length; if (wild && wild[0] && @@ -3889,7 +3888,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, field->field_name) & COL_ACLS; if (!tables->schema_table && !col_access) continue; - end= tmp; + char *end= tmp; for (uint bitnr=0; col_access ; col_access>>=1,bitnr++) { if (col_access & 1) @@ -4015,7 +4014,6 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, table->field[15]->store((const char*) pos, strlen((const char*) pos), cs); - end= tmp; if (field->unireg_check == Field::NEXT_NUMBER) table->field[16]->store(STRING_WITH_LEN("auto_increment"), cs); if (show_table->timestamp_field == field && diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 47b91fcca0e..f765e5c5cae 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -6507,7 +6507,6 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, uint index_add_count= 0; uint *index_add_buffer= NULL; uint candidate_key_count= 0; - bool committed= 0; bool no_pk; DBUG_ENTER("mysql_alter_table"); @@ -7380,7 +7379,6 @@ view_err: DBUG_PRINT("info", ("Committing before unlocking table")); if (ha_autocommit_or_rollback(thd, 0) || end_active_trans(thd)) goto err1; - committed= 1; } /*end of if (! new_table) for add/drop index*/ diff --git a/sql/table.cc b/sql/table.cc index dde3654dab1..e989ab039a0 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -534,7 +534,7 @@ int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags) int error, table_type; bool error_given; File file; - uchar head[288], *disk_buff; + uchar head[288]; char path[FN_REFLEN]; MEM_ROOT **root_ptr, *old_root; DBUG_ENTER("open_table_def"); @@ -543,7 +543,6 @@ int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags) error= 1; error_given= 0; - disk_buff= NULL; strxmov(path, share->normalized_path.str, reg_ext, NullS); if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0) diff --git a/sql/udf_example.c b/sql/udf_example.c index 637293209e0..468118b44ef 100644 --- a/sql/udf_example.c +++ b/sql/udf_example.c @@ -1067,7 +1067,7 @@ char *myfunc_argument_name(UDF_INIT *initid __attribute__((unused)), { if (!args->attributes[0]) { - null_value= 0; + *null_value= 1; return 0; } (*length)--; /* space for ending \0 (for debugging purposes) */ diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc index e3bc7f55dd2..5a3399b2401 100644 --- a/storage/csv/ha_tina.cc +++ b/storage/csv/ha_tina.cc @@ -468,7 +468,7 @@ int ha_tina::encode_quote(uchar *buf) const char *ptr; const char *end_ptr; const bool was_null= (*field)->is_null(); - + /* assistance for backwards compatibility in production builds. note: this will not work for ENUM columns. @@ -480,7 +480,7 @@ int ha_tina::encode_quote(uchar *buf) } (*field)->val_str(&attribute,&attribute); - + if (was_null) (*field)->set_null(); @@ -491,34 +491,30 @@ int ha_tina::encode_quote(uchar *buf) buffer.append('"'); - while (ptr < end_ptr) + for (; ptr < end_ptr; ptr++) { if (*ptr == '"') { buffer.append('\\'); buffer.append('"'); - *ptr++; } else if (*ptr == '\r') { buffer.append('\\'); buffer.append('r'); - *ptr++; } else if (*ptr == '\\') { buffer.append('\\'); buffer.append('\\'); - *ptr++; } else if (*ptr == '\n') { buffer.append('\\'); buffer.append('n'); - *ptr++; } else - buffer.append(*ptr++); + buffer.append(*ptr); } buffer.append('"'); } diff --git a/storage/example/ha_example.cc b/storage/example/ha_example.cc index 604722c3c8c..2a4fe538c85 100644 --- a/storage/example/ha_example.cc +++ b/storage/example/ha_example.cc @@ -153,7 +153,7 @@ static int example_done_func(void *p) hash_free(&example_open_tables); pthread_mutex_destroy(&example_mutex); - DBUG_RETURN(0); + DBUG_RETURN(error); } diff --git a/storage/myisam/mi_locking.c b/storage/myisam/mi_locking.c index 342efff4842..589b9cf89b7 100644 --- a/storage/myisam/mi_locking.c +++ b/storage/myisam/mi_locking.c @@ -29,7 +29,6 @@ int mi_lock_database(MI_INFO *info, int lock_type) int error; uint count; MYISAM_SHARE *share=info->s; - uint flag; DBUG_ENTER("mi_lock_database"); DBUG_PRINT("enter",("lock_type: %d old lock %d r_locks: %u w_locks: %u " "global_changed: %d open_count: %u name: '%s'", @@ -48,7 +47,7 @@ int mi_lock_database(MI_INFO *info, int lock_type) DBUG_RETURN(0); } - flag=error=0; + error= 0; pthread_mutex_lock(&share->intern_lock); if (share->kfile >= 0) /* May only be false on windows */ { @@ -120,14 +119,12 @@ int mi_lock_database(MI_INFO *info, int lock_type) { if (share->r_locks) { /* Only read locks left */ - flag=1; if (my_lock(share->kfile,F_RDLCK,0L,F_TO_EOF, MYF(MY_WME | MY_SEEK_NOT_DONE)) && !error) error=my_errno; } else if (!share->w_locks) { /* No more locks */ - flag=1; if (my_lock(share->kfile,F_UNLCK,0L,F_TO_EOF, MYF(MY_WME | MY_SEEK_NOT_DONE)) && !error) error=my_errno; @@ -148,7 +145,6 @@ int mi_lock_database(MI_INFO *info, int lock_type) */ if (share->w_locks == 1) { - flag=1; if (my_lock(share->kfile,lock_type,0L,F_TO_EOF, MYF(MY_SEEK_NOT_DONE))) { @@ -163,7 +159,6 @@ int mi_lock_database(MI_INFO *info, int lock_type) } if (!share->r_locks && !share->w_locks) { - flag=1; if (my_lock(share->kfile,lock_type,0L,F_TO_EOF, info->lock_wait | MY_SEEK_NOT_DONE)) { @@ -188,7 +183,6 @@ int mi_lock_database(MI_INFO *info, int lock_type) { /* Change READONLY to RW */ if (share->r_locks == 1) { - flag=1; if (my_lock(share->kfile,lock_type,0L,F_TO_EOF, MYF(info->lock_wait | MY_SEEK_NOT_DONE))) { @@ -205,7 +199,6 @@ int mi_lock_database(MI_INFO *info, int lock_type) { if (!share->w_locks) { - flag=1; if (my_lock(share->kfile,lock_type,0L,F_TO_EOF, info->lock_wait | MY_SEEK_NOT_DONE)) { @@ -252,11 +245,6 @@ int mi_lock_database(MI_INFO *info, int lock_type) } #endif pthread_mutex_unlock(&share->intern_lock); -#if defined(FULL_LOG) || defined(_lint) - lock_type|=(int) (flag << 8); /* Set bit to set if real lock */ - myisam_log_command(MI_LOG_LOCK,info,(uchar*) &lock_type,sizeof(lock_type), - error); -#endif DBUG_RETURN(error); } /* mi_lock_database */ diff --git a/storage/myisam/rt_split.c b/storage/myisam/rt_split.c index 88cf643faf9..03d22de68fa 100644 --- a/storage/myisam/rt_split.c +++ b/storage/myisam/rt_split.c @@ -255,7 +255,6 @@ int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key, SplitStruct *stop; double *coord_buf; double *next_coord; - double *old_coord; int n_dim; uchar *source_cur, *cur1, *cur2; uchar *new_page= info->buff; @@ -293,8 +292,6 @@ int rtree_split_page(MI_INFO *info, MI_KEYDEF *keyinfo, uchar *page, uchar *key, rtree_d_mbr(keyinfo->seg, key, key_length, cur->coords); cur->key = key; - old_coord = next_coord; - if (split_rtree_node(task, max_keys + 1, mi_getint(page) + full_length + 2, full_length, rt_PAGE_MIN_SIZE(keyinfo->block_length), diff --git a/storage/myisammrg/myrg_open.c b/storage/myisammrg/myrg_open.c index 5fcbe0c3297..18f8aa8d2c0 100644 --- a/storage/myisammrg/myrg_open.c +++ b/storage/myisammrg/myrg_open.c @@ -227,9 +227,7 @@ MYRG_INFO *myrg_parent_open(const char *parent_name, int save_errno; int insert_method; uint length; - uint dir_length; uint child_count; - size_t name_buff_length; File fd; IO_CACHE file_cache; char parent_name_buff[FN_REFLEN * 2]; @@ -299,7 +297,6 @@ MYRG_INFO *myrg_parent_open(const char *parent_name, } /* Call callback for each child. */ - dir_length= dirname_part(parent_name_buff, parent_name, &name_buff_length); my_b_seek(&file_cache, 0); while ((length= my_b_gets(&file_cache, child_name_buff, FN_REFLEN - 1))) { @@ -379,7 +376,6 @@ int myrg_attach_children(MYRG_INFO *m_info, int handle_locking, { ulonglong file_offset; MI_INFO *myisam; - int rc; int errpos; int save_errno; uint idx; @@ -398,7 +394,6 @@ int myrg_attach_children(MYRG_INFO *m_info, int handle_locking, here and in ha_myisammrg::store_lock() forces consistent data. */ pthread_mutex_lock(&m_info->mutex); - rc= 1; errpos= 0; file_offset= 0; min_keys= 0; diff --git a/strings/decimal.c b/strings/decimal.c index 4403fc9fd6b..bda296ce832 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -1934,8 +1934,7 @@ static int do_sub(decimal_t *from1, decimal_t *from2, decimal_t *to) int decimal_intg(decimal_t *from) { int res; - dec1 *tmp_res; - tmp_res= remove_leading_zeroes(from, &res); + remove_leading_zeroes(from, &res); return res; } From e24abd9091ce28a27f27073ab70aed94851362bc Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 21 Jul 2010 18:05:57 +0300 Subject: [PATCH 111/112] Addendum #4 to bug #53095 SHOW DATABASES LIKE ... was not converting to lowercase on comparison as the documentation is suggesting. Fixed it to behave similarly to SHOW TABLES LIKE ... and updated the failing on MacOSX lowercase_table2 test case. --- mysql-test/r/lowercase_table2.result | 3 ++- sql/sql_show.cc | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/lowercase_table2.result b/mysql-test/r/lowercase_table2.result index 51c2ac0faf5..c9a46b70fab 100644 --- a/mysql-test/r/lowercase_table2.result +++ b/mysql-test/r/lowercase_table2.result @@ -56,6 +56,7 @@ CREATE DATABASE `TEST_$1`; SHOW DATABASES LIKE "TEST%"; Database (TEST%) TEST_$1 +test DROP DATABASE `test_$1`; CREATE TABLE T1 (a int) engine=innodb; INSERT INTO T1 VALUES (1); @@ -171,6 +172,6 @@ create table myUC (i int); select TABLE_SCHEMA,TABLE_NAME FROM information_schema.TABLES where TABLE_SCHEMA ='mysqltest_LC2'; TABLE_SCHEMA TABLE_NAME -mysqltest_LC2 myUC +mysqltest_lc2 myUC use test; drop database mysqltest_LC2; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index eb5d3a1965d..616bced8f4a 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -521,8 +521,19 @@ find_files(THD *thd, List *files, const char *db, continue; file_name_len= filename_to_tablename(file->name, uname, sizeof(uname)); - if (wild && wild_compare(uname, wild, 0)) - continue; + if (wild) + { + if (lower_case_table_names) + { + if (my_wildcmp(files_charset_info, + uname, uname + file_name_len, + wild, wild + wild_length, + wild_prefix, wild_one,wild_many)) + continue; + } + else if (wild_compare(uname, wild, 0)) + continue; + } if (!(file_name= thd->make_lex_string(file_name, uname, file_name_len, TRUE))) { From e9a52f962f2d89fe1938145105bcb35f970a2414 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 22 Jul 2010 11:15:15 -0500 Subject: [PATCH 112/112] Bug#49542 - Do as the comment suggests and downgrade directory errors from find_file() to a warning unless they happen during a SHOW command. --- sql/sql_show.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index eb5d3a1965d..c979d44dc1c 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1,4 +1,4 @@ -/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. +/* Copyright 2000, 2010 Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -9,9 +9,9 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* Function with list databases, tables or fields */ @@ -2986,7 +2986,7 @@ make_table_name_list(THD *thd, List *table_names, LEX *lex, */ if (res == FIND_FILES_DIR) { - if (lex->sql_command != SQLCOM_SELECT) + if (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) return 1; thd->clear_error(); return 2;