diesel/pg/expression/
array_comparison.rs

1use crate::expression::subselect::Subselect;
2use crate::expression::{AsExpression, Expression, TypedExpressionType, ValidGrouping};
3use crate::pg::Pg;
4use crate::query_builder::*;
5use crate::result::QueryResult;
6use crate::sql_types::{Array, SqlType};
7
8/// Creates a PostgreSQL `ANY` expression.
9///
10/// As with most bare functions, this is not exported by default. You can import
11/// it specifically from `diesel::pg::expression::dsl::any`, or `diesel::dsl::any`.
12///
13/// # Example
14///
15/// ```rust
16/// # include!("../../doctest_setup.rs");
17/// # use diesel::dsl::*;
18/// #
19/// # fn main() {
20/// #     use schema::users::dsl::*;
21/// #     let connection = &mut establish_connection();
22/// #     diesel::sql_query("INSERT INTO users (name) VALUES ('Jim')").execute(connection).unwrap();
23/// let sean = (1, "Sean".to_string());
24/// let jim = (3, "Jim".to_string());
25/// let data = users.filter(name.eq(any(vec!["Sean", "Jim"])));
26/// assert_eq!(Ok(vec![sean, jim]), data.load(connection));
27/// # }
28/// ```
29#[deprecated(since = "2.0.0", note = "Use `ExpressionMethods::eq_any` instead")]
30pub fn any<ST, T>(vals: T) -> Any<T::Expression>
31where
32    T: AsArrayExpression<ST>,
33{
34    Any::new(vals.as_expression())
35}
36
37/// Creates a PostgreSQL `ALL` expression.
38///
39/// As with most bare functions, this is not exported by default. You can import
40/// it specifically as `diesel::pg::expression::dsl::all`, or `diesel::dsl::all`.
41///
42/// # Example
43///
44/// ```rust
45/// # include!("../../doctest_setup.rs");
46/// # use diesel::dsl::*;
47/// #
48/// # fn main() {
49/// #     use schema::users::dsl::*;
50/// #     let connection = &mut establish_connection();
51/// #     diesel::sql_query("INSERT INTO users (name) VALUES ('Jim')").execute(connection).unwrap();
52/// let tess = (2, "Tess".to_string());
53/// let data = users.filter(name.ne(all(vec!["Sean", "Jim"])));
54/// assert_eq!(Ok(vec![tess]), data.load(connection));
55/// # }
56/// ```
57#[deprecated(since = "2.0.0", note = "Use `ExpressionMethods::ne_all` instead")]
58pub fn all<ST, T>(vals: T) -> All<T::Expression>
59where
60    T: AsArrayExpression<ST>,
61{
62    All::new(vals.as_expression())
63}
64
65#[doc(hidden)]
66#[derive(Debug, Copy, Clone, QueryId, ValidGrouping)]
67pub struct Any<Expr> {
68    expr: Expr,
69}
70
71impl<Expr> Any<Expr> {
72    fn new(expr: Expr) -> Self {
73        Any { expr: expr }
74    }
75}
76
77impl<Expr, ST> Expression for Any<Expr>
78where
79    Expr: Expression<SqlType = Array<ST>>,
80    ST: SqlType + TypedExpressionType,
81{
82    type SqlType = ST;
83}
84
85impl<Expr> QueryFragment<Pg> for Any<Expr>
86where
87    Expr: QueryFragment<Pg>,
88{
89    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, Pg>) -> QueryResult<()> {
90        out.push_sql("ANY(");
91        self.expr.walk_ast(out.reborrow())?;
92        out.push_sql(")");
93        Ok(())
94    }
95}
96
97impl_selectable_expression!(Any<Expr>);
98
99#[doc(hidden)]
100#[derive(Debug, Copy, Clone, QueryId, ValidGrouping)]
101pub struct All<Expr> {
102    expr: Expr,
103}
104
105impl<Expr> All<Expr> {
106    fn new(expr: Expr) -> Self {
107        All { expr: expr }
108    }
109}
110
111impl<Expr, ST> Expression for All<Expr>
112where
113    Expr: Expression<SqlType = Array<ST>>,
114    ST: SqlType + TypedExpressionType,
115{
116    type SqlType = ST;
117}
118
119impl<Expr> QueryFragment<Pg> for All<Expr>
120where
121    Expr: QueryFragment<Pg>,
122{
123    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, Pg>) -> QueryResult<()> {
124        out.push_sql("ALL(");
125        self.expr.walk_ast(out.reborrow())?;
126        out.push_sql(")");
127        Ok(())
128    }
129}
130
131impl_selectable_expression!(All<Expr>);
132
133pub trait AsArrayExpression<ST: 'static> {
134    type Expression: Expression<SqlType = Array<ST>>;
135
136    // This method is part of the public API
137    // we won't change it to appease a clippy lint
138    #[allow(clippy::wrong_self_convention)]
139    fn as_expression(self) -> Self::Expression;
140}
141
142impl<ST, T> AsArrayExpression<ST> for T
143where
144    ST: 'static,
145    T: AsExpression<Array<ST>>,
146{
147    type Expression = <T as AsExpression<Array<ST>>>::Expression;
148
149    fn as_expression(self) -> Self::Expression {
150        <T as AsExpression<Array<ST>>>::as_expression(self)
151    }
152}
153
154impl<ST, F, S, D, W, O, LOf, G, H, LC> AsArrayExpression<ST>
155    for SelectStatement<F, S, D, W, O, LOf, G, H, LC>
156where
157    ST: 'static,
158    Self: SelectQuery<SqlType = ST>,
159{
160    type Expression = Subselect<Self, Array<ST>>;
161
162    fn as_expression(self) -> Self::Expression {
163        Subselect::new(self)
164    }
165}
166
167impl<ST, QS, DB, GB> AsArrayExpression<ST> for BoxedSelectStatement<'_, ST, QS, DB, GB>
168where
169    ST: 'static,
170    Self: SelectQuery<SqlType = ST>,
171{
172    type Expression = Subselect<Self, Array<ST>>;
173
174    fn as_expression(self) -> Self::Expression {
175        Subselect::new(self)
176    }
177}