on dev help sign in
some aggregate stuff
e5dd493Eitan Chatav
squeal-postgresql/src/Squeal/PostgreSQL/Expression.hs+46−45
@@ -136,7 +136,7 @@ module Squeal.PostgreSQL.Expression
136 -- ** Aggregation
136 -- ** Aggregation
137 , Aggregate (..)
137 , Aggregate (..)
138 , DistinctExpression (..)
138 , DistinctExpression (..)
139− , PGAvg (avg, avgDistinct)
139+ , PGAvg
140 , countStar
140 , countStar
141 -- * Window Functions
141 -- * Window Functions
142 , WindowDefinition (..)
142 , WindowDefinition (..)
@@ -261,7 +261,7 @@ class KnownNat n => HasParameter
261 | n params -> ty where
261 | n params -> ty where
262 -- | `parameter` takes a `Nat` using type application and a `TypeExpression`.
262 -- | `parameter` takes a `Nat` using type application and a `TypeExpression`.
263 --
263 --
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)
265 -- >>> printSQL expr
265 -- >>> printSQL expr
266 -- ($1 :: int4)
266 -- ($1 :: int4)
267 parameter
267 parameter
@@ -277,7 +277,7 @@ instance {-# OVERLAPPABLE #-} (KnownNat n, HasParameter (n-1) params ty)
277-- | `param` takes a `Nat` using type application and for basic types,
277-- | `param` takes a `Nat` using type application and for basic types,
278-- infers a `TypeExpression`.
278-- infers a `TypeExpression`.
279--
279--
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)
281-- >>> printSQL expr
281-- >>> printSQL expr
282-- ($1 :: int4)
282-- ($1 :: int4)
283param
283param
@@ -436,7 +436,7 @@ matchNull y f x = ifThenElse (isNull x) y
436`nullIf` gives @NULL@.
436`nullIf` gives @NULL@.
437
437
438>>> :set -XTypeApplications -XDataKinds
438>>> :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)
440>>> printSQL expr
440>>> printSQL expr
441NULL IF (FALSE, ($1 :: bool))
441NULL IF (FALSE, ($1 :: bool))
442-}
442-}
@@ -498,7 +498,7 @@ row exprs = UnsafeExpression $ "ROW" <> parenthesized
498-- type Schema = '["complex" ::: 'Typedef Complex]
498-- type Schema = '["complex" ::: 'Typedef Complex]
499-- :}
499-- :}
500--
500--
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)
502-- >>> printSQL $ i & field #complex #imaginary
502-- >>> printSQL $ i & field #complex #imaginary
503-- (ROW(0, 1)::"complex")."imaginary"
503-- (ROW(0, 1)::"complex")."imaginary"
504field
504field
@@ -522,7 +522,7 @@ instance Monoid
522 mempty = array []
522 mempty = array []
523 mappend = (<>)
523 mappend = (<>)
524
524
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)
526-- >>> printSQL expr
526-- >>> printSQL expr
527-- GREATEST(CURRENT_TIMESTAMP, ($1 :: timestamp with time zone))
527-- GREATEST(CURRENT_TIMESTAMP, ($1 :: timestamp with time zone))
528greatest
528greatest
@@ -1398,7 +1398,7 @@ class Aggregate expr aggr where
1398
1398
1399 -- | >>> :{
1399 -- | >>> :{
1400 -- let
1400 -- 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)
1402 -- expression = count #col
1402 -- expression = count #col
1403 -- in printSQL expression
1403 -- in printSQL expression
1404 -- :}
1404 -- :}
@@ -1484,23 +1484,37 @@ class Aggregate expr aggr where
1484 -- ^ what to aggregate
1484 -- ^ what to aggregate
1485 -> aggr commons schemas params from (nullity 'PGbool)
1485 -> aggr commons schemas params from (nullity 'PGbool)
1486
1486
1487− -- | minimum and maximum aggregation
1487+ -- | maximum aggregation
1488− max_, min_
1488+ max_
1489 :: expr commons schemas params from (nullity ty)
1489 :: expr commons schemas params from (nullity ty)
1490− -- ^ what to aggregate
1490+ -- ^ what to maximize
1491 -> aggr commons schemas params from (nullity ty)
1491 -> aggr commons schemas params from (nullity ty)
1492
1492
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+
1493−instance Aggregate (Expression 'Ungrouped) (Expression ('Grouped bys)) where
1505+instance {-# OVERLAPPABLE #-} expr ~ (Expression 'Ungrouped)
1506+ => Aggregate expr (Expression ('Grouped bys)) where
1494− count = unsafeAggregate "count"
1507+ count = unsafeAggregate "count"
1495− sum_ = unsafeAggregate "sum"
1508+ sum_ = unsafeAggregate "sum"
1496− bitAnd = unsafeAggregate "bit_and"
1509+ bitAnd = unsafeAggregate "bit_and"
1497− bitOr = unsafeAggregate "bit_or"
1510+ bitOr = unsafeAggregate "bit_or"
1498− boolAnd = unsafeAggregate "bool_and"
1511+ boolAnd = unsafeAggregate "bool_and"
1499− boolOr = unsafeAggregate "bool_or"
1512+ boolOr = unsafeAggregate "bool_or"
1500− every = unsafeAggregate "every"
1513+ every = unsafeAggregate "every"
1501− max_ = unsafeAggregate "max"
1514+ max_ = unsafeAggregate "max"
1502− min_ = unsafeAggregate "min"
1515+ min_ = unsafeAggregate "min"
1516+ avg = unsafeAggregate "avg"
1503−instance Aggregate DistinctExpression (Expression ('Grouped bys)) where
1517+instance {-# OVERLAPPING #-} Aggregate DistinctExpression (Expression ('Grouped bys)) where
1504 count = unsafeAggregate "count"
1518 count = unsafeAggregate "count"
1505 sum_ = unsafeAggregate "sum"
1519 sum_ = unsafeAggregate "sum"
1506 bitAnd = unsafeAggregate "bit_and"
1520 bitAnd = unsafeAggregate "bit_and"
@@ -1510,6 +1524,7 @@ instance Aggregate DistinctExpression (Expression ('Grouped bys)) where
1510 every = unsafeAggregate "every"
1524 every = unsafeAggregate "every"
1511 max_ = unsafeAggregate "max"
1525 max_ = unsafeAggregate "max"
1512 min_ = unsafeAggregate "min"
1526 min_ = unsafeAggregate "min"
1527+ avg = unsafeAggregate "avg"
1513instance Aggregate (Expression grp) (WindowFunction grp) where
1528instance Aggregate (Expression grp) (WindowFunction grp) where
1514 count = unsafeWindowFunction1 "count"
1529 count = unsafeWindowFunction1 "count"
1515 sum_ = unsafeWindowFunction1 "sum"
1530 sum_ = unsafeWindowFunction1 "sum"
@@ -1520,6 +1535,7 @@ instance Aggregate (Expression grp) (WindowFunction grp) where
1520 every = unsafeWindowFunction1 "every"
1535 every = unsafeWindowFunction1 "every"
1521 max_ = unsafeWindowFunction1 "max"
1536 max_ = unsafeWindowFunction1 "max"
1522 min_ = unsafeWindowFunction1 "min"
1537 min_ = unsafeWindowFunction1 "min"
1538+ avg = unsafeWindowFunction1 "avg"
1523
1539
1524newtype DistinctExpression commons schemas params from ty
1540newtype DistinctExpression commons schemas params from ty
1525 = Distinct (Expression 'Ungrouped commons schemas params from ty)
1541 = Distinct (Expression 'Ungrouped commons schemas params from ty)
@@ -1536,30 +1552,15 @@ unsafeAggregate
1536unsafeAggregate fun x = UnsafeExpression $ mconcat
1552unsafeAggregate fun x = UnsafeExpression $ mconcat
1537 [fun, "(", renderSQL x, ")"]
1553 [fun, "(", renderSQL x, ")"]
1538
1554
1539−-- | escape hatch to define aggregate functions over distinct values
1555+-- | A type family that calculates `PGAvg` type of a `PGType`.
1540−unsafeAggregateDistinct
1556+type family PGAvg ty where
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+ PGAvg 'PGint2 = 'PGnumeric
1557−instance PGAvg 'PGint4 'PGnumeric
1558+ PGAvg 'PGint4 = 'PGnumeric
1558−instance PGAvg 'PGint8 'PGnumeric
1559+ PGAvg 'PGint8 = 'PGnumeric
1559−instance PGAvg 'PGnumeric 'PGnumeric
1560+ PGAvg 'PGnumeric = 'PGnumeric
1560−instance PGAvg 'PGfloat4 'PGfloat8
1561+ PGAvg 'PGfloat4 = 'PGfloat8
1561−instance PGAvg 'PGfloat8 'PGfloat8
1562+ PGAvg 'PGfloat8 = 'PGfloat8
1562−instance PGAvg 'PGinterval 'PGinterval
1563+ PGAvg 'PGinterval = 'PGinterval
1563
1564
1564-- | A special aggregation that does not require an input
1565-- | A special aggregation that does not require an input
1565--
1566--