module Opaleye.Aggregate
(
aggregate
, aggregateOrdered
, distinctAggregator
, Aggregator
, groupBy
, Opaleye.Aggregate.sum
, sumInt4
, sumInt8
, count
, countStar
, avg
, Opaleye.Aggregate.max
, Opaleye.Aggregate.min
, boolOr
, boolAnd
, arrayAgg
, jsonAgg
, stringAgg
, countRows
) where
import Control.Applicative (pure)
import Data.Profunctor (lmap)
import qualified Data.Profunctor as P
import qualified Opaleye.Internal.Aggregate as A
import Opaleye.Internal.Aggregate (Aggregator, orderAggregate)
import qualified Opaleye.Internal.Column as IC
import qualified Opaleye.Internal.QueryArr as Q
import qualified Opaleye.Internal.HaskellDB.PrimQuery as HPQ
import qualified Opaleye.Internal.PackMap as PM
import qualified Opaleye.Column as C
import qualified Opaleye.Order as Ord
import qualified Opaleye.Select as S
import qualified Opaleye.SqlTypes as T
import qualified Opaleye.Join as J
aggregate :: Aggregator a b -> S.Select a -> S.Select b
aggregate :: Aggregator a b -> Select a -> Select b
aggregate Aggregator a b
agg Select a
q = (((), Tag) -> (b, PrimQuery, Tag)) -> Select b
forall a b. ((a, Tag) -> (b, PrimQuery, Tag)) -> QueryArr a b
Q.productQueryArr (Aggregator a b -> (a, PrimQuery, Tag) -> (b, PrimQuery, Tag)
forall a b.
Aggregator a b -> (a, PrimQuery, Tag) -> (b, PrimQuery, Tag)
A.aggregateU Aggregator a b
agg ((a, PrimQuery, Tag) -> (b, PrimQuery, Tag))
-> (((), Tag) -> (a, PrimQuery, Tag))
-> ((), Tag)
-> (b, PrimQuery, Tag)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Select a -> ((), Tag) -> (a, PrimQuery, Tag)
forall a b. QueryArr a b -> (a, Tag) -> (b, PrimQuery, Tag)
Q.runSimpleQueryArr Select a
q)
aggregateOrdered :: Ord.Order a -> Aggregator a b -> S.Select a -> S.Select b
aggregateOrdered :: Order a -> Aggregator a b -> Select a -> Select b
aggregateOrdered Order a
o Aggregator a b
agg = Aggregator a b -> Select a -> Select b
forall a b. Aggregator a b -> Select a -> Select b
aggregate (Order a -> Aggregator a b -> Aggregator a b
forall a b. Order a -> Aggregator a b -> Aggregator a b
orderAggregate Order a
o Aggregator a b
agg)
distinctAggregator :: Aggregator a b -> Aggregator a b
distinctAggregator :: Aggregator a b -> Aggregator a b
distinctAggregator (A.Aggregator (PM.PackMap forall (f :: * -> *).
Applicative f =>
((Maybe (AggrOp, [OrderExpr], AggrDistinct), PrimExpr)
-> f PrimExpr)
-> a -> f b
pm)) =
PackMap
(Maybe (AggrOp, [OrderExpr], AggrDistinct), PrimExpr) PrimExpr a b
-> Aggregator a b
forall a b.
PackMap
(Maybe (AggrOp, [OrderExpr], AggrDistinct), PrimExpr) PrimExpr a b
-> Aggregator a b
A.Aggregator ((forall (f :: * -> *).
Applicative f =>
((Maybe (AggrOp, [OrderExpr], AggrDistinct), PrimExpr)
-> f PrimExpr)
-> a -> f b)
-> PackMap
(Maybe (AggrOp, [OrderExpr], AggrDistinct), PrimExpr) PrimExpr a b
forall a b s t.
(forall (f :: * -> *). Applicative f => (a -> f b) -> s -> f t)
-> PackMap a b s t
PM.PackMap (\(Maybe (AggrOp, [OrderExpr], AggrDistinct), PrimExpr) -> f PrimExpr
f a
c -> ((Maybe (AggrOp, [OrderExpr], AggrDistinct), PrimExpr)
-> f PrimExpr)
-> a -> f b
forall (f :: * -> *).
Applicative f =>
((Maybe (AggrOp, [OrderExpr], AggrDistinct), PrimExpr)
-> f PrimExpr)
-> a -> f b
pm ((Maybe (AggrOp, [OrderExpr], AggrDistinct), PrimExpr) -> f PrimExpr
f ((Maybe (AggrOp, [OrderExpr], AggrDistinct), PrimExpr)
-> f PrimExpr)
-> ((Maybe (AggrOp, [OrderExpr], AggrDistinct), PrimExpr)
-> (Maybe (AggrOp, [OrderExpr], AggrDistinct), PrimExpr))
-> (Maybe (AggrOp, [OrderExpr], AggrDistinct), PrimExpr)
-> f PrimExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe (AggrOp, [OrderExpr], AggrDistinct)
-> Maybe (AggrOp, [OrderExpr], AggrDistinct))
-> (Maybe (AggrOp, [OrderExpr], AggrDistinct), PrimExpr)
-> (Maybe (AggrOp, [OrderExpr], AggrDistinct), PrimExpr)
forall (p :: * -> * -> *) a b c.
Strong p =>
p a b -> p (a, c) (b, c)
P.first' (((AggrOp, [OrderExpr], AggrDistinct)
-> (AggrOp, [OrderExpr], AggrDistinct))
-> Maybe (AggrOp, [OrderExpr], AggrDistinct)
-> Maybe (AggrOp, [OrderExpr], AggrDistinct)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(AggrOp
a,[OrderExpr]
b,AggrDistinct
_) -> (AggrOp
a,[OrderExpr]
b,AggrDistinct
HPQ.AggrDistinct)))) a
c))
groupBy :: Aggregator (C.Column a) (C.Column a)
groupBy :: Aggregator (Column a) (Column a)
groupBy = Maybe AggrOp -> Aggregator (Column a) (Column a)
forall a b. Maybe AggrOp -> Aggregator (Column a) (Column b)
A.makeAggr' Maybe AggrOp
forall a. Maybe a
Nothing
sum :: Aggregator (C.Column a) (C.Column a)
sum :: Aggregator (Column a) (Column a)
sum = AggrOp -> Aggregator (Column a) (Column a)
forall a b. AggrOp -> Aggregator (Column a) (Column b)
A.makeAggr AggrOp
HPQ.AggrSum
sumInt4 :: Aggregator (C.Column T.SqlInt4) (C.Column T.SqlInt8)
sumInt4 :: Aggregator (Column SqlInt4) (Column SqlInt8)
sumInt4 = (Column SqlInt4 -> Column SqlInt8)
-> Aggregator (Column SqlInt4) (Column SqlInt4)
-> Aggregator (Column SqlInt4) (Column SqlInt8)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Column SqlInt4 -> Column SqlInt8
forall a b. Column a -> Column b
C.unsafeCoerceColumn Aggregator (Column SqlInt4) (Column SqlInt4)
forall a. Aggregator (Column a) (Column a)
Opaleye.Aggregate.sum
sumInt8 :: Aggregator (C.Column T.SqlInt8) (C.Column T.SqlNumeric)
sumInt8 :: Aggregator (Column SqlInt8) (Column SqlNumeric)
sumInt8 = (Column SqlInt8 -> Column SqlNumeric)
-> Aggregator (Column SqlInt8) (Column SqlInt8)
-> Aggregator (Column SqlInt8) (Column SqlNumeric)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Column SqlInt8 -> Column SqlNumeric
forall a b. Column a -> Column b
C.unsafeCoerceColumn Aggregator (Column SqlInt8) (Column SqlInt8)
forall a. Aggregator (Column a) (Column a)
Opaleye.Aggregate.sum
count :: Aggregator (C.Column a) (C.Column T.SqlInt8)
count :: Aggregator (Column a) (Column SqlInt8)
count = AggrOp -> Aggregator (Column a) (Column SqlInt8)
forall a b. AggrOp -> Aggregator (Column a) (Column b)
A.makeAggr AggrOp
HPQ.AggrCount
countStar :: Aggregator a (C.Column T.SqlInt8)
countStar :: Aggregator a (Column SqlInt8)
countStar = (a -> Column SqlInt4)
-> Aggregator (Column SqlInt4) (Column SqlInt8)
-> Aggregator a (Column SqlInt8)
forall (p :: * -> * -> *) a b c.
Profunctor p =>
(a -> b) -> p b c -> p a c
lmap (Column SqlInt4 -> a -> Column SqlInt4
forall a b. a -> b -> a
const (Column SqlInt4
0 :: C.Column T.SqlInt4)) Aggregator (Column SqlInt4) (Column SqlInt8)
forall a. Aggregator (Column a) (Column SqlInt8)
count
avg :: Aggregator (C.Column T.SqlFloat8) (C.Column T.SqlFloat8)
avg :: Aggregator (Column SqlFloat8) (Column SqlFloat8)
avg = AggrOp -> Aggregator (Column SqlFloat8) (Column SqlFloat8)
forall a b. AggrOp -> Aggregator (Column a) (Column b)
A.makeAggr AggrOp
HPQ.AggrAvg
max :: Ord.SqlOrd a => Aggregator (C.Column a) (C.Column a)
max :: Aggregator (Column a) (Column a)
max = AggrOp -> Aggregator (Column a) (Column a)
forall a b. AggrOp -> Aggregator (Column a) (Column b)
A.makeAggr AggrOp
HPQ.AggrMax
min :: Ord.SqlOrd a => Aggregator (C.Column a) (C.Column a)
min :: Aggregator (Column a) (Column a)
min = AggrOp -> Aggregator (Column a) (Column a)
forall a b. AggrOp -> Aggregator (Column a) (Column b)
A.makeAggr AggrOp
HPQ.AggrMin
boolOr :: Aggregator (C.Column T.SqlBool) (C.Column T.SqlBool)
boolOr :: Aggregator (Column SqlBool) (Column SqlBool)
boolOr = AggrOp -> Aggregator (Column SqlBool) (Column SqlBool)
forall a b. AggrOp -> Aggregator (Column a) (Column b)
A.makeAggr AggrOp
HPQ.AggrBoolOr
boolAnd :: Aggregator (C.Column T.SqlBool) (C.Column T.SqlBool)
boolAnd :: Aggregator (Column SqlBool) (Column SqlBool)
boolAnd = AggrOp -> Aggregator (Column SqlBool) (Column SqlBool)
forall a b. AggrOp -> Aggregator (Column a) (Column b)
A.makeAggr AggrOp
HPQ.AggrBoolAnd
arrayAgg :: Aggregator (C.Column a) (C.Column (T.SqlArray a))
arrayAgg :: Aggregator (Column a) (Column (SqlArray a))
arrayAgg = AggrOp -> Aggregator (Column a) (Column (SqlArray a))
forall a b. AggrOp -> Aggregator (Column a) (Column b)
A.makeAggr AggrOp
HPQ.AggrArr
jsonAgg :: Aggregator (C.Column a) (C.Column T.SqlJson)
jsonAgg :: Aggregator (Column a) (Column SqlJson)
jsonAgg = AggrOp -> Aggregator (Column a) (Column SqlJson)
forall a b. AggrOp -> Aggregator (Column a) (Column b)
A.makeAggr AggrOp
HPQ.JsonArr
stringAgg :: C.Column T.SqlText
-> Aggregator (C.Column T.SqlText) (C.Column T.SqlText)
stringAgg :: Column SqlText -> Aggregator (Column SqlText) (Column SqlText)
stringAgg = Maybe AggrOp -> Aggregator (Column SqlText) (Column SqlText)
forall a b. Maybe AggrOp -> Aggregator (Column a) (Column b)
A.makeAggr' (Maybe AggrOp -> Aggregator (Column SqlText) (Column SqlText))
-> (Column SqlText -> Maybe AggrOp)
-> Column SqlText
-> Aggregator (Column SqlText) (Column SqlText)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AggrOp -> Maybe AggrOp
forall a. a -> Maybe a
Just (AggrOp -> Maybe AggrOp)
-> (Column SqlText -> AggrOp) -> Column SqlText -> Maybe AggrOp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PrimExpr -> AggrOp
HPQ.AggrStringAggr (PrimExpr -> AggrOp)
-> (Column SqlText -> PrimExpr) -> Column SqlText -> AggrOp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Column SqlText -> PrimExpr
forall a. Column a -> PrimExpr
IC.unColumn
countRows :: S.Select a -> S.Select (C.Column T.SqlInt8)
countRows :: Select a -> Select (Column SqlInt8)
countRows = (Column (Nullable SqlInt8) -> Column SqlInt8)
-> SelectArr () (Column (Nullable SqlInt8))
-> Select (Column SqlInt8)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Column SqlInt8 -> Column (Nullable SqlInt8) -> Column SqlInt8
forall a. Column a -> Column (Nullable a) -> Column a
C.fromNullable Column SqlInt8
0)
(SelectArr () (Column (Nullable SqlInt8))
-> Select (Column SqlInt8))
-> (Select a -> SelectArr () (Column (Nullable SqlInt8)))
-> Select a
-> Select (Column SqlInt8)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (((), Column (Nullable SqlInt8)) -> Column (Nullable SqlInt8))
-> SelectArr () ((), Column (Nullable SqlInt8))
-> SelectArr () (Column (Nullable SqlInt8))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((), Column (Nullable SqlInt8)) -> Column (Nullable SqlInt8)
forall a b. (a, b) -> b
snd
(SelectArr () ((), Column (Nullable SqlInt8))
-> SelectArr () (Column (Nullable SqlInt8)))
-> (Select a -> SelectArr () ((), Column (Nullable SqlInt8)))
-> Select a
-> SelectArr () (Column (Nullable SqlInt8))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\Select (Column SqlInt4)
q -> Select ()
-> Select (Column SqlInt8)
-> (((), Column SqlInt8) -> Field SqlBool)
-> SelectArr () ((), Column (Nullable SqlInt8))
forall fieldsL fieldsR nullableFieldsR.
(Default Unpackspec fieldsL fieldsL,
Default Unpackspec fieldsR fieldsR,
Default NullMaker fieldsR nullableFieldsR) =>
Select fieldsL
-> Select fieldsR
-> ((fieldsL, fieldsR) -> Field SqlBool)
-> Select (fieldsL, nullableFieldsR)
J.leftJoin (() -> Select ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ())
(Aggregator (Column SqlInt4) (Column SqlInt8)
-> Select (Column SqlInt4) -> Select (Column SqlInt8)
forall a b. Aggregator a b -> Select a -> Select b
aggregate Aggregator (Column SqlInt4) (Column SqlInt8)
forall a. Aggregator (Column a) (Column SqlInt8)
count Select (Column SqlInt4)
q)
(Column SqlBool -> ((), Column SqlInt8) -> Column SqlBool
forall a b. a -> b -> a
const (Bool -> Field SqlBool
T.sqlBool Bool
True)))
(Select (Column SqlInt4)
-> SelectArr () ((), Column (Nullable SqlInt8)))
-> (Select a -> Select (Column SqlInt4))
-> Select a
-> SelectArr () ((), Column (Nullable SqlInt8))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Column SqlInt4) -> Select a -> Select (Column SqlInt4)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Column SqlInt4 -> a -> Column SqlInt4
forall a b. a -> b -> a
const (Column SqlInt4
0 :: C.Column T.SqlInt4))