Commit 9077ee44 authored by serg@serg.mylan's avatar serg@serg.mylan

Merge bk-internal.mysql.com:/home/bk/mysql-5.0

into serg.mylan:/usr/home/serg/Abk/mysql-5.0
parents 83330214 2d11bbdb
...@@ -9,10 +9,10 @@ select * from t1; ...@@ -9,10 +9,10 @@ select * from t1;
a a
xa start 'test2'; xa start 'test2';
xa start 'test-bad'; 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); insert t1 values (20);
xa prepare 'test2'; 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 end 'test2';
xa prepare 'test2'; xa prepare 'test2';
xa commit 'test2'; xa commit 'test2';
...@@ -21,13 +21,23 @@ a ...@@ -21,13 +21,23 @@ a
20 20
xa start 'testa','testb'; xa start 'testa','testb';
insert t1 values (30); 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'; 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'; xa start 'testa','testb';
ERROR XAE08: XAER_DUPID: The XID already exists 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; xa start 0x7465737462, 0x2030405060, 0xb;
insert t1 values (40); insert t1 values (40);
xa end 'testb',' 0@P`',11; xa end 'testb',' 0@P`',11;
xa prepare 'testb',0x2030405060,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; xa recover;
formatID gtrid_length bqual_length data formatID gtrid_length bqual_length data
11 5 5 testb 0@P` 11 5 5 testb 0@P`
......
...@@ -26,13 +26,24 @@ select * from t1; ...@@ -26,13 +26,24 @@ select * from t1;
xa start 'testa','testb'; xa start 'testa','testb';
insert t1 values (30); insert t1 values (30);
--error 1399
commit;
xa end 'testa','testb'; xa end 'testa','testb';
--error 1399
begin;
--error 1399
create table t2 (a int);
connect (con1,localhost,,,); connect (con1,localhost,,,);
connection con1; connection con1;
--error 1440 --error 1440
xa start 'testa','testb'; xa start 'testa','testb';
--error 1440
xa start 'testa','testb', 123;
# gtrid [ , bqual [ , formatID ] ] # gtrid [ , bqual [ , formatID ] ]
xa start 0x7465737462, 0x2030405060, 0xb; xa start 0x7465737462, 0x2030405060, 0xb;
...@@ -40,6 +51,9 @@ insert t1 values (40); ...@@ -40,6 +51,9 @@ insert t1 values (40);
xa end 'testb',' 0@P`',11; xa end 'testb',' 0@P`',11;
xa prepare 'testb',0x2030405060,11; xa prepare 'testb',0x2030405060,11;
--error 1399
start transaction;
xa recover; xa recover;
# uncomment the line below when binlog will be able to prepare # uncomment the line below when binlog will be able to prepare
......
...@@ -228,7 +228,7 @@ struct xid_t { ...@@ -228,7 +228,7 @@ struct xid_t {
char data[XIDDATASIZE]; // not \0-terminated ! char data[XIDDATASIZE]; // not \0-terminated !
bool eq(struct xid_t *xid) 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) bool eq(long g, long b, const char *d)
{ return g == gtrid_length && b == bqual_length && !memcmp(d, data, g+b); } { return g == gtrid_length && b == bqual_length && !memcmp(d, data, g+b); }
void set(struct xid_t *xid) void set(struct xid_t *xid)
...@@ -276,6 +276,14 @@ struct xid_t { ...@@ -276,6 +276,14 @@ struct xid_t {
return sizeof(formatID)+sizeof(gtrid_length)+sizeof(bqual_length)+ return sizeof(formatID)+sizeof(gtrid_length)+sizeof(bqual_length)+
gtrid_length+bqual_length; gtrid_length+bqual_length;
} }
byte *key()
{
return (byte *)&gtrid_length;
}
uint key_length()
{
return sizeof(gtrid_length)+sizeof(bqual_length)+gtrid_length+bqual_length;
}
}; };
typedef struct xid_t XID; typedef struct xid_t XID;
......
...@@ -5311,7 +5311,8 @@ ER_XAER_NOTA XAE04 ...@@ -5311,7 +5311,8 @@ ER_XAER_NOTA XAE04
ER_XAER_INVAL XAE05 ER_XAER_INVAL XAE05
eng "XAER_INVAL: Invalid arguments (or unsupported command)" eng "XAER_INVAL: Invalid arguments (or unsupported command)"
ER_XAER_RMFAIL XAE07 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 ER_XAER_OUTSIDE XAE09
eng "XAER_OUTSIDE: Some work is done outside global transaction" eng "XAER_OUTSIDE: Some work is done outside global transaction"
ER_XAER_RMERR XAE03 ER_XAER_RMERR XAE03
......
...@@ -1982,8 +1982,8 @@ HASH xid_cache; ...@@ -1982,8 +1982,8 @@ HASH xid_cache;
static byte *xid_get_hash_key(const byte *ptr,uint *length, static byte *xid_get_hash_key(const byte *ptr,uint *length,
my_bool not_used __attribute__((unused))) my_bool not_used __attribute__((unused)))
{ {
*length=((XID_STATE*)ptr)->xid.length(); *length=((XID_STATE*)ptr)->xid.key_length();
return (byte *)&((XID_STATE*)ptr)->xid; return ((XID_STATE*)ptr)->xid.key();
} }
static void xid_free_hash (void *ptr) static void xid_free_hash (void *ptr)
...@@ -2011,7 +2011,7 @@ void xid_cache_free() ...@@ -2011,7 +2011,7 @@ void xid_cache_free()
XID_STATE *xid_cache_search(XID *xid) XID_STATE *xid_cache_search(XID *xid)
{ {
pthread_mutex_lock(&LOCK_xid_cache); 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); pthread_mutex_unlock(&LOCK_xid_cache);
return res; return res;
} }
...@@ -2022,7 +2022,7 @@ bool xid_cache_insert(XID *xid, enum xa_states xa_state) ...@@ -2022,7 +2022,7 @@ bool xid_cache_insert(XID *xid, enum xa_states xa_state)
XID_STATE *xs; XID_STATE *xs;
my_bool res; my_bool res;
pthread_mutex_lock(&LOCK_xid_cache); 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; res=0;
else if (!(xs=(XID_STATE *)my_malloc(sizeof(*xs), MYF(MY_WME)))) else if (!(xs=(XID_STATE *)my_malloc(sizeof(*xs), MYF(MY_WME))))
res=1; res=1;
...@@ -2041,8 +2041,8 @@ bool xid_cache_insert(XID *xid, enum xa_states xa_state) ...@@ -2041,8 +2041,8 @@ bool xid_cache_insert(XID *xid, enum xa_states xa_state)
bool xid_cache_insert(XID_STATE *xid_state) bool xid_cache_insert(XID_STATE *xid_state)
{ {
pthread_mutex_lock(&LOCK_xid_cache); pthread_mutex_lock(&LOCK_xid_cache);
DBUG_ASSERT(hash_search(&xid_cache, (byte *)&xid_state->xid, DBUG_ASSERT(hash_search(&xid_cache, xid_state->xid.key(),
xid_state->xid.length())==0); xid_state->xid.key_length())==0);
my_bool res=my_hash_insert(&xid_cache, (byte*)xid_state); my_bool res=my_hash_insert(&xid_cache, (byte*)xid_state);
pthread_mutex_unlock(&LOCK_xid_cache); pthread_mutex_unlock(&LOCK_xid_cache);
return res; return res;
......
...@@ -134,6 +134,12 @@ static bool end_active_trans(THD *thd) ...@@ -134,6 +134,12 @@ static bool end_active_trans(THD *thd)
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0)); my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
DBUG_RETURN(1); 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 | if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN |
OPTION_TABLE_LOCK)) OPTION_TABLE_LOCK))
{ {
...@@ -1368,6 +1374,12 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion) ...@@ -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)); my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
DBUG_RETURN(1); 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) { switch (completion) {
case COMMIT: case COMMIT:
/* /*
...@@ -3926,6 +3938,12 @@ end_with_restore_list: ...@@ -3926,6 +3938,12 @@ end_with_restore_list:
break; break;
case SQLCOM_BEGIN: 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)) if (begin_trans(thd))
goto error; goto error;
send_ok(thd); send_ok(thd);
......
...@@ -4135,6 +4135,9 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) ...@@ -4135,6 +4135,9 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
{ {
/* fix undefined null bits */ /* fix undefined null bits */
t->record[0][t->s->null_bytes-1] |= null_mask; 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); row_crc= my_checksum(row_crc, t->record[0], t->s->null_bytes);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment