Commit 762cb225 authored by monty@mashka.mysql.fi's avatar monty@mashka.mysql.fi

Changed my_strntoxxx functions to clear error number on start

Allow one to change ANSI_QUOTES mode per thread and on the fly
parent eb22615e
...@@ -840,17 +840,19 @@ int Field_decimal::store(longlong nr) ...@@ -840,17 +840,19 @@ int Field_decimal::store(longlong nr)
double Field_decimal::val_real(void) double Field_decimal::val_real(void)
{ {
int err; int not_used;
return my_strntod(my_charset_bin, ptr, field_length, NULL, &err); return my_strntod(my_charset_bin, ptr, field_length, NULL, &not_used);
} }
longlong Field_decimal::val_int(void) longlong Field_decimal::val_int(void)
{ {
int err; int not_used;
if (unsigned_flag) if (unsigned_flag)
return my_strntoull(my_charset_bin, ptr, field_length, 10, NULL, &err); return my_strntoull(my_charset_bin, ptr, field_length, 10, NULL,
&not_used);
else else
return my_strntoll( my_charset_bin, ptr, field_length, 10, NULL, &err); return my_strntoll( my_charset_bin, ptr, field_length, 10, NULL,
&not_used);
} }
...@@ -952,9 +954,9 @@ void Field_decimal::sql_type(String &res) const ...@@ -952,9 +954,9 @@ void Field_decimal::sql_type(String &res) const
int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs) int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs)
{ {
int err; int not_used; // We can ignore result from str2int
char *end; char *end;
long tmp= my_strntol(cs, from, len, 10, &end, &err); long tmp= my_strntol(cs, from, len, 10, &end, &not_used);
int error= 0; int error= 0;
if (unsigned_flag) if (unsigned_flag)
...@@ -1154,10 +1156,11 @@ void Field_tiny::sql_type(String &res) const ...@@ -1154,10 +1156,11 @@ void Field_tiny::sql_type(String &res) const
int Field_short::store(const char *from,uint len,CHARSET_INFO *cs) int Field_short::store(const char *from,uint len,CHARSET_INFO *cs)
{ {
int err; int not_used; // We can ignore result from str2int
char *end; char *end;
long tmp= my_strntol(cs, from, len, 10, &end, &err); long tmp= my_strntol(cs, from, len, 10, &end, &not_used);
int error= 0; int error= 0;
if (unsigned_flag) if (unsigned_flag)
{ {
if (tmp < 0) if (tmp < 0)
...@@ -1427,9 +1430,9 @@ void Field_short::sql_type(String &res) const ...@@ -1427,9 +1430,9 @@ void Field_short::sql_type(String &res) const
int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs) int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs)
{ {
int err; int not_used; // We can ignore result from str2int
char *end; char *end;
long tmp= my_strntol(cs, from, len, 10, &end, &err); long tmp= my_strntol(cs, from, len, 10, &end, &not_used);
int error= 0; int error= 0;
if (unsigned_flag) if (unsigned_flag)
...@@ -2134,7 +2137,7 @@ void Field_longlong::sql_type(String &res) const ...@@ -2134,7 +2137,7 @@ void Field_longlong::sql_type(String &res) const
int Field_float::store(const char *from,uint len,CHARSET_INFO *cs) int Field_float::store(const char *from,uint len,CHARSET_INFO *cs)
{ {
int err=0; int err;
Field_float::store(my_strntod(cs,(char*) from,len,(char**)NULL,&err)); Field_float::store(my_strntod(cs,(char*) from,len,(char**)NULL,&err));
if (err || current_thd->count_cuted_fields && !test_if_real(from,len,cs)) if (err || current_thd->count_cuted_fields && !test_if_real(from,len,cs))
{ {
...@@ -2407,7 +2410,7 @@ void Field_float::sql_type(String &res) const ...@@ -2407,7 +2410,7 @@ void Field_float::sql_type(String &res) const
int Field_double::store(const char *from,uint len,CHARSET_INFO *cs) int Field_double::store(const char *from,uint len,CHARSET_INFO *cs)
{ {
int err= 0; int err;
double j= my_strntod(cs,(char*) from,len,(char**)0,&err); double j= my_strntod(cs,(char*) from,len,(char**)0,&err);
if (err || current_thd->count_cuted_fields && !test_if_real(from,len,cs)) if (err || current_thd->count_cuted_fields && !test_if_real(from,len,cs))
{ {
...@@ -3193,9 +3196,9 @@ void Field_time::sql_type(String &res) const ...@@ -3193,9 +3196,9 @@ void Field_time::sql_type(String &res) const
int Field_year::store(const char *from, uint len,CHARSET_INFO *cs) int Field_year::store(const char *from, uint len,CHARSET_INFO *cs)
{ {
int err; int not_used; // We can ignore result from str2int
char *end; char *end;
long nr= my_strntol(cs, from, len, 10, &end, &err); long nr= my_strntol(cs, from, len, 10, &end, &not_used);
if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155) if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155)
{ {
...@@ -3932,17 +3935,17 @@ int Field_string::store(longlong nr) ...@@ -3932,17 +3935,17 @@ int Field_string::store(longlong nr)
double Field_string::val_real(void) double Field_string::val_real(void)
{ {
int err; int not_used;
CHARSET_INFO *cs=charset(); CHARSET_INFO *cs=charset();
return my_strntod(cs,ptr,field_length,(char**)0,&err); return my_strntod(cs,ptr,field_length,(char**)0,&not_used);
} }
longlong Field_string::val_int(void) longlong Field_string::val_int(void)
{ {
int err; int not_used;
CHARSET_INFO *cs=charset(); CHARSET_INFO *cs=charset();
return my_strntoll(cs,ptr,field_length,10,NULL,&err); return my_strntoll(cs,ptr,field_length,10,NULL,&not_used);
} }
...@@ -4017,7 +4020,6 @@ int Field_string::pack_cmp(const char *a, const char *b, uint length) ...@@ -4017,7 +4020,6 @@ int Field_string::pack_cmp(const char *a, const char *b, uint length)
{ {
uint a_length= (uint) (uchar) *a++; uint a_length= (uint) (uchar) *a++;
uint b_length= (uint) (uchar) *b++; uint b_length= (uint) (uchar) *b++;
return my_strnncoll(field_charset, return my_strnncoll(field_charset,
(const uchar*)a,a_length, (const uchar*)a,a_length,
(const uchar*)b,b_length); (const uchar*)b,b_length);
...@@ -4031,7 +4033,6 @@ int Field_string::pack_cmp(const char *b, uint length) ...@@ -4031,7 +4033,6 @@ int Field_string::pack_cmp(const char *b, uint length)
while (end > ptr && end[-1] == ' ') while (end > ptr && end[-1] == ' ')
end--; end--;
uint a_length = (uint) (end - ptr); uint a_length = (uint) (end - ptr);
return my_strnncoll(field_charset, return my_strnncoll(field_charset,
(const uchar*)ptr,a_length, (const uchar*)ptr,a_length,
(const uchar*)b, b_length); (const uchar*)b, b_length);
...@@ -4101,19 +4102,19 @@ int Field_varstring::store(longlong nr) ...@@ -4101,19 +4102,19 @@ int Field_varstring::store(longlong nr)
double Field_varstring::val_real(void) double Field_varstring::val_real(void)
{ {
int err; int not_used;
uint length=uint2korr(ptr)+2; uint length=uint2korr(ptr)+2;
CHARSET_INFO *cs=charset(); CHARSET_INFO *cs=charset();
return my_strntod(cs,ptr+2,length,(char**)0,&err); return my_strntod(cs,ptr+2,length,(char**)0, &not_used);
} }
longlong Field_varstring::val_int(void) longlong Field_varstring::val_int(void)
{ {
int err; int not_used;
uint length=uint2korr(ptr)+2; uint length=uint2korr(ptr)+2;
CHARSET_INFO *cs=charset(); CHARSET_INFO *cs=charset();
return my_strntoll(cs,ptr+2,length,10,NULL,&err); return my_strntoll(cs,ptr+2,length,10,NULL, &not_used);
} }
...@@ -4421,26 +4422,26 @@ int Field_blob::store(longlong nr) ...@@ -4421,26 +4422,26 @@ int Field_blob::store(longlong nr)
double Field_blob::val_real(void) double Field_blob::val_real(void)
{ {
int err; int not_used;
char *blob; char *blob;
memcpy_fixed(&blob,ptr+packlength,sizeof(char*)); memcpy_fixed(&blob,ptr+packlength,sizeof(char*));
if (!blob) if (!blob)
return 0.0; return 0.0;
uint32 length=get_length(ptr); uint32 length=get_length(ptr);
CHARSET_INFO *cs=charset(); CHARSET_INFO *cs=charset();
return my_strntod(cs,blob,length,(char**)0,&err); return my_strntod(cs,blob,length,(char**)0, &not_used);
} }
longlong Field_blob::val_int(void) longlong Field_blob::val_int(void)
{ {
int err; int not_used;
char *blob; char *blob;
memcpy_fixed(&blob,ptr+packlength,sizeof(char*)); memcpy_fixed(&blob,ptr+packlength,sizeof(char*));
if (!blob) if (!blob)
return 0; return 0;
uint32 length=get_length(ptr); uint32 length=get_length(ptr);
return my_strntoll(charset(),blob,length,10,NULL,&err); return my_strntoll(charset(),blob,length,10,NULL,&not_used);
} }
...@@ -4610,10 +4611,8 @@ void Field_blob::sort_string(char *to,uint length) ...@@ -4610,10 +4611,8 @@ void Field_blob::sort_string(char *to,uint length)
blob_length=my_strnxfrm(field_charset, blob_length=my_strnxfrm(field_charset,
(unsigned char *)to, length, (unsigned char *)to, length,
(unsigned char *)blob, blob_length); (unsigned char *)blob, blob_length);
if (blob_length >= length) if (blob_length < length)
return; bzero(to+blob_length, length-blob_length);
to+=blob_length;
bzero(to,length-blob_length);
} }
} }
......
...@@ -242,6 +242,7 @@ static void free_cache_entry(TABLE *table) ...@@ -242,6 +242,7 @@ static void free_cache_entry(TABLE *table)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/* Free resources allocated by filesort() and read_record() */
void free_io_cache(TABLE *table) void free_io_cache(TABLE *table)
{ {
......
...@@ -107,7 +107,7 @@ void lex_init(void) ...@@ -107,7 +107,7 @@ void lex_init(void)
state_map[i]=(uchar) STATE_CHAR; state_map[i]=(uchar) STATE_CHAR;
} }
state_map[(uchar)'_']=state_map[(uchar)'$']=(uchar) STATE_IDENT; state_map[(uchar)'_']=state_map[(uchar)'$']=(uchar) STATE_IDENT;
state_map[(uchar)'\'']=state_map[(uchar)'"']=(uchar) STATE_STRING; state_map[(uchar)'\'']=(uchar) STATE_STRING;
state_map[(uchar)'-']=state_map[(uchar)'+']=(uchar) STATE_SIGNED_NUMBER; state_map[(uchar)'-']=state_map[(uchar)'+']=(uchar) STATE_SIGNED_NUMBER;
state_map[(uchar)'.']=(uchar) STATE_REAL_OR_POINT; state_map[(uchar)'.']=(uchar) STATE_REAL_OR_POINT;
state_map[(uchar)'>']=state_map[(uchar)'=']=state_map[(uchar)'!']= (uchar) STATE_CMP_OP; state_map[(uchar)'>']=state_map[(uchar)'=']=state_map[(uchar)'!']= (uchar) STATE_CMP_OP;
...@@ -122,10 +122,7 @@ void lex_init(void) ...@@ -122,10 +122,7 @@ void lex_init(void)
state_map[(uchar)'*']= (uchar) STATE_END_LONG_COMMENT; state_map[(uchar)'*']= (uchar) STATE_END_LONG_COMMENT;
state_map[(uchar)'@']= (uchar) STATE_USER_END; state_map[(uchar)'@']= (uchar) STATE_USER_END;
state_map[(uchar) '`']= (uchar) STATE_USER_VARIABLE_DELIMITER; state_map[(uchar) '`']= (uchar) STATE_USER_VARIABLE_DELIMITER;
if (global_system_variables.sql_mode & MODE_ANSI_QUOTES) state_map[(uchar)'"']= (uchar) STAT_STRING_OR_DELIMITER;
{
state_map[(uchar) '"'] = STATE_USER_VARIABLE_DELIMITER;
}
/* /*
Create a second map to make it faster to find identifiers Create a second map to make it faster to find identifiers
...@@ -652,12 +649,13 @@ int yylex(void *arg, void *yythd) ...@@ -652,12 +649,13 @@ int yylex(void *arg, void *yythd)
return(IDENT); return(IDENT);
case STATE_USER_VARIABLE_DELIMITER: case STATE_USER_VARIABLE_DELIMITER:
{
char delim= c; // Used char
lex->tok_start=lex->ptr; // Skip first ` lex->tok_start=lex->ptr; // Skip first `
#ifdef USE_MB #ifdef USE_MB
if (use_mb(system_charset_info)) if (use_mb(system_charset_info))
{ {
while ((c=yyGet()) && state_map[c] != STATE_USER_VARIABLE_DELIMITER && while ((c=yyGet()) && c != delim && c != (uchar) NAMES_SEP_CHAR)
c != (uchar) NAMES_SEP_CHAR)
{ {
if (my_ismbhead(system_charset_info, c)) if (my_ismbhead(system_charset_info, c))
{ {
...@@ -673,16 +671,15 @@ int yylex(void *arg, void *yythd) ...@@ -673,16 +671,15 @@ int yylex(void *arg, void *yythd)
else else
#endif #endif
{ {
while ((c=yyGet()) && state_map[c] != STATE_USER_VARIABLE_DELIMITER && while ((c=yyGet()) && c != delim && c != (uchar) NAMES_SEP_CHAR) ;
c != (uchar) NAMES_SEP_CHAR) ;
} }
yylval->lex_str=get_token(lex,yyLength()); yylval->lex_str=get_token(lex,yyLength());
if (lex->convert_set) if (lex->convert_set)
lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen); lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen);
if (state_map[c] == STATE_USER_VARIABLE_DELIMITER) if (c == delim)
yySkip(); // Skip end ` yySkip(); // Skip end `
return(IDENT); return(IDENT);
}
case STATE_SIGNED_NUMBER: // Incomplete signed number case STATE_SIGNED_NUMBER: // Incomplete signed number
if (prev_state == STATE_OPERATOR_OR_IDENT) if (prev_state == STATE_OPERATOR_OR_IDENT)
{ {
...@@ -795,6 +792,13 @@ int yylex(void *arg, void *yythd) ...@@ -795,6 +792,13 @@ int yylex(void *arg, void *yythd)
lex->next_state= STATE_START; // Allow signed numbers lex->next_state= STATE_START; // Allow signed numbers
return(tokval); return(tokval);
case STAT_STRING_OR_DELIMITER:
if (((THD *) yythd)->variables.sql_mode & MODE_ANSI_QUOTES)
{
state= STATE_USER_VARIABLE_DELIMITER;
break;
}
/* " used for strings */
case STATE_STRING: // Incomplete text string case STATE_STRING: // Incomplete text string
if (!(yylval->lex_str.str = get_text(lex))) if (!(yylval->lex_str.str = get_text(lex)))
{ {
...@@ -889,6 +893,7 @@ int yylex(void *arg, void *yythd) ...@@ -889,6 +893,7 @@ int yylex(void *arg, void *yythd)
switch (state_map[yyPeek()]) { switch (state_map[yyPeek()]) {
case STATE_STRING: case STATE_STRING:
case STATE_USER_VARIABLE_DELIMITER: case STATE_USER_VARIABLE_DELIMITER:
case STAT_STRING_OR_DELIMITER:
break; break;
case STATE_USER_END: case STATE_USER_END:
lex->next_state=STATE_SYSTEM_VAR; lex->next_state=STATE_SYSTEM_VAR;
......
...@@ -86,7 +86,8 @@ enum lex_states ...@@ -86,7 +86,8 @@ enum lex_states
STATE_REAL_OR_POINT, STATE_BOOL, STATE_EOL, STATE_ESCAPE, STATE_LONG_COMMENT, STATE_REAL_OR_POINT, STATE_BOOL, STATE_EOL, STATE_ESCAPE, STATE_LONG_COMMENT,
STATE_END_LONG_COMMENT, STATE_COLON, STATE_SET_VAR, STATE_USER_END, STATE_END_LONG_COMMENT, STATE_COLON, STATE_SET_VAR, STATE_USER_END,
STATE_HOSTNAME, STATE_SKIP, STATE_USER_VARIABLE_DELIMITER, STATE_SYSTEM_VAR, STATE_HOSTNAME, STATE_SKIP, STATE_USER_VARIABLE_DELIMITER, STATE_SYSTEM_VAR,
STATE_IDENT_OR_KEYWORD, STATE_IDENT_OR_HEX, STATE_IDENT_OR_BIN STATE_IDENT_OR_KEYWORD, STATE_IDENT_OR_HEX, STATE_IDENT_OR_BIN,
STAT_STRING_OR_DELIMITER
}; };
......
...@@ -214,6 +214,7 @@ long my_strntol_8bit(CHARSET_INFO *cs, ...@@ -214,6 +214,7 @@ long my_strntol_8bit(CHARSET_INFO *cs,
const char *save, *e; const char *save, *e;
int overflow; int overflow;
*err= 0; /* Initialize error indicator */
if (base < 0 || base == 1 || base > 36) if (base < 0 || base == 1 || base > 36)
base = 10; base = 10;
...@@ -330,6 +331,7 @@ ulong my_strntoul_8bit(CHARSET_INFO *cs, ...@@ -330,6 +331,7 @@ ulong my_strntoul_8bit(CHARSET_INFO *cs,
const char *save, *e; const char *save, *e;
int overflow; int overflow;
*err= 0; /* Initialize error indicator */
if (base < 0 || base == 1 || base > 36) if (base < 0 || base == 1 || base > 36)
base = 10; base = 10;
...@@ -437,6 +439,7 @@ longlong my_strntoll_8bit(CHARSET_INFO *cs __attribute__((unused)), ...@@ -437,6 +439,7 @@ longlong my_strntoll_8bit(CHARSET_INFO *cs __attribute__((unused)),
const char *save; const char *save;
int overflow; int overflow;
*err= 0; /* Initialize error indicator */
if (base < 0 || base == 1 || base > 36) if (base < 0 || base == 1 || base > 36)
base = 10; base = 10;
...@@ -553,6 +556,7 @@ ulonglong my_strntoull_8bit(CHARSET_INFO *cs, ...@@ -553,6 +556,7 @@ ulonglong my_strntoull_8bit(CHARSET_INFO *cs,
const char *save; const char *save;
int overflow; int overflow;
*err= 0; /* Initialize error indicator */
if (base < 0 || base == 1 || base > 36) if (base < 0 || base == 1 || base > 36)
base = 10; base = 10;
...@@ -655,7 +659,8 @@ ulonglong my_strntoull_8bit(CHARSET_INFO *cs, ...@@ -655,7 +659,8 @@ ulonglong my_strntoull_8bit(CHARSET_INFO *cs,
cs Character set information cs Character set information
str String to convert to double str String to convert to double
length Optional length for string. length Optional length for string.
end pointer to end of converted string end result pointer to end of converted string
err Error number if failed conversion
NOTES: NOTES:
If length is not INT_MAX32 or str[length] != 0 then the given str must If length is not INT_MAX32 or str[length] != 0 then the given str must
...@@ -665,23 +670,28 @@ ulonglong my_strntoull_8bit(CHARSET_INFO *cs, ...@@ -665,23 +670,28 @@ ulonglong my_strntoull_8bit(CHARSET_INFO *cs,
It's implemented this way to save a buffer allocation and a memory copy. It's implemented this way to save a buffer allocation and a memory copy.
RETURN RETURN
value of number in string Value of number in string
*/ */
double my_strntod_8bit(CHARSET_INFO *cs __attribute__((unused)), double my_strntod_8bit(CHARSET_INFO *cs __attribute__((unused)),
char *str, uint length, char *str, uint length,
char **end, int *err __attribute__ ((unused))) char **end, int *err)
{ {
char end_char; char end_char;
double result; double result;
errno= 0; /* Safety */
if (length == INT_MAX32 || str[length] == 0) if (length == INT_MAX32 || str[length] == 0)
return strtod(str, end); result= strtod(str, end);
end_char= str[length]; else
str[length]= 0; {
result= strtod(str, end); end_char= str[length];
str[length]= end_char; /* Restore end char */ str[length]= 0;
result= strtod(str, end);
str[length]= end_char; /* Restore end char */
}
*err= errno;
return result; return result;
} }
......
...@@ -2459,7 +2459,9 @@ long my_strntol_ucs2(CHARSET_INFO *cs, ...@@ -2459,7 +2459,9 @@ long my_strntol_ucs2(CHARSET_INFO *cs,
register const char *e=nptr+l; register const char *e=nptr+l;
const char *save; const char *save;
do { *err= 0;
do
{
if ((cnv=cs->mb_wc(cs,&wc,s,e))>0) if ((cnv=cs->mb_wc(cs,&wc,s,e))>0)
{ {
switch (wc) switch (wc)
...@@ -2570,7 +2572,9 @@ ulong my_strntoul_ucs2(CHARSET_INFO *cs, ...@@ -2570,7 +2572,9 @@ ulong my_strntoul_ucs2(CHARSET_INFO *cs,
register const char *e=nptr+l; register const char *e=nptr+l;
const char *save; const char *save;
do { *err= 0;
do
{
if ((cnv=cs->mb_wc(cs,&wc,s,e))>0) if ((cnv=cs->mb_wc(cs,&wc,s,e))>0)
{ {
switch (wc) switch (wc)
...@@ -2675,7 +2679,9 @@ longlong my_strntoll_ucs2(CHARSET_INFO *cs, ...@@ -2675,7 +2679,9 @@ longlong my_strntoll_ucs2(CHARSET_INFO *cs,
register const char *e=nptr+l; register const char *e=nptr+l;
const char *save; const char *save;
do { *err= 0;
do
{
if ((cnv=cs->mb_wc(cs,&wc,s,e))>0) if ((cnv=cs->mb_wc(cs,&wc,s,e))>0)
{ {
switch (wc) switch (wc)
...@@ -2788,7 +2794,9 @@ ulonglong my_strntoull_ucs2(CHARSET_INFO *cs, ...@@ -2788,7 +2794,9 @@ ulonglong my_strntoull_ucs2(CHARSET_INFO *cs,
register const char *e=nptr+l; register const char *e=nptr+l;
const char *save; const char *save;
do { *err= 0;
do
{
if ((cnv=cs->mb_wc(cs,&wc,s,e))>0) if ((cnv=cs->mb_wc(cs,&wc,s,e))>0)
{ {
switch (wc) switch (wc)
...@@ -2821,7 +2829,8 @@ ulonglong my_strntoull_ucs2(CHARSET_INFO *cs, ...@@ -2821,7 +2829,8 @@ ulonglong my_strntoull_ucs2(CHARSET_INFO *cs,
cutoff = (~(ulonglong) 0) / (unsigned long int) base; cutoff = (~(ulonglong) 0) / (unsigned long int) base;
cutlim = (uint) ((~(ulonglong) 0) % (unsigned long int) base); cutlim = (uint) ((~(ulonglong) 0) % (unsigned long int) base);
do { do
{
if ((cnv=cs->mb_wc(cs,&wc,s,e))>0) if ((cnv=cs->mb_wc(cs,&wc,s,e))>0)
{ {
s+=cnv; s+=cnv;
...@@ -2878,7 +2887,7 @@ ulonglong my_strntoull_ucs2(CHARSET_INFO *cs, ...@@ -2878,7 +2887,7 @@ ulonglong my_strntoull_ucs2(CHARSET_INFO *cs,
double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)), double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)),
char *nptr, uint length, char *nptr, uint length,
char **endptr, int *err __attribute__ ((unused))) char **endptr, int *err)
{ {
char buf[256]; char buf[256];
double res; double res;
...@@ -2887,7 +2896,8 @@ double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)), ...@@ -2887,7 +2896,8 @@ double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)),
register const char *end; register const char *end;
my_wc_t wc; my_wc_t wc;
int cnv; int cnv;
*err= 0;
/* Cut too long strings */ /* Cut too long strings */
if (length >= sizeof(buf)) if (length >= sizeof(buf))
length= sizeof(buf)-1; length= sizeof(buf)-1;
...@@ -2902,7 +2912,9 @@ double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)), ...@@ -2902,7 +2912,9 @@ double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)),
} }
*b= 0; *b= 0;
errno= 0;
res=strtod(buf, endptr); res=strtod(buf, endptr);
*err= errno;
if (endptr) if (endptr)
*endptr=(char*) (*endptr-buf+nptr); *endptr=(char*) (*endptr-buf+nptr);
return res; return res;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment