@@ -1,14 +1,13 @@
11{-|
2−Module: Squeal.PostgreSQL.Query
2+Module: Squeal.PostgreSQL.Expression
33Description: Squeal expressions
4−Copyright: (c) Eitan Chatav, 2017
4+Copyright: (c) Eitan Chatav, 2019
55Maintainer: eitan@morphism.tech
66Stability: experimental
77
88Squeal expressions are the atoms used to build statements.
99-}
1010
11−{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
1211{-# LANGUAGE
1312 AllowAmbiguousTypes
1413 , ConstraintKinds
@@ -16,11 +15,13 @@ Squeal expressions are the atoms used to build statements.
1615 , FlexibleContexts
1716 , FlexibleInstances
1817 , FunctionalDependencies
18+ , GADTs
1919 , GeneralizedNewtypeDeriving
2020 , LambdaCase
2121 , MagicHash
2222 , OverloadedStrings
2323 , ScopedTypeVariables
24+ , StandaloneDeriving
2425 , TypeApplications
2526 , TypeFamilies
2627 , TypeInType
@@ -31,508 +32,351 @@ Squeal expressions are the atoms used to build statements.
3132
3233module Squeal.PostgreSQL.Expression
3334 ( -- * Expression
34− Expression (UnsafeExpression, renderExpression)
35− , HasParameter (parameter)
36− , param
37− -- ** Null
38− , null_
39− , notNull
40− , coalesce
41− , fromNull
42− , isNull
43− , isNotNull
44− , matchNull
45− , nullIf
46− -- ** Collections
47− , array
48− , row
49− -- ** Functions
50− , unsafeBinaryOp
51− , unsafeUnaryOp
35+ Expression (..)
36+ , Expr
37+ , type (-->)
38+ , FunctionDB
5239 , unsafeFunction
53− , unsafeVariadicFunction
54− , atan2_
55− , cast
56− , quot_
57− , rem_
58− , trunc
59− , round_
60− , ceiling_
61− , greatest
62− , least
63− -- ** Conditions
64− , Condition
65− , true
66− , false
67− , not_
68− , (.&&)
69− , (.||)
70− , caseWhenThenElse
71− , ifThenElse
72− , (.==)
73− , (./=)
74− , (.>=)
75− , (.<)
76− , (.<=)
77− , (.>)
78− -- ** Time
79− , currentDate
80− , currentTime
81− , currentTimestamp
82− , localTime
83− , localTimestamp
84− -- ** Text
85− , lower
86− , upper
87− , charLength
88− , like
89− -- ** json or jsonb operators
90− , PGarray
91− , PGarrayOf
92− , PGjsonKey
93− , PGjson_
94− , PGobjectpairs
95− , (.->)
96− , (.->>)
97− , (.#>)
98− , (.#>>)
99− -- *** jsonb only operators
100− , (.@>)
101− , (.<@)
102− , (.?)
103− , (.?|)
104− , (.?&)
105− , (.||.)
106− , (.-.)
107− , (#-.)
108− -- *** Functions
109− , toJson
110− , toJsonb
111− , arrayToJson
112− , rowToJson
113− , jsonBuildArray
114− , jsonbBuildArray
115− , jsonBuildObject
116− , jsonbBuildObject
117− , jsonObject
118− , jsonbObject
119− , jsonZipObject
120− , jsonbZipObject
121− , jsonArrayLength
122− , jsonbArrayLength
123− , jsonExtractPath
124− , jsonbExtractPath
125− , jsonExtractPathAsText
126− , jsonbExtractPathAsText
127− , jsonObjectKeys
128− , jsonbObjectKeys
129− , jsonTypeof
130− , jsonbTypeof
131− -- ** Aggregation
132− , unsafeAggregate, unsafeAggregateDistinct
133− , sum_, sumDistinct
134− , PGAvg (avg, avgDistinct)
135− , bitAnd, bitOr, boolAnd, boolOr
136− , bitAndDistinct, bitOrDistinct, boolAndDistinct, boolOrDistinct
137− , countStar
138− , count, countDistinct
139− , every, everyDistinct
140− , max_, maxDistinct, min_, minDistinct
141− -- * Types
142− , TypeExpression (UnsafeTypeExpression, renderTypeExpression)
143− , PGTyped (pgtype)
144− , bool
145− , int2
146− , smallint
147− , int4
148− , int
149− , integer
150− , int8
151− , bigint
152− , numeric
153− , float4
154− , real
155− , float8
156− , doublePrecision
157− , text
158− , char
159− , character
160− , varchar
161− , characterVarying
162− , bytea
163− , timestamp
164− , timestampWithTimeZone
165− , date
166− , time
167− , timeWithTimeZone
168− , interval
169− , uuid
170− , inet
171− , json
172− , jsonb
173− , vararray
174− , fixarray
40+ , function
41+ , unsafeLeftOp
42+ , leftOp
43+ , unsafeRightOp
44+ , rightOp
45+ , Operator
46+ , OperatorDB
47+ , unsafeBinaryOp
48+ , binaryOp
49+ , FunctionVar
50+ , unsafeFunctionVar
51+ , type (--->)
52+ , FunctionNDB
53+ , unsafeFunctionN
54+ , functionN
55+ , PGSubset (..)
56+ , PGIntersect (..)
17557 -- * Re-export
17658 , (&)
177− , NP ((:*), Nil)
59+ , K (..)
60+ , unK
17861 ) where
17962
18063import Control.Category
18164import Control.DeepSeq
18265import Data.ByteString (ByteString)
18366import Data.Function ((&))
184−import Data.Semigroup
185−import Data.Ratio
67+import Data.Semigroup hiding (All)
18668import Data.String
187−import Generics.SOP hiding (from)
69+import Generics.SOP hiding (All, from)
18870import GHC.OverloadedLabels
18971import GHC.TypeLits
72+import Numeric
19073import Prelude hiding (id, (.))
19174
19275import qualified GHC.Generics as GHC
19376
77+import Squeal.PostgreSQL.Alias
78+import Squeal.PostgreSQL.List
19479import Squeal.PostgreSQL.Render
19580import Squeal.PostgreSQL.Schema
19681
82+-- $setup
83+-- >>> import Squeal.PostgreSQL
84+
19785{-----------------------------------------
19886column expressions
19987-----------------------------------------}
20088
20189{- | `Expression`s are used in a variety of contexts,
202−such as in the target list of the `Squeal.PostgreSQL.Query.select` command,
90+such as in the target `Squeal.PostgreSQL.Query.List` of the
91+`Squeal.PostgreSQL.Query.select` command,
20392as new column values in `Squeal.PostgreSQL.Manipulation.insertRow` or
20493`Squeal.PostgreSQL.Manipulation.update`,
205−or in search `Condition`s in a number of commands.
94+or in search `Squeal.PostgreSQL.Logic.Condition`s in a number of commands.
20695
20796The expression syntax allows the calculation of
20897values from primitive expression using arithmetic, logical,
20998and other operations.
99+
100+The type parameters of `Expression` are
101+
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`.
210113-}
211114newtype Expression
212− (schema :: SchemaType)
213− (relations :: RelationsType)
214− (grouping :: Grouping)
115+ (outer :: FromType)
116+ (commons :: FromType)
117+ (grp :: Grouping)
118+ (schemas :: SchemasType)
215119 (params :: [NullityType])
120+ (from :: FromType)
216121 (ty :: NullityType)
217122 = UnsafeExpression { renderExpression :: ByteString }
218123 deriving (GHC.Generic,Show,Eq,Ord,NFData)
219−
220−instance RenderSQL (Expression schema relations grouping params ty) where
124+instance RenderSQL (Expression outer commons grp schemas params from ty) where
221125 renderSQL = renderExpression
222126
223−{- | A `HasParameter` constraint is used to indicate a value that is
224−supplied externally to a SQL statement.
225−`Squeal.PostgreSQL.PQ.manipulateParams`,
226−`Squeal.PostgreSQL.PQ.queryParams` and
227−`Squeal.PostgreSQL.PQ.traversePrepared` support specifying data values
228−separately from the SQL command string, in which case `param`s are used to
229−refer to the out-of-line data values.
127+-- | An `Expr` is a closed `Expression`.
128+-- It is a F@RankNType@ but don't be scared.
129+-- Think of it as an expression which sees no
130+-- namespaces, so you can't use parameters
131+-- or alias references. It can be used as
132+-- a simple piece of more complex `Expression`s.
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
137+
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
142+ -- ^ left input
143+ -> Expression outer commons grp schemas params from x2
144+ -- ^ right input
145+ -> Expression outer commons grp schemas params from y
146+ -- ^ output
147+
148+type OperatorDB schemas x1 x2 y
149+ = forall outer commons grp params from
150+ . Expression outer commons grp schemas params from x1
151+ -- ^ left input
152+ -> Expression outer commons grp schemas params from x2
153+ -- ^ right input
154+ -> Expression outer commons grp schemas params from y
155+ -- ^ output
156+
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`.
162+type (-->) x y
163+ = forall outer commons grp schemas params from
164+ . Expression outer commons grp schemas params from x
165+ -- ^ input
166+ -> Expression outer commons grp schemas params from y
167+ -- ^ output
168+
169+type FunctionDB schemas x y
170+ = forall outer commons grp params from
171+ . Expression outer commons grp schemas params from x
172+ -- ^ input
173+ -> Expression outer commons grp schemas params from y
174+ -- ^ output
175+
176+{- | A @RankNType@ for functions with a fixed-length list of heterogeneous arguments.
177+Use the `*:` operator to end your argument lists, like so.
178+
179+>>> printSQL (unsafeFunctionN "fun" (true :* false :* localTime *: true))
180+fun(TRUE, FALSE, LOCALTIME, TRUE)
230181-}
231−class KnownNat n => HasParameter
232− (n :: Nat)
233− (schema :: SchemaType)
234− (params :: [NullityType])
235− (ty :: NullityType)
236− | n params -> ty where
237− -- | `parameter` takes a `Nat` using type application and a `TypeExpression`.
238− --
239− -- >>> let expr = parameter @1 int4 :: Expression sch rels grp '[ 'Null 'PGint4] ('Null 'PGint4)
240− -- >>> printSQL expr
241− -- ($1 :: int4)
242− parameter
243− :: TypeExpression schema (PGTypeOf ty)
244− -> Expression schema relations grouping params ty
245− parameter ty = UnsafeExpression $ parenthesized $
246− "$" <> renderNat (Proxy @n) <+> "::"
247− <+> renderTypeExpression ty
248−instance {-# OVERLAPPING #-} HasParameter 1 schema (ty1:tys) ty1
249−instance {-# OVERLAPPABLE #-} (KnownNat n, HasParameter (n-1) schema params ty)
250− => HasParameter n schema (ty' : params) ty
251−
252−-- | `param` takes a `Nat` using type application and for basic types,
253−-- infers a `TypeExpression`.
254−--
255−-- >>> let expr = param @1 :: Expression sch rels grp '[ 'Null 'PGint4] ('Null 'PGint4)
256−-- >>> printSQL expr
257−-- ($1 :: int4)
258−param
259− :: forall n schema params relations grouping ty
260− . (PGTyped schema (PGTypeOf ty), HasParameter n schema params ty)
261− => Expression schema relations grouping params ty -- ^ param
262−param = parameter @n pgtype
263−
264−instance (HasUnique relation relations columns, Has column columns ty)
265− => IsLabel column (Expression schema relations 'Ungrouped params ty) where
266− fromLabel = UnsafeExpression $ renderAlias (Alias @column)
267−instance (HasUnique relation relations columns, Has column columns ty)
268− => IsLabel column
269− (Aliased (Expression schema relations 'Ungrouped params) (column ::: ty)) where
270− fromLabel = fromLabel @column `As` Alias @column
271−instance (HasUnique relation relations columns, Has column columns ty)
272− => IsLabel column
273− (NP (Aliased (Expression schema relations 'Ungrouped params)) '[column ::: ty]) where
274− fromLabel = fromLabel @column :* Nil
275−
276−instance (Has relation relations columns, Has column columns ty)
277− => IsQualified relation column (Expression schema relations 'Ungrouped params ty) where
278− relation ! column = UnsafeExpression $
279− renderAlias relation <> "." <> renderAlias column
280−instance (Has relation relations columns, Has column columns ty)
281− => IsQualified relation column
282− (Aliased (Expression schema relations 'Ungrouped params) (column ::: ty)) where
283− relation ! column = relation ! column `As` column
284−instance (Has relation relations columns, Has column columns ty)
285− => IsQualified relation column
286− (NP (Aliased (Expression schema relations 'Ungrouped params)) '[column ::: ty]) where
287− relation ! column = relation ! column :* Nil
182+type (--->) xs y
183+ = forall outer commons grp schemas params from
184+ . NP (Expression outer commons grp schemas params from) xs
185+ -- ^ inputs
186+ -> Expression outer commons grp schemas params from y
187+ -- ^ output
188+
189+type FunctionNDB schemas xs y
190+ = forall outer commons grp params from
191+ . NP (Expression outer commons grp schemas params from) xs
192+ -- ^ inputs
193+ -> Expression outer commons grp schemas params from y
194+ -- ^ output
195+
196+{- | A @RankNType@ for functions with a variable-length list of
197+homogeneous arguments and at least 1 more argument.
198+-}
199+type FunctionVar x0 x1 y
200+ = forall outer commons grp schemas params from
201+ . [Expression outer commons grp schemas params from x0]
202+ -- ^ inputs
203+ -> Expression outer commons grp schemas params from x1
204+ -- ^ must have at least 1 input
205+ -> Expression outer commons grp schemas params from y
206+ -- ^ output
207+
208+{- | >>> printSQL (unsafeFunctionVar "greatest" [true, null_] false)
209+greatest(TRUE, NULL, FALSE)
210+-}
211+unsafeFunctionVar :: ByteString -> FunctionVar x0 x1 y
212+unsafeFunctionVar fun xs x = UnsafeExpression $ fun <> parenthesized
213+ (commaSeparated (renderSQL <$> xs) <> ", " <> renderSQL x)
214+
215+instance (HasUnique tab (Join outer from) row, Has col row ty)
216+ => IsLabel col (Expression outer commons 'Ungrouped schemas params from ty) where
217+ fromLabel = UnsafeExpression $ renderSQL (Alias @col)
218+instance (HasUnique tab (Join outer from) row, Has col row ty, tys ~ '[ty])
219+ => IsLabel col (NP (Expression outer commons 'Ungrouped schemas params from) tys) where
220+ fromLabel = fromLabel @col :* Nil
221+instance (HasUnique tab (Join outer from) row, Has col row ty, column ~ (col ::: ty))
222+ => IsLabel col
223+ (Aliased (Expression outer commons 'Ungrouped schemas params from) column) where
224+ fromLabel = fromLabel @col `As` Alias
225+instance (HasUnique tab (Join outer from) row, Has col row ty, columns ~ '[col ::: ty])
226+ => IsLabel col
227+ (NP (Aliased (Expression outer commons 'Ungrouped schemas params from)) columns) where
228+ fromLabel = fromLabel @col :* Nil
229+
230+instance (Has tab (Join outer from) row, Has col row ty)
231+ => IsQualified tab col (Expression outer commons 'Ungrouped schemas params from ty) where
232+ tab ! col = UnsafeExpression $
233+ renderSQL tab <> "." <> renderSQL col
234+instance (Has tab (Join outer from) row, Has col row ty, tys ~ '[ty])
235+ => IsQualified tab col (NP (Expression outer commons 'Ungrouped schemas params from) tys) where
236+ tab ! col = tab ! col :* Nil
237+instance (Has tab (Join outer from) row, Has col row ty, column ~ (col ::: ty))
238+ => IsQualified tab col
239+ (Aliased (Expression outer commons 'Ungrouped schemas params from) column) where
240+ tab ! col = tab ! col `As` col
241+instance (Has tab (Join outer from) row, Has col row ty, columns ~ '[col ::: ty])
242+ => IsQualified tab col
243+ (NP (Aliased (Expression outer commons 'Ungrouped schemas params from)) columns) where
244+ tab ! col = tab ! col :* Nil
288245
289246instance
290− ( HasUnique relation relations columns
291− , Has column columns ty
292− , GroupedBy relation column bys
293− ) => IsLabel column
294− (Expression schema relations ('Grouped bys) params ty) where
295− fromLabel = UnsafeExpression $ renderAlias (Alias @column)
247+ ( HasUnique tab (Join outer from) row
248+ , Has col row ty
249+ , GroupedBy tab col bys
250+ ) => IsLabel col
251+ (Expression outer commons ('Grouped bys) schemas params from ty) where
252+ fromLabel = UnsafeExpression $ renderSQL (Alias @col)
253+instance
254+ ( HasUnique tab (Join outer from) row
255+ , Has col row ty
256+ , GroupedBy tab col bys
257+ , tys ~ '[ty]
258+ ) => IsLabel col
259+ (NP (Expression outer commons ('Grouped bys) schemas params from) tys) where
260+ fromLabel = fromLabel @col :* Nil
296261instance
297− ( HasUnique relation relations columns
298− , Has column columns ty
299− , GroupedBy relation column bys
300− ) => IsLabel column
301− ( Aliased (Expression schema relations ('Grouped bys) params)
302− (column ::: ty) ) where
303− fromLabel = fromLabel @column `As` Alias @column
262+ ( HasUnique tab (Join outer from) row
263+ , Has col row ty
264+ , GroupedBy tab col bys
265+ , column ~ (col ::: ty)
266+ ) => IsLabel col
267+ (Aliased (Expression outer commons ('Grouped bys) schemas params from) column) where
268+ fromLabel = fromLabel @col `As` Alias
304269instance
305− ( HasUnique relation relations columns
306− , Has column columns ty
307− , GroupedBy relation column bys
308− ) => IsLabel column
309− ( NP (Aliased (Expression schema relations ('Grouped bys) params))
310− '[column ::: ty] ) where
311− fromLabel = fromLabel @column :* Nil
270+ ( HasUnique tab (Join outer from) row
271+ , Has col row ty
272+ , GroupedBy tab col bys
273+ , columns ~ '[col ::: ty]
274+ ) => IsLabel col
275+ (NP (Aliased (Expression outer commons ('Grouped bys) schemas params from)) columns) where
276+ fromLabel = fromLabel @col :* Nil
312277
313278instance
314− ( Has relation relations columns
315− , Has column columns ty
316− , GroupedBy relation column bys
317− ) => IsQualified relation column
318− (Expression schema relations ('Grouped bys) params ty) where
319− relation ! column = UnsafeExpression $
320− renderAlias relation <> "." <> renderAlias column
279+ ( Has tab (Join outer from) row
280+ , Has col row ty
281+ , GroupedBy tab col bys
282+ ) => IsQualified tab col
283+ (Expression outer commons ('Grouped bys) schemas params from ty) where
284+ tab ! col = UnsafeExpression $
285+ renderSQL tab <> "." <> renderSQL col
321286instance
322− ( Has relation relations columns
323− , Has column columns ty
324− , GroupedBy relation column bys
325− ) => IsQualified relation column
326− (Aliased (Expression schema relations ('Grouped bys) params)
327− (column ::: ty)) where
328− relation ! column = relation ! column `As` column
287+ ( Has tab (Join outer from) row
288+ , Has col row ty
289+ , GroupedBy tab col bys
290+ , tys ~ '[ty]
291+ ) => IsQualified tab col
292+ (NP (Expression outer commons ('Grouped bys) schemas params from) tys) where
293+ tab ! col = tab ! col :* Nil
329294instance
330− ( Has relation relations columns
331− , Has column columns ty
332− , GroupedBy relation column bys
333− ) => IsQualified relation column
334− ( NP (Aliased (Expression schema relations ('Grouped bys) params))
335− '[column ::: ty]) where
336− relation ! column = relation ! column :* Nil
337−
338−-- | analagous to `Nothing`
339−--
340−-- >>> printSQL null_
341−-- NULL
342−null_ :: Expression schema rels grouping params ('Null ty)
343−null_ = UnsafeExpression "NULL"
344−
345−-- | analagous to `Just`
346−--
347−-- >>> printSQL $ notNull true
348−-- TRUE
349−notNull
350− :: Expression schema rels grouping params ('NotNull ty)
351− -> Expression schema rels grouping params ('Null ty)
352−notNull = UnsafeExpression . renderExpression
353−
354−-- | return the leftmost value which is not NULL
355−--
356−-- >>> printSQL $ coalesce [null_, notNull true] false
357−-- COALESCE(NULL, TRUE, FALSE)
358−coalesce
359− :: [Expression schema relations grouping params ('Null ty)]
360− -- ^ @NULL@s may be present
361− -> Expression schema relations grouping params ('NotNull ty)
362− -- ^ @NULL@ is absent
363− -> Expression schema relations grouping params ('NotNull ty)
364−coalesce nullxs notNullx = UnsafeExpression $
365− "COALESCE" <> parenthesized (commaSeparated
366− ((renderExpression <$> nullxs) <> [renderExpression notNullx]))
367−
368−-- | analagous to `Data.Maybe.fromMaybe` using @COALESCE@
369−--
370−-- >>> printSQL $ fromNull true null_
371−-- COALESCE(NULL, TRUE)
372−fromNull
373− :: Expression schema relations grouping params ('NotNull ty)
374− -- ^ what to convert @NULL@ to
375− -> Expression schema relations grouping params ('Null ty)
376− -> Expression schema relations grouping params ('NotNull ty)
377−fromNull notNullx nullx = coalesce [nullx] notNullx
378−
379−-- | >>> printSQL $ null_ & isNull
380−-- NULL IS NULL
381−isNull
382− :: Expression schema relations grouping params ('Null ty)
383− -- ^ possibly @NULL@
384− -> Condition schema relations grouping params
385−isNull x = UnsafeExpression $ renderExpression x <+> "IS NULL"
386−
387−-- | >>> printSQL $ null_ & isNotNull
388−-- NULL IS NOT NULL
389−isNotNull
390− :: Expression schema relations grouping params ('Null ty)
391− -- ^ possibly @NULL@
392− -> Condition schema relations grouping params
393−isNotNull x = UnsafeExpression $ renderExpression x <+> "IS NOT NULL"
394−
395−-- | analagous to `maybe` using @IS NULL@
396−--
397−-- >>> printSQL $ matchNull true not_ null_
398−-- CASE WHEN NULL IS NULL THEN TRUE ELSE (NOT NULL) END
399−matchNull
400− :: Expression schema relations grouping params (nullty)
401− -- ^ what to convert @NULL@ to
402− -> ( Expression schema relations grouping params ('NotNull ty)
403− -> Expression schema relations grouping params (nullty) )
404− -- ^ function to perform when @NULL@ is absent
405− -> Expression schema relations grouping params ('Null ty)
406− -> Expression schema relations grouping params (nullty)
407−matchNull y f x = ifThenElse (isNull x) y
408− (f (UnsafeExpression (renderExpression x)))
409−
410−{-| right inverse to `fromNull`, if its arguments are equal then
411−`nullIf` gives @NULL@.
412−
413−>>> :set -XTypeApplications -XDataKinds
414−>>> let expr = nullIf false (param @1) :: Expression schema rels grp '[ 'NotNull 'PGbool] ('Null 'PGbool)
415−>>> printSQL expr
416−NULL IF (FALSE, ($1 :: bool))
417−-}
418−nullIf
419− :: Expression schema relations grouping params ('NotNull ty)
420− -- ^ @NULL@ is absent
421− -> Expression schema relations grouping params ('NotNull ty)
422− -- ^ @NULL@ is absent
423− -> Expression schema relations grouping params ('Null ty)
424−nullIf x y = UnsafeExpression $ "NULL IF" <+> parenthesized
425− (renderExpression x <> ", " <> renderExpression y)
426−
427−-- | >>> printSQL $ array [null_, notNull false, notNull true]
428−-- ARRAY[NULL, FALSE, TRUE]
429−array
430− :: [Expression schema relations grouping params ('Null ty)]
431− -- ^ array elements
432− -> Expression schema relations grouping params (nullity ('PGvararray ty))
433−array xs = UnsafeExpression $
434− "ARRAY[" <> commaSeparated (renderExpression <$> xs) <> "]"
295+ ( Has tab (Join outer from) row
296+ , Has col row ty
297+ , GroupedBy tab col bys
298+ , column ~ (col ::: ty)
299+ ) => IsQualified tab col
300+ (Aliased (Expression outer commons ('Grouped bys) schemas params from) column) where
301+ tab ! col = tab ! col `As` col
302+instance
303+ ( Has tab (Join outer from) row
304+ , Has col row ty
305+ , GroupedBy tab col bys
306+ , columns ~ '[col ::: ty]
307+ ) => IsQualified tab col
308+ (NP (Aliased (Expression outer commons ('Grouped bys) schemas params from)) columns) where
309+ tab ! col = tab ! col :* Nil
435310
436311instance (KnownSymbol label, label `In` labels) => IsPGlabel label
437− (Expression schema relations grouping params (nullity ('PGenum labels))) where
438− label = UnsafeExpression $ renderLabel (PGlabel @label)
439−
440−-- | A row constructor is an expression that builds a row value
441−-- (also called a composite value) using values for its member fields.
442−--
443−-- >>> type Complex = PGcomposite '["real" ::: 'PGfloat8, "imaginary" ::: 'PGfloat8]
444−-- >>> let i = row (0 `As` #real :* 1 `As` #imaginary :* Nil) :: Expression '[] '[] 'Ungrouped '[] ('NotNull Complex)
445−-- >>> printSQL i
446−-- ROW(0, 1)
447−row
448− :: SListI (Nulls fields)
449− => NP (Aliased (Expression schema relations grouping params)) (Nulls fields)
450− -- ^ zero or more expressions for the row field values
451− -> Expression schema relations grouping params (nullity ('PGcomposite fields))
452−row exprs = UnsafeExpression $ "ROW" <> parenthesized
453− (renderCommaSeparated (\ (expr `As` _) -> renderExpression expr) exprs)
454−
455−instance Has field fields ty => IsLabel field
456− ( Expression schema relation grouping params (nullity ('PGcomposite fields))
457− -> Expression schema relation grouping params ('Null ty) ) where
458− fromLabel expr = UnsafeExpression $
459− parenthesized (renderExpression expr) <> "." <>
460− fromString (symbolVal (Proxy @field))
461−
462−instance Semigroup
463− (Expression schema relations grouping params (nullity ('PGvararray ty))) where
464− (<>) = unsafeBinaryOp "||"
465−
466−instance Monoid
467− (Expression schema relations grouping params (nullity ('PGvararray ty))) where
468− mempty = array []
469− mappend = (<>)
470−
471−-- | >>> let expr = greatest currentTimestamp [param @1] :: Expression sch rels grp '[ 'NotNull 'PGtimestamptz] ('NotNull 'PGtimestamptz)
472−-- >>> printSQL expr
473−-- GREATEST(CURRENT_TIMESTAMP, ($1 :: timestamp with time zone))
474−greatest
475− :: Expression schema relations grouping params (nullty)
476− -- ^ needs at least 1 argument
477− -> [Expression schema relations grouping params (nullty)]
478− -- ^ or more
479− -> Expression schema relations grouping params (nullty)
480−greatest x xs = UnsafeExpression $ "GREATEST("
481− <> commaSeparated (renderExpression <$> (x:xs)) <> ")"
482−
483−-- | >>> printSQL $ least currentTimestamp [null_]
484−-- LEAST(CURRENT_TIMESTAMP, NULL)
485−least
486− :: Expression schema relations grouping params (nullty)
487− -- ^ needs at least 1 argument
488− -> [Expression schema relations grouping params (nullty)]
489− -- ^ or more
490− -> Expression schema relations grouping params (nullty)
491−least x xs = UnsafeExpression $ "LEAST("
492− <> commaSeparated (renderExpression <$> (x:xs)) <> ")"
312+ (Expression outer commons grp schemas params from (null ('PGenum labels))) where
313+ label = UnsafeExpression $ renderSQL (PGlabel @label)
493314
494315-- | >>> printSQL $ unsafeBinaryOp "OR" true false
495316-- (TRUE OR FALSE)
496−unsafeBinaryOp
497− :: ByteString
498− -- ^ operator
499− -> Expression schema relations grouping params (ty0)
500− -> Expression schema relations grouping params (ty1)
501− -> Expression schema relations grouping params (ty2)
317+unsafeBinaryOp :: ByteString -> Operator ty0 ty1 ty2
502318unsafeBinaryOp op x y = UnsafeExpression $ parenthesized $
503− renderExpression x <+> op <+> renderExpression y
319+ renderSQL x <+> op <+> renderSQL y
320+
321+binaryOp
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
504327
505−-- | >>> printSQL $ unsafeUnaryOp "NOT" true
328+-- | >>> printSQL $ unsafeLeftOp "NOT" true
506329-- (NOT TRUE)
507−unsafeUnaryOp
508− :: ByteString
509− -- ^ operator
510− -> Expression schema relations grouping params (ty0)
511− -> Expression schema relations grouping params (ty1)
512−unsafeUnaryOp op x = UnsafeExpression $ parenthesized $
513− op <+> renderExpression x
330+unsafeLeftOp :: ByteString -> x --> y
331+unsafeLeftOp op x = UnsafeExpression $ parenthesized $ op <+> renderSQL x
332+
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
339+
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
344+
345+rightOp
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
514351
515352-- | >>> printSQL $ unsafeFunction "f" true
516353-- f(TRUE)
517−unsafeFunction
518− :: ByteString
519− -- ^ function
520− -> Expression schema relations grouping params (xty)
521− -> Expression schema relations grouping params (yty)
354+unsafeFunction :: ByteString -> x --> y
522355unsafeFunction fun x = UnsafeExpression $
523− fun <> parenthesized (renderExpression x)
524−
525−unsafeVariadicFunction
526− :: SListI elems
527− => ByteString
528− -- ^ function
529− -> NP (Expression schema relations grouping params) elems
530− -> Expression schema relations grouping params ret
531−unsafeVariadicFunction fun x = UnsafeExpression $
532− fun <> parenthesized (commaSeparated (hcollapse (hmap (K . renderExpression) x)))
533−
534−instance PGNum ty
535− => Num (Expression schema relations grouping params (nullity ty)) where
356+ fun <> parenthesized (renderSQL x)
357+
358+function
359+ :: (Has sch schemas schema, Has fun schema ('Function ('[x] :=> 'Returns y)))
360+ => QualifiedAlias sch fun
361+ -> FunctionDB schemas x y
362+function = unsafeFunction . renderSQL
363+
364+-- | >>> printSQL $ unsafeFunctionN "f" (currentTime :* localTimestamp :* false *: literal 'a')
365+-- f(CURRENT_TIME, LOCALTIMESTAMP, FALSE, E'a')
366+unsafeFunctionN :: SListI xs => ByteString -> xs ---> y
367+unsafeFunctionN fun xs = UnsafeExpression $
368+ fun <> parenthesized (renderCommaSeparated renderSQL xs)
369+
370+functionN
371+ :: ( Has sch schemas schema
372+ , Has fun schema ('Function (xs :=> 'Returns y))
373+ , SListI xs )
374+ => QualifiedAlias sch fun
375+ -> FunctionNDB schemas xs y
376+functionN = unsafeFunctionN . renderSQL
377+
378+instance ty `In` PGNum
379+ => Num (Expression outer commons grp schemas params from (null ty)) where
536380 (+) = unsafeBinaryOp "+"
537381 (-) = unsafeBinaryOp "-"
538382 (*) = unsafeBinaryOp "*"
@@ -543,19 +387,24 @@ instance PGNum ty
543387 . fromString
544388 . show
545389
546−instance (PGNum ty, PGFloating ty) => Fractional
547− (Expression schema relations grouping params (nullity ty)) where
390+instance (ty `In` PGNum, ty `In` PGFloating) => Fractional
391+ (Expression outer commons grp schemas params from (null ty)) where
548392 (/) = unsafeBinaryOp "/"
549− fromRational x = fromInteger (numerator x) / fromInteger (denominator x)
393+ fromRational
394+ = UnsafeExpression
395+ . fromString
396+ . ($ "")
397+ . showFFloat Nothing
398+ . fromRat @Double
550399
551−instance (PGNum ty, PGFloating ty) => Floating
552− (Expression schema relations grouping params (nullity ty)) where
400+instance (ty `In` PGNum, ty `In` PGFloating) => Floating
401+ (Expression outer commons grp schemas params from (null ty)) where
553402 pi = UnsafeExpression "pi()"
554403 exp = unsafeFunction "exp"
555404 log = unsafeFunction "ln"
556405 sqrt = unsafeFunction "sqrt"
557406 b ** x = UnsafeExpression $
558− "power(" <> renderExpression b <> ", " <> renderExpression x <> ")"
407+ "power(" <> renderSQL b <> ", " <> renderSQL x <> ")"
559408 logBase b y = log y / log b
560409 sin = unsafeFunction "sin"
561410 cos = unsafeFunction "cos"
@@ -570,1049 +419,54 @@ instance (PGNum ty, PGFloating ty) => Floating
570419 acosh x = log (x + sqrt (x*x - 1))
571420 atanh x = log ((1 + x) / (1 - x)) / 2
572421
573−-- | >>> :{
574−-- let
575−-- expression :: Expression schema relations grouping params (nullity 'PGfloat4)
576−-- expression = atan2_ pi 2
577−-- in printSQL expression
578−-- :}
579−-- atan2(pi(), 2)
580−atan2_
581− :: PGFloating float
582− => Expression schema relations grouping params (nullity float)
583− -- ^ numerator
584− -> Expression schema relations grouping params (nullity float)
585− -- ^ denominator
586− -> Expression schema relations grouping params (nullity float)
587−atan2_ y x = UnsafeExpression $
588− "atan2(" <> renderExpression y <> ", " <> renderExpression x <> ")"
589−
590−-- When a `cast` is applied to an `Expression` of a known type, it
591−-- represents a run-time type conversion. The cast will succeed only if a
592−-- suitable type conversion operation has been defined.
593−--
594−-- | >>> printSQL $ true & cast int4
595−-- (TRUE :: int4)
596−cast
597− :: TypeExpression schema ty1
598− -- ^ type to cast as
599− -> Expression schema relations grouping params (nullity ty0)
600− -- ^ value to convert
601− -> Expression schema relations grouping params (nullity ty1)
602−cast ty x = UnsafeExpression $ parenthesized $
603− renderExpression x <+> "::" <+> renderTypeExpression ty
604−
605−-- | integer division, truncates the result
606−--
607−-- >>> :{
608−-- let
609−-- expression :: Expression schema relations grouping params (nullity 'PGint2)
610−-- expression = 5 `quot_` 2
611−-- in printSQL expression
612−-- :}
613−-- (5 / 2)
614−quot_
615− :: PGIntegral int
616− => Expression schema relations grouping params (nullity int)
617− -- ^ numerator
618− -> Expression schema relations grouping params (nullity int)
619− -- ^ denominator
620− -> Expression schema relations grouping params (nullity int)
621−quot_ = unsafeBinaryOp "/"
622−
623−-- | remainder upon integer division
624−--
625−-- >>> :{
626−-- let
627−-- expression :: Expression schema relations grouping params (nullity 'PGint2)
628−-- expression = 5 `rem_` 2
629−-- in printSQL expression
630−-- :}
631−-- (5 % 2)
632−rem_
633− :: PGIntegral int
634− => Expression schema relations grouping params (nullity int)
635− -- ^ numerator
636− -> Expression schema relations grouping params (nullity int)
637− -- ^ denominator
638− -> Expression schema relations grouping params (nullity int)
639−rem_ = unsafeBinaryOp "%"
640−
641−-- | >>> :{
642−-- let
643−-- expression :: Expression schema relations grouping params (nullity 'PGfloat4)
644−-- expression = trunc pi
645−-- in printSQL expression
646−-- :}
647−-- trunc(pi())
648−trunc
649− :: PGFloating frac
650− => Expression schema relations grouping params (nullity frac)
651− -- ^ fractional number
652− -> Expression schema relations grouping params (nullity frac)
653−trunc = unsafeFunction "trunc"
654−
655−-- | >>> :{
656−-- let
657−-- expression :: Expression schema relations grouping params (nullity 'PGfloat4)
658−-- expression = round_ pi
659−-- in printSQL expression
660−-- :}
661−-- round(pi())
662−round_
663− :: PGFloating frac
664− => Expression schema relations grouping params (nullity frac)
665− -- ^ fractional number
666− -> Expression schema relations grouping params (nullity frac)
667−round_ = unsafeFunction "round"
668−
669−-- | >>> :{
670−-- let
671−-- expression :: Expression schema relations grouping params (nullity 'PGfloat4)
672−-- expression = ceiling_ pi
673−-- in printSQL expression
674−-- :}
675−-- ceiling(pi())
676−ceiling_
677− :: PGFloating frac
678− => Expression schema relations grouping params (nullity frac)
679− -- ^ fractional number
680− -> Expression schema relations grouping params (nullity frac)
681−ceiling_ = unsafeFunction "ceiling"
682−
683−-- | A `Condition` is a boolean valued `Expression`. While SQL allows
684−-- conditions to have @NULL@, Squeal instead chooses to disallow @NULL@,
685−-- forcing one to handle the case of @NULL@ explicitly to produce
686−-- a `Condition`.
687−type Condition schema relations grouping params =
688− Expression schema relations grouping params ('NotNull 'PGbool)
689−
690−-- | >>> printSQL true
691−-- TRUE
692−true :: Condition schema relations grouping params
693−true = UnsafeExpression "TRUE"
694−
695−-- | >>> printSQL false
696−-- FALSE
697−false :: Condition schema relations grouping params
698−false = UnsafeExpression "FALSE"
699−
700−-- | >>> printSQL $ not_ true
701−-- (NOT TRUE)
702−not_
703− :: Condition schema relations grouping params
704− -> Condition schema relations grouping params
705−not_ = unsafeUnaryOp "NOT"
706−
707−-- | >>> printSQL $ true .&& false
708−-- (TRUE AND FALSE)
709−(.&&)
710− :: Condition schema relations grouping params
711− -> Condition schema relations grouping params
712− -> Condition schema relations grouping params
713−(.&&) = unsafeBinaryOp "AND"
714−
715−-- | >>> printSQL $ true .|| false
716−-- (TRUE OR FALSE)
717−(.||)
718− :: Condition schema relations grouping params
719− -> Condition schema relations grouping params
720− -> Condition schema relations grouping params
721−(.||) = unsafeBinaryOp "OR"
722−
723−-- | >>> :{
724−-- let
725−-- expression :: Expression schema relations grouping params (nullity 'PGint2)
726−-- expression = caseWhenThenElse [(true, 1), (false, 2)] 3
727−-- in printSQL expression
728−-- :}
729−-- CASE WHEN TRUE THEN 1 WHEN FALSE THEN 2 ELSE 3 END
730−caseWhenThenElse
731− :: [ ( Condition schema relations grouping params
732− , Expression schema relations grouping params (ty)
733− ) ]
734− -- ^ whens and thens
735− -> Expression schema relations grouping params (ty)
736− -- ^ else
737− -> Expression schema relations grouping params (ty)
738−caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
739− [ "CASE"
740− , mconcat
741− [ mconcat
742− [ " WHEN ", renderExpression when_
743− , " THEN ", renderExpression then_
744− ]
745− | (when_,then_) <- whenThens
746− ]
747− , " ELSE ", renderExpression else_
748− , " END"
749− ]
750−
751−-- | >>> :{
752−-- let
753−-- expression :: Expression schema relations grouping params (nullity 'PGint2)
754−-- expression = ifThenElse true 1 0
755−-- in printSQL expression
756−-- :}
757−-- CASE WHEN TRUE THEN 1 ELSE 0 END
758−ifThenElse
759− :: Condition schema relations grouping params
760− -> Expression schema relations grouping params (ty) -- ^ then
761− -> Expression schema relations grouping params (ty) -- ^ else
762− -> Expression schema relations grouping params (ty)
763−ifThenElse if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
764−
765−-- | Comparison operations like `.==`, `./=`, `.>`, `.>=`, `.<` and `.<=`
766−-- will produce @NULL@s if one of their arguments is @NULL@.
767−--
768−-- >>> printSQL $ notNull true .== null_
769−-- (TRUE = NULL)
770−(.==)
771− :: Expression schema relations grouping params (nullity ty) -- ^ lhs
772− -> Expression schema relations grouping params (nullity ty) -- ^ rhs
773− -> Expression schema relations grouping params (nullity 'PGbool)
774−(.==) = unsafeBinaryOp "="
775−infix 4 .==
776−
777−-- | >>> printSQL $ notNull true ./= null_
778−-- (TRUE <> NULL)
779−(./=)
780− :: Expression schema relations grouping params (nullity ty) -- ^ lhs
781− -> Expression schema relations grouping params (nullity ty) -- ^ rhs
782− -> Expression schema relations grouping params (nullity 'PGbool)
783−(./=) = unsafeBinaryOp "<>"
784−infix 4 ./=
785−
786−-- | >>> printSQL $ notNull true .>= null_
787−-- (TRUE >= NULL)
788−(.>=)
789− :: Expression schema relations grouping params (nullity ty) -- ^ lhs
790− -> Expression schema relations grouping params (nullity ty) -- ^ rhs
791− -> Expression schema relations grouping params (nullity 'PGbool)
792−(.>=) = unsafeBinaryOp ">="
793−infix 4 .>=
794−
795−-- | >>> printSQL $ notNull true .< null_
796−-- (TRUE < NULL)
797−(.<)
798− :: Expression schema relations grouping params (nullity ty) -- ^ lhs
799− -> Expression schema relations grouping params (nullity ty) -- ^ rhs
800− -> Expression schema relations grouping params (nullity 'PGbool)
801−(.<) = unsafeBinaryOp "<"
802−infix 4 .<
803−
804−-- | >>> printSQL $ notNull true .<= null_
805−-- (TRUE <= NULL)
806−(.<=)
807− :: Expression schema relations grouping params (nullity ty) -- ^ lhs
808− -> Expression schema relations grouping params (nullity ty) -- ^ rhs
809− -> Expression schema relations grouping params (nullity 'PGbool)
810−(.<=) = unsafeBinaryOp "<="
811−infix 4 .<=
812−
813−-- | >>> printSQL $ notNull true .> null_
814−-- (TRUE > NULL)
815−(.>)
816− :: Expression schema relations grouping params (nullity ty) -- ^ lhs
817− -> Expression schema relations grouping params (nullity ty) -- ^ rhs
818− -> Expression schema relations grouping params (nullity 'PGbool)
819−(.>) = unsafeBinaryOp ">"
820−infix 4 .>
821−
822−-- | >>> printSQL currentDate
823−-- CURRENT_DATE
824−currentDate
825− :: Expression schema relations grouping params (nullity 'PGdate)
826−currentDate = UnsafeExpression "CURRENT_DATE"
827−
828−-- | >>> printSQL currentTime
829−-- CURRENT_TIME
830−currentTime
831− :: Expression schema relations grouping params (nullity 'PGtimetz)
832−currentTime = UnsafeExpression "CURRENT_TIME"
833−
834−-- | >>> printSQL currentTimestamp
835−-- CURRENT_TIMESTAMP
836−currentTimestamp
837− :: Expression schema relations grouping params (nullity 'PGtimestamptz)
838−currentTimestamp = UnsafeExpression "CURRENT_TIMESTAMP"
839−
840−-- | >>> printSQL localTime
841−-- LOCALTIME
842−localTime
843− :: Expression schema relations grouping params (nullity 'PGtime)
844−localTime = UnsafeExpression "LOCALTIME"
845−
846−-- | >>> printSQL localTimestamp
847−-- LOCALTIMESTAMP
848−localTimestamp
849− :: Expression schema relations grouping params (nullity 'PGtimestamp)
850−localTimestamp = UnsafeExpression "LOCALTIMESTAMP"
851−
852−{-----------------------------------------
853−text
854−-----------------------------------------}
422+-- | Contained by operators
423+class PGSubset ty where
424+ (@>) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
425+ (@>) = unsafeBinaryOp "@>"
426+ (<@) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
427+ (<@) = unsafeBinaryOp "<@"
428+instance PGSubset 'PGjsonb
429+instance PGSubset 'PGtsquery
430+instance PGSubset ('PGvararray ty)
431+instance PGSubset ('PGrange ty)
432+
433+class PGIntersect ty where
434+ (@&&) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
435+ (@&&) = unsafeBinaryOp "&&"
436+instance PGIntersect ('PGvararray ty)
437+instance PGIntersect ('PGrange ty)
855438
856439instance IsString
857− (Expression schema relations grouping params (nullity 'PGtext)) where
440+ (Expression outer commons grp schemas params from (null 'PGtext)) where
858441 fromString str = UnsafeExpression $
859442 "E\'" <> fromString (escape =<< str) <> "\'"
860− where
861− escape = \case
862− '\NUL' -> "\\0"
863− '\'' -> "''"
864− '"' -> "\\\""
865− '\b' -> "\\b"
866− '\n' -> "\\n"
867− '\r' -> "\\r"
868− '\t' -> "\\t"
869− '\\' -> "\\\\"
870− c -> [c]
443+instance IsString
444+ (Expression outer commons grp schemas params from (null 'PGtsvector)) where
445+ fromString str = UnsafeExpression . parenthesized . (<> " :: tsvector") $
446+ "E\'" <> fromString (escape =<< str) <> "\'"
447+instance IsString
448+ (Expression outer commons grp schemas params from (null 'PGtsquery)) where
449+ fromString str = UnsafeExpression . parenthesized . (<> " :: tsquery") $
450+ "E\'" <> fromString (escape =<< str) <> "\'"
871451
872452instance Semigroup
873− (Expression schema relations grouping params (nullity 'PGtext)) where
453+ (Expression outer commons grp schemas params from (null ('PGvararray ty))) where
454+ (<>) = unsafeBinaryOp "||"
455+instance Semigroup
456+ (Expression outer commons grp schemas params from (null 'PGjsonb)) where
457+ (<>) = unsafeBinaryOp "||"
458+instance Semigroup
459+ (Expression outer commons grp schemas params from (null 'PGtext)) where
460+ (<>) = unsafeBinaryOp "||"
461+instance Semigroup
462+ (Expression outer commons grp schemas params from (null 'PGtsvector)) where
874463 (<>) = unsafeBinaryOp "||"
875464
876465instance Monoid
877− (Expression schema relations grouping params (nullity 'PGtext)) where
466+ (Expression outer commons grp schemas params from (null 'PGtext)) where
467+ mempty = fromString ""
468+ mappend = (<>)
469+instance Monoid
470+ (Expression outer commons grp schemas params from (null 'PGtsvector)) where
878471 mempty = fromString ""
879472 mappend = (<>)
880−
881−-- | >>> printSQL $ lower "ARRRGGG"
882−-- lower(E'ARRRGGG')
883−lower
884− :: Expression schema relations grouping params (nullity 'PGtext)
885− -- ^ string to lower case
886− -> Expression schema relations grouping params (nullity 'PGtext)
887−lower = unsafeFunction "lower"
888−
889−-- | >>> printSQL $ upper "eeee"
890−-- upper(E'eeee')
891−upper
892− :: Expression schema relations grouping params (nullity 'PGtext)
893− -- ^ string to upper case
894− -> Expression schema relations grouping params (nullity 'PGtext)
895−upper = unsafeFunction "upper"
896−
897−-- | >>> printSQL $ charLength "four"
898−-- char_length(E'four')
899−charLength
900− :: Expression schema relations grouping params (nullity 'PGtext)
901− -- ^ string to measure
902− -> Expression schema relations grouping params (nullity 'PGint4)
903−charLength = unsafeFunction "char_length"
904−
905−-- | The `like` expression returns true if the @string@ matches
906−-- the supplied @pattern@. If @pattern@ does not contain percent signs
907−-- or underscores, then the pattern only represents the string itself;
908−-- in that case `like` acts like the equals operator. An underscore (_)
909−-- in pattern stands for (matches) any single character; a percent sign (%)
910−-- matches any sequence of zero or more characters.
911−--
912−-- >>> printSQL $ "abc" `like` "a%"
913−-- (E'abc' LIKE E'a%')
914−like
915− :: Expression schema relations grouping params (nullity 'PGtext)
916− -- ^ string
917− -> Expression schema relations grouping params (nullity 'PGtext)
918− -- ^ pattern
919− -> Expression schema relations grouping params (nullity 'PGbool)
920−like = unsafeBinaryOp "LIKE"
921−
922−{-----------------------------------------
923− -- json and jsonb support
924−
925−See https://www.postgresql.org/docs/10/static/functions-json.html -- most
926−comments lifted directly from this page.
927−
928−Table 9.44: json and jsonb operators
929−-----------------------------------------}
930−
931−-- | Get JSON value (object field or array element) at a key.
932−(.->)
933− :: (PGjson_ json, PGjsonKey key)
934− => Expression schema relations grouping params (nullity json)
935− -> Expression schema relations grouping params (nullity key)
936− -> Expression schema relations grouping params ('Null json)
937−(.->) = unsafeBinaryOp "->"
938−
939−-- | Get JSON value (object field or array element) at a key, as text.
940−(.->>)
941− :: (PGjson_ json, PGjsonKey key)
942− => Expression schema relations grouping params (nullity json)
943− -> Expression schema relations grouping params (nullity key)
944− -> Expression schema relations grouping params ('Null 'PGtext)
945−(.->>) = unsafeBinaryOp "->>"
946−
947−-- | Get JSON value at a specified path.
948−(.#>)
949− :: (PGjson_ json, PGtextArray "(.#>)" path)
950− => Expression schema relations grouping params (nullity json)
951− -> Expression schema relations grouping params (nullity path)
952− -> Expression schema relations grouping params ('Null json)
953−(.#>) = unsafeBinaryOp "#>"
954−
955−-- | Get JSON value at a specified path as text.
956−(.#>>)
957− :: (PGjson_ json, PGtextArray "(.#>>)" path)
958− => Expression schema relations grouping params (nullity json)
959− -> Expression schema relations grouping params (nullity path)
960− -> Expression schema relations grouping params ('Null 'PGtext)
961−(.#>>) = unsafeBinaryOp "#>>"
962−
963−-- Additional jsonb operators
964−
965−-- | Does the left JSON value contain the right JSON path/value entries at the
966−-- top level?
967−(.@>)
968− :: Expression schema relations grouping params (nullity 'PGjsonb)
969− -> Expression schema relations grouping params (nullity 'PGjsonb)
970− -> Expression schema relations grouping params ('NotNull 'PGbool)
971−(.@>) = unsafeBinaryOp "@>"
972−
973−-- | Are the left JSON path/value entries contained at the top level within the
974−-- right JSON value?
975−(.<@)
976− :: Expression schema relations grouping params (nullity 'PGjsonb)
977− -> Expression schema relations grouping params (nullity 'PGjsonb)
978− -> Expression schema relations grouping params ('NotNull 'PGbool)
979−(.<@) = unsafeBinaryOp "<@"
980−
981−-- | Does the string exist as a top-level key within the JSON value?
982−(.?)
983− :: Expression schema relations grouping params (nullity 'PGjsonb)
984− -> Expression schema relations grouping params (nullity 'PGtext)
985− -> Expression schema relations grouping params ('NotNull 'PGbool)
986−(.?) = unsafeBinaryOp "?"
987−
988−-- | Do any of these array strings exist as top-level keys?
989−(.?|)
990− :: Expression schema relations grouping params (nullity 'PGjsonb)
991− -> Expression schema relations grouping params (nullity ('PGvararray 'PGtext))
992− -> Expression schema relations grouping params ('NotNull 'PGbool)
993−(.?|) = unsafeBinaryOp "?|"
994−
995−-- | Do all of these array strings exist as top-level keys?
996−(.?&)
997− :: Expression schema relations grouping params (nullity 'PGjsonb)
998− -> Expression schema relations grouping params (nullity ('PGvararray 'PGtext))
999− -> Expression schema relations grouping params ('NotNull 'PGbool)
1000−(.?&) = unsafeBinaryOp "?&"
1001−
1002−-- | Concatenate two jsonb values into a new jsonb value.
1003−(.||.)
1004− :: Expression schema relations grouping params (nullity 'PGjsonb)
1005− -> Expression schema relations grouping params (nullity 'PGjsonb)
1006− -> Expression schema relations grouping params (nullity 'PGjsonb)
1007−(.||.) = unsafeBinaryOp "||"
1008−
1009−-- | Delete a key or keys from a JSON object, or remove an array element.
1010−--
1011−-- If the right operand is..
1012−--
1013−-- @ text @: Delete key/value pair or string element from left operand. Key/value pairs
1014−-- are matched based on their key value.
1015−--
1016−-- @ text[] @: Delete multiple key/value pairs or string elements
1017−-- from left operand. Key/value pairs are matched based on their key value.
1018−--
1019−-- @ integer @: Delete the array element with specified index (Negative integers
1020−-- count from the end). Throws an error if top level container is not an array.
1021−(.-.)
1022− :: (key `In` '[ 'PGtext, 'PGvararray 'PGtext, 'PGint4, 'PGint2 ]) -- hlint error without parens here
1023− => Expression schema relations grouping params (nullity 'PGjsonb)
1024− -> Expression schema relations grouping params (nullity key)
1025− -> Expression schema relations grouping params (nullity 'PGjsonb)
1026−(.-.) = unsafeBinaryOp "-"
1027−
1028−-- | Delete the field or element with specified path (for JSON arrays, negative
1029−-- integers count from the end)
1030−(#-.)
1031− :: PGtextArray "(#-.)" arrayty
1032− => Expression schema relations grouping params (nullity 'PGjsonb)
1033− -> Expression schema relations grouping params (nullity arrayty)
1034− -> Expression schema relations grouping params (nullity 'PGjsonb)
1035−(#-.) = unsafeBinaryOp "#-"
1036−
1037−{-----------------------------------------
1038−Table 9.45: JSON creation functions
1039−-----------------------------------------}
1040−
1041−-- | Returns the value as json. Arrays and composites are converted
1042−-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1043−-- type to json, the cast function will be used to perform the conversion;
1044−-- otherwise, a scalar value is produced. For any scalar type other than a
1045−-- number, a Boolean, or a null value, the text representation will be used, in
1046−-- such a fashion that it is a valid json value.
1047−toJson
1048− :: Expression schema relations grouping params (nullity ty)
1049− -> Expression schema relations grouping params (nullity 'PGjson)
1050−toJson = unsafeFunction "to_json"
1051−
1052−-- | Returns the value as jsonb. Arrays and composites are converted
1053−-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1054−-- type to json, the cast function will be used to perform the conversion;
1055−-- otherwise, a scalar value is produced. For any scalar type other than a
1056−-- number, a Boolean, or a null value, the text representation will be used, in
1057−-- such a fashion that it is a valid jsonb value.
1058−toJsonb
1059− :: Expression schema relations grouping params (nullity ty)
1060− -> Expression schema relations grouping params (nullity 'PGjsonb)
1061−toJsonb = unsafeUnaryOp "to_jsonb"
1062−
1063−-- | Returns the array as a JSON array. A PostgreSQL multidimensional array
1064−-- becomes a JSON array of arrays. Line feeds will be added between dimension-1
1065−-- elements if pretty_bool is true.
1066−arrayToJson
1067− :: PGarray "arrayToJson" arr
1068− => Expression schema relations grouping params (nullity arr)
1069− -> Expression schema relations grouping params (nullity 'PGjson)
1070−arrayToJson = unsafeFunction "array_to_json"
1071−
1072−-- | Returns the row as a JSON object. Line feeds will be added between level-1
1073−-- elements if pretty_bool is true.
1074−rowToJson
1075− :: Expression schema relations grouping params (nullity ('PGcomposite ty))
1076− -> Expression schema relations grouping params (nullity 'PGjson)
1077−rowToJson = unsafeFunction "row_to_json"
1078−
1079−-- | Builds a possibly-heterogeneously-typed JSON array out of a variadic
1080−-- argument list.
1081−jsonBuildArray
1082− :: SListI elems
1083− => NP (Expression schema relations grouping params) elems
1084− -> Expression schema relations grouping params (nullity 'PGjson)
1085−jsonBuildArray = unsafeVariadicFunction "json_build_array"
1086−
1087−-- | Builds a possibly-heterogeneously-typed (binary) JSON array out of a
1088−-- variadic argument list.
1089−jsonbBuildArray
1090− :: SListI elems
1091− => NP (Expression schema relations grouping params) elems
1092− -> Expression schema relations grouping params (nullity 'PGjsonb)
1093−jsonbBuildArray = unsafeVariadicFunction "jsonb_build_array"
1094−
1095−-- | Builds a possibly-heterogeneously-typed JSON object out of a variadic
1096−-- argument list. The elements of the argument list must alternate between text
1097−-- and values.
1098−jsonBuildObject
1099− :: (PGobjectpairs "jsonBuildObject" elems, SListI elems)
1100− => NP (Expression schema relations grouping params) elems
1101− -> Expression schema relations grouping params (nullity 'PGjson)
1102−jsonBuildObject = unsafeVariadicFunction "json_build_object"
1103−
1104−-- | Builds a possibly-heterogeneously-typed (binary) JSON object out of a
1105−-- variadic argument list. The elements of the argument list must alternate
1106−-- between text and values.
1107−jsonbBuildObject
1108− :: (PGobjectpairs "jsonbBuildObject" elems, SListI elems)
1109− => NP (Expression schema relations grouping params) elems
1110− -> Expression schema relations grouping params (nullity 'PGjsonb)
1111−jsonbBuildObject = unsafeVariadicFunction "jsonb_build_object"
1112−
1113−-- | Builds a JSON object out of a text array. The array must have either
1114−-- exactly one dimension with an even number of members, in which case they are
1115−-- taken as alternating key/value pairs, or two dimensions such that each inner
1116−-- array has exactly two elements, which are taken as a key/value pair.
1117−jsonObject
1118− :: PGarrayOf "jsonObject" arr 'PGtext
1119− => Expression schema relations grouping params (nullity arr)
1120− -> Expression schema relations grouping params (nullity 'PGjson)
1121−jsonObject = unsafeFunction "json_object"
1122−
1123−-- | Builds a binary JSON object out of a text array. The array must have either
1124−-- exactly one dimension with an even number of members, in which case they are
1125−-- taken as alternating key/value pairs, or two dimensions such that each inner
1126−-- array has exactly two elements, which are taken as a key/value pair.
1127−jsonbObject
1128− :: PGarrayOf "jsonbObject" arr 'PGtext
1129− => Expression schema relations grouping params (nullity arr)
1130− -> Expression schema relations grouping params (nullity 'PGjsonb)
1131−jsonbObject = unsafeFunction "jsonb_object"
1132−
1133−-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1134−-- keys and one for values, that are zipped pairwise to create a JSON object.
1135−jsonZipObject
1136− :: ( PGarrayOf "jsonZipObject" keysArray 'PGtext
1137− , PGarrayOf "jsonZipObject" valuesArray 'PGtext)
1138− => Expression schema relations grouping params (nullity keysArray)
1139− -> Expression schema relations grouping params (nullity valuesArray)
1140− -> Expression schema relations grouping params (nullity 'PGjson)
1141−jsonZipObject ks vs =
1142− unsafeVariadicFunction "json_object" (ks :* vs :* Nil)
1143−
1144−-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1145−-- keys and one for values, that are zipped pairwise to create a binary JSON
1146−-- object.
1147−jsonbZipObject
1148− :: ( PGarrayOf "jsonbZipObject" keysArray 'PGtext
1149− , PGarrayOf "jsonbZipObject" valuesArray 'PGtext)
1150− => Expression schema relations grouping params (nullity keysArray)
1151− -> Expression schema relations grouping params (nullity valuesArray)
1152− -> Expression schema relations grouping params (nullity 'PGjsonb)
1153−jsonbZipObject ks vs =
1154− unsafeVariadicFunction "jsonb_object" (ks :* vs :* Nil)
1155−
1156−{-----------------------------------------
1157−Table 9.46: JSON processing functions
1158−-----------------------------------------}
1159−
1160−-- | Returns the number of elements in the outermost JSON array.
1161−jsonArrayLength
1162− :: Expression schema relations grouping params (nullity 'PGjson)
1163− -> Expression schema relations grouping params (nullity 'PGint4)
1164−jsonArrayLength = unsafeFunction "json_array_length"
1165−
1166−-- | Returns the number of elements in the outermost binary JSON array.
1167−jsonbArrayLength
1168− :: Expression schema relations grouping params (nullity 'PGjsonb)
1169− -> Expression schema relations grouping params (nullity 'PGint4)
1170−jsonbArrayLength = unsafeFunction "jsonb_array_length"
1171−
1172−-- | Returns JSON value pointed to by path_elems (equivalent to #> operator).
1173−jsonExtractPath
1174− :: SListI elems
1175− => Expression schema relations grouping params (nullity 'PGjson)
1176− -> NP (Expression schema relations grouping params) elems
1177− -> Expression schema relations grouping params (nullity 'PGjsonb)
1178−jsonExtractPath x xs =
1179− unsafeVariadicFunction "json_extract_path" (x :* xs)
1180−
1181−-- | Returns JSON value pointed to by path_elems (equivalent to #> operator).
1182−jsonbExtractPath
1183− :: SListI elems
1184− => Expression schema relations grouping params (nullity 'PGjsonb)
1185− -> NP (Expression schema relations grouping params) elems
1186− -> Expression schema relations grouping params (nullity 'PGjsonb)
1187−jsonbExtractPath x xs =
1188− unsafeVariadicFunction "jsonb_extract_path" (x :* xs)
1189−
1190−-- | Returns JSON value pointed to by path_elems (equivalent to #> operator),
1191−-- as text.
1192−jsonExtractPathAsText
1193− :: SListI elems
1194− => Expression schema relations grouping params (nullity 'PGjson)
1195− -> NP (Expression schema relations grouping params) elems
1196− -> Expression schema relations grouping params (nullity 'PGjsonb)
1197−jsonExtractPathAsText x xs =
1198− unsafeVariadicFunction "json_extract_path_text" (x :* xs)
1199−
1200−-- | Returns JSON value pointed to by path_elems (equivalent to #> operator),
1201−-- as text.
1202−jsonbExtractPathAsText
1203− :: SListI elems
1204− => Expression schema relations grouping params (nullity 'PGjsonb)
1205− -> NP (Expression schema relations grouping params) elems
1206− -> Expression schema relations grouping params (nullity 'PGjsonb)
1207−jsonbExtractPathAsText x xs =
1208− unsafeVariadicFunction "jsonb_extract_path_text" (x :* xs)
1209−
1210−-- | Returns set of keys in the outermost JSON object.
1211−jsonObjectKeys
1212− :: Expression schema relations grouping params (nullity 'PGjson)
1213− -> Expression schema relations grouping params (nullity 'PGtext)
1214−jsonObjectKeys = unsafeFunction "json_object_keys"
1215−
1216−-- | Returns set of keys in the outermost JSON object.
1217−jsonbObjectKeys
1218− :: Expression schema relations grouping params (nullity 'PGjsonb)
1219− -> Expression schema relations grouping params (nullity 'PGtext)
1220−jsonbObjectKeys = unsafeFunction "jsonb_object_keys"
1221−
1222−-- | Returns the type of the outermost JSON value as a text string. Possible
1223−-- types are object, array, string, number, boolean, and null.
1224−jsonTypeof
1225− :: Expression schema relations grouping params (nullity 'PGjson)
1226− -> Expression schema relations grouping params (nullity 'PGtext)
1227−jsonTypeof = unsafeFunction "json_typeof"
1228−
1229−-- | Returns the type of the outermost binary JSON value as a text string.
1230−-- Possible types are object, array, string, number, boolean, and null.
1231−jsonbTypeof
1232− :: Expression schema relations grouping params (nullity 'PGjsonb)
1233− -> Expression schema relations grouping params (nullity 'PGtext)
1234−jsonbTypeof = unsafeFunction "jsonb_typeof"
1235−
1236−{-----------------------------------------
1237−aggregation
1238−-----------------------------------------}
1239−
1240−-- | escape hatch to define aggregate functions
1241−unsafeAggregate
1242− :: ByteString -- ^ aggregate function
1243− -> Expression schema relations 'Ungrouped params (xty)
1244− -> Expression schema relations ('Grouped bys) params (yty)
1245−unsafeAggregate fun x = UnsafeExpression $ mconcat
1246− [fun, "(", renderExpression x, ")"]
1247−
1248−-- | escape hatch to define aggregate functions over distinct values
1249−unsafeAggregateDistinct
1250− :: ByteString -- ^ aggregate function
1251− -> Expression schema relations 'Ungrouped params (xty)
1252− -> Expression schema relations ('Grouped bys) params (yty)
1253−unsafeAggregateDistinct fun x = UnsafeExpression $ mconcat
1254− [fun, "(DISTINCT ", renderExpression x, ")"]
1255−
1256−-- | >>> :{
1257−-- let
1258−-- expression :: Expression schema '[tab ::: '["col" ::: 'Null 'PGnumeric]] ('Grouped bys) params ('Null 'PGnumeric)
1259−-- expression = sum_ #col
1260−-- in printSQL expression
1261−-- :}
1262−-- sum("col")
1263−sum_
1264− :: PGNum ty
1265− => Expression schema relations 'Ungrouped params (nullity ty)
1266− -- ^ what to sum
1267− -> Expression schema relations ('Grouped bys) params (nullity ty)
1268−sum_ = unsafeAggregate "sum"
1269−
1270−-- | >>> :{
1271−-- let
1272−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGnumeric]] ('Grouped bys) params (nullity 'PGnumeric)
1273−-- expression = sumDistinct #col
1274−-- in printSQL expression
1275−-- :}
1276−-- sum(DISTINCT "col")
1277−sumDistinct
1278− :: PGNum ty
1279− => Expression schema relations 'Ungrouped params (nullity ty)
1280− -- ^ what to sum
1281− -> Expression schema relations ('Grouped bys) params (nullity ty)
1282−sumDistinct = unsafeAggregateDistinct "sum"
1283−
1284−-- | A constraint for `PGType`s that you can take averages of and the resulting
1285−-- `PGType`.
1286−class PGAvg ty avg | ty -> avg where
1287− avg, avgDistinct
1288− :: Expression schema relations 'Ungrouped params (nullity ty)
1289− -- ^ what to average
1290− -> Expression schema relations ('Grouped bys) params (nullity avg)
1291− avg = unsafeAggregate "avg"
1292− avgDistinct = unsafeAggregateDistinct "avg"
1293−instance PGAvg 'PGint2 'PGnumeric
1294−instance PGAvg 'PGint4 'PGnumeric
1295−instance PGAvg 'PGint8 'PGnumeric
1296−instance PGAvg 'PGnumeric 'PGnumeric
1297−instance PGAvg 'PGfloat4 'PGfloat8
1298−instance PGAvg 'PGfloat8 'PGfloat8
1299−instance PGAvg 'PGinterval 'PGinterval
1300−
1301−-- | >>> :{
1302−-- let
1303−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
1304−-- expression = bitAnd #col
1305−-- in printSQL expression
1306−-- :}
1307−-- bit_and("col")
1308−bitAnd
1309− :: PGIntegral int
1310− => Expression schema relations 'Ungrouped params (nullity int)
1311− -- ^ what to aggregate
1312− -> Expression schema relations ('Grouped bys) params (nullity int)
1313−bitAnd = unsafeAggregate "bit_and"
1314−
1315−-- | >>> :{
1316−-- let
1317−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
1318−-- expression = bitOr #col
1319−-- in printSQL expression
1320−-- :}
1321−-- bit_or("col")
1322−bitOr
1323− :: PGIntegral int
1324− => Expression schema relations 'Ungrouped params (nullity int)
1325− -- ^ what to aggregate
1326− -> Expression schema relations ('Grouped bys) params (nullity int)
1327−bitOr = unsafeAggregate "bit_or"
1328−
1329−-- | >>> :{
1330−-- let
1331−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
1332−-- expression = bitAndDistinct #col
1333−-- in printSQL expression
1334−-- :}
1335−-- bit_and(DISTINCT "col")
1336−bitAndDistinct
1337− :: PGIntegral int
1338− => Expression schema relations 'Ungrouped params (nullity int)
1339− -- ^ what to aggregate
1340− -> Expression schema relations ('Grouped bys) params (nullity int)
1341−bitAndDistinct = unsafeAggregateDistinct "bit_and"
1342−
1343−-- | >>> :{
1344−-- let
1345−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
1346−-- expression = bitOrDistinct #col
1347−-- in printSQL expression
1348−-- :}
1349−-- bit_or(DISTINCT "col")
1350−bitOrDistinct
1351− :: PGIntegral int
1352− => Expression schema relations 'Ungrouped params (nullity int)
1353− -- ^ what to aggregate
1354− -> Expression schema relations ('Grouped bys) params (nullity int)
1355−bitOrDistinct = unsafeAggregateDistinct "bit_or"
1356−
1357−-- | >>> :{
1358−-- let
1359−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1360−-- expression = boolAnd #col
1361−-- in printSQL expression
1362−-- :}
1363−-- bool_and("col")
1364−boolAnd
1365− :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1366− -- ^ what to aggregate
1367− -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1368−boolAnd = unsafeAggregate "bool_and"
1369−
1370−-- | >>> :{
1371−-- let
1372−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1373−-- expression = boolOr #col
1374−-- in printSQL expression
1375−-- :}
1376−-- bool_or("col")
1377−boolOr
1378− :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1379− -- ^ what to aggregate
1380− -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1381−boolOr = unsafeAggregate "bool_or"
1382−
1383−-- | >>> :{
1384−-- let
1385−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1386−-- expression = boolAndDistinct #col
1387−-- in printSQL expression
1388−-- :}
1389−-- bool_and(DISTINCT "col")
1390−boolAndDistinct
1391− :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1392− -- ^ what to aggregate
1393− -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1394−boolAndDistinct = unsafeAggregateDistinct "bool_and"
1395−
1396−-- | >>> :{
1397−-- let
1398−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1399−-- expression = boolOrDistinct #col
1400−-- in printSQL expression
1401−-- :}
1402−-- bool_or(DISTINCT "col")
1403−boolOrDistinct
1404− :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1405− -- ^ what to aggregate
1406− -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1407−boolOrDistinct = unsafeAggregateDistinct "bool_or"
1408−
1409−-- | A special aggregation that does not require an input
1410−--
1411−-- >>> printSQL countStar
1412−-- count(*)
1413−countStar
1414− :: Expression schema relations ('Grouped bys) params ('NotNull 'PGint8)
1415−countStar = UnsafeExpression $ "count(*)"
1416−
1417−-- | >>> :{
1418−-- let
1419−-- expression :: Expression schema '[tab ::: '["col" ::: nullity ty]] (Grouped bys) params ('NotNull 'PGint8)
1420−-- expression = count #col
1421−-- in printSQL expression
1422−-- :}
1423−-- count("col")
1424−count
1425− :: Expression schema relations 'Ungrouped params ty
1426− -- ^ what to count
1427− -> Expression schema relations ('Grouped bys) params ('NotNull 'PGint8)
1428−count = unsafeAggregate "count"
1429−
1430−-- | >>> :{
1431−-- let
1432−-- expression :: Expression schema '[tab ::: '["col" ::: nullity ty]] (Grouped bys) params ('NotNull 'PGint8)
1433−-- expression = countDistinct #col
1434−-- in printSQL expression
1435−-- :}
1436−-- count(DISTINCT "col")
1437−countDistinct
1438− :: Expression schema relations 'Ungrouped params ty
1439− -- ^ what to count
1440− -> Expression schema relations ('Grouped bys) params ('NotNull 'PGint8)
1441−countDistinct = unsafeAggregateDistinct "count"
1442−
1443−-- | synonym for `boolAnd`
1444−--
1445−-- >>> :{
1446−-- let
1447−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1448−-- expression = every #col
1449−-- in printSQL expression
1450−-- :}
1451−-- every("col")
1452−every
1453− :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1454− -- ^ what to aggregate
1455− -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1456−every = unsafeAggregate "every"
1457−
1458−-- | synonym for `boolAndDistinct`
1459−--
1460−-- >>> :{
1461−-- let
1462−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1463−-- expression = everyDistinct #col
1464−-- in printSQL expression
1465−-- :}
1466−-- every(DISTINCT "col")
1467−everyDistinct
1468− :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1469− -- ^ what to aggregate
1470− -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1471−everyDistinct = unsafeAggregateDistinct "every"
1472−
1473−-- | minimum and maximum aggregation
1474−max_, min_, maxDistinct, minDistinct
1475− :: Expression schema relations 'Ungrouped params (nullity ty)
1476− -- ^ what to aggregate
1477− -> Expression schema relations ('Grouped bys) params (nullity ty)
1478−max_ = unsafeAggregate "max"
1479−min_ = unsafeAggregate "min"
1480−maxDistinct = unsafeAggregateDistinct "max"
1481−minDistinct = unsafeAggregateDistinct "min"
1482−
1483−{-----------------------------------------
1484−type expressions
1485−-----------------------------------------}
1486−
1487−-- | `TypeExpression`s are used in `cast`s and `createTable` commands.
1488−newtype TypeExpression (schema :: SchemaType) (ty :: PGType)
1489− = UnsafeTypeExpression { renderTypeExpression :: ByteString }
1490− deriving (GHC.Generic,Show,Eq,Ord,NFData)
1491−
1492−instance (Has alias schema ('Typedef ty))
1493− => IsLabel alias (TypeExpression schema ty) where
1494− fromLabel = UnsafeTypeExpression (renderAlias (fromLabel @alias))
1495−
1496−-- | logical Boolean (true/false)
1497−bool :: TypeExpression schema 'PGbool
1498−bool = UnsafeTypeExpression "bool"
1499−-- | signed two-byte integer
1500−int2, smallint :: TypeExpression schema 'PGint2
1501−int2 = UnsafeTypeExpression "int2"
1502−smallint = UnsafeTypeExpression "smallint"
1503−-- | signed four-byte integer
1504−int4, int, integer :: TypeExpression schema 'PGint4
1505−int4 = UnsafeTypeExpression "int4"
1506−int = UnsafeTypeExpression "int"
1507−integer = UnsafeTypeExpression "integer"
1508−-- | signed eight-byte integer
1509−int8, bigint :: TypeExpression schema 'PGint8
1510−int8 = UnsafeTypeExpression "int8"
1511−bigint = UnsafeTypeExpression "bigint"
1512−-- | arbitrary precision numeric type
1513−numeric :: TypeExpression schema 'PGnumeric
1514−numeric = UnsafeTypeExpression "numeric"
1515−-- | single precision floating-point number (4 bytes)
1516−float4, real :: TypeExpression schema 'PGfloat4
1517−float4 = UnsafeTypeExpression "float4"
1518−real = UnsafeTypeExpression "real"
1519−-- | double precision floating-point number (8 bytes)
1520−float8, doublePrecision :: TypeExpression schema 'PGfloat8
1521−float8 = UnsafeTypeExpression "float8"
1522−doublePrecision = UnsafeTypeExpression "double precision"
1523−-- | variable-length character string
1524−text :: TypeExpression schema 'PGtext
1525−text = UnsafeTypeExpression "text"
1526−-- | fixed-length character string
1527−char, character
1528− :: (KnownNat n, 1 <= n)
1529− => proxy n
1530− -> TypeExpression schema ('PGchar n)
1531−char p = UnsafeTypeExpression $ "char(" <> renderNat p <> ")"
1532−character p = UnsafeTypeExpression $ "character(" <> renderNat p <> ")"
1533−-- | variable-length character string
1534−varchar, characterVarying
1535− :: (KnownNat n, 1 <= n)
1536− => proxy n
1537− -> TypeExpression schema ('PGvarchar n)
1538−varchar p = UnsafeTypeExpression $ "varchar(" <> renderNat p <> ")"
1539−characterVarying p = UnsafeTypeExpression $
1540− "character varying(" <> renderNat p <> ")"
1541−-- | binary data ("byte array")
1542−bytea :: TypeExpression schema 'PGbytea
1543−bytea = UnsafeTypeExpression "bytea"
1544−-- | date and time (no time zone)
1545−timestamp :: TypeExpression schema 'PGtimestamp
1546−timestamp = UnsafeTypeExpression "timestamp"
1547−-- | date and time, including time zone
1548−timestampWithTimeZone :: TypeExpression schema 'PGtimestamptz
1549−timestampWithTimeZone = UnsafeTypeExpression "timestamp with time zone"
1550−-- | calendar date (year, month, day)
1551−date :: TypeExpression schema 'PGdate
1552−date = UnsafeTypeExpression "date"
1553−-- | time of day (no time zone)
1554−time :: TypeExpression schema 'PGtime
1555−time = UnsafeTypeExpression "time"
1556−-- | time of day, including time zone
1557−timeWithTimeZone :: TypeExpression schema 'PGtimetz
1558−timeWithTimeZone = UnsafeTypeExpression "time with time zone"
1559−-- | time span
1560−interval :: TypeExpression schema 'PGinterval
1561−interval = UnsafeTypeExpression "interval"
1562−-- | universally unique identifier
1563−uuid :: TypeExpression schema 'PGuuid
1564−uuid = UnsafeTypeExpression "uuid"
1565−-- | IPv4 or IPv6 host address
1566−inet :: TypeExpression schema 'PGinet
1567−inet = UnsafeTypeExpression "inet"
1568−-- | textual JSON data
1569−json :: TypeExpression schema 'PGjson
1570−json = UnsafeTypeExpression "json"
1571−-- | binary JSON data, decomposed
1572−jsonb :: TypeExpression schema 'PGjsonb
1573−jsonb = UnsafeTypeExpression "jsonb"
1574−-- | variable length array
1575−vararray
1576− :: TypeExpression schema pg
1577− -> TypeExpression schema ('PGvararray pg)
1578−vararray ty = UnsafeTypeExpression $ renderTypeExpression ty <> "[]"
1579−-- | fixed length array
1580−--
1581−-- >>> renderTypeExpression (fixarray (Proxy @2) json)
1582−-- "json[2]"
1583−fixarray
1584− :: KnownNat n
1585− => proxy n
1586− -> TypeExpression schema pg
1587− -> TypeExpression schema ('PGfixarray n pg)
1588−fixarray p ty = UnsafeTypeExpression $
1589− renderTypeExpression ty <> "[" <> renderNat p <> "]"
1590−
1591−-- | `pgtype` is a demoted version of a `PGType`
1592−class PGTyped schema (ty :: PGType) where pgtype :: TypeExpression schema ty
1593−instance PGTyped schema 'PGbool where pgtype = bool
1594−instance PGTyped schema 'PGint2 where pgtype = int2
1595−instance PGTyped schema 'PGint4 where pgtype = int4
1596−instance PGTyped schema 'PGint8 where pgtype = int8
1597−instance PGTyped schema 'PGnumeric where pgtype = numeric
1598−instance PGTyped schema 'PGfloat4 where pgtype = float4
1599−instance PGTyped schema 'PGfloat8 where pgtype = float8
1600−instance PGTyped schema 'PGtext where pgtype = text
1601−instance (KnownNat n, 1 <= n)
1602− => PGTyped schema ('PGchar n) where pgtype = char (Proxy @n)
1603−instance (KnownNat n, 1 <= n)
1604− => PGTyped schema ('PGvarchar n) where pgtype = varchar (Proxy @n)
1605−instance PGTyped schema 'PGbytea where pgtype = bytea
1606−instance PGTyped schema 'PGtimestamp where pgtype = timestamp
1607−instance PGTyped schema 'PGtimestamptz where pgtype = timestampWithTimeZone
1608−instance PGTyped schema 'PGdate where pgtype = date
1609−instance PGTyped schema 'PGtime where pgtype = time
1610−instance PGTyped schema 'PGtimetz where pgtype = timeWithTimeZone
1611−instance PGTyped schema 'PGinterval where pgtype = interval
1612−instance PGTyped schema 'PGuuid where pgtype = uuid
1613−instance PGTyped schema 'PGjson where pgtype = json
1614−instance PGTyped schema 'PGjsonb where pgtype = jsonb
1615−instance PGTyped schema ty => PGTyped schema ('PGvararray ty) where
1616− pgtype = vararray (pgtype @schema @ty)
1617−instance (KnownNat n, PGTyped schema ty) => PGTyped schema ('PGfixarray n ty) where
1618− pgtype = fixarray (Proxy @n) (pgtype @schema @ty)