maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #09365
Please review MDEV-9653 Assertion `length || !scale' failed in uint my_decimal_length_to_precision(uint, uint, bool)
Hello Sergei,
Please review a patch for:
MDEV-9653 Assertion `length || !scale' failed in uint
my_decimal_length_to_precision(uint, uint, bool)
Thanks!
diff --git a/mysql-test/r/func_hybrid_type.result b/mysql-test/r/func_hybrid_type.result
index 95a8a82..29f9f46 100644
--- a/mysql-test/r/func_hybrid_type.result
+++ b/mysql-test/r/func_hybrid_type.result
@@ -3396,5 +3396,17 @@ c1
DROP TABLE t2;
DROP TABLE t1;
#
+# MDEV-9653 Assertion `length || !scale' failed in uint my_decimal_length_to_precision(uint, uint, bool)
+#
+SELECT CASE 0 WHEN 1 THEN (CASE 2 WHEN 3 THEN NULL END) WHEN 4 THEN 5 END;
+CASE 0 WHEN 1 THEN (CASE 2 WHEN 3 THEN NULL END) WHEN 4 THEN 5 END
+NULL
+SELECT CASE 0 WHEN 1 THEN (COALESCE(NULL)) WHEN 4 THEN 5 END;
+CASE 0 WHEN 1 THEN (COALESCE(NULL)) WHEN 4 THEN 5 END
+NULL
+SELECT CASE WHEN TRUE THEN COALESCE(NULL) ELSE 4 END;
+CASE WHEN TRUE THEN COALESCE(NULL) ELSE 4 END
+NULL
+#
# End of 10.1 tests
#
diff --git a/mysql-test/t/func_hybrid_type.test b/mysql-test/t/func_hybrid_type.test
index 047e5f7..cc5d067 100644
--- a/mysql-test/t/func_hybrid_type.test
+++ b/mysql-test/t/func_hybrid_type.test
@@ -434,5 +434,13 @@ DROP TABLE t1;
--echo #
+--echo # MDEV-9653 Assertion `length || !scale' failed in uint my_decimal_length_to_precision(uint, uint, bool)
+--echo #
+SELECT CASE 0 WHEN 1 THEN (CASE 2 WHEN 3 THEN NULL END) WHEN 4 THEN 5 END;
+SELECT CASE 0 WHEN 1 THEN (COALESCE(NULL)) WHEN 4 THEN 5 END;
+SELECT CASE WHEN TRUE THEN COALESCE(NULL) ELSE 4 END;
+
+
+--echo #
--echo # End of 10.1 tests
--echo #
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 2783a05..73a47ac 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -3086,10 +3086,28 @@ void Item_func_case::agg_str_lengths(Item* arg)
void Item_func_case::agg_num_lengths(Item *arg)
{
- uint len= my_decimal_length_to_precision(arg->max_length, arg->decimals,
- arg->unsigned_flag) - arg->decimals;
- set_if_bigger(max_length, len);
- set_if_bigger(decimals, arg->decimals);
+ /*
+ In a query like this:
+ SELECT CASE WHEN TRUE
+ THEN COALESCE(CAST(NULL AS UNSIGNED))
+ ELSE 40
+ END;
+ "arg" corresponding to Item_func_coalesce has:
+ arg->max_length==0
+ arg->decimals==31 (NOT_FIXED_DEC).
+ my_decimal_length_to_precision() does not expect this kind of input
+ and would crash on DBUG_ASSERT. See MDEV-9653.
+ So let's skip length calculation for explicit NULLs and
+ for expressions derived from explicit NULLs.
+ */
+ if (arg->field_type() != MYSQL_TYPE_NULL)
+ {
+ uint len= my_decimal_length_to_precision(arg->max_length, arg->decimals,
+ arg->unsigned_flag) -
+ arg->decimals;
+ set_if_bigger(max_length, len);
+ set_if_bigger(decimals, arg->decimals);
+ }
unsigned_flag= unsigned_flag && arg->unsigned_flag;
}
Follow ups