Skip to content

Commit c24b0e0

Browse files
authored
Implement ASSERT statement (apache#226)
As supported by PostgreSQL and BigQuery (with some differences between them)
1 parent 5cab189 commit c24b0e0

File tree

4 files changed

+78
-0
lines changed

4 files changed

+78
-0
lines changed

src/ast/mod.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,14 @@ pub enum Statement {
551551
Rollback { chain: bool },
552552
/// CREATE SCHEMA
553553
CreateSchema { schema_name: ObjectName },
554+
555+
/// ASSERT <condition> [AS <message>]
556+
Assert {
557+
condition: Expr,
558+
// AS or ,
559+
separator: String,
560+
message: Option<Expr>,
561+
},
554562
}
555563

556564
impl fmt::Display for Statement {
@@ -810,6 +818,18 @@ impl fmt::Display for Statement {
810818
write!(f, "ROLLBACK{}", if *chain { " AND CHAIN" } else { "" },)
811819
}
812820
Statement::CreateSchema { schema_name } => write!(f, "CREATE SCHEMA {}", schema_name),
821+
Statement::Assert {
822+
condition,
823+
separator,
824+
message,
825+
} => {
826+
write!(f, "ASSERT {}", condition)?;
827+
828+
if let Some(m) = message {
829+
write!(f, " {} {}", separator, m)?;
830+
}
831+
Ok(())
832+
}
813833
}
814834
}
815835
}

src/dialect/keywords.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ define_keywords!(
7979
AS,
8080
ASC,
8181
ASENSITIVE,
82+
ASSERT,
8283
ASYMMETRIC,
8384
AT,
8485
ATOMIC,

src/parser.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ impl Parser {
148148
Keyword::BEGIN => Ok(self.parse_begin()?),
149149
Keyword::COMMIT => Ok(self.parse_commit()?),
150150
Keyword::ROLLBACK => Ok(self.parse_rollback()?),
151+
Keyword::ASSERT => Ok(self.parse_assert()?),
151152
_ => self.expected("an SQL statement", Token::Word(w)),
152153
},
153154
Token::LParen => {
@@ -179,6 +180,22 @@ impl Parser {
179180
}
180181
Ok(expr)
181182
}
183+
pub fn parse_assert(&mut self) -> Result<Statement, ParserError> {
184+
let condition = self.parse_expr()?;
185+
let (separator, message) = if self.consume_token(&Token::Comma) {
186+
(",".to_string(), Some(self.parse_expr()?))
187+
} else if self.parse_keyword(Keyword::AS) {
188+
("AS".to_string(), Some(self.parse_expr()?))
189+
} else {
190+
("".to_string(), None)
191+
};
192+
193+
Ok(Statement::Assert {
194+
condition,
195+
separator,
196+
message,
197+
})
198+
}
182199

183200
/// Parse an expression prefix
184201
pub fn parse_prefix(&mut self) -> Result<Expr, ParserError> {

tests/sqlparser_common.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,6 +1156,46 @@ fn parse_create_table_with_multiple_on_delete_fails() {
11561156
.expect_err("should have failed");
11571157
}
11581158

1159+
#[test]
1160+
fn parse_assert() {
1161+
let sql = "ASSERT (SELECT COUNT(*) FROM table) > 0";
1162+
let ast = one_statement_parses_to(sql, "ASSERT (SELECT COUNT(*) FROM table) > 0");
1163+
match ast {
1164+
Statement::Assert {
1165+
condition: _condition,
1166+
separator,
1167+
message,
1168+
} => {
1169+
assert_eq!(message, None);
1170+
assert_eq!(separator, "");
1171+
}
1172+
_ => unreachable!(),
1173+
}
1174+
}
1175+
1176+
#[test]
1177+
fn parse_assert_message() {
1178+
let sql = "ASSERT (SELECT COUNT(*) FROM table) > 0 AS 'No rows in table'";
1179+
let ast = one_statement_parses_to(
1180+
sql,
1181+
"ASSERT (SELECT COUNT(*) FROM table) > 0 AS 'No rows in table'",
1182+
);
1183+
match ast {
1184+
Statement::Assert {
1185+
condition: _condition,
1186+
message: Some(message),
1187+
separator,
1188+
} => {
1189+
assert_eq!(separator, "AS");
1190+
match message {
1191+
Expr::Value(Value::SingleQuotedString(s)) => assert_eq!(s, "No rows in table"),
1192+
_ => unreachable!(),
1193+
};
1194+
}
1195+
_ => unreachable!(),
1196+
}
1197+
}
1198+
11591199
#[test]
11601200
fn parse_create_schema() {
11611201
let sql = "CREATE SCHEMA X";

0 commit comments

Comments
 (0)