Skip to content

Commit ee0b686

Browse files
authored
fix: auto commit of ddl not work when calling procedure in transaction (#18753)
* fix: auto commit of ddl not work when calling procedure in transaction * add logic test * fix * add more tests
1 parent 2d1617a commit ee0b686

File tree

9 files changed

+782
-5
lines changed

9 files changed

+782
-5
lines changed

src/query/service/src/interpreters/util.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ use databend_common_sql::Planner;
3333
use futures_util::TryStreamExt;
3434
use itertools::Itertools;
3535

36+
use crate::interpreters::interpreter::auto_commit_if_not_allowed_in_transaction;
3637
use crate::interpreters::InterpreterFactory;
3738
use crate::sessions::QueryContext;
3839

@@ -129,7 +130,10 @@ impl Client for ScriptClient {
129130

130131
let mut planner = Planner::new(ctx.clone());
131132
// In script ignore query level settings.
132-
let (plan, _) = planner.plan_sql(query).await?;
133+
let extras = planner.parse_sql(query)?;
134+
auto_commit_if_not_allowed_in_transaction(ctx.clone(), &extras.statement).await?;
135+
let plan = planner.plan_stmt(&extras.statement, false).await?;
136+
133137
let interpreter = InterpreterFactory::get(ctx.clone(), &plan).await?;
134138
let stream = interpreter.execute(ctx.clone()).await?;
135139
let blocks = stream.try_collect::<Vec<_>>().await?;

tests/compat_fuse/compat-logictest/rbac/fuse_compat_write

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,4 @@ GRANT create sequence on *.* to role 'role1';
5959
statement ok
6060
GRANT create procedure on *.* to role 'role1';
6161

62-
statement ok
63-
unset global enable_experimental_procedure;
62+

tests/sqllogictests/suites/base/15_procedure/15_0002_procedure.test

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,5 +192,3 @@ call procedure p2('x');
192192
statement ok
193193
drop procedure p2(string);
194194

195-
statement ok
196-
unset global enable_experimental_procedure;
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
statement ok
2+
set global enable_experimental_procedure=1;
3+
4+
statement ok
5+
create or replace database test_auto_commit;
6+
7+
statement ok
8+
use test_auto_commit;
9+
10+
statement ok
11+
create table test_table (id int, data string);
12+
13+
statement ok
14+
drop procedure if exists proc_create_table();
15+
16+
statement ok
17+
CREATE PROCEDURE proc_create_table() RETURNS int LANGUAGE SQL AS $$
18+
BEGIN
19+
CREATE TABLE new_table (x int);
20+
INSERT INTO new_table VALUES (42);
21+
RETURN 1;
22+
END;
23+
$$;
24+
25+
statement ok
26+
drop procedure if exists proc_drop_table();
27+
28+
statement ok
29+
CREATE PROCEDURE proc_drop_table() RETURNS int LANGUAGE SQL AS $$
30+
BEGIN
31+
DROP TABLE IF EXISTS new_table;
32+
RETURN 1;
33+
END;
34+
$$;
35+
36+
statement ok
37+
drop procedure if exists proc_only_dml();
38+
39+
statement ok
40+
CREATE PROCEDURE proc_only_dml() RETURNS int LANGUAGE SQL AS $$
41+
BEGIN
42+
INSERT INTO test_table VALUES (2, 'from_proc');
43+
UPDATE test_table SET data = 'updated' WHERE id = 1;
44+
RETURN 1;
45+
END;
46+
$$;
47+
48+
statement ok
49+
begin;
50+
51+
statement ok
52+
insert into test_table values (10, 'txn_data');
53+
54+
statement ok
55+
call procedure proc_create_table();
56+
57+
query I
58+
select count(*) from test_table;
59+
----
60+
1
61+
62+
statement ok
63+
rollback;
64+
65+
query I
66+
select count(*) from test_table;
67+
----
68+
1
69+
70+
statement ok
71+
call procedure proc_drop_table();
72+
73+
statement ok
74+
begin;
75+
76+
statement ok
77+
insert into test_table values (11, 'txn_data2');
78+
79+
statement ok
80+
call procedure proc_only_dml();
81+
82+
query I
83+
select count(*) from test_table;
84+
----
85+
3
86+
87+
statement ok
88+
rollback;
89+
90+
query I
91+
select count(*) from test_table;
92+
----
93+
1
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
statement ok
2+
set global enable_experimental_procedure=1;
3+
4+
statement ok
5+
create or replace table t_rollback_1 (str varchar);
6+
7+
statement ok
8+
drop procedure if exists test_rollback_on_error();
9+
10+
# Test procedure with automatic rollback on division by zero error
11+
statement ok
12+
CREATE PROCEDURE test_rollback_on_error() RETURNS int not null LANGUAGE SQL AS $$
13+
BEGIN
14+
insert into t_rollback_1 (str) values ('a'), ('b');
15+
select 1/0;
16+
RETURN 1;
17+
END;
18+
$$;
19+
20+
# Test error causes rollback - data should not be inserted
21+
statement error
22+
begin;
23+
call procedure test_rollback_on_error();
24+
commit;
25+
26+
query I
27+
select * from t_rollback_1;
28+
----
29+
30+
31+
statement ok
32+
create or replace table t_rollback_1 (str varchar);
33+
34+
statement ok
35+
drop procedure if exists test_rollback_on_syntax_error();
36+
37+
# Test procedure with automatic rollback on syntax error
38+
statement ok
39+
CREATE PROCEDURE test_rollback_on_syntax_error() RETURNS int not null LANGUAGE SQL AS $$
40+
BEGIN
41+
insert into t_rollback_1 (str) values ('a'), ('b');
42+
1;
43+
RETURN 1;
44+
END;
45+
$$;
46+
47+
# Test syntax error causes rollback - data should not be inserted
48+
statement error
49+
begin;
50+
call procedure test_rollback_on_syntax_error();
51+
commit;
52+
53+
query I
54+
select * from t_rollback_1;
55+
----
56+
57+
58+
statement ok
59+
create or replace table t_rollback_1 (str varchar);
60+
61+
statement ok
62+
drop procedure if exists test_rollback_on_column_error();
63+
64+
# Test procedure with automatic rollback on non-existent column error
65+
statement ok
66+
CREATE PROCEDURE test_rollback_on_column_error() RETURNS int not null LANGUAGE SQL AS $$
67+
BEGIN
68+
insert into t_rollback_1 (str) values ('a'), ('b');
69+
select nonexistent from t_rollback_1;
70+
RETURN 1;
71+
END;
72+
$$;
73+
74+
# Test column error causes rollback - data should not be inserted
75+
statement error
76+
begin;
77+
call procedure test_rollback_on_column_error();
78+
commit;
79+
80+
query I
81+
select * from t_rollback_1;
82+
----
83+
84+
85+
statement ok
86+
drop procedure if exists test_rollback_on_error();
87+
88+
statement ok
89+
drop procedure if exists test_rollback_on_syntax_error();
90+
91+
statement ok
92+
drop procedure if exists test_rollback_on_column_error();
93+
94+
statement ok
95+
drop table t_rollback_1;
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
statement ok
2+
set global enable_experimental_procedure=1;
3+
4+
statement ok
5+
create or replace database test_procedure_snapshots;
6+
7+
statement ok
8+
use test_procedure_snapshots;
9+
10+
statement ok
11+
create or replace table t(c int);
12+
13+
###################################
14+
# no snapshots left if tx aborted #
15+
###################################
16+
17+
statement ok
18+
drop procedure if exists test_rollback_no_snapshots();
19+
20+
# Test procedure that will be rolled back - should leave no snapshots
21+
statement ok
22+
CREATE PROCEDURE test_rollback_no_snapshots() RETURNS int not null LANGUAGE SQL AS $$
23+
BEGIN
24+
insert into t values(1);
25+
insert into t values(1);
26+
select 1/0;
27+
RETURN 1;
28+
END;
29+
$$;
30+
31+
statement error
32+
begin;
33+
call procedure test_rollback_no_snapshots();
34+
rollback;
35+
36+
query I
37+
select count() from fuse_snapshot('test_procedure_snapshots', 't');
38+
----
39+
0
40+
41+
#####################################################
42+
# one snapshot left if table mutated multiple times #
43+
#####################################################
44+
45+
statement ok
46+
drop procedure if exists test_commit_one_snapshot();
47+
48+
# Test procedure that commits successfully - should create one snapshot
49+
statement ok
50+
CREATE PROCEDURE test_commit_one_snapshot() RETURNS int not null LANGUAGE SQL AS $$
51+
BEGIN
52+
insert into t values(1);
53+
insert into t values(1);
54+
insert into t values(1);
55+
RETURN 1;
56+
END;
57+
$$;
58+
59+
statement ok
60+
begin;
61+
62+
statement ok
63+
call procedure test_commit_one_snapshot();
64+
65+
statement ok
66+
commit;
67+
68+
query I
69+
select count() from fuse_snapshot('test_procedure_snapshots', 't');
70+
----
71+
1
72+
73+
statement ok
74+
create or replace table transaction(c int);
75+
76+
statement ok
77+
drop procedure if exists test_rollback_no_snapshots();
78+
79+
statement ok
80+
drop procedure if exists test_commit_one_snapshot();
81+
82+
statement ok
83+
drop database test_procedure_snapshots;

0 commit comments

Comments
 (0)