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