@@ -1,14 +1,13 @@
2−Module: Squeal.PostgreSQL.Query
2+Module: Squeal.PostgreSQL.Expression
3Description: Squeal expressions
3Description: Squeal expressions
4−Copyright: (c) Eitan Chatav, 2017
4+Copyright: (c) Eitan Chatav, 2019
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 #-}
12{-# LANGUAGE
11{-# LANGUAGE
13 AllowAmbiguousTypes
12 AllowAmbiguousTypes
14 , ConstraintKinds
13 , ConstraintKinds
@@ -34,585 +33,350 @@ Squeal expressions are the atoms used to build statements.
34module Squeal.PostgreSQL.Expression
33module Squeal.PostgreSQL.Expression
35 ( -- * Expression
34 ( -- * Expression
36 Expression (..)
35 Expression (..)
37− , HasParameter (parameter)
36+ , Expr
38− , param
37+ , type (-->)
39− -- ** Null
38+ , FunctionDB
56 , unsafeFunction
39 , unsafeFunction
57− , unsafeVariadicFunction
40+ , function
58− , atan2_
41+ , unsafeLeftOp
60− , quot_
43+ , unsafeRightOp
62− , trunc
45+ , Operator
63− , round_
46+ , OperatorDB
64− , ceiling_
47+ , unsafeBinaryOp
65− , greatest
48+ , binaryOp
66− , least
49+ , FunctionVar
67− -- ** Conditions
50+ , unsafeFunctionVar
68− , true
51+ , type (--->)
69− , false
52+ , FunctionNDB
70− , not_
53+ , unsafeFunctionN
71− , (.&&)
54+ , functionN
72− , (.||)
55+ , PGSubset (..)
73− , Condition
56+ , PGIntersect (..)
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
195 -- * Re-export
57 -- * Re-export
203import Control.Category
63import Control.Category
204import Control.DeepSeq
64import Control.DeepSeq
205import Data.ByteString (ByteString)
65import Data.ByteString (ByteString)
206−import Data.ByteString.Lazy (toStrict)
207import Data.Function ((&))
66import Data.Function ((&))
208import Data.Semigroup hiding (All)
67import Data.Semigroup hiding (All)
209−import qualified Data.Aeson as JSON
211import Data.String
68import Data.String
213−import Generics.SOP hiding (from)
69+import Generics.SOP hiding (All, from)
214−import GHC.Generics ((:*:) (..))
215import GHC.OverloadedLabels
70import GHC.OverloadedLabels
216import GHC.TypeLits
71import GHC.TypeLits
217import Prelude hiding (id, (.))
73import Prelude hiding (id, (.))
219−import qualified Data.ByteString as ByteString
220import qualified GHC.Generics as GHC
75import qualified GHC.Generics as GHC
77+import Squeal.PostgreSQL.Alias
78+import Squeal.PostgreSQL.List
222import Squeal.PostgreSQL.Render
79import Squeal.PostgreSQL.Render
223import Squeal.PostgreSQL.Schema
80import Squeal.PostgreSQL.Schema
83+-- >>> import Squeal.PostgreSQL
225{-----------------------------------------
85{-----------------------------------------
226column expressions
86column expressions
227-----------------------------------------}
87-----------------------------------------}
229{- | `Expression`s are used in a variety of contexts,
89{- | `Expression`s are used in a variety of contexts,
90+such as in the target `Squeal.PostgreSQL.Query.List` of the
230−such as in the target list of the `Squeal.PostgreSQL.Query.select` command,
91+`Squeal.PostgreSQL.Query.select` command,
231as new column values in `Squeal.PostgreSQL.Manipulation.insertRow` or
92as new column values in `Squeal.PostgreSQL.Manipulation.insertRow` or
232`Squeal.PostgreSQL.Manipulation.update`,
93`Squeal.PostgreSQL.Manipulation.update`,
233−or in search `Condition`s in a number of commands.
94+or in search `Squeal.PostgreSQL.Logic.Condition`s in a number of commands.
235The expression syntax allows the calculation of
96The expression syntax allows the calculation of
236values from primitive expression using arithmetic, logical,
97values from primitive expression using arithmetic, logical,
237and other operations.
98and 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`.
239newtype Expression
114newtype Expression
240− (grp :: Grouping)
115+ (outer :: FromType)
241 (commons :: FromType)
116 (commons :: FromType)
242 (schemas :: SchemasType)
118 (schemas :: SchemasType)
243 (params :: [NullityType])
119 (params :: [NullityType])
244 (from :: FromType)
120 (from :: FromType)
245 (ty :: NullityType)
121 (ty :: NullityType)
246 = UnsafeExpression { renderExpression :: ByteString }
122 = UnsafeExpression { renderExpression :: ByteString }
247 deriving (GHC.Generic,Show,Eq,Ord,NFData)
123 deriving (GHC.Generic,Show,Eq,Ord,NFData)
249−instance RenderSQL (Expression grp commons schemas params from ty) where
124+instance RenderSQL (Expression outer commons grp schemas params from ty) where
250 renderSQL = renderExpression
125 renderSQL = renderExpression
252−{- | A `HasParameter` constraint is used to indicate a value that is
127+-- | An `Expr` is a closed `Expression`.
253−supplied externally to a SQL statement.
128+-- It is a F@RankNType@ but don't be scared.
254−`Squeal.PostgreSQL.PQ.manipulateParams`,
129+-- Think of it as an expression which sees no
255−`Squeal.PostgreSQL.PQ.queryParams` and
130+-- namespaces, so you can't use parameters
256−`Squeal.PostgreSQL.PQ.traversePrepared` support specifying data values
131+-- or alias references. It can be used as
257−separately from the SQL command string, in which case `param`s are used to
132+-- a simple piece of more complex `Expression`s.
258−refer to the out-of-line data values.
133+type Expr x
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)
260−class KnownNat n => HasParameter
182+type (--->) xs y
261− (n :: Nat)
183+ = forall outer commons grp schemas params from
262− (params :: [NullityType])
184+ . NP (Expression outer commons grp schemas params from) xs
263− (ty :: NullityType)
185+ -- ^ inputs
264− | n params -> ty where
186+ -> Expression outer commons grp schemas params from y
265− -- | `parameter` takes a `Nat` using type application and a `TypeExpression`.
187+ -- ^ output
267− -- >>> let expr = parameter @1 int4 :: Expression grp '[] schemas '[ 'Null 'PGint4] from ('Null 'PGint4)
189+type FunctionNDB schemas xs y
268− -- >>> printSQL expr
190+ = forall outer commons grp params from
269− -- ($1 :: int4)
191+ . NP (Expression outer commons grp schemas params from) xs
270− parameter
192+ -- ^ inputs
271− :: TypeExpression schemas ty
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
200+ = forall outer commons grp schemas params from
201+ . [Expression outer commons grp schemas params from x0]
203+ -> Expression outer commons grp schemas params from x1
204+ -- ^ must have at least 1 input
272− -> Expression grp commons schemas params from ty
205+ -> Expression outer commons grp schemas params from y
208+{- | >>> printSQL (unsafeFunctionVar "greatest" [true, null_] false)
209+greatest(TRUE, NULL, FALSE)
211+unsafeFunctionVar :: ByteString -> FunctionVar x0 x1 y
273− parameter ty = UnsafeExpression $ parenthesized $
212+unsafeFunctionVar fun xs x = UnsafeExpression $ fun <> parenthesized
274− "$" <> renderNat @n <+> "::"
213+ (commaSeparated (renderSQL <$> xs) <> ", " <> renderSQL x)
276−instance {-# OVERLAPPING #-} HasParameter 1 (ty1:tys) ty1
277−instance {-# OVERLAPPABLE #-} (KnownNat n, HasParameter (n-1) params ty)
278− => HasParameter n (ty' : params) ty
280−-- | `param` takes a `Nat` using type application and for basic types,
281−-- infers a `TypeExpression`.
283−-- >>> let expr = param @1 :: Expression grp commons schemas '[ 'Null 'PGint4] from ('Null 'PGint4)
287− :: forall n commons schemas params from grp ty
288− . (PGTyped schemas ty, HasParameter n params ty)
289− => Expression grp commons schemas params from ty -- ^ param
290−param = parameter @n (pgtype @schemas)
292−instance (HasUnique tab from row, Has col row ty)
215+instance (HasUnique tab (Join outer from) row, Has col row ty)
293− => IsLabel col (Expression 'Ungrouped commons schemas params from ty) where
216+ => IsLabel col (Expression outer commons 'Ungrouped schemas params from ty) where
294 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
217 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
295−instance (HasUnique tab from row, Has col row ty, tys ~ '[ty])
218+instance (HasUnique tab (Join outer from) row, Has col row ty, tys ~ '[ty])
296− => IsLabel col (NP (Expression 'Ungrouped commons schemas params from) tys) where
219+ => IsLabel col (NP (Expression outer commons 'Ungrouped schemas params from) tys) where
297 fromLabel = fromLabel @col :* Nil
220 fromLabel = fromLabel @col :* Nil
298−instance (HasUnique tab from row, Has col row ty, column ~ (col ::: ty))
221+instance (HasUnique tab (Join outer from) row, Has col row ty, column ~ (col ::: ty))
299 => IsLabel col
222 => IsLabel col
300− (Aliased (Expression 'Ungrouped commons schemas params from) column) where
223+ (Aliased (Expression outer commons 'Ungrouped schemas params from) column) where
301 fromLabel = fromLabel @col `As` Alias
224 fromLabel = fromLabel @col `As` Alias
302−instance (HasUnique tab from row, Has col row ty, columns ~ '[col ::: ty])
225+instance (HasUnique tab (Join outer from) row, Has col row ty, columns ~ '[col ::: ty])
303 => IsLabel col
226 => IsLabel col
304− (NP (Aliased (Expression 'Ungrouped commons schemas params from)) columns) where
227+ (NP (Aliased (Expression outer commons 'Ungrouped schemas params from)) columns) where
305 fromLabel = fromLabel @col :* Nil
228 fromLabel = fromLabel @col :* Nil
307−instance (Has tab from row, Has col row ty)
230+instance (Has tab (Join outer from) row, Has col row ty)
308− => IsQualified tab col (Expression 'Ungrouped commons schemas params from ty) where
231+ => IsQualified tab col (Expression outer commons 'Ungrouped schemas params from ty) where
309 tab ! col = UnsafeExpression $
232 tab ! col = UnsafeExpression $
310 renderSQL tab <> "." <> renderSQL col
233 renderSQL tab <> "." <> renderSQL col
311−instance (Has tab from row, Has col row ty, tys ~ '[ty])
234+instance (Has tab (Join outer from) row, Has col row ty, tys ~ '[ty])
312− => IsQualified tab col (NP (Expression 'Ungrouped commons schemas params from) tys) where
235+ => IsQualified tab col (NP (Expression outer commons 'Ungrouped schemas params from) tys) where
313 tab ! col = tab ! col :* Nil
236 tab ! col = tab ! col :* Nil
314−instance (Has tab from row, Has col row ty, column ~ (col ::: ty))
237+instance (Has tab (Join outer from) row, Has col row ty, column ~ (col ::: ty))
315 => IsQualified tab col
238 => IsQualified tab col
316− (Aliased (Expression 'Ungrouped commons schemas params from) column) where
239+ (Aliased (Expression outer commons 'Ungrouped schemas params from) column) where
317 tab ! col = tab ! col `As` col
240 tab ! col = tab ! col `As` col
318−instance (Has tab from row, Has col row ty, columns ~ '[col ::: ty])
241+instance (Has tab (Join outer from) row, Has col row ty, columns ~ '[col ::: ty])
319 => IsQualified tab col
242 => IsQualified tab col
320− (NP (Aliased (Expression 'Ungrouped commons schemas params from)) columns) where
243+ (NP (Aliased (Expression outer commons 'Ungrouped schemas params from)) columns) where
321 tab ! col = tab ! col :* Nil
244 tab ! col = tab ! col :* Nil
324− ( HasUnique tab from row
247+ ( HasUnique tab (Join outer from) row
325 , Has col row ty
248 , Has col row ty
326 , GroupedBy tab col bys
249 , GroupedBy tab col bys
327 ) => IsLabel col
250 ) => IsLabel col
328− (Expression ('Grouped bys) commons schemas params from ty) where
251+ (Expression outer commons ('Grouped bys) schemas params from ty) where
329 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
252 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
331− ( HasUnique tab from row
254+ ( HasUnique tab (Join outer from) row
332 , Has col row ty
255 , Has col row ty
333 , GroupedBy tab col bys
256 , GroupedBy tab col bys
334 , tys ~ '[ty]
257 , tys ~ '[ty]
335 ) => IsLabel col
258 ) => IsLabel col
336− (NP (Expression ('Grouped bys) commons schemas params from) tys) where
259+ (NP (Expression outer commons ('Grouped bys) schemas params from) tys) where
337 fromLabel = fromLabel @col :* Nil
260 fromLabel = fromLabel @col :* Nil
339− ( HasUnique tab from row
262+ ( HasUnique tab (Join outer from) row
340 , Has col row ty
263 , Has col row ty
341 , GroupedBy tab col bys
264 , GroupedBy tab col bys
342 , column ~ (col ::: ty)
265 , column ~ (col ::: ty)
343 ) => IsLabel col
266 ) => IsLabel col
344− (Aliased (Expression ('Grouped bys) commons schemas params from) column) where
267+ (Aliased (Expression outer commons ('Grouped bys) schemas params from) column) where
345 fromLabel = fromLabel @col `As` Alias
268 fromLabel = fromLabel @col `As` Alias
347− ( HasUnique tab from row
270+ ( HasUnique tab (Join outer from) row
348 , Has col row ty
271 , Has col row ty
349 , GroupedBy tab col bys
272 , GroupedBy tab col bys
350 , columns ~ '[col ::: ty]
273 , columns ~ '[col ::: ty]
351 ) => IsLabel col
274 ) => IsLabel col
352− (NP (Aliased (Expression ('Grouped bys) commons schemas params from)) columns) where
275+ (NP (Aliased (Expression outer commons ('Grouped bys) schemas params from)) columns) where
353 fromLabel = fromLabel @col :* Nil
276 fromLabel = fromLabel @col :* Nil
356− ( Has tab from row
279+ ( Has tab (Join outer from) row
357 , Has col row ty
280 , Has col row ty
358 , GroupedBy tab col bys
281 , GroupedBy tab col bys
359 ) => IsQualified tab col
282 ) => IsQualified tab col
360− (Expression ('Grouped bys) commons schemas params from ty) where
283+ (Expression outer commons ('Grouped bys) schemas params from ty) where
361 tab ! col = UnsafeExpression $
284 tab ! col = UnsafeExpression $
362 renderSQL tab <> "." <> renderSQL col
285 renderSQL tab <> "." <> renderSQL col
364− ( Has tab from row
287+ ( Has tab (Join outer from) row
365 , Has col row ty
288 , Has col row ty
366 , GroupedBy tab col bys
289 , GroupedBy tab col bys
367 , tys ~ '[ty]
290 , tys ~ '[ty]
368 ) => IsQualified tab col
291 ) => IsQualified tab col
369− (NP (Expression ('Grouped bys) commons schemas params from) tys) where
292+ (NP (Expression outer commons ('Grouped bys) schemas params from) tys) where
370 tab ! col = tab ! col :* Nil
293 tab ! col = tab ! col :* Nil
372− ( Has tab from row
295+ ( Has tab (Join outer from) row
373 , Has col row ty
296 , Has col row ty
374 , GroupedBy tab col bys
297 , GroupedBy tab col bys
375 , column ~ (col ::: ty)
298 , column ~ (col ::: ty)
376 ) => IsQualified tab col
299 ) => IsQualified tab col
377− (Aliased (Expression ('Grouped bys) commons schemas params from) column) where
300+ (Aliased (Expression outer commons ('Grouped bys) schemas params from) column) where
378 tab ! col = tab ! col `As` col
301 tab ! col = tab ! col `As` col
380− ( Has tab from row
303+ ( Has tab (Join outer from) row
381 , Has col row ty
304 , Has col row ty
382 , GroupedBy tab col bys
305 , GroupedBy tab col bys
383 , columns ~ '[col ::: ty]
306 , columns ~ '[col ::: ty]
384 ) => IsQualified tab col
307 ) => IsQualified tab col
385− (NP (Aliased (Expression ('Grouped bys) commons schemas params from)) columns) where
308+ (NP (Aliased (Expression outer commons ('Grouped bys) schemas params from)) columns) where
386 tab ! col = tab ! col :* Nil
309 tab ! col = tab ! col :* Nil
388−-- | analagous to `Nothing`
390−-- >>> printSQL null_
392−null_ :: Expression commons schemas rels grouping params ('Null ty)
393−null_ = UnsafeExpression "NULL"
395−-- | analagous to `Just`
397−-- >>> printSQL $ notNull true
400− :: Expression commons schemas rels grouping params ('NotNull ty)
401− -> Expression commons schemas rels grouping params ('Null ty)
402−notNull = UnsafeExpression . renderSQL
404−-- | return the leftmost value which is not NULL
406−-- >>> printSQL $ coalesce [null_, true] false
407−-- COALESCE(NULL, TRUE, FALSE)
409− :: [Expression grp commons schemas params from ('Null ty)]
410− -- ^ @NULL@s may be present
411− -> Expression grp commons schemas params from ('NotNull ty)
412− -- ^ @NULL@ is absent
413− -> Expression grp commons schemas params from ('NotNull ty)
414−coalesce nullxs notNullx = UnsafeExpression $
415− "COALESCE" <> parenthesized (commaSeparated
416− ((renderSQL <$> nullxs) <> [renderSQL notNullx]))
418−-- | analagous to `Data.Maybe.fromMaybe` using @COALESCE@
420−-- >>> printSQL $ fromNull true null_
421−-- COALESCE(NULL, TRUE)
423− :: Expression grp commons schemas params from ('NotNull ty)
424− -- ^ what to convert @NULL@ to
425− -> Expression grp commons schemas params from ('Null ty)
426− -> Expression grp commons schemas params from ('NotNull ty)
427−fromNull notNullx nullx = coalesce [nullx] notNullx
429−-- | >>> printSQL $ null_ & isNull
432− :: Expression grp commons schemas params from ('Null ty)
433− -- ^ possibly @NULL@
434− -> Condition grp commons schemas params from
435−isNull x = UnsafeExpression $ renderSQL x <+> "IS NULL"
437−-- | >>> printSQL $ null_ & isNotNull
440− :: Expression grp commons schemas params from ('Null ty)
441− -- ^ possibly @NULL@
442− -> Condition grp commons schemas params from
443−isNotNull x = UnsafeExpression $ renderSQL x <+> "IS NOT NULL"
445−-- | analagous to `maybe` using @IS NULL@
447−-- >>> printSQL $ matchNull true not_ null_
448−-- CASE WHEN NULL IS NULL THEN TRUE ELSE (NOT NULL) END
450− :: Expression grp commons schemas params from (nullty)
451− -- ^ what to convert @NULL@ to
452− -> ( Expression grp commons schemas params from ('NotNull ty)
453− -> Expression grp commons schemas params from (nullty) )
454− -- ^ function to perform when @NULL@ is absent
455− -> Expression grp commons schemas params from ('Null ty)
456− -> Expression grp commons schemas params from (nullty)
457−matchNull y f x = ifThenElse (isNull x) y
458− (f (UnsafeExpression (renderSQL x)))
460−{-| right inverse to `fromNull`, if its arguments are equal then
461−`nullIf` gives @NULL@.
463−>>> :set -XTypeApplications -XDataKinds
464−>>> let expr = nullIf false (param @1) :: Expression grp commons schemas '[ 'NotNull 'PGbool] from ('Null 'PGbool)
466−NULL IF (FALSE, ($1 :: bool))
469− :: Expression grp commons schemas params from ('NotNull ty)
470− -- ^ @NULL@ is absent
471− -> Expression grp commons schemas params from ('NotNull ty)
472− -- ^ @NULL@ is absent
473− -> Expression grp commons schemas params from ('Null ty)
474−nullIf x y = UnsafeExpression $ "NULL IF" <+> parenthesized
475− (renderSQL x <> ", " <> renderSQL y)
477−-- | >>> printSQL $ array [null_, false, true]
478−-- ARRAY[NULL, FALSE, TRUE]
480− :: [Expression grp commons schemas params from ty]
482− -> Expression grp commons schemas params from (nullity ('PGvararray ty))
483−array xs = UnsafeExpression $
484− "ARRAY[" <> commaSeparated (renderSQL <$> xs) <> "]"
486−-- | >>> printSQL $ array [null_, false, true] & index 2
487−-- (ARRAY[NULL, FALSE, TRUE])[2]
489− :: Word64 -- ^ index
490− -> Expression grp commons schemas params from (nullity ('PGvararray ty)) -- ^ array
491− -> Expression grp commons schemas params from (NullifyType ty)
492−index n expr = UnsafeExpression $
493− parenthesized (renderSQL expr) <> "[" <> fromString (show n) <> "]"
495instance (KnownSymbol label, label `In` labels) => IsPGlabel label
311instance (KnownSymbol label, label `In` labels) => IsPGlabel label
496− (Expression grp commons schemas params from (nullity ('PGenum labels))) where
312+ (Expression outer commons grp schemas params from (null ('PGenum labels))) where
497 label = UnsafeExpression $ renderSQL (PGlabel @label)
313 label = UnsafeExpression $ renderSQL (PGlabel @label)
499−-- | A row constructor is an expression that builds a row value
500−-- (also called a composite value) using values for its member fields.
503−-- type Complex = 'PGcomposite
504−-- '[ "real" ::: 'NotNull 'PGfloat8
505−-- , "imaginary" ::: 'NotNull 'PGfloat8 ]
508−-- >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression grp commons schemas params from ('NotNull Complex)
513− => NP (Aliased (Expression grp commons schemas params from)) row
514− -- ^ zero or more expressions for the row field values
515− -> Expression grp commons schemas params from (nullity ('PGcomposite row))
516−row exprs = UnsafeExpression $ "ROW" <> parenthesized
517− (renderCommaSeparated (\ (expr `As` _) -> renderSQL expr) exprs)
520−-- type Complex = 'PGcomposite
521−-- '[ "real" ::: 'NotNull 'PGfloat8
522−-- , "imaginary" ::: 'NotNull 'PGfloat8 ]
523−-- type Schema = '["complex" ::: 'Typedef Complex]
526−-- >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression grp '[] (Public Schema) from params ('NotNull Complex)
527−-- >>> printSQL $ i & field #complex #imaginary
528−-- (ROW(0, 1)::"complex")."imaginary"
530− :: ( Has sch schemas schema
531− , Has tydef schema ('Typedef ('PGcomposite row))
533− => QualifiedAlias sch tydef -- ^ row type
534− -> Alias field -- ^ field name
535− -> Expression grp commons schemas params from ('NotNull ('PGcomposite row))
536− -> Expression grp commons schemas params from ty
537−field td fld expr = UnsafeExpression $
538− parenthesized (renderSQL expr <> "::" <> renderSQL td)
539− <> "." <> renderSQL fld
542− (Expression grp commons schemas params from (nullity ('PGvararray ty))) where
543− (<>) = unsafeBinaryOp "||"
546− (Expression grp commons schemas params from (nullity ('PGvararray ty))) where
550−-- | >>> let expr = greatest currentTimestamp [param @1] :: Expression grp commons schemas '[ 'NotNull 'PGtimestamptz] from ('NotNull 'PGtimestamptz)
552−-- GREATEST(CURRENT_TIMESTAMP, ($1 :: timestamp with time zone))
554− :: Expression grp commons schemas params from (nullty)
555− -- ^ needs at least 1 argument
556− -> [Expression grp commons schemas params from (nullty)]
558− -> Expression grp commons schemas params from (nullty)
559−greatest x xs = UnsafeExpression $ "GREATEST("
560− <> commaSeparated (renderSQL <$> (x:xs)) <> ")"
562−-- | >>> printSQL $ least currentTimestamp [null_]
563−-- LEAST(CURRENT_TIMESTAMP, NULL)
565− :: Expression grp commons schemas params from (nullty)
566− -- ^ needs at least 1 argument
567− -> [Expression grp commons schemas params from (nullty)]
569− -> Expression grp commons schemas params from (nullty)
570−least x xs = UnsafeExpression $ "LEAST("
571− <> commaSeparated (renderSQL <$> (x:xs)) <> ")"
573-- | >>> printSQL $ unsafeBinaryOp "OR" true false
315-- | >>> printSQL $ unsafeBinaryOp "OR" true false
574-- (TRUE OR FALSE)
316-- (TRUE OR FALSE)
575−unsafeBinaryOp
317+unsafeBinaryOp :: ByteString -> Operator ty0 ty1 ty2
578− -> Expression grp commons schemas params from (ty0)
579− -> Expression grp commons schemas params from (ty1)
580− -> Expression grp commons schemas params from (ty2)
581unsafeBinaryOp op x y = UnsafeExpression $ parenthesized $
318unsafeBinaryOp op x y = UnsafeExpression $ parenthesized $
582 renderSQL x <+> op <+> renderSQL y
319 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
584−-- | >>> printSQL $ unsafeUnaryOp "NOT" true
328+-- | >>> printSQL $ unsafeLeftOp "NOT" true
585-- (NOT TRUE)
329-- (NOT TRUE)
587− :: ByteString
330+unsafeLeftOp :: ByteString -> x --> y
588− -- ^ operator
331+unsafeLeftOp op x = UnsafeExpression $ parenthesized $ op <+> renderSQL x
589− -> Expression grp commons schemas params from (ty0)
332+
590− -> Expression grp commons schemas params from (ty1)
333+leftOp
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
591−unsafeUnaryOp op x = UnsafeExpression $ parenthesized $
343+unsafeRightOp op x = UnsafeExpression $ parenthesized $ renderSQL x <+> op
592− op <+> renderSQL x
344+
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
594-- | >>> printSQL $ unsafeFunction "f" true
352-- | >>> printSQL $ unsafeFunction "f" true
595-- f(TRUE)
353-- f(TRUE)
596−unsafeFunction
354+unsafeFunction :: ByteString -> x --> y
599− -> Expression grp commons schemas params from (xty)
600− -> Expression grp commons schemas params from (yty)
601unsafeFunction fun x = UnsafeExpression $
355unsafeFunction fun x = UnsafeExpression $
602 fun <> parenthesized (renderSQL x)
356 fun <> parenthesized (renderSQL x)
604−-- | Helper for defining variadic functions.
358+function
605−unsafeVariadicFunction
359+ :: (Has sch schemas schema, Has fun schema ('Function ('[x] :=> 'Returns y)))
606− :: SListI elems
360+ => QualifiedAlias sch fun
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')
607− => ByteString
366+unsafeFunctionN :: SListI xs => ByteString -> xs ---> y
609− -> NP (Expression grp commons schemas params from) elems
610− -> Expression grp commons schemas params from ret
611−unsafeVariadicFunction fun x = UnsafeExpression $
367+unsafeFunctionN fun xs = UnsafeExpression $
612− fun <> parenthesized (commaSeparated (hcollapse (hmap (K . renderSQL) x)))
368+ fun <> parenthesized (renderCommaSeparated renderSQL xs)
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
614instance ty `In` PGNum
378instance ty `In` PGNum
615− => Num (Expression grp commons schemas params from (nullity ty)) where
379+ => Num (Expression outer commons grp schemas params from (null ty)) where
616 (+) = unsafeBinaryOp "+"
380 (+) = unsafeBinaryOp "+"
617 (-) = unsafeBinaryOp "-"
381 (-) = unsafeBinaryOp "-"
618 (*) = unsafeBinaryOp "*"
382 (*) = unsafeBinaryOp "*"
@@ -624,12 +388,17 @@ instance ty `In` PGNum
626instance (ty `In` PGNum, ty `In` PGFloating) => Fractional
390instance (ty `In` PGNum, ty `In` PGFloating) => Fractional
627− (Expression grp commons schemas params from (nullity ty)) where
391+ (Expression outer commons grp schemas params from (null ty)) where
628 (/) = unsafeBinaryOp "/"
392 (/) = unsafeBinaryOp "/"
629− fromRational x = fromInteger (numerator x) / fromInteger (denominator x)
393+ fromRational
397+ . showFFloat Nothing
631instance (ty `In` PGNum, ty `In` PGFloating) => Floating
400instance (ty `In` PGNum, ty `In` PGFloating) => Floating
632− (Expression grp commons schemas params from (nullity ty)) where
401+ (Expression outer commons grp schemas params from (null ty)) where
633 pi = UnsafeExpression "pi()"
402 pi = UnsafeExpression "pi()"
634 exp = unsafeFunction "exp"
403 exp = unsafeFunction "exp"
635 log = unsafeFunction "ln"
404 log = unsafeFunction "ln"
@@ -650,1549 +419,54 @@ instance (ty `In` PGNum, ty `In` PGFloating) => Floating
650 acosh x = log (x + sqrt (x*x - 1))
419 acosh x = log (x + sqrt (x*x - 1))
651 atanh x = log ((1 + x) / (1 - x)) / 2
420 atanh x = log ((1 + x) / (1 - x)) / 2
653−-- | >>> :{
422+-- | Contained by operators
654−-- let
423+class PGSubset ty where
655−-- expression :: Expression grp commons schemas params from (nullity 'PGfloat4)
424+ (@>) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
656−-- expression = atan2_ pi 2
425+ (@>) = unsafeBinaryOp "@>"
657−-- in printSQL expression
426+ (<@) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
658−-- :}
427+ (<@) = unsafeBinaryOp "<@"
659−-- atan2(pi(), 2)
428+instance PGSubset 'PGjsonb
660−atan2_
429+instance PGSubset 'PGtsquery
661− :: float `In` PGFloating
430+instance PGSubset ('PGvararray ty)
662− => Expression grp commons schemas params from (nullity float)
431+instance PGSubset ('PGrange ty)
664− -> Expression grp commons schemas params from (nullity float)
433+class PGIntersect ty where
665− -- ^ denominator
434+ (@&&) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
666− -> Expression grp commons schemas params from (nullity float)
435+ (@&&) = unsafeBinaryOp "&&"
667−atan2_ y x = UnsafeExpression $
436+instance PGIntersect ('PGvararray ty)
668− "atan2(" <> renderSQL y <> ", " <> renderSQL x <> ")"
437+instance PGIntersect ('PGrange ty)
670−-- When a `cast` is applied to an `Expression` of a known type, it
671−-- represents a run-time type conversion. The cast will succeed only if a
672−-- suitable type conversion operation has been defined.
674−-- | >>> printSQL $ true & cast int4
677− :: TypeExpression schemas ty1
678− -- ^ type to cast as
679− -> Expression grp commons schemas params from ty0
680− -- ^ value to convert
681− -> Expression grp commons schemas params from ty1
682−cast ty x = UnsafeExpression $ parenthesized $
683− renderSQL x <+> "::" <+> renderSQL ty
685−-- | integer division, truncates the result
689−-- expression :: Expression grp commons schemas params from (nullity 'PGint2)
690−-- expression = 5 `quot_` 2
691−-- in printSQL expression
695− :: int `In` PGIntegral
696− => Expression grp commons schemas params from (nullity int)
698− -> Expression grp commons schemas params from (nullity int)
700− -> Expression grp commons schemas params from (nullity int)
701−quot_ = unsafeBinaryOp "/"
703−-- | remainder upon integer division
707−-- expression :: Expression grp commons schemas params from (nullity 'PGint2)
708−-- expression = 5 `rem_` 2
709−-- in printSQL expression
713− :: int `In` PGIntegral
714− => Expression grp commons schemas params from (nullity int)
716− -> Expression grp commons schemas params from (nullity int)
718− -> Expression grp commons schemas params from (nullity int)
719−rem_ = unsafeBinaryOp "%"
723−-- expression :: Expression grp commons schemas params from (nullity 'PGfloat4)
724−-- expression = trunc pi
725−-- in printSQL expression
729− :: frac `In` PGFloating
730− => Expression grp commons schemas params from (nullity frac)
731− -- ^ fractional number
732− -> Expression grp commons schemas params from (nullity frac)
733−trunc = unsafeFunction "trunc"
737−-- expression :: Expression grp commons schemas params from (nullity 'PGfloat4)
738−-- expression = round_ pi
739−-- in printSQL expression
743− :: frac `In` PGFloating
744− => Expression grp commons schemas params from (nullity frac)
745− -- ^ fractional number
746− -> Expression grp commons schemas params from (nullity frac)
747−round_ = unsafeFunction "round"
751−-- expression :: Expression grp commons schemas params from (nullity 'PGfloat4)
752−-- expression = ceiling_ pi
753−-- in printSQL expression
757− :: frac `In` PGFloating
758− => Expression grp commons schemas params from (nullity frac)
759− -- ^ fractional number
760− -> Expression grp commons schemas params from (nullity frac)
761−ceiling_ = unsafeFunction "ceiling"
763−-- | A `Condition` is an `Expression`, which can evaluate
764−-- to `true`, `false` or `null_`. This is because SQL uses
765−-- a three valued logic.
766−type Condition grp commons schemas params from =
767− Expression grp commons schemas params from ('Null 'PGbool)
769−-- | >>> printSQL true
771−true :: Expression grp commons schemas params from (nullity 'PGbool)
772−true = UnsafeExpression "TRUE"
774−-- | >>> printSQL false
776−false :: Expression grp commons schemas params from (nullity 'PGbool)
777−false = UnsafeExpression "FALSE"
779−-- | >>> printSQL $ not_ true
782− :: Expression grp commons schemas params from (nullity 'PGbool)
783− -> Expression grp commons schemas params from (nullity 'PGbool)
784−not_ = unsafeUnaryOp "NOT"
786−-- | >>> printSQL $ true .&& false
789− :: Expression grp commons schemas params from (nullity 'PGbool)
790− -> Expression grp commons schemas params from (nullity 'PGbool)
791− -> Expression grp commons schemas params from (nullity 'PGbool)
793−(.&&) = unsafeBinaryOp "AND"
795−-- | >>> printSQL $ true .|| false
798− :: Expression grp commons schemas params from (nullity 'PGbool)
799− -> Expression grp commons schemas params from (nullity 'PGbool)
800− -> Expression grp commons schemas params from (nullity 'PGbool)
802−(.||) = unsafeBinaryOp "OR"
806−-- expression :: Expression grp commons schemas params from (nullity 'PGint2)
807−-- expression = caseWhenThenElse [(true, 1), (false, 2)] 3
808−-- in printSQL expression
810−-- CASE WHEN TRUE THEN 1 WHEN FALSE THEN 2 ELSE 3 END
812− :: [ ( Condition grp commons schemas params from
813− , Expression grp commons schemas params from ty
815− -- ^ whens and thens
816− -> Expression grp commons schemas params from ty
818− -> Expression grp commons schemas params from ty
819−caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
823− [ " WHEN ", renderSQL when_
824− , " THEN ", renderSQL then_
826− | (when_,then_) <- whenThens
828− , " ELSE ", renderSQL else_
834−-- expression :: Expression grp commons schemas params from (nullity 'PGint2)
835−-- expression = ifThenElse true 1 0
836−-- in printSQL expression
838−-- CASE WHEN TRUE THEN 1 ELSE 0 END
840− :: Condition grp commons schemas params from
841− -> Expression grp commons schemas params from ty -- ^ then
842− -> Expression grp commons schemas params from ty -- ^ else
843− -> Expression grp commons schemas params from ty
844−ifThenElse if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
846−-- | Comparison operations like `.==`, `./=`, `.>`, `.>=`, `.<` and `.<=`
847−-- will produce @NULL@s if one of their arguments is @NULL@.
849−-- >>> printSQL $ true .== null_
852− :: Expression grp commons schemas params from (nullity0 ty) -- ^ lhs
853− -> Expression grp commons schemas params from (nullity1 ty) -- ^ rhs
854− -> Condition grp commons schemas params from
855−(.==) = unsafeBinaryOp "="
858−-- | >>> printSQL $ true ./= null_
861− :: Expression grp commons schemas params from (nullity0 ty) -- ^ lhs
862− -> Expression grp commons schemas params from (nullity1 ty) -- ^ rhs
863− -> Condition grp commons schemas params from
864−(./=) = unsafeBinaryOp "<>"
867−-- | >>> printSQL $ true .>= null_
870− :: Expression grp commons schemas params from (nullity0 ty) -- ^ lhs
871− -> Expression grp commons schemas params from (nullity1 ty) -- ^ rhs
872− -> Condition grp commons schemas params from
873−(.>=) = unsafeBinaryOp ">="
876−-- | >>> printSQL $ true .< null_
879− :: Expression grp commons schemas params from (nullity0 ty) -- ^ lhs
880− -> Expression grp commons schemas params from (nullity1 ty) -- ^ rhs
881− -> Condition grp commons schemas params from
882−(.<) = unsafeBinaryOp "<"
885−-- | >>> printSQL $ true .<= null_
888− :: Expression grp commons schemas params from (nullity0 ty) -- ^ lhs
889− -> Expression grp commons schemas params from (nullity1 ty) -- ^ rhs
890− -> Condition grp commons schemas params from
891−(.<=) = unsafeBinaryOp "<="
894−-- | >>> printSQL $ true .> null_
897− :: Expression grp commons schemas params from (nullity0 ty) -- ^ lhs
898− -> Expression grp commons schemas params from (nullity1 ty) -- ^ rhs
899− -> Condition grp commons schemas params from
900−(.>) = unsafeBinaryOp ">"
903−-- | >>> printSQL currentDate
906− :: Expression grp commons schemas params from (nullity 'PGdate)
907−currentDate = UnsafeExpression "CURRENT_DATE"
909−-- | >>> printSQL currentTime
912− :: Expression grp commons schemas params from (nullity 'PGtimetz)
913−currentTime = UnsafeExpression "CURRENT_TIME"
915−-- | >>> printSQL currentTimestamp
918− :: Expression grp commons schemas params from (nullity 'PGtimestamptz)
919−currentTimestamp = UnsafeExpression "CURRENT_TIMESTAMP"
921−-- | >>> printSQL localTime
924− :: Expression grp commons schemas params from (nullity 'PGtime)
925−localTime = UnsafeExpression "LOCALTIME"
927−-- | >>> printSQL localTimestamp
930− :: Expression grp commons schemas params from (nullity 'PGtimestamp)
931−localTimestamp = UnsafeExpression "LOCALTIMESTAMP"
933−{-----------------------------------------
935−-----------------------------------------}
937instance IsString
439instance IsString
938− (Expression grp commons schemas params from (nullity 'PGtext)) where
440+ (Expression outer commons grp schemas params from (null 'PGtext)) where
939 fromString str = UnsafeExpression $
441 fromString str = UnsafeExpression $
940 "E\'" <> fromString (escape =<< str) <> "\'"
442 "E\'" <> fromString (escape =<< str) <> "\'"
941− where
443+instance IsString
942− escape = \case
444+ (Expression outer commons grp schemas params from (null 'PGtsvector)) where
943− '\NUL' -> "\\0"
445+ fromString str = UnsafeExpression . parenthesized . (<> " :: tsvector") $
944− '\'' -> "''"
446+ "E\'" <> fromString (escape =<< str) <> "\'"
945− '"' -> "\\\""
447+instance IsString
946− '\b' -> "\\b"
448+ (Expression outer commons grp schemas params from (null 'PGtsquery)) where
947− '\n' -> "\\n"
449+ fromString str = UnsafeExpression . parenthesized . (<> " :: tsquery") $
948− '\r' -> "\\r"
450+ "E\'" <> fromString (escape =<< str) <> "\'"
953instance Semigroup
452instance 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 "||"
954− (Expression grp commons schemas params from (nullity 'PGtext)) where
459+ (Expression outer commons grp schemas params from (null 'PGtext)) where
460+ (<>) = unsafeBinaryOp "||"
462+ (Expression outer commons grp schemas params from (null 'PGtsvector)) where
955 (<>) = unsafeBinaryOp "||"
463 (<>) = unsafeBinaryOp "||"
957instance Monoid
465instance Monoid
958− (Expression grp commons schemas params from (nullity 'PGtext)) where
466+ (Expression outer commons grp schemas params from (null 'PGtext)) where
467+ mempty = fromString ""
470+ (Expression outer commons grp schemas params from (null 'PGtsvector)) where
959 mempty = fromString ""
471 mempty = fromString ""
960 mappend = (<>)
472 mappend = (<>)
962−-- | >>> printSQL $ lower "ARRRGGG"
965− :: Expression grp commons schemas params from (nullity 'PGtext)
966− -- ^ string to lower case
967− -> Expression grp commons schemas params from (nullity 'PGtext)
968−lower = unsafeFunction "lower"
970−-- | >>> printSQL $ upper "eeee"
973− :: Expression grp commons schemas params from (nullity 'PGtext)
974− -- ^ string to upper case
975− -> Expression grp commons schemas params from (nullity 'PGtext)
976−upper = unsafeFunction "upper"
978−-- | >>> printSQL $ charLength "four"
979−-- char_length(E'four')
981− :: Expression grp commons schemas params from (nullity 'PGtext)
982− -- ^ string to measure
983− -> Expression grp commons schemas params from (nullity 'PGint4)
984−charLength = unsafeFunction "char_length"
986−-- | The `like` expression returns true if the @string@ matches
987−-- the supplied @pattern@. If @pattern@ does not contain percent signs
988−-- or underscores, then the pattern only represents the string itself;
989−-- in that case `like` acts like the equals operator. An underscore (_)
990−-- in pattern stands for (matches) any single character; a percent sign (%)
991−-- matches any sequence of zero or more characters.
993−-- >>> printSQL $ "abc" `like` "a%"
994−-- (E'abc' LIKE E'a%')
996− :: Expression grp commons schemas params from (nullity 'PGtext)
998− -> Expression grp commons schemas params from (nullity 'PGtext)
1000− -> Expression grp commons schemas params from (nullity 'PGbool)
1001−like = unsafeBinaryOp "LIKE"
1003−-- | The key word ILIKE can be used instead of LIKE to make the
1004−-- match case-insensitive according to the active locale.
1006−-- >>> printSQL $ "abc" `ilike` "a%"
1007−-- (E'abc' ILIKE E'a%')
1009− :: Expression grp commons schemas params from (nullity 'PGtext)
1011− -> Expression grp commons schemas params from (nullity 'PGtext)
1013− -> Expression grp commons schemas params from (nullity 'PGbool)
1014−ilike = unsafeBinaryOp "ILIKE"
1016−{-----------------------------------------
1017− -- json and jsonb support
1019−See https://www.postgresql.org/docs/10/static/functions-json.html -- most
1020−comments lifted directly from this page.
1022−Table 9.44: json and jsonb operators
1023−-----------------------------------------}
1025−-- | Get JSON value (object field or array element) at a key.
1027− :: (json `In` PGJsonType, key `In` PGJsonKey)
1028− => Expression grp commons schemas params from (nullity json)
1029− -> Expression grp commons schemas params from (nullity key)
1030− -> Expression grp commons schemas params from ('Null json)
1032−(.->) = unsafeBinaryOp "->"
1034−-- | Get JSON value (object field or array element) at a key, as text.
1036− :: (json `In` PGJsonType, key `In` PGJsonKey)
1037− => Expression grp commons schemas params from (nullity json)
1038− -> Expression grp commons schemas params from (nullity key)
1039− -> Expression grp commons schemas params from ('Null 'PGtext)
1041−(.->>) = unsafeBinaryOp "->>"
1043−-- | Get JSON value at a specified path.
1045− :: (json `In` PGJsonType, PGTextArray "(.#>)" path)
1046− => Expression grp commons schemas params from (nullity json)
1047− -> Expression grp commons schemas params from (nullity path)
1048− -> Expression grp commons schemas params from ('Null json)
1050−(.#>) = unsafeBinaryOp "#>"
1052−-- | Get JSON value at a specified path as text.
1054− :: (json `In` PGJsonType, PGTextArray "(.#>>)" path)
1055− => Expression grp commons schemas params from (nullity json)
1056− -> Expression grp commons schemas params from (nullity path)
1057− -> Expression grp commons schemas params from ('Null 'PGtext)
1059−(.#>>) = unsafeBinaryOp "#>>"
1061−-- Additional jsonb operators
1063−-- | Does the left JSON value contain the right JSON path/value entries at the
1066− :: Expression grp commons schemas params from (nullity 'PGjsonb)
1067− -> Expression grp commons schemas params from (nullity 'PGjsonb)
1068− -> Condition grp commons schemas params from
1070−(.@>) = unsafeBinaryOp "@>"
1072−-- | Are the left JSON path/value entries contained at the top level within the
1073−-- right JSON value?
1075− :: Expression grp commons schemas params from (nullity 'PGjsonb)
1076− -> Expression grp commons schemas params from (nullity 'PGjsonb)
1077− -> Condition grp commons schemas params from
1079−(.<@) = unsafeBinaryOp "<@"
1081−-- | Does the string exist as a top-level key within the JSON value?
1083− :: Expression grp commons schemas params from (nullity 'PGjsonb)
1084− -> Expression grp commons schemas params from (nullity 'PGtext)
1085− -> Condition grp commons schemas params from
1087−(.?) = unsafeBinaryOp "?"
1089−-- | Do any of these array strings exist as top-level keys?
1091− :: Expression grp commons schemas params from (nullity 'PGjsonb)
1092− -> Expression grp commons schemas params from (nullity ('PGvararray ('NotNull 'PGtext)))
1093− -> Condition grp commons schemas params from
1095−(.?|) = unsafeBinaryOp "?|"
1097−-- | Do all of these array strings exist as top-level keys?
1099− :: Expression grp commons schemas params from (nullity 'PGjsonb)
1100− -> Expression grp commons schemas params from (nullity ('PGvararray ('NotNull 'PGtext)))
1101− -> Condition grp commons schemas params from
1103−(.?&) = unsafeBinaryOp "?&"
1105−-- | Concatenate two jsonb values into a new jsonb value.
1107− Semigroup (Expression commons schemas from grouping param (nullity 'PGjsonb)) where
1108− (<>) = unsafeBinaryOp "||"
1110−-- | Delete a key or keys from a JSON object, or remove an array element.
1112−-- If the right operand is..
1114−-- @ text @: Delete key/value pair or string element from left operand. Key/value pairs
1115−-- are matched based on their key value.
1117−-- @ text[] @: Delete multiple key/value pairs or string elements
1118−-- from left operand. Key/value pairs are matched based on their key value.
1120−-- @ integer @: Delete the array element with specified index (Negative integers
1121−-- count from the end). Throws an error if top level container is not an array.
1123− :: (key `In` '[ 'PGtext, 'PGvararray ('NotNull 'PGtext), 'PGint4, 'PGint2 ]) -- hlint error without parens here
1124− => Expression grp commons schemas params from (nullity 'PGjsonb)
1125− -> Expression grp commons schemas params from (nullity key)
1126− -> Expression grp commons schemas params from (nullity 'PGjsonb)
1128−(.-.) = unsafeBinaryOp "-"
1130−-- | Delete the field or element with specified path (for JSON arrays, negative
1131−-- integers count from the end)
1133− :: PGTextArray "(#-.)" arrayty
1134− => Expression grp commons schemas params from (nullity 'PGjsonb)
1135− -> Expression grp commons schemas params from (nullity arrayty)
1136− -> Expression grp commons schemas params from (nullity 'PGjsonb)
1138−(#-.) = unsafeBinaryOp "#-"
1140−{-----------------------------------------
1141−Table 9.45: JSON creation functions
1142−-----------------------------------------}
1144−-- | Literal binary JSON
1147− => x -> Expression grp commons schemas params from (nullity 'PGjsonb)
1148−jsonbLit = cast jsonb . UnsafeExpression
1149− . singleQuotedUtf8 . toStrict . JSON.encode
1154− => x -> Expression grp commons schemas params from (nullity 'PGjson)
1155−jsonLit = cast json . UnsafeExpression
1156− . singleQuotedUtf8 . toStrict . JSON.encode
1158−-- | Returns the value as json. Arrays and composites are converted
1159−-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1160−-- type to json, the cast function will be used to perform the conversion;
1161−-- otherwise, a scalar value is produced. For any scalar type other than a
1162−-- number, a Boolean, or a null value, the text representation will be used, in
1163−-- such a fashion that it is a valid json value.
1165− :: Expression grp commons schemas params from (nullity ty)
1166− -> Expression grp commons schemas params from (nullity 'PGjson)
1167−toJson = unsafeFunction "to_json"
1169−-- | Returns the value as jsonb. Arrays and composites are converted
1170−-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1171−-- type to json, the cast function will be used to perform the conversion;
1172−-- otherwise, a scalar value is produced. For any scalar type other than a
1173−-- number, a Boolean, or a null value, the text representation will be used, in
1174−-- such a fashion that it is a valid jsonb value.
1176− :: Expression grp commons schemas params from (nullity ty)
1177− -> Expression grp commons schemas params from (nullity 'PGjsonb)
1178−toJsonb = unsafeFunction "to_jsonb"
1180−-- | Returns the array as a JSON array. A PostgreSQL multidimensional array
1181−-- becomes a JSON array of arrays.
1183− :: PGArray "arrayToJson" arr
1184− => Expression grp commons schemas params from (nullity arr)
1185− -> Expression grp commons schemas params from (nullity 'PGjson)
1186−arrayToJson = unsafeFunction "array_to_json"
1188−-- | Returns the row as a JSON object.
1190− :: Expression grp commons schemas params from (nullity ('PGcomposite ty))
1191− -> Expression grp commons schemas params from (nullity 'PGjson)
1192−rowToJson = unsafeFunction "row_to_json"
1194−-- | Builds a possibly-heterogeneously-typed JSON array out of a variadic
1198− => NP (Expression grp commons schemas params from) elems
1199− -> Expression grp commons schemas params from (nullity 'PGjson)
1200−jsonBuildArray = unsafeVariadicFunction "json_build_array"
1202−-- | Builds a possibly-heterogeneously-typed (binary) JSON array out of a
1203−-- variadic argument list.
1206− => NP (Expression grp commons schemas params from) elems
1207− -> Expression grp commons schemas params from (nullity 'PGjsonb)
1208−jsonbBuildArray = unsafeVariadicFunction "jsonb_build_array"
1212− => NP (Aliased (Expression grp commons schemas params from)) elems
1215− (`appEndo` []) . hcfoldMap (Proxy :: Proxy Top)
1216− (\(col `As` name) -> Endo $ \xs ->
1217− renderAliasString name : renderSQL col : xs)
1219− renderAliasString :: KnownSymbol alias => Alias alias -> ByteString
1220− renderAliasString = singleQuotedText . fromString . symbolVal
1222−-- | Builds a possibly-heterogeneously-typed JSON object out of a variadic
1223−-- argument list. The elements of the argument list must alternate between text
1227− => NP (Aliased (Expression grp commons schemas params from)) elems
1228− -> Expression grp commons schemas params from (nullity 'PGjson)
1230− = unsafeFunction "json_build_object"
1233− . unsafeRowFunction
1235−-- | Builds a possibly-heterogeneously-typed (binary) JSON object out of a
1236−-- variadic argument list. The elements of the argument list must alternate
1237−-- between text and values.
1240− => NP (Aliased (Expression grp commons schemas params from)) elems
1241− -> Expression grp commons schemas params from (nullity 'PGjsonb)
1243− = unsafeFunction "jsonb_build_object"
1246− . unsafeRowFunction
1248−-- | Builds a JSON object out of a text array. The array must have either
1249−-- exactly one dimension with an even number of members, in which case they are
1250−-- taken as alternating key/value pairs, or two dimensions such that each inner
1251−-- array has exactly two elements, which are taken as a key/value pair.
1253− :: PGArrayOf "jsonObject" arr ('NotNull 'PGtext)
1254− => Expression grp commons schemas params from (nullity arr)
1255− -> Expression grp commons schemas params from (nullity 'PGjson)
1256−jsonObject = unsafeFunction "json_object"
1258−-- | Builds a binary JSON object out of a text array. The array must have either
1259−-- exactly one dimension with an even number of members, in which case they are
1260−-- taken as alternating key/value pairs, or two dimensions such that each inner
1261−-- array has exactly two elements, which are taken as a key/value pair.
1263− :: PGArrayOf "jsonbObject" arr ('NotNull 'PGtext)
1264− => Expression grp commons schemas params from (nullity arr)
1265− -> Expression grp commons schemas params from (nullity 'PGjsonb)
1266−jsonbObject = unsafeFunction "jsonb_object"
1268−-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1269−-- keys and one for values, that are zipped pairwise to create a JSON object.
1271− :: ( PGArrayOf "jsonZipObject" keysArray ('NotNull 'PGtext)
1272− , PGArrayOf "jsonZipObject" valuesArray ('NotNull 'PGtext))
1273− => Expression grp commons schemas params from (nullity keysArray)
1274− -> Expression grp commons schemas params from (nullity valuesArray)
1275− -> Expression grp commons schemas params from (nullity 'PGjson)
1276−jsonZipObject ks vs =
1277− unsafeVariadicFunction "json_object" (ks :* vs :* Nil)
1279−-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1280−-- keys and one for values, that are zipped pairwise to create a binary JSON
1283− :: ( PGArrayOf "jsonbZipObject" keysArray ('NotNull 'PGtext)
1284− , PGArrayOf "jsonbZipObject" valuesArray ('NotNull 'PGtext))
1285− => Expression grp commons schemas params from (nullity keysArray)
1286− -> Expression grp commons schemas params from (nullity valuesArray)
1287− -> Expression grp commons schemas params from (nullity 'PGjsonb)
1288−jsonbZipObject ks vs =
1289− unsafeVariadicFunction "jsonb_object" (ks :* vs :* Nil)
1291−{-----------------------------------------
1292−Table 9.46: JSON processing functions
1293−-----------------------------------------}
1295−-- | Returns the number of elements in the outermost JSON array.
1297− :: Expression grp commons schemas params from (nullity 'PGjson)
1298− -> Expression grp commons schemas params from (nullity 'PGint4)
1299−jsonArrayLength = unsafeFunction "json_array_length"
1301−-- | Returns the number of elements in the outermost binary JSON array.
1303− :: Expression grp commons schemas params from (nullity 'PGjsonb)
1304− -> Expression grp commons schemas params from (nullity 'PGint4)
1305−jsonbArrayLength = unsafeFunction "jsonb_array_length"
1307−-- | Returns JSON value pointed to by the given path (equivalent to #>
1311− => Expression grp commons schemas params from (nullity 'PGjson)
1312− -> NP (Expression grp commons schemas params from) elems
1313− -> Expression grp commons schemas params from (nullity 'PGjsonb)
1314−jsonExtractPath x xs =
1315− unsafeVariadicFunction "json_extract_path" (x :* xs)
1317−-- | Returns JSON value pointed to by the given path (equivalent to #>
1321− => Expression grp commons schemas params from (nullity 'PGjsonb)
1322− -> NP (Expression grp commons schemas params from) elems
1323− -> Expression grp commons schemas params from (nullity 'PGjsonb)
1324−jsonbExtractPath x xs =
1325− unsafeVariadicFunction "jsonb_extract_path" (x :* xs)
1327−-- | Returns JSON value pointed to by the given path (equivalent to #>
1328−-- operator), as text.
1329−jsonExtractPathAsText
1331− => Expression grp commons schemas params from (nullity 'PGjson)
1332− -> NP (Expression grp commons schemas params from) elems
1333− -> Expression grp commons schemas params from (nullity 'PGjson)
1334−jsonExtractPathAsText x xs =
1335− unsafeVariadicFunction "json_extract_path_text" (x :* xs)
1337−-- | Returns JSON value pointed to by the given path (equivalent to #>
1338−-- operator), as text.
1339−jsonbExtractPathAsText
1341− => Expression grp commons schemas params from (nullity 'PGjsonb)
1342− -> NP (Expression grp commons schemas params from) elems
1343− -> Expression grp commons schemas params from (nullity 'PGjsonb)
1344−jsonbExtractPathAsText x xs =
1345− unsafeVariadicFunction "jsonb_extract_path_text" (x :* xs)
1347−-- | Returns the type of the outermost JSON value as a text string. Possible
1348−-- types are object, array, string, number, boolean, and null.
1350− :: Expression grp commons schemas params from (nullity 'PGjson)
1351− -> Expression grp commons schemas params from (nullity 'PGtext)
1352−jsonTypeof = unsafeFunction "json_typeof"
1354−-- | Returns the type of the outermost binary JSON value as a text string.
1355−-- Possible types are object, array, string, number, boolean, and null.
1357− :: Expression grp commons schemas params from (nullity 'PGjsonb)
1358− -> Expression grp commons schemas params from (nullity 'PGtext)
1359−jsonbTypeof = unsafeFunction "jsonb_typeof"
1361−-- | Returns its argument with all object fields that have null values omitted.
1362−-- Other null values are untouched.
1364− :: Expression grp commons schemas params from (nullity 'PGjson)
1365− -> Expression grp commons schemas params from (nullity 'PGjson)
1366−jsonStripNulls = unsafeFunction "json_strip_nulls"
1368−-- | Returns its argument with all object fields that have null values omitted.
1369−-- Other null values are untouched.
1371− :: Expression grp commons schemas params from (nullity 'PGjsonb)
1372− -> Expression grp commons schemas params from (nullity 'PGjsonb)
1373−jsonbStripNulls = unsafeFunction "jsonb_strip_nulls"
1375−-- | @ jsonbSet target path new_value create_missing @
1377−-- Returns target with the section designated by path replaced by new_value,
1378−-- or with new_value added if create_missing is true ( default is true) and the
1379−-- item designated by path does not exist. As with the path orientated
1380−-- operators, negative integers that appear in path count from the end of JSON
1383− :: PGTextArray "jsonbSet" arr
1384− => Expression grp commons schemas params from (nullity 'PGjsonb)
1385− -> Expression grp commons schemas params from (nullity arr)
1386− -> Expression grp commons schemas params from (nullity 'PGjsonb)
1387− -> Maybe (Expression grp commons schemas params from (nullity 'PGbool))
1388− -> Expression grp commons schemas params from (nullity 'PGjsonb)
1389−jsonbSet tgt path val createMissing = case createMissing of
1390− Just m -> unsafeVariadicFunction "jsonb_set" (tgt :* path :* val :* m :* Nil)
1391− Nothing -> unsafeVariadicFunction "jsonb_set" (tgt :* path :* val :* Nil)
1393−-- | @ jsonbInsert target path new_value insert_after @
1395−-- Returns target with new_value inserted. If target section designated by
1396−-- path is in a JSONB array, new_value will be inserted before target or after
1397−-- if insert_after is true (default is false). If target section designated by
1398−-- path is in JSONB object, new_value will be inserted only if target does not
1399−-- exist. As with the path orientated operators, negative integers that appear
1400−-- in path count from the end of JSON arrays.
1402− :: PGTextArray "jsonbInsert" arr
1403− => Expression grp commons schemas params from (nullity 'PGjsonb)
1404− -> Expression grp commons schemas params from (nullity arr)
1405− -> Expression grp commons schemas params from (nullity 'PGjsonb)
1406− -> Maybe (Expression grp commons schemas params from (nullity 'PGbool))
1407− -> Expression grp commons schemas params from (nullity 'PGjsonb)
1408−jsonbInsert tgt path val insertAfter = case insertAfter of
1409− Just i -> unsafeVariadicFunction "jsonb_insert" (tgt :* path :* val :* i :* Nil)
1410− Nothing -> unsafeVariadicFunction "jsonb_insert" (tgt :* path :* val :* Nil)
1412−-- | Returns its argument as indented JSON text.
1414− :: Expression grp commons schemas params from (nullity 'PGjsonb)
1415− -> Expression grp commons schemas params from (nullity 'PGtext)
1416−jsonbPretty = unsafeFunction "jsonb_pretty"
1418−{-----------------------------------------
1420−-----------------------------------------}
1422−class Aggregate expr1 expr2 aggr
1423− | aggr -> expr1, aggr -> expr2 where
1425− -- | A special aggregation that does not require an input
1429− -- expression :: Expression (Grouped bys) commons schemas params from ('NotNull 'PGint8)
1430− -- expression = countStar
1431− -- in printSQL expression
1434− countStar :: aggr ('NotNull 'PGint8)
1438− -- expression :: Expression (Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity ty]] ('NotNull 'PGint8)
1439− -- expression = count (All #col)
1440− -- in printSQL expression
1442− -- count(ALL "col")
1446− -> aggr ('NotNull 'PGint8)
1450− -- expression :: Expression ('Grouped bys) commons schemas params '[tab ::: '["col" ::: 'Null 'PGnumeric]] ('Null 'PGnumeric)
1451− -- expression = sum_ (Distinct #col)
1452− -- in printSQL expression
1454− -- sum(DISTINCT "col")
1457− => expr1 (nullity ty)
1458− -> aggr (nullity ty)
1460− -- | input values, including nulls, concatenated into an array
1463− -> aggr ('NotNull ('PGvararray ty))
1467− -- expression :: Expression ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity 'PGint4]] (nullity 'PGint4)
1468− -- expression = bitAnd (Distinct #col)
1469− -- in printSQL expression
1471− -- bit_and(DISTINCT "col")
1473− :: int `In` PGIntegral
1474− => expr1 (nullity int)
1475− -- ^ what to aggregate
1476− -> aggr (nullity int)
1480− -- expression :: Expression ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity 'PGint4]] (nullity 'PGint4)
1481− -- expression = bitOr (All #col)
1482− -- in printSQL expression
1484− -- bit_or(ALL "col")
1486− :: int `In` PGIntegral
1487− => expr1 (nullity int)
1488− -- ^ what to aggregate
1489− -> aggr (nullity int)
1493− -- winFun :: WindowFunction 'Ungrouped commons schemas params '[tab ::: '["col" ::: nullity 'PGbool]] (nullity 'PGbool)
1494− -- winFun = boolAnd #col
1495− -- in printSQL winFun
1499− :: expr1 (nullity 'PGbool)
1500− -- ^ what to aggregate
1501− -> aggr (nullity 'PGbool)
1505− -- expression :: Expression (Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity 'PGbool]] (nullity 'PGbool)
1506− -- expression = boolOr (All #col)
1507− -- in printSQL expression
1509− -- bool_or(ALL "col")
1511− :: expr1(nullity 'PGbool)
1512− -- ^ what to aggregate
1513− -> aggr (nullity 'PGbool)
1515− -- | synonym for `boolAnd`
1519− -- expression :: Expression ('Grouped bys) commons schemas params '[tab ::: '["col" ::: nullity 'PGbool]] (nullity 'PGbool)
1520− -- expression = every (Distinct #col)
1521− -- in printSQL expression
1523− -- every(DISTINCT "col")
1525− :: expr1 (nullity 'PGbool)
1526− -- ^ what to aggregate
1527− -> aggr (nullity 'PGbool)
1529− -- | maximum value of expression across all input values
1531− :: expr1 (nullity ty)
1532− -- ^ what to maximize
1533− -> aggr (nullity ty)
1535− -- | minimum value of expression across all input values
1537− :: expr1 (nullity ty)
1538− -- ^ what to minimize
1539− -> aggr (nullity ty)
1541− -- | average aggregation
1543− :: expr1 (nullity ty)
1544− -- ^ what to average
1545− -> aggr (nullity (PGAvg ty))
1547− {- | correlation coefficient
1550− expression :: Expression ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1551− expression = corr (All (#y :*: #x))
1552− in printSQL expression
1557− :: expr2 (nullity 'PGfloat8)
1558− -> aggr (nullity 'PGfloat8)
1560− {- | population covariance
1563− expression :: Expression ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1564− expression = covarPop (All (#y :*: #x))
1565− in printSQL expression
1567− covar_pop(ALL "y", "x")
1570− :: expr2 (nullity 'PGfloat8)
1571− -> aggr (nullity 'PGfloat8)
1573− {- | sample covariance
1576− winFun :: WindowFunction 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1577− winFun = covarSamp (#y :*: #x)
1580− covar_samp("y", "x")
1583− :: expr2 (nullity 'PGfloat8)
1584− -> aggr (nullity 'PGfloat8)
1586− {- | average of the independent variable (sum(X)/N)
1589− expression :: Expression ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1590− expression = regrAvgX (All (#y :*: #x))
1591− in printSQL expression
1593− regr_avgx(ALL "y", "x")
1596− :: expr2 (nullity 'PGfloat8)
1597− -> aggr (nullity 'PGfloat8)
1599− {- | average of the dependent variable (sum(Y)/N)
1602− winFun :: WindowFunction 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1603− winFun = regrAvgY (#y :*: #x)
1606− regr_avgy("y", "x")
1609− :: expr2 (nullity 'PGfloat8)
1610− -> aggr (nullity 'PGfloat8)
1612− {- | number of input rows in which both expressions are nonnull
1615− winFun :: WindowFunction 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGint8)
1616− winFun = regrCount (#y :*: #x)
1619− regr_count("y", "x")
1622− :: expr2 (nullity 'PGfloat8)
1623− -> aggr (nullity 'PGint8)
1625− {- | y-intercept of the least-squares-fit linear equation determined by the (X, Y) pairs
1628− expression :: Expression ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('NotNull 'PGfloat8)
1629− expression = regrIntercept (All (#y :*: #x))
1630− in printSQL expression
1632− regr_intercept(ALL "y", "x")
1635− :: expr2 (nullity 'PGfloat8)
1636− -> aggr (nullity 'PGfloat8)
1638− -- | @regr_r2(Y, X)@, square of the correlation coefficient
1640− :: expr2 (nullity 'PGfloat8)
1641− -> aggr (nullity 'PGfloat8)
1643− -- | @regr_slope(Y, X)@, slope of the least-squares-fit linear equation
1644− -- determined by the (X, Y) pairs
1646− :: expr2 (nullity 'PGfloat8)
1647− -> aggr (nullity 'PGfloat8)
1649− -- | @regr_sxx(Y, X)@, sum(X^2) - sum(X)^2/N
1650− -- (“sum of squares” of the independent variable)
1652− :: expr2 (nullity 'PGfloat8)
1653− -> aggr (nullity 'PGfloat8)
1655− -- | @regr_sxy(Y, X)@, sum(X*Y) - sum(X) * sum(Y)/N
1656− -- (“sum of products” of independent times dependent variable)
1658− :: expr2 (nullity 'PGfloat8)
1659− -> aggr (nullity 'PGfloat8)
1661− -- | @regr_syy(Y, X)@, sum(Y^2) - sum(Y)^2/N
1662− -- (“sum of squares” of the dependent variable)
1664− :: expr2 (nullity 'PGfloat8)
1665− -> aggr (nullity 'PGfloat8)
1667− -- | historical alias for `stddevSamp`
1669− :: expr1 (nullity ty)
1670− -> aggr (nullity (PGAvg ty))
1672− -- | population standard deviation of the input values
1674− :: expr1 (nullity ty)
1675− -> aggr (nullity (PGAvg ty))
1677− -- | sample standard deviation of the input values
1679− :: expr1 (nullity ty)
1680− -> aggr (nullity (PGAvg ty))
1682− -- | historical alias for `varSamp`
1684− :: expr1 (nullity ty)
1685− -> aggr (nullity (PGAvg ty))
1687− -- | population variance of the input values
1688− -- (square of the population standard deviation)
1690− :: expr1 (nullity ty)
1691− -> aggr (nullity (PGAvg ty))
1693− -- | sample variance of the input values
1694− -- (square of the sample standard deviation)
1696− :: expr1 (nullity ty)
1697− -> aggr (nullity (PGAvg ty))
1699−data Distinction expr ty
1701− | Distinct (expr ty)
1702− deriving (GHC.Generic,Show,Eq,Ord)
1703−instance NFData (Distinction (Expression grp commons schemas params from) ty)
1704−instance RenderSQL (Distinction (Expression grp commons schemas params from) ty) where
1706− All x -> "ALL" <+> renderSQL x
1707− Distinct x -> "DISTINCT" <+> renderSQL x
1710− ( Expression grp commons schemas params from
1712− Expression grp commons schemas params from) xty ) where
1715− "ALL" <+> renderSQL x <> ", " <> renderSQL x'
1716− Distinct (x :*: x') ->
1717− "DISTINCT" <+> renderSQL x <> ", " <> renderSQL x'
1720− (Distinction (Expression 'Ungrouped commons schemas params from))
1721− (Distinction (Expression 'Ungrouped commons schemas params from :*: Expression 'Ungrouped commons schemas params from))
1722− (Expression ('Grouped bys) commons schemas params from) where
1723− countStar = UnsafeExpression "count(*)"
1724− count = unsafeAggregate1 "count"
1725− sum_ = unsafeAggregate1 "sum"
1726− arrayAgg = unsafeAggregate1 "array_agg"
1727− bitAnd = unsafeAggregate1 "bit_and"
1728− bitOr = unsafeAggregate1 "bit_or"
1729− boolAnd = unsafeAggregate1 "bool_and"
1730− boolOr = unsafeAggregate1 "bool_or"
1731− every = unsafeAggregate1 "every"
1732− max_ = unsafeAggregate1 "max"
1733− min_ = unsafeAggregate1 "min"
1734− avg = unsafeAggregate1 "avg"
1735− corr = unsafeAggregate2 "corr"
1736− covarPop = unsafeAggregate2 "covar_pop"
1737− covarSamp = unsafeAggregate2 "covar_samp"
1738− regrAvgX = unsafeAggregate2 "regr_avgx"
1739− regrAvgY = unsafeAggregate2 "regr_avgy"
1740− regrCount = unsafeAggregate2 "regr_count"
1741− regrIntercept = unsafeAggregate2 "regr_intercept"
1742− regrR2 = unsafeAggregate2 "regr_r2"
1743− regrSlope = unsafeAggregate2 "regr_slope"
1744− regrSxx = unsafeAggregate2 "regr_sxx"
1745− regrSxy = unsafeAggregate2 "regr_sxy"
1746− regrSyy = unsafeAggregate2 "regr_syy"
1747− stddev = unsafeAggregate1 "stddev"
1748− stddevPop = unsafeAggregate1 "stddev_pop"
1749− stddevSamp = unsafeAggregate1 "stddev_samp"
1750− variance = unsafeAggregate1 "variance"
1751− varPop = unsafeAggregate1 "var_pop"
1752− varSamp = unsafeAggregate1 "var_samp"
1754− (Expression grp commons schemas params from)
1755− (Expression grp commons schemas params from :*: Expression grp commons schemas params from)
1756− (WindowFunction grp commons schemas params from) where
1757− countStar = UnsafeWindowFunction "count(*)"
1758− count = unsafeWindowFunction1 "count"
1759− sum_ = unsafeWindowFunction1 "sum"
1760− arrayAgg = unsafeWindowFunction1 "array_agg"
1761− bitAnd = unsafeWindowFunction1 "bit_and"
1762− bitOr = unsafeWindowFunction1 "bit_or"
1763− boolAnd = unsafeWindowFunction1 "bool_and"
1764− boolOr = unsafeWindowFunction1 "bool_or"
1765− every = unsafeWindowFunction1 "every"
1766− max_ = unsafeWindowFunction1 "max"
1767− min_ = unsafeWindowFunction1 "min"
1768− avg = unsafeWindowFunction1 "avg"
1769− corr = unsafeWindowFunction2 "corr"
1770− covarPop = unsafeWindowFunction2 "covar_pop"
1771− covarSamp = unsafeWindowFunction2 "covar_samp"
1772− regrAvgX = unsafeWindowFunction2 "regr_avgx"
1773− regrAvgY = unsafeWindowFunction2 "regr_avgy"
1774− regrCount = unsafeWindowFunction2 "regr_count"
1775− regrIntercept = unsafeWindowFunction2 "regr_intercept"
1776− regrR2 = unsafeWindowFunction2 "regr_r2"
1777− regrSlope = unsafeWindowFunction2 "regr_slope"
1778− regrSxx = unsafeWindowFunction2 "regr_sxx"
1779− regrSxy = unsafeWindowFunction2 "regr_sxy"
1780− regrSyy = unsafeWindowFunction2 "regr_syy"
1781− stddev = unsafeWindowFunction1 "stddev"
1782− stddevPop = unsafeWindowFunction1 "stddev_pop"
1783− stddevSamp = unsafeWindowFunction1 "stddev_samp"
1784− variance = unsafeWindowFunction1 "variance"
1785− varPop = unsafeWindowFunction1 "var_pop"
1786− varSamp = unsafeWindowFunction1 "var_samp"
1788−-- | escape hatch to define aggregate functions
1790− :: ByteString -- ^ aggregate function
1791− -> Distinction (Expression 'Ungrouped commons schemas params from) xty
1792− -> Expression ('Grouped bys) commons schemas params from yty
1793−unsafeAggregate1 fun x = UnsafeExpression $ mconcat
1794− [fun, "(", renderSQL x, ")"]
1796−-- | escape hatch to define aggregate binary functions
1798− :: ByteString -- ^ aggregate function
1799− -> Distinction (Expression 'Ungrouped commons schemas params from :*: Expression 'Ungrouped commons schemas params from) xty
1800− -> Expression ('Grouped bys) commons schemas params from yty
1801−unsafeAggregate2 fun xx = UnsafeExpression $ mconcat
1802− [fun, "(", renderSQL xx, ")"]
1804−-- | A type family that calculates `PGAvg` type of a `PGType`.
1805−type family PGAvg ty where
1806− PGAvg 'PGint2 = 'PGnumeric
1807− PGAvg 'PGint4 = 'PGnumeric
1808− PGAvg 'PGint8 = 'PGnumeric
1809− PGAvg 'PGnumeric = 'PGnumeric
1810− PGAvg 'PGfloat4 = 'PGfloat8
1811− PGAvg 'PGfloat8 = 'PGfloat8
1812− PGAvg 'PGinterval = 'PGinterval
1813− PGAvg pg = TypeError
1814− ('Text "Squeal type error: No average for " ':<>: 'ShowType pg)
1816−{-----------------------------------------
1818−-----------------------------------------}
1820−-- | `TypeExpression`s are used in `cast`s and `createTable` commands.
1821−newtype TypeExpression (schemas :: SchemasType) (ty :: NullityType)
1822− = UnsafeTypeExpression { renderTypeExpression :: ByteString }
1823− deriving (GHC.Generic,Show,Eq,Ord,NFData)
1824−instance RenderSQL (TypeExpression schemas ty) where
1825− renderSQL = renderTypeExpression
1827−-- | The enum or composite type in a `Typedef` can be expressed by its alias.
1829− :: (Has sch schemas schema, Has td schema ('Typedef ty))
1830− => QualifiedAlias sch td
1831− -> TypeExpression schemas (nullity ty)
1832−typedef = UnsafeTypeExpression . renderSQL
1834−-- | The composite type corresponding to a `Table` definition can be expressed
1837− :: (Has sch schemas schema, Has tab schema ('Table table))
1838− => QualifiedAlias sch tab
1839− -> TypeExpression schemas (nullity ('PGcomposite (TableToRow table)))
1840−typetable = UnsafeTypeExpression . renderSQL
1842−-- | The composite type corresponding to a `View` definition can be expressed
1845− :: (Has sch schemas schema, Has vw schema ('View view))
1846− => QualifiedAlias sch vw
1847− -> TypeExpression schemas (nullity ('PGcomposite view))
1848−typeview = UnsafeTypeExpression . renderSQL
1850−-- | logical Boolean (true/false)
1851−bool :: TypeExpression schemas (nullity 'PGbool)
1852−bool = UnsafeTypeExpression "bool"
1853−-- | signed two-byte integer
1854−int2, smallint :: TypeExpression schemas (nullity 'PGint2)
1855−int2 = UnsafeTypeExpression "int2"
1856−smallint = UnsafeTypeExpression "smallint"
1857−-- | signed four-byte integer
1858−int4, int, integer :: TypeExpression schemas (nullity 'PGint4)
1859−int4 = UnsafeTypeExpression "int4"
1860−int = UnsafeTypeExpression "int"
1861−integer = UnsafeTypeExpression "integer"
1862−-- | signed eight-byte integer
1863−int8, bigint :: TypeExpression schemas (nullity 'PGint8)
1864−int8 = UnsafeTypeExpression "int8"
1865−bigint = UnsafeTypeExpression "bigint"
1866−-- | arbitrary precision numeric type
1867−numeric :: TypeExpression schemas (nullity 'PGnumeric)
1868−numeric = UnsafeTypeExpression "numeric"
1869−-- | single precision floating-point number (4 bytes)
1870−float4, real :: TypeExpression schemas (nullity 'PGfloat4)
1871−float4 = UnsafeTypeExpression "float4"
1872−real = UnsafeTypeExpression "real"
1873−-- | double precision floating-point number (8 bytes)
1874−float8, doublePrecision :: TypeExpression schemas (nullity 'PGfloat8)
1875−float8 = UnsafeTypeExpression "float8"
1876−doublePrecision = UnsafeTypeExpression "double precision"
1877−-- | variable-length character string
1878−text :: TypeExpression schemas (nullity 'PGtext)
1879−text = UnsafeTypeExpression "text"
1880−-- | fixed-length character string
1882− :: forall n schemas nullity. (KnownNat n, 1 <= n)
1883− => TypeExpression schemas (nullity ('PGchar n))
1884−char = UnsafeTypeExpression $ "char(" <> renderNat @n <> ")"
1885−character = UnsafeTypeExpression $ "character(" <> renderNat @n <> ")"
1886−-- | variable-length character string
1887−varchar, characterVarying
1888− :: forall n schemas nullity. (KnownNat n, 1 <= n)
1889− => TypeExpression schemas (nullity ('PGvarchar n))
1890−varchar = UnsafeTypeExpression $ "varchar(" <> renderNat @n <> ")"
1891−characterVarying = UnsafeTypeExpression $
1892− "character varying(" <> renderNat @n <> ")"
1893−-- | binary data ("byte array")
1894−bytea :: TypeExpression schemas (nullity 'PGbytea)
1895−bytea = UnsafeTypeExpression "bytea"
1896−-- | date and time (no time zone)
1897−timestamp :: TypeExpression schemas (nullity 'PGtimestamp)
1898−timestamp = UnsafeTypeExpression "timestamp"
1899−-- | date and time, including time zone
1900−timestampWithTimeZone :: TypeExpression schemas (nullity 'PGtimestamptz)
1901−timestampWithTimeZone = UnsafeTypeExpression "timestamp with time zone"
1902−-- | calendar date (year, month, day)
1903−date :: TypeExpression schemas (nullity 'PGdate)
1904−date = UnsafeTypeExpression "date"
1905−-- | time of day (no time zone)
1906−time :: TypeExpression schemas (nullity 'PGtime)
1907−time = UnsafeTypeExpression "time"
1908−-- | time of day, including time zone
1909−timeWithTimeZone :: TypeExpression schemas (nullity 'PGtimetz)
1910−timeWithTimeZone = UnsafeTypeExpression "time with time zone"
1912−interval :: TypeExpression schemas (nullity 'PGinterval)
1913−interval = UnsafeTypeExpression "interval"
1914−-- | universally unique identifier
1915−uuid :: TypeExpression schemas (nullity 'PGuuid)
1916−uuid = UnsafeTypeExpression "uuid"
1917−-- | IPv4 or IPv6 host address
1918−inet :: TypeExpression schemas (nullity 'PGinet)
1919−inet = UnsafeTypeExpression "inet"
1920−-- | textual JSON data
1921−json :: TypeExpression schemas (nullity 'PGjson)
1922−json = UnsafeTypeExpression "json"
1923−-- | binary JSON data, decomposed
1924−jsonb :: TypeExpression schemas (nullity 'PGjsonb)
1925−jsonb = UnsafeTypeExpression "jsonb"
1926−-- | variable length array
1928− :: TypeExpression schemas pg
1929− -> TypeExpression schemas (nullity ('PGvararray pg))
1930−vararray ty = UnsafeTypeExpression $ renderSQL ty <> "[]"
1931−-- | fixed length array
1933−-- >>> renderSQL (fixarray @'[2] json)
1936− :: forall dims schemas nullity pg. All KnownNat dims
1937− => TypeExpression schemas pg
1938− -> TypeExpression schemas (nullity ('PGfixarray dims pg))
1939−fixarray ty = UnsafeTypeExpression $
1940− renderSQL ty <> renderDims @dims
1942− renderDims :: forall ns. All KnownNat ns => ByteString
1946− . ByteString.intercalate "]["
1948− $ hcmap (Proxy @KnownNat)
1949− (K . fromString . show . natVal)
1950− (hpure Proxy :: NP Proxy ns)
1952−-- | `pgtype` is a demoted version of a `PGType`
1953−class PGTyped schemas (ty :: NullityType) where
1954− pgtype :: TypeExpression schemas ty
1955−instance PGTyped schemas (nullity 'PGbool) where pgtype = bool
1956−instance PGTyped schemas (nullity 'PGint2) where pgtype = int2
1957−instance PGTyped schemas (nullity 'PGint4) where pgtype = int4
1958−instance PGTyped schemas (nullity 'PGint8) where pgtype = int8
1959−instance PGTyped schemas (nullity 'PGnumeric) where pgtype = numeric
1960−instance PGTyped schemas (nullity 'PGfloat4) where pgtype = float4
1961−instance PGTyped schemas (nullity 'PGfloat8) where pgtype = float8
1962−instance PGTyped schemas (nullity 'PGtext) where pgtype = text
1963−instance (KnownNat n, 1 <= n)
1964− => PGTyped schemas (nullity ('PGchar n)) where pgtype = char @n
1965−instance (KnownNat n, 1 <= n)
1966− => PGTyped schemas (nullity ('PGvarchar n)) where pgtype = varchar @n
1967−instance PGTyped schemas (nullity 'PGbytea) where pgtype = bytea
1968−instance PGTyped schemas (nullity 'PGtimestamp) where pgtype = timestamp
1969−instance PGTyped schemas (nullity 'PGtimestamptz) where pgtype = timestampWithTimeZone
1970−instance PGTyped schemas (nullity 'PGdate) where pgtype = date
1971−instance PGTyped schemas (nullity 'PGtime) where pgtype = time
1972−instance PGTyped schemas (nullity 'PGtimetz) where pgtype = timeWithTimeZone
1973−instance PGTyped schemas (nullity 'PGinterval) where pgtype = interval
1974−instance PGTyped schemas (nullity 'PGuuid) where pgtype = uuid
1975−instance PGTyped schemas (nullity 'PGjson) where pgtype = json
1976−instance PGTyped schemas (nullity 'PGjsonb) where pgtype = jsonb
1977−instance PGTyped schemas ty
1978− => PGTyped schemas (nullity ('PGvararray ty)) where
1979− pgtype = vararray (pgtype @schemas @ty)
1980−instance (All KnownNat dims, PGTyped schemas ty)
1981− => PGTyped schemas (nullity ('PGfixarray dims ty)) where
1982− pgtype = fixarray @dims (pgtype @schemas @ty)
1984−{-----------------------------------------
1986−-----------------------------------------}
1988−-- | `SortExpression`s are used by `sortBy` to optionally sort the results
1989−-- of a `Query`. `Asc` or `Desc` set the sort direction of a `NotNull` result
1990−-- column to ascending or descending. Ascending order puts smaller values
1991−-- first, where "smaller" is defined in terms of the `.<` operator. Similarly,
1992−-- descending order is determined with the `.>` operator. `AscNullsFirst`,
1993−-- `AscNullsLast`, `DescNullsFirst` and `DescNullsLast` options are used to
1994−-- determine whether nulls appear before or after non-null values in the sort
1995−-- ordering of a `Null` result column.
1996−data SortExpression grp commons schemas params from where
1998− :: Expression grp commons schemas params from ('NotNull ty)
1999− -> SortExpression grp commons schemas params from
2001− :: Expression grp commons schemas params from ('NotNull ty)
2002− -> SortExpression grp commons schemas params from
2004− :: Expression grp commons schemas params from ('Null ty)
2005− -> SortExpression grp commons schemas params from
2007− :: Expression grp commons schemas params from ('Null ty)
2008− -> SortExpression grp commons schemas params from
2010− :: Expression grp commons schemas params from ('Null ty)
2011− -> SortExpression grp commons schemas params from
2013− :: Expression grp commons schemas params from ('Null ty)
2014− -> SortExpression grp commons schemas params from
2015−deriving instance Show (SortExpression grp commons schemas params from)
2017−class OrderBy expr where
2019− :: [SortExpression grp commons schemas params from]
2020− -> expr grp commons schemas params from
2021− -> expr grp commons schemas params from
2023−-- | Render a `SortExpression`.
2024−instance RenderSQL (SortExpression grp commons schemas params from) where
2026− Asc expression -> renderSQL expression <+> "ASC"
2027− Desc expression -> renderSQL expression <+> "DESC"
2028− AscNullsFirst expression -> renderSQL expression
2029− <+> "ASC NULLS FIRST"
2030− DescNullsFirst expression -> renderSQL expression
2031− <+> "DESC NULLS FIRST"
2032− AscNullsLast expression -> renderSQL expression <+> "ASC NULLS LAST"
2033− DescNullsLast expression -> renderSQL expression <+> "DESC NULLS LAST"
2035−data WindowDefinition grp commons schemas params from where
2038− => NP (Expression grp commons schemas params from) bys
2039− -> [SortExpression grp commons schemas params from]
2040− -> WindowDefinition grp commons schemas params from
2042−instance OrderBy WindowDefinition where
2043− orderBy sortsR (WindowDefinition parts sortsL)
2044− = WindowDefinition parts (sortsL ++ sortsR)
2046−instance RenderSQL (WindowDefinition commons schemas from grp params) where
2047− renderSQL (WindowDefinition part ord) =
2048− renderPartitionByClause part <> renderOrderByClause ord
2050− renderPartitionByClause = \case
2052− parts -> "PARTITION" <+> "BY" <+> renderCommaSeparated renderExpression parts
2053− renderOrderByClause = \case
2055− srts -> " ORDER" <+> "BY"
2056− <+> commaSeparated (renderSQL <$> srts)
2060− => NP (Expression grp commons schemas params from) bys
2061− -> WindowDefinition grp commons schemas params from
2062−partitionBy bys = WindowDefinition bys []
2064−newtype WindowFunction
2066− (commons :: FromType)
2067− (schemas :: SchemasType)
2068− (params :: [NullityType])
2070− (ty :: NullityType)
2071− = UnsafeWindowFunction { renderWindowFunction :: ByteString }
2072− deriving (GHC.Generic,Show,Eq,Ord,NFData)
2074−instance RenderSQL (WindowFunction grp commons schemas params from ty) where
2075− renderSQL = renderWindowFunction
2077−unsafeWindowFunction1
2079− -> Expression grp commons schemas params from ty0
2080− -> WindowFunction grp commons schemas params from ty1
2081−unsafeWindowFunction1 fun x
2082− = UnsafeWindowFunction $ fun <> parenthesized (renderSQL x)
2084−unsafeWindowFunction2
2086− -> (Expression grp commons schemas params from :*: Expression grp commons schemas params from) ty0
2087− -> WindowFunction grp commons schemas params from ty1
2088−unsafeWindowFunction2 fun (x :*: x')
2089− = UnsafeWindowFunction $ fun <> parenthesized (renderSQL x <> ", " <> renderSQL x')
2091−{- | rank of the current row with gaps; same as `rowNumber` of its first peer
2095−rank :: WindowFunction grp commons schemas params from ('NotNull 'PGint8)
2096−rank = UnsafeWindowFunction "rank()"
2098−{- | number of the current row within its partition, counting from 1
2099−>>> printSQL rowNumber
2102−rowNumber :: WindowFunction grp commons schemas params from ('NotNull 'PGint8)
2103−rowNumber = UnsafeWindowFunction "row_number()"
2105−{- | rank of the current row without gaps; this function counts peer groups
2106−>>> printSQL denseRank
2109−denseRank :: WindowFunction grp commons schemas params from ('NotNull 'PGint8)
2110−denseRank = UnsafeWindowFunction "dense_rank()"
2112−{- | relative rank of the current row: (rank - 1) / (total partition rows - 1)
2113−>>> printSQL percentRank
2116−percentRank :: WindowFunction grp commons schemas params from ('NotNull 'PGfloat8)
2117−percentRank = UnsafeWindowFunction "percent_rank()"
2119−{- | cumulative distribution: (number of partition rows
2120−preceding or peer with current row) / total partition rows
2121−>>> printSQL cumeDist
2124−cumeDist :: WindowFunction grp commons schemas params from ('NotNull 'PGfloat8)
2125−cumeDist = UnsafeWindowFunction "cume_dist()"
2127−{- | integer ranging from 1 to the argument value,
2128−dividing the partition as equally as possible
2131− :: Expression grp commons schemas params from ('NotNull 'PGint4)
2133− -> WindowFunction grp commons schemas params from ('NotNull 'PGint4)
2134−ntile = unsafeWindowFunction1 "ntile"
2136−{- | returns value evaluated at the row that is offset rows before the current
2137−row within the partition; if there is no such row, instead return default
2138−(which must be of the same type as value). Both offset and default are
2139−evaluated with respect to the current row.
2142− :: Expression grp commons schemas params from ty
2144− -> Expression grp commons schemas params from ('NotNull 'PGint4)
2146− -> Expression grp commons schemas params from ty
2148− -> WindowFunction grp commons schemas params from ty
2149−lag value offset def = UnsafeWindowFunction $ "lag"
2151− (commaSeparated ([renderSQL value, renderSQL offset, renderSQL def]))
2153−{- | returns value evaluated at the row that is offset rows after the current
2154−row within the partition; if there is no such row, instead return default
2155−(which must be of the same type as value). Both offset and default are
2156−evaluated with respect to the current row.
2159− :: Expression grp commons schemas params from ty
2161− -> Expression grp commons schemas params from ('NotNull 'PGint4)
2163− -> Expression grp commons schemas params from ty
2165− -> WindowFunction grp commons schemas params from ty
2166−lead value offset def = UnsafeWindowFunction $ "lag"
2168− (commaSeparated ([renderSQL value, renderSQL offset, renderSQL def]))
2170−{- | returns value evaluated at the row that is the
2171−first row of the window frame
2174− :: Expression grp commons schemas params from ty
2176− -> WindowFunction grp commons schemas params from ty
2177−firstValue = unsafeWindowFunction1 "first_value"
2179−{- | returns value evaluated at the row that is the
2180−last row of the window frame
2183− :: Expression grp commons schemas params from ty
2185− -> WindowFunction grp commons schemas params from ty
2186−lastValue = unsafeWindowFunction1 "last_value"
2188−{- | returns value evaluated at the row that is the nth
2189−row of the window frame (counting from 1); null if no such row
2192− :: Expression grp commons schemas params from (nullity ty)
2194− -> Expression grp commons schemas params from ('NotNull 'PGint4)
2196− -> WindowFunction grp commons schemas params from ('Null ty)
2197−nthValue value nth = UnsafeWindowFunction $ "nth_value"
2198− <> parenthesized (commaSeparated [renderSQL value, renderSQL nth])