Commit 7ed30b97 authored by evgen@sunlight.local's avatar evgen@sunlight.local
Browse files

Merge epotemkin@bk-internal.mysql.com:/home/bk/mysql-5.0-opt

into  sunlight.local:/local_work/27216-bug-5.0-opt-mysql
parents bb5cdfb8 36bf417b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -4355,6 +4355,7 @@ static my_bool setup_one_fetch_function(MYSQL_BIND *param, MYSQL_FIELD *field)
  case MYSQL_TYPE_STRING:
  case MYSQL_TYPE_DECIMAL:
  case MYSQL_TYPE_NEWDECIMAL:
  case MYSQL_TYPE_NEWDATE:
    DBUG_ASSERT(param->buffer_length != 0);
    param->fetch_result= fetch_result_str;
    break;
@@ -4427,6 +4428,7 @@ static my_bool setup_one_fetch_function(MYSQL_BIND *param, MYSQL_FIELD *field)
  case MYSQL_TYPE_VAR_STRING:
  case MYSQL_TYPE_STRING:
  case MYSQL_TYPE_BIT:
  case MYSQL_TYPE_NEWDATE:
    param->skip_result= skip_result_string;
    break;
  default:
+1 −1
Original line number Diff line number Diff line
@@ -481,7 +481,7 @@ str_to_date(a,b)
create table t2 select str_to_date(a,b) from t1;
describe t2;
Field	Type	Null	Key	Default	Extra
str_to_date(a,b)	binary(29)	YES		NULL	
str_to_date(a,b)	datetime	YES		NULL	
select str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S.%f") as f1,
str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:%S") as f2,
str_to_date("2003-01-02", "%Y-%m-%d") as f3,
+61 −0
Original line number Diff line number Diff line
@@ -427,3 +427,64 @@ f1
Warnings:
Warning	1292	Incorrect datetime value: '2007010100000' for column 'f1' at row 1
drop table t1;
#
# Bug#27216: functions with parameters of different date types may
#            return wrong type of the result.
#
create table t1 (f1 date, f2 datetime, f3 varchar(20));
create table t2 as select coalesce(f1,f1) as f4 from t1;
desc t2;
Field	Type	Null	Key	Default	Extra
f4	date	YES		NULL	
create table t3 as select coalesce(f1,f2) as f4 from t1;
desc t3;
Field	Type	Null	Key	Default	Extra
f4	datetime	YES		NULL	
create table t4 as select coalesce(f2,f2) as f4 from t1;
desc t4;
Field	Type	Null	Key	Default	Extra
f4	datetime	YES		NULL	
create table t5 as select coalesce(f1,f3) as f4 from t1;
desc t5;
Field	Type	Null	Key	Default	Extra
f4	varbinary(20)	YES		NULL	
create table t6 as select coalesce(f2,f3) as f4 from t1;
desc t6;
Field	Type	Null	Key	Default	Extra
f4	varbinary(20)	YES		NULL	
create table t7 as select coalesce(makedate(1997,1),f2) as f4 from t1;
desc t7;
Field	Type	Null	Key	Default	Extra
f4	datetime	YES		NULL	
create table t8 as select coalesce(cast('01-01-01' as datetime),f2) as f4
from t1;
desc t8;
Field	Type	Null	Key	Default	Extra
f4	datetime	YES		NULL	
create table t9 as select case when 1 then cast('01-01-01' as date)
when 0 then cast('01-01-01' as date) end as f4 from t1;
desc t9;
Field	Type	Null	Key	Default	Extra
f4	date	YES		NULL	
create table t10 as select case when 1 then cast('01-01-01' as datetime)
when 0 then cast('01-01-01' as datetime) end as f4 from t1;
desc t10;
Field	Type	Null	Key	Default	Extra
f4	datetime	YES		NULL	
create table t11 as select if(1, cast('01-01-01' as datetime),
cast('01-01-01' as date)) as f4 from t1;
desc t11;
Field	Type	Null	Key	Default	Extra
f4	datetime	YES		NULL	
create table t12 as select least(cast('01-01-01' as datetime),
cast('01-01-01' as date)) as f4 from t1;
desc t12;
Field	Type	Null	Key	Default	Extra
f4	datetime	YES		NULL	
create table t13 as select ifnull(cast('01-01-01' as datetime),
cast('01-01-01' as date)) as f4 from t1;
desc t13;
Field	Type	Null	Key	Default	Extra
f4	datetime	YES		NULL	
drop tables t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13;
###################################################################
+38 −0
Original line number Diff line number Diff line
@@ -282,3 +282,41 @@ select * from t1 where f1 between 20020101 and 20070101000000;
select * from t1 where f1 between 2002010 and 20070101000000;
select * from t1 where f1 between 20020101 and 2007010100000;
drop table t1;

