module Rel8.Expr.Window
  ( cumulative
  , rowNumber
  , rank
  , denseRank
  , percentRank
  , cumeDist
  , ntile
  , lagExpr, lagExprOn
  , leadExpr, leadExprOn
  , firstValueExpr, firstValueExprOn
  , lastValueExpr, lastValueExprOn
  , nthValueExpr, nthValueExprOn
  )
where

-- base
import Data.Int ( Int32, Int64 )
import Prelude

-- opaleye
import qualified Opaleye.Internal.Aggregate as Opaleye
import qualified Opaleye.Internal.PackMap as Opaleye
import qualified Opaleye.Internal.Window as Opaleye
import qualified Opaleye.Window as Opaleye

-- profunctors
import Data.Profunctor (dimap, lmap)

-- rel8
import Rel8.Aggregate (Aggregator' (Aggregator))
import Rel8.Expr ( Expr )
import Rel8.Expr.Opaleye ( fromColumn, fromPrimExpr, toColumn, toPrimExpr )
import Rel8.Schema.Null ( Nullify )
import Rel8.Window ( Window( Window ) )


-- | 'cumulative' allows the use of aggregation functions in 'Window'
-- expressions. In particular, @'cumulative' 'Rel8.sum'@
-- (when combined with 'Rel8.Window.orderPartitionBy') gives a running total,
-- also known as a \"cumulative sum\", hence the name @cumulative@.
cumulative :: Aggregator' fold i a -> Window i a
cumulative :: forall (fold :: Fold) i a. Aggregator' fold i a -> Window i a
cumulative Aggregator' fold i a
f =
  WindowFunction i a -> Window i a
forall i a. WindowFunction i a -> Window i a
fromWindowFunction (WindowFunction i a -> Window i a)
-> WindowFunction i a -> Window i a
forall a b. (a -> b) -> a -> b
$ Aggregator i a -> (i -> i) -> WindowFunction i a
forall a b a'. Aggregator a b -> (a' -> a) -> WindowFunction a' b
Opaleye.aggregatorWindowFunction (Aggregator' fold i a -> Aggregator i a
forall (fold :: Fold) i a. Aggregator' fold i a -> Aggregator i a
fromAggregate Aggregator' fold i a
f) i -> i
forall a. a -> a
id


