mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-32879 Server crash in my_decimal::operator= or unexpected ER_DUP_ENTRY upon comparison with INET6 and similar types
During the 10.5->10.6 merge please use the 10.6 code on conflicts. This is the 10.5 version of the patch (a backport of the 10.6 version). Unlike 10.6 version, it makes changes in plugin/type_inet/sql_type_inet.* rather than in sql/sql_type_fixedbin.h Item_bool_rowready_func2, Item_func_between, Item_func_in did not check if a not-NULL argument of an arbitrary data type can produce a NULL value on conversion to INET6. This caused a crash on DBUG_ASSERT() in conversion failures, because the function returned SQL NULL for something that has Item::maybe_null() equal to false. Adding setting NULL-ability in such cases. Details: - Removing the code in Item_func::setup_args_and_comparator() performing character set aggregation with optional narrowing. This aggregation is done inside Arg_comparator::set_cmp_func_string(). So this code was redundant - Removing Item_func::setup_args_and_comparator() as it git simplified to just to two lines: convert_const_compared_to_int_field(thd); return cmp->set_cmp_func(thd, this, &args[0], &args[1], true); Using these lines directly in: - Item_bool_rowready_func2::fix_length_and_dec() - Item_func_nullif::fix_length_and_dec() - Adding a new virtual method: - Type_handler::Item_bool_rowready_func2_fix_length_and_dec(). - Adding tests detecting if the data type conversion can return SQL NULL into the following methods of Type_handler_inet6: - Item_bool_rowready_func2_fix_length_and_dec - Item_func_between_fix_length_and_dec - Item_func_in_fix_comparator_compatible_types
This commit is contained in:
@ -15405,7 +15405,7 @@ static bool check_row_equality(THD *thd, const Arg_comparator *comparators,
|
||||
{
|
||||
Item_func_eq *eq_item;
|
||||
if (!(eq_item= new (thd->mem_root) Item_func_eq(thd, left_item, right_item)) ||
|
||||
eq_item->set_cmp_func())
|
||||
eq_item->set_cmp_func(thd))
|
||||
return FALSE;
|
||||
eq_item->quick_fix_field();
|
||||
eq_list->push_back(eq_item, thd->mem_root);
|
||||
@ -16155,7 +16155,7 @@ Item *eliminate_item_equal(THD *thd, COND *cond, COND_EQUAL *upper_levels,
|
||||
Don't produce equality if const is equal to item_const.
|
||||
*/
|
||||
Item_func_eq *func= new (thd->mem_root) Item_func_eq(thd, item_const, upper_const);
|
||||
func->set_cmp_func();
|
||||
func->set_cmp_func(thd);
|
||||
func->quick_fix_field();
|
||||
if (func->val_int())
|
||||
item= 0;
|
||||
@ -16203,7 +16203,7 @@ Item *eliminate_item_equal(THD *thd, COND *cond, COND_EQUAL *upper_levels,
|
||||
field_item->remove_item_direct_ref(),
|
||||
head_item->remove_item_direct_ref());
|
||||
|
||||
if (!eq_item || eq_item->set_cmp_func())
|
||||
if (!eq_item || eq_item->set_cmp_func(thd))
|
||||
return 0;
|
||||
eq_item->quick_fix_field();
|
||||
}
|
||||
@ -16621,7 +16621,7 @@ change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list,
|
||||
So make sure to use set_cmp_func() only for non-LIKE operators.
|
||||
*/
|
||||
if (functype != Item_func::LIKE_FUNC)
|
||||
((Item_bool_rowready_func2*) func)->set_cmp_func();
|
||||
((Item_bool_rowready_func2*) func)->set_cmp_func(thd);
|
||||
}
|
||||
}
|
||||
else if (can_change_cond_ref_to_const(func, left_item, right_item,
|
||||
@ -16646,7 +16646,7 @@ change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list,
|
||||
save_list->push_back(tmp2);
|
||||
}
|
||||
if (functype != Item_func::LIKE_FUNC)
|
||||
((Item_bool_rowready_func2*) func)->set_cmp_func();
|
||||
((Item_bool_rowready_func2*) func)->set_cmp_func(thd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user