mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
MDEV-36235 Incorrect result for BETWEEN over unique blob prefix
Disallow range optimization for BETWEEN when casting one of the arguments from STRING to a numeric type would be required to construct a range for the query. Adds a new method on Item_func_between called can_optimize_range_const which allows range optimization when the types of the arguments to BETWEEN would permit it.
This commit is contained in:
committed by
Dave Gosselin
parent
07b442aa68
commit
15fd232da4
@@ -397,3 +397,61 @@ indexed_col not_indexed_col
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t1;
|
||||
SET note_verbosity=DEFAULT;
|
||||
#
|
||||
# MDEV-36235 Incorrect result for BETWEEN over unique blob prefix
|
||||
#
|
||||
CREATE TABLE t1 (c1 BINARY(16), UNIQUE (c1));
|
||||
INSERT INTO t1 (c1) VALUES (-2),(-1),(1),(2);
|
||||
SELECT HEX(c1) FROM t1 WHERE 'a' BETWEEN 0 AND (c1);
|
||||
HEX(c1)
|
||||
31000000000000000000000000000000
|
||||
32000000000000000000000000000000
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: '-2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: '1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: '2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
SELECT HEX(c1) FROM t1 IGNORE KEY(c1) WHERE 'a' BETWEEN 0 AND (c1);
|
||||
HEX(c1)
|
||||
31000000000000000000000000000000
|
||||
32000000000000000000000000000000
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: '-2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: '1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: '2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
SELECT HEX(c1) FROM t1 WHERE '#' BETWEEN c1 AND 0;
|
||||
HEX(c1)
|
||||
2D310000000000000000000000000000
|
||||
2D320000000000000000000000000000
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '-2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
SELECT HEX(c1) FROM t1 IGNORE KEY(c1) WHERE '#' BETWEEN c1 AND 0;
|
||||
HEX(c1)
|
||||
2D320000000000000000000000000000
|
||||
2D310000000000000000000000000000
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '-2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '-1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
DROP TABLE t1;
|
||||
|
@@ -178,3 +178,14 @@ DELIMITER ;$$
|
||||
--source unusable_keys_joins.inc
|
||||
DROP TABLE t1;
|
||||
SET note_verbosity=DEFAULT;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-36235 Incorrect result for BETWEEN over unique blob prefix
|
||||
--echo #
|
||||
CREATE TABLE t1 (c1 BINARY(16), UNIQUE (c1));
|
||||
INSERT INTO t1 (c1) VALUES (-2),(-1),(1),(2);
|
||||
SELECT HEX(c1) FROM t1 WHERE 'a' BETWEEN 0 AND (c1);
|
||||
SELECT HEX(c1) FROM t1 IGNORE KEY(c1) WHERE 'a' BETWEEN 0 AND (c1);
|
||||
SELECT HEX(c1) FROM t1 WHERE '#' BETWEEN c1 AND 0;
|
||||
SELECT HEX(c1) FROM t1 IGNORE KEY(c1) WHERE '#' BETWEEN c1 AND 0;
|
||||
DROP TABLE t1;
|
||||
|
@@ -1419,3 +1419,193 @@ Note 1105 Cannot use key parts with `test`.`t1`.`indexed_col` in the rewritten c
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t1;
|
||||
SET note_verbosity=DEFAULT;
|
||||
#
|
||||
# MDEV-36235 Incorrect result for BETWEEN over unique blob prefix
|
||||
#
|
||||
CREATE TABLE t1 (c1 TINYBLOB, UNIQUE (c1(2))) engine=myisam;
|
||||
INSERT INTO t1 (c1) VALUES (1);
|
||||
SELECT c1 FROM t1 WHERE 'a' BETWEEN 0 AND (c1);
|
||||
c1
|
||||
1
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (c1 TINYBLOB, UNIQUE (c1(2)));
|
||||
INSERT INTO t1 (c1) VALUES (1),(2),(3),(4),(5);
|
||||
SELECT c1 FROM t1 WHERE 'a' BETWEEN 0 AND (c1);
|
||||
c1
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
SELECT c1 FROM t1 WHERE 3 BETWEEN 10*POW(-1,c1) AND (c1);
|
||||
c1
|
||||
3
|
||||
5
|
||||
SELECT c1 FROM t1 WHERE 'a' BETWEEN 10*POW(-1,c1) AND (c1);
|
||||
c1
|
||||
1
|
||||
3
|
||||
5
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (c1 TINYBLOB, UNIQUE (c1(2))) engine=myisam;
|
||||
INSERT INTO t1 (c1) VALUES (-2),(-1),(1),(2),(3),(4),(5);
|
||||
SELECT c1 FROM t1 WHERE 'a' BETWEEN 0 AND (c1);
|
||||
c1
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
SELECT c1 FROM t1 WHERE '#' BETWEEN c1 AND 0;
|
||||
c1
|
||||
-2
|
||||
-1
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (c1 TINYBLOB NOT NULL);
|
||||
INSERT INTO t1 (c1) VALUES (-2),(-1),(1),(2),(3),(4),(5);
|
||||
SELECT c1 FROM t1 WHERE 'a' BETWEEN 0 AND (c1);
|
||||
c1
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
SELECT c1 FROM t1 WHERE '#' BETWEEN c1 AND 0;
|
||||
c1
|
||||
-2
|
||||
-1
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (c1 TINYBLOB, UNIQUE (c1(2))) engine=innodb;
|
||||
INSERT INTO t1 (c1) VALUES (-2),(-1),(1),(2),(3),(4),(5);
|
||||
SELECT c1 FROM t1 WHERE 'a' BETWEEN 0 AND (c1);
|
||||
c1
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
SELECT c1 FROM t1 WHERE '#' BETWEEN c1 AND 0;
|
||||
c1
|
||||
-2
|
||||
-1
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
ALTER TABLE t1 engine=myisam;
|
||||
SELECT c1 FROM t1 WHERE 'a' BETWEEN 0 AND (c1);
|
||||
c1
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
SELECT c1 FROM t1 WHERE '#' BETWEEN c1 AND 0;
|
||||
c1
|
||||
-2
|
||||
-1
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (c1 TINYBLOB, UNIQUE (c1)) engine=innodb;
|
||||
INSERT INTO t1 (c1) VALUES (-2),(-1),(1),(2),(3),(4),(5);
|
||||
SELECT c1 FROM t1 WHERE 'a' BETWEEN 0 AND (c1);
|
||||
c1
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
SELECT c1 FROM t1 WHERE '#' BETWEEN c1 AND 0;
|
||||
c1
|
||||
-2
|
||||
-1
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
DROP TABLE t1;
|
||||
|
@@ -808,3 +808,48 @@ DELIMITER ;$$
|
||||
--source unusable_keys_joins.inc
|
||||
DROP TABLE t1;
|
||||
SET note_verbosity=DEFAULT;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-36235 Incorrect result for BETWEEN over unique blob prefix
|
||||
--echo #
|
||||
# myisam has a special optimization for tables with one row
|
||||
CREATE TABLE t1 (c1 TINYBLOB, UNIQUE (c1(2))) engine=myisam;
|
||||
INSERT INTO t1 (c1) VALUES (1);
|
||||
SELECT c1 FROM t1 WHERE 'a' BETWEEN 0 AND (c1);
|
||||
DROP TABLE t1;
|
||||
|
||||
# This case shows that we don't transform the entire WHERE clause
|
||||
# into a range condition.
|
||||
CREATE TABLE t1 (c1 TINYBLOB, UNIQUE (c1(2)));
|
||||
INSERT INTO t1 (c1) VALUES (1),(2),(3),(4),(5);
|
||||
SELECT c1 FROM t1 WHERE 'a' BETWEEN 0 AND (c1);
|
||||
SELECT c1 FROM t1 WHERE 3 BETWEEN 10*POW(-1,c1) AND (c1);
|
||||
SELECT c1 FROM t1 WHERE 'a' BETWEEN 10*POW(-1,c1) AND (c1);
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (c1 TINYBLOB, UNIQUE (c1(2))) engine=myisam;
|
||||
INSERT INTO t1 (c1) VALUES (-2),(-1),(1),(2),(3),(4),(5);
|
||||
SELECT c1 FROM t1 WHERE 'a' BETWEEN 0 AND (c1);
|
||||
SELECT c1 FROM t1 WHERE '#' BETWEEN c1 AND 0;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (c1 TINYBLOB NOT NULL);
|
||||
INSERT INTO t1 (c1) VALUES (-2),(-1),(1),(2),(3),(4),(5);
|
||||
SELECT c1 FROM t1 WHERE 'a' BETWEEN 0 AND (c1);
|
||||
SELECT c1 FROM t1 WHERE '#' BETWEEN c1 AND 0;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (c1 TINYBLOB, UNIQUE (c1(2))) engine=innodb;
|
||||
INSERT INTO t1 (c1) VALUES (-2),(-1),(1),(2),(3),(4),(5);
|
||||
SELECT c1 FROM t1 WHERE 'a' BETWEEN 0 AND (c1);
|
||||
SELECT c1 FROM t1 WHERE '#' BETWEEN c1 AND 0;
|
||||
ALTER TABLE t1 engine=myisam;
|
||||
SELECT c1 FROM t1 WHERE 'a' BETWEEN 0 AND (c1);
|
||||
SELECT c1 FROM t1 WHERE '#' BETWEEN c1 AND 0;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (c1 TINYBLOB, UNIQUE (c1)) engine=innodb;
|
||||
INSERT INTO t1 (c1) VALUES (-2),(-1),(1),(2),(3),(4),(5);
|
||||
SELECT c1 FROM t1 WHERE 'a' BETWEEN 0 AND (c1);
|
||||
SELECT c1 FROM t1 WHERE '#' BETWEEN c1 AND 0;
|
||||
DROP TABLE t1;
|
||||
|
42
mysql-test/main/type_varbinary.result
Normal file
42
mysql-test/main/type_varbinary.result
Normal file
@@ -0,0 +1,42 @@
|
||||
#
|
||||
# MDEV-36235 Incorrect result for BETWEEN over unique blob prefix
|
||||
#
|
||||
CREATE TABLE t1 (c1 VARBINARY(10), UNIQUE (c1));
|
||||
INSERT INTO t1 (c1) VALUES (-2),(-1),(1),(2);
|
||||
SELECT c1 FROM t1 WHERE 'a' BETWEEN 0 AND (c1);
|
||||
c1
|
||||
1
|
||||
2
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
SELECT c1 FROM t1 IGNORE KEY(c1) WHERE 'a' BETWEEN 0 AND (c1);
|
||||
c1
|
||||
1
|
||||
2
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'a'
|
||||
SELECT c1 FROM t1 WHERE '#' BETWEEN c1 AND 0;
|
||||
c1
|
||||
-1
|
||||
-2
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
SELECT c1 FROM t1 IGNORE KEY(c1) WHERE '#' BETWEEN c1 AND 0;
|
||||
c1
|
||||
-2
|
||||
-1
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
Warning 1292 Truncated incorrect DECIMAL value: '#'
|
||||
DROP TABLE t1;
|
10
mysql-test/main/type_varbinary.test
Normal file
10
mysql-test/main/type_varbinary.test
Normal file
@@ -0,0 +1,10 @@
|
||||
--echo #
|
||||
--echo # MDEV-36235 Incorrect result for BETWEEN over unique blob prefix
|
||||
--echo #
|
||||
CREATE TABLE t1 (c1 VARBINARY(10), UNIQUE (c1));
|
||||
INSERT INTO t1 (c1) VALUES (-2),(-1),(1),(2);
|
||||
SELECT c1 FROM t1 WHERE 'a' BETWEEN 0 AND (c1);
|
||||
SELECT c1 FROM t1 IGNORE KEY(c1) WHERE 'a' BETWEEN 0 AND (c1);
|
||||
SELECT c1 FROM t1 WHERE '#' BETWEEN c1 AND 0;
|
||||
SELECT c1 FROM t1 IGNORE KEY(c1) WHERE '#' BETWEEN c1 AND 0;
|
||||
DROP TABLE t1;
|
@@ -2407,3 +2407,26 @@ f::f
|
||||
DROP TABLE t1;
|
||||
SET max_sort_length=DEFAULT;
|
||||
# End of 10.8 tests
|
||||
#
|
||||
# MDEV-36235 Incorrect result for BETWEEN over unique blob prefix
|
||||
#
|
||||
CREATE OR REPLACE TABLE t1 (c1 BINARY(16), UNIQUE (c1));
|
||||
INSERT INTO t1 (c1) VALUES (0x00000000000000000000000000000001);
|
||||
INSERT INTO t1 (c1) VALUES (0x00000000000000000000000000000002);
|
||||
SELECT CAST(c1 AS INET6) FROM t1 WHERE '::1' BETWEEN CAST('::1' AS INET6) AND c1;
|
||||
CAST(c1 AS INET6)
|
||||
::1
|
||||
::2
|
||||
SELECT CAST(c1 AS INET6) FROM t1 IGNORE KEY(c1) WHERE '::1' BETWEEN CAST('::1' AS INET6) AND c1;
|
||||
CAST(c1 AS INET6)
|
||||
::1
|
||||
::2
|
||||
SELECT CAST(c1 AS INET6) FROM t1 WHERE '::2' BETWEEN c1 AND CAST('::2' AS INET6);
|
||||
CAST(c1 AS INET6)
|
||||
::1
|
||||
::2
|
||||
SELECT CAST(c1 AS INET6) FROM t1 IGNORE KEY(c1) WHERE '::2' BETWEEN c1 AND CAST('::2' AS INET6);
|
||||
CAST(c1 AS INET6)
|
||||
::1
|
||||
::2
|
||||
DROP TABLE t1;
|
||||
|
@@ -1741,3 +1741,15 @@ DROP TABLE t1;
|
||||
SET max_sort_length=DEFAULT;
|
||||
|
||||
--echo # End of 10.8 tests
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-36235 Incorrect result for BETWEEN over unique blob prefix
|
||||
--echo #
|
||||
CREATE OR REPLACE TABLE t1 (c1 BINARY(16), UNIQUE (c1));
|
||||
INSERT INTO t1 (c1) VALUES (0x00000000000000000000000000000001);
|
||||
INSERT INTO t1 (c1) VALUES (0x00000000000000000000000000000002);
|
||||
SELECT CAST(c1 AS INET6) FROM t1 WHERE '::1' BETWEEN CAST('::1' AS INET6) AND c1;
|
||||
SELECT CAST(c1 AS INET6) FROM t1 IGNORE KEY(c1) WHERE '::1' BETWEEN CAST('::1' AS INET6) AND c1;
|
||||
SELECT CAST(c1 AS INET6) FROM t1 WHERE '::2' BETWEEN c1 AND CAST('::2' AS INET6);
|
||||
SELECT CAST(c1 AS INET6) FROM t1 IGNORE KEY(c1) WHERE '::2' BETWEEN c1 AND CAST('::2' AS INET6);
|
||||
DROP TABLE t1;
|
||||
|
@@ -1003,6 +1003,23 @@ public:
|
||||
|
||||
class Item_func_between :public Item_func_opt_neg
|
||||
{
|
||||
/*
|
||||
If the types of the arguments to BETWEEN permit, then:
|
||||
|
||||
WHERE const1 BETWEEN expr2 AND field1
|
||||
can be optimized as if it was just:
|
||||
WHERE const1 <= field1
|
||||
|
||||
as expr2 could be an arbitrary expression. More generally,
|
||||
this optimization is permitted if aggregation for comparison
|
||||
for three expressions (const1,const2,field1) and for two
|
||||
expressions (const1,field1) return the same type handler.
|
||||
|
||||
@param [IN] field_item - This is a field from the right side
|
||||
of the BETWEEN operator.
|
||||
*/
|
||||
bool can_optimize_range_const(Item_field *field_item) const;
|
||||
|
||||
protected:
|
||||
SEL_TREE *get_func_mm_tree(RANGE_OPT_PARAM *param,
|
||||
Field *field, Item *value) override;
|
||||
|
@@ -8364,9 +8364,9 @@ SEL_TREE *Item_func_in::get_func_row_mm_tree(RANGE_OPT_PARAM *param,
|
||||
(makes sense only when cond_func is BETWEEN or IN)
|
||||
|
||||
DESCRIPTION
|
||||
For a simple SARGable predicate of the form (f op c), where f is a field and
|
||||
c is a constant, the function builds a conjunction of all SEL_TREES that can
|
||||
be obtained by the substitution of f for all different fields equal to f.
|
||||
For a simple SARGable predicate of the form (f op c), where f is a field
|
||||
and c is a constant, the function builds a conjunction of all SEL_TREES that
|
||||
can be obtained by the substitution of f for all different fields equal to f.
|
||||
|
||||
NOTES
|
||||
If the WHERE condition contains a predicate (fi op c),
|
||||
@@ -8379,24 +8379,26 @@ SEL_TREE *Item_func_in::get_func_row_mm_tree(RANGE_OPT_PARAM *param,
|
||||
and
|
||||
a SEL_TREE for t1.a > 10 will be built for quick select from t1.
|
||||
|
||||
A BETWEEN predicate of the form (fi [NOT] BETWEEN c1 AND c2) is treated
|
||||
in a similar way: we build a conjuction of trees for the results
|
||||
of all substitutions of fi for equal fj.
|
||||
A BETWEEN predicate of the form (fi [NOT] BETWEEN c1 AND c2), where fi
|
||||
is some field, is treated in a similar way: we build a conjuction of
|
||||
trees for the results of all substitutions of fi equal fj.
|
||||
|
||||
Yet a predicate of the form (c BETWEEN f1i AND f2i) is processed
|
||||
differently. It is considered as a conjuction of two SARGable
|
||||
predicates (f1i <= c) and (f2i <=c) and the function get_full_func_mm_tree
|
||||
predicates (f1i <= c) and (c <= f2i) and the function get_full_func_mm_tree
|
||||
is called for each of them separately producing trees for
|
||||
AND j (f1j <=c ) and AND j (f2j <= c)
|
||||
AND j (f1j <= c) and AND j (c <= f2j)
|
||||
After this these two trees are united in one conjunctive tree.
|
||||
It's easy to see that the same tree is obtained for
|
||||
AND j,k (f1j <=c AND f2k<=c)
|
||||
AND j,k (f1j <= c AND c <= f2k)
|
||||
which is equivalent to
|
||||
AND j,k (c BETWEEN f1j AND f2k).
|
||||
|
||||
The validity of the processing of the predicate (c NOT BETWEEN f1i AND f2i)
|
||||
which equivalent to (f1i > c OR f2i < c) is not so obvious. Here the
|
||||
function get_full_func_mm_tree is called for (f1i > c) and (f2i < c)
|
||||
producing trees for AND j (f1j > c) and AND j (f2j < c). Then this two
|
||||
trees are united in one OR-tree. The expression
|
||||
function get_full_func_mm_tree is called for (f1i > c) and called for
|
||||
(f2i < c) producing trees for AND j (f1j > c) and AND j (f2j < c). Then
|
||||
this two trees are united in one OR-tree. The expression
|
||||
(AND j (f1j > c) OR AND j (f2j < c)
|
||||
is equivalent to the expression
|
||||
AND j,k (f1j > c OR f2k < c)
|
||||
@@ -8623,6 +8625,19 @@ SEL_TREE *Item::get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr)
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Item_func_between::can_optimize_range_const(Item_field *field_item) const
|
||||
{
|
||||
const Type_handler *fi_handler= field_item->type_handler_for_comparison();
|
||||
Type_handler_hybrid_field_type cmp(fi_handler);
|
||||
if (cmp.aggregate_for_comparison(args[0]->type_handler_for_comparison()) ||
|
||||
cmp.type_handler() != m_comparator.type_handler())
|
||||
return false; // Cannot optimize range because of type mismatch.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
SEL_TREE *
|
||||
Item_func_between::get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr)
|
||||
{
|
||||
@@ -8648,6 +8663,8 @@ Item_func_between::get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr)
|
||||
if (arguments()[i]->real_item()->type() == Item::FIELD_ITEM)
|
||||
{
|
||||
Item_field *field_item= (Item_field*) (arguments()[i]->real_item());
|
||||
if (!can_optimize_range_const(field_item))
|
||||
continue;
|
||||
SEL_TREE *tmp= get_full_func_mm_tree(param, field_item,
|
||||
(Item*)(intptr) i);
|
||||
if (negated)
|
||||
|
Reference in New Issue
Block a user