Commit 100f0c96 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-23388 Assertion `args[0]->decimals == 0' failed in Item_func_round::fix_arg_int

Type_handler_temporal_result::Item_func_min_max_fix_attributes()
in an expression GREATEST(string,date), e.g:

  SELECT GREATEST('1', CAST('2020-12-12' AS DATE));

incorrectly evaluated decimals as 6 (like for DATETIME).

Adding a separate virtual implementation:
  Type_handler_date_common::Item_func_min_max_fix_attributes()
This makes the code simpler.
parent 6a2ee9c8
...@@ -1103,5 +1103,35 @@ t2 CREATE TABLE `t2` ( ...@@ -1103,5 +1103,35 @@ t2 CREATE TABLE `t2` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2,t1; 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 # End of 10.4 tests
# #
...@@ -749,6 +749,28 @@ CREATE TABLE t2 AS SELECT FLOOR(a), CEIL(a),ROUND(a),TRUNCATE(a,0) FROM t1; ...@@ -749,6 +749,28 @@ CREATE TABLE t2 AS SELECT FLOOR(a), CEIL(a),ROUND(a),TRUNCATE(a,0) FROM t1;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
DROP TABLE t2,t1; 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 #
--echo # End of 10.4 tests --echo # End of 10.4 tests
--echo # --echo #
...@@ -4120,6 +4120,7 @@ bool Type_handler_temporal_result:: ...@@ -4120,6 +4120,7 @@ bool Type_handler_temporal_result::
Item_func_min_max_fix_attributes(THD *thd, Item_func_min_max *func, Item_func_min_max_fix_attributes(THD *thd, Item_func_min_max *func,
Item **items, uint nitems) const 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, bool rc= Type_handler::Item_func_min_max_fix_attributes(thd, func,
items, nitems); items, nitems);
bool is_time= func->field_type() == MYSQL_TYPE_TIME; bool is_time= func->field_type() == MYSQL_TYPE_TIME;
...@@ -4174,7 +4175,6 @@ bool Type_handler_temporal_result:: ...@@ -4174,7 +4175,6 @@ bool Type_handler_temporal_result::
DATETIME DATETIME no conversion DATETIME DATETIME no conversion
DATETIME TIMESTAMP safe conversion DATETIME TIMESTAMP safe conversion
DATETIME DATE safe conversion DATETIME DATE safe conversion
DATE DATE no conversion
TIME TIME no conversion TIME TIME no conversion
Note, a function cannot return TIMESTAMP if it has non-TIMESTAMP Note, a function cannot return TIMESTAMP if it has non-TIMESTAMP
...@@ -4191,9 +4191,6 @@ bool Type_handler_temporal_result:: ...@@ -4191,9 +4191,6 @@ bool Type_handler_temporal_result::
-------------------- ------------- ------- -------------------- ------------- -------
TIMESTAMP TIME Not possible TIMESTAMP TIME Not possible
DATETIME TIME depends on OLD_MODE_ZERO_DATE_TIME_CAST 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 TIMESTAMP Not possible
TIME DATETIME Not possible TIME DATETIME Not possible
TIME DATE Not possible TIME DATE Not possible
...@@ -4216,6 +4213,30 @@ bool Type_handler_temporal_result:: ...@@ -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:: bool Type_handler_real_result::
Item_func_min_max_fix_attributes(THD *thd, Item_func_min_max *func, Item_func_min_max_fix_attributes(THD *thd, Item_func_min_max *func,
Item **items, uint nitems) const Item **items, uint nitems) const
......
...@@ -5508,6 +5508,8 @@ class Type_handler_date_common: public Type_handler_temporal_with_date ...@@ -5508,6 +5508,8 @@ class Type_handler_date_common: public Type_handler_temporal_with_date
Type_handler_hybrid_field_type *, Type_handler_hybrid_field_type *,
Type_all_attributes *atrr, Type_all_attributes *atrr,
Item **items, uint nitems) const; 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, void Item_param_set_param_func(Item_param *param,
uchar **pos, ulong len) const; uchar **pos, ulong len) const;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment