1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use std::marker::PhantomData;

use backend::*;
use expression::{AsExpression, Expression, SelectableExpression, NonAggregate};
use pg::{Pg, PgQueryBuilder};
use query_builder::*;
use query_builder::debug::DebugQueryBuilder;
use result::QueryResult;
use types::{Array, HasSqlType};

/// Creates a PostgreSQL `ANY` expression.
///
/// As with most bare functions, this is not exported by default. You can import
/// it specifically from `diesel::expression::any`, or glob import
/// `diesel::expression::dsl::*`
///
/// # Example
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("src/doctest_setup.rs");
/// # use diesel::expression::dsl::*;
/// #
/// # table! {
/// #     users {
/// #         id -> Serial,
/// #         name -> VarChar,
/// #     }
/// # }
/// #
/// # fn main() {
/// #     use self::users::dsl::*;
/// #     let connection = establish_connection();
/// #     connection.execute("INSERT INTO users (name) VALUES ('Jim')").unwrap();
/// let sean = (1, "Sean".to_string());
/// let jim = (3, "Jim".to_string());
/// let data = users.filter(name.eq(any(vec!["Sean", "Jim"])));
/// assert_eq!(Ok(vec![sean, jim]), data.load(&connection));
/// # }
/// ```
pub fn any<ST, T>(vals: T) -> Any<T::Expression, ST> where
    Pg: HasSqlType<ST>,
    T: AsExpression<Array<ST>>,
{
    Any::new(vals.as_expression())
}

#[doc(hidden)]
pub struct Any<Expr, ST> {
    expr: Expr,
    _marker: PhantomData<ST>,
}

impl<Expr, ST> Any<Expr, ST> {
    fn new(expr: Expr) -> Self {
        Any {
            expr: expr,
            _marker: PhantomData,
        }
    }
}

impl<Expr, ST> Expression for Any<Expr, ST> where
    Pg: HasSqlType<ST>,
    Expr: Expression<SqlType=Array<ST>>,
{
    type SqlType = ST;
}

impl<Expr, ST> QueryFragment<Pg> for Any<Expr, ST> where
    Expr: QueryFragment<Pg>,
{
    fn to_sql(&self, out: &mut PgQueryBuilder) -> BuildQueryResult {
        out.push_sql("ANY(");
        try!(self.expr.to_sql(out));
        out.push_sql(")");
        Ok(())
    }

    fn collect_binds(&self, out: &mut <Pg as Backend>::BindCollector) -> QueryResult<()> {
        try!(self.expr.collect_binds(out));
        Ok(())
    }

    fn is_safe_to_cache_prepared(&self) -> bool {
        self.expr.is_safe_to_cache_prepared()
    }
}

impl<Expr, ST> QueryFragment<Debug> for Any<Expr, ST> where
    Expr: QueryFragment<Debug>,
{
    fn to_sql(&self, out: &mut DebugQueryBuilder) -> BuildQueryResult {
        out.push_sql("ANY(");
        try!(self.expr.to_sql(out));
        out.push_sql(")");
        Ok(())
    }

    fn collect_binds(&self, out: &mut <Debug as Backend>::BindCollector) -> QueryResult<()> {
        try!(self.expr.collect_binds(out));
        Ok(())
    }

    fn is_safe_to_cache_prepared(&self) -> bool {
        self.expr.is_safe_to_cache_prepared()
    }
}

impl_query_id!(Any<Expr, ST>);

impl<Expr, ST, QS> SelectableExpression<QS> for Any<Expr, ST> where
    Pg: HasSqlType<ST>,
    Any<Expr, ST>: Expression,
    Expr: SelectableExpression<QS>,
{
}

impl<Expr, ST> NonAggregate for Any<Expr, ST> where
    Expr: NonAggregate,
    Any<Expr, ST>: Expression,
{
}