diesel/expression/functions/aggregate_expressions/
over_clause.rs

1use 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
13/// Only aggregate functions allow to use filter
14pub(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)] // not even sure why rustc believes this is public
25#[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}