diff options
author | unknown <serg@serg.mylan> | 2005-04-04 00:50:05 +0200 |
---|---|---|
committer | unknown <serg@serg.mylan> | 2005-04-04 00:50:05 +0200 |
commit | 2fc4270b4c52b5144c30af9202152677b04fe3a3 (patch) | |
tree | 3fdc4c1722aa761278c731cc61aa182bf7a1463d | |
parent | 5b0c75259c0b62a0a8efc4964fb70816e1d1954e (diff) | |
download | mariadb-git-2fc4270b4c52b5144c30af9202152677b04fe3a3.tar.gz |
XID SQL syntax
minor cleanups
XA tests
include/m_ctype.h:
minor cleanup
sql/field.cc:
minor cleanup
sql/handler.cc:
XID SQL syntax
sql/handler.h:
XID SQL syntax
sql/item_sum.h:
minor cleanup
sql/lock.cc:
comments
sql/sql_class.cc:
minor cleanup
sql/sql_lex.h:
XID SQL syntax
sql/sql_parse.cc:
XID SQL syntax
sql/sql_yacc.yy:
XID SQL syntax
cleanups
-rw-r--r-- | include/m_ctype.h | 2 | ||||
-rw-r--r-- | mysql-test/r/xa.result | 45 | ||||
-rw-r--r-- | mysql-test/t/xa.test | 57 | ||||
-rw-r--r-- | sql/field.cc | 4 | ||||
-rw-r--r-- | sql/handler.cc | 9 | ||||
-rw-r--r-- | sql/handler.h | 23 | ||||
-rw-r--r-- | sql/item_sum.h | 2 | ||||
-rw-r--r-- | sql/lock.cc | 17 | ||||
-rw-r--r-- | sql/sql_class.cc | 10 | ||||
-rw-r--r-- | sql/sql_lex.h | 9 | ||||
-rw-r--r-- | sql/sql_parse.cc | 18 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 150 |
12 files changed, 239 insertions, 107 deletions
diff --git a/include/m_ctype.h b/include/m_ctype.h index c41c7385b3d..f5a1503234c 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -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); diff --git a/mysql-test/r/xa.result b/mysql-test/r/xa.result new file mode 100644 index 00000000000..1dde495d6ae --- /dev/null +++ b/mysql-test/r/xa.result @@ -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; diff --git a/mysql-test/t/xa.test b/mysql-test/t/xa.test new file mode 100644 index 00000000000..1f2fb5056ed --- /dev/null +++ b/mysql-test/t/xa.test @@ -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; + diff --git a/sql/field.cc b/sql/field.cc index f3666f862af..bc5868fbea3 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -3230,13 +3230,13 @@ int Field_long::store(const char *from,uint len,CHARSET_INFO *cs) long store_tmp; int error; char *end; - + tmp_scan= cs->cset->scan(cs, from, from+len, MY_SEQ_SPACES); len-= tmp_scan; 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) { diff --git a/sql/handler.cc b/sql/handler.cc index 143e56fdc7c..fd9ec7cf423 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -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,9 +2364,8 @@ 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) { handler *file= get_new_handler(0,(enum db_type) types->db_type); diff --git a/sql/handler.h b/sql/handler.h index e5b63c7f25c..3751af29194 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -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); diff --git a/sql/item_sum.h b/sql/item_sum.h index d03ef94b9cd..8c8360b0726 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -734,7 +734,7 @@ public: 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; } diff --git a/sql/lock.cc b/sql/lock.cc index 266e8dc4d4d..a8ccba32d4f 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -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: @@ -773,7 +780,7 @@ static void print_lock_error(int error, const char *table) table instance of thd2 thd1: COMMIT; # blocked by thd3. thd1 blocks thd2 which blocks thd3 which blocks thd1: deadlock. - + Note that we need to support that one thread does FLUSH TABLES WITH READ LOCK; and then COMMIT; (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; 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 @@ -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) and if old_message is set */ - if (unlikely(need_exit_cond)) - thd->exit_cond(old_message); + if (unlikely(need_exit_cond)) + 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); } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index cf7240e4dba..04de761aece 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -342,7 +342,9 @@ void THD::change_user(void) void THD::cleanup(void) { 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) { lock=locked_tables; locked_tables=0; @@ -384,17 +386,17 @@ THD::~THD() add_to_status(&global_status_var, &status_var); /* Close connection */ -#ifndef EMBEDDED_LIBRARY +#ifndef EMBEDDED_LIBRARY if (net.vio) { vio_delete(net.vio); - net_end(&net); + net_end(&net); } #endif if (!cleanup_done) cleanup(); - ha_close_connection(this); + ha_close_connection(this); sp_cache_clear(&sp_proc_cache); sp_cache_clear(&sp_func_cache); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 2391c0b7ef9..34ed1e83c86 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -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; @@ -738,7 +739,7 @@ typedef struct st_lex enum enum_tx_isolation tx_isolation; enum enum_ha_read_modes ha_read_mode; union { - enum ha_rkey_function ha_rkey_mode; + enum ha_rkey_function ha_rkey_mode; enum xa_option_words xa_opt; }; enum enum_var_type option_type; @@ -764,15 +765,15 @@ typedef struct st_lex ALTER_INFO alter_info; /* Prepared statements SQL syntax:*/ LEX_STRING prepared_stmt_name; /* Statement name (in all queries) */ - /* + /* Prepared statement query text or name of variable that holds the 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 */ bool prepared_stmt_code_is_varref; /* 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 implicitly used by the statement. diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 21282e9e620..a734af4b0e6 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4323,7 +4323,7 @@ unsent_create_error: 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 @@ unsent_create_error: 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 @@ unsent_create_error: } 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 @@ unsent_create_error: 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 @@ unsent_create_error: 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 @@ unsent_create_error: 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 @@ unsent_create_error: 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); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 4924f78dc0a..3c2577acf96 100644 --- a/sql/sql_yacc.yy +++ b/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 WARN_DEPRECATED(A,B) \ +#define WARN_DEPRECATED(A,B) \ 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)); -#define TEST_ASSERT(A) \ - if (!(A)) \ +#define TEST_ASSERT(A) \ + if (!(A)) \ { \ yyerror(ER(ER_SYNTAX_ERROR)); \ YYABORT; \ @@ -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); @@ -4989,7 +4988,7 @@ table_ref: join_table_list: derived_table_list { TEST_ASSERT($$=$1); } ; - + /* Warning - may return NULL in case of incomplete SELECT */ derived_table_list: table_ref { $$=$1; } @@ -5033,7 +5032,7 @@ join_table: $$=$6; } | table_ref RIGHT opt_outer JOIN_SYM table_ref ON expr - { + { LEX *lex= Lex; TEST_ASSERT($1 && $5); if (!($$= lex->current_select->convert_right_join())) @@ -5047,7 +5046,7 @@ join_table: sel->save_names_for_using_list($1, $5); } USING '(' using_list ')' - { + { LEX *lex= Lex; if (!($$= lex->current_select->convert_right_join())) YYABORT; @@ -5063,7 +5062,7 @@ join_table: } | table_ref NATURAL JOIN_SYM table_factor { TEST_ASSERT($1 && ($$=$4)); add_join_natural($1,$4); }; - + normal_join: JOIN_SYM {} @@ -5109,9 +5108,9 @@ table_factor: sel->master_unit()->fake_select_lex; } if ($2->init_nested_join(lex->thd)) - YYABORT; + YYABORT; $$= 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. */ } | '(' 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 alter value of Lex->current_select. */ - if (!($3 || $6) && $2->embedding && + if (!($3 || $6) && $2->embedding && !$2->embedding->nested_join->join_list.elements) { /* we have a derived table ($3 == NULL) but no alias, @@ -5144,7 +5143,7 @@ table_factor: (List<String> *)0))) YYABORT; - sel->add_joined_table($$); + sel->add_joined_table($$); } else if ($4 || $6) @@ -5171,7 +5170,7 @@ select_derived: LEX *lex= Lex; /* for normal joins, $3 != NULL and end_nested_join() != NULL, for derived tables, both must equal NULL */ - + if (!($$= $1->end_nested_join(lex->thd)) && $3) YYABORT; if (!$3 && $$) @@ -5215,7 +5214,7 @@ select_derived_init: SELECT_SYM { LEX *lex= Lex; - SELECT_LEX *sel= lex->current_select; + SELECT_LEX *sel= lex->current_select; TABLE_LIST *embedding; if (!sel->embedding || sel->end_nested_join(lex->thd)) { @@ -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,11 +5524,12 @@ delete_limit_clause: sel->explicit_limit= 1; }; -ULONG_NUM: - NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } +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); } + | DECIMAL_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 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; @@ -6688,7 +6688,7 @@ fields_or_vars: | field_or_var { Lex->field_list.push_back($1); } ; - + field_or_var: simple_ident_nospvar {$$= $1;} | '@' ident_or_text @@ -6836,9 +6836,9 @@ NUM_literal: } } ; - + /********************************************************************** -** Createing different items. +** Creating different items. **********************************************************************/ insert_ident: @@ -6854,8 +6854,8 @@ table_wild: | ident '.' ident '.' '*' { $$ = new Item_field((YYTHD->client_capabilities & - CLIENT_NO_SCHEMA ? NullS : $1.str), - $3.str,"*"); + CLIENT_NO_SCHEMA ? NullS : $1.str), + $3.str,"*"); Lex->current_select->with_wild++; } ; @@ -6898,53 +6898,53 @@ simple_ident_nospvar: (Item*) new Item_ref(NullS,NullS,$1.str); } | simple_ident_q { $$= $1; } - ; + ; simple_ident_q: ident '.' ident { THD *thd= YYTHD; LEX *lex= thd->lex; - + /* FIXME This will work ok in simple_ident_nospvar case because we can't meet simple_ident_nospvar in trigger now. But it should be changed in future. */ 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"))) { Item_trigger_field *trg_fld; bool new_row= ($1.str[0]=='N' || $1.str[0]=='n'); - + if (lex->trg_chistics.event == TRG_EVENT_INSERT && !new_row) { my_error(ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0), "OLD", "on INSERT"); YYABORT; } - + if (lex->trg_chistics.event == TRG_EVENT_DELETE && new_row) { my_error(ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0), "NEW", "on DELETE"); YYABORT; } - + if (!(trg_fld= new Item_trigger_field(new_row ? Item_trigger_field::NEW_ROW: Item_trigger_field::OLD_ROW, $3.str))) YYABORT; - + /* Let us add this item to list of all Item_trigger_field objects in trigger. */ lex->trg_table_fields.link_in_list((byte *)trg_fld, (byte**)&trg_fld->next_trg_field); - + $$= (Item *)trg_fld; } else @@ -7073,7 +7073,7 @@ ident: ; ident_or_text: - ident { $$=$1;} + ident { $$=$1;} | TEXT_STRING_sys { $$=$1;} | LEX_HOSTNAME { $$=$1;}; @@ -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,38 +8413,52 @@ 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 {} | START_SYM {} |