1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-07-30 19:23:07 +03:00

MCOL-4868 UPDATE on a ColumnStore table containing an IN-subquery

on a non-ColumnStore table does not work.

As part of MCOL-4617, we moved the in-to-exists predicate creation
and injection from the server into the engine. However, when query
with an IN Subquery contains a non-ColumnStore table, the server
still performs the in-to-exists predicate transformation for the
foreign engine table. This caused ColumnStore's execution plan to
contain incorrect WHERE predicates. As a fix, we call
mutate_optimizer_flags() for the WRITE lock, in addition to the READ
table lock. And in mutate_optimizer_flags(), we change the optimizer
flag from OPTIMIZER_SWITCH_IN_TO_EXISTS to OPTIMIZER_SWITCH_MATERIALIZATION.
This commit is contained in:
Gagan Goel
2021-12-14 19:25:03 -05:00
parent 6144e6ff99
commit 7f456e58cc
6 changed files with 209 additions and 12 deletions

View File

@ -0,0 +1,91 @@
DROP DATABASE IF EXISTS `mcol_4868`;
CREATE DATABASE `mcol_4868`;
USE `mcol_4868`;
CREATE USER IF NOT EXISTS'cejuser'@'localhost' IDENTIFIED BY 'Vagrant1|0000001';
GRANT ALL PRIVILEGES ON *.* TO 'cejuser'@'localhost';
FLUSH PRIVILEGES;
CREATE TABLE test_cs (a INT, b VARCHAR(100)) ENGINE=COLUMNSTORE;
INSERT INTO test_cs VALUES (1,'Test1'), (2,'Test2'), (3,'Test3'), (4,'Test4');
INSERT INTO test_cs VALUES (null,'TestNULL'), (6,NULL), (7,'Test7');
CREATE TABLE test_innodb (a INT, b VARCHAR(100));
INSERT INTO test_innodb VALUES (1,'innodb1'), (2,'innodb2'), (3,'innodb3'), (5, 'innodb5');
SELECT * FROM test_cs;
a b
1 Test1
2 Test2
3 Test3
4 Test4
NULL TestNULL
6 NULL
7 Test7
SELECT * FROM test_innodb;
a b
1 innodb1
2 innodb2
3 innodb3
5 innodb5
SELECT * FROM test_cs WHERE a IN (SELECT a FROM test_innodb);
a b
1 Test1
2 Test2
3 Test3
UPDATE test_cs SET b='Update_cs' WHERE a IN (SELECT a FROM test_innodb);
SELECT * FROM test_cs;
a b
1 Update_cs
2 Update_cs
3 Update_cs
4 Test4
NULL TestNULL
6 NULL
7 Test7
SELECT * FROM test_innodb WHERE a IN (SELECT a FROM test_cs);
a b
1 innodb1
2 innodb2
3 innodb3
UPDATE test_innodb SET b='Update_inno' WHERE a IN (SELECT a FROM test_cs);
SELECT * FROM test_innodb;
a b
1 Update_inno
2 Update_inno
3 Update_inno
5 innodb5
SELECT * FROM test_cs WHERE a IN (SELECT a FROM test_cs);
a b
1 Update_cs
2 Update_cs
3 Update_cs
4 Test4
6 NULL
7 Test7
UPDATE test_cs SET b='Update_cs2' WHERE a IN (SELECT a FROM test_cs);
SELECT * FROM test_cs;
a b
1 Update_cs2
2 Update_cs2
3 Update_cs2
4 Update_cs2
NULL TestNULL
6 Update_cs2
7 Update_cs2
DELETE FROM test_cs WHERE a IN (SELECT a FROM test_innodb);
SELECT * FROM test_cs;
a b
4 Update_cs2
NULL TestNULL
6 Update_cs2
7 Update_cs2
DELETE FROM test_cs;
INSERT INTO test_cs VALUES (1,'Test1'), (2,'Test2'), (3,'Test3'), (4,'Test4');
INSERT INTO test_cs VALUES (null,'TestNULL'), (6,NULL), (7,'Test7');
DELETE FROM test_innodb WHERE a IN (SELECT a FROM test_cs);
SELECT * FROM test_innodb;
a b
5 innodb5
DELETE FROM test_cs WHERE a IN (SELECT a FROM test_cs);
SELECT * FROM test_cs;
a b
NULL TestNULL
DROP USER 'cejuser'@'localhost';
DROP DATABASE `mcol_4868`;

