summaryrefslogtreecommitdiff
path: root/sql/item.h
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2020-05-20 11:53:09 +0400
committerAlexander Barkov <bar@mariadb.com>2020-05-20 11:53:09 +0400
commitd4f97e2086848cedfdd35a6c1cf286f8dad26c5c (patch)
tree0395f96dd3a403f94285ccab1515913802211f7a /sql/item.h
parent294ac1fbab306e97dad3588a00e3527f2056e7e4 (diff)
downloadmariadb-git-d4f97e2086848cedfdd35a6c1cf286f8dad26c5c.tar.gz
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; }
Diffstat (limited to 'sql/item.h')
-rw-r--r--sql/item.h17
1 files changed, 17 insertions, 0 deletions
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 *);