diff --git a/README.md b/README.md index 7032b49..f449e82 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/sqllogictest/src/parser.rs b/sqllogictest/src/parser.rs index 034d5be..2426a0a 100644 --- a/sqllogictest/src/parser.rs +++ b/sqllogictest/src/parser.rs @@ -765,12 +765,16 @@ fn parse_inner(loc: &Location, script: &str) -> Result { 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 backoff ` + // 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::().map_err(|_| { @@ -809,12 +813,16 @@ fn parse_inner(loc: &Location, script: &str) -> Result { 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 backoff ` + // 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 @ ..] => { // query [] [