Commit 15ef38d2 authored by Sergei Petrunia's avatar Sergei Petrunia

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.
parent 1b5da2ca
......@@ -2113,3 +2113,34 @@ a b
0 0
1 1
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;
select a, b from t2 where (a, b) in ((0, 0), (1, 1));
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;
flag=EQ_RANGE;
if ((table_key->flags & HA_NOSAME) &&
min_part == key_tree->part &&
key_tree->part == table_key->key_parts-1)
{
DBUG_ASSERT(min_part == max_part);
if ((table_key->flags & HA_NULL_PART_KEY) &&
null_part_in_key(key,
param->min_key,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment