From 6650a42264d653c975ab0a9ee424d3e4ae0a63e2 Mon Sep 17 00:00:00 2001 From: PranavKTiwari Date: Fri, 15 May 2026 12:01:49 +0530 Subject: [PATCH] MDEV-35920: Fix assertion failure decimals == 0 in Item_func_mod::fix_length_and_dec_int Hex hybrid literals (0x..) were incorrectly treated as string values during hybrid expression aggregation (CASE/COALESCE/IF/LEAST/IFNULL), causing NOT_FIXED_DEC to propagate into numeric contexts. This led to an assertion failure in MOD() which requires decimals == 0 for integer arithmetic. Fix ensures hex hybrid values retain string collation behavior but enforce numeric semantics by setting decimals = 0 and unsigned_flag = true. Add regression test for MOD() with hex in hybrid expressions --- mysql-test/main/bug35920.result | 15 +++++++++++++++ mysql-test/main/bug35920.test | 11 +++++++++++ sql/sql_type.cc | 31 +++++++++++++++++++++++++++++++ sql/sql_type.h | 8 ++++++++ 4 files changed, 65 insertions(+) create mode 100644 mysql-test/main/bug35920.result create mode 100644 mysql-test/main/bug35920.test diff --git a/mysql-test/main/bug35920.result b/mysql-test/main/bug35920.result new file mode 100644 index 0000000000000..e280963cd259f --- /dev/null +++ b/mysql-test/main/bug35920.result @@ -0,0 +1,15 @@ +# +# MDEV-35920: Hex hybrid type causing invalid decimals in arithmetic context +# +SELECT MOD(COALESCE(0x30), 1); +MOD(COALESCE(0x30), 1) +0 +SELECT MOD(LEAST(0x30,0x30), 1); +MOD(LEAST(0x30,0x30), 1) +0 +SELECT MOD(IFNULL(0x30,0x30), 1); +MOD(IFNULL(0x30,0x30), 1) +0 +SELECT MOD(IF(0,0x30,0x30), 1); +MOD(IF(0,0x30,0x30), 1) +0 diff --git a/mysql-test/main/bug35920.test b/mysql-test/main/bug35920.test new file mode 100644 index 0000000000000..caee246b09426 --- /dev/null +++ b/mysql-test/main/bug35920.test @@ -0,0 +1,11 @@ +--echo # +--echo # MDEV-35920: Hex hybrid type causing invalid decimals in arithmetic context +--echo # + +SELECT MOD(COALESCE(0x30), 1); + +SELECT MOD(LEAST(0x30,0x30), 1); + +SELECT MOD(IFNULL(0x30,0x30), 1); + +SELECT MOD(IF(0,0x30,0x30), 1); diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 8a75ebdb6a53b..a2670f9a67740 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -1383,6 +1383,26 @@ aggregate_attributes_string(const LEX_CSTRING &func_name, } +/** + Aggregate result type attributes for hexadecimal/hybrid string functions. + + @param field_type Field type. + @param items Argument array. + @param nitems Number of arguments. + + @retval False on success, true on error. +*/ +bool Type_std_attributes:: +aggregate_attributes_hex_hybrid(const LEX_CSTRING &func_name, + Item **items, uint nitems) +{ + if (aggregate_attributes_string(func_name, items, nitems)) + return true; + unsigned_flag= true; + decimals= 0; + return false; +} + /* Find a handler by its ODBC literal data type. @@ -4786,6 +4806,17 @@ bool Type_handler_string_result:: return func->aggregate_attributes_string(func_name, items, nitems); } +bool Type_handler_hex_hybrid:: + Item_hybrid_func_fix_attributes(THD *thd, + const LEX_CSTRING &name, + Type_handler_hybrid_field_type *, + Type_all_attributes *attr, + Item **items, + uint nitems) const +{ + return attr->aggregate_attributes_hex_hybrid(name, items, nitems); +} + /* diff --git a/sql/sql_type.h b/sql/sql_type.h index 45ed3744be0a8..7958de5a5fbab 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -3359,6 +3359,8 @@ class Type_std_attributes: public Type_numeric_attributes } bool aggregate_attributes_string(const LEX_CSTRING &func_name, Item **item, uint nitems); + bool aggregate_attributes_hex_hybrid(const LEX_CSTRING &func_name, + Item **item, uint nitems); void aggregate_attributes_temporal(uint int_part_length, Item **item, uint nitems) { @@ -7395,6 +7397,12 @@ class Type_handler_hex_hybrid: public Type_handler_varchar const Type_handler *cast_to_int_type_handler() const override; bool Item_func_round_fix_length_and_dec(Item_func_round *) const override; bool Item_func_int_val_fix_length_and_dec(Item_func_int_val*) const override; + bool Item_hybrid_func_fix_attributes(THD *thd, + const LEX_CSTRING &name, + Type_handler_hybrid_field_type *, + Type_all_attributes *attr, + Item **items, + uint nitems) const override; };