@@ -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,486 +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− , atan2_
54− , cast
55− , quot_
56− , rem_
57− , trunc
58− , round_
59− , ceiling_
60− , greatest
61− , least
62− -- ** Conditions
63− , Condition
64− , true
65− , false
66− , not_
67− , (.&&)
68− , (.||)
69− , caseWhenThenElse
70− , ifThenElse
71− , (.==)
72− , (./=)
73− , (.>=)
74− , (.<)
75− , (.<=)
76− , (.>)
77− -- ** Time
78− , currentDate
79− , currentTime
80− , currentTimestamp
81− , localTime
82− , localTimestamp
83− -- ** Text
84− , lower
85− , upper
86− , charLength
87− , like
88− -- ** json or jsonb operators
89− , PGarray
90− , PGarrayOf
91− , (.->)
92− , (.->>)
93− , (.#>)
94− , (.#>>)
95− -- *** jsonb only operators
96− , (.@>)
97− , (.<@)
98− , (.?)
99− , (.?|)
100− , (.?&)
101− , (.||.)
102− , (.-.)
103− , (#-.)
104− -- *** Functions
105− , toJson
106− , toJsonb
107− , arrayToJson
108− , rowToJson
109− -- ** Aggregation
110− , unsafeAggregate, unsafeAggregateDistinct
111− , sum_, sumDistinct
112− , PGAvg (avg, avgDistinct)
113− , bitAnd, bitOr, boolAnd, boolOr
114− , bitAndDistinct, bitOrDistinct, boolAndDistinct, boolOrDistinct
115− , countStar
116− , count, countDistinct
117− , every, everyDistinct
118− , max_, maxDistinct, min_, minDistinct
119− -- * Types
120− , TypeExpression (UnsafeTypeExpression, renderTypeExpression)
121− , PGTyped (pgtype)
122− , bool
123− , int2
124− , smallint
125− , int4
126− , int
127− , integer
128− , int8
129− , bigint
130− , numeric
131− , float4
132− , real
133− , float8
134− , doublePrecision
135− , text
136− , char
137− , character
138− , varchar
139− , characterVarying
140− , bytea
141− , timestamp
142− , timestampWithTimeZone
143− , date
144− , time
145− , timeWithTimeZone
146− , interval
147− , uuid
148− , inet
149− , json
150− , jsonb
151− , vararray
152− , 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 (..)
15357 -- * Re-export
15458 , (&)
155− , NP ((:*), Nil)
59+ , K (..)
60+ , unK
15661 ) where
15762
15863import Control.Category
15964import Control.DeepSeq
16065import Data.ByteString (ByteString)
16166import Data.Function ((&))
162−import Data.Semigroup
163−import Data.Ratio
67+import Data.Semigroup hiding (All)
16468import Data.String
165−import Generics.SOP hiding (from)
166−import GHC.Exts (Constraint)
69+import Generics.SOP hiding (All, from)
16770import GHC.OverloadedLabels
16871import GHC.TypeLits
72+import Numeric
16973import Prelude hiding (id, (.))
17074
17175import qualified GHC.Generics as GHC
17276
77+import Squeal.PostgreSQL.Alias
78+import Squeal.PostgreSQL.List
17379import Squeal.PostgreSQL.Render
17480import Squeal.PostgreSQL.Schema
17581
82+-- $setup
83+-- >>> import Squeal.PostgreSQL
84+
17685{-----------------------------------------
17786column expressions
17887-----------------------------------------}
17988
18089{- | `Expression`s are used in a variety of contexts,
181−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,
18292as new column values in `Squeal.PostgreSQL.Manipulation.insertRow` or
18393`Squeal.PostgreSQL.Manipulation.update`,
184−or in search `Condition`s in a number of commands.
94+or in search `Squeal.PostgreSQL.Logic.Condition`s in a number of commands.
18595
18696The expression syntax allows the calculation of
18797values from primitive expression using arithmetic, logical,
18898and 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`.
189113-}
190114newtype Expression
191− (schema :: SchemaType)
192− (relations :: RelationsType)
193− (grouping :: Grouping)
115+ (outer :: FromType)
116+ (commons :: FromType)
117+ (grp :: Grouping)
118+ (schemas :: SchemasType)
194119 (params :: [NullityType])
120+ (from :: FromType)
195121 (ty :: NullityType)
196122 = UnsafeExpression { renderExpression :: ByteString }
197123 deriving (GHC.Generic,Show,Eq,Ord,NFData)
198−
199−instance RenderSQL (Expression schema relations grouping params ty) where
124+instance RenderSQL (Expression outer commons grp schemas params from ty) where
200125 renderSQL = renderExpression
201126
202−{- | A `HasParameter` constraint is used to indicate a value that is
203−supplied externally to a SQL statement.
204−`Squeal.PostgreSQL.PQ.manipulateParams`,
205−`Squeal.PostgreSQL.PQ.queryParams` and
206−`Squeal.PostgreSQL.PQ.traversePrepared` support specifying data values
207−separately from the SQL command string, in which case `param`s are used to
208−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)
209181-}
210−class KnownNat n => HasParameter
211− (n :: Nat)
212− (schema :: SchemaType)
213− (params :: [NullityType])
214− (ty :: NullityType)
215− | n params -> ty where
216− -- | `parameter` takes a `Nat` using type application and a `TypeExpression`.
217− --
218− -- >>> let expr = parameter @1 int4 :: Expression sch rels grp '[ 'Null 'PGint4] ('Null 'PGint4)
219− -- >>> printSQL expr
220− -- ($1 :: int4)
221− parameter
222− :: TypeExpression schema (PGTypeOf ty)
223− -> Expression schema relations grouping params ty
224− parameter ty = UnsafeExpression $ parenthesized $
225− "$" <> renderNat (Proxy @n) <+> "::"
226− <+> renderTypeExpression ty
227−instance {-# OVERLAPPING #-} HasParameter 1 schema (ty1:tys) ty1
228−instance {-# OVERLAPPABLE #-} (KnownNat n, HasParameter (n-1) schema params ty)
229− => HasParameter n schema (ty' : params) ty
230−
231−-- | `param` takes a `Nat` using type application and for basic types,
232−-- infers a `TypeExpression`.
233−--
234−-- >>> let expr = param @1 :: Expression sch rels grp '[ 'Null 'PGint4] ('Null 'PGint4)
235−-- >>> printSQL expr
236−-- ($1 :: int4)
237−param
238− :: forall n schema params relations grouping ty
239− . (PGTyped schema (PGTypeOf ty), HasParameter n schema params ty)
240− => Expression schema relations grouping params ty -- ^ param
241−param = parameter @n pgtype
242−
243−instance (HasUnique relation relations columns, Has column columns ty)
244− => IsLabel column (Expression schema relations 'Ungrouped params ty) where
245− fromLabel = UnsafeExpression $ renderAlias (Alias @column)
246−instance (HasUnique relation relations columns, Has column columns ty)
247− => IsLabel column
248− (Aliased (Expression schema relations 'Ungrouped params) (column ::: ty)) where
249− fromLabel = fromLabel @column `As` Alias @column
250−instance (HasUnique relation relations columns, Has column columns ty)
251− => IsLabel column
252− (NP (Aliased (Expression schema relations 'Ungrouped params)) '[column ::: ty]) where
253− fromLabel = fromLabel @column :* Nil
254−
255−instance (Has relation relations columns, Has column columns ty)
256− => IsQualified relation column (Expression schema relations 'Ungrouped params ty) where
257− relation ! column = UnsafeExpression $
258− renderAlias relation <> "." <> renderAlias column
259−instance (Has relation relations columns, Has column columns ty)
260− => IsQualified relation column
261− (Aliased (Expression schema relations 'Ungrouped params) (column ::: ty)) where
262− relation ! column = relation ! column `As` column
263−instance (Has relation relations columns, Has column columns ty)
264− => IsQualified relation column
265− (NP (Aliased (Expression schema relations 'Ungrouped params)) '[column ::: ty]) where
266− 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
267245
268246instance
269− ( HasUnique relation relations columns
270− , Has column columns ty
271− , GroupedBy relation column bys
272− ) => IsLabel column
273− (Expression schema relations ('Grouped bys) params ty) where
274− 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
275261instance
276− ( HasUnique relation relations columns
277− , Has column columns ty
278− , GroupedBy relation column bys
279− ) => IsLabel column
280− ( Aliased (Expression schema relations ('Grouped bys) params)
281− (column ::: ty) ) where
282− 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
283269instance
284− ( HasUnique relation relations columns
285− , Has column columns ty
286− , GroupedBy relation column bys
287− ) => IsLabel column
288− ( NP (Aliased (Expression schema relations ('Grouped bys) params))
289− '[column ::: ty] ) where
290− 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
291277
292278instance
293− ( Has relation relations columns
294− , Has column columns ty
295− , GroupedBy relation column bys
296− ) => IsQualified relation column
297− (Expression schema relations ('Grouped bys) params ty) where
298− relation ! column = UnsafeExpression $
299− 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
300286instance
301− ( Has relation relations columns
302− , Has column columns ty
303− , GroupedBy relation column bys
304− ) => IsQualified relation column
305− (Aliased (Expression schema relations ('Grouped bys) params)
306− (column ::: ty)) where
307− 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
308294instance
309− ( Has relation relations columns
310− , Has column columns ty
311− , GroupedBy relation column bys
312− ) => IsQualified relation column
313− ( NP (Aliased (Expression schema relations ('Grouped bys) params))
314− '[column ::: ty]) where
315− relation ! column = relation ! column :* Nil
316−
317−-- | analagous to `Nothing`
318−--
319−-- >>> printSQL null_
320−-- NULL
321−null_ :: Expression schema rels grouping params ('Null ty)
322−null_ = UnsafeExpression "NULL"
323−
324−-- | analagous to `Just`
325−--
326−-- >>> printSQL $ notNull true
327−-- TRUE
328−notNull
329− :: Expression schema rels grouping params ('NotNull ty)
330− -> Expression schema rels grouping params ('Null ty)
331−notNull = UnsafeExpression . renderExpression
332−
333−-- | return the leftmost value which is not NULL
334−--
335−-- >>> printSQL $ coalesce [null_, notNull true] false
336−-- COALESCE(NULL, TRUE, FALSE)
337−coalesce
338− :: [Expression schema relations grouping params ('Null ty)]
339− -- ^ @NULL@s may be present
340− -> Expression schema relations grouping params ('NotNull ty)
341− -- ^ @NULL@ is absent
342− -> Expression schema relations grouping params ('NotNull ty)
343−coalesce nullxs notNullx = UnsafeExpression $
344− "COALESCE" <> parenthesized (commaSeparated
345− ((renderExpression <$> nullxs) <> [renderExpression notNullx]))
346−
347−-- | analagous to `Data.Maybe.fromMaybe` using @COALESCE@
348−--
349−-- >>> printSQL $ fromNull true null_
350−-- COALESCE(NULL, TRUE)
351−fromNull
352− :: Expression schema relations grouping params ('NotNull ty)
353− -- ^ what to convert @NULL@ to
354− -> Expression schema relations grouping params ('Null ty)
355− -> Expression schema relations grouping params ('NotNull ty)
356−fromNull notNullx nullx = coalesce [nullx] notNullx
357−
358−-- | >>> printSQL $ null_ & isNull
359−-- NULL IS NULL
360−isNull
361− :: Expression schema relations grouping params ('Null ty)
362− -- ^ possibly @NULL@
363− -> Condition schema relations grouping params
364−isNull x = UnsafeExpression $ renderExpression x <+> "IS NULL"
365−
366−-- | >>> printSQL $ null_ & isNotNull
367−-- NULL IS NOT NULL
368−isNotNull
369− :: Expression schema relations grouping params ('Null ty)
370− -- ^ possibly @NULL@
371− -> Condition schema relations grouping params
372−isNotNull x = UnsafeExpression $ renderExpression x <+> "IS NOT NULL"
373−
374−-- | analagous to `maybe` using @IS NULL@
375−--
376−-- >>> printSQL $ matchNull true not_ null_
377−-- CASE WHEN NULL IS NULL THEN TRUE ELSE (NOT NULL) END
378−matchNull
379− :: Expression schema relations grouping params (nullty)
380− -- ^ what to convert @NULL@ to
381− -> ( Expression schema relations grouping params ('NotNull ty)
382− -> Expression schema relations grouping params (nullty) )
383− -- ^ function to perform when @NULL@ is absent
384− -> Expression schema relations grouping params ('Null ty)
385− -> Expression schema relations grouping params (nullty)
386−matchNull y f x = ifThenElse (isNull x) y
387− (f (UnsafeExpression (renderExpression x)))
388−
389−{-| right inverse to `fromNull`, if its arguments are equal then
390−`nullIf` gives @NULL@.
391−
392−>>> :set -XTypeApplications -XDataKinds
393−>>> let expr = nullIf false (param @1) :: Expression schema rels grp '[ 'NotNull 'PGbool] ('Null 'PGbool)
394−>>> printSQL expr
395−NULL IF (FALSE, ($1 :: bool))
396−-}
397−nullIf
398− :: Expression schema relations grouping params ('NotNull ty)
399− -- ^ @NULL@ is absent
400− -> Expression schema relations grouping params ('NotNull ty)
401− -- ^ @NULL@ is absent
402− -> Expression schema relations grouping params ('Null ty)
403−nullIf x y = UnsafeExpression $ "NULL IF" <+> parenthesized
404− (renderExpression x <> ", " <> renderExpression y)
405−
406−-- | >>> printSQL $ array [null_, notNull false, notNull true]
407−-- ARRAY[NULL, FALSE, TRUE]
408−array
409− :: [Expression schema relations grouping params ('Null ty)]
410− -- ^ array elements
411− -> Expression schema relations grouping params (nullity ('PGvararray ty))
412−array xs = UnsafeExpression $
413− "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
414310
415311instance (KnownSymbol label, label `In` labels) => IsPGlabel label
416− (Expression schema relations grouping params (nullity ('PGenum labels))) where
417− label = UnsafeExpression $ renderLabel (PGlabel @label)
418−
419−-- | A row constructor is an expression that builds a row value
420−-- (also called a composite value) using values for its member fields.
421−--
422−-- >>> type Complex = PGcomposite '["real" ::: 'PGfloat8, "imaginary" ::: 'PGfloat8]
423−-- >>> let i = row (0 `As` #real :* 1 `As` #imaginary :* Nil) :: Expression '[] '[] 'Ungrouped '[] ('NotNull Complex)
424−-- >>> printSQL i
425−-- ROW(0, 1)
426−row
427− :: SListI (Nulls fields)
428− => NP (Aliased (Expression schema relations grouping params)) (Nulls fields)
429− -- ^ zero or more expressions for the row field values
430− -> Expression schema relations grouping params (nullity ('PGcomposite fields))
431−row exprs = UnsafeExpression $ "ROW" <> parenthesized
432− (renderCommaSeparated (\ (expr `As` _) -> renderExpression expr) exprs)
433−
434−instance Has field fields ty => IsLabel field
435− ( Expression schema relation grouping params (nullity ('PGcomposite fields))
436− -> Expression schema relation grouping params ('Null ty) ) where
437− fromLabel expr = UnsafeExpression $
438− parenthesized (renderExpression expr) <> "." <>
439− fromString (symbolVal (Proxy @field))
440−
441−instance Semigroup
442− (Expression schema relations grouping params (nullity ('PGvararray ty))) where
443− (<>) = unsafeBinaryOp "||"
444−
445−instance Monoid
446− (Expression schema relations grouping params (nullity ('PGvararray ty))) where
447− mempty = array []
448− mappend = (<>)
449−
450−-- | >>> let expr = greatest currentTimestamp [param @1] :: Expression sch rels grp '[ 'NotNull 'PGtimestamptz] ('NotNull 'PGtimestamptz)
451−-- >>> printSQL expr
452−-- GREATEST(CURRENT_TIMESTAMP, ($1 :: timestamp with time zone))
453−greatest
454− :: Expression schema relations grouping params (nullty)
455− -- ^ needs at least 1 argument
456− -> [Expression schema relations grouping params (nullty)]
457− -- ^ or more
458− -> Expression schema relations grouping params (nullty)
459−greatest x xs = UnsafeExpression $ "GREATEST("
460− <> commaSeparated (renderExpression <$> (x:xs)) <> ")"
461−
462−-- | >>> printSQL $ least currentTimestamp [null_]
463−-- LEAST(CURRENT_TIMESTAMP, NULL)
464−least
465− :: Expression schema relations grouping params (nullty)
466− -- ^ needs at least 1 argument
467− -> [Expression schema relations grouping params (nullty)]
468− -- ^ or more
469− -> Expression schema relations grouping params (nullty)
470−least x xs = UnsafeExpression $ "LEAST("
471− <> commaSeparated (renderExpression <$> (x:xs)) <> ")"
312+ (Expression outer commons grp schemas params from (null ('PGenum labels))) where
313+ label = UnsafeExpression $ renderSQL (PGlabel @label)
472314
473315-- | >>> printSQL $ unsafeBinaryOp "OR" true false
474316-- (TRUE OR FALSE)
475−unsafeBinaryOp
476− :: ByteString
477− -- ^ operator
478− -> Expression schema relations grouping params (ty0)
479− -> Expression schema relations grouping params (ty1)
480− -> Expression schema relations grouping params (ty2)
317+unsafeBinaryOp :: ByteString -> Operator ty0 ty1 ty2
481318unsafeBinaryOp op x y = UnsafeExpression $ parenthesized $
482− renderExpression x <+> op <+> renderExpression y
319+ renderSQL x <+> op <+> renderSQL y
483320
484−-- | >>> 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
485329-- (NOT TRUE)
486−unsafeUnaryOp
487− :: ByteString
488− -- ^ operator
489− -> Expression schema relations grouping params (ty0)
490− -> Expression schema relations grouping params (ty1)
491−unsafeUnaryOp op x = UnsafeExpression $ parenthesized $
492− 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
493351
494352-- | >>> printSQL $ unsafeFunction "f" true
495353-- f(TRUE)
496−unsafeFunction
497− :: ByteString
498− -- ^ function
499− -> Expression schema relations grouping params (xty)
500− -> Expression schema relations grouping params (yty)
354+unsafeFunction :: ByteString -> x --> y
501355unsafeFunction fun x = UnsafeExpression $
502− fun <> parenthesized (renderExpression x)
503−
504−unsafeVariadicFunction
505− :: ByteString
506− -- ^ function
507− -> [Expression schema relations grouping params xty]
508− -> Expression schema relations grouping params (yty)
509−unsafeVariadicFunction fun x = UnsafeExpression $
510− fun <> parenthesized (commaSeparated (map renderExpression x))
511−
512−instance PGNum ty
513− => 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
514380 (+) = unsafeBinaryOp "+"
515381 (-) = unsafeBinaryOp "-"
516382 (*) = unsafeBinaryOp "*"
@@ -521,19 +387,24 @@ instance PGNum ty
521387 . fromString
522388 . show
523389
524−instance (PGNum ty, PGFloating ty) => Fractional
525− (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
526392 (/) = unsafeBinaryOp "/"
527− fromRational x = fromInteger (numerator x) / fromInteger (denominator x)
393+ fromRational
394+ = UnsafeExpression
395+ . fromString
396+ . ($ "")
397+ . showFFloat Nothing
398+ . fromRat @Double
528399
529−instance (PGNum ty, PGFloating ty) => Floating
530− (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
531402 pi = UnsafeExpression "pi()"
532403 exp = unsafeFunction "exp"
533404 log = unsafeFunction "ln"
534405 sqrt = unsafeFunction "sqrt"
535406 b ** x = UnsafeExpression $
536− "power(" <> renderExpression b <> ", " <> renderExpression x <> ")"
407+ "power(" <> renderSQL b <> ", " <> renderSQL x <> ")"
537408 logBase b y = log y / log b
538409 sin = unsafeFunction "sin"
539410 cos = unsafeFunction "cos"
@@ -548,916 +419,54 @@ instance (PGNum ty, PGFloating ty) => Floating
548419 acosh x = log (x + sqrt (x*x - 1))
549420 atanh x = log ((1 + x) / (1 - x)) / 2
550421
551−-- | >>> :{
552−-- let
553−-- expression :: Expression schema relations grouping params (nullity 'PGfloat4)
554−-- expression = atan2_ pi 2
555−-- in printSQL expression
556−-- :}
557−-- atan2(pi(), 2)
558−atan2_
559− :: PGFloating float
560− => Expression schema relations grouping params (nullity float)
561− -- ^ numerator
562− -> Expression schema relations grouping params (nullity float)
563− -- ^ denominator
564− -> Expression schema relations grouping params (nullity float)
565−atan2_ y x = UnsafeExpression $
566− "atan2(" <> renderExpression y <> ", " <> renderExpression x <> ")"
567−
568−-- When a `cast` is applied to an `Expression` of a known type, it
569−-- represents a run-time type conversion. The cast will succeed only if a
570−-- suitable type conversion operation has been defined.
571−--
572−-- | >>> printSQL $ true & cast int4
573−-- (TRUE :: int4)
574−cast
575− :: TypeExpression schema ty1
576− -- ^ type to cast as
577− -> Expression schema relations grouping params (nullity ty0)
578− -- ^ value to convert
579− -> Expression schema relations grouping params (nullity ty1)
580−cast ty x = UnsafeExpression $ parenthesized $
581− renderExpression x <+> "::" <+> renderTypeExpression ty
582−
583−-- | integer division, truncates the result
584−--
585−-- >>> :{
586−-- let
587−-- expression :: Expression schema relations grouping params (nullity 'PGint2)
588−-- expression = 5 `quot_` 2
589−-- in printSQL expression
590−-- :}
591−-- (5 / 2)
592−quot_
593− :: PGIntegral int
594− => Expression schema relations grouping params (nullity int)
595− -- ^ numerator
596− -> Expression schema relations grouping params (nullity int)
597− -- ^ denominator
598− -> Expression schema relations grouping params (nullity int)
599−quot_ = unsafeBinaryOp "/"
600−
601−-- | remainder upon integer division
602−--
603−-- >>> :{
604−-- let
605−-- expression :: Expression schema relations grouping params (nullity 'PGint2)
606−-- expression = 5 `rem_` 2
607−-- in printSQL expression
608−-- :}
609−-- (5 % 2)
610−rem_
611− :: PGIntegral int
612− => Expression schema relations grouping params (nullity int)
613− -- ^ numerator
614− -> Expression schema relations grouping params (nullity int)
615− -- ^ denominator
616− -> Expression schema relations grouping params (nullity int)
617−rem_ = unsafeBinaryOp "%"
618−
619−-- | >>> :{
620−-- let
621−-- expression :: Expression schema relations grouping params (nullity 'PGfloat4)
622−-- expression = trunc pi
623−-- in printSQL expression
624−-- :}
625−-- trunc(pi())
626−trunc
627− :: PGFloating frac
628− => Expression schema relations grouping params (nullity frac)
629− -- ^ fractional number
630− -> Expression schema relations grouping params (nullity frac)
631−trunc = unsafeFunction "trunc"
632−
633−-- | >>> :{
634−-- let
635−-- expression :: Expression schema relations grouping params (nullity 'PGfloat4)
636−-- expression = round_ pi
637−-- in printSQL expression
638−-- :}
639−-- round(pi())
640−round_
641− :: PGFloating frac
642− => Expression schema relations grouping params (nullity frac)
643− -- ^ fractional number
644− -> Expression schema relations grouping params (nullity frac)
645−round_ = unsafeFunction "round"
646−
647−-- | >>> :{
648−-- let
649−-- expression :: Expression schema relations grouping params (nullity 'PGfloat4)
650−-- expression = ceiling_ pi
651−-- in printSQL expression
652−-- :}
653−-- ceiling(pi())
654−ceiling_
655− :: PGFloating frac
656− => Expression schema relations grouping params (nullity frac)
657− -- ^ fractional number
658− -> Expression schema relations grouping params (nullity frac)
659−ceiling_ = unsafeFunction "ceiling"
660−
661−-- | A `Condition` is a boolean valued `Expression`. While SQL allows
662−-- conditions to have @NULL@, Squeal instead chooses to disallow @NULL@,
663−-- forcing one to handle the case of @NULL@ explicitly to produce
664−-- a `Condition`.
665−type Condition schema relations grouping params =
666− Expression schema relations grouping params ('NotNull 'PGbool)
667−
668−-- | >>> printSQL true
669−-- TRUE
670−true :: Condition schema relations grouping params
671−true = UnsafeExpression "TRUE"
672−
673−-- | >>> printSQL false
674−-- FALSE
675−false :: Condition schema relations grouping params
676−false = UnsafeExpression "FALSE"
677−
678−-- | >>> printSQL $ not_ true
679−-- (NOT TRUE)
680−not_
681− :: Condition schema relations grouping params
682− -> Condition schema relations grouping params
683−not_ = unsafeUnaryOp "NOT"
684−
685−-- | >>> printSQL $ true .&& false
686−-- (TRUE AND FALSE)
687−(.&&)
688− :: Condition schema relations grouping params
689− -> Condition schema relations grouping params
690− -> Condition schema relations grouping params
691−(.&&) = unsafeBinaryOp "AND"
692−
693−-- | >>> printSQL $ true .|| false
694−-- (TRUE OR FALSE)
695−(.||)
696− :: Condition schema relations grouping params
697− -> Condition schema relations grouping params
698− -> Condition schema relations grouping params
699−(.||) = unsafeBinaryOp "OR"
700−
701−-- | >>> :{
702−-- let
703−-- expression :: Expression schema relations grouping params (nullity 'PGint2)
704−-- expression = caseWhenThenElse [(true, 1), (false, 2)] 3
705−-- in printSQL expression
706−-- :}
707−-- CASE WHEN TRUE THEN 1 WHEN FALSE THEN 2 ELSE 3 END
708−caseWhenThenElse
709− :: [ ( Condition schema relations grouping params
710− , Expression schema relations grouping params (ty)
711− ) ]
712− -- ^ whens and thens
713− -> Expression schema relations grouping params (ty)
714− -- ^ else
715− -> Expression schema relations grouping params (ty)
716−caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
717− [ "CASE"
718− , mconcat
719− [ mconcat
720− [ " WHEN ", renderExpression when_
721− , " THEN ", renderExpression then_
722− ]
723− | (when_,then_) <- whenThens
724− ]
725− , " ELSE ", renderExpression else_
726− , " END"
727− ]
728−
729−-- | >>> :{
730−-- let
731−-- expression :: Expression schema relations grouping params (nullity 'PGint2)
732−-- expression = ifThenElse true 1 0
733−-- in printSQL expression
734−-- :}
735−-- CASE WHEN TRUE THEN 1 ELSE 0 END
736−ifThenElse
737− :: Condition schema relations grouping params
738− -> Expression schema relations grouping params (ty) -- ^ then
739− -> Expression schema relations grouping params (ty) -- ^ else
740− -> Expression schema relations grouping params (ty)
741−ifThenElse if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
742−
743−-- | Comparison operations like `.==`, `./=`, `.>`, `.>=`, `.<` and `.<=`
744−-- will produce @NULL@s if one of their arguments is @NULL@.
745−--
746−-- >>> printSQL $ notNull true .== null_
747−-- (TRUE = NULL)
748−(.==)
749− :: Expression schema relations grouping params (nullity ty) -- ^ lhs
750− -> Expression schema relations grouping params (nullity ty) -- ^ rhs
751− -> Expression schema relations grouping params (nullity 'PGbool)
752−(.==) = unsafeBinaryOp "="
753−infix 4 .==
754−
755−-- | >>> printSQL $ notNull true ./= null_
756−-- (TRUE <> NULL)
757−(./=)
758− :: Expression schema relations grouping params (nullity ty) -- ^ lhs
759− -> Expression schema relations grouping params (nullity ty) -- ^ rhs
760− -> Expression schema relations grouping params (nullity 'PGbool)
761−(./=) = unsafeBinaryOp "<>"
762−infix 4 ./=
763−
764−-- | >>> printSQL $ notNull true .>= null_
765−-- (TRUE >= NULL)
766−(.>=)
767− :: Expression schema relations grouping params (nullity ty) -- ^ lhs
768− -> Expression schema relations grouping params (nullity ty) -- ^ rhs
769− -> Expression schema relations grouping params (nullity 'PGbool)
770−(.>=) = unsafeBinaryOp ">="
771−infix 4 .>=
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 currentDate
801−-- CURRENT_DATE
802−currentDate
803− :: Expression schema relations grouping params (nullity 'PGdate)
804−currentDate = UnsafeExpression "CURRENT_DATE"
805−
806−-- | >>> printSQL currentTime
807−-- CURRENT_TIME
808−currentTime
809− :: Expression schema relations grouping params (nullity 'PGtimetz)
810−currentTime = UnsafeExpression "CURRENT_TIME"
811−
812−-- | >>> printSQL currentTimestamp
813−-- CURRENT_TIMESTAMP
814−currentTimestamp
815− :: Expression schema relations grouping params (nullity 'PGtimestamptz)
816−currentTimestamp = UnsafeExpression "CURRENT_TIMESTAMP"
817−
818−-- | >>> printSQL localTime
819−-- LOCALTIME
820−localTime
821− :: Expression schema relations grouping params (nullity 'PGtime)
822−localTime = UnsafeExpression "LOCALTIME"
823−
824−-- | >>> printSQL localTimestamp
825−-- LOCALTIMESTAMP
826−localTimestamp
827− :: Expression schema relations grouping params (nullity 'PGtimestamp)
828−localTimestamp = UnsafeExpression "LOCALTIMESTAMP"
829−
830−{-----------------------------------------
831−text
832−-----------------------------------------}
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)
833438
834439instance IsString
835− (Expression schema relations grouping params (nullity 'PGtext)) where
440+ (Expression outer commons grp schemas params from (null 'PGtext)) where
836441 fromString str = UnsafeExpression $
837442 "E\'" <> fromString (escape =<< str) <> "\'"
838− where
839− escape = \case
840− '\NUL' -> "\\0"
841− '\'' -> "''"
842− '"' -> "\\\""
843− '\b' -> "\\b"
844− '\n' -> "\\n"
845− '\r' -> "\\r"
846− '\t' -> "\\t"
847− '\\' -> "\\\\"
848− 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) <> "\'"
849451
850452instance Semigroup
851− (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
852463 (<>) = unsafeBinaryOp "||"
853464
854465instance Monoid
855− (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
856471 mempty = fromString ""
857472 mappend = (<>)
858−
859−-- | >>> printSQL $ lower "ARRRGGG"
860−-- lower(E'ARRRGGG')
861−lower
862− :: Expression schema relations grouping params (nullity 'PGtext)
863− -- ^ string to lower case
864− -> Expression schema relations grouping params (nullity 'PGtext)
865−lower = unsafeFunction "lower"
866−
867−-- | >>> printSQL $ upper "eeee"
868−-- upper(E'eeee')
869−upper
870− :: Expression schema relations grouping params (nullity 'PGtext)
871− -- ^ string to upper case
872− -> Expression schema relations grouping params (nullity 'PGtext)
873−upper = unsafeFunction "upper"
874−
875−-- | >>> printSQL $ charLength "four"
876−-- char_length(E'four')
877−charLength
878− :: Expression schema relations grouping params (nullity 'PGtext)
879− -- ^ string to measure
880− -> Expression schema relations grouping params (nullity 'PGint4)
881−charLength = unsafeFunction "char_length"
882−
883−-- | The `like` expression returns true if the @string@ matches
884−-- the supplied @pattern@. If @pattern@ does not contain percent signs
885−-- or underscores, then the pattern only represents the string itself;
886−-- in that case `like` acts like the equals operator. An underscore (_)
887−-- in pattern stands for (matches) any single character; a percent sign (%)
888−-- matches any sequence of zero or more characters.
889−--
890−-- >>> printSQL $ "abc" `like` "a%"
891−-- (E'abc' LIKE E'a%')
892−like
893− :: Expression schema relations grouping params (nullity 'PGtext)
894− -- ^ string
895− -> Expression schema relations grouping params (nullity 'PGtext)
896− -- ^ pattern
897− -> Expression schema relations grouping params (nullity 'PGbool)
898−like = unsafeBinaryOp "LIKE"
899−
900−{-----------------------------------------
901−json and jsonb operators
902−see https://www.postgresql.org/docs/10/static/functions-json.html
903−-----------------------------------------}
904−
905−type PGjsonKey key = key `In` '[ 'PGint2, 'PGint4, 'PGtext ]
906−type PGjson_ json = json `In` '[ 'PGjson, 'PGjsonb ]
907−
908−type Placeholder k
909− = 'Text "(_"
910− ':<>: 'Text "::"
911− ':<>: 'ShowType k ':<>:
912− 'Text ")"
913−
914−type ErrArrayOf arr ty = arr ':<>: 'Text " " ':<>: ty
915−type ErrPGfixarrayOf t = ErrArrayOf ('ShowType 'PGfixarray ':<>: 'Text " " ':<>: Placeholder Nat) t
916−type ErrPGvararrayOf t = ErrArrayOf ('ShowType 'PGvararray) t
917−
918−type family PGarray arr :: Constraint where
919− PGarray ('PGvararray x) = ()
920− PGarray ('PGfixarray n x) = ()
921− PGarray val = TypeError
922− ('Text "Unsatisfied PGarrayOf constraint. Expected either: "
923− ':$$: 'Text " • " ':<>: ErrPGvararrayOf (Placeholder PGType)
924− ':$$: 'Text " • " ':<>: ErrPGfixarrayOf (Placeholder PGType)
925− ':$$: 'Text "But got: " ':<>: 'ShowType val)
926−
927−type family PGarrayOf arr ty :: Constraint where
928− PGarrayOf ('PGvararray x) ty = x ~ ty
929− PGarrayOf ('PGfixarray n x) ty = x ~ ty
930− PGarrayOf val ty = TypeError
931− ('Text "Unsatisfied PGarrayOf constraint. Expected either: "
932− ':$$: 'Text " • " ':<>: ErrPGvararrayOf ('ShowType ty)
933− ':$$: 'Text " • " ':<>: ErrPGfixarrayOf ('ShowType ty)
934− ':$$: 'Text "But got: " ':<>: 'ShowType val)
935−
936−type IsPGtextArray arr = PGarrayOf arr 'PGtext
937−
938−-- | Get JSON value (object field or array element) at a key.
939−(.->)
940− :: (PGjson_ json, PGjsonKey key)
941− => Expression schema relations grouping params (jnull json)
942− -> Expression schema relations grouping params (knull key)
943− -> Expression schema relations grouping params ('Null json)
944−(.->) = unsafeBinaryOp "->"
945−
946−-- | Get JSON value (object field or array element) at a key, as text.
947−(.->>)
948− :: (PGjson_ json, PGjsonKey key)
949− => Expression schema relations grouping params (jnull json)
950− -> Expression schema relations grouping params (knull key)
951− -> Expression schema relations grouping params ('Null 'PGtext)
952−(.->>) = unsafeBinaryOp "->>"
953−
954−-- | Get JSON value at a specified path.
955−(.#>)
956− :: (PGjson_ json, IsPGtextArray path)
957− => Expression schema relations grouping params (jnull json)
958− -> Expression schema relations grouping params (knull path)
959− -> Expression schema relations grouping params ('Null json)
960−(.#>) = unsafeBinaryOp "#>"
961−
962−-- | Get JSON value at a specified path as text.
963−(.#>>)
964− :: (PGjson_ json, IsPGtextArray path)
965− => Expression schema relations grouping params (jnull json)
966− -> Expression schema relations grouping params (knull path)
967− -> Expression schema relations grouping params ('Null 'PGtext)
968−(.#>>) = unsafeBinaryOp "#>>"
969−
970−-- Additional jsonb operators
971−
972−-- | Or operator for nulls; if either argument is null, then the result is null.
973−type family Null2 a b where
974− Null2 'Null a = 'Null
975− Null2 a 'Null = 'Null
976− Null2 'NotNull 'NotNull = 'NotNull
977−
978−-- | See 'Null2'
979−type family NullOfN xs where
980− NullOfN ('Null ty:xs) = 'Null
981− NullOfN (x:xs) = NullOfN xs
982− NullOfN '[] = 'NotNull
983−
984−-- | Does the left JSON value contain the right JSON path/value entries at the
985−-- top level?
986−(.@>)
987− :: Expression schema relations grouping params (null0 'PGjsonb)
988− -> Expression schema relations grouping params (null1 'PGjsonb)
989− -> Expression schema relations grouping params (Null2 null0 null1 'PGbool)
990−(.@>) = unsafeBinaryOp "@>"
991−
992−-- | Are the left JSON path/value entries contained at the top level within the
993−-- right JSON value?
994−(.<@)
995− :: Expression schema relations grouping params (null0 'PGjsonb)
996− -> Expression schema relations grouping params (null1 'PGjsonb)
997− -> Expression schema relations grouping params (Null2 null0 null1 'PGbool)
998−(.<@) = unsafeBinaryOp "<@"
999−
1000−-- | Does the string exist as a top-level key within the JSON value?
1001−(.?)
1002− :: Expression schema relations grouping params (null0 'PGjsonb)
1003− -> Expression schema relations grouping params (null1 'PGtext)
1004− -> Expression schema relations grouping params (Null2 null0 null1 'PGbool)
1005−(.?) = unsafeBinaryOp "?"
1006−
1007−-- | Do any of these array strings exist as top-level keys?
1008−(.?|)
1009− :: Expression schema relations grouping params (null0 'PGjsonb)
1010− -> Expression schema relations grouping params (null1 ('PGvararray 'PGtext))
1011− -> Expression schema relations grouping params (Null2 null0 null1 'PGbool)
1012−(.?|) = unsafeBinaryOp "?|"
1013−
1014−-- | Do all of these array strings exist as top-level keys?
1015−(.?&)
1016− :: Expression schema relations grouping params (null0 'PGjsonb)
1017− -> Expression schema relations grouping params (null1 ('PGvararray 'PGtext))
1018− -> Expression schema relations grouping params (Null2 null0 null1 'PGbool)
1019−(.?&) = unsafeBinaryOp "?&"
1020−
1021−-- | Concatenate two jsonb values into a new jsonb value
1022−(.||.)
1023− :: Expression schema relations grouping params (null0 'PGjsonb)
1024− -> Expression schema relations grouping params (null1 'PGjsonb)
1025− -> Expression schema relations grouping params (Null2 null0 null1 'PGjsonb)
1026−(.||.) = unsafeBinaryOp "||"
1027−
1028−-- | Delete a key or keys from a JSON object, or remove an array element.
1029−--
1030−-- If the right operand is..
1031−--
1032−-- @ text @: Delete key/value pair or string element from left operand. Key/value pairs
1033−-- are matched based on their key value.
1034−--
1035−-- @ text[] @: Delete multiple key/value pairs or string elements
1036−-- from left operand. Key/value pairs are matched based on their key value.
1037−--
1038−-- @ integer @: Delete the array element with specified index (Negative integers
1039−-- count from the end). Throws an error if top level container is not an array.
1040−(.-.)
1041− :: (key `In` '[ 'PGtext, 'PGvararray 'PGtext, 'PGint4, 'PGint2 ]) -- hlint error without parens here
1042− => Expression schema relations grouping params (null0 'PGjsonb)
1043− -> Expression schema relations grouping params (null1 key)
1044− -> Expression schema relations grouping params (Null2 null0 null1 'PGjsonb)
1045−(.-.) = unsafeBinaryOp "-"
1046−
1047−-- | Delete the field or element with specified path (for JSON arrays, negative
1048−-- integers count from the end)
1049−(#-.)
1050− :: IsPGtextArray arrayty
1051− => Expression schema relations grouping params (null0 'PGjsonb)
1052− -> Expression schema relations grouping params (null1 arrayty)
1053− -> Expression schema relations grouping params (Null2 null0 null1 'PGjsonb)
1054−(#-.) = unsafeBinaryOp "#-"
1055−
1056−toJson
1057− :: Expression schema relations grouping params (nullity ty)
1058− -> Expression schema relations grouping params (nullity 'PGjson)
1059−toJson = unsafeFunction "to_json"
1060−
1061−toJsonb
1062− :: Expression schema relations grouping params (nullity ty)
1063− -> Expression schema relations grouping params (nullity 'PGjsonb)
1064−toJsonb = unsafeUnaryOp "to_jsonb"
1065−
1066−arrayToJson
1067− :: PGarray arr
1068− => Expression schema relations grouping params (nullity arr)
1069− -> Expression schema relations grouping params (nullity 'PGjson)
1070−arrayToJson = unsafeFunction "array_to_json"
1071−
1072−rowToJson
1073− :: Expression schema relations grouping params (nullity ('PGcomposite ty))
1074− -> Expression schema relations grouping params (nullity 'PGjson)
1075−rowToJson = unsafeFunction "row_to_json"
1076−
1077−-- TODO: jsonBuildArray, jsonbBuildArray, jsonObject, jsonbObject
1078−-- probably something like
1079−-- :: NP (Expression s r g p) xs -> Expression s r g p ('NotNull 'PGjson[b])
1080−
1081−{-----------------------------------------
1082−aggregation
1083−-----------------------------------------}
1084−
1085−-- | escape hatch to define aggregate functions
1086−unsafeAggregate
1087− :: ByteString -- ^ aggregate function
1088− -> Expression schema relations 'Ungrouped params (xty)
1089− -> Expression schema relations ('Grouped bys) params (yty)
1090−unsafeAggregate fun x = UnsafeExpression $ mconcat
1091− [fun, "(", renderExpression x, ")"]
1092−
1093−-- | escape hatch to define aggregate functions over distinct values
1094−unsafeAggregateDistinct
1095− :: ByteString -- ^ aggregate function
1096− -> Expression schema relations 'Ungrouped params (xty)
1097− -> Expression schema relations ('Grouped bys) params (yty)
1098−unsafeAggregateDistinct fun x = UnsafeExpression $ mconcat
1099− [fun, "(DISTINCT ", renderExpression x, ")"]
1100−
1101−-- | >>> :{
1102−-- let
1103−-- expression :: Expression schema '[tab ::: '["col" ::: 'Null 'PGnumeric]] ('Grouped bys) params ('Null 'PGnumeric)
1104−-- expression = sum_ #col
1105−-- in printSQL expression
1106−-- :}
1107−-- sum("col")
1108−sum_
1109− :: PGNum ty
1110− => Expression schema relations 'Ungrouped params (nullity ty)
1111− -- ^ what to sum
1112− -> Expression schema relations ('Grouped bys) params (nullity ty)
1113−sum_ = unsafeAggregate "sum"
1114−
1115−-- | >>> :{
1116−-- let
1117−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGnumeric]] ('Grouped bys) params (nullity 'PGnumeric)
1118−-- expression = sumDistinct #col
1119−-- in printSQL expression
1120−-- :}
1121−-- sum(DISTINCT "col")
1122−sumDistinct
1123− :: PGNum ty
1124− => Expression schema relations 'Ungrouped params (nullity ty)
1125− -- ^ what to sum
1126− -> Expression schema relations ('Grouped bys) params (nullity ty)
1127−sumDistinct = unsafeAggregateDistinct "sum"
1128−
1129−-- | A constraint for `PGType`s that you can take averages of and the resulting
1130−-- `PGType`.
1131−class PGAvg ty avg | ty -> avg where
1132− avg, avgDistinct
1133− :: Expression schema relations 'Ungrouped params (nullity ty)
1134− -- ^ what to average
1135− -> Expression schema relations ('Grouped bys) params (nullity avg)
1136− avg = unsafeAggregate "avg"
1137− avgDistinct = unsafeAggregateDistinct "avg"
1138−instance PGAvg 'PGint2 'PGnumeric
1139−instance PGAvg 'PGint4 'PGnumeric
1140−instance PGAvg 'PGint8 'PGnumeric
1141−instance PGAvg 'PGnumeric 'PGnumeric
1142−instance PGAvg 'PGfloat4 'PGfloat8
1143−instance PGAvg 'PGfloat8 'PGfloat8
1144−instance PGAvg 'PGinterval 'PGinterval
1145−
1146−-- | >>> :{
1147−-- let
1148−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
1149−-- expression = bitAnd #col
1150−-- in printSQL expression
1151−-- :}
1152−-- bit_and("col")
1153−bitAnd
1154− :: PGIntegral int
1155− => Expression schema relations 'Ungrouped params (nullity int)
1156− -- ^ what to aggregate
1157− -> Expression schema relations ('Grouped bys) params (nullity int)
1158−bitAnd = unsafeAggregate "bit_and"
1159−
1160−-- | >>> :{
1161−-- let
1162−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
1163−-- expression = bitOr #col
1164−-- in printSQL expression
1165−-- :}
1166−-- bit_or("col")
1167−bitOr
1168− :: PGIntegral int
1169− => Expression schema relations 'Ungrouped params (nullity int)
1170− -- ^ what to aggregate
1171− -> Expression schema relations ('Grouped bys) params (nullity int)
1172−bitOr = unsafeAggregate "bit_or"
1173−
1174−-- | >>> :{
1175−-- let
1176−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
1177−-- expression = bitAndDistinct #col
1178−-- in printSQL expression
1179−-- :}
1180−-- bit_and(DISTINCT "col")
1181−bitAndDistinct
1182− :: PGIntegral int
1183− => Expression schema relations 'Ungrouped params (nullity int)
1184− -- ^ what to aggregate
1185− -> Expression schema relations ('Grouped bys) params (nullity int)
1186−bitAndDistinct = unsafeAggregateDistinct "bit_and"
1187−
1188−-- | >>> :{
1189−-- let
1190−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
1191−-- expression = bitOrDistinct #col
1192−-- in printSQL expression
1193−-- :}
1194−-- bit_or(DISTINCT "col")
1195−bitOrDistinct
1196− :: PGIntegral int
1197− => Expression schema relations 'Ungrouped params (nullity int)
1198− -- ^ what to aggregate
1199− -> Expression schema relations ('Grouped bys) params (nullity int)
1200−bitOrDistinct = unsafeAggregateDistinct "bit_or"
1201−
1202−-- | >>> :{
1203−-- let
1204−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1205−-- expression = boolAnd #col
1206−-- in printSQL expression
1207−-- :}
1208−-- bool_and("col")
1209−boolAnd
1210− :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1211− -- ^ what to aggregate
1212− -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1213−boolAnd = unsafeAggregate "bool_and"
1214−
1215−-- | >>> :{
1216−-- let
1217−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1218−-- expression = boolOr #col
1219−-- in printSQL expression
1220−-- :}
1221−-- bool_or("col")
1222−boolOr
1223− :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1224− -- ^ what to aggregate
1225− -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1226−boolOr = unsafeAggregate "bool_or"
1227−
1228−-- | >>> :{
1229−-- let
1230−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1231−-- expression = boolAndDistinct #col
1232−-- in printSQL expression
1233−-- :}
1234−-- bool_and(DISTINCT "col")
1235−boolAndDistinct
1236− :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1237− -- ^ what to aggregate
1238− -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1239−boolAndDistinct = unsafeAggregateDistinct "bool_and"
1240−
1241−-- | >>> :{
1242−-- let
1243−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1244−-- expression = boolOrDistinct #col
1245−-- in printSQL expression
1246−-- :}
1247−-- bool_or(DISTINCT "col")
1248−boolOrDistinct
1249− :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1250− -- ^ what to aggregate
1251− -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1252−boolOrDistinct = unsafeAggregateDistinct "bool_or"
1253−
1254−-- | A special aggregation that does not require an input
1255−--
1256−-- >>> printSQL countStar
1257−-- count(*)
1258−countStar
1259− :: Expression schema relations ('Grouped bys) params ('NotNull 'PGint8)
1260−countStar = UnsafeExpression $ "count(*)"
1261−
1262−-- | >>> :{
1263−-- let
1264−-- expression :: Expression schema '[tab ::: '["col" ::: nullity ty]] (Grouped bys) params ('NotNull 'PGint8)
1265−-- expression = count #col
1266−-- in printSQL expression
1267−-- :}
1268−-- count("col")
1269−count
1270− :: Expression schema relations 'Ungrouped params ty
1271− -- ^ what to count
1272− -> Expression schema relations ('Grouped bys) params ('NotNull 'PGint8)
1273−count = unsafeAggregate "count"
1274−
1275−-- | >>> :{
1276−-- let
1277−-- expression :: Expression schema '[tab ::: '["col" ::: nullity ty]] (Grouped bys) params ('NotNull 'PGint8)
1278−-- expression = countDistinct #col
1279−-- in printSQL expression
1280−-- :}
1281−-- count(DISTINCT "col")
1282−countDistinct
1283− :: Expression schema relations 'Ungrouped params ty
1284− -- ^ what to count
1285− -> Expression schema relations ('Grouped bys) params ('NotNull 'PGint8)
1286−countDistinct = unsafeAggregateDistinct "count"
1287−
1288−-- | synonym for `boolAnd`
1289−--
1290−-- >>> :{
1291−-- let
1292−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1293−-- expression = every #col
1294−-- in printSQL expression
1295−-- :}
1296−-- every("col")
1297−every
1298− :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1299− -- ^ what to aggregate
1300− -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1301−every = unsafeAggregate "every"
1302−
1303−-- | synonym for `boolAndDistinct`
1304−--
1305−-- >>> :{
1306−-- let
1307−-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1308−-- expression = everyDistinct #col
1309−-- in printSQL expression
1310−-- :}
1311−-- every(DISTINCT "col")
1312−everyDistinct
1313− :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
1314− -- ^ what to aggregate
1315− -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
1316−everyDistinct = unsafeAggregateDistinct "every"
1317−
1318−-- | minimum and maximum aggregation
1319−max_, min_, maxDistinct, minDistinct
1320− :: Expression schema relations 'Ungrouped params (nullity ty)
1321− -- ^ what to aggregate
1322− -> Expression schema relations ('Grouped bys) params (nullity ty)
1323−max_ = unsafeAggregate "max"
1324−min_ = unsafeAggregate "min"
1325−maxDistinct = unsafeAggregateDistinct "max"
1326−minDistinct = unsafeAggregateDistinct "min"
1327−
1328−{-----------------------------------------
1329−type expressions
1330−-----------------------------------------}
1331−
1332−-- | `TypeExpression`s are used in `cast`s and `createTable` commands.
1333−newtype TypeExpression (schema :: SchemaType) (ty :: PGType)
1334− = UnsafeTypeExpression { renderTypeExpression :: ByteString }
1335− deriving (GHC.Generic,Show,Eq,Ord,NFData)
1336−
1337−instance (Has alias schema ('Typedef ty))
1338− => IsLabel alias (TypeExpression schema ty) where
1339− fromLabel = UnsafeTypeExpression (renderAlias (fromLabel @alias))
1340−
1341−-- | logical Boolean (true/false)
1342−bool :: TypeExpression schema 'PGbool
1343−bool = UnsafeTypeExpression "bool"
1344−-- | signed two-byte integer
1345−int2, smallint :: TypeExpression schema 'PGint2
1346−int2 = UnsafeTypeExpression "int2"
1347−smallint = UnsafeTypeExpression "smallint"
1348−-- | signed four-byte integer
1349−int4, int, integer :: TypeExpression schema 'PGint4
1350−int4 = UnsafeTypeExpression "int4"
1351−int = UnsafeTypeExpression "int"
1352−integer = UnsafeTypeExpression "integer"
1353−-- | signed eight-byte integer
1354−int8, bigint :: TypeExpression schema 'PGint8
1355−int8 = UnsafeTypeExpression "int8"
1356−bigint = UnsafeTypeExpression "bigint"
1357−-- | arbitrary precision numeric type
1358−numeric :: TypeExpression schema 'PGnumeric
1359−numeric = UnsafeTypeExpression "numeric"
1360−-- | single precision floating-point number (4 bytes)
1361−float4, real :: TypeExpression schema 'PGfloat4
1362−float4 = UnsafeTypeExpression "float4"
1363−real = UnsafeTypeExpression "real"
1364−-- | double precision floating-point number (8 bytes)
1365−float8, doublePrecision :: TypeExpression schema 'PGfloat8
1366−float8 = UnsafeTypeExpression "float8"
1367−doublePrecision = UnsafeTypeExpression "double precision"
1368−-- | variable-length character string
1369−text :: TypeExpression schema 'PGtext
1370−text = UnsafeTypeExpression "text"
1371−-- | fixed-length character string
1372−char, character
1373− :: (KnownNat n, 1 <= n)
1374− => proxy n
1375− -> TypeExpression schema ('PGchar n)
1376−char p = UnsafeTypeExpression $ "char(" <> renderNat p <> ")"
1377−character p = UnsafeTypeExpression $ "character(" <> renderNat p <> ")"
1378−-- | variable-length character string
1379−varchar, characterVarying
1380− :: (KnownNat n, 1 <= n)
1381− => proxy n
1382− -> TypeExpression schema ('PGvarchar n)
1383−varchar p = UnsafeTypeExpression $ "varchar(" <> renderNat p <> ")"
1384−characterVarying p = UnsafeTypeExpression $
1385− "character varying(" <> renderNat p <> ")"
1386−-- | binary data ("byte array")
1387−bytea :: TypeExpression schema 'PGbytea
1388−bytea = UnsafeTypeExpression "bytea"
1389−-- | date and time (no time zone)
1390−timestamp :: TypeExpression schema 'PGtimestamp
1391−timestamp = UnsafeTypeExpression "timestamp"
1392−-- | date and time, including time zone
1393−timestampWithTimeZone :: TypeExpression schema 'PGtimestamptz
1394−timestampWithTimeZone = UnsafeTypeExpression "timestamp with time zone"
1395−-- | calendar date (year, month, day)
1396−date :: TypeExpression schema 'PGdate
1397−date = UnsafeTypeExpression "date"
1398−-- | time of day (no time zone)
1399−time :: TypeExpression schema 'PGtime
1400−time = UnsafeTypeExpression "time"
1401−-- | time of day, including time zone
1402−timeWithTimeZone :: TypeExpression schema 'PGtimetz
1403−timeWithTimeZone = UnsafeTypeExpression "time with time zone"
1404−-- | time span
1405−interval :: TypeExpression schema 'PGinterval
1406−interval = UnsafeTypeExpression "interval"
1407−-- | universally unique identifier
1408−uuid :: TypeExpression schema 'PGuuid
1409−uuid = UnsafeTypeExpression "uuid"
1410−-- | IPv4 or IPv6 host address
1411−inet :: TypeExpression schema 'PGinet
1412−inet = UnsafeTypeExpression "inet"
1413−-- | textual JSON data
1414−json :: TypeExpression schema 'PGjson
1415−json = UnsafeTypeExpression "json"
1416−-- | binary JSON data, decomposed
1417−jsonb :: TypeExpression schema 'PGjsonb
1418−jsonb = UnsafeTypeExpression "jsonb"
1419−-- | variable length array
1420−vararray
1421− :: TypeExpression schema pg
1422− -> TypeExpression schema ('PGvararray pg)
1423−vararray ty = UnsafeTypeExpression $ renderTypeExpression ty <> "[]"
1424−-- | fixed length array
1425−--
1426−-- >>> renderTypeExpression (fixarray (Proxy @2) json)
1427−-- "json[2]"
1428−fixarray
1429− :: KnownNat n
1430− => proxy n
1431− -> TypeExpression schema pg
1432− -> TypeExpression schema ('PGfixarray n pg)
1433−fixarray p ty = UnsafeTypeExpression $
1434− renderTypeExpression ty <> "[" <> renderNat p <> "]"
1435−
1436−-- | `pgtype` is a demoted version of a `PGType`
1437−class PGTyped schema (ty :: PGType) where pgtype :: TypeExpression schema ty
1438−instance PGTyped schema 'PGbool where pgtype = bool
1439−instance PGTyped schema 'PGint2 where pgtype = int2
1440−instance PGTyped schema 'PGint4 where pgtype = int4
1441−instance PGTyped schema 'PGint8 where pgtype = int8
1442−instance PGTyped schema 'PGnumeric where pgtype = numeric
1443−instance PGTyped schema 'PGfloat4 where pgtype = float4
1444−instance PGTyped schema 'PGfloat8 where pgtype = float8
1445−instance PGTyped schema 'PGtext where pgtype = text
1446−instance (KnownNat n, 1 <= n)
1447− => PGTyped schema ('PGchar n) where pgtype = char (Proxy @n)
1448−instance (KnownNat n, 1 <= n)
1449− => PGTyped schema ('PGvarchar n) where pgtype = varchar (Proxy @n)
1450−instance PGTyped schema 'PGbytea where pgtype = bytea
1451−instance PGTyped schema 'PGtimestamp where pgtype = timestamp
1452−instance PGTyped schema 'PGtimestamptz where pgtype = timestampWithTimeZone
1453−instance PGTyped schema 'PGdate where pgtype = date
1454−instance PGTyped schema 'PGtime where pgtype = time
1455−instance PGTyped schema 'PGtimetz where pgtype = timeWithTimeZone
1456−instance PGTyped schema 'PGinterval where pgtype = interval
1457−instance PGTyped schema 'PGuuid where pgtype = uuid
1458−instance PGTyped schema 'PGjson where pgtype = json
1459−instance PGTyped schema 'PGjsonb where pgtype = jsonb
1460−instance PGTyped schema ty => PGTyped schema ('PGvararray ty) where
1461− pgtype = vararray (pgtype @schema @ty)
1462−instance (KnownNat n, PGTyped schema ty) => PGTyped schema ('PGfixarray n ty) where
1463− pgtype = fixarray (Proxy @n) (pgtype @schema @ty)