@@ -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
@@ -15,13 +16,11 @@ Squeal expressions are the atoms used to build statements.
15 , FlexibleContexts
16 , FlexibleContexts
16 , FlexibleInstances
17 , FlexibleInstances
17 , FunctionalDependencies
18 , FunctionalDependencies
19 , GeneralizedNewtypeDeriving
19 , GeneralizedNewtypeDeriving
20 , LambdaCase
20 , LambdaCase
21 , MagicHash
21 , MagicHash
22 , OverloadedStrings
22 , OverloadedStrings
23 , ScopedTypeVariables
23 , ScopedTypeVariables
25 , TypeApplications
24 , TypeApplications
26 , TypeFamilies
25 , TypeFamilies
27 , TypeInType
26 , TypeInType
@@ -32,351 +31,505 @@ Squeal expressions are the atoms used to build statements.
33module Squeal.PostgreSQL.Expression
32module Squeal.PostgreSQL.Expression
34 ( -- * Expression
33 ( -- * Expression
35− Expression (..)
34+ Expression (UnsafeExpression, renderExpression)
36− , Expr
35+ , HasParameter (parameter)
37− , type (-->)
36+ , param
38− , FunctionDB
37+ -- ** Null
39− , unsafeFunction
38+ , null_
40− , function
39+ , notNull
41− , unsafeLeftOp
40+ , coalesce
42− , leftOp
41+ , fromNull
43− , unsafeRightOp
42+ , isNull
44− , rightOp
43+ , isNotNull
45− , Operator
44+ , matchNull
46− , OperatorDB
45+ , nullIf
47 , unsafeBinaryOp
50 , unsafeBinaryOp
48− , binaryOp
51+ , unsafeUnaryOp
49− , FunctionVar
52+ , unsafeFunction
50− , unsafeFunctionVar
53+ , unsafeVariadicFunction
51− , type (--->)
54+ , atan2_
52− , FunctionNDB
55+ , cast
53− , unsafeFunctionN
56+ , quot_
54− , functionN
57+ , rem_
55− , PGSubset (..)
58+ , trunc
56− , PGIntersect (..)
59+ , round_
89+ -- ** json or jsonb operators
99+ -- *** jsonb only operators
123+ , jsonEachAsComposite
124+ , jsonbEachAsComposite
128+ , unsafeAggregate, unsafeAggregateDistinct
130+ , PGAvg (avg, avgDistinct)
131+ , bitAnd, bitOr, boolAnd, boolOr
132+ , bitAndDistinct, bitOrDistinct, boolAndDistinct, boolOrDistinct
134+ , count, countDistinct
135+ , every, everyDistinct
136+ , max_, maxDistinct, min_, minDistinct
138+ , TypeExpression (UnsafeTypeExpression, renderTypeExpression)
160+ , timestampWithTimeZone
57 -- * Re-export
171 -- * Re-export
59− , K (..)
173+ , NP ((:*), Nil)
63import Control.Category
176import Control.Category
64import Control.DeepSeq
177import Control.DeepSeq
65import Data.ByteString (ByteString)
178import Data.ByteString (ByteString)
66import Data.Function ((&))
179import Data.Function ((&))
67−import Data.Semigroup hiding (All)
180+import Data.Semigroup
68import Data.String
182import Data.String
69−import Generics.SOP hiding (All, from)
183+import Generics.SOP hiding (from)
184+import GHC.Exts (Constraint)
70import GHC.OverloadedLabels
185import GHC.OverloadedLabels
71import GHC.TypeLits
186import GHC.TypeLits
73import Prelude hiding (id, (.))
187import Prelude hiding (id, (.))
75import qualified GHC.Generics as GHC
189import qualified GHC.Generics as GHC
77−import Squeal.PostgreSQL.Alias
78−import Squeal.PostgreSQL.List
79import Squeal.PostgreSQL.Render
191import Squeal.PostgreSQL.Render
80import Squeal.PostgreSQL.Schema
192import Squeal.PostgreSQL.Schema
83−-- >>> import Squeal.PostgreSQL
85{-----------------------------------------
194{-----------------------------------------
86column expressions
195column expressions
87-----------------------------------------}
196-----------------------------------------}
89{- | `Expression`s are used in a variety of contexts,
198{- | `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,
199+such as in the target list of the `Squeal.PostgreSQL.Query.select` command,
92as new column values in `Squeal.PostgreSQL.Manipulation.insertRow` or
200as new column values in `Squeal.PostgreSQL.Manipulation.insertRow` or
93`Squeal.PostgreSQL.Manipulation.update`,
201`Squeal.PostgreSQL.Manipulation.update`,
94−or in search `Squeal.PostgreSQL.Logic.Condition`s in a number of commands.
202+or in search `Condition`s in a number of commands.
96The expression syntax allows the calculation of
204The expression syntax allows the calculation of
97values from primitive expression using arithmetic, logical,
205values from primitive expression using arithmetic, logical,
98and other operations.
206and 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
208newtype Expression
115− (outer :: FromType)
209+ (schema :: SchemaType)
116− (commons :: FromType)
210+ (relations :: RelationsType)
117− (grp :: Grouping)
211+ (grouping :: Grouping)
118− (schemas :: SchemasType)
119 (params :: [NullityType])
212 (params :: [NullityType])
121 (ty :: NullityType)
213 (ty :: NullityType)
122 = UnsafeExpression { renderExpression :: ByteString }
214 = UnsafeExpression { renderExpression :: ByteString }
123 deriving (GHC.Generic,Show,Eq,Ord,NFData)
215 deriving (GHC.Generic,Show,Eq,Ord,NFData)
124−instance RenderSQL (Expression outer commons grp schemas params from ty) where
217+instance RenderSQL (Expression schema relations grouping params ty) where
125 renderSQL = renderExpression
218 renderSQL = renderExpression
127−-- | An `Expr` is a closed `Expression`.
220+{- | A `HasParameter` constraint is used to indicate a value that is
128−-- It is a F@RankNType@ but don't be scared.
221+supplied externally to a SQL statement.
129−-- Think of it as an expression which sees no
222+`Squeal.PostgreSQL.PQ.manipulateParams`,
130−-- namespaces, so you can't use parameters
223+`Squeal.PostgreSQL.PQ.queryParams` and
131−-- or alias references. It can be used as
224+`Squeal.PostgreSQL.PQ.traversePrepared` support specifying data values
132−-- a simple piece of more complex `Expression`s.
225+separately from the SQL command string, in which case `param`s are used to
133−type Expr x
226+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
228+class KnownNat n => HasParameter
200− = forall outer commons grp schemas params from
229+ (n :: Nat)
201− . [Expression outer commons grp schemas params from x0]
230+ (schema :: SchemaType)
202− -- ^ inputs
231+ (params :: [NullityType])
203− -> Expression outer commons grp schemas params from x1
232+ (ty :: NullityType)
204− -- ^ must have at least 1 input
233+ | n params -> ty where
205− -> Expression outer commons grp schemas params from y
234+ -- | `parameter` takes a `Nat` using type application and a `TypeExpression`.
207−
236+ -- >>> let expr = parameter @1 int4 :: Expression sch rels grp '[ 'Null 'PGint4] ('Null 'PGint4)
208−{- | >>> printSQL (unsafeFunctionVar "greatest" [true, null_] false)
237+ -- >>> printSQL expr
209−greatest(TRUE, NULL, FALSE)
238+ -- ($1 :: int4)
211−unsafeFunctionVar :: ByteString -> FunctionVar x0 x1 y
240+ :: TypeExpression schema (PGTypeOf ty)
241+ -> Expression schema relations grouping params ty
212−unsafeFunctionVar fun xs x = UnsafeExpression $ fun <> parenthesized
242+ parameter ty = UnsafeExpression $ parenthesized $
213− (commaSeparated (renderSQL <$> xs) <> ", " <> renderSQL x)
243+ "$" <> renderNat (Proxy @n) <+> "::"
214−
244+ <+> renderTypeExpression ty
215−instance (HasUnique tab (Join outer from) row, Has col row ty)
245+instance {-# OVERLAPPING #-} HasParameter 1 schema (ty1:tys) ty1
216− => IsLabel col (Expression outer commons 'Ungrouped schemas params from ty) where
246+instance {-# OVERLAPPABLE #-} (KnownNat n, HasParameter (n-1) schema params ty)
217− fromLabel = UnsafeExpression $ renderSQL (Alias @col)
247+ => HasParameter n schema (ty' : params) ty
218−instance (HasUnique tab (Join outer from) row, Has col row ty, tys ~ '[ty])
248+
219− => IsLabel col (NP (Expression outer commons 'Ungrouped schemas params from) tys) where
249+-- | `param` takes a `Nat` using type application and for basic types,
220− fromLabel = fromLabel @col :* Nil
250+-- infers a `TypeExpression`.
252+-- >>> let expr = param @1 :: Expression sch rels grp '[ 'Null 'PGint4] ('Null 'PGint4)
256+ :: forall n schema params relations grouping ty
257+ . (PGTyped schema (PGTypeOf ty), HasParameter n schema params ty)
258+ => Expression schema relations grouping params ty -- ^ param
259+param = parameter @n pgtype
221−instance (HasUnique tab (Join outer from) row, Has col row ty, column ~ (col ::: ty))
261+instance (HasUnique relation relations columns, Has column columns ty)
223− (Aliased (Expression outer commons 'Ungrouped schemas params from) column) where
262+ => IsLabel column (Expression schema relations 'Ungrouped params ty) where
224− fromLabel = fromLabel @col `As` Alias
263+ fromLabel = UnsafeExpression $ renderAlias (Alias @column)
225−instance (HasUnique tab (Join outer from) row, Has col row ty, columns ~ '[col ::: ty])
264+instance (HasUnique relation relations columns, Has column columns ty)
226− => IsLabel col
265+ => IsLabel column
227− (NP (Aliased (Expression outer commons 'Ungrouped schemas params from)) columns) where
266+ (Aliased (Expression schema relations 'Ungrouped params) (column ::: ty)) where
228− fromLabel = fromLabel @col :* Nil
267+ fromLabel = fromLabel @column `As` Alias @column
229−
268+instance (HasUnique relation relations columns, Has column columns ty)
230−instance (Has tab (Join outer from) row, Has col row ty)
269+ => IsLabel column
231− => IsQualified tab col (Expression outer commons 'Ungrouped schemas params from ty) where
270+ (NP (Aliased (Expression schema relations 'Ungrouped params)) '[column ::: ty]) where
232− tab ! col = UnsafeExpression $
271+ fromLabel = fromLabel @column :* Nil
233− renderSQL tab <> "." <> renderSQL col
272+
234−instance (Has tab (Join outer from) row, Has col row ty, tys ~ '[ty])
273+instance (Has relation relations columns, Has column columns ty)
235− => IsQualified tab col (NP (Expression outer commons 'Ungrouped schemas params from) tys) where
274+ => IsQualified relation column (Expression schema relations 'Ungrouped params ty) where
236− tab ! col = tab ! col :* Nil
275+ relation ! column = UnsafeExpression $
276+ renderAlias relation <> "." <> renderAlias column
237−instance (Has tab (Join outer from) row, Has col row ty, column ~ (col ::: ty))
277+instance (Has relation relations columns, Has column columns ty)
238− => IsQualified tab col
278+ => IsQualified relation column
239− (Aliased (Expression outer commons 'Ungrouped schemas params from) column) where
279+ (Aliased (Expression schema relations 'Ungrouped params) (column ::: ty)) where
240− tab ! col = tab ! col `As` col
280+ relation ! column = relation ! column `As` column
241−instance (Has tab (Join outer from) row, Has col row ty, columns ~ '[col ::: ty])
281+instance (Has relation relations columns, Has column columns ty)
242− => IsQualified tab col
282+ => IsQualified relation column
243− (NP (Aliased (Expression outer commons 'Ungrouped schemas params from)) columns) where
283+ (NP (Aliased (Expression schema relations 'Ungrouped params)) '[column ::: ty]) where
244− tab ! col = tab ! col :* Nil
284+ relation ! column = relation ! column :* Nil
247− ( HasUnique tab (Join outer from) row
287+ ( HasUnique relation relations columns
248− , Has col row ty
288+ , Has column columns ty
249− , GroupedBy tab col bys
289+ , GroupedBy relation column bys
250− ) => IsLabel col
290+ ) => IsLabel column
251− (Expression outer commons ('Grouped bys) schemas params from ty) where
291+ (Expression schema relations ('Grouped bys) params ty) where
252− fromLabel = UnsafeExpression $ renderSQL (Alias @col)
292+ fromLabel = UnsafeExpression $ renderAlias (Alias @column)
254− ( HasUnique tab (Join outer from) row
256− , GroupedBy tab col bys
259− (NP (Expression outer commons ('Grouped bys) schemas params from) tys) where
260− fromLabel = fromLabel @col :* Nil
262− ( HasUnique tab (Join outer from) row
294+ ( HasUnique relation relations columns
263− , Has col row ty
295+ , Has column columns ty
264− , GroupedBy tab col bys
296+ , GroupedBy relation column bys
265− , column ~ (col ::: ty)
266− ) => IsLabel col
297+ ) => IsLabel column
267− (Aliased (Expression outer commons ('Grouped bys) schemas params from) column) where
298+ ( Aliased (Expression schema relations ('Grouped bys) params)
299+ (column ::: ty) ) where
268− fromLabel = fromLabel @col `As` Alias
300+ fromLabel = fromLabel @column `As` Alias @column
270− ( HasUnique tab (Join outer from) row
302+ ( HasUnique relation relations columns
271− , Has col row ty
303+ , Has column columns ty
272− , GroupedBy tab col bys
304+ , GroupedBy relation column bys
273− , columns ~ '[col ::: ty]
274− ) => IsLabel col
305+ ) => IsLabel column
275− (NP (Aliased (Expression outer commons ('Grouped bys) schemas params from)) columns) where
306+ ( NP (Aliased (Expression schema relations ('Grouped bys) params))
307+ '[column ::: ty] ) where
276− fromLabel = fromLabel @col :* Nil
308+ fromLabel = fromLabel @column :* Nil
279− ( Has tab (Join outer from) row
311+ ( Has relation relations columns
280− , Has col row ty
312+ , Has column columns ty
281− , GroupedBy tab col bys
313+ , GroupedBy relation column bys
282− ) => IsQualified tab col
314+ ) => IsQualified relation column
283− (Expression outer commons ('Grouped bys) schemas params from ty) where
315+ (Expression schema relations ('Grouped bys) params ty) where
284− tab ! col = UnsafeExpression $
316+ relation ! column = UnsafeExpression $
285− renderSQL tab <> "." <> renderSQL col
317+ renderAlias relation <> "." <> renderAlias column
287− ( Has tab (Join outer from) row
289− , GroupedBy tab col bys
291− ) => IsQualified tab col
292− (NP (Expression outer commons ('Grouped bys) schemas params from) tys) where
293− tab ! col = tab ! col :* Nil
295− ( Has tab (Join outer from) row
319+ ( Has relation relations columns
296− , Has col row ty
320+ , Has column columns ty
297− , GroupedBy tab col bys
321+ , GroupedBy relation column bys
298− , column ~ (col ::: ty)
299− ) => IsQualified tab col
322+ ) => IsQualified relation column
300− (Aliased (Expression outer commons ('Grouped bys) schemas params from) column) where
323+ (Aliased (Expression schema relations ('Grouped bys) params)
301− tab ! col = tab ! col `As` col
324+ (column ::: ty)) where
325+ relation ! column = relation ! column `As` column
303− ( Has tab (Join outer from) row
327+ ( Has relation relations columns
304− , Has col row ty
328+ , Has column columns ty
305− , GroupedBy tab col bys
329+ , GroupedBy relation column bys
306− , columns ~ '[col ::: ty]
307− ) => IsQualified tab col
330+ ) => IsQualified relation column
308− (NP (Aliased (Expression outer commons ('Grouped bys) schemas params from)) columns) where
331+ ( NP (Aliased (Expression schema relations ('Grouped bys) params))
309− tab ! col = tab ! col :* Nil
332+ '[column ::: ty]) where
333+ relation ! column = relation ! column :* Nil
335+-- | analagous to `Nothing`
337+-- >>> printSQL null_
339+null_ :: Expression schema rels grouping params ('Null ty)
340+null_ = UnsafeExpression "NULL"
342+-- | analagous to `Just`
344+-- >>> printSQL $ notNull true
347+ :: Expression schema rels grouping params ('NotNull ty)
348+ -> Expression schema rels grouping params ('Null ty)
349+notNull = UnsafeExpression . renderExpression
351+-- | return the leftmost value which is not NULL
353+-- >>> printSQL $ coalesce [null_, notNull true] false
354+-- COALESCE(NULL, TRUE, FALSE)
356+ :: [Expression schema relations grouping params ('Null ty)]
357+ -- ^ @NULL@s may be present
358+ -> Expression schema relations grouping params ('NotNull ty)
359+ -- ^ @NULL@ is absent
360+ -> Expression schema relations grouping params ('NotNull ty)
361+coalesce nullxs notNullx = UnsafeExpression $
362+ "COALESCE" <> parenthesized (commaSeparated
363+ ((renderExpression <$> nullxs) <> [renderExpression notNullx]))
365+-- | analagous to `Data.Maybe.fromMaybe` using @COALESCE@
367+-- >>> printSQL $ fromNull true null_
368+-- COALESCE(NULL, TRUE)
370+ :: Expression schema relations grouping params ('NotNull ty)
371+ -- ^ what to convert @NULL@ to
372+ -> Expression schema relations grouping params ('Null ty)
373+ -> Expression schema relations grouping params ('NotNull ty)
374+fromNull notNullx nullx = coalesce [nullx] notNullx
376+-- | >>> printSQL $ null_ & isNull
379+ :: Expression schema relations grouping params ('Null ty)
380+ -- ^ possibly @NULL@
381+ -> Condition schema relations grouping params
382+isNull x = UnsafeExpression $ renderExpression x <+> "IS NULL"
384+-- | >>> printSQL $ null_ & isNotNull
387+ :: Expression schema relations grouping params ('Null ty)
388+ -- ^ possibly @NULL@
389+ -> Condition schema relations grouping params
390+isNotNull x = UnsafeExpression $ renderExpression x <+> "IS NOT NULL"
392+-- | analagous to `maybe` using @IS NULL@
394+-- >>> printSQL $ matchNull true not_ null_
395+-- CASE WHEN NULL IS NULL THEN TRUE ELSE (NOT NULL) END
397+ :: Expression schema relations grouping params (nullty)
398+ -- ^ what to convert @NULL@ to
399+ -> ( Expression schema relations grouping params ('NotNull ty)
400+ -> Expression schema relations grouping params (nullty) )
401+ -- ^ function to perform when @NULL@ is absent
402+ -> Expression schema relations grouping params ('Null ty)
403+ -> Expression schema relations grouping params (nullty)
404+matchNull y f x = ifThenElse (isNull x) y
405+ (f (UnsafeExpression (renderExpression x)))
407+{-| right inverse to `fromNull`, if its arguments are equal then
408+`nullIf` gives @NULL@.
410+>>> :set -XTypeApplications -XDataKinds
411+>>> let expr = nullIf false (param @1) :: Expression schema rels grp '[ 'NotNull 'PGbool] ('Null 'PGbool)
413+NULL IF (FALSE, ($1 :: bool))
416+ :: Expression schema relations grouping params ('NotNull ty)
417+ -- ^ @NULL@ is absent
418+ -> Expression schema relations grouping params ('NotNull ty)
419+ -- ^ @NULL@ is absent
420+ -> Expression schema relations grouping params ('Null ty)
421+nullIf x y = UnsafeExpression $ "NULL IF" <+> parenthesized
422+ (renderExpression x <> ", " <> renderExpression y)
424+-- | >>> printSQL $ array [null_, notNull false, notNull true]
425+-- ARRAY[NULL, FALSE, TRUE]
427+ :: [Expression schema relations grouping params ('Null ty)]
429+ -> Expression schema relations grouping params (nullity ('PGvararray ty))
430+array xs = UnsafeExpression $
431+ "ARRAY[" <> commaSeparated (renderExpression <$> xs) <> "]"
311instance (KnownSymbol label, label `In` labels) => IsPGlabel label
433instance (KnownSymbol label, label `In` labels) => IsPGlabel label
312− (Expression outer commons grp schemas params from (null ('PGenum labels))) where
434+ (Expression schema relations grouping params (nullity ('PGenum labels))) where
313− label = UnsafeExpression $ renderSQL (PGlabel @label)
435+ label = UnsafeExpression $ renderLabel (PGlabel @label)
437+-- | A row constructor is an expression that builds a row value
438+-- (also called a composite value) using values for its member fields.
440+-- >>> type Complex = PGcomposite '["real" ::: 'PGfloat8, "imaginary" ::: 'PGfloat8]
441+-- >>> let i = row (0 `As` #real :* 1 `As` #imaginary :* Nil) :: Expression '[] '[] 'Ungrouped '[] ('NotNull Complex)
445+ :: SListI (Nulls fields)
446+ => NP (Aliased (Expression schema relations grouping params)) (Nulls fields)
447+ -- ^ zero or more expressions for the row field values
448+ -> Expression schema relations grouping params (nullity ('PGcomposite fields))
449+row exprs = UnsafeExpression $ "ROW" <> parenthesized
450+ (renderCommaSeparated (\ (expr `As` _) -> renderExpression expr) exprs)
452+instance Has field fields ty => IsLabel field
453+ ( Expression schema relation grouping params (nullity ('PGcomposite fields))
454+ -> Expression schema relation grouping params ('Null ty) ) where
455+ fromLabel expr = UnsafeExpression $
456+ parenthesized (renderExpression expr) <> "." <>
457+ fromString (symbolVal (Proxy @field))
460+ (Expression schema relations grouping params (nullity ('PGvararray ty))) where
461+ (<>) = unsafeBinaryOp "||"
464+ (Expression schema relations grouping params (nullity ('PGvararray ty))) where
468+-- | >>> let expr = greatest currentTimestamp [param @1] :: Expression sch rels grp '[ 'NotNull 'PGtimestamptz] ('NotNull 'PGtimestamptz)
470+-- GREATEST(CURRENT_TIMESTAMP, ($1 :: timestamp with time zone))
472+ :: Expression schema relations grouping params (nullty)
473+ -- ^ needs at least 1 argument
474+ -> [Expression schema relations grouping params (nullty)]
476+ -> Expression schema relations grouping params (nullty)
477+greatest x xs = UnsafeExpression $ "GREATEST("
478+ <> commaSeparated (renderExpression <$> (x:xs)) <> ")"
480+-- | >>> printSQL $ least currentTimestamp [null_]
481+-- LEAST(CURRENT_TIMESTAMP, NULL)
483+ :: Expression schema relations grouping params (nullty)
484+ -- ^ needs at least 1 argument
485+ -> [Expression schema relations grouping params (nullty)]
487+ -> Expression schema relations grouping params (nullty)
488+least x xs = UnsafeExpression $ "LEAST("
489+ <> commaSeparated (renderExpression <$> (x:xs)) <> ")"
315-- | >>> printSQL $ unsafeBinaryOp "OR" true false
491-- | >>> printSQL $ unsafeBinaryOp "OR" true false
316-- (TRUE OR FALSE)
492-- (TRUE OR FALSE)
317−unsafeBinaryOp :: ByteString -> Operator ty0 ty1 ty2
493+unsafeBinaryOp
496+ -> Expression schema relations grouping params (ty0)
497+ -> Expression schema relations grouping params (ty1)
498+ -> Expression schema relations grouping params (ty2)
318unsafeBinaryOp op x y = UnsafeExpression $ parenthesized $
499unsafeBinaryOp op x y = UnsafeExpression $ parenthesized $
319− renderSQL x <+> op <+> renderSQL y
500+ renderExpression x <+> op <+> renderExpression 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
502+-- | >>> printSQL $ unsafeUnaryOp "NOT" true
329-- (NOT TRUE)
503-- (NOT TRUE)
330−unsafeLeftOp :: ByteString -> x --> y
505+ :: ByteString
331−unsafeLeftOp op x = UnsafeExpression $ parenthesized $ op <+> renderSQL x
506+ -- ^ operator
332−
507+ -> Expression schema relations grouping params (ty0)
333−leftOp
508+ -> Expression schema relations grouping params (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
509+unsafeUnaryOp op x = UnsafeExpression $ parenthesized $
344−
510+ op <+> renderExpression 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
512-- | >>> printSQL $ unsafeFunction "f" true
353-- f(TRUE)
513-- f(TRUE)
354−unsafeFunction :: ByteString -> x --> y
514+unsafeFunction
517+ -> Expression schema relations grouping params (xty)
518+ -> Expression schema relations grouping params (yty)
355unsafeFunction fun x = UnsafeExpression $
519unsafeFunction fun x = UnsafeExpression $
356− fun <> parenthesized (renderSQL x)
520+ fun <> parenthesized (renderExpression x)
358−function
522+unsafeVariadicFunction
359− :: (Has sch schemas schema, Has fun schema ('Function ('[x] :=> 'Returns y)))
523+ :: 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')
366−unsafeFunctionN :: SListI xs => ByteString -> xs ---> y
524+ => ByteString
526+ -> NP (Expression schema relations grouping params) elems
527+ -> Expression schema relations grouping params ret
367−unsafeFunctionN fun xs = UnsafeExpression $
528+unsafeVariadicFunction fun x = UnsafeExpression $
368− fun <> parenthesized (renderCommaSeparated renderSQL xs)
529+ fun <> parenthesized (commaSeparated (hcollapse (hmap (K . renderExpression) 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
378−instance ty `In` PGNum
531+instance PGNum ty
379− => Num (Expression outer commons grp schemas params from (null ty)) where
532+ => Num (Expression schema relations grouping params (nullity ty)) where
380 (+) = unsafeBinaryOp "+"
533 (+) = unsafeBinaryOp "+"
381 (-) = unsafeBinaryOp "-"
534 (-) = unsafeBinaryOp "-"
382 (*) = unsafeBinaryOp "*"
535 (*) = unsafeBinaryOp "*"
@@ -387,24 +540,19 @@ instance ty `In` PGNum
387 . fromString
540 . fromString
390−instance (ty `In` PGNum, ty `In` PGFloating) => Fractional
543+instance (PGNum ty, PGFloating ty) => Fractional
391− (Expression outer commons grp schemas params from (null ty)) where
544+ (Expression schema relations grouping params (nullity ty)) where
392 (/) = unsafeBinaryOp "/"
545 (/) = unsafeBinaryOp "/"
393− fromRational
546+ fromRational x = fromInteger (numerator x) / fromInteger (denominator x)
397− . showFFloat Nothing
400−instance (ty `In` PGNum, ty `In` PGFloating) => Floating
548+instance (PGNum ty, PGFloating ty) => Floating
401− (Expression outer commons grp schemas params from (null ty)) where
549+ (Expression schema relations grouping params (nullity ty)) where
402 pi = UnsafeExpression "pi()"
550 pi = UnsafeExpression "pi()"
403 exp = unsafeFunction "exp"
551 exp = unsafeFunction "exp"
404 log = unsafeFunction "ln"
552 log = unsafeFunction "ln"
405 sqrt = unsafeFunction "sqrt"
553 sqrt = unsafeFunction "sqrt"
406 b ** x = UnsafeExpression $
554 b ** x = UnsafeExpression $
407− "power(" <> renderSQL b <> ", " <> renderSQL x <> ")"
555+ "power(" <> renderExpression b <> ", " <> renderExpression x <> ")"
408 logBase b y = log y / log b
556 logBase b y = log y / log b
409 sin = unsafeFunction "sin"
557 sin = unsafeFunction "sin"
410 cos = unsafeFunction "cos"
558 cos = unsafeFunction "cos"
@@ -419,54 +567,1071 @@ instance (ty `In` PGNum, ty `In` PGFloating) => Floating
419 acosh x = log (x + sqrt (x*x - 1))
567 acosh x = log (x + sqrt (x*x - 1))
420 atanh x = log ((1 + x) / (1 - x)) / 2
568 atanh x = log ((1 + x) / (1 - x)) / 2
422−-- | Contained by operators
570+-- | >>> :{
423−class PGSubset ty where
571+-- let
424− (@>) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
572+-- expression :: Expression schema relations grouping params (nullity 'PGfloat4)
425− (@>) = unsafeBinaryOp "@>"
573+-- expression = atan2_ pi 2
426− (<@) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
574+-- in printSQL expression
427− (<@) = unsafeBinaryOp "<@"
575+-- :}
428−instance PGSubset 'PGjsonb
576+-- atan2(pi(), 2)
429−instance PGSubset 'PGtsquery
577+atan2_
430−instance PGSubset ('PGvararray ty)
578+ :: PGFloating float
431−instance PGSubset ('PGrange ty)
579+ => Expression schema relations grouping params (nullity float)
433−class PGIntersect ty where
581+ -> Expression schema relations grouping params (nullity float)
434− (@&&) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
582+ -- ^ denominator
435− (@&&) = unsafeBinaryOp "&&"
583+ -> Expression schema relations grouping params (nullity float)
436−instance PGIntersect ('PGvararray ty)
584+atan2_ y x = UnsafeExpression $
437−instance PGIntersect ('PGrange ty)
585+ "atan2(" <> renderExpression y <> ", " <> renderExpression x <> ")"
587+-- When a `cast` is applied to an `Expression` of a known type, it
588+-- represents a run-time type conversion. The cast will succeed only if a
589+-- suitable type conversion operation has been defined.
591+-- | >>> printSQL $ true & cast int4
594+ :: TypeExpression schema ty1
595+ -- ^ type to cast as
596+ -> Expression schema relations grouping params (nullity ty0)
597+ -- ^ value to convert
598+ -> Expression schema relations grouping params (nullity ty1)
599+cast ty x = UnsafeExpression $ parenthesized $
600+ renderExpression x <+> "::" <+> renderTypeExpression ty
602+-- | integer division, truncates the result
606+-- expression :: Expression schema relations grouping params (nullity 'PGint2)
607+-- expression = 5 `quot_` 2
608+-- in printSQL expression
613+ => Expression schema relations grouping params (nullity int)
615+ -> Expression schema relations grouping params (nullity int)
617+ -> Expression schema relations grouping params (nullity int)
618+quot_ = unsafeBinaryOp "/"
620+-- | remainder upon integer division
624+-- expression :: Expression schema relations grouping params (nullity 'PGint2)
625+-- expression = 5 `rem_` 2
626+-- in printSQL expression
631+ => Expression schema relations grouping params (nullity int)
633+ -> Expression schema relations grouping params (nullity int)
635+ -> Expression schema relations grouping params (nullity int)
636+rem_ = unsafeBinaryOp "%"
640+-- expression :: Expression schema relations grouping params (nullity 'PGfloat4)
641+-- expression = trunc pi
642+-- in printSQL expression
647+ => Expression schema relations grouping params (nullity frac)
648+ -- ^ fractional number
649+ -> Expression schema relations grouping params (nullity frac)
650+trunc = unsafeFunction "trunc"
654+-- expression :: Expression schema relations grouping params (nullity 'PGfloat4)
655+-- expression = round_ pi
656+-- in printSQL expression
661+ => Expression schema relations grouping params (nullity frac)
662+ -- ^ fractional number
663+ -> Expression schema relations grouping params (nullity frac)
664+round_ = unsafeFunction "round"
668+-- expression :: Expression schema relations grouping params (nullity 'PGfloat4)
669+-- expression = ceiling_ pi
670+-- in printSQL expression
675+ => Expression schema relations grouping params (nullity frac)
676+ -- ^ fractional number
677+ -> Expression schema relations grouping params (nullity frac)
678+ceiling_ = unsafeFunction "ceiling"
680+-- | A `Condition` is a boolean valued `Expression`. While SQL allows
681+-- conditions to have @NULL@, Squeal instead chooses to disallow @NULL@,
682+-- forcing one to handle the case of @NULL@ explicitly to produce
684+type Condition schema relations grouping params =
685+ Expression schema relations grouping params ('NotNull 'PGbool)
687+-- | >>> printSQL true
689+true :: Condition schema relations grouping params
690+true = UnsafeExpression "TRUE"
692+-- | >>> printSQL false
694+false :: Condition schema relations grouping params
695+false = UnsafeExpression "FALSE"
697+-- | >>> printSQL $ not_ true
700+ :: Condition schema relations grouping params
701+ -> Condition schema relations grouping params
702+not_ = unsafeUnaryOp "NOT"
704+-- | >>> printSQL $ true .&& false
707+ :: Condition schema relations grouping params
708+ -> Condition schema relations grouping params
709+ -> Condition schema relations grouping params
710+(.&&) = unsafeBinaryOp "AND"
712+-- | >>> printSQL $ true .|| false
715+ :: Condition schema relations grouping params
716+ -> Condition schema relations grouping params
717+ -> Condition schema relations grouping params
718+(.||) = unsafeBinaryOp "OR"
722+-- expression :: Expression schema relations grouping params (nullity 'PGint2)
723+-- expression = caseWhenThenElse [(true, 1), (false, 2)] 3
724+-- in printSQL expression
726+-- CASE WHEN TRUE THEN 1 WHEN FALSE THEN 2 ELSE 3 END
728+ :: [ ( Condition schema relations grouping params
729+ , Expression schema relations grouping params (ty)
731+ -- ^ whens and thens
732+ -> Expression schema relations grouping params (ty)
734+ -> Expression schema relations grouping params (ty)
735+caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
739+ [ " WHEN ", renderExpression when_
740+ , " THEN ", renderExpression then_
742+ | (when_,then_) <- whenThens
744+ , " ELSE ", renderExpression else_
750+-- expression :: Expression schema relations grouping params (nullity 'PGint2)
751+-- expression = ifThenElse true 1 0
752+-- in printSQL expression
754+-- CASE WHEN TRUE THEN 1 ELSE 0 END
756+ :: Condition schema relations grouping params
757+ -> Expression schema relations grouping params (ty) -- ^ then
758+ -> Expression schema relations grouping params (ty) -- ^ else
759+ -> Expression schema relations grouping params (ty)
760+ifThenElse if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
762+-- | Comparison operations like `.==`, `./=`, `.>`, `.>=`, `.<` and `.<=`
763+-- will produce @NULL@s if one of their arguments is @NULL@.
765+-- >>> printSQL $ notNull true .== null_
768+ :: Expression schema relations grouping params (nullity ty) -- ^ lhs
769+ -> Expression schema relations grouping params (nullity ty) -- ^ rhs
770+ -> Expression schema relations grouping params (nullity 'PGbool)
771+(.==) = unsafeBinaryOp "="
774+-- | >>> printSQL $ notNull true ./= null_
777+ :: Expression schema relations grouping params (nullity ty) -- ^ lhs
778+ -> Expression schema relations grouping params (nullity ty) -- ^ rhs
779+ -> Expression schema relations grouping params (nullity 'PGbool)
780+(./=) = unsafeBinaryOp "<>"
783+-- | >>> printSQL $ notNull true .>= null_
786+ :: Expression schema relations grouping params (nullity ty) -- ^ lhs
787+ -> Expression schema relations grouping params (nullity ty) -- ^ rhs
788+ -> Expression schema relations grouping params (nullity 'PGbool)
789+(.>=) = unsafeBinaryOp ">="
792+-- | >>> printSQL $ notNull true .< null_
795+ :: Expression schema relations grouping params (nullity ty) -- ^ lhs
796+ -> Expression schema relations grouping params (nullity ty) -- ^ rhs
797+ -> Expression schema relations grouping params (nullity 'PGbool)
798+(.<) = unsafeBinaryOp "<"
801+-- | >>> printSQL $ notNull true .<= null_
804+ :: Expression schema relations grouping params (nullity ty) -- ^ lhs
805+ -> Expression schema relations grouping params (nullity ty) -- ^ rhs
806+ -> Expression schema relations grouping params (nullity 'PGbool)
807+(.<=) = unsafeBinaryOp "<="
810+-- | >>> printSQL $ notNull true .> null_
813+ :: Expression schema relations grouping params (nullity ty) -- ^ lhs
814+ -> Expression schema relations grouping params (nullity ty) -- ^ rhs
815+ -> Expression schema relations grouping params (nullity 'PGbool)
816+(.>) = unsafeBinaryOp ">"
819+-- | >>> printSQL currentDate
822+ :: Expression schema relations grouping params (nullity 'PGdate)
823+currentDate = UnsafeExpression "CURRENT_DATE"
825+-- | >>> printSQL currentTime
828+ :: Expression schema relations grouping params (nullity 'PGtimetz)
829+currentTime = UnsafeExpression "CURRENT_TIME"
831+-- | >>> printSQL currentTimestamp
834+ :: Expression schema relations grouping params (nullity 'PGtimestamptz)
835+currentTimestamp = UnsafeExpression "CURRENT_TIMESTAMP"
837+-- | >>> printSQL localTime
840+ :: Expression schema relations grouping params (nullity 'PGtime)
841+localTime = UnsafeExpression "LOCALTIME"
843+-- | >>> printSQL localTimestamp
846+ :: Expression schema relations grouping params (nullity 'PGtimestamp)
847+localTimestamp = UnsafeExpression "LOCALTIMESTAMP"
849+{-----------------------------------------
851+-----------------------------------------}
439instance IsString
853instance IsString
440− (Expression outer commons grp schemas params from (null 'PGtext)) where
854+ (Expression schema relations grouping params (nullity 'PGtext)) where
441 fromString str = UnsafeExpression $
855 fromString str = UnsafeExpression $
442 "E\'" <> fromString (escape =<< str) <> "\'"
856 "E\'" <> fromString (escape =<< str) <> "\'"
443−instance IsString
857+ where
444− (Expression outer commons grp schemas params from (null 'PGtsvector)) where
858+ escape = \case
445− fromString str = UnsafeExpression . parenthesized . (<> " :: tsvector") $
859+ '\NUL' -> "\\0"
446− "E\'" <> fromString (escape =<< str) <> "\'"
860+ '\'' -> "''"
447−instance IsString
861+ '"' -> "\\\""
448− (Expression outer commons grp schemas params from (null 'PGtsquery)) where
862+ '\b' -> "\\b"
449− fromString str = UnsafeExpression . parenthesized . (<> " :: tsquery") $
863+ '\n' -> "\\n"
450− "E\'" <> fromString (escape =<< str) <> "\'"
864+ '\r' -> "\\r"
452instance Semigroup
869instance Semigroup
453− (Expression outer commons grp schemas params from (null ('PGvararray ty))) where
870+ (Expression schema relations grouping params (nullity 'PGtext)) 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
460− (<>) = unsafeBinaryOp "||"
462− (Expression outer commons grp schemas params from (null 'PGtsvector)) where
463 (<>) = unsafeBinaryOp "||"
871 (<>) = unsafeBinaryOp "||"
465instance Monoid
873instance Monoid
466− (Expression outer commons grp schemas params from (null 'PGtext)) where
874+ (Expression schema relations grouping params (nullity 'PGtext)) where
467− mempty = fromString ""
470− (Expression outer commons grp schemas params from (null 'PGtsvector)) where
471 mempty = fromString ""
875 mempty = fromString ""
472 mappend = (<>)
876 mappend = (<>)
878+-- | >>> printSQL $ lower "ARRRGGG"
881+ :: Expression schema relations grouping params (nullity 'PGtext)
882+ -- ^ string to lower case
883+ -> Expression schema relations grouping params (nullity 'PGtext)
884+lower = unsafeFunction "lower"
886+-- | >>> printSQL $ upper "eeee"
889+ :: Expression schema relations grouping params (nullity 'PGtext)
890+ -- ^ string to upper case
891+ -> Expression schema relations grouping params (nullity 'PGtext)
892+upper = unsafeFunction "upper"
894+-- | >>> printSQL $ charLength "four"
895+-- char_length(E'four')
897+ :: Expression schema relations grouping params (nullity 'PGtext)
898+ -- ^ string to measure
899+ -> Expression schema relations grouping params (nullity 'PGint4)
900+charLength = unsafeFunction "char_length"
902+-- | The `like` expression returns true if the @string@ matches
903+-- the supplied @pattern@. If @pattern@ does not contain percent signs
904+-- or underscores, then the pattern only represents the string itself;
905+-- in that case `like` acts like the equals operator. An underscore (_)
906+-- in pattern stands for (matches) any single character; a percent sign (%)
907+-- matches any sequence of zero or more characters.
909+-- >>> printSQL $ "abc" `like` "a%"
910+-- (E'abc' LIKE E'a%')
912+ :: Expression schema relations grouping params (nullity 'PGtext)
914+ -> Expression schema relations grouping params (nullity 'PGtext)
916+ -> Expression schema relations grouping params (nullity 'PGbool)
917+like = unsafeBinaryOp "LIKE"
919+{-----------------------------------------
920+ -- json and jsonb support
922+See https://www.postgresql.org/docs/10/static/functions-json.html -- most
923+comments lifted directly from this page.
925+Table 9.44: json and jsonb operators
926+-----------------------------------------}
928+-- | Get JSON value (object field or array element) at a key.
930+ :: (PGjson_ json, PGjsonKey key)
931+ => Expression schema relations grouping params (nullity json)
932+ -> Expression schema relations grouping params (nullity key)
933+ -> Expression schema relations grouping params ('Null json)
934+(.->) = unsafeBinaryOp "->"
936+-- | Get JSON value (object field or array element) at a key, as text.
938+ :: (PGjson_ json, PGjsonKey key)
939+ => Expression schema relations grouping params (nullity json)
940+ -> Expression schema relations grouping params (nullity key)
941+ -> Expression schema relations grouping params ('Null 'PGtext)
942+(.->>) = unsafeBinaryOp "->>"
944+-- | Get JSON value at a specified path.
946+ :: (PGjson_ json, PGtextArray "(.#>)" path)
947+ => Expression schema relations grouping params (nullity json)
948+ -> Expression schema relations grouping params (nullity path)
949+ -> Expression schema relations grouping params ('Null json)
950+(.#>) = unsafeBinaryOp "#>"
952+-- | Get JSON value at a specified path as text.
954+ :: (PGjson_ json, PGtextArray "(.#>>)" path)
955+ => Expression schema relations grouping params (nullity json)
956+ -> Expression schema relations grouping params (nullity path)
957+ -> Expression schema relations grouping params ('Null 'PGtext)
958+(.#>>) = unsafeBinaryOp "#>>"
960+-- Additional jsonb operators
962+-- | Does the left JSON value contain the right JSON path/value entries at the
965+ :: Expression schema relations grouping params (nullity 'PGjsonb)
966+ -> Expression schema relations grouping params (nullity 'PGjsonb)
967+ -> Expression schema relations grouping params ('NotNull 'PGbool)
968+(.@>) = unsafeBinaryOp "@>"
970+-- | Are the left JSON path/value entries contained at the top level within the
973+ :: Expression schema relations grouping params (nullity 'PGjsonb)
974+ -> Expression schema relations grouping params (nullity 'PGjsonb)
975+ -> Expression schema relations grouping params ('NotNull 'PGbool)
976+(.<@) = unsafeBinaryOp "<@"
978+-- | Does the string exist as a top-level key within the JSON value?
980+ :: Expression schema relations grouping params (nullity 'PGjsonb)
981+ -> Expression schema relations grouping params (nullity 'PGtext)
982+ -> Expression schema relations grouping params ('NotNull 'PGbool)
983+(.?) = unsafeBinaryOp "?"
985+-- | Do any of these array strings exist as top-level keys?
987+ :: Expression schema relations grouping params (nullity 'PGjsonb)
988+ -> Expression schema relations grouping params (nullity ('PGvararray 'PGtext))
989+ -> Expression schema relations grouping params ('NotNull 'PGbool)
990+(.?|) = unsafeBinaryOp "?|"
992+-- | Do all of these array strings exist as top-level keys?
994+ :: Expression schema relations grouping params (nullity 'PGjsonb)
995+ -> Expression schema relations grouping params (nullity ('PGvararray 'PGtext))
996+ -> Expression schema relations grouping params ('NotNull 'PGbool)
997+(.?&) = unsafeBinaryOp "?&"
999+-- | Concatenate two jsonb values into a new jsonb value.
1001+ :: Expression schema relations grouping params (nullity 'PGjsonb)
1002+ -> Expression schema relations grouping params (nullity 'PGjsonb)
1003+ -> Expression schema relations grouping params (nullity 'PGjsonb)
1004+(.||.) = unsafeBinaryOp "||"
1006+-- | Delete a key or keys from a JSON object, or remove an array element.
1008+-- If the right operand is..
1010+-- @ text @: Delete key/value pair or string element from left operand. Key/value pairs
1011+-- are matched based on their key value.
1013+-- @ text[] @: Delete multiple key/value pairs or string elements
1014+-- from left operand. Key/value pairs are matched based on their key value.
1016+-- @ integer @: Delete the array element with specified index (Negative integers
1017+-- count from the end). Throws an error if top level container is not an array.
1019+ :: (key `In` '[ 'PGtext, 'PGvararray 'PGtext, 'PGint4, 'PGint2 ]) -- hlint error without parens here
1020+ => Expression schema relations grouping params (nullity 'PGjsonb)
1021+ -> Expression schema relations grouping params (nullity key)
1022+ -> Expression schema relations grouping params (nullity 'PGjsonb)
1023+(.-.) = unsafeBinaryOp "-"
1025+-- | Delete the field or element with specified path (for JSON arrays, negative
1026+-- integers count from the end)
1028+ :: PGtextArray "(#-.)" arrayty
1029+ => Expression schema relations grouping params (nullity 'PGjsonb)
1030+ -> Expression schema relations grouping params (nullity arrayty)
1031+ -> Expression schema relations grouping params (nullity 'PGjsonb)
1032+(#-.) = unsafeBinaryOp "#-"
1034+{-----------------------------------------
1035+Table 9.45: JSON creation functions
1036+-----------------------------------------}
1038+-- | Returns the value as json. Arrays and composites are converted
1039+-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1040+-- type to json, the cast function will be used to perform the conversion;
1041+-- otherwise, a scalar value is produced. For any scalar type other than a
1042+-- number, a Boolean, or a null value, the text representation will be used, in
1043+-- such a fashion that it is a valid json value.
1045+ :: Expression schema relations grouping params (nullity ty)
1046+ -> Expression schema relations grouping params (nullity 'PGjson)
1047+toJson = unsafeFunction "to_json"
1049+-- | Returns the value as jsonb. Arrays and composites are converted
1050+-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1051+-- type to json, the cast function will be used to perform the conversion;
1052+-- otherwise, a scalar value is produced. For any scalar type other than a
1053+-- number, a Boolean, or a null value, the text representation will be used, in
1054+-- such a fashion that it is a valid jsonb value.
1056+ :: Expression schema relations grouping params (nullity ty)
1057+ -> Expression schema relations grouping params (nullity 'PGjsonb)
1058+toJsonb = unsafeUnaryOp "to_jsonb"
1060+-- | Returns the array as a JSON array. A PostgreSQL multidimensional array
1061+-- becomes a JSON array of arrays. Line feeds will be added between dimension-1
1062+-- elements if pretty_bool is true.
1064+ :: PGarray "arrayToJson" arr
1065+ => Expression schema relations grouping params (nullity arr)
1066+ -> Expression schema relations grouping params (nullity 'PGjson)
1067+arrayToJson = unsafeFunction "array_to_json"
1069+-- | Returns the row as a JSON object. Line feeds will be added between level-1
1070+-- elements if pretty_bool is true.
1072+ :: Expression schema relations grouping params (nullity ('PGcomposite ty))
1073+ -> Expression schema relations grouping params (nullity 'PGjson)
1074+rowToJson = unsafeFunction "row_to_json"
1076+-- | Builds a possibly-heterogeneously-typed JSON array out of a variadic
1080+ => NP (Expression schema relations grouping params) elems
1081+ -> Expression schema relations grouping params (nullity 'PGjson)
1082+jsonBuildArray = unsafeVariadicFunction "json_build_array"
1084+-- | Builds a possibly-heterogeneously-typed (binary) JSON array out of a
1085+-- variadic argument list.
1088+ => NP (Expression schema relations grouping params) elems
1089+ -> Expression schema relations grouping params (nullity 'PGjsonb)
1090+jsonbBuildArray = unsafeVariadicFunction "jsonb_build_array"
1092+-- | Builds a possibly-heterogeneously-typed JSON object out of a variadic
1093+-- argument list. The elements of the argument list must alternate between text
1096+ :: (PGobjectpairs "jsonBuildObject" elems, SListI elems)
1097+ => NP (Expression schema relations grouping params) elems
1098+ -> Expression schema relations grouping params (nullity 'PGjson)
1099+jsonBuildObject = unsafeVariadicFunction "json_build_object"
1101+-- | Builds a possibly-heterogeneously-typed (binary) JSON object out of a
1102+-- variadic argument list. The elements of the argument list must alternate
1103+-- between text and values.
1105+ :: (PGobjectpairs "jsonbBuildObject" elems, SListI elems)
1106+ => NP (Expression schema relations grouping params) elems
1107+ -> Expression schema relations grouping params (nullity 'PGjsonb)
1108+jsonbBuildObject = unsafeVariadicFunction "jsonb_build_object"
1110+-- | Builds a JSON object out of a text array. The array must have either
1111+-- exactly one dimension with an even number of members, in which case they are
1112+-- taken as alternating key/value pairs, or two dimensions such that each inner
1113+-- array has exactly two elements, which are taken as a key/value pair.
1115+ :: PGarrayOf "jsonObject" arr 'PGtext
1116+ => Expression schema relations grouping params (nullity arr)
1117+ -> Expression schema relations grouping params (nullity 'PGjson)
1118+jsonObject = unsafeFunction "json_object"
1120+-- | Builds a binary JSON object out of a text array. The array must have either
1121+-- exactly one dimension with an even number of members, in which case they are
1122+-- taken as alternating key/value pairs, or two dimensions such that each inner
1123+-- array has exactly two elements, which are taken as a key/value pair.
1125+ :: PGarrayOf "jsonbObject" arr 'PGtext
1126+ => Expression schema relations grouping params (nullity arr)
1127+ -> Expression schema relations grouping params (nullity 'PGjsonb)
1128+jsonbObject = unsafeFunction "jsonb_object"
1130+-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1131+-- keys and one for values, that are zipped pairwise to create a JSON object.
1133+ :: ( PGarrayOf "jsonZipObject" keysArray 'PGtext
1134+ , PGarrayOf "jsonZipObject" valuesArray 'PGtext)
1135+ => Expression schema relations grouping params (nullity keysArray)
1136+ -> Expression schema relations grouping params (nullity valuesArray)
1137+ -> Expression schema relations grouping params (nullity 'PGjson)
1138+jsonZipObject ks vs =
1139+ unsafeVariadicFunction "json_object" (ks :* vs :* Nil)
1141+-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1142+-- keys and one for values, that are zipped pairwise to create a binary JSON
1145+ :: ( PGarrayOf "jsonbZipObject" keysArray 'PGtext
1146+ , PGarrayOf "jsonbZipObject" valuesArray 'PGtext)
1147+ => Expression schema relations grouping params (nullity keysArray)
1148+ -> Expression schema relations grouping params (nullity valuesArray)
1149+ -> Expression schema relations grouping params (nullity 'PGjsonb)
1150+jsonbZipObject ks vs =
1151+ unsafeVariadicFunction "jsonb_object" (ks :* vs :* Nil)
1153+{-----------------------------------------
1154+Table 9.46: JSON processing functions
1155+-----------------------------------------}
1157+-- | Returns the number of elements in the outermost JSON array.
1159+ :: Expression schema relations grouping params (nullity 'PGjson)
1160+ -> Expression schema relations grouping params (nullity 'PGint4)
1161+jsonArrayLength = unsafeFunction "json_array_length"
1163+-- | Returns the number of elements in the outermost binary JSON array.
1165+ :: Expression schema relations grouping params (nullity 'PGjsonb)
1166+ -> Expression schema relations grouping params (nullity 'PGint4)
1167+jsonbArrayLength = unsafeFunction "jsonb_array_length"
1169+-- | Expands the outermost JSON object into a set of key/value pairs.
1171+-- See also 'Squeal.PostgreSQL.Query.jsonEach'.
1173+ :: Expression schema relations grouping params (nullity 'PGjson)
1174+ -> Expression schema relations grouping params
1175+ (nullity ('PGcomposite '[ "key" ::: 'PGtext, "value" ::: 'PGjson ]))
1176+jsonEachAsComposite = unsafeFunction "json_each"
1178+-- | Expands the outermost JSON object into a set of key/value pairs.
1180+-- See also 'Squeal.PostgreSQL.Query.jsonbEach'
1181+jsonbEachAsComposite
1182+ :: Expression schema relations grouping params (nullity 'PGjsonb)
1183+ -> Expression schema relations grouping params
1184+ (nullity ('PGcomposite '[ "key" ::: 'PGtext, "value" ::: 'PGjsonb ]))
1185+jsonbEachAsComposite = unsafeFunction "jsonb_each"
1187+-- | Expands the outermost JSON object into a set of key/value pairs.
1189+-- See also 'Squeal.PostgreSQL.Query.jsonEachText'.
1190+jsonEachTextAsComposite
1191+ :: Expression schema relations grouping params (nullity 'PGjson)
1192+ -> Expression schema relations grouping params
1193+ (nullity ('PGcomposite '[ "key" ::: 'PGtext, "value" ::: 'PGtext ]))
1194+jsonEachTextAsComposite = unsafeFunction "json_each_text"
1196+-- | Expands the outermost JSON object into a set of key/value pairs.
1198+-- See also 'Squeal.PostgreSQL.Query.jsonbEachText'
1199+jsonbEachTextAsComposite
1200+ :: Expression schema relations grouping params (nullity 'PGjsonb)
1201+ -> Expression schema relations grouping params
1202+ (nullity ('PGcomposite '[ "key" ::: 'PGtext, "value" ::: 'PGtext ]))
1203+jsonbEachTextAsComposite = unsafeFunction "jsonb_each_text"
1205+-- | Returns JSON value pointed to by path_elems (equivalent to #> operator).
1208+ => Expression schema relations grouping params (nullity 'PGjson)
1209+ -> NP (Expression schema relations grouping params) elems
1210+ -> Expression schema relations grouping params (nullity 'PGjsonb)
1211+jsonExtractPath x xs =
1212+ unsafeVariadicFunction "json_extract_path" (x :* xs)
1214+-- | Returns JSON value pointed to by path_elems (equivalent to #> operator).
1217+ => Expression schema relations grouping params (nullity 'PGjsonb)
1218+ -> NP (Expression schema relations grouping params) elems
1219+ -> Expression schema relations grouping params (nullity 'PGjsonb)
1220+jsonbExtractPath x xs =
1221+ unsafeVariadicFunction "jsonb_extract_path" (x :* xs)
1223+-- | Returns JSON value pointed to by path_elems (equivalent to #> operator),
1227+ => Expression schema relations grouping params (nullity 'PGjson)
1228+ -> NP (Expression schema relations grouping params) elems
1229+ -> Expression schema relations grouping params (nullity 'PGjsonb)
1230+jsonExtractPathText x xs =
1231+ unsafeVariadicFunction "json_extract_path_text" (x :* xs)
1233+-- | Returns JSON value pointed to by path_elems (equivalent to #> operator),
1235+jsonbExtractPathText
1237+ => Expression schema relations grouping params (nullity 'PGjsonb)
1238+ -> NP (Expression schema relations grouping params) elems
1239+ -> Expression schema relations grouping params (nullity 'PGjsonb)
1240+jsonbExtractPathText x xs =
1241+ unsafeVariadicFunction "jsonb_extract_path_text" (x :* xs)
1243+-- | Returns set of keys in the outermost JSON object.
1245+ :: Expression schema relations grouping params (nullity 'PGjson)
1246+ -> Expression schema relations grouping params (nullity 'PGtext)
1247+jsonObjectKeys = unsafeFunction "json_object_keys"
1249+-- | Returns set of keys in the outermost JSON object.
1251+ :: Expression schema relations grouping params (nullity 'PGjsonb)
1252+ -> Expression schema relations grouping params (nullity 'PGtext)
1253+jsonbObjectKeys = unsafeFunction "jsonb_object_keys"
1255+{-----------------------------------------
1257+-----------------------------------------}
1259+-- | escape hatch to define aggregate functions
1261+ :: ByteString -- ^ aggregate function
1262+ -> Expression schema relations 'Ungrouped params (xty)
1263+ -> Expression schema relations ('Grouped bys) params (yty)
1264+unsafeAggregate fun x = UnsafeExpression $ mconcat
1265+ [fun, "(", renderExpression x, ")"]
1267+-- | escape hatch to define aggregate functions over distinct values
1268+unsafeAggregateDistinct
1269+ :: ByteString -- ^ aggregate function
1270+ -> Expression schema relations 'Ungrouped params (xty)
1271+ -> Expression schema relations ('Grouped bys) params (yty)
1272+unsafeAggregateDistinct fun x = UnsafeExpression $ mconcat
1273+ [fun, "(DISTINCT ", renderExpression x, ")"]
1277+-- expression :: Expression schema '[tab ::: '["col" ::: 'Null 'PGnumeric]] ('Grouped bys) params ('Null 'PGnumeric)
1278+-- expression = sum_ #col
1279+-- in printSQL expression
1284+ => Expression schema relations 'Ungrouped params (nullity ty)
1286+ -> Expression schema relations ('Grouped bys) params (nullity ty)
1287+sum_ = unsafeAggregate "sum"
1291+-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGnumeric]] ('Grouped bys) params (nullity 'PGnumeric)
1292+-- expression = sumDistinct #col
1293+-- in printSQL expression
1295+-- sum(DISTINCT "col")
1298+ => Expression schema relations 'Ungrouped params (nullity ty)
1300+ -> Expression schema relations ('Grouped bys) params (nullity ty)
1301+sumDistinct = unsafeAggregateDistinct "sum"
1303+-- | A constraint for `PGType`s that you can take averages of and the resulting
1305+class PGAvg ty avg | ty -> avg where
1307+ :: Expression schema relations 'Ungrouped params (nullity ty)
1308+ -- ^ what to average
1309+ -> Expression schema relations ('Grouped bys) params (nullity avg)
1310+ avg = unsafeAggregate "avg"
1311+ avgDistinct = unsafeAggregateDistinct "avg"
1312+instance PGAvg 'PGint2 'PGnumeric
1313+instance PGAvg 'PGint4 'PGnumeric
1314+instance PGAvg 'PGint8 'PGnumeric
1315+instance PGAvg 'PGnumeric 'PGnumeric
1316+instance PGAvg 'PGfloat4 'PGfloat8
1317+instance PGAvg 'PGfloat8 'PGfloat8
1318+instance PGAvg 'PGinterval 'PGinterval
1322+-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
1323+-- expression = bitAnd #col
1324+-- in printSQL expression
1329+ => Expression schema relations 'Ungrouped params (nullity int)
1330+ -- ^ what to aggregate
1331+ -> Expression schema relations ('Grouped bys) params (nullity int)
1332+bitAnd = unsafeAggregate "bit_and"
1336+-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
1337+-- expression = bitOr #col
1338+-- in printSQL expression
1343+ => Expression schema relations 'Ungrouped params (nullity int)
1344+ -- ^ what to aggregate
1345+ -> Expression schema relations ('Grouped bys) params (nullity int)
1346+bitOr = unsafeAggregate "bit_or"
1350+-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
1351+-- expression = bitAndDistinct #col
1352+-- in printSQL expression
1354+-- bit_and(DISTINCT "col")
1357+ => Expression schema relations 'Ungrouped params (nullity int)
1358+ -- ^ what to aggregate
1359+ -> Expression schema relations ('Grouped bys) params (nullity int)
1360+bitAndDistinct = unsafeAggregateDistinct "bit_and"
1364+-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
1365+-- expression = bitOrDistinct #col
1366+-- in printSQL expression
1368+-- bit_or(DISTINCT "col")
1371+ => Expression schema relations 'Ungrouped params (nullity int)
1372+ -- ^ what to aggregate
1373+ -> Expression schema relations ('Grouped bys) params (nullity int)
1374+bitOrDistinct = unsafeAggregateDistinct "bit_or"
1378+-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1379+-- expression = boolAnd #col
1380+-- in printSQL expression
1384+ :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1385+ -- ^ what to aggregate
1386+ -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1387+boolAnd = unsafeAggregate "bool_and"
1391+-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1392+-- expression = boolOr #col
1393+-- in printSQL expression
1397+ :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1398+ -- ^ what to aggregate
1399+ -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1400+boolOr = unsafeAggregate "bool_or"
1404+-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1405+-- expression = boolAndDistinct #col
1406+-- in printSQL expression
1408+-- bool_and(DISTINCT "col")
1410+ :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1411+ -- ^ what to aggregate
1412+ -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1413+boolAndDistinct = unsafeAggregateDistinct "bool_and"
1417+-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1418+-- expression = boolOrDistinct #col
1419+-- in printSQL expression
1421+-- bool_or(DISTINCT "col")
1423+ :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1424+ -- ^ what to aggregate
1425+ -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1426+boolOrDistinct = unsafeAggregateDistinct "bool_or"
1428+-- | A special aggregation that does not require an input
1430+-- >>> printSQL countStar
1433+ :: Expression schema relations ('Grouped bys) params ('NotNull 'PGint8)
1434+countStar = UnsafeExpression $ "count(*)"
1438+-- expression :: Expression schema '[tab ::: '["col" ::: nullity ty]] (Grouped bys) params ('NotNull 'PGint8)
1439+-- expression = count #col
1440+-- in printSQL expression
1444+ :: Expression schema relations 'Ungrouped params ty
1446+ -> Expression schema relations ('Grouped bys) params ('NotNull 'PGint8)
1447+count = unsafeAggregate "count"
1451+-- expression :: Expression schema '[tab ::: '["col" ::: nullity ty]] (Grouped bys) params ('NotNull 'PGint8)
1452+-- expression = countDistinct #col
1453+-- in printSQL expression
1455+-- count(DISTINCT "col")
1457+ :: Expression schema relations 'Ungrouped params ty
1459+ -> Expression schema relations ('Grouped bys) params ('NotNull 'PGint8)
1460+countDistinct = unsafeAggregateDistinct "count"
1462+-- | synonym for `boolAnd`
1466+-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1467+-- expression = every #col
1468+-- in printSQL expression
1472+ :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1473+ -- ^ what to aggregate
1474+ -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1475+every = unsafeAggregate "every"
1477+-- | synonym for `boolAndDistinct`
1481+-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1482+-- expression = everyDistinct #col
1483+-- in printSQL expression
1485+-- every(DISTINCT "col")
1487+ :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1488+ -- ^ what to aggregate
1489+ -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1490+everyDistinct = unsafeAggregateDistinct "every"
1492+-- | minimum and maximum aggregation
1493+max_, min_, maxDistinct, minDistinct
1494+ :: Expression schema relations 'Ungrouped params (nullity ty)
1495+ -- ^ what to aggregate
1496+ -> Expression schema relations ('Grouped bys) params (nullity ty)
1497+max_ = unsafeAggregate "max"
1498+min_ = unsafeAggregate "min"
1499+maxDistinct = unsafeAggregateDistinct "max"
1500+minDistinct = unsafeAggregateDistinct "min"
1502+{-----------------------------------------
1504+-----------------------------------------}
1506+-- | `TypeExpression`s are used in `cast`s and `createTable` commands.
1507+newtype TypeExpression (schema :: SchemaType) (ty :: PGType)
1508+ = UnsafeTypeExpression { renderTypeExpression :: ByteString }
1509+ deriving (GHC.Generic,Show,Eq,Ord,NFData)
1511+instance (Has alias schema ('Typedef ty))
1512+ => IsLabel alias (TypeExpression schema ty) where
1513+ fromLabel = UnsafeTypeExpression (renderAlias (fromLabel @alias))
1515+-- | logical Boolean (true/false)
1516+bool :: TypeExpression schema 'PGbool
1517+bool = UnsafeTypeExpression "bool"
1518+-- | signed two-byte integer
1519+int2, smallint :: TypeExpression schema 'PGint2
1520+int2 = UnsafeTypeExpression "int2"
1521+smallint = UnsafeTypeExpression "smallint"
1522+-- | signed four-byte integer
1523+int4, int, integer :: TypeExpression schema 'PGint4
1524+int4 = UnsafeTypeExpression "int4"
1525+int = UnsafeTypeExpression "int"
1526+integer = UnsafeTypeExpression "integer"
1527+-- | signed eight-byte integer
1528+int8, bigint :: TypeExpression schema 'PGint8
1529+int8 = UnsafeTypeExpression "int8"
1530+bigint = UnsafeTypeExpression "bigint"
1531+-- | arbitrary precision numeric type
1532+numeric :: TypeExpression schema 'PGnumeric
1533+numeric = UnsafeTypeExpression "numeric"
1534+-- | single precision floating-point number (4 bytes)
1535+float4, real :: TypeExpression schema 'PGfloat4
1536+float4 = UnsafeTypeExpression "float4"
1537+real = UnsafeTypeExpression "real"
1538+-- | double precision floating-point number (8 bytes)
1539+float8, doublePrecision :: TypeExpression schema 'PGfloat8
1540+float8 = UnsafeTypeExpression "float8"
1541+doublePrecision = UnsafeTypeExpression "double precision"
1542+-- | variable-length character string
1543+text :: TypeExpression schema 'PGtext
1544+text = UnsafeTypeExpression "text"
1545+-- | fixed-length character string
1547+ :: (KnownNat n, 1 <= n)
1549+ -> TypeExpression schema ('PGchar n)
1550+char p = UnsafeTypeExpression $ "char(" <> renderNat p <> ")"
1551+character p = UnsafeTypeExpression $ "character(" <> renderNat p <> ")"
1552+-- | variable-length character string
1553+varchar, characterVarying
1554+ :: (KnownNat n, 1 <= n)
1556+ -> TypeExpression schema ('PGvarchar n)
1557+varchar p = UnsafeTypeExpression $ "varchar(" <> renderNat p <> ")"
1558+characterVarying p = UnsafeTypeExpression $
1559+ "character varying(" <> renderNat p <> ")"
1560+-- | binary data ("byte array")
1561+bytea :: TypeExpression schema 'PGbytea
1562+bytea = UnsafeTypeExpression "bytea"
1563+-- | date and time (no time zone)
1564+timestamp :: TypeExpression schema 'PGtimestamp
1565+timestamp = UnsafeTypeExpression "timestamp"
1566+-- | date and time, including time zone
1567+timestampWithTimeZone :: TypeExpression schema 'PGtimestamptz
1568+timestampWithTimeZone = UnsafeTypeExpression "timestamp with time zone"
1569+-- | calendar date (year, month, day)
1570+date :: TypeExpression schema 'PGdate
1571+date = UnsafeTypeExpression "date"
1572+-- | time of day (no time zone)
1573+time :: TypeExpression schema 'PGtime
1574+time = UnsafeTypeExpression "time"
1575+-- | time of day, including time zone
1576+timeWithTimeZone :: TypeExpression schema 'PGtimetz
1577+timeWithTimeZone = UnsafeTypeExpression "time with time zone"
1579+interval :: TypeExpression schema 'PGinterval
1580+interval = UnsafeTypeExpression "interval"
1581+-- | universally unique identifier
1582+uuid :: TypeExpression schema 'PGuuid
1583+uuid = UnsafeTypeExpression "uuid"
1584+-- | IPv4 or IPv6 host address
1585+inet :: TypeExpression schema 'PGinet
1586+inet = UnsafeTypeExpression "inet"
1587+-- | textual JSON data
1588+json :: TypeExpression schema 'PGjson
1589+json = UnsafeTypeExpression "json"
1590+-- | binary JSON data, decomposed
1591+jsonb :: TypeExpression schema 'PGjsonb
1592+jsonb = UnsafeTypeExpression "jsonb"
1593+-- | variable length array
1595+ :: TypeExpression schema pg
1596+ -> TypeExpression schema ('PGvararray pg)
1597+vararray ty = UnsafeTypeExpression $ renderTypeExpression ty <> "[]"
1598+-- | fixed length array
1600+-- >>> renderTypeExpression (fixarray (Proxy @2) json)
1605+ -> TypeExpression schema pg
1606+ -> TypeExpression schema ('PGfixarray n pg)
1607+fixarray p ty = UnsafeTypeExpression $
1608+ renderTypeExpression ty <> "[" <> renderNat p <> "]"
1610+-- | `pgtype` is a demoted version of a `PGType`
1611+class PGTyped schema (ty :: PGType) where pgtype :: TypeExpression schema ty
1612+instance PGTyped schema 'PGbool where pgtype = bool
1613+instance PGTyped schema 'PGint2 where pgtype = int2
1614+instance PGTyped schema 'PGint4 where pgtype = int4
1615+instance PGTyped schema 'PGint8 where pgtype = int8
1616+instance PGTyped schema 'PGnumeric where pgtype = numeric
1617+instance PGTyped schema 'PGfloat4 where pgtype = float4
1618+instance PGTyped schema 'PGfloat8 where pgtype = float8
1619+instance PGTyped schema 'PGtext where pgtype = text
1620+instance (KnownNat n, 1 <= n)
1621+ => PGTyped schema ('PGchar n) where pgtype = char (Proxy @n)
1622+instance (KnownNat n, 1 <= n)
1623+ => PGTyped schema ('PGvarchar n) where pgtype = varchar (Proxy @n)
1624+instance PGTyped schema 'PGbytea where pgtype = bytea
1625+instance PGTyped schema 'PGtimestamp where pgtype = timestamp
1626+instance PGTyped schema 'PGtimestamptz where pgtype = timestampWithTimeZone
1627+instance PGTyped schema 'PGdate where pgtype = date
1628+instance PGTyped schema 'PGtime where pgtype = time
1629+instance PGTyped schema 'PGtimetz where pgtype = timeWithTimeZone
1630+instance PGTyped schema 'PGinterval where pgtype = interval
1631+instance PGTyped schema 'PGuuid where pgtype = uuid
1632+instance PGTyped schema 'PGjson where pgtype = json
1633+instance PGTyped schema 'PGjsonb where pgtype = jsonb
1634+instance PGTyped schema ty => PGTyped schema ('PGvararray ty) where
1635+ pgtype = vararray (pgtype @schema @ty)
1636+instance (KnownNat n, PGTyped schema ty) => PGTyped schema ('PGfixarray n ty) where
1637+ pgtype = fixarray (Proxy @n) (pgtype @schema @ty)