Skip to content

Commit 99e8301

Browse files
authored
feat: support retry for [statement|query] error (#244)
* impl Signed-off-by: Eric Fu <fuyufjh@gmail.com> * readme Signed-off-by: Eric Fu <fuyufjh@gmail.com> * minor fixes Signed-off-by: Eric Fu <fuyufjh@gmail.com> --------- Signed-off-by: Eric Fu <fuyufjh@gmail.com>
1 parent c3b9d45 commit 99e8301

File tree

4 files changed

+60
-15
lines changed

4 files changed

+60
-15
lines changed

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,23 @@ SELECT id FROM test;
140140
----
141141
1
142142
143+
query error retry 3 backoff 5s
144+
SELECT id FROM test;
145+
----
146+
database error: table not found
147+
148+
143149
statement ok retry 3 backoff 5s
144150
UPDATE test SET id = 1;
151+
152+
statement error
153+
UPDATE test SET value = value + 1;
154+
----
155+
database error: table not found
145156
```
146157

158+
Due to the limitation of syntax, the retry clause can't be used along with the single-line regex error message extension.
159+
147160
### Extension: Environment variable substitution in query and statement
148161

149162
It needs to be enabled by adding `control substitution on` to the test file.

sqllogictest/src/parser.rs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -755,12 +755,16 @@ fn parse_inner<T: ColumnType>(loc: &Location, script: &str) -> Result<Vec<Record
755755
["statement", res @ ..] => {
756756
let (mut expected, res) = match res {
757757
["ok", retry @ ..] => (StatementExpect::Ok, retry),
758-
["error", err_tokens @ ..] => {
759-
// NOTE: `statement error` can't be used with `retry` now because all the
760-
// tokens after `error` are treated as error message.
761-
let error = ExpectedError::parse_inline_tokens(err_tokens)
762-
.map_err(|e| e.at(loc.clone()))?;
763-
(StatementExpect::Error(error), &[][..])
758+
["error", res @ ..] => {
759+
if res.len() == 4 && res[0] == "retry" && res[2] == "backoff" {
760+
// `statement error retry <num> backoff <duration>`
761+
// To keep syntax simple, let's assume the error message must be multiline.
762+
(StatementExpect::Error(ExpectedError::Empty), res)
763+
} else {
764+
let error = ExpectedError::parse_inline_tokens(res)
765+
.map_err(|e| e.at(loc.clone()))?;
766+
(StatementExpect::Error(error), &[][..])
767+
}
764768
}
765769
["count", count_str, retry @ ..] => {
766770
let count = count_str.parse::<u64>().map_err(|_| {
@@ -799,12 +803,16 @@ fn parse_inner<T: ColumnType>(loc: &Location, script: &str) -> Result<Vec<Record
799803
}
800804
["query", res @ ..] => {
801805
let (mut expected, res) = match res {
802-
["error", err_tokens @ ..] => {
803-
// NOTE: `query error` can't be used with `retry` now because all the tokens
804-
// after `error` are treated as error message.
805-
let error = ExpectedError::parse_inline_tokens(err_tokens)
806-
.map_err(|e| e.at(loc.clone()))?;
807-
(QueryExpect::Error(error), &[][..])
806+
["error", res @ ..] => {
807+
if res.len() == 4 && res[0] == "retry" && res[2] == "backoff" {
808+
// `query error retry <num> backoff <duration>`
809+
// To keep syntax simple, let's assume the error message must be multiline.
810+
(QueryExpect::Error(ExpectedError::Empty), res)
811+
} else {
812+
let error = ExpectedError::parse_inline_tokens(res)
813+
.map_err(|e| e.at(loc.clone()))?;
814+
(QueryExpect::Error(error), &[][..])
815+
}
808816
}
809817
[type_str, res @ ..] => {
810818
let types = type_str

tests/retry/query_retry.slt

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,19 @@ SELECT id FROM test ORDER BY random();
1010
2
1111
3
1212

13-
query I retry 1 backoff 500ms
13+
query I retry 2 backoff 500ms
1414
SELECT id FROM test;
1515
----
16-
1
16+
1
17+
18+
query error retry 2 backoff 500ms
19+
SELECT id FROM test;
20+
----
21+
table not found
22+
23+
24+
query error
25+
SELECT id FROM test;
26+
----
27+
table not found
28+

tests/retry/statement_retry.slt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,16 @@ statement ok retry 3 backoff 5s
22
INSERT INTO test VALUES (1);
33

44
statement count 5 retry 2 backoff 1s
5-
UPDATE test SET value = value + 1;
5+
UPDATE test SET value = value + 1;
6+
7+
statement error retry 2 backoff 500ms
8+
UPDATE test SET value = value + 1;
9+
----
10+
table not found
11+
12+
13+
statement error
14+
UPDATE test SET value = value + 1;
15+
----
16+
table not found
17+

0 commit comments

Comments
 (0)