-- | [@row_number()@](https://www.postgresql.org/docs/current/functions-window.html)
rowNumber :: Window i (Expr Int64)
rowNumber :: forall i. Window i (Expr Int64)
rowNumber = WindowFunction i (Expr Int64) -> Window i (Expr Int64)
forall i a. WindowFunction i a -> Window i a
fromWindowFunction (WindowFunction i (Expr Int64) -> Window i (Expr Int64))
-> WindowFunction i (Expr Int64) -> Window i (Expr Int64)
forall a b. (a -> b) -> a -> b
$ PrimExpr -> Expr Int64
forall a. PrimExpr -> Expr a
fromPrimExpr (PrimExpr -> Expr Int64)
-> (Field_ 'NonNullable SqlInt8 -> PrimExpr)
-> Field_ 'NonNullable SqlInt8
-> Expr Int64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Field_ 'NonNullable SqlInt8 -> PrimExpr
forall (n :: Nullability) b. Field_ n b -> PrimExpr
fromColumn (Field_ 'NonNullable SqlInt8 -> Expr Int64)
-> WindowFunction i (Field_ 'NonNullable SqlInt8)
-> WindowFunction i (Expr Int64)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> WindowFunction i (Field_ 'NonNullable SqlInt8)
forall a. WindowFunction a (Field_ 'NonNullable SqlInt8)
Opaleye.rowNumber


-- | [@rank()@](https://www.postgresql.org/docs/current/functions-window.html)
rank :: Window i (Expr Int64)
rank :: forall i. Window i (Expr Int64)
rank = WindowFunction i (Expr Int64) -> Window i (Expr Int64)
forall i a. WindowFunction i a -> Window i a
fromWindowFunction (WindowFunction i (Expr Int64) -> Window i (Expr Int64))
-> WindowFunction i (Expr Int64) -> Window i (Expr Int64)
forall a b. (a -> b) -> a -> b
$ PrimExpr -> Expr Int64
forall a. PrimExpr -> Expr a
fromPrimExpr (PrimExpr -> Expr Int64)
-> (Field_ 'NonNullable SqlInt8 -> PrimExpr)
-> Field_ 'NonNullable SqlInt8
-> Expr Int64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Field_ 'NonNullable SqlInt8 -> PrimExpr
forall (n :: Nullability) b. Field_ n b -> PrimExpr
fromColumn (Field_ 'NonNullable SqlInt8 -> Expr Int64)
-> WindowFunction i (Field_ 'NonNullable SqlInt8)
-> WindowFunction i (Expr Int64)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> WindowFunction i (Field_ 'NonNullable SqlInt8)
forall a. WindowFunction a (Field_ 'NonNullable SqlInt8)
Opaleye.rank


-- | [@dense_rank()@](https://www.postgresql.org/docs/current/functions-window.html)
denseRank :: Window i (Expr Int64)
denseRank :: forall i. Window i (Expr Int64)
denseRank = WindowFunction i (Expr Int64) -> Window i (Expr Int64)
forall i a. WindowFunction i a -> Window i a
fromWindowFunction (WindowFunction i (Expr Int64) -> Window i (Expr Int64))
-> WindowFunction i (Expr Int64) -> Window i (Expr Int64)
forall a b. (a -> b) -> a -> b
$ PrimExpr -> Expr Int64
forall a. PrimExpr -> Expr a
fromPrimExpr (PrimExpr -> Expr Int64)
-> (Field_ 'NonNullable SqlInt8 -> PrimExpr)
-> Field_ 'NonNullable SqlInt8
-> Expr Int64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Field_ 'NonNullable SqlInt8 -> PrimExpr
forall (n :: Nullability) b. Field_ n b -> PrimExpr
fromColumn (Field_ 'NonNullable SqlInt8 -> Expr Int64)
-> WindowFunction i (Field_ 'NonNullable SqlInt8)
-> WindowFunction i (Expr Int64)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> WindowFunction i (Field_ 'NonNullable SqlInt8)
forall a. WindowFunction a (Field_ 'NonNullable SqlInt8)
Opaleye.denseRank


-- | [@percent_rank()@](https://www.postgresql.org/docs/current/functions-window.html)
percentRank :: Window i (Expr Double)
percentRank :: forall i. Window i (Expr Double)
percentRank = WindowFunction i (Expr Double) -> Window i (Expr Double)
forall i a. WindowFunction i a -> Window i a
fromWindowFunction (WindowFunction i (Expr Double) -> Window i (Expr Double))
-> WindowFunction i (Expr Double) -> Window i (Expr Double)
forall a b. (a -> b) -> a -> b
$ PrimExpr -> Expr Double
forall a. PrimExpr -> Expr a
fromPrimExpr (PrimExpr -> Expr Double)
-> (Field_ 'NonNullable SqlFloat8 -> PrimExpr)
-> Field_ 'NonNullable SqlFloat8
-> Expr Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Field_ 'NonNullable SqlFloat8 -> PrimExpr
forall (n :: Nullability) b. Field_ n b -> PrimExpr
fromColumn (Field_ 'NonNullable SqlFloat8 -> Expr Double)
-> WindowFunction i (Field_ 'NonNullable SqlFloat8)
-> WindowFunction i (Expr Double)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> WindowFunction i (Field_ 'NonNullable SqlFloat8)
forall a. WindowFunction a (Field_ 'NonNullable SqlFloat8)
Opaleye.percentRank


-- | [@cume_dist()@](https://www.postgresql.org/docs/current/functions-window.html)
cumeDist :: Window i (Expr Double)
cumeDist :: forall i. Window i (Expr Double)
cumeDist = WindowFunction i (Expr Double) -> Window i (Expr Double)
forall i a. WindowFunction i a -> Window i a
fromWindowFunction (WindowFunction i (Expr Double) -> Window i (Expr Double))
-> WindowFunction i (Expr Double) -> Window i (Expr Double)
forall a b. (a -> b) -> a -> b
$ PrimExpr -> Expr Double
forall a. PrimExpr -> Expr a
fromPrimExpr (PrimExpr -> Expr Double)
-> (Field_ 'NonNullable SqlFloat8 -> PrimExpr)
-> Field_ 'NonNullable SqlFloat8
-> Expr Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Field_ 'NonNullable SqlFloat8 -> PrimExpr
forall (n :: Nullability) b. Field_ n b -> PrimExpr
fromColumn (Field_ 'NonNullable SqlFloat8 -> Expr Double)
-> WindowFunction i (Field_ 'NonNullable SqlFloat8)
-> WindowFunction i (Expr Double)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> WindowFunction i (Field_ 'NonNullable SqlFloat8)
forall a. WindowFunction a (Field_ 'NonNullable SqlFloat8)
Opaleye.cumeDist


-- | [@ntile(num_buckets)@](https://www.postgresql.org/docs/current/functions-window.html)
ntile :: Expr Int32 -> Window i (Expr Int32)
ntile :: forall i. Expr Int32 -> Window i (Expr Int32)
ntile Expr Int32
buckets = WindowFunction i (Expr Int32) -> Window i (Expr Int32)
forall i a. WindowFunction i a -> Window i a
fromWindowFunction (WindowFunction i (Expr Int32) -> Window i (Expr Int32))
-> WindowFunction i (Expr Int32) -> Window i (Expr Int32)
forall a b. (a -> b) -> a -> b
$ PrimExpr -> Expr Int32
forall a. PrimExpr -> Expr a
fromPrimExpr (PrimExpr -> Expr Int32)
-> (Field_ 'NonNullable SqlInt4 -> PrimExpr)
-> Field_ 'NonNullable SqlInt4
-> Expr Int32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Field_ 'NonNullable SqlInt4 -> PrimExpr
forall (n :: Nullability) b. Field_ n b -> PrimExpr
fromColumn (Field_ 'NonNullable SqlInt4 -> Expr Int32)
-> WindowFunction i (Field_ 'NonNullable SqlInt4)
-> WindowFunction i (Expr Int32)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
  Field_ 'NonNullable SqlInt4
-> WindowFunction i (Field_ 'NonNullable SqlInt4)
forall a.
Field_ 'NonNullable SqlInt4
-> WindowFunction a (Field_ 'NonNullable SqlInt4)
Opaleye.ntile (PrimExpr -> Field_ 'NonNullable SqlInt4
forall (n :: Nullability) b. PrimExpr -> Field_ n b
toColumn (Expr Int32 -> PrimExpr
forall a. Expr a -> PrimExpr
toPrimExpr Expr Int32
buckets))


-- | [@lag(value, offset, default)@](https://www.postgresql.org/docs/current/functions-window.html)
lagExpr :: Expr Int32 -> Expr a -> Window (Expr a) (Expr a)
lagExpr :: forall a. Expr Int32 -> Expr a -> Window (Expr a) (Expr a)
lagExpr Expr Int32
offset Expr a
def =
  WindowFunction (Expr a) (Expr a) -> Window (Expr a) (Expr a)
forall i a. WindowFunction i a -> Window i a
fromWindowFunction (WindowFunction (Expr a) (Expr a) -> Window (Expr a) (Expr a))
-> WindowFunction (Expr a) (Expr a) -> Window (Expr a) (Expr a)
forall a b. (a -> b) -> a -> b
$
    (Expr a -> Field_ Any Any)
-> (Field_ Any Any -> Expr a)
-> WindowFunction (Field_ Any Any) (Field_ Any Any)
-> WindowFunction (Expr a) (Expr a)
forall a b c d.
(a -> b) -> (c -> d) -> WindowFunction b c -> WindowFunction a d
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap (PrimExpr -> Field_ Any Any
forall (n :: Nullability) b. PrimExpr -> Field_ n b
toColumn (PrimExpr -> Field_ Any Any)
-> (Expr a -> PrimExpr) -> Expr a -> Field_ Any Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr a -> PrimExpr
forall a. Expr a -> PrimExpr
toPrimExpr) (PrimExpr -> Expr a
forall a. PrimExpr -> Expr a
fromPrimExpr (PrimExpr -> Expr a)
-> (Field_ Any Any -> PrimExpr) -> Field_ Any Any -> Expr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Field_ Any Any -> PrimExpr
forall (n :: Nullability) b. Field_ n b -> PrimExpr
fromColumn) (WindowFunction (Field_ Any Any) (Field_ Any Any)
 -> WindowFunction (Expr a) (Expr a))
-> WindowFunction (Field_ Any Any) (Field_ Any Any)
-> WindowFunction (Expr a) (Expr a)
forall a b. (a -> b) -> a -> b
$
      Field_ 'NonNullable SqlInt4
-> Field_ Any Any
-> WindowFunction (Field_ Any Any) (Field_ Any Any)
forall (n :: Nullability) a.
Field_ 'NonNullable SqlInt4
-> Field_ n a -> WindowFunction (Field_ n a) (Field_ n a)
Opaleye.lag (PrimExpr -> Field_ 'NonNullable SqlInt4
forall (n :: Nullability) b. PrimExpr -> Field_ n b
toColumn (Expr Int32 -> PrimExpr
forall a. Expr a -> PrimExpr
toPrimExpr Expr Int32
offset)) (PrimExpr -> Field_ Any Any
forall (n :: Nullability) b. PrimExpr -> Field_ n b
toColumn (Expr a -> PrimExpr
forall a. Expr a -> PrimExpr
toPrimExpr Expr a
def))


-- | Applies 'lag' to the column selected by the given function.
lagExprOn :: Expr Int32 -> Expr a -> (i -> Expr a) -> Window i (Expr a)
lagExprOn :: forall a i.
Expr Int32 -> Expr a -> (i -> Expr a) -> Window i (Expr a)
lagExprOn Expr Int32
offset Expr a
def i -> Expr a
f = (i -> Expr a) -> Window (Expr a) (Expr a) -> Window i (Expr a)
forall a b c. (a -> b) -> Window b c -> Window a c
forall (p :: * -> * -> *) a b c.
Profunctor p =>
(a -> b) -> p b c -> p a c
lmap i -> Expr a
f (Expr Int32 -> Expr a -> Window (Expr a) (Expr a)
forall a. Expr Int32 -> Expr a -> Window (Expr a) (Expr a)
lagExpr Expr Int32
offset Expr a
def)


-- | [@lead(value, offset, default)@](https://www.postgresql.org/docs/current/functions-window.html)
leadExpr :: Expr Int32 -> Expr a -> Window (Expr a) (Expr a)
leadExpr :: forall a. Expr Int32 -> Expr a -> Window (Expr a) (Expr a)
leadExpr Expr Int32
offset Expr a
def =
  WindowFunction (Expr a) (Expr a) -> Window (Expr a) (Expr a)
forall i a. WindowFunction i a -> Window i a
fromWindowFunction (WindowFunction (Expr a) (Expr a) -> Window (Expr a) (Expr a))
-> WindowFunction (Expr a) (Expr a) -> Window (Expr a) (Expr a)
forall a b. (a -> b) -> a -> b
$
    (Expr a -> Field_ Any Any)
-> (Field_ Any Any -> Expr a)
-> WindowFunction (Field_ Any Any) (Field_ Any Any)
-> WindowFunction (Expr a) (Expr a)
forall a b c d.
(a -> b) -> (c -> d) -> WindowFunction b c -> WindowFunction a d
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap (PrimExpr -> Field_ Any Any
forall (n :: Nullability) b. PrimExpr -> Field_ n b
toColumn (PrimExpr -> Field_ Any Any)
-> (Expr a -> PrimExpr) -> Expr a -> Field_ Any Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr a -> PrimExpr
forall a. Expr a -> PrimExpr
toPrimExpr) (PrimExpr -> Expr a
forall a. PrimExpr -> Expr a
fromPrimExpr (PrimExpr -> Expr a)
-> (Field_ Any Any -> PrimExpr) -> Field_ Any Any -> Expr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Field_ Any Any -> PrimExpr
forall (n :: Nullability) b. Field_ n b -> PrimExpr
fromColumn) (WindowFunction (Field_ Any Any) (Field_ Any Any)
 -> WindowFunction (Expr a) (Expr a))
-> WindowFunction (Field_ Any Any) (Field_ Any Any)
-> WindowFunction (Expr a) (Expr a)
forall a b. (a -> b) -> a -> b
$
      Field_ 'NonNullable SqlInt4
-> Field_ Any Any
-> WindowFunction (Field_ Any Any) (Field_ Any Any)
forall (n :: Nullability) a.
Field_ 'NonNullable SqlInt4
-> Field_ n a -> WindowFunction (Field_ n a) (Field_ n a)
Opaleye.lead (PrimExpr -> Field_ 'NonNullable SqlInt4
forall (n :: Nullability) b. PrimExpr -> Field_ n b
toColumn (Expr Int32 -> PrimExpr
forall a. Expr a -> PrimExpr
toPrimExpr Expr Int32
offset)) (PrimExpr -> Field_ Any Any
forall (n :: Nullability) b. PrimExpr -> Field_ n b
toColumn (Expr a -> PrimExpr
forall a. Expr a -> PrimExpr
toPrimExpr Expr a
def))


-- | Applies 'lead' to the column selected by the given function.
leadExprOn :: Expr Int32 -> Expr a -> (i -> Expr a) -> Window i (Expr a)
leadExprOn :: forall a i.
Expr Int32 -> Expr a -> (i -> Expr a) -> Window i (Expr a)
leadExprOn Expr Int32
offset Expr a
def i -> Expr a
f = (i -> Expr a) -> Window (Expr a) (Expr a) -> Window i (Expr a)
forall a b c. (a -> b) -> Window b c -> Window a c
forall (p :: * -> * -> *) a b c.
Profunctor p =>
(a -> b) -> p b c -> p a c
lmap i -> Expr a
f (Expr Int32 -> Expr a -> Window (Expr a) (Expr a)
forall a. Expr Int32 -> Expr a -> Window (Expr a) (Expr a)
leadExpr Expr Int32
offset Expr a
def)


-- | [@first_value(value)@](https://www.postgresql.org/docs/current/functions-window.html)
firstValueExpr :: Window (Expr a) (Expr a)
firstValueExpr :: forall a. Window (Expr a) (Expr a)
firstValueExpr =
  WindowFunction (Expr a) (Expr a) -> Window (Expr a) (Expr a)
forall i a. WindowFunction i a -> Window i a
fromWindowFunction (WindowFunction (Expr a) (Expr a) -> Window (Expr a) (Expr a))
-> WindowFunction (Expr a) (Expr a) -> Window (Expr a) (Expr a)
forall a b. (a -> b) -> a -> b
$
    (Expr a -> Field_ Any Any)
-> (Field_ Any Any -> Expr a)
-> WindowFunction (Field_ Any Any) (Field_ Any Any)
-> WindowFunction (Expr a) (Expr a)
forall a b c d.
(a -> b) -> (c -> d) -> WindowFunction b c -> WindowFunction a d
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap (PrimExpr -> Field_ Any Any
forall (n :: Nullability) b. PrimExpr -> Field_ n b
toColumn (PrimExpr -> Field_ Any Any)
-> (Expr a -> PrimExpr) -> Expr a -> Field_ Any Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr a -> PrimExpr
forall a. Expr a -> PrimExpr
toPrimExpr) (PrimExpr -> Expr a
forall a. PrimExpr -> Expr a
fromPrimExpr (PrimExpr -> Expr a)
-> (Field_ Any Any -> PrimExpr) -> Field_ Any Any -> Expr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Field_ Any Any -> PrimExpr
forall (n :: Nullability) b. Field_ n b -> PrimExpr
fromColumn)
      WindowFunction (Field_ Any Any) (Field_ Any Any)
forall (n :: Nullability) a.
WindowFunction (Field_ n a) (Field_ n a)
Opaleye.firstValue


-- | Applies 'firstValue' to the column selected by the given function.
firstValueExprOn :: (i -> Expr a) -> Window i (Expr a)
firstValueExprOn :: forall i a. (i -> Expr a) -> Window i (Expr a)
firstValueExprOn i -> Expr a
f = (i -> Expr a) -> Window (Expr a) (Expr a) -> Window i (Expr a)
forall a b c. (a -> b) -> Window b c -> Window a c
forall (p :: * -> * -> *) a b c.
Profunctor p =>
(a -> b) -> p b c -> p a c
lmap i -> Expr a
f Window (Expr a) (Expr a)
forall a. Window (Expr a) (Expr a)
firstValueExpr


-- | [@last_value(value)@](https://www.postgresql.org/docs/current/functions-window.html)
lastValueExpr :: Window (Expr a) (Expr a)
lastValueExpr :: forall a. Window (Expr a) (Expr a)
lastValueExpr =
  WindowFunction (Expr a) (Expr a) -> Window (Expr a) (Expr a)
forall i a. WindowFunction i a -> Window i a
fromWindowFunction (WindowFunction (Expr a) (Expr a) -> Window (Expr a) (Expr a))
-> WindowFunction (Expr a) (Expr a) -> Window (Expr a) (Expr a)
forall a b. (a -> b) -> a -> b
$
    (Expr a -> Field_ Any Any)
-> (Field_ Any Any -> Expr a)
-> WindowFunction (Field_ Any Any) (Field_ Any Any)
-> WindowFunction (Expr a) (Expr a)
forall a b c d.
(a -> b) -> (c -> d) -> WindowFunction b c -> WindowFunction a d
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap (PrimExpr -> Field_ Any Any
forall (n :: Nullability) b. PrimExpr -> Field_ n b
toColumn (PrimExpr -> Field_ Any Any)
-> (Expr a -> PrimExpr) -> Expr a -> Field_ Any Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr a -> PrimExpr
forall a. Expr a -> PrimExpr
toPrimExpr) (PrimExpr -> Expr a
forall a. PrimExpr -> Expr a
fromPrimExpr (PrimExpr -> Expr a)
-> (Field_ Any Any -> PrimExpr) -> Field_ Any Any -> Expr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Field_ Any Any -> PrimExpr
forall (n :: Nullability) b. Field_ n b -> PrimExpr
fromColumn)
      WindowFunction (Field_ Any Any) (Field_ Any Any)
forall (n :: Nullability) a.
WindowFunction (Field_ n a) (Field_ n a)
Opaleye.lastValue


-- | Applies 'lastValue' to the column selected by the given function.
lastValueExprOn :: (i -> Expr a) -> Window i (Expr a)
lastValueExprOn :: forall i a. (i -> Expr a) -> Window i (Expr a)
lastValueExprOn i -> Expr a
f = (i -> Expr a) -> Window (Expr a) (Expr a) -> Window i (Expr a)
forall a b c. (a -> b) -> Window b c -> Window a c
forall (p :: * -> * -> *) a b c.
Profunctor p =>
(a -> b) -> p b c -> p a c
lmap i -> Expr a
f Window (Expr a) (Expr a)
forall a. Window (Expr a) (Expr a)
lastValueExpr


-- | [@nth_value(value, n)@](https://www.postgresql.org/docs/current/functions-window.html)
nthValueExpr :: Expr Int32 -> Window (Expr a) (Expr (Nullify a))
nthValueExpr :: forall a. Expr Int32 -> Window (Expr a) (Expr (Nullify a))
nthValueExpr Expr Int32
n =
  WindowFunction (Expr a) (Expr (Nullify a))
-> Window (Expr a) (Expr (Nullify a))
forall i a. WindowFunction i a -> Window i a
fromWindowFunction (WindowFunction (Expr a) (Expr (Nullify a))
 -> Window (Expr a) (Expr (Nullify a)))
-> WindowFunction (Expr a) (Expr (Nullify a))
-> Window (Expr a) (Expr (Nullify a))
forall a b. (a -> b) -> a -> b
$
    (Expr a -> Field_ Any Any)
-> (Field_ 'Nullable Any -> Expr (Nullify a))
-> WindowFunction (Field_ Any Any) (Field_ 'Nullable Any)
-> WindowFunction (Expr a) (Expr (Nullify a))
forall a b c d.
(a -> b) -> (c -> d) -> WindowFunction b c -> WindowFunction a d
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap (PrimExpr -> Field_ Any Any
forall (n :: Nullability) b. PrimExpr -> Field_ n b
toColumn (PrimExpr -> Field_ Any Any)
-> (Expr a -> PrimExpr) -> Expr a -> Field_ Any Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expr a -> PrimExpr
forall a. Expr a -> PrimExpr
toPrimExpr) (PrimExpr -> Expr (Nullify a)
forall a. PrimExpr -> Expr a
fromPrimExpr (PrimExpr -> Expr (Nullify a))
-> (Field_ 'Nullable Any -> PrimExpr)
-> Field_ 'Nullable Any
-> Expr (Nullify a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Field_ 'Nullable Any -> PrimExpr
forall (n :: Nullability) b. Field_ n b -> PrimExpr
fromColumn) (WindowFunction (Field_ Any Any) (Field_ 'Nullable Any)
 -> WindowFunction (Expr a) (Expr (Nullify a)))
-> WindowFunction (Field_ Any Any) (Field_ 'Nullable Any)
-> WindowFunction (Expr a) (Expr (Nullify a))
forall a b. (a -> b) -> a -> b
$
      Field_ 'NonNullable SqlInt4
-> WindowFunction (Field_ Any Any) (Field_ 'Nullable Any)
forall (n :: Nullability) a.
Field_ 'NonNullable SqlInt4
-> WindowFunction (Field_ n a) (FieldNullable a)
Opaleye.nthValue (PrimExpr -> Field_ 'NonNullable SqlInt4
forall (n :: Nullability) b. PrimExpr -> Field_ n b
toColumn (Expr Int32 -> PrimExpr
forall a. Expr a -> PrimExpr
toPrimExpr Expr Int32
n))


-- | [@nth_value(value, n)@](https://www.postgresql.org/docs/current/functions-window.html)
nthValueExprOn :: Expr Int32 -> (i -> Expr a) -> Window i (Expr (Nullify a))
nthValueExprOn :: forall i a.
Expr Int32 -> (i -> Expr a) -> Window i (Expr (Nullify a))
nthValueExprOn Expr Int32
n i -> Expr a
f = (i -> Expr a)
-> Window (Expr a) (Expr (Maybe (Unnullify' (IsMaybe a) a)))
-> Window i (Expr (Maybe (Unnullify' (IsMaybe a) a)))
forall a b c. (a -> b) -> Window b c -> Window a c
forall (p :: * -> * -> *) a b c.
Profunctor p =>
(a -> b) -> p b c -> p a c
lmap i -> Expr a
f (Expr Int32
-> Window (Expr a) (Expr (Maybe (Unnullify' (IsMaybe a) a)))
forall a. Expr Int32 -> Window (Expr a) (Expr (Nullify a))
nthValueExpr Expr Int32
n)


fromAggregate :: Aggregator' fold i a -> Opaleye.Aggregator i a
fromAggregate :: forall (fold :: Fold) i a. Aggregator' fold i a -> Aggregator i a
fromAggregate (Aggregator Fallback fold a
_ Aggregator i a
a) = Aggregator i a
a


fromWindowFunction :: Opaleye.WindowFunction i a -> Window i a
fromWindowFunction :: forall i a. WindowFunction i a -> Window i a
fromWindowFunction (Opaleye.WindowFunction (Opaleye.PackMap forall (f :: * -> *).
Applicative f =>
(WndwOp -> f PrimExpr) -> i -> f a
w)) =
  Windows i a -> Window i a
forall a b. Windows a b -> Window a b
Window (Windows i a -> Window i a) -> Windows i a -> Window i a
forall a b. (a -> b) -> a -> b
$ PackMap (WndwOp, Window i) PrimExpr i a -> Windows i a
forall a b. PackMap (WndwOp, Window a) PrimExpr a b -> Windows a b
Opaleye.Windows (PackMap (WndwOp, Window i) PrimExpr i a -> Windows i a)
-> PackMap (WndwOp, Window i) PrimExpr i a -> Windows i a
forall a b. (a -> b) -> a -> b
$ (forall (f :: * -> *).
 Applicative f =>
 ((WndwOp, Window i) -> f PrimExpr) -> i -> f a)
-> PackMap (WndwOp, Window i) PrimExpr i a
forall a b s t.
(forall (f :: * -> *). Applicative f => (a -> f b) -> s -> f t)
-> PackMap a b s t
Opaleye.PackMap ((forall (f :: * -> *).
  Applicative f =>
  ((WndwOp, Window i) -> f PrimExpr) -> i -> f a)
 -> PackMap (WndwOp, Window i) PrimExpr i a)
-> (forall (f :: * -> *).
    Applicative f =>
    ((WndwOp, Window i) -> f PrimExpr) -> i -> f a)
-> PackMap (WndwOp, Window i) PrimExpr i a
forall a b. (a -> b) -> a -> b
$ \(WndwOp, Window i) -> f PrimExpr
f -> (WndwOp -> f PrimExpr) -> i -> f a
forall (f :: * -> *).
Applicative f =>
(WndwOp -> f PrimExpr) -> i -> f a
w ((WndwOp -> f PrimExpr) -> i -> f a)
-> (WndwOp -> f PrimExpr) -> i -> f a
forall a b. (a -> b) -> a -> b
$ \WndwOp
o -> (WndwOp, Window i) -> f PrimExpr
f (WndwOp
o, Window i
forall a. Monoid a => a
mempty)