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; }
_______________________________________________ Mailing list: https://launchpad.net/~maria-developers Post to : maria-developers@lists.launchpad.net Unsubscribe : https://launchpad.net/~maria-developers More help : https://help.launchpad.net/ListHelp