mirror of
https://github.com/diesel-rs/diesel.git
synced 2024-10-04 17:47:17 +03:00
Merge pull request #27 from derekprior/dp-is-null
Implement `IS NULL` and `IS NOT NULL`
This commit is contained in:
commit
ac9f71bcd6
@ -16,6 +16,14 @@ pub trait ExpressionMethods: Expression + Sized {
|
||||
NotEq::new(self, other.as_expression())
|
||||
}
|
||||
|
||||
fn is_null(self) -> IsNull<Self> {
|
||||
IsNull::new(self)
|
||||
}
|
||||
|
||||
fn is_not_null(self) -> IsNotNull<Self> {
|
||||
IsNotNull::new(self)
|
||||
}
|
||||
|
||||
fn gt<T: AsExpression<Self::SqlType>>(self, other: T) -> Gt<Self, T::Expression> {
|
||||
Gt::new(self, other.as_expression())
|
||||
}
|
||||
|
@ -47,6 +47,50 @@ macro_rules! infix_predicate {
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! postfix_predicate {
|
||||
($name:ident, $operator:expr) => {
|
||||
postfix_predicate!($name, $operator, $crate::types::Bool);
|
||||
};
|
||||
|
||||
($name:ident, $operator:expr, $return_type:ty) => {
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct $name<T> {
|
||||
expr: T,
|
||||
}
|
||||
|
||||
impl<T> $name<T> {
|
||||
pub fn new(expr: T) -> Self {
|
||||
$name {
|
||||
expr: expr,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> $crate::expression::Expression for $name<T> where
|
||||
T: $crate::expression::Expression,
|
||||
{
|
||||
type SqlType = $return_type;
|
||||
|
||||
fn to_sql(&self, out: &mut $crate::query_builder::QueryBuilder) -> $crate::query_builder::BuildQueryResult {
|
||||
try!(self.expr.to_sql(out));
|
||||
out.push_sql($operator);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, QS> $crate::expression::SelectableExpression<QS> for $name<T> where
|
||||
T: $crate::expression::SelectableExpression<QS>,
|
||||
{
|
||||
}
|
||||
|
||||
impl<T> $crate::expression::NonAggregate for $name<T> where
|
||||
T: $crate::expression::NonAggregate,
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
infix_predicate!(And, " AND ");
|
||||
infix_predicate!(Between, " BETWEEN ");
|
||||
infix_predicate!(Eq, " = ");
|
||||
@ -60,6 +104,9 @@ infix_predicate!(NotEq, " != ");
|
||||
infix_predicate!(NotLike, " NOT LIKE ");
|
||||
infix_predicate!(Or, " OR ");
|
||||
|
||||
postfix_predicate!(IsNull, " IS NULL");
|
||||
postfix_predicate!(IsNotNull, " IS NOT NULL");
|
||||
|
||||
use query_source::Column;
|
||||
use query_builder::*;
|
||||
use super::{Expression, SelectableExpression};
|
||||
|
@ -49,6 +49,40 @@ fn filter_by_equality_on_nullable_columns() {
|
||||
assert_eq!(vec![tess], source.load(&connection).unwrap().collect::<Vec<_>>());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn filter_by_is_not_null_on_nullable_columns() {
|
||||
use schema::users::dsl::*;
|
||||
|
||||
let connection = connection();
|
||||
setup_users_table(&connection);
|
||||
let data = vec![
|
||||
NewUser::new("Derek", Some("red")),
|
||||
NewUser::new("Gordon", None),
|
||||
];
|
||||
connection.insert_returning_count(&users, &data).unwrap();
|
||||
|
||||
let derek = User::with_hair_color(1, "Derek", "red");
|
||||
let source = users.filter(hair_color.is_not_null());
|
||||
assert_eq!(vec![derek], source.load(&connection).unwrap().collect::<Vec<_>>());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn filter_by_is_null_on_nullable_columns() {
|
||||
use schema::users::dsl::*;
|
||||
|
||||
let connection = connection();
|
||||
setup_users_table(&connection);
|
||||
let data = vec![
|
||||
NewUser::new("Derek", Some("red")),
|
||||
NewUser::new("Gordon", None),
|
||||
];
|
||||
connection.insert_returning_count(&users, &data).unwrap();
|
||||
|
||||
let gordon = User::new(2, "Gordon");
|
||||
let source = users.filter(hair_color.is_null());
|
||||
assert_eq!(vec![gordon], source.load(&connection).unwrap().collect::<Vec<_>>());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn filter_after_joining() {
|
||||
use schema::users::name;
|
||||
|
Loading…
Reference in New Issue
Block a user