Loading libmysql/libmysql.c +2 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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: Loading mysql-test/r/date_formats.result +1 −1 Original line number Diff line number Diff line Loading @@ -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, Loading mysql-test/r/type_datetime.result +61 −0 Original line number Diff line number Diff line Loading @@ -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; ################################################################### mysql-test/t/type_datetime.test +38 −0 Original line number Diff line number Diff line Loading @@ -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 ################################################################### sql/item_cmpfunc.cc +36 −4 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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); } Loading Loading @@ -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 { Loading @@ -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 ) Loading Loading @@ -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 Loading Loading @@ -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 Loading
libmysql/libmysql.c +2 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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: Loading
mysql-test/r/date_formats.result +1 −1 Original line number Diff line number Diff line Loading @@ -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, Loading
mysql-test/r/type_datetime.result +61 −0 Original line number Diff line number Diff line Loading @@ -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; ###################################################################
mysql-test/t/type_datetime.test +38 −0 Original line number Diff line number Diff line Loading @@ -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 ###################################################################
sql/item_cmpfunc.cc +36 −4 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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); } Loading Loading @@ -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 { Loading @@ -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 ) Loading Loading @@ -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 Loading Loading @@ -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