@@ -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,515 +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 (PGTypeOf ty)
251− -> Expression schema relations grouping params ty
252− parameter ty = UnsafeExpression $ parenthesized $
253− "$" <> renderNat (Proxy @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 (PGTypeOf 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 ('Null 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−-- >>> type Complex = PGcomposite '["real" ::: 'PGfloat8, "imaginary" ::: 'PGfloat8]
451−-- >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression '[] '[] 'Ungrouped '[] ('NotNull Complex)
452−-- >>> printSQL i
453−-- ROW(0, 1)
454−row
455− :: SListI (Nulls fields)
456− => NP (Aliased (Expression schema relations grouping params)) (Nulls fields)
457− -- ^ zero or more expressions for the row field values
458− -> Expression schema relations grouping params (nullity ('PGcomposite fields))
459−row exprs = UnsafeExpression $ "ROW" <> parenthesized
460− (renderCommaSeparated (\ (expr `As` _) -> renderExpression expr) exprs)
461−
462−instance Has field fields ty => IsLabel field
463− ( Expression schema relation grouping params (nullity ('PGcomposite fields))
464− -> Expression schema relation grouping params ('Null ty) ) where
465− fromLabel expr = UnsafeExpression $
466− parenthesized (renderExpression expr) <> "." <>
467− fromString (symbolVal (Proxy @field))
468−
469−instance Semigroup
470− (Expression schema relations grouping params (nullity ('PGvararray ty))) where
471− (<>) = unsafeBinaryOp "||"
472−
473−instance Monoid
474− (Expression schema relations grouping params (nullity ('PGvararray ty))) where
475− mempty = array []
476− mappend = (<>)
477−
478−-- | >>> let expr = greatest currentTimestamp [param @1] :: Expression sch rels grp '[ 'NotNull 'PGtimestamptz] ('NotNull 'PGtimestamptz)
479−-- >>> printSQL expr
480−-- GREATEST(CURRENT_TIMESTAMP, ($1 :: timestamp with time zone))
481−greatest
482− :: Expression schema relations grouping params (nullty)
483− -- ^ needs at least 1 argument
484− -> [Expression schema relations grouping params (nullty)]
485− -- ^ or more
486− -> Expression schema relations grouping params (nullty)
487−greatest x xs = UnsafeExpression $ "GREATEST("
488− <> commaSeparated (renderExpression <$> (x:xs)) <> ")"
489−
490−-- | >>> printSQL $ least currentTimestamp [null_]
491−-- LEAST(CURRENT_TIMESTAMP, NULL)
492−least
493− :: Expression schema relations grouping params (nullty)
494− -- ^ needs at least 1 argument
495− -> [Expression schema relations grouping params (nullty)]
496− -- ^ or more
497− -> Expression schema relations grouping params (nullty)
498−least x xs = UnsafeExpression $ "LEAST("
499− <> commaSeparated (renderExpression <$> (x:xs)) <> ")"
312+ (Expression outer commons grp schemas params from (null ('PGenum labels))) where
313+ label = UnsafeExpression $ renderSQL (PGlabel @label)
500314
501315-- | >>> printSQL $ unsafeBinaryOp "OR" true false
502316-- (TRUE OR FALSE)
503−unsafeBinaryOp
504− :: ByteString
505− -- ^ operator
506− -> Expression schema relations grouping params (ty0)
507− -> Expression schema relations grouping params (ty1)
508− -> Expression schema relations grouping params (ty2)
317+unsafeBinaryOp :: ByteString -> Operator ty0 ty1 ty2
509318unsafeBinaryOp op x y = UnsafeExpression $ parenthesized $
510− 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
511327
512−-- | >>> printSQL $ unsafeUnaryOp "NOT" true
328+-- | >>> printSQL $ unsafeLeftOp "NOT" true
513329-- (NOT TRUE)
514−unsafeUnaryOp
515− :: ByteString
516− -- ^ operator
517− -> Expression schema relations grouping params (ty0)
518− -> Expression schema relations grouping params (ty1)
519−unsafeUnaryOp op x = UnsafeExpression $ parenthesized $
520− 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
521351
522352-- | >>> printSQL $ unsafeFunction "f" true
523353-- f(TRUE)
524−unsafeFunction
525− :: ByteString
526− -- ^ function
527− -> Expression schema relations grouping params (xty)
528− -> Expression schema relations grouping params (yty)
354+unsafeFunction :: ByteString -> x --> y
529355unsafeFunction fun x = UnsafeExpression $
530− fun <> parenthesized (renderExpression x)
531−
532−unsafeVariadicFunction
533− :: SListI elems
534− => ByteString
535− -- ^ function
536− -> NP (Expression schema relations grouping params) elems
537− -> Expression schema relations grouping params ret
538−unsafeVariadicFunction fun x = UnsafeExpression $
539− fun <> parenthesized (commaSeparated (hcollapse (hmap (K . renderExpression) x)))
540−
541−instance PGNum ty
542− => 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
543380 (+) = unsafeBinaryOp "+"
544381 (-) = unsafeBinaryOp "-"
545382 (*) = unsafeBinaryOp "*"
@@ -550,19 +387,24 @@ instance PGNum ty
550387 . fromString
551388 . show
552389
553−instance (PGNum ty, PGFloating ty) => Fractional
554− (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
555392 (/) = unsafeBinaryOp "/"
556− fromRational x = fromInteger (numerator x) / fromInteger (denominator x)
393+ fromRational
394+ = UnsafeExpression
395+ . fromString
396+ . ($ "")
397+ . showFFloat Nothing
398+ . fromRat @Double
557399
558−instance (PGNum ty, PGFloating ty) => Floating
559− (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
560402 pi = UnsafeExpression "pi()"
561403 exp = unsafeFunction "exp"
562404 log = unsafeFunction "ln"
563405 sqrt = unsafeFunction "sqrt"
564406 b ** x = UnsafeExpression $
565− "power(" <> renderExpression b <> ", " <> renderExpression x <> ")"
407+ "power(" <> renderSQL b <> ", " <> renderSQL x <> ")"
566408 logBase b y = log y / log b
567409 sin = unsafeFunction "sin"
568410 cos = unsafeFunction "cos"
@@ -577,1129 +419,54 @@ instance (PGNum ty, PGFloating ty) => Floating
577419 acosh x = log (x + sqrt (x*x - 1))
578420 atanh x = log ((1 + x) / (1 - x)) / 2
579421
580−-- | >>> :{
581−-- let
582−-- expression :: Expression schema relations grouping params (nullity 'PGfloat4)
583−-- expression = atan2_ pi 2
584−-- in printSQL expression
585−-- :}
586−-- atan2(pi(), 2)
587−atan2_
588− :: PGFloating float
589− => Expression schema relations grouping params (nullity float)
590− -- ^ numerator
591− -> Expression schema relations grouping params (nullity float)
592− -- ^ denominator
593− -> Expression schema relations grouping params (nullity float)
594−atan2_ y x = UnsafeExpression $
595− "atan2(" <> renderExpression y <> ", " <> renderExpression x <> ")"
596−
597−-- When a `cast` is applied to an `Expression` of a known type, it
598−-- represents a run-time type conversion. The cast will succeed only if a
599−-- suitable type conversion operation has been defined.
600−--
601−-- | >>> printSQL $ true & cast int4
602−-- (TRUE :: int4)
603−cast
604− :: TypeExpression schema ty1
605− -- ^ type to cast as
606− -> Expression schema relations grouping params (nullity ty0)
607− -- ^ value to convert
608− -> Expression schema relations grouping params (nullity ty1)
609−cast ty x = UnsafeExpression $ parenthesized $
610− renderExpression x <+> "::" <+> renderTypeExpression ty
611−
612−-- | integer division, truncates the result
613−--
614−-- >>> :{
615−-- let
616−-- expression :: Expression schema relations grouping params (nullity 'PGint2)
617−-- expression = 5 `quot_` 2
618−-- in printSQL expression
619−-- :}
620−-- (5 / 2)
621−quot_
622− :: PGIntegral int
623− => Expression schema relations grouping params (nullity int)
624− -- ^ numerator
625− -> Expression schema relations grouping params (nullity int)
626− -- ^ denominator
627− -> Expression schema relations grouping params (nullity int)
628−quot_ = unsafeBinaryOp "/"
629−
630−-- | remainder upon integer division
631−--
632−-- >>> :{
633−-- let
634−-- expression :: Expression schema relations grouping params (nullity 'PGint2)
635−-- expression = 5 `rem_` 2
636−-- in printSQL expression
637−-- :}
638−-- (5 % 2)
639−rem_
640− :: PGIntegral int
641− => Expression schema relations grouping params (nullity int)
642− -- ^ numerator
643− -> Expression schema relations grouping params (nullity int)
644− -- ^ denominator
645− -> Expression schema relations grouping params (nullity int)
646−rem_ = unsafeBinaryOp "%"
647−
648−-- | >>> :{
649−-- let
650−-- expression :: Expression schema relations grouping params (nullity 'PGfloat4)
651−-- expression = trunc pi
652−-- in printSQL expression
653−-- :}
654−-- trunc(pi())
655−trunc
656− :: PGFloating frac
657− => Expression schema relations grouping params (nullity frac)
658− -- ^ fractional number
659− -> Expression schema relations grouping params (nullity frac)
660−trunc = unsafeFunction "trunc"
661−
662−-- | >>> :{
663−-- let
664−-- expression :: Expression schema relations grouping params (nullity 'PGfloat4)
665−-- expression = round_ pi
666−-- in printSQL expression
667−-- :}
668−-- round(pi())
669−round_
670− :: PGFloating frac
671− => Expression schema relations grouping params (nullity frac)
672− -- ^ fractional number
673− -> Expression schema relations grouping params (nullity frac)
674−round_ = unsafeFunction "round"
675−
676−-- | >>> :{
677−-- let
678−-- expression :: Expression schema relations grouping params (nullity 'PGfloat4)
679−-- expression = ceiling_ pi
680−-- in printSQL expression
681−-- :}
682−-- ceiling(pi())
683−ceiling_
684− :: PGFloating frac
685− => Expression schema relations grouping params (nullity frac)
686− -- ^ fractional number
687− -> Expression schema relations grouping params (nullity frac)
688−ceiling_ = unsafeFunction "ceiling"
689−
690−-- | A `Condition` is a boolean valued `Expression`. While SQL allows
691−-- conditions to have @NULL@, Squeal instead chooses to disallow @NULL@,
692−-- forcing one to handle the case of @NULL@ explicitly to produce
693−-- a `Condition`.
694−type Condition schema relations grouping params =
695− Expression schema relations grouping params ('NotNull 'PGbool)
696−
697−-- | >>> printSQL true
698−-- TRUE
699−true :: Condition schema relations grouping params
700−true = UnsafeExpression "TRUE"
701−
702−-- | >>> printSQL false
703−-- FALSE
704−false :: Condition schema relations grouping params
705−false = UnsafeExpression "FALSE"
706−
707−-- | >>> printSQL $ not_ true
708−-- (NOT TRUE)
709−not_
710− :: Condition schema relations grouping params
711− -> Condition schema relations grouping params
712−not_ = unsafeUnaryOp "NOT"
713−
714−-- | >>> printSQL $ true .&& false
715−-- (TRUE AND FALSE)
716−(.&&)
717− :: Condition schema relations grouping params
718− -> Condition schema relations grouping params
719− -> Condition schema relations grouping params
720−(.&&) = unsafeBinaryOp "AND"
721−
722−-- | >>> printSQL $ true .|| false
723−-- (TRUE OR FALSE)
724−(.||)
725− :: Condition schema relations grouping params
726− -> Condition schema relations grouping params
727− -> Condition schema relations grouping params
728−(.||) = unsafeBinaryOp "OR"
729−
730−-- | >>> :{
731−-- let
732−-- expression :: Expression schema relations grouping params (nullity 'PGint2)
733−-- expression = caseWhenThenElse [(true, 1), (false, 2)] 3
734−-- in printSQL expression
735−-- :}
736−-- CASE WHEN TRUE THEN 1 WHEN FALSE THEN 2 ELSE 3 END
737−caseWhenThenElse
738− :: [ ( Condition schema relations grouping params
739− , Expression schema relations grouping params (ty)
740− ) ]
741− -- ^ whens and thens
742− -> Expression schema relations grouping params (ty)
743− -- ^ else
744− -> Expression schema relations grouping params (ty)
745−caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
746− [ "CASE"
747− , mconcat
748− [ mconcat
749− [ " WHEN ", renderExpression when_
750− , " THEN ", renderExpression then_
751− ]
752− | (when_,then_) <- whenThens
753− ]
754− , " ELSE ", renderExpression else_
755− , " END"
756− ]
757−
758−-- | >>> :{
759−-- let
760−-- expression :: Expression schema relations grouping params (nullity 'PGint2)
761−-- expression = ifThenElse true 1 0
762−-- in printSQL expression
763−-- :}
764−-- CASE WHEN TRUE THEN 1 ELSE 0 END
765−ifThenElse
766− :: Condition schema relations grouping params
767− -> Expression schema relations grouping params (ty) -- ^ then
768− -> Expression schema relations grouping params (ty) -- ^ else
769− -> Expression schema relations grouping params (ty)
770−ifThenElse if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
771−
772−-- | Comparison operations like `.==`, `./=`, `.>`, `.>=`, `.<` and `.<=`
773−-- will produce @NULL@s if one of their arguments is @NULL@.
774−--
775−-- >>> printSQL $ notNull true .== null_
776−-- (TRUE = NULL)
777−(.==)
778− :: Expression schema relations grouping params (nullity ty) -- ^ lhs
779− -> Expression schema relations grouping params (nullity ty) -- ^ rhs
780− -> Expression schema relations grouping params (nullity 'PGbool)
781−(.==) = unsafeBinaryOp "="
782−infix 4 .==
783−
784−-- | >>> printSQL $ notNull true ./= null_
785−-- (TRUE <> NULL)
786−(./=)
787− :: Expression schema relations grouping params (nullity ty) -- ^ lhs
788− -> Expression schema relations grouping params (nullity ty) -- ^ rhs
789− -> Expression schema relations grouping params (nullity 'PGbool)
790−(./=) = unsafeBinaryOp "<>"
791−infix 4 ./=
792−
793−-- | >>> printSQL $ notNull true .>= null_
794−-- (TRUE >= NULL)
795−(.>=)
796− :: Expression schema relations grouping params (nullity ty) -- ^ lhs
797− -> Expression schema relations grouping params (nullity ty) -- ^ rhs
798− -> Expression schema relations grouping params (nullity 'PGbool)
799−(.>=) = unsafeBinaryOp ">="
800−infix 4 .>=
801−
802−-- | >>> printSQL $ notNull true .< null_
803−-- (TRUE < NULL)
804−(.<)
805− :: Expression schema relations grouping params (nullity ty) -- ^ lhs
806− -> Expression schema relations grouping params (nullity ty) -- ^ rhs
807− -> Expression schema relations grouping params (nullity 'PGbool)
808−(.<) = unsafeBinaryOp "<"
809−infix 4 .<
810−
811−-- | >>> printSQL $ notNull true .<= null_
812−-- (TRUE <= NULL)
813−(.<=)
814− :: Expression schema relations grouping params (nullity ty) -- ^ lhs
815− -> Expression schema relations grouping params (nullity ty) -- ^ rhs
816− -> Expression schema relations grouping params (nullity 'PGbool)
817−(.<=) = unsafeBinaryOp "<="
818−infix 4 .<=
819−
820−-- | >>> printSQL $ notNull true .> null_
821−-- (TRUE > NULL)
822−(.>)
823− :: Expression schema relations grouping params (nullity ty) -- ^ lhs
824− -> Expression schema relations grouping params (nullity ty) -- ^ rhs
825− -> Expression schema relations grouping params (nullity 'PGbool)
826−(.>) = unsafeBinaryOp ">"
827−infix 4 .>
828−
829−-- | >>> printSQL currentDate
830−-- CURRENT_DATE
831−currentDate
832− :: Expression schema relations grouping params (nullity 'PGdate)
833−currentDate = UnsafeExpression "CURRENT_DATE"
834−
835−-- | >>> printSQL currentTime
836−-- CURRENT_TIME
837−currentTime
838− :: Expression schema relations grouping params (nullity 'PGtimetz)
839−currentTime = UnsafeExpression "CURRENT_TIME"
840−
841−-- | >>> printSQL currentTimestamp
842−-- CURRENT_TIMESTAMP
843−currentTimestamp
844− :: Expression schema relations grouping params (nullity 'PGtimestamptz)
845−currentTimestamp = UnsafeExpression "CURRENT_TIMESTAMP"
846−
847−-- | >>> printSQL localTime
848−-- LOCALTIME
849−localTime
850− :: Expression schema relations grouping params (nullity 'PGtime)
851−localTime = UnsafeExpression "LOCALTIME"
852−
853−-- | >>> printSQL localTimestamp
854−-- LOCALTIMESTAMP
855−localTimestamp
856− :: Expression schema relations grouping params (nullity 'PGtimestamp)
857−localTimestamp = UnsafeExpression "LOCALTIMESTAMP"
858−
859−{-----------------------------------------
860−text
861−-----------------------------------------}
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)
862438
863439instance IsString
864− (Expression schema relations grouping params (nullity 'PGtext)) where
440+ (Expression outer commons grp schemas params from (null 'PGtext)) where
865441 fromString str = UnsafeExpression $
866442 "E\'" <> fromString (escape =<< str) <> "\'"
867− where
868− escape = \case
869− '\NUL' -> "\\0"
870− '\'' -> "''"
871− '"' -> "\\\""
872− '\b' -> "\\b"
873− '\n' -> "\\n"
874− '\r' -> "\\r"
875− '\t' -> "\\t"
876− '\\' -> "\\\\"
877− 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) <> "\'"
878451
879452instance Semigroup
880− (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
881463 (<>) = unsafeBinaryOp "||"
882464
883465instance Monoid
884− (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
885471 mempty = fromString ""
886472 mappend = (<>)
887−
888−-- | >>> printSQL $ lower "ARRRGGG"
889−-- lower(E'ARRRGGG')
890−lower
891− :: Expression schema relations grouping params (nullity 'PGtext)
892− -- ^ string to lower case
893− -> Expression schema relations grouping params (nullity 'PGtext)
894−lower = unsafeFunction "lower"
895−
896−-- | >>> printSQL $ upper "eeee"
897−-- upper(E'eeee')
898−upper
899− :: Expression schema relations grouping params (nullity 'PGtext)
900− -- ^ string to upper case
901− -> Expression schema relations grouping params (nullity 'PGtext)
902−upper = unsafeFunction "upper"
903−
904−-- | >>> printSQL $ charLength "four"
905−-- char_length(E'four')
906−charLength
907− :: Expression schema relations grouping params (nullity 'PGtext)
908− -- ^ string to measure
909− -> Expression schema relations grouping params (nullity 'PGint4)
910−charLength = unsafeFunction "char_length"
911−
912−-- | The `like` expression returns true if the @string@ matches
913−-- the supplied @pattern@. If @pattern@ does not contain percent signs
914−-- or underscores, then the pattern only represents the string itself;
915−-- in that case `like` acts like the equals operator. An underscore (_)
916−-- in pattern stands for (matches) any single character; a percent sign (%)
917−-- matches any sequence of zero or more characters.
918−--
919−-- >>> printSQL $ "abc" `like` "a%"
920−-- (E'abc' LIKE E'a%')
921−like
922− :: Expression schema relations grouping params (nullity 'PGtext)
923− -- ^ string
924− -> Expression schema relations grouping params (nullity 'PGtext)
925− -- ^ pattern
926− -> Expression schema relations grouping params (nullity 'PGbool)
927−like = unsafeBinaryOp "LIKE"
928−
929−{-----------------------------------------
930− -- json and jsonb support
931−
932−See https://www.postgresql.org/docs/10/static/functions-json.html -- most
933−comments lifted directly from this page.
934−
935−Table 9.44: json and jsonb operators
936−-----------------------------------------}
937−
938−-- | Get JSON value (object field or array element) at a key.
939−(.->)
940− :: (PGjson_ json, PGjsonKey key)
941− => Expression schema relations grouping params (nullity json)
942− -> Expression schema relations grouping params (nullity key)
943− -> Expression schema relations grouping params ('Null json)
944−(.->) = unsafeBinaryOp "->"
945−
946−-- | Get JSON value (object field or array element) at a key, as text.
947−(.->>)
948− :: (PGjson_ json, PGjsonKey key)
949− => Expression schema relations grouping params (nullity json)
950− -> Expression schema relations grouping params (nullity key)
951− -> Expression schema relations grouping params ('Null 'PGtext)
952−(.->>) = unsafeBinaryOp "->>"
953−
954−-- | Get JSON value at a specified path.
955−(.#>)
956− :: (PGjson_ json, PGtextArray "(.#>)" path)
957− => Expression schema relations grouping params (nullity json)
958− -> Expression schema relations grouping params (nullity path)
959− -> Expression schema relations grouping params ('Null json)
960−(.#>) = unsafeBinaryOp "#>"
961−
962−-- | Get JSON value at a specified path as text.
963−(.#>>)
964− :: (PGjson_ json, PGtextArray "(.#>>)" path)
965− => Expression schema relations grouping params (nullity json)
966− -> Expression schema relations grouping params (nullity path)
967− -> Expression schema relations grouping params ('Null 'PGtext)
968−(.#>>) = unsafeBinaryOp "#>>"
969−
970−-- Additional jsonb operators
971−
972−-- | Does the left JSON value contain the right JSON path/value entries at the
973−-- top level?
974−(.@>)
975− :: Expression schema relations grouping params (nullity 'PGjsonb)
976− -> Expression schema relations grouping params (nullity 'PGjsonb)
977− -> Condition schema relations grouping params
978−(.@>) = unsafeBinaryOp "@>"
979−
980−-- | Are the left JSON path/value entries contained at the top level within the
981−-- right JSON value?
982−(.<@)
983− :: Expression schema relations grouping params (nullity 'PGjsonb)
984− -> Expression schema relations grouping params (nullity 'PGjsonb)
985− -> Condition schema relations grouping params
986−(.<@) = unsafeBinaryOp "<@"
987−
988−-- | Does the string exist as a top-level key within the JSON value?
989−(.?)
990− :: Expression schema relations grouping params (nullity 'PGjsonb)
991− -> Expression schema relations grouping params (nullity 'PGtext)
992− -> Condition schema relations grouping params
993−(.?) = unsafeBinaryOp "?"
994−
995−-- | Do any 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− -> Condition schema relations grouping params
1000−(.?|) = unsafeBinaryOp "?|"
1001−
1002−-- | Do all of these array strings exist as top-level keys?
1003−(.?&)
1004− :: Expression schema relations grouping params (nullity 'PGjsonb)
1005− -> Expression schema relations grouping params (nullity ('PGvararray 'PGtext))
1006− -> Condition schema relations grouping params
1007−(.?&) = unsafeBinaryOp "?&"
1008−
1009−-- | Concatenate two jsonb values into a new jsonb value.
1010−instance
1011− Semigroup (Expression schema relations grouping param (nullity 'PGjsonb)) where
1012− (<>) = unsafeBinaryOp "||"
1013−
1014−-- | Delete a key or keys from a JSON object, or remove an array element.
1015−--
1016−-- If the right operand is..
1017−--
1018−-- @ text @: Delete key/value pair or string element from left operand. Key/value pairs
1019−-- are matched based on their key value.
1020−--
1021−-- @ text[] @: Delete multiple key/value pairs or string elements
1022−-- from left operand. Key/value pairs are matched based on their key value.
1023−--
1024−-- @ integer @: Delete the array element with specified index (Negative integers
1025−-- count from the end). Throws an error if top level container is not an array.
1026−(.-.)
1027− :: (key `In` '[ 'PGtext, 'PGvararray 'PGtext, 'PGint4, 'PGint2 ]) -- hlint error without parens here
1028− => Expression schema relations grouping params (nullity 'PGjsonb)
1029− -> Expression schema relations grouping params (nullity key)
1030− -> Expression schema relations grouping params (nullity 'PGjsonb)
1031−(.-.) = unsafeBinaryOp "-"
1032−
1033−-- | Delete the field or element with specified path (for JSON arrays, negative
1034−-- integers count from the end)
1035−(#-.)
1036− :: PGtextArray "(#-.)" arrayty
1037− => Expression schema relations grouping params (nullity 'PGjsonb)
1038− -> Expression schema relations grouping params (nullity arrayty)
1039− -> Expression schema relations grouping params (nullity 'PGjsonb)
1040−(#-.) = unsafeBinaryOp "#-"
1041−
1042−{-----------------------------------------
1043−Table 9.45: JSON creation functions
1044−-----------------------------------------}
1045−
1046−-- | Literal binary JSON
1047−jsonbLit :: JSON.Value -> Expression schema relations grouping params (nullity 'PGjsonb)
1048−jsonbLit = cast jsonb . UnsafeExpression . singleQuotedUtf8 . toStrict . JSON.encode
1049−
1050−-- | Literal JSON
1051−jsonLit :: JSON.Value -> Expression schema relations grouping params (nullity 'PGjson)
1052−jsonLit = cast json . UnsafeExpression . singleQuotedUtf8 . toStrict . JSON.encode
1053−
1054−-- | Returns the value as json. Arrays and composites are converted
1055−-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1056−-- type to json, the cast function will be used to perform the conversion;
1057−-- otherwise, a scalar value is produced. For any scalar type other than a
1058−-- number, a Boolean, or a null value, the text representation will be used, in
1059−-- such a fashion that it is a valid json value.
1060−toJson
1061− :: Expression schema relations grouping params (nullity ty)
1062− -> Expression schema relations grouping params (nullity 'PGjson)
1063−toJson = unsafeFunction "to_json"
1064−
1065−-- | Returns the value as jsonb. Arrays and composites are converted
1066−-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1067−-- type to json, the cast function will be used to perform the conversion;
1068−-- otherwise, a scalar value is produced. For any scalar type other than a
1069−-- number, a Boolean, or a null value, the text representation will be used, in
1070−-- such a fashion that it is a valid jsonb value.
1071−toJsonb
1072− :: Expression schema relations grouping params (nullity ty)
1073− -> Expression schema relations grouping params (nullity 'PGjsonb)
1074−toJsonb = unsafeFunction "to_jsonb"
1075−
1076−-- | Returns the array as a JSON array. A PostgreSQL multidimensional array
1077−-- becomes a JSON array of arrays.
1078−arrayToJson
1079− :: PGarray "arrayToJson" arr
1080− => Expression schema relations grouping params (nullity arr)
1081− -> Expression schema relations grouping params (nullity 'PGjson)
1082−arrayToJson = unsafeFunction "array_to_json"
1083−
1084−-- | Returns the row as a JSON object.
1085−rowToJson
1086− :: Expression schema relations grouping params (nullity ('PGcomposite ty))
1087− -> Expression schema relations grouping params (nullity 'PGjson)
1088−rowToJson = unsafeFunction "row_to_json"
1089−
1090−-- | Builds a possibly-heterogeneously-typed JSON array out of a variadic
1091−-- argument list.
1092−jsonBuildArray
1093− :: SListI elems
1094− => NP (Expression schema relations grouping params) elems
1095− -> Expression schema relations grouping params (nullity 'PGjson)
1096−jsonBuildArray = unsafeVariadicFunction "json_build_array"
1097−
1098−-- | Builds a possibly-heterogeneously-typed (binary) JSON array out of a
1099−-- variadic argument list.
1100−jsonbBuildArray
1101− :: SListI elems
1102− => NP (Expression schema relations grouping params) elems
1103− -> Expression schema relations grouping params (nullity 'PGjsonb)
1104−jsonbBuildArray = unsafeVariadicFunction "jsonb_build_array"
1105−
1106−unsafeRowFunction
1107− :: All Top elems
1108− => NP (Aliased (Expression schema relations grouping params)) elems
1109− -> [ByteString]
1110−unsafeRowFunction =
1111− (`appEndo` []) . hcfoldMap (Proxy :: Proxy Top)
1112− (\(col `As` name) -> Endo $ \xs ->
1113− renderAliasString name : renderExpression col : xs)
1114−
1115−-- | Builds a possibly-heterogeneously-typed JSON object out of a variadic
1116−-- argument list. The elements of the argument list must alternate between text
1117−-- and values.
1118−jsonBuildObject
1119− :: All Top elems
1120− => NP (Aliased (Expression schema relations grouping params)) elems
1121− -> Expression schema relations grouping params (nullity 'PGjson)
1122−jsonBuildObject
1123− = unsafeFunction "json_build_object"
1124− . UnsafeExpression
1125− . commaSeparated
1126− . unsafeRowFunction
1127−
1128−-- | Builds a possibly-heterogeneously-typed (binary) JSON object out of a
1129−-- variadic argument list. The elements of the argument list must alternate
1130−-- between text and values.
1131−jsonbBuildObject
1132− :: All Top elems
1133− => NP (Aliased (Expression schema relations grouping params)) elems
1134− -> Expression schema relations grouping params (nullity 'PGjsonb)
1135−jsonbBuildObject
1136− = unsafeFunction "jsonb_build_object"
1137− . UnsafeExpression
1138− . commaSeparated
1139− . unsafeRowFunction
1140−
1141−-- | Builds a JSON object out of a text array. The array must have either
1142−-- exactly one dimension with an even number of members, in which case they are
1143−-- taken as alternating key/value pairs, or two dimensions such that each inner
1144−-- array has exactly two elements, which are taken as a key/value pair.
1145−jsonObject
1146− :: PGarrayOf "jsonObject" arr 'PGtext
1147− => Expression schema relations grouping params (nullity arr)
1148− -> Expression schema relations grouping params (nullity 'PGjson)
1149−jsonObject = unsafeFunction "json_object"
1150−
1151−-- | Builds a binary JSON object out of a text array. The array must have either
1152−-- exactly one dimension with an even number of members, in which case they are
1153−-- taken as alternating key/value pairs, or two dimensions such that each inner
1154−-- array has exactly two elements, which are taken as a key/value pair.
1155−jsonbObject
1156− :: PGarrayOf "jsonbObject" arr 'PGtext
1157− => Expression schema relations grouping params (nullity arr)
1158− -> Expression schema relations grouping params (nullity 'PGjsonb)
1159−jsonbObject = unsafeFunction "jsonb_object"
1160−
1161−-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1162−-- keys and one for values, that are zipped pairwise to create a JSON object.
1163−jsonZipObject
1164− :: ( PGarrayOf "jsonZipObject" keysArray 'PGtext
1165− , PGarrayOf "jsonZipObject" valuesArray 'PGtext)
1166− => Expression schema relations grouping params (nullity keysArray)
1167− -> Expression schema relations grouping params (nullity valuesArray)
1168− -> Expression schema relations grouping params (nullity 'PGjson)
1169−jsonZipObject ks vs =
1170− unsafeVariadicFunction "json_object" (ks :* vs :* Nil)
1171−
1172−-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1173−-- keys and one for values, that are zipped pairwise to create a binary JSON
1174−-- object.
1175−jsonbZipObject
1176− :: ( PGarrayOf "jsonbZipObject" keysArray 'PGtext
1177− , PGarrayOf "jsonbZipObject" valuesArray 'PGtext)
1178− => Expression schema relations grouping params (nullity keysArray)
1179− -> Expression schema relations grouping params (nullity valuesArray)
1180− -> Expression schema relations grouping params (nullity 'PGjsonb)
1181−jsonbZipObject ks vs =
1182− unsafeVariadicFunction "jsonb_object" (ks :* vs :* Nil)
1183−
1184−{-----------------------------------------
1185−Table 9.46: JSON processing functions
1186−-----------------------------------------}
1187−
1188−-- | Returns the number of elements in the outermost JSON array.
1189−jsonArrayLength
1190− :: Expression schema relations grouping params (nullity 'PGjson)
1191− -> Expression schema relations grouping params (nullity 'PGint4)
1192−jsonArrayLength = unsafeFunction "json_array_length"
1193−
1194−-- | Returns the number of elements in the outermost binary JSON array.
1195−jsonbArrayLength
1196− :: Expression schema relations grouping params (nullity 'PGjsonb)
1197− -> Expression schema relations grouping params (nullity 'PGint4)
1198−jsonbArrayLength = unsafeFunction "jsonb_array_length"
1199−
1200−-- | Returns JSON value pointed to by the given path (equivalent to #>
1201−-- operator).
1202−jsonExtractPath
1203− :: SListI elems
1204− => Expression schema relations grouping params (nullity 'PGjson)
1205− -> NP (Expression schema relations grouping params) elems
1206− -> Expression schema relations grouping params (nullity 'PGjsonb)
1207−jsonExtractPath x xs =
1208− unsafeVariadicFunction "json_extract_path" (x :* xs)
1209−
1210−-- | Returns JSON value pointed to by the given path (equivalent to #>
1211−-- operator).
1212−jsonbExtractPath
1213− :: SListI elems
1214− => Expression schema relations grouping params (nullity 'PGjsonb)
1215− -> NP (Expression schema relations grouping params) elems
1216− -> Expression schema relations grouping params (nullity 'PGjsonb)
1217−jsonbExtractPath x xs =
1218− unsafeVariadicFunction "jsonb_extract_path" (x :* xs)
1219−
1220−-- | Returns JSON value pointed to by the given path (equivalent to #>
1221−-- operator), as text.
1222−jsonExtractPathAsText
1223− :: SListI elems
1224− => Expression schema relations grouping params (nullity 'PGjson)
1225− -> NP (Expression schema relations grouping params) elems
1226− -> Expression schema relations grouping params (nullity 'PGjson)
1227−jsonExtractPathAsText x xs =
1228− unsafeVariadicFunction "json_extract_path_text" (x :* xs)
1229−
1230−-- | Returns JSON value pointed to by the given path (equivalent to #>
1231−-- operator), as text.
1232−jsonbExtractPathAsText
1233− :: SListI elems
1234− => Expression schema relations grouping params (nullity 'PGjsonb)
1235− -> NP (Expression schema relations grouping params) elems
1236− -> Expression schema relations grouping params (nullity 'PGjsonb)
1237−jsonbExtractPathAsText x xs =
1238− unsafeVariadicFunction "jsonb_extract_path_text" (x :* xs)
1239−
1240−-- | Returns set of keys in the outermost JSON object.
1241−jsonObjectKeys
1242− :: Expression schema relations grouping params (nullity 'PGjson)
1243− -> Expression schema relations grouping params (nullity 'PGtext)
1244−jsonObjectKeys = unsafeFunction "json_object_keys"
1245−
1246−-- | Returns set of keys in the outermost JSON object.
1247−jsonbObjectKeys
1248− :: Expression schema relations grouping params (nullity 'PGjsonb)
1249− -> Expression schema relations grouping params (nullity 'PGtext)
1250−jsonbObjectKeys = unsafeFunction "jsonb_object_keys"
1251−
1252−-- | Returns the type of the outermost JSON value as a text string. Possible
1253−-- types are object, array, string, number, boolean, and null.
1254−jsonTypeof
1255− :: Expression schema relations grouping params (nullity 'PGjson)
1256− -> Expression schema relations grouping params (nullity 'PGtext)
1257−jsonTypeof = unsafeFunction "json_typeof"
1258−
1259−-- | Returns the type of the outermost binary JSON value as a text string.
1260−-- Possible types are object, array, string, number, boolean, and null.
1261−jsonbTypeof
1262− :: Expression schema relations grouping params (nullity 'PGjsonb)
1263− -> Expression schema relations grouping params (nullity 'PGtext)
1264−jsonbTypeof = unsafeFunction "jsonb_typeof"
1265−
1266−-- | Returns its argument with all object fields that have null values omitted.
1267−-- Other null values are untouched.
1268−jsonStripNulls
1269− :: Expression schema relations grouping params (nullity 'PGjson)
1270− -> Expression schema relations grouping params (nullity 'PGjson)
1271−jsonStripNulls = unsafeFunction "json_strip_nulls"
1272−
1273−-- | Returns its argument with all object fields that have null values omitted.
1274−-- Other null values are untouched.
1275−jsonbStripNulls
1276− :: Expression schema relations grouping params (nullity 'PGjsonb)
1277− -> Expression schema relations grouping params (nullity 'PGjsonb)
1278−jsonbStripNulls = unsafeFunction "jsonb_strip_nulls"
1279−
1280−-- | @ jsonbSet target path new_value create_missing @
1281−--
1282−-- Returns target with the section designated by path replaced by new_value,
1283−-- or with new_value added if create_missing is true ( default is true) and the
1284−-- item designated by path does not exist. As with the path orientated
1285−-- operators, negative integers that appear in path count from the end of JSON
1286−-- arrays.
1287−jsonbSet
1288− :: PGtextArray "jsonbSet" arr
1289− => Expression schema relations grouping params (nullity 'PGjsonb)
1290− -> Expression schema relations grouping params (nullity arr)
1291− -> Expression schema relations grouping params (nullity 'PGjsonb)
1292− -> Maybe (Expression schema relations grouping params (nullity 'PGbool))
1293− -> Expression schema relations grouping params (nullity 'PGjsonb)
1294−jsonbSet tgt path val createMissing = case createMissing of
1295− Just m -> unsafeVariadicFunction "jsonb_set" (tgt :* path :* val :* m :* Nil)
1296− Nothing -> unsafeVariadicFunction "jsonb_set" (tgt :* path :* val :* Nil)
1297−
1298−-- | @ jsonbInsert target path new_value insert_after @
1299−--
1300−-- Returns target with new_value inserted. If target section designated by
1301−-- path is in a JSONB array, new_value will be inserted before target or after
1302−-- if insert_after is true (default is false). If target section designated by
1303−-- path is in JSONB object, new_value will be inserted only if target does not
1304−-- exist. As with the path orientated operators, negative integers that appear
1305−-- in path count from the end of JSON arrays.
1306−jsonbInsert
1307− :: PGtextArray "jsonbInsert" arr
1308− => Expression schema relations grouping params (nullity 'PGjsonb)
1309− -> Expression schema relations grouping params (nullity arr)
1310− -> Expression schema relations grouping params (nullity 'PGjsonb)
1311− -> Maybe (Expression schema relations grouping params (nullity 'PGbool))
1312− -> Expression schema relations grouping params (nullity 'PGjsonb)
1313−jsonbInsert tgt path val insertAfter = case insertAfter of
1314− Just i -> unsafeVariadicFunction "jsonb_insert" (tgt :* path :* val :* i :* Nil)
1315− Nothing -> unsafeVariadicFunction "jsonb_insert" (tgt :* path :* val :* Nil)
1316−
1317−-- | Returns its argument as indented JSON text.
1318−jsonbPretty
1319− :: Expression schema relations grouping params (nullity 'PGjsonb)
1320− -> Expression schema relations grouping params (nullity 'PGtext)
1321−jsonbPretty = unsafeFunction "jsonb_pretty"
1322−
1323−{-----------------------------------------
1324−aggregation
1325−-----------------------------------------}
1326−
1327−-- | escape hatch to define aggregate functions
1328−unsafeAggregate
1329− :: ByteString -- ^ aggregate function
1330− -> Expression schema relations 'Ungrouped params (xty)
1331− -> Expression schema relations ('Grouped bys) params (yty)
1332−unsafeAggregate fun x = UnsafeExpression $ mconcat
1333− [fun, "(", renderExpression x, ")"]
1334−
1335−-- | escape hatch to define aggregate functions over distinct values
1336−unsafeAggregateDistinct
1337− :: ByteString -- ^ aggregate function
1338− -> Expression schema relations 'Ungrouped params (xty)
1339− -> Expression schema relations ('Grouped bys) params (yty)
1340−unsafeAggregateDistinct fun x = UnsafeExpression $ mconcat
1341− [fun, "(DISTINCT ", renderExpression x, ")"]
1342−
1343−-- | >>> :{
1344−-- let
1345−-- expression :: Expression schema '[tab ::: '["col" ::: 'Null 'PGnumeric]] ('Grouped bys) params ('Null 'PGnumeric)
1346−-- expression = sum_ #col
1347−-- in printSQL expression
1348−-- :}
1349−-- sum("col")
1350−sum_
1351− :: PGNum ty
1352− => Expression schema relations 'Ungrouped params (nullity ty)
1353− -- ^ what to sum
1354− -> Expression schema relations ('Grouped bys) params (nullity ty)
1355−sum_ = unsafeAggregate "sum"
1356−
1357−-- | >>> :{
1358−-- let
1359−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGnumeric]] ('Grouped bys) params (nullity 'PGnumeric)
1360−-- expression = sumDistinct #col
1361−-- in printSQL expression
1362−-- :}
1363−-- sum(DISTINCT "col")
1364−sumDistinct
1365− :: PGNum ty
1366− => Expression schema relations 'Ungrouped params (nullity ty)
1367− -- ^ what to sum
1368− -> Expression schema relations ('Grouped bys) params (nullity ty)
1369−sumDistinct = unsafeAggregateDistinct "sum"
1370−
1371−-- | A constraint for `PGType`s that you can take averages of and the resulting
1372−-- `PGType`.
1373−class PGAvg ty avg | ty -> avg where
1374− avg, avgDistinct
1375− :: Expression schema relations 'Ungrouped params (nullity ty)
1376− -- ^ what to average
1377− -> Expression schema relations ('Grouped bys) params (nullity avg)
1378− avg = unsafeAggregate "avg"
1379− avgDistinct = unsafeAggregateDistinct "avg"
1380−instance PGAvg 'PGint2 'PGnumeric
1381−instance PGAvg 'PGint4 'PGnumeric
1382−instance PGAvg 'PGint8 'PGnumeric
1383−instance PGAvg 'PGnumeric 'PGnumeric
1384−instance PGAvg 'PGfloat4 'PGfloat8
1385−instance PGAvg 'PGfloat8 'PGfloat8
1386−instance PGAvg 'PGinterval 'PGinterval
1387−
1388−-- | >>> :{
1389−-- let
1390−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
1391−-- expression = bitAnd #col
1392−-- in printSQL expression
1393−-- :}
1394−-- bit_and("col")
1395−bitAnd
1396− :: PGIntegral int
1397− => Expression schema relations 'Ungrouped params (nullity int)
1398− -- ^ what to aggregate
1399− -> Expression schema relations ('Grouped bys) params (nullity int)
1400−bitAnd = unsafeAggregate "bit_and"
1401−
1402−-- | >>> :{
1403−-- let
1404−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
1405−-- expression = bitOr #col
1406−-- in printSQL expression
1407−-- :}
1408−-- bit_or("col")
1409−bitOr
1410− :: PGIntegral int
1411− => Expression schema relations 'Ungrouped params (nullity int)
1412− -- ^ what to aggregate
1413− -> Expression schema relations ('Grouped bys) params (nullity int)
1414−bitOr = unsafeAggregate "bit_or"
1415−
1416−-- | >>> :{
1417−-- let
1418−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
1419−-- expression = bitAndDistinct #col
1420−-- in printSQL expression
1421−-- :}
1422−-- bit_and(DISTINCT "col")
1423−bitAndDistinct
1424− :: PGIntegral int
1425− => Expression schema relations 'Ungrouped params (nullity int)
1426− -- ^ what to aggregate
1427− -> Expression schema relations ('Grouped bys) params (nullity int)
1428−bitAndDistinct = unsafeAggregateDistinct "bit_and"
1429−
1430−-- | >>> :{
1431−-- let
1432−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
1433−-- expression = bitOrDistinct #col
1434−-- in printSQL expression
1435−-- :}
1436−-- bit_or(DISTINCT "col")
1437−bitOrDistinct
1438− :: PGIntegral int
1439− => Expression schema relations 'Ungrouped params (nullity int)
1440− -- ^ what to aggregate
1441− -> Expression schema relations ('Grouped bys) params (nullity int)
1442−bitOrDistinct = unsafeAggregateDistinct "bit_or"
1443−
1444−-- | >>> :{
1445−-- let
1446−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1447−-- expression = boolAnd #col
1448−-- in printSQL expression
1449−-- :}
1450−-- bool_and("col")
1451−boolAnd
1452− :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1453− -- ^ what to aggregate
1454− -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1455−boolAnd = unsafeAggregate "bool_and"
1456−
1457−-- | >>> :{
1458−-- let
1459−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1460−-- expression = boolOr #col
1461−-- in printSQL expression
1462−-- :}
1463−-- bool_or("col")
1464−boolOr
1465− :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1466− -- ^ what to aggregate
1467− -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1468−boolOr = unsafeAggregate "bool_or"
1469−
1470−-- | >>> :{
1471−-- let
1472−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1473−-- expression = boolAndDistinct #col
1474−-- in printSQL expression
1475−-- :}
1476−-- bool_and(DISTINCT "col")
1477−boolAndDistinct
1478− :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1479− -- ^ what to aggregate
1480− -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1481−boolAndDistinct = unsafeAggregateDistinct "bool_and"
1482−
1483−-- | >>> :{
1484−-- let
1485−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1486−-- expression = boolOrDistinct #col
1487−-- in printSQL expression
1488−-- :}
1489−-- bool_or(DISTINCT "col")
1490−boolOrDistinct
1491− :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1492− -- ^ what to aggregate
1493− -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1494−boolOrDistinct = unsafeAggregateDistinct "bool_or"
1495−
1496−-- | A special aggregation that does not require an input
1497−--
1498−-- >>> printSQL countStar
1499−-- count(*)
1500−countStar
1501− :: Expression schema relations ('Grouped bys) params ('NotNull 'PGint8)
1502−countStar = UnsafeExpression $ "count(*)"
1503−
1504−-- | >>> :{
1505−-- let
1506−-- expression :: Expression schema '[tab ::: '["col" ::: nullity ty]] (Grouped bys) params ('NotNull 'PGint8)
1507−-- expression = count #col
1508−-- in printSQL expression
1509−-- :}
1510−-- count("col")
1511−count
1512− :: Expression schema relations 'Ungrouped params ty
1513− -- ^ what to count
1514− -> Expression schema relations ('Grouped bys) params ('NotNull 'PGint8)
1515−count = unsafeAggregate "count"
1516−
1517−-- | >>> :{
1518−-- let
1519−-- expression :: Expression schema '[tab ::: '["col" ::: nullity ty]] (Grouped bys) params ('NotNull 'PGint8)
1520−-- expression = countDistinct #col
1521−-- in printSQL expression
1522−-- :}
1523−-- count(DISTINCT "col")
1524−countDistinct
1525− :: Expression schema relations 'Ungrouped params ty
1526− -- ^ what to count
1527− -> Expression schema relations ('Grouped bys) params ('NotNull 'PGint8)
1528−countDistinct = unsafeAggregateDistinct "count"
1529−
1530−-- | synonym for `boolAnd`
1531−--
1532−-- >>> :{
1533−-- let
1534−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1535−-- expression = every #col
1536−-- in printSQL expression
1537−-- :}
1538−-- every("col")
1539−every
1540− :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1541− -- ^ what to aggregate
1542− -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1543−every = unsafeAggregate "every"
1544−
1545−-- | synonym for `boolAndDistinct`
1546−--
1547−-- >>> :{
1548−-- let
1549−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1550−-- expression = everyDistinct #col
1551−-- in printSQL expression
1552−-- :}
1553−-- every(DISTINCT "col")
1554−everyDistinct
1555− :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1556− -- ^ what to aggregate
1557− -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1558−everyDistinct = unsafeAggregateDistinct "every"
1559−
1560−-- | minimum and maximum aggregation
1561−max_, min_, maxDistinct, minDistinct
1562− :: Expression schema relations 'Ungrouped params (nullity ty)
1563− -- ^ what to aggregate
1564− -> Expression schema relations ('Grouped bys) params (nullity ty)
1565−max_ = unsafeAggregate "max"
1566−min_ = unsafeAggregate "min"
1567−maxDistinct = unsafeAggregateDistinct "max"
1568−minDistinct = unsafeAggregateDistinct "min"
1569−
1570−{-----------------------------------------
1571−type expressions
1572−-----------------------------------------}
1573−
1574−-- | `TypeExpression`s are used in `cast`s and `createTable` commands.
1575−newtype TypeExpression (schema :: SchemaType) (ty :: PGType)
1576− = UnsafeTypeExpression { renderTypeExpression :: ByteString }
1577− deriving (GHC.Generic,Show,Eq,Ord,NFData)
1578−
1579−instance (Has alias schema ('Typedef ty))
1580− => IsLabel alias (TypeExpression schema ty) where
1581− fromLabel = UnsafeTypeExpression (renderAlias (fromLabel @alias))
1582−
1583−-- | logical Boolean (true/false)
1584−bool :: TypeExpression schema 'PGbool
1585−bool = UnsafeTypeExpression "bool"
1586−-- | signed two-byte integer
1587−int2, smallint :: TypeExpression schema 'PGint2
1588−int2 = UnsafeTypeExpression "int2"
1589−smallint = UnsafeTypeExpression "smallint"
1590−-- | signed four-byte integer
1591−int4, int, integer :: TypeExpression schema 'PGint4
1592−int4 = UnsafeTypeExpression "int4"
1593−int = UnsafeTypeExpression "int"
1594−integer = UnsafeTypeExpression "integer"
1595−-- | signed eight-byte integer
1596−int8, bigint :: TypeExpression schema 'PGint8
1597−int8 = UnsafeTypeExpression "int8"
1598−bigint = UnsafeTypeExpression "bigint"
1599−-- | arbitrary precision numeric type
1600−numeric :: TypeExpression schema 'PGnumeric
1601−numeric = UnsafeTypeExpression "numeric"
1602−-- | single precision floating-point number (4 bytes)
1603−float4, real :: TypeExpression schema 'PGfloat4
1604−float4 = UnsafeTypeExpression "float4"
1605−real = UnsafeTypeExpression "real"
1606−-- | double precision floating-point number (8 bytes)
1607−float8, doublePrecision :: TypeExpression schema 'PGfloat8
1608−float8 = UnsafeTypeExpression "float8"
1609−doublePrecision = UnsafeTypeExpression "double precision"
1610−-- | variable-length character string
1611−text :: TypeExpression schema 'PGtext
1612−text = UnsafeTypeExpression "text"
1613−-- | fixed-length character string
1614−char, character
1615− :: (KnownNat n, 1 <= n)
1616− => proxy n
1617− -> TypeExpression schema ('PGchar n)
1618−char p = UnsafeTypeExpression $ "char(" <> renderNat p <> ")"
1619−character p = UnsafeTypeExpression $ "character(" <> renderNat p <> ")"
1620−-- | variable-length character string
1621−varchar, characterVarying
1622− :: (KnownNat n, 1 <= n)
1623− => proxy n
1624− -> TypeExpression schema ('PGvarchar n)
1625−varchar p = UnsafeTypeExpression $ "varchar(" <> renderNat p <> ")"
1626−characterVarying p = UnsafeTypeExpression $
1627− "character varying(" <> renderNat p <> ")"
1628−-- | binary data ("byte array")
1629−bytea :: TypeExpression schema 'PGbytea
1630−bytea = UnsafeTypeExpression "bytea"
1631−-- | date and time (no time zone)
1632−timestamp :: TypeExpression schema 'PGtimestamp
1633−timestamp = UnsafeTypeExpression "timestamp"
1634−-- | date and time, including time zone
1635−timestampWithTimeZone :: TypeExpression schema 'PGtimestamptz
1636−timestampWithTimeZone = UnsafeTypeExpression "timestamp with time zone"
1637−-- | calendar date (year, month, day)
1638−date :: TypeExpression schema 'PGdate
1639−date = UnsafeTypeExpression "date"
1640−-- | time of day (no time zone)
1641−time :: TypeExpression schema 'PGtime
1642−time = UnsafeTypeExpression "time"
1643−-- | time of day, including time zone
1644−timeWithTimeZone :: TypeExpression schema 'PGtimetz
1645−timeWithTimeZone = UnsafeTypeExpression "time with time zone"
1646−-- | time span
1647−interval :: TypeExpression schema 'PGinterval
1648−interval = UnsafeTypeExpression "interval"
1649−-- | universally unique identifier
1650−uuid :: TypeExpression schema 'PGuuid
1651−uuid = UnsafeTypeExpression "uuid"
1652−-- | IPv4 or IPv6 host address
1653−inet :: TypeExpression schema 'PGinet
1654−inet = UnsafeTypeExpression "inet"
1655−-- | textual JSON data
1656−json :: TypeExpression schema 'PGjson
1657−json = UnsafeTypeExpression "json"
1658−-- | binary JSON data, decomposed
1659−jsonb :: TypeExpression schema 'PGjsonb
1660−jsonb = UnsafeTypeExpression "jsonb"
1661−-- | variable length array
1662−vararray
1663− :: TypeExpression schema pg
1664− -> TypeExpression schema ('PGvararray pg)
1665−vararray ty = UnsafeTypeExpression $ renderTypeExpression ty <> "[]"
1666−-- | fixed length array
1667−--
1668−-- >>> renderTypeExpression (fixarray (Proxy @2) json)
1669−-- "json[2]"
1670−fixarray
1671− :: KnownNat n
1672− => proxy n
1673− -> TypeExpression schema pg
1674− -> TypeExpression schema ('PGfixarray n pg)
1675−fixarray p ty = UnsafeTypeExpression $
1676− renderTypeExpression ty <> "[" <> renderNat p <> "]"
1677−
1678−-- | `pgtype` is a demoted version of a `PGType`
1679−class PGTyped schema (ty :: PGType) where pgtype :: TypeExpression schema ty
1680−instance PGTyped schema 'PGbool where pgtype = bool
1681−instance PGTyped schema 'PGint2 where pgtype = int2
1682−instance PGTyped schema 'PGint4 where pgtype = int4
1683−instance PGTyped schema 'PGint8 where pgtype = int8
1684−instance PGTyped schema 'PGnumeric where pgtype = numeric
1685−instance PGTyped schema 'PGfloat4 where pgtype = float4
1686−instance PGTyped schema 'PGfloat8 where pgtype = float8
1687−instance PGTyped schema 'PGtext where pgtype = text
1688−instance (KnownNat n, 1 <= n)
1689− => PGTyped schema ('PGchar n) where pgtype = char (Proxy @n)
1690−instance (KnownNat n, 1 <= n)
1691− => PGTyped schema ('PGvarchar n) where pgtype = varchar (Proxy @n)
1692−instance PGTyped schema 'PGbytea where pgtype = bytea
1693−instance PGTyped schema 'PGtimestamp where pgtype = timestamp
1694−instance PGTyped schema 'PGtimestamptz where pgtype = timestampWithTimeZone
1695−instance PGTyped schema 'PGdate where pgtype = date
1696−instance PGTyped schema 'PGtime where pgtype = time
1697−instance PGTyped schema 'PGtimetz where pgtype = timeWithTimeZone
1698−instance PGTyped schema 'PGinterval where pgtype = interval
1699−instance PGTyped schema 'PGuuid where pgtype = uuid
1700−instance PGTyped schema 'PGjson where pgtype = json
1701−instance PGTyped schema 'PGjsonb where pgtype = jsonb
1702−instance PGTyped schema ty => PGTyped schema ('PGvararray ty) where
1703− pgtype = vararray (pgtype @schema @ty)
1704−instance (KnownNat n, PGTyped schema ty) => PGTyped schema ('PGfixarray n ty) where
1705− pgtype = fixarray (Proxy @n) (pgtype @schema @ty)