mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-10228: Delete missing rows with OR conditions
Fix get_quick_keys(): When building range tree from a condition in form keypart1=const AND (keypart2 < 0 OR keypart2>=0) the SEL_ARG for keypart2 represents an interval (-inf, +inf). However, the logic that sets UNIQUE_RANGE flag fails to recognize this, and sets UNIQUE_RANGE flag if (keypart1, keypart2) covered a unique key. As a result, range access executor assumes the interval can have at most one row and only reads the first row from it.
This commit is contained in:
@ -2113,3 +2113,34 @@ a b
|
|||||||
0 0
|
0 0
|
||||||
1 1
|
1 1
|
||||||
drop table t2;
|
drop table t2;
|
||||||
|
#
|
||||||
|
# MDEV-10228: Delete missing rows with OR conditions
|
||||||
|
# (The example uses UPDATE, because UPDATE allows to use index hints
|
||||||
|
# and so it's possible to make an example that works with any storage
|
||||||
|
# engine)
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
key1varchar varchar(14) NOT NULL,
|
||||||
|
key2int int(11) NOT NULL DEFAULT '0',
|
||||||
|
col1 int,
|
||||||
|
PRIMARY KEY (key1varchar,key2int),
|
||||||
|
KEY key1varchar (key1varchar),
|
||||||
|
KEY key2int (key2int)
|
||||||
|
) DEFAULT CHARSET=utf8;
|
||||||
|
insert into t1 values
|
||||||
|
('value1',0, 0),
|
||||||
|
('value1',1, 0),
|
||||||
|
('value1',1000685, 0),
|
||||||
|
('value1',1003560, 0),
|
||||||
|
('value1',1004807, 0);
|
||||||
|
update t1 force index (PRIMARY) set col1=12345
|
||||||
|
where (key1varchar='value1' AND (key2int <=1 OR key2int > 1));
|
||||||
|
# The following must show col1=12345 for all rows:
|
||||||
|
select * from t1;
|
||||||
|
key1varchar key2int col1
|
||||||
|
value1 0 12345
|
||||||
|
value1 1 12345
|
||||||
|
value1 1000685 12345
|
||||||
|
value1 1003560 12345
|
||||||
|
value1 1004807 12345
|
||||||
|
drop table t1;
|
||||||
|
@ -1689,3 +1689,32 @@ insert into t2 values (0, 0, 0, 0), (1, 1, 1, 1);
|
|||||||
analyze table t2;
|
analyze table t2;
|
||||||
select a, b from t2 where (a, b) in ((0, 0), (1, 1));
|
select a, b from t2 where (a, b) in ((0, 0), (1, 1));
|
||||||
drop table t2;
|
drop table t2;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-10228: Delete missing rows with OR conditions
|
||||||
|
--echo # (The example uses UPDATE, because UPDATE allows to use index hints
|
||||||
|
--echo # and so it's possible to make an example that works with any storage
|
||||||
|
--echo # engine)
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
key1varchar varchar(14) NOT NULL,
|
||||||
|
key2int int(11) NOT NULL DEFAULT '0',
|
||||||
|
col1 int,
|
||||||
|
PRIMARY KEY (key1varchar,key2int),
|
||||||
|
KEY key1varchar (key1varchar),
|
||||||
|
KEY key2int (key2int)
|
||||||
|
) DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
insert into t1 values
|
||||||
|
('value1',0, 0),
|
||||||
|
('value1',1, 0),
|
||||||
|
('value1',1000685, 0),
|
||||||
|
('value1',1003560, 0),
|
||||||
|
('value1',1004807, 0);
|
||||||
|
|
||||||
|
update t1 force index (PRIMARY) set col1=12345
|
||||||
|
where (key1varchar='value1' AND (key2int <=1 OR key2int > 1));
|
||||||
|
--echo # The following must show col1=12345 for all rows:
|
||||||
|
select * from t1;
|
||||||
|
drop table t1;
|
||||||
|
@ -10409,8 +10409,10 @@ get_quick_keys(PARAM *param,QUICK_RANGE_SELECT *quick,KEY_PART *key,
|
|||||||
KEY *table_key=quick->head->key_info+quick->index;
|
KEY *table_key=quick->head->key_info+quick->index;
|
||||||
flag=EQ_RANGE;
|
flag=EQ_RANGE;
|
||||||
if ((table_key->flags & HA_NOSAME) &&
|
if ((table_key->flags & HA_NOSAME) &&
|
||||||
|
min_part == key_tree->part &&
|
||||||
key_tree->part == table_key->key_parts-1)
|
key_tree->part == table_key->key_parts-1)
|
||||||
{
|
{
|
||||||
|
DBUG_ASSERT(min_part == max_part);
|
||||||
if ((table_key->flags & HA_NULL_PART_KEY) &&
|
if ((table_key->flags & HA_NULL_PART_KEY) &&
|
||||||
null_part_in_key(key,
|
null_part_in_key(key,
|
||||||
param->min_key,
|
param->min_key,
|
||||||
|
Reference in New Issue
Block a user