[MCOL-424] cross engine subquery losing where clause causing incorrect results Created: 2016-11-29  Updated: 2021-06-11  Resolved: 2016-12-02

Status: Closed
Project: MariaDB ColumnStore
Component/s: None
Affects Version/s: None
Fix Version/s: 1.0.6

Type: Bug Priority: Major
Reporter: David Thompson (Inactive) Assignee: Daniel Lee (Inactive)
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates MCOL-437 Cross Join between InnoDB and Columns... Closed
Problem/Incident
causes MCOL-441 Segfault on query after an error Closed
Sprint: 2016-23

 Description   

Query:
SELECT * FROM trans_test t WHERE t.`member_id` IN (SELECT id FROM member_test WHERE id =1)

It is returning all rows from member_test

In info.log on um1, I can see the following:
CAL0000: QUERY to foreign engine: SELECT id FROM member_test

It looks as if the where condition is being excluded

SELECT * FROM trans_test t WHERE t.`member_id` IN (1) yields the correct result. I would expect the same result from the above query.

Steps to repro:

CREATE TABLE `trans_test` (
  `id` int(11) DEFAULT NULL,
  `member_id` int(11) DEFAULT NULL,
  `name` varchar(50) DEFAULT NULL
) ENGINE=Columnstore DEFAULT CHARSET=latin1;
 
/*Data for the table `trans_test` */
 
insert  into `trans_test`(`id`,`member_id`,`name`) values (1,1,'trans 1');
insert  into `trans_test`(`id`,`member_id`,`name`) values (2,2,'trans 2');
insert  into `trans_test`(`id`,`member_id`,`name`) values (3,1,'trans 3');
insert  into `trans_test`(`id`,`member_id`,`name`) values (4,2,'trans 4');
insert  into `trans_test`(`id`,`member_id`,`name`) values (5,1,'trans 5');
 
 
CREATE TABLE `member_test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
 
/*Data for the table `member_test` */
 
insert  into `member_test`(`id`,`name`) values (1,'member 1');
insert  into `member_test`(`id`,`name`) values (2,'member 2');
insert  into `member_test`(`id`,`name`) values (3,'member 3');
 
SELECT * FROM trans_test t WHERE t.`member_id` IN (SELECT id FROM member_test WHERE id =1);



 Comments   
Comment by David Thompson (Inactive) [ 2016-11-29 ]

The following variations do work, so the system must be trying to be smart somewhere..
select * from trans_test where member_id in (select id from member_test where id < 2 );
select * from trans_test where member_id in (select id from member_test where name = 'member 1');
select * from trans_test where member_id = 1;

Comment by David Thompson (Inactive) [ 2016-11-29 ]

I have a suspicion this is to do with aliases, if you update member_test to not have an id column the query behaves correctly (it also behaves the same whether myisam or innodb):

create table member_test2 as select id mt_id, name from member_test;
 
MariaDB [test]> select * from trans_test where member_id  in (select mt_id from member_test2 where mt_id = 1 );
+------+-----------+---------+
| id   | member_id | name    |
+------+-----------+---------+
|    1 |         1 | trans 1 |
|    3 |         1 | trans 3 |
|    5 |         1 | trans 5 |
+------+-----------+---------+
3 rows in set (0.02 sec)

Comment by Andrew Hutchings (Inactive) [ 2016-11-29 ]

The reason appears to be that the initial myisam part of the query is optimized as a primary key match rather than a where condition, so there is no where condition pushed down which the cross engine processor is looking for. In the member_test2 example there are no indexes so there is a where condition to push down.

Whilst I work on a solution a possible workaround is to remove the primary key from these tables.

Comment by Andrew Hutchings (Inactive) [ 2016-11-30 ]

The problem was the where condition wasn't pushed down due to it being an index lookup. I have created a fix which will disable indexes whilst doing the first pass optimization but will use indexes for the cross-join execution or any query on a non-ColumnStore table.

Two possible workarounds if the row count of the MyISAM table is low are to remove indexes or disable them using `USE INDEX()` after the table name in the FROM clause in the subquery.

Comment by Daniel Lee (Inactive) [ 2016-12-02 ]

Build verified: Build from Github

[root@localhost mariadb-columnstore-server]# git show
commit 3795bd4cf42d59b792c473101703911fb53e9297
Merge: 570184c 84714c9
Author: dhall-InfiniDB <david.hall@mariadb.com>
Date: Wed Nov 30 11:42:14 2016 -0600

Merge pull request #18 from mariadb-corporation/MCOL-424

MCOL-424 Disable indexes for cross-engine

[root@localhost mariadb-columnstore-server]# cd mariadb-columnstore-engine/
[root@localhost mariadb-columnstore-engine]# git show
commit 63266938716bd933b80eb03fc8aa4ef10d25eab6
Merge: 691c52c 4efd58d
Author: david hill <david.hill@mariadb.com>
Date: Fri Dec 2 10:03:11 2016 -0600

merge mcol-421 branch

Verified the test case in the bug description
MariaDB [mytest]> SELECT * FROM trans_test t WHERE t.`member_id` IN (SELECT id FROM member_test WHERE id =1);
----------------------

id member_id name

----------------------

1 1 trans 1
3 1 trans 3
5 1 trans 5

----------------------
3 rows in set (0.19 sec)

Generated at Thu Feb 08 02:20:58 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.