Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support retry for [statement|query] error #244

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,23 @@ SELECT id FROM test;
----
1

query error retry 3 backoff 5s
SELECT id FROM test;
----
database error: table not found


statement ok retry 3 backoff 5s
UPDATE test SET id = 1;

statement error
UPDATE test SET value = value + 1;
----
database error: table not found
```

Due to the limitation of syntax, the retry clause can't be used along with the single-line regex error message extension.

### Extension: Environment variable substitution in query and statement

It needs to be enabled by adding `control substitution on` to the test file.
Expand Down
32 changes: 20 additions & 12 deletions sqllogictest/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -755,12 +755,16 @@ fn parse_inner<T: ColumnType>(loc: &Location, script: &str) -> Result<Vec<Record
["statement", res @ ..] => {
let (mut expected, res) = match res {
["ok", retry @ ..] => (StatementExpect::Ok, retry),
["error", err_tokens @ ..] => {
// NOTE: `statement error` can't be used with `retry` now because all the
// tokens after `error` are treated as error message.
let error = ExpectedError::parse_inline_tokens(err_tokens)
.map_err(|e| e.at(loc.clone()))?;
(StatementExpect::Error(error), &[][..])
["error", res @ ..] => {
if res.len() == 4 && res[0] == "retry" && res[2] == "backoff" {
// `statement error retry <num> backoff <duration>`
// To keep syntax simple, let's assume the error message must be multiline.
(StatementExpect::Error(ExpectedError::Empty), res)
} else {
let error = ExpectedError::parse_inline_tokens(res)
.map_err(|e| e.at(loc.clone()))?;
(StatementExpect::Error(error), &[][..])
}
}
["count", count_str, retry @ ..] => {
let count = count_str.parse::<u64>().map_err(|_| {
Expand Down Expand Up @@ -799,12 +803,16 @@ fn parse_inner<T: ColumnType>(loc: &Location, script: &str) -> Result<Vec<Record
}
["query", res @ ..] => {
let (mut expected, res) = match res {
["error", err_tokens @ ..] => {
// NOTE: `query error` can't be used with `retry` now because all the tokens
// after `error` are treated as error message.
let error = ExpectedError::parse_inline_tokens(err_tokens)
.map_err(|e| e.at(loc.clone()))?;
(QueryExpect::Error(error), &[][..])
["error", res @ ..] => {
if res.len() == 4 && res[0] == "retry" && res[2] == "backoff" {
// `query error retry <num> backoff <duration>`
// To keep syntax simple, let's assume the error message must be multiline.
(QueryExpect::Error(ExpectedError::Empty), res)
} else {
let error = ExpectedError::parse_inline_tokens(res)
.map_err(|e| e.at(loc.clone()))?;
(QueryExpect::Error(error), &[][..])
}
}
[type_str, res @ ..] => {
let types = type_str
Expand Down
16 changes: 14 additions & 2 deletions tests/retry/query_retry.slt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,19 @@ SELECT id FROM test ORDER BY random();
2
3

query I retry 1 backoff 500ms
query I retry 2 backoff 500ms
SELECT id FROM test;
----
1
1

query error retry 2 backoff 500ms
SELECT id FROM test;
----
table not found


query error
SELECT id FROM test;
----
table not found

14 changes: 13 additions & 1 deletion tests/retry/statement_retry.slt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,16 @@ statement ok retry 3 backoff 5s
INSERT INTO test VALUES (1);

statement count 5 retry 2 backoff 1s
UPDATE test SET value = value + 1;
UPDATE test SET value = value + 1;

statement error retry 2 backoff 500ms
UPDATE test SET value = value + 1;
----
table not found


statement error
UPDATE test SET value = value + 1;
----
table not found

Loading