Commit d4f97e20 authored by Alexander Barkov's avatar Alexander Barkov

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; }
parent 294ac1fb
......@@ -2814,3 +2814,28 @@ SET STORAGE_ENGINE=Default;
#
# End of 10.2 tests
#
#
# Start of 10.3 tests
#
#
# MDEV-22391 Assertion `0' failed in Item_type_holder::val_str on utf16 charset table query
#
SET NAMES utf8;
CREATE TABLE t1 (a TEXT CHARACTER SET utf16);
SELECT * FROM (VALUES (1) UNION SELECT * FROM t1) AS t;
1
1
DROP TABLE t1;
VALUES (1) UNION SELECT _utf16 0x0020;
1
1
VALUES ('') UNION SELECT _utf16 0x0020 COLLATE utf16_bin;
VALUES ('') UNION VALUES ( _utf16 0x0020 COLLATE utf16_bin);
#
# End of 10.3 tests
#
......@@ -934,3 +934,24 @@ let $coll_pad='utf16_bin';
--echo #
--echo # End of 10.2 tests
--echo #
--echo #
--echo # Start of 10.3 tests
--echo #
--echo #
--echo # MDEV-22391 Assertion `0' failed in Item_type_holder::val_str on utf16 charset table query
--echo #
SET NAMES utf8;
CREATE TABLE t1 (a TEXT CHARACTER SET utf16);
SELECT * FROM (VALUES (1) UNION SELECT * FROM t1) AS t;
DROP TABLE t1;
VALUES (1) UNION SELECT _utf16 0x0020;
VALUES ('') UNION SELECT _utf16 0x0020 COLLATE utf16_bin;
VALUES ('') UNION VALUES ( _utf16 0x0020 COLLATE utf16_bin);
--echo #
--echo # End of 10.3 tests
--echo #
......@@ -11321,5 +11321,17 @@ SELECT x AS 5天内最近一次登录时间 FROM t1;
1
DROP TABLE t1;
#
# MDEV-22391 Assertion `0' failed in Item_type_holder::val_str on utf16 charset table query
#
SET NAMES utf8;
VALUES (_latin1 0xDF) UNION SELECT _utf8'a' COLLATE utf8_bin;
_latin1 0xDF
ß
a
VALUES (_latin1 0xDF) UNION VALUES(_utf8'a' COLLATE utf8_bin);
_latin1 0xDF
ß
a
#
# End of 10.3 tests
#
......@@ -2256,6 +2256,13 @@ INSERT INTO t1 VALUES (1);
SELECT x AS 5天内最近一次登录时间 FROM t1;
DROP TABLE t1;
--echo #
--echo # MDEV-22391 Assertion `0' failed in Item_type_holder::val_str on utf16 charset table query
--echo #
SET NAMES utf8;
VALUES (_latin1 0xDF) UNION SELECT _utf8'a' COLLATE utf8_bin;
VALUES (_latin1 0xDF) UNION VALUES(_utf8'a' COLLATE utf8_bin);
--echo #
--echo # End of 10.3 tests
......
......@@ -6602,6 +6602,23 @@ class Item_type_holder: public Item,
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 *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment