mirror of
https://github.com/MariaDB/server.git
synced 2026-05-06 07:05:33 +02:00
MDEV-5056: Wrong result (extra rows) with materialization+semijoin, IN subqueries
Apply fix suggested by Igor: - When eliminate_item_equal() generates pair-wise equalities from a multi-equality, do generate a "bridge" equality between the first field inside SJM nest and the field that's first in the overall multi-equality.
This commit is contained in:
parent
ea78785b8b
commit
229aa1d4bf
4 changed files with 72 additions and 2 deletions
|
|
@ -2038,6 +2038,27 @@ SELECT * FROM t1 WHERE 8 IN (SELECT MIN(pk) FROM t1) AND (pk = a OR pk = b);
|
|||
pk a b
|
||||
DROP TABLE t1;
|
||||
# End of 5.3 tests
|
||||
#
|
||||
# MDEV-5056: Wrong result (extra rows) with materialization+semijoin, IN subqueries
|
||||
#
|
||||
set @tmp_mdev5056=@@join_cache_level;
|
||||
SET join_cache_level = 2;
|
||||
CREATE TABLE t1 ( c1 VARCHAR(2), c2 VARCHAR(2), INDEX(c1) ) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES
|
||||
('JP','OM'),('VA','JP'),('CA','ML'),('ML','EG'),('DK','CA'),
|
||||
('DK','QA'),('YE','PL'),('TR','ZW'),('DK','SK'),('SK','DK'),
|
||||
('RO','ML'),('ML','BG'),('BG','ZW'),('ZW','GE'),('GE','JP'),
|
||||
('PL','EG'),('QA','YE'),('WF','DK'),('DK','JP'),('EG','OM');
|
||||
CREATE TABLE t2 ( c3 VARCHAR(2), c4 VARCHAR(2) ) ENGINE=MyISAM;
|
||||
INSERT INTO t2 VALUES ('CA','ML'),('IN','HU'),('HU','IN');
|
||||
SELECT * FROM t1 AS alias1, t1 AS alias2
|
||||
WHERE ( alias2.c2, alias1.c1 ) IN ( SELECT c4, c3 FROM t2 ) AND alias1.c1 IN ( SELECT c2 FROM t1 );
|
||||
c1 c2 c1 c2
|
||||
CA ML CA ML
|
||||
CA ML RO ML
|
||||
DROP TABLE t1,t2;
|
||||
set join_cache_level=@tmp_mdev5056;
|
||||
# End of 5.5 tests
|
||||
set @subselect_mat_test_optimizer_switch_value=null;
|
||||
set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
|
||||
set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
|
||||
|
|
|
|||
|
|
@ -2078,3 +2078,24 @@ SELECT * FROM t1 WHERE 8 IN (SELECT MIN(pk) FROM t1) AND (pk = a OR pk = b);
|
|||
pk a b
|
||||
DROP TABLE t1;
|
||||
# End of 5.3 tests
|
||||
#
|
||||
# MDEV-5056: Wrong result (extra rows) with materialization+semijoin, IN subqueries
|
||||
#
|
||||
set @tmp_mdev5056=@@join_cache_level;
|
||||
SET join_cache_level = 2;
|
||||
CREATE TABLE t1 ( c1 VARCHAR(2), c2 VARCHAR(2), INDEX(c1) ) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES
|
||||
('JP','OM'),('VA','JP'),('CA','ML'),('ML','EG'),('DK','CA'),
|
||||
('DK','QA'),('YE','PL'),('TR','ZW'),('DK','SK'),('SK','DK'),
|
||||
('RO','ML'),('ML','BG'),('BG','ZW'),('ZW','GE'),('GE','JP'),
|
||||
('PL','EG'),('QA','YE'),('WF','DK'),('DK','JP'),('EG','OM');
|
||||
CREATE TABLE t2 ( c3 VARCHAR(2), c4 VARCHAR(2) ) ENGINE=MyISAM;
|
||||
INSERT INTO t2 VALUES ('CA','ML'),('IN','HU'),('HU','IN');
|
||||
SELECT * FROM t1 AS alias1, t1 AS alias2
|
||||
WHERE ( alias2.c2, alias1.c1 ) IN ( SELECT c4, c3 FROM t2 ) AND alias1.c1 IN ( SELECT c2 FROM t1 );
|
||||
c1 c2 c1 c2
|
||||
CA ML CA ML
|
||||
CA ML RO ML
|
||||
DROP TABLE t1,t2;
|
||||
set join_cache_level=@tmp_mdev5056;
|
||||
# End of 5.5 tests
|
||||
|
|
|
|||
|
|
@ -1726,3 +1726,29 @@ SELECT * FROM t1 WHERE 8 IN (SELECT MIN(pk) FROM t1) AND (pk = a OR pk = b);
|
|||
DROP TABLE t1;
|
||||
|
||||
--echo # End of 5.3 tests
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-5056: Wrong result (extra rows) with materialization+semijoin, IN subqueries
|
||||
--echo #
|
||||
set @tmp_mdev5056=@@join_cache_level;
|
||||
SET join_cache_level = 2;
|
||||
|
||||
CREATE TABLE t1 ( c1 VARCHAR(2), c2 VARCHAR(2), INDEX(c1) ) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES
|
||||
('JP','OM'),('VA','JP'),('CA','ML'),('ML','EG'),('DK','CA'),
|
||||
('DK','QA'),('YE','PL'),('TR','ZW'),('DK','SK'),('SK','DK'),
|
||||
('RO','ML'),('ML','BG'),('BG','ZW'),('ZW','GE'),('GE','JP'),
|
||||
('PL','EG'),('QA','YE'),('WF','DK'),('DK','JP'),('EG','OM');
|
||||
|
||||
CREATE TABLE t2 ( c3 VARCHAR(2), c4 VARCHAR(2) ) ENGINE=MyISAM;
|
||||
INSERT INTO t2 VALUES ('CA','ML'),('IN','HU'),('HU','IN');
|
||||
|
||||
SELECT * FROM t1 AS alias1, t1 AS alias2
|
||||
WHERE ( alias2.c2, alias1.c1 ) IN ( SELECT c4, c3 FROM t2 ) AND alias1.c1 IN ( SELECT c2 FROM t1 );
|
||||
|
||||
DROP TABLE t1,t2;
|
||||
set join_cache_level=@tmp_mdev5056;
|
||||
|
||||
--echo # End of 5.5 tests
|
||||
|
||||
|
|
|
|||
|
|
@ -12295,12 +12295,14 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
|
|||
/*
|
||||
If we're inside an SJM-nest (current_sjm!=NULL), and the multi-equality
|
||||
doesn't include a constant, we should produce equality with the first
|
||||
of the equals in this SJM.
|
||||
of the equal items in this SJM (except for the first element inside the
|
||||
SJM. For that, we produce the equality with the "head" item).
|
||||
|
||||
In other cases, get the "head" item, which is either first of the
|
||||
equals on top level, or the constant.
|
||||
*/
|
||||
Item *head_item= (!item_const && current_sjm)? current_sjm_head: head;
|
||||
Item *head_item= (!item_const && current_sjm &&
|
||||
current_sjm_head != field_item) ? current_sjm_head: head;
|
||||
Item *head_real_item= head_item->real_item();
|
||||
if (head_real_item->type() == Item::FIELD_ITEM)
|
||||
head_item= head_real_item;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue