summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2019-10-14 08:21:08 +0400
committerAlexander Barkov <bar@mariadb.com>2019-10-14 08:21:08 +0400
commit5392726e3c4f924745412500a7d1e030226a68d1 (patch)
treeb4267ef4878509fad2ee7d98bce7e07a37ac7c85
parentfa8437908ba55022d5f186d63dec4f01afb59746 (diff)
downloadmariadb-git-5392726e3c4f924745412500a7d1e030226a68d1.tar.gz
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
-rw-r--r--mysql-test/main/type_binary.result40
-rw-r--r--mysql-test/main/type_binary.test28
-rw-r--r--mysql-test/main/xml.result13
-rw-r--r--mysql-test/main/xml.test14
-rw-r--r--plugin/type_inet/mysql-test/type_inet/type_inet6.result37
-rw-r--r--plugin/type_inet/mysql-test/type_inet/type_inet6.test25
-rw-r--r--plugin/type_inet/sql_type_inet.cc9
-rw-r--r--sql/item_func.h17
-rw-r--r--sql/item_timefunc.cc6
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></a>', '/a', '<b></b>')) AS f;
+f
+foo
+<b></b>
+#
+# 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></a>', '/a', '<b></b>')) 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