--echo #
--echo # Bug#27216: functions with parameters of different date types may
--echo #            return wrong type of the result.
--echo #
create table t1 (f1 date, f2 datetime, f3 varchar(20));
create table t2 as select coalesce(f1,f1) as f4 from t1;
desc t2;
create table t3 as select coalesce(f1,f2) as f4 from t1;
desc t3;
create table t4 as select coalesce(f2,f2) as f4 from t1;
desc t4;
create table t5 as select coalesce(f1,f3) as f4 from t1;
desc t5;
create table t6 as select coalesce(f2,f3) as f4 from t1;
desc t6;
create table t7 as select coalesce(makedate(1997,1),f2) as f4 from t1;
desc t7;
create table t8 as select coalesce(cast('01-01-01' as datetime),f2) as f4
  from t1;
desc t8;
create table t9 as select case when 1 then cast('01-01-01' as date)
  when 0 then cast('01-01-01' as date) end as f4 from t1;
desc t9;
create table t10 as select case when 1 then cast('01-01-01' as datetime)
  when 0 then cast('01-01-01' as datetime) end as f4 from t1;
desc t10;
create table t11 as select if(1, cast('01-01-01' as datetime),
  cast('01-01-01' as date)) as f4 from t1;
desc t11;
create table t12 as select least(cast('01-01-01' as datetime),
  cast('01-01-01' as date)) as f4 from t1;
desc t12;
create table t13 as select ifnull(cast('01-01-01' as datetime),
  cast('01-01-01' as date)) as f4 from t1;
desc t13;
drop tables t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13;
--echo ###################################################################
+36 −4
Original line number Diff line number Diff line
@@ -147,6 +147,36 @@ static int agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems)
}


/**
  @brief Aggregates field types from the array of items.

  @param[in] items  array of items to aggregate the type from
  @paran[in] nitems number of items in the array

  @details This function aggregates field types from the array of items.
    Found type is supposed to be used later as the result field type
    of a multi-argument function.
    Aggregation itself is performed by the Field::field_type_merge()
    function.

  @note The term "aggregation" is used here in the sense of inferring the
    result type of a function from its argument types.

  @return aggregated field type.
*/

enum_field_types agg_field_type(Item **items, uint nitems)
{
  uint i;
  if (!nitems || items[0]->result_type() == ROW_RESULT )
    return (enum_field_types)-1;
  enum_field_types res= items[0]->field_type();
  for (i= 1 ; i < nitems ; i++)
    res= Field::field_type_merge(res, items[i]->field_type());
  return res;
}


static void my_coll_agg_error(DTCollation &c1, DTCollation &c2,
                              const char *fname)
{
@@ -2009,9 +2039,7 @@ Item_func_ifnull::fix_length_and_dec()
  default:
    DBUG_ASSERT(0);
  }
  cached_field_type= args[0]->field_type();
  if (cached_field_type != args[1]->field_type())
    cached_field_type= Item_func::field_type();
  cached_field_type= agg_field_type(args, 2);
}


@@ -2159,11 +2187,13 @@ Item_func_if::fix_length_and_dec()
  {
    cached_result_type= arg2_type;
    collation.set(args[2]->collation.collation);
    cached_field_type= args[2]->field_type();
  }
  else if (null2)
  {
    cached_result_type= arg1_type;
    collation.set(args[1]->collation.collation);
    cached_field_type= args[1]->field_type();
  }
  else
  {
@@ -2177,6 +2207,7 @@ Item_func_if::fix_length_and_dec()
    {
      collation.set(&my_charset_bin);	// Number
    }
    cached_field_type= agg_field_type(args + 1, 2);
  }

  if ((cached_result_type == DECIMAL_RESULT )
@@ -2556,7 +2587,7 @@ void Item_func_case::fix_length_and_dec()
      agg_arg_charsets(collation, agg, nagg, MY_COLL_ALLOW_CONV, 1))
    return;
  
  
  cached_field_type= agg_field_type(agg, nagg);
  /*
    Aggregate first expression and all THEN expression types
    and collations when string comparison
@@ -2695,6 +2726,7 @@ my_decimal *Item_func_coalesce::decimal_op(my_decimal *decimal_value)

void Item_func_coalesce::fix_length_and_dec()
{
  cached_field_type= agg_field_type(args, arg_count);
  agg_result_type(&hybrid_type, args, arg_count);
  switch (hybrid_type) {
  case STRING_RESULT:
Loading