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