Commit 3f28924e authored by unknown's avatar unknown

Merge mysql.com:/home/hf/work/27921/my51-27921

into  mysql.com:/home/hf/work/27957/my51-27957


mysql-test/r/cast.result:
  Auto merged
sql/item_create.cc:
  Auto merged
sql/item_func.cc:
  Auto merged
sql/item_func.h:
  Auto merged
sql/my_decimal.h:
  Auto merged
sql/sql_yacc.yy:
  Auto merged
parents 62db8d6d 812a6ee7
...@@ -3346,6 +3346,19 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -3346,6 +3346,19 @@ 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.
DROP DATABASE IF EXISTS `d-1`; DROP DATABASE IF EXISTS `d-1`;
CREATE DATABASE `d-1`; CREATE DATABASE `d-1`;
......
...@@ -8772,8 +8772,7 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, ...@@ -8772,8 +8772,7 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
case MYSQL_TYPE_NULL: case MYSQL_TYPE_NULL:
break; break;
case MYSQL_TYPE_NEWDECIMAL: case MYSQL_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,
......
...@@ -3916,6 +3916,7 @@ Create_func_master_pos_wait Create_func_master_pos_wait::s_singleton; ...@@ -3916,6 +3916,7 @@ Create_func_master_pos_wait Create_func_master_pos_wait::s_singleton;
Item* Item*
Create_func_master_pos_wait::create_native(THD *thd, LEX_STRING name, Create_func_master_pos_wait::create_native(THD *thd, LEX_STRING name,
List<Item> *item_list) List<Item> *item_list)
{ {
Item *func= NULL; Item *func= NULL;
int arg_count= 0; int arg_count= 0;
...@@ -3946,7 +3947,6 @@ Create_func_master_pos_wait::create_native(THD *thd, LEX_STRING name, ...@@ -3946,7 +3947,6 @@ Create_func_master_pos_wait::create_native(THD *thd, LEX_STRING name,
my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str); my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
break; break;
} }
}
return func; return func;
} }
...@@ -4970,11 +4970,15 @@ find_qualified_function_builder(THD *thd) ...@@ -4970,11 +4970,15 @@ find_qualified_function_builder(THD *thd)
return & Create_sp_func::s_singleton; return & Create_sp_func::s_singleton;
} }
Item*
create_func_cast(THD *thd, 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;
ulong len;
uint dec;
LINT_INIT(res); LINT_INIT(res);
switch (cast_type) { switch (cast_type) {
...@@ -4998,18 +5002,21 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type, int len, int dec, ...@@ -4998,18 +5002,21 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type, int len, int dec,
break; break;
case ITEM_CAST_DECIMAL: case ITEM_CAST_DECIMAL:
{ {
int 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 (thd->mem_root) Item_decimal_typecast(a, tmp_len, dec); res= new (thd->mem_root) Item_decimal_typecast(a, len, dec);
break; break;
} }
case ITEM_CAST_CHAR: case ITEM_CAST_CHAR:
{ {
CHARSET_INFO *real_cs= (cs ? cs : thd->variables.collation_connection); CHARSET_INFO *real_cs= (cs ? cs : thd->variables.collation_connection);
len= c_len ? atoi(c_len) : -1;
res= new (thd->mem_root) Item_char_typecast(a, len, real_cs); res= new (thd->mem_root) Item_char_typecast(a, len, real_cs);
break; break;
} }
...@@ -5022,4 +5029,3 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type, int len, int dec, ...@@ -5022,4 +5029,3 @@ create_func_cast(THD *thd, Item *a, Cast_target cast_type, int len, int dec,
} }
return res; return res;
} }
...@@ -159,9 +159,9 @@ class Create_udf_func : public Create_func ...@@ -159,9 +159,9 @@ class Create_udf_func : public Create_func
@param dec TODO @param dec TODO
@param cs The character set @param cs The character set
*/ */
Item* Item *
create_func_cast(THD *thd, Item *a, Cast_target cast_type, int len, int dec, create_func_cast(THD *thd, Item *a, Cast_target cast_type,
const char *len, const char *dec,
CHARSET_INFO *cs); CHARSET_INFO *cs);
#endif #endif
...@@ -1080,9 +1080,26 @@ my_decimal *Item_decimal_typecast::val_decimal(my_decimal *dec) ...@@ -1080,9 +1080,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(')');
} }
......
...@@ -333,8 +333,8 @@ class Item_decimal_typecast :public Item_func ...@@ -333,8 +333,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();
......
...@@ -395,5 +395,16 @@ int my_decimal_intg(const my_decimal *a) ...@@ -395,5 +395,16 @@ int my_decimal_intg(const my_decimal *a)
} }
void my_decimal_trim(ulong *precision, uint *scale)
{
if (!(*precision) && !(*scale))
{
*precision= 10;
*scale= 0;
return;
}
}
#endif /*my_decimal_h*/ #endif /*my_decimal_h*/
...@@ -6503,15 +6503,13 @@ simple_expr: ...@@ -6503,15 +6503,13 @@ simple_expr:
} }
| BINARY simple_expr %prec NEG | BINARY simple_expr %prec NEG
{ {
$$= create_func_cast(YYTHD, $2, ITEM_CAST_CHAR, -1, 0, $$= create_func_cast(YYTHD, $2, ITEM_CAST_CHAR, NULL, NULL,
&my_charset_bin); &my_charset_bin);
} }
| CAST_SYM '(' expr AS cast_type ')' | CAST_SYM '(' expr AS cast_type ')'
{ {
LEX *lex= Lex; LEX *lex= Lex;
$$= create_func_cast(YYTHD, $3, $5, $$= create_func_cast(YYTHD, $3, $5, lex->length, lex->dec,
lex->length ? atoi(lex->length) : -1,
lex->dec ? atoi(lex->dec) : 0,
lex->charset); lex->charset);
if (!$$) if (!$$)
MYSQL_YYABORT; MYSQL_YYABORT;
...@@ -6520,9 +6518,7 @@ simple_expr: ...@@ -6520,9 +6518,7 @@ simple_expr:
{ $$= new (YYTHD->mem_root) Item_func_case(* $3, $2, $4 ); } { $$= new (YYTHD->mem_root) Item_func_case(* $3, $2, $4 ); }
| CONVERT_SYM '(' expr ',' cast_type ')' | CONVERT_SYM '(' expr ',' cast_type ')'
{ {
$$= create_func_cast(YYTHD, $3, $5, $$= create_func_cast(YYTHD, $3, $5, Lex->length, Lex->dec,
Lex->length ? atoi(Lex->length) : -1,
Lex->dec ? atoi(Lex->dec) : 0,
Lex->charset); Lex->charset);
if (!$$) if (!$$)
MYSQL_YYABORT; MYSQL_YYABORT;
......
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