View File

@ -0,0 +1,70 @@
#
# MCOL-4868 UPDATE on a ColumnStore table containing an IN-subquery
# on a non-ColumnStore table does not work.
#
-- source include/have_innodb.inc
-- source ../include/have_columnstore.inc
if (!$MASTER_MYPORT)
{
# Running with --extern
let $MASTER_MYPORT=`SELECT @@port`;
}
--disable_warnings
DROP DATABASE IF EXISTS `mcol_4868`;
--enable_warnings
CREATE DATABASE `mcol_4868`;
USE `mcol_4868`;
#
# Enable cross engine join
# Configure user and password in Columnstore.xml file
#
--exec $MCS_MCSSETCONFIG CrossEngineSupport User 'cejuser'
--exec $MCS_MCSSETCONFIG CrossEngineSupport Password 'Vagrant1|0000001'
--exec $MCS_MCSSETCONFIG CrossEngineSupport Port $MASTER_MYPORT
#
# Create corresponding in the server
#
--disable_warnings
CREATE USER IF NOT EXISTS'cejuser'@'localhost' IDENTIFIED BY 'Vagrant1|0000001';
--enable_warnings
GRANT ALL PRIVILEGES ON *.* TO 'cejuser'@'localhost';
FLUSH PRIVILEGES;
CREATE TABLE test_cs (a INT, b VARCHAR(100)) ENGINE=COLUMNSTORE;
INSERT INTO test_cs VALUES (1,'Test1'), (2,'Test2'), (3,'Test3'), (4,'Test4');
INSERT INTO test_cs VALUES (null,'TestNULL'), (6,NULL), (7,'Test7');
CREATE TABLE test_innodb (a INT, b VARCHAR(100));
INSERT INTO test_innodb VALUES (1,'innodb1'), (2,'innodb2'), (3,'innodb3'), (5, 'innodb5');
SELECT * FROM test_cs;
SELECT * FROM test_innodb;
SELECT * FROM test_cs WHERE a IN (SELECT a FROM test_innodb);
UPDATE test_cs SET b='Update_cs' WHERE a IN (SELECT a FROM test_innodb);
SELECT * FROM test_cs;
SELECT * FROM test_innodb WHERE a IN (SELECT a FROM test_cs);
UPDATE test_innodb SET b='Update_inno' WHERE a IN (SELECT a FROM test_cs);
SELECT * FROM test_innodb;
SELECT * FROM test_cs WHERE a IN (SELECT a FROM test_cs);
UPDATE test_cs SET b='Update_cs2' WHERE a IN (SELECT a FROM test_cs);
SELECT * FROM test_cs;
# Test DELETEs
DELETE FROM test_cs WHERE a IN (SELECT a FROM test_innodb);
SELECT * FROM test_cs;
DELETE FROM test_cs;
INSERT INTO test_cs VALUES (1,'Test1'), (2,'Test2'), (3,'Test3'), (4,'Test4');
INSERT INTO test_cs VALUES (null,'TestNULL'), (6,NULL), (7,'Test7');
DELETE FROM test_innodb WHERE a IN (SELECT a FROM test_cs);
SELECT * FROM test_innodb;
DELETE FROM test_cs WHERE a IN (SELECT a FROM test_cs);
SELECT * FROM test_cs;
# Cleanup
DROP USER 'cejuser'@'localhost';
DROP DATABASE `mcol_4868`;