@@ -1,14 +1,13 @@
11{-|
22Module: 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
@@ -35,358 +34,213 @@ module Squeal.PostgreSQL.Expression
3534 ( -- * Expression
3635 Expression (..)
3736 , Expr
37+ , type (-->)
38+ , FunctionDB
39+ , unsafeFunction
40+ , function
41+ , unsafeLeftOp
42+ , leftOp
43+ , unsafeRightOp
44+ , rightOp
3845 , Operator
39− , (:-->)
40− , HasParameter (parameter)
41− , param
42− -- ** Null
43− , null_
44− , notNull
45− , coalesce
46− , fromNull
47− , isNull
48− , isNotNull
49− , matchNull
50− , nullIf
51− -- ** Collections
52− , array
53− , cardinality
54− , index
55− , row
56− , field
57− -- ** Functions
46+ , OperatorDB
5847 , unsafeBinaryOp
59− , unsafeUnaryOpL
60− , unsafeFunction
61− , unsafeVariadicFunction
62− , atan2_
63− , cast
64− , quot_
65− , rem_
66− , trunc
67− , round_
68− , ceiling_
69− , greatest
70− , least
71− -- ** Conditions
72− , true
73− , false
74− , not_
75− , (.&&)
76− , (.||)
77− , Condition
78− , caseWhenThenElse
79− , ifThenElse
80− , (.==)
81− , (./=)
82− , (.>=)
83− , (.<)
84− , (.<=)
85− , (.>)
86− , between
87− , notBetween
88− , betweenSymmetric
89− , notBetweenSymmetric
90− , isDistinctFrom
91− , isNotDistinctFrom
92− , isTrue
93− , isNotTrue
94− , isFalse
95− , isNotFalse
96− , isUnknown
97− , isNotUnknown
98− -- ** Time
99− , currentDate
100− , currentTime
101− , currentTimestamp
102− , localTime
103− , localTimestamp
104− , TimeOp (..)
105− , makeDate
106− , makeTime
107− , makeTimestamp
108− , makeTimestamptz
109− -- ** Text
110− , lower
111− , upper
112− , charLength
113− , like
114− , ilike
115− -- ** Json
116− -- *** Json and Jsonb operators
117− , (.->)
118− , (.->>)
119− , (.#>)
120− , (.#>>)
121− -- *** Jsonb operators
122− , (.@>)
123− , (.<@)
124− , (.?)
125− , (.?|)
126− , (.?&)
127− , (.-.)
128− , (#-.)
129− -- *** Functions
130− , jsonLit
131− , jsonbLit
132− , toJson
133− , toJsonb
134− , arrayToJson
135− , rowToJson
136− , jsonBuildArray
137− , jsonbBuildArray
138− , jsonBuildObject
139− , jsonbBuildObject
140− , jsonObject
141− , jsonbObject
142− , jsonZipObject
143− , jsonbZipObject
144− , jsonArrayLength
145− , jsonbArrayLength
146− , jsonExtractPath
147− , jsonbExtractPath
148− , jsonExtractPathAsText
149− , jsonbExtractPathAsText
150− , jsonTypeof
151− , jsonbTypeof
152− , jsonStripNulls
153− , jsonbStripNulls
154− , jsonbSet
155− , jsonbInsert
156− , jsonbPretty
157− -- ** Text Search
158− , (@@)
159− , (.&)
160− , (.|)
161− , (.!)
162− , (<->)
163− -- ** Aggregation
164− , Aggregate (..)
165− , Distinction (..)
166− , PGAvg
167− -- * Window Functions
168− , WindowDefinition (..)
169− , partitionBy
170− , WindowFunction (..)
171− , rank
172− , rowNumber
173− , denseRank
174− , percentRank
175− , cumeDist
176− , ntile
177− , lag
178− , lead
179− , firstValue
180− , lastValue
181− , nthValue
182− -- * Sorting
183− , SortExpression (..)
184− , OrderBy (..)
185− -- * Types
186− , TypeExpression (..)
187− , PGTyped (..)
188− , typedef
189− , typetable
190− , typeview
191− , bool
192− , int2
193− , smallint
194− , int4
195− , int
196− , integer
197− , int8
198− , bigint
199− , numeric
200− , float4
201− , real
202− , float8
203− , doublePrecision
204− , money
205− , text
206− , char
207− , character
208− , varchar
209− , characterVarying
210− , bytea
211− , timestamp
212− , timestampWithTimeZone
213− , date
214− , time
215− , timeWithTimeZone
216− , interval
217− , uuid
218− , inet
219− , json
220− , jsonb
221− , vararray
222− , fixarray
223− , tsvector
224− , tsquery
225− , arrayToTSvector
226− , tsvectorLength
227− , numnode
228− , plainToTSquery
229− , phraseToTSquery
230− , websearchToTSquery
231− , queryTree
232− , toTSquery
233− , toTSvector
48+ , binaryOp
49+ , FunctionVar
50+ , unsafeFunctionVar
51+ , type (--->)
52+ , FunctionNDB
53+ , unsafeFunctionN
54+ , functionN
55+ , PGSubset (..)
56+ , PGIntersect (..)
23457 -- * Re-export
23558 , (&)
236− , NP (..)
237− , (:*:) (..)
23859 , K (..)
60+ , unK
23961 ) where
24062
24163import Control.Category
24264import Control.DeepSeq
24365import Data.ByteString (ByteString)
244−import Data.ByteString.Lazy (toStrict)
24566import Data.Function ((&))
24667import Data.Semigroup hiding (All)
247−import qualified Data.Aeson as JSON
24868import Data.String
249−import Data.Word
25069import Generics.SOP hiding (All, from)
251−import GHC.Generics ((:*:) (..))
25270import GHC.OverloadedLabels
25371import GHC.TypeLits
25472import Numeric
25573import Prelude hiding (id, (.))
25674
257−import qualified Data.ByteString as ByteString
25875import qualified GHC.Generics as GHC
259−import qualified Generics.SOP as SOP
26076
77+import Squeal.PostgreSQL.Alias
78+import Squeal.PostgreSQL.List
26179import Squeal.PostgreSQL.Render
26280import Squeal.PostgreSQL.Schema
26381
82+-- $setup
83+-- >>> import Squeal.PostgreSQL
84+
26485{-----------------------------------------
26586column expressions
26687-----------------------------------------}
26788
26889{- | `Expression`s are used in a variety of contexts,
269−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,
27092as new column values in `Squeal.PostgreSQL.Manipulation.insertRow` or
27193`Squeal.PostgreSQL.Manipulation.update`,
272−or in search `Condition`s in a number of commands.
94+or in search `Squeal.PostgreSQL.Logic.Condition`s in a number of commands.
27395
27496The expression syntax allows the calculation of
27597values from primitive expression using arithmetic, logical,
27698and 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`.
277113-}
278114newtype Expression
279115 (outer :: FromType)
280− (grp :: Grouping)
281116 (commons :: FromType)
117+ (grp :: Grouping)
282118 (schemas :: SchemasType)
283119 (params :: [NullityType])
284120 (from :: FromType)
285121 (ty :: NullityType)
286122 = UnsafeExpression { renderExpression :: ByteString }
287123 deriving (GHC.Generic,Show,Eq,Ord,NFData)
288−instance RenderSQL (Expression outer grp commons schemas params from ty) where
124+instance RenderSQL (Expression outer commons grp schemas params from ty) where
289125 renderSQL = renderExpression
290126
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.
291133type Expr x
292− = forall outer grp commons schemas params from
293− . Expression outer grp commons schemas params from x
134+ = forall outer commons grp schemas params from
135+ . Expression outer commons grp schemas params from x
136+ -- ^ cannot reference aliases
294137
138+-- | A @RankNType@ for binary operators.
295139type Operator x1 x2 y
296− = forall outer grp commons schemas params from
297− . Expression outer grp commons schemas params from x1
298− -> Expression outer grp commons schemas params from x2
299− -> Expression outer grp commons schemas params from y
300−
301−type (:-->) x y
302− = forall outer grp commons schemas params from
303− . Expression outer grp commons schemas params from x
304− -> Expression outer grp commons schemas params from y
305−
306−type FunctionHet xs y
307− = forall outer grp commons schemas params from
308− . NP (Expression outer grp commons schemas params from) xs
309− -> Expression outer grp commons schemas params from y
310−
311−type FunctionHom x y
312− = forall outer grp commons schemas params from
313− . [Expression outer grp commons schemas params from x]
314− -> Expression outer grp commons schemas params from x
315− -> Expression outer grp commons schemas params from y
316−
317−unsafeFunctionHom :: ByteString -> FunctionHom x y
318−unsafeFunctionHom fun xs x = UnsafeExpression $ fun <> parenthesized
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)
181+-}
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
319213 (commaSeparated (renderSQL <$> xs) <> ", " <> renderSQL x)
320214
321−{- | A `HasParameter` constraint is used to indicate a value that is
322−supplied externally to a SQL statement.
323−`Squeal.PostgreSQL.PQ.manipulateParams`,
324−`Squeal.PostgreSQL.PQ.queryParams` and
325−`Squeal.PostgreSQL.PQ.traversePrepared` support specifying data values
326−separately from the SQL command string, in which case `param`s are used to
327−refer to the out-of-line data values.
328−-}
329−class KnownNat n => HasParameter
330− (n :: Nat)
331− (params :: [NullityType])
332− (ty :: NullityType)
333− | n params -> ty where
334− -- | `parameter` takes a `Nat` using type application and a `TypeExpression`.
335− --
336− -- >>> let expr = parameter @1 int4 :: Expression outer grp '[] schemas '[ 'Null 'PGint4] from ('Null 'PGint4)
337− -- >>> printSQL expr
338− -- ($1 :: int4)
339− parameter
340− :: TypeExpression schemas ty
341− -> Expression outer grp commons schemas params from ty
342− parameter ty = UnsafeExpression $ parenthesized $
343− "$" <> renderNat @n <+> "::"
344− <+> renderSQL ty
345−instance {-# OVERLAPPING #-} HasParameter 1 (ty1:tys) ty1
346−instance {-# OVERLAPPABLE #-} (KnownNat n, HasParameter (n-1) params ty)
347− => HasParameter n (ty' : params) ty
348−
349−-- | `param` takes a `Nat` using type application and for basic types,
350−-- infers a `TypeExpression`.
351−--
352−-- >>> let expr = param @1 :: Expression outer grp commons schemas '[ 'Null 'PGint4] from ('Null 'PGint4)
353−-- >>> printSQL expr
354−-- ($1 :: int4)
355−param
356− :: forall n outer commons schemas params from grp ty
357− . (PGTyped schemas ty, HasParameter n params ty)
358− => Expression outer grp commons schemas params from ty -- ^ param
359−param = parameter @n (pgtype @schemas)
360−
361215instance (HasUnique tab (Join outer from) row, Has col row ty)
362− => IsLabel col (Expression outer 'Ungrouped commons schemas params from ty) where
216+ => IsLabel col (Expression outer commons 'Ungrouped schemas params from ty) where
363217 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
364218instance (HasUnique tab (Join outer from) row, Has col row ty, tys ~ '[ty])
365− => IsLabel col (NP (Expression outer 'Ungrouped commons schemas params from) tys) where
219+ => IsLabel col (NP (Expression outer commons 'Ungrouped schemas params from) tys) where
366220 fromLabel = fromLabel @col :* Nil
367221instance (HasUnique tab (Join outer from) row, Has col row ty, column ~ (col ::: ty))
368222 => IsLabel col
369− (Aliased (Expression outer 'Ungrouped commons schemas params from) column) where
223+ (Aliased (Expression outer commons 'Ungrouped schemas params from) column) where
370224 fromLabel = fromLabel @col `As` Alias
371225instance (HasUnique tab (Join outer from) row, Has col row ty, columns ~ '[col ::: ty])
372226 => IsLabel col
373− (NP (Aliased (Expression outer 'Ungrouped commons schemas params from)) columns) where
227+ (NP (Aliased (Expression outer commons 'Ungrouped schemas params from)) columns) where
374228 fromLabel = fromLabel @col :* Nil
375229
376230instance (Has tab (Join outer from) row, Has col row ty)
377− => IsQualified tab col (Expression outer 'Ungrouped commons schemas params from ty) where
231+ => IsQualified tab col (Expression outer commons 'Ungrouped schemas params from ty) where
378232 tab ! col = UnsafeExpression $
379233 renderSQL tab <> "." <> renderSQL col
380234instance (Has tab (Join outer from) row, Has col row ty, tys ~ '[ty])
381− => IsQualified tab col (NP (Expression outer 'Ungrouped commons schemas params from) tys) where
235+ => IsQualified tab col (NP (Expression outer commons 'Ungrouped schemas params from) tys) where
382236 tab ! col = tab ! col :* Nil
383237instance (Has tab (Join outer from) row, Has col row ty, column ~ (col ::: ty))
384238 => IsQualified tab col
385− (Aliased (Expression outer 'Ungrouped commons schemas params from) column) where
239+ (Aliased (Expression outer commons 'Ungrouped schemas params from) column) where
386240 tab ! col = tab ! col `As` col
387241instance (Has tab (Join outer from) row, Has col row ty, columns ~ '[col ::: ty])
388242 => IsQualified tab col
389− (NP (Aliased (Expression outer 'Ungrouped commons schemas params from)) columns) where
243+ (NP (Aliased (Expression outer commons 'Ungrouped schemas params from)) columns) where
390244 tab ! col = tab ! col :* Nil
391245
392246instance
@@ -394,7 +248,7 @@ instance
394248 , Has col row ty
395249 , GroupedBy tab col bys
396250 ) => IsLabel col
397− (Expression outer ('Grouped bys) commons schemas params from ty) where
251+ (Expression outer commons ('Grouped bys) schemas params from ty) where
398252 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
399253instance
400254 ( HasUnique tab (Join outer from) row
@@ -402,7 +256,7 @@ instance
402256 , GroupedBy tab col bys
403257 , tys ~ '[ty]
404258 ) => IsLabel col
405− (NP (Expression outer ('Grouped bys) commons schemas params from) tys) where
259+ (NP (Expression outer commons ('Grouped bys) schemas params from) tys) where
406260 fromLabel = fromLabel @col :* Nil
407261instance
408262 ( HasUnique tab (Join outer from) row
@@ -410,7 +264,7 @@ instance
410264 , GroupedBy tab col bys
411265 , column ~ (col ::: ty)
412266 ) => IsLabel col
413− (Aliased (Expression outer ('Grouped bys) commons schemas params from) column) where
267+ (Aliased (Expression outer commons ('Grouped bys) schemas params from) column) where
414268 fromLabel = fromLabel @col `As` Alias
415269instance
416270 ( HasUnique tab (Join outer from) row
@@ -418,7 +272,7 @@ instance
418272 , GroupedBy tab col bys
419273 , columns ~ '[col ::: ty]
420274 ) => IsLabel col
421− (NP (Aliased (Expression outer ('Grouped bys) commons schemas params from)) columns) where
275+ (NP (Aliased (Expression outer commons ('Grouped bys) schemas params from)) columns) where
422276 fromLabel = fromLabel @col :* Nil
423277
424278instance
@@ -426,7 +280,7 @@ instance
426280 , Has col row ty
427281 , GroupedBy tab col bys
428282 ) => IsQualified tab col
429− (Expression outer ('Grouped bys) commons schemas params from ty) where
283+ (Expression outer commons ('Grouped bys) schemas params from ty) where
430284 tab ! col = UnsafeExpression $
431285 renderSQL tab <> "." <> renderSQL col
432286instance
@@ -435,7 +289,7 @@ instance
435289 , GroupedBy tab col bys
436290 , tys ~ '[ty]
437291 ) => IsQualified tab col
438− (NP (Expression outer ('Grouped bys) commons schemas params from) tys) where
292+ (NP (Expression outer commons ('Grouped bys) schemas params from) tys) where
439293 tab ! col = tab ! col :* Nil
440294instance
441295 ( Has tab (Join outer from) row
@@ -443,7 +297,7 @@ instance
443297 , GroupedBy tab col bys
444298 , column ~ (col ::: ty)
445299 ) => IsQualified tab col
446− (Aliased (Expression outer ('Grouped bys) commons schemas params from) column) where
300+ (Aliased (Expression outer commons ('Grouped bys) schemas params from) column) where
447301 tab ! col = tab ! col `As` col
448302instance
449303 ( Has tab (Join outer from) row
@@ -451,223 +305,78 @@ instance
451305 , GroupedBy tab col bys
452306 , columns ~ '[col ::: ty]
453307 ) => IsQualified tab col
454− (NP (Aliased (Expression outer ('Grouped bys) commons schemas params from)) columns) where
308+ (NP (Aliased (Expression outer commons ('Grouped bys) schemas params from)) columns) where
455309 tab ! col = tab ! col :* Nil
456310
457−-- | analagous to `Nothing`
458−--
459−-- >>> printSQL null_
460−-- NULL
461−null_ :: Expr ('Null ty)
462−null_ = UnsafeExpression "NULL"
463−
464−-- | analagous to `Just`
465−--
466−-- >>> printSQL $ notNull true
467−-- TRUE
468−notNull :: 'NotNull ty :--> 'Null ty
469−notNull = UnsafeExpression . renderSQL
470−
471−-- | return the leftmost value which is not NULL
472−--
473−-- >>> printSQL $ coalesce [null_, true] false
474−-- COALESCE(NULL, TRUE, FALSE)
475−coalesce
476− :: [Expression outer grp commons schemas params from ('Null ty)]
477− -- ^ @NULL@s may be present
478− -> Expression outer grp commons schemas params from ('NotNull ty)
479− -- ^ @NULL@ is absent
480− -> Expression outer grp commons schemas params from ('NotNull ty)
481−coalesce nullxs notNullx = UnsafeExpression $
482− "COALESCE" <> parenthesized (commaSeparated
483− ((renderSQL <$> nullxs) <> [renderSQL notNullx]))
484−
485−-- | analagous to `Data.Maybe.fromMaybe` using @COALESCE@
486−--
487−-- >>> printSQL $ fromNull true null_
488−-- COALESCE(NULL, TRUE)
489−fromNull
490− :: Expression outer grp commons schemas params from ('NotNull ty)
491− -- ^ what to convert @NULL@ to
492− -> Expression outer grp commons schemas params from ('Null ty)
493− -> Expression outer grp commons schemas params from ('NotNull ty)
494−fromNull notNullx nullx = coalesce [nullx] notNullx
495−
496−-- | >>> printSQL $ null_ & isNull
497−-- NULL IS NULL
498−isNull
499− :: Expression outer grp commons schemas params from ('Null ty)
500− -- ^ possibly @NULL@
501− -> Condition outer grp commons schemas params from
502−isNull x = UnsafeExpression $ renderSQL x <+> "IS NULL"
503−
504−-- | >>> printSQL $ null_ & isNotNull
505−-- NULL IS NOT NULL
506−isNotNull
507− :: Expression outer grp commons schemas params from ('Null ty)
508− -- ^ possibly @NULL@
509− -> Condition outer grp commons schemas params from
510−isNotNull x = UnsafeExpression $ renderSQL x <+> "IS NOT NULL"
511−
512−-- | analagous to `maybe` using @IS NULL@
513−--
514−-- >>> printSQL $ matchNull true not_ null_
515−-- CASE WHEN NULL IS NULL THEN TRUE ELSE (NOT NULL) END
516−matchNull
517− :: Expression outer grp commons schemas params from (nullty)
518− -- ^ what to convert @NULL@ to
519− -> ( Expression outer grp commons schemas params from ('NotNull ty)
520− -> Expression outer grp commons schemas params from (nullty) )
521− -- ^ function to perform when @NULL@ is absent
522− -> Expression outer grp commons schemas params from ('Null ty)
523− -> Expression outer grp commons schemas params from (nullty)
524−matchNull y f x = ifThenElse (isNull x) y
525− (f (UnsafeExpression (renderSQL x)))
526−
527−{-| right inverse to `fromNull`, if its arguments are equal then
528−`nullIf` gives @NULL@.
529−
530−>>> :set -XTypeApplications -XDataKinds
531−>>> let expr = nullIf false (param @1) :: Expression outer grp commons schemas '[ 'NotNull 'PGbool] from ('Null 'PGbool)
532−>>> printSQL expr
533−NULL IF (FALSE, ($1 :: bool))
534−-}
535−nullIf
536− :: Expression outer grp commons schemas params from ('NotNull ty)
537− -- ^ @NULL@ is absent
538− -> Expression outer grp commons schemas params from ('NotNull ty)
539− -- ^ @NULL@ is absent
540− -> Expression outer grp commons schemas params from ('Null ty)
541−nullIf x y = UnsafeExpression $ "NULL IF" <+> parenthesized
542− (renderSQL x <> ", " <> renderSQL y)
543−
544−-- | >>> printSQL $ array [null_, false, true]
545−-- ARRAY[NULL, FALSE, TRUE]
546−array
547− :: [Expression outer grp commons schemas params from ty]
548− -- ^ array elements
549− -> Expression outer grp commons schemas params from (null ('PGvararray ty))
550−array xs = UnsafeExpression $
551− "ARRAY[" <> commaSeparated (renderSQL <$> xs) <> "]"
552−
553−-- | >>> printSQL $ cardinality (array [null_, false, true])
554−-- cardinality(ARRAY[NULL, FALSE, TRUE])
555−cardinality :: null ('PGvararray ty) :--> null 'PGint8
556−cardinality = unsafeFunction "cardinality"
557−
558−-- | >>> printSQL $ array [null_, false, true] & index 2
559−-- (ARRAY[NULL, FALSE, TRUE])[2]
560−index
561− :: Word64 -- ^ index
562− -> null ('PGvararray ty) :--> NullifyType ty
563−index n expr = UnsafeExpression $
564− parenthesized (renderSQL expr) <> "[" <> fromString (show n) <> "]"
565−
566311instance (KnownSymbol label, label `In` labels) => IsPGlabel label
567− (Expression outer grp commons schemas params from (null ('PGenum labels))) where
312+ (Expression outer commons grp schemas params from (null ('PGenum labels))) where
568313 label = UnsafeExpression $ renderSQL (PGlabel @label)
569314
570−-- | A row constructor is an expression that builds a row value
571−-- (also called a composite value) using values for its member fields.
572−--
573−-- >>> :{
574−-- type Complex = 'PGcomposite
575−-- '[ "real" ::: 'NotNull 'PGfloat8
576−-- , "imaginary" ::: 'NotNull 'PGfloat8 ]
577−-- :}
578−--
579−-- >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression outer grp commons schemas params from ('NotNull Complex)
580−-- >>> printSQL i
581−-- ROW(0, 1)
582−row
583− :: SListI row
584− => NP (Aliased (Expression outer grp commons schemas params from)) row
585− -- ^ zero or more expressions for the row field values
586− -> Expression outer grp commons schemas params from (null ('PGcomposite row))
587−row exprs = UnsafeExpression $ "ROW" <> parenthesized
588− (renderCommaSeparated (\ (expr `As` _) -> renderSQL expr) exprs)
589−
590−-- | >>> :{
591−-- type Complex = 'PGcomposite
592−-- '[ "real" ::: 'NotNull 'PGfloat8
593−-- , "imaginary" ::: 'NotNull 'PGfloat8 ]
594−-- type Schema = '["complex" ::: 'Typedef Complex]
595−-- :}
596−--
597−-- >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression outer grp '[] (Public Schema) from params ('NotNull Complex)
598−-- >>> printSQL $ i & field #complex #imaginary
599−-- (ROW(0, 1)::"complex")."imaginary"
600−field
601− :: ( Has sch schemas schema
602− , Has tydef schema ('Typedef ('PGcomposite row))
603− , Has field row ty)
604− => QualifiedAlias sch tydef -- ^ row type
605− -> Alias field -- ^ field name
606− -> Expression outer grp commons schemas params from ('NotNull ('PGcomposite row))
607− -> Expression outer grp commons schemas params from ty
608−field td fld expr = UnsafeExpression $
609− parenthesized (renderSQL expr <> "::" <> renderSQL td)
610− <> "." <> renderSQL fld
611−
612−instance Semigroup
613− (Expression outer grp commons schemas params from (null ('PGvararray ty))) where
614− (<>) = unsafeBinaryOp "||"
615−
616−instance Monoid
617− (Expression outer grp commons schemas params from (null ('PGvararray ty))) where
618− mempty = array []
619− mappend = (<>)
620−
621−-- | >>> let expr = greatest [param @1] currentTimestamp :: Expression outer grp commons schemas '[ 'NotNull 'PGtimestamptz] from ('NotNull 'PGtimestamptz)
622−-- >>> printSQL expr
623−-- GREATEST(($1 :: timestamp with time zone), CURRENT_TIMESTAMP)
624−greatest :: FunctionHom ty ty
625−greatest = unsafeFunctionHom "GREATEST"
626−
627−-- | >>> printSQL $ least [null_] currentTimestamp
628−-- LEAST(NULL, CURRENT_TIMESTAMP)
629−least :: FunctionHom ty ty
630−least = unsafeFunctionHom "LEAST"
631−
632315-- | >>> printSQL $ unsafeBinaryOp "OR" true false
633316-- (TRUE OR FALSE)
634−unsafeBinaryOp :: ByteString {- ^ operator -} -> Operator ty0 ty1 ty2
317+unsafeBinaryOp :: ByteString -> Operator ty0 ty1 ty2
635318unsafeBinaryOp op x y = UnsafeExpression $ parenthesized $
636319 renderSQL x <+> op <+> renderSQL y
637320
638−-- | >>> printSQL $ unsafeUnaryOpL "NOT" true
639−-- (NOT TRUE)
640−unsafeUnaryOpL :: ByteString {- ^ operator -} -> x :--> y
641−unsafeUnaryOpL op x = UnsafeExpression $ parenthesized $ op <+> renderSQL x
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
642327
643−unsafeUnaryOpR :: ByteString {- ^ operator -} -> x :--> y
644−unsafeUnaryOpR op x = UnsafeExpression $ parenthesized $ renderSQL x <+> op
328+-- | >>> printSQL $ unsafeLeftOp "NOT" true
329+-- (NOT TRUE)
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
645351
646352-- | >>> printSQL $ unsafeFunction "f" true
647353-- f(TRUE)
648−unsafeFunction :: ByteString {- ^ function -} -> x :--> y
354+unsafeFunction :: ByteString -> x --> y
649355unsafeFunction fun x = UnsafeExpression $
650356 fun <> parenthesized (renderSQL x)
651357
652−unsafeFunctionHet
653− :: SListI xs
654− => ByteString {- ^ function -}
655− -> FunctionHet xs y
656−unsafeFunctionHet fun xs = UnsafeExpression $
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 $
657368 fun <> parenthesized (renderCommaSeparated renderSQL xs)
658369
659−-- | Helper for defining variadic functions.
660−unsafeVariadicFunction
661− :: SListI elems
662− => ByteString
663− -- ^ function
664− -> NP (Expression outer grp commons schemas params from) elems
665− -> Expression outer grp commons schemas params from ret
666−unsafeVariadicFunction fun x = UnsafeExpression $
667− fun <> parenthesized (commaSeparated (hcollapse (hmap (K . renderSQL) x)))
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
668377
669378instance ty `In` PGNum
670− => Num (Expression outer grp commons schemas params from (null ty)) where
379+ => Num (Expression outer commons grp schemas params from (null ty)) where
671380 (+) = unsafeBinaryOp "+"
672381 (-) = unsafeBinaryOp "-"
673382 (*) = unsafeBinaryOp "*"
@@ -679,7 +388,7 @@ instance ty `In` PGNum
679388 . show
680389
681390instance (ty `In` PGNum, ty `In` PGFloating) => Fractional
682− (Expression outer grp commons schemas params from (null ty)) where
391+ (Expression outer commons grp schemas params from (null ty)) where
683392 (/) = unsafeBinaryOp "/"
684393 fromRational
685394 = UnsafeExpression
@@ -689,7 +398,7 @@ instance (ty `In` PGNum, ty `In` PGFloating) => Fractional
689398 . fromRat @Double
690399
691400instance (ty `In` PGNum, ty `In` PGFloating) => Floating
692− (Expression outer grp commons schemas params from (null ty)) where
401+ (Expression outer commons grp schemas params from (null ty)) where
693402 pi = UnsafeExpression "pi()"
694403 exp = unsafeFunction "exp"
695404 log = unsafeFunction "ln"
@@ -710,1768 +419,54 @@ instance (ty `In` PGNum, ty `In` PGFloating) => Floating
710419 acosh x = log (x + sqrt (x*x - 1))
711420 atanh x = log ((1 + x) / (1 - x)) / 2
712421
713−-- | >>> :{
714−-- let
715−-- expression :: Expr (null 'PGfloat4)
716−-- expression = atan2_ (pi *: 2)
717−-- in printSQL expression
718−-- :}
719−-- atan2(pi(), 2)
720−atan2_
721− :: float `In` PGFloating
722− => FunctionHet '[ null float, null float] (null float)
723−atan2_ = unsafeFunctionHet "atan2"
724−
725−-- When a `cast` is applied to an `Expression` of a known type, it
726−-- represents a run-time type conversion. The cast will succeed only if a
727−-- suitable type conversion operation has been defined.
728−--
729−-- | >>> printSQL $ true & cast int4
730−-- (TRUE :: int4)
731−cast
732− :: TypeExpression schemas ty1
733− -- ^ type to cast as
734− -> Expression outer grp commons schemas params from ty0
735− -- ^ value to convert
736− -> Expression outer grp commons schemas params from ty1
737−cast ty x = UnsafeExpression $ parenthesized $
738− renderSQL x <+> "::" <+> renderSQL ty
739−
740−-- | integer division, truncates the result
741−--
742−-- >>> :{
743−-- let
744−-- expression :: Expression outer grp commons schemas params from (null 'PGint2)
745−-- expression = 5 `quot_` 2
746−-- in printSQL expression
747−-- :}
748−-- (5 / 2)
749−quot_
750− :: int `In` PGIntegral
751− => Operator (null int) (null int) (null int)
752−quot_ = unsafeBinaryOp "/"
753−
754−-- | remainder upon integer division
755−--
756−-- >>> :{
757−-- let
758−-- expression :: Expression outer grp commons schemas params from (null 'PGint2)
759−-- expression = 5 `rem_` 2
760−-- in printSQL expression
761−-- :}
762−-- (5 % 2)
763−rem_
764− :: int `In` PGIntegral
765− => Operator (null int) (null int) (null int)
766−rem_ = unsafeBinaryOp "%"
767−
768−-- | >>> :{
769−-- let
770−-- expression :: Expression outer grp commons schemas params from (null 'PGfloat4)
771−-- expression = trunc pi
772−-- in printSQL expression
773−-- :}
774−-- trunc(pi())
775−trunc :: frac `In` PGFloating => null frac :--> null frac
776−trunc = unsafeFunction "trunc"
777−
778−-- | >>> :{
779−-- let
780−-- expression :: Expression outer grp commons schemas params from (null 'PGfloat4)
781−-- expression = round_ pi
782−-- in printSQL expression
783−-- :}
784−-- round(pi())
785−round_ :: frac `In` PGFloating => null frac :--> null frac
786−round_ = unsafeFunction "round"
787−
788−-- | >>> :{
789−-- let
790−-- expression :: Expression outer grp commons schemas params from (null 'PGfloat4)
791−-- expression = ceiling_ pi
792−-- in printSQL expression
793−-- :}
794−-- ceiling(pi())
795−ceiling_ :: frac `In` PGFloating => null frac :--> null frac
796−ceiling_ = unsafeFunction "ceiling"
797−
798−-- | A `Condition` is an `Expression`, which can evaluate
799−-- to `true`, `false` or `null_`. This is because SQL uses
800−-- a three valued logic.
801−type Condition outer grp commons schemas params from =
802− Expression outer grp commons schemas params from ('Null 'PGbool)
803−
804−-- | >>> printSQL true
805−-- TRUE
806−true :: Expr (null 'PGbool)
807−true = UnsafeExpression "TRUE"
808−
809−-- | >>> printSQL false
810−-- FALSE
811−false :: Expr (null 'PGbool)
812−false = UnsafeExpression "FALSE"
813−
814−-- | >>> printSQL $ not_ true
815−-- (NOT TRUE)
816−not_ :: null 'PGbool :--> null 'PGbool
817−not_ = unsafeUnaryOpL "NOT"
818−
819−-- | >>> printSQL $ true .&& false
820−-- (TRUE AND FALSE)
821−(.&&) :: Operator (null 'PGbool) (null 'PGbool) (null 'PGbool)
822−infixr 3 .&&
823−(.&&) = unsafeBinaryOp "AND"
824−
825−-- | >>> printSQL $ true .|| false
826−-- (TRUE OR FALSE)
827−(.||) :: Operator (null 'PGbool) (null 'PGbool) (null 'PGbool)
828−infixr 2 .||
829−(.||) = unsafeBinaryOp "OR"
830−
831−-- | >>> :{
832−-- let
833−-- expression :: Expression outer grp commons schemas params from (null 'PGint2)
834−-- expression = caseWhenThenElse [(true, 1), (false, 2)] 3
835−-- in printSQL expression
836−-- :}
837−-- CASE WHEN TRUE THEN 1 WHEN FALSE THEN 2 ELSE 3 END
838−caseWhenThenElse
839− :: [ ( Condition outer grp commons schemas params from
840− , Expression outer grp commons schemas params from ty
841− ) ]
842− -- ^ whens and thens
843− -> Expression outer grp commons schemas params from ty
844− -- ^ else
845− -> Expression outer grp commons schemas params from ty
846−caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
847− [ "CASE"
848− , mconcat
849− [ mconcat
850− [ " WHEN ", renderSQL when_
851− , " THEN ", renderSQL then_
852− ]
853− | (when_,then_) <- whenThens
854− ]
855− , " ELSE ", renderSQL else_
856− , " END"
857− ]
858−
859−-- | >>> :{
860−-- let
861−-- expression :: Expression outer grp commons schemas params from (null 'PGint2)
862−-- expression = ifThenElse true 1 0
863−-- in printSQL expression
864−-- :}
865−-- CASE WHEN TRUE THEN 1 ELSE 0 END
866−ifThenElse
867− :: Condition outer grp commons schemas params from
868− -> Expression outer grp commons schemas params from ty -- ^ then
869− -> Expression outer grp commons schemas params from ty -- ^ else
870− -> Expression outer grp commons schemas params from ty
871−ifThenElse if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
872−
873−-- | Comparison operations like `.==`, `./=`, `.>`, `.>=`, `.<` and `.<=`
874−-- will produce @NULL@s if one of their arguments is @NULL@.
875−--
876−-- >>> printSQL $ true .== null_
877−-- (TRUE = NULL)
878−(.==) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
879−(.==) = unsafeBinaryOp "="
880−infix 4 .==
881−
882−-- | >>> printSQL $ true ./= null_
883−-- (TRUE <> NULL)
884−(./=) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
885−(./=) = unsafeBinaryOp "<>"
886−infix 4 ./=
887−
888−-- | >>> printSQL $ true .>= null_
889−-- (TRUE >= NULL)
890−(.>=) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
891−(.>=) = unsafeBinaryOp ">="
892−infix 4 .>=
893−
894−-- | >>> printSQL $ true .< null_
895−-- (TRUE < NULL)
896−(.<) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
897−(.<) = unsafeBinaryOp "<"
898−infix 4 .<
899−
900−-- | >>> printSQL $ true .<= null_
901−-- (TRUE <= NULL)
902−(.<=) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
903−(.<=) = unsafeBinaryOp "<="
904−infix 4 .<=
905−
906−-- | >>> printSQL $ true .> null_
907−-- (TRUE > NULL)
908−(.>) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
909−(.>) = unsafeBinaryOp ">"
910−infix 4 .>
911−
912−{- | between
913−>>> printSQL $ true `between` (null_, false)
914−TRUE BETWEEN NULL AND FALSE
915−-}
916−between
917− :: Expression outer grp commons schemas params from (null ty)
918− -> ( Expression outer grp commons schemas params from (null ty)
919− , Expression outer grp commons schemas params from (null ty) ) -- ^ bounds
920− -> Condition outer grp commons schemas params from
921−between a (x,y) = UnsafeExpression $ renderSQL a <+> "BETWEEN"
922− <+> renderSQL x <+> "AND" <+> renderSQL y
923−
924−{- | not between
925−>>> printSQL $ true `notBetween` (null_, false)
926−TRUE NOT BETWEEN NULL AND FALSE
927−-}
928−notBetween
929− :: Expression outer grp commons schemas params from (null ty)
930− -> ( Expression outer grp commons schemas params from (null ty)
931− , Expression outer grp commons schemas params from (null ty) ) -- ^ bounds
932− -> Condition outer grp commons schemas params from
933−notBetween a (x,y) = UnsafeExpression $ renderSQL a <+> "NOT BETWEEN"
934− <+> renderSQL x <+> "AND" <+> renderSQL y
935−
936−{- | between, after sorting the comparison values
937−>>> printSQL $ true `betweenSymmetric` (null_, false)
938−TRUE BETWEEN SYMMETRIC NULL AND FALSE
939−-}
940−betweenSymmetric
941− :: Expression outer grp commons schemas params from (null ty)
942− -> ( Expression outer grp commons schemas params from (null ty)
943− , Expression outer grp commons schemas params from (null ty) ) -- ^ bounds
944− -> Condition outer grp commons schemas params from
945−betweenSymmetric a (x,y) = UnsafeExpression $ renderSQL a
946− <+> "BETWEEN SYMMETRIC" <+> renderSQL x <+> "AND" <+> renderSQL y
947−
948−{- | not between, after sorting the comparison values
949−>>> printSQL $ true `notBetweenSymmetric` (null_, false)
950−TRUE NOT BETWEEN SYMMETRIC NULL AND FALSE
951−-}
952−notBetweenSymmetric
953− :: Expression outer grp commons schemas params from (null ty)
954− -> ( Expression outer grp commons schemas params from (null ty)
955− , Expression outer grp commons schemas params from (null ty) ) -- ^ bounds
956− -> Condition outer grp commons schemas params from
957−notBetweenSymmetric a (x,y) = UnsafeExpression $ renderSQL a
958− <+> "NOT BETWEEN SYMMETRIC" <+> renderSQL x <+> "AND" <+> renderSQL y
959−
960−{- | not equal, treating null like an ordinary value
961−>>> printSQL $ true `isDistinctFrom` null_
962−(TRUE IS DISTINCT FROM NULL)
963−-}
964−isDistinctFrom :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
965−isDistinctFrom = unsafeBinaryOp "IS DISTINCT FROM"
966−
967−{- | equal, treating null like an ordinary value
968−>>> printSQL $ true `isNotDistinctFrom` null_
969−(TRUE IS NOT DISTINCT FROM NULL)
970−-}
971−isNotDistinctFrom :: Operator (null0 ty) (null1 ty) ('NotNull 'PGbool)
972−isNotDistinctFrom = unsafeBinaryOp "IS NOT DISTINCT FROM"
973−
974−{- | is true
975−>>> printSQL $ true & isTrue
976−(TRUE IS TRUE)
977−-}
978−isTrue :: null 'PGbool :--> 'NotNull 'PGbool
979−isTrue = unsafeUnaryOpR "IS TRUE"
980−
981−{- | is false or unknown
982−>>> printSQL $ true & isNotTrue
983−(TRUE IS NOT TRUE)
984−-}
985−isNotTrue :: null 'PGbool :--> 'NotNull 'PGbool
986−isNotTrue = unsafeUnaryOpR "IS NOT TRUE"
987−
988−{- | is false
989−>>> printSQL $ true & isFalse
990−(TRUE IS FALSE)
991−-}
992−isFalse :: null 'PGbool :--> 'NotNull 'PGbool
993−isFalse = unsafeUnaryOpR "IS FALSE"
994−
995−{- | is true or unknown
996−>>> printSQL $ true & isNotFalse
997−(TRUE IS NOT FALSE)
998−-}
999−isNotFalse :: null 'PGbool :--> 'NotNull 'PGbool
1000−isNotFalse = unsafeUnaryOpR "IS NOT FALSE"
1001−
1002−{- | is unknown
1003−>>> printSQL $ true & isUnknown
1004−(TRUE IS UNKNOWN)
1005−-}
1006−isUnknown :: null 'PGbool :--> 'NotNull 'PGbool
1007−isUnknown = unsafeUnaryOpR "IS UNKNOWN"
1008−
1009−{- | is true or false
1010−>>> printSQL $ true & isNotUnknown
1011−(TRUE IS NOT UNKNOWN)
1012−-}
1013−isNotUnknown :: null 'PGbool :--> 'NotNull 'PGbool
1014−isNotUnknown = unsafeUnaryOpR "IS NOT UNKNOWN"
1015−
1016−-- | >>> printSQL currentDate
1017−-- CURRENT_DATE
1018−currentDate :: Expr (null 'PGdate)
1019−currentDate = UnsafeExpression "CURRENT_DATE"
1020−
1021−-- | >>> printSQL currentTime
1022−-- CURRENT_TIME
1023−currentTime :: Expr (null 'PGtimetz)
1024−currentTime = UnsafeExpression "CURRENT_TIME"
1025−
1026−-- | >>> printSQL currentTimestamp
1027−-- CURRENT_TIMESTAMP
1028−currentTimestamp :: Expr (null 'PGtimestamptz)
1029−currentTimestamp = UnsafeExpression "CURRENT_TIMESTAMP"
1030−
1031−-- | >>> printSQL localTime
1032−-- LOCALTIME
1033−localTime :: Expr (null 'PGtime)
1034−localTime = UnsafeExpression "LOCALTIME"
1035−
1036−-- | >>> printSQL localTimestamp
1037−-- LOCALTIMESTAMP
1038−localTimestamp :: Expr (null 'PGtimestamp)
1039−localTimestamp = UnsafeExpression "LOCALTIMESTAMP"
1040−
1041−{-----------------------------------------
1042−text
1043−-----------------------------------------}
1044−
1045−escape :: Char -> String
1046−escape = \case
1047− '\NUL' -> "\\0"
1048− '\'' -> "''"
1049− '"' -> "\\\""
1050− '\b' -> "\\b"
1051− '\n' -> "\\n"
1052− '\r' -> "\\r"
1053− '\t' -> "\\t"
1054− '\\' -> "\\\\"
1055− c -> [c]
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)
1056438
1057439instance IsString
1058− (Expression outer grp commons schemas params from (null 'PGtext)) where
440+ (Expression outer commons grp schemas params from (null 'PGtext)) where
1059441 fromString str = UnsafeExpression $
1060442 "E\'" <> fromString (escape =<< str) <> "\'"
1061443instance IsString
1062− (Expression outer grp commons schemas params from (null 'PGtsvector)) where
1063− fromString str = cast tsvector . UnsafeExpression $
444+ (Expression outer commons grp schemas params from (null 'PGtsvector)) where
445+ fromString str = UnsafeExpression . parenthesized . (<> " :: tsvector") $
1064446 "E\'" <> fromString (escape =<< str) <> "\'"
1065447instance IsString
1066− (Expression outer grp commons schemas params from (null 'PGtsquery)) where
1067− fromString str = cast tsquery . UnsafeExpression $
448+ (Expression outer commons grp schemas params from (null 'PGtsquery)) where
449+ fromString str = UnsafeExpression . parenthesized . (<> " :: tsquery") $
1068450 "E\'" <> fromString (escape =<< str) <> "\'"
1069451
1070452instance Semigroup
1071− (Expression outer grp commons schemas params from (null 'PGtext)) where
453+ (Expression outer commons grp schemas params from (null ('PGvararray ty))) where
1072454 (<>) = unsafeBinaryOp "||"
1073455instance Semigroup
1074− (Expression outer grp commons schemas params from (null 'PGtsvector)) where
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
1075463 (<>) = unsafeBinaryOp "||"
1076464
1077465instance Monoid
1078− (Expression outer grp commons schemas params from (null 'PGtext)) where
466+ (Expression outer commons grp schemas params from (null 'PGtext)) where
1079467 mempty = fromString ""
1080468 mappend = (<>)
1081469instance Monoid
1082− (Expression outer grp commons schemas params from (null 'PGtsvector)) where
470+ (Expression outer commons grp schemas params from (null 'PGtsvector)) where
1083471 mempty = fromString ""
1084472 mappend = (<>)
1085−
1086−-- | >>> printSQL $ lower "ARRRGGG"
1087−-- lower(E'ARRRGGG')
1088−lower :: null 'PGtext :--> null 'PGtext
1089−lower = unsafeFunction "lower"
1090−
1091−-- | >>> printSQL $ upper "eeee"
1092−-- upper(E'eeee')
1093−upper :: null 'PGtext :--> null 'PGtext
1094−upper = unsafeFunction "upper"
1095−
1096−-- | >>> printSQL $ charLength "four"
1097−-- char_length(E'four')
1098−charLength :: null 'PGtext :--> null 'PGint4
1099−charLength = unsafeFunction "char_length"
1100−
1101−-- | The `like` expression returns true if the @string@ matches
1102−-- the supplied @pattern@. If @pattern@ does not contain percent signs
1103−-- or underscores, then the pattern only represents the string itself;
1104−-- in that case `like` acts like the equals operator. An underscore (_)
1105−-- in pattern stands for (matches) any single character; a percent sign (%)
1106−-- matches any sequence of zero or more characters.
1107−--
1108−-- >>> printSQL $ "abc" `like` "a%"
1109−-- (E'abc' LIKE E'a%')
1110−like :: Operator (null 'PGtext) (null 'PGtext) ('Null 'PGbool)
1111−like = unsafeBinaryOp "LIKE"
1112−
1113−-- | The key word ILIKE can be used instead of LIKE to make the
1114−-- match case-insensitive according to the active locale.
1115−--
1116−-- >>> printSQL $ "abc" `ilike` "a%"
1117−-- (E'abc' ILIKE E'a%')
1118−ilike :: Operator (null 'PGtext) (null 'PGtext) ('Null 'PGbool)
1119−ilike = unsafeBinaryOp "ILIKE"
1120−
1121−{-----------------------------------------
1122− -- json and jsonb support
1123−
1124−See https://www.postgresql.org/docs/10/static/functions-json.html -- most
1125−comments lifted directly from this page.
1126−
1127−Table 9.44: json and jsonb operators
1128−-----------------------------------------}
1129−
1130−-- | Get JSON value (object field or array element) at a key.
1131−(.->)
1132− :: (json `In` PGJsonType, key `In` PGJsonKey)
1133− => Operator (null json) (null key) ('Null json)
1134−infixl 8 .->
1135−(.->) = unsafeBinaryOp "->"
1136−
1137−-- | Get JSON value (object field or array element) at a key, as text.
1138−(.->>)
1139− :: (json `In` PGJsonType, key `In` PGJsonKey)
1140− => Operator (null json) (null key) ('Null 'PGtext)
1141−infixl 8 .->>
1142−(.->>) = unsafeBinaryOp "->>"
1143−
1144−-- | Get JSON value at a specified path.
1145−(.#>)
1146− :: (json `In` PGJsonType, PGTextArray "(.#>)" path)
1147− => Operator (null json) (null path) ('Null json)
1148−infixl 8 .#>
1149−(.#>) = unsafeBinaryOp "#>"
1150−
1151−-- | Get JSON value at a specified path as text.
1152−(.#>>)
1153− :: (json `In` PGJsonType, PGTextArray "(.#>>)" path)
1154− => Operator (null json) (null path) ('Null 'PGtext)
1155−infixl 8 .#>>
1156−(.#>>) = unsafeBinaryOp "#>>"
1157−
1158−-- Additional jsonb operators
1159−
1160−-- | Does the left JSON value contain the right JSON path/value entries at the
1161−-- top level?
1162−(.@>)
1163− :: Operator (null 'PGjsonb) (null 'PGjsonb) ('Null 'PGbool)
1164−infixl 9 .@>
1165−(.@>) = unsafeBinaryOp "@>"
1166−
1167−-- | Are the left JSON path/value entries contained at the top level within the
1168−-- right JSON value?
1169−(.<@) :: Operator (null 'PGjsonb) (null 'PGjsonb) ('Null 'PGbool)
1170−infixl 9 .<@
1171−(.<@) = unsafeBinaryOp "<@"
1172−
1173−-- | Does the string exist as a top-level key within the JSON value?
1174−(.?) :: Operator (null 'PGjsonb) (null 'PGtext) ('Null 'PGbool)
1175−infixl 9 .?
1176−(.?) = unsafeBinaryOp "?"
1177−
1178−-- | Do any of these array strings exist as top-level keys?
1179−(.?|) :: Operator
1180− (null 'PGjsonb)
1181− (null ('PGvararray ('NotNull 'PGtext)))
1182− ('Null 'PGbool)
1183−infixl 9 .?|
1184−(.?|) = unsafeBinaryOp "?|"
1185−
1186−-- | Do all of these array strings exist as top-level keys?
1187−(.?&) :: Operator
1188− (null 'PGjsonb)
1189− (null ('PGvararray ('NotNull 'PGtext)))
1190− ('Null 'PGbool)
1191−infixl 9 .?&
1192−(.?&) = unsafeBinaryOp "?&"
1193−
1194−-- | Concatenate two jsonb values into a new jsonb value.
1195−instance Semigroup
1196− (Expression outer grp commons schemas params from (null 'PGjsonb)) where
1197− (<>) = unsafeBinaryOp "||"
1198−
1199−-- | Delete a key or keys from a JSON object, or remove an array element.
1200−--
1201−-- If the right operand is..
1202−--
1203−-- @ text @: Delete key/value pair or string element from left operand. Key/value pairs
1204−-- are matched based on their key value.
1205−--
1206−-- @ text[] @: Delete multiple key/value pairs or string elements
1207−-- from left operand. Key/value pairs are matched based on their key value.
1208−--
1209−-- @ integer @: Delete the array element with specified index (Negative integers
1210−-- count from the end). Throws an error if top level container is not an array.
1211−(.-.)
1212− :: (key `In` '[ 'PGtext, 'PGvararray ('NotNull 'PGtext), 'PGint4, 'PGint2 ]) -- hlint error without parens here
1213− => Operator (null 'PGjsonb) (null key) (null 'PGjsonb)
1214−infixl 6 .-.
1215−(.-.) = unsafeBinaryOp "-"
1216−
1217−-- | Delete the field or element with specified path (for JSON arrays, negative
1218−-- integers count from the end)
1219−(#-.)
1220− :: PGTextArray "(#-.)" arrayty
1221− => Operator (null 'PGjsonb) (null arrayty)(null 'PGjsonb)
1222−infixl 6 #-.
1223−(#-.) = unsafeBinaryOp "#-"
1224−
1225−{-----------------------------------------
1226−Table 9.45: JSON creation functions
1227−-----------------------------------------}
1228−
1229−-- | Literal binary JSON
1230−jsonbLit :: JSON.ToJSON x => x -> Expr (null 'PGjsonb)
1231−jsonbLit = cast jsonb . UnsafeExpression
1232− . singleQuotedUtf8 . toStrict . JSON.encode
1233−
1234−-- | Literal JSON
1235−jsonLit :: JSON.ToJSON x => x -> Expr (null 'PGjson)
1236−jsonLit = cast json . UnsafeExpression
1237− . singleQuotedUtf8 . toStrict . JSON.encode
1238−
1239−-- | Returns the value as json. Arrays and composites are converted
1240−-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1241−-- type to json, the cast function will be used to perform the conversion;
1242−-- otherwise, a scalar value is produced. For any scalar type other than a
1243−-- number, a Boolean, or a null value, the text representation will be used, in
1244−-- such a fashion that it is a valid json value.
1245−toJson :: null ty :--> null 'PGjson
1246−toJson = unsafeFunction "to_json"
1247−
1248−-- | Returns the value as jsonb. Arrays and composites are converted
1249−-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1250−-- type to json, the cast function will be used to perform the conversion;
1251−-- otherwise, a scalar value is produced. For any scalar type other than a
1252−-- number, a Boolean, or a null value, the text representation will be used, in
1253−-- such a fashion that it is a valid jsonb value.
1254−toJsonb :: null ty :--> null 'PGjsonb
1255−toJsonb = unsafeFunction "to_jsonb"
1256−
1257−-- | Returns the array as a JSON array. A PostgreSQL multidimensional array
1258−-- becomes a JSON array of arrays.
1259−arrayToJson
1260− :: PGArray "arrayToJson" arr
1261− => null arr :--> null 'PGjson
1262−arrayToJson = unsafeFunction "array_to_json"
1263−
1264−-- | Returns the row as a JSON object.
1265−rowToJson :: null ('PGcomposite ty) :--> null 'PGjson
1266−rowToJson = unsafeFunction "row_to_json"
1267−
1268−-- | Builds a possibly-heterogeneously-typed JSON array out of a variadic
1269−-- argument list.
1270−jsonBuildArray
1271− :: SListI elems
1272− => NP (Expression outer grp commons schemas params from) elems
1273− -> Expression outer grp commons schemas params from (null 'PGjson)
1274−jsonBuildArray = unsafeVariadicFunction "json_build_array"
1275−
1276−-- | Builds a possibly-heterogeneously-typed (binary) JSON array out of a
1277−-- variadic argument list.
1278−jsonbBuildArray
1279− :: SListI elems
1280− => NP (Expression outer grp commons schemas params from) elems
1281− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1282−jsonbBuildArray = unsafeVariadicFunction "jsonb_build_array"
1283−
1284−unsafeRowFunction
1285− :: SOP.SListI elems
1286− => NP (Aliased (Expression outer grp commons schemas params from)) elems
1287− -> [ByteString]
1288−unsafeRowFunction =
1289− (`appEndo` []) . hcfoldMap (Proxy :: SOP.Proxy SOP.Top)
1290− (\(col `As` name) -> Endo $ \xs ->
1291− renderAliasString name : renderSQL col : xs)
1292− where
1293− renderAliasString :: KnownSymbol alias => Alias alias -> ByteString
1294− renderAliasString = singleQuotedText . fromString . symbolVal
1295−
1296−-- | Builds a possibly-heterogeneously-typed JSON object out of a variadic
1297−-- argument list. The elements of the argument list must alternate between text
1298−-- and values.
1299−jsonBuildObject
1300− :: SOP.SListI elems
1301− => NP (Aliased (Expression outer grp commons schemas params from)) elems
1302− -> Expression outer grp commons schemas params from (null 'PGjson)
1303−jsonBuildObject
1304− = unsafeFunction "json_build_object"
1305− . UnsafeExpression
1306− . commaSeparated
1307− . unsafeRowFunction
1308−
1309−-- | Builds a possibly-heterogeneously-typed (binary) JSON object out of a
1310−-- variadic argument list. The elements of the argument list must alternate
1311−-- between text and values.
1312−jsonbBuildObject
1313− :: SOP.SListI elems
1314− => NP (Aliased (Expression outer grp commons schemas params from)) elems
1315− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1316−jsonbBuildObject
1317− = unsafeFunction "jsonb_build_object"
1318− . UnsafeExpression
1319− . commaSeparated
1320− . unsafeRowFunction
1321−
1322−-- | Builds a JSON object out of a text array. The array must have either
1323−-- exactly one dimension with an even number of members, in which case they are
1324−-- taken as alternating key/value pairs, or two dimensions such that each inner
1325−-- array has exactly two elements, which are taken as a key/value pair.
1326−jsonObject
1327− :: PGArrayOf "jsonObject" arr ('NotNull 'PGtext)
1328− => null arr :--> null 'PGjson
1329−jsonObject = unsafeFunction "json_object"
1330−
1331−-- | Builds a binary JSON object out of a text array. The array must have either
1332−-- exactly one dimension with an even number of members, in which case they are
1333−-- taken as alternating key/value pairs, or two dimensions such that each inner
1334−-- array has exactly two elements, which are taken as a key/value pair.
1335−jsonbObject
1336− :: PGArrayOf "jsonbObject" arr ('NotNull 'PGtext)
1337− => null arr :--> null 'PGjsonb
1338−jsonbObject = unsafeFunction "jsonb_object"
1339−
1340−-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1341−-- keys and one for values, that are zipped pairwise to create a JSON object.
1342−jsonZipObject
1343− :: ( PGArrayOf "jsonZipObject" keysArray ('NotNull 'PGtext)
1344− , PGArrayOf "jsonZipObject" valuesArray ('NotNull 'PGtext))
1345− => Expression outer grp commons schemas params from (null keysArray)
1346− -> Expression outer grp commons schemas params from (null valuesArray)
1347− -> Expression outer grp commons schemas params from (null 'PGjson)
1348−jsonZipObject ks vs =
1349− unsafeVariadicFunction "json_object" (ks :* vs :* Nil)
1350−
1351−-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1352−-- keys and one for values, that are zipped pairwise to create a binary JSON
1353−-- object.
1354−jsonbZipObject
1355− :: ( PGArrayOf "jsonbZipObject" keysArray ('NotNull 'PGtext)
1356− , PGArrayOf "jsonbZipObject" valuesArray ('NotNull 'PGtext))
1357− => Expression outer grp commons schemas params from (null keysArray)
1358− -> Expression outer grp commons schemas params from (null valuesArray)
1359− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1360−jsonbZipObject ks vs =
1361− unsafeVariadicFunction "jsonb_object" (ks :* vs :* Nil)
1362−
1363−{-----------------------------------------
1364−Table 9.46: JSON processing functions
1365−-----------------------------------------}
1366−
1367−-- | Returns the number of elements in the outermost JSON array.
1368−jsonArrayLength :: null 'PGjson :--> null 'PGint4
1369−jsonArrayLength = unsafeFunction "json_array_length"
1370−
1371−-- | Returns the number of elements in the outermost binary JSON array.
1372−jsonbArrayLength :: null 'PGjsonb :--> null 'PGint4
1373−jsonbArrayLength = unsafeFunction "jsonb_array_length"
1374−
1375−-- | Returns JSON value pointed to by the given path (equivalent to #>
1376−-- operator).
1377−jsonExtractPath
1378− :: SListI elems
1379− => Expression outer grp commons schemas params from (null 'PGjson)
1380− -> NP (Expression outer grp commons schemas params from) elems
1381− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1382−jsonExtractPath x xs =
1383− unsafeVariadicFunction "json_extract_path" (x :* xs)
1384−
1385−-- | Returns JSON value pointed to by the given path (equivalent to #>
1386−-- operator).
1387−jsonbExtractPath
1388− :: SListI elems
1389− => Expression outer grp commons schemas params from (null 'PGjsonb)
1390− -> NP (Expression outer grp commons schemas params from) elems
1391− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1392−jsonbExtractPath x xs =
1393− unsafeVariadicFunction "jsonb_extract_path" (x :* xs)
1394−
1395−-- | Returns JSON value pointed to by the given path (equivalent to #>
1396−-- operator), as text.
1397−jsonExtractPathAsText
1398− :: SListI elems
1399− => Expression outer grp commons schemas params from (null 'PGjson)
1400− -> NP (Expression outer grp commons schemas params from) elems
1401− -> Expression outer grp commons schemas params from (null 'PGjson)
1402−jsonExtractPathAsText x xs =
1403− unsafeVariadicFunction "json_extract_path_text" (x :* xs)
1404−
1405−-- | Returns JSON value pointed to by the given path (equivalent to #>
1406−-- operator), as text.
1407−jsonbExtractPathAsText
1408− :: SListI elems
1409− => Expression outer grp commons schemas params from (null 'PGjsonb)
1410− -> NP (Expression outer grp commons schemas params from) elems
1411− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1412−jsonbExtractPathAsText x xs =
1413− unsafeVariadicFunction "jsonb_extract_path_text" (x :* xs)
1414−
1415−-- | Returns the type of the outermost JSON value as a text string. Possible
1416−-- types are object, array, string, number, boolean, and null.
1417−jsonTypeof :: null 'PGjson :--> null 'PGtext
1418−jsonTypeof = unsafeFunction "json_typeof"
1419−
1420−-- | Returns the type of the outermost binary JSON value as a text string.
1421−-- Possible types are object, array, string, number, boolean, and null.
1422−jsonbTypeof :: null 'PGjsonb :--> null 'PGtext
1423−jsonbTypeof = unsafeFunction "jsonb_typeof"
1424−
1425−-- | Returns its argument with all object fields that have null values omitted.
1426−-- Other null values are untouched.
1427−jsonStripNulls :: null 'PGjson :--> null 'PGjson
1428−jsonStripNulls = unsafeFunction "json_strip_nulls"
1429−
1430−-- | Returns its argument with all object fields that have null values omitted.
1431−-- Other null values are untouched.
1432−jsonbStripNulls :: null 'PGjsonb :--> null 'PGjsonb
1433−jsonbStripNulls = unsafeFunction "jsonb_strip_nulls"
1434−
1435−-- | @ jsonbSet target path new_value create_missing @
1436−--
1437−-- Returns target with the section designated by path replaced by new_value,
1438−-- or with new_value added if create_missing is true ( default is true) and the
1439−-- item designated by path does not exist. As with the path orientated
1440−-- operators, negative integers that appear in path count from the end of JSON
1441−-- arrays.
1442−jsonbSet
1443− :: PGTextArray "jsonbSet" arr
1444− => Expression outer grp commons schemas params from (null 'PGjsonb)
1445− -> Expression outer grp commons schemas params from (null arr)
1446− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1447− -> Maybe (Expression outer grp commons schemas params from (null 'PGbool))
1448− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1449−jsonbSet tgt path val createMissing = case createMissing of
1450− Just m -> unsafeVariadicFunction "jsonb_set" (tgt :* path :* val :* m :* Nil)
1451− Nothing -> unsafeVariadicFunction "jsonb_set" (tgt :* path :* val :* Nil)
1452−
1453−-- | @ jsonbInsert target path new_value insert_after @
1454−--
1455−-- Returns target with new_value inserted. If target section designated by
1456−-- path is in a JSONB array, new_value will be inserted before target or after
1457−-- if insert_after is true (default is false). If target section designated by
1458−-- path is in JSONB object, new_value will be inserted only if target does not
1459−-- exist. As with the path orientated operators, negative integers that appear
1460−-- in path count from the end of JSON arrays.
1461−jsonbInsert
1462− :: PGTextArray "jsonbInsert" arr
1463− => Expression outer grp commons schemas params from (null 'PGjsonb)
1464− -> Expression outer grp commons schemas params from (null arr)
1465− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1466− -> Maybe (Expression outer grp commons schemas params from (null 'PGbool))
1467− -> Expression outer grp commons schemas params from (null 'PGjsonb)
1468−jsonbInsert tgt path val insertAfter = case insertAfter of
1469− Just i -> unsafeVariadicFunction "jsonb_insert" (tgt :* path :* val :* i :* Nil)
1470− Nothing -> unsafeVariadicFunction "jsonb_insert" (tgt :* path :* val :* Nil)
1471−
1472−-- | Returns its argument as indented JSON text.
1473−jsonbPretty :: null 'PGjsonb :--> null 'PGtext
1474−jsonbPretty = unsafeFunction "jsonb_pretty"
1475−
1476−(@@) :: Operator (null 'PGtsvector) (null 'PGtsquery) ('Null 'PGbool)
1477−(@@) = unsafeBinaryOp "@@"
1478−
1479−(.&) :: Operator (null 'PGtsquery) (null 'PGtsquery) (null 'PGtsquery)
1480−(.&) = unsafeBinaryOp "&&"
1481−
1482−(.|) :: Operator (null 'PGtsquery) (null 'PGtsquery) (null 'PGtsquery)
1483−(.|) = unsafeBinaryOp "||"
1484−
1485−(.!) :: null 'PGtsquery :--> null 'PGtsquery
1486−(.!) = unsafeUnaryOpL "!!"
1487−
1488−(<->) :: Operator (null 'PGtsquery) (null 'PGtsquery) (null 'PGtsquery)
1489−(<->) = unsafeBinaryOp "<->"
1490−
1491−arrayToTSvector
1492− :: null ('PGvararray ('NotNull 'PGtext))
1493− :--> null 'PGtsvector
1494−arrayToTSvector = unsafeFunction "array_to_tsvector"
1495−
1496−tsvectorLength :: null 'PGtsvector :--> null 'PGint4
1497−tsvectorLength = unsafeFunction "length"
1498−
1499−numnode :: null 'PGtsquery :--> null 'PGint4
1500−numnode = unsafeFunction "numnode"
1501−
1502−plainToTSquery
1503− :: FunctionHet '[null 'PGtext, null 'PGtext] (null 'PGtsquery)
1504−plainToTSquery = unsafeFunctionHet "plainto_tsquery"
1505−
1506−phraseToTSquery
1507− :: FunctionHet '[null 'PGtext, null 'PGtext] (null 'PGtsquery)
1508−phraseToTSquery = unsafeFunctionHet "phraseto_tsquery"
1509−
1510−websearchToTSquery
1511− :: FunctionHet '[null 'PGtext, null 'PGtext] (null 'PGtsquery)
1512−websearchToTSquery = unsafeFunctionHet "websearch_to_tsquery"
1513−
1514−queryTree :: null 'PGtsquery :--> null 'PGtext
1515−queryTree = unsafeFunction "query_tree"
1516−
1517−toTSquery
1518− :: FunctionHet '[null 'PGtext, null 'PGtext] (null 'PGtsquery)
1519−toTSquery = unsafeFunctionHet "to_tsquery"
1520−
1521−toTSvector
1522− :: ty `In` '[ 'PGtext, 'PGjson, 'PGjsonb]
1523− => FunctionHet '[null 'PGtext, null ty] (null 'PGtsquery)
1524−toTSvector = unsafeFunctionHet "to_tsvector"
1525−
1526−{-----------------------------------------
1527−aggregation
1528−-----------------------------------------}
1529−
1530−{- |
1531−`Aggregate` functions compute a single result from a set of input values.
1532−`Aggregate` functions can be used as `GroupedBy` `Expression`s as well
1533−as `WindowFunction`s.
1534−-}
1535−class Aggregate expr1 expr2 aggr
1536− | aggr -> expr1, aggr -> expr2 where
1537−
1538− -- | A special aggregation that does not require an input
1539− --
1540− -- >>> :{
1541− -- let
1542− -- expression :: Expression '[] ('Grouped bys) commons schemas params from ('NotNull 'PGint8)
1543− -- expression = countStar
1544− -- in printSQL expression
1545− -- :}
1546− -- count(*)
1547− countStar :: aggr ('NotNull 'PGint8)
1548−
1549− -- | >>> :{
1550− -- let
1551− -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: null ty]] ('NotNull 'PGint8)
1552− -- expression = count (All #col)
1553− -- in printSQL expression
1554− -- :}
1555− -- count(ALL "col")
1556− count
1557− :: expr1 ty
1558− -- ^ what to count
1559− -> aggr ('NotNull 'PGint8)
1560−
1561− -- | >>> :{
1562− -- let
1563− -- expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: 'Null 'PGnumeric]] ('NotNull 'PGnumeric)
1564− -- expression = sum_ (Distinct #col)
1565− -- in printSQL expression
1566− -- :}
1567− -- sum(DISTINCT "col")
1568− sum_
1569− :: ty `In` PGNum
1570− => expr1 (null ty)
1571− -> aggr ('NotNull ty)
1572−
1573− -- | input values, including nulls, concatenated into an array
1574− arrayAgg
1575− :: expr1 ty
1576− -> aggr ('Null ('PGvararray ty))
1577−
1578− -- | aggregates values as a JSON array
1579− jsonAgg
1580− :: expr1 ty
1581− -> aggr ('Null 'PGjson)
1582−
1583− -- | aggregates values as a JSON array
1584− jsonbAgg
1585− :: expr1 ty
1586− -> aggr ('Null 'PGjsonb)
1587−
1588− {- |
1589− the bitwise AND of all non-null input values, or null if none
1590− >>> :{
1591− let
1592− expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: null 'PGint4]] ('Null 'PGint4)
1593− expression = bitAnd (Distinct #col)
1594− in printSQL expression
1595− :}
1596− bit_and(DISTINCT "col")
1597− -}
1598− bitAnd
1599− :: int `In` PGIntegral
1600− => expr1 (null int)
1601− -- ^ what to aggregate
1602− -> aggr ('Null int)
1603−
1604− {- |
1605− the bitwise OR of all non-null input values, or null if none
1606−
1607− >>> :{
1608− let
1609− expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: null 'PGint4]] ('Null 'PGint4)
1610− expression = bitOr (All #col)
1611− in printSQL expression
1612− :}
1613− bit_or(ALL "col")
1614− -}
1615− bitOr
1616− :: int `In` PGIntegral
1617− => expr1 (null int)
1618− -- ^ what to aggregate
1619− -> aggr ('Null int)
1620−
1621− {- |
1622− true if all input values are true, otherwise false
1623−
1624− >>> :{
1625− let
1626− winFun :: WindowFunction '[] 'Ungrouped commons schemas params '[tab ::: '["col" ::: null 'PGbool]] ('Null 'PGbool)
1627− winFun = boolAnd #col
1628− in printSQL winFun
1629− :}
1630− bool_and("col")
1631− -}
1632− boolAnd
1633− :: expr1 (null 'PGbool)
1634− -- ^ what to aggregate
1635− -> aggr ('Null 'PGbool)
1636−
1637− {- |
1638− true if at least one input value is true, otherwise false
1639−
1640− >>> :{
1641− let
1642− expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: null 'PGbool]] ('Null 'PGbool)
1643− expression = boolOr (All #col)
1644− in printSQL expression
1645− :}
1646− bool_or(ALL "col")
1647− -}
1648− boolOr
1649− :: expr1(null 'PGbool)
1650− -- ^ what to aggregate
1651− -> aggr ('Null 'PGbool)
1652−
1653− {- |
1654− equivalent to `boolAnd`
1655−
1656− >>> :{
1657− let
1658− expression :: Expression '[] ('Grouped bys) commons schemas params '[tab ::: '["col" ::: null 'PGbool]] ('Null 'PGbool)
1659− expression = every (Distinct #col)
1660− in printSQL expression
1661− :}
1662− every(DISTINCT "col")
1663− -}
1664− every
1665− :: expr1 (null 'PGbool)
1666− -- ^ what to aggregate
1667− -> aggr ('Null 'PGbool)
1668−
1669− {- |maximum value of expression across all input values-}
1670− max_
1671− :: expr1 (null ty)
1672− -- ^ what to maximize
1673− -> aggr ('Null ty)
1674−
1675− -- | minimum value of expression across all input values
1676− min_
1677− :: expr1 (null ty)
1678− -- ^ what to minimize
1679− -> aggr ('Null ty)
1680−
1681− -- | the average (arithmetic mean) of all input values
1682− avg
1683− :: expr1 (null ty)
1684− -- ^ what to average
1685− -> aggr ('Null (PGAvg ty))
1686−
1687− {- | correlation coefficient
1688− >>> :{
1689− let
1690− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1691− expression = corr (All (#y :*: #x))
1692− in printSQL expression
1693− :}
1694− corr(ALL "y", "x")
1695− -}
1696− corr
1697− :: expr2 (null 'PGfloat8)
1698− -> aggr ('Null 'PGfloat8)
1699−
1700− {- | population covariance
1701− >>> :{
1702− let
1703− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1704− expression = covarPop (All (#y :*: #x))
1705− in printSQL expression
1706− :}
1707− covar_pop(ALL "y", "x")
1708− -}
1709− covarPop
1710− :: expr2 (null 'PGfloat8)
1711− -> aggr ('Null 'PGfloat8)
1712−
1713− {- | sample covariance
1714− >>> :{
1715− let
1716− winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1717− winFun = covarSamp (#y :*: #x)
1718− in printSQL winFun
1719− :}
1720− covar_samp("y", "x")
1721− -}
1722− covarSamp
1723− :: expr2 (null 'PGfloat8)
1724− -> aggr ('Null 'PGfloat8)
1725−
1726− {- | average of the independent variable (sum(X)/N)
1727− >>> :{
1728− let
1729− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1730− expression = regrAvgX (All (#y :*: #x))
1731− in printSQL expression
1732− :}
1733− regr_avgx(ALL "y", "x")
1734− -}
1735− regrAvgX
1736− :: expr2 (null 'PGfloat8)
1737− -> aggr ('Null 'PGfloat8)
1738−
1739− {- | average of the dependent variable (sum(Y)/N)
1740− >>> :{
1741− let
1742− winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1743− winFun = regrAvgY (#y :*: #x)
1744− in printSQL winFun
1745− :}
1746− regr_avgy("y", "x")
1747− -}
1748− regrAvgY
1749− :: expr2 (null 'PGfloat8)
1750− -> aggr ('Null 'PGfloat8)
1751−
1752− {- | number of input rows in which both expressions are nonnull
1753− >>> :{
1754− let
1755− winFun :: WindowFunction '[] 'Ungrouped c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGint8)
1756− winFun = regrCount (#y :*: #x)
1757− in printSQL winFun
1758− :}
1759− regr_count("y", "x")
1760− -}
1761− regrCount
1762− :: expr2 (null 'PGfloat8)
1763− -> aggr ('Null 'PGint8)
1764−
1765− {- | y-intercept of the least-squares-fit linear equation determined by the (X, Y) pairs
1766− >>> :{
1767− let
1768− expression :: Expression '[] ('Grouped g) c s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1769− expression = regrIntercept (All (#y :*: #x))
1770− in printSQL expression
1771− :}
1772− regr_intercept(ALL "y", "x")
1773− -}
1774− regrIntercept
1775− :: expr2 (null 'PGfloat8)
1776− -> aggr ('Null 'PGfloat8)
1777−
1778− -- | @regr_r2(Y, X)@, square of the correlation coefficient
1779− regrR2
1780− :: expr2 (null 'PGfloat8)
1781− -> aggr ('Null 'PGfloat8)
1782−
1783− -- | @regr_slope(Y, X)@, slope of the least-squares-fit linear equation
1784− -- determined by the (X, Y) pairs
1785− regrSlope
1786− :: expr2 (null 'PGfloat8)
1787− -> aggr ('Null 'PGfloat8)
1788−
1789− -- | @regr_sxx(Y, X)@, sum(X^2) - sum(X)^2/N
1790− -- (“sum of squares” of the independent variable)
1791− regrSxx
1792− :: expr2 (null 'PGfloat8)
1793− -> aggr ('Null 'PGfloat8)
1794−
1795− -- | @regr_sxy(Y, X)@, sum(X*Y) - sum(X) * sum(Y)/N
1796− -- (“sum of products” of independent times dependent variable)
1797− regrSxy
1798− :: expr2 (null 'PGfloat8)
1799− -> aggr ('Null 'PGfloat8)
1800−
1801− -- | @regr_syy(Y, X)@, sum(Y^2) - sum(Y)^2/N
1802− -- (“sum of squares” of the dependent variable)
1803− regrSyy
1804− :: expr2 (null 'PGfloat8)
1805− -> aggr ('Null 'PGfloat8)
1806−
1807− -- | historical alias for `stddevSamp`
1808− stddev
1809− :: expr1 (null ty)
1810− -> aggr ('Null (PGAvg ty))
1811−
1812− -- | population standard deviation of the input values
1813− stddevPop
1814− :: expr1 (null ty)
1815− -> aggr ('Null (PGAvg ty))
1816−
1817− -- | sample standard deviation of the input values
1818− stddevSamp
1819− :: expr1 (null ty)
1820− -> aggr ('Null (PGAvg ty))
1821−
1822− -- | historical alias for `varSamp`
1823− variance
1824− :: expr1 (null ty)
1825− -> aggr ('Null (PGAvg ty))
1826−
1827− -- | population variance of the input values
1828− -- (square of the population standard deviation)
1829− varPop
1830− :: expr1 (null ty)
1831− -> aggr ('Null (PGAvg ty))
1832−
1833− -- | sample variance of the input values
1834− -- (square of the sample standard deviation)
1835− varSamp
1836− :: expr1 (null ty)
1837− -> aggr ('Null (PGAvg ty))
1838−
1839−{- |
1840−`Distinction`s are used for the input of `Aggregate` `Expression`s.
1841−`All` invokes the aggregate once for each input row.
1842−`Distinct` invokes the aggregate once for each distinct value of the expression
1843−(or distinct set of values, for multiple expressions) found in the input
1844−-}
1845−data Distinction expr ty
1846− = All (expr ty)
1847− | Distinct (expr ty)
1848− deriving (GHC.Generic,Show,Eq,Ord)
1849−instance NFData (Distinction (Expression outer grp commons schemas params from) ty)
1850−instance RenderSQL (Distinction (Expression outer grp commons schemas params from) ty) where
1851− renderSQL = \case
1852− All x -> "ALL" <+> renderSQL x
1853− Distinct x -> "DISTINCT" <+> renderSQL x
1854−instance RenderSQL
1855− (Distinction
1856− ( Expression outer grp commons schemas params from
1857− :*:
1858− Expression outer grp commons schemas params from) xty ) where
1859− renderSQL = \case
1860− All (x :*: x') ->
1861− "ALL" <+> renderSQL x <> ", " <> renderSQL x'
1862− Distinct (x :*: x') ->
1863− "DISTINCT" <+> renderSQL x <> ", " <> renderSQL x'
1864−
1865−instance Aggregate
1866− (Distinction (Expression outer 'Ungrouped commons schemas params from))
1867− (Distinction (Expression outer 'Ungrouped commons schemas params from :*: Expression outer 'Ungrouped commons schemas params from))
1868− (Expression outer ('Grouped bys) commons schemas params from) where
1869− countStar = UnsafeExpression "count(*)"
1870− count = unsafeAggregate1 "count"
1871− sum_ = unsafeAggregate1 "sum"
1872− arrayAgg = unsafeAggregate1 "array_agg"
1873− jsonAgg = unsafeAggregate1 "json_agg"
1874− jsonbAgg = unsafeAggregate1 "jsonb_agg"
1875− bitAnd = unsafeAggregate1 "bit_and"
1876− bitOr = unsafeAggregate1 "bit_or"
1877− boolAnd = unsafeAggregate1 "bool_and"
1878− boolOr = unsafeAggregate1 "bool_or"
1879− every = unsafeAggregate1 "every"
1880− max_ = unsafeAggregate1 "max"
1881− min_ = unsafeAggregate1 "min"
1882− avg = unsafeAggregate1 "avg"
1883− corr = unsafeAggregate2 "corr"
1884− covarPop = unsafeAggregate2 "covar_pop"
1885− covarSamp = unsafeAggregate2 "covar_samp"
1886− regrAvgX = unsafeAggregate2 "regr_avgx"
1887− regrAvgY = unsafeAggregate2 "regr_avgy"
1888− regrCount = unsafeAggregate2 "regr_count"
1889− regrIntercept = unsafeAggregate2 "regr_intercept"
1890− regrR2 = unsafeAggregate2 "regr_r2"
1891− regrSlope = unsafeAggregate2 "regr_slope"
1892− regrSxx = unsafeAggregate2 "regr_sxx"
1893− regrSxy = unsafeAggregate2 "regr_sxy"
1894− regrSyy = unsafeAggregate2 "regr_syy"
1895− stddev = unsafeAggregate1 "stddev"
1896− stddevPop = unsafeAggregate1 "stddev_pop"
1897− stddevSamp = unsafeAggregate1 "stddev_samp"
1898− variance = unsafeAggregate1 "variance"
1899− varPop = unsafeAggregate1 "var_pop"
1900− varSamp = unsafeAggregate1 "var_samp"
1901−instance Aggregate
1902− (Expression outer grp commons schemas params from)
1903− (Expression outer grp commons schemas params from :*: Expression outer grp commons schemas params from)
1904− (WindowFunction outer grp commons schemas params from) where
1905− countStar = UnsafeWindowFunction "count(*)"
1906− count = unsafeWindowFunction1 "count"
1907− sum_ = unsafeWindowFunction1 "sum"
1908− arrayAgg = unsafeWindowFunction1 "array_agg"
1909− jsonAgg = unsafeWindowFunction1 "json_agg"
1910− jsonbAgg = unsafeWindowFunction1 "jsonb_agg"
1911− bitAnd = unsafeWindowFunction1 "bit_and"
1912− bitOr = unsafeWindowFunction1 "bit_or"
1913− boolAnd = unsafeWindowFunction1 "bool_and"
1914− boolOr = unsafeWindowFunction1 "bool_or"
1915− every = unsafeWindowFunction1 "every"
1916− max_ = unsafeWindowFunction1 "max"
1917− min_ = unsafeWindowFunction1 "min"
1918− avg = unsafeWindowFunction1 "avg"
1919− corr = unsafeWindowFunction2 "corr"
1920− covarPop = unsafeWindowFunction2 "covar_pop"
1921− covarSamp = unsafeWindowFunction2 "covar_samp"
1922− regrAvgX = unsafeWindowFunction2 "regr_avgx"
1923− regrAvgY = unsafeWindowFunction2 "regr_avgy"
1924− regrCount = unsafeWindowFunction2 "regr_count"
1925− regrIntercept = unsafeWindowFunction2 "regr_intercept"
1926− regrR2 = unsafeWindowFunction2 "regr_r2"
1927− regrSlope = unsafeWindowFunction2 "regr_slope"
1928− regrSxx = unsafeWindowFunction2 "regr_sxx"
1929− regrSxy = unsafeWindowFunction2 "regr_sxy"
1930− regrSyy = unsafeWindowFunction2 "regr_syy"
1931− stddev = unsafeWindowFunction1 "stddev"
1932− stddevPop = unsafeWindowFunction1 "stddev_pop"
1933− stddevSamp = unsafeWindowFunction1 "stddev_samp"
1934− variance = unsafeWindowFunction1 "variance"
1935− varPop = unsafeWindowFunction1 "var_pop"
1936− varSamp = unsafeWindowFunction1 "var_samp"
1937−
1938−-- | escape hatch to define aggregate functions
1939−unsafeAggregate1
1940− :: ByteString -- ^ aggregate function
1941− -> Distinction (Expression outer 'Ungrouped commons schemas params from) xty
1942− -> Expression outer ('Grouped bys) commons schemas params from yty
1943−unsafeAggregate1 fun x = UnsafeExpression $ mconcat
1944− [fun, "(", renderSQL x, ")"]
1945−
1946−-- | escape hatch to define aggregate binary functions
1947−unsafeAggregate2
1948− :: ByteString -- ^ aggregate function
1949− -> Distinction (Expression outer 'Ungrouped commons schemas params from :*: Expression outer 'Ungrouped commons schemas params from) xty
1950− -> Expression outer ('Grouped bys) commons schemas params from yty
1951−unsafeAggregate2 fun xx = UnsafeExpression $ mconcat
1952− [fun, "(", renderSQL xx, ")"]
1953−
1954−-- | A type family that calculates `PGAvg` type of a `PGType`.
1955−type family PGAvg ty where
1956− PGAvg 'PGint2 = 'PGnumeric
1957− PGAvg 'PGint4 = 'PGnumeric
1958− PGAvg 'PGint8 = 'PGnumeric
1959− PGAvg 'PGnumeric = 'PGnumeric
1960− PGAvg 'PGfloat4 = 'PGfloat8
1961− PGAvg 'PGfloat8 = 'PGfloat8
1962− PGAvg 'PGinterval = 'PGinterval
1963− PGAvg pg = TypeError
1964− ('Text "Squeal type error: No average for " ':<>: 'ShowType pg)
1965−
1966−{-----------------------------------------
1967−type expressions
1968−-----------------------------------------}
1969−
1970−-- | `TypeExpression`s are used in `cast`s and
1971−-- `Squeal.PostgreSQL.Definition.createTable` commands.
1972−newtype TypeExpression (schemas :: SchemasType) (ty :: NullityType)
1973− = UnsafeTypeExpression { renderTypeExpression :: ByteString }
1974− deriving (GHC.Generic,Show,Eq,Ord,NFData)
1975−instance RenderSQL (TypeExpression schemas ty) where
1976− renderSQL = renderTypeExpression
1977−
1978−-- | The enum or composite type in a `Typedef` can be expressed by its alias.
1979−typedef
1980− :: (Has sch schemas schema, Has td schema ('Typedef ty))
1981− => QualifiedAlias sch td
1982− -> TypeExpression schemas (null ty)
1983−typedef = UnsafeTypeExpression . renderSQL
1984−
1985−-- | The composite type corresponding to a `Table` definition can be expressed
1986−-- by its alias.
1987−typetable
1988− :: (Has sch schemas schema, Has tab schema ('Table table))
1989− => QualifiedAlias sch tab
1990− -> TypeExpression schemas (null ('PGcomposite (TableToRow table)))
1991−typetable = UnsafeTypeExpression . renderSQL
1992−
1993−-- | The composite type corresponding to a `View` definition can be expressed
1994−-- by its alias.
1995−typeview
1996− :: (Has sch schemas schema, Has vw schema ('View view))
1997− => QualifiedAlias sch vw
1998− -> TypeExpression schemas (null ('PGcomposite view))
1999−typeview = UnsafeTypeExpression . renderSQL
2000−
2001−-- | logical Boolean (true/false)
2002−bool :: TypeExpression schemas (null 'PGbool)
2003−bool = UnsafeTypeExpression "bool"
2004−-- | signed two-byte integer
2005−int2, smallint :: TypeExpression schemas (null 'PGint2)
2006−int2 = UnsafeTypeExpression "int2"
2007−smallint = UnsafeTypeExpression "smallint"
2008−-- | signed four-byte integer
2009−int4, int, integer :: TypeExpression schemas (null 'PGint4)
2010−int4 = UnsafeTypeExpression "int4"
2011−int = UnsafeTypeExpression "int"
2012−integer = UnsafeTypeExpression "integer"
2013−-- | signed eight-byte integer
2014−int8, bigint :: TypeExpression schemas (null 'PGint8)
2015−int8 = UnsafeTypeExpression "int8"
2016−bigint = UnsafeTypeExpression "bigint"
2017−-- | arbitrary precision numeric type
2018−numeric :: TypeExpression schemas (null 'PGnumeric)
2019−numeric = UnsafeTypeExpression "numeric"
2020−-- | single precision floating-point number (4 bytes)
2021−float4, real :: TypeExpression schemas (null 'PGfloat4)
2022−float4 = UnsafeTypeExpression "float4"
2023−real = UnsafeTypeExpression "real"
2024−-- | double precision floating-point number (8 bytes)
2025−float8, doublePrecision :: TypeExpression schemas (null 'PGfloat8)
2026−float8 = UnsafeTypeExpression "float8"
2027−doublePrecision = UnsafeTypeExpression "double precision"
2028−-- | currency amount
2029−money :: TypeExpression schema (null 'PGmoney)
2030−money = UnsafeTypeExpression "money"
2031−-- | variable-length character string
2032−text :: TypeExpression schemas (null 'PGtext)
2033−text = UnsafeTypeExpression "text"
2034−-- | fixed-length character string
2035−char, character
2036− :: forall n schemas null. (KnownNat n, 1 <= n)
2037− => TypeExpression schemas (null ('PGchar n))
2038−char = UnsafeTypeExpression $ "char(" <> renderNat @n <> ")"
2039−character = UnsafeTypeExpression $ "character(" <> renderNat @n <> ")"
2040−-- | variable-length character string
2041−varchar, characterVarying
2042− :: forall n schemas null. (KnownNat n, 1 <= n)
2043− => TypeExpression schemas (null ('PGvarchar n))
2044−varchar = UnsafeTypeExpression $ "varchar(" <> renderNat @n <> ")"
2045−characterVarying = UnsafeTypeExpression $
2046− "character varying(" <> renderNat @n <> ")"
2047−-- | binary data ("byte array")
2048−bytea :: TypeExpression schemas (null 'PGbytea)
2049−bytea = UnsafeTypeExpression "bytea"
2050−-- | date and time (no time zone)
2051−timestamp :: TypeExpression schemas (null 'PGtimestamp)
2052−timestamp = UnsafeTypeExpression "timestamp"
2053−-- | date and time, including time zone
2054−timestampWithTimeZone :: TypeExpression schemas (null 'PGtimestamptz)
2055−timestampWithTimeZone = UnsafeTypeExpression "timestamp with time zone"
2056−-- | calendar date (year, month, day)
2057−date :: TypeExpression schemas (null 'PGdate)
2058−date = UnsafeTypeExpression "date"
2059−-- | time of day (no time zone)
2060−time :: TypeExpression schemas (null 'PGtime)
2061−time = UnsafeTypeExpression "time"
2062−-- | time of day, including time zone
2063−timeWithTimeZone :: TypeExpression schemas (null 'PGtimetz)
2064−timeWithTimeZone = UnsafeTypeExpression "time with time zone"
2065−-- | time span
2066−interval :: TypeExpression schemas (null 'PGinterval)
2067−interval = UnsafeTypeExpression "interval"
2068−-- | universally unique identifier
2069−uuid :: TypeExpression schemas (null 'PGuuid)
2070−uuid = UnsafeTypeExpression "uuid"
2071−-- | IPv4 or IPv6 host address
2072−inet :: TypeExpression schemas (null 'PGinet)
2073−inet = UnsafeTypeExpression "inet"
2074−-- | textual JSON data
2075−json :: TypeExpression schemas (null 'PGjson)
2076−json = UnsafeTypeExpression "json"
2077−-- | binary JSON data, decomposed
2078−jsonb :: TypeExpression schemas (null 'PGjsonb)
2079−jsonb = UnsafeTypeExpression "jsonb"
2080−-- | variable length array
2081−vararray
2082− :: TypeExpression schemas pg
2083− -> TypeExpression schemas (null ('PGvararray pg))
2084−vararray ty = UnsafeTypeExpression $ renderSQL ty <> "[]"
2085−-- | fixed length array
2086−--
2087−-- >>> renderSQL (fixarray @'[2] json)
2088−-- "json[2]"
2089−fixarray
2090− :: forall dims schemas null pg. SOP.All KnownNat dims
2091− => TypeExpression schemas pg
2092− -> TypeExpression schemas (null ('PGfixarray dims pg))
2093−fixarray ty = UnsafeTypeExpression $
2094− renderSQL ty <> renderDims @dims
2095− where
2096− renderDims :: forall ns. SOP.All KnownNat ns => ByteString
2097− renderDims =
2098− ("[" <>)
2099− . (<> "]")
2100− . ByteString.intercalate "]["
2101− . hcollapse
2102− $ hcmap (SOP.Proxy @KnownNat)
2103− (K . fromString . show . natVal)
2104− (hpure SOP.Proxy :: NP SOP.Proxy ns)
2105−tsvector :: TypeExpression schemas (null 'PGtsvector)
2106−tsvector = UnsafeTypeExpression "tsvector"
2107−tsquery :: TypeExpression schemas (null 'PGtsquery)
2108−tsquery = UnsafeTypeExpression "tsquery"
2109−
2110−-- | `pgtype` is a demoted version of a `PGType`
2111−class PGTyped schemas (ty :: NullityType) where
2112− pgtype :: TypeExpression schemas ty
2113−instance PGTyped schemas (null 'PGbool) where pgtype = bool
2114−instance PGTyped schemas (null 'PGint2) where pgtype = int2
2115−instance PGTyped schemas (null 'PGint4) where pgtype = int4
2116−instance PGTyped schemas (null 'PGint8) where pgtype = int8
2117−instance PGTyped schemas (null 'PGnumeric) where pgtype = numeric
2118−instance PGTyped schemas (null 'PGfloat4) where pgtype = float4
2119−instance PGTyped schemas (null 'PGfloat8) where pgtype = float8
2120−instance PGTyped schemas (null 'PGmoney) where pgtype = money
2121−instance PGTyped schemas (null 'PGtext) where pgtype = text
2122−instance (KnownNat n, 1 <= n)
2123− => PGTyped schemas (null ('PGchar n)) where pgtype = char @n
2124−instance (KnownNat n, 1 <= n)
2125− => PGTyped schemas (null ('PGvarchar n)) where pgtype = varchar @n
2126−instance PGTyped schemas (null 'PGbytea) where pgtype = bytea
2127−instance PGTyped schemas (null 'PGtimestamp) where pgtype = timestamp
2128−instance PGTyped schemas (null 'PGtimestamptz) where pgtype = timestampWithTimeZone
2129−instance PGTyped schemas (null 'PGdate) where pgtype = date
2130−instance PGTyped schemas (null 'PGtime) where pgtype = time
2131−instance PGTyped schemas (null 'PGtimetz) where pgtype = timeWithTimeZone
2132−instance PGTyped schemas (null 'PGinterval) where pgtype = interval
2133−instance PGTyped schemas (null 'PGuuid) where pgtype = uuid
2134−instance PGTyped schemas (null 'PGjson) where pgtype = json
2135−instance PGTyped schemas (null 'PGjsonb) where pgtype = jsonb
2136−instance PGTyped schemas ty
2137− => PGTyped schemas (null ('PGvararray ty)) where
2138− pgtype = vararray (pgtype @schemas @ty)
2139−instance (SOP.All KnownNat dims, PGTyped schemas ty)
2140− => PGTyped schemas (null ('PGfixarray dims ty)) where
2141− pgtype = fixarray @dims (pgtype @schemas @ty)
2142−instance PGTyped schemas (null 'PGtsvector) where pgtype = tsvector
2143−instance PGTyped schemas (null 'PGtsquery) where pgtype = tsquery
2144−
2145−{-----------------------------------------
2146−Sorting
2147−-----------------------------------------}
2148−
2149−-- | `SortExpression`s are used by `orderBy` to optionally sort the results
2150−-- of a `Squeal.PostgreSQL.Query.Query`. `Asc` or `Desc`
2151−-- set the sort direction of a `NotNull` result
2152−-- column to ascending or descending. Ascending order puts smaller values
2153−-- first, where "smaller" is defined in terms of the `.<` operator. Similarly,
2154−-- descending order is determined with the `.>` operator. `AscNullsFirst`,
2155−-- `AscNullsLast`, `DescNullsFirst` and `DescNullsLast` options are used to
2156−-- determine whether nulls appear before or after non-null values in the sort
2157−-- ordering of a `Null` result column.
2158−data SortExpression outer grp commons schemas params from where
2159− Asc
2160− :: Expression outer grp commons schemas params from ('NotNull ty)
2161− -> SortExpression outer grp commons schemas params from
2162− Desc
2163− :: Expression outer grp commons schemas params from ('NotNull ty)
2164− -> SortExpression outer grp commons schemas params from
2165− AscNullsFirst
2166− :: Expression outer grp commons schemas params from ('Null ty)
2167− -> SortExpression outer grp commons schemas params from
2168− AscNullsLast
2169− :: Expression outer grp commons schemas params from ('Null ty)
2170− -> SortExpression outer grp commons schemas params from
2171− DescNullsFirst
2172− :: Expression outer grp commons schemas params from ('Null ty)
2173− -> SortExpression outer grp commons schemas params from
2174− DescNullsLast
2175− :: Expression outer grp commons schemas params from ('Null ty)
2176− -> SortExpression outer grp commons schemas params from
2177−deriving instance Show (SortExpression outer grp commons schemas params from)
2178−
2179−{- |
2180−The `orderBy` clause causes the result rows of a `Squeal.PostgreSQL.Query.TableExpression`
2181−to be sorted according to the specified `SortExpression`(s).
2182−If two rows are equal according to the leftmost expression,
2183−they are compared according to the next expression and so on.
2184−If they are equal according to all specified expressions,
2185−they are returned in an implementation-dependent order.
2186−
2187−You can also control the order in which rows are processed by window functions
2188−using `orderBy` within `Squeal.PostgreSQL.Query.Over`.
2189−-}
2190−class OrderBy expr where
2191− orderBy
2192− :: [SortExpression outer grp commons schemas params from]
2193− -> expr outer grp commons schemas params from
2194− -> expr outer grp commons schemas params from
2195−
2196−-- | Render a `SortExpression`.
2197−instance RenderSQL (SortExpression outer grp commons schemas params from) where
2198− renderSQL = \case
2199− Asc expression -> renderSQL expression <+> "ASC"
2200− Desc expression -> renderSQL expression <+> "DESC"
2201− AscNullsFirst expression -> renderSQL expression
2202− <+> "ASC NULLS FIRST"
2203− DescNullsFirst expression -> renderSQL expression
2204− <+> "DESC NULLS FIRST"
2205− AscNullsLast expression -> renderSQL expression <+> "ASC NULLS LAST"
2206− DescNullsLast expression -> renderSQL expression <+> "DESC NULLS LAST"
2207−
2208−-- | A `WindowDefinition` is a set of table rows that are somehow related
2209−-- to the current row
2210−data WindowDefinition outer grp commons schemas params from where
2211− WindowDefinition
2212− :: SListI bys
2213− => NP (Expression outer grp commons schemas params from) bys
2214− -> [SortExpression outer grp commons schemas params from]
2215− -> WindowDefinition outer grp commons schemas params from
2216−
2217−instance OrderBy WindowDefinition where
2218− orderBy sortsR (WindowDefinition parts sortsL)
2219− = WindowDefinition parts (sortsL ++ sortsR)
2220−
2221−instance RenderSQL (WindowDefinition outer commons schemas from grp params) where
2222− renderSQL (WindowDefinition part ord) =
2223− renderPartitionByClause part <> renderOrderByClause ord
2224− where
2225− renderPartitionByClause = \case
2226− Nil -> ""
2227− parts -> "PARTITION" <+> "BY" <+> renderCommaSeparated renderExpression parts
2228− renderOrderByClause = \case
2229− [] -> ""
2230− srts -> " ORDER" <+> "BY"
2231− <+> commaSeparated (renderSQL <$> srts)
2232−
2233−{- |
2234−The `partitionBy` clause within `Squeal.PostgreSQL.Query.Over` divides the rows into groups,
2235−or partitions, that share the same values of the `partitionBy` `Expression`(s).
2236−For each row, the window function is computed across the rows that fall into
2237−the same partition as the current row.
2238−-}
2239−partitionBy
2240− :: SListI bys
2241− => NP (Expression outer grp commons schemas params from) bys
2242− -> WindowDefinition outer grp commons schemas params from
2243−partitionBy bys = WindowDefinition bys []
2244−
2245−{- |
2246−A window function performs a calculation across a set of table rows
2247−that are somehow related to the current row. This is comparable to the type
2248−of calculation that can be done with an aggregate function.
2249−However, window functions do not cause rows to become grouped into a single
2250−output row like non-window aggregate calls would.
2251−Instead, the rows retain their separate identities.
2252−Behind the scenes, the window function is able to access more than
2253−just the current row of the query result.
2254−-}
2255−newtype WindowFunction
2256− (outer :: FromType)
2257− (grp :: Grouping)
2258− (commons :: FromType)
2259− (schemas :: SchemasType)
2260− (params :: [NullityType])
2261− (from :: FromType)
2262− (ty :: NullityType)
2263− = UnsafeWindowFunction { renderWindowFunction :: ByteString }
2264− deriving (GHC.Generic,Show,Eq,Ord,NFData)
2265−
2266−instance RenderSQL (WindowFunction outer grp commons schemas params from ty) where
2267− renderSQL = renderWindowFunction
2268−
2269−unsafeWindowFunction1
2270− :: ByteString
2271− -> Expression outer grp commons schemas params from ty0
2272− -> WindowFunction outer grp commons schemas params from ty1
2273−unsafeWindowFunction1 fun x
2274− = UnsafeWindowFunction $ fun <> parenthesized (renderSQL x)
2275−
2276−unsafeWindowFunction2
2277− :: ByteString
2278− -> (Expression outer grp commons schemas params from :*: Expression outer grp commons schemas params from) ty0
2279− -> WindowFunction outer grp commons schemas params from ty1
2280−unsafeWindowFunction2 fun (x :*: x')
2281− = UnsafeWindowFunction $ fun <> parenthesized (renderSQL x <> ", " <> renderSQL x')
2282−
2283−{- | rank of the current row with gaps; same as `rowNumber` of its first peer
2284−>>> printSQL rank
2285−rank()
2286−-}
2287−rank :: WindowFunction outer grp commons schemas params from ('NotNull 'PGint8)
2288−rank = UnsafeWindowFunction "rank()"
2289−
2290−{- | number of the current row within its partition, counting from 1
2291−>>> printSQL rowNumber
2292−row_number()
2293−-}
2294−rowNumber :: WindowFunction outer grp commons schemas params from ('NotNull 'PGint8)
2295−rowNumber = UnsafeWindowFunction "row_number()"
2296−
2297−{- | rank of the current row without gaps; this function counts peer groups
2298−>>> printSQL denseRank
2299−dense_rank()
2300−-}
2301−denseRank :: WindowFunction outer grp commons schemas params from ('NotNull 'PGint8)
2302−denseRank = UnsafeWindowFunction "dense_rank()"
2303−
2304−{- | relative rank of the current row: (rank - 1) / (total partition rows - 1)
2305−>>> printSQL percentRank
2306−percent_rank()
2307−-}
2308−percentRank :: WindowFunction outer grp commons schemas params from ('NotNull 'PGfloat8)
2309−percentRank = UnsafeWindowFunction "percent_rank()"
2310−
2311−{- | cumulative distribution: (number of partition rows
2312−preceding or peer with current row) / total partition rows
2313−>>> printSQL cumeDist
2314−cume_dist()
2315−-}
2316−cumeDist :: WindowFunction outer grp commons schemas params from ('NotNull 'PGfloat8)
2317−cumeDist = UnsafeWindowFunction "cume_dist()"
2318−
2319−{- | integer ranging from 1 to the argument value,
2320−dividing the partition as equally as possible
2321−-}
2322−ntile
2323− :: Expression outer grp commons schemas params from ('NotNull 'PGint4)
2324− -- ^ num buckets
2325− -> WindowFunction outer grp commons schemas params from ('NotNull 'PGint4)
2326−ntile = unsafeWindowFunction1 "ntile"
2327−
2328−{- | returns value evaluated at the row that is offset rows before the current
2329−row within the partition; if there is no such row, instead return default
2330−(which must be of the same type as value). Both offset and default are
2331−evaluated with respect to the current row.
2332−-}
2333−lag
2334− :: Expression outer grp commons schemas params from ty
2335− -- ^ value
2336− -> Expression outer grp commons schemas params from ('NotNull 'PGint4)
2337− -- ^ offset
2338− -> Expression outer grp commons schemas params from ty
2339− -- ^ default
2340− -> WindowFunction outer grp commons schemas params from ty
2341−lag value offset def = UnsafeWindowFunction $ "lag"
2342− <> parenthesized
2343− (commaSeparated ([renderSQL value, renderSQL offset, renderSQL def]))
2344−
2345−{- | returns value evaluated at the row that is offset rows after the current
2346−row within the partition; if there is no such row, instead return default
2347−(which must be of the same type as value). Both offset and default are
2348−evaluated with respect to the current row.
2349−-}
2350−lead
2351− :: Expression outer grp commons schemas params from ty
2352− -- ^ value
2353− -> Expression outer grp commons schemas params from ('NotNull 'PGint4)
2354− -- ^ offset
2355− -> Expression outer grp commons schemas params from ty
2356− -- ^ default
2357− -> WindowFunction outer grp commons schemas params from ty
2358−lead value offset def = UnsafeWindowFunction $ "lag"
2359− <> parenthesized
2360− (commaSeparated ([renderSQL value, renderSQL offset, renderSQL def]))
2361−
2362−{- | returns value evaluated at the row that is the
2363−first row of the window frame
2364−-}
2365−firstValue
2366− :: Expression outer grp commons schemas params from ty
2367− -- ^ value
2368− -> WindowFunction outer grp commons schemas params from ty
2369−firstValue = unsafeWindowFunction1 "first_value"
2370−
2371−{- | returns value evaluated at the row that is the
2372−last row of the window frame
2373−-}
2374−lastValue
2375− :: Expression outer grp commons schemas params from ty
2376− -- ^ value
2377− -> WindowFunction outer grp commons schemas params from ty
2378−lastValue = unsafeWindowFunction1 "last_value"
2379−
2380−{- | returns value evaluated at the row that is the nth
2381−row of the window frame (counting from 1); null if no such row
2382−-}
2383−nthValue
2384− :: Expression outer grp commons schemas params from (null ty)
2385− -- ^ value
2386− -> Expression outer grp commons schemas params from ('NotNull 'PGint4)
2387− -- ^ nth
2388− -> WindowFunction outer grp commons schemas params from ('Null ty)
2389−nthValue value nth = UnsafeWindowFunction $ "nth_value"
2390− <> parenthesized (commaSeparated [renderSQL value, renderSQL nth])
2391−
2392−{-|
2393−Create date from year, month and day fields
2394−
2395−>>> printSQL (makeDate (1984 :* 7 *: 3))
2396−make_date(1984, 7, 3)
2397−-}
2398−makeDate :: FunctionHet
2399− '[ null 'PGint4, null 'PGint4, null 'PGint4 ]
2400− ( null 'PGdate )
2401−makeDate = unsafeFunctionHet "make_date"
2402−
2403−{-|
2404−Create time from hour, minute and seconds fields
2405−
2406−>>> printSQL (makeTime (8 :* 15 *: 23.5))
2407−make_time(8, 15, 23.5)
2408−-}
2409−makeTime :: FunctionHet
2410− '[ null 'PGint4, null 'PGint4, null 'PGfloat8 ]
2411− ( null 'PGtime )
2412−makeTime = unsafeFunctionHet "make_time"
2413−
2414−{-|
2415−Create timestamp from year, month, day, hour, minute and seconds fields
2416−
2417−>>> printSQL (makeTimestamp (2013 :* 7 :* 15 :* 8 :* 15 *: 23.5))
2418−make_timestamp(2013, 7, 15, 8, 15, 23.5)
2419−-}
2420−makeTimestamp :: FunctionHet
2421− '[ null 'PGint4, null 'PGint4, null 'PGint4
2422− , null 'PGint4, null 'PGint4, null 'PGfloat8 ]
2423− ( null 'PGtimestamp )
2424−makeTimestamp = unsafeFunctionHet "make_timestamp"
2425−
2426−{-|
2427−Create timestamp with time zone from
2428−year, month, day, hour, minute and seconds fields;
2429−the current time zone is used
2430−
2431−>>> printSQL (makeTimestamptz (2013 :* 7 :* 15 :* 8 :* 15 *: 23.5))
2432−make_timestamptz(2013, 7, 15, 8, 15, 23.5)
2433−-}
2434−makeTimestamptz :: FunctionHet
2435− '[ null 'PGint4, null 'PGint4, null 'PGint4
2436− , null 'PGint4, null 'PGint4, null 'PGfloat8 ]
2437− ( null 'PGtimestamptz )
2438−makeTimestamptz = unsafeFunctionHet "make_timestamptz"
2439−
2440−{-|
2441−Affine space operations on time types.
2442−-}
2443−class TimeOp time diff | time -> diff where
2444− {-|
2445− >>> printSQL (makeDate (1984 :* 7 *: 3) !+ 365)
2446− (make_date(1984, 7, 3) + 365)
2447− -}
2448− (!+) :: Operator (null time) (null diff) (null time)
2449− (!+) = unsafeBinaryOp "+"
2450− {-|
2451− >>> printSQL (365 +! makeDate (1984 :* 7 *: 3))
2452− (365 + make_date(1984, 7, 3))
2453− -}
2454− (+!) :: Operator (null diff) (null time) (null time)
2455− (+!) = unsafeBinaryOp "+"
2456− {-|
2457− >>> printSQL (makeDate (1984 :* 7 *: 3) !- 365)
2458− (make_date(1984, 7, 3) - 365)
2459− -}
2460− (!-) :: Operator (null time) (null diff) (null time)
2461− (!-) = unsafeBinaryOp "-"
2462− {-|
2463− >>> printSQL (makeDate (1984 :* 7 *: 3) !-! currentDate)
2464− (make_date(1984, 7, 3) - CURRENT_DATE)
2465− -}
2466− (!-!) :: Operator (null time) (null time) (null diff)
2467− (!-!) = unsafeBinaryOp "-"
2468−instance TimeOp 'PGtimestamp 'PGinterval
2469−instance TimeOp 'PGtimestamptz 'PGinterval
2470−instance TimeOp 'PGtime 'PGinterval
2471−instance TimeOp 'PGtimetz 'PGinterval
2472−instance TimeOp 'PGinterval 'PGinterval
2473−instance TimeOp 'PGdate 'PGint4
2474−infixl 6 !+
2475−infixl 6 +!
2476−infixl 6 !-
2477−infixl 6 !-!