feat: Convert IS TRUE|FALSE to expression (#499)

This commit is contained in:
Dmitry Patsura 2022-05-24 16:26:50 +03:00 committed by GitHub
parent a6d7a35dac
commit 4070f3ec6e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 20 deletions

View file

@ -233,6 +233,10 @@ pub enum Expr {
},
/// CompositeAccess (postgres) eg: SELECT (information_schema._pg_expandarray(array['i','i'])).n
CompositeAccess { expr: Box<Expr>, key: Ident },
/// `IS FALSE` operator
IsFalse(Box<Expr>),
/// `IS TRUE` operator
IsTrue(Box<Expr>),
/// `IS NULL` operator
IsNull(Box<Expr>),
/// `IS NOT NULL` operator
@ -379,6 +383,8 @@ impl fmt::Display for Expr {
Ok(())
}
Expr::CompoundIdentifier(s) => write!(f, "{}", display_separated(s, ".")),
Expr::IsTrue(ast) => write!(f, "{} IS TRUE", ast),
Expr::IsFalse(ast) => write!(f, "{} IS FALSE", ast),
Expr::IsNull(ast) => write!(f, "{} IS NULL", ast),
Expr::IsNotNull(ast) => write!(f, "{} IS NOT NULL", ast),
Expr::InList {

View file

@ -1155,6 +1155,10 @@ impl<'a> Parser<'a> {
Ok(Expr::IsNull(Box::new(expr)))
} else if self.parse_keywords(&[Keyword::NOT, Keyword::NULL]) {
Ok(Expr::IsNotNull(Box::new(expr)))
} else if self.parse_keywords(&[Keyword::TRUE]) {
Ok(Expr::IsTrue(Box::new(expr)))
} else if self.parse_keywords(&[Keyword::FALSE]) {
Ok(Expr::IsFalse(Box::new(expr)))
} else if self.parse_keywords(&[Keyword::DISTINCT, Keyword::FROM]) {
let expr2 = self.parse_expr()?;
Ok(Expr::IsDistinctFrom(Box::new(expr), Box::new(expr2)))
@ -1162,21 +1166,9 @@ impl<'a> Parser<'a> {
{
let expr2 = self.parse_expr()?;
Ok(Expr::IsNotDistinctFrom(Box::new(expr), Box::new(expr2)))
} else if let Some(right) =
self.parse_one_of_keywords(&[Keyword::TRUE, Keyword::FALSE])
{
let mut val = Value::Boolean(true);
if right == Keyword::FALSE {
val = Value::Boolean(false);
}
Ok(Expr::BinaryOp {
left: Box::new(expr),
op: BinaryOperator::Eq,
right: Box::new(Expr::Value(val)),
})
} else {
self.expected(
"[NOT] NULL or [NOT] DISTINCT FROM TRUE FALSE after IS",
"[NOT] NULL or TRUE|FALSE or [NOT] DISTINCT FROM after IS",
self.peek_token(),
)
}

View file

@ -4768,21 +4768,30 @@ fn parse_position_negative() {
#[test]
fn parse_is_boolean() {
one_statement_parses_to(
"SELECT f from foo where field is true",
"SELECT f FROM foo WHERE field = true",
use self::Expr::*;
let sql = "a IS FALSE";
assert_eq!(
IsFalse(Box::new(Identifier(Ident::new("a")))),
verified_expr(sql)
);
one_statement_parses_to(
"SELECT f from foo where field is false",
"SELECT f FROM foo WHERE field = false",
let sql = "a IS TRUE";
assert_eq!(
IsTrue(Box::new(Identifier(Ident::new("a")))),
verified_expr(sql)
);
verified_stmt("SELECT f FROM foo WHERE field IS TRUE");
verified_stmt("SELECT f FROM foo WHERE field IS FALSE");
let sql = "SELECT f from foo where field is 0";
let res = parse_sql_statements(sql);
assert_eq!(
ParserError::ParserError(
"Expected [NOT] NULL or [NOT] DISTINCT FROM TRUE FALSE after IS, found: 0".to_string()
"Expected [NOT] NULL or TRUE|FALSE or [NOT] DISTINCT FROM after IS, found: 0"
.to_string()
),
res.unwrap_err()
);