summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2021-10-14 08:37:23 +0400
committerAlexander Barkov <bar@mariadb.com>2021-10-14 08:37:23 +0400
commitdf383043427fb22b0735fe31968db860f4cdb7a0 (patch)
tree570ba7b6afad8b97e4d4fc03d555df9bcecc0dd7
parentbd1573b0f332d4c7c08aab2974aadd544dbc24e3 (diff)
downloadmariadb-git-bb-10.5-bar-MDEV-26742.tar.gz
MDEV-26742 Assertion `field->type_handler() == this' failed in FixedBinTypeBundle<NATIVE_LEN, MAX_CHAR_LEN>::Type_handler_fbt::stored_field_cmp_to_itembb-10.5-bar-MDEV-26742
-rw-r--r--plugin/type_inet/mysql-test/type_inet/type_inet6_innodb.result27
-rw-r--r--plugin/type_inet/mysql-test/type_inet/type_inet6_innodb.test18
-rw-r--r--plugin/type_inet/mysql-test/type_inet/type_inet6_myisam.result19
-rw-r--r--plugin/type_inet/mysql-test/type_inet/type_inet6_myisam.test12
-rw-r--r--sql/field.cc19
-rw-r--r--sql/field.h2
6 files changed, 95 insertions, 2 deletions
diff --git a/plugin/type_inet/mysql-test/type_inet/type_inet6_innodb.result b/plugin/type_inet/mysql-test/type_inet/type_inet6_innodb.result
index 5f7063b8f4b..a6911751747 100644
--- a/plugin/type_inet/mysql-test/type_inet/type_inet6_innodb.result
+++ b/plugin/type_inet/mysql-test/type_inet/type_inet6_innodb.result
@@ -88,5 +88,32 @@ Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = INET6'::ff'
DROP TABLE t1;
#
+# MDEV-26742 Assertion `field->type_handler() == this' failed in FixedBinTypeBundle<NATIVE_LEN, MAX_CHAR_LEN>::Type_handler_fbt::stored_field_cmp_to_item
+#
+CREATE TABLE t1 (pk inet6, c text) engine=myisam;
+INSERT INTO t1 VALUES ('::',1);
+CREATE TABLE t2 (d text, KEY (d)) engine=innodb ;
+Warnings:
+Note 1071 Specified key was too long; max key length is 3072 bytes
+INSERT INTO t2 VALUES (2);
+SELECT * FROM t2 JOIN t1 ON ( t1.pk > t2.d);
+d pk c
+Warnings:
+Warning 1292 Incorrect inet6 value: '2'
+UPDATE t2 JOIN t1 ON ( t1.pk > t2.d) SET t1.c = 1;
+ERROR 22007: Incorrect inet6 value: '2'
+SET sql_mode='';
+UPDATE t2 JOIN t1 ON ( t1.pk > t2.d) SET t1.c = 1;
+Warnings:
+Warning 1292 Incorrect inet6 value: '2'
+SET sql_mode=DEFAULT;
+SELECT * FROM t1;
+pk c
+:: 1
+SELECT * FROM t2;
+d
+2
+DROP TABLE t1, t2;
+#
# End of 10.5 tests
#
diff --git a/plugin/type_inet/mysql-test/type_inet/type_inet6_innodb.test b/plugin/type_inet/mysql-test/type_inet/type_inet6_innodb.test
index dd6049abbf3..55826cc3e3f 100644
--- a/plugin/type_inet/mysql-test/type_inet/type_inet6_innodb.test
+++ b/plugin/type_inet/mysql-test/type_inet/type_inet6_innodb.test
@@ -12,6 +12,24 @@
SET default_storage_engine=InnoDB;
--source type_inet6_engines.inc
+--echo #
+--echo # MDEV-26742 Assertion `field->type_handler() == this' failed in FixedBinTypeBundle<NATIVE_LEN, MAX_CHAR_LEN>::Type_handler_fbt::stored_field_cmp_to_item
+--echo #
+
+CREATE TABLE t1 (pk inet6, c text) engine=myisam;
+INSERT INTO t1 VALUES ('::',1);
+CREATE TABLE t2 (d text, KEY (d)) engine=innodb ;
+INSERT INTO t2 VALUES (2);
+SELECT * FROM t2 JOIN t1 ON ( t1.pk > t2.d);
+--error ER_TRUNCATED_WRONG_VALUE
+UPDATE t2 JOIN t1 ON ( t1.pk > t2.d) SET t1.c = 1;
+SET sql_mode='';
+UPDATE t2 JOIN t1 ON ( t1.pk > t2.d) SET t1.c = 1;
+SET sql_mode=DEFAULT;
+SELECT * FROM t1;
+SELECT * FROM t2;
+DROP TABLE t1, t2;
+
--echo #
--echo # End of 10.5 tests
diff --git a/plugin/type_inet/mysql-test/type_inet/type_inet6_myisam.result b/plugin/type_inet/mysql-test/type_inet/type_inet6_myisam.result
index c8dba6ff959..ba65d61cb08 100644
--- a/plugin/type_inet/mysql-test/type_inet/type_inet6_myisam.result
+++ b/plugin/type_inet/mysql-test/type_inet/type_inet6_myisam.result
@@ -88,5 +88,24 @@ Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = INET6'::ff'
DROP TABLE t1;
#
+# MDEV-26742 Assertion `field->type_handler() == this' failed in FixedBinTypeBundle<NATIVE_LEN, MAX_CHAR_LEN>::Type_handler_fbt::stored_field_cmp_to_item
+#
+CREATE TABLE t1 (c varchar(64), key(c)) engine=myisam;
+INSERT INTO t1 VALUES ('0::1'),('::1'),('::2');
+SELECT * FROM t1 WHERE c>CAST('::1' AS INET6);
+c
+::2
+EXPLAIN SELECT * FROM t1 WHERE c>CAST('::1' AS INET6);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index c c 67 NULL 3 Using where; Using index
+SELECT * FROM t1 WHERE c=CAST('::1' AS INET6);
+c
+0::1
+::1
+EXPLAIN SELECT * FROM t1 WHERE c=CAST('::1' AS INET6);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index c c 67 NULL 3 Using where; Using index
+DROP TABLE t1;
+#
# End of 10.5 tests
#
diff --git a/plugin/type_inet/mysql-test/type_inet/type_inet6_myisam.test b/plugin/type_inet/mysql-test/type_inet/type_inet6_myisam.test
index c5183f01cf0..0ba8369ac95 100644
--- a/plugin/type_inet/mysql-test/type_inet/type_inet6_myisam.test
+++ b/plugin/type_inet/mysql-test/type_inet/type_inet6_myisam.test
@@ -10,6 +10,18 @@
SET default_storage_engine=MyISAM;
--source type_inet6_engines.inc
+--echo #
+--echo # MDEV-26742 Assertion `field->type_handler() == this' failed in FixedBinTypeBundle<NATIVE_LEN, MAX_CHAR_LEN>::Type_handler_fbt::stored_field_cmp_to_item
+--echo #
+
+CREATE TABLE t1 (c varchar(64), key(c)) engine=myisam;
+INSERT INTO t1 VALUES ('0::1'),('::1'),('::2');
+SELECT * FROM t1 WHERE c>CAST('::1' AS INET6);
+EXPLAIN SELECT * FROM t1 WHERE c>CAST('::1' AS INET6);
+SELECT * FROM t1 WHERE c=CAST('::1' AS INET6);
+EXPLAIN SELECT * FROM t1 WHERE c=CAST('::1' AS INET6);
+DROP TABLE t1;
+
--echo #
--echo # End of 10.5 tests
diff --git a/sql/field.cc b/sql/field.cc
index 7ff07540538..2c768527ced 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1276,6 +1276,21 @@ bool Field::can_be_substituted_to_equal_item(const Context &ctx,
}
+bool Field::cmp_is_done_using_type_handler_of_this(const Item_bool_func *cond,
+ const Item *item) const
+{
+ /*
+ We could eventually take comparison_type_handler() from cond,
+ instead of calculating it again. But only some descendants of
+ Item_bool_func has this method. So this needs some hierarchy changes.
+ Another option is to pass "class Context" to this method.
+ */
+ Type_handler_hybrid_field_type cmp(type_handler_for_comparison());
+ return !cmp.aggregate_for_comparison(item->type_handler_for_comparison()) &&
+ cmp.type_handler() == type_handler_for_comparison();
+}
+
+
/*
This handles all numeric and BIT data types.
*/
@@ -7356,7 +7371,7 @@ bool
Field_longstr::cmp_to_string_with_same_collation(const Item_bool_func *cond,
const Item *item) const
{
- return item->cmp_type() == STRING_RESULT &&
+ return cmp_is_done_using_type_handler_of_this(cond, item) &&
charset() == cond->compare_collation();
}
@@ -7365,7 +7380,7 @@ bool
Field_longstr::cmp_to_string_with_stricter_collation(const Item_bool_func *cond,
const Item *item) const
{
- return item->cmp_type() == STRING_RESULT &&
+ return cmp_is_done_using_type_handler_of_this(cond, item) &&
(charset() == cond->compare_collation() ||
cond->compare_collation()->state & MY_CS_BINSORT);
}
diff --git a/sql/field.h b/sql/field.h
index 6747f8070dc..47a85efc43e 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1648,6 +1648,8 @@ protected:
}
int warn_if_overflow(int op_result);
Copy_func *get_identical_copy_func() const;
+ bool cmp_is_done_using_type_handler_of_this(const Item_bool_func *cond,
+ const Item *item) const;
bool can_optimize_scalar_range(const RANGE_OPT_PARAM *param,
const KEY_PART *key_part,
const Item_bool_func *cond,