@@ -1,13 +1,14 @@
2−Module: Squeal.PostgreSQL.Expression
2+Module: Squeal.PostgreSQL.Query
3Description: Squeal expressions
3Description: Squeal expressions
4−Copyright: (c) Eitan Chatav, 2019
4+Copyright: (c) Eitan Chatav, 2017
5Maintainer: eitan@morphism.tech
5Maintainer: eitan@morphism.tech
6Stability: experimental
6Stability: experimental
8Squeal expressions are the atoms used to build statements.
8Squeal expressions are the atoms used to build statements.
11+{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
11{-# LANGUAGE
12{-# LANGUAGE
12 AllowAmbiguousTypes
13 AllowAmbiguousTypes
13 , ConstraintKinds
14 , ConstraintKinds
@@ -33,214 +34,291 @@ Squeal expressions are the atoms used to build statements.
33module Squeal.PostgreSQL.Expression
34module Squeal.PostgreSQL.Expression
34 ( -- * Expression
35 ( -- * Expression
35 Expression (..)
36 Expression (..)
36− , Expr
37+ , HasParameter (parameter)
37− , type (-->)
38+ , param
38− , FunctionDB
39+ -- ** Null
39− , unsafeFunction
40+ , null_
40− , function
41+ , notNull
41− , unsafeLeftOp
42+ , coalesce
42− , leftOp
43+ , fromNull
43− , unsafeRightOp
44+ , isNull
44− , rightOp
45+ , isNotNull
45− , Operator
46+ , matchNull
46− , OperatorDB
47+ , nullIf
47 , unsafeBinaryOp
54 , unsafeBinaryOp
48− , binaryOp
55+ , unsafeUnaryOp
49− , FunctionVar
56+ , unsafeFunction
50− , unsafeFunctionVar
57+ , unsafeVariadicFunction
51− , type (--->)
58+ , atan2_
52− , FunctionNDB
59+ , cast
53− , unsafeFunctionN
60+ , quot_
54− , functionN
61+ , rem_
55− , PGSubset (..)
62+ , trunc
56− , PGIntersect (..)
63+ , round_
95+ -- *** Json and Jsonb operators
100+ -- *** Jsonb operators
127+ , jsonExtractPathAsText
128+ , jsonbExtractPathAsText
140+ -- * Window Functions
141+ , WindowDefinition (..)
143+ , WindowFunction (..)
156+ , SortExpression (..)
159+ , TypeExpression (..)
184+ , timestampWithTimeZone
57 -- * Re-export
195 -- * Re-export
63import Control.Category
203import Control.Category
64import Control.DeepSeq
204import Control.DeepSeq
65import Data.ByteString (ByteString)
205import Data.ByteString (ByteString)
206+import Data.ByteString.Lazy (toStrict)
66import Data.Function ((&))
207import Data.Function ((&))
67import Data.Semigroup hiding (All)
208import Data.Semigroup hiding (All)
209+import qualified Data.Aeson as JSON
68import Data.String
211import Data.String
69−import Generics.SOP hiding (All, from)
213+import Generics.SOP hiding (from)
214+import GHC.Generics ((:*:) (..))
70import GHC.OverloadedLabels
215import GHC.OverloadedLabels
71import GHC.TypeLits
216import GHC.TypeLits
73import Prelude hiding (id, (.))
217import Prelude hiding (id, (.))
219+import qualified Data.ByteString as ByteString
75import qualified GHC.Generics as GHC
220import qualified GHC.Generics as GHC
77−import Squeal.PostgreSQL.Alias
78−import Squeal.PostgreSQL.List
79import Squeal.PostgreSQL.Render
222import Squeal.PostgreSQL.Render
80import Squeal.PostgreSQL.Schema
223import Squeal.PostgreSQL.Schema
83−-- >>> import Squeal.PostgreSQL
85{-----------------------------------------
225{-----------------------------------------
86column expressions
226column expressions
87-----------------------------------------}
227-----------------------------------------}
89{- | `Expression`s are used in a variety of contexts,
229{- | `Expression`s are used in a variety of contexts,
90−such as in the target `Squeal.PostgreSQL.Query.List` of the
91−`Squeal.PostgreSQL.Query.select` command,
230+such as in the target list of the `Squeal.PostgreSQL.Query.select` command,
92as new column values in `Squeal.PostgreSQL.Manipulation.insertRow` or
231as new column values in `Squeal.PostgreSQL.Manipulation.insertRow` or
93`Squeal.PostgreSQL.Manipulation.update`,
232`Squeal.PostgreSQL.Manipulation.update`,
94−or in search `Squeal.PostgreSQL.Logic.Condition`s in a number of commands.
233+or in search `Condition`s in a number of commands.
96The expression syntax allows the calculation of
235The expression syntax allows the calculation of
97values from primitive expression using arithmetic, logical,
236values from primitive expression using arithmetic, logical,
98and other operations.
237and other operations.
100−The type parameters of `Expression` are
102−* @outer :: @ `FromType`, the @from@ clauses of any outer queries in which
103− the `Expression` is a correlated subquery expression;
104−* @commons :: @ `FromType`, the `Squeal.PostgreSQL.Query.CommonTableExpression`s
105− that are in scope for the `Expression`;
106−* @grp :: @ `Grouping`, the `Grouping` of the @from@ clause which may limit
107− which columns may be referenced by alias;
108−* @schemas :: @ `SchemasType`, the schemas of your database that are in
109− scope for the `Expression`;
110−* @from :: @ `FromType`, the @from@ clause which the `Expression` may use
111− to reference columns by alias;
112−* @ty :: @ `NullityType`, the type of the `Expression`.
114newtype Expression
239newtype Expression
115 (outer :: FromType)
240 (outer :: FromType)
116− (commons :: FromType)
117 (grp :: Grouping)
241 (grp :: Grouping)
242+ (commons :: FromType)
118 (schemas :: SchemasType)
243 (schemas :: SchemasType)
119 (params :: [NullityType])
244 (params :: [NullityType])
120 (from :: FromType)
245 (from :: FromType)
121 (ty :: NullityType)
246 (ty :: NullityType)
122 = UnsafeExpression { renderExpression :: ByteString }
247 = UnsafeExpression { renderExpression :: ByteString }
123 deriving (GHC.Generic,Show,Eq,Ord,NFData)
248 deriving (GHC.Generic,Show,Eq,Ord,NFData)
124−instance RenderSQL (Expression outer commons grp schemas params from ty) where
250+instance RenderSQL (Expression outer grp commons schemas params from ty) where
125 renderSQL = renderExpression
251 renderSQL = renderExpression
127−-- | An `Expr` is a closed `Expression`.
253+{- | A `HasParameter` constraint is used to indicate a value that is
128−-- It is a F@RankNType@ but don't be scared.
254+supplied externally to a SQL statement.
129−-- Think of it as an expression which sees no
255+`Squeal.PostgreSQL.PQ.manipulateParams`,
130−-- namespaces, so you can't use parameters
256+`Squeal.PostgreSQL.PQ.queryParams` and
131−-- or alias references. It can be used as
257+`Squeal.PostgreSQL.PQ.traversePrepared` support specifying data values
132−-- a simple piece of more complex `Expression`s.
258+separately from the SQL command string, in which case `param`s are used to
133−type Expr x
259+refer to the out-of-line data values.
134− = forall outer commons grp schemas params from
135− . Expression outer commons grp schemas params from x
136− -- ^ cannot reference aliases
138−-- | A @RankNType@ for binary operators.
139−type Operator x1 x2 y
140− = forall outer commons grp schemas params from
141− . Expression outer commons grp schemas params from x1
143− -> Expression outer commons grp schemas params from x2
145− -> Expression outer commons grp schemas params from y
148−type OperatorDB schemas x1 x2 y
149− = forall outer commons grp params from
150− . Expression outer commons grp schemas params from x1
152− -> Expression outer commons grp schemas params from x2
154− -> Expression outer commons grp schemas params from y
157−-- | A @RankNType@ for functions with a single argument.
158−-- These could be either function calls or unary operators.
159−-- This is a subtype of the usual Haskell function type `Prelude.->`,
160−-- indeed a subcategory as it is closed under the usual
161−-- `Prelude..` and `Prelude.id`.
163− = forall outer commons grp schemas params from
164− . Expression outer commons grp schemas params from x
166− -> Expression outer commons grp schemas params from y
169−type FunctionDB schemas x y
170− = forall outer commons grp params from
171− . Expression outer commons grp schemas params from x
173− -> Expression outer commons grp schemas params from y
176−{- | A @RankNType@ for functions with a fixed-length list of heterogeneous arguments.
177−Use the `*:` operator to end your argument lists, like so.
179−>>> printSQL (unsafeFunctionN "fun" (true :* false :* localTime *: true))
180−fun(TRUE, FALSE, LOCALTIME, TRUE)
183− = forall outer commons grp schemas params from
184− . NP (Expression outer commons grp schemas params from) xs
186− -> Expression outer commons grp schemas params from y
189−type FunctionNDB schemas xs y
190− = forall outer commons grp params from
191− . NP (Expression outer commons grp schemas params from) xs
193− -> Expression outer commons grp schemas params from y
196−{- | A @RankNType@ for functions with a variable-length list of
197−homogeneous arguments and at least 1 more argument.
199−type FunctionVar x0 x1 y
261+class KnownNat n => HasParameter
200− = forall outer commons grp schemas params from
262+ (n :: Nat)
201− . [Expression outer commons grp schemas params from x0]
263+ (params :: [NullityType])
202− -- ^ inputs
264+ (ty :: NullityType)
203− -> Expression outer commons grp schemas params from x1
265+ | n params -> ty where
204− -- ^ must have at least 1 input
266+ -- | `parameter` takes a `Nat` using type application and a `TypeExpression`.
205− -> Expression outer commons grp schemas params from y
268+ -- >>> let expr = parameter @1 int4 :: Expression outer grp '[] schemas '[ 'Null 'PGint4] from ('Null 'PGint4)
206− -- ^ output
269+ -- >>> printSQL expr
208−{- | >>> printSQL (unsafeFunctionVar "greatest" [true, null_] false)
271+ parameter
209−greatest(TRUE, NULL, FALSE)
272+ :: TypeExpression schemas ty
210−-}
273+ -> Expression outer grp commons schemas params from ty
211−unsafeFunctionVar :: ByteString -> FunctionVar x0 x1 y
212−unsafeFunctionVar fun xs x = UnsafeExpression $ fun <> parenthesized
274+ parameter ty = UnsafeExpression $ parenthesized $
213− (commaSeparated (renderSQL <$> xs) <> ", " <> renderSQL x)
275+ "$" <> renderNat @n <+> "::"
277+instance {-# OVERLAPPING #-} HasParameter 1 (ty1:tys) ty1
278+instance {-# OVERLAPPABLE #-} (KnownNat n, HasParameter (n-1) params ty)
279+ => HasParameter n (ty' : params) ty
281+-- | `param` takes a `Nat` using type application and for basic types,
282+-- infers a `TypeExpression`.
284+-- >>> let expr = param @1 :: Expression outer grp commons schemas '[ 'Null 'PGint4] from ('Null 'PGint4)
288+ :: forall n outer commons schemas params from grp ty
289+ . (PGTyped schemas ty, HasParameter n params ty)
290+ => Expression outer grp commons schemas params from ty -- ^ param
291+param = parameter @n (pgtype @schemas)
215instance (HasUnique tab (Join outer from) row, Has col row ty)
293instance (HasUnique tab (Join outer from) row, Has col row ty)
216− => IsLabel col (Expression outer commons 'Ungrouped schemas params from ty) where
294+ => IsLabel col (Expression outer 'Ungrouped commons schemas params from ty) where
217 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
295 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
218instance (HasUnique tab (Join outer from) row, Has col row ty, tys ~ '[ty])
296instance (HasUnique tab (Join outer from) row, Has col row ty, tys ~ '[ty])
219− => IsLabel col (NP (Expression outer commons 'Ungrouped schemas params from) tys) where
297+ => IsLabel col (NP (Expression outer 'Ungrouped commons schemas params from) tys) where
220 fromLabel = fromLabel @col :* Nil
298 fromLabel = fromLabel @col :* Nil
221instance (HasUnique tab (Join outer from) row, Has col row ty, column ~ (col ::: ty))
299instance (HasUnique tab (Join outer from) row, Has col row ty, column ~ (col ::: ty))
222 => IsLabel col
300 => IsLabel col
223− (Aliased (Expression outer commons 'Ungrouped schemas params from) column) where
301+ (Aliased (Expression outer 'Ungrouped commons schemas params from) column) where
224 fromLabel = fromLabel @col `As` Alias
302 fromLabel = fromLabel @col `As` Alias
225instance (HasUnique tab (Join outer from) row, Has col row ty, columns ~ '[col ::: ty])
303instance (HasUnique tab (Join outer from) row, Has col row ty, columns ~ '[col ::: ty])
226 => IsLabel col
304 => IsLabel col
227− (NP (Aliased (Expression outer commons 'Ungrouped schemas params from)) columns) where
305+ (NP (Aliased (Expression outer 'Ungrouped commons schemas params from)) columns) where
228 fromLabel = fromLabel @col :* Nil
306 fromLabel = fromLabel @col :* Nil
230instance (Has tab (Join outer from) row, Has col row ty)
308instance (Has tab (Join outer from) row, Has col row ty)
231− => IsQualified tab col (Expression outer commons 'Ungrouped schemas params from ty) where
309+ => IsQualified tab col (Expression outer 'Ungrouped commons schemas params from ty) where
232 tab ! col = UnsafeExpression $
310 tab ! col = UnsafeExpression $
233 renderSQL tab <> "." <> renderSQL col
311 renderSQL tab <> "." <> renderSQL col
234instance (Has tab (Join outer from) row, Has col row ty, tys ~ '[ty])
312instance (Has tab (Join outer from) row, Has col row ty, tys ~ '[ty])
235− => IsQualified tab col (NP (Expression outer commons 'Ungrouped schemas params from) tys) where
313+ => IsQualified tab col (NP (Expression outer 'Ungrouped commons schemas params from) tys) where
236 tab ! col = tab ! col :* Nil
314 tab ! col = tab ! col :* Nil
237instance (Has tab (Join outer from) row, Has col row ty, column ~ (col ::: ty))
315instance (Has tab (Join outer from) row, Has col row ty, column ~ (col ::: ty))
238 => IsQualified tab col
316 => IsQualified tab col
239− (Aliased (Expression outer commons 'Ungrouped schemas params from) column) where
317+ (Aliased (Expression outer 'Ungrouped commons schemas params from) column) where
240 tab ! col = tab ! col `As` col
318 tab ! col = tab ! col `As` col
241instance (Has tab (Join outer from) row, Has col row ty, columns ~ '[col ::: ty])
319instance (Has tab (Join outer from) row, Has col row ty, columns ~ '[col ::: ty])
242 => IsQualified tab col
320 => IsQualified tab col
243− (NP (Aliased (Expression outer commons 'Ungrouped schemas params from)) columns) where
321+ (NP (Aliased (Expression outer 'Ungrouped commons schemas params from)) columns) where
244 tab ! col = tab ! col :* Nil
322 tab ! col = tab ! col :* Nil
@@ -248,7 +326,7 @@ instance
248 , Has col row ty
326 , Has col row ty
249 , GroupedBy tab col bys
327 , GroupedBy tab col bys
250 ) => IsLabel col
328 ) => IsLabel col
251− (Expression outer commons ('Grouped bys) schemas params from ty) where
329+ (Expression outer ('Grouped bys) commons schemas params from ty) where
252 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
330 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
254 ( HasUnique tab (Join outer from) row
332 ( HasUnique tab (Join outer from) row
@@ -256,7 +334,7 @@ instance
256 , GroupedBy tab col bys
334 , GroupedBy tab col bys
257 , tys ~ '[ty]
335 , tys ~ '[ty]
258 ) => IsLabel col
336 ) => IsLabel col
259− (NP (Expression outer commons ('Grouped bys) schemas params from) tys) where
337+ (NP (Expression outer ('Grouped bys) commons schemas params from) tys) where
260 fromLabel = fromLabel @col :* Nil
338 fromLabel = fromLabel @col :* Nil
262 ( HasUnique tab (Join outer from) row
340 ( HasUnique tab (Join outer from) row
@@ -264,7 +342,7 @@ instance
264 , GroupedBy tab col bys
342 , GroupedBy tab col bys
265 , column ~ (col ::: ty)
343 , column ~ (col ::: ty)
266 ) => IsLabel col
344 ) => IsLabel col
267− (Aliased (Expression outer commons ('Grouped bys) schemas params from) column) where
345+ (Aliased (Expression outer ('Grouped bys) commons schemas params from) column) where
268 fromLabel = fromLabel @col `As` Alias
346 fromLabel = fromLabel @col `As` Alias
270 ( HasUnique tab (Join outer from) row
348 ( HasUnique tab (Join outer from) row
@@ -272,7 +350,7 @@ instance
272 , GroupedBy tab col bys
350 , GroupedBy tab col bys
273 , columns ~ '[col ::: ty]
351 , columns ~ '[col ::: ty]
274 ) => IsLabel col
352 ) => IsLabel col
275− (NP (Aliased (Expression outer commons ('Grouped bys) schemas params from)) columns) where
353+ (NP (Aliased (Expression outer ('Grouped bys) commons schemas params from)) columns) where
276 fromLabel = fromLabel @col :* Nil
354 fromLabel = fromLabel @col :* Nil
@@ -280,7 +358,7 @@ instance
280 , Has col row ty
358 , Has col row ty
281 , GroupedBy tab col bys
359 , GroupedBy tab col bys
282 ) => IsQualified tab col
360 ) => IsQualified tab col
283− (Expression outer commons ('Grouped bys) schemas params from ty) where
361+ (Expression outer ('Grouped bys) commons schemas params from ty) where
284 tab ! col = UnsafeExpression $
362 tab ! col = UnsafeExpression $
285 renderSQL tab <> "." <> renderSQL col
363 renderSQL tab <> "." <> renderSQL col
@@ -289,7 +367,7 @@ instance
289 , GroupedBy tab col bys
367 , GroupedBy tab col bys
290 , tys ~ '[ty]
368 , tys ~ '[ty]
291 ) => IsQualified tab col
369 ) => IsQualified tab col
292− (NP (Expression outer commons ('Grouped bys) schemas params from) tys) where
370+ (NP (Expression outer ('Grouped bys) commons schemas params from) tys) where
293 tab ! col = tab ! col :* Nil
371 tab ! col = tab ! col :* Nil
295 ( Has tab (Join outer from) row
373 ( Has tab (Join outer from) row
@@ -297,7 +375,7 @@ instance
297 , GroupedBy tab col bys
375 , GroupedBy tab col bys
298 , column ~ (col ::: ty)
376 , column ~ (col ::: ty)
299 ) => IsQualified tab col
377 ) => IsQualified tab col
300− (Aliased (Expression outer commons ('Grouped bys) schemas params from) column) where
378+ (Aliased (Expression outer ('Grouped bys) commons schemas params from) column) where
301 tab ! col = tab ! col `As` col
379 tab ! col = tab ! col `As` col
303 ( Has tab (Join outer from) row
381 ( Has tab (Join outer from) row
@@ -305,78 +383,237 @@ instance
305 , GroupedBy tab col bys
383 , GroupedBy tab col bys
306 , columns ~ '[col ::: ty]
384 , columns ~ '[col ::: ty]
307 ) => IsQualified tab col
385 ) => IsQualified tab col
308− (NP (Aliased (Expression outer commons ('Grouped bys) schemas params from)) columns) where
386+ (NP (Aliased (Expression outer ('Grouped bys) commons schemas params from)) columns) where
309 tab ! col = tab ! col :* Nil
387 tab ! col = tab ! col :* Nil
389+-- | analagous to `Nothing`
391+-- >>> printSQL null_
393+null_ :: Expression outer grp commons schemas params from ('Null ty)
394+null_ = UnsafeExpression "NULL"
396+-- | analagous to `Just`
398+-- >>> printSQL $ notNull true
401+ :: Expression outer grp commons schemas params from ('NotNull ty)
402+ -> Expression outer grp commons schemas params from ('Null ty)
403+notNull = UnsafeExpression . renderSQL
405+-- | return the leftmost value which is not NULL
407+-- >>> printSQL $ coalesce [null_, true] false
408+-- COALESCE(NULL, TRUE, FALSE)
410+ :: [Expression outer grp commons schemas params from ('Null ty)]
411+ -- ^ @NULL@s may be present
412+ -> Expression outer grp commons schemas params from ('NotNull ty)
413+ -- ^ @NULL@ is absent
414+ -> Expression outer grp commons schemas params from ('NotNull ty)
415+coalesce nullxs notNullx = UnsafeExpression $
416+ "COALESCE" <> parenthesized (commaSeparated
417+ ((renderSQL <$> nullxs) <> [renderSQL notNullx]))
419+-- | analagous to `Data.Maybe.fromMaybe` using @COALESCE@
421+-- >>> printSQL $ fromNull true null_
422+-- COALESCE(NULL, TRUE)
424+ :: Expression outer grp commons schemas params from ('NotNull ty)
425+ -- ^ what to convert @NULL@ to
426+ -> Expression outer grp commons schemas params from ('Null ty)
427+ -> Expression outer grp commons schemas params from ('NotNull ty)
428+fromNull notNullx nullx = coalesce [nullx] notNullx
430+-- | >>> printSQL $ null_ & isNull
433+ :: Expression outer grp commons schemas params from ('Null ty)
434+ -- ^ possibly @NULL@
435+ -> Condition outer grp commons schemas params from
436+isNull x = UnsafeExpression $ renderSQL x <+> "IS NULL"
438+-- | >>> printSQL $ null_ & isNotNull
441+ :: Expression outer grp commons schemas params from ('Null ty)
442+ -- ^ possibly @NULL@
443+ -> Condition outer grp commons schemas params from
444+isNotNull x = UnsafeExpression $ renderSQL x <+> "IS NOT NULL"
446+-- | analagous to `maybe` using @IS NULL@
448+-- >>> printSQL $ matchNull true not_ null_
449+-- CASE WHEN NULL IS NULL THEN TRUE ELSE (NOT NULL) END
451+ :: Expression outer grp commons schemas params from (nullty)
452+ -- ^ what to convert @NULL@ to
453+ -> ( Expression outer grp commons schemas params from ('NotNull ty)
454+ -> Expression outer grp commons schemas params from (nullty) )
455+ -- ^ function to perform when @NULL@ is absent
456+ -> Expression outer grp commons schemas params from ('Null ty)
457+ -> Expression outer grp commons schemas params from (nullty)
458+matchNull y f x = ifThenElse (isNull x) y
459+ (f (UnsafeExpression (renderSQL x)))
461+{-| right inverse to `fromNull`, if its arguments are equal then
462+`nullIf` gives @NULL@.
464+>>> :set -XTypeApplications -XDataKinds
465+>>> let expr = nullIf false (param @1) :: Expression outer grp commons schemas '[ 'NotNull 'PGbool] from ('Null 'PGbool)
467+NULL IF (FALSE, ($1 :: bool))
470+ :: Expression outer grp commons schemas params from ('NotNull ty)
471+ -- ^ @NULL@ is absent
472+ -> Expression outer grp commons schemas params from ('NotNull ty)
473+ -- ^ @NULL@ is absent
474+ -> Expression outer grp commons schemas params from ('Null ty)
475+nullIf x y = UnsafeExpression $ "NULL IF" <+> parenthesized
476+ (renderSQL x <> ", " <> renderSQL y)
478+-- | >>> printSQL $ array [null_, false, true]
479+-- ARRAY[NULL, FALSE, TRUE]
481+ :: [Expression outer grp commons schemas params from ty]
483+ -> Expression outer grp commons schemas params from (nullity ('PGvararray ty))
484+array xs = UnsafeExpression $
485+ "ARRAY[" <> commaSeparated (renderSQL <$> xs) <> "]"
487+-- | >>> printSQL $ array [null_, false, true] & index 2
488+-- (ARRAY[NULL, FALSE, TRUE])[2]
490+ :: Word64 -- ^ index
491+ -> Expression outer grp commons schemas params from (nullity ('PGvararray ty)) -- ^ array
492+ -> Expression outer grp commons schemas params from (NullifyType ty)
493+index n expr = UnsafeExpression $
494+ parenthesized (renderSQL expr) <> "[" <> fromString (show n) <> "]"
311instance (KnownSymbol label, label `In` labels) => IsPGlabel label
496instance (KnownSymbol label, label `In` labels) => IsPGlabel label
312− (Expression outer commons grp schemas params from (null ('PGenum labels))) where
497+ (Expression outer grp commons schemas params from (nullity ('PGenum labels))) where
313 label = UnsafeExpression $ renderSQL (PGlabel @label)
498 label = UnsafeExpression $ renderSQL (PGlabel @label)
500+-- | A row constructor is an expression that builds a row value
501+-- (also called a composite value) using values for its member fields.
504+-- type Complex = 'PGcomposite
505+-- '[ "real" ::: 'NotNull 'PGfloat8
506+-- , "imaginary" ::: 'NotNull 'PGfloat8 ]
509+-- >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression outer grp commons schemas params from ('NotNull Complex)
514+ => NP (Aliased (Expression outer grp commons schemas params from)) row
515+ -- ^ zero or more expressions for the row field values
516+ -> Expression outer grp commons schemas params from (nullity ('PGcomposite row))
517+row exprs = UnsafeExpression $ "ROW" <> parenthesized
518+ (renderCommaSeparated (\ (expr `As` _) -> renderSQL expr) exprs)
521+-- type Complex = 'PGcomposite
522+-- '[ "real" ::: 'NotNull 'PGfloat8
523+-- , "imaginary" ::: 'NotNull 'PGfloat8 ]
524+-- type Schema = '["complex" ::: 'Typedef Complex]
527+-- >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression outer grp '[] (Public Schema) from params ('NotNull Complex)
528+-- >>> printSQL $ i & field #complex #imaginary
529+-- (ROW(0, 1)::"complex")."imaginary"
531+ :: ( Has sch schemas schema
532+ , Has tydef schema ('Typedef ('PGcomposite row))
534+ => QualifiedAlias sch tydef -- ^ row type
535+ -> Alias field -- ^ field name
536+ -> Expression outer grp commons schemas params from ('NotNull ('PGcomposite row))
537+ -> Expression outer grp commons schemas params from ty
538+field td fld expr = UnsafeExpression $
539+ parenthesized (renderSQL expr <> "::" <> renderSQL td)
540+ <> "." <> renderSQL fld
543+ (Expression outer grp commons schemas params from (nullity ('PGvararray ty))) where
544+ (<>) = unsafeBinaryOp "||"
547+ (Expression outer grp commons schemas params from (nullity ('PGvararray ty))) where
551+-- | >>> let expr = greatest currentTimestamp [param @1] :: Expression outer grp commons schemas '[ 'NotNull 'PGtimestamptz] from ('NotNull 'PGtimestamptz)
553+-- GREATEST(CURRENT_TIMESTAMP, ($1 :: timestamp with time zone))
555+ :: Expression outer grp commons schemas params from (nullty)
556+ -- ^ needs at least 1 argument
557+ -> [Expression outer grp commons schemas params from (nullty)]
559+ -> Expression outer grp commons schemas params from (nullty)
560+greatest x xs = UnsafeExpression $ "GREATEST("
561+ <> commaSeparated (renderSQL <$> (x:xs)) <> ")"
563+-- | >>> printSQL $ least currentTimestamp [null_]
564+-- LEAST(CURRENT_TIMESTAMP, NULL)
566+ :: Expression outer grp commons schemas params from (nullty)
567+ -- ^ needs at least 1 argument
568+ -> [Expression outer grp commons schemas params from (nullty)]
570+ -> Expression outer grp commons schemas params from (nullty)
571+least x xs = UnsafeExpression $ "LEAST("
572+ <> commaSeparated (renderSQL <$> (x:xs)) <> ")"
315-- | >>> printSQL $ unsafeBinaryOp "OR" true false
574-- | >>> printSQL $ unsafeBinaryOp "OR" true false
316-- (TRUE OR FALSE)
575-- (TRUE OR FALSE)
317−unsafeBinaryOp :: ByteString -> Operator ty0 ty1 ty2
576+unsafeBinaryOp
579+ -> Expression outer grp commons schemas params from (ty0)
580+ -> Expression outer grp commons schemas params from (ty1)
581+ -> Expression outer grp commons schemas params from (ty2)
318unsafeBinaryOp op x y = UnsafeExpression $ parenthesized $
582unsafeBinaryOp op x y = UnsafeExpression $ parenthesized $
319 renderSQL x <+> op <+> renderSQL y
583 renderSQL x <+> op <+> renderSQL y
322− :: forall op sch schemas schema x y z.
323− ( Has sch schemas schema
324− , Has op schema ('Operator ('BinaryOp x y z)) )
325− => OperatorDB schemas x y z
326−binaryOp = unsafeBinaryOp $ renderSymbol @op
328−-- | >>> printSQL $ unsafeLeftOp "NOT" true
585+-- | >>> printSQL $ unsafeUnaryOp "NOT" true
329-- (NOT TRUE)
586-- (NOT TRUE)
330−unsafeLeftOp :: ByteString -> x --> y
588+ :: ByteString
331−unsafeLeftOp op x = UnsafeExpression $ parenthesized $ op <+> renderSQL x
589+ -- ^ operator
332−
590+ -> Expression outer grp commons schemas params from (ty0)
333−leftOp
591+ -> Expression outer grp commons schemas params from (ty1)
334− :: forall op sch schemas schema x y.
335− ( Has sch schemas schema
336− , Has op schema ('Operator ('LeftOp x y)) )
337− => FunctionDB schemas x y
338−leftOp = unsafeLeftOp $ renderSymbol @op
340−-- | >>> printSQL $ true & unsafeRightOp "IS NOT TRUE"
341−-- (TRUE IS NOT TRUE)
342−unsafeRightOp :: ByteString -> x --> y
343−unsafeRightOp op x = UnsafeExpression $ parenthesized $ renderSQL x <+> op
592+unsafeUnaryOp op x = UnsafeExpression $ parenthesized $
344−
593+ op <+> renderSQL x
346− :: forall op sch schemas schema x y.
347− ( Has sch schemas schema
348− , Has op schema ('Operator ('RightOp x y)) )
349− => FunctionDB schemas x y
350−rightOp = unsafeRightOp $ renderSymbol @op
352-- | >>> printSQL $ unsafeFunction "f" true
595-- | >>> printSQL $ unsafeFunction "f" true
353-- f(TRUE)
596-- f(TRUE)
354−unsafeFunction :: ByteString -> x --> y
597+unsafeFunction
600+ -> Expression outer grp commons schemas params from (xty)
601+ -> Expression outer grp commons schemas params from (yty)
355unsafeFunction fun x = UnsafeExpression $
602unsafeFunction fun x = UnsafeExpression $
356 fun <> parenthesized (renderSQL x)
603 fun <> parenthesized (renderSQL x)
358−function
605+-- | Helper for defining variadic functions.
359− :: (Has sch schemas schema, Has fun schema ('Function ('[x] :=> 'Returns y)))
606+unsafeVariadicFunction
360− => QualifiedAlias sch fun
607+ :: SListI elems
361− -> FunctionDB schemas x y
362−function = unsafeFunction . renderSQL
364−-- | >>> printSQL $ unsafeFunctionN "f" (currentTime :* localTimestamp :* false *: literal 'a')
365−-- f(CURRENT_TIME, LOCALTIMESTAMP, FALSE, E'a')
366−unsafeFunctionN :: SListI xs => ByteString -> xs ---> y
608+ => ByteString
610+ -> NP (Expression outer grp commons schemas params from) elems
611+ -> Expression outer grp commons schemas params from ret
367−unsafeFunctionN fun xs = UnsafeExpression $
612+unsafeVariadicFunction fun x = UnsafeExpression $
368− fun <> parenthesized (renderCommaSeparated renderSQL xs)
613+ fun <> parenthesized (commaSeparated (hcollapse (hmap (K . renderSQL) x)))
371− :: ( Has sch schemas schema
372− , Has fun schema ('Function (xs :=> 'Returns y))
374− => QualifiedAlias sch fun
375− -> FunctionNDB schemas xs y
376−functionN = unsafeFunctionN . renderSQL
378instance ty `In` PGNum
615instance ty `In` PGNum
379− => Num (Expression outer commons grp schemas params from (null ty)) where
616+ => Num (Expression outer grp commons schemas params from (nullity ty)) where
380 (+) = unsafeBinaryOp "+"
617 (+) = unsafeBinaryOp "+"
381 (-) = unsafeBinaryOp "-"
618 (-) = unsafeBinaryOp "-"
382 (*) = unsafeBinaryOp "*"
619 (*) = unsafeBinaryOp "*"
@@ -388,17 +625,12 @@ instance ty `In` PGNum
390instance (ty `In` PGNum, ty `In` PGFloating) => Fractional
627instance (ty `In` PGNum, ty `In` PGFloating) => Fractional
391− (Expression outer commons grp schemas params from (null ty)) where
628+ (Expression outer grp commons schemas params from (nullity ty)) where
392 (/) = unsafeBinaryOp "/"
629 (/) = unsafeBinaryOp "/"
393− fromRational
630+ fromRational x = fromInteger (numerator x) / fromInteger (denominator x)
397− . showFFloat Nothing
400instance (ty `In` PGNum, ty `In` PGFloating) => Floating
632instance (ty `In` PGNum, ty `In` PGFloating) => Floating
401− (Expression outer commons grp schemas params from (null ty)) where
633+ (Expression outer grp commons schemas params from (nullity ty)) where
402 pi = UnsafeExpression "pi()"
634 pi = UnsafeExpression "pi()"
403 exp = unsafeFunction "exp"
635 exp = unsafeFunction "exp"
404 log = unsafeFunction "ln"
636 log = unsafeFunction "ln"
@@ -419,54 +651,1564 @@ instance (ty `In` PGNum, ty `In` PGFloating) => Floating
419 acosh x = log (x + sqrt (x*x - 1))
651 acosh x = log (x + sqrt (x*x - 1))
420 atanh x = log ((1 + x) / (1 - x)) / 2
652 atanh x = log ((1 + x) / (1 - x)) / 2
422−-- | Contained by operators
654+-- | >>> :{
423−class PGSubset ty where
655+-- let
424− (@>) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
656+-- expression :: Expression outer grp commons schemas params from (nullity 'PGfloat4)
425− (@>) = unsafeBinaryOp "@>"
657+-- expression = atan2_ pi 2
426− (<@) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
658+-- in printSQL expression
427− (<@) = unsafeBinaryOp "<@"
659+-- :}
428−instance PGSubset 'PGjsonb
660+-- atan2(pi(), 2)
429−instance PGSubset 'PGtsquery
661+atan2_
430−instance PGSubset ('PGvararray ty)
662+ :: float `In` PGFloating
431−instance PGSubset ('PGrange ty)
663+ => Expression outer grp commons schemas params from (nullity float)
433−class PGIntersect ty where
665+ -> Expression outer grp commons schemas params from (nullity float)
434− (@&&) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
666+ -- ^ denominator
435− (@&&) = unsafeBinaryOp "&&"
667+ -> Expression outer grp commons schemas params from (nullity float)
436−instance PGIntersect ('PGvararray ty)
668+atan2_ y x = UnsafeExpression $
437−instance PGIntersect ('PGrange ty)
669+ "atan2(" <> renderSQL y <> ", " <> renderSQL x <> ")"
671+-- When a `cast` is applied to an `Expression` of a known type, it
672+-- represents a run-time type conversion. The cast will succeed only if a
673+-- suitable type conversion operation has been defined.
675+-- | >>> printSQL $ true & cast int4
678+ :: TypeExpression schemas ty1
679+ -- ^ type to cast as
680+ -> Expression outer grp commons schemas params from ty0
681+ -- ^ value to convert
682+ -> Expression outer grp commons schemas params from ty1
683+cast ty x = UnsafeExpression $ parenthesized $
684+ renderSQL x <+> "::" <+> renderSQL ty
686+-- | integer division, truncates the result
690+-- expression :: Expression outer grp commons schemas params from (nullity 'PGint2)
691+-- expression = 5 `quot_` 2
692+-- in printSQL expression
696+ :: int `In` PGIntegral
697+ => Expression outer grp commons schemas params from (nullity int)
699+ -> Expression outer grp commons schemas params from (nullity int)
701+ -> Expression outer grp commons schemas params from (nullity int)
702+quot_ = unsafeBinaryOp "/"
704+-- | remainder upon integer division
708+-- expression :: Expression outer grp commons schemas params from (nullity 'PGint2)
709+-- expression = 5 `rem_` 2
710+-- in printSQL expression
714+ :: int `In` PGIntegral
715+ => Expression outer grp commons schemas params from (nullity int)
717+ -> Expression outer grp commons schemas params from (nullity int)
719+ -> Expression outer grp commons schemas params from (nullity int)
720+rem_ = unsafeBinaryOp "%"
724+-- expression :: Expression outer grp commons schemas params from (nullity 'PGfloat4)
725+-- expression = trunc pi
726+-- in printSQL expression
730+ :: frac `In` PGFloating
731+ => Expression outer grp commons schemas params from (nullity frac)
732+ -- ^ fractional number
733+ -> Expression outer grp commons schemas params from (nullity frac)
734+trunc = unsafeFunction "trunc"
738+-- expression :: Expression outer grp commons schemas params from (nullity 'PGfloat4)
739+-- expression = round_ pi
740+-- in printSQL expression
744+ :: frac `In` PGFloating
745+ => Expression outer grp commons schemas params from (nullity frac)
746+ -- ^ fractional number
747+ -> Expression outer grp commons schemas params from (nullity frac)
748+round_ = unsafeFunction "round"
752+-- expression :: Expression outer grp commons schemas params from (nullity 'PGfloat4)
753+-- expression = ceiling_ pi
754+-- in printSQL expression
758+ :: frac `In` PGFloating
759+ => Expression outer grp commons schemas params from (nullity frac)
760+ -- ^ fractional number
761+ -> Expression outer grp commons schemas params from (nullity frac)
762+ceiling_ = unsafeFunction "ceiling"
764+-- | A `Condition` is an `Expression`, which can evaluate
765+-- to `true`, `false` or `null_`. This is because SQL uses
766+-- a three valued logic.
767+type Condition outer grp commons schemas params from =
768+ Expression outer grp commons schemas params from ('Null 'PGbool)
770+-- | >>> printSQL true
772+true :: Expression outer grp commons schemas params from (nullity 'PGbool)
773+true = UnsafeExpression "TRUE"
775+-- | >>> printSQL false
777+false :: Expression outer grp commons schemas params from (nullity 'PGbool)
778+false = UnsafeExpression "FALSE"
780+-- | >>> printSQL $ not_ true
783+ :: Expression outer grp commons schemas params from (nullity 'PGbool)
784+ -> Expression outer grp commons schemas params from (nullity 'PGbool)
785+not_ = unsafeUnaryOp "NOT"
787+-- | >>> printSQL $ true .&& false
790+ :: Expression outer grp commons schemas params from (nullity 'PGbool)
791+ -> Expression outer grp commons schemas params from (nullity 'PGbool)
792+ -> Expression outer grp commons schemas params from (nullity 'PGbool)
794+(.&&) = unsafeBinaryOp "AND"
796+-- | >>> printSQL $ true .|| false
799+ :: Expression outer grp commons schemas params from (nullity 'PGbool)
800+ -> Expression outer grp commons schemas params from (nullity 'PGbool)
801+ -> Expression outer grp commons schemas params from (nullity 'PGbool)
803+(.||) = unsafeBinaryOp "OR"
807+-- expression :: Expression outer grp commons schemas params from (nullity 'PGint2)
808+-- expression = caseWhenThenElse [(true, 1), (false, 2)] 3
809+-- in printSQL expression
811+-- CASE WHEN TRUE THEN 1 WHEN FALSE THEN 2 ELSE 3 END
813+ :: [ ( Condition outer grp commons schemas params from
814+ , Expression outer grp commons schemas params from ty
816+ -- ^ whens and thens
817+ -> Expression outer grp commons schemas params from ty
819+ -> Expression outer grp commons schemas params from ty
820+caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
824+ [ " WHEN ", renderSQL when_
825+ , " THEN ", renderSQL then_
827+ | (when_,then_) <- whenThens
829+ , " ELSE ", renderSQL else_
835+-- expression :: Expression outer grp commons schemas params from (nullity 'PGint2)
836+-- expression = ifThenElse true 1 0
837+-- in printSQL expression
839+-- CASE WHEN TRUE THEN 1 ELSE 0 END
841+ :: Condition outer grp commons schemas params from
842+ -> Expression outer grp commons schemas params from ty -- ^ then
843+ -> Expression outer grp commons schemas params from ty -- ^ else
844+ -> Expression outer grp commons schemas params from ty
845+ifThenElse if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
847+-- | Comparison operations like `.==`, `./=`, `.>`, `.>=`, `.<` and `.<=`
848+-- will produce @NULL@s if one of their arguments is @NULL@.
850+-- >>> printSQL $ true .== null_
853+ :: Expression outer grp commons schemas params from (nullity0 ty) -- ^ lhs
854+ -> Expression outer grp commons schemas params from (nullity1 ty) -- ^ rhs
855+ -> Condition outer grp commons schemas params from
856+(.==) = unsafeBinaryOp "="
859+-- | >>> printSQL $ true ./= null_
862+ :: Expression outer grp commons schemas params from (nullity0 ty) -- ^ lhs
863+ -> Expression outer grp commons schemas params from (nullity1 ty) -- ^ rhs
864+ -> Condition outer grp commons schemas params from
865+(./=) = unsafeBinaryOp "<>"
868+-- | >>> printSQL $ true .>= null_
871+ :: Expression outer grp commons schemas params from (nullity0 ty) -- ^ lhs
872+ -> Expression outer grp commons schemas params from (nullity1 ty) -- ^ rhs
873+ -> Condition outer grp commons schemas params from
874+(.>=) = unsafeBinaryOp ">="
877+-- | >>> printSQL $ true .< null_
880+ :: Expression outer grp commons schemas params from (nullity0 ty) -- ^ lhs
881+ -> Expression outer grp commons schemas params from (nullity1 ty) -- ^ rhs
882+ -> Condition outer grp commons schemas params from
883+(.<) = unsafeBinaryOp "<"
886+-- | >>> printSQL $ true .<= null_
889+ :: Expression outer grp commons schemas params from (nullity0 ty) -- ^ lhs
890+ -> Expression outer grp commons schemas params from (nullity1 ty) -- ^ rhs
891+ -> Condition outer grp commons schemas params from
892+(.<=) = unsafeBinaryOp "<="
895+-- | >>> printSQL $ true .> null_
898+ :: Expression outer grp commons schemas params from (nullity0 ty) -- ^ lhs
899+ -> Expression outer grp commons schemas params from (nullity1 ty) -- ^ rhs
900+ -> Condition outer grp commons schemas params from
901+(.>) = unsafeBinaryOp ">"
904+-- | >>> printSQL currentDate
907+ :: Expression outer grp commons schemas params from (nullity 'PGdate)
908+currentDate = UnsafeExpression "CURRENT_DATE"
910+-- | >>> printSQL currentTime
913+ :: Expression outer grp commons schemas params from (nullity 'PGtimetz)
914+currentTime = UnsafeExpression "CURRENT_TIME"
916+-- | >>> printSQL currentTimestamp
919+ :: Expression outer grp commons schemas params from (nullity 'PGtimestamptz)
920+currentTimestamp = UnsafeExpression "CURRENT_TIMESTAMP"
922+-- | >>> printSQL localTime
925+ :: Expression outer grp commons schemas params from (nullity 'PGtime)
926+localTime = UnsafeExpression "LOCALTIME"
928+-- | >>> printSQL localTimestamp
931+ :: Expression outer grp commons schemas params from (nullity 'PGtimestamp)
932+localTimestamp = UnsafeExpression "LOCALTIMESTAMP"
934+{-----------------------------------------
936+-----------------------------------------}
439instance IsString
938instance IsString
440− (Expression outer commons grp schemas params from (null 'PGtext)) where
939+ (Expression outer grp commons schemas params from (nullity 'PGtext)) where
441 fromString str = UnsafeExpression $
940 fromString str = UnsafeExpression $
442 "E\'" <> fromString (escape =<< str) <> "\'"
941 "E\'" <> fromString (escape =<< str) <> "\'"
443−instance IsString
942+ where
444− (Expression outer commons grp schemas params from (null 'PGtsvector)) where
943+ escape = \case
445− fromString str = UnsafeExpression . parenthesized . (<> " :: tsvector") $
944+ '\NUL' -> "\\0"
446− "E\'" <> fromString (escape =<< str) <> "\'"
945+ '\'' -> "''"
447−instance IsString
946+ '"' -> "\\\""
448− (Expression outer commons grp schemas params from (null 'PGtsquery)) where
947+ '\b' -> "\\b"
449− fromString str = UnsafeExpression . parenthesized . (<> " :: tsquery") $
948+ '\n' -> "\\n"
450− "E\'" <> fromString (escape =<< str) <> "\'"
949+ '\r' -> "\\r"
452instance Semigroup
954instance Semigroup
453− (Expression outer commons grp schemas params from (null ('PGvararray ty))) where
454− (<>) = unsafeBinaryOp "||"
456− (Expression outer commons grp schemas params from (null 'PGjsonb)) where
457− (<>) = unsafeBinaryOp "||"
459− (Expression outer commons grp schemas params from (null 'PGtext)) where
955+ (Expression outer grp commons schemas params from (nullity 'PGtext)) where
460− (<>) = unsafeBinaryOp "||"
462− (Expression outer commons grp schemas params from (null 'PGtsvector)) where
463 (<>) = unsafeBinaryOp "||"
956 (<>) = unsafeBinaryOp "||"
465instance Monoid
958instance Monoid
466− (Expression outer commons grp schemas params from (null 'PGtext)) where
959+ (Expression outer grp commons schemas params from (nullity 'PGtext)) where
467− mempty = fromString ""
470− (Expression outer commons grp schemas params from (null 'PGtsvector)) where
471 mempty = fromString ""
960 mempty = fromString ""
472 mappend = (<>)
961 mappend = (<>)
963+-- | >>> printSQL $ lower "ARRRGGG"
966+ :: Expression outer grp commons schemas params from (nullity 'PGtext)
967+ -- ^ string to lower case
968+ -> Expression outer grp commons schemas params from (nullity 'PGtext)
969+lower = unsafeFunction "lower"
971+-- | >>> printSQL $ upper "eeee"
974+ :: Expression outer grp commons schemas params from (nullity 'PGtext)
975+ -- ^ string to upper case
976+ -> Expression outer grp commons schemas params from (nullity 'PGtext)
977+upper = unsafeFunction "upper"
979+-- | >>> printSQL $ charLength "four"
980+-- char_length(E'four')
982+ :: Expression outer grp commons schemas params from (nullity 'PGtext)
983+ -- ^ string to measure
984+ -> Expression outer grp commons schemas params from (nullity 'PGint4)
985+charLength = unsafeFunction "char_length"
987+-- | The `like` expression returns true if the @string@ matches
988+-- the supplied @pattern@. If @pattern@ does not contain percent signs
989+-- or underscores, then the pattern only represents the string itself;
990+-- in that case `like` acts like the equals operator. An underscore (_)
991+-- in pattern stands for (matches) any single character; a percent sign (%)
992+-- matches any sequence of zero or more characters.
994+-- >>> printSQL $ "abc" `like` "a%"
995+-- (E'abc' LIKE E'a%')
997+ :: Expression outer grp commons schemas params from (nullity 'PGtext)
999+ -> Expression outer grp commons schemas params from (nullity 'PGtext)
1001+ -> Expression outer grp commons schemas params from (nullity 'PGbool)
1002+like = unsafeBinaryOp "LIKE"
1004+-- | The key word ILIKE can be used instead of LIKE to make the
1005+-- match case-insensitive according to the active locale.
1007+-- >>> printSQL $ "abc" `ilike` "a%"
1008+-- (E'abc' ILIKE E'a%')
1010+ :: Expression outer grp commons schemas params from (nullity 'PGtext)
1012+ -> Expression outer grp commons schemas params from (nullity 'PGtext)
1014+ -> Expression outer grp commons schemas params from (nullity 'PGbool)
1015+ilike = unsafeBinaryOp "ILIKE"
1017+{-----------------------------------------
1018+ -- json and jsonb support
1020+See https://www.postgresql.org/docs/10/static/functions-json.html -- most
1021+comments lifted directly from this page.
1023+Table 9.44: json and jsonb operators
1024+-----------------------------------------}
1026+-- | Get JSON value (object field or array element) at a key.
1028+ :: (json `In` PGJsonType, key `In` PGJsonKey)
1029+ => Expression outer grp commons schemas params from (nullity json)
1030+ -> Expression outer grp commons schemas params from (nullity key)
1031+ -> Expression outer grp commons schemas params from ('Null json)
1033+(.->) = unsafeBinaryOp "->"
1035+-- | Get JSON value (object field or array element) at a key, as text.
1037+ :: (json `In` PGJsonType, key `In` PGJsonKey)
1038+ => Expression outer grp commons schemas params from (nullity json)
1039+ -> Expression outer grp commons schemas params from (nullity key)
1040+ -> Expression outer grp commons schemas params from ('Null 'PGtext)
1042+(.->>) = unsafeBinaryOp "->>"
1044+-- | Get JSON value at a specified path.
1046+ :: (json `In` PGJsonType, PGTextArray "(.#>)" path)
1047+ => Expression outer grp commons schemas params from (nullity json)
1048+ -> Expression outer grp commons schemas params from (nullity path)
1049+ -> Expression outer grp commons schemas params from ('Null json)
1051+(.#>) = unsafeBinaryOp "#>"
1053+-- | Get JSON value at a specified path as text.
1055+ :: (json `In` PGJsonType, PGTextArray "(.#>>)" path)
1056+ => Expression outer grp commons schemas params from (nullity json)
1057+ -> Expression outer grp commons schemas params from (nullity path)
1058+ -> Expression outer grp commons schemas params from ('Null 'PGtext)
1060+(.#>>) = unsafeBinaryOp "#>>"
1062+-- Additional jsonb operators
1064+-- | Does the left JSON value contain the right JSON path/value entries at the
1067+ :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1068+ -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1069+ -> Condition outer grp commons schemas params from
1071+(.@>) = unsafeBinaryOp "@>"
1073+-- | Are the left JSON path/value entries contained at the top level within the
1074+-- right JSON value?
1076+ :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1077+ -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1078+ -> Condition outer grp commons schemas params from
1080+(.<@) = unsafeBinaryOp "<@"
1082+-- | Does the string exist as a top-level key within the JSON value?
1084+ :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1085+ -> Expression outer grp commons schemas params from (nullity 'PGtext)
1086+ -> Condition outer grp commons schemas params from
1088+(.?) = unsafeBinaryOp "?"
1090+-- | Do any of these array strings exist as top-level keys?
1092+ :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1093+ -> Expression outer grp commons schemas params from (nullity ('PGvararray ('NotNull 'PGtext)))
1094+ -> Condition outer grp commons schemas params from
1096+(.?|) = unsafeBinaryOp "?|"
1098+-- | Do all of these array strings exist as top-level keys?
1100+ :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1101+ -> Expression outer grp commons schemas params from (nullity ('PGvararray ('NotNull 'PGtext)))
1102+ -> Condition outer grp commons schemas params from
1104+(.?&) = unsafeBinaryOp "?&"
1106+-- | Concatenate two jsonb values into a new jsonb value.
1108+ (Expression outer grp commons schemas params from (nullity 'PGjsonb)) where
1109+ (<>) = unsafeBinaryOp "||"
1111+-- | Delete a key or keys from a JSON object, or remove an array element.
1113+-- If the right operand is..
1115+-- @ text @: Delete key/value pair or string element from left operand. Key/value pairs
1116+-- are matched based on their key value.
1118+-- @ text[] @: Delete multiple key/value pairs or string elements
1119+-- from left operand. Key/value pairs are matched based on their key value.
1121+-- @ integer @: Delete the array element with specified index (Negative integers
1122+-- count from the end). Throws an error if top level container is not an array.
1124+ :: (key `In` '[ 'PGtext, 'PGvararray ('NotNull 'PGtext), 'PGint4, 'PGint2 ]) -- hlint error without parens here
1125+ => Expression outer grp commons schemas params from (nullity 'PGjsonb)
1126+ -> Expression outer grp commons schemas params from (nullity key)
1127+ -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1129+(.-.) = unsafeBinaryOp "-"
1131+-- | Delete the field or element with specified path (for JSON arrays, negative
1132+-- integers count from the end)
1134+ :: PGTextArray "(#-.)" arrayty
1135+ => Expression outer grp commons schemas params from (nullity 'PGjsonb)
1136+ -> Expression outer grp commons schemas params from (nullity arrayty)
1137+ -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1139+(#-.) = unsafeBinaryOp "#-"
1141+{-----------------------------------------
1142+Table 9.45: JSON creation functions
1143+-----------------------------------------}
1145+-- | Literal binary JSON
1148+ => x -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1149+jsonbLit = cast jsonb . UnsafeExpression
1150+ . singleQuotedUtf8 . toStrict . JSON.encode
1155+ => x -> Expression outer grp commons schemas params from (nullity 'PGjson)
1156+jsonLit = cast json . UnsafeExpression
1157+ . singleQuotedUtf8 . toStrict . JSON.encode
1159+-- | Returns the value as json. Arrays and composites are converted
1160+-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1161+-- type to json, the cast function will be used to perform the conversion;
1162+-- otherwise, a scalar value is produced. For any scalar type other than a
1163+-- number, a Boolean, or a null value, the text representation will be used, in
1164+-- such a fashion that it is a valid json value.
1166+ :: Expression outer grp commons schemas params from (nullity ty)
1167+ -> Expression outer grp commons schemas params from (nullity 'PGjson)
1168+toJson = unsafeFunction "to_json"
1170+-- | Returns the value as jsonb. Arrays and composites are converted
1171+-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1172+-- type to json, the cast function will be used to perform the conversion;
1173+-- otherwise, a scalar value is produced. For any scalar type other than a
1174+-- number, a Boolean, or a null value, the text representation will be used, in
1175+-- such a fashion that it is a valid jsonb value.
1177+ :: Expression outer grp commons schemas params from (nullity ty)
1178+ -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1179+toJsonb = unsafeFunction "to_jsonb"
1181+-- | Returns the array as a JSON array. A PostgreSQL multidimensional array
1182+-- becomes a JSON array of arrays.
1184+ :: PGArray "arrayToJson" arr
1185+ => Expression outer grp commons schemas params from (nullity arr)
1186+ -> Expression outer grp commons schemas params from (nullity 'PGjson)
1187+arrayToJson = unsafeFunction "array_to_json"
1189+-- | Returns the row as a JSON object.
1191+ :: Expression outer grp commons schemas params from (nullity ('PGcomposite ty))
1192+ -> Expression outer grp commons schemas params from (nullity 'PGjson)
1193+rowToJson = unsafeFunction "row_to_json"
1195+-- | Builds a possibly-heterogeneously-typed JSON array out of a variadic
1199+ => NP (Expression outer grp commons schemas params from) elems
1200+ -> Expression outer grp commons schemas params from (nullity 'PGjson)
1201+jsonBuildArray = unsafeVariadicFunction "json_build_array"
1203+-- | Builds a possibly-heterogeneously-typed (binary) JSON array out of a
1204+-- variadic argument list.
1207+ => NP (Expression outer grp commons schemas params from) elems
1208+ -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1209+jsonbBuildArray = unsafeVariadicFunction "jsonb_build_array"
1213+ => NP (Aliased (Expression outer grp commons schemas params from)) elems
1216+ (`appEndo` []) . hcfoldMap (Proxy :: Proxy Top)
1217+ (\(col `As` name) -> Endo $ \xs ->
1218+ renderAliasString name : renderSQL col : xs)
1220+ renderAliasString :: KnownSymbol alias => Alias alias -> ByteString
1221+ renderAliasString = singleQuotedText . fromString . symbolVal
1223+-- | Builds a possibly-heterogeneously-typed JSON object out of a variadic
1224+-- argument list. The elements of the argument list must alternate between text
1228+ => NP (Aliased (Expression outer grp commons schemas params from)) elems
1229+ -> Expression outer grp commons schemas params from (nullity 'PGjson)
1231+ = unsafeFunction "json_build_object"
1234+ . unsafeRowFunction
1236+-- | Builds a possibly-heterogeneously-typed (binary) JSON object out of a
1237+-- variadic argument list. The elements of the argument list must alternate
1238+-- between text and values.
1241+ => NP (Aliased (Expression outer grp commons schemas params from)) elems
1242+ -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1244+ = unsafeFunction "jsonb_build_object"
1247+ . unsafeRowFunction
1249+-- | Builds a JSON object out of a text array. The array must have either
1250+-- exactly one dimension with an even number of members, in which case they are
1251+-- taken as alternating key/value pairs, or two dimensions such that each inner
1252+-- array has exactly two elements, which are taken as a key/value pair.
1254+ :: PGArrayOf "jsonObject" arr ('NotNull 'PGtext)
1255+ => Expression outer grp commons schemas params from (nullity arr)
1256+ -> Expression outer grp commons schemas params from (nullity 'PGjson)
1257+jsonObject = unsafeFunction "json_object"
1259+-- | Builds a binary JSON object out of a text array. The array must have either
1260+-- exactly one dimension with an even number of members, in which case they are
1261+-- taken as alternating key/value pairs, or two dimensions such that each inner
1262+-- array has exactly two elements, which are taken as a key/value pair.
1264+ :: PGArrayOf "jsonbObject" arr ('NotNull 'PGtext)
1265+ => Expression outer grp commons schemas params from (nullity arr)
1266+ -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1267+jsonbObject = unsafeFunction "jsonb_object"
1269+-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1270+-- keys and one for values, that are zipped pairwise to create a JSON object.
1272+ :: ( PGArrayOf "jsonZipObject" keysArray ('NotNull 'PGtext)
1273+ , PGArrayOf "jsonZipObject" valuesArray ('NotNull 'PGtext))
1274+ => Expression outer grp commons schemas params from (nullity keysArray)
1275+ -> Expression outer grp commons schemas params from (nullity valuesArray)
1276+ -> Expression outer grp commons schemas params from (nullity 'PGjson)
1277+jsonZipObject ks vs =
1278+ unsafeVariadicFunction "json_object" (ks :* vs :* Nil)
1280+-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1281+-- keys and one for values, that are zipped pairwise to create a binary JSON
1284+ :: ( PGArrayOf "jsonbZipObject" keysArray ('NotNull 'PGtext)
1285+ , PGArrayOf "jsonbZipObject" valuesArray ('NotNull 'PGtext))
1286+ => Expression outer grp commons schemas params from (nullity keysArray)
1287+ -> Expression outer grp commons schemas params from (nullity valuesArray)
1288+ -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1289+jsonbZipObject ks vs =
1290+ unsafeVariadicFunction "jsonb_object" (ks :* vs :* Nil)
1292+{-----------------------------------------
1293+Table 9.46: JSON processing functions
1294+-----------------------------------------}
1296+-- | Returns the number of elements in the outermost JSON array.
1298+ :: Expression outer grp commons schemas params from (nullity 'PGjson)
1299+ -> Expression outer grp commons schemas params from (nullity 'PGint4)
1300+jsonArrayLength = unsafeFunction "json_array_length"
1302+-- | Returns the number of elements in the outermost binary JSON array.
1304+ :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1305+ -> Expression outer grp commons schemas params from (nullity 'PGint4)
1306+jsonbArrayLength = unsafeFunction "jsonb_array_length"
1308+-- | Returns JSON value pointed to by the given path (equivalent to #>
1312+ => Expression outer grp commons schemas params from (nullity 'PGjson)
1313+ -> NP (Expression outer grp commons schemas params from) elems
1314+ -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1315+jsonExtractPath x xs =
1316+ unsafeVariadicFunction "json_extract_path" (x :* xs)
1318+-- | Returns JSON value pointed to by the given path (equivalent to #>
1322+ => Expression outer grp commons schemas params from (nullity 'PGjsonb)
1323+ -> NP (Expression outer grp commons schemas params from) elems
1324+ -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1325+jsonbExtractPath x xs =
1326+ unsafeVariadicFunction "jsonb_extract_path" (x :* xs)
1328+-- | Returns JSON value pointed to by the given path (equivalent to #>
1329+-- operator), as text.
1330+jsonExtractPathAsText
1332+ => Expression outer grp commons schemas params from (nullity 'PGjson)
1333+ -> NP (Expression outer grp commons schemas params from) elems
1334+ -> Expression outer grp commons schemas params from (nullity 'PGjson)
1335+jsonExtractPathAsText x xs =
1336+ unsafeVariadicFunction "json_extract_path_text" (x :* xs)
1338+-- | Returns JSON value pointed to by the given path (equivalent to #>
1339+-- operator), as text.
1340+jsonbExtractPathAsText
1342+ => Expression outer grp commons schemas params from (nullity 'PGjsonb)
1343+ -> NP (Expression outer grp commons schemas params from) elems
1344+ -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1345+jsonbExtractPathAsText x xs =
1346+ unsafeVariadicFunction "jsonb_extract_path_text" (x :* xs)
1348+-- | Returns the type of the outermost JSON value as a text string. Possible
1349+-- types are object, array, string, number, boolean, and null.
1351+ :: Expression outer grp commons schemas params from (nullity 'PGjson)
1352+ -> Expression outer grp commons schemas params from (nullity 'PGtext)
1353+jsonTypeof = unsafeFunction "json_typeof"
1355+-- | Returns the type of the outermost binary JSON value as a text string.
1356+-- Possible types are object, array, string, number, boolean, and null.
1358+ :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1359+ -> Expression outer grp commons schemas params from (nullity 'PGtext)
1360+jsonbTypeof = unsafeFunction "jsonb_typeof"
1362+-- | Returns its argument with all object fields that have null values omitted.
1363+-- Other null values are untouched.
1365+ :: Expression outer grp commons schemas params from (nullity 'PGjson)
1366+ -> Expression outer grp commons schemas params from (nullity 'PGjson)
1367+jsonStripNulls = unsafeFunction "json_strip_nulls"
1369+-- | Returns its argument with all object fields that have null values omitted.
1370+-- Other null values are untouched.
1372+ :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1373+ -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1374+jsonbStripNulls = unsafeFunction "jsonb_strip_nulls"
1376+-- | @ jsonbSet target path new_value create_missing @
1378+-- Returns target with the section designated by path replaced by new_value,
1379+-- or with new_value added if create_missing is true ( default is true) and the
1380+-- item designated by path does not exist. As with the path orientated
1381+-- operators, negative integers that appear in path count from the end of JSON
1384+ :: PGTextArray "jsonbSet" arr
1385+ => Expression outer grp commons schemas params from (nullity 'PGjsonb)
1386+ -> Expression outer grp commons schemas params from (nullity arr)
1387+ -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1388+ -> Maybe (Expression outer grp commons schemas params from (nullity 'PGbool))
1389+ -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1390+jsonbSet tgt path val createMissing = case createMissing of
1391+ Just m -> unsafeVariadicFunction "jsonb_set" (tgt :* path :* val :* m :* Nil)
1392+ Nothing -> unsafeVariadicFunction "jsonb_set" (tgt :* path :* val :* Nil)
1394+-- | @ jsonbInsert target path new_value insert_after @
1396+-- Returns target with new_value inserted. If target section designated by
1397+-- path is in a JSONB array, new_value will be inserted before target or after
1398+-- if insert_after is true (default is false). If target section designated by
1399+-- path is in JSONB object, new_value will be inserted only if target does not
1400+-- exist. As with the path orientated operators, negative integers that appear
1401+-- in path count from the end of JSON arrays.
1403+ :: PGTextArray "jsonbInsert" arr
1404+ => Expression outer grp commons schemas params from (nullity 'PGjsonb)
1405+ -> Expression outer grp commons schemas params from (nullity arr)
1406+ -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1407+ -> Maybe (Expression outer grp commons schemas params from (nullity 'PGbool))
1408+ -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
1409+jsonbInsert tgt path val insertAfter = case insertAfter of
1410+ Just i -> unsafeVariadicFunction "jsonb_insert" (tgt :* path :* val :* i :* Nil)
1411+ Nothing -> unsafeVariadicFunction "jsonb_insert" (tgt :* path :* val :* Nil)
1413+-- | Returns its argument as indented JSON text.
1415+ :: Expression outer grp commons schemas params from (nullity 'PGjsonb)
1416+ -> Expression outer grp commons schemas params from (nullity 'PGtext)
1417+jsonbPretty = unsafeFunction "jsonb_pretty"
1419+{-----------------------------------------
1421+-----------------------------------------}
1423+class Aggregate expr1 expr2 aggr
1424+ | aggr -> expr1, aggr -> expr2 where
1426+ -- | A special aggregation that does not require an input
1430+ -- expression :: Expression '[] ('Grouped bys) commons schemas params from ('NotNull 'PGint8)
1431+ -- expression = countStar
1432+ -- in printSQL expression
1435+ countStar :: aggr ('NotNull 'PGint8)
1439+ -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity ty]] ('NotNull 'PGint8)
1440+ -- expression = count (All #col)
1441+ -- in printSQL expression
1443+ -- count(ALL "col")
1447+ -> aggr ('NotNull 'PGint8)
1451+ -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: 'Null 'PGnumeric]] ('Null 'PGnumeric)
1452+ -- expression = sum_ (Distinct #col)
1453+ -- in printSQL expression
1455+ -- sum(DISTINCT "col")
1458+ => expr1 (nullity ty)
1459+ -> aggr (nullity ty)
1461+ -- | input values, including nulls, concatenated into an array
1464+ -> aggr ('NotNull ('PGvararray ty))
1466+ -- | aggregates values as a JSON array
1469+ -> aggr ('NotNull 'PGjson)
1471+ -- | aggregates values as a JSON array
1474+ -> aggr ('NotNull 'PGjsonb)
1478+ -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity 'PGint4]] (nullity 'PGint4)
1479+ -- expression = bitAnd (Distinct #col)
1480+ -- in printSQL expression
1482+ -- bit_and(DISTINCT "col")
1484+ :: int `In` PGIntegral
1485+ => expr1 (nullity int)
1486+ -- ^ what to aggregate
1487+ -> aggr (nullity int)
1491+ -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity 'PGint4]] (nullity 'PGint4)
1492+ -- expression = bitOr (All #col)
1493+ -- in printSQL expression
1495+ -- bit_or(ALL "col")
1497+ :: int `In` PGIntegral
1498+ => expr1 (nullity int)
1499+ -- ^ what to aggregate
1500+ -> aggr (nullity int)
1504+ -- winFun :: WindowFunction '[] 'Ungrouped commons schemas params '[tab ::: '["col" ::: nullity 'PGbool]] (nullity 'PGbool)
1505+ -- winFun = boolAnd #col
1506+ -- in printSQL winFun
1510+ :: expr1 (nullity 'PGbool)
1511+ -- ^ what to aggregate
1512+ -> aggr (nullity 'PGbool)
1516+ -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity 'PGbool]] (nullity 'PGbool)
1517+ -- expression = boolOr (All #col)
1518+ -- in printSQL expression
1520+ -- bool_or(ALL "col")
1522+ :: expr1(nullity 'PGbool)
1523+ -- ^ what to aggregate
1524+ -> aggr (nullity 'PGbool)
1526+ -- | synonym for `boolAnd`
1530+ -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity 'PGbool]] (nullity 'PGbool)
1531+ -- expression = every (Distinct #col)
1532+ -- in printSQL expression
1534+ -- every(DISTINCT "col")
1536+ :: expr1 (nullity 'PGbool)
1537+ -- ^ what to aggregate
1538+ -> aggr (nullity 'PGbool)
1540+ -- | maximum value of expression across all input values
1542+ :: expr1 (nullity ty)
1543+ -- ^ what to maximize
1544+ -> aggr (nullity ty)
1546+ -- | minimum value of expression across all input values
1548+ :: expr1 (nullity ty)
1549+ -- ^ what to minimize
1550+ -> aggr (nullity ty)
1552+ -- | average aggregation
1554+ :: expr1 (nullity ty)
1555+ -- ^ what to average
1556+ -> aggr (nullity (PGAvg ty))
1558+ {- | correlation coefficient
1561+ expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1562+ expression = corr (All (#y :*: #x))
1563+ in printSQL expression
1568+ :: expr2 (nullity 'PGfloat8)
1569+ -> aggr (nullity 'PGfloat8)
1571+ {- | population covariance
1574+ expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1575+ expression = covarPop (All (#y :*: #x))
1576+ in printSQL expression
1578+ covar_pop(ALL "y", "x")
1581+ :: expr2 (nullity 'PGfloat8)
1582+ -> aggr (nullity 'PGfloat8)
1584+ {- | sample covariance
1587+ winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1588+ winFun = covarSamp (#y :*: #x)
1591+ covar_samp("y", "x")
1594+ :: expr2 (nullity 'PGfloat8)
1595+ -> aggr (nullity 'PGfloat8)
1597+ {- | average of the independent variable (sum(X)/N)
1600+ expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1601+ expression = regrAvgX (All (#y :*: #x))
1602+ in printSQL expression
1604+ regr_avgx(ALL "y", "x")
1607+ :: expr2 (nullity 'PGfloat8)
1608+ -> aggr (nullity 'PGfloat8)
1610+ {- | average of the dependent variable (sum(Y)/N)
1613+ winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1614+ winFun = regrAvgY (#y :*: #x)
1617+ regr_avgy("y", "x")
1620+ :: expr2 (nullity 'PGfloat8)
1621+ -> aggr (nullity 'PGfloat8)
1623+ {- | number of input rows in which both expressions are nonnull
1626+ winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGint8)
1627+ winFun = regrCount (#y :*: #x)
1630+ regr_count("y", "x")
1633+ :: expr2 (nullity 'PGfloat8)
1634+ -> aggr (nullity 'PGint8)
1636+ {- | y-intercept of the least-squares-fit linear equation determined by the (X, Y) pairs
1639+ expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1640+ expression = regrIntercept (All (#y :*: #x))
1641+ in printSQL expression
1643+ regr_intercept(ALL "y", "x")
1646+ :: expr2 (nullity 'PGfloat8)
1647+ -> aggr (nullity 'PGfloat8)
1649+ -- | @regr_r2(Y, X)@, square of the correlation coefficient
1651+ :: expr2 (nullity 'PGfloat8)
1652+ -> aggr (nullity 'PGfloat8)
1654+ -- | @regr_slope(Y, X)@, slope of the least-squares-fit linear equation
1655+ -- determined by the (X, Y) pairs
1657+ :: expr2 (nullity 'PGfloat8)
1658+ -> aggr (nullity 'PGfloat8)
1660+ -- | @regr_sxx(Y, X)@, sum(X^2) - sum(X)^2/N
1661+ -- (“sum of squares” of the independent variable)
1663+ :: expr2 (nullity 'PGfloat8)
1664+ -> aggr (nullity 'PGfloat8)
1666+ -- | @regr_sxy(Y, X)@, sum(X*Y) - sum(X) * sum(Y)/N
1667+ -- (“sum of products” of independent times dependent variable)
1669+ :: expr2 (nullity 'PGfloat8)
1670+ -> aggr (nullity 'PGfloat8)
1672+ -- | @regr_syy(Y, X)@, sum(Y^2) - sum(Y)^2/N
1673+ -- (“sum of squares” of the dependent variable)
1675+ :: expr2 (nullity 'PGfloat8)
1676+ -> aggr (nullity 'PGfloat8)
1678+ -- | historical alias for `stddevSamp`
1680+ :: expr1 (nullity ty)
1681+ -> aggr (nullity (PGAvg ty))
1683+ -- | population standard deviation of the input values
1685+ :: expr1 (nullity ty)
1686+ -> aggr (nullity (PGAvg ty))
1688+ -- | sample standard deviation of the input values
1690+ :: expr1 (nullity ty)
1691+ -> aggr (nullity (PGAvg ty))
1693+ -- | historical alias for `varSamp`
1695+ :: expr1 (nullity ty)
1696+ -> aggr (nullity (PGAvg ty))
1698+ -- | population variance of the input values
1699+ -- (square of the population standard deviation)
1701+ :: expr1 (nullity ty)
1702+ -> aggr (nullity (PGAvg ty))
1704+ -- | sample variance of the input values
1705+ -- (square of the sample standard deviation)
1707+ :: expr1 (nullity ty)
1708+ -> aggr (nullity (PGAvg ty))
1710+data Distinction expr ty
1712+ | Distinct (expr ty)
1713+ deriving (GHC.Generic,Show,Eq,Ord)
1714+instance NFData (Distinction (Expression outer grp commons schemas params from) ty)
1715+instance RenderSQL (Distinction (Expression outer grp commons schemas params from) ty) where
1717+ All x -> "ALL" <+> renderSQL x
1718+ Distinct x -> "DISTINCT" <+> renderSQL x
1721+ ( Expression outer grp commons schemas params from
1723+ Expression outer grp commons schemas params from) xty ) where
1726+ "ALL" <+> renderSQL x <> ", " <> renderSQL x'
1727+ Distinct (x :*: x') ->
1728+ "DISTINCT" <+> renderSQL x <> ", " <> renderSQL x'
1731+ (Distinction (Expression outer 'Ungrouped commons schemas params from))
1732+ (Distinction (Expression outer 'Ungrouped commons schemas params from :*: Expression outer 'Ungrouped commons schemas params from))
1733+ (Expression outer ('Grouped bys) commons schemas params from) where
1734+ countStar = UnsafeExpression "count(*)"
1735+ count = unsafeAggregate1 "count"
1736+ sum_ = unsafeAggregate1 "sum"
1737+ arrayAgg = unsafeAggregate1 "array_agg"
1738+ jsonAgg = unsafeAggregate1 "json_agg"
1739+ jsonbAgg = unsafeAggregate1 "jsonb_agg"
1740+ bitAnd = unsafeAggregate1 "bit_and"
1741+ bitOr = unsafeAggregate1 "bit_or"
1742+ boolAnd = unsafeAggregate1 "bool_and"
1743+ boolOr = unsafeAggregate1 "bool_or"
1744+ every = unsafeAggregate1 "every"
1745+ max_ = unsafeAggregate1 "max"
1746+ min_ = unsafeAggregate1 "min"
1747+ avg = unsafeAggregate1 "avg"
1748+ corr = unsafeAggregate2 "corr"
1749+ covarPop = unsafeAggregate2 "covar_pop"
1750+ covarSamp = unsafeAggregate2 "covar_samp"
1751+ regrAvgX = unsafeAggregate2 "regr_avgx"
1752+ regrAvgY = unsafeAggregate2 "regr_avgy"
1753+ regrCount = unsafeAggregate2 "regr_count"
1754+ regrIntercept = unsafeAggregate2 "regr_intercept"
1755+ regrR2 = unsafeAggregate2 "regr_r2"
1756+ regrSlope = unsafeAggregate2 "regr_slope"
1757+ regrSxx = unsafeAggregate2 "regr_sxx"
1758+ regrSxy = unsafeAggregate2 "regr_sxy"
1759+ regrSyy = unsafeAggregate2 "regr_syy"
1760+ stddev = unsafeAggregate1 "stddev"
1761+ stddevPop = unsafeAggregate1 "stddev_pop"
1762+ stddevSamp = unsafeAggregate1 "stddev_samp"
1763+ variance = unsafeAggregate1 "variance"
1764+ varPop = unsafeAggregate1 "var_pop"
1765+ varSamp = unsafeAggregate1 "var_samp"
1767+ (Expression outer grp commons schemas params from)
1768+ (Expression outer grp commons schemas params from :*: Expression outer grp commons schemas params from)
1769+ (WindowFunction outer grp commons schemas params from) where
1770+ countStar = UnsafeWindowFunction "count(*)"
1771+ count = unsafeWindowFunction1 "count"
1772+ sum_ = unsafeWindowFunction1 "sum"
1773+ arrayAgg = unsafeWindowFunction1 "array_agg"
1774+ jsonAgg = unsafeWindowFunction1 "json_agg"
1775+ jsonbAgg = unsafeWindowFunction1 "jsonb_agg"
1776+ bitAnd = unsafeWindowFunction1 "bit_and"
1777+ bitOr = unsafeWindowFunction1 "bit_or"
1778+ boolAnd = unsafeWindowFunction1 "bool_and"
1779+ boolOr = unsafeWindowFunction1 "bool_or"
1780+ every = unsafeWindowFunction1 "every"
1781+ max_ = unsafeWindowFunction1 "max"
1782+ min_ = unsafeWindowFunction1 "min"
1783+ avg = unsafeWindowFunction1 "avg"
1784+ corr = unsafeWindowFunction2 "corr"
1785+ covarPop = unsafeWindowFunction2 "covar_pop"
1786+ covarSamp = unsafeWindowFunction2 "covar_samp"
1787+ regrAvgX = unsafeWindowFunction2 "regr_avgx"
1788+ regrAvgY = unsafeWindowFunction2 "regr_avgy"
1789+ regrCount = unsafeWindowFunction2 "regr_count"
1790+ regrIntercept = unsafeWindowFunction2 "regr_intercept"
1791+ regrR2 = unsafeWindowFunction2 "regr_r2"
1792+ regrSlope = unsafeWindowFunction2 "regr_slope"
1793+ regrSxx = unsafeWindowFunction2 "regr_sxx"
1794+ regrSxy = unsafeWindowFunction2 "regr_sxy"
1795+ regrSyy = unsafeWindowFunction2 "regr_syy"
1796+ stddev = unsafeWindowFunction1 "stddev"
1797+ stddevPop = unsafeWindowFunction1 "stddev_pop"
1798+ stddevSamp = unsafeWindowFunction1 "stddev_samp"
1799+ variance = unsafeWindowFunction1 "variance"
1800+ varPop = unsafeWindowFunction1 "var_pop"
1801+ varSamp = unsafeWindowFunction1 "var_samp"
1803+-- | escape hatch to define aggregate functions
1805+ :: ByteString -- ^ aggregate function
1806+ -> Distinction (Expression outer 'Ungrouped commons schemas params from) xty
1807+ -> Expression outer ('Grouped bys) commons schemas params from yty
1808+unsafeAggregate1 fun x = UnsafeExpression $ mconcat
1809+ [fun, "(", renderSQL x, ")"]
1811+-- | escape hatch to define aggregate binary functions
1813+ :: ByteString -- ^ aggregate function
1814+ -> Distinction (Expression outer 'Ungrouped commons schemas params from :*: Expression outer 'Ungrouped commons schemas params from) xty
1815+ -> Expression outer ('Grouped bys) commons schemas params from yty
1816+unsafeAggregate2 fun xx = UnsafeExpression $ mconcat
1817+ [fun, "(", renderSQL xx, ")"]
1819+-- | A type family that calculates `PGAvg` type of a `PGType`.
1820+type family PGAvg ty where
1821+ PGAvg 'PGint2 = 'PGnumeric
1822+ PGAvg 'PGint4 = 'PGnumeric
1823+ PGAvg 'PGint8 = 'PGnumeric
1824+ PGAvg 'PGnumeric = 'PGnumeric
1825+ PGAvg 'PGfloat4 = 'PGfloat8
1826+ PGAvg 'PGfloat8 = 'PGfloat8
1827+ PGAvg 'PGinterval = 'PGinterval
1828+ PGAvg pg = TypeError
1829+ ('Text "Squeal type error: No average for " ':<>: 'ShowType pg)
1831+{-----------------------------------------
1833+-----------------------------------------}
1835+-- | `TypeExpression`s are used in `cast`s and `createTable` commands.
1836+newtype TypeExpression (schemas :: SchemasType) (ty :: NullityType)
1837+ = UnsafeTypeExpression { renderTypeExpression :: ByteString }
1838+ deriving (GHC.Generic,Show,Eq,Ord,NFData)
1839+instance RenderSQL (TypeExpression schemas ty) where
1840+ renderSQL = renderTypeExpression
1842+-- | The enum or composite type in a `Typedef` can be expressed by its alias.
1844+ :: (Has sch schemas schema, Has td schema ('Typedef ty))
1845+ => QualifiedAlias sch td
1846+ -> TypeExpression schemas (nullity ty)
1847+typedef = UnsafeTypeExpression . renderSQL
1849+-- | The composite type corresponding to a `Table` definition can be expressed
1852+ :: (Has sch schemas schema, Has tab schema ('Table table))
1853+ => QualifiedAlias sch tab
1854+ -> TypeExpression schemas (nullity ('PGcomposite (TableToRow table)))
1855+typetable = UnsafeTypeExpression . renderSQL
1857+-- | The composite type corresponding to a `View` definition can be expressed
1860+ :: (Has sch schemas schema, Has vw schema ('View view))
1861+ => QualifiedAlias sch vw
1862+ -> TypeExpression schemas (nullity ('PGcomposite view))
1863+typeview = UnsafeTypeExpression . renderSQL
1865+-- | logical Boolean (true/false)
1866+bool :: TypeExpression schemas (nullity 'PGbool)
1867+bool = UnsafeTypeExpression "bool"
1868+-- | signed two-byte integer
1869+int2, smallint :: TypeExpression schemas (nullity 'PGint2)
1870+int2 = UnsafeTypeExpression "int2"
1871+smallint = UnsafeTypeExpression "smallint"
1872+-- | signed four-byte integer
1873+int4, int, integer :: TypeExpression schemas (nullity 'PGint4)
1874+int4 = UnsafeTypeExpression "int4"
1875+int = UnsafeTypeExpression "int"
1876+integer = UnsafeTypeExpression "integer"
1877+-- | signed eight-byte integer
1878+int8, bigint :: TypeExpression schemas (nullity 'PGint8)
1879+int8 = UnsafeTypeExpression "int8"
1880+bigint = UnsafeTypeExpression "bigint"
1881+-- | arbitrary precision numeric type
1882+numeric :: TypeExpression schemas (nullity 'PGnumeric)
1883+numeric = UnsafeTypeExpression "numeric"
1884+-- | single precision floating-point number (4 bytes)
1885+float4, real :: TypeExpression schemas (nullity 'PGfloat4)
1886+float4 = UnsafeTypeExpression "float4"
1887+real = UnsafeTypeExpression "real"
1888+-- | double precision floating-point number (8 bytes)
1889+float8, doublePrecision :: TypeExpression schemas (nullity 'PGfloat8)
1890+float8 = UnsafeTypeExpression "float8"
1891+doublePrecision = UnsafeTypeExpression "double precision"
1892+-- | variable-length character string
1893+text :: TypeExpression schemas (nullity 'PGtext)
1894+text = UnsafeTypeExpression "text"
1895+-- | fixed-length character string
1897+ :: forall n schemas nullity. (KnownNat n, 1 <= n)
1898+ => TypeExpression schemas (nullity ('PGchar n))
1899+char = UnsafeTypeExpression $ "char(" <> renderNat @n <> ")"
1900+character = UnsafeTypeExpression $ "character(" <> renderNat @n <> ")"
1901+-- | variable-length character string
1902+varchar, characterVarying
1903+ :: forall n schemas nullity. (KnownNat n, 1 <= n)
1904+ => TypeExpression schemas (nullity ('PGvarchar n))
1905+varchar = UnsafeTypeExpression $ "varchar(" <> renderNat @n <> ")"
1906+characterVarying = UnsafeTypeExpression $
1907+ "character varying(" <> renderNat @n <> ")"
1908+-- | binary data ("byte array")
1909+bytea :: TypeExpression schemas (nullity 'PGbytea)
1910+bytea = UnsafeTypeExpression "bytea"
1911+-- | date and time (no time zone)
1912+timestamp :: TypeExpression schemas (nullity 'PGtimestamp)
1913+timestamp = UnsafeTypeExpression "timestamp"
1914+-- | date and time, including time zone
1915+timestampWithTimeZone :: TypeExpression schemas (nullity 'PGtimestamptz)
1916+timestampWithTimeZone = UnsafeTypeExpression "timestamp with time zone"
1917+-- | calendar date (year, month, day)
1918+date :: TypeExpression schemas (nullity 'PGdate)
1919+date = UnsafeTypeExpression "date"
1920+-- | time of day (no time zone)
1921+time :: TypeExpression schemas (nullity 'PGtime)
1922+time = UnsafeTypeExpression "time"
1923+-- | time of day, including time zone
1924+timeWithTimeZone :: TypeExpression schemas (nullity 'PGtimetz)
1925+timeWithTimeZone = UnsafeTypeExpression "time with time zone"
1927+interval :: TypeExpression schemas (nullity 'PGinterval)
1928+interval = UnsafeTypeExpression "interval"
1929+-- | universally unique identifier
1930+uuid :: TypeExpression schemas (nullity 'PGuuid)
1931+uuid = UnsafeTypeExpression "uuid"
1932+-- | IPv4 or IPv6 host address
1933+inet :: TypeExpression schemas (nullity 'PGinet)
1934+inet = UnsafeTypeExpression "inet"
1935+-- | textual JSON data
1936+json :: TypeExpression schemas (nullity 'PGjson)
1937+json = UnsafeTypeExpression "json"
1938+-- | binary JSON data, decomposed
1939+jsonb :: TypeExpression schemas (nullity 'PGjsonb)
1940+jsonb = UnsafeTypeExpression "jsonb"
1941+-- | variable length array
1943+ :: TypeExpression schemas pg
1944+ -> TypeExpression schemas (nullity ('PGvararray pg))
1945+vararray ty = UnsafeTypeExpression $ renderSQL ty <> "[]"
1946+-- | fixed length array
1948+-- >>> renderSQL (fixarray @'[2] json)
1951+ :: forall dims schemas nullity pg. All KnownNat dims
1952+ => TypeExpression schemas pg
1953+ -> TypeExpression schemas (nullity ('PGfixarray dims pg))
1954+fixarray ty = UnsafeTypeExpression $
1955+ renderSQL ty <> renderDims @dims
1957+ renderDims :: forall ns. All KnownNat ns => ByteString
1961+ . ByteString.intercalate "]["
1963+ $ hcmap (Proxy @KnownNat)
1964+ (K . fromString . show . natVal)
1965+ (hpure Proxy :: NP Proxy ns)
1967+-- | `pgtype` is a demoted version of a `PGType`
1968+class PGTyped schemas (ty :: NullityType) where
1969+ pgtype :: TypeExpression schemas ty
1970+instance PGTyped schemas (nullity 'PGbool) where pgtype = bool
1971+instance PGTyped schemas (nullity 'PGint2) where pgtype = int2
1972+instance PGTyped schemas (nullity 'PGint4) where pgtype = int4
1973+instance PGTyped schemas (nullity 'PGint8) where pgtype = int8
1974+instance PGTyped schemas (nullity 'PGnumeric) where pgtype = numeric
1975+instance PGTyped schemas (nullity 'PGfloat4) where pgtype = float4
1976+instance PGTyped schemas (nullity 'PGfloat8) where pgtype = float8
1977+instance PGTyped schemas (nullity 'PGtext) where pgtype = text
1978+instance (KnownNat n, 1 <= n)
1979+ => PGTyped schemas (nullity ('PGchar n)) where pgtype = char @n
1980+instance (KnownNat n, 1 <= n)
1981+ => PGTyped schemas (nullity ('PGvarchar n)) where pgtype = varchar @n
1982+instance PGTyped schemas (nullity 'PGbytea) where pgtype = bytea
1983+instance PGTyped schemas (nullity 'PGtimestamp) where pgtype = timestamp
1984+instance PGTyped schemas (nullity 'PGtimestamptz) where pgtype = timestampWithTimeZone
1985+instance PGTyped schemas (nullity 'PGdate) where pgtype = date
1986+instance PGTyped schemas (nullity 'PGtime) where pgtype = time
1987+instance PGTyped schemas (nullity 'PGtimetz) where pgtype = timeWithTimeZone
1988+instance PGTyped schemas (nullity 'PGinterval) where pgtype = interval
1989+instance PGTyped schemas (nullity 'PGuuid) where pgtype = uuid
1990+instance PGTyped schemas (nullity 'PGjson) where pgtype = json
1991+instance PGTyped schemas (nullity 'PGjsonb) where pgtype = jsonb
1992+instance PGTyped schemas ty
1993+ => PGTyped schemas (nullity ('PGvararray ty)) where
1994+ pgtype = vararray (pgtype @schemas @ty)
1995+instance (All KnownNat dims, PGTyped schemas ty)
1996+ => PGTyped schemas (nullity ('PGfixarray dims ty)) where
1997+ pgtype = fixarray @dims (pgtype @schemas @ty)
1999+{-----------------------------------------
2001+-----------------------------------------}
2003+-- | `SortExpression`s are used by `sortBy` to optionally sort the results
2004+-- of a `Query`. `Asc` or `Desc` set the sort direction of a `NotNull` result
2005+-- column to ascending or descending. Ascending order puts smaller values
2006+-- first, where "smaller" is defined in terms of the `.<` operator. Similarly,
2007+-- descending order is determined with the `.>` operator. `AscNullsFirst`,
2008+-- `AscNullsLast`, `DescNullsFirst` and `DescNullsLast` options are used to
2009+-- determine whether nulls appear before or after non-null values in the sort
2010+-- ordering of a `Null` result column.
2011+data SortExpression outer grp commons schemas params from where
2013+ :: Expression outer grp commons schemas params from ('NotNull ty)
2014+ -> SortExpression outer grp commons schemas params from
2016+ :: Expression outer grp commons schemas params from ('NotNull ty)
2017+ -> SortExpression outer grp commons schemas params from
2019+ :: Expression outer grp commons schemas params from ('Null ty)
2020+ -> SortExpression outer grp commons schemas params from
2022+ :: Expression outer grp commons schemas params from ('Null ty)
2023+ -> SortExpression outer grp commons schemas params from
2025+ :: Expression outer grp commons schemas params from ('Null ty)
2026+ -> SortExpression outer grp commons schemas params from
2028+ :: Expression outer grp commons schemas params from ('Null ty)
2029+ -> SortExpression outer grp commons schemas params from
2030+deriving instance Show (SortExpression outer grp commons schemas params from)
2032+class OrderBy expr where
2034+ :: [SortExpression outer grp commons schemas params from]
2035+ -> expr outer grp commons schemas params from
2036+ -> expr outer grp commons schemas params from
2038+-- | Render a `SortExpression`.
2039+instance RenderSQL (SortExpression outer grp commons schemas params from) where
2041+ Asc expression -> renderSQL expression <+> "ASC"
2042+ Desc expression -> renderSQL expression <+> "DESC"
2043+ AscNullsFirst expression -> renderSQL expression
2044+ <+> "ASC NULLS FIRST"
2045+ DescNullsFirst expression -> renderSQL expression
2046+ <+> "DESC NULLS FIRST"
2047+ AscNullsLast expression -> renderSQL expression <+> "ASC NULLS LAST"
2048+ DescNullsLast expression -> renderSQL expression <+> "DESC NULLS LAST"
2050+data WindowDefinition outer grp commons schemas params from where
2053+ => NP (Expression outer grp commons schemas params from) bys
2054+ -> [SortExpression outer grp commons schemas params from]
2055+ -> WindowDefinition outer grp commons schemas params from
2057+instance OrderBy WindowDefinition where
2058+ orderBy sortsR (WindowDefinition parts sortsL)
2059+ = WindowDefinition parts (sortsL ++ sortsR)
2061+instance RenderSQL (WindowDefinition outer commons schemas from grp params) where
2062+ renderSQL (WindowDefinition part ord) =
2063+ renderPartitionByClause part <> renderOrderByClause ord
2065+ renderPartitionByClause = \case
2067+ parts -> "PARTITION" <+> "BY" <+> renderCommaSeparated renderExpression parts
2068+ renderOrderByClause = \case
2070+ srts -> " ORDER" <+> "BY"
2071+ <+> commaSeparated (renderSQL <$> srts)
2075+ => NP (Expression outer grp commons schemas params from) bys
2076+ -> WindowDefinition outer grp commons schemas params from
2077+partitionBy bys = WindowDefinition bys []
2079+newtype WindowFunction
2080+ (outer :: FromType)
2082+ (commons :: FromType)
2083+ (schemas :: SchemasType)
2084+ (params :: [NullityType])
2086+ (ty :: NullityType)
2087+ = UnsafeWindowFunction { renderWindowFunction :: ByteString }
2088+ deriving (GHC.Generic,Show,Eq,Ord,NFData)
2090+instance RenderSQL (WindowFunction outer grp commons schemas params from ty) where
2091+ renderSQL = renderWindowFunction
2093+unsafeWindowFunction1
2095+ -> Expression outer grp commons schemas params from ty0
2096+ -> WindowFunction outer grp commons schemas params from ty1
2097+unsafeWindowFunction1 fun x
2098+ = UnsafeWindowFunction $ fun <> parenthesized (renderSQL x)
2100+unsafeWindowFunction2
2102+ -> (Expression outer grp commons schemas params from :*: Expression outer grp commons schemas params from) ty0
2103+ -> WindowFunction outer grp commons schemas params from ty1
2104+unsafeWindowFunction2 fun (x :*: x')
2105+ = UnsafeWindowFunction $ fun <> parenthesized (renderSQL x <> ", " <> renderSQL x')
2107+{- | rank of the current row with gaps; same as `rowNumber` of its first peer
2111+rank :: WindowFunction outer grp commons schemas params from ('NotNull 'PGint8)
2112+rank = UnsafeWindowFunction "rank()"
2114+{- | number of the current row within its partition, counting from 1
2115+>>> printSQL rowNumber
2118+rowNumber :: WindowFunction outer grp commons schemas params from ('NotNull 'PGint8)
2119+rowNumber = UnsafeWindowFunction "row_number()"
2121+{- | rank of the current row without gaps; this function counts peer groups
2122+>>> printSQL denseRank
2125+denseRank :: WindowFunction outer grp commons schemas params from ('NotNull 'PGint8)
2126+denseRank = UnsafeWindowFunction "dense_rank()"
2128+{- | relative rank of the current row: (rank - 1) / (total partition rows - 1)
2129+>>> printSQL percentRank
2132+percentRank :: WindowFunction outer grp commons schemas params from ('NotNull 'PGfloat8)
2133+percentRank = UnsafeWindowFunction "percent_rank()"
2135+{- | cumulative distribution: (number of partition rows
2136+preceding or peer with current row) / total partition rows
2137+>>> printSQL cumeDist
2140+cumeDist :: WindowFunction outer grp commons schemas params from ('NotNull 'PGfloat8)
2141+cumeDist = UnsafeWindowFunction "cume_dist()"
2143+{- | integer ranging from 1 to the argument value,
2144+dividing the partition as equally as possible
2147+ :: Expression outer grp commons schemas params from ('NotNull 'PGint4)
2149+ -> WindowFunction outer grp commons schemas params from ('NotNull 'PGint4)
2150+ntile = unsafeWindowFunction1 "ntile"
2152+{- | returns value evaluated at the row that is offset rows before the current
2153+row within the partition; if there is no such row, instead return default
2154+(which must be of the same type as value). Both offset and default are
2155+evaluated with respect to the current row.
2158+ :: Expression outer grp commons schemas params from ty
2160+ -> Expression outer grp commons schemas params from ('NotNull 'PGint4)
2162+ -> Expression outer grp commons schemas params from ty
2164+ -> WindowFunction outer grp commons schemas params from ty
2165+lag value offset def = UnsafeWindowFunction $ "lag"
2167+ (commaSeparated ([renderSQL value, renderSQL offset, renderSQL def]))
2169+{- | returns value evaluated at the row that is offset rows after the current
2170+row within the partition; if there is no such row, instead return default
2171+(which must be of the same type as value). Both offset and default are
2172+evaluated with respect to the current row.
2175+ :: Expression outer grp commons schemas params from ty
2177+ -> Expression outer grp commons schemas params from ('NotNull 'PGint4)
2179+ -> Expression outer grp commons schemas params from ty
2181+ -> WindowFunction outer grp commons schemas params from ty
2182+lead value offset def = UnsafeWindowFunction $ "lag"
2184+ (commaSeparated ([renderSQL value, renderSQL offset, renderSQL def]))
2186+{- | returns value evaluated at the row that is the
2187+first row of the window frame
2190+ :: Expression outer grp commons schemas params from ty
2192+ -> WindowFunction outer grp commons schemas params from ty
2193+firstValue = unsafeWindowFunction1 "first_value"
2195+{- | returns value evaluated at the row that is the
2196+last row of the window frame
2199+ :: Expression outer grp commons schemas params from ty
2201+ -> WindowFunction outer grp commons schemas params from ty
2202+lastValue = unsafeWindowFunction1 "last_value"
2204+{- | returns value evaluated at the row that is the nth
2205+row of the window frame (counting from 1); null if no such row
2208+ :: Expression outer grp commons schemas params from (nullity ty)
2210+ -> Expression outer grp commons schemas params from ('NotNull 'PGint4)
2212+ -> WindowFunction outer grp commons schemas params from ('Null ty)
2213+nthValue value nth = UnsafeWindowFunction $ "nth_value"
2214+ <> parenthesized (commaSeparated [renderSQL value, renderSQL nth])