diff --git a/mysql-test/r/func_hybrid_type.result b/mysql-test/r/func_hybrid_type.result index dfc552cc58c..a8fd8a2d38a 100644 --- a/mysql-test/r/func_hybrid_type.result +++ b/mysql-test/r/func_hybrid_type.result @@ -1000,14 +1000,14 @@ t2 CREATE TABLE `t2` ( `least____a_a` int(11) DEFAULT NULL, `greatest_a_a` int(11) DEFAULT NULL, `___________b` bit(8) DEFAULT NULL, - `case_______b` int(8) unsigned DEFAULT NULL, - `case_____b_b` int(8) unsigned DEFAULT NULL, - `coalesce___b` int(8) unsigned DEFAULT NULL, - `coalesce_b_b` int(8) unsigned DEFAULT NULL, - `if_______b_b` int(8) unsigned DEFAULT NULL, + `case_______b` bit(8) DEFAULT NULL, + `case_____b_b` bit(8) DEFAULT NULL, + `coalesce___b` bit(8) DEFAULT NULL, + `coalesce_b_b` bit(8) DEFAULT NULL, + `if_______b_b` bit(8) DEFAULT NULL, `ifnull___b_b` bit(8) DEFAULT NULL, - `least____b_b` int(8) unsigned DEFAULT NULL, - `greatest_b_b` int(8) unsigned DEFAULT NULL + `least____b_b` bit(8) DEFAULT NULL, + `greatest_b_b` bit(8) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR @@ -1119,18 +1119,18 @@ GREATEST(a, b) AS greatest_a_b, GREATEST(b, a) AS greatest_b_a FROM t1; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def case_____a_b 8 10 10 Y 32928 0 63 -def case_____b_a 8 10 2 Y 32928 0 63 -def coalesce_a_b 8 10 10 Y 32928 0 63 -def coalesce_b_a 8 10 2 Y 32928 0 63 -def if_______a_b 8 10 2 Y 32928 0 63 -def if_______b_a 8 10 10 Y 32928 0 63 -def ifnull___a_b 8 10 10 Y 32928 0 63 -def ifnull___b_a 8 10 2 Y 32928 0 63 -def least____a_b 8 10 2 Y 32928 0 63 -def least____b_a 8 10 2 Y 32928 0 63 -def greatest_a_b 8 10 10 Y 32928 0 63 -def greatest_b_a 8 10 10 Y 32928 0 63 +def case_____a_b 3 10 10 Y 32928 0 63 +def case_____b_a 3 10 2 Y 32928 0 63 +def coalesce_a_b 3 10 10 Y 32928 0 63 +def coalesce_b_a 3 10 2 Y 32928 0 63 +def if_______a_b 3 10 2 Y 32928 0 63 +def if_______b_a 3 10 10 Y 32928 0 63 +def ifnull___a_b 3 10 10 Y 32928 0 63 +def ifnull___b_a 3 10 2 Y 32928 0 63 +def least____a_b 3 10 2 Y 32928 0 63 +def least____b_a 3 10 2 Y 32928 0 63 +def greatest_a_b 3 10 10 Y 32928 0 63 +def greatest_b_a 3 10 10 Y 32928 0 63 case_____a_b 4294967295 case_____b_a 50 coalesce_a_b 4294967295 @@ -1177,14 +1177,14 @@ t2 CREATE TABLE `t2` ( `least____a_a` int(10) unsigned DEFAULT NULL, `greatest_a_a` int(10) unsigned DEFAULT NULL, `___________b` bit(8) DEFAULT NULL, - `case_______b` int(8) unsigned DEFAULT NULL, - `case_____b_b` int(8) unsigned DEFAULT NULL, - `coalesce___b` int(8) unsigned DEFAULT NULL, - `coalesce_b_b` int(8) unsigned DEFAULT NULL, - `if_______b_b` int(8) unsigned DEFAULT NULL, + `case_______b` bit(8) DEFAULT NULL, + `case_____b_b` bit(8) DEFAULT NULL, + `coalesce___b` bit(8) DEFAULT NULL, + `coalesce_b_b` bit(8) DEFAULT NULL, + `if_______b_b` bit(8) DEFAULT NULL, `ifnull___b_b` bit(8) DEFAULT NULL, - `least____b_b` int(8) unsigned DEFAULT NULL, - `greatest_b_b` int(8) unsigned DEFAULT NULL + `least____b_b` bit(8) DEFAULT NULL, + `greatest_b_b` bit(8) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR @@ -1212,8 +1212,8 @@ t2 CREATE TABLE `t2` ( `coalesce_b_a` int(10) unsigned DEFAULT NULL, `if_______a_b` int(10) unsigned DEFAULT NULL, `if_______b_a` int(10) unsigned DEFAULT NULL, - `ifnull___a_b` bigint(10) unsigned DEFAULT NULL, - `ifnull___b_a` bigint(10) unsigned DEFAULT NULL, + `ifnull___a_b` int(10) unsigned DEFAULT NULL, + `ifnull___b_a` int(10) unsigned DEFAULT NULL, `least____a_b` int(10) unsigned DEFAULT NULL, `least____b_a` int(10) unsigned DEFAULT NULL, `greatest_a_b` int(10) unsigned DEFAULT NULL, @@ -1345,23 +1345,23 @@ SHOW CREATE TABLE t2; Table Create Table t2 CREATE TABLE `t2` ( `___________a` bit(7) DEFAULT NULL, - `case_______a` int(7) unsigned DEFAULT NULL, - `case_____a_a` int(7) unsigned DEFAULT NULL, - `coalesce___a` int(7) unsigned DEFAULT NULL, - `coalesce_a_a` int(7) unsigned DEFAULT NULL, - `if_______a_a` int(7) unsigned DEFAULT NULL, + `case_______a` bit(7) DEFAULT NULL, + `case_____a_a` bit(7) DEFAULT NULL, + `coalesce___a` bit(7) DEFAULT NULL, + `coalesce_a_a` bit(7) DEFAULT NULL, + `if_______a_a` bit(7) DEFAULT NULL, `ifnull___a_a` bit(7) DEFAULT NULL, - `least____a_a` int(7) unsigned DEFAULT NULL, - `greatest_a_a` int(7) unsigned DEFAULT NULL, + `least____a_a` bit(7) DEFAULT NULL, + `greatest_a_a` bit(7) DEFAULT NULL, `___________b` bit(8) DEFAULT NULL, - `case_______b` int(8) unsigned DEFAULT NULL, - `case_____b_b` int(8) unsigned DEFAULT NULL, - `coalesce___b` int(8) unsigned DEFAULT NULL, - `coalesce_b_b` int(8) unsigned DEFAULT NULL, - `if_______b_b` int(8) unsigned DEFAULT NULL, + `case_______b` bit(8) DEFAULT NULL, + `case_____b_b` bit(8) DEFAULT NULL, + `coalesce___b` bit(8) DEFAULT NULL, + `coalesce_b_b` bit(8) DEFAULT NULL, + `if_______b_b` bit(8) DEFAULT NULL, `ifnull___b_b` bit(8) DEFAULT NULL, - `least____b_b` int(8) unsigned DEFAULT NULL, - `greatest_b_b` int(8) unsigned DEFAULT NULL + `least____b_b` bit(8) DEFAULT NULL, + `greatest_b_b` bit(8) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR @@ -1383,18 +1383,18 @@ FROM t1; SHOW CREATE TABLE t2; Table Create Table t2 CREATE TABLE `t2` ( - `case_____a_b` int(8) unsigned DEFAULT NULL, - `case_____b_a` int(8) unsigned DEFAULT NULL, - `coalesce_a_b` int(8) unsigned DEFAULT NULL, - `coalesce_b_a` int(8) unsigned DEFAULT NULL, - `if_______a_b` int(8) unsigned DEFAULT NULL, - `if_______b_a` int(8) unsigned DEFAULT NULL, + `case_____a_b` bit(8) DEFAULT NULL, + `case_____b_a` bit(8) DEFAULT NULL, + `coalesce_a_b` bit(8) DEFAULT NULL, + `coalesce_b_a` bit(8) DEFAULT NULL, + `if_______a_b` bit(8) DEFAULT NULL, + `if_______b_a` bit(8) DEFAULT NULL, `ifnull___a_b` bit(8) DEFAULT NULL, `ifnull___b_a` bit(8) DEFAULT NULL, - `least____a_b` int(8) unsigned DEFAULT NULL, - `least____b_a` int(8) unsigned DEFAULT NULL, - `greatest_a_b` int(8) unsigned DEFAULT NULL, - `greatest_b_a` int(8) unsigned DEFAULT NULL + `least____a_b` bit(8) DEFAULT NULL, + `least____b_a` bit(8) DEFAULT NULL, + `greatest_a_b` bit(8) DEFAULT NULL, + `greatest_b_a` bit(8) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; DROP TABLE t1; @@ -1429,8 +1429,8 @@ def coalesce___a 4 12 1 Y 32896 31 63 def coalesce_a_a 4 12 1 Y 32896 31 63 def if_______a_a 4 12 1 Y 32896 31 63 def ifnull___a_a 4 12 1 Y 32896 31 63 -def least____a_a 5 23 1 Y 32896 31 63 -def greatest_a_a 5 23 1 Y 32896 31 63 +def least____a_a 4 23 1 Y 32896 31 63 +def greatest_a_a 4 23 1 Y 32896 31 63 def test t1 t1 b ___________b 2 6 6 Y 32768 0 63 def case_______b 2 6 6 Y 32896 0 63 def case_____b_b 2 6 6 Y 32896 0 63 @@ -1522,23 +1522,23 @@ SHOW CREATE TABLE t2; Table Create Table t2 CREATE TABLE `t2` ( `___________a` float DEFAULT NULL, - `case_______a` double DEFAULT NULL, - `case_____a_a` double DEFAULT NULL, - `coalesce___a` double DEFAULT NULL, - `coalesce_a_a` double DEFAULT NULL, - `if_______a_a` double DEFAULT NULL, + `case_______a` float DEFAULT NULL, + `case_____a_a` float DEFAULT NULL, + `coalesce___a` float DEFAULT NULL, + `coalesce_a_a` float DEFAULT NULL, + `if_______a_a` float DEFAULT NULL, `ifnull___a_a` float DEFAULT NULL, - `least____a_a` double DEFAULT NULL, - `greatest_a_a` double DEFAULT NULL, + `least____a_a` float DEFAULT NULL, + `greatest_a_a` float DEFAULT NULL, `___________b` smallint(6) DEFAULT NULL, - `case_______b` int(6) DEFAULT NULL, - `case_____b_b` int(6) DEFAULT NULL, - `coalesce___b` int(6) DEFAULT NULL, - `coalesce_b_b` int(6) DEFAULT NULL, - `if_______b_b` int(6) DEFAULT NULL, + `case_______b` smallint(6) DEFAULT NULL, + `case_____b_b` smallint(6) DEFAULT NULL, + `coalesce___b` smallint(6) DEFAULT NULL, + `coalesce_b_b` smallint(6) DEFAULT NULL, + `if_______b_b` smallint(6) DEFAULT NULL, `ifnull___b_b` smallint(6) DEFAULT NULL, - `least____b_b` int(6) DEFAULT NULL, - `greatest_b_b` int(6) DEFAULT NULL + `least____b_b` smallint(6) DEFAULT NULL, + `greatest_b_b` smallint(6) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR @@ -1560,12 +1560,12 @@ FROM t1; SHOW CREATE TABLE t2; Table Create Table t2 CREATE TABLE `t2` ( - `case_____a_b` double DEFAULT NULL, - `case_____b_a` double DEFAULT NULL, - `coalesce_a_b` double DEFAULT NULL, - `coalesce_b_a` double DEFAULT NULL, - `if_______a_b` double DEFAULT NULL, - `if_______b_a` double DEFAULT NULL, + `case_____a_b` float DEFAULT NULL, + `case_____b_a` float DEFAULT NULL, + `coalesce_a_b` float DEFAULT NULL, + `coalesce_b_a` float DEFAULT NULL, + `if_______a_b` float DEFAULT NULL, + `if_______b_a` float DEFAULT NULL, `ifnull___a_b` float DEFAULT NULL, `ifnull___b_a` float DEFAULT NULL, `least____a_b` double DEFAULT NULL, @@ -1885,14 +1885,14 @@ t2 CREATE TABLE `t2` ( `least____a_a` int(11) DEFAULT NULL, `greatest_a_a` int(11) DEFAULT NULL, `___________b` year(4) DEFAULT NULL, - `case_______b` int(4) unsigned DEFAULT NULL, - `case_____b_b` int(4) unsigned DEFAULT NULL, - `coalesce___b` int(4) unsigned DEFAULT NULL, - `coalesce_b_b` int(4) unsigned DEFAULT NULL, - `if_______b_b` int(4) unsigned DEFAULT NULL, + `case_______b` year(4) DEFAULT NULL, + `case_____b_b` year(4) DEFAULT NULL, + `coalesce___b` year(4) DEFAULT NULL, + `coalesce_b_b` year(4) DEFAULT NULL, + `if_______b_b` year(4) DEFAULT NULL, `ifnull___b_b` year(4) DEFAULT NULL, - `least____b_b` int(4) unsigned DEFAULT NULL, - `greatest_b_b` int(4) unsigned DEFAULT NULL + `least____b_b` year(4) DEFAULT NULL, + `greatest_b_b` year(4) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR @@ -2062,14 +2062,14 @@ t2 CREATE TABLE `t2` ( `least____a_a` int(10) unsigned DEFAULT NULL, `greatest_a_a` int(10) unsigned DEFAULT NULL, `___________b` year(4) DEFAULT NULL, - `case_______b` int(4) unsigned DEFAULT NULL, - `case_____b_b` int(4) unsigned DEFAULT NULL, - `coalesce___b` int(4) unsigned DEFAULT NULL, - `coalesce_b_b` int(4) unsigned DEFAULT NULL, - `if_______b_b` int(4) unsigned DEFAULT NULL, + `case_______b` year(4) DEFAULT NULL, + `case_____b_b` year(4) DEFAULT NULL, + `coalesce___b` year(4) DEFAULT NULL, + `coalesce_b_b` year(4) DEFAULT NULL, + `if_______b_b` year(4) DEFAULT NULL, `ifnull___b_b` year(4) DEFAULT NULL, - `least____b_b` int(4) unsigned DEFAULT NULL, - `greatest_b_b` int(4) unsigned DEFAULT NULL + `least____b_b` year(4) DEFAULT NULL, + `greatest_b_b` year(4) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR @@ -3512,5 +3512,40 @@ t2 CREATE TABLE `t2` ( DROP TABLE t2; DROP TABLE t1; # +# MDEV-12617 CASE and CASE-alike hybrid functions do not preserve exact data types +# +CREATE TABLE t1 (a FLOAT(10,2)); +CREATE TABLE t2 AS SELECT COALESCE(a) FROM t1; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `COALESCE(a)` float(10,2) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t2, t1; +CREATE TABLE t1 (a FLOAT(10,2)); +CREATE TABLE t2 AS SELECT LEAST(a,a) FROM t1; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `LEAST(a,a)` float(19,2) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t2, t1; +CREATE TABLE t1 (a TINYINT(1)); +CREATE TABLE t2 AS SELECT COALESCE(a) FROM t1; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `COALESCE(a)` tinyint(4) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t2, t1; +CREATE TABLE t1 (a TINYINT(1)); +CREATE TABLE t2 AS SELECT LEAST(a,a) FROM t1; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `LEAST(a,a)` tinyint(4) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t2, t1; +# # End of 10.3 tests # diff --git a/mysql-test/r/null.result b/mysql-test/r/null.result index 8bbdfb2f90b..2fa89a2d001 100644 --- a/mysql-test/r/null.result +++ b/mysql-test/r/null.result @@ -613,22 +613,22 @@ FROM t1; SHOW CREATE TABLE t2; Table Create Table t2 CREATE TABLE `t2` ( - `NULLIF(c_tinyint, 1)` int(4) DEFAULT NULL, - `NULLIF(c_tinyint, c_smallint)` int(4) DEFAULT NULL, - `NULLIF(c_tinyint, c_tinyint)` int(4) DEFAULT NULL, - `NULLIF(c_tinyint, c_int)` int(4) DEFAULT NULL, - `NULLIF(c_tinyint, c_bigint)` int(4) DEFAULT NULL, - `NULLIF(c_tinyint, c_float)` int(4) DEFAULT NULL, - `NULLIF(c_tinyint, c_double)` int(4) DEFAULT NULL, - `NULLIF(c_tinyint, c_decimal103)` int(4) DEFAULT NULL, - `NULLIF(c_tinyint, c_varchar10)` int(4) DEFAULT NULL, - `NULLIF(c_tinyint, c_text)` int(4) DEFAULT NULL, - `NULLIF(c_tinyint, c_blob)` int(4) DEFAULT NULL, - `NULLIF(c_tinyint, c_enum)` int(4) DEFAULT NULL, - `NULLIF(c_tinyint, c_datetime3)` int(4) DEFAULT NULL, - `NULLIF(c_tinyint, c_timestamp3)` int(4) DEFAULT NULL, - `NULLIF(c_tinyint, c_date)` int(4) DEFAULT NULL, - `NULLIF(c_tinyint, c_time)` int(4) DEFAULT NULL + `NULLIF(c_tinyint, 1)` tinyint(4) DEFAULT NULL, + `NULLIF(c_tinyint, c_smallint)` tinyint(4) DEFAULT NULL, + `NULLIF(c_tinyint, c_tinyint)` tinyint(4) DEFAULT NULL, + `NULLIF(c_tinyint, c_int)` tinyint(4) DEFAULT NULL, + `NULLIF(c_tinyint, c_bigint)` tinyint(4) DEFAULT NULL, + `NULLIF(c_tinyint, c_float)` tinyint(4) DEFAULT NULL, + `NULLIF(c_tinyint, c_double)` tinyint(4) DEFAULT NULL, + `NULLIF(c_tinyint, c_decimal103)` tinyint(4) DEFAULT NULL, + `NULLIF(c_tinyint, c_varchar10)` tinyint(4) DEFAULT NULL, + `NULLIF(c_tinyint, c_text)` tinyint(4) DEFAULT NULL, + `NULLIF(c_tinyint, c_blob)` tinyint(4) DEFAULT NULL, + `NULLIF(c_tinyint, c_enum)` tinyint(4) DEFAULT NULL, + `NULLIF(c_tinyint, c_datetime3)` tinyint(4) DEFAULT NULL, + `NULLIF(c_tinyint, c_timestamp3)` tinyint(4) DEFAULT NULL, + `NULLIF(c_tinyint, c_date)` tinyint(4) DEFAULT NULL, + `NULLIF(c_tinyint, c_time)` tinyint(4) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; CREATE TABLE t2 AS SELECT @@ -652,22 +652,22 @@ FROM t1; SHOW CREATE TABLE t2; Table Create Table t2 CREATE TABLE `t2` ( - `NULLIF(c_smallint, 1)` int(6) DEFAULT NULL, - `NULLIF(c_smallint, c_smallint)` int(6) DEFAULT NULL, - `NULLIF(c_smallint, c_tinyint)` int(6) DEFAULT NULL, - `NULLIF(c_smallint, c_int)` int(6) DEFAULT NULL, - `NULLIF(c_smallint, c_bigint)` int(6) DEFAULT NULL, - `NULLIF(c_smallint, c_float)` int(6) DEFAULT NULL, - `NULLIF(c_smallint, c_double)` int(6) DEFAULT NULL, - `NULLIF(c_smallint, c_decimal103)` int(6) DEFAULT NULL, - `NULLIF(c_smallint, c_varchar10)` int(6) DEFAULT NULL, - `NULLIF(c_smallint, c_text)` int(6) DEFAULT NULL, - `NULLIF(c_smallint, c_blob)` int(6) DEFAULT NULL, - `NULLIF(c_smallint, c_enum)` int(6) DEFAULT NULL, - `NULLIF(c_smallint, c_datetime3)` int(6) DEFAULT NULL, - `NULLIF(c_smallint, c_timestamp3)` int(6) DEFAULT NULL, - `NULLIF(c_smallint, c_date)` int(6) DEFAULT NULL, - `NULLIF(c_smallint, c_time)` int(6) DEFAULT NULL + `NULLIF(c_smallint, 1)` smallint(6) DEFAULT NULL, + `NULLIF(c_smallint, c_smallint)` smallint(6) DEFAULT NULL, + `NULLIF(c_smallint, c_tinyint)` smallint(6) DEFAULT NULL, + `NULLIF(c_smallint, c_int)` smallint(6) DEFAULT NULL, + `NULLIF(c_smallint, c_bigint)` smallint(6) DEFAULT NULL, + `NULLIF(c_smallint, c_float)` smallint(6) DEFAULT NULL, + `NULLIF(c_smallint, c_double)` smallint(6) DEFAULT NULL, + `NULLIF(c_smallint, c_decimal103)` smallint(6) DEFAULT NULL, + `NULLIF(c_smallint, c_varchar10)` smallint(6) DEFAULT NULL, + `NULLIF(c_smallint, c_text)` smallint(6) DEFAULT NULL, + `NULLIF(c_smallint, c_blob)` smallint(6) DEFAULT NULL, + `NULLIF(c_smallint, c_enum)` smallint(6) DEFAULT NULL, + `NULLIF(c_smallint, c_datetime3)` smallint(6) DEFAULT NULL, + `NULLIF(c_smallint, c_timestamp3)` smallint(6) DEFAULT NULL, + `NULLIF(c_smallint, c_date)` smallint(6) DEFAULT NULL, + `NULLIF(c_smallint, c_time)` smallint(6) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; CREATE TABLE t2 AS SELECT @@ -769,22 +769,22 @@ FROM t1; SHOW CREATE TABLE t2; Table Create Table t2 CREATE TABLE `t2` ( - `NULLIF(c_float, 1)` double DEFAULT NULL, - `NULLIF(c_float, c_smallint)` double DEFAULT NULL, - `NULLIF(c_float, c_tinyint)` double DEFAULT NULL, - `NULLIF(c_float, c_int)` double DEFAULT NULL, - `NULLIF(c_float, c_bigint)` double DEFAULT NULL, - `NULLIF(c_float, c_float)` double DEFAULT NULL, - `NULLIF(c_float, c_double)` double DEFAULT NULL, - `NULLIF(c_float, c_decimal103)` double DEFAULT NULL, - `NULLIF(c_float, c_varchar10)` double DEFAULT NULL, - `NULLIF(c_float, c_text)` double DEFAULT NULL, - `NULLIF(c_float, c_blob)` double DEFAULT NULL, - `NULLIF(c_float, c_enum)` double DEFAULT NULL, - `NULLIF(c_float, c_datetime3)` double DEFAULT NULL, - `NULLIF(c_float, c_timestamp3)` double DEFAULT NULL, - `NULLIF(c_float, c_date)` double DEFAULT NULL, - `NULLIF(c_float, c_time)` double DEFAULT NULL + `NULLIF(c_float, 1)` float DEFAULT NULL, + `NULLIF(c_float, c_smallint)` float DEFAULT NULL, + `NULLIF(c_float, c_tinyint)` float DEFAULT NULL, + `NULLIF(c_float, c_int)` float DEFAULT NULL, + `NULLIF(c_float, c_bigint)` float DEFAULT NULL, + `NULLIF(c_float, c_float)` float DEFAULT NULL, + `NULLIF(c_float, c_double)` float DEFAULT NULL, + `NULLIF(c_float, c_decimal103)` float DEFAULT NULL, + `NULLIF(c_float, c_varchar10)` float DEFAULT NULL, + `NULLIF(c_float, c_text)` float DEFAULT NULL, + `NULLIF(c_float, c_blob)` float DEFAULT NULL, + `NULLIF(c_float, c_enum)` float DEFAULT NULL, + `NULLIF(c_float, c_datetime3)` float DEFAULT NULL, + `NULLIF(c_float, c_timestamp3)` float DEFAULT NULL, + `NULLIF(c_float, c_date)` float DEFAULT NULL, + `NULLIF(c_float, c_time)` float DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; CREATE TABLE t2 AS SELECT diff --git a/mysql-test/t/func_hybrid_type.test b/mysql-test/t/func_hybrid_type.test index 918320a68c5..0957dfd33ec 100644 --- a/mysql-test/t/func_hybrid_type.test +++ b/mysql-test/t/func_hybrid_type.test @@ -510,6 +510,29 @@ SHOW CREATE TABLE t2; DROP TABLE t2; DROP TABLE t1; +--echo # +--echo # MDEV-12617 CASE and CASE-alike hybrid functions do not preserve exact data types +--echo # + +CREATE TABLE t1 (a FLOAT(10,2)); +CREATE TABLE t2 AS SELECT COALESCE(a) FROM t1; +SHOW CREATE TABLE t2; +DROP TABLE t2, t1; + +CREATE TABLE t1 (a FLOAT(10,2)); +CREATE TABLE t2 AS SELECT LEAST(a,a) FROM t1; +SHOW CREATE TABLE t2; +DROP TABLE t2, t1; + +CREATE TABLE t1 (a TINYINT(1)); +CREATE TABLE t2 AS SELECT COALESCE(a) FROM t1; +SHOW CREATE TABLE t2; +DROP TABLE t2, t1; + +CREATE TABLE t1 (a TINYINT(1)); +CREATE TABLE t2 AS SELECT LEAST(a,a) FROM t1; +SHOW CREATE TABLE t2; +DROP TABLE t2, t1; --echo # --echo # End of 10.3 tests diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 6712b98dbc3..62ebc100d90 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2786,7 +2786,7 @@ Item_func_nullif::is_null() Item_func_case::Item_func_case(THD *thd, List &list, Item *first_expr_arg, Item *else_expr_arg): - Item_func_hybrid_field_type(thd), + Item_func_case_expression(thd), Predicant_to_list_comparator(thd, list.elements/*QQ*/), first_expr_num(-1), else_expr_num(-1), left_cmp_type(INT_RESULT), m_found_types(0) diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 6a6adb28ebd..e9d4426d919 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -965,13 +965,13 @@ public: }; -class Item_func_coalesce :public Item_func_hybrid_field_type +class Item_func_coalesce :public Item_func_case_expression { public: Item_func_coalesce(THD *thd, Item *a, Item *b): - Item_func_hybrid_field_type(thd, a, b) {} + Item_func_case_expression(thd, a, b) {} Item_func_coalesce(THD *thd, List &list): - Item_func_hybrid_field_type(thd, list) {} + Item_func_case_expression(thd, list) {} double real_op(); longlong int_op(); String *str_op(String *); @@ -995,7 +995,7 @@ public: IF(switch, arg1, arg2) NVL2(switch, arg1, arg2) */ -class Item_func_case_abbreviation2 :public Item_func_hybrid_field_type +class Item_func_case_abbreviation2 :public Item_func_case_expression { protected: void fix_length_and_dec2(Item **items) @@ -1034,9 +1034,9 @@ protected: public: Item_func_case_abbreviation2(THD *thd, Item *a, Item *b): - Item_func_hybrid_field_type(thd, a, b) { } + Item_func_case_expression(thd, a, b) { } Item_func_case_abbreviation2(THD *thd, Item *a, Item *b, Item *c): - Item_func_hybrid_field_type(thd, a, b, c) { } + Item_func_case_expression(thd, a, b, c) { } }; @@ -1056,8 +1056,6 @@ public: maybe_null= args[1]->maybe_null; } const char *func_name() const { return "ifnull"; } - Field *create_field_for_create_select(TABLE *table) - { return tmp_table_field_from_field_type(table); } table_map not_null_tables() const { return 0; } uint decimal_precision() const @@ -1161,7 +1159,7 @@ public: }; -class Item_func_nullif :public Item_func_hybrid_field_type +class Item_func_nullif :public Item_func_case_expression { Arg_comparator cmp; /* @@ -1199,7 +1197,7 @@ public: See also Item_func_nullif::fix_length_and_dec(). */ Item_func_nullif(THD *thd, Item *a, Item *b): - Item_func_hybrid_field_type(thd, a, b, a), + Item_func_case_expression(thd, a, b, a), m_cache(NULL), m_arg0(NULL) { arg_count--; } @@ -2031,7 +2029,7 @@ public: function and only comparators for there result types are used. */ -class Item_func_case :public Item_func_hybrid_field_type, +class Item_func_case :public Item_func_case_expression, public Predicant_to_list_comparator { int first_expr_num, else_expr_num; diff --git a/sql/item_func.h b/sql/item_func.h index 33f671c179a..a448074ef5a 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -599,6 +599,38 @@ public: }; +/* + This class resembles SQL standard CASE-alike expressions: + CASE and its abbreviations COALESCE, NULLIF, IFNULL, IF. + + ::= + | +*/ +class Item_func_case_expression: public Item_func_hybrid_field_type +{ +public: + Item_func_case_expression(THD *thd) + :Item_func_hybrid_field_type(thd) + { } + Item_func_case_expression(THD *thd, Item *a) + :Item_func_hybrid_field_type(thd, a) + { } + Item_func_case_expression(THD *thd, Item *a, Item *b) + :Item_func_hybrid_field_type(thd, a, b) + { } + Item_func_case_expression(THD *thd, Item *a, Item *b, Item *c) + :Item_func_hybrid_field_type(thd, a, b, c) + { } + Item_func_case_expression(THD *thd, List &list): + Item_func_hybrid_field_type(thd, list) + { } + Field *create_tmp_field(bool group, TABLE *table) + { return tmp_table_field_from_field_type(table); } + Field *create_field_for_create_select(TABLE *table) + { return tmp_table_field_from_field_type(table); } +}; + + class Item_func_numhybrid: public Item_func_hybrid_field_type { protected: @@ -1404,6 +1436,10 @@ public: Item_func_min_max(THD *thd, List &list, int cmp_sign_arg): Item_hybrid_func(thd, list), cmp_sign(cmp_sign_arg) {} + Field *create_tmp_field(bool group, TABLE *table) + { return tmp_table_field_from_field_type(table); } + Field *create_field_for_create_select(TABLE *table) + { return tmp_table_field_from_field_type(table); } String *val_str_native(String *str); double val_real_native(); longlong val_int_native(); diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 23cfe20e5e6..0b311a34d94 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -513,6 +513,21 @@ Type_handler_hybrid_field_type::aggregate_for_result(const Type_handler *other) } +/* + This method is called for CASE (and its abbreviations) and LEAST/GREATEST + when data type aggregation returned LONGLONG and there were some BIT + expressions. This helps to adjust the data type from LONGLONG to LONG + if all expressions fit. +*/ +const Type_handler * +Type_handler::bit_and_int_mixture_handler(uint max_char_length) +{ + if (max_char_length <= MY_INT32_NUM_DECIMAL_DIGITS) + return &type_handler_long; + return &type_handler_longlong; +} + + /** @brief Aggregates field types from the array of items. @@ -552,6 +567,8 @@ Type_handler_hybrid_field_type::aggregate_for_result(const char *funcname, Item **items, uint nitems, bool treat_bit_as_number) { + bool bit_and_non_bit_mixture_found= false; + uint32 max_display_length; if (!nitems || items[0]->result_type() == ROW_RESULT) { DBUG_ASSERT(0); @@ -559,12 +576,15 @@ Type_handler_hybrid_field_type::aggregate_for_result(const char *funcname, return true; } set_handler(items[0]->type_handler()); + max_display_length= items[0]->max_display_length(); for (uint i= 1 ; i < nitems ; i++) { const Type_handler *cur= items[i]->type_handler(); + set_if_bigger(max_display_length, items[i]->max_display_length()); if (treat_bit_as_number && ((type_handler() == &type_handler_bit) ^ (cur == &type_handler_bit))) { + bit_and_non_bit_mixture_found= true; if (type_handler() == &type_handler_bit) set_handler(&type_handler_longlong); // BIT + non-BIT else @@ -577,6 +597,8 @@ Type_handler_hybrid_field_type::aggregate_for_result(const char *funcname, return true; } } + if (bit_and_non_bit_mixture_found && type_handler() == &type_handler_longlong) + set_handler(Type_handler::bit_and_int_mixture_handler(max_display_length)); return false; } @@ -728,7 +750,9 @@ Type_handler_hybrid_field_type::aggregate_for_min_max(const Type_handler *h) } else { - m_type_handler= &type_handler_double; + // Preserve FLOAT if two FLOATs, set to DOUBLE otherwise. + if (m_type_handler != &type_handler_float || h != &type_handler_float) + m_type_handler= &type_handler_double; } return false; } @@ -738,12 +762,19 @@ bool Type_handler_hybrid_field_type::aggregate_for_min_max(const char *funcname, Item **items, uint nitems) { + bool bit_and_non_bit_mixture_found= false; + uint32 max_display_length; // LEAST/GREATEST require at least two arguments DBUG_ASSERT(nitems > 1); set_handler(items[0]->type_handler()); + max_display_length= items[0]->max_display_length(); for (uint i= 1; i < nitems; i++) { const Type_handler *cur= items[i]->type_handler(); + set_if_bigger(max_display_length, items[i]->max_display_length()); + // Check if BIT + non-BIT, or non-BIT + BIT + bit_and_non_bit_mixture_found|= (m_type_handler == &type_handler_bit) != + (cur == &type_handler_bit); if (aggregate_for_min_max(cur)) { my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0), @@ -751,6 +782,8 @@ Type_handler_hybrid_field_type::aggregate_for_min_max(const char *funcname, return true; } } + if (bit_and_non_bit_mixture_found && type_handler() == &type_handler_longlong) + set_handler(Type_handler::bit_and_int_mixture_handler(max_display_length)); return false; } diff --git a/sql/sql_type.h b/sql/sql_type.h index 67a302e1f8d..90bcb9bcc82 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -535,6 +535,7 @@ protected: public: static const Type_handler *blob_type_handler(uint max_octet_length); static const Type_handler *string_type_handler(uint max_octet_length); + static const Type_handler *bit_and_int_mixture_handler(uint max_char_len); /** Return a string type handler for Item If too_big_for_varchar() returns a BLOB variant, according to length.