@@ -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,521 +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− , (.->)
95− , (.->>)
96− , (.#>)
97− , (.#>>)
98− -- *** jsonb only operators
99− , (.@>)
100− , (.<@)
101− , (.?)
102− , (.?|)
103− , (.?&)
104− , (.-.)
105− , (#-.)
106− -- *** Functions
107− , jsonLit
108− , jsonbLit
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− , jsonStripNulls
132− , jsonbStripNulls
133− , jsonbSet
134− , jsonbInsert
135− , jsonbPretty
136− -- ** Aggregation
137− , unsafeAggregate, unsafeAggregateDistinct
138− , sum_, sumDistinct
139− , PGAvg (avg, avgDistinct)
140− , bitAnd, bitOr, boolAnd, boolOr
141− , bitAndDistinct, bitOrDistinct, boolAndDistinct, boolOrDistinct
142− , countStar
143− , count, countDistinct
144− , every, everyDistinct
145− , max_, maxDistinct, min_, minDistinct
146− -- * Types
147− , TypeExpression (UnsafeTypeExpression, renderTypeExpression)
148− , PGTyped (pgtype)
149− , bool
150− , int2
151− , smallint
152− , int4
153− , int
154− , integer
155− , int8
156− , bigint
157− , numeric
158− , float4
159− , real
160− , float8
161− , doublePrecision
162− , text
163− , char
164− , character
165− , varchar
166− , characterVarying
167− , bytea
168− , timestamp
169− , timestampWithTimeZone
170− , date
171− , time
172− , timeWithTimeZone
173− , interval
174− , uuid
175− , inet
176− , json
177− , jsonb
178− , vararray
179− , 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 (..)
18057 -- * Re-export
18158 , (&)
182− , NP ((:*), Nil)
59+ , K (..)
60+ , unK
18361 ) where
18462
18563import Control.Category
18664import Control.DeepSeq
18765import Data.ByteString (ByteString)
188−import Data.ByteString.Lazy (toStrict)
18966import Data.Function ((&))
19067import Data.Semigroup hiding (All)
191−import qualified Data.Aeson as JSON
192−import Data.Ratio
19368import Data.String
194−import Generics.SOP hiding (from)
69+import Generics.SOP hiding (All, from)
19570import GHC.OverloadedLabels
19671import GHC.TypeLits
72+import Numeric
19773import Prelude hiding (id, (.))
19874
19975import qualified GHC.Generics as GHC
20076
77+import Squeal.PostgreSQL.Alias
78+import Squeal.PostgreSQL.List
20179import Squeal.PostgreSQL.Render
20280import Squeal.PostgreSQL.Schema
20381
82+-- $setup
83+-- >>> import Squeal.PostgreSQL
84+
20485{-----------------------------------------
20586column expressions
20687-----------------------------------------}
20788
20889{- | `Expression`s are used in a variety of contexts,
209−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,
21092as new column values in `Squeal.PostgreSQL.Manipulation.insertRow` or
21193`Squeal.PostgreSQL.Manipulation.update`,
212−or in search `Condition`s in a number of commands.
94+or in search `Squeal.PostgreSQL.Logic.Condition`s in a number of commands.
21395
21496The expression syntax allows the calculation of
21597values from primitive expression using arithmetic, logical,
21698and 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`.
217113-}
218114newtype Expression
219− (schema :: SchemaType)
220− (relations :: RelationsType)
221− (grouping :: Grouping)
115+ (outer :: FromType)
116+ (commons :: FromType)
117+ (grp :: Grouping)
118+ (schemas :: SchemasType)
222119 (params :: [NullityType])
120+ (from :: FromType)
223121 (ty :: NullityType)
224122 = UnsafeExpression { renderExpression :: ByteString }
225123 deriving (GHC.Generic,Show,Eq,Ord,NFData)
226−
227−instance RenderSQL (Expression schema relations grouping params ty) where
124+instance RenderSQL (Expression outer commons grp schemas params from ty) where
228125 renderSQL = renderExpression
229126
230−{- | A `HasParameter` constraint is used to indicate a value that is
231−supplied externally to a SQL statement.
232−`Squeal.PostgreSQL.PQ.manipulateParams`,
233−`Squeal.PostgreSQL.PQ.queryParams` and
234−`Squeal.PostgreSQL.PQ.traversePrepared` support specifying data values
235−separately from the SQL command string, in which case `param`s are used to
236−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)
237181-}
238−class KnownNat n => HasParameter
239− (n :: Nat)
240− (schema :: SchemaType)
241− (params :: [NullityType])
242− (ty :: NullityType)
243− | n params -> ty where
244− -- | `parameter` takes a `Nat` using type application and a `TypeExpression`.
245− --
246− -- >>> let expr = parameter @1 int4 :: Expression sch rels grp '[ 'Null 'PGint4] ('Null 'PGint4)
247− -- >>> printSQL expr
248− -- ($1 :: int4)
249− parameter
250− :: TypeExpression schema ty
251− -> Expression schema relations grouping params ty
252− parameter ty = UnsafeExpression $ parenthesized $
253− "$" <> renderNat @n <+> "::"
254− <+> renderTypeExpression ty
255−instance {-# OVERLAPPING #-} HasParameter 1 schema (ty1:tys) ty1
256−instance {-# OVERLAPPABLE #-} (KnownNat n, HasParameter (n-1) schema params ty)
257− => HasParameter n schema (ty' : params) ty
258−
259−-- | `param` takes a `Nat` using type application and for basic types,
260−-- infers a `TypeExpression`.
261−--
262−-- >>> let expr = param @1 :: Expression sch rels grp '[ 'Null 'PGint4] ('Null 'PGint4)
263−-- >>> printSQL expr
264−-- ($1 :: int4)
265−param
266− :: forall n schema params relations grouping ty
267− . (PGTyped schema ty, HasParameter n schema params ty)
268− => Expression schema relations grouping params ty -- ^ param
269−param = parameter @n pgtype
270−
271−instance (HasUnique relation relations columns, Has column columns ty)
272− => IsLabel column (Expression schema relations 'Ungrouped params ty) where
273− fromLabel = UnsafeExpression $ renderAlias (Alias @column)
274−instance (HasUnique relation relations columns, Has column columns ty)
275− => IsLabel column
276− (Aliased (Expression schema relations 'Ungrouped params) (column ::: ty)) where
277− fromLabel = fromLabel @column `As` Alias @column
278−instance (HasUnique relation relations columns, Has column columns ty)
279− => IsLabel column
280− (NP (Aliased (Expression schema relations 'Ungrouped params)) '[column ::: ty]) where
281− fromLabel = fromLabel @column :* Nil
282−
283−instance (Has relation relations columns, Has column columns ty)
284− => IsQualified relation column (Expression schema relations 'Ungrouped params ty) where
285− relation ! column = UnsafeExpression $
286− renderAlias relation <> "." <> renderAlias column
287−instance (Has relation relations columns, Has column columns ty)
288− => IsQualified relation column
289− (Aliased (Expression schema relations 'Ungrouped params) (column ::: ty)) where
290− relation ! column = relation ! column `As` column
291−instance (Has relation relations columns, Has column columns ty)
292− => IsQualified relation column
293− (NP (Aliased (Expression schema relations 'Ungrouped params)) '[column ::: ty]) where
294− 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
295245
296246instance
297− ( HasUnique relation relations columns
298− , Has column columns ty
299− , GroupedBy relation column bys
300− ) => IsLabel column
301− (Expression schema relations ('Grouped bys) params ty) where
302− 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
303261instance
304− ( HasUnique relation relations columns
305− , Has column columns ty
306− , GroupedBy relation column bys
307− ) => IsLabel column
308− ( Aliased (Expression schema relations ('Grouped bys) params)
309− (column ::: ty) ) where
310− 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
311269instance
312− ( HasUnique relation relations columns
313− , Has column columns ty
314− , GroupedBy relation column bys
315− ) => IsLabel column
316− ( NP (Aliased (Expression schema relations ('Grouped bys) params))
317− '[column ::: ty] ) where
318− 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
319277
320278instance
321− ( Has relation relations columns
322− , Has column columns ty
323− , GroupedBy relation column bys
324− ) => IsQualified relation column
325− (Expression schema relations ('Grouped bys) params ty) where
326− relation ! column = UnsafeExpression $
327− 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
328286instance
329− ( Has relation relations columns
330− , Has column columns ty
331− , GroupedBy relation column bys
332− ) => IsQualified relation column
333− (Aliased (Expression schema relations ('Grouped bys) params)
334− (column ::: ty)) where
335− 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
336294instance
337− ( Has relation relations columns
338− , Has column columns ty
339− , GroupedBy relation column bys
340− ) => IsQualified relation column
341− ( NP (Aliased (Expression schema relations ('Grouped bys) params))
342− '[column ::: ty]) where
343− relation ! column = relation ! column :* Nil
344−
345−-- | analagous to `Nothing`
346−--
347−-- >>> printSQL null_
348−-- NULL
349−null_ :: Expression schema rels grouping params ('Null ty)
350−null_ = UnsafeExpression "NULL"
351−
352−-- | analagous to `Just`
353−--
354−-- >>> printSQL $ notNull true
355−-- TRUE
356−notNull
357− :: Expression schema rels grouping params ('NotNull ty)
358− -> Expression schema rels grouping params ('Null ty)
359−notNull = UnsafeExpression . renderExpression
360−
361−-- | return the leftmost value which is not NULL
362−--
363−-- >>> printSQL $ coalesce [null_, notNull true] false
364−-- COALESCE(NULL, TRUE, FALSE)
365−coalesce
366− :: [Expression schema relations grouping params ('Null ty)]
367− -- ^ @NULL@s may be present
368− -> Expression schema relations grouping params ('NotNull ty)
369− -- ^ @NULL@ is absent
370− -> Expression schema relations grouping params ('NotNull ty)
371−coalesce nullxs notNullx = UnsafeExpression $
372− "COALESCE" <> parenthesized (commaSeparated
373− ((renderExpression <$> nullxs) <> [renderExpression notNullx]))
374−
375−-- | analagous to `Data.Maybe.fromMaybe` using @COALESCE@
376−--
377−-- >>> printSQL $ fromNull true null_
378−-- COALESCE(NULL, TRUE)
379−fromNull
380− :: Expression schema relations grouping params ('NotNull ty)
381− -- ^ what to convert @NULL@ to
382− -> Expression schema relations grouping params ('Null ty)
383− -> Expression schema relations grouping params ('NotNull ty)
384−fromNull notNullx nullx = coalesce [nullx] notNullx
385−
386−-- | >>> printSQL $ null_ & isNull
387−-- NULL IS NULL
388−isNull
389− :: Expression schema relations grouping params ('Null ty)
390− -- ^ possibly @NULL@
391− -> Condition schema relations grouping params
392−isNull x = UnsafeExpression $ renderExpression x <+> "IS NULL"
393−
394−-- | >>> printSQL $ null_ & isNotNull
395−-- NULL IS NOT NULL
396−isNotNull
397− :: Expression schema relations grouping params ('Null ty)
398− -- ^ possibly @NULL@
399− -> Condition schema relations grouping params
400−isNotNull x = UnsafeExpression $ renderExpression x <+> "IS NOT NULL"
401−
402−-- | analagous to `maybe` using @IS NULL@
403−--
404−-- >>> printSQL $ matchNull true not_ null_
405−-- CASE WHEN NULL IS NULL THEN TRUE ELSE (NOT NULL) END
406−matchNull
407− :: Expression schema relations grouping params (nullty)
408− -- ^ what to convert @NULL@ to
409− -> ( Expression schema relations grouping params ('NotNull ty)
410− -> Expression schema relations grouping params (nullty) )
411− -- ^ function to perform when @NULL@ is absent
412− -> Expression schema relations grouping params ('Null ty)
413− -> Expression schema relations grouping params (nullty)
414−matchNull y f x = ifThenElse (isNull x) y
415− (f (UnsafeExpression (renderExpression x)))
416−
417−{-| right inverse to `fromNull`, if its arguments are equal then
418−`nullIf` gives @NULL@.
419−
420−>>> :set -XTypeApplications -XDataKinds
421−>>> let expr = nullIf false (param @1) :: Expression schema rels grp '[ 'NotNull 'PGbool] ('Null 'PGbool)
422−>>> printSQL expr
423−NULL IF (FALSE, ($1 :: bool))
424−-}
425−nullIf
426− :: Expression schema relations grouping params ('NotNull ty)
427− -- ^ @NULL@ is absent
428− -> Expression schema relations grouping params ('NotNull ty)
429− -- ^ @NULL@ is absent
430− -> Expression schema relations grouping params ('Null ty)
431−nullIf x y = UnsafeExpression $ "NULL IF" <+> parenthesized
432− (renderExpression x <> ", " <> renderExpression y)
433−
434−-- | >>> printSQL $ array [null_, notNull false, notNull true]
435−-- ARRAY[NULL, FALSE, TRUE]
436−array
437− :: [Expression schema relations grouping params ty]
438− -- ^ array elements
439− -> Expression schema relations grouping params (nullity ('PGvararray ty))
440−array xs = UnsafeExpression $
441− "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
442310
443311instance (KnownSymbol label, label `In` labels) => IsPGlabel label
444− (Expression schema relations grouping params (nullity ('PGenum labels))) where
445− label = UnsafeExpression $ renderLabel (PGlabel @label)
446−
447−-- | A row constructor is an expression that builds a row value
448−-- (also called a composite value) using values for its member fields.
449−--
450−-- >>> :{
451−-- type Complex = 'PGcomposite
452−-- '[ "real" ::: 'NotNull 'PGfloat8
453−-- , "imaginary" ::: 'NotNull 'PGfloat8 ]
454−-- :}
455−--
456−-- >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression '[] '[] 'Ungrouped '[] ('NotNull Complex)
457−-- >>> printSQL i
458−-- ROW(0, 1)
459−row
460− :: SListI fields
461− => NP (Aliased (Expression schema relations grouping params)) fields
462− -- ^ zero or more expressions for the row field values
463− -> Expression schema relations grouping params (nullity ('PGcomposite fields))
464−row exprs = UnsafeExpression $ "ROW" <> parenthesized
465− (renderCommaSeparated (\ (expr `As` _) -> renderExpression expr) exprs)
466−
467−instance Has field fields ty => IsLabel field
468− ( Expression schema relation grouping params ('NotNull ('PGcomposite fields))
469− -> Expression schema relation grouping params ty ) where
470− fromLabel expr = UnsafeExpression $
471− parenthesized (renderExpression expr) <> "." <>
472− renderSymbol @field
473−
474−instance Semigroup
475− (Expression schema relations grouping params (nullity ('PGvararray ty))) where
476− (<>) = unsafeBinaryOp "||"
477−
478−instance Monoid
479− (Expression schema relations grouping params (nullity ('PGvararray ty))) where
480− mempty = array []
481− mappend = (<>)
482−
483−-- | >>> let expr = greatest currentTimestamp [param @1] :: Expression sch rels grp '[ 'NotNull 'PGtimestamptz] ('NotNull 'PGtimestamptz)
484−-- >>> printSQL expr
485−-- GREATEST(CURRENT_TIMESTAMP, ($1 :: timestamp with time zone))
486−greatest
487− :: Expression schema relations grouping params (nullty)
488− -- ^ needs at least 1 argument
489− -> [Expression schema relations grouping params (nullty)]
490− -- ^ or more
491− -> Expression schema relations grouping params (nullty)
492−greatest x xs = UnsafeExpression $ "GREATEST("
493− <> commaSeparated (renderExpression <$> (x:xs)) <> ")"
494−
495−-- | >>> printSQL $ least currentTimestamp [null_]
496−-- LEAST(CURRENT_TIMESTAMP, NULL)
497−least
498− :: Expression schema relations grouping params (nullty)
499− -- ^ needs at least 1 argument
500− -> [Expression schema relations grouping params (nullty)]
501− -- ^ or more
502− -> Expression schema relations grouping params (nullty)
503−least x xs = UnsafeExpression $ "LEAST("
504− <> commaSeparated (renderExpression <$> (x:xs)) <> ")"
312+ (Expression outer commons grp schemas params from (null ('PGenum labels))) where
313+ label = UnsafeExpression $ renderSQL (PGlabel @label)
505314
506315-- | >>> printSQL $ unsafeBinaryOp "OR" true false
507316-- (TRUE OR FALSE)
508−unsafeBinaryOp
509− :: ByteString
510− -- ^ operator
511− -> Expression schema relations grouping params (ty0)
512− -> Expression schema relations grouping params (ty1)
513− -> Expression schema relations grouping params (ty2)
317+unsafeBinaryOp :: ByteString -> Operator ty0 ty1 ty2
514318unsafeBinaryOp op x y = UnsafeExpression $ parenthesized $
515− 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
516327
517−-- | >>> printSQL $ unsafeUnaryOp "NOT" true
328+-- | >>> printSQL $ unsafeLeftOp "NOT" true
518329-- (NOT TRUE)
519−unsafeUnaryOp
520− :: ByteString
521− -- ^ operator
522− -> Expression schema relations grouping params (ty0)
523− -> Expression schema relations grouping params (ty1)
524−unsafeUnaryOp op x = UnsafeExpression $ parenthesized $
525− 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
526351
527352-- | >>> printSQL $ unsafeFunction "f" true
528353-- f(TRUE)
529−unsafeFunction
530− :: ByteString
531− -- ^ function
532− -> Expression schema relations grouping params (xty)
533− -> Expression schema relations grouping params (yty)
354+unsafeFunction :: ByteString -> x --> y
534355unsafeFunction fun x = UnsafeExpression $
535− fun <> parenthesized (renderExpression x)
536−
537−-- | Helper for defining variadic functions.
538−unsafeVariadicFunction
539− :: SListI elems
540− => ByteString
541− -- ^ function
542− -> NP (Expression schema relations grouping params) elems
543− -> Expression schema relations grouping params ret
544−unsafeVariadicFunction fun x = UnsafeExpression $
545− fun <> parenthesized (commaSeparated (hcollapse (hmap (K . renderExpression) x)))
546−
547−instance PGNum ty
548− => 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
549380 (+) = unsafeBinaryOp "+"
550381 (-) = unsafeBinaryOp "-"
551382 (*) = unsafeBinaryOp "*"
@@ -556,19 +387,24 @@ instance PGNum ty
556387 . fromString
557388 . show
558389
559−instance (PGNum ty, PGFloating ty) => Fractional
560− (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
561392 (/) = unsafeBinaryOp "/"
562− fromRational x = fromInteger (numerator x) / fromInteger (denominator x)
393+ fromRational
394+ = UnsafeExpression
395+ . fromString
396+ . ($ "")
397+ . showFFloat Nothing
398+ . fromRat @Double
563399
564−instance (PGNum ty, PGFloating ty) => Floating
565− (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
566402 pi = UnsafeExpression "pi()"
567403 exp = unsafeFunction "exp"
568404 log = unsafeFunction "ln"
569405 sqrt = unsafeFunction "sqrt"
570406 b ** x = UnsafeExpression $
571− "power(" <> renderExpression b <> ", " <> renderExpression x <> ")"
407+ "power(" <> renderSQL b <> ", " <> renderSQL x <> ")"
572408 logBase b y = log y / log b
573409 sin = unsafeFunction "sin"
574410 cos = unsafeFunction "cos"
@@ -583,1129 +419,54 @@ instance (PGNum ty, PGFloating ty) => Floating
583419 acosh x = log (x + sqrt (x*x - 1))
584420 atanh x = log ((1 + x) / (1 - x)) / 2
585421
586−-- | >>> :{
587−-- let
588−-- expression :: Expression schema relations grouping params (nullity 'PGfloat4)
589−-- expression = atan2_ pi 2
590−-- in printSQL expression
591−-- :}
592−-- atan2(pi(), 2)
593−atan2_
594− :: PGFloating float
595− => Expression schema relations grouping params (nullity float)
596− -- ^ numerator
597− -> Expression schema relations grouping params (nullity float)
598− -- ^ denominator
599− -> Expression schema relations grouping params (nullity float)
600−atan2_ y x = UnsafeExpression $
601− "atan2(" <> renderExpression y <> ", " <> renderExpression x <> ")"
602−
603−-- When a `cast` is applied to an `Expression` of a known type, it
604−-- represents a run-time type conversion. The cast will succeed only if a
605−-- suitable type conversion operation has been defined.
606−--
607−-- | >>> printSQL $ true & cast int4
608−-- (TRUE :: int4)
609−cast
610− :: TypeExpression schema ty1
611− -- ^ type to cast as
612− -> Expression schema relations grouping params ty0
613− -- ^ value to convert
614− -> Expression schema relations grouping params ty1
615−cast ty x = UnsafeExpression $ parenthesized $
616− renderExpression x <+> "::" <+> renderTypeExpression ty
617−
618−-- | integer division, truncates the result
619−--
620−-- >>> :{
621−-- let
622−-- expression :: Expression schema relations grouping params (nullity 'PGint2)
623−-- expression = 5 `quot_` 2
624−-- in printSQL expression
625−-- :}
626−-- (5 / 2)
627−quot_
628− :: PGIntegral int
629− => Expression schema relations grouping params (nullity int)
630− -- ^ numerator
631− -> Expression schema relations grouping params (nullity int)
632− -- ^ denominator
633− -> Expression schema relations grouping params (nullity int)
634−quot_ = unsafeBinaryOp "/"
635−
636−-- | remainder upon integer division
637−--
638−-- >>> :{
639−-- let
640−-- expression :: Expression schema relations grouping params (nullity 'PGint2)
641−-- expression = 5 `rem_` 2
642−-- in printSQL expression
643−-- :}
644−-- (5 % 2)
645−rem_
646− :: PGIntegral int
647− => Expression schema relations grouping params (nullity int)
648− -- ^ numerator
649− -> Expression schema relations grouping params (nullity int)
650− -- ^ denominator
651− -> Expression schema relations grouping params (nullity int)
652−rem_ = unsafeBinaryOp "%"
653−
654−-- | >>> :{
655−-- let
656−-- expression :: Expression schema relations grouping params (nullity 'PGfloat4)
657−-- expression = trunc pi
658−-- in printSQL expression
659−-- :}
660−-- trunc(pi())
661−trunc
662− :: PGFloating frac
663− => Expression schema relations grouping params (nullity frac)
664− -- ^ fractional number
665− -> Expression schema relations grouping params (nullity frac)
666−trunc = unsafeFunction "trunc"
667−
668−-- | >>> :{
669−-- let
670−-- expression :: Expression schema relations grouping params (nullity 'PGfloat4)
671−-- expression = round_ pi
672−-- in printSQL expression
673−-- :}
674−-- round(pi())
675−round_
676− :: PGFloating frac
677− => Expression schema relations grouping params (nullity frac)
678− -- ^ fractional number
679− -> Expression schema relations grouping params (nullity frac)
680−round_ = unsafeFunction "round"
681−
682−-- | >>> :{
683−-- let
684−-- expression :: Expression schema relations grouping params (nullity 'PGfloat4)
685−-- expression = ceiling_ pi
686−-- in printSQL expression
687−-- :}
688−-- ceiling(pi())
689−ceiling_
690− :: PGFloating frac
691− => Expression schema relations grouping params (nullity frac)
692− -- ^ fractional number
693− -> Expression schema relations grouping params (nullity frac)
694−ceiling_ = unsafeFunction "ceiling"
695−
696−-- | A `Condition` is a boolean valued `Expression`. While SQL allows
697−-- conditions to have @NULL@, Squeal instead chooses to disallow @NULL@,
698−-- forcing one to handle the case of @NULL@ explicitly to produce
699−-- a `Condition`.
700−type Condition schema relations grouping params =
701− Expression schema relations grouping params ('NotNull 'PGbool)
702−
703−-- | >>> printSQL true
704−-- TRUE
705−true :: Condition schema relations grouping params
706−true = UnsafeExpression "TRUE"
707−
708−-- | >>> printSQL false
709−-- FALSE
710−false :: Condition schema relations grouping params
711−false = UnsafeExpression "FALSE"
712−
713−-- | >>> printSQL $ not_ true
714−-- (NOT TRUE)
715−not_
716− :: Condition schema relations grouping params
717− -> Condition schema relations grouping params
718−not_ = unsafeUnaryOp "NOT"
719−
720−-- | >>> printSQL $ true .&& false
721−-- (TRUE AND FALSE)
722−(.&&)
723− :: Condition schema relations grouping params
724− -> Condition schema relations grouping params
725− -> Condition schema relations grouping params
726−(.&&) = unsafeBinaryOp "AND"
727−
728−-- | >>> printSQL $ true .|| false
729−-- (TRUE OR FALSE)
730−(.||)
731− :: Condition schema relations grouping params
732− -> Condition schema relations grouping params
733− -> Condition schema relations grouping params
734−(.||) = unsafeBinaryOp "OR"
735−
736−-- | >>> :{
737−-- let
738−-- expression :: Expression schema relations grouping params (nullity 'PGint2)
739−-- expression = caseWhenThenElse [(true, 1), (false, 2)] 3
740−-- in printSQL expression
741−-- :}
742−-- CASE WHEN TRUE THEN 1 WHEN FALSE THEN 2 ELSE 3 END
743−caseWhenThenElse
744− :: [ ( Condition schema relations grouping params
745− , Expression schema relations grouping params (ty)
746− ) ]
747− -- ^ whens and thens
748− -> Expression schema relations grouping params (ty)
749− -- ^ else
750− -> Expression schema relations grouping params (ty)
751−caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
752− [ "CASE"
753− , mconcat
754− [ mconcat
755− [ " WHEN ", renderExpression when_
756− , " THEN ", renderExpression then_
757− ]
758− | (when_,then_) <- whenThens
759− ]
760− , " ELSE ", renderExpression else_
761− , " END"
762− ]
763−
764−-- | >>> :{
765−-- let
766−-- expression :: Expression schema relations grouping params (nullity 'PGint2)
767−-- expression = ifThenElse true 1 0
768−-- in printSQL expression
769−-- :}
770−-- CASE WHEN TRUE THEN 1 ELSE 0 END
771−ifThenElse
772− :: Condition schema relations grouping params
773− -> Expression schema relations grouping params (ty) -- ^ then
774− -> Expression schema relations grouping params (ty) -- ^ else
775− -> Expression schema relations grouping params (ty)
776−ifThenElse if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
777−
778−-- | Comparison operations like `.==`, `./=`, `.>`, `.>=`, `.<` and `.<=`
779−-- will produce @NULL@s if one of their arguments is @NULL@.
780−--
781−-- >>> printSQL $ notNull true .== null_
782−-- (TRUE = NULL)
783−(.==)
784− :: Expression schema relations grouping params (nullity ty) -- ^ lhs
785− -> Expression schema relations grouping params (nullity ty) -- ^ rhs
786− -> Expression schema relations grouping params (nullity 'PGbool)
787−(.==) = unsafeBinaryOp "="
788−infix 4 .==
789−
790−-- | >>> printSQL $ notNull true ./= null_
791−-- (TRUE <> NULL)
792−(./=)
793− :: Expression schema relations grouping params (nullity ty) -- ^ lhs
794− -> Expression schema relations grouping params (nullity ty) -- ^ rhs
795− -> Expression schema relations grouping params (nullity 'PGbool)
796−(./=) = unsafeBinaryOp "<>"
797−infix 4 ./=
798−
799−-- | >>> printSQL $ notNull true .>= null_
800−-- (TRUE >= NULL)
801−(.>=)
802− :: Expression schema relations grouping params (nullity ty) -- ^ lhs
803− -> Expression schema relations grouping params (nullity ty) -- ^ rhs
804− -> Expression schema relations grouping params (nullity 'PGbool)
805−(.>=) = unsafeBinaryOp ">="
806−infix 4 .>=
807−
808−-- | >>> printSQL $ notNull true .< null_
809−-- (TRUE < NULL)
810−(.<)
811− :: Expression schema relations grouping params (nullity ty) -- ^ lhs
812− -> Expression schema relations grouping params (nullity ty) -- ^ rhs
813− -> Expression schema relations grouping params (nullity 'PGbool)
814−(.<) = unsafeBinaryOp "<"
815−infix 4 .<
816−
817−-- | >>> printSQL $ notNull true .<= null_
818−-- (TRUE <= NULL)
819−(.<=)
820− :: Expression schema relations grouping params (nullity ty) -- ^ lhs
821− -> Expression schema relations grouping params (nullity ty) -- ^ rhs
822− -> Expression schema relations grouping params (nullity 'PGbool)
823−(.<=) = unsafeBinaryOp "<="
824−infix 4 .<=
825−
826−-- | >>> printSQL $ notNull true .> null_
827−-- (TRUE > NULL)
828−(.>)
829− :: Expression schema relations grouping params (nullity ty) -- ^ lhs
830− -> Expression schema relations grouping params (nullity ty) -- ^ rhs
831− -> Expression schema relations grouping params (nullity 'PGbool)
832−(.>) = unsafeBinaryOp ">"
833−infix 4 .>
834−
835−-- | >>> printSQL currentDate
836−-- CURRENT_DATE
837−currentDate
838− :: Expression schema relations grouping params (nullity 'PGdate)
839−currentDate = UnsafeExpression "CURRENT_DATE"
840−
841−-- | >>> printSQL currentTime
842−-- CURRENT_TIME
843−currentTime
844− :: Expression schema relations grouping params (nullity 'PGtimetz)
845−currentTime = UnsafeExpression "CURRENT_TIME"
846−
847−-- | >>> printSQL currentTimestamp
848−-- CURRENT_TIMESTAMP
849−currentTimestamp
850− :: Expression schema relations grouping params (nullity 'PGtimestamptz)
851−currentTimestamp = UnsafeExpression "CURRENT_TIMESTAMP"
852−
853−-- | >>> printSQL localTime
854−-- LOCALTIME
855−localTime
856− :: Expression schema relations grouping params (nullity 'PGtime)
857−localTime = UnsafeExpression "LOCALTIME"
858−
859−-- | >>> printSQL localTimestamp
860−-- LOCALTIMESTAMP
861−localTimestamp
862− :: Expression schema relations grouping params (nullity 'PGtimestamp)
863−localTimestamp = UnsafeExpression "LOCALTIMESTAMP"
864−
865−{-----------------------------------------
866−text
867−-----------------------------------------}
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)
868438
869439instance IsString
870− (Expression schema relations grouping params (nullity 'PGtext)) where
440+ (Expression outer commons grp schemas params from (null 'PGtext)) where
871441 fromString str = UnsafeExpression $
872442 "E\'" <> fromString (escape =<< str) <> "\'"
873− where
874− escape = \case
875− '\NUL' -> "\\0"
876− '\'' -> "''"
877− '"' -> "\\\""
878− '\b' -> "\\b"
879− '\n' -> "\\n"
880− '\r' -> "\\r"
881− '\t' -> "\\t"
882− '\\' -> "\\\\"
883− 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) <> "\'"
884451
885452instance Semigroup
886− (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
887463 (<>) = unsafeBinaryOp "||"
888464
889465instance Monoid
890− (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
891471 mempty = fromString ""
892472 mappend = (<>)
893−
894−-- | >>> printSQL $ lower "ARRRGGG"
895−-- lower(E'ARRRGGG')
896−lower
897− :: Expression schema relations grouping params (nullity 'PGtext)
898− -- ^ string to lower case
899− -> Expression schema relations grouping params (nullity 'PGtext)
900−lower = unsafeFunction "lower"
901−
902−-- | >>> printSQL $ upper "eeee"
903−-- upper(E'eeee')
904−upper
905− :: Expression schema relations grouping params (nullity 'PGtext)
906− -- ^ string to upper case
907− -> Expression schema relations grouping params (nullity 'PGtext)
908−upper = unsafeFunction "upper"
909−
910−-- | >>> printSQL $ charLength "four"
911−-- char_length(E'four')
912−charLength
913− :: Expression schema relations grouping params (nullity 'PGtext)
914− -- ^ string to measure
915− -> Expression schema relations grouping params (nullity 'PGint4)
916−charLength = unsafeFunction "char_length"
917−
918−-- | The `like` expression returns true if the @string@ matches
919−-- the supplied @pattern@. If @pattern@ does not contain percent signs
920−-- or underscores, then the pattern only represents the string itself;
921−-- in that case `like` acts like the equals operator. An underscore (_)
922−-- in pattern stands for (matches) any single character; a percent sign (%)
923−-- matches any sequence of zero or more characters.
924−--
925−-- >>> printSQL $ "abc" `like` "a%"
926−-- (E'abc' LIKE E'a%')
927−like
928− :: Expression schema relations grouping params (nullity 'PGtext)
929− -- ^ string
930− -> Expression schema relations grouping params (nullity 'PGtext)
931− -- ^ pattern
932− -> Expression schema relations grouping params (nullity 'PGbool)
933−like = unsafeBinaryOp "LIKE"
934−
935−{-----------------------------------------
936− -- json and jsonb support
937−
938−See https://www.postgresql.org/docs/10/static/functions-json.html -- most
939−comments lifted directly from this page.
940−
941−Table 9.44: json and jsonb operators
942−-----------------------------------------}
943−
944−-- | Get JSON value (object field or array element) at a key.
945−(.->)
946− :: (PGjson_ json, PGjsonKey key)
947− => Expression schema relations grouping params (nullity json)
948− -> Expression schema relations grouping params (nullity key)
949− -> Expression schema relations grouping params ('Null json)
950−(.->) = unsafeBinaryOp "->"
951−
952−-- | Get JSON value (object field or array element) at a key, as text.
953−(.->>)
954− :: (PGjson_ json, PGjsonKey key)
955− => Expression schema relations grouping params (nullity json)
956− -> Expression schema relations grouping params (nullity key)
957− -> Expression schema relations grouping params ('Null 'PGtext)
958−(.->>) = unsafeBinaryOp "->>"
959−
960−-- | Get JSON value at a specified path.
961−(.#>)
962− :: (PGjson_ json, PGtextArray "(.#>)" path)
963− => Expression schema relations grouping params (nullity json)
964− -> Expression schema relations grouping params (nullity path)
965− -> Expression schema relations grouping params ('Null json)
966−(.#>) = unsafeBinaryOp "#>"
967−
968−-- | Get JSON value at a specified path as text.
969−(.#>>)
970− :: (PGjson_ json, PGtextArray "(.#>>)" path)
971− => Expression schema relations grouping params (nullity json)
972− -> Expression schema relations grouping params (nullity path)
973− -> Expression schema relations grouping params ('Null 'PGtext)
974−(.#>>) = unsafeBinaryOp "#>>"
975−
976−-- Additional jsonb operators
977−
978−-- | Does the left JSON value contain the right JSON path/value entries at the
979−-- top level?
980−(.@>)
981− :: Expression schema relations grouping params (nullity 'PGjsonb)
982− -> Expression schema relations grouping params (nullity 'PGjsonb)
983− -> Condition schema relations grouping params
984−(.@>) = unsafeBinaryOp "@>"
985−
986−-- | Are the left JSON path/value entries contained at the top level within the
987−-- right JSON value?
988−(.<@)
989− :: Expression schema relations grouping params (nullity 'PGjsonb)
990− -> Expression schema relations grouping params (nullity 'PGjsonb)
991− -> Condition schema relations grouping params
992−(.<@) = unsafeBinaryOp "<@"
993−
994−-- | Does the string exist as a top-level key within the JSON value?
995−(.?)
996− :: Expression schema relations grouping params (nullity 'PGjsonb)
997− -> Expression schema relations grouping params (nullity 'PGtext)
998− -> Condition schema relations grouping params
999−(.?) = unsafeBinaryOp "?"
1000−
1001−-- | Do any of these array strings exist as top-level keys?
1002−(.?|)
1003− :: Expression schema relations grouping params (nullity 'PGjsonb)
1004− -> Expression schema relations grouping params (nullity ('PGvararray ('NotNull 'PGtext)))
1005− -> Condition schema relations grouping params
1006−(.?|) = unsafeBinaryOp "?|"
1007−
1008−-- | Do all of these array strings exist as top-level keys?
1009−(.?&)
1010− :: Expression schema relations grouping params (nullity 'PGjsonb)
1011− -> Expression schema relations grouping params (nullity ('PGvararray ('NotNull 'PGtext)))
1012− -> Condition schema relations grouping params
1013−(.?&) = unsafeBinaryOp "?&"
1014−
1015−-- | Concatenate two jsonb values into a new jsonb value.
1016−instance
1017− Semigroup (Expression schema relations grouping param (nullity 'PGjsonb)) where
1018− (<>) = unsafeBinaryOp "||"
1019−
1020−-- | Delete a key or keys from a JSON object, or remove an array element.
1021−--
1022−-- If the right operand is..
1023−--
1024−-- @ text @: Delete key/value pair or string element from left operand. Key/value pairs
1025−-- are matched based on their key value.
1026−--
1027−-- @ text[] @: Delete multiple key/value pairs or string elements
1028−-- from left operand. Key/value pairs are matched based on their key value.
1029−--
1030−-- @ integer @: Delete the array element with specified index (Negative integers
1031−-- count from the end). Throws an error if top level container is not an array.
1032−(.-.)
1033− :: (key `In` '[ 'PGtext, 'PGvararray ('NotNull 'PGtext), 'PGint4, 'PGint2 ]) -- hlint error without parens here
1034− => Expression schema relations grouping params (nullity 'PGjsonb)
1035− -> Expression schema relations grouping params (nullity key)
1036− -> Expression schema relations grouping params (nullity 'PGjsonb)
1037−(.-.) = unsafeBinaryOp "-"
1038−
1039−-- | Delete the field or element with specified path (for JSON arrays, negative
1040−-- integers count from the end)
1041−(#-.)
1042− :: PGtextArray "(#-.)" arrayty
1043− => Expression schema relations grouping params (nullity 'PGjsonb)
1044− -> Expression schema relations grouping params (nullity arrayty)
1045− -> Expression schema relations grouping params (nullity 'PGjsonb)
1046−(#-.) = unsafeBinaryOp "#-"
1047−
1048−{-----------------------------------------
1049−Table 9.45: JSON creation functions
1050−-----------------------------------------}
1051−
1052−-- | Literal binary JSON
1053−jsonbLit :: JSON.Value -> Expression schema relations grouping params (nullity 'PGjsonb)
1054−jsonbLit = cast jsonb . UnsafeExpression . singleQuotedUtf8 . toStrict . JSON.encode
1055−
1056−-- | Literal JSON
1057−jsonLit :: JSON.Value -> Expression schema relations grouping params (nullity 'PGjson)
1058−jsonLit = cast json . UnsafeExpression . singleQuotedUtf8 . toStrict . JSON.encode
1059−
1060−-- | Returns the value as json. Arrays and composites are converted
1061−-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1062−-- type to json, the cast function will be used to perform the conversion;
1063−-- otherwise, a scalar value is produced. For any scalar type other than a
1064−-- number, a Boolean, or a null value, the text representation will be used, in
1065−-- such a fashion that it is a valid json value.
1066−toJson
1067− :: Expression schema relations grouping params (nullity ty)
1068− -> Expression schema relations grouping params (nullity 'PGjson)
1069−toJson = unsafeFunction "to_json"
1070−
1071−-- | Returns the value as jsonb. Arrays and composites are converted
1072−-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1073−-- type to json, the cast function will be used to perform the conversion;
1074−-- otherwise, a scalar value is produced. For any scalar type other than a
1075−-- number, a Boolean, or a null value, the text representation will be used, in
1076−-- such a fashion that it is a valid jsonb value.
1077−toJsonb
1078− :: Expression schema relations grouping params (nullity ty)
1079− -> Expression schema relations grouping params (nullity 'PGjsonb)
1080−toJsonb = unsafeFunction "to_jsonb"
1081−
1082−-- | Returns the array as a JSON array. A PostgreSQL multidimensional array
1083−-- becomes a JSON array of arrays.
1084−arrayToJson
1085− :: PGarray "arrayToJson" arr
1086− => Expression schema relations grouping params (nullity arr)
1087− -> Expression schema relations grouping params (nullity 'PGjson)
1088−arrayToJson = unsafeFunction "array_to_json"
1089−
1090−-- | Returns the row as a JSON object.
1091−rowToJson
1092− :: Expression schema relations grouping params (nullity ('PGcomposite ty))
1093− -> Expression schema relations grouping params (nullity 'PGjson)
1094−rowToJson = unsafeFunction "row_to_json"
1095−
1096−-- | Builds a possibly-heterogeneously-typed JSON array out of a variadic
1097−-- argument list.
1098−jsonBuildArray
1099− :: SListI elems
1100− => NP (Expression schema relations grouping params) elems
1101− -> Expression schema relations grouping params (nullity 'PGjson)
1102−jsonBuildArray = unsafeVariadicFunction "json_build_array"
1103−
1104−-- | Builds a possibly-heterogeneously-typed (binary) JSON array out of a
1105−-- variadic argument list.
1106−jsonbBuildArray
1107− :: SListI elems
1108− => NP (Expression schema relations grouping params) elems
1109− -> Expression schema relations grouping params (nullity 'PGjsonb)
1110−jsonbBuildArray = unsafeVariadicFunction "jsonb_build_array"
1111−
1112−unsafeRowFunction
1113− :: All Top elems
1114− => NP (Aliased (Expression schema relations grouping params)) elems
1115− -> [ByteString]
1116−unsafeRowFunction =
1117− (`appEndo` []) . hcfoldMap (Proxy :: Proxy Top)
1118− (\(col `As` name) -> Endo $ \xs ->
1119− renderAliasString name : renderExpression col : xs)
1120−
1121−-- | Builds a possibly-heterogeneously-typed JSON object out of a variadic
1122−-- argument list. The elements of the argument list must alternate between text
1123−-- and values.
1124−jsonBuildObject
1125− :: All Top elems
1126− => NP (Aliased (Expression schema relations grouping params)) elems
1127− -> Expression schema relations grouping params (nullity 'PGjson)
1128−jsonBuildObject
1129− = unsafeFunction "json_build_object"
1130− . UnsafeExpression
1131− . commaSeparated
1132− . unsafeRowFunction
1133−
1134−-- | Builds a possibly-heterogeneously-typed (binary) JSON object out of a
1135−-- variadic argument list. The elements of the argument list must alternate
1136−-- between text and values.
1137−jsonbBuildObject
1138− :: All Top elems
1139− => NP (Aliased (Expression schema relations grouping params)) elems
1140− -> Expression schema relations grouping params (nullity 'PGjsonb)
1141−jsonbBuildObject
1142− = unsafeFunction "jsonb_build_object"
1143− . UnsafeExpression
1144− . commaSeparated
1145− . unsafeRowFunction
1146−
1147−-- | Builds a JSON object out of a text array. The array must have either
1148−-- exactly one dimension with an even number of members, in which case they are
1149−-- taken as alternating key/value pairs, or two dimensions such that each inner
1150−-- array has exactly two elements, which are taken as a key/value pair.
1151−jsonObject
1152− :: PGarrayOf "jsonObject" arr ('NotNull 'PGtext)
1153− => Expression schema relations grouping params (nullity arr)
1154− -> Expression schema relations grouping params (nullity 'PGjson)
1155−jsonObject = unsafeFunction "json_object"
1156−
1157−-- | Builds a binary JSON object out of a text array. The array must have either
1158−-- exactly one dimension with an even number of members, in which case they are
1159−-- taken as alternating key/value pairs, or two dimensions such that each inner
1160−-- array has exactly two elements, which are taken as a key/value pair.
1161−jsonbObject
1162− :: PGarrayOf "jsonbObject" arr ('NotNull 'PGtext)
1163− => Expression schema relations grouping params (nullity arr)
1164− -> Expression schema relations grouping params (nullity 'PGjsonb)
1165−jsonbObject = unsafeFunction "jsonb_object"
1166−
1167−-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1168−-- keys and one for values, that are zipped pairwise to create a JSON object.
1169−jsonZipObject
1170− :: ( PGarrayOf "jsonZipObject" keysArray ('NotNull 'PGtext)
1171− , PGarrayOf "jsonZipObject" valuesArray ('NotNull 'PGtext))
1172− => Expression schema relations grouping params (nullity keysArray)
1173− -> Expression schema relations grouping params (nullity valuesArray)
1174− -> Expression schema relations grouping params (nullity 'PGjson)
1175−jsonZipObject ks vs =
1176− unsafeVariadicFunction "json_object" (ks :* vs :* Nil)
1177−
1178−-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1179−-- keys and one for values, that are zipped pairwise to create a binary JSON
1180−-- object.
1181−jsonbZipObject
1182− :: ( PGarrayOf "jsonbZipObject" keysArray ('NotNull 'PGtext)
1183− , PGarrayOf "jsonbZipObject" valuesArray ('NotNull 'PGtext))
1184− => Expression schema relations grouping params (nullity keysArray)
1185− -> Expression schema relations grouping params (nullity valuesArray)
1186− -> Expression schema relations grouping params (nullity 'PGjsonb)
1187−jsonbZipObject ks vs =
1188− unsafeVariadicFunction "jsonb_object" (ks :* vs :* Nil)
1189−
1190−{-----------------------------------------
1191−Table 9.46: JSON processing functions
1192−-----------------------------------------}
1193−
1194−-- | Returns the number of elements in the outermost JSON array.
1195−jsonArrayLength
1196− :: Expression schema relations grouping params (nullity 'PGjson)
1197− -> Expression schema relations grouping params (nullity 'PGint4)
1198−jsonArrayLength = unsafeFunction "json_array_length"
1199−
1200−-- | Returns the number of elements in the outermost binary JSON array.
1201−jsonbArrayLength
1202− :: Expression schema relations grouping params (nullity 'PGjsonb)
1203− -> Expression schema relations grouping params (nullity 'PGint4)
1204−jsonbArrayLength = unsafeFunction "jsonb_array_length"
1205−
1206−-- | Returns JSON value pointed to by the given path (equivalent to #>
1207−-- operator).
1208−jsonExtractPath
1209− :: SListI elems
1210− => Expression schema relations grouping params (nullity 'PGjson)
1211− -> NP (Expression schema relations grouping params) elems
1212− -> Expression schema relations grouping params (nullity 'PGjsonb)
1213−jsonExtractPath x xs =
1214− unsafeVariadicFunction "json_extract_path" (x :* xs)
1215−
1216−-- | Returns JSON value pointed to by the given path (equivalent to #>
1217−-- operator).
1218−jsonbExtractPath
1219− :: SListI elems
1220− => Expression schema relations grouping params (nullity 'PGjsonb)
1221− -> NP (Expression schema relations grouping params) elems
1222− -> Expression schema relations grouping params (nullity 'PGjsonb)
1223−jsonbExtractPath x xs =
1224− unsafeVariadicFunction "jsonb_extract_path" (x :* xs)
1225−
1226−-- | Returns JSON value pointed to by the given path (equivalent to #>
1227−-- operator), as text.
1228−jsonExtractPathAsText
1229− :: SListI elems
1230− => Expression schema relations grouping params (nullity 'PGjson)
1231− -> NP (Expression schema relations grouping params) elems
1232− -> Expression schema relations grouping params (nullity 'PGjson)
1233−jsonExtractPathAsText x xs =
1234− unsafeVariadicFunction "json_extract_path_text" (x :* xs)
1235−
1236−-- | Returns JSON value pointed to by the given path (equivalent to #>
1237−-- operator), as text.
1238−jsonbExtractPathAsText
1239− :: SListI elems
1240− => Expression schema relations grouping params (nullity 'PGjsonb)
1241− -> NP (Expression schema relations grouping params) elems
1242− -> Expression schema relations grouping params (nullity 'PGjsonb)
1243−jsonbExtractPathAsText x xs =
1244− unsafeVariadicFunction "jsonb_extract_path_text" (x :* xs)
1245−
1246−-- | Returns set of keys in the outermost JSON object.
1247−jsonObjectKeys
1248− :: Expression schema relations grouping params (nullity 'PGjson)
1249− -> Expression schema relations grouping params (nullity 'PGtext)
1250−jsonObjectKeys = unsafeFunction "json_object_keys"
1251−
1252−-- | Returns set of keys in the outermost JSON object.
1253−jsonbObjectKeys
1254− :: Expression schema relations grouping params (nullity 'PGjsonb)
1255− -> Expression schema relations grouping params (nullity 'PGtext)
1256−jsonbObjectKeys = unsafeFunction "jsonb_object_keys"
1257−
1258−-- | Returns the type of the outermost JSON value as a text string. Possible
1259−-- types are object, array, string, number, boolean, and null.
1260−jsonTypeof
1261− :: Expression schema relations grouping params (nullity 'PGjson)
1262− -> Expression schema relations grouping params (nullity 'PGtext)
1263−jsonTypeof = unsafeFunction "json_typeof"
1264−
1265−-- | Returns the type of the outermost binary JSON value as a text string.
1266−-- Possible types are object, array, string, number, boolean, and null.
1267−jsonbTypeof
1268− :: Expression schema relations grouping params (nullity 'PGjsonb)
1269− -> Expression schema relations grouping params (nullity 'PGtext)
1270−jsonbTypeof = unsafeFunction "jsonb_typeof"
1271−
1272−-- | Returns its argument with all object fields that have null values omitted.
1273−-- Other null values are untouched.
1274−jsonStripNulls
1275− :: Expression schema relations grouping params (nullity 'PGjson)
1276− -> Expression schema relations grouping params (nullity 'PGjson)
1277−jsonStripNulls = unsafeFunction "json_strip_nulls"
1278−
1279−-- | Returns its argument with all object fields that have null values omitted.
1280−-- Other null values are untouched.
1281−jsonbStripNulls
1282− :: Expression schema relations grouping params (nullity 'PGjsonb)
1283− -> Expression schema relations grouping params (nullity 'PGjsonb)
1284−jsonbStripNulls = unsafeFunction "jsonb_strip_nulls"
1285−
1286−-- | @ jsonbSet target path new_value create_missing @
1287−--
1288−-- Returns target with the section designated by path replaced by new_value,
1289−-- or with new_value added if create_missing is true ( default is true) and the
1290−-- item designated by path does not exist. As with the path orientated
1291−-- operators, negative integers that appear in path count from the end of JSON
1292−-- arrays.
1293−jsonbSet
1294− :: PGtextArray "jsonbSet" arr
1295− => Expression schema relations grouping params (nullity 'PGjsonb)
1296− -> Expression schema relations grouping params (nullity arr)
1297− -> Expression schema relations grouping params (nullity 'PGjsonb)
1298− -> Maybe (Expression schema relations grouping params (nullity 'PGbool))
1299− -> Expression schema relations grouping params (nullity 'PGjsonb)
1300−jsonbSet tgt path val createMissing = case createMissing of
1301− Just m -> unsafeVariadicFunction "jsonb_set" (tgt :* path :* val :* m :* Nil)
1302− Nothing -> unsafeVariadicFunction "jsonb_set" (tgt :* path :* val :* Nil)
1303−
1304−-- | @ jsonbInsert target path new_value insert_after @
1305−--
1306−-- Returns target with new_value inserted. If target section designated by
1307−-- path is in a JSONB array, new_value will be inserted before target or after
1308−-- if insert_after is true (default is false). If target section designated by
1309−-- path is in JSONB object, new_value will be inserted only if target does not
1310−-- exist. As with the path orientated operators, negative integers that appear
1311−-- in path count from the end of JSON arrays.
1312−jsonbInsert
1313− :: PGtextArray "jsonbInsert" arr
1314− => Expression schema relations grouping params (nullity 'PGjsonb)
1315− -> Expression schema relations grouping params (nullity arr)
1316− -> Expression schema relations grouping params (nullity 'PGjsonb)
1317− -> Maybe (Expression schema relations grouping params (nullity 'PGbool))
1318− -> Expression schema relations grouping params (nullity 'PGjsonb)
1319−jsonbInsert tgt path val insertAfter = case insertAfter of
1320− Just i -> unsafeVariadicFunction "jsonb_insert" (tgt :* path :* val :* i :* Nil)
1321− Nothing -> unsafeVariadicFunction "jsonb_insert" (tgt :* path :* val :* Nil)
1322−
1323−-- | Returns its argument as indented JSON text.
1324−jsonbPretty
1325− :: Expression schema relations grouping params (nullity 'PGjsonb)
1326− -> Expression schema relations grouping params (nullity 'PGtext)
1327−jsonbPretty = unsafeFunction "jsonb_pretty"
1328−
1329−{-----------------------------------------
1330−aggregation
1331−-----------------------------------------}
1332−
1333−-- | escape hatch to define aggregate functions
1334−unsafeAggregate
1335− :: ByteString -- ^ aggregate function
1336− -> Expression schema relations 'Ungrouped params (xty)
1337− -> Expression schema relations ('Grouped bys) params (yty)
1338−unsafeAggregate fun x = UnsafeExpression $ mconcat
1339− [fun, "(", renderExpression x, ")"]
1340−
1341−-- | escape hatch to define aggregate functions over distinct values
1342−unsafeAggregateDistinct
1343− :: ByteString -- ^ aggregate function
1344− -> Expression schema relations 'Ungrouped params (xty)
1345− -> Expression schema relations ('Grouped bys) params (yty)
1346−unsafeAggregateDistinct fun x = UnsafeExpression $ mconcat
1347− [fun, "(DISTINCT ", renderExpression x, ")"]
1348−
1349−-- | >>> :{
1350−-- let
1351−-- expression :: Expression schema '[tab ::: '["col" ::: 'Null 'PGnumeric]] ('Grouped bys) params ('Null 'PGnumeric)
1352−-- expression = sum_ #col
1353−-- in printSQL expression
1354−-- :}
1355−-- sum("col")
1356−sum_
1357− :: PGNum ty
1358− => Expression schema relations 'Ungrouped params (nullity ty)
1359− -- ^ what to sum
1360− -> Expression schema relations ('Grouped bys) params (nullity ty)
1361−sum_ = unsafeAggregate "sum"
1362−
1363−-- | >>> :{
1364−-- let
1365−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGnumeric]] ('Grouped bys) params (nullity 'PGnumeric)
1366−-- expression = sumDistinct #col
1367−-- in printSQL expression
1368−-- :}
1369−-- sum(DISTINCT "col")
1370−sumDistinct
1371− :: PGNum ty
1372− => Expression schema relations 'Ungrouped params (nullity ty)
1373− -- ^ what to sum
1374− -> Expression schema relations ('Grouped bys) params (nullity ty)
1375−sumDistinct = unsafeAggregateDistinct "sum"
1376−
1377−-- | A constraint for `PGType`s that you can take averages of and the resulting
1378−-- `PGType`.
1379−class PGAvg ty avg | ty -> avg where
1380− avg, avgDistinct
1381− :: Expression schema relations 'Ungrouped params (nullity ty)
1382− -- ^ what to average
1383− -> Expression schema relations ('Grouped bys) params (nullity avg)
1384− avg = unsafeAggregate "avg"
1385− avgDistinct = unsafeAggregateDistinct "avg"
1386−instance PGAvg 'PGint2 'PGnumeric
1387−instance PGAvg 'PGint4 'PGnumeric
1388−instance PGAvg 'PGint8 'PGnumeric
1389−instance PGAvg 'PGnumeric 'PGnumeric
1390−instance PGAvg 'PGfloat4 'PGfloat8
1391−instance PGAvg 'PGfloat8 'PGfloat8
1392−instance PGAvg 'PGinterval 'PGinterval
1393−
1394−-- | >>> :{
1395−-- let
1396−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
1397−-- expression = bitAnd #col
1398−-- in printSQL expression
1399−-- :}
1400−-- bit_and("col")
1401−bitAnd
1402− :: PGIntegral int
1403− => Expression schema relations 'Ungrouped params (nullity int)
1404− -- ^ what to aggregate
1405− -> Expression schema relations ('Grouped bys) params (nullity int)
1406−bitAnd = unsafeAggregate "bit_and"
1407−
1408−-- | >>> :{
1409−-- let
1410−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
1411−-- expression = bitOr #col
1412−-- in printSQL expression
1413−-- :}
1414−-- bit_or("col")
1415−bitOr
1416− :: PGIntegral int
1417− => Expression schema relations 'Ungrouped params (nullity int)
1418− -- ^ what to aggregate
1419− -> Expression schema relations ('Grouped bys) params (nullity int)
1420−bitOr = unsafeAggregate "bit_or"
1421−
1422−-- | >>> :{
1423−-- let
1424−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
1425−-- expression = bitAndDistinct #col
1426−-- in printSQL expression
1427−-- :}
1428−-- bit_and(DISTINCT "col")
1429−bitAndDistinct
1430− :: PGIntegral int
1431− => Expression schema relations 'Ungrouped params (nullity int)
1432− -- ^ what to aggregate
1433− -> Expression schema relations ('Grouped bys) params (nullity int)
1434−bitAndDistinct = unsafeAggregateDistinct "bit_and"
1435−
1436−-- | >>> :{
1437−-- let
1438−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
1439−-- expression = bitOrDistinct #col
1440−-- in printSQL expression
1441−-- :}
1442−-- bit_or(DISTINCT "col")
1443−bitOrDistinct
1444− :: PGIntegral int
1445− => Expression schema relations 'Ungrouped params (nullity int)
1446− -- ^ what to aggregate
1447− -> Expression schema relations ('Grouped bys) params (nullity int)
1448−bitOrDistinct = unsafeAggregateDistinct "bit_or"
1449−
1450−-- | >>> :{
1451−-- let
1452−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1453−-- expression = boolAnd #col
1454−-- in printSQL expression
1455−-- :}
1456−-- bool_and("col")
1457−boolAnd
1458− :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1459− -- ^ what to aggregate
1460− -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1461−boolAnd = unsafeAggregate "bool_and"
1462−
1463−-- | >>> :{
1464−-- let
1465−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1466−-- expression = boolOr #col
1467−-- in printSQL expression
1468−-- :}
1469−-- bool_or("col")
1470−boolOr
1471− :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1472− -- ^ what to aggregate
1473− -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1474−boolOr = unsafeAggregate "bool_or"
1475−
1476−-- | >>> :{
1477−-- let
1478−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1479−-- expression = boolAndDistinct #col
1480−-- in printSQL expression
1481−-- :}
1482−-- bool_and(DISTINCT "col")
1483−boolAndDistinct
1484− :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1485− -- ^ what to aggregate
1486− -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1487−boolAndDistinct = unsafeAggregateDistinct "bool_and"
1488−
1489−-- | >>> :{
1490−-- let
1491−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1492−-- expression = boolOrDistinct #col
1493−-- in printSQL expression
1494−-- :}
1495−-- bool_or(DISTINCT "col")
1496−boolOrDistinct
1497− :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1498− -- ^ what to aggregate
1499− -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1500−boolOrDistinct = unsafeAggregateDistinct "bool_or"
1501−
1502−-- | A special aggregation that does not require an input
1503−--
1504−-- >>> printSQL countStar
1505−-- count(*)
1506−countStar
1507− :: Expression schema relations ('Grouped bys) params ('NotNull 'PGint8)
1508−countStar = UnsafeExpression $ "count(*)"
1509−
1510−-- | >>> :{
1511−-- let
1512−-- expression :: Expression schema '[tab ::: '["col" ::: nullity ty]] (Grouped bys) params ('NotNull 'PGint8)
1513−-- expression = count #col
1514−-- in printSQL expression
1515−-- :}
1516−-- count("col")
1517−count
1518− :: Expression schema relations 'Ungrouped params ty
1519− -- ^ what to count
1520− -> Expression schema relations ('Grouped bys) params ('NotNull 'PGint8)
1521−count = unsafeAggregate "count"
1522−
1523−-- | >>> :{
1524−-- let
1525−-- expression :: Expression schema '[tab ::: '["col" ::: nullity ty]] (Grouped bys) params ('NotNull 'PGint8)
1526−-- expression = countDistinct #col
1527−-- in printSQL expression
1528−-- :}
1529−-- count(DISTINCT "col")
1530−countDistinct
1531− :: Expression schema relations 'Ungrouped params ty
1532− -- ^ what to count
1533− -> Expression schema relations ('Grouped bys) params ('NotNull 'PGint8)
1534−countDistinct = unsafeAggregateDistinct "count"
1535−
1536−-- | synonym for `boolAnd`
1537−--
1538−-- >>> :{
1539−-- let
1540−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1541−-- expression = every #col
1542−-- in printSQL expression
1543−-- :}
1544−-- every("col")
1545−every
1546− :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1547− -- ^ what to aggregate
1548− -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1549−every = unsafeAggregate "every"
1550−
1551−-- | synonym for `boolAndDistinct`
1552−--
1553−-- >>> :{
1554−-- let
1555−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1556−-- expression = everyDistinct #col
1557−-- in printSQL expression
1558−-- :}
1559−-- every(DISTINCT "col")
1560−everyDistinct
1561− :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1562− -- ^ what to aggregate
1563− -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1564−everyDistinct = unsafeAggregateDistinct "every"
1565−
1566−-- | minimum and maximum aggregation
1567−max_, min_, maxDistinct, minDistinct
1568− :: Expression schema relations 'Ungrouped params (nullity ty)
1569− -- ^ what to aggregate
1570− -> Expression schema relations ('Grouped bys) params (nullity ty)
1571−max_ = unsafeAggregate "max"
1572−min_ = unsafeAggregate "min"
1573−maxDistinct = unsafeAggregateDistinct "max"
1574−minDistinct = unsafeAggregateDistinct "min"
1575−
1576−{-----------------------------------------
1577−type expressions
1578−-----------------------------------------}
1579−
1580−-- | `TypeExpression`s are used in `cast`s and `createTable` commands.
1581−newtype TypeExpression (schema :: SchemaType) (ty :: NullityType)
1582− = UnsafeTypeExpression { renderTypeExpression :: ByteString }
1583− deriving (GHC.Generic,Show,Eq,Ord,NFData)
1584−
1585−instance (Has alias schema ('Typedef ty))
1586− => IsLabel alias (TypeExpression schema (nullity ty)) where
1587− fromLabel = UnsafeTypeExpression (renderAlias (fromLabel @alias))
1588−
1589−-- | logical Boolean (true/false)
1590−bool :: TypeExpression schema (nullity 'PGbool)
1591−bool = UnsafeTypeExpression "bool"
1592−-- | signed two-byte integer
1593−int2, smallint :: TypeExpression schema (nullity 'PGint2)
1594−int2 = UnsafeTypeExpression "int2"
1595−smallint = UnsafeTypeExpression "smallint"
1596−-- | signed four-byte integer
1597−int4, int, integer :: TypeExpression schema (nullity 'PGint4)
1598−int4 = UnsafeTypeExpression "int4"
1599−int = UnsafeTypeExpression "int"
1600−integer = UnsafeTypeExpression "integer"
1601−-- | signed eight-byte integer
1602−int8, bigint :: TypeExpression schema (nullity 'PGint8)
1603−int8 = UnsafeTypeExpression "int8"
1604−bigint = UnsafeTypeExpression "bigint"
1605−-- | arbitrary precision numeric type
1606−numeric :: TypeExpression schema (nullity 'PGnumeric)
1607−numeric = UnsafeTypeExpression "numeric"
1608−-- | single precision floating-point number (4 bytes)
1609−float4, real :: TypeExpression schema (nullity 'PGfloat4)
1610−float4 = UnsafeTypeExpression "float4"
1611−real = UnsafeTypeExpression "real"
1612−-- | double precision floating-point number (8 bytes)
1613−float8, doublePrecision :: TypeExpression schema (nullity 'PGfloat8)
1614−float8 = UnsafeTypeExpression "float8"
1615−doublePrecision = UnsafeTypeExpression "double precision"
1616−-- | variable-length character string
1617−text :: TypeExpression schema (nullity 'PGtext)
1618−text = UnsafeTypeExpression "text"
1619−-- | fixed-length character string
1620−char, character
1621− :: forall n schema nullity. (KnownNat n, 1 <= n)
1622− => TypeExpression schema (nullity ('PGchar n))
1623−char = UnsafeTypeExpression $ "char(" <> renderNat @n <> ")"
1624−character = UnsafeTypeExpression $ "character(" <> renderNat @n <> ")"
1625−-- | variable-length character string
1626−varchar, characterVarying
1627− :: forall n schema nullity. (KnownNat n, 1 <= n)
1628− => TypeExpression schema (nullity ('PGvarchar n))
1629−varchar = UnsafeTypeExpression $ "varchar(" <> renderNat @n <> ")"
1630−characterVarying = UnsafeTypeExpression $
1631− "character varying(" <> renderNat @n <> ")"
1632−-- | binary data ("byte array")
1633−bytea :: TypeExpression schema (nullity 'PGbytea)
1634−bytea = UnsafeTypeExpression "bytea"
1635−-- | date and time (no time zone)
1636−timestamp :: TypeExpression schema (nullity 'PGtimestamp)
1637−timestamp = UnsafeTypeExpression "timestamp"
1638−-- | date and time, including time zone
1639−timestampWithTimeZone :: TypeExpression schema (nullity 'PGtimestamptz)
1640−timestampWithTimeZone = UnsafeTypeExpression "timestamp with time zone"
1641−-- | calendar date (year, month, day)
1642−date :: TypeExpression schema (nullity 'PGdate)
1643−date = UnsafeTypeExpression "date"
1644−-- | time of day (no time zone)
1645−time :: TypeExpression schema (nullity 'PGtime)
1646−time = UnsafeTypeExpression "time"
1647−-- | time of day, including time zone
1648−timeWithTimeZone :: TypeExpression schema (nullity 'PGtimetz)
1649−timeWithTimeZone = UnsafeTypeExpression "time with time zone"
1650−-- | time span
1651−interval :: TypeExpression schema (nullity 'PGinterval)
1652−interval = UnsafeTypeExpression "interval"
1653−-- | universally unique identifier
1654−uuid :: TypeExpression schema (nullity 'PGuuid)
1655−uuid = UnsafeTypeExpression "uuid"
1656−-- | IPv4 or IPv6 host address
1657−inet :: TypeExpression schema (nullity 'PGinet)
1658−inet = UnsafeTypeExpression "inet"
1659−-- | textual JSON data
1660−json :: TypeExpression schema (nullity 'PGjson)
1661−json = UnsafeTypeExpression "json"
1662−-- | binary JSON data, decomposed
1663−jsonb :: TypeExpression schema (nullity 'PGjsonb)
1664−jsonb = UnsafeTypeExpression "jsonb"
1665−-- | variable length array
1666−vararray
1667− :: TypeExpression schema pg
1668− -> TypeExpression schema (nullity ('PGvararray pg))
1669−vararray ty = UnsafeTypeExpression $ renderTypeExpression ty <> "[]"
1670−-- | fixed length array
1671−--
1672−-- >>> renderTypeExpression (fixarray @2 json)
1673−-- "json[2]"
1674−fixarray
1675− :: forall n schema nullity pg. KnownNat n
1676− => TypeExpression schema pg
1677− -> TypeExpression schema (nullity ('PGfixarray n pg))
1678−fixarray ty = UnsafeTypeExpression $
1679− renderTypeExpression ty <> "[" <> renderNat @n <> "]"
1680−
1681−-- | `pgtype` is a demoted version of a `PGType`
1682−class PGTyped schema (ty :: NullityType) where
1683− pgtype :: TypeExpression schema ty
1684−instance PGTyped schema (nullity 'PGbool) where pgtype = bool
1685−instance PGTyped schema (nullity 'PGint2) where pgtype = int2
1686−instance PGTyped schema (nullity 'PGint4) where pgtype = int4
1687−instance PGTyped schema (nullity 'PGint8) where pgtype = int8
1688−instance PGTyped schema (nullity 'PGnumeric) where pgtype = numeric
1689−instance PGTyped schema (nullity 'PGfloat4) where pgtype = float4
1690−instance PGTyped schema (nullity 'PGfloat8) where pgtype = float8
1691−instance PGTyped schema (nullity 'PGtext) where pgtype = text
1692−instance (KnownNat n, 1 <= n)
1693− => PGTyped schema (nullity ('PGchar n)) where pgtype = char @n
1694−instance (KnownNat n, 1 <= n)
1695− => PGTyped schema (nullity ('PGvarchar n)) where pgtype = varchar @n
1696−instance PGTyped schema (nullity 'PGbytea) where pgtype = bytea
1697−instance PGTyped schema (nullity 'PGtimestamp) where pgtype = timestamp
1698−instance PGTyped schema (nullity 'PGtimestamptz) where pgtype = timestampWithTimeZone
1699−instance PGTyped schema (nullity 'PGdate) where pgtype = date
1700−instance PGTyped schema (nullity 'PGtime) where pgtype = time
1701−instance PGTyped schema (nullity 'PGtimetz) where pgtype = timeWithTimeZone
1702−instance PGTyped schema (nullity 'PGinterval) where pgtype = interval
1703−instance PGTyped schema (nullity 'PGuuid) where pgtype = uuid
1704−instance PGTyped schema (nullity 'PGjson) where pgtype = json
1705−instance PGTyped schema (nullity 'PGjsonb) where pgtype = jsonb
1706−instance PGTyped schema ty
1707− => PGTyped schema (nullity ('PGvararray ty)) where
1708− pgtype = vararray (pgtype @schema @ty)
1709−instance (KnownNat n, PGTyped schema ty)
1710− => PGTyped schema (nullity ('PGfixarray n ty)) where
1711− pgtype = fixarray @n (pgtype @schema @ty)