@@ -1,5 +1,5 @@
11{-|
2−Module: Squeal.PostgreSQL.Query
2+Module: Squeal.PostgreSQL.Expression
33Description: Squeal expressions
44Copyright: (c) Eitan Chatav, 2017
55Maintainer: eitan@morphism.tech
@@ -210,7 +210,7 @@ import qualified Data.Aeson as JSON
210210import Data.Ratio
211211import Data.String
212212import Data.Word
213−import Generics.SOP hiding (from)
213+import Generics.SOP hiding (All, from)
214214import GHC.Generics ((:*:) (..))
215215import GHC.OverloadedLabels
216216import GHC.TypeLits
@@ -218,6 +218,7 @@ import Prelude hiding (id, (.))
218218
219219import qualified Data.ByteString as ByteString
220220import qualified GHC.Generics as GHC
221+import qualified Generics.SOP as SOP
221222
222223import Squeal.PostgreSQL.Render
223224import Squeal.PostgreSQL.Schema
@@ -1216,11 +1217,11 @@ jsonbBuildArray
12161217jsonbBuildArray = unsafeVariadicFunction "jsonb_build_array"
12171218
12181219unsafeRowFunction
1219− :: All Top elems
1220+ :: SOP.All SOP.Top elems
12201221 => NP (Aliased (Expression outer grp commons schemas params from)) elems
12211222 -> [ByteString]
12221223unsafeRowFunction =
1223− (`appEndo` []) . hcfoldMap (Proxy :: Proxy Top)
1224+ (`appEndo` []) . hcfoldMap (Proxy :: SOP.Proxy SOP.Top)
12241225 (\(col `As` name) -> Endo $ \xs ->
12251226 renderAliasString name : renderSQL col : xs)
12261227 where
@@ -1231,7 +1232,7 @@ unsafeRowFunction =
12311232-- argument list. The elements of the argument list must alternate between text
12321233-- and values.
12331234jsonBuildObject
1234− :: All Top elems
1235+ :: SOP.All SOP.Top elems
12351236 => NP (Aliased (Expression outer grp commons schemas params from)) elems
12361237 -> Expression outer grp commons schemas params from (nullity 'PGjson)
12371238jsonBuildObject
@@ -1244,7 +1245,7 @@ jsonBuildObject
12441245-- variadic argument list. The elements of the argument list must alternate
12451246-- between text and values.
12461247jsonbBuildObject
1247− :: All Top elems
1248+ :: SOP.All SOP.Top elems
12481249 => NP (Aliased (Expression outer grp commons schemas params from)) elems
12491250 -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
12501251jsonbBuildObject
@@ -1427,6 +1428,11 @@ jsonbPretty = unsafeFunction "jsonb_pretty"
14271428aggregation
14281429-----------------------------------------}
14291430
1431+{- |
1432+`Aggregate` functions compute a single result from a set of input values.
1433+`Aggregate` functions can be used as `GroupedBy` `Expression`s as well
1434+as `WindowFunction`s.
1435+-}
14301436class Aggregate expr1 expr2 aggr
14311437 | aggr -> expr1, aggr -> expr2 where
14321438
@@ -1714,6 +1720,12 @@ class Aggregate expr1 expr2 aggr
17141720 :: expr1 (nullity ty)
17151721 -> aggr (nullity (PGAvg ty))
17161722
1723+{- |
1724+`Distinction`s are used for the input of `Aggregate` `Expression`s.
1725+`All` invokes the aggregate once for each input row.
1726+`Distinct` invokes the aggregate once for each distinct value of the expression
1727+(or distinct set of values, for multiple expressions) found in the input
1728+-}
17171729data Distinction expr ty
17181730 = All (expr ty)
17191731 | Distinct (expr ty)
@@ -1839,7 +1851,8 @@ type family PGAvg ty where
18391851type expressions
18401852-----------------------------------------}
18411853
1842−-- | `TypeExpression`s are used in `cast`s and `createTable` commands.
1854+-- | `TypeExpression`s are used in `cast`s and
1855+-- `Squeal.PostgreSQL.Definition.createTable` commands.
18431856newtype TypeExpression (schemas :: SchemasType) (ty :: NullityType)
18441857 = UnsafeTypeExpression { renderTypeExpression :: ByteString }
18451858 deriving (GHC.Generic,Show,Eq,Ord,NFData)
@@ -1955,21 +1968,21 @@ vararray ty = UnsafeTypeExpression $ renderSQL ty <> "[]"
19551968-- >>> renderSQL (fixarray @'[2] json)
19561969-- "json[2]"
19571970fixarray
1958− :: forall dims schemas nullity pg. All KnownNat dims
1971+ :: forall dims schemas nullity pg. SOP.All KnownNat dims
19591972 => TypeExpression schemas pg
19601973 -> TypeExpression schemas (nullity ('PGfixarray dims pg))
19611974fixarray ty = UnsafeTypeExpression $
19621975 renderSQL ty <> renderDims @dims
19631976 where
1964− renderDims :: forall ns. All KnownNat ns => ByteString
1977+ renderDims :: forall ns. SOP.All KnownNat ns => ByteString
19651978 renderDims =
19661979 ("[" <>)
19671980 . (<> "]")
19681981 . ByteString.intercalate "]["
19691982 . hcollapse
1970− $ hcmap (Proxy @KnownNat)
1983+ $ hcmap (SOP.Proxy @KnownNat)
19711984 (K . fromString . show . natVal)
1972− (hpure Proxy :: NP Proxy ns)
1985+ (hpure SOP.Proxy :: NP SOP.Proxy ns)
19731986
19741987-- | `pgtype` is a demoted version of a `PGType`
19751988class PGTyped schemas (ty :: NullityType) where
@@ -1999,7 +2012,7 @@ instance PGTyped schemas (nullity 'PGjsonb) where pgtype = jsonb
19992012instance PGTyped schemas ty
20002013 => PGTyped schemas (nullity ('PGvararray ty)) where
20012014 pgtype = vararray (pgtype @schemas @ty)
2002−instance (All KnownNat dims, PGTyped schemas ty)
2015+instance (SOP.All KnownNat dims, PGTyped schemas ty)
20032016 => PGTyped schemas (nullity ('PGfixarray dims ty)) where
20042017 pgtype = fixarray @dims (pgtype @schemas @ty)
20052018
@@ -2007,8 +2020,9 @@ instance (All KnownNat dims, PGTyped schemas ty)
20072020Sorting
20082021-----------------------------------------}
20092022
2010−-- | `SortExpression`s are used by `sortBy` to optionally sort the results
2011−-- of a `Query`. `Asc` or `Desc` set the sort direction of a `NotNull` result
2023+-- | `SortExpression`s are used by `orderBy` to optionally sort the results
2024+-- of a `Squeal.PostgreSQL.Query.Query`. `Asc` or `Desc`
2025+-- set the sort direction of a `NotNull` result
20122026-- column to ascending or descending. Ascending order puts smaller values
20132027-- first, where "smaller" is defined in terms of the `.<` operator. Similarly,
20142028-- descending order is determined with the `.>` operator. `AscNullsFirst`,
@@ -2016,26 +2030,37 @@ Sorting
20162030-- determine whether nulls appear before or after non-null values in the sort
20172031-- ordering of a `Null` result column.
20182032data SortExpression outer grp commons schemas params from where
2019− Asc
2020− :: Expression outer grp commons schemas params from ('NotNull ty)
2021− -> SortExpression outer grp commons schemas params from
2022− Desc
2023− :: Expression outer grp commons schemas params from ('NotNull ty)
2024− -> SortExpression outer grp commons schemas params from
2025− AscNullsFirst
2026− :: Expression outer grp commons schemas params from ('Null ty)
2027− -> SortExpression outer grp commons schemas params from
2028− AscNullsLast
2029− :: Expression outer grp commons schemas params from ('Null ty)
2030− -> SortExpression outer grp commons schemas params from
2031− DescNullsFirst
2032− :: Expression outer grp commons schemas params from ('Null ty)
2033− -> SortExpression outer grp commons schemas params from
2034− DescNullsLast
2035− :: Expression outer grp commons schemas params from ('Null ty)
2036− -> SortExpression outer grp commons schemas params from
2033+ Asc
2034+ :: Expression outer grp commons schemas params from ('NotNull ty)
2035+ -> SortExpression outer grp commons schemas params from
2036+ Desc
2037+ :: Expression outer grp commons schemas params from ('NotNull ty)
2038+ -> SortExpression outer grp commons schemas params from
2039+ AscNullsFirst
2040+ :: Expression outer grp commons schemas params from ('Null ty)
2041+ -> SortExpression outer grp commons schemas params from
2042+ AscNullsLast
2043+ :: Expression outer grp commons schemas params from ('Null ty)
2044+ -> SortExpression outer grp commons schemas params from
2045+ DescNullsFirst
2046+ :: Expression outer grp commons schemas params from ('Null ty)
2047+ -> SortExpression outer grp commons schemas params from
2048+ DescNullsLast
2049+ :: Expression outer grp commons schemas params from ('Null ty)
2050+ -> SortExpression outer grp commons schemas params from
20372051deriving instance Show (SortExpression outer grp commons schemas params from)
20382052
2053+{- |
2054+The `orderBy` clause causes the result rows of a `Squeal.PostgreSQL.Query.TableExpression`
2055+to be sorted according to the specified `SortExpression`(s).
2056+If two rows are equal according to the leftmost expression,
2057+they are compared according to the next expression and so on.
2058+If they are equal according to all specified expressions,
2059+they are returned in an implementation-dependent order.
2060+
2061+You can also control the order in which rows are processed by window functions
2062+using `orderBy` within `Squeal.PostgreSQL.Query.Over`.
2063+-}
20392064class OrderBy expr where
20402065 orderBy
20412066 :: [SortExpression outer grp commons schemas params from]
@@ -2054,6 +2079,8 @@ instance RenderSQL (SortExpression outer grp commons schemas params from) where
20542079 AscNullsLast expression -> renderSQL expression <+> "ASC NULLS LAST"
20552080 DescNullsLast expression -> renderSQL expression <+> "DESC NULLS LAST"
20562081
2082+-- | A `WindowDefinition` is a set of table rows that are somehow related
2083+-- to the current row
20572084data WindowDefinition outer grp commons schemas params from where
20582085 WindowDefinition
20592086 :: SListI bys
@@ -2077,12 +2104,28 @@ instance RenderSQL (WindowDefinition outer commons schemas from grp params) wher
20772104 srts -> " ORDER" <+> "BY"
20782105 <+> commaSeparated (renderSQL <$> srts)
20792106
2107+{- |
2108+The `partitionBy` clause within `Squeal.PostgreSQL.Query.Over` divides the rows into groups,
2109+or partitions, that share the same values of the `partitionBy` `Expression`(s).
2110+For each row, the window function is computed across the rows that fall into
2111+the same partition as the current row.
2112+-}
20802113partitionBy
20812114 :: SListI bys
20822115 => NP (Expression outer grp commons schemas params from) bys
20832116 -> WindowDefinition outer grp commons schemas params from
20842117partitionBy bys = WindowDefinition bys []
20852118
2119+{- |
2120+A window function performs a calculation across a set of table rows
2121+that are somehow related to the current row. This is comparable to the type
2122+of calculation that can be done with an aggregate function.
2123+However, window functions do not cause rows to become grouped into a single
2124+output row like non-window aggregate calls would.
2125+Instead, the rows retain their separate identities.
2126+Behind the scenes, the window function is able to access more than
2127+just the current row of the query result.
2128+-}
20862129newtype WindowFunction
20872130 (outer :: FromType)
20882131 (grp :: Grouping)