From 10953a6d8cf01991de1ab8b4829a7b4952d05268 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Wed, 5 Oct 2005 16:38:53 +0200 Subject: [PATCH 1/3] Bug#13143 - formatID should not affect XID's uniqueness --- mysql-test/r/xa.result | 2 ++ mysql-test/t/xa.test | 2 ++ sql/handler.h | 10 +++++++++- sql/sql_class.cc | 12 ++++++------ 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/xa.result b/mysql-test/r/xa.result index f3d7e151628..ae5407ce409 100644 --- a/mysql-test/r/xa.result +++ b/mysql-test/r/xa.result @@ -24,6 +24,8 @@ insert t1 values (30); xa end 'testa','testb'; xa start 'testa','testb'; ERROR XAE08: XAER_DUPID: The XID already exists +xa start 'testa','testb', 123; +ERROR XAE08: XAER_DUPID: The XID already exists xa start 0x7465737462, 0x2030405060, 0xb; insert t1 values (40); xa end 'testb',' 0@P`',11; diff --git a/mysql-test/t/xa.test b/mysql-test/t/xa.test index 1347fd05415..f059f8f9bb5 100644 --- a/mysql-test/t/xa.test +++ b/mysql-test/t/xa.test @@ -33,6 +33,8 @@ connection con1; --error 1440 xa start 'testa','testb'; +--error 1440 +xa start 'testa','testb', 123; # gtrid [ , bqual [ , formatID ] ] xa start 0x7465737462, 0x2030405060, 0xb; diff --git a/sql/handler.h b/sql/handler.h index 664427fe5c4..d58d28ad7b0 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -228,7 +228,7 @@ struct xid_t { char data[XIDDATASIZE]; // not \0-terminated ! bool eq(struct xid_t *xid) - { return !memcmp(this, xid, length()); } + { return eq(xid->gtrid_length, xid->bqual_length, xid->data); } bool eq(long g, long b, const char *d) { return g == gtrid_length && b == bqual_length && !memcmp(d, data, g+b); } void set(struct xid_t *xid) @@ -276,6 +276,14 @@ struct xid_t { return sizeof(formatID)+sizeof(gtrid_length)+sizeof(bqual_length)+ gtrid_length+bqual_length; } + byte *key() + { + return (byte *)>rid_length; + } + uint key_length() + { + return sizeof(gtrid_length)+sizeof(bqual_length)+gtrid_length+bqual_length; + } }; typedef struct xid_t XID; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 2917626ff35..fc7ea6a2794 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1982,8 +1982,8 @@ HASH xid_cache; static byte *xid_get_hash_key(const byte *ptr,uint *length, my_bool not_used __attribute__((unused))) { - *length=((XID_STATE*)ptr)->xid.length(); - return (byte *)&((XID_STATE*)ptr)->xid; + *length=((XID_STATE*)ptr)->xid.key_length(); + return ((XID_STATE*)ptr)->xid.key(); } static void xid_free_hash (void *ptr) @@ -2011,7 +2011,7 @@ void xid_cache_free() XID_STATE *xid_cache_search(XID *xid) { pthread_mutex_lock(&LOCK_xid_cache); - XID_STATE *res=(XID_STATE *)hash_search(&xid_cache, (byte *)xid, xid->length()); + XID_STATE *res=(XID_STATE *)hash_search(&xid_cache, xid->key(), xid->key_length()); pthread_mutex_unlock(&LOCK_xid_cache); return res; } @@ -2022,7 +2022,7 @@ bool xid_cache_insert(XID *xid, enum xa_states xa_state) XID_STATE *xs; my_bool res; pthread_mutex_lock(&LOCK_xid_cache); - if (hash_search(&xid_cache, (byte *)xid, xid->length())) + if (hash_search(&xid_cache, xid->key(), xid->key_length())) res=0; else if (!(xs=(XID_STATE *)my_malloc(sizeof(*xs), MYF(MY_WME)))) res=1; @@ -2041,8 +2041,8 @@ bool xid_cache_insert(XID *xid, enum xa_states xa_state) bool xid_cache_insert(XID_STATE *xid_state) { pthread_mutex_lock(&LOCK_xid_cache); - DBUG_ASSERT(hash_search(&xid_cache, (byte *)&xid_state->xid, - xid_state->xid.length())==0); + DBUG_ASSERT(hash_search(&xid_cache, xid_state->xid.key(), + xid_state->xid.key_length())==0); my_bool res=my_hash_insert(&xid_cache, (byte*)xid_state); pthread_mutex_unlock(&LOCK_xid_cache); return res; From 83683bb6490da40a63051100b0f897246502e433 Mon Sep 17 00:00:00 2001 From: "serg@mysql.com" <> Date: Wed, 5 Oct 2005 19:36:20 +0200 Subject: [PATCH 2/3] sql_table.cc: fixed CHECKSUM TABLE to be independent from the first 'deleted' bit in the null bitmask (undefined in the InnoDB) bug#13710 --- sql/sql_table.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 3f0dffea110..0bb4a0bbaed 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4125,6 +4125,9 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) { /* fix undefined null bits */ t->record[0][t->s->null_bytes-1] |= null_mask; + if (!(t->s->db_create_options & HA_OPTION_PACK_RECORD)) + t->record[0][0] |= 1; + row_crc= my_checksum(row_crc, t->record[0], t->s->null_bytes); } From 2356401750e7a23a14d620c5ef68e50bfaf72b7f Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Wed, 5 Oct 2005 19:58:16 +0200 Subject: [PATCH 3/3] Bug#12935 Local and XA transactions not mutually exclusive --- mysql-test/r/xa.result | 12 ++++++++++-- mysql-test/t/xa.test | 12 ++++++++++++ sql/share/errmsg.txt | 3 ++- sql/sql_parse.cc | 18 ++++++++++++++++++ 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/xa.result b/mysql-test/r/xa.result index ae5407ce409..5fb03d2378e 100644 --- a/mysql-test/r/xa.result +++ b/mysql-test/r/xa.result @@ -9,10 +9,10 @@ select * from t1; a xa start 'test2'; xa start 'test-bad'; -ERROR XAE07: XAER_RMFAIL: The command cannot be executed in the ACTIVE state +ERROR XAE07: XAER_RMFAIL: The command cannot be executed when global transaction is in the ACTIVE state insert t1 values (20); xa prepare 'test2'; -ERROR XAE07: XAER_RMFAIL: The command cannot be executed in the ACTIVE state +ERROR XAE07: XAER_RMFAIL: The command cannot be executed when global transaction is in the ACTIVE state xa end 'test2'; xa prepare 'test2'; xa commit 'test2'; @@ -21,7 +21,13 @@ a 20 xa start 'testa','testb'; insert t1 values (30); +commit; +ERROR XAE07: XAER_RMFAIL: The command cannot be executed when global transaction is in the ACTIVE state xa end 'testa','testb'; +begin; +ERROR XAE07: XAER_RMFAIL: The command cannot be executed when global transaction is in the IDLE state +create table t2 (a int); +ERROR XAE07: XAER_RMFAIL: The command cannot be executed when global transaction is in the IDLE state xa start 'testa','testb'; ERROR XAE08: XAER_DUPID: The XID already exists xa start 'testa','testb', 123; @@ -30,6 +36,8 @@ xa start 0x7465737462, 0x2030405060, 0xb; insert t1 values (40); xa end 'testb',' 0@P`',11; xa prepare 'testb',0x2030405060,11; +start transaction; +ERROR XAE07: XAER_RMFAIL: The command cannot be executed when global transaction is in the PREPARED state xa recover; formatID gtrid_length bqual_length data 11 5 5 testb 0@P` diff --git a/mysql-test/t/xa.test b/mysql-test/t/xa.test index f059f8f9bb5..92405bac137 100644 --- a/mysql-test/t/xa.test +++ b/mysql-test/t/xa.test @@ -26,8 +26,17 @@ select * from t1; xa start 'testa','testb'; insert t1 values (30); + +--error 1399 +commit; + xa end 'testa','testb'; +--error 1399 +begin; +--error 1399 +create table t2 (a int); + connect (con1,localhost,,,); connection con1; @@ -42,6 +51,9 @@ insert t1 values (40); xa end 'testb',' 0@P`',11; xa prepare 'testb',0x2030405060,11; +--error 1399 +start transaction; + xa recover; # uncomment the line below when binlog will be able to prepare diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index d3964fe6e52..10f0d0691d1 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5311,7 +5311,8 @@ ER_XAER_NOTA XAE04 ER_XAER_INVAL XAE05 eng "XAER_INVAL: Invalid arguments (or unsupported command)" ER_XAER_RMFAIL XAE07 - eng "XAER_RMFAIL: The command cannot be executed in the %.64s state" + eng "XAER_RMFAIL: The command cannot be executed when global transaction is in the %.64s state" + rus "XAER_RMFAIL: эту команду нельзя выполнять когда глобальная транзакция находится в состоянии '%.64s'" ER_XAER_OUTSIDE XAE09 eng "XAER_OUTSIDE: Some work is done outside global transaction" ER_XAER_RMERR XAE03 diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e16d75165fd..57b7c387ac9 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -134,6 +134,12 @@ static bool end_active_trans(THD *thd) my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0)); DBUG_RETURN(1); } + if (thd->transaction.xid_state.xa_state != XA_NOTR) + { + my_error(ER_XAER_RMFAIL, MYF(0), + xa_state_names[thd->transaction.xid_state.xa_state]); + DBUG_RETURN(1); + } if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN | OPTION_TABLE_LOCK)) { @@ -1368,6 +1374,12 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion) my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0)); DBUG_RETURN(1); } + if (thd->transaction.xid_state.xa_state != XA_NOTR) + { + my_error(ER_XAER_RMFAIL, MYF(0), + xa_state_names[thd->transaction.xid_state.xa_state]); + DBUG_RETURN(1); + } switch (completion) { case COMMIT: /* @@ -3926,6 +3938,12 @@ end_with_restore_list: break; case SQLCOM_BEGIN: + if (thd->transaction.xid_state.xa_state != XA_NOTR) + { + my_error(ER_XAER_RMFAIL, MYF(0), + xa_state_names[thd->transaction.xid_state.xa_state]); + break; + } if (begin_trans(thd)) goto error; send_ok(thd);