on da76712 help sign in
rel8/src/Rel8/Expr/Window.hs
121 lines 4.1 kB history raw
1module Rel8.Expr.Window
2 ( cumulative
3 , rowNumber
4 , rank
5 , denseRank
6 , percentRank
7 , cumeDist
8 , ntile
9 , lag
10 , lead
11 , firstValue
12 , lastValue
13 , nthValue
14 )
15where
17-- base
18import Data.Int ( Int32, Int64 )
19import Prelude
21-- opaleye
22import qualified Opaleye.Internal.Aggregate as Opaleye
23import qualified Opaleye.Internal.PackMap as Opaleye
24import qualified Opaleye.Internal.Window as Opaleye
25import qualified Opaleye.Window as Opaleye
27-- profunctors
28import Data.Profunctor (dimap)
30-- rel8
31import Rel8.Aggregate ( Aggregate( Aggregate ) )
32import Rel8.Expr ( Expr )
33import Rel8.Expr.Opaleye ( fromColumn, fromPrimExpr, toColumn, toPrimExpr )
34import Rel8.Schema.Null ( Nullify )
35import Rel8.Window ( Window( Window ) )
38cumulative :: (a -> Aggregate b) -> Window a (Expr b)
39cumulative f =
40 fromWindowFunction $ Opaleye.aggregatorWindowFunction (fromAggregate f) id
43-- | [@row_number()@](https://www.postgresql.org/docs/current/functions-window.html)
44rowNumber :: Window a (Expr Int64)
45rowNumber = fromWindowFunction $ fromPrimExpr . fromColumn <$> Opaleye.rowNumber
48-- | [@rank()@](https://www.postgresql.org/docs/current/functions-window.html)
49rank :: Window a (Expr Int64)
50rank = fromWindowFunction $ fromPrimExpr . fromColumn <$> Opaleye.rank
53-- | [@dense_rank()@](https://www.postgresql.org/docs/current/functions-window.html)
54denseRank :: Window a (Expr Int64)
55denseRank = fromWindowFunction $ fromPrimExpr . fromColumn <$> Opaleye.denseRank
58-- | [@percent_rank()@](https://www.postgresql.org/docs/current/functions-window.html)
59percentRank :: Window a (Expr Double)
60percentRank = fromWindowFunction $ fromPrimExpr . fromColumn <$> Opaleye.percentRank
63-- | [@cume_dist()@](https://www.postgresql.org/docs/current/functions-window.html)
64cumeDist :: Window a (Expr Double)
65cumeDist = fromWindowFunction $ fromPrimExpr . fromColumn <$> Opaleye.cumeDist
68-- | [@ntile(num_buckets)@](https://www.postgresql.org/docs/current/functions-window.html)
69ntile :: Expr Int32 -> Window a (Expr Int32)
70ntile buckets = fromWindowFunction $ fromPrimExpr . fromColumn <$>
71 Opaleye.ntile (toColumn (toPrimExpr buckets))
74-- | [@lag(value, offset, default)@](https://www.postgresql.org/docs/current/functions-window.html)
75lag :: Expr Int32 -> Expr a -> Window (Expr a) (Expr a)
76lag offset def =
77 fromWindowFunction $
78 dimap (toColumn . toPrimExpr) (fromPrimExpr . fromColumn) $
79 Opaleye.lag (toColumn (toPrimExpr offset)) (toColumn (toPrimExpr def))
82-- | [@lead(value, offset, default)@](https://www.postgresql.org/docs/current/functions-window.html)
83lead :: Expr Int32 -> Expr a -> Window (Expr a) (Expr a)
84lead offset def =
85 fromWindowFunction $
86 dimap (toColumn . toPrimExpr) (fromPrimExpr . fromColumn) $
87 Opaleye.lead (toColumn (toPrimExpr offset)) (toColumn (toPrimExpr def))
90-- | [@first_value(value)@](https://www.postgresql.org/docs/current/functions-window.html)
91firstValue :: Window (Expr a) (Expr a)
92firstValue =
93 fromWindowFunction $
94 dimap (toColumn . toPrimExpr) (fromPrimExpr . fromColumn)
95 Opaleye.firstValue
98-- | [@last_value(value)@](https://www.postgresql.org/docs/current/functions-window.html)
99lastValue :: Window (Expr a) (Expr a)
100lastValue =
101 fromWindowFunction $
102 dimap (toColumn . toPrimExpr) (fromPrimExpr . fromColumn)
103 Opaleye.lastValue
106-- | [@nth_value(value, n)@](https://www.postgresql.org/docs/current/functions-window.html)
107nthValue :: Expr Int32 -> Window (Expr a) (Expr (Nullify a))
108nthValue n =
109 fromWindowFunction $
110 dimap (toColumn . toPrimExpr) (fromPrimExpr . fromColumn) $
111 Opaleye.nthValue (toColumn (toPrimExpr n))
114fromAggregate :: (a -> Aggregate b) -> Opaleye.Aggregator a (Expr b)
115fromAggregate f = Opaleye.Aggregator $ Opaleye.PackMap $ \w a -> case f a of
116 Aggregate (Opaleye.Aggregator (Opaleye.PackMap x)) -> x w ()
119fromWindowFunction :: Opaleye.WindowFunction a b -> Window a b
120fromWindowFunction (Opaleye.WindowFunction (Opaleye.PackMap w)) =
121 Window $ Opaleye.Windows $ Opaleye.PackMap $ \f -> w $ \o -> f (o, mempty)