diff --git a/.bzrignore b/.bzrignore index 978926c8c37..88995ac7c65 100644 --- a/.bzrignore +++ b/.bzrignore @@ -562,3 +562,8 @@ bkpull.log.2 bkpull.log.3 build.log sql/safe_to_cache_query.txt +bkpull.log.4 +bkpull.log.5 +bkpull.log.6 +bkpush.log +sql/sql_yacc.output diff --git a/include/m_ctype.h b/include/m_ctype.h index b16db5cde97..4af23bb3ab5 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -125,11 +125,11 @@ typedef struct charset_info_st /* Charset dependant snprintf() */ int (*snprintf)(struct charset_info_st *, char *to, uint n, const char *fmt, ...); - long (*strtol)(struct charset_info_st *, const char *s, char **e, int base); - ulong (*strtoul)(struct charset_info_st *, const char *s, char **e, int base); - longlong (*strtoll)(struct charset_info_st *, const char *s, char **e, int base); - ulonglong (*strtoull)(struct charset_info_st *, const char *s, char **e, int base); - double (*strtod)(struct charset_info_st *, const char *s, char **e); + long (*strntol)(struct charset_info_st *, const char *s, uint l,char **e, int base); + ulong (*strntoul)(struct charset_info_st *, const char *s, uint l, char **e, int base); + longlong (*strntoll)(struct charset_info_st *, const char *s, uint l, char **e, int base); + ulonglong (*strntoull)(struct charset_info_st *, const char *s, uint l, char **e, int base); + double (*strntod)(struct charset_info_st *, const char *s, uint l, char **e); } CHARSET_INFO; @@ -169,11 +169,11 @@ int my_wc_mb_8bit(CHARSET_INFO *cs,my_wc_t wc, uchar *s, uchar *e); int my_snprintf_8bit(struct charset_info_st *, char *to, uint n, const char *fmt, ...); -long my_strtol_8bit(CHARSET_INFO *, const char *s, char **e, int base); -ulong my_strtoul_8bit(CHARSET_INFO *, const char *s, char **e, int base); -longlong my_strtoll_8bit(CHARSET_INFO *, const char *s, char **e, int base); -ulonglong my_strtoull_8bit(CHARSET_INFO *, const char *s, char **e, int base); -double my_strtod_8bit(CHARSET_INFO *, const char *s, char **e); +long my_strntol_8bit(CHARSET_INFO *, const char *s, uint l,char **e, int base); +ulong my_strntoul_8bit(CHARSET_INFO *, const char *s, uint l,char **e, int base); +longlong my_strntoll_8bit(CHARSET_INFO *, const char *s, uint l,char **e, int base); +ulonglong my_strntoull_8bit(CHARSET_INFO *, const char *s, uint l,char **e, int base); +double my_strntod_8bit(CHARSET_INFO *, const char *s, uint l,char **e); my_bool my_like_range_simple(CHARSET_INFO *cs, const char *ptr, uint ptr_length, @@ -257,11 +257,11 @@ int my_wildcmp_mb(CHARSET_INFO *, #define my_strcasecmp(s, a, b) ((s)->strcasecmp((s), (a), (b))) #define my_strncasecmp(s, a, b, l) ((s)->strncasecmp((s), (a), (b), (l))) -#define my_strtol(s, a, b, c) ((s)->strtol((s),(a),(b),(c))) -#define my_strtoul(s, a, b, c) ((s)->strtoul((s),(a),(b),(c))) -#define my_strtoll(s, a, b, c) ((s)->strtoll((s),(a),(b),(c))) -#define my_strtoull(s, a, b, c) ((s)->strtoull((s),(a),(b),(c))) -#define my_strtod(s, a, b) ((s)->strtod((s),(a),(b))) +#define my_strntol(s, a, b, c, d) ((s)->strntol((s),(a),(b),(c),(d))) +#define my_strntoul(s, a, b, c, d) ((s)->strntoul((s),(a),(b),(c),(d))) +#define my_strntoll(s, a, b, c, d) ((s)->strntoll((s),(a),(b),(c),(d))) +#define my_strntoull(s, a, b, c,d) ((s)->strntoull((s),(a),(b),(c),(d))) +#define my_strntod(s, a, b, c ) ((s)->strntod((s),(a),(b),(c))) /* XXX: still need to take care of this one */ diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index f91cacd2f6d..990c313686a 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -425,6 +425,33 @@ a b 0 10 1 11 drop table t1, t2; +drop table if exists t11, t12, t2; +create table t11 (a int NOT NULL, b int, primary key (a)); +create table t12 (a int NOT NULL, b int, primary key (a)); +create table t2 (a int NOT NULL, b int, primary key (a)); +insert into t11 values (0, 10),(1, 11),(2, 12); +insert into t12 values (33, 10),(22, 11),(2, 12); +insert into t2 values (1, 21),(2, 12),(3, 23); +select * from t11; +a b +0 10 +1 11 +2 12 +select * from t12; +a b +33 10 +22 11 +2 12 +delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2 where t11.a = t2.a); +select * from t11; +a b +0 10 +1 11 +select * from t12; +a b +33 10 +22 11 +drop table t11, t12, t2; CREATE TABLE t1 (x int); create table t2 (a int); insert into t2 values (1); diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 3888584900d..c9ab505bffb 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -254,6 +254,21 @@ delete from t1 where b = (select b from t2 where t1.a = t2.a); select * from t1; drop table t1, t2; +#multi-delete with subselects +drop table if exists t11, t12, t2; +create table t11 (a int NOT NULL, b int, primary key (a)); +create table t12 (a int NOT NULL, b int, primary key (a)); +create table t2 (a int NOT NULL, b int, primary key (a)); +insert into t11 values (0, 10),(1, 11),(2, 12); +insert into t12 values (33, 10),(22, 11),(2, 12); +insert into t2 values (1, 21),(2, 12),(3, 23); +select * from t11; +select * from t12; +delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2 where t11.a = t2.a); +select * from t11; +select * from t12; +drop table t11, t12, t2; + #insert with subselects CREATE TABLE t1 (x int); create table t2 (a int); diff --git a/mysys/charset.c b/mysys/charset.c index 91bae04046b..cf0628495fc 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -391,10 +391,11 @@ static CHARSET_INFO *add_charset(CHARSET_INFO *cs, myf flags) cs->hash_caseup = my_hash_caseup_simple; cs->hash_sort = my_hash_sort_simple; cs->snprintf = my_snprintf_8bit; - cs->strtol = my_strtol_8bit; - cs->strtoul = my_strtoul_8bit; - cs->strtoll = my_strtoll_8bit; - cs->strtoull = my_strtoull_8bit; + cs->strntol = my_strntol_8bit; + cs->strntoul = my_strntoul_8bit; + cs->strntoll = my_strntoll_8bit; + cs->strntoull = my_strntoull_8bit; + cs->strntod = my_strntod_8bit; cs->mbmaxlen = 1; set_max_sort_char(cs); diff --git a/readline/terminal.c b/readline/terminal.c index 9ca4d6e43c5..397b10a1d46 100644 --- a/readline/terminal.c +++ b/readline/terminal.c @@ -84,8 +84,8 @@ static int tcap_initialized; # if defined (__EMX__) || defined (NEED_EXTERN_PC) extern # endif /* __EMX__ || NEED_EXTERN_PC */ -const char PC; -const char *BC, *UP; +char PC; +char *BC, *UP; #endif /* __linux__ */ /* Some strings to control terminal actions. These are output by tputs (). */ diff --git a/sql/field.cc b/sql/field.cc index f2324a0a331..e0910caeea2 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -921,8 +921,7 @@ void Field_decimal::sql_type(String &res) const int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs) { - String tmp_str(from,len,default_charset_info); - long tmp= strtol(tmp_str.c_ptr(),NULL,10); + long tmp= my_strntol(cs,from,len,(char **)NULL,10); int error= 0; if (unsigned_flag) @@ -1116,8 +1115,7 @@ void Field_tiny::sql_type(String &res) const int Field_short::store(const char *from,uint len,CHARSET_INFO *cs) { - String tmp_str(from,len,default_charset_info); - long tmp= strtol(tmp_str.c_ptr(),NULL,10); + long tmp= my_strntol(cs,from,len,NULL,10); int error= 0; if (unsigned_flag) { @@ -1380,8 +1378,7 @@ void Field_short::sql_type(String &res) const int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs) { - String tmp_str(from,len,default_charset_info); - long tmp= strtol(tmp_str.c_ptr(),NULL,10); + long tmp= my_strntol(cs,from,len,NULL,10); int error= 0; if (unsigned_flag) @@ -3097,8 +3094,7 @@ void Field_time::sql_type(String &res) const int Field_year::store(const char *from, uint len,CHARSET_INFO *cs) { - String tmp_str(from,len,default_charset_info); - long nr= strtol(tmp_str.c_ptr(),NULL,10); + long nr= my_strntol(cs,from,len,NULL,10); if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155) { diff --git a/sql/gstream.cc b/sql/gstream.cc index bd2345212c3..5a58fef6744 100644 --- a/sql/gstream.cc +++ b/sql/gstream.cc @@ -99,7 +99,7 @@ int GTextReadStream::get_next_number(double *d) char *endptr; - *d = my_strtod(my_charset_latin1, cur, &endptr); + *d = strtod(cur, &endptr); if(endptr) { diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 5b97b2f7750..07958ebcfab 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -43,7 +43,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, if ((open_and_lock_tables(thd, table_list))) DBUG_RETURN(-1); - fix_tables_pointers(&thd->lex.select_lex); + fix_tables_pointers(thd->lex.all_selects_list); table= table_list->table; table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); thd->proc_info="init"; diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 6dc001a1932..afdd1ccfdb2 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -50,21 +50,6 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t) if (res) DBUG_RETURN(-1); - for (SELECT_LEX *ssl= sl; ssl; ssl= ssl->next_select_in_list()) - { - TABLE_LIST *t_tables= (TABLE_LIST *)ssl->table_list.first; - for (TABLE_LIST *cursor= (TABLE_LIST *)t_tables; - cursor; - cursor=cursor->next) - { - if (cursor->derived) - { - res= mysql_derived(thd, lex, (SELECT_LEX_UNIT *)cursor->derived, - cursor); - if (res) DBUG_RETURN(res); - } - } - } Item *item; List_iterator it(sl->item_list); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 295c1e339c5..1ca44046997 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -157,7 +157,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List &fields, res= open_and_lock_tables(thd, table_list); if (res) DBUG_RETURN(-1); - fix_tables_pointers(&thd->lex.select_lex); + fix_tables_pointers(thd->lex.all_selects_list); table= table_list->table; thd->proc_info="init"; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 08855ba1a7c..b9691bb1059 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -389,6 +389,8 @@ typedef struct st_lex SELECT_LEX select_lex; /* first SELECT_LEX */ /* current SELECT_LEX in parsing */ SELECT_LEX_NODE *current_select; + /* list of all SELECT_LEX */ + SELECT_LEX *all_selects_list; uchar *ptr,*tok_start,*tok_end,*end_of_query; char *length,*dec,*change,*name; char *backup_dir; /* For RESTORE/BACKUP */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 182ab69308f..a410a9f2d7e 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -51,7 +51,7 @@ #define TRANS_MEM_ROOT_BLOCK_SIZE 4096 #define TRANS_MEM_ROOT_PREALLOC 4096 -extern int yyparse(void); +extern int yyparse(void *thd); extern "C" pthread_mutex_t THR_LOCK_keycache; #ifdef SOLARIS extern "C" int gethostname(char *name, int namelen); @@ -1321,7 +1321,7 @@ mysql_execute_command(THD *thd) that is not a SHOW command or a select that only access local variables, but for now this is probably good enough. */ - if (tables || lex->select_lex.next_select_in_list()) + if (tables || &lex->select_lex != lex->all_selects_list) mysql_reset_errors(thd); /* Save old warning count to be able to send to client how many warnings we @@ -1358,22 +1358,23 @@ mysql_execute_command(THD *thd) */ if (lex->derived_tables) { - for (SELECT_LEX *sl= &lex->select_lex; sl; sl= sl->next_select_in_list()) - if (sl->linkage != DERIVED_TABLE_TYPE) - for (TABLE_LIST *cursor= sl->get_table_list(); - cursor; - cursor= cursor->next) - if (cursor->derived && (res=mysql_derived(thd, lex, - (SELECT_LEX_UNIT *) - cursor->derived, - cursor))) - { - if (res < 0 || thd->net.report_error) - send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); - DBUG_VOID_RETURN; - } - } - if ((lex->select_lex.next_select_in_list() && + for (SELECT_LEX *sl= lex->all_selects_list; + sl; + sl= sl->next_select_in_list()) + for (TABLE_LIST *cursor= sl->get_table_list(); + cursor; + cursor= cursor->next) + if (cursor->derived && (res=mysql_derived(thd, lex, + (SELECT_LEX_UNIT *) + cursor->derived, + cursor))) + { + if (res < 0 || thd->net.report_error) + send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); + DBUG_VOID_RETURN; + } + } + if ((&lex->select_lex != lex->all_selects_list && lex->unit.create_total_list(thd, lex, &tables)) || (table_rules_on && tables && thd->slave_thread && !tables_ok(thd,tables))) @@ -1420,7 +1421,7 @@ mysql_execute_command(THD *thd) } else thd->send_explain_fields(result); - fix_tables_pointers(select_lex); + fix_tables_pointers(lex->all_selects_list); res= mysql_explain_union(thd, &thd->lex.unit, result); MYSQL_LOCK *save_lock= thd->lock; thd->lock= (MYSQL_LOCK *)0; @@ -2100,10 +2101,12 @@ mysql_execute_command(THD *thd) /* Fix tables-to-be-deleted-from list to point at opened tables */ for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next) auxi->table= auxi->table_list->table; + fix_tables_pointers(lex->all_selects_list); if (!thd->fatal_error && (result= new multi_delete(thd,aux_tables, table_count))) { - res= mysql_select(thd,tables,select_lex->item_list, + res= mysql_select(thd,select_lex->get_table_list(), + select_lex->item_list, select_lex->where, (ORDER *)NULL,(ORDER *)NULL,(Item *)NULL, (ORDER *)NULL, @@ -2846,9 +2849,11 @@ mysql_init_query(THD *thd) lex->value_list.empty(); lex->param_list.empty(); lex->unit.global_parameters= lex->unit.slave= lex->current_select= - &lex->select_lex; + lex->all_selects_list= &lex->select_lex; lex->select_lex.master= &lex->unit; lex->select_lex.prev= &lex->unit.slave; + lex->select_lex.link_next= 0; + lex->select_lex.link_prev= (st_select_lex_node**)&(lex->all_selects_list); lex->olap=lex->describe=0; lex->derived_tables= false; thd->check_loops_counter= thd->select_number= @@ -2901,8 +2906,7 @@ mysql_new_select(LEX *lex, bool move_down) select_lex->master_unit()->global_parameters= select_lex; DBUG_ASSERT(lex->current_select->linkage != GLOBAL_OPTIONS_TYPE); - select_lex->include_global(lex->current_select->select_lex()-> - next_select_in_list_addr()); + select_lex->include_global((st_select_lex_node**)&lex->all_selects_list); lex->current_select= select_lex; return 0; } @@ -2956,7 +2960,7 @@ mysql_parse(THD *thd, char *inBuf, uint length) if (query_cache_send_result_to_client(thd, inBuf, length) <= 0) { LEX *lex=lex_start(thd, (uchar*) inBuf, length); - if (!yyparse() && ! thd->fatal_error) + if (!yyparse((void *)thd) && ! thd->fatal_error) { if (mqh_used && thd->user_connect && check_mqh(thd, lex->sql_command)) diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index b631a30fed9..f86add6c389 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -71,7 +71,7 @@ Long data handling: #define IS_PARAM_NULL(pos, param_no) pos[param_no/8] & (1 << param_no & 7) -extern int yyparse(void); +extern int yyparse(void *thd); /* Find prepared statement in thd @@ -618,7 +618,7 @@ static bool parse_prepare_query(PREP_STMT *stmt, LEX *lex=lex_start(thd, (uchar*) packet, length); lex->safe_to_cache_query= 0; - if (!yyparse() && !thd->fatal_error) + if (!yyparse((void *)thd) && !thd->fatal_error) error= send_prepare_results(stmt); lex_end(lex); DBUG_RETURN(error); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 8f406efc030..bb7f23a6710 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -158,7 +158,7 @@ int handle_select(THD *thd, LEX *lex, select_result *result) { int res; register SELECT_LEX *select_lex = &lex->select_lex; - fix_tables_pointers(select_lex); + fix_tables_pointers(lex->all_selects_list); if (select_lex->next_select()) res=mysql_union(thd,lex,result); else @@ -7514,7 +7514,7 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) { res= mysql_explain_select(thd, sl, (((&thd->lex.select_lex)==sl)? - ((sl->next_select_in_list())?"PRIMARY": + ((thd->lex.all_selects_list != sl)?"PRIMARY": "SIMPLE"): ((sl == first)? ((sl->linkage == DERIVED_TABLE_TYPE) ? diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 409b00b5703..c2ba65248a7 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -70,7 +70,7 @@ int mysql_update(THD *thd, if ((open_and_lock_tables(thd, table_list))) DBUG_RETURN(-1); - fix_tables_pointers(&thd->lex.select_lex); + fix_tables_pointers(thd->lex.all_selects_list); table= table_list->table; save_time_stamp=table->time_stamp; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index cbe72313b93..77d7b48d57f 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -17,10 +17,16 @@ /* sql_yacc.yy */ %{ +/* Pass thd as an arg to yyparse(). The type will be void*, so it +** must be cast to (THD*) when used. Use the YYTHD macro for this. +*/ +#define YYPARSE_PARAM yythd +#define YYTHD ((THD *)yythd) + #define MYSQL_YACC #define YYINITDEPTH 100 #define YYMAXDEPTH 3200 /* Because of 64K stack */ -#define Lex current_lex +#define Lex (&(YYTHD->lex)) #define Select Lex->current_select #include "mysql_priv.h" #include "slave.h" @@ -35,9 +41,9 @@ int yylex(void *yylval); #define yyoverflow(A,B,C,D,E,F) if (my_yyoverflow((B),(D),(int*) (F))) { yyerror((char*) (A)); return 2; } -inline Item *or_or_concat(Item* A, Item* B) +inline Item *or_or_concat(THD *thd, Item* A, Item* B) { - return (current_thd->sql_mode & MODE_PIPES_AS_CONCAT ? + return (thd->sql_mode & MODE_PIPES_AS_CONCAT ? (Item*) new Item_func_concat(A,B) : (Item*) new Item_cond_or(A,B)); } @@ -669,11 +675,11 @@ END_OF_INPUT query: END_OF_INPUT { - THD *thd=current_thd; + THD *thd= YYTHD; if (!thd->bootstrap && (!(thd->lex.select_lex.options & OPTION_FOUND_COMMENT))) { - send_error(current_thd,ER_EMPTY_QUERY); + send_error(thd,ER_EMPTY_QUERY); YYABORT; } else @@ -799,7 +805,7 @@ master_def: create: CREATE opt_table_options TABLE_SYM opt_if_not_exists table_ident { - THD *thd=current_thd; + THD *thd= YYTHD; LEX *lex=Lex; lex->sql_command= SQLCOM_CREATE_TABLE; if (!lex->select_lex.add_table_to_list($5, @@ -1083,7 +1089,7 @@ type: | TIME_SYM { $$=FIELD_TYPE_TIME; } | TIMESTAMP { - if (current_thd->sql_mode & MODE_SAPDB) + if (YYTHD->sql_mode & MODE_SAPDB) $$=FIELD_TYPE_DATETIME; else $$=FIELD_TYPE_TIMESTAMP; @@ -1154,7 +1160,7 @@ int_type: | BIGINT { $$=FIELD_TYPE_LONGLONG; }; real_type: - REAL { $$= current_thd->sql_mode & MODE_REAL_AS_FLOAT ? + REAL { $$= YYTHD->sql_mode & MODE_REAL_AS_FLOAT ? FIELD_TYPE_FLOAT : FIELD_TYPE_DOUBLE; } | DOUBLE_SYM { $$=FIELD_TYPE_DOUBLE; } | DOUBLE_SYM PRECISION { $$=FIELD_TYPE_DOUBLE; }; @@ -1219,7 +1225,7 @@ charset_name: { if (!($$=get_charset_by_name("binary",MYF(0)))) { - net_printf(current_thd,ER_UNKNOWN_CHARACTER_SET,"binary"); + net_printf(YYTHD,ER_UNKNOWN_CHARACTER_SET,"binary"); YYABORT; } } @@ -1227,7 +1233,7 @@ charset_name: { if (!($$=get_charset_by_name($1.str,MYF(0)))) { - net_printf(current_thd,ER_UNKNOWN_CHARACTER_SET,$1.str); + net_printf(YYTHD,ER_UNKNOWN_CHARACTER_SET,$1.str); YYABORT; } }; @@ -1254,8 +1260,9 @@ opt_binary: opt_primary: /* empty */ - | PRIMARY_SYM; - + | PRIMARY_SYM + ; + references: REFERENCES table_ident { @@ -1355,7 +1362,7 @@ string_list: alter: ALTER opt_ignore TABLE_SYM table_ident { - THD *thd=current_thd; + THD *thd= YYTHD; LEX *lex=&thd->lex; lex->sql_command = SQLCOM_ALTER_TABLE; lex->name=0; @@ -1802,7 +1809,7 @@ expr_expr: { $$= new Item_func_between($1,$3,$5); } | expr NOT BETWEEN_SYM no_and_expr AND expr { $$= new Item_func_not(new Item_func_between($1,$4,$6)); } - | expr OR_OR_CONCAT expr { $$= or_or_concat($1,$3); } + | expr OR_OR_CONCAT expr { $$= or_or_concat(YYTHD, $1,$3); } | expr OR expr { $$= new Item_cond_or($1,$3); } | expr XOR expr { $$= new Item_cond_xor($1,$3); } | expr AND expr { $$= new Item_cond_and($1,$3); } @@ -1848,7 +1855,7 @@ no_in_expr: { $$= new Item_func_between($1,$3,$5); } | no_in_expr NOT BETWEEN_SYM no_and_expr AND expr { $$= new Item_func_not(new Item_func_between($1,$4,$6)); } - | no_in_expr OR_OR_CONCAT expr { $$= or_or_concat($1,$3); } + | no_in_expr OR_OR_CONCAT expr { $$= or_or_concat(YYTHD, $1,$3); } | no_in_expr OR expr { $$= new Item_cond_or($1,$3); } | no_in_expr XOR expr { $$= new Item_cond_xor($1,$3); } | no_in_expr AND expr { $$= new Item_cond_and($1,$3); } @@ -1903,7 +1910,7 @@ no_and_expr: { $$= new Item_func_between($1,$3,$5); } | no_and_expr NOT BETWEEN_SYM no_and_expr AND expr { $$= new Item_func_not(new Item_func_between($1,$4,$6)); } - | no_and_expr OR_OR_CONCAT expr { $$= or_or_concat($1,$3); } + | no_and_expr OR_OR_CONCAT expr { $$= or_or_concat(YYTHD, $1,$3); } | no_and_expr OR expr { $$= new Item_cond_or($1,$3); } | no_and_expr XOR expr { $$= new Item_cond_xor($1,$3); } | no_and_expr LIKE simple_expr opt_escape { $$= new Item_func_like($1,$3,$4); } @@ -3059,7 +3066,7 @@ update_list: }; opt_low_priority: - /* empty */ { $$= current_thd->update_lock_default; } + /* empty */ { $$= YYTHD->update_lock_default; } | LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; }; /* Delete rows from a table */ @@ -3243,7 +3250,7 @@ show_param: { Lex->sql_command= SQLCOM_SHOW_PROCESSLIST;} | opt_var_type VARIABLES wild { - THD *thd= current_thd; + THD *thd= YYTHD; thd->lex.sql_command= SQLCOM_SHOW_VARIABLES; thd->lex.option_type= (enum_var_type) $1; } @@ -3454,7 +3461,7 @@ opt_local: | LOCAL_SYM { $$=1;}; load_data_lock: - /* empty */ { $$= current_thd->update_lock_default; } + /* empty */ { $$= YYTHD->update_lock_default; } | CONCURRENT { $$= TL_WRITE_CONCURRENT_INSERT ; } | LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; }; @@ -3503,13 +3510,13 @@ opt_ignore_lines: /* Common definitions */ text_literal: - TEXT_STRING { $$ = new Item_string($1.str,$1.length,current_thd->thd_charset); } + TEXT_STRING { $$ = new Item_string($1.str,$1.length,YYTHD->thd_charset); } | UNDERSCORE_CHARSET TEXT_STRING { $$ = new Item_string($2.str,$2.length,Lex->charset); } | text_literal TEXT_STRING { ((Item_string*) $1)->append($2.str,$2.length); }; text_string: - TEXT_STRING { $$= new String($1.str,$1.length,current_thd->thd_charset); } + TEXT_STRING { $$= new String($1.str,$1.length,YYTHD->thd_charset); } | HEX_NUM { Item *tmp = new Item_varbinary($1.str,$1.length); @@ -3519,7 +3526,7 @@ param_marker: '?' { LEX *lex=Lex; - if (current_thd->prepare_command) + if (YYTHD->prepare_command) { lex->param_list.push_back($$=new Item_param()); lex->param_count++; @@ -3555,7 +3562,7 @@ insert_ident: table_wild: ident '.' '*' { $$ = new Item_field(NullS,$1.str,"*"); } | ident '.' ident '.' '*' - { $$ = new Item_field((current_thd->client_capabilities & + { $$ = new Item_field((YYTHD->client_capabilities & CLIENT_NO_SCHEMA ? NullS : $1.str),$3.str,"*"); }; order_ident: @@ -3580,7 +3587,7 @@ simple_ident: | ident '.' ident '.' ident { SELECT_LEX_NODE *sel=Select; - $$ = !sel->create_refs || sel->get_in_sum_expr() > 0 ? (Item*) new Item_field((current_thd->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str) : (Item*) new Item_ref((current_thd->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str); + $$ = !sel->create_refs || sel->get_in_sum_expr() > 0 ? (Item*) new Item_field((YYTHD->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str) : (Item*) new Item_ref((YYTHD->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str); }; @@ -3864,7 +3871,7 @@ option_value: } | PASSWORD equal text_or_password { - THD *thd=current_thd; + THD *thd=YYTHD; LEX_USER *user; if (!(user=(LEX_USER*) sql_alloc(sizeof(LEX_USER)))) YYABORT; @@ -3946,7 +3953,7 @@ table_lock: lock_option: READ_SYM { $$=TL_READ_NO_INSERT; } - | WRITE_SYM { $$=current_thd->update_lock_default; } + | WRITE_SYM { $$=YYTHD->update_lock_default; } | LOW_PRIORITY WRITE_SYM { $$=TL_WRITE_LOW_PRIORITY; } | READ_SYM LOCAL_SYM { $$= TL_READ; } ; @@ -4383,7 +4390,7 @@ singleval_subselect: singleval_subselect_init: select_init { - $$= new Item_singleval_subselect(current_thd, + $$= new Item_singleval_subselect(YYTHD, Lex->current_select->master_unit()-> first_select()); }; @@ -4398,7 +4405,7 @@ exists_subselect: exists_subselect_init: select_init { - $$= new Item_exists_subselect(current_thd, + $$= new Item_exists_subselect(YYTHD, Lex->current_select->master_unit()-> first_select()); }; diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c index 39ddee854ff..b41ed82aeae 100644 --- a/strings/ctype-big5.c +++ b/strings/ctype-big5.c @@ -6249,11 +6249,11 @@ CHARSET_INFO my_charset_big5 = my_hash_sort_simple, 0, my_snprintf_8bit, - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }; diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c index 2573ec89660..7431ce82df5 100644 --- a/strings/ctype-bin.c +++ b/strings/ctype-bin.c @@ -22,6 +22,26 @@ #include "m_string.h" #include "m_ctype.h" +static uchar ctype_bin[] = { + 0, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 72, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 132,132,132,132,132,132,132,132,132,132, 16, 16, 16, 16, 16, 16, + 16,129,129,129,129,129,129, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 16, 16, 16, + 16,130,130,130,130,130,130, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 16, 16, 16, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 72, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 16, 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 16, 2, 2, 2, 2, 2, 2, 2, 2 +}; + static int my_strnncoll_binary(CHARSET_INFO * cs __attribute__((unused)), const uchar *s, uint slen, @@ -242,7 +262,7 @@ static CHARSET_INFO my_charset_bin_st = MY_CS_COMPILED|MY_CS_BINSORT,/* state */ "binary", /* name */ "", /* comment */ - NULL, /* ctype */ + ctype_bin, /* ctype */ NULL, /* to_lower */ NULL, /* to_upper */ NULL, /* sort_order */ @@ -270,11 +290,11 @@ static CHARSET_INFO my_charset_bin_st = my_hash_sort_bin, /* hash_sort */ 255, /* max_sort_char */ my_snprintf_8bit, /* snprintf */ - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }; diff --git a/strings/ctype-czech.c b/strings/ctype-czech.c index ea3cc702abd..837545ce70f 100644 --- a/strings/ctype-czech.c +++ b/strings/ctype-czech.c @@ -627,11 +627,11 @@ CHARSET_INFO my_charset_czech = my_hash_sort_simple, 0, my_snprintf_8bit, - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }; #endif diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c index 8a614851fe3..57d237364f6 100644 --- a/strings/ctype-euc_kr.c +++ b/strings/ctype-euc_kr.c @@ -8667,11 +8667,11 @@ CHARSET_INFO my_charset_euc_kr = my_hash_sort_simple, 0, my_snprintf_8bit, - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }; #endif diff --git a/strings/ctype-gb2312.c b/strings/ctype-gb2312.c index 7a8e9f011a0..205b7c2a1da 100644 --- a/strings/ctype-gb2312.c +++ b/strings/ctype-gb2312.c @@ -5717,11 +5717,11 @@ CHARSET_INFO my_charset_gb2312 = my_hash_sort_simple, 0, my_snprintf_8bit, - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }; #endif diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c index 504039a4e59..aec38e8dfa8 100644 --- a/strings/ctype-gbk.c +++ b/strings/ctype-gbk.c @@ -9904,11 +9904,11 @@ CHARSET_INFO my_charset_gbk = my_hash_sort_simple, 0, my_snprintf_8bit, - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }; diff --git a/strings/ctype-latin1_de.c b/strings/ctype-latin1_de.c index 13a35e3c82e..696fa0f6192 100644 --- a/strings/ctype-latin1_de.c +++ b/strings/ctype-latin1_de.c @@ -445,11 +445,11 @@ CHARSET_INFO my_charset_latin1_de = my_hash_sort_simple, 0, my_snprintf_8bit, - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }; #endif diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index f9a9caad206..be4fdc9cb8d 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -15,12 +15,13 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include "my_sys.h" -#include "m_ctype.h" #include "m_string.h" +#include "m_ctype.h" +#include "my_sys.h" /* defines errno */ #include "stdarg.h" #include "assert.h" + int my_strnxfrm_simple(CHARSET_INFO * cs, uchar *dest, uint len, const uchar *src, uint srclen) @@ -244,34 +245,468 @@ void my_hash_sort_simple(CHARSET_INFO *cs, } } -long my_strtol_8bit(CHARSET_INFO *cs __attribute__((unused)), - const char *s, char **e, int base) + +#define MY_ERRNO(y) + +long my_strntol_8bit(CHARSET_INFO *cs, + const char *nptr, uint l, char **endptr, int base) { - return strtol(s,e,base); + int negative; + register ulong cutoff; + register unsigned int cutlim; + register ulong i; + register const char *s; + register unsigned char c; + const char *save, *e; + int overflow; + + if (base < 0 || base == 1 || base > 36) + base = 10; + + s = nptr; + e = nptr+l; + + for ( ; s='0' && c<='9') + c -= '0'; + else if (c>='A' && c<='F') + c = c - 'A' + 10; + else if (c>='a' && c<='f') + c = c - 'a' + 10; + else + break; + if (c >= base) + break; + if (i > cutoff || (i == cutoff && c > cutlim)) + overflow = 1; + else + { + i *= (ulong) base; + i += c; + } + } + + if (s == save) + goto noconv; + + if (endptr != NULL) + *endptr = (char *) s; + + if (negative) + { + if (i > (ulong) LONG_MIN) + overflow = 1; + } + else if (i > (ulong) LONG_MAX) + overflow = 1; + + if (overflow) + { + MY_ERRNO(ERANGE); + return negative ? LONG_MIN : LONG_MAX; + } + + return (negative ? -((long) i) : (long) i); + +noconv: + MY_ERRNO(EDOM); + if (endptr != NULL) + *endptr = (char *) nptr; + return 0L; } -ulong my_strtoul_8bit(CHARSET_INFO *cs __attribute__((unused)), - const char *s, char **e, int base) + +ulong my_strntoul_8bit(CHARSET_INFO *cs, + const char *nptr, uint l, char **endptr, int base) { - return strtoul(s,e,base); + int negative; + register ulong cutoff; + register unsigned int cutlim; + register ulong i; + register const char *s; + register unsigned char c; + const char *save, *e; + int overflow; + + if (base < 0 || base == 1 || base > 36) + base = 10; + + s = nptr; + e = nptr+l; + + for( ; s='0' && c<='9') + c -= '0'; + else if (c>='A' && c<='F') + c = c - 'A' + 10; + else if (c>='a' && c<='a') + c = c - 'a' + 10; + else + break; + if (c >= base) + break; + if (i > cutoff || (i == cutoff && c > cutlim)) + overflow = 1; + else + { + i *= (ulong) base; + i += c; + } + } + + if (s == save) + goto noconv; + + if (endptr != NULL) + *endptr = (char *) s; + + if (overflow) + { + MY_ERRNO(ERANGE); + return ((ulong)~0L); + } + + return (negative ? -((long) i) : (long) i); + +noconv: + MY_ERRNO(EDOM); + if (endptr != NULL) + *endptr = (char *) nptr; + return 0L; } -longlong my_strtoll_8bit(CHARSET_INFO *cs __attribute__((unused)), - const char *s, char **e, int base) + +longlong my_strntoll_8bit(CHARSET_INFO *cs __attribute__((unused)), + const char *nptr, uint l, char **endptr, int base) { - return strtoll(s,e,base); + int negative; + register ulonglong cutoff; + register unsigned int cutlim; + register ulonglong i; + register const char *s, *e; + register unsigned char c; + const char *save; + int overflow; + + if (base < 0 || base == 1 || base > 36) + base = 10; + + s = nptr; + e = nptr+l; + + for(; s='0' && c<='9') + c -= '0'; + else if (c>='A' && c<='F') + c = c - 'A' + 10; + else if (c>='a' && c<='f') + c = c - 'a' + 10; + else + break; + if (c >= base) + break; + if (i > cutoff || (i == cutoff && c > cutlim)) + overflow = 1; + else + { + i *= (ulonglong) base; + i += c; + } + } + + if (s == save) + goto noconv; + + if (endptr != NULL) + *endptr = (char *) s; + + if (negative) + { + if (i > (ulonglong) LONGLONG_MIN) + overflow = 1; + } + else if (i > (ulonglong) LONGLONG_MAX) + overflow = 1; + + if (overflow) + { + MY_ERRNO(ERANGE); + return negative ? LONGLONG_MIN : LONGLONG_MAX; + } + + return (negative ? -((longlong) i) : (longlong) i); + +noconv: + MY_ERRNO(EDOM); + if (endptr != NULL) + *endptr = (char *) nptr; + return 0L; } -ulonglong my_strtoull_8bit(CHARSET_INFO *cs __attribute__((unused)), - const char *s, char **e, int base) + +ulonglong my_strntoull_8bit(CHARSET_INFO *cs, + const char *nptr, uint l, char **endptr, int base) { - return strtoul(s,e,base); + int negative; + register ulonglong cutoff; + register unsigned int cutlim; + register ulonglong i; + register const char *s, *e; + register unsigned char c; + const char *save; + int overflow; + + if (base < 0 || base == 1 || base > 36) + base = 10; + + s = nptr; + e = nptr+l; + + for(; s='0' && c<='9') + c -= '0'; + else if (c>='A' && c<='F') + c = c - 'A' + 10; + else if (c>='a' && c<='f') + c = c - 'a' + 10; + else + break; + if (c >= base) + break; + if (i > cutoff || (i == cutoff && c > cutlim)) + overflow = 1; + else + { + i *= (ulonglong) base; + i += c; + } + } + + if (s == save) + goto noconv; + + if (endptr != NULL) + *endptr = (char *) s; + + if (overflow) + { + MY_ERRNO(ERANGE); + return (~(ulonglong) 0); + } + + return (negative ? -((longlong) i) : (longlong) i); + +noconv: + MY_ERRNO(EDOM); + if (endptr != NULL) + *endptr = (char *) nptr; + return 0L; } -double my_strtod_8bit(CHARSET_INFO *cs __attribute__((unused)), - const char *s, char **e) +double my_strntod_8bit(CHARSET_INFO *cs __attribute__((unused)), + const char *s, uint l, char **e) { - return strtod(s,e); + char buf[256]; + double res; + if((l+1)>sizeof(buf)) + { + if (e) + memcpy(*e,s,sizeof(s)); + return 0; + } + strncpy(buf,s,l); + buf[l]='\0'; + res=strtod(buf,e); + if (e) + memcpy(*e,*e-buf+s,sizeof(s)); + return res; } diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c index 91a9fae55fa..1ccf0b1d8f2 100644 --- a/strings/ctype-sjis.c +++ b/strings/ctype-sjis.c @@ -4491,11 +4491,11 @@ CHARSET_INFO my_charset_sjis = my_hash_sort_simple, 0, my_snprintf_8bit, - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }; #endif diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c index 86056e4f55c..3852589659b 100644 --- a/strings/ctype-tis620.c +++ b/strings/ctype-tis620.c @@ -719,11 +719,11 @@ CHARSET_INFO my_charset_tis620 = my_hash_sort_simple, 0, my_snprintf_8bit, - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }; diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c index 7ae229c0135..0f4d8f5dfe2 100644 --- a/strings/ctype-ujis.c +++ b/strings/ctype-ujis.c @@ -8461,11 +8461,11 @@ CHARSET_INFO my_charset_ujis = my_hash_sort_simple, 0, my_snprintf_8bit, - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }; diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index b471a37a852..8adeed7144a 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -19,7 +19,10 @@ /* Written by Alexander Barkov */ #include -#include +#include "m_string.h" +#include "m_ctype.h" +#include "my_sys.h" /* defines errno */ + #ifdef HAVE_CHARSET_utf8 #define HAVE_UNIDATA @@ -1986,11 +1989,11 @@ CHARSET_INFO my_charset_utf8 = my_hash_sort_utf8, /* hash_sort */ 0, my_snprintf_8bit, - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }; @@ -2438,35 +2441,459 @@ static int my_snprintf_ucs2(CHARSET_INFO *cs __attribute__((unused)) return my_vsnprintf_ucs2(to, n, fmt, args); } +#define MY_ERRNO(x) -static long my_strtol_ucs2(CHARSET_INFO *cs __attribute__((unused)), - const char *s, char **e, int base) +long my_strntol_ucs2(CHARSET_INFO *cs, + const char *nptr, uint l, char **endptr, int base) { - return strtol(s,e,base); + int negative; + register ulong cutoff; + register unsigned int cutlim; + register ulong i; + register const char *s; + register unsigned char c; + const char *save, *e; + int overflow; + + if (base < 0 || base == 1 || base > 36) + base = 10; + + s = nptr; + e = nptr+l; + + for ( ; s= base) + break; + if (i > cutoff || (i == cutoff && c > cutlim)) + overflow = 1; + else + { + i *= (ulong) base; + i += c; + } + } + + if (s == save) + goto noconv; + + if (endptr != NULL) + *endptr = (char *) s; + + if (negative) + { + if (i > (ulong) LONG_MIN) + overflow = 1; + } + else if (i > (ulong) LONG_MAX) + overflow = 1; + + if (overflow) + { + MY_ERRNO(ERANGE); + return negative ? LONG_MIN : LONG_MAX; + } + + return (negative ? -((long) i) : (long) i); + +noconv: + MY_ERRNO(EDOM); + if (endptr != NULL) + *endptr = (char *) nptr; + return 0L; } -static ulong my_strtoul_ucs2(CHARSET_INFO *cs __attribute__((unused)), - const char *s, char **e, int base) + +ulong my_strntoul_ucs2(CHARSET_INFO *cs, + const char *nptr, uint l, char **endptr, int base) { - return strtoul(s,e,base); + int negative; + register ulong cutoff; + register unsigned int cutlim; + register ulong i; + register const char *s; + register unsigned char c; + const char *save, *e; + int overflow; + + if (base < 0 || base == 1 || base > 36) + base = 10; + + s = nptr; + e = nptr+l; + + for( ; s= base) + break; + if (i > cutoff || (i == cutoff && c > cutlim)) + overflow = 1; + else + { + i *= (ulong) base; + i += c; + } + } + + if (s == save) + goto noconv; + + if (endptr != NULL) + *endptr = (char *) s; + + if (overflow) + { + MY_ERRNO(ERANGE); + return ((ulong)~0L); + } + + return (negative ? -((long) i) : (long) i); + +noconv: + MY_ERRNO(EDOM); + if (endptr != NULL) + *endptr = (char *) nptr; + return 0L; } -static longlong my_strtoll_ucs2(CHARSET_INFO *cs __attribute__((unused)), - const char *s, char **e, int base) + +longlong my_strntoll_ucs2(CHARSET_INFO *cs __attribute__((unused)), + const char *nptr, uint l, char **endptr, int base) { - return strtoll(s,e,base); + int negative; + register ulonglong cutoff; + register unsigned int cutlim; + register ulonglong i; + register const char *s, *e; + register unsigned char c; + const char *save; + int overflow; + + if (base < 0 || base == 1 || base > 36) + base = 10; + + s = nptr; + e = nptr+l; + + for(; s= base) + break; + if (i > cutoff || (i == cutoff && c > cutlim)) + overflow = 1; + else + { + i *= (ulonglong) base; + i += c; + } + } + + if (s == save) + goto noconv; + + if (endptr != NULL) + *endptr = (char *) s; + + if (negative) + { + if (i > (ulonglong) LONGLONG_MIN) + overflow = 1; + } + else if (i > (ulonglong) LONGLONG_MAX) + overflow = 1; + + if (overflow) + { + MY_ERRNO(ERANGE); + return negative ? LONGLONG_MIN : LONGLONG_MAX; + } + + return (negative ? -((longlong) i) : (longlong) i); + +noconv: + MY_ERRNO(EDOM); + if (endptr != NULL) + *endptr = (char *) nptr; + return 0L; } -static ulonglong my_strtoull_ucs2(CHARSET_INFO *cs __attribute__((unused)), - const char *s, char **e, int base) + +ulonglong my_strntoull_ucs2(CHARSET_INFO *cs, + const char *nptr, uint l, char **endptr, int base) { - return strtoul(s,e,base); + int negative; + register ulonglong cutoff; + register unsigned int cutlim; + register ulonglong i; + register const char *s, *e; + register unsigned char c; + const char *save; + int overflow; + + if (base < 0 || base == 1 || base > 36) + base = 10; + + s = nptr; + e = nptr+l; + + for(; s= base) + break; + if (i > cutoff || (i == cutoff && c > cutlim)) + overflow = 1; + else + { + i *= (ulonglong) base; + i += c; + } + } + + if (s == save) + goto noconv; + + if (endptr != NULL) + *endptr = (char *) s; + + if (overflow) + { + MY_ERRNO(ERANGE); + return (~(ulonglong) 0); + } + + return (negative ? -((longlong) i) : (longlong) i); + +noconv: + MY_ERRNO(EDOM); + if (endptr != NULL) + *endptr = (char *) nptr; + return 0L; } -double my_strtod_ucs2(CHARSET_INFO *cs __attribute__((unused)), - const char *s, char **e) +double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)), + const char *s, uint l, char **e) { - return strtod(s,e); + char buf[256]; + double res; + if((l+1)>sizeof(buf)) + { + if (e) + memcpy(*e,s,sizeof(s)); + return 0; + } + strncpy(buf,s,l); + buf[l]='\0'; + res=strtod(buf,e); + if (e) + memcpy(*e,*e-buf+s,sizeof(s)); + return res; } @@ -2504,11 +2931,11 @@ CHARSET_INFO my_charset_ucs2 = my_hash_sort_ucs2, /* hash_sort */ 0, my_snprintf_ucs2, - my_strtol_ucs2, - my_strtoul_ucs2, - my_strtoll_ucs2, - my_strtoull_ucs2, - my_strtod_ucs2 + my_strntol_ucs2, + my_strntoul_ucs2, + my_strntoll_ucs2, + my_strntoull_ucs2, + my_strntod_ucs2 }; diff --git a/strings/ctype-win1250ch.c b/strings/ctype-win1250ch.c index 73e4a5745af..ae7ab6067f8 100644 --- a/strings/ctype-win1250ch.c +++ b/strings/ctype-win1250ch.c @@ -653,11 +653,11 @@ CHARSET_INFO my_charset_win1250ch = my_hash_sort_simple, 0, my_snprintf_8bit, - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }; diff --git a/strings/ctype.c b/strings/ctype.c index 7ce259bc00f..43a9be3ab4b 100644 --- a/strings/ctype.c +++ b/strings/ctype.c @@ -2841,11 +2841,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit, - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }, #endif @@ -2884,11 +2884,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }, #endif @@ -2926,11 +2926,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }, #endif @@ -2968,11 +2968,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }, #endif @@ -3011,11 +3011,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }, #endif @@ -3053,11 +3053,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }, #endif @@ -3095,11 +3095,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }, #endif @@ -3137,11 +3137,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }, #endif @@ -3180,11 +3180,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }, #endif @@ -3222,11 +3222,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }, #endif @@ -3264,11 +3264,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }, #endif @@ -3306,11 +3306,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }, #endif @@ -3348,11 +3348,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }, #endif @@ -3390,11 +3390,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }, #endif @@ -3432,11 +3432,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }, #endif @@ -3475,11 +3475,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }, #endif @@ -3517,11 +3517,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }, #endif @@ -3560,11 +3560,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }, #endif @@ -3603,11 +3603,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }, #endif @@ -3645,11 +3645,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }, #endif @@ -3687,11 +3687,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }, #endif @@ -3729,11 +3729,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }, #endif @@ -3771,11 +3771,11 @@ static CHARSET_INFO compiled_charsets[] = { my_hash_sort_simple, 0, my_snprintf_8bit - my_strtol_8bit, - my_strtoul_8bit, - my_strtoll_8bit, - my_strtoull_8bit, - my_strtod_8bit + my_strntol_8bit, + my_strntoul_8bit, + my_strntoll_8bit, + my_strntoull_8bit, + my_strntod_8bit }, #endif