mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
fixed bug #910 (right type of ifnull function)
mysql-test/r/create.result: added test for bug #910 (right type of ifnull function) mysql-test/t/create.test: added test for bug #910 (right type of ifnull function) sql/field.h: added new constructors of Field_decimal, Field_tiny, Field_short, Field_float, Field_null, Field_year for using in Item::tmp_table_field_from_field_type sql/item.cc: added Item::tmp_table_field_from_field_type sql/item.h: added Item::tmp_table_field_from_field_type
This commit is contained in:
@ -310,3 +310,52 @@ t1 CREATE TABLE `t1` (
|
|||||||
) TYPE=MyISAM CHARSET=latin1
|
) TYPE=MyISAM CHARSET=latin1
|
||||||
SET SESSION table_type=default;
|
SET SESSION table_type=default;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1(a int,b int,c int unsigned,d date,e char,f datetime,g time,h blob);
|
||||||
|
insert into t1(a)values(1);
|
||||||
|
insert into t1(a,b,c,d,e,f,g,h)
|
||||||
|
values(2,-2,2,'1825-12-14','a','2003-1-1 3:2:1','4:3:2','binary data');
|
||||||
|
select * from t1;
|
||||||
|
a b c d e f g h
|
||||||
|
1 NULL NULL NULL NULL NULL NULL NULL
|
||||||
|
2 -2 2 1825-12-14 a 2003-01-01 03:02:01 04:03:02 binary data
|
||||||
|
select a,
|
||||||
|
ifnull(b,cast(-7 as signed)) as b,
|
||||||
|
ifnull(c,cast(7 as unsigned)) as c,
|
||||||
|
ifnull(d,cast('2000-01-01' as date)) as d,
|
||||||
|
ifnull(e,cast('b' as char)) as e,
|
||||||
|
ifnull(f,cast('2000-01-01' as datetime)) as f,
|
||||||
|
ifnull(g,cast('5:4:3' as time)) as g,
|
||||||
|
ifnull(h,cast('yet another binary data' as binary)) as h,
|
||||||
|
addtime(cast('1:0:0' as time),cast('1:0:0' as time)) as dd
|
||||||
|
from t1;
|
||||||
|
a b c d e f g h dd
|
||||||
|
1 -7 7 2000-01-01 b 2000-01-01 00:00:00 05:04:03 yet another binary data 02:00:00
|
||||||
|
2 -2 2 1825-12-14 a 2003-01-01 03:02:01 04:03:02 binary data 02:00:00
|
||||||
|
create table t2
|
||||||
|
select
|
||||||
|
a,
|
||||||
|
ifnull(b,cast(-7 as signed)) as b,
|
||||||
|
ifnull(c,cast(7 as unsigned)) as c,
|
||||||
|
ifnull(d,cast('2000-01-01' as date)) as d,
|
||||||
|
ifnull(e,cast('b' as char)) as e,
|
||||||
|
ifnull(f,cast('2000-01-01' as datetime)) as f,
|
||||||
|
ifnull(g,cast('5:4:3' as time)) as g,
|
||||||
|
ifnull(h,cast('yet another binary data' as binary)) as h,
|
||||||
|
addtime(cast('1:0:0' as time),cast('1:0:0' as time)) as dd
|
||||||
|
from t1;
|
||||||
|
explain t2;
|
||||||
|
Field Type Null Key Default Extra
|
||||||
|
a int(11) YES NULL
|
||||||
|
b bigint(11) 0
|
||||||
|
c bigint(10) 0
|
||||||
|
d date 0000-00-00
|
||||||
|
e char(1)
|
||||||
|
f datetime 0000-00-00 00:00:00
|
||||||
|
g time 00:00:00
|
||||||
|
h mediumblob
|
||||||
|
dd time 00:00:00
|
||||||
|
select * from t2;
|
||||||
|
a b c d e f g h dd
|
||||||
|
1 -7 7 2000-01-01 b 2000-01-01 00:00:00 05:04:03 yet another binary data 02:00:00
|
||||||
|
2 -2 2 1825-12-14 a 2003-01-01 03:02:01 04:03:02 binary data 02:00:00
|
||||||
|
drop table t1, t2;
|
||||||
|
@ -215,3 +215,41 @@ CREATE TABLE t1 (a int not null);
|
|||||||
show create table t1;
|
show create table t1;
|
||||||
SET SESSION table_type=default;
|
SET SESSION table_type=default;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test types of data for create select with functions
|
||||||
|
#
|
||||||
|
|
||||||
|
create table t1(a int,b int,c int unsigned,d date,e char,f datetime,g time,h blob);
|
||||||
|
insert into t1(a)values(1);
|
||||||
|
insert into t1(a,b,c,d,e,f,g,h)
|
||||||
|
values(2,-2,2,'1825-12-14','a','2003-1-1 3:2:1','4:3:2','binary data');
|
||||||
|
select * from t1;
|
||||||
|
select a,
|
||||||
|
ifnull(b,cast(-7 as signed)) as b,
|
||||||
|
ifnull(c,cast(7 as unsigned)) as c,
|
||||||
|
ifnull(d,cast('2000-01-01' as date)) as d,
|
||||||
|
ifnull(e,cast('b' as char)) as e,
|
||||||
|
ifnull(f,cast('2000-01-01' as datetime)) as f,
|
||||||
|
ifnull(g,cast('5:4:3' as time)) as g,
|
||||||
|
ifnull(h,cast('yet another binary data' as binary)) as h,
|
||||||
|
addtime(cast('1:0:0' as time),cast('1:0:0' as time)) as dd
|
||||||
|
from t1;
|
||||||
|
|
||||||
|
create table t2
|
||||||
|
select
|
||||||
|
a,
|
||||||
|
ifnull(b,cast(-7 as signed)) as b,
|
||||||
|
ifnull(c,cast(7 as unsigned)) as c,
|
||||||
|
ifnull(d,cast('2000-01-01' as date)) as d,
|
||||||
|
ifnull(e,cast('b' as char)) as e,
|
||||||
|
ifnull(f,cast('2000-01-01' as datetime)) as f,
|
||||||
|
ifnull(g,cast('5:4:3' as time)) as g,
|
||||||
|
ifnull(h,cast('yet another binary data' as binary)) as h,
|
||||||
|
addtime(cast('1:0:0' as time),cast('1:0:0' as time)) as dd
|
||||||
|
from t1;
|
||||||
|
explain t2;
|
||||||
|
|
||||||
|
select * from t2;
|
||||||
|
|
||||||
|
drop table t1, t2;
|
||||||
|
29
sql/field.h
29
sql/field.h
@ -305,6 +305,11 @@ public:
|
|||||||
unireg_check_arg, field_name_arg, table_arg,
|
unireg_check_arg, field_name_arg, table_arg,
|
||||||
dec_arg, zero_arg,unsigned_arg)
|
dec_arg, zero_arg,unsigned_arg)
|
||||||
{}
|
{}
|
||||||
|
Field_decimal(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg,
|
||||||
|
struct st_table *table_arg,bool unsigned_arg)
|
||||||
|
:Field_num((char*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0,
|
||||||
|
NONE, field_name_arg, table_arg,0,0,unsigned_arg)
|
||||||
|
{}
|
||||||
enum_field_types type() const { return FIELD_TYPE_DECIMAL;}
|
enum_field_types type() const { return FIELD_TYPE_DECIMAL;}
|
||||||
enum ha_base_keytype key_type() const
|
enum ha_base_keytype key_type() const
|
||||||
{ return zerofill ? HA_KEYTYPE_BINARY : HA_KEYTYPE_NUM; }
|
{ return zerofill ? HA_KEYTYPE_BINARY : HA_KEYTYPE_NUM; }
|
||||||
@ -334,6 +339,11 @@ public:
|
|||||||
unireg_check_arg, field_name_arg, table_arg,
|
unireg_check_arg, field_name_arg, table_arg,
|
||||||
0, zero_arg,unsigned_arg)
|
0, zero_arg,unsigned_arg)
|
||||||
{}
|
{}
|
||||||
|
Field_tiny(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg,
|
||||||
|
struct st_table *table_arg,bool unsigned_arg)
|
||||||
|
:Field_num((char*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0,
|
||||||
|
NONE, field_name_arg, table_arg,0,0,unsigned_arg)
|
||||||
|
{}
|
||||||
enum Item_result result_type () const { return INT_RESULT; }
|
enum Item_result result_type () const { return INT_RESULT; }
|
||||||
enum_field_types type() const { return FIELD_TYPE_TINY;}
|
enum_field_types type() const { return FIELD_TYPE_TINY;}
|
||||||
enum ha_base_keytype key_type() const
|
enum ha_base_keytype key_type() const
|
||||||
@ -364,6 +374,11 @@ public:
|
|||||||
unireg_check_arg, field_name_arg, table_arg,
|
unireg_check_arg, field_name_arg, table_arg,
|
||||||
0, zero_arg,unsigned_arg)
|
0, zero_arg,unsigned_arg)
|
||||||
{}
|
{}
|
||||||
|
Field_short(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg,
|
||||||
|
struct st_table *table_arg,bool unsigned_arg)
|
||||||
|
:Field_num((char*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0,
|
||||||
|
NONE, field_name_arg, table_arg,0,0,unsigned_arg)
|
||||||
|
{}
|
||||||
enum Item_result result_type () const { return INT_RESULT; }
|
enum Item_result result_type () const { return INT_RESULT; }
|
||||||
enum_field_types type() const { return FIELD_TYPE_SHORT;}
|
enum_field_types type() const { return FIELD_TYPE_SHORT;}
|
||||||
enum ha_base_keytype key_type() const
|
enum ha_base_keytype key_type() const
|
||||||
@ -497,6 +512,11 @@ public:
|
|||||||
unireg_check_arg, field_name_arg, table_arg,
|
unireg_check_arg, field_name_arg, table_arg,
|
||||||
dec_arg, zero_arg,unsigned_arg)
|
dec_arg, zero_arg,unsigned_arg)
|
||||||
{}
|
{}
|
||||||
|
Field_float(uint32 len_arg, bool maybe_null_arg, const char *field_name_arg,
|
||||||
|
struct st_table *table_arg, uint8 dec_arg)
|
||||||
|
:Field_num((char*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0, (uint) 0,
|
||||||
|
NONE, field_name_arg, table_arg,dec_arg,0,0)
|
||||||
|
{}
|
||||||
enum_field_types type() const { return FIELD_TYPE_FLOAT;}
|
enum_field_types type() const { return FIELD_TYPE_FLOAT;}
|
||||||
enum ha_base_keytype key_type() const { return HA_KEYTYPE_FLOAT; }
|
enum ha_base_keytype key_type() const { return HA_KEYTYPE_FLOAT; }
|
||||||
int store(const char *to,uint length,CHARSET_INFO *charset);
|
int store(const char *to,uint length,CHARSET_INFO *charset);
|
||||||
@ -558,6 +578,11 @@ public:
|
|||||||
:Field_str(ptr_arg, len_arg, null, 1,
|
:Field_str(ptr_arg, len_arg, null, 1,
|
||||||
unireg_check_arg, field_name_arg, table_arg, cs)
|
unireg_check_arg, field_name_arg, table_arg, cs)
|
||||||
{}
|
{}
|
||||||
|
Field_null(uint32 len_arg, const char *field_name_arg,
|
||||||
|
struct st_table *table_arg, CHARSET_INFO *cs)
|
||||||
|
:Field_str((char*) 0, len_arg, null, 1,
|
||||||
|
NONE, field_name_arg, table_arg, cs)
|
||||||
|
{}
|
||||||
enum_field_types type() const { return FIELD_TYPE_NULL;}
|
enum_field_types type() const { return FIELD_TYPE_NULL;}
|
||||||
int store(const char *to, uint length, CHARSET_INFO *cs) { null[0]=1; return 0; }
|
int store(const char *to, uint length, CHARSET_INFO *cs) { null[0]=1; return 0; }
|
||||||
int store(double nr) { null[0]=1; return 0; }
|
int store(double nr) { null[0]=1; return 0; }
|
||||||
@ -627,6 +652,10 @@ public:
|
|||||||
:Field_tiny(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
|
:Field_tiny(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
|
||||||
unireg_check_arg, field_name_arg, table_arg, 1, 1)
|
unireg_check_arg, field_name_arg, table_arg, 1, 1)
|
||||||
{}
|
{}
|
||||||
|
Field_year(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg,
|
||||||
|
struct st_table *table_arg)
|
||||||
|
:Field_tiny(len_arg,maybe_null_arg,field_name_arg,table_arg,1)
|
||||||
|
{}
|
||||||
enum_field_types type() const { return FIELD_TYPE_YEAR;}
|
enum_field_types type() const { return FIELD_TYPE_YEAR;}
|
||||||
int store(const char *to,uint length,CHARSET_INFO *charset);
|
int store(const char *to,uint length,CHARSET_INFO *charset);
|
||||||
int store(double nr);
|
int store(double nr);
|
||||||
|
67
sql/item.cc
67
sql/item.cc
@ -983,6 +983,73 @@ enum_field_types Item::field_type() const
|
|||||||
FIELD_TYPE_DOUBLE);
|
FIELD_TYPE_DOUBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Field *Item::tmp_table_field_from_field_type(TABLE *table)
|
||||||
|
{
|
||||||
|
switch (field_type())
|
||||||
|
{
|
||||||
|
case MYSQL_TYPE_DECIMAL:
|
||||||
|
return new Field_decimal(max_length, maybe_null, name, table,
|
||||||
|
unsigned_flag);
|
||||||
|
case MYSQL_TYPE_TINY:
|
||||||
|
return new Field_tiny(max_length, maybe_null, name, table,
|
||||||
|
unsigned_flag);
|
||||||
|
case MYSQL_TYPE_SHORT:
|
||||||
|
return new Field_short(max_length, maybe_null, name, table,
|
||||||
|
unsigned_flag);
|
||||||
|
case MYSQL_TYPE_LONG:
|
||||||
|
return new Field_long(max_length, maybe_null, name, table,
|
||||||
|
unsigned_flag);
|
||||||
|
case MYSQL_TYPE_FLOAT:
|
||||||
|
return new Field_float(max_length, maybe_null, name, table, decimals);
|
||||||
|
case MYSQL_TYPE_DOUBLE:
|
||||||
|
return new Field_double(max_length, maybe_null, name, table, decimals);
|
||||||
|
case MYSQL_TYPE_NULL:
|
||||||
|
return new Field_null(max_length, name, table, &my_charset_bin);
|
||||||
|
#ifdef HAVE_LONG_LONG
|
||||||
|
case MYSQL_TYPE_LONGLONG:
|
||||||
|
return new Field_longlong(max_length, maybe_null, name, table,
|
||||||
|
unsigned_flag);
|
||||||
|
#endif
|
||||||
|
case MYSQL_TYPE_NEWDATE:
|
||||||
|
case MYSQL_TYPE_INT24:
|
||||||
|
return new Field_long(max_length, maybe_null, name, table,
|
||||||
|
unsigned_flag);
|
||||||
|
case MYSQL_TYPE_DATE:
|
||||||
|
return new Field_date(maybe_null, name, table, &my_charset_bin);
|
||||||
|
case MYSQL_TYPE_TIME:
|
||||||
|
return new Field_time(maybe_null, name, table, &my_charset_bin);
|
||||||
|
case MYSQL_TYPE_TIMESTAMP:
|
||||||
|
case MYSQL_TYPE_DATETIME:
|
||||||
|
return new Field_datetime(maybe_null, name, table, &my_charset_bin);
|
||||||
|
case MYSQL_TYPE_YEAR:
|
||||||
|
return new Field_year(max_length, maybe_null, name, table);
|
||||||
|
case MYSQL_TYPE_ENUM:
|
||||||
|
case MYSQL_TYPE_SET:
|
||||||
|
return new Field_long(max_length, maybe_null, name, table,
|
||||||
|
unsigned_flag);
|
||||||
|
case MYSQL_TYPE_TINY_BLOB:
|
||||||
|
case MYSQL_TYPE_MEDIUM_BLOB:
|
||||||
|
case MYSQL_TYPE_LONG_BLOB:
|
||||||
|
case MYSQL_TYPE_BLOB:
|
||||||
|
case MYSQL_TYPE_GEOMETRY:
|
||||||
|
return new Field_blob(max_length, maybe_null, name, table, collation.collation);
|
||||||
|
case MYSQL_TYPE_VAR_STRING:
|
||||||
|
if (max_length > 255)
|
||||||
|
return new Field_blob(max_length, maybe_null, name, table, collation.collation);
|
||||||
|
else
|
||||||
|
return new Field_varstring(max_length, maybe_null, name, table, collation.collation);
|
||||||
|
case MYSQL_TYPE_STRING:
|
||||||
|
if (max_length > 255)
|
||||||
|
return new Field_blob(max_length, maybe_null, name, table, collation.collation);
|
||||||
|
else
|
||||||
|
return new Field_string(max_length, maybe_null, name, table, collation.collation);
|
||||||
|
default:
|
||||||
|
// This case should never be choosen
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
void Item_field::make_field(Send_field *tmp_field)
|
void Item_field::make_field(Send_field *tmp_field)
|
||||||
{
|
{
|
||||||
|
@ -180,6 +180,8 @@ public:
|
|||||||
virtual bool null_inside() { return 0; }
|
virtual bool null_inside() { return 0; }
|
||||||
// used in row subselects to get value of elements
|
// used in row subselects to get value of elements
|
||||||
virtual void bring_value() {}
|
virtual void bring_value() {}
|
||||||
|
|
||||||
|
Field *tmp_table_field_from_field_type(TABLE *table);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -687,8 +687,21 @@ Item_func_ifnull::fix_length_and_dec()
|
|||||||
agg_arg_collations(collation, args, arg_count);
|
agg_arg_collations(collation, args, arg_count);
|
||||||
else if (cached_result_type != REAL_RESULT)
|
else if (cached_result_type != REAL_RESULT)
|
||||||
decimals= 0;
|
decimals= 0;
|
||||||
|
|
||||||
|
cached_field_type= args[0]->field_type();
|
||||||
|
if (cached_field_type != args[1]->field_type())
|
||||||
|
cached_field_type= Item_func::field_type();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum_field_types Item_func_ifnull::field_type() const
|
||||||
|
{
|
||||||
|
return cached_field_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
Field *Item_func_ifnull::tmp_table_field(TABLE *table)
|
||||||
|
{
|
||||||
|
return tmp_table_field_from_field_type(table);
|
||||||
|
}
|
||||||
|
|
||||||
double
|
double
|
||||||
Item_func_ifnull::val()
|
Item_func_ifnull::val()
|
||||||
|
@ -281,6 +281,8 @@ public:
|
|||||||
class Item_func_ifnull :public Item_func
|
class Item_func_ifnull :public Item_func
|
||||||
{
|
{
|
||||||
enum Item_result cached_result_type;
|
enum Item_result cached_result_type;
|
||||||
|
enum_field_types cached_field_type;
|
||||||
|
bool field_type_defined;
|
||||||
public:
|
public:
|
||||||
Item_func_ifnull(Item *a,Item *b)
|
Item_func_ifnull(Item *a,Item *b)
|
||||||
:Item_func(a,b), cached_result_type(INT_RESULT)
|
:Item_func(a,b), cached_result_type(INT_RESULT)
|
||||||
@ -289,8 +291,10 @@ public:
|
|||||||
longlong val_int();
|
longlong val_int();
|
||||||
String *val_str(String *str);
|
String *val_str(String *str);
|
||||||
enum Item_result result_type () const { return cached_result_type; }
|
enum Item_result result_type () const { return cached_result_type; }
|
||||||
|
enum_field_types field_type() const;
|
||||||
void fix_length_and_dec();
|
void fix_length_and_dec();
|
||||||
const char *func_name() const { return "ifnull"; }
|
const char *func_name() const { return "ifnull"; }
|
||||||
|
Field *tmp_table_field(TABLE *table);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user