From d4f97e2086848cedfdd35a6c1cf286f8dad26c5c Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 20 May 2020 11:53:09 +0400 Subject: MDEV-22391 Assertion `0' failed in Item_type_holder::val_str on utf16 charset table query Problem: When handling a query like this: VALUES ('') UNION SELECT _utf16 0x0020 COLLATE utf16_bin; Type_handler_string_result::Item_hybrid_func_fix_attributes() tried to apply character set conversion Item_type_holder, which causes a crash on DBUG_ASSERT(0) inside Item_type_holder::val_str(). Fix: Overriding Item_type_holder's methods to avoid this, as follows: bool const_item() const { return false; } bool is_expensive() { return true; } --- sql/item.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'sql/item.h') diff --git a/sql/item.h b/sql/item.h index 39451d2631a..769e6b80ca9 100644 --- a/sql/item.h +++ b/sql/item.h @@ -6602,6 +6602,23 @@ public: enum Type type() const { return TYPE_HOLDER; } TYPELIB *get_typelib() const { return enum_set_typelib; } + /* + When handling a query like this: + VALUES ('') UNION VALUES( _utf16 0x0020 COLLATE utf16_bin); + Item_type_holder can be passed to + Type_handler_xxx::Item_hybrid_func_fix_attributes() + We don't want the latter to perform character set conversion of a + Item_type_holder by calling its val_str(), which calls DBUG_ASSERT(0). + Let's override const_item() and is_expensive() to avoid this. + Note, Item_hybrid_func_fix_attributes() could probably + have a new argument to distinguish what we need: + - (a) aggregate data type attributes only + - (b) install converters after attribute aggregation + So st_select_lex_unit::join_union_type_attributes() could + ask it to do (a) only, without (b). + */ + bool const_item() const { return false; } + bool is_expensive() { return true; } double val_real(); longlong val_int(); my_decimal *val_decimal(my_decimal *); -- cgit v1.2.1