@@ -11,21 +11,15 @@ Squeal expressions are the atoms used to build statements.
1111{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
1212{-# LANGUAGE
1313 AllowAmbiguousTypes
14− , DataKinds
1514 , DeriveGeneric
16− , DeriveDataTypeable
1715 , FlexibleContexts
1816 , FlexibleInstances
1917 , FunctionalDependencies
20− , GADTs
2118 , GeneralizedNewtypeDeriving
2219 , LambdaCase
2320 , MagicHash
2421 , OverloadedStrings
25− , PolyKinds
26− , RankNTypes
2722 , ScopedTypeVariables
28− , StandaloneDeriving
2923 , TypeApplications
3024 , TypeFamilies
3125 , TypeInType
@@ -33,21 +27,23 @@ Squeal expressions are the atoms used to build statements.
3327 , UndecidableInstances
3428#-}
3529
36−module Squeal.PostgreSQL.Expression
30+module Squeal.PostgreSQL.Expression
3731 ( -- * Expression
3832 Expression (UnsafeExpression, renderExpression)
39− , HasParameter (param)
33+ , HasParameter (parameter)
34+ , param
4035 -- ** Null
4136 , null_
42− , unNull
37+ , notNull
4338 , coalesce
4439 , fromNull
4540 , isNull
46− , isn'tNull
41+ , isNotNull
4742 , matchNull
4843 , nullIf
49− -- ** Arrays
44+ -- ** Collections
5045 , array
46+ , row
5147 -- ** Functions
5248 , unsafeBinaryOp
5349 , unsafeUnaryOp
@@ -97,8 +93,6 @@ module Squeal.PostgreSQL.Expression
9793 , count, countDistinct
9894 , every, everyDistinct
9995 , max_, maxDistinct, min_, minDistinct
100− -- * Tables
101− , Table (UnsafeTable, renderTable)
10296 -- * Types
10397 , TypeExpression (UnsafeTypeExpression, renderTypeExpression)
10498 , PGTyped (pgtype)
@@ -115,12 +109,6 @@ module Squeal.PostgreSQL.Expression
115109 , real
116110 , float8
117111 , doublePrecision
118− , serial2
119− , smallserial
120− , serial4
121− , serial
122− , serial8
123− , bigserial
124112 , text
125113 , char
126114 , character
@@ -139,8 +127,6 @@ module Squeal.PostgreSQL.Expression
139127 , jsonb
140128 , vararray
141129 , fixarray
142− , notNull
143− , default_
144130 -- * Re-export
145131 , (&)
146132 , NP ((:*), Nil)
@@ -150,7 +136,7 @@ import Control.Category
150136import Control.DeepSeq
151137import Data.ByteString (ByteString)
152138import Data.Function ((&))
153−import Data.Monoid hiding (All)
139+import Data.Semigroup
154140import Data.Ratio
155141import Data.String
156142import Generics.SOP hiding (from)
@@ -178,6 +164,7 @@ values from primitive expression using arithmetic, logical,
178164and other operations.
179165-}
180166newtype Expression
167+ (schema :: SchemaType)
181168 (relations :: RelationsType)
182169 (grouping :: Grouping)
183170 (params :: [NullityType])
@@ -185,6 +172,9 @@ newtype Expression
185172 = UnsafeExpression { renderExpression :: ByteString }
186173 deriving (GHC.Generic,Show,Eq,Ord,NFData)
187174
175+instance RenderSQL (Expression schema relations grouping params ty) where
176+ renderSQL = renderExpression
177+
188178{- | A `HasParameter` constraint is used to indicate a value that is
189179supplied externally to a SQL statement.
190180`Squeal.PostgreSQL.PQ.manipulateParams`,
@@ -193,203 +183,302 @@ supplied externally to a SQL statement.
193183separately from the SQL command string, in which case `param`s are used to
194184refer to the out-of-line data values.
195185-}
196−class (PGTyped (PGTypeOf ty), KnownNat n) => HasParameter
186+class KnownNat n => HasParameter
197187 (n :: Nat)
188+ (schema :: SchemaType)
198189 (params :: [NullityType])
199190 (ty :: NullityType)
200191 | n params -> ty where
201− param :: Expression relations grouping params ty
202− param = UnsafeExpression $ parenthesized $
192+ -- | `parameter` takes a `Nat` using type application and a `TypeExpression`.
193+ --
194+ -- >>> let expr = parameter @1 int4 :: Expression sch rels grp '[ 'Null 'PGint4] ('Null 'PGint4)
195+ -- >>> printSQL expr
196+ -- ($1 :: int4)
197+ parameter
198+ :: TypeExpression schema (PGTypeOf ty)
199+ -> Expression schema relations grouping params ty
200+ parameter ty = UnsafeExpression $ parenthesized $
203201 "$" <> renderNat (Proxy @n) <+> "::"
204− <+> renderTypeExpression (pgtype @(PGTypeOf ty))
205−instance {-# OVERLAPPING #-} PGTyped (PGTypeOf ty1)
206− => HasParameter 1 (ty1:tys) ty1
207−instance {-# OVERLAPPABLE #-} (KnownNat n, HasParameter (n-1) params ty)
208− => HasParameter n (ty' : params) ty
202+ <+> renderTypeExpression ty
203+instance {-# OVERLAPPING #-} HasParameter 1 schema (ty1:tys) ty1
204+instance {-# OVERLAPPABLE #-} (KnownNat n, HasParameter (n-1) schema params ty)
205+ => HasParameter n schema (ty' : params) ty
206+
207+-- | `param` takes a `Nat` using type application and for basic types,
208+-- infers a `TypeExpression`.
209+--
210+-- >>> let expr = param @1 :: Expression sch rels grp '[ 'Null 'PGint4] ('Null 'PGint4)
211+-- >>> printSQL expr
212+-- ($1 :: int4)
213+param
214+ :: forall n schema params relations grouping ty
215+ . (PGTyped schema (PGTypeOf ty), HasParameter n schema params ty)
216+ => Expression schema relations grouping params ty -- ^ param
217+param = parameter @n pgtype
209218
210219instance (HasUnique relation relations columns, Has column columns ty)
211− => IsLabel column (Expression relations 'Ungrouped params ty) where
220+ => IsLabel column (Expression schema relations 'Ungrouped params ty) where
212221 fromLabel = UnsafeExpression $ renderAlias (Alias @column)
222+instance (HasUnique relation relations columns, Has column columns ty)
223+ => IsLabel column
224+ (Aliased (Expression schema relations 'Ungrouped params) (column ::: ty)) where
225+ fromLabel = fromLabel @column `As` Alias @column
226+instance (HasUnique relation relations columns, Has column columns ty)
227+ => IsLabel column
228+ (NP (Aliased (Expression schema relations 'Ungrouped params)) '[column ::: ty]) where
229+ fromLabel = fromLabel @column :* Nil
213230
214231instance (Has relation relations columns, Has column columns ty)
215− => IsQualified relation column (Expression relations 'Ungrouped params ty) where
232+ => IsQualified relation column (Expression schema relations 'Ungrouped params ty) where
216233 relation ! column = UnsafeExpression $
217234 renderAlias relation <> "." <> renderAlias column
218−
235+instance (Has relation relations columns, Has column columns ty)
236+ => IsQualified relation column
237+ (Aliased (Expression schema relations 'Ungrouped params) (column ::: ty)) where
238+ relation ! column = relation ! column `As` column
239+instance (Has relation relations columns, Has column columns ty)
240+ => IsQualified relation column
241+ (NP (Aliased (Expression schema relations 'Ungrouped params)) '[column ::: ty]) where
242+ relation ! column = relation ! column :* Nil
243+
219244instance
220245 ( HasUnique relation relations columns
221246 , Has column columns ty
222247 , GroupedBy relation column bys
223248 ) => IsLabel column
224− (Expression relations ('Grouped bys) params ty) where
249+ (Expression schema relations ('Grouped bys) params ty) where
225250 fromLabel = UnsafeExpression $ renderAlias (Alias @column)
226−
251+instance
252+ ( HasUnique relation relations columns
253+ , Has column columns ty
254+ , GroupedBy relation column bys
255+ ) => IsLabel column
256+ ( Aliased (Expression schema relations ('Grouped bys) params)
257+ (column ::: ty) ) where
258+ fromLabel = fromLabel @column `As` Alias @column
259+instance
260+ ( HasUnique relation relations columns
261+ , Has column columns ty
262+ , GroupedBy relation column bys
263+ ) => IsLabel column
264+ ( NP (Aliased (Expression schema relations ('Grouped bys) params))
265+ '[column ::: ty] ) where
266+ fromLabel = fromLabel @column :* Nil
267+
227268instance
228269 ( Has relation relations columns
229270 , Has column columns ty
230271 , GroupedBy relation column bys
231272 ) => IsQualified relation column
232− (Expression relations ('Grouped bys) params ty) where
273+ (Expression schema relations ('Grouped bys) params ty) where
233274 relation ! column = UnsafeExpression $
234275 renderAlias relation <> "." <> renderAlias column
276+instance
277+ ( Has relation relations columns
278+ , Has column columns ty
279+ , GroupedBy relation column bys
280+ ) => IsQualified relation column
281+ (Aliased (Expression schema relations ('Grouped bys) params)
282+ (column ::: ty)) where
283+ relation ! column = relation ! column `As` column
284+instance
285+ ( Has relation relations columns
286+ , Has column columns ty
287+ , GroupedBy relation column bys
288+ ) => IsQualified relation column
289+ ( NP (Aliased (Expression schema relations ('Grouped bys) params))
290+ '[column ::: ty]) where
291+ relation ! column = relation ! column :* Nil
235292
236293-- | analagous to `Nothing`
237294--
238−-- >>> renderExpression $ null_
239−-- "NULL"
240−null_ :: Expression relations grouping params ('Null ty)
295+-- >>> printSQL null_
296+-- NULL
297+null_ :: Expression schema rels grouping params ('Null ty)
241298null_ = UnsafeExpression "NULL"
242299
243300-- | analagous to `Just`
244301--
245−-- >>> renderExpression $ unNull true
246−-- "TRUE"
247−unNull
248− :: Expression relations grouping params ('NotNull ty)
249− -- ^ not @NULL@
250− -> Expression relations grouping params ('Null ty)
251−unNull = UnsafeExpression . renderExpression
302+-- >>> printSQL $ notNull true
303+-- TRUE
304+notNull
305+ :: Expression schema rels grouping params ('NotNull ty)
306+ -> Expression schema rels grouping params ('Null ty)
307+notNull = UnsafeExpression . renderExpression
252308
253309-- | return the leftmost value which is not NULL
254310--
255−-- >>> renderExpression $ coalesce [null_, unNull true] false
256−-- "COALESCE(NULL, TRUE, FALSE)"
311+-- >>> printSQL $ coalesce [null_, notNull true] false
312+-- COALESCE(NULL, TRUE, FALSE)
257313coalesce
258− :: [Expression relations grouping params ('Null ty)]
314+ :: [Expression schema relations grouping params ('Null ty)]
259315 -- ^ @NULL@s may be present
260− -> Expression relations grouping params ('NotNull ty)
316+ -> Expression schema relations grouping params ('NotNull ty)
261317 -- ^ @NULL@ is absent
262− -> Expression relations grouping params ('NotNull ty)
318+ -> Expression schema relations grouping params ('NotNull ty)
263319coalesce nullxs notNullx = UnsafeExpression $
264320 "COALESCE" <> parenthesized (commaSeparated
265321 ((renderExpression <$> nullxs) <> [renderExpression notNullx]))
266322
267323-- | analagous to `Data.Maybe.fromMaybe` using @COALESCE@
268324--
269−-- >>> renderExpression $ fromNull true null_
270−-- "COALESCE(NULL, TRUE)"
325+-- >>> printSQL $ fromNull true null_
326+-- COALESCE(NULL, TRUE)
271327fromNull
272− :: Expression relations grouping params ('NotNull ty)
328+ :: Expression schema relations grouping params ('NotNull ty)
273329 -- ^ what to convert @NULL@ to
274− -> Expression relations grouping params ('Null ty)
275− -> Expression relations grouping params ('NotNull ty)
330+ -> Expression schema relations grouping params ('Null ty)
331+ -> Expression schema relations grouping params ('NotNull ty)
276332fromNull notNullx nullx = coalesce [nullx] notNullx
277333
278−-- | >>> renderExpression $ null_ & isNull
279−-- "NULL IS NULL"
334+-- | >>> printSQL $ null_ & isNull
335+-- NULL IS NULL
280336isNull
281− :: Expression relations grouping params ('Null ty)
337+ :: Expression schema relations grouping params ('Null ty)
282338 -- ^ possibly @NULL@
283− -> Condition relations grouping params
339+ -> Condition schema relations grouping params
284340isNull x = UnsafeExpression $ renderExpression x <+> "IS NULL"
285341
286−-- | >>> renderExpression $ null_ & isn'tNull
287−-- "NULL IS NOT NULL"
288−isn'tNull
289− :: Expression relations grouping params ('Null ty)
342+-- | >>> printSQL $ null_ & isNotNull
343+-- NULL IS NOT NULL
344+isNotNull
345+ :: Expression schema relations grouping params ('Null ty)
290346 -- ^ possibly @NULL@
291− -> Condition relations grouping params
292−isn'tNull x = UnsafeExpression $ renderExpression x <+> "IS NOT NULL"
347+ -> Condition schema relations grouping params
348+isNotNull x = UnsafeExpression $ renderExpression x <+> "IS NOT NULL"
293349
294350-- | analagous to `maybe` using @IS NULL@
295351--
296−-- >>> renderExpression $ matchNull true not_ null_
297−-- "CASE WHEN NULL IS NULL THEN TRUE ELSE (NOT NULL) END"
352+-- >>> printSQL $ matchNull true not_ null_
353+-- CASE WHEN NULL IS NULL THEN TRUE ELSE (NOT NULL) END
298354matchNull
299− :: Expression relations grouping params (nullty)
355+ :: Expression schema relations grouping params (nullty)
300356 -- ^ what to convert @NULL@ to
301− -> ( Expression relations grouping params ('NotNull ty)
302− -> Expression relations grouping params (nullty) )
357+ -> ( Expression schema relations grouping params ('NotNull ty)
358+ -> Expression schema relations grouping params (nullty) )
303359 -- ^ function to perform when @NULL@ is absent
304− -> Expression relations grouping params ('Null ty)
305− -> Expression relations grouping params (nullty)
360+ -> Expression schema relations grouping params ('Null ty)
361+ -> Expression schema relations grouping params (nullty)
306362matchNull y f x = ifThenElse (isNull x) y
307363 (f (UnsafeExpression (renderExpression x)))
308364
309−-- | right inverse to `fromNull`, if its arguments are equal then
310−-- `nullIf` gives @NULL@.
311−--
312−-- >>> :set -XTypeApplications -XDataKinds
313−-- >>> renderExpression @_ @_ @'[_] $ fromNull false (nullIf false (param @1))
314−-- "COALESCE(NULL IF (FALSE, ($1 :: bool)), FALSE)"
365+{-| right inverse to `fromNull`, if its arguments are equal then
366+`nullIf` gives @NULL@.
367+
368+>>> :set -XTypeApplications -XDataKinds
369+>>> let expr = nullIf false (param @1) :: Expression schema rels grp '[ 'NotNull 'PGbool] ('Null 'PGbool)
370+>>> printSQL expr
371+NULL IF (FALSE, ($1 :: bool))
372+-}
315373nullIf
316− :: Expression relations grouping params ('NotNull ty)
374+ :: Expression schema relations grouping params ('NotNull ty)
317375 -- ^ @NULL@ is absent
318− -> Expression relations grouping params ('NotNull ty)
376+ -> Expression schema relations grouping params ('NotNull ty)
319377 -- ^ @NULL@ is absent
320− -> Expression relations grouping params ('Null ty)
378+ -> Expression schema relations grouping params ('Null ty)
321379nullIf x y = UnsafeExpression $ "NULL IF" <+> parenthesized
322380 (renderExpression x <> ", " <> renderExpression y)
323381
324−-- | >>> renderExpression $ array [null_, unNull false, unNull true]
325−-- "ARRAY[NULL, FALSE, TRUE]"
382+-- | >>> printSQL $ array [null_, notNull false, notNull true]
383+-- ARRAY[NULL, FALSE, TRUE]
326384array
327− :: [Expression relations grouping params ('Null ty)]
385+ :: [Expression schema relations grouping params ('Null ty)]
328386 -- ^ array elements
329− -> Expression relations grouping params (nullity ('PGvararray ty))
387+ -> Expression schema relations grouping params (nullity ('PGvararray ty))
330388array xs = UnsafeExpression $
331389 "ARRAY[" <> commaSeparated (renderExpression <$> xs) <> "]"
332390
391+instance (KnownSymbol label, label `In` labels) => IsPGlabel label
392+ (Expression schema relations grouping params (nullity ('PGenum labels))) where
393+ label = UnsafeExpression $ renderLabel (PGlabel @label)
394+
395+-- | A row constructor is an expression that builds a row value
396+-- (also called a composite value) using values for its member fields.
397+--
398+-- >>> type Complex = PGcomposite '["real" ::: 'PGfloat8, "imaginary" ::: 'PGfloat8]
399+-- >>> let i = row (0 `As` #real :* 1 `As` #imaginary :* Nil) :: Expression '[] '[] 'Ungrouped '[] ('NotNull Complex)
400+-- >>> printSQL i
401+-- ROW(0, 1)
402+row
403+ :: SListI (Nulls fields)
404+ => NP (Aliased (Expression schema relations grouping params)) (Nulls fields)
405+ -- ^ zero or more expressions for the row field values
406+ -> Expression schema relations grouping params (nullity ('PGcomposite fields))
407+row exprs = UnsafeExpression $ "ROW" <> parenthesized
408+ (renderCommaSeparated (\ (expr `As` _) -> renderExpression expr) exprs)
409+
410+instance Has field fields ty => IsLabel field
411+ ( Expression schema relation grouping params (nullity ('PGcomposite fields))
412+ -> Expression schema relation grouping params ('Null ty) ) where
413+ fromLabel expr = UnsafeExpression $
414+ parenthesized (renderExpression expr) <> "." <>
415+ fromString (symbolVal (Proxy @field))
416+
417+instance Semigroup
418+ (Expression schema relations grouping params (nullity ('PGvararray ty))) where
419+ (<>) = unsafeBinaryOp "||"
420+
333421instance Monoid
334− (Expression relations grouping params (nullity ('PGvararray ty))) where
422+ (Expression schema relations grouping params (nullity ('PGvararray ty))) where
335423 mempty = array []
336− mappend = unsafeBinaryOp "||"
424+ mappend = (<>)
337425
338−-- | >>> renderExpression @_ @_ @'[_] $ greatest currentTimestamp [param @1]
339−-- "GREATEST(CURRENT_TIMESTAMP, ($1 :: timestamp with time zone))"
426+-- | >>> let expr = greatest currentTimestamp [param @1] :: Expression sch rels grp '[ 'NotNull 'PGtimestamptz] ('NotNull 'PGtimestamptz)
427+-- >>> printSQL expr
428+-- GREATEST(CURRENT_TIMESTAMP, ($1 :: timestamp with time zone))
340429greatest
341− :: Expression relations grouping params (nullty)
430+ :: Expression schema relations grouping params (nullty)
342431 -- ^ needs at least 1 argument
343− -> [Expression relations grouping params (nullty)]
432+ -> [Expression schema relations grouping params (nullty)]
344433 -- ^ or more
345− -> Expression relations grouping params (nullty)
434+ -> Expression schema relations grouping params (nullty)
346435greatest x xs = UnsafeExpression $ "GREATEST("
347436 <> commaSeparated (renderExpression <$> (x:xs)) <> ")"
348437
349−-- | >>> renderExpression $ least currentTimestamp [null_]
350−-- "LEAST(CURRENT_TIMESTAMP, NULL)"
438+-- | >>> printSQL $ least currentTimestamp [null_]
439+-- LEAST(CURRENT_TIMESTAMP, NULL)
351440least
352− :: Expression relations grouping params (nullty)
441+ :: Expression schema relations grouping params (nullty)
353442 -- ^ needs at least 1 argument
354− -> [Expression relations grouping params (nullty)]
443+ -> [Expression schema relations grouping params (nullty)]
355444 -- ^ or more
356− -> Expression relations grouping params (nullty)
445+ -> Expression schema relations grouping params (nullty)
357446least x xs = UnsafeExpression $ "LEAST("
358447 <> commaSeparated (renderExpression <$> (x:xs)) <> ")"
359448
360−-- | >>> renderExpression $ unsafeBinaryOp "OR" true false
361−-- "(TRUE OR FALSE)"
449+-- | >>> printSQL $ unsafeBinaryOp "OR" true false
450+-- (TRUE OR FALSE)
362451unsafeBinaryOp
363452 :: ByteString
364453 -- ^ operator
365− -> Expression relations grouping params (ty0)
366− -> Expression relations grouping params (ty1)
367− -> Expression relations grouping params (ty2)
454+ -> Expression schema relations grouping params (ty0)
455+ -> Expression schema relations grouping params (ty1)
456+ -> Expression schema relations grouping params (ty2)
368457unsafeBinaryOp op x y = UnsafeExpression $ parenthesized $
369458 renderExpression x <+> op <+> renderExpression y
370459
371−-- | >>> renderExpression $ unsafeUnaryOp "NOT" true
372−-- "(NOT TRUE)"
460+-- | >>> printSQL $ unsafeUnaryOp "NOT" true
461+-- (NOT TRUE)
373462unsafeUnaryOp
374463 :: ByteString
375464 -- ^ operator
376− -> Expression relations grouping params (ty0)
377− -> Expression relations grouping params (ty1)
465+ -> Expression schema relations grouping params (ty0)
466+ -> Expression schema relations grouping params (ty1)
378467unsafeUnaryOp op x = UnsafeExpression $ parenthesized $
379468 op <+> renderExpression x
380469
381−-- | >>> renderExpression $ unsafeFunction "f" true
382−-- "f(TRUE)"
470+-- | >>> printSQL $ unsafeFunction "f" true
471+-- f(TRUE)
383472unsafeFunction
384473 :: ByteString
385474 -- ^ function
386− -> Expression relations grouping params (xty)
387− -> Expression relations grouping params (yty)
475+ -> Expression schema relations grouping params (xty)
476+ -> Expression schema relations grouping params (yty)
388477unsafeFunction fun x = UnsafeExpression $
389478 fun <> parenthesized (renderExpression x)
390479
391480instance PGNum ty
392− => Num (Expression relations grouping params (nullity ty)) where
481+ => Num (Expression schema relations grouping params (nullity ty)) where
393482 (+) = unsafeBinaryOp "+"
394483 (-) = unsafeBinaryOp "-"
395484 (*) = unsafeBinaryOp "*"
@@ -401,12 +490,12 @@ instance PGNum ty
401490 . show
402491
403492instance (PGNum ty, PGFloating ty) => Fractional
404− (Expression relations grouping params (nullity ty)) where
493+ (Expression schema relations grouping params (nullity ty)) where
405494 (/) = unsafeBinaryOp "/"
406495 fromRational x = fromInteger (numerator x) / fromInteger (denominator x)
407496
408497instance (PGNum ty, PGFloating ty) => Floating
409− (Expression relations grouping params (nullity ty)) where
498+ (Expression schema relations grouping params (nullity ty)) where
410499 pi = UnsafeExpression "pi()"
411500 exp = unsafeFunction "exp"
412501 log = unsafeFunction "ln"
@@ -429,18 +518,18 @@ instance (PGNum ty, PGFloating ty) => Floating
429518
430519-- | >>> :{
431520-- let
432−-- expression :: Expression relations grouping params (nullity 'PGfloat4)
521+-- expression :: Expression schema relations grouping params (nullity 'PGfloat4)
433522-- expression = atan2_ pi 2
434−-- in renderExpression expression
523+-- in printSQL expression
435524-- :}
436−-- "atan2(pi(), 2)"
525+-- atan2(pi(), 2)
437526atan2_
438527 :: PGFloating float
439− => Expression relations grouping params (nullity float)
528+ => Expression schema relations grouping params (nullity float)
440529 -- ^ numerator
441− -> Expression relations grouping params (nullity float)
530+ -> Expression schema relations grouping params (nullity float)
442531 -- ^ denominator
443− -> Expression relations grouping params (nullity float)
532+ -> Expression schema relations grouping params (nullity float)
444533atan2_ y x = UnsafeExpression $
445534 "atan2(" <> renderExpression y <> ", " <> renderExpression x <> ")"
446535
@@ -448,14 +537,14 @@ atan2_ y x = UnsafeExpression $
448537-- represents a run-time type conversion. The cast will succeed only if a
449538-- suitable type conversion operation has been defined.
450539--
451−-- | >>> renderExpression $ true & cast int4
452−-- "(TRUE :: int4)"
540+-- | >>> printSQL $ true & cast int4
541+-- (TRUE :: int4)
453542cast
454− :: TypeExpression ('NoDef :=> 'Null ty1)
543+ :: TypeExpression schema ty1
455544 -- ^ type to cast as
456− -> Expression relations grouping params (nullity ty0)
545+ -> Expression schema relations grouping params (nullity ty0)
457546 -- ^ value to convert
458− -> Expression relations grouping params (nullity ty1)
547+ -> Expression schema relations grouping params (nullity ty1)
459548cast ty x = UnsafeExpression $ parenthesized $
460549 renderExpression x <+> "::" <+> renderTypeExpression ty
461550
@@ -463,135 +552,135 @@ cast ty x = UnsafeExpression $ parenthesized $
463552--
464553-- >>> :{
465554-- let
466−-- expression :: Expression relations grouping params (nullity 'PGint2)
555+-- expression :: Expression schema relations grouping params (nullity 'PGint2)
467556-- expression = 5 `quot_` 2
468−-- in renderExpression expression
557+-- in printSQL expression
469558-- :}
470−-- "(5 / 2)"
559+-- (5 / 2)
471560quot_
472561 :: PGIntegral int
473− => Expression relations grouping params (nullity int)
562+ => Expression schema relations grouping params (nullity int)
474563 -- ^ numerator
475− -> Expression relations grouping params (nullity int)
564+ -> Expression schema relations grouping params (nullity int)
476565 -- ^ denominator
477− -> Expression relations grouping params (nullity int)
566+ -> Expression schema relations grouping params (nullity int)
478567quot_ = unsafeBinaryOp "/"
479568
480569-- | remainder upon integer division
481570--
482571-- >>> :{
483572-- let
484−-- expression :: Expression relations grouping params (nullity 'PGint2)
573+-- expression :: Expression schema relations grouping params (nullity 'PGint2)
485574-- expression = 5 `rem_` 2
486−-- in renderExpression expression
575+-- in printSQL expression
487576-- :}
488−-- "(5 % 2)"
577+-- (5 % 2)
489578rem_
490579 :: PGIntegral int
491− => Expression relations grouping params (nullity int)
580+ => Expression schema relations grouping params (nullity int)
492581 -- ^ numerator
493− -> Expression relations grouping params (nullity int)
582+ -> Expression schema relations grouping params (nullity int)
494583 -- ^ denominator
495− -> Expression relations grouping params (nullity int)
584+ -> Expression schema relations grouping params (nullity int)
496585rem_ = unsafeBinaryOp "%"
497586
498587-- | >>> :{
499588-- let
500−-- expression :: Expression relations grouping params (nullity 'PGfloat4)
589+-- expression :: Expression schema relations grouping params (nullity 'PGfloat4)
501590-- expression = trunc pi
502−-- in renderExpression expression
591+-- in printSQL expression
503592-- :}
504−-- "trunc(pi())"
593+-- trunc(pi())
505594trunc
506595 :: PGFloating frac
507− => Expression relations grouping params (nullity frac)
596+ => Expression schema relations grouping params (nullity frac)
508597 -- ^ fractional number
509− -> Expression relations grouping params (nullity frac)
598+ -> Expression schema relations grouping params (nullity frac)
510599trunc = unsafeFunction "trunc"
511600
512601-- | >>> :{
513602-- let
514−-- expression :: Expression relations grouping params (nullity 'PGfloat4)
603+-- expression :: Expression schema relations grouping params (nullity 'PGfloat4)
515604-- expression = round_ pi
516−-- in renderExpression expression
605+-- in printSQL expression
517606-- :}
518−-- "round(pi())"
607+-- round(pi())
519608round_
520609 :: PGFloating frac
521− => Expression relations grouping params (nullity frac)
610+ => Expression schema relations grouping params (nullity frac)
522611 -- ^ fractional number
523− -> Expression relations grouping params (nullity frac)
612+ -> Expression schema relations grouping params (nullity frac)
524613round_ = unsafeFunction "round"
525614
526615-- | >>> :{
527616-- let
528−-- expression :: Expression relations grouping params (nullity 'PGfloat4)
617+-- expression :: Expression schema relations grouping params (nullity 'PGfloat4)
529618-- expression = ceiling_ pi
530−-- in renderExpression expression
619+-- in printSQL expression
531620-- :}
532−-- "ceiling(pi())"
621+-- ceiling(pi())
533622ceiling_
534623 :: PGFloating frac
535− => Expression relations grouping params (nullity frac)
624+ => Expression schema relations grouping params (nullity frac)
536625 -- ^ fractional number
537− -> Expression relations grouping params (nullity frac)
626+ -> Expression schema relations grouping params (nullity frac)
538627ceiling_ = unsafeFunction "ceiling"
539628
540629-- | A `Condition` is a boolean valued `Expression`. While SQL allows
541630-- conditions to have @NULL@, Squeal instead chooses to disallow @NULL@,
542631-- forcing one to handle the case of @NULL@ explicitly to produce
543632-- a `Condition`.
544−type Condition relations grouping params =
545− Expression relations grouping params ('NotNull 'PGbool)
633+type Condition schema relations grouping params =
634+ Expression schema relations grouping params ('NotNull 'PGbool)
546635
547−-- | >>> renderExpression true
548−-- "TRUE"
549−true :: Condition relations grouping params
636+-- | >>> printSQL true
637+-- TRUE
638+true :: Condition schema relations grouping params
550639true = UnsafeExpression "TRUE"
551640
552−-- | >>> renderExpression false
553−-- "FALSE"
554−false :: Condition relations grouping params
641+-- | >>> printSQL false
642+-- FALSE
643+false :: Condition schema relations grouping params
555644false = UnsafeExpression "FALSE"
556645
557−-- | >>> renderExpression $ not_ true
558−-- "(NOT TRUE)"
646+-- | >>> printSQL $ not_ true
647+-- (NOT TRUE)
559648not_
560− :: Condition relations grouping params
561− -> Condition relations grouping params
649+ :: Condition schema relations grouping params
650+ -> Condition schema relations grouping params
562651not_ = unsafeUnaryOp "NOT"
563652
564−-- | >>> renderExpression $ true .&& false
565−-- "(TRUE AND FALSE)"
653+-- | >>> printSQL $ true .&& false
654+-- (TRUE AND FALSE)
566655(.&&)
567− :: Condition relations grouping params
568− -> Condition relations grouping params
569− -> Condition relations grouping params
656+ :: Condition schema relations grouping params
657+ -> Condition schema relations grouping params
658+ -> Condition schema relations grouping params
570659(.&&) = unsafeBinaryOp "AND"
571660
572−-- | >>> renderExpression $ true .|| false
573−-- "(TRUE OR FALSE)"
661+-- | >>> printSQL $ true .|| false
662+-- (TRUE OR FALSE)
574663(.||)
575− :: Condition relations grouping params
576− -> Condition relations grouping params
577− -> Condition relations grouping params
664+ :: Condition schema relations grouping params
665+ -> Condition schema relations grouping params
666+ -> Condition schema relations grouping params
578667(.||) = unsafeBinaryOp "OR"
579668
580669-- | >>> :{
581670-- let
582−-- expression :: Expression relations grouping params (nullity 'PGint2)
671+-- expression :: Expression schema relations grouping params (nullity 'PGint2)
583672-- expression = caseWhenThenElse [(true, 1), (false, 2)] 3
584−-- in renderExpression expression
673+-- in printSQL expression
585674-- :}
586−-- "CASE WHEN TRUE THEN 1 WHEN FALSE THEN 2 ELSE 3 END"
675+-- CASE WHEN TRUE THEN 1 WHEN FALSE THEN 2 ELSE 3 END
587676caseWhenThenElse
588− :: [ ( Condition relations grouping params
589− , Expression relations grouping params (ty)
677+ :: [ ( Condition schema relations grouping params
678+ , Expression schema relations grouping params (ty)
590679 ) ]
591680 -- ^ whens and thens
592− -> Expression relations grouping params (ty)
681+ -> Expression schema relations grouping params (ty)
593682 -- ^ else
594− -> Expression relations grouping params (ty)
683+ -> Expression schema relations grouping params (ty)
595684caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
596685 [ "CASE"
597686 , mconcat
@@ -607,103 +696,103 @@ caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
607696
608697-- | >>> :{
609698-- let
610−-- expression :: Expression relations grouping params (nullity 'PGint2)
699+-- expression :: Expression schema relations grouping params (nullity 'PGint2)
611700-- expression = ifThenElse true 1 0
612−-- in renderExpression expression
701+-- in printSQL expression
613702-- :}
614−-- "CASE WHEN TRUE THEN 1 ELSE 0 END"
703+-- CASE WHEN TRUE THEN 1 ELSE 0 END
615704ifThenElse
616− :: Condition relations grouping params
617− -> Expression relations grouping params (ty) -- ^ then
618− -> Expression relations grouping params (ty) -- ^ else
619− -> Expression relations grouping params (ty)
705+ :: Condition schema relations grouping params
706+ -> Expression schema relations grouping params (ty) -- ^ then
707+ -> Expression schema relations grouping params (ty) -- ^ else
708+ -> Expression schema relations grouping params (ty)
620709ifThenElse if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
621710
622711-- | Comparison operations like `.==`, `./=`, `.>`, `.>=`, `.<` and `.<=`
623712-- will produce @NULL@s if one of their arguments is @NULL@.
624713--
625−-- >>> renderExpression $ unNull true .== null_
626−-- "(TRUE = NULL)"
714+-- >>> printSQL $ notNull true .== null_
715+-- (TRUE = NULL)
627716(.==)
628− :: Expression relations grouping params (nullity ty) -- ^ lhs
629− -> Expression relations grouping params (nullity ty) -- ^ rhs
630− -> Expression relations grouping params (nullity 'PGbool)
717+ :: Expression schema relations grouping params (nullity ty) -- ^ lhs
718+ -> Expression schema relations grouping params (nullity ty) -- ^ rhs
719+ -> Expression schema relations grouping params (nullity 'PGbool)
631720(.==) = unsafeBinaryOp "="
632721infix 4 .==
633722
634−-- | >>> renderExpression $ unNull true ./= null_
635−-- "(TRUE <> NULL)"
723+-- | >>> printSQL $ notNull true ./= null_
724+-- (TRUE <> NULL)
636725(./=)
637− :: Expression relations grouping params (nullity ty) -- ^ lhs
638− -> Expression relations grouping params (nullity ty) -- ^ rhs
639− -> Expression relations grouping params (nullity 'PGbool)
726+ :: Expression schema relations grouping params (nullity ty) -- ^ lhs
727+ -> Expression schema relations grouping params (nullity ty) -- ^ rhs
728+ -> Expression schema relations grouping params (nullity 'PGbool)
640729(./=) = unsafeBinaryOp "<>"
641730infix 4 ./=
642731
643−-- | >>> renderExpression $ unNull true .>= null_
644−-- "(TRUE >= NULL)"
732+-- | >>> printSQL $ notNull true .>= null_
733+-- (TRUE >= NULL)
645734(.>=)
646− :: Expression relations grouping params (nullity ty) -- ^ lhs
647− -> Expression relations grouping params (nullity ty) -- ^ rhs
648− -> Expression relations grouping params (nullity 'PGbool)
735+ :: Expression schema relations grouping params (nullity ty) -- ^ lhs
736+ -> Expression schema relations grouping params (nullity ty) -- ^ rhs
737+ -> Expression schema relations grouping params (nullity 'PGbool)
649738(.>=) = unsafeBinaryOp ">="
650739infix 4 .>=
651740
652−-- | >>> renderExpression $ unNull true .< null_
653−-- "(TRUE < NULL)"
741+-- | >>> printSQL $ notNull true .< null_
742+-- (TRUE < NULL)
654743(.<)
655− :: Expression relations grouping params (nullity ty) -- ^ lhs
656− -> Expression relations grouping params (nullity ty) -- ^ rhs
657− -> Expression relations grouping params (nullity 'PGbool)
744+ :: Expression schema relations grouping params (nullity ty) -- ^ lhs
745+ -> Expression schema relations grouping params (nullity ty) -- ^ rhs
746+ -> Expression schema relations grouping params (nullity 'PGbool)
658747(.<) = unsafeBinaryOp "<"
659748infix 4 .<
660749
661−-- | >>> renderExpression $ unNull true .<= null_
662−-- "(TRUE <= NULL)"
750+-- | >>> printSQL $ notNull true .<= null_
751+-- (TRUE <= NULL)
663752(.<=)
664− :: Expression relations grouping params (nullity ty) -- ^ lhs
665− -> Expression relations grouping params (nullity ty) -- ^ rhs
666− -> Expression relations grouping params (nullity 'PGbool)
753+ :: Expression schema relations grouping params (nullity ty) -- ^ lhs
754+ -> Expression schema relations grouping params (nullity ty) -- ^ rhs
755+ -> Expression schema relations grouping params (nullity 'PGbool)
667756(.<=) = unsafeBinaryOp "<="
668757infix 4 .<=
669758
670−-- | >>> renderExpression $ unNull true .> null_
671−-- "(TRUE > NULL)"
759+-- | >>> printSQL $ notNull true .> null_
760+-- (TRUE > NULL)
672761(.>)
673− :: Expression relations grouping params (nullity ty) -- ^ lhs
674− -> Expression relations grouping params (nullity ty) -- ^ rhs
675− -> Expression relations grouping params (nullity 'PGbool)
762+ :: Expression schema relations grouping params (nullity ty) -- ^ lhs
763+ -> Expression schema relations grouping params (nullity ty) -- ^ rhs
764+ -> Expression schema relations grouping params (nullity 'PGbool)
676765(.>) = unsafeBinaryOp ">"
677766infix 4 .>
678767
679−-- | >>> renderExpression currentDate
680−-- "CURRENT_DATE"
768+-- | >>> printSQL currentDate
769+-- CURRENT_DATE
681770currentDate
682− :: Expression relations grouping params (nullity 'PGdate)
771+ :: Expression schema relations grouping params (nullity 'PGdate)
683772currentDate = UnsafeExpression "CURRENT_DATE"
684773
685−-- | >>> renderExpression currentTime
686−-- "CURRENT_TIME"
774+-- | >>> printSQL currentTime
775+-- CURRENT_TIME
687776currentTime
688− :: Expression relations grouping params (nullity 'PGtimetz)
777+ :: Expression schema relations grouping params (nullity 'PGtimetz)
689778currentTime = UnsafeExpression "CURRENT_TIME"
690779
691−-- | >>> renderExpression currentTimestamp
692−-- "CURRENT_TIMESTAMP"
780+-- | >>> printSQL currentTimestamp
781+-- CURRENT_TIMESTAMP
693782currentTimestamp
694− :: Expression relations grouping params (nullity 'PGtimestamptz)
783+ :: Expression schema relations grouping params (nullity 'PGtimestamptz)
695784currentTimestamp = UnsafeExpression "CURRENT_TIMESTAMP"
696785
697−-- | >>> renderExpression localTime
698−-- "LOCALTIME"
786+-- | >>> printSQL localTime
787+-- LOCALTIME
699788localTime
700− :: Expression relations grouping params (nullity 'PGtime)
789+ :: Expression schema relations grouping params (nullity 'PGtime)
701790localTime = UnsafeExpression "LOCALTIME"
702791
703−-- | >>> renderExpression localTimestamp
704−-- "LOCALTIMESTAMP"
792+-- | >>> printSQL localTimestamp
793+-- LOCALTIMESTAMP
705794localTimestamp
706− :: Expression relations grouping params (nullity 'PGtimestamp)
795+ :: Expression schema relations grouping params (nullity 'PGtimestamp)
707796localTimestamp = UnsafeExpression "LOCALTIMESTAMP"
708797
709798{-----------------------------------------
@@ -711,7 +800,7 @@ text
711800-----------------------------------------}
712801
713802instance IsString
714− (Expression relations grouping params (nullity 'PGtext)) where
803+ (Expression schema relations grouping params (nullity 'PGtext)) where
715804 fromString str = UnsafeExpression $
716805 "E\'" <> fromString (escape =<< str) <> "\'"
717806 where
@@ -726,33 +815,37 @@ instance IsString
726815 '\\' -> "\\\\"
727816 c -> [c]
728817
818+instance Semigroup
819+ (Expression schema relations grouping params (nullity 'PGtext)) where
820+ (<>) = unsafeBinaryOp "||"
821+
729822instance Monoid
730− (Expression relations grouping params (nullity 'PGtext)) where
823+ (Expression schema relations grouping params (nullity 'PGtext)) where
731824 mempty = fromString ""
732− mappend = unsafeBinaryOp "||"
825+ mappend = (<>)
733826
734−-- | >>> renderExpression $ lower "ARRRGGG"
735−-- "lower(E'ARRRGGG')"
827+-- | >>> printSQL $ lower "ARRRGGG"
828+-- lower(E'ARRRGGG')
736829lower
737− :: Expression relations grouping params (nullity 'PGtext)
830+ :: Expression schema relations grouping params (nullity 'PGtext)
738831 -- ^ string to lower case
739− -> Expression relations grouping params (nullity 'PGtext)
832+ -> Expression schema relations grouping params (nullity 'PGtext)
740833lower = unsafeFunction "lower"
741834
742−-- | >>> renderExpression $ upper "eeee"
743−-- "upper(E'eeee')"
835+-- | >>> printSQL $ upper "eeee"
836+-- upper(E'eeee')
744837upper
745− :: Expression relations grouping params (nullity 'PGtext)
838+ :: Expression schema relations grouping params (nullity 'PGtext)
746839 -- ^ string to upper case
747− -> Expression relations grouping params (nullity 'PGtext)
840+ -> Expression schema relations grouping params (nullity 'PGtext)
748841upper = unsafeFunction "upper"
749842
750−-- | >>> renderExpression $ charLength "four"
751−-- "char_length(E'four')"
843+-- | >>> printSQL $ charLength "four"
844+-- char_length(E'four')
752845charLength
753− :: Expression relations grouping params (nullity 'PGtext)
846+ :: Expression schema relations grouping params (nullity 'PGtext)
754847 -- ^ string to measure
755− -> Expression relations grouping params (nullity 'PGint4)
848+ -> Expression schema relations grouping params (nullity 'PGint4)
756849charLength = unsafeFunction "char_length"
757850
758851-- | The `like` expression returns true if the @string@ matches
@@ -762,14 +855,14 @@ charLength = unsafeFunction "char_length"
762855-- in pattern stands for (matches) any single character; a percent sign (%)
763856-- matches any sequence of zero or more characters.
764857--
765−-- >>> renderExpression $ "abc" `like` "a%"
766−-- "(E'abc' LIKE E'a%')"
858+-- >>> printSQL $ "abc" `like` "a%"
859+-- (E'abc' LIKE E'a%')
767860like
768− :: Expression relations grouping params (nullity 'PGtext)
861+ :: Expression schema relations grouping params (nullity 'PGtext)
769862 -- ^ string
770− -> Expression relations grouping params (nullity 'PGtext)
863+ -> Expression schema relations grouping params (nullity 'PGtext)
771864 -- ^ pattern
772− -> Expression relations grouping params (nullity 'PGbool)
865+ -> Expression schema relations grouping params (nullity 'PGbool)
773866like = unsafeBinaryOp "LIKE"
774867
775868{-----------------------------------------
@@ -779,54 +872,54 @@ aggregation
779872-- | escape hatch to define aggregate functions
780873unsafeAggregate
781874 :: ByteString -- ^ aggregate function
782− -> Expression relations 'Ungrouped params (xty)
783− -> Expression relations ('Grouped bys) params (yty)
875+ -> Expression schema relations 'Ungrouped params (xty)
876+ -> Expression schema relations ('Grouped bys) params (yty)
784877unsafeAggregate fun x = UnsafeExpression $ mconcat
785878 [fun, "(", renderExpression x, ")"]
786879
787880-- | escape hatch to define aggregate functions over distinct values
788881unsafeAggregateDistinct
789882 :: ByteString -- ^ aggregate function
790− -> Expression relations 'Ungrouped params (xty)
791− -> Expression relations ('Grouped bys) params (yty)
883+ -> Expression schema relations 'Ungrouped params (xty)
884+ -> Expression schema relations ('Grouped bys) params (yty)
792885unsafeAggregateDistinct fun x = UnsafeExpression $ mconcat
793886 [fun, "(DISTINCT ", renderExpression x, ")"]
794887
795888-- | >>> :{
796889-- let
797−-- expression :: Expression '[tab ::: '["col" ::: 'Null 'PGnumeric]] ('Grouped bys) params ('Null 'PGnumeric)
890+-- expression :: Expression schema '[tab ::: '["col" ::: 'Null 'PGnumeric]] ('Grouped bys) params ('Null 'PGnumeric)
798891-- expression = sum_ #col
799−-- in renderExpression expression
892+-- in printSQL expression
800893-- :}
801−-- "sum(\"col\")"
894+-- sum("col")
802895sum_
803896 :: PGNum ty
804− => Expression relations 'Ungrouped params (nullity ty)
897+ => Expression schema relations 'Ungrouped params (nullity ty)
805898 -- ^ what to sum
806− -> Expression relations ('Grouped bys) params (nullity ty)
899+ -> Expression schema relations ('Grouped bys) params (nullity ty)
807900sum_ = unsafeAggregate "sum"
808901
809902-- | >>> :{
810903-- let
811−-- expression :: Expression '[tab ::: '["col" ::: nullity 'PGnumeric]] ('Grouped bys) params (nullity 'PGnumeric)
904+-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGnumeric]] ('Grouped bys) params (nullity 'PGnumeric)
812905-- expression = sumDistinct #col
813−-- in renderExpression expression
906+-- in printSQL expression
814907-- :}
815−-- "sum(DISTINCT \"col\")"
908+-- sum(DISTINCT "col")
816909sumDistinct
817910 :: PGNum ty
818− => Expression relations 'Ungrouped params (nullity ty)
911+ => Expression schema relations 'Ungrouped params (nullity ty)
819912 -- ^ what to sum
820− -> Expression relations ('Grouped bys) params (nullity ty)
913+ -> Expression schema relations ('Grouped bys) params (nullity ty)
821914sumDistinct = unsafeAggregateDistinct "sum"
822915
823916-- | A constraint for `PGType`s that you can take averages of and the resulting
824917-- `PGType`.
825918class PGAvg ty avg | ty -> avg where
826919 avg, avgDistinct
827− :: Expression relations 'Ungrouped params (nullity ty)
920+ :: Expression schema relations 'Ungrouped params (nullity ty)
828921 -- ^ what to average
829− -> Expression relations ('Grouped bys) params (nullity avg)
922+ -> Expression schema relations ('Grouped bys) params (nullity avg)
830923 avg = unsafeAggregate "avg"
831924 avgDistinct = unsafeAggregateDistinct "avg"
832925instance PGAvg 'PGint2 'PGnumeric
@@ -839,312 +932,281 @@ instance PGAvg 'PGinterval 'PGinterval
839932
840933-- | >>> :{
841934-- let
842−-- expression :: Expression '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
935+-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
843936-- expression = bitAnd #col
844−-- in renderExpression expression
937+-- in printSQL expression
845938-- :}
846−-- "bit_and(\"col\")"
939+-- bit_and("col")
847940bitAnd
848941 :: PGIntegral int
849− => Expression relations 'Ungrouped params (nullity int)
942+ => Expression schema relations 'Ungrouped params (nullity int)
850943 -- ^ what to aggregate
851− -> Expression relations ('Grouped bys) params (nullity int)
944+ -> Expression schema relations ('Grouped bys) params (nullity int)
852945bitAnd = unsafeAggregate "bit_and"
853946
854947-- | >>> :{
855948-- let
856−-- expression :: Expression '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
949+-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
857950-- expression = bitOr #col
858−-- in renderExpression expression
951+-- in printSQL expression
859952-- :}
860−-- "bit_or(\"col\")"
953+-- bit_or("col")
861954bitOr
862955 :: PGIntegral int
863− => Expression relations 'Ungrouped params (nullity int)
956+ => Expression schema relations 'Ungrouped params (nullity int)
864957 -- ^ what to aggregate
865− -> Expression relations ('Grouped bys) params (nullity int)
958+ -> Expression schema relations ('Grouped bys) params (nullity int)
866959bitOr = unsafeAggregate "bit_or"
867960
868961-- | >>> :{
869962-- let
870−-- expression :: Expression '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
963+-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
871964-- expression = bitAndDistinct #col
872−-- in renderExpression expression
965+-- in printSQL expression
873966-- :}
874−-- "bit_and(DISTINCT \"col\")"
967+-- bit_and(DISTINCT "col")
875968bitAndDistinct
876969 :: PGIntegral int
877− => Expression relations 'Ungrouped params (nullity int)
970+ => Expression schema relations 'Ungrouped params (nullity int)
878971 -- ^ what to aggregate
879− -> Expression relations ('Grouped bys) params (nullity int)
972+ -> Expression schema relations ('Grouped bys) params (nullity int)
880973bitAndDistinct = unsafeAggregateDistinct "bit_and"
881974
882975-- | >>> :{
883976-- let
884−-- expression :: Expression '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
977+-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGint4]] (Grouped bys) params (nullity 'PGint4)
885978-- expression = bitOrDistinct #col
886−-- in renderExpression expression
979+-- in printSQL expression
887980-- :}
888−-- "bit_or(DISTINCT \"col\")"
981+-- bit_or(DISTINCT "col")
889982bitOrDistinct
890983 :: PGIntegral int
891− => Expression relations 'Ungrouped params (nullity int)
984+ => Expression schema relations 'Ungrouped params (nullity int)
892985 -- ^ what to aggregate
893− -> Expression relations ('Grouped bys) params (nullity int)
986+ -> Expression schema relations ('Grouped bys) params (nullity int)
894987bitOrDistinct = unsafeAggregateDistinct "bit_or"
895988
896989-- | >>> :{
897990-- let
898−-- expression :: Expression '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
991+-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
899992-- expression = boolAnd #col
900−-- in renderExpression expression
993+-- in printSQL expression
901994-- :}
902−-- "bool_and(\"col\")"
995+-- bool_and("col")
903996boolAnd
904− :: Expression relations 'Ungrouped params (nullity 'PGbool)
997+ :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
905998 -- ^ what to aggregate
906− -> Expression relations ('Grouped bys) params (nullity 'PGbool)
999+ -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
9071000boolAnd = unsafeAggregate "bool_and"
9081001
9091002-- | >>> :{
9101003-- let
911−-- expression :: Expression '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1004+-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
9121005-- expression = boolOr #col
913−-- in renderExpression expression
1006+-- in printSQL expression
9141007-- :}
915−-- "bool_or(\"col\")"
1008+-- bool_or("col")
9161009boolOr
917− :: Expression relations 'Ungrouped params (nullity 'PGbool)
1010+ :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
9181011 -- ^ what to aggregate
919− -> Expression relations ('Grouped bys) params (nullity 'PGbool)
1012+ -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
9201013boolOr = unsafeAggregate "bool_or"
9211014
9221015-- | >>> :{
9231016-- let
924−-- expression :: Expression '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1017+-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
9251018-- expression = boolAndDistinct #col
926−-- in renderExpression expression
1019+-- in printSQL expression
9271020-- :}
928−-- "bool_and(DISTINCT \"col\")"
1021+-- bool_and(DISTINCT "col")
9291022boolAndDistinct
930− :: Expression relations 'Ungrouped params (nullity 'PGbool)
1023+ :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
9311024 -- ^ what to aggregate
932− -> Expression relations ('Grouped bys) params (nullity 'PGbool)
1025+ -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
9331026boolAndDistinct = unsafeAggregateDistinct "bool_and"
9341027
9351028-- | >>> :{
9361029-- let
937−-- expression :: Expression '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1030+-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
9381031-- expression = boolOrDistinct #col
939−-- in renderExpression expression
1032+-- in printSQL expression
9401033-- :}
941−-- "bool_or(DISTINCT \"col\")"
1034+-- bool_or(DISTINCT "col")
9421035boolOrDistinct
943− :: Expression relations 'Ungrouped params (nullity 'PGbool)
1036+ :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
9441037 -- ^ what to aggregate
945− -> Expression relations ('Grouped bys) params (nullity 'PGbool)
1038+ -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
9461039boolOrDistinct = unsafeAggregateDistinct "bool_or"
9471040
9481041-- | A special aggregation that does not require an input
9491042--
950−-- >>> renderExpression countStar
951−-- "count(*)"
1043+-- >>> printSQL countStar
1044+-- count(*)
9521045countStar
953− :: Expression relations ('Grouped bys) params ('NotNull 'PGint8)
1046+ :: Expression schema relations ('Grouped bys) params ('NotNull 'PGint8)
9541047countStar = UnsafeExpression $ "count(*)"
9551048
9561049-- | >>> :{
9571050-- let
958−-- expression :: Expression '[tab ::: '["col" ::: nullity ty]] (Grouped bys) params ('NotNull 'PGint8)
1051+-- expression :: Expression schema '[tab ::: '["col" ::: nullity ty]] (Grouped bys) params ('NotNull 'PGint8)
9591052-- expression = count #col
960−-- in renderExpression expression
1053+-- in printSQL expression
9611054-- :}
962−-- "count(\"col\")"
1055+-- count("col")
9631056count
964− :: Expression relations 'Ungrouped params ty
1057+ :: Expression schema relations 'Ungrouped params ty
9651058 -- ^ what to count
966− -> Expression relations ('Grouped bys) params ('NotNull 'PGint8)
1059+ -> Expression schema relations ('Grouped bys) params ('NotNull 'PGint8)
9671060count = unsafeAggregate "count"
9681061
9691062-- | >>> :{
9701063-- let
971−-- expression :: Expression '[tab ::: '["col" ::: nullity ty]] (Grouped bys) params ('NotNull 'PGint8)
1064+-- expression :: Expression schema '[tab ::: '["col" ::: nullity ty]] (Grouped bys) params ('NotNull 'PGint8)
9721065-- expression = countDistinct #col
973−-- in renderExpression expression
1066+-- in printSQL expression
9741067-- :}
975−-- "count(DISTINCT \"col\")"
1068+-- count(DISTINCT "col")
9761069countDistinct
977− :: Expression relations 'Ungrouped params ty
1070+ :: Expression schema relations 'Ungrouped params ty
9781071 -- ^ what to count
979− -> Expression relations ('Grouped bys) params ('NotNull 'PGint8)
1072+ -> Expression schema relations ('Grouped bys) params ('NotNull 'PGint8)
9801073countDistinct = unsafeAggregateDistinct "count"
9811074
9821075-- | synonym for `boolAnd`
9831076--
9841077-- >>> :{
9851078-- let
986−-- expression :: Expression '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1079+-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
9871080-- expression = every #col
988−-- in renderExpression expression
1081+-- in printSQL expression
9891082-- :}
990−-- "every(\"col\")"
1083+-- every("col")
9911084every
992− :: Expression relations 'Ungrouped params (nullity 'PGbool)
1085+ :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
9931086 -- ^ what to aggregate
994− -> Expression relations ('Grouped bys) params (nullity 'PGbool)
1087+ -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
9951088every = unsafeAggregate "every"
9961089
9971090-- | synonym for `boolAndDistinct`
9981091--
9991092-- >>> :{
10001093-- let
1001−-- expression :: Expression '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
1094+-- expression :: Expression schema '[tab ::: '["col" ::: nullity 'PGbool]] (Grouped bys) params (nullity 'PGbool)
10021095-- expression = everyDistinct #col
1003−-- in renderExpression expression
1096+-- in printSQL expression
10041097-- :}
1005−-- "every(DISTINCT \"col\")"
1098+-- every(DISTINCT "col")
10061099everyDistinct
1007− :: Expression relations 'Ungrouped params (nullity 'PGbool)
1100+ :: Expression schema relations 'Ungrouped params (nullity 'PGbool)
10081101 -- ^ what to aggregate
1009− -> Expression relations ('Grouped bys) params (nullity 'PGbool)
1102+ -> Expression schema relations ('Grouped bys) params (nullity 'PGbool)
10101103everyDistinct = unsafeAggregateDistinct "every"
10111104
10121105-- | minimum and maximum aggregation
10131106max_, min_, maxDistinct, minDistinct
1014− :: Expression relations 'Ungrouped params (nullity ty)
1107+ :: Expression schema relations 'Ungrouped params (nullity ty)
10151108 -- ^ what to aggregate
1016− -> Expression relations ('Grouped bys) params (nullity ty)
1109+ -> Expression schema relations ('Grouped bys) params (nullity ty)
10171110max_ = unsafeAggregate "max"
10181111min_ = unsafeAggregate "min"
10191112maxDistinct = unsafeAggregateDistinct "max"
10201113minDistinct = unsafeAggregateDistinct "min"
10211114
1022−{-----------------------------------------
1023−tables
1024−-----------------------------------------}
1025−
1026−-- | A `Table` from a table expression is a way
1027−-- to call a table reference by its alias.
1028−newtype Table
1029− (schema :: TablesType)
1030− (columns :: RelationType)
1031− = UnsafeTable { renderTable :: ByteString }
1032− deriving (GHC.Generic,Show,Eq,Ord,NFData)
1033−instance
1034− ( Has alias schema table
1035− , relation ~ ColumnsToRelation (TableToColumns table)
1036− ) => IsLabel alias (Table schema relation) where
1037− fromLabel = UnsafeTable $ renderAlias (Alias @alias)
1038−
10391115{-----------------------------------------
10401116type expressions
10411117-----------------------------------------}
10421118
10431119-- | `TypeExpression`s are used in `cast`s and `createTable` commands.
1044−newtype TypeExpression (ty :: ColumnType)
1120+newtype TypeExpression (schema :: SchemaType) (ty :: PGType)
10451121 = UnsafeTypeExpression { renderTypeExpression :: ByteString }
10461122 deriving (GHC.Generic,Show,Eq,Ord,NFData)
10471123
1124+instance (Has alias schema ('Typedef ty))
1125+ => IsLabel alias (TypeExpression schema ty) where
1126+ fromLabel = UnsafeTypeExpression (renderAlias (fromLabel @alias))
1127+
10481128-- | logical Boolean (true/false)
1049−bool :: TypeExpression ('NoDef :=> 'Null 'PGbool)
1129+bool :: TypeExpression schema 'PGbool
10501130bool = UnsafeTypeExpression "bool"
10511131-- | signed two-byte integer
1052−int2, smallint :: TypeExpression ('NoDef :=> 'Null 'PGint2)
1132+int2, smallint :: TypeExpression schema 'PGint2
10531133int2 = UnsafeTypeExpression "int2"
10541134smallint = UnsafeTypeExpression "smallint"
10551135-- | signed four-byte integer
1056−int4, int, integer :: TypeExpression ('NoDef :=> 'Null 'PGint4)
1136+int4, int, integer :: TypeExpression schema 'PGint4
10571137int4 = UnsafeTypeExpression "int4"
10581138int = UnsafeTypeExpression "int"
10591139integer = UnsafeTypeExpression "integer"
10601140-- | signed eight-byte integer
1061−int8, bigint :: TypeExpression ('NoDef :=> 'Null 'PGint8)
1141+int8, bigint :: TypeExpression schema 'PGint8
10621142int8 = UnsafeTypeExpression "int8"
10631143bigint = UnsafeTypeExpression "bigint"
10641144-- | arbitrary precision numeric type
1065−numeric :: TypeExpression ('NoDef :=> 'Null 'PGnumeric)
1145+numeric :: TypeExpression schema 'PGnumeric
10661146numeric = UnsafeTypeExpression "numeric"
10671147-- | single precision floating-point number (4 bytes)
1068−float4, real :: TypeExpression ('NoDef :=> 'Null 'PGfloat4)
1148+float4, real :: TypeExpression schema 'PGfloat4
10691149float4 = UnsafeTypeExpression "float4"
10701150real = UnsafeTypeExpression "real"
10711151-- | double precision floating-point number (8 bytes)
1072−float8, doublePrecision :: TypeExpression ('NoDef :=> 'Null 'PGfloat8)
1152+float8, doublePrecision :: TypeExpression schema 'PGfloat8
10731153float8 = UnsafeTypeExpression "float8"
10741154doublePrecision = UnsafeTypeExpression "double precision"
1075−-- | not a true type, but merely a notational convenience for creating
1076−-- unique identifier columns with type `'PGint2`
1077−serial2, smallserial
1078− :: TypeExpression ('Def :=> 'NotNull 'PGint2)
1079−serial2 = UnsafeTypeExpression "serial2"
1080−smallserial = UnsafeTypeExpression "smallserial"
1081−-- | not a true type, but merely a notational convenience for creating
1082−-- unique identifier columns with type `'PGint4`
1083−serial4, serial
1084− :: TypeExpression ('Def :=> 'NotNull 'PGint4)
1085−serial4 = UnsafeTypeExpression "serial4"
1086−serial = UnsafeTypeExpression "serial"
1087−-- | not a true type, but merely a notational convenience for creating
1088−-- unique identifier columns with type `'PGint8`
1089−serial8, bigserial
1090− :: TypeExpression ('Def :=> 'NotNull 'PGint8)
1091−serial8 = UnsafeTypeExpression "serial8"
1092−bigserial = UnsafeTypeExpression "bigserial"
10931155-- | variable-length character string
1094−text :: TypeExpression ('NoDef :=> 'Null 'PGtext)
1156+text :: TypeExpression schema 'PGtext
10951157text = UnsafeTypeExpression "text"
10961158-- | fixed-length character string
10971159char, character
10981160 :: (KnownNat n, 1 <= n)
10991161 => proxy n
1100− -> TypeExpression ('NoDef :=> 'Null ('PGchar n))
1162+ -> TypeExpression schema ('PGchar n)
11011163char p = UnsafeTypeExpression $ "char(" <> renderNat p <> ")"
11021164character p = UnsafeTypeExpression $ "character(" <> renderNat p <> ")"
11031165-- | variable-length character string
11041166varchar, characterVarying
11051167 :: (KnownNat n, 1 <= n)
11061168 => proxy n
1107− -> TypeExpression ('NoDef :=> 'Null ('PGvarchar n))
1169+ -> TypeExpression schema ('PGvarchar n)
11081170varchar p = UnsafeTypeExpression $ "varchar(" <> renderNat p <> ")"
11091171characterVarying p = UnsafeTypeExpression $
11101172 "character varying(" <> renderNat p <> ")"
11111173-- | binary data ("byte array")
1112−bytea :: TypeExpression ('NoDef :=> 'Null 'PGbytea)
1174+bytea :: TypeExpression schema 'PGbytea
11131175bytea = UnsafeTypeExpression "bytea"
11141176-- | date and time (no time zone)
1115−timestamp :: TypeExpression ('NoDef :=> 'Null 'PGtimestamp)
1177+timestamp :: TypeExpression schema 'PGtimestamp
11161178timestamp = UnsafeTypeExpression "timestamp"
11171179-- | date and time, including time zone
1118−timestampWithTimeZone :: TypeExpression ('NoDef :=> 'Null 'PGtimestamptz)
1180+timestampWithTimeZone :: TypeExpression schema 'PGtimestamptz
11191181timestampWithTimeZone = UnsafeTypeExpression "timestamp with time zone"
11201182-- | calendar date (year, month, day)
1121−date :: TypeExpression ('NoDef :=> 'Null 'PGdate)
1183+date :: TypeExpression schema 'PGdate
11221184date = UnsafeTypeExpression "date"
11231185-- | time of day (no time zone)
1124−time :: TypeExpression ('NoDef :=> 'Null 'PGtime)
1186+time :: TypeExpression schema 'PGtime
11251187time = UnsafeTypeExpression "time"
11261188-- | time of day, including time zone
1127−timeWithTimeZone :: TypeExpression ('NoDef :=> 'Null 'PGtimetz)
1189+timeWithTimeZone :: TypeExpression schema 'PGtimetz
11281190timeWithTimeZone = UnsafeTypeExpression "time with time zone"
11291191-- | time span
1130−interval :: TypeExpression ('NoDef :=> 'Null 'PGinterval)
1192+interval :: TypeExpression schema 'PGinterval
11311193interval = UnsafeTypeExpression "interval"
11321194-- | universally unique identifier
1133−uuid :: TypeExpression ('NoDef :=> 'Null 'PGuuid)
1195+uuid :: TypeExpression schema 'PGuuid
11341196uuid = UnsafeTypeExpression "uuid"
11351197-- | IPv4 or IPv6 host address
1136−inet :: TypeExpression ('NoDef :=> 'Null 'PGinet)
1198+inet :: TypeExpression schema 'PGinet
11371199inet = UnsafeTypeExpression "inet"
11381200-- | textual JSON data
1139−json :: TypeExpression ('NoDef :=> 'Null 'PGjson)
1201+json :: TypeExpression schema 'PGjson
11401202json = UnsafeTypeExpression "json"
11411203-- | binary JSON data, decomposed
1142−jsonb :: TypeExpression ('NoDef :=> 'Null 'PGjsonb)
1204+jsonb :: TypeExpression schema 'PGjsonb
11431205jsonb = UnsafeTypeExpression "jsonb"
11441206-- | variable length array
11451207vararray
1146− :: TypeExpression ('NoDef :=> 'Null pg)
1147− -> TypeExpression ('NoDef :=> 'Null ('PGvararray pg))
1208+ :: TypeExpression schema pg
1209+ -> TypeExpression schema ('PGvararray pg)
11481210vararray ty = UnsafeTypeExpression $ renderTypeExpression ty <> "[]"
11491211-- | fixed length array
11501212--
@@ -1153,52 +1215,36 @@ vararray ty = UnsafeTypeExpression $ renderTypeExpression ty <> "[]"
11531215fixarray
11541216 :: KnownNat n
11551217 => proxy n
1156− -> TypeExpression ('NoDef :=> 'Null pg)
1157− -> TypeExpression ('NoDef :=> 'Null ('PGfixarray n pg))
1218+ -> TypeExpression schema pg
1219+ -> TypeExpression schema ('PGfixarray n pg)
11581220fixarray p ty = UnsafeTypeExpression $
11591221 renderTypeExpression ty <> "[" <> renderNat p <> "]"
11601222
1161−-- | used in `createTable` commands as a column constraint to ensure
1162−-- @NULL@ is not present
1163−notNull
1164− :: TypeExpression (def :=> 'Null ty)
1165− -> TypeExpression (def :=> 'NotNull ty)
1166−notNull ty = UnsafeTypeExpression $ renderTypeExpression ty <+> "NOT NULL"
1167−
1168−-- | used in `createTable` commands as a column constraint to give a default
1169−default_
1170− :: Expression '[] 'Ungrouped '[] ty
1171− -> TypeExpression ('NoDef :=> ty)
1172− -> TypeExpression ('Def :=> ty)
1173−default_ x ty = UnsafeTypeExpression $
1174− renderTypeExpression ty <+> "DEFAULT" <+> renderExpression x
1175−
11761223-- | `pgtype` is a demoted version of a `PGType`
1177−class PGTyped (ty :: PGType) where
1178− pgtype :: TypeExpression ('NoDef :=> 'Null ty)
1179−instance PGTyped 'PGbool where pgtype = bool
1180−instance PGTyped 'PGint2 where pgtype = int2
1181−instance PGTyped 'PGint4 where pgtype = int4
1182−instance PGTyped 'PGint8 where pgtype = int8
1183−instance PGTyped 'PGnumeric where pgtype = numeric
1184−instance PGTyped 'PGfloat4 where pgtype = float4
1185−instance PGTyped 'PGfloat8 where pgtype = float8
1186−instance PGTyped 'PGtext where pgtype = text
1224+class PGTyped schema (ty :: PGType) where pgtype :: TypeExpression schema ty
1225+instance PGTyped schema 'PGbool where pgtype = bool
1226+instance PGTyped schema 'PGint2 where pgtype = int2
1227+instance PGTyped schema 'PGint4 where pgtype = int4
1228+instance PGTyped schema 'PGint8 where pgtype = int8
1229+instance PGTyped schema 'PGnumeric where pgtype = numeric
1230+instance PGTyped schema 'PGfloat4 where pgtype = float4
1231+instance PGTyped schema 'PGfloat8 where pgtype = float8
1232+instance PGTyped schema 'PGtext where pgtype = text
11871233instance (KnownNat n, 1 <= n)
1188− => PGTyped ('PGchar n) where pgtype = char (Proxy @n)
1234+ => PGTyped schema ('PGchar n) where pgtype = char (Proxy @n)
11891235instance (KnownNat n, 1 <= n)
1190− => PGTyped ('PGvarchar n) where pgtype = varchar (Proxy @n)
1191−instance PGTyped 'PGbytea where pgtype = bytea
1192−instance PGTyped 'PGtimestamp where pgtype = timestamp
1193−instance PGTyped 'PGtimestamptz where pgtype = timestampWithTimeZone
1194−instance PGTyped 'PGdate where pgtype = date
1195−instance PGTyped 'PGtime where pgtype = time
1196−instance PGTyped 'PGtimetz where pgtype = timeWithTimeZone
1197−instance PGTyped 'PGinterval where pgtype = interval
1198−instance PGTyped 'PGuuid where pgtype = uuid
1199−instance PGTyped 'PGjson where pgtype = json
1200−instance PGTyped 'PGjsonb where pgtype = jsonb
1201−instance PGTyped ty => PGTyped ('PGvararray ty) where
1202− pgtype = vararray (pgtype @ty)
1203−instance (KnownNat n, PGTyped ty) => PGTyped ('PGfixarray n ty) where
1204− pgtype = fixarray (Proxy @n) (pgtype @ty)
1236+ => PGTyped schema ('PGvarchar n) where pgtype = varchar (Proxy @n)
1237+instance PGTyped schema 'PGbytea where pgtype = bytea
1238+instance PGTyped schema 'PGtimestamp where pgtype = timestamp
1239+instance PGTyped schema 'PGtimestamptz where pgtype = timestampWithTimeZone
1240+instance PGTyped schema 'PGdate where pgtype = date
1241+instance PGTyped schema 'PGtime where pgtype = time
1242+instance PGTyped schema 'PGtimetz where pgtype = timeWithTimeZone
1243+instance PGTyped schema 'PGinterval where pgtype = interval
1244+instance PGTyped schema 'PGuuid where pgtype = uuid
1245+instance PGTyped schema 'PGjson where pgtype = json
1246+instance PGTyped schema 'PGjsonb where pgtype = jsonb
1247+instance PGTyped schema ty => PGTyped schema ('PGvararray ty) where
1248+ pgtype = vararray (pgtype @schema @ty)
1249+instance (KnownNat n, PGTyped schema ty) => PGTyped schema ('PGfixarray n ty) where
1250+ pgtype = fixarray (Proxy @n) (pgtype @schema @ty)