Bug #27921 View ignores precision for CAST()
Item_decimal_typecast::print properly implemented mysql-test/r/view.result: Bug #27921 View ignores precision for CAST() test result mysql-test/t/view.test: Bug #27921 View ignores precision for CAST() test case sql/field.cc: zero decimals handling unified sql/item_create.cc: Bug #27921 View ignores precision for CAST() create_func_cast parameters changed, zero precision handling unified sql/item_create.h: Bug #27921 View ignores precision for CAST() create_func_cast parameters changed sql/item_func.cc: Bug #27921 View ignores precision for CAST() Item_decimal_typecast::print properly implemented sql/item_func.h: Bug #27921 View ignores precision for CAST() max_length counting fixed sql/my_decimal.h: Bug #27921 View ignores precision for CAST() my_decimal_trim() implemented to unify zero precision handling sql/sql_yacc.yy: Bug #27921 View ignores precision for CAST() create_func_cast calls simplified
This commit is contained in:
parent
187ccf4bca
commit
f2a52dd0f0
@ -1789,7 +1789,7 @@ drop table t1;
|
|||||||
create view v1 as select cast(1 as decimal);
|
create view v1 as select cast(1 as decimal);
|
||||||
select * from v1;
|
select * from v1;
|
||||||
cast(1 as decimal)
|
cast(1 as decimal)
|
||||||
1.00
|
1
|
||||||
drop view v1;
|
drop view v1;
|
||||||
create table t1(f1 int);
|
create table t1(f1 int);
|
||||||
create table t2(f2 int);
|
create table t2(f2 int);
|
||||||
@ -3354,4 +3354,17 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL Using filesort
|
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL Using filesort
|
||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
CREATE VIEW v1 AS SELECT CAST( 1.23456789 AS DECIMAL( 7,5 ) ) AS col;
|
||||||
|
SELECT * FROM v1;
|
||||||
|
col
|
||||||
|
1.23457
|
||||||
|
DESCRIBE v1;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
col decimal(7,5) NO 0.00000
|
||||||
|
DROP VIEW v1;
|
||||||
|
CREATE VIEW v1 AS SELECT CAST(1.23456789 AS DECIMAL(8,0)) AS col;
|
||||||
|
SHOW CREATE VIEW v1;
|
||||||
|
View Create View
|
||||||
|
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(1.23456789 as decimal(8,0)) AS `col`
|
||||||
|
DROP VIEW v1;
|
||||||
End of 5.0 tests.
|
End of 5.0 tests.
|
||||||
|
@ -3221,4 +3221,16 @@ EXPLAIN SELECT * FROM t1 UNION SELECT * FROM v1 ORDER BY a;
|
|||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #27921 View ignores precision for CAST()
|
||||||
|
#
|
||||||
|
CREATE VIEW v1 AS SELECT CAST( 1.23456789 AS DECIMAL( 7,5 ) ) AS col;
|
||||||
|
SELECT * FROM v1;
|
||||||
|
DESCRIBE v1;
|
||||||
|
DROP VIEW v1;
|
||||||
|
|
||||||
|
CREATE VIEW v1 AS SELECT CAST(1.23456789 AS DECIMAL(8,0)) AS col;
|
||||||
|
SHOW CREATE VIEW v1;
|
||||||
|
DROP VIEW v1;
|
||||||
|
|
||||||
--echo End of 5.0 tests.
|
--echo End of 5.0 tests.
|
||||||
|
@ -8426,8 +8426,7 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
|
|||||||
case FIELD_TYPE_NULL:
|
case FIELD_TYPE_NULL:
|
||||||
break;
|
break;
|
||||||
case FIELD_TYPE_NEWDECIMAL:
|
case FIELD_TYPE_NEWDECIMAL:
|
||||||
if (!fld_length && !decimals)
|
my_decimal_trim(&length, &decimals);
|
||||||
length= 10;
|
|
||||||
if (length > DECIMAL_MAX_PRECISION)
|
if (length > DECIMAL_MAX_PRECISION)
|
||||||
{
|
{
|
||||||
my_error(ER_TOO_BIG_PRECISION, MYF(0), length, fld_name,
|
my_error(ER_TOO_BIG_PRECISION, MYF(0), length, fld_name,
|
||||||
|
@ -445,11 +445,13 @@ Item *create_load_file(Item* a)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Item *create_func_cast(Item *a, Cast_target cast_type, int len, int dec,
|
Item *create_func_cast(Item *a, Cast_target cast_type,
|
||||||
|
const char *c_len, const char *c_dec,
|
||||||
CHARSET_INFO *cs)
|
CHARSET_INFO *cs)
|
||||||
{
|
{
|
||||||
Item *res;
|
Item *res;
|
||||||
int tmp_len;
|
ulong len;
|
||||||
|
uint dec;
|
||||||
LINT_INIT(res);
|
LINT_INIT(res);
|
||||||
|
|
||||||
switch (cast_type) {
|
switch (cast_type) {
|
||||||
@ -460,15 +462,18 @@ Item *create_func_cast(Item *a, Cast_target cast_type, int len, int dec,
|
|||||||
case ITEM_CAST_TIME: res= new Item_time_typecast(a); break;
|
case ITEM_CAST_TIME: res= new Item_time_typecast(a); break;
|
||||||
case ITEM_CAST_DATETIME: res= new Item_datetime_typecast(a); break;
|
case ITEM_CAST_DATETIME: res= new Item_datetime_typecast(a); break;
|
||||||
case ITEM_CAST_DECIMAL:
|
case ITEM_CAST_DECIMAL:
|
||||||
tmp_len= (len>0) ? len : 10;
|
len= c_len ? atoi(c_len) : 0;
|
||||||
if (tmp_len < dec)
|
dec= c_dec ? atoi(c_dec) : 0;
|
||||||
|
my_decimal_trim(&len, &dec);
|
||||||
|
if (len < dec)
|
||||||
{
|
{
|
||||||
my_error(ER_M_BIGGER_THAN_D, MYF(0), "");
|
my_error(ER_M_BIGGER_THAN_D, MYF(0), "");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
res= new Item_decimal_typecast(a, tmp_len, dec ? dec : 2);
|
res= new Item_decimal_typecast(a, len, dec);
|
||||||
break;
|
break;
|
||||||
case ITEM_CAST_CHAR:
|
case ITEM_CAST_CHAR:
|
||||||
|
len= c_len ? atoi(c_len) : -1;
|
||||||
res= new Item_char_typecast(a, len, cs ? cs :
|
res= new Item_char_typecast(a, len, cs ? cs :
|
||||||
current_thd->variables.collation_connection);
|
current_thd->variables.collation_connection);
|
||||||
break;
|
break;
|
||||||
@ -476,6 +481,7 @@ Item *create_func_cast(Item *a, Cast_target cast_type, int len, int dec,
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Item *create_func_is_free_lock(Item* a)
|
Item *create_func_is_free_lock(Item* a)
|
||||||
{
|
{
|
||||||
current_thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
|
current_thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
|
||||||
|
@ -27,7 +27,8 @@ Item *create_func_bit_length(Item* a);
|
|||||||
Item *create_func_coercibility(Item* a);
|
Item *create_func_coercibility(Item* a);
|
||||||
Item *create_func_ceiling(Item* a);
|
Item *create_func_ceiling(Item* a);
|
||||||
Item *create_func_char_length(Item* a);
|
Item *create_func_char_length(Item* a);
|
||||||
Item *create_func_cast(Item *a, Cast_target cast_type, int len, int dec,
|
Item *create_func_cast(Item *a, Cast_target cast_type,
|
||||||
|
const char *len, const char *dec,
|
||||||
CHARSET_INFO *cs);
|
CHARSET_INFO *cs);
|
||||||
Item *create_func_connection_id(void);
|
Item *create_func_connection_id(void);
|
||||||
Item *create_func_conv(Item* a, Item *b, Item *c);
|
Item *create_func_conv(Item* a, Item *b, Item *c);
|
||||||
|
@ -1059,9 +1059,26 @@ my_decimal *Item_decimal_typecast::val_decimal(my_decimal *dec)
|
|||||||
|
|
||||||
void Item_decimal_typecast::print(String *str)
|
void Item_decimal_typecast::print(String *str)
|
||||||
{
|
{
|
||||||
|
char len_buf[20*3 + 1];
|
||||||
|
char *end;
|
||||||
|
CHARSET_INFO *cs= str->charset();
|
||||||
|
|
||||||
|
uint precision= my_decimal_length_to_precision(max_length, decimals,
|
||||||
|
unsigned_flag);
|
||||||
str->append(STRING_WITH_LEN("cast("));
|
str->append(STRING_WITH_LEN("cast("));
|
||||||
args[0]->print(str);
|
args[0]->print(str);
|
||||||
str->append(STRING_WITH_LEN(" as decimal)"));
|
str->append(STRING_WITH_LEN(" as decimal("));
|
||||||
|
|
||||||
|
end=int10_to_str(precision, len_buf,10);
|
||||||
|
str->append(len_buf, (uint32) (end - len_buf));
|
||||||
|
|
||||||
|
str->append(',');
|
||||||
|
|
||||||
|
end=int10_to_str(decimals, len_buf,10);
|
||||||
|
str->append(len_buf, (uint32) (end - len_buf));
|
||||||
|
|
||||||
|
str->append(')');
|
||||||
|
str->append(')');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -331,8 +331,8 @@ class Item_decimal_typecast :public Item_func
|
|||||||
public:
|
public:
|
||||||
Item_decimal_typecast(Item *a, int len, int dec) :Item_func(a)
|
Item_decimal_typecast(Item *a, int len, int dec) :Item_func(a)
|
||||||
{
|
{
|
||||||
max_length= len + 2;
|
|
||||||
decimals= dec;
|
decimals= dec;
|
||||||
|
max_length= my_decimal_precision_to_length(len, dec, unsigned_flag);
|
||||||
}
|
}
|
||||||
String *val_str(String *str);
|
String *val_str(String *str);
|
||||||
double val_real();
|
double val_real();
|
||||||
|
@ -387,5 +387,18 @@ int my_decimal_cmp(const my_decimal *a, const my_decimal *b)
|
|||||||
return decimal_cmp((decimal_t*) a, (decimal_t*) b);
|
return decimal_cmp((decimal_t*) a, (decimal_t*) b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline
|
||||||
|
void my_decimal_trim(ulong *precision, uint *scale)
|
||||||
|
{
|
||||||
|
if (!(*precision) && !(*scale))
|
||||||
|
{
|
||||||
|
*precision= 10;
|
||||||
|
*scale= 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /*my_decimal_h*/
|
#endif /*my_decimal_h*/
|
||||||
|
|
||||||
|
@ -4699,15 +4699,12 @@ simple_expr:
|
|||||||
| ASCII_SYM '(' expr ')' { $$= new Item_func_ascii($3); }
|
| ASCII_SYM '(' expr ')' { $$= new Item_func_ascii($3); }
|
||||||
| BINARY simple_expr %prec NEG
|
| BINARY simple_expr %prec NEG
|
||||||
{
|
{
|
||||||
$$= create_func_cast($2, ITEM_CAST_CHAR, -1, 0, &my_charset_bin);
|
$$= create_func_cast($2, ITEM_CAST_CHAR, NULL, NULL, &my_charset_bin);
|
||||||
}
|
}
|
||||||
| CAST_SYM '(' expr AS cast_type ')'
|
| CAST_SYM '(' expr AS cast_type ')'
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
$$= create_func_cast($3, $5,
|
$$= create_func_cast($3, $5, lex->length, lex->dec, lex->charset);
|
||||||
lex->length ? atoi(lex->length) : -1,
|
|
||||||
lex->dec ? atoi(lex->dec) : 0,
|
|
||||||
lex->charset);
|
|
||||||
if (!$$)
|
if (!$$)
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
@ -4715,10 +4712,7 @@ simple_expr:
|
|||||||
{ $$= new Item_func_case(* $3, $2, $4 ); }
|
{ $$= new Item_func_case(* $3, $2, $4 ); }
|
||||||
| CONVERT_SYM '(' expr ',' cast_type ')'
|
| CONVERT_SYM '(' expr ',' cast_type ')'
|
||||||
{
|
{
|
||||||
$$= create_func_cast($3, $5,
|
$$= create_func_cast($3, $5, Lex->length, Lex->dec, Lex->charset);
|
||||||
Lex->length ? atoi(Lex->length) : -1,
|
|
||||||
Lex->dec ? atoi(Lex->dec) : 0,
|
|
||||||
Lex->charset);
|
|
||||||
if (!$$)
|
if (!$$)
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user