@@ -136,7 +136,7 @@ module Squeal.PostgreSQL.Expression
136136 -- ** Aggregation
137137 , Aggregate (..)
138138 , DistinctExpression (..)
139− , PGAvg (avg, avgDistinct)
139+ , PGAvg
140140 , countStar
141141 -- * Window Functions
142142 , WindowDefinition (..)
@@ -261,7 +261,7 @@ class KnownNat n => HasParameter
261261 | n params -> ty where
262262 -- | `parameter` takes a `Nat` using type application and a `TypeExpression`.
263263 --
264− -- >>> let expr = parameter @1 int4 :: Expression '[] schemas '[ 'Null 'PGint4] grp from ('Null 'PGint4)
264+ -- >>> let expr = parameter @1 int4 :: Expression grp '[] schemas '[ 'Null 'PGint4] from ('Null 'PGint4)
265265 -- >>> printSQL expr
266266 -- ($1 :: int4)
267267 parameter
@@ -277,7 +277,7 @@ instance {-# OVERLAPPABLE #-} (KnownNat n, HasParameter (n-1) params ty)
277277-- | `param` takes a `Nat` using type application and for basic types,
278278-- infers a `TypeExpression`.
279279--
280−-- >>> let expr = param @1 :: Expression commons schemas '[ 'Null 'PGint4] grp from ('Null 'PGint4)
280+-- >>> let expr = param @1 :: Expression grp commons schemas '[ 'Null 'PGint4] from ('Null 'PGint4)
281281-- >>> printSQL expr
282282-- ($1 :: int4)
283283param
@@ -436,7 +436,7 @@ matchNull y f x = ifThenElse (isNull x) y
436436`nullIf` gives @NULL@.
437437
438438>>> :set -XTypeApplications -XDataKinds
439−>>> let expr = nullIf false (param @1) :: Expression commons schemas '[ 'NotNull 'PGbool] grp from ('Null 'PGbool)
439+>>> let expr = nullIf false (param @1) :: Expression grp commons schemas '[ 'NotNull 'PGbool] from ('Null 'PGbool)
440440>>> printSQL expr
441441NULL IF (FALSE, ($1 :: bool))
442442-}
@@ -498,7 +498,7 @@ row exprs = UnsafeExpression $ "ROW" <> parenthesized
498498-- type Schema = '["complex" ::: 'Typedef Complex]
499499-- :}
500500--
501−-- >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression '[] (Public Schema) from grp params ('NotNull Complex)
501+-- >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression grp '[] (Public Schema) from params ('NotNull Complex)
502502-- >>> printSQL $ i & field #complex #imaginary
503503-- (ROW(0, 1)::"complex")."imaginary"
504504field
@@ -522,7 +522,7 @@ instance Monoid
522522 mempty = array []
523523 mappend = (<>)
524524
525−-- | >>> let expr = greatest currentTimestamp [param @1] :: Expression commons schemas '[ 'NotNull 'PGtimestamptz] grp from ('NotNull 'PGtimestamptz)
525+-- | >>> let expr = greatest currentTimestamp [param @1] :: Expression grp commons schemas '[ 'NotNull 'PGtimestamptz] from ('NotNull 'PGtimestamptz)
526526-- >>> printSQL expr
527527-- GREATEST(CURRENT_TIMESTAMP, ($1 :: timestamp with time zone))
528528greatest
@@ -1398,7 +1398,7 @@ class Aggregate expr aggr where
13981398
13991399 -- | >>> :{
14001400 -- let
1401− -- expression :: Expression commons schemas params (Grouped bys) '[tab ::: '["col" ::: nullity ty]] ('NotNull 'PGint8)
1401+ -- expression :: Expression (Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity ty]] ('NotNull 'PGint8)
14021402 -- expression = count #col
14031403 -- in printSQL expression
14041404 -- :}
@@ -1484,23 +1484,37 @@ class Aggregate expr aggr where
14841484 -- ^ what to aggregate
14851485 -> aggr commons schemas params from (nullity 'PGbool)
14861486
1487− -- | minimum and maximum aggregation
1488− max_, min_
1487+ -- | maximum aggregation
1488+ max_
14891489 :: expr commons schemas params from (nullity ty)
1490− -- ^ what to aggregate
1490+ -- ^ what to maximize
14911491 -> aggr commons schemas params from (nullity ty)
14921492
1493−instance Aggregate (Expression 'Ungrouped) (Expression ('Grouped bys)) where
1494− count = unsafeAggregate "count"
1495− sum_ = unsafeAggregate "sum"
1496− bitAnd = unsafeAggregate "bit_and"
1497− bitOr = unsafeAggregate "bit_or"
1498− boolAnd = unsafeAggregate "bool_and"
1499− boolOr = unsafeAggregate "bool_or"
1500− every = unsafeAggregate "every"
1501− max_ = unsafeAggregate "max"
1502− min_ = unsafeAggregate "min"
1503−instance Aggregate DistinctExpression (Expression ('Grouped bys)) where
1493+ -- | minimum aggregation
1494+ min_
1495+ :: expr commons schemas params from (nullity ty)
1496+ -- ^ what to minimize
1497+ -> aggr commons schemas params from (nullity ty)
1498+
1499+ -- | average aggregation
1500+ avg
1501+ :: expr commons schemas params from (nullity ty)
1502+ -- ^ what to average
1503+ -> aggr commons schemas params from (nullity (PGAvg ty))
1504+
1505+instance {-# OVERLAPPABLE #-} expr ~ (Expression 'Ungrouped)
1506+ => Aggregate expr (Expression ('Grouped bys)) where
1507+ count = unsafeAggregate "count"
1508+ sum_ = unsafeAggregate "sum"
1509+ bitAnd = unsafeAggregate "bit_and"
1510+ bitOr = unsafeAggregate "bit_or"
1511+ boolAnd = unsafeAggregate "bool_and"
1512+ boolOr = unsafeAggregate "bool_or"
1513+ every = unsafeAggregate "every"
1514+ max_ = unsafeAggregate "max"
1515+ min_ = unsafeAggregate "min"
1516+ avg = unsafeAggregate "avg"
1517+instance {-# OVERLAPPING #-} Aggregate DistinctExpression (Expression ('Grouped bys)) where
15041518 count = unsafeAggregate "count"
15051519 sum_ = unsafeAggregate "sum"
15061520 bitAnd = unsafeAggregate "bit_and"
@@ -1510,6 +1524,7 @@ instance Aggregate DistinctExpression (Expression ('Grouped bys)) where
15101524 every = unsafeAggregate "every"
15111525 max_ = unsafeAggregate "max"
15121526 min_ = unsafeAggregate "min"
1527+ avg = unsafeAggregate "avg"
15131528instance Aggregate (Expression grp) (WindowFunction grp) where
15141529 count = unsafeWindowFunction1 "count"
15151530 sum_ = unsafeWindowFunction1 "sum"
@@ -1520,6 +1535,7 @@ instance Aggregate (Expression grp) (WindowFunction grp) where
15201535 every = unsafeWindowFunction1 "every"
15211536 max_ = unsafeWindowFunction1 "max"
15221537 min_ = unsafeWindowFunction1 "min"
1538+ avg = unsafeWindowFunction1 "avg"
15231539
15241540newtype DistinctExpression commons schemas params from ty
15251541 = Distinct (Expression 'Ungrouped commons schemas params from ty)
@@ -1536,30 +1552,15 @@ unsafeAggregate
15361552unsafeAggregate fun x = UnsafeExpression $ mconcat
15371553 [fun, "(", renderSQL x, ")"]
15381554
1539−-- | escape hatch to define aggregate functions over distinct values
1540−unsafeAggregateDistinct
1541− :: ByteString -- ^ aggregate function
1542− -> Expression 'Ungrouped commons schemas params from xty
1543− -> Expression ('Grouped bys) commons schemas params from yty
1544−unsafeAggregateDistinct fun x = UnsafeExpression $ mconcat
1545− [fun, "(DISTINCT ", renderSQL x, ")"]
1546−
1547−-- | A constraint for `PGType`s that you can take averages of and the resulting
1548−-- `PGType`.
1549−class PGAvg ty avg | ty -> avg where
1550− avg, avgDistinct
1551− :: Expression 'Ungrouped commons schemas params from (nullity ty)
1552− -- ^ what to average
1553− -> Expression ('Grouped bys) commons schemas params from (nullity avg)
1554− avg = unsafeAggregate "avg"
1555− avgDistinct = unsafeAggregateDistinct "avg"
1556−instance PGAvg 'PGint2 'PGnumeric
1557−instance PGAvg 'PGint4 'PGnumeric
1558−instance PGAvg 'PGint8 'PGnumeric
1559−instance PGAvg 'PGnumeric 'PGnumeric
1560−instance PGAvg 'PGfloat4 'PGfloat8
1561−instance PGAvg 'PGfloat8 'PGfloat8
1562−instance PGAvg 'PGinterval 'PGinterval
1555+-- | A type family that calculates `PGAvg` type of a `PGType`.
1556+type family PGAvg ty where
1557+ PGAvg 'PGint2 = 'PGnumeric
1558+ PGAvg 'PGint4 = 'PGnumeric
1559+ PGAvg 'PGint8 = 'PGnumeric
1560+ PGAvg 'PGnumeric = 'PGnumeric
1561+ PGAvg 'PGfloat4 = 'PGfloat8
1562+ PGAvg 'PGfloat8 = 'PGfloat8
1563+ PGAvg 'PGinterval = 'PGinterval
15631564
15641565-- | A special aggregation that does not require an input
15651566--