Commit 52770e86 authored by serg@serg.mylan's avatar serg@serg.mylan

XID SQL syntax

minor cleanups
XA tests
parent 45a79c90
......@@ -186,7 +186,7 @@ typedef struct my_charset_handler_st
int base, char **e, int *err);
double (*strntod)(struct charset_info_st *, char *s, uint l, char **e,
int *err);
longlong (*my_strtoll10)(struct charset_info_st *cs,
longlong (*strtoll10)(struct charset_info_st *cs,
const char *nptr, char **endptr, int *error);
ulong (*scan)(struct charset_info_st *, const char *b, const char *e,
int sq);
......
drop table if exists t1, t2;
create table t1 (a int) engine=innodb;
xa start 'test1';
insert t1 values (10);
xa end 'test1';
xa prepare 'test1';
xa rollback 'test1';
select * from t1;
a
xa start 'test2';
xa start 'test-bad';
ERROR XAE07: XAER_RMFAIL: The command cannot be executed in the ACTIVE state
insert t1 values (20);
xa prepare 'test2';
ERROR XAE07: XAER_RMFAIL: The command cannot be executed in the ACTIVE state
xa end 'test2';
xa prepare 'test2';
xa commit 'test2';
select * from t1;
a
20
xa start 'testa','testb';
insert t1 values (30);
xa end 'testa','testb';
xa start 0x7465737462, 0x2030405060, 0xb;
insert t1 values (40);
xa end 'testb',' 0@P`',11;
xa prepare 'testb',0x2030405060,11;
xa recover;
formatID gtrid_length bqual_length data
11 5 5 testb 0@P`
xa prepare 'testa','testb';
xa recover;
formatID gtrid_length bqual_length data
11 5 5 testb 0@P`
1 5 5 testatestb
xa commit 'testb',0x2030405060,11;
xa rollback 'testa','testb';
xa start 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz';
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 '' at line 1
select * from t1;
a
20
40
drop table t1;
#
# WL#1756
#
-- source include/have_innodb.inc
--disable_warnings
drop table if exists t1, t2;
--enable_warnings
create table t1 (a int) engine=innodb;
xa start 'test1';
insert t1 values (10);
xa end 'test1';
xa prepare 'test1';
xa rollback 'test1';
select * from t1;
xa start 'test2';
--error 1399
xa start 'test-bad';
insert t1 values (20);
--error 1399
xa prepare 'test2';
xa end 'test2';
xa prepare 'test2';
xa commit 'test2';
select * from t1;
xa start 'testa','testb';
insert t1 values (30);
xa end 'testa','testb';
connect (con1,localhost,,,);
connection con1;
xa start 0x7465737462, 0x2030405060, 0xb;
insert t1 values (40);
xa end 'testb',' 0@P`',11;
xa prepare 'testb',0x2030405060,11;
xa recover;
# uncomment the line below when binlog will be able to prepare
#disconnect con1;
connection default;
xa prepare 'testa','testb';
xa recover;
xa commit 'testb',0x2030405060,11;
xa rollback 'testa','testb';
--error 1064
xa start 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz';
select * from t1;
drop table t1;
......@@ -3236,7 +3236,7 @@ int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
from+= tmp_scan;
end= (char*) from+len;
tmp= cs->cset->my_strtoll10(cs, from, &end, &error);
tmp= cs->cset->strtoll10(cs, from, &end, &error);
if (error != MY_ERRNO_EDOM)
{
......
......@@ -750,17 +750,15 @@ int ha_autocommit_or_rollback(THD *thd, int error)
DBUG_RETURN(error);
}
int ha_commit_or_rollback_by_xid(LEX_STRING *ident, bool commit)
int ha_commit_or_rollback_by_xid(XID *xid, bool commit)
{
XID xid;
handlerton **ht= handlertons, **end_ht=ht+total_ha;
int res= 1;
xid.set(ident);
for ( ; ht < end_ht ; ht++)
if ((*ht)->recover)
res= res &&
(*(commit ? (*ht)->commit_by_xid : (*ht)->rollback_by_xid))(&xid);
(*(commit ? (*ht)->commit_by_xid : (*ht)->rollback_by_xid))(xid);
return res;
}
......@@ -2366,7 +2364,6 @@ TYPELIB *ha_known_exts(void)
const char **ext, *old_ext;
known_extensions_id= mysys_usage_id;
found_exts.push_back((char*) ".db");
for (types= sys_table_types; types->type; types++)
{
if (*types->value == SHOW_OPTION_YES)
......
......@@ -213,13 +213,22 @@ struct xid_t {
long bqual_length;
char data[XIDDATASIZE]; // not \0-terminated !
bool eq(LEX_STRING *l) { return eq(l->length, 0, l->str); }
bool eq(struct xid_t *xid)
{ return !memcmp(this, xid, sizeof(long)*3+gtrid_length+bqual_length); }
bool eq(long g, long b, const char *d)
{ return g == gtrid_length && b == bqual_length && !memcmp(d, data, g+b); }
void set(LEX_STRING *l) { set(l->length, 0, l->str); }
void set(struct xid_t *xid)
{ memcpy(this, xid, sizeof(long)*3+xid->gtrid_length+xid->bqual_length); }
void set(long f, const char *g, long gl, const char *b, long bl)
{
formatID= f;
memcpy(data, g, gtrid_length= gl);
memcpy(data+gl, b, bqual_length= bl);
}
void set(ulonglong xid)
{
my_xid tmp;
formatID= 1;
set(MYSQL_XID_PREFIX_LEN, 0, MYSQL_XID_PREFIX);
memcpy(data+MYSQL_XID_PREFIX_LEN, &server_id, sizeof(server_id));
tmp= xid;
......@@ -228,7 +237,7 @@ struct xid_t {
}
void set(long g, long b, const char *d)
{
formatID=1;
formatID= 1;
gtrid_length= g;
bqual_length= b;
memcpy(data, d, g+b);
......@@ -244,7 +253,7 @@ struct xid_t {
my_xid get_my_xid()
{
return gtrid_length == MYSQL_XID_GTRID_LEN && bqual_length == 0 &&
*(ulong*)(data+MYSQL_XID_PREFIX_LEN) == server_id &&
!memcmp(data+MYSQL_XID_PREFIX_LEN, &server_id, sizeof(server_id)) &&
!memcmp(data, MYSQL_XID_PREFIX, MYSQL_XID_PREFIX_LEN) ?
quick_get_my_xid() : 0;
}
......@@ -261,8 +270,8 @@ typedef struct xid_t XID;
/*
handlerton is a singleton structure - one instance per storage engine -
to provide access to storage engine functionality that works on
"global" level (unlike handler class that works on per-table basis)
to provide access to storage engine functionality that works on the
"global" level (unlike handler class that works on a per-table basis)
usually handlerton instance is defined statically in ha_xxx.cc as
......@@ -826,7 +835,7 @@ int ha_release_temporary_latches(THD *thd);
/* transactions: interface to handlerton functions */
int ha_start_consistent_snapshot(THD *thd);
int ha_commit_or_rollback_by_xid(LEX_STRING *ident, bool commit);
int ha_commit_or_rollback_by_xid(XID *xid, bool commit);
int ha_commit_one_phase(THD *thd, bool all);
int ha_rollback_trans(THD *thd, bool all);
int ha_prepare(THD *thd);
......
......@@ -734,7 +734,7 @@ class Item_sum_udf_str :public Item_udf_sum
return 0; /* Null value */
cs= res->charset();
end= (char*) res->ptr()+res->length();
return cs->cset->my_strtoll10(cs, res->ptr(), &end, &err_not_used);
return cs->cset->strtoll10(cs, res->ptr(), &end, &err_not_used);
}
my_decimal *val_decimal(my_decimal *dec);
enum Item_result result_type () const { return STRING_RESULT; }
......
......@@ -736,6 +736,13 @@ static void print_lock_error(int error, const char *table)
protect_against_global_read_lock
count of threads which have set protection against global read lock.
access to them is protected with a mutex LOCK_global_read_lock
(XXX: one should never take LOCK_open if LOCK_global_read_lock is taken,
otherwise a deadlock may occur - see mysql_rm_table. Other mutexes could
be a problem too - grep the code for global_read_lock if you want to use
any other mutex here)
How blocking of threads by global read lock is achieved: that's
advisory. Any piece of code which should be blocked by global read lock must
be designed like this:
......@@ -818,7 +825,7 @@ bool lock_global_read_lock(THD *thd)
}
thd->global_read_lock= GOT_GLOBAL_READ_LOCK;
global_read_lock++;
thd->exit_cond(old_message);
thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock
}
/*
We DON'T set global_read_lock_blocks_commit now, it will be set after
......@@ -888,7 +895,7 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh,
and if old_message is set
*/
if (unlikely(need_exit_cond))
thd->exit_cond(old_message);
thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock
else
pthread_mutex_unlock(&LOCK_global_read_lock);
DBUG_RETURN(result);
......@@ -938,7 +945,7 @@ bool make_global_read_lock_block_commit(THD *thd)
global_read_lock_blocks_commit--; // undo what we did
else
thd->global_read_lock= MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT;
thd->exit_cond(old_message);
thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock
DBUG_RETURN(error);
}
......@@ -342,6 +342,8 @@ void THD::change_user(void)
void THD::cleanup(void)
{
DBUG_ENTER("THD::cleanup");
/* TODO uncomment the line below when binlog will be able to prepare */
// if (transaction.xa_state != XA_PREPARED)
ha_rollback(this);
if (locked_tables)
{
......
......@@ -696,6 +696,7 @@ typedef struct st_lex
Item *default_value, *on_update_value;
LEX_STRING comment, ident;
LEX_USER *grant_user;
XID *xid;
gptr yacc_yyss,yacc_yyvs;
THD *thd;
CHARSET_INFO *charset;
......
......@@ -4323,7 +4323,7 @@ mysql_execute_command(THD *thd)
case SQLCOM_XA_START:
if (thd->transaction.xa_state == XA_IDLE && thd->lex->xa_opt == XA_RESUME)
{
if (! thd->transaction.xid.eq(&thd->lex->ident))
if (! thd->transaction.xid.eq(thd->lex->xid))
{
my_error(ER_XAER_NOTA, MYF(0));
break;
......@@ -4332,7 +4332,7 @@ mysql_execute_command(THD *thd)
send_ok(thd);
break;
}
if (thd->lex->ident.length > MAXGTRIDSIZE || thd->lex->xa_opt != XA_NONE)
if (thd->lex->xa_opt != XA_NONE)
{ // JOIN is not supported yet. TODO
my_error(ER_XAER_INVAL, MYF(0));
break;
......@@ -4350,7 +4350,7 @@ mysql_execute_command(THD *thd)
}
DBUG_ASSERT(thd->transaction.xid.is_null());
thd->transaction.xa_state=XA_ACTIVE;
thd->transaction.xid.set(&thd->lex->ident);
thd->transaction.xid.set(thd->lex->xid);
thd->options= ((thd->options & (ulong) ~(OPTION_STATUS_NO_TRANS_UPDATE)) |
OPTION_BEGIN);
thd->server_status|= SERVER_STATUS_IN_TRANS;
......@@ -4369,7 +4369,7 @@ mysql_execute_command(THD *thd)
xa_state_names[thd->transaction.xa_state]);
break;
}
if (!thd->transaction.xid.eq(&thd->lex->ident))
if (!thd->transaction.xid.eq(thd->lex->xid))
{
my_error(ER_XAER_NOTA, MYF(0));
break;
......@@ -4384,7 +4384,7 @@ mysql_execute_command(THD *thd)
xa_state_names[thd->transaction.xa_state]);
break;
}
if (!thd->transaction.xid.eq(&thd->lex->ident))
if (!thd->transaction.xid.eq(thd->lex->xid))
{
my_error(ER_XAER_NOTA, MYF(0));
break;
......@@ -4399,9 +4399,9 @@ mysql_execute_command(THD *thd)
send_ok(thd);
break;
case SQLCOM_XA_COMMIT:
if (!thd->transaction.xid.eq(&thd->lex->ident))
if (!thd->transaction.xid.eq(thd->lex->xid))
{
if (!(res= !ha_commit_or_rollback_by_xid(&thd->lex->ident, 1)))
if (!(res= !ha_commit_or_rollback_by_xid(thd->lex->xid, 1)))
my_error(ER_XAER_NOTA, MYF(0));
else
send_ok(thd);
......@@ -4434,9 +4434,9 @@ mysql_execute_command(THD *thd)
thd->transaction.xa_state=XA_NOTR;
break;
case SQLCOM_XA_ROLLBACK:
if (!thd->transaction.xid.eq(&thd->lex->ident))
if (!thd->transaction.xid.eq(thd->lex->xid))
{
if (!(res= !ha_commit_or_rollback_by_xid(&thd->lex->ident, 0)))
if (!(res= !ha_commit_or_rollback_by_xid(thd->lex->xid, 0)))
my_error(ER_XAER_NOTA, MYF(0));
else
send_ok(thd);
......
......@@ -243,7 +243,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token DUPLICATE_SYM
%token DYNAMIC_SYM
%token EACH_SYM
%token EALLOCATE_SYM
%token ELSEIF_SYM
%token ELT_FUNC
%token ENABLE_SYM
......@@ -702,7 +701,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
union_opt select_derived_init
%type <ulong_num>
ULONG_NUM raid_types merge_insert_types
ulong_num raid_types merge_insert_types
%type <ulonglong_number>
ulonglong_num
......@@ -1039,16 +1038,16 @@ master_def:
Lex->mi.password = $3.str;
}
|
MASTER_PORT_SYM EQ ULONG_NUM
MASTER_PORT_SYM EQ ulong_num
{
Lex->mi.port = $3;
}
|
MASTER_CONNECT_RETRY_SYM EQ ULONG_NUM
MASTER_CONNECT_RETRY_SYM EQ ulong_num
{
Lex->mi.connect_retry = $3;
}
| MASTER_SSL_SYM EQ ULONG_NUM
| MASTER_SSL_SYM EQ ulong_num
{
Lex->mi.ssl= $3 ?
LEX_MASTER_INFO::SSL_ENABLE : LEX_MASTER_INFO::SSL_DISABLE;
......@@ -1102,7 +1101,7 @@ master_file_def:
{
Lex->mi.relay_log_name = $3.str;
}
| RELAY_LOG_POS_SYM EQ ULONG_NUM
| RELAY_LOG_POS_SYM EQ ulong_num
{
Lex->mi.relay_log_pos = $3;
/* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */
......@@ -1792,7 +1791,7 @@ sp_hcond_list:
;
sp_cond:
ULONG_NUM
ulong_num
{ /* mysql errno */
$$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t));
$$->type= sp_cond_type_t::number;
......@@ -2578,18 +2577,18 @@ create_table_option:
| TYPE_SYM opt_equal storage_engines { Lex->create_info.db_type= $3; WARN_DEPRECATED("TYPE=storage_engine","ENGINE=storage_engine"); Lex->create_info.used_fields|= HA_CREATE_USED_ENGINE; }
| MAX_ROWS opt_equal ulonglong_num { Lex->create_info.max_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MAX_ROWS;}
| MIN_ROWS opt_equal ulonglong_num { Lex->create_info.min_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MIN_ROWS;}
| AVG_ROW_LENGTH opt_equal ULONG_NUM { Lex->create_info.avg_row_length=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AVG_ROW_LENGTH;}
| AVG_ROW_LENGTH opt_equal ulong_num { Lex->create_info.avg_row_length=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AVG_ROW_LENGTH;}
| PASSWORD opt_equal TEXT_STRING_sys { Lex->create_info.password=$3.str; Lex->create_info.used_fields|= HA_CREATE_USED_PASSWORD; }
| COMMENT_SYM opt_equal TEXT_STRING_sys { Lex->create_info.comment=$3.str; Lex->create_info.used_fields|= HA_CREATE_USED_COMMENT; }
| AUTO_INC opt_equal ulonglong_num { Lex->create_info.auto_increment_value=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AUTO;}
| PACK_KEYS_SYM opt_equal ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_PACK_KEYS : HA_OPTION_NO_PACK_KEYS; Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;}
| PACK_KEYS_SYM opt_equal ulong_num { Lex->create_info.table_options|= $3 ? HA_OPTION_PACK_KEYS : HA_OPTION_NO_PACK_KEYS; Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;}
| PACK_KEYS_SYM opt_equal DEFAULT { Lex->create_info.table_options&= ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS); Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;}
| CHECKSUM_SYM opt_equal ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM; Lex->create_info.used_fields|= HA_CREATE_USED_CHECKSUM; }
| DELAY_KEY_WRITE_SYM opt_equal ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_DELAY_KEY_WRITE : HA_OPTION_NO_DELAY_KEY_WRITE; Lex->create_info.used_fields|= HA_CREATE_USED_DELAY_KEY_WRITE; }
| CHECKSUM_SYM opt_equal ulong_num { Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM; Lex->create_info.used_fields|= HA_CREATE_USED_CHECKSUM; }
| DELAY_KEY_WRITE_SYM opt_equal ulong_num { Lex->create_info.table_options|= $3 ? HA_OPTION_DELAY_KEY_WRITE : HA_OPTION_NO_DELAY_KEY_WRITE; Lex->create_info.used_fields|= HA_CREATE_USED_DELAY_KEY_WRITE; }
| ROW_FORMAT_SYM opt_equal row_types { Lex->create_info.row_type= $3; Lex->create_info.used_fields|= HA_CREATE_USED_ROW_FORMAT; }
| RAID_TYPE opt_equal raid_types { Lex->create_info.raid_type= $3; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;}
| RAID_CHUNKS opt_equal ULONG_NUM { Lex->create_info.raid_chunks= $3; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;}
| RAID_CHUNKSIZE opt_equal ULONG_NUM { Lex->create_info.raid_chunksize= $3*RAID_BLOCK_SIZE; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;}
| RAID_CHUNKS opt_equal ulong_num { Lex->create_info.raid_chunks= $3; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;}
| RAID_CHUNKSIZE opt_equal ulong_num { Lex->create_info.raid_chunksize= $3*RAID_BLOCK_SIZE; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;}
| UNION_SYM opt_equal '(' table_list ')'
{
/* Move the union list to the merge_list */
......@@ -2666,7 +2665,7 @@ row_types:
raid_types:
RAID_STRIPED_SYM { $$= RAID_TYPE_0; }
| RAID_0_SYM { $$= RAID_TYPE_0; }
| ULONG_NUM { $$=$1;};
| ulong_num { $$=$1;};
merge_insert_types:
NO_SYM { $$= MERGE_INSERT_DISABLED; }
......@@ -4704,7 +4703,7 @@ simple_expr:
{ $$= new Item_func_yearweek($3,new Item_int((char*) "0",0,1)); }
| YEARWEEK '(' expr ',' expr ')'
{ $$= new Item_func_yearweek($3, $5); }
| BENCHMARK_SYM '(' ULONG_NUM ',' expr ')'
| BENCHMARK_SYM '(' ulong_num ',' expr ')'
{
$$=new Item_func_benchmark($3,$5);
Lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
......@@ -5488,21 +5487,21 @@ limit_clause:
;
limit_options:
ULONG_NUM
ulong_num
{
SELECT_LEX *sel= Select;
sel->select_limit= $1;
sel->offset_limit= 0L;
sel->explicit_limit= 1;
}
| ULONG_NUM ',' ULONG_NUM
| ulong_num ',' ulong_num
{
SELECT_LEX *sel= Select;
sel->select_limit= $3;
sel->offset_limit= $1;
sel->explicit_limit= 1;
}
| ULONG_NUM OFFSET_SYM ULONG_NUM
| ulong_num OFFSET_SYM ulong_num
{
SELECT_LEX *sel= Select;
sel->select_limit= $1;
......@@ -5525,8 +5524,9 @@ delete_limit_clause:
sel->explicit_limit= 1;
};
ULONG_NUM:
ulong_num:
NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
| HEX_NUM { int error; $$= (ulong) strtol($1.str, (char**) 0, 16); }
| LONG_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
| ULONGLONG_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
| DECIMAL_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
......@@ -6139,7 +6139,7 @@ show_param:
| NEW_SYM MASTER_SYM FOR_SYM SLAVE WITH MASTER_LOG_FILE_SYM EQ
TEXT_STRING_sys AND_SYM MASTER_LOG_POS_SYM EQ ulonglong_num
AND_SYM MASTER_SERVER_ID_SYM EQ
ULONG_NUM
ulong_num
{
Lex->sql_command = SQLCOM_SHOW_NEW_MASTER;
Lex->mi.log_file_name = $8.str;
......@@ -6838,7 +6838,7 @@ NUM_literal:
;
/**********************************************************************
** Createing different items.
** Creating different items.
**********************************************************************/
insert_ident:
......@@ -8124,25 +8124,25 @@ grant_option_list:
grant_option:
GRANT OPTION { Lex->grant |= GRANT_ACL;}
| MAX_QUERIES_PER_HOUR ULONG_NUM
| MAX_QUERIES_PER_HOUR ulong_num
{
LEX *lex=Lex;
lex->mqh.questions=$2;
lex->mqh.specified_limits|= USER_RESOURCES::QUERIES_PER_HOUR;
}
| MAX_UPDATES_PER_HOUR ULONG_NUM
| MAX_UPDATES_PER_HOUR ulong_num
{
LEX *lex=Lex;
lex->mqh.updates=$2;
lex->mqh.specified_limits|= USER_RESOURCES::UPDATES_PER_HOUR;
}
| MAX_CONNECTIONS_PER_HOUR ULONG_NUM
| MAX_CONNECTIONS_PER_HOUR ulong_num
{
LEX *lex=Lex;
lex->mqh.conn_per_hour= $2;
lex->mqh.specified_limits|= USER_RESOURCES::CONNECTIONS_PER_HOUR;
}
| MAX_USER_CONNECTIONS_SYM ULONG_NUM
| MAX_USER_CONNECTIONS_SYM ulong_num
{
LEX *lex=Lex;
lex->mqh.user_conn= $2;
......@@ -8413,37 +8413,51 @@ check_option:
xa: XA_SYM begin_or_start xid opt_join_or_resume
{
LEX *lex= Lex;
lex->sql_command = SQLCOM_XA_START;
Lex->sql_command = SQLCOM_XA_START;
}
| XA_SYM END xid opt_suspend_or_migrate
{
LEX *lex= Lex;
lex->sql_command = SQLCOM_XA_END;
Lex->sql_command = SQLCOM_XA_END;
}
| XA_SYM PREPARE_SYM xid
{
LEX *lex= Lex;
lex->sql_command = SQLCOM_XA_PREPARE;
Lex->sql_command = SQLCOM_XA_PREPARE;
}
| XA_SYM COMMIT_SYM xid opt_one_phase
{
LEX *lex= Lex;
lex->sql_command = SQLCOM_XA_COMMIT;
Lex->sql_command = SQLCOM_XA_COMMIT;
}
| XA_SYM ROLLBACK_SYM xid
{
LEX *lex= Lex;
lex->sql_command = SQLCOM_XA_ROLLBACK;
Lex->sql_command = SQLCOM_XA_ROLLBACK;
}
| XA_SYM RECOVER_SYM
{
LEX *lex= Lex;
lex->sql_command = SQLCOM_XA_RECOVER;
Lex->sql_command = SQLCOM_XA_RECOVER;
}
;
xid: ident_or_text { Lex->ident=$1; }
xid: text_string
{
TEST_ASSERT($1->length() <= MAXGTRIDSIZE);
if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID))))
YYABORT;
Lex->xid->set(1L, $1->ptr(), $1->length(), 0, 0);
}
| text_string ',' text_string
{
TEST_ASSERT($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE);
if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID))))
YYABORT;
Lex->xid->set(1L, $1->ptr(), $1->length(), $3->ptr(), $3->length());
}
| text_string ',' text_string ',' ulong_num
{
TEST_ASSERT($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE);
if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID))))
YYABORT;
Lex->xid->set($5, $1->ptr(), $1->length(), $3->ptr(), $3->length());
}
;
begin_or_start: BEGIN_SYM {}
......
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