diesel/expression/functions/aggregate_expressions/
over_clause.rs1use super::aggregate_filter::{Filter, NoFilter};
2use super::aggregate_order::NoOrder;
3use super::partition_by::NoPartition;
4use super::prefix::NoPrefix;
5use super::IsWindowFunction;
6use super::NoFrame;
7use super::WindowFunctionFragment;
8use super::{AggregateExpression, IsAggregateFunction};
9use crate::query_builder::QueryFragment;
10use crate::query_builder::{AstPass, QueryId};
11use crate::QueryResult;
12
13pub(super) trait ValidAggregateFilterForWindow<Fn, Window> {}
15
16impl<Fn, W> ValidAggregateFilterForWindow<Fn, W> for NoFilter {}
17pub struct NoWindow;
#[automatically_derived]
impl ::core::fmt::Debug for NoWindow {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "NoWindow")
}
}
#[automatically_derived]
impl ::core::clone::Clone for NoWindow {
#[inline]
fn clone(&self) -> NoWindow { *self }
}
#[automatically_derived]
impl ::core::marker::Copy for NoWindow { }
const _: () =
{
use diesel;
#[allow(non_camel_case_types)]
impl diesel::query_builder::QueryId for NoWindow {
type QueryId = NoWindow<>;
const HAS_STATIC_QUERY_ID: bool = true;
const IS_WINDOW_FUNCTION: bool = false;
}
};
impl<DB> crate::query_builder::QueryFragment<DB> for NoWindow 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!(NoWindow);
18
19impl<F, Fn> ValidAggregateFilterForWindow<Fn, NoWindow> for Filter<F> {}
20
21impl<DB, T> WindowFunctionFragment<T, DB> for NoWindow where DB: crate::backend::Backend {}
22
23#[derive(#[automatically_derived]
impl<Partition: ::core::clone::Clone, Order: ::core::clone::Clone,
Frame: ::core::clone::Clone> ::core::clone::Clone for
OverClause<Partition, Order, Frame> {
#[inline]
fn clone(&self) -> OverClause<Partition, Order, Frame> {
OverClause {
partition_by: ::core::clone::Clone::clone(&self.partition_by),
order: ::core::clone::Clone::clone(&self.order),
frame_clause: ::core::clone::Clone::clone(&self.frame_clause),
}
}
}Clone, #[automatically_derived]
impl<Partition: ::core::marker::Copy, Order: ::core::marker::Copy,
Frame: ::core::marker::Copy> ::core::marker::Copy for
OverClause<Partition, Order, Frame> {
}Copy, const _: () =
{
use diesel;
#[allow(non_camel_case_types)]
impl<Partition: diesel::query_builder::QueryId,
Order: diesel::query_builder::QueryId,
Frame: diesel::query_builder::QueryId>
diesel::query_builder::QueryId for
OverClause<Partition, Order, Frame> {
type QueryId =
OverClause<<Partition as
diesel::query_builder::QueryId>::QueryId,
<Order as diesel::query_builder::QueryId>::QueryId,
<Frame as diesel::query_builder::QueryId>::QueryId>;
const HAS_STATIC_QUERY_ID: bool =
<Partition as
diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID &&
<Order as
diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID &&
<Frame as
diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID &&
true;
const IS_WINDOW_FUNCTION: bool = true;
}
};QueryId, #[automatically_derived]
impl<Partition: ::core::fmt::Debug, Order: ::core::fmt::Debug,
Frame: ::core::fmt::Debug> ::core::fmt::Debug for
OverClause<Partition, Order, Frame> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f, "OverClause",
"partition_by", &self.partition_by, "order", &self.order,
"frame_clause", &&self.frame_clause)
}
}Debug)]
24#[doc(hidden)] #[diesel(diesel_internal_is_window = true)]
26pub struct OverClause<Partition = NoPartition, Order = NoOrder, Frame = NoFrame> {
27 pub(crate) partition_by: Partition,
28 pub(crate) order: Order,
29 pub(crate) frame_clause: Frame,
30}
31
32impl<F, Fn, Partition, Order, Frame>
33 ValidAggregateFilterForWindow<Fn, OverClause<Partition, Order, Frame>> for Filter<F>
34where
35 Fn: IsAggregateFunction,
36{
37}
38
39impl<Partition, Order, Frame, DB> QueryFragment<DB> for OverClause<Partition, Order, Frame>
40where
41 Partition: QueryFragment<DB>,
42 Order: QueryFragment<DB>,
43 Frame: QueryFragment<DB>,
44 DB: crate::backend::Backend,
45{
46 fn walk_ast<'b>(&'b self, mut pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
47 pass.push_sql(" OVER (");
48 self.partition_by.walk_ast(pass.reborrow())?;
49 self.order.walk_ast(pass.reborrow())?;
50 self.frame_clause.walk_ast(pass.reborrow())?;
51 pass.push_sql(")");
52 Ok(())
53 }
54}
55
56pub trait OverDsl {
57 type Output;
58
59 fn over(self) -> Self::Output;
60}
61
62impl<F> OverDsl for F
63where
64 F: IsWindowFunction,
65{
66 type Output = AggregateExpression<F, NoPrefix, NoOrder, NoFilter, OverClause>;
67
68 fn over(self) -> Self::Output {
69 AggregateExpression {
70 prefix: NoPrefix,
71 function: self,
72 order: NoOrder,
73 filter: NoFilter,
74 window: OverClause {
75 partition_by: NoPartition,
76 order: NoOrder,
77 frame_clause: NoFrame,
78 },
79 }
80 }
81}
82
83impl<Fn, Filter> OverDsl for AggregateExpression<Fn, NoPrefix, NoOrder, Filter, NoWindow>
84where
85 Filter: ValidAggregateFilterForWindow<Fn, OverClause>,
86{
87 type Output = AggregateExpression<Fn, NoPrefix, NoOrder, Filter, OverClause>;
88
89 fn over(self) -> Self::Output {
90 AggregateExpression {
91 prefix: NoPrefix,
92 function: self.function,
93 order: NoOrder,
94 filter: self.filter,
95 window: OverClause {
96 partition_by: NoPartition,
97 order: NoOrder,
98 frame_clause: NoFrame,
99 },
100 }
101 }
102}