From 5392726e3c4f924745412500a7d1e030226a68d1 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Mon, 14 Oct 2019 08:21:08 +0400 Subject: MDEV-20818 ER_CRASHED_ON_USAGE or Assertion `length <= column->length' failed in write_block_record on temporary table The patch for `MDEV-20795 CAST(inet6 AS BINARY) returns wrong result` unintentionally changed what Item_char_typecast::type_handler() returns. This broke UNIONs with the BINARY() function, as the Aria engine started to get columns of unexpected data types. Restoring previous behaviour, to return Type_handler::string_type_handler(max_length). The prototype for Item_handed_func::return_type_handler() has changed from: const Type_handler *return_type_handler() const to: const Type_handler *return_type_handler(const Item_handled_func *) const --- mysql-test/main/type_binary.result | 40 ++++++++++++++++++++++ mysql-test/main/type_binary.test | 28 +++++++++++++++ mysql-test/main/xml.result | 13 +++++++ mysql-test/main/xml.test | 14 ++++++++ .../mysql-test/type_inet/type_inet6.result | 37 ++++++++++++++++++++ .../type_inet/mysql-test/type_inet/type_inet6.test | 25 ++++++++++++++ plugin/type_inet/sql_type_inet.cc | 9 ++--- sql/item_func.h | 17 ++++----- sql/item_timefunc.cc | 6 ++-- 9 files changed, 171 insertions(+), 18 deletions(-) diff --git a/mysql-test/main/type_binary.result b/mysql-test/main/type_binary.result index 7dfe44ab045..76dab6e4e93 100644 --- a/mysql-test/main/type_binary.result +++ b/mysql-test/main/type_binary.result @@ -180,3 +180,43 @@ DROP TABLE t1; # # End of 10.0 tests # +# +# Start of 10.5 tests +# +# +# MDEV-20818 ER_CRASHED_ON_USAGE or Assertion `length <= column->length' failed in write_block_record on temporary table +# +CREATE TABLE t1 (a VARCHAR(39)); +SELECT +CAST(a AS BINARY(0)), +CAST(a AS BINARY(1)), +CAST(a AS BINARY(16)), +CAST(a AS BINARY(255)), +CAST(a AS BINARY(256)), +CAST(a AS BINARY(512)), +CAST(a AS BINARY(513)), +CAST(a AS BINARY(65532)), +CAST(a AS BINARY(65533)), +CAST(a AS BINARY(65534)), +CAST(a AS BINARY(65535)), +CAST(a AS BINARY(65536)), +CAST(a AS BINARY(16777215)), +CAST(a AS BINARY(16777216)) +FROM t1; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def CAST(a AS BINARY(0)) 253 0 0 Y 128 0 63 +def CAST(a AS BINARY(1)) 253 1 0 Y 128 0 63 +def CAST(a AS BINARY(16)) 253 16 0 Y 128 0 63 +def CAST(a AS BINARY(255)) 253 255 0 Y 128 0 63 +def CAST(a AS BINARY(256)) 253 256 0 Y 128 0 63 +def CAST(a AS BINARY(512)) 253 512 0 Y 128 0 63 +def CAST(a AS BINARY(513)) 253 513 0 Y 128 0 63 +def CAST(a AS BINARY(65532)) 252 65532 0 Y 128 0 63 +def CAST(a AS BINARY(65533)) 252 65533 0 Y 128 0 63 +def CAST(a AS BINARY(65534)) 252 65534 0 Y 128 0 63 +def CAST(a AS BINARY(65535)) 252 65535 0 Y 128 0 63 +def CAST(a AS BINARY(65536)) 250 65536 0 Y 128 0 63 +def CAST(a AS BINARY(16777215)) 250 16777215 0 Y 128 0 63 +def CAST(a AS BINARY(16777216)) 251 16777216 0 Y 128 0 63 +CAST(a AS BINARY(0)) CAST(a AS BINARY(1)) CAST(a AS BINARY(16)) CAST(a AS BINARY(255)) CAST(a AS BINARY(256)) CAST(a AS BINARY(512)) CAST(a AS BINARY(513)) CAST(a AS BINARY(65532)) CAST(a AS BINARY(65533)) CAST(a AS BINARY(65534)) CAST(a AS BINARY(65535)) CAST(a AS BINARY(65536)) CAST(a AS BINARY(16777215)) CAST(a AS BINARY(16777216)) +DROP TABLE t1; diff --git a/mysql-test/main/type_binary.test b/mysql-test/main/type_binary.test index 952bc6ef231..9f7a0db66d5 100644 --- a/mysql-test/main/type_binary.test +++ b/mysql-test/main/type_binary.test @@ -126,3 +126,31 @@ DROP TABLE t1; --echo # End of 10.0 tests --echo # +--echo # +--echo # Start of 10.5 tests +--echo # + +--echo # +--echo # MDEV-20818 ER_CRASHED_ON_USAGE or Assertion `length <= column->length' failed in write_block_record on temporary table +--echo # + +CREATE TABLE t1 (a VARCHAR(39)); +--enable_metadata +SELECT + CAST(a AS BINARY(0)), + CAST(a AS BINARY(1)), + CAST(a AS BINARY(16)), + CAST(a AS BINARY(255)), + CAST(a AS BINARY(256)), + CAST(a AS BINARY(512)), + CAST(a AS BINARY(513)), + CAST(a AS BINARY(65532)), + CAST(a AS BINARY(65533)), + CAST(a AS BINARY(65534)), + CAST(a AS BINARY(65535)), + CAST(a AS BINARY(65536)), + CAST(a AS BINARY(16777215)), + CAST(a AS BINARY(16777216)) +FROM t1; +--disable_metadata +DROP TABLE t1; diff --git a/mysql-test/main/xml.result b/mysql-test/main/xml.result index 2cd70c08a94..25a1193934e 100644 --- a/mysql-test/main/xml.result +++ b/mysql-test/main/xml.result @@ -1309,3 +1309,16 @@ DROP TABLE t1; # # End of 10.2 tests # +# +# Start of 10.5 tests +# +# +# MDEV-20818 ER_CRASHED_ON_USAGE or Assertion `length <= column->length' failed in write_block_record on temporary table +# +SELECT 'foo' AS f UNION SELECT BINARY( UpdateXML('', '/a', '')) AS f; +f +foo + +# +# Start of 10.5 tests +# diff --git a/mysql-test/main/xml.test b/mysql-test/main/xml.test index b567f03a431..3c7ecf6d060 100644 --- a/mysql-test/main/xml.test +++ b/mysql-test/main/xml.test @@ -782,3 +782,17 @@ DROP TABLE t1; --echo # --echo # End of 10.2 tests --echo # + +--echo # +--echo # Start of 10.5 tests +--echo # + +--echo # +--echo # MDEV-20818 ER_CRASHED_ON_USAGE or Assertion `length <= column->length' failed in write_block_record on temporary table +--echo # + +SELECT 'foo' AS f UNION SELECT BINARY( UpdateXML('', '/a', '')) AS f; + +--echo # +--echo # Start of 10.5 tests +--echo # diff --git a/plugin/type_inet/mysql-test/type_inet/type_inet6.result b/plugin/type_inet/mysql-test/type_inet/type_inet6.result index 9e3601e414b..4cc1ac370a0 100644 --- a/plugin/type_inet/mysql-test/type_inet/type_inet6.result +++ b/plugin/type_inet/mysql-test/type_inet/type_inet6.result @@ -1931,3 +1931,40 @@ INSERT INTO t1 (a) VALUES ('::'); ALTER TABLE t1 MODIFY a DATE; ERROR 22007: Incorrect date value: '::' for column `test`.`t1`.`a` at row 1 DROP TABLE t1; +# +# MDEV-20818 ER_CRASHED_ON_USAGE or Assertion `length <= column->length' failed in write_block_record on temporary table +# +CREATE TABLE t1 (a INET6); +SELECT +CAST(a AS BINARY(0)), +CAST(a AS BINARY(1)), +CAST(a AS BINARY(16)), +CAST(a AS BINARY(255)), +CAST(a AS BINARY(256)), +CAST(a AS BINARY(512)), +CAST(a AS BINARY(513)), +CAST(a AS BINARY(65532)), +CAST(a AS BINARY(65533)), +CAST(a AS BINARY(65534)), +CAST(a AS BINARY(65535)), +CAST(a AS BINARY(65536)), +CAST(a AS BINARY(16777215)), +CAST(a AS BINARY(16777216)) +FROM t1; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def CAST(a AS BINARY(0)) 254 0 0 Y 128 0 63 +def CAST(a AS BINARY(1)) 254 1 0 Y 128 0 63 +def CAST(a AS BINARY(16)) 254 16 0 Y 128 0 63 +def CAST(a AS BINARY(255)) 254 255 0 Y 128 0 63 +def CAST(a AS BINARY(256)) 253 256 0 Y 128 0 63 +def CAST(a AS BINARY(512)) 253 512 0 Y 128 0 63 +def CAST(a AS BINARY(513)) 253 513 0 Y 128 0 63 +def CAST(a AS BINARY(65532)) 253 65532 0 Y 128 0 63 +def CAST(a AS BINARY(65533)) 252 65533 0 Y 128 0 63 +def CAST(a AS BINARY(65534)) 252 65534 0 Y 128 0 63 +def CAST(a AS BINARY(65535)) 252 65535 0 Y 128 0 63 +def CAST(a AS BINARY(65536)) 250 65536 0 Y 128 0 63 +def CAST(a AS BINARY(16777215)) 250 16777215 0 Y 128 0 63 +def CAST(a AS BINARY(16777216)) 251 16777216 0 Y 128 0 63 +CAST(a AS BINARY(0)) CAST(a AS BINARY(1)) CAST(a AS BINARY(16)) CAST(a AS BINARY(255)) CAST(a AS BINARY(256)) CAST(a AS BINARY(512)) CAST(a AS BINARY(513)) CAST(a AS BINARY(65532)) CAST(a AS BINARY(65533)) CAST(a AS BINARY(65534)) CAST(a AS BINARY(65535)) CAST(a AS BINARY(65536)) CAST(a AS BINARY(16777215)) CAST(a AS BINARY(16777216)) +DROP TABLE t1; diff --git a/plugin/type_inet/mysql-test/type_inet/type_inet6.test b/plugin/type_inet/mysql-test/type_inet/type_inet6.test index a17f5dd69f7..875aaa0b7e9 100644 --- a/plugin/type_inet/mysql-test/type_inet/type_inet6.test +++ b/plugin/type_inet/mysql-test/type_inet/type_inet6.test @@ -1411,3 +1411,28 @@ INSERT INTO t1 (a) VALUES ('::'); --error ER_TRUNCATED_WRONG_VALUE ALTER TABLE t1 MODIFY a DATE; DROP TABLE t1; + +--echo # +--echo # MDEV-20818 ER_CRASHED_ON_USAGE or Assertion `length <= column->length' failed in write_block_record on temporary table +--echo # + +CREATE TABLE t1 (a INET6); +--enable_metadata +SELECT + CAST(a AS BINARY(0)), + CAST(a AS BINARY(1)), + CAST(a AS BINARY(16)), + CAST(a AS BINARY(255)), + CAST(a AS BINARY(256)), + CAST(a AS BINARY(512)), + CAST(a AS BINARY(513)), + CAST(a AS BINARY(65532)), + CAST(a AS BINARY(65533)), + CAST(a AS BINARY(65534)), + CAST(a AS BINARY(65535)), + CAST(a AS BINARY(65536)), + CAST(a AS BINARY(16777215)), + CAST(a AS BINARY(16777216)) +FROM t1; +--disable_metadata +DROP TABLE t1; diff --git a/plugin/type_inet/sql_type_inet.cc b/plugin/type_inet/sql_type_inet.cc index 9bf77e62d24..d6c6703aaa3 100644 --- a/plugin/type_inet/sql_type_inet.cc +++ b/plugin/type_inet/sql_type_inet.cc @@ -1226,13 +1226,8 @@ class Item_char_typecast_func_handler_inet6_to_binary: public Item_handled_func::Handler_str { public: - const Type_handler *return_type_handler() const override - { - return &type_handler_string; - } - const Type_handler * - type_handler_for_create_select(const Item_handled_func *item) - const override + const Type_handler *return_type_handler(const Item_handled_func *item) + const override { if (item->max_length > MAX_FIELD_VARCHARLENGTH) return Type_handler::blob_type_handler(item->max_length); diff --git a/sql/item_func.h b/sql/item_func.h index 5b0093167d4..2525f6f1f0b 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -466,11 +466,12 @@ public: virtual longlong val_int(Item_handled_func *) const= 0; virtual my_decimal *val_decimal(Item_handled_func *, my_decimal *) const= 0; virtual bool get_date(THD *thd, Item_handled_func *, MYSQL_TIME *, date_mode_t fuzzydate) const= 0; - virtual const Type_handler *return_type_handler() const= 0; + virtual const Type_handler * + return_type_handler(const Item_handled_func *item) const= 0; virtual const Type_handler * type_handler_for_create_select(const Item_handled_func *item) const { - return return_type_handler(); + return return_type_handler(item); } virtual bool fix_length_and_dec(Item_handled_func *) const= 0; }; @@ -529,14 +530,14 @@ public: class Handler_temporal_string: public Handler_temporal { public: - const Type_handler *return_type_handler() const + const Type_handler *return_type_handler(const Item_handled_func *) const { return &type_handler_string; } const Type_handler * type_handler_for_create_select(const Item_handled_func *item) const { - return return_type_handler()->type_handler_for_tmp_table(item); + return return_type_handler(item)->type_handler_for_tmp_table(item); } double val_real(Item_handled_func *item) const { @@ -560,7 +561,7 @@ public: class Handler_date: public Handler_temporal { public: - const Type_handler *return_type_handler() const + const Type_handler *return_type_handler(const Item_handled_func *) const { return &type_handler_newdate; } @@ -591,7 +592,7 @@ public: class Handler_time: public Handler_temporal { public: - const Type_handler *return_type_handler() const + const Type_handler *return_type_handler(const Item_handled_func *) const { return &type_handler_time2; } @@ -617,7 +618,7 @@ public: class Handler_datetime: public Handler_temporal { public: - const Type_handler *return_type_handler() const + const Type_handler *return_type_handler(const Item_handled_func *) const { return &type_handler_datetime2; } @@ -653,7 +654,7 @@ public: } const Type_handler *type_handler() const { - return m_func_handler->return_type_handler(); + return m_func_handler->return_type_handler(this); } Field *create_field_for_create_select(MEM_ROOT *root, TABLE *table) { diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 631829eee1d..8639edf2944 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2420,14 +2420,14 @@ String *Item_char_typecast::val_str_binary_from_native(String *str) class Item_char_typecast_func_handler: public Item_handled_func::Handler_str { public: - const Type_handler *return_type_handler() const + const Type_handler *return_type_handler(const Item_handled_func *item) const { - return &type_handler_varchar; + return Type_handler::string_type_handler(item->max_length); } const Type_handler * type_handler_for_create_select(const Item_handled_func *item) const { - return return_type_handler()->type_handler_for_tmp_table(item); + return return_type_handler(item)->type_handler_for_tmp_table(item); } bool fix_length_and_dec(Item_handled_func *item) const -- cgit v1.2.1