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