Commit 63cf4946 authored by vva@eagle.mysql.r18.ru's avatar vva@eagle.mysql.r18.ru

Merge vvagin@bk-internal.mysql.com:/home/bk/mysql-4.1

into eagle.mysql.r18.ru:/home/vva/work/BUG_910/mysql-4.1
parents 42171225 79be4841
...@@ -312,3 +312,52 @@ SET SESSION table_type=default; ...@@ -312,3 +312,52 @@ SET SESSION table_type=default;
drop table t1; drop table t1;
create table t1 select x'4132'; create table t1 select x'4132';
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;
...@@ -219,6 +219,44 @@ drop table t1; ...@@ -219,6 +219,44 @@ drop table t1;
# #
# Bug # 801 # Bug # 801
# #
create table t1 select x'4132'; create table t1 select x'4132';
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;
...@@ -305,6 +305,11 @@ class Field_decimal :public Field_num { ...@@ -305,6 +305,11 @@ class Field_decimal :public Field_num {
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 @@ class Field_tiny :public Field_num { ...@@ -334,6 +339,11 @@ class Field_tiny :public Field_num {
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 @@ class Field_short :public Field_num { ...@@ -364,6 +374,11 @@ class Field_short :public Field_num {
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 @@ class Field_float :public Field_num { ...@@ -497,6 +512,11 @@ class Field_float :public Field_num {
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 @@ class Field_null :public Field_str { ...@@ -558,6 +578,11 @@ class Field_null :public Field_str {
: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 @@ class Field_year :public Field_tiny { ...@@ -627,6 +652,10 @@ class Field_year :public Field_tiny {
: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);
......
...@@ -910,6 +910,73 @@ enum_field_types Item::field_type() const ...@@ -910,6 +910,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)
{ {
......
...@@ -205,6 +205,8 @@ class Item { ...@@ -205,6 +205,8 @@ class Item {
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);
}; };
......
...@@ -698,8 +698,21 @@ Item_func_ifnull::fix_length_and_dec() ...@@ -698,8 +698,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()
......
...@@ -280,6 +280,8 @@ class Item_func_interval :public Item_int_func ...@@ -280,6 +280,8 @@ class Item_func_interval :public Item_int_func
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)
...@@ -288,8 +290,10 @@ class Item_func_ifnull :public Item_func ...@@ -288,8 +290,10 @@ class Item_func_ifnull :public Item_func
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);
table_map not_null_tables() const { return 0; } table_map not_null_tables() const { return 0; }
}; };
......
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