BigQuery: Add support for BEGIN (#1718)

This commit is contained in:
Ifeanyi Ubah 2025-02-24 08:34:36 +01:00 committed by GitHub
parent 72312ba82a
commit aab12add36
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 190 additions and 33 deletions

View file

@ -236,6 +236,52 @@ fn parse_big_query_non_reserved_column_alias() {
bigquery().verified_stmt(sql);
}
#[test]
fn parse_at_at_identifier() {
bigquery().verified_stmt("SELECT @@error.stack_trace, @@error.message");
}
#[test]
fn parse_begin() {
let sql = r#"BEGIN SELECT 1; EXCEPTION WHEN ERROR THEN SELECT 2; END"#;
let Statement::StartTransaction {
statements,
exception_statements,
has_end_keyword,
..
} = bigquery().verified_stmt(sql)
else {
unreachable!();
};
assert_eq!(1, statements.len());
assert_eq!(1, exception_statements.unwrap().len());
assert!(has_end_keyword);
bigquery().verified_stmt(
"BEGIN SELECT 1; SELECT 2; EXCEPTION WHEN ERROR THEN SELECT 2; SELECT 4; END",
);
bigquery()
.verified_stmt("BEGIN SELECT 1; EXCEPTION WHEN ERROR THEN SELECT @@error.stack_trace; END");
bigquery().verified_stmt("BEGIN EXCEPTION WHEN ERROR THEN SELECT 2; END");
bigquery().verified_stmt("BEGIN SELECT 1; SELECT 2; EXCEPTION WHEN ERROR THEN END");
bigquery().verified_stmt("BEGIN EXCEPTION WHEN ERROR THEN END");
bigquery().verified_stmt("BEGIN SELECT 1; SELECT 2; END");
bigquery().verified_stmt("BEGIN END");
assert_eq!(
bigquery()
.parse_sql_statements("BEGIN SELECT 1; SELECT 2 END")
.unwrap_err(),
ParserError::ParserError("Expected: ;, found: END".to_string())
);
assert_eq!(
bigquery()
.parse_sql_statements("BEGIN SELECT 1; EXCEPTION WHEN ERROR THEN SELECT 2 END")
.unwrap_err(),
ParserError::ParserError("Expected: ;, found: END".to_string())
);
}
#[test]
fn parse_delete_statement() {
let sql = "DELETE \"table\" WHERE 1";

View file

@ -8343,7 +8343,12 @@ fn lateral_function() {
#[test]
fn parse_start_transaction() {
match verified_stmt("START TRANSACTION READ ONLY, READ WRITE, ISOLATION LEVEL SERIALIZABLE") {
let dialects = all_dialects_except(|d|
// BigQuery does not support this syntax
d.is::<BigQueryDialect>());
match dialects
.verified_stmt("START TRANSACTION READ ONLY, READ WRITE, ISOLATION LEVEL SERIALIZABLE")
{
Statement::StartTransaction { modes, .. } => assert_eq!(
modes,
vec![
@ -8357,7 +8362,7 @@ fn parse_start_transaction() {
// For historical reasons, PostgreSQL allows the commas between the modes to
// be omitted.
match one_statement_parses_to(
match dialects.one_statement_parses_to(
"START TRANSACTION READ ONLY READ WRITE ISOLATION LEVEL SERIALIZABLE",
"START TRANSACTION READ ONLY, READ WRITE, ISOLATION LEVEL SERIALIZABLE",
) {
@ -8372,40 +8377,40 @@ fn parse_start_transaction() {
_ => unreachable!(),
}
verified_stmt("START TRANSACTION");
verified_stmt("BEGIN");
verified_stmt("BEGIN WORK");
verified_stmt("BEGIN TRANSACTION");
dialects.verified_stmt("START TRANSACTION");
dialects.verified_stmt("BEGIN");
dialects.verified_stmt("BEGIN WORK");
dialects.verified_stmt("BEGIN TRANSACTION");
verified_stmt("START TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");
verified_stmt("START TRANSACTION ISOLATION LEVEL READ COMMITTED");
verified_stmt("START TRANSACTION ISOLATION LEVEL REPEATABLE READ");
verified_stmt("START TRANSACTION ISOLATION LEVEL SERIALIZABLE");
dialects.verified_stmt("START TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");
dialects.verified_stmt("START TRANSACTION ISOLATION LEVEL READ COMMITTED");
dialects.verified_stmt("START TRANSACTION ISOLATION LEVEL REPEATABLE READ");
dialects.verified_stmt("START TRANSACTION ISOLATION LEVEL SERIALIZABLE");
// Regression test for https://github.com/sqlparser-rs/sqlparser-rs/pull/139,
// in which START TRANSACTION would fail to parse if followed by a statement
// terminator.
assert_eq!(
parse_sql_statements("START TRANSACTION; SELECT 1"),
dialects.parse_sql_statements("START TRANSACTION; SELECT 1"),
Ok(vec![
verified_stmt("START TRANSACTION"),
verified_stmt("SELECT 1"),
])
);
let res = parse_sql_statements("START TRANSACTION ISOLATION LEVEL BAD");
let res = dialects.parse_sql_statements("START TRANSACTION ISOLATION LEVEL BAD");
assert_eq!(
ParserError::ParserError("Expected: isolation level, found: BAD".to_string()),
res.unwrap_err()
);
let res = parse_sql_statements("START TRANSACTION BAD");
let res = dialects.parse_sql_statements("START TRANSACTION BAD");
assert_eq!(
ParserError::ParserError("Expected: end of statement, found: BAD".to_string()),
res.unwrap_err()
);
let res = parse_sql_statements("START TRANSACTION READ ONLY,");
let res = dialects.parse_sql_statements("START TRANSACTION READ ONLY,");
assert_eq!(
ParserError::ParserError("Expected: transaction mode, found: EOF".to_string()),
res.unwrap_err()

View file

@ -518,23 +518,6 @@ fn parse_start_transaction_with_modifier() {
sqlite_and_generic().verified_stmt("BEGIN DEFERRED");
sqlite_and_generic().verified_stmt("BEGIN IMMEDIATE");
sqlite_and_generic().verified_stmt("BEGIN EXCLUSIVE");
let unsupported_dialects = all_dialects_except(|d| d.supports_start_transaction_modifier());
let res = unsupported_dialects.parse_sql_statements("BEGIN DEFERRED");
assert_eq!(
ParserError::ParserError("Expected: end of statement, found: DEFERRED".to_string()),
res.unwrap_err(),
);
let res = unsupported_dialects.parse_sql_statements("BEGIN IMMEDIATE");
assert_eq!(
ParserError::ParserError("Expected: end of statement, found: IMMEDIATE".to_string()),
res.unwrap_err(),
);
let res = unsupported_dialects.parse_sql_statements("BEGIN EXCLUSIVE");
assert_eq!(
ParserError::ParserError("Expected: end of statement, found: EXCLUSIVE".to_string()),
res.unwrap_err(),
);
}
#[test]