1use super::from_clause::AsQuerySource;
2use super::*;
3use crate::backend::DieselReserveSpecialization;
4use crate::expression::grouped::Grouped;
5use crate::expression::operators::{And, Or};
6use crate::expression::*;
7use crate::sql_types::BoolOrNullableBool;
8use alloc::sync::Arc;
9
10pub trait WhereAnd<Predicate> {
13 type Output;
15
16 fn and(self, predicate: Predicate) -> Self::Output;
18}
19
20pub trait WhereOr<Predicate> {
23 type Output;
25
26 fn or(self, predicate: Predicate) -> Self::Output;
28}
29
30#[derive(#[automatically_derived]
impl ::core::fmt::Debug for NoWhereClause {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "NoWhereClause")
}
}Debug, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for NoWhereClause { }
#[automatically_derived]
impl ::core::clone::Clone for NoWhereClause {
#[inline]
fn clone(&self) -> Self { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for NoWhereClause { }Copy, const _: () =
{
use diesel;
#[allow(non_camel_case_types)]
impl diesel::query_builder::QueryId for NoWhereClause {
type QueryId = NoWhereClause<>;
const HAS_STATIC_QUERY_ID: bool = true;
const IS_WINDOW_FUNCTION: bool = false;
}
};QueryId)]
32pub struct NoWhereClause;
33
34impl<DB> QueryFragment<DB> for NoWhereClause
35where
36 DB: Backend + DieselReserveSpecialization,
37{
38 fn walk_ast<'b>(&'b self, _: AstPass<'_, 'b, DB>) -> QueryResult<()> {
39 Ok(())
40 }
41}
42
43impl<Predicate> WhereAnd<Predicate> for NoWhereClause
44where
45 Predicate: Expression,
46 Predicate::SqlType: BoolOrNullableBool,
47{
48 type Output = WhereClause<Predicate>;
49
50 fn and(self, predicate: Predicate) -> Self::Output {
51 WhereClause(predicate)
52 }
53}
54
55impl<Predicate> WhereOr<Predicate> for NoWhereClause
56where
57 Predicate: Expression,
58 Predicate::SqlType: BoolOrNullableBool,
59{
60 type Output = WhereClause<Predicate>;
61
62 fn or(self, predicate: Predicate) -> Self::Output {
63 WhereClause(predicate)
64 }
65}
66
67impl<DB> From<NoWhereClause> for BoxedWhereClause<'_, DB> {
68 fn from(_: NoWhereClause) -> Self {
69 BoxedWhereClause::None
70 }
71}
72
73impl<DB> From<NoWhereClause> for BoxedCloneWhereClause<'_, DB> {
74 fn from(_: NoWhereClause) -> Self {
75 BoxedCloneWhereClause::None
76 }
77}
78
79#[derive(#[automatically_derived]
impl<Expr: ::core::fmt::Debug> ::core::fmt::Debug for WhereClause<Expr> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "WhereClause",
&&self.0)
}
}Debug, #[automatically_derived]
impl<Expr: ::core::clone::Clone> ::core::clone::Clone for WhereClause<Expr> {
#[inline]
fn clone(&self) -> Self {
WhereClause(::core::clone::Clone::clone(&self.0))
}
}Clone, #[automatically_derived]
impl<Expr: ::core::marker::Copy> ::core::marker::Copy for WhereClause<Expr> {
}Copy)]
81pub struct WhereClause<Expr>(Expr);
82
83impl<Expr: diesel::query_builder::QueryId> diesel::query_builder::QueryId for WhereClause<Expr> {
84 type QueryId = WhereClause<<Expr as diesel::query_builder::QueryId>::QueryId>;
85 const HAS_STATIC_QUERY_ID: bool =
86 <Expr as diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID && true;
87
88 const IS_WINDOW_FUNCTION: bool = const {
89 if Expr::IS_WINDOW_FUNCTION {
90 {
::core::panicking::panic_fmt(format_args!("Using window functions in WHERE clauses is not supported"));
};panic!("Using window functions in WHERE clauses is not supported");
91 }
92 false
93 };
94}
95
96impl<DB, Expr> QueryFragment<DB> for WhereClause<Expr>
97where
98 DB: Backend + DieselReserveSpecialization,
99 Expr: QueryFragment<DB>,
100{
101 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
102 out.push_sql(" WHERE ");
103 self.0.walk_ast(out.reborrow())?;
104 Ok(())
105 }
106}
107
108impl<Expr, Predicate> WhereAnd<Predicate> for WhereClause<Expr>
109where
110 Expr: Expression,
111 Expr::SqlType: BoolOrNullableBool,
112 Predicate: Expression,
113 Predicate::SqlType: BoolOrNullableBool,
114{
115 type Output = WhereClause<Grouped<And<Expr, Predicate>>>;
116
117 fn and(self, predicate: Predicate) -> Self::Output {
118 WhereClause(Grouped(And::new(self.0, predicate)))
119 }
120}
121
122impl<Expr, Predicate> WhereOr<Predicate> for WhereClause<Expr>
123where
124 Expr: Expression,
125 Expr::SqlType: BoolOrNullableBool,
126 Predicate: Expression,
127 Predicate::SqlType: BoolOrNullableBool,
128{
129 type Output = WhereClause<Grouped<Or<Expr, Predicate>>>;
130
131 fn or(self, predicate: Predicate) -> Self::Output {
132 WhereClause(Grouped(Or::new(self.0, predicate)))
133 }
134}
135
136impl<'a, DB, Predicate> From<WhereClause<Predicate>> for BoxedWhereClause<'a, DB>
137where
138 DB: Backend,
139 Predicate: QueryFragment<DB> + Send + 'a,
140{
141 fn from(where_clause: WhereClause<Predicate>) -> Self {
142 BoxedWhereClause::Where(Box::new(where_clause.0))
143 }
144}
145
146impl<'a, DB, Predicate> From<WhereClause<Predicate>> for BoxedCloneWhereClause<'a, DB>
147where
148 DB: Backend,
149 Predicate: QueryFragment<DB> + Send + Sync + 'a,
150{
151 fn from(where_clause: WhereClause<Predicate>) -> Self {
152 BoxedCloneWhereClause::Where(Arc::new(where_clause.0))
153 }
154}
155
156pub trait ValidWhereClause<QS> {}
159
160impl<QS> ValidWhereClause<QS> for NoWhereClause {}
161
162impl<QS, Expr> ValidWhereClause<QS> for WhereClause<Expr>
163where
164 Expr: AppearsOnTable<QS::QuerySource>,
165 QS: AsQuerySource,
166{
167}
168
169impl<Expr> ValidWhereClause<NoFromClause> for WhereClause<Expr> where
170 Expr: AppearsOnTable<NoFromClause>
171{
172}
173
174impl<GB> ValidGrouping<GB> for NoWhereClause {
175 type IsAggregate = is_aggregate::Never;
176}
177
178impl<GB, Expr: ValidGrouping<GB>> ValidGrouping<GB> for WhereClause<Expr> {
179 type IsAggregate = Expr::IsAggregate;
180}
181
182#[allow(missing_debug_implementations)] pub enum BoxedWhereClause<'a, DB> {
184 Where(Box<dyn QueryFragment<DB> + Send + 'a>),
185 None,
186}
187
188impl<DB> QueryFragment<DB> for BoxedWhereClause<'_, DB>
189where
190 DB: Backend + DieselReserveSpecialization,
191{
192 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
193 match *self {
194 BoxedWhereClause::Where(ref where_clause) => {
195 out.push_sql(" WHERE ");
196 where_clause.walk_ast(out)
197 }
198 BoxedWhereClause::None => Ok(()),
199 }
200 }
201}
202
203impl<DB> QueryId for BoxedWhereClause<'_, DB> {
204 type QueryId = ();
205
206 const HAS_STATIC_QUERY_ID: bool = false;
207}
208
209impl<'a, DB, Predicate> WhereAnd<Predicate> for BoxedWhereClause<'a, DB>
210where
211 DB: Backend + 'a,
212 Predicate: QueryFragment<DB> + Send + 'a,
213 Grouped<And<Box<dyn QueryFragment<DB> + Send + 'a>, Predicate>>: QueryFragment<DB>,
214{
215 type Output = Self;
216
217 fn and(self, predicate: Predicate) -> Self::Output {
218 use self::BoxedWhereClause::Where;
219
220 match self {
221 Where(where_clause) => Where(Box::new(Grouped(And::new(where_clause, predicate)))),
222 BoxedWhereClause::None => Where(Box::new(predicate)),
223 }
224 }
225}
226
227impl<'a, DB, Predicate> WhereOr<Predicate> for BoxedWhereClause<'a, DB>
228where
229 DB: Backend + 'a,
230 Predicate: QueryFragment<DB> + Send + 'a,
231 Grouped<Or<Box<dyn QueryFragment<DB> + Send + 'a>, Predicate>>: QueryFragment<DB>,
232{
233 type Output = Self;
234
235 fn or(self, predicate: Predicate) -> Self::Output {
236 use self::BoxedWhereClause::Where;
237
238 match self {
239 Where(where_clause) => Where(Box::new(Grouped(Or::new(where_clause, predicate)))),
240 BoxedWhereClause::None => Where(Box::new(predicate)),
241 }
242 }
243}
244
245#[allow(missing_debug_implementations)] pub enum BoxedCloneWhereClause<'a, DB> {
247 Where(Arc<dyn QueryFragment<DB> + Send + Sync + 'a>),
248 None,
249}
250
251impl<DB> Clone for BoxedCloneWhereClause<'_, DB> {
252 fn clone(&self) -> Self {
253 match self {
254 Self::Where(clause) => Self::Where(Arc::clone(clause)),
255 Self::None => Self::None,
256 }
257 }
258}
259
260impl<DB> QueryFragment<DB> for BoxedCloneWhereClause<'_, DB>
261where
262 DB: Backend + DieselReserveSpecialization,
263{
264 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
265 match *self {
266 BoxedCloneWhereClause::Where(ref where_clause) => {
267 out.push_sql(" WHERE ");
268 where_clause.walk_ast(out)
269 }
270 BoxedCloneWhereClause::None => Ok(()),
271 }
272 }
273}
274
275impl<DB> QueryId for BoxedCloneWhereClause<'_, DB> {
276 type QueryId = ();
277
278 const HAS_STATIC_QUERY_ID: bool = false;
279}
280
281impl<'a, DB, Predicate> WhereAnd<Predicate> for BoxedCloneWhereClause<'a, DB>
282where
283 DB: Backend + 'a,
284 Predicate: QueryFragment<DB> + Send + Sync + 'a,
285 Grouped<And<Arc<dyn QueryFragment<DB> + Send + Sync + 'a>, Predicate>>: QueryFragment<DB>,
286{
287 type Output = Self;
288
289 fn and(self, predicate: Predicate) -> Self::Output {
290 use self::BoxedCloneWhereClause::Where;
291
292 match self {
293 Where(where_clause) => Where(Arc::new(Grouped(And::new(where_clause, predicate)))),
294 BoxedCloneWhereClause::None => Where(Arc::new(predicate)),
295 }
296 }
297}
298
299impl<'a, DB, Predicate> WhereOr<Predicate> for BoxedCloneWhereClause<'a, DB>
300where
301 DB: Backend + 'a,
302 Predicate: QueryFragment<DB> + Send + Sync + 'a,
303 Grouped<Or<Arc<dyn QueryFragment<DB> + Send + Sync + 'a>, Predicate>>: QueryFragment<DB>,
304{
305 type Output = Self;
306
307 fn or(self, predicate: Predicate) -> Self::Output {
308 use self::BoxedCloneWhereClause::Where;
309
310 match self {
311 Where(where_clause) => Where(Arc::new(Grouped(Or::new(where_clause, predicate)))),
312 BoxedCloneWhereClause::None => Where(Arc::new(predicate)),
313 }
314 }
315}