summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2020-06-13 09:30:04 +0400
committerAlexander Barkov <bar@mariadb.com>2020-06-13 09:30:04 +0400
commit6c30bc2181328ea619d1ab61a464feb0514bf12a (patch)
treec5a1bc61de369ed5e5df9fb441fb2aa7ea2e5292
parent81a08c5462154e169d0a35e52c023d066065b175 (diff)
downloadmariadb-git-6c30bc2181328ea619d1ab61a464feb0514bf12a.tar.gz
MDEV-22268 virtual longlong Item_func_div::int_op(): Assertion `0' failed in Item_func_div::int_op
Item_func_div::fix_length_and_dec_temporal() set the return data type to integer in case of @div_precision_increment==0 for temporal input with FSP=0. This caused Item_func_div to call int_op(), which is not implemented, so a crash on DBUG_ASSERT(0) happened. Fixing fix_length_and_dec_temporal() to set the result type to DECIMAL.
-rw-r--r--mysql-test/main/func_math.result30
-rw-r--r--mysql-test/main/func_math.test23
-rw-r--r--sql/item_func.h4
-rw-r--r--sql/sql_type.cc11
4 files changed, 61 insertions, 7 deletions
diff --git a/mysql-test/main/func_math.result b/mysql-test/main/func_math.result
index 2cb012c84aa..bf8e25b4ee1 100644
--- a/mysql-test/main/func_math.result
+++ b/mysql-test/main/func_math.result
@@ -2251,5 +2251,35 @@ SELECT ROUND( i, 18446744073709551594 ) AS f FROM t1;
f
DROP TABLE t1;
#
+# MDEV-22268 virtual longlong Item_func_div::int_op(): Assertion `0' failed in Item_func_div::int_op
+#
+SET sql_mode='';
+SET @@SESSION.div_precision_increment=0;
+SELECT UTC_TIME / 0;
+UTC_TIME / 0
+NULL
+SELECT TIMESTAMP'2001-01-01 00:00:00'/0;
+TIMESTAMP'2001-01-01 00:00:00'/0
+NULL
+SELECT TIME'00:00:00'/0;
+TIME'00:00:00'/0
+NULL
+CREATE TABLE t1 AS SELECT
+UTC_TIME / 0 AS c1,
+TIMESTAMP'2001-01-01 00:00:00'/0 AS c3,
+TIME'00:00:00'/0 AS c4;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` decimal(7,0) DEFAULT NULL,
+ `c3` decimal(14,0) DEFAULT NULL,
+ `c4` decimal(7,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+SELECT(-0 * MOD((UTC_TIME / -0)MOD (ATAN('<img src_x0=x onerror="javascript:alert(0)">') MOD COT(0)),-0)) MOD (0 DIV 0);
+ERROR 22003: DOUBLE value is out of range in 'cot(0)'
+SET @@SESSION.div_precision_increment=DEFAULT;
+SET sql_mode=DEFAULT;
+#
# End of 10.3 tests
#
diff --git a/mysql-test/main/func_math.test b/mysql-test/main/func_math.test
index 7bd0b0e5a4f..f169ae0c326 100644
--- a/mysql-test/main/func_math.test
+++ b/mysql-test/main/func_math.test
@@ -1111,6 +1111,29 @@ CREATE TABLE t1 (i INT(23));
SELECT ROUND( i, 18446744073709551594 ) AS f FROM t1;
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-22268 virtual longlong Item_func_div::int_op(): Assertion `0' failed in Item_func_div::int_op
+--echo #
+
+SET sql_mode='';
+SET @@SESSION.div_precision_increment=0;
+SELECT UTC_TIME / 0;
+SELECT TIMESTAMP'2001-01-01 00:00:00'/0;
+SELECT TIME'00:00:00'/0;
+CREATE TABLE t1 AS SELECT
+ UTC_TIME / 0 AS c1,
+ TIMESTAMP'2001-01-01 00:00:00'/0 AS c3,
+ TIME'00:00:00'/0 AS c4;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+--error ER_DATA_OUT_OF_RANGE
+SELECT(-0 * MOD((UTC_TIME / -0)MOD (ATAN('<img src_x0=x onerror="javascript:alert(0)">') MOD COT(0)),-0)) MOD (0 DIV 0);
+
+SET @@SESSION.div_precision_increment=DEFAULT;
+SET sql_mode=DEFAULT;
+
--echo #
--echo # End of 10.3 tests
--echo #
diff --git a/sql/item_func.h b/sql/item_func.h
index 3fc02e6e51d..754b1cd1eb2 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -754,11 +754,11 @@ class Item_num_op :public Item_func_numhybrid
decimals= 0;
set_handler(type_handler_long_or_longlong());
}
- void fix_length_and_dec_temporal()
+ void fix_length_and_dec_temporal(bool downcast_decimal_to_int)
{
set_handler(&type_handler_newdecimal);
fix_length_and_dec_decimal();
- if (decimals == 0)
+ if (decimals == 0 && downcast_decimal_to_int)
set_handler(type_handler_long_or_longlong());
}
bool need_parentheses_in_default() { return true; }
diff --git a/sql/sql_type.cc b/sql/sql_type.cc
index 114e4cac367..fae4c1d8301 100644
--- a/sql/sql_type.cc
+++ b/sql/sql_type.cc
@@ -4772,7 +4772,7 @@ bool Type_handler_decimal_result::
bool Type_handler_temporal_result::
Item_func_plus_fix_length_and_dec(Item_func_plus *item) const
{
- item->fix_length_and_dec_temporal();
+ item->fix_length_and_dec_temporal(true);
return false;
}
@@ -4821,7 +4821,7 @@ bool Type_handler_decimal_result::
bool Type_handler_temporal_result::
Item_func_minus_fix_length_and_dec(Item_func_minus *item) const
{
- item->fix_length_and_dec_temporal();
+ item->fix_length_and_dec_temporal(true);
return false;
}
@@ -4870,7 +4870,7 @@ bool Type_handler_decimal_result::
bool Type_handler_temporal_result::
Item_func_mul_fix_length_and_dec(Item_func_mul *item) const
{
- item->fix_length_and_dec_temporal();
+ item->fix_length_and_dec_temporal(true);
return false;
}
@@ -4919,7 +4919,8 @@ bool Type_handler_decimal_result::
bool Type_handler_temporal_result::
Item_func_div_fix_length_and_dec(Item_func_div *item) const
{
- item->fix_length_and_dec_temporal();
+ // Item_func_div::int_op() is not implemented. Disallow DECIMAL->INT downcast.
+ item->fix_length_and_dec_temporal(false);
return false;
}
@@ -4968,7 +4969,7 @@ bool Type_handler_decimal_result::
bool Type_handler_temporal_result::
Item_func_mod_fix_length_and_dec(Item_func_mod *item) const
{
- item->fix_length_and_dec_temporal();
+ item->fix_length_and_dec_temporal(true);
return false;
}