diff --git a/src/common.rs b/src/common.rs index 1d6cd4d..8c8b92f 100644 --- a/src/common.rs +++ b/src/common.rs @@ -219,6 +219,7 @@ pub enum Operator { In, NotIn, Is, + IsNot } impl Display for Operator { @@ -237,6 +238,7 @@ impl Display for Operator { Operator::LessOrEqual => "<=", Operator::In => "IN", Operator::NotIn => "NOT IN", + Operator::IsNot => "IS NOT", Operator::Is => "IS", }; write!(f, "{}", op) diff --git a/src/condition.rs b/src/condition.rs index a210b7a..7a3a739 100644 --- a/src/condition.rs +++ b/src/condition.rs @@ -206,15 +206,13 @@ fn is_null(i: &[u8]) -> IResult<&[u8], (Operator, ConditionExpression)> { tag_no_case("null"), ))(i)?; - // XXX(malte): bit of a hack; would consumers ever need to know - // about "IS NULL" vs. "= NULL"? Ok(( remaining_input, ( if not.is_some() { - Operator::NotEqual + Operator::IsNot } else { - Operator::Equal + Operator::Is }, ConditionExpression::Base(ConditionBase::Literal(Literal::Null)), ), @@ -838,11 +836,34 @@ mod tests { let res = condition_expr(cond.as_bytes()); let expected = - flat_condition_tree(Operator::Equal, Field("bar".into()), Literal(Literal::Null)); + flat_condition_tree(Operator::Is, Field("bar".into()), Literal(Literal::Null)); assert_eq!(res.unwrap().1, expected); let cond = "bar IS NOT NULL"; + let res = condition_expr(cond.as_bytes()); + let expected = flat_condition_tree( + Operator::IsNot, + Field("bar".into()), + Literal(Literal::Null), + ); + assert_eq!(res.unwrap().1, expected); + } + + #[test] + fn null_equality() { + use common::Literal; + use ConditionBase::*; + + let cond = "bar = NULL"; + + let res = condition_expr(cond.as_bytes()); + let expected = + flat_condition_tree(Operator::Equal, Field("bar".into()), Literal(Literal::Null)); + assert_eq!(res.unwrap().1, expected); + + let cond = "bar != NULL"; + let res = condition_expr(cond.as_bytes()); let expected = flat_condition_tree( Operator::NotEqual, @@ -903,7 +924,7 @@ mod tests { ConditionExpression::LogicalOp(ConditionTree { operator: Operator::And, left: Box::new(flat_condition_tree( - Operator::Equal, + Operator::Is, Field("parent_comments.user_id".into()), Literal(Literal::Null), )), @@ -922,7 +943,7 @@ mod tests { ConditionExpression::LogicalOp(ConditionTree { operator: Operator::Or, left: Box::new(flat_condition_tree( - Operator::Equal, + Operator::Is, Field("parent_comments.id".into()), Literal(Literal::Null), )), diff --git a/src/select.rs b/src/select.rs index 8735e95..0763684 100644 --- a/src/select.rs +++ b/src/select.rs @@ -936,7 +936,7 @@ mod tests { left: Box::new(ComparisonOp(ConditionTree { left: Box::new(Base(Field(Column::from("votes.story_id")))), right: Box::new(Base(Literal(Literal::Null))), - operator: Operator::Equal, + operator: Operator::Is, })), right: Box::new(ComparisonOp(ConditionTree { left: Box::new(Base(Field(Column::from("votes.vote")))),