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