diff --git a/client/mysqldump.c b/client/mysqldump.c index 6b2c2a06834..d755a17b815 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -4110,7 +4110,7 @@ static my_bool dump_all_views_in_db(char *database) for (numrows= 0 ; (table= getTableName(1)); ) { char *end= strmov(afterdot, table); - if (include_table((uchar*) hash_key,end - hash_key)) + if (include_table(hash_key,end - hash_key)) { numrows++; dynstr_append_checked(&query, quote_name(table, table_buff, 1)); @@ -4131,7 +4131,7 @@ static my_bool dump_all_views_in_db(char *database) while ((table= getTableName(0))) { char *end= strmov(afterdot, table); - if (include_table((uchar*) hash_key, end - hash_key)) + if (include_table(hash_key, end - hash_key)) get_view_structure(table, database); } if (opt_xml) diff --git a/cmd-line-utils/readline/bind.c b/cmd-line-utils/readline/bind.c index baed1dfad49..fc7bebfd813 100644 --- a/cmd-line-utils/readline/bind.c +++ b/cmd-line-utils/readline/bind.c @@ -701,7 +701,7 @@ rl_function_of_keyseq (keyseq, map, type) { unsigned char ic = keyseq[i]; - if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii) + if (META_BYTE (ic) && _rl_convert_meta_chars_to_ascii) { if (map[ESC].type == ISKMAP) { diff --git a/cmd-line-utils/readline/chardefs.h b/cmd-line-utils/readline/chardefs.h index def3a111bd3..36fe7fdd7ac 100644 --- a/cmd-line-utils/readline/chardefs.h +++ b/cmd-line-utils/readline/chardefs.h @@ -59,7 +59,8 @@ #define largest_char 255 /* Largest character value. */ #define CTRL_CHAR(c) ((c) < control_character_threshold && (((c) & 0x80) == 0)) -#define META_CHAR(c) ((c) > meta_character_threshold && (c) <= largest_char) +#define META_BYTE(c) ((c) > meta_character_threshold) +#define META_CHAR(c) (META_BYTE(c) && (c) <= largest_char) #define CTRL(c) ((c) & control_character_mask) #define META(c) ((c) | meta_character_bit) diff --git a/cmd-line-utils/readline/display.c b/cmd-line-utils/readline/display.c index 6f63faa9738..842a586b76b 100644 --- a/cmd-line-utils/readline/display.c +++ b/cmd-line-utils/readline/display.c @@ -1888,7 +1888,7 @@ rl_character_len (c, pos) uc = (unsigned char)c; - if (META_CHAR (uc)) + if (META_BYTE (uc)) return ((_rl_output_meta_chars == 0) ? 4 : 1); if (uc == '\t') diff --git a/dbug/user.r b/dbug/user.r index 19de840d0ad..ef67ef7a7cf 100644 --- a/dbug/user.r +++ b/dbug/user.r @@ -32,6 +32,7 @@ .\" === Set line length .\".ll 6.5i .TL +.warn 0 D B U G .P 0 C Program Debugging Package diff --git a/include/my_sys.h b/include/my_sys.h index 01804cd089f..263b567684d 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -511,7 +511,7 @@ typedef int (*qsort2_cmp)(const void *, const void *, const void *); ((info)->write_pos + (Count) <=(info)->write_end ?\ (memcpy((info)->write_pos, (Buffer), (size_t)(Count)),\ ((info)->write_pos+=(Count)),0) : \ - (*(info)->write_function)((info),(Buffer),(Count))) + (*(info)->write_function)((info),(uchar *)(Buffer),(Count))) #define my_b_get(info) \ ((info)->read_pos != (info)->read_end ?\ diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index 5e3582d5e16..7a56584190d 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -25,6 +25,7 @@ test_SCRIPTS = mtr \ mysql-stress-test.pl nobase_test_DATA = \ + valgrind.supp \ lib/v1/mysql-test-run.pl \ lib/v1/mtr_cases.pl \ lib/v1/mtr_io.pl \ @@ -41,7 +42,6 @@ nobase_test_DATA = \ lib/v1/mtr_im.pl \ lib/v1/mtr_process.pl \ lib/v1/mtr_unique.pl \ -\ lib/mtr_cases.pm \ lib/mtr_gcov.pl \ lib/mtr_gprof.pl \ @@ -69,9 +69,8 @@ nobase_test_DATA = \ SUBDIRS = lib/My/SafeProcess EXTRA_DIST = README \ - valgrind.supp \ $(test_SCRIPTS) \ - $(nobase_test_DATA) + $(nobase_test_DATA) # List of directories containing test + result files and the # related test data files that should be copied @@ -93,7 +92,7 @@ TEST_DIRS = t r include std_data std_data/parts collections \ suite/jp suite/jp/t suite/jp/r suite/jp/std_data suite/jp/include \ suite/manual/t suite/manual/r \ suite/ndb_team suite/ndb_team/t suite/ndb_team/r \ - suite/rpl suite/rpl/data suite/rpl/include suite/rpl/r \ + suite/rpl suite/rpl/include suite/rpl/r \ suite/rpl/t \ suite/stress/include suite/stress/t suite/stress/r \ suite/ndb suite/ndb/t suite/ndb/r \ diff --git a/mysql-test/r/xa.result b/mysql-test/r/xa.result index 592cf07522b..92f52b402ec 100644 --- a/mysql-test/r/xa.result +++ b/mysql-test/r/xa.result @@ -75,3 +75,9 @@ xa rollback 'a','c'; xa start 'a','c'; drop table t1; End of 5.0 tests +xa start 'a'; +xa end 'a'; +xa rollback 'a'; +xa start 'a'; +xa end 'a'; +xa rollback 'a'; diff --git a/mysql-test/t/xa.test b/mysql-test/t/xa.test index 04ecf518577..a0d5aa60641 100644 --- a/mysql-test/t/xa.test +++ b/mysql-test/t/xa.test @@ -124,6 +124,17 @@ drop table t1; --echo End of 5.0 tests +# +# Bug#44672: Assertion failed: thd->transaction.xid_state.xid.is_null() +# + +xa start 'a'; +xa end 'a'; +xa rollback 'a'; +xa start 'a'; +xa end 'a'; +xa rollback 'a'; + # Wait till all disconnects are completed --source include/wait_until_count_sessions.inc diff --git a/sql/handler.cc b/sql/handler.cc index d22ee220dc1..9246c04ce7d 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1073,6 +1073,13 @@ int ha_commit_trans(THD *thd, bool all) user, or an implicit commit issued by a DDL. */ THD_TRANS *trans= all ? &thd->transaction.all : &thd->transaction.stmt; + /* + "real" is a nick name for a transaction for which a commit will + make persistent changes. E.g. a 'stmt' transaction inside a 'all' + transation is not 'real': even though it's possible to commit it, + the changes are not durable as they might be rolled back if the + enclosing 'all' transaction is rolled back. + */ bool is_real_trans= all || thd->transaction.all.ha_list == 0; Ha_trx_info *ha_info= trans->ha_list; my_xid xid= thd->transaction.xid_state.xid.get_my_xid(); @@ -1184,16 +1191,9 @@ end: if (rw_trans) start_waiting_global_read_lock(thd); } - else if (all) - { - /* - A COMMIT of an empty transaction. There may be savepoints. - Destroy them. If the transaction is not empty - savepoints are cleared in ha_commit_one_phase() - or ha_rollback_trans(). - */ + /* Free resources and perform other cleanup even for 'empty' transactions. */ + else if (is_real_trans) thd->transaction.cleanup(); - } #endif /* USING_TRANSACTIONS */ DBUG_RETURN(error); } @@ -1206,6 +1206,13 @@ int ha_commit_one_phase(THD *thd, bool all) { int error=0; THD_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt; + /* + "real" is a nick name for a transaction for which a commit will + make persistent changes. E.g. a 'stmt' transaction inside a 'all' + transation is not 'real': even though it's possible to commit it, + the changes are not durable as they might be rolled back if the + enclosing 'all' transaction is rolled back. + */ bool is_real_trans=all || thd->transaction.all.ha_list == 0; Ha_trx_info *ha_info= trans->ha_list, *ha_info_next; DBUG_ENTER("ha_commit_one_phase"); @@ -1227,8 +1234,6 @@ int ha_commit_one_phase(THD *thd, bool all) } trans->ha_list= 0; trans->no_2pc=0; - if (is_real_trans) - thd->transaction.xid_state.xid.null(); if (all) { #ifdef HAVE_QUERY_CACHE @@ -1236,8 +1241,9 @@ int ha_commit_one_phase(THD *thd, bool all) query_cache.invalidate(thd->transaction.changed_tables); #endif thd->variables.tx_isolation=thd->session_tx_isolation; - thd->transaction.cleanup(); } + if (is_real_trans) + thd->transaction.cleanup(); } #endif /* USING_TRANSACTIONS */ DBUG_RETURN(error); @@ -1249,6 +1255,13 @@ int ha_rollback_trans(THD *thd, bool all) int error=0; THD_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt; Ha_trx_info *ha_info= trans->ha_list, *ha_info_next; + /* + "real" is a nick name for a transaction for which a commit will + make persistent changes. E.g. a 'stmt' transaction inside a 'all' + transation is not 'real': even though it's possible to commit it, + the changes are not durable as they might be rolled back if the + enclosing 'all' transaction is rolled back. + */ bool is_real_trans=all || thd->transaction.all.ha_list == 0; DBUG_ENTER("ha_rollback_trans"); @@ -1294,18 +1307,13 @@ int ha_rollback_trans(THD *thd, bool all) } trans->ha_list= 0; trans->no_2pc=0; - if (is_real_trans) - { - if (thd->transaction_rollback_request) - thd->transaction.xid_state.rm_error= thd->main_da.sql_errno(); - else - thd->transaction.xid_state.xid.null(); - } + if (is_real_trans && thd->transaction_rollback_request) + thd->transaction.xid_state.rm_error= thd->main_da.sql_errno(); if (all) thd->variables.tx_isolation=thd->session_tx_isolation; } /* Always cleanup. Even if there nht==0. There may be savepoints. */ - if (all) + if (is_real_trans) thd->transaction.cleanup(); #endif /* USING_TRANSACTIONS */ if (all) diff --git a/sql/sql_class.h b/sql/sql_class.h index f4d55917b48..ae7f2a51428 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1464,6 +1464,14 @@ public: { changed_tables= 0; savepoints= 0; + /* + If rm_error is raised, it means that this piece of a distributed + transaction has failed and must be rolled back. But the user must + rollback it explicitly, so don't start a new distributed XA until + then. + */ + if (!xid_state.rm_error) + xid_state.xid.null(); #ifdef USING_TRANSACTIONS free_root(&mem_root,MYF(MY_KEEP_PREALLOC)); #endif diff --git a/storage/myisammrg/myrg_create.c b/storage/myisammrg/myrg_create.c index df81b730bfd..eaed470daec 100644 --- a/storage/myisammrg/myrg_create.c +++ b/storage/myisammrg/myrg_create.c @@ -46,7 +46,7 @@ int myrg_create(const char *name, const char **table_names, fn_same(buff,name,4); *(end=strend(buff))='\n'; end[1]=0; - if (my_write(file,(char*) buff,(uint) (end-buff+1), + if (my_write(file,(uchar*) buff,(uint) (end-buff+1), MYF(MY_WME | MY_NABP))) goto err; } diff --git a/strings/ctype.c b/strings/ctype.c index 446eb168804..4a54d898337 100644 --- a/strings/ctype.c +++ b/strings/ctype.c @@ -328,7 +328,10 @@ my_string_repertoire(CHARSET_INFO *cs, const char *str, ulong length) { my_wc_t wc; int chlen; - for (; (chlen= cs->cset->mb_wc(cs, &wc, str, strend)) > 0; str+= chlen) + for (; (chlen= cs->cset->mb_wc(cs, &wc, + (const unsigned char *) str, + (const unsigned char *) strend)) > 0; + str+= chlen) { if (wc > 0x7F) return MY_REPERTOIRE_UNICODE30;