Commit 3ca302db authored by serg@serg.mylan's avatar serg@serg.mylan

bug #715: SELECT YEAR+0 FROM foobar is parsed as 'SELECT' 'YEAR' '+0' => syntax error

parent 859a4cc1
drop table if exists t1;
select 0,256,00000000000000065536,2147483647,-2147483648,2147483648,+4294967296;
0 256 00000000000000065536 2147483647 -2147483648 2147483648 +4294967296
0 256 00000000000000065536 2147483647 -2147483648 2147483648 4294967296
0 256 65536 2147483647 -2147483648 2147483648 4294967296
select 9223372036854775807,-009223372036854775808;
9223372036854775807 -009223372036854775808
9223372036854775807 -9223372036854775808
select +9999999999999999999,-9999999999999999999;
+9999999999999999999 -9999999999999999999
9999999999999999999 -9999999999999999999
9999999999999999999 -10000000000000000000
select cast(9223372036854775808 as unsigned)+1;
cast(9223372036854775808 as unsigned)+1
......@@ -14,6 +14,9 @@ cast(9223372036854775808 as unsigned)+1
select 9223372036854775808+1;
9223372036854775808+1
9223372036854775809
select -(0-3),round(-(0-3)), round(9999999999999999999);
-(0-3) round(-(0-3)) round(9999999999999999999)
3 3 10000000000000000000
create table t1 (a bigint unsigned not null, primary key(a));
insert into t1 values (18446744073709551615), (0xFFFFFFFFFFFFFFFE);
select * from t1;
......
......@@ -436,8 +436,8 @@ a
99999999999
drop table t1;
CREATE TABLE t1 (a_dec DECIMAL(-1,0));
ERROR 42000: Too big column length for column 'a_dec' (max = 255). Use BLOB instead
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 '-1,0))' at line 1
CREATE TABLE t1 (a_dec DECIMAL(-2,1));
ERROR 42000: Too big column length for column 'a_dec' (max = 255). Use BLOB instead
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 '-2,1))' at line 1
CREATE TABLE t1 (a_dec DECIMAL(-1,1));
ERROR 42000: Too big column length for column 'a_dec' (max = 255). Use BLOB instead
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 '-1,1))' at line 1
......@@ -13,6 +13,8 @@ select 9223372036854775807,-009223372036854775808;
select +9999999999999999999,-9999999999999999999;
select cast(9223372036854775808 as unsigned)+1;
select 9223372036854775808+1;
select -(0-3),round(-(0-3)), round(9999999999999999999);
#
# In 3.23 we have to disable the test of column to bigint as
# this fails on AIX powerpc (the resolution for double is not good enough)
......
......@@ -237,9 +237,9 @@ drop table t1;
# Test of wrong decimal type
#
--error 1074
--error 1064
CREATE TABLE t1 (a_dec DECIMAL(-1,0));
--error 1074
--error 1064
CREATE TABLE t1 (a_dec DECIMAL(-2,1));
--error 1074
--error 1064
CREATE TABLE t1 (a_dec DECIMAL(-1,1));
......@@ -63,7 +63,7 @@ static void init_state_maps(CHARSET_INFO *cs)
uint i;
uchar *state_map= cs->state_map;
uchar *ident_map= cs->ident_map;
/* Fill state_map with states to get a faster parser */
for (i=0; i < 256 ; i++)
{
......@@ -76,13 +76,12 @@ static void init_state_maps(CHARSET_INFO *cs)
state_map[i]=(uchar) MY_LEX_IDENT;
#endif
else if (!my_isgraph(cs,i))
state_map[i]=(uchar) MY_LEX_SKIP;
state_map[i]=(uchar) MY_LEX_SKIP;
else
state_map[i]=(uchar) MY_LEX_CHAR;
}
state_map[(uchar)'_']=state_map[(uchar)'$']=(uchar) MY_LEX_IDENT;
state_map[(uchar)'\'']=(uchar) MY_LEX_STRING;
state_map[(uchar)'-']=state_map[(uchar)'+']=(uchar) MY_LEX_SIGNED_NUMBER;
state_map[(uchar)'.']=(uchar) MY_LEX_REAL_OR_POINT;
state_map[(uchar)'>']=state_map[(uchar)'=']=state_map[(uchar)'!']= (uchar) MY_LEX_CMP_OP;
state_map[(uchar)'<']= (uchar) MY_LEX_LONG_CMP_OP;
......
......@@ -374,7 +374,7 @@ public:
Item_uint(const char *str_arg, uint length) :
Item_int(str_arg, (longlong) strtoull(str_arg,(char**) 0,10), length) {}
Item_uint(uint32 i) :Item_int((longlong) i, 10) {}
double val() { return ulonglong2double(value); }
double val() { return ulonglong2double((ulonglong)value); }
String *val_str(String*);
Item *new_item() { return new Item_uint(name,max_length); }
bool fix_fields(THD *thd, struct st_table_list *list, Item **item)
......
......@@ -597,7 +597,8 @@ void Item_func_neg::fix_length_and_dec()
{
decimals=args[0]->decimals;
max_length=args[0]->max_length;
hybrid_type= args[0]->result_type() == INT_RESULT ? INT_RESULT : REAL_RESULT;
hybrid_type= args[0]->result_type() == INT_RESULT && !args[0]->unsigned_flag ?
INT_RESULT : REAL_RESULT;
}
double Item_func_abs::val()
......
......@@ -455,6 +455,13 @@ int yylex(void *arg, void *yythd)
}
case MY_LEX_CHAR: // Unknown or single char token
case MY_LEX_SKIP: // This should not happen
if (c == '-' && yyPeek() == '-' &&
(my_isspace(cs,yyPeek2()) ||
my_iscntrl(cs,yyPeek2())))
{
state=MY_LEX_COMMENT;
break;
}
yylval->lex_str.str=(char*) (lex->ptr=lex->tok_start);// Set to first chr
yylval->lex_str.length=1;
c=yyGet();
......@@ -694,37 +701,6 @@ int yylex(void *arg, void *yythd)
lex->next_state= MY_LEX_START;
return(IDENT);
}
case MY_LEX_SIGNED_NUMBER: // Incomplete signed number
if (prev_state == MY_LEX_OPERATOR_OR_IDENT)
{
if (c == '-' && yyPeek() == '-' &&
(my_isspace(cs,yyPeek2()) ||
my_iscntrl(cs,yyPeek2())))
state=MY_LEX_COMMENT;
else
state= MY_LEX_CHAR; // Must be operator
break;
}
if (!my_isdigit(cs,c=yyGet()) || yyPeek() == 'x')
{
if (c != '.')
{
if (c == '-' && my_isspace(cs,yyPeek()))
state= MY_LEX_COMMENT;
else
state= MY_LEX_CHAR; // Return sign as single char
break;
}
yyUnget(); // Fix for next loop
}
while (my_isdigit(cs,c=yyGet())) ; // Incomplete real or int number
if ((c == 'e' || c == 'E') &&
(yyPeek() == '+' || yyPeek() == '-' || my_isdigit(cs,yyPeek())))
{ // Real number
yyUnget();
c= '.'; // Fool next test
}
// fall through
case MY_LEX_INT_OR_REAL: // Compleat int or incompleat real
if (c != '.')
{ // Found complete integer number.
......
......@@ -2294,7 +2294,8 @@ simple_expr:
YYABORT;
}
| sum_expr
| '-' expr %prec NEG { $$= new Item_func_neg($2); }
| '+' expr %prec NEG { $$= $2; }
| '-' expr %prec NEG { $$= new Item_func_neg($2); }
| '~' expr %prec NEG { $$= new Item_func_bit_neg($2); }
| NOT expr %prec NEG { $$= new Item_func_not($2); }
| '!' expr %prec NEG { $$= new Item_func_not($2); }
......@@ -4138,7 +4139,7 @@ literal:
Lex->next_state=MY_LEX_OPERATOR_OR_IDENT;}
| HEX_NUM { $$ = new Item_varbinary($1.str,$1.length);}
| UNDERSCORE_CHARSET HEX_NUM
{
{
Item *tmp= new Item_varbinary($2.str,$2.length);
String *str= tmp ? tmp->val_str((String*) 0) : (String*) 0;
$$ = new Item_string(str ? str->ptr() : "", str ? str->length() : 0,
......@@ -4310,8 +4311,6 @@ ident:
LEX *lex= Lex;
$$.str= lex->thd->strmake($1.str,$1.length);
$$.length=$1.length;
if (lex->next_state != MY_LEX_END)
lex->next_state= MY_LEX_OPERATOR_OR_IDENT;
}
;
......
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