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)
double Field_decimal::val_real(void)
{
int err;
return my_strntod(my_charset_bin, ptr, field_length, NULL, &err);
int not_used;
return my_strntod(my_charset_bin, ptr, field_length, NULL, &not_used);
}
longlong Field_decimal::val_int(void)
{
int err;
int not_used;
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
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
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;
long tmp= my_strntol(cs, from, len, 10, &end, &err);
long tmp= my_strntol(cs, from, len, 10, &end, &not_used);
int error= 0;
if (unsigned_flag)
......@@ -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 err;
int not_used; // We can ignore result from str2int
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;
if (unsigned_flag)
{
if (tmp < 0)
......@@ -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 err;
int not_used; // We can ignore result from str2int
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;
if (unsigned_flag)
......@@ -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 err=0;
int 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))
{
......@@ -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 err= 0;
int 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))
{
......@@ -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 err;
int not_used; // We can ignore result from str2int
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)
{
......@@ -3932,17 +3935,17 @@ int Field_string::store(longlong nr)
double Field_string::val_real(void)
{
int err;
int not_used;
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)
{
int err;
int not_used;
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)
{
uint a_length= (uint) (uchar) *a++;
uint b_length= (uint) (uchar) *b++;
return my_strnncoll(field_charset,
(const uchar*)a,a_length,
(const uchar*)b,b_length);
......@@ -4031,7 +4033,6 @@ int Field_string::pack_cmp(const char *b, uint length)
while (end > ptr && end[-1] == ' ')
end--;
uint a_length = (uint) (end - ptr);
return my_strnncoll(field_charset,
(const uchar*)ptr,a_length,
(const uchar*)b, b_length);
......@@ -4101,19 +4102,19 @@ int Field_varstring::store(longlong nr)
double Field_varstring::val_real(void)
{
int err;
int not_used;
uint length=uint2korr(ptr)+2;
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)
{
int err;
int not_used;
uint length=uint2korr(ptr)+2;
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)
double Field_blob::val_real(void)
{
int err;
int not_used;
char *blob;
memcpy_fixed(&blob,ptr+packlength,sizeof(char*));
if (!blob)
return 0.0;
uint32 length=get_length(ptr);
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)
{
int err;
int not_used;
char *blob;
memcpy_fixed(&blob,ptr+packlength,sizeof(char*));
if (!blob)
return 0;
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)
blob_length=my_strnxfrm(field_charset,
(unsigned char *)to, length,
(unsigned char *)blob, blob_length);
if (blob_length >= length)
return;
to+=blob_length;
bzero(to,length-blob_length);
if (blob_length < length)
bzero(to+blob_length, length-blob_length);
}
}
......
......@@ -242,6 +242,7 @@ static void free_cache_entry(TABLE *table)
DBUG_VOID_RETURN;
}
/* Free resources allocated by filesort() and read_record() */
void free_io_cache(TABLE *table)
{
......
......@@ -107,7 +107,7 @@ void lex_init(void)
state_map[i]=(uchar) STATE_CHAR;
}
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)'.']=(uchar) STATE_REAL_OR_POINT;
state_map[(uchar)'>']=state_map[(uchar)'=']=state_map[(uchar)'!']= (uchar) STATE_CMP_OP;
......@@ -122,10 +122,7 @@ void lex_init(void)
state_map[(uchar)'*']= (uchar) STATE_END_LONG_COMMENT;
state_map[(uchar)'@']= (uchar) STATE_USER_END;
state_map[(uchar) '`']= (uchar) STATE_USER_VARIABLE_DELIMITER;
if (global_system_variables.sql_mode & MODE_ANSI_QUOTES)
{
state_map[(uchar) '"'] = STATE_USER_VARIABLE_DELIMITER;
}
state_map[(uchar)'"']= (uchar) STAT_STRING_OR_DELIMITER;
/*
Create a second map to make it faster to find identifiers
......@@ -652,12 +649,13 @@ int yylex(void *arg, void *yythd)
return(IDENT);
case STATE_USER_VARIABLE_DELIMITER:
{
char delim= c; // Used char
lex->tok_start=lex->ptr; // Skip first `
#ifdef USE_MB
if (use_mb(system_charset_info))
{
while ((c=yyGet()) && state_map[c] != STATE_USER_VARIABLE_DELIMITER &&
c != (uchar) NAMES_SEP_CHAR)
while ((c=yyGet()) && c != delim && c != (uchar) NAMES_SEP_CHAR)
{
if (my_ismbhead(system_charset_info, c))
{
......@@ -673,16 +671,15 @@ int yylex(void *arg, void *yythd)
else
#endif
{
while ((c=yyGet()) && state_map[c] != STATE_USER_VARIABLE_DELIMITER &&
c != (uchar) NAMES_SEP_CHAR) ;
while ((c=yyGet()) && c != delim && c != (uchar) NAMES_SEP_CHAR) ;
}
yylval->lex_str=get_token(lex,yyLength());
if (lex->convert_set)
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 `
return(IDENT);
}
case STATE_SIGNED_NUMBER: // Incomplete signed number
if (prev_state == STATE_OPERATOR_OR_IDENT)
{
......@@ -795,6 +792,13 @@ int yylex(void *arg, void *yythd)
lex->next_state= STATE_START; // Allow signed numbers
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
if (!(yylval->lex_str.str = get_text(lex)))
{
......@@ -889,6 +893,7 @@ int yylex(void *arg, void *yythd)
switch (state_map[yyPeek()]) {
case STATE_STRING:
case STATE_USER_VARIABLE_DELIMITER:
case STAT_STRING_OR_DELIMITER:
break;
case STATE_USER_END:
lex->next_state=STATE_SYSTEM_VAR;
......
......@@ -86,7 +86,8 @@ enum lex_states
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_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,
const char *save, *e;
int overflow;
*err= 0; /* Initialize error indicator */
if (base < 0 || base == 1 || base > 36)
base = 10;
......@@ -330,6 +331,7 @@ ulong my_strntoul_8bit(CHARSET_INFO *cs,
const char *save, *e;
int overflow;
*err= 0; /* Initialize error indicator */
if (base < 0 || base == 1 || base > 36)
base = 10;
......@@ -437,6 +439,7 @@ longlong my_strntoll_8bit(CHARSET_INFO *cs __attribute__((unused)),
const char *save;
int overflow;
*err= 0; /* Initialize error indicator */
if (base < 0 || base == 1 || base > 36)
base = 10;
......@@ -553,6 +556,7 @@ ulonglong my_strntoull_8bit(CHARSET_INFO *cs,
const char *save;
int overflow;
*err= 0; /* Initialize error indicator */
if (base < 0 || base == 1 || base > 36)
base = 10;
......@@ -655,7 +659,8 @@ ulonglong my_strntoull_8bit(CHARSET_INFO *cs,
cs Character set information
str String to convert to double
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:
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,
It's implemented this way to save a buffer allocation and a memory copy.
RETURN
value of number in string
Value of number in string
*/
double my_strntod_8bit(CHARSET_INFO *cs __attribute__((unused)),
char *str, uint length,
char **end, int *err __attribute__ ((unused)))
char **end, int *err)
{
char end_char;
double result;
errno= 0; /* Safety */
if (length == INT_MAX32 || str[length] == 0)
return strtod(str, end);
end_char= str[length];
str[length]= 0;
result= strtod(str, end);
str[length]= end_char; /* Restore end char */
result= strtod(str, end);
else
{
end_char= str[length];
str[length]= 0;
result= strtod(str, end);
str[length]= end_char; /* Restore end char */
}
*err= errno;
return result;
}
......
......@@ -2459,7 +2459,9 @@ long my_strntol_ucs2(CHARSET_INFO *cs,
register const char *e=nptr+l;
const char *save;
do {
*err= 0;
do
{
if ((cnv=cs->mb_wc(cs,&wc,s,e))>0)
{
switch (wc)
......@@ -2570,7 +2572,9 @@ ulong my_strntoul_ucs2(CHARSET_INFO *cs,
register const char *e=nptr+l;
const char *save;
do {
*err= 0;
do
{
if ((cnv=cs->mb_wc(cs,&wc,s,e))>0)
{
switch (wc)
......@@ -2675,7 +2679,9 @@ longlong my_strntoll_ucs2(CHARSET_INFO *cs,
register const char *e=nptr+l;
const char *save;
do {
*err= 0;
do
{
if ((cnv=cs->mb_wc(cs,&wc,s,e))>0)
{
switch (wc)
......@@ -2788,7 +2794,9 @@ ulonglong my_strntoull_ucs2(CHARSET_INFO *cs,
register const char *e=nptr+l;
const char *save;
do {
*err= 0;
do
{
if ((cnv=cs->mb_wc(cs,&wc,s,e))>0)
{
switch (wc)
......@@ -2821,7 +2829,8 @@ ulonglong my_strntoull_ucs2(CHARSET_INFO *cs,
cutoff = (~(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)
{
s+=cnv;
......@@ -2878,7 +2887,7 @@ ulonglong my_strntoull_ucs2(CHARSET_INFO *cs,
double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)),
char *nptr, uint length,
char **endptr, int *err __attribute__ ((unused)))
char **endptr, int *err)
{
char buf[256];
double res;
......@@ -2887,7 +2896,8 @@ double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)),
register const char *end;
my_wc_t wc;
int cnv;
*err= 0;
/* Cut too long strings */
if (length >= sizeof(buf))
length= sizeof(buf)-1;
......@@ -2902,7 +2912,9 @@ double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)),
}
*b= 0;
errno= 0;
res=strtod(buf, endptr);
*err= errno;
if (endptr)
*endptr=(char*) (*endptr-buf+nptr);
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