diff --git a/mysql-test/main/type_date.result b/mysql-test/main/type_date.result index f40a27e5f5c..1724b7ae605 100644 --- a/mysql-test/main/type_date.result +++ b/mysql-test/main/type_date.result @@ -1103,5 +1103,35 @@ t2 CREATE TABLE `t2` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2,t1; # +# MDEV-23388 Assertion `args[0]->decimals == 0' failed in Item_func_round::fix_arg_int +# +SELECT ROUND(GREATEST('1', CAST('2020-12-12' AS DATE))); +ROUND(GREATEST('1', CAST('2020-12-12' AS DATE))) +20201212 +Warnings: +Warning 1292 Truncated incorrect datetime value: '1' +SELECT GREATEST('1', CAST('2020-12-12' AS DATE)); +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def GREATEST('1', CAST('2020-12-12' AS DATE)) 10 10 10 Y 128 0 63 +GREATEST('1', CAST('2020-12-12' AS DATE)) +2020-12-12 +Warnings: +Warning 1292 Truncated incorrect datetime value: '1' +CREATE TABLE t1 (c_date DATE NOT NULL, c_int INT NOT NULL); +CREATE TABLE t2 AS SELECT +GREATEST(c_date,c_date), +GREATEST(c_date,c_int), +GREATEST(c_int,c_date) +FROM t1; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `GREATEST(c_date,c_date)` date NOT NULL, + `GREATEST(c_date,c_int)` date DEFAULT NULL, + `GREATEST(c_int,c_date)` date DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t2; +DROP TABLE t1; +# # End of 10.4 tests # diff --git a/mysql-test/main/type_date.test b/mysql-test/main/type_date.test index 33598846504..a29f78a679b 100644 --- a/mysql-test/main/type_date.test +++ b/mysql-test/main/type_date.test @@ -749,6 +749,28 @@ CREATE TABLE t2 AS SELECT FLOOR(a), CEIL(a),ROUND(a),TRUNCATE(a,0) FROM t1; SHOW CREATE TABLE t2; DROP TABLE t2,t1; +--echo # +--echo # MDEV-23388 Assertion `args[0]->decimals == 0' failed in Item_func_round::fix_arg_int +--echo # + +SELECT ROUND(GREATEST('1', CAST('2020-12-12' AS DATE))); + +--disable_ps_protocol +--enable_metadata +SELECT GREATEST('1', CAST('2020-12-12' AS DATE)); +--disable_metadata +--enable_ps_protocol + +CREATE TABLE t1 (c_date DATE NOT NULL, c_int INT NOT NULL); +CREATE TABLE t2 AS SELECT + GREATEST(c_date,c_date), + GREATEST(c_date,c_int), + GREATEST(c_int,c_date) +FROM t1; +SHOW CREATE TABLE t2; +DROP TABLE t2; +DROP TABLE t1; + --echo # --echo # End of 10.4 tests --echo # diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 0b333d44b77..eb284302613 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -4120,6 +4120,7 @@ bool Type_handler_temporal_result:: Item_func_min_max_fix_attributes(THD *thd, Item_func_min_max *func, Item **items, uint nitems) const { + DBUG_ASSERT(func->field_type() != MYSQL_TYPE_DATE); bool rc= Type_handler::Item_func_min_max_fix_attributes(thd, func, items, nitems); bool is_time= func->field_type() == MYSQL_TYPE_TIME; @@ -4174,7 +4175,6 @@ bool Type_handler_temporal_result:: DATETIME DATETIME no conversion DATETIME TIMESTAMP safe conversion DATETIME DATE safe conversion - DATE DATE no conversion TIME TIME no conversion Note, a function cannot return TIMESTAMP if it has non-TIMESTAMP @@ -4191,9 +4191,6 @@ bool Type_handler_temporal_result:: -------------------- ------------- ------- TIMESTAMP TIME Not possible DATETIME TIME depends on OLD_MODE_ZERO_DATE_TIME_CAST - DATE TIMESTAMP Not possible - DATE DATETIME Not possible - DATE TIME Not possible TIME TIMESTAMP Not possible TIME DATETIME Not possible TIME DATE Not possible @@ -4216,6 +4213,30 @@ bool Type_handler_temporal_result:: } +bool Type_handler_date_common:: + Item_func_min_max_fix_attributes(THD *thd, Item_func_min_max *func, + Item **items, uint nitems) const +{ + func->fix_attributes_date(); + if (func->maybe_null) + return false; + /* + We cannot trust the generic maybe_null value calculated during fix_fields(). + If a conversion from non-temoral types to DATE happens, + then the result can be NULL (even if all arguments are not NULL). + */ + for (uint i= 0; i < nitems; i++) + { + if (items[i]->type_handler()->cmp_type() != TIME_RESULT) + { + func->maybe_null= true; + break; + } + } + return false; +} + + bool Type_handler_real_result:: Item_func_min_max_fix_attributes(THD *thd, Item_func_min_max *func, Item **items, uint nitems) const diff --git a/sql/sql_type.h b/sql/sql_type.h index badd8d2f7f5..30618df82ab 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -5508,6 +5508,8 @@ public: Type_handler_hybrid_field_type *, Type_all_attributes *atrr, Item **items, uint nitems) const; + bool Item_func_min_max_fix_attributes(THD *thd, Item_func_min_max *func, + Item **items, uint nitems) const; void Item_param_set_param_func(Item_param *param, uchar **pos, ulong len) const; };