提交 ea99be98 编写于 作者: L lihongjian 提交者: mergify[bot]

fix(tianmu)Fix delete from Multiple-Table, Failed to delete the data (#663)(#678)

Cause:
At present, the primary key of the tianmu engine does not fully support delete and update statements.
Temporary solution:
Modify the execution plan of the SQL layer so that the delete and update statements do not follow the primary key logic
上级 454c9c48
......@@ -198,19 +198,16 @@ select * from t11;
a b
0 10
1 11
2 12
select * from t12;
a b
33 10
0 11
2 12
delete from t11 where t11.b <> (select b from t2 where t11.a < t2.a);
ERROR 21000: Subquery returns more than 1 row
select * from t11;
a b
0 10
1 11
2 12
delete ignore from t11 where t11.b <> (select b from t2 where t11.a < t2.a);
Warnings:
Warning 1242 Subquery returns more than 1 row
......@@ -263,9 +260,6 @@ a b a b a b
delete t2.*,t3.* from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b;
select * from t3;
a b
1 1
2 1
1 3
drop table t1,t2,t3;
create table t1(a date not null)ENGINE=TIANMU;
insert into t1 values (0);
......
create table t11 (a int NOT NULL, b int, primary key (a))ENGINE=TIANMU;
create table t12 (a int NOT NULL, b int, primary key (a))ENGINE=TIANMU;
insert into t11 values (0, 10),(1, 11),(2, 12);
insert into t12 values (33, 10),(0, 11),(2, 12);
explain select t11.*,t12.* from t11,t12 where t11.a = t12.a;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t11 NULL ALL PRIMARY NULL NULL NULL 3 100.00 NULL
1 SIMPLE t12 NULL eq_ref PRIMARY PRIMARY 4 test.t11.a 1 100.00 NULL
select t11.*,t12.* from t11,t12 where t11.a = t12.a;
a b a b
0 10 0 11
2 12 2 12
explain delete t11.*,t12.* from t11,t12 where t11.a = t12.a;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 DELETE t11 NULL ALL NULL NULL NULL NULL 3 100.00 NULL
1 DELETE t12 NULL ALL NULL NULL NULL NULL 3 33.33 Using where
delete t11.*,t12.* from t11,t12 where t11.a = t12.a;
select * from t11;
a b
1 11
select * from t12;
a b
33 10
drop table t11,t12;
CREATE TABLE t1 (a int not null,b int not null)ENGINE=TIANMU;
CREATE TABLE t2 (a int not null, b int not null, primary key (a,b))ENGINE=TIANMU;
CREATE TABLE t3 (a int not null, b int not null, primary key (a,b))ENGINE=TIANMU;
insert into t1 values (1,1),(2,1),(1,3);
insert into t2 values (1,1),(2,2),(3,3);
insert into t3 values (1,1),(2,1),(1,3);
delete t2.*,t3.* from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b;
select * from t1;
a b
1 1
2 1
1 3
select * from t2;
a b
3 3
select * from t3;
a b
drop table t1,t2,t3;
CREATE TABLE t1 (sku int PRIMARY KEY, pr int)engine=tianmu;
CREATE TABLE t2 (sku int PRIMARY KEY, sppr int, name varchar(255))engine=tianmu;
INSERT INTO t1 VALUES
(10, 10), (20, 10), (30, 20), (40, 30), (50, 10), (60, 10);
INSERT INTO t2 VALUES
(10, 10, 'aaa'), (20, 10, 'bbb'), (30, 10, 'ccc'), (40, 20, 'ddd'),
(50, 10, 'eee'), (60, 20, 'fff'), (70, 20, 'ggg'), (80, 30, 'hhh');
SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr
FROM t2, t1 WHERE t2.sku=20 AND (t2.sku=t1.sku OR t2.sppr=t1.sku);
sku sppr name sku pr
20 10 bbb 10 10
20 10 bbb 20 10
delete t2,t1
FROM t2, t1 WHERE t2.sku=20 AND (t2.sku=t1.sku OR t2.sppr=t1.sku);
SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr
FROM t2, t1 WHERE t2.sku=20 AND (t2.sku=t1.sku OR t2.sppr=t1.sku);
sku sppr name sku pr
drop table t1,t2;
CREATE TABLE t1 (sku int PRIMARY KEY, pr int)engine=tianmu;
CREATE TABLE t2 (sku int PRIMARY KEY, sppr int, name varchar(255))engine=tianmu;
INSERT INTO t1 VALUES
(10, 10), (20, 10), (30, 20), (40, 30), (50, 10), (60, 10);
INSERT INTO t2 VALUES
(10, 10, 'aaa'), (20, 10, 'bbb'), (30, 10, 'ccc'), (40, 20, 'ddd'),
(50, 10, 'eee'), (60, 20, 'fff'), (70, 20, 'ggg'), (80, 30, 'hhh');
SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr
FROM t1,t2 WHERE
t1.sku=10 AND
(t2.sku=20 AND
(t2.sku=t1.sku OR
t2.sppr=t1.sku));
sku sppr name sku pr
20 10 bbb 10 10
delete t1,t2
FROM t1,t2 WHERE
t1.sku=10 AND
(t2.sku=20 AND
(t2.sku=t1.sku OR
t2.sppr=t1.sku));
SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr
FROM t1,t2 WHERE
t1.sku=10 AND
(t2.sku=20 AND
(t2.sku=t1.sku OR
t2.sppr=t1.sku));
sku sppr name sku pr
drop table t1,t2;
--source include/have_tianmu.inc
create table t11 (a int NOT NULL, b int, primary key (a))ENGINE=TIANMU;
create table t12 (a int NOT NULL, b int, primary key (a))ENGINE=TIANMU;
insert into t11 values (0, 10),(1, 11),(2, 12);
insert into t12 values (33, 10),(0, 11),(2, 12);
--disable_warnings
explain select t11.*,t12.* from t11,t12 where t11.a = t12.a;
--enable_warnings
select t11.*,t12.* from t11,t12 where t11.a = t12.a;
--disable_warnings
explain delete t11.*,t12.* from t11,t12 where t11.a = t12.a;
--disable_warnings
delete t11.*,t12.* from t11,t12 where t11.a = t12.a;
select * from t11;
select * from t12;
drop table t11,t12;
CREATE TABLE t1 (a int not null,b int not null)ENGINE=TIANMU;
CREATE TABLE t2 (a int not null, b int not null, primary key (a,b))ENGINE=TIANMU;
CREATE TABLE t3 (a int not null, b int not null, primary key (a,b))ENGINE=TIANMU;
insert into t1 values (1,1),(2,1),(1,3);
insert into t2 values (1,1),(2,2),(3,3);
insert into t3 values (1,1),(2,1),(1,3);
delete t2.*,t3.* from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b;
select * from t1;
select * from t2;
select * from t3;
drop table t1,t2,t3;
CREATE TABLE t1 (sku int PRIMARY KEY, pr int)engine=tianmu;
CREATE TABLE t2 (sku int PRIMARY KEY, sppr int, name varchar(255))engine=tianmu;
INSERT INTO t1 VALUES
(10, 10), (20, 10), (30, 20), (40, 30), (50, 10), (60, 10);
INSERT INTO t2 VALUES
(10, 10, 'aaa'), (20, 10, 'bbb'), (30, 10, 'ccc'), (40, 20, 'ddd'),
(50, 10, 'eee'), (60, 20, 'fff'), (70, 20, 'ggg'), (80, 30, 'hhh');
SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr
FROM t2, t1 WHERE t2.sku=20 AND (t2.sku=t1.sku OR t2.sppr=t1.sku);
delete t2,t1
FROM t2, t1 WHERE t2.sku=20 AND (t2.sku=t1.sku OR t2.sppr=t1.sku);
SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr
FROM t2, t1 WHERE t2.sku=20 AND (t2.sku=t1.sku OR t2.sppr=t1.sku);
drop table t1,t2;
CREATE TABLE t1 (sku int PRIMARY KEY, pr int)engine=tianmu;
CREATE TABLE t2 (sku int PRIMARY KEY, sppr int, name varchar(255))engine=tianmu;
INSERT INTO t1 VALUES
(10, 10), (20, 10), (30, 20), (40, 30), (50, 10), (60, 10);
INSERT INTO t2 VALUES
(10, 10, 'aaa'), (20, 10, 'bbb'), (30, 10, 'ccc'), (40, 20, 'ddd'),
(50, 10, 'eee'), (60, 20, 'fff'), (70, 20, 'ggg'), (80, 30, 'hhh');
SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr
FROM t1,t2 WHERE
t1.sku=10 AND
(t2.sku=20 AND
(t2.sku=t1.sku OR
t2.sppr=t1.sku));
delete t1,t2
FROM t1,t2 WHERE
t1.sku=10 AND
(t2.sku=20 AND
(t2.sku=t1.sku OR
t2.sppr=t1.sku));
SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr
FROM t1,t2 WHERE
t1.sku=10 AND
(t2.sku=20 AND
(t2.sku=t1.sku OR
t2.sppr=t1.sku));
drop table t1,t2;
\ No newline at end of file
......@@ -5126,7 +5126,19 @@ bool JOIN::make_join_plan()
// Build the key access information, which is the basis for ref access.
if (where_cond || select_lex->outer_join)
{
if (update_ref_and_keys(thd, &keyuse_array, join_tab, tables, where_cond,
/*
The primary key of the tianmu engine does not support delete and update statements.
The following codes can be deleted after subsequent support
*/
TABLE *const table= join_tab->table();
bool tianmu_engine = table->s->db_type() ? table->s->db_type()->db_type == DB_TYPE_TIANMU: false;
enum_sql_command sqlCommand = thd->lex->sql_command;
bool tianmuDeleteOrUpdate = (tianmu_engine && (sqlCommand == SQLCOM_DELETE ||
sqlCommand == SQLCOM_DELETE_MULTI ||
sqlCommand == SQLCOM_UPDATE ||
sqlCommand == SQLCOM_UPDATE_MULTI));
if (!tianmuDeleteOrUpdate && update_ref_and_keys(thd, &keyuse_array, join_tab, tables, where_cond,
cond_equal, ~select_lex->outer_join, select_lex,
&sargables))
DBUG_RETURN(true);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册