mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
XID SQL syntax
minor cleanups XA tests
This commit is contained in:
@ -186,7 +186,7 @@ typedef struct my_charset_handler_st
|
|||||||
int base, char **e, int *err);
|
int base, char **e, int *err);
|
||||||
double (*strntod)(struct charset_info_st *, char *s, uint l, char **e,
|
double (*strntod)(struct charset_info_st *, char *s, uint l, char **e,
|
||||||
int *err);
|
int *err);
|
||||||
longlong (*my_strtoll10)(struct charset_info_st *cs,
|
longlong (*strtoll10)(struct charset_info_st *cs,
|
||||||
const char *nptr, char **endptr, int *error);
|
const char *nptr, char **endptr, int *error);
|
||||||
ulong (*scan)(struct charset_info_st *, const char *b, const char *e,
|
ulong (*scan)(struct charset_info_st *, const char *b, const char *e,
|
||||||
int sq);
|
int sq);
|
||||||
|
45
mysql-test/r/xa.result
Normal file
45
mysql-test/r/xa.result
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
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;
|
57
mysql-test/t/xa.test
Normal file
57
mysql-test/t/xa.test
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#
|
||||||
|
# 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;
|
||||||
|
|
@ -3230,13 +3230,13 @@ int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
|
|||||||
long store_tmp;
|
long store_tmp;
|
||||||
int error;
|
int error;
|
||||||
char *end;
|
char *end;
|
||||||
|
|
||||||
tmp_scan= cs->cset->scan(cs, from, from+len, MY_SEQ_SPACES);
|
tmp_scan= cs->cset->scan(cs, from, from+len, MY_SEQ_SPACES);
|
||||||
len-= tmp_scan;
|
len-= tmp_scan;
|
||||||
from+= tmp_scan;
|
from+= tmp_scan;
|
||||||
|
|
||||||
end= (char*) from+len;
|
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)
|
if (error != MY_ERRNO_EDOM)
|
||||||
{
|
{
|
||||||
|
@ -750,17 +750,15 @@ int ha_autocommit_or_rollback(THD *thd, int error)
|
|||||||
DBUG_RETURN(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;
|
handlerton **ht= handlertons, **end_ht=ht+total_ha;
|
||||||
int res= 1;
|
int res= 1;
|
||||||
|
|
||||||
xid.set(ident);
|
|
||||||
for ( ; ht < end_ht ; ht++)
|
for ( ; ht < end_ht ; ht++)
|
||||||
if ((*ht)->recover)
|
if ((*ht)->recover)
|
||||||
res= res &&
|
res= res &&
|
||||||
(*(commit ? (*ht)->commit_by_xid : (*ht)->rollback_by_xid))(&xid);
|
(*(commit ? (*ht)->commit_by_xid : (*ht)->rollback_by_xid))(xid);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2366,9 +2364,8 @@ TYPELIB *ha_known_exts(void)
|
|||||||
const char **ext, *old_ext;
|
const char **ext, *old_ext;
|
||||||
|
|
||||||
known_extensions_id= mysys_usage_id;
|
known_extensions_id= mysys_usage_id;
|
||||||
found_exts.push_back((char*) ".db");
|
|
||||||
for (types= sys_table_types; types->type; types++)
|
for (types= sys_table_types; types->type; types++)
|
||||||
{
|
{
|
||||||
if (*types->value == SHOW_OPTION_YES)
|
if (*types->value == SHOW_OPTION_YES)
|
||||||
{
|
{
|
||||||
handler *file= get_new_handler(0,(enum db_type) types->db_type);
|
handler *file= get_new_handler(0,(enum db_type) types->db_type);
|
||||||
|
@ -213,13 +213,22 @@ struct xid_t {
|
|||||||
long bqual_length;
|
long bqual_length;
|
||||||
char data[XIDDATASIZE]; // not \0-terminated !
|
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)
|
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(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)
|
void set(ulonglong xid)
|
||||||
{
|
{
|
||||||
my_xid tmp;
|
my_xid tmp;
|
||||||
|
formatID= 1;
|
||||||
set(MYSQL_XID_PREFIX_LEN, 0, MYSQL_XID_PREFIX);
|
set(MYSQL_XID_PREFIX_LEN, 0, MYSQL_XID_PREFIX);
|
||||||
memcpy(data+MYSQL_XID_PREFIX_LEN, &server_id, sizeof(server_id));
|
memcpy(data+MYSQL_XID_PREFIX_LEN, &server_id, sizeof(server_id));
|
||||||
tmp= xid;
|
tmp= xid;
|
||||||
@ -228,7 +237,7 @@ struct xid_t {
|
|||||||
}
|
}
|
||||||
void set(long g, long b, const char *d)
|
void set(long g, long b, const char *d)
|
||||||
{
|
{
|
||||||
formatID=1;
|
formatID= 1;
|
||||||
gtrid_length= g;
|
gtrid_length= g;
|
||||||
bqual_length= b;
|
bqual_length= b;
|
||||||
memcpy(data, d, g+b);
|
memcpy(data, d, g+b);
|
||||||
@ -244,7 +253,7 @@ struct xid_t {
|
|||||||
my_xid get_my_xid()
|
my_xid get_my_xid()
|
||||||
{
|
{
|
||||||
return gtrid_length == MYSQL_XID_GTRID_LEN && bqual_length == 0 &&
|
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) ?
|
!memcmp(data, MYSQL_XID_PREFIX, MYSQL_XID_PREFIX_LEN) ?
|
||||||
quick_get_my_xid() : 0;
|
quick_get_my_xid() : 0;
|
||||||
}
|
}
|
||||||
@ -261,8 +270,8 @@ typedef struct xid_t XID;
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
handlerton is a singleton structure - one instance per storage engine -
|
handlerton is a singleton structure - one instance per storage engine -
|
||||||
to provide access to storage engine functionality that works on
|
to provide access to storage engine functionality that works on the
|
||||||
"global" level (unlike handler class that works on per-table basis)
|
"global" level (unlike handler class that works on a per-table basis)
|
||||||
|
|
||||||
usually handlerton instance is defined statically in ha_xxx.cc as
|
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 */
|
/* transactions: interface to handlerton functions */
|
||||||
int ha_start_consistent_snapshot(THD *thd);
|
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_commit_one_phase(THD *thd, bool all);
|
||||||
int ha_rollback_trans(THD *thd, bool all);
|
int ha_rollback_trans(THD *thd, bool all);
|
||||||
int ha_prepare(THD *thd);
|
int ha_prepare(THD *thd);
|
||||||
|
@ -734,7 +734,7 @@ public:
|
|||||||
return 0; /* Null value */
|
return 0; /* Null value */
|
||||||
cs= res->charset();
|
cs= res->charset();
|
||||||
end= (char*) res->ptr()+res->length();
|
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);
|
my_decimal *val_decimal(my_decimal *dec);
|
||||||
enum Item_result result_type () const { return STRING_RESULT; }
|
enum Item_result result_type () const { return STRING_RESULT; }
|
||||||
|
17
sql/lock.cc
17
sql/lock.cc
@ -736,6 +736,13 @@ static void print_lock_error(int error, const char *table)
|
|||||||
protect_against_global_read_lock
|
protect_against_global_read_lock
|
||||||
count of threads which have set protection 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
|
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
|
advisory. Any piece of code which should be blocked by global read lock must
|
||||||
be designed like this:
|
be designed like this:
|
||||||
@ -773,7 +780,7 @@ static void print_lock_error(int error, const char *table)
|
|||||||
table instance of thd2
|
table instance of thd2
|
||||||
thd1: COMMIT; # blocked by thd3.
|
thd1: COMMIT; # blocked by thd3.
|
||||||
thd1 blocks thd2 which blocks thd3 which blocks thd1: deadlock.
|
thd1 blocks thd2 which blocks thd3 which blocks thd1: deadlock.
|
||||||
|
|
||||||
Note that we need to support that one thread does
|
Note that we need to support that one thread does
|
||||||
FLUSH TABLES WITH READ LOCK; and then COMMIT;
|
FLUSH TABLES WITH READ LOCK; and then COMMIT;
|
||||||
(that's what innobackup does, for some good reason).
|
(that's what innobackup does, for some good reason).
|
||||||
@ -818,7 +825,7 @@ bool lock_global_read_lock(THD *thd)
|
|||||||
}
|
}
|
||||||
thd->global_read_lock= GOT_GLOBAL_READ_LOCK;
|
thd->global_read_lock= GOT_GLOBAL_READ_LOCK;
|
||||||
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
|
We DON'T set global_read_lock_blocks_commit now, it will be set after
|
||||||
@ -887,8 +894,8 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh,
|
|||||||
The following is only true in case of a global read locks (which is rare)
|
The following is only true in case of a global read locks (which is rare)
|
||||||
and if old_message is set
|
and if old_message is set
|
||||||
*/
|
*/
|
||||||
if (unlikely(need_exit_cond))
|
if (unlikely(need_exit_cond))
|
||||||
thd->exit_cond(old_message);
|
thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock
|
||||||
else
|
else
|
||||||
pthread_mutex_unlock(&LOCK_global_read_lock);
|
pthread_mutex_unlock(&LOCK_global_read_lock);
|
||||||
DBUG_RETURN(result);
|
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
|
global_read_lock_blocks_commit--; // undo what we did
|
||||||
else
|
else
|
||||||
thd->global_read_lock= MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT;
|
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);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,7 +342,9 @@ void THD::change_user(void)
|
|||||||
void THD::cleanup(void)
|
void THD::cleanup(void)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("THD::cleanup");
|
DBUG_ENTER("THD::cleanup");
|
||||||
ha_rollback(this);
|
/* TODO uncomment the line below when binlog will be able to prepare */
|
||||||
|
// if (transaction.xa_state != XA_PREPARED)
|
||||||
|
ha_rollback(this);
|
||||||
if (locked_tables)
|
if (locked_tables)
|
||||||
{
|
{
|
||||||
lock=locked_tables; locked_tables=0;
|
lock=locked_tables; locked_tables=0;
|
||||||
@ -384,17 +386,17 @@ THD::~THD()
|
|||||||
add_to_status(&global_status_var, &status_var);
|
add_to_status(&global_status_var, &status_var);
|
||||||
|
|
||||||
/* Close connection */
|
/* Close connection */
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
if (net.vio)
|
if (net.vio)
|
||||||
{
|
{
|
||||||
vio_delete(net.vio);
|
vio_delete(net.vio);
|
||||||
net_end(&net);
|
net_end(&net);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (!cleanup_done)
|
if (!cleanup_done)
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
ha_close_connection(this);
|
ha_close_connection(this);
|
||||||
|
|
||||||
sp_cache_clear(&sp_proc_cache);
|
sp_cache_clear(&sp_proc_cache);
|
||||||
sp_cache_clear(&sp_func_cache);
|
sp_cache_clear(&sp_func_cache);
|
||||||
|
@ -696,6 +696,7 @@ typedef struct st_lex
|
|||||||
Item *default_value, *on_update_value;
|
Item *default_value, *on_update_value;
|
||||||
LEX_STRING comment, ident;
|
LEX_STRING comment, ident;
|
||||||
LEX_USER *grant_user;
|
LEX_USER *grant_user;
|
||||||
|
XID *xid;
|
||||||
gptr yacc_yyss,yacc_yyvs;
|
gptr yacc_yyss,yacc_yyvs;
|
||||||
THD *thd;
|
THD *thd;
|
||||||
CHARSET_INFO *charset;
|
CHARSET_INFO *charset;
|
||||||
@ -738,7 +739,7 @@ typedef struct st_lex
|
|||||||
enum enum_tx_isolation tx_isolation;
|
enum enum_tx_isolation tx_isolation;
|
||||||
enum enum_ha_read_modes ha_read_mode;
|
enum enum_ha_read_modes ha_read_mode;
|
||||||
union {
|
union {
|
||||||
enum ha_rkey_function ha_rkey_mode;
|
enum ha_rkey_function ha_rkey_mode;
|
||||||
enum xa_option_words xa_opt;
|
enum xa_option_words xa_opt;
|
||||||
};
|
};
|
||||||
enum enum_var_type option_type;
|
enum enum_var_type option_type;
|
||||||
@ -764,15 +765,15 @@ typedef struct st_lex
|
|||||||
ALTER_INFO alter_info;
|
ALTER_INFO alter_info;
|
||||||
/* Prepared statements SQL syntax:*/
|
/* Prepared statements SQL syntax:*/
|
||||||
LEX_STRING prepared_stmt_name; /* Statement name (in all queries) */
|
LEX_STRING prepared_stmt_name; /* Statement name (in all queries) */
|
||||||
/*
|
/*
|
||||||
Prepared statement query text or name of variable that holds the
|
Prepared statement query text or name of variable that holds the
|
||||||
prepared statement (in PREPARE ... queries)
|
prepared statement (in PREPARE ... queries)
|
||||||
*/
|
*/
|
||||||
LEX_STRING prepared_stmt_code;
|
LEX_STRING prepared_stmt_code;
|
||||||
/* If true, prepared_stmt_code is a name of variable that holds the query */
|
/* If true, prepared_stmt_code is a name of variable that holds the query */
|
||||||
bool prepared_stmt_code_is_varref;
|
bool prepared_stmt_code_is_varref;
|
||||||
/* Names of user variables holding parameters (in EXECUTE) */
|
/* Names of user variables holding parameters (in EXECUTE) */
|
||||||
List<LEX_STRING> prepared_stmt_params;
|
List<LEX_STRING> prepared_stmt_params;
|
||||||
/*
|
/*
|
||||||
Points to part of global table list which contains time zone tables
|
Points to part of global table list which contains time zone tables
|
||||||
implicitly used by the statement.
|
implicitly used by the statement.
|
||||||
|
@ -4323,7 +4323,7 @@ unsent_create_error:
|
|||||||
case SQLCOM_XA_START:
|
case SQLCOM_XA_START:
|
||||||
if (thd->transaction.xa_state == XA_IDLE && thd->lex->xa_opt == XA_RESUME)
|
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));
|
my_error(ER_XAER_NOTA, MYF(0));
|
||||||
break;
|
break;
|
||||||
@ -4332,7 +4332,7 @@ unsent_create_error:
|
|||||||
send_ok(thd);
|
send_ok(thd);
|
||||||
break;
|
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
|
{ // JOIN is not supported yet. TODO
|
||||||
my_error(ER_XAER_INVAL, MYF(0));
|
my_error(ER_XAER_INVAL, MYF(0));
|
||||||
break;
|
break;
|
||||||
@ -4350,7 +4350,7 @@ unsent_create_error:
|
|||||||
}
|
}
|
||||||
DBUG_ASSERT(thd->transaction.xid.is_null());
|
DBUG_ASSERT(thd->transaction.xid.is_null());
|
||||||
thd->transaction.xa_state=XA_ACTIVE;
|
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)) |
|
thd->options= ((thd->options & (ulong) ~(OPTION_STATUS_NO_TRANS_UPDATE)) |
|
||||||
OPTION_BEGIN);
|
OPTION_BEGIN);
|
||||||
thd->server_status|= SERVER_STATUS_IN_TRANS;
|
thd->server_status|= SERVER_STATUS_IN_TRANS;
|
||||||
@ -4369,7 +4369,7 @@ unsent_create_error:
|
|||||||
xa_state_names[thd->transaction.xa_state]);
|
xa_state_names[thd->transaction.xa_state]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!thd->transaction.xid.eq(&thd->lex->ident))
|
if (!thd->transaction.xid.eq(thd->lex->xid))
|
||||||
{
|
{
|
||||||
my_error(ER_XAER_NOTA, MYF(0));
|
my_error(ER_XAER_NOTA, MYF(0));
|
||||||
break;
|
break;
|
||||||
@ -4384,7 +4384,7 @@ unsent_create_error:
|
|||||||
xa_state_names[thd->transaction.xa_state]);
|
xa_state_names[thd->transaction.xa_state]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!thd->transaction.xid.eq(&thd->lex->ident))
|
if (!thd->transaction.xid.eq(thd->lex->xid))
|
||||||
{
|
{
|
||||||
my_error(ER_XAER_NOTA, MYF(0));
|
my_error(ER_XAER_NOTA, MYF(0));
|
||||||
break;
|
break;
|
||||||
@ -4399,9 +4399,9 @@ unsent_create_error:
|
|||||||
send_ok(thd);
|
send_ok(thd);
|
||||||
break;
|
break;
|
||||||
case SQLCOM_XA_COMMIT:
|
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));
|
my_error(ER_XAER_NOTA, MYF(0));
|
||||||
else
|
else
|
||||||
send_ok(thd);
|
send_ok(thd);
|
||||||
@ -4434,9 +4434,9 @@ unsent_create_error:
|
|||||||
thd->transaction.xa_state=XA_NOTR;
|
thd->transaction.xa_state=XA_NOTR;
|
||||||
break;
|
break;
|
||||||
case SQLCOM_XA_ROLLBACK:
|
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));
|
my_error(ER_XAER_NOTA, MYF(0));
|
||||||
else
|
else
|
||||||
send_ok(thd);
|
send_ok(thd);
|
||||||
|
150
sql/sql_yacc.yy
150
sql/sql_yacc.yy
@ -47,13 +47,13 @@ const LEX_STRING null_lex_str={0,0};
|
|||||||
|
|
||||||
#define yyoverflow(A,B,C,D,E,F) {ulong val= *(F); if(my_yyoverflow((B), (D), &val)) { yyerror((char*) (A)); return 2; } else { *(F)= (YYSIZE_T)val; }}
|
#define yyoverflow(A,B,C,D,E,F) {ulong val= *(F); if(my_yyoverflow((B), (D), &val)) { yyerror((char*) (A)); return 2; } else { *(F)= (YYSIZE_T)val; }}
|
||||||
|
|
||||||
#define WARN_DEPRECATED(A,B) \
|
#define WARN_DEPRECATED(A,B) \
|
||||||
push_warning_printf(((THD *)yythd), MYSQL_ERROR::WARN_LEVEL_WARN, \
|
push_warning_printf(((THD *)yythd), MYSQL_ERROR::WARN_LEVEL_WARN, \
|
||||||
ER_WARN_DEPRECATED_SYNTAX, \
|
ER_WARN_DEPRECATED_SYNTAX, \
|
||||||
ER(ER_WARN_DEPRECATED_SYNTAX), (A), (B));
|
ER(ER_WARN_DEPRECATED_SYNTAX), (A), (B));
|
||||||
|
|
||||||
#define TEST_ASSERT(A) \
|
#define TEST_ASSERT(A) \
|
||||||
if (!(A)) \
|
if (!(A)) \
|
||||||
{ \
|
{ \
|
||||||
yyerror(ER(ER_SYNTAX_ERROR)); \
|
yyerror(ER(ER_SYNTAX_ERROR)); \
|
||||||
YYABORT; \
|
YYABORT; \
|
||||||
@ -243,7 +243,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
%token DUPLICATE_SYM
|
%token DUPLICATE_SYM
|
||||||
%token DYNAMIC_SYM
|
%token DYNAMIC_SYM
|
||||||
%token EACH_SYM
|
%token EACH_SYM
|
||||||
%token EALLOCATE_SYM
|
|
||||||
%token ELSEIF_SYM
|
%token ELSEIF_SYM
|
||||||
%token ELT_FUNC
|
%token ELT_FUNC
|
||||||
%token ENABLE_SYM
|
%token ENABLE_SYM
|
||||||
@ -702,7 +701,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
union_opt select_derived_init
|
union_opt select_derived_init
|
||||||
|
|
||||||
%type <ulong_num>
|
%type <ulong_num>
|
||||||
ULONG_NUM raid_types merge_insert_types
|
ulong_num raid_types merge_insert_types
|
||||||
|
|
||||||
%type <ulonglong_number>
|
%type <ulonglong_number>
|
||||||
ulonglong_num
|
ulonglong_num
|
||||||
@ -1039,16 +1038,16 @@ master_def:
|
|||||||
Lex->mi.password = $3.str;
|
Lex->mi.password = $3.str;
|
||||||
}
|
}
|
||||||
|
|
|
|
||||||
MASTER_PORT_SYM EQ ULONG_NUM
|
MASTER_PORT_SYM EQ ulong_num
|
||||||
{
|
{
|
||||||
Lex->mi.port = $3;
|
Lex->mi.port = $3;
|
||||||
}
|
}
|
||||||
|
|
|
|
||||||
MASTER_CONNECT_RETRY_SYM EQ ULONG_NUM
|
MASTER_CONNECT_RETRY_SYM EQ ulong_num
|
||||||
{
|
{
|
||||||
Lex->mi.connect_retry = $3;
|
Lex->mi.connect_retry = $3;
|
||||||
}
|
}
|
||||||
| MASTER_SSL_SYM EQ ULONG_NUM
|
| MASTER_SSL_SYM EQ ulong_num
|
||||||
{
|
{
|
||||||
Lex->mi.ssl= $3 ?
|
Lex->mi.ssl= $3 ?
|
||||||
LEX_MASTER_INFO::SSL_ENABLE : LEX_MASTER_INFO::SSL_DISABLE;
|
LEX_MASTER_INFO::SSL_ENABLE : LEX_MASTER_INFO::SSL_DISABLE;
|
||||||
@ -1102,7 +1101,7 @@ master_file_def:
|
|||||||
{
|
{
|
||||||
Lex->mi.relay_log_name = $3.str;
|
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;
|
Lex->mi.relay_log_pos = $3;
|
||||||
/* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */
|
/* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */
|
||||||
@ -1792,7 +1791,7 @@ sp_hcond_list:
|
|||||||
;
|
;
|
||||||
|
|
||||||
sp_cond:
|
sp_cond:
|
||||||
ULONG_NUM
|
ulong_num
|
||||||
{ /* mysql errno */
|
{ /* mysql errno */
|
||||||
$$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t));
|
$$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t));
|
||||||
$$->type= sp_cond_type_t::number;
|
$$->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; }
|
| 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;}
|
| 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;}
|
| 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; }
|
| 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; }
|
| 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;}
|
| 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;}
|
| 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; }
|
| 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; }
|
| 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; }
|
| 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_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_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_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 ')'
|
| UNION_SYM opt_equal '(' table_list ')'
|
||||||
{
|
{
|
||||||
/* Move the union list to the merge_list */
|
/* Move the union list to the merge_list */
|
||||||
@ -2666,7 +2665,7 @@ row_types:
|
|||||||
raid_types:
|
raid_types:
|
||||||
RAID_STRIPED_SYM { $$= RAID_TYPE_0; }
|
RAID_STRIPED_SYM { $$= RAID_TYPE_0; }
|
||||||
| RAID_0_SYM { $$= RAID_TYPE_0; }
|
| RAID_0_SYM { $$= RAID_TYPE_0; }
|
||||||
| ULONG_NUM { $$=$1;};
|
| ulong_num { $$=$1;};
|
||||||
|
|
||||||
merge_insert_types:
|
merge_insert_types:
|
||||||
NO_SYM { $$= MERGE_INSERT_DISABLED; }
|
NO_SYM { $$= MERGE_INSERT_DISABLED; }
|
||||||
@ -4704,7 +4703,7 @@ simple_expr:
|
|||||||
{ $$= new Item_func_yearweek($3,new Item_int((char*) "0",0,1)); }
|
{ $$= new Item_func_yearweek($3,new Item_int((char*) "0",0,1)); }
|
||||||
| YEARWEEK '(' expr ',' expr ')'
|
| YEARWEEK '(' expr ',' expr ')'
|
||||||
{ $$= new Item_func_yearweek($3, $5); }
|
{ $$= new Item_func_yearweek($3, $5); }
|
||||||
| BENCHMARK_SYM '(' ULONG_NUM ',' expr ')'
|
| BENCHMARK_SYM '(' ulong_num ',' expr ')'
|
||||||
{
|
{
|
||||||
$$=new Item_func_benchmark($3,$5);
|
$$=new Item_func_benchmark($3,$5);
|
||||||
Lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
|
Lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
|
||||||
@ -4989,7 +4988,7 @@ table_ref:
|
|||||||
join_table_list:
|
join_table_list:
|
||||||
derived_table_list { TEST_ASSERT($$=$1); }
|
derived_table_list { TEST_ASSERT($$=$1); }
|
||||||
;
|
;
|
||||||
|
|
||||||
/* Warning - may return NULL in case of incomplete SELECT */
|
/* Warning - may return NULL in case of incomplete SELECT */
|
||||||
derived_table_list:
|
derived_table_list:
|
||||||
table_ref { $$=$1; }
|
table_ref { $$=$1; }
|
||||||
@ -5033,7 +5032,7 @@ join_table:
|
|||||||
$$=$6;
|
$$=$6;
|
||||||
}
|
}
|
||||||
| table_ref RIGHT opt_outer JOIN_SYM table_ref ON expr
|
| table_ref RIGHT opt_outer JOIN_SYM table_ref ON expr
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
TEST_ASSERT($1 && $5);
|
TEST_ASSERT($1 && $5);
|
||||||
if (!($$= lex->current_select->convert_right_join()))
|
if (!($$= lex->current_select->convert_right_join()))
|
||||||
@ -5047,7 +5046,7 @@ join_table:
|
|||||||
sel->save_names_for_using_list($1, $5);
|
sel->save_names_for_using_list($1, $5);
|
||||||
}
|
}
|
||||||
USING '(' using_list ')'
|
USING '(' using_list ')'
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
if (!($$= lex->current_select->convert_right_join()))
|
if (!($$= lex->current_select->convert_right_join()))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
@ -5063,7 +5062,7 @@ join_table:
|
|||||||
}
|
}
|
||||||
| table_ref NATURAL JOIN_SYM table_factor
|
| table_ref NATURAL JOIN_SYM table_factor
|
||||||
{ TEST_ASSERT($1 && ($$=$4)); add_join_natural($1,$4); };
|
{ TEST_ASSERT($1 && ($$=$4)); add_join_natural($1,$4); };
|
||||||
|
|
||||||
|
|
||||||
normal_join:
|
normal_join:
|
||||||
JOIN_SYM {}
|
JOIN_SYM {}
|
||||||
@ -5109,9 +5108,9 @@ table_factor:
|
|||||||
sel->master_unit()->fake_select_lex;
|
sel->master_unit()->fake_select_lex;
|
||||||
}
|
}
|
||||||
if ($2->init_nested_join(lex->thd))
|
if ($2->init_nested_join(lex->thd))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
$$= 0;
|
$$= 0;
|
||||||
/* incomplete derived tables return NULL, we must be
|
/* incomplete derived tables return NULL, we must be
|
||||||
nested in select_derived rule to be here. */
|
nested in select_derived rule to be here. */
|
||||||
}
|
}
|
||||||
| '(' get_select_lex select_derived union_opt ')' opt_table_alias
|
| '(' get_select_lex select_derived union_opt ')' opt_table_alias
|
||||||
@ -5119,7 +5118,7 @@ table_factor:
|
|||||||
/* Use $2 instead of Lex->current_select as derived table will
|
/* Use $2 instead of Lex->current_select as derived table will
|
||||||
alter value of Lex->current_select. */
|
alter value of Lex->current_select. */
|
||||||
|
|
||||||
if (!($3 || $6) && $2->embedding &&
|
if (!($3 || $6) && $2->embedding &&
|
||||||
!$2->embedding->nested_join->join_list.elements)
|
!$2->embedding->nested_join->join_list.elements)
|
||||||
{
|
{
|
||||||
/* we have a derived table ($3 == NULL) but no alias,
|
/* we have a derived table ($3 == NULL) but no alias,
|
||||||
@ -5144,7 +5143,7 @@ table_factor:
|
|||||||
(List<String> *)0)))
|
(List<String> *)0)))
|
||||||
|
|
||||||
YYABORT;
|
YYABORT;
|
||||||
sel->add_joined_table($$);
|
sel->add_joined_table($$);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if ($4 || $6)
|
if ($4 || $6)
|
||||||
@ -5171,7 +5170,7 @@ select_derived:
|
|||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
/* for normal joins, $3 != NULL and end_nested_join() != NULL,
|
/* for normal joins, $3 != NULL and end_nested_join() != NULL,
|
||||||
for derived tables, both must equal NULL */
|
for derived tables, both must equal NULL */
|
||||||
|
|
||||||
if (!($$= $1->end_nested_join(lex->thd)) && $3)
|
if (!($$= $1->end_nested_join(lex->thd)) && $3)
|
||||||
YYABORT;
|
YYABORT;
|
||||||
if (!$3 && $$)
|
if (!$3 && $$)
|
||||||
@ -5215,7 +5214,7 @@ select_derived_init:
|
|||||||
SELECT_SYM
|
SELECT_SYM
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
SELECT_LEX *sel= lex->current_select;
|
SELECT_LEX *sel= lex->current_select;
|
||||||
TABLE_LIST *embedding;
|
TABLE_LIST *embedding;
|
||||||
if (!sel->embedding || sel->end_nested_join(lex->thd))
|
if (!sel->embedding || sel->end_nested_join(lex->thd))
|
||||||
{
|
{
|
||||||
@ -5488,21 +5487,21 @@ limit_clause:
|
|||||||
;
|
;
|
||||||
|
|
||||||
limit_options:
|
limit_options:
|
||||||
ULONG_NUM
|
ulong_num
|
||||||
{
|
{
|
||||||
SELECT_LEX *sel= Select;
|
SELECT_LEX *sel= Select;
|
||||||
sel->select_limit= $1;
|
sel->select_limit= $1;
|
||||||
sel->offset_limit= 0L;
|
sel->offset_limit= 0L;
|
||||||
sel->explicit_limit= 1;
|
sel->explicit_limit= 1;
|
||||||
}
|
}
|
||||||
| ULONG_NUM ',' ULONG_NUM
|
| ulong_num ',' ulong_num
|
||||||
{
|
{
|
||||||
SELECT_LEX *sel= Select;
|
SELECT_LEX *sel= Select;
|
||||||
sel->select_limit= $3;
|
sel->select_limit= $3;
|
||||||
sel->offset_limit= $1;
|
sel->offset_limit= $1;
|
||||||
sel->explicit_limit= 1;
|
sel->explicit_limit= 1;
|
||||||
}
|
}
|
||||||
| ULONG_NUM OFFSET_SYM ULONG_NUM
|
| ulong_num OFFSET_SYM ulong_num
|
||||||
{
|
{
|
||||||
SELECT_LEX *sel= Select;
|
SELECT_LEX *sel= Select;
|
||||||
sel->select_limit= $1;
|
sel->select_limit= $1;
|
||||||
@ -5525,11 +5524,12 @@ delete_limit_clause:
|
|||||||
sel->explicit_limit= 1;
|
sel->explicit_limit= 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
ULONG_NUM:
|
ulong_num:
|
||||||
NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
|
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); }
|
| LONG_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
|
||||||
| ULONGLONG_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); }
|
| DECIMAL_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
|
||||||
| FLOAT_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
|
| FLOAT_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
|
| 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
|
TEXT_STRING_sys AND_SYM MASTER_LOG_POS_SYM EQ ulonglong_num
|
||||||
AND_SYM MASTER_SERVER_ID_SYM EQ
|
AND_SYM MASTER_SERVER_ID_SYM EQ
|
||||||
ULONG_NUM
|
ulong_num
|
||||||
{
|
{
|
||||||
Lex->sql_command = SQLCOM_SHOW_NEW_MASTER;
|
Lex->sql_command = SQLCOM_SHOW_NEW_MASTER;
|
||||||
Lex->mi.log_file_name = $8.str;
|
Lex->mi.log_file_name = $8.str;
|
||||||
@ -6688,7 +6688,7 @@ fields_or_vars:
|
|||||||
| field_or_var
|
| field_or_var
|
||||||
{ Lex->field_list.push_back($1); }
|
{ Lex->field_list.push_back($1); }
|
||||||
;
|
;
|
||||||
|
|
||||||
field_or_var:
|
field_or_var:
|
||||||
simple_ident_nospvar {$$= $1;}
|
simple_ident_nospvar {$$= $1;}
|
||||||
| '@' ident_or_text
|
| '@' ident_or_text
|
||||||
@ -6836,9 +6836,9 @@ NUM_literal:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
** Createing different items.
|
** Creating different items.
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
insert_ident:
|
insert_ident:
|
||||||
@ -6854,8 +6854,8 @@ table_wild:
|
|||||||
| ident '.' ident '.' '*'
|
| ident '.' ident '.' '*'
|
||||||
{
|
{
|
||||||
$$ = new Item_field((YYTHD->client_capabilities &
|
$$ = new Item_field((YYTHD->client_capabilities &
|
||||||
CLIENT_NO_SCHEMA ? NullS : $1.str),
|
CLIENT_NO_SCHEMA ? NullS : $1.str),
|
||||||
$3.str,"*");
|
$3.str,"*");
|
||||||
Lex->current_select->with_wild++;
|
Lex->current_select->with_wild++;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -6898,53 +6898,53 @@ simple_ident_nospvar:
|
|||||||
(Item*) new Item_ref(NullS,NullS,$1.str);
|
(Item*) new Item_ref(NullS,NullS,$1.str);
|
||||||
}
|
}
|
||||||
| simple_ident_q { $$= $1; }
|
| simple_ident_q { $$= $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
simple_ident_q:
|
simple_ident_q:
|
||||||
ident '.' ident
|
ident '.' ident
|
||||||
{
|
{
|
||||||
THD *thd= YYTHD;
|
THD *thd= YYTHD;
|
||||||
LEX *lex= thd->lex;
|
LEX *lex= thd->lex;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
FIXME This will work ok in simple_ident_nospvar case because
|
FIXME This will work ok in simple_ident_nospvar case because
|
||||||
we can't meet simple_ident_nospvar in trigger now. But it
|
we can't meet simple_ident_nospvar in trigger now. But it
|
||||||
should be changed in future.
|
should be changed in future.
|
||||||
*/
|
*/
|
||||||
if (lex->sphead && lex->sphead->m_type == TYPE_ENUM_TRIGGER &&
|
if (lex->sphead && lex->sphead->m_type == TYPE_ENUM_TRIGGER &&
|
||||||
(!my_strcasecmp(system_charset_info, $1.str, "NEW") ||
|
(!my_strcasecmp(system_charset_info, $1.str, "NEW") ||
|
||||||
!my_strcasecmp(system_charset_info, $1.str, "OLD")))
|
!my_strcasecmp(system_charset_info, $1.str, "OLD")))
|
||||||
{
|
{
|
||||||
Item_trigger_field *trg_fld;
|
Item_trigger_field *trg_fld;
|
||||||
bool new_row= ($1.str[0]=='N' || $1.str[0]=='n');
|
bool new_row= ($1.str[0]=='N' || $1.str[0]=='n');
|
||||||
|
|
||||||
if (lex->trg_chistics.event == TRG_EVENT_INSERT &&
|
if (lex->trg_chistics.event == TRG_EVENT_INSERT &&
|
||||||
!new_row)
|
!new_row)
|
||||||
{
|
{
|
||||||
my_error(ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0), "OLD", "on INSERT");
|
my_error(ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0), "OLD", "on INSERT");
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lex->trg_chistics.event == TRG_EVENT_DELETE &&
|
if (lex->trg_chistics.event == TRG_EVENT_DELETE &&
|
||||||
new_row)
|
new_row)
|
||||||
{
|
{
|
||||||
my_error(ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0), "NEW", "on DELETE");
|
my_error(ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0), "NEW", "on DELETE");
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(trg_fld= new Item_trigger_field(new_row ?
|
if (!(trg_fld= new Item_trigger_field(new_row ?
|
||||||
Item_trigger_field::NEW_ROW:
|
Item_trigger_field::NEW_ROW:
|
||||||
Item_trigger_field::OLD_ROW,
|
Item_trigger_field::OLD_ROW,
|
||||||
$3.str)))
|
$3.str)))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Let us add this item to list of all Item_trigger_field objects
|
Let us add this item to list of all Item_trigger_field objects
|
||||||
in trigger.
|
in trigger.
|
||||||
*/
|
*/
|
||||||
lex->trg_table_fields.link_in_list((byte *)trg_fld,
|
lex->trg_table_fields.link_in_list((byte *)trg_fld,
|
||||||
(byte**)&trg_fld->next_trg_field);
|
(byte**)&trg_fld->next_trg_field);
|
||||||
|
|
||||||
$$= (Item *)trg_fld;
|
$$= (Item *)trg_fld;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -7073,7 +7073,7 @@ ident:
|
|||||||
;
|
;
|
||||||
|
|
||||||
ident_or_text:
|
ident_or_text:
|
||||||
ident { $$=$1;}
|
ident { $$=$1;}
|
||||||
| TEXT_STRING_sys { $$=$1;}
|
| TEXT_STRING_sys { $$=$1;}
|
||||||
| LEX_HOSTNAME { $$=$1;};
|
| LEX_HOSTNAME { $$=$1;};
|
||||||
|
|
||||||
@ -8124,25 +8124,25 @@ grant_option_list:
|
|||||||
|
|
||||||
grant_option:
|
grant_option:
|
||||||
GRANT OPTION { Lex->grant |= GRANT_ACL;}
|
GRANT OPTION { Lex->grant |= GRANT_ACL;}
|
||||||
| MAX_QUERIES_PER_HOUR ULONG_NUM
|
| MAX_QUERIES_PER_HOUR ulong_num
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->mqh.questions=$2;
|
lex->mqh.questions=$2;
|
||||||
lex->mqh.specified_limits|= USER_RESOURCES::QUERIES_PER_HOUR;
|
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 *lex=Lex;
|
||||||
lex->mqh.updates=$2;
|
lex->mqh.updates=$2;
|
||||||
lex->mqh.specified_limits|= USER_RESOURCES::UPDATES_PER_HOUR;
|
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 *lex=Lex;
|
||||||
lex->mqh.conn_per_hour= $2;
|
lex->mqh.conn_per_hour= $2;
|
||||||
lex->mqh.specified_limits|= USER_RESOURCES::CONNECTIONS_PER_HOUR;
|
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 *lex=Lex;
|
||||||
lex->mqh.user_conn= $2;
|
lex->mqh.user_conn= $2;
|
||||||
@ -8413,38 +8413,52 @@ check_option:
|
|||||||
|
|
||||||
xa: XA_SYM begin_or_start xid opt_join_or_resume
|
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
|
| 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
|
| 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
|
| 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
|
| XA_SYM ROLLBACK_SYM xid
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
Lex->sql_command = SQLCOM_XA_ROLLBACK;
|
||||||
lex->sql_command = SQLCOM_XA_ROLLBACK;
|
|
||||||
}
|
}
|
||||||
| XA_SYM RECOVER_SYM
|
| 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 {}
|
begin_or_start: BEGIN_SYM {}
|
||||||
| START_SYM {}
|
| START_SYM {}
|
||||||
|
Reference in New Issue
Block a user