summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <vva@eagle.mysql.r18.ru>2003-08-27 19:15:27 -0400
committerunknown <vva@eagle.mysql.r18.ru>2003-08-27 19:15:27 -0400
commit808e1afce81bb1408045c4452c489ad5871d79c8 (patch)
tree19dff2fde41401617e06827c33867e068f9ce734
parentaf544cbdfbeb7d60c82aaca6e9bb141d4923d8fc (diff)
parentf6f2320835470a7d19f1638ecb1ad21585900028 (diff)
downloadmariadb-git-808e1afce81bb1408045c4452c489ad5871d79c8.tar.gz
Merge eagle.mysql.r18.ru:/home/vva/work/mysql.orig/clear/mysql-4.1
into eagle.mysql.r18.ru:/home/vva/work/BUG_910/mysql-4.1 sql/field.h: Auto merged sql/item.h: Auto merged sql/item_cmpfunc.cc: Auto merged
-rw-r--r--mysql-test/r/create.result49
-rw-r--r--mysql-test/t/create.test38
-rw-r--r--sql/field.h29
-rw-r--r--sql/item.cc67
-rw-r--r--sql/item.h2
-rw-r--r--sql/item_cmpfunc.cc13
-rw-r--r--sql/item_cmpfunc.h4
7 files changed, 202 insertions, 0 deletions
diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result
index 9a0eca52b84..5567cc7c841 100644
--- a/mysql-test/r/create.result
+++ b/mysql-test/r/create.result
@@ -310,3 +310,52 @@ t1 CREATE TABLE `t1` (
) TYPE=MyISAM CHARSET=latin1
SET SESSION table_type=default;
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;
diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test
index 9bc37a0864d..b89cf854ffb 100644
--- a/mysql-test/t/create.test
+++ b/mysql-test/t/create.test
@@ -215,3 +215,41 @@ CREATE TABLE t1 (a int not null);
show create table t1;
SET SESSION table_type=default;
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;
diff --git a/sql/field.h b/sql/field.h
index 794b4a89542..10d3e671867 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -305,6 +305,11 @@ public:
unireg_check_arg, field_name_arg, table_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 ha_base_keytype key_type() const
{ return zerofill ? HA_KEYTYPE_BINARY : HA_KEYTYPE_NUM; }
@@ -334,6 +339,11 @@ public:
unireg_check_arg, field_name_arg, table_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_field_types type() const { return FIELD_TYPE_TINY;}
enum ha_base_keytype key_type() const
@@ -364,6 +374,11 @@ public:
unireg_check_arg, field_name_arg, table_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_field_types type() const { return FIELD_TYPE_SHORT;}
enum ha_base_keytype key_type() const
@@ -497,6 +512,11 @@ public:
unireg_check_arg, field_name_arg, table_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 ha_base_keytype key_type() const { return HA_KEYTYPE_FLOAT; }
int store(const char *to,uint length,CHARSET_INFO *charset);
@@ -558,6 +578,11 @@ public:
:Field_str(ptr_arg, len_arg, null, 1,
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;}
int store(const char *to, uint length, CHARSET_INFO *cs) { 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,
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;}
int store(const char *to,uint length,CHARSET_INFO *charset);
int store(double nr);
diff --git a/sql/item.cc b/sql/item.cc
index 17b0519b61c..29f76ecff94 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -983,6 +983,73 @@ enum_field_types Item::field_type() const
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 */
void Item_field::make_field(Send_field *tmp_field)
{
diff --git a/sql/item.h b/sql/item.h
index 3412b43da44..e8ef3b39a27 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -180,6 +180,8 @@ public:
virtual bool null_inside() { return 0; }
// used in row subselects to get value of elements
virtual void bring_value() {}
+
+ Field *tmp_table_field_from_field_type(TABLE *table);
};
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 642be5491aa..6eb1cb75871 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -687,8 +687,21 @@ Item_func_ifnull::fix_length_and_dec()
agg_arg_collations(collation, args, arg_count);
else if (cached_result_type != REAL_RESULT)
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
Item_func_ifnull::val()
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 25cc97d60bf..5dd919c984b 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -281,6 +281,8 @@ public:
class Item_func_ifnull :public Item_func
{
enum Item_result cached_result_type;
+ enum_field_types cached_field_type;
+ bool field_type_defined;
public:
Item_func_ifnull(Item *a,Item *b)
:Item_func(a,b), cached_result_type(INT_RESULT)
@@ -289,8 +291,10 @@ public:
longlong val_int();
String *val_str(String *str);
enum Item_result result_type () const { return cached_result_type; }
+ enum_field_types field_type() const;
void fix_length_and_dec();
const char *func_name() const { return "ifnull"; }
+ Field *tmp_table_field(TABLE *table);
};