diesel/expression/functions/aggregate_expressions/
aggregate_filter.rs1use super::AggregateExpression;
2use super::IsAggregateFunction;
3use super::NoWindow;
4use super::aggregate_order::NoOrder;
5use super::over_clause::ValidAggregateFilterForWindow;
6use super::prefix::NoPrefix;
7use crate::Expression;
8use crate::QueryResult;
9use crate::backend::{Backend, SqlDialect, sql_dialect};
10use crate::query_builder::QueryFragment;
11use crate::query_builder::where_clause::NoWhereClause;
12use crate::query_builder::where_clause::WhereAnd;
13use crate::query_builder::{AstPass, QueryId};
14use crate::sql_types::BoolOrNullableBool;
15
16pub struct NoFilter;
#[automatically_derived]
impl ::core::fmt::Debug for NoFilter {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "NoFilter")
}
}
#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for NoFilter { }
#[automatically_derived]
impl ::core::clone::Clone for NoFilter {
#[inline]
fn clone(&self) -> NoFilter { *self }
}
#[automatically_derived]
impl ::core::marker::Copy for NoFilter { }
const _: () =
{
use diesel;
#[allow(non_camel_case_types)]
impl diesel::query_builder::QueryId for NoFilter {
type QueryId = NoFilter<>;
const HAS_STATIC_QUERY_ID: bool = true;
const IS_WINDOW_FUNCTION: bool = false;
}
};
impl<DB> crate::query_builder::QueryFragment<DB> for NoFilter where
DB: crate::backend::Backend + crate::backend::DieselReserveSpecialization
{
fn walk_ast<'b>(&'b self,
_pass: crate::query_builder::AstPass<'_, 'b, DB>)
-> crate::QueryResult<()> {
Ok(())
}
}empty_clause!(NoFilter);
17
18#[derive(const _: () =
{
use diesel;
#[allow(non_camel_case_types)]
impl<P: diesel::query_builder::QueryId> diesel::query_builder::QueryId
for Filter<P> {
type QueryId =
Filter<<P as diesel::query_builder::QueryId>::QueryId>;
const HAS_STATIC_QUERY_ID: bool =
<P as diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID &&
true;
const IS_WINDOW_FUNCTION: bool =
<P as diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION ||
false;
}
};QueryId, #[automatically_derived]
impl<P: ::core::marker::Copy> ::core::marker::Copy for Filter<P> { }Copy, #[automatically_derived]
impl<P: ::core::clone::Clone> ::core::clone::Clone for Filter<P> {
#[inline]
fn clone(&self) -> Filter<P> {
Filter(::core::clone::Clone::clone(&self.0))
}
}Clone, #[automatically_derived]
impl<P: ::core::fmt::Debug> ::core::fmt::Debug for Filter<P> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Filter",
&&self.0)
}
}Debug)]
19pub struct Filter<P>(P);
20
21impl<P, DB> QueryFragment<DB> for Filter<P>
22where
23 Self: QueryFragment<DB, DB::AggregateFunctionExpressions>,
24 DB: Backend,
25{
26 fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
27 <Self as QueryFragment<DB, DB::AggregateFunctionExpressions>>::walk_ast(self, pass)
28 }
29}
30
31impl<P, DB>
32 QueryFragment<
33 DB,
34 sql_dialect::aggregate_function_expressions::PostgresLikeAggregateFunctionExpressions,
35 > for Filter<P>
36where
37 P: QueryFragment<DB>,
38 DB: Backend + SqlDialect<AggregateFunctionExpressions = sql_dialect::aggregate_function_expressions::PostgresLikeAggregateFunctionExpressions>,
39{
40 fn walk_ast<'b>(&'b self, mut pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
41 pass.push_sql(" FILTER (");
42 self.0.walk_ast(pass.reborrow())?;
43 pass.push_sql(")");
44 Ok(())
45 }
46}
47
48pub trait FilterDsl<P> {
49 type Output;
50
51 fn filter(self, f: P) -> Self::Output;
52}
53
54impl<P, T, ST> FilterDsl<P> for T
55where
56 T: IsAggregateFunction,
57 P: Expression<SqlType = ST>,
58 ST: BoolOrNullableBool,
59{
60 type Output =
61 AggregateExpression<T, NoPrefix, NoOrder, Filter<<NoWhereClause as WhereAnd<P>>::Output>>;
62
63 fn filter(self, f: P) -> Self::Output {
64 AggregateExpression {
65 prefix: NoPrefix,
66 function: self,
67 order: NoOrder,
68 filter: Filter(NoWhereClause.and(f)),
69 window: NoWindow,
70 }
71 }
72}
73
74impl<Fn, P, Prefix, Order, F, Window, ST> FilterDsl<P>
75 for AggregateExpression<Fn, Prefix, Order, Filter<F>, Window>
76where
77 P: Expression<SqlType = ST>,
78 ST: BoolOrNullableBool,
79 F: WhereAnd<P>,
80 Filter<<F as WhereAnd<P>>::Output>: ValidAggregateFilterForWindow<Fn, Window>,
81{
82 type Output =
83 AggregateExpression<Fn, Prefix, Order, Filter<<F as WhereAnd<P>>::Output>, Window>;
84
85 fn filter(self, f: P) -> Self::Output {
86 AggregateExpression {
87 prefix: self.prefix,
88 function: self.function,
89 order: self.order,
90 filter: Filter(WhereAnd::<P>::and(self.filter.0, f)),
91 window: self.window,
92 }
93 }
94}
95
96impl<Fn, P, Prefix, Order, Window, ST> FilterDsl<P>
97 for AggregateExpression<Fn, Prefix, Order, NoFilter, Window>
98where
99 P: Expression<SqlType = ST>,
100 ST: BoolOrNullableBool,
101 NoWhereClause: WhereAnd<P>,
102 Filter<<NoWhereClause as WhereAnd<P>>::Output>: ValidAggregateFilterForWindow<Fn, Window>,
103{
104 type Output = AggregateExpression<
105 Fn,
106 Prefix,
107 Order,
108 Filter<<NoWhereClause as WhereAnd<P>>::Output>,
109 Window,
110 >;
111
112 fn filter(self, f: P) -> Self::Output {
113 AggregateExpression {
114 prefix: self.prefix,
115 function: self.function,
116 order: self.order,
117 filter: Filter(WhereAnd::<P>::and(NoWhereClause, f)),
118 window: self.window,
119 }
120 }
121}