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