@@ -1,14 +1,13 @@
11{-|
2−Module: Squeal.PostgreSQL.Query
2+Module: 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
@@ -16,11 +15,13 @@ Squeal expressions are the atoms used to build statements.
1615 , FlexibleContexts
1716 , FlexibleInstances
1817 , FunctionalDependencies
18+ , GADTs
1919 , GeneralizedNewtypeDeriving
2020 , LambdaCase
2121 , MagicHash
2222 , OverloadedStrings
2323 , ScopedTypeVariables
24+ , StandaloneDeriving
2425 , TypeApplications
2526 , TypeFamilies
2627 , TypeInType
@@ -32,546 +33,350 @@ Squeal expressions are the atoms used to build statements.
3233module Squeal.PostgreSQL.Expression
3334 ( -- * Expression
3435 Expression (..)
35− , HasParameter (parameter)
36− , param
37− -- ** Null
38− , null_
39− , notNull
40− , coalesce
41− , fromNull
42− , isNull
43− , isNotNull
44− , matchNull
45− , nullIf
46− -- ** Collections
47− , array
48− , index
49− , row
50− , field
51− -- ** Functions
52− , unsafeBinaryOp
53− , unsafeUnaryOp
36+ , Expr
37+ , type (-->)
38+ , FunctionDB
5439 , unsafeFunction
55− , unsafeVariadicFunction
56− , atan2_
57− , cast
58− , quot_
59− , rem_
60− , trunc
61− , round_
62− , ceiling_
63− , greatest
64− , least
65− -- ** Conditions
66− , true
67− , false
68− , not_
69− , (.&&)
70− , (.||)
71− , Condition
72− , caseWhenThenElse
73− , ifThenElse
74− , (.==)
75− , (./=)
76− , (.>=)
77− , (.<)
78− , (.<=)
79− , (.>)
80− -- ** Time
81− , currentDate
82− , currentTime
83− , currentTimestamp
84− , localTime
85− , localTimestamp
86− -- ** Text
87− , lower
88− , upper
89− , charLength
90− , like
91− , ilike
92− -- ** Json
93− -- *** Json and Jsonb operators
94− , (.->)
95− , (.->>)
96− , (.#>)
97− , (.#>>)
98− -- *** Jsonb operators
99− , (.@>)
100− , (.<@)
101− , (.?)
102− , (.?|)
103− , (.?&)
104− , (.-.)
105− , (#-.)
106− -- *** Functions
107− , jsonLit
108− , jsonbLit
109− , toJson
110− , toJsonb
111− , arrayToJson
112− , rowToJson
113− , jsonBuildArray
114− , jsonbBuildArray
115− , jsonBuildObject
116− , jsonbBuildObject
117− , jsonObject
118− , jsonbObject
119− , jsonZipObject
120− , jsonbZipObject
121− , jsonArrayLength
122− , jsonbArrayLength
123− , jsonExtractPath
124− , jsonbExtractPath
125− , jsonExtractPathAsText
126− , jsonbExtractPathAsText
127− , jsonTypeof
128− , jsonbTypeof
129− , jsonStripNulls
130− , jsonbStripNulls
131− , jsonbSet
132− , jsonbInsert
133− , jsonbPretty
134− -- ** Aggregation
135− , unsafeAggregate, unsafeAggregateDistinct
136− , sum_, sumDistinct
137− , PGAvg (avg, avgDistinct)
138− , bitAnd, bitOr, boolAnd, boolOr
139− , bitAndDistinct, bitOrDistinct, boolAndDistinct, boolOrDistinct
140− , countStar
141− , count, countDistinct
142− , every, everyDistinct
143− , max_, maxDistinct, min_, minDistinct
144− -- * Types
145− , TypeExpression (..)
146− , PGTyped (..)
147− , typedef
148− , typetable
149− , typeview
150− , bool
151− , int2
152− , smallint
153− , int4
154− , int
155− , integer
156− , int8
157− , bigint
158− , numeric
159− , float4
160− , real
161− , float8
162− , doublePrecision
163− , text
164− , char
165− , character
166− , varchar
167− , characterVarying
168− , bytea
169− , timestamp
170− , timestampWithTimeZone
171− , date
172− , time
173− , timeWithTimeZone
174− , interval
175− , uuid
176− , inet
177− , json
178− , jsonb
179− , vararray
180− , fixarray
40+ , function
41+ , unsafeLeftOp
42+ , leftOp
43+ , unsafeRightOp
44+ , rightOp
45+ , Operator
46+ , OperatorDB
47+ , unsafeBinaryOp
48+ , binaryOp
49+ , FunctionVar
50+ , unsafeFunctionVar
51+ , type (--->)
52+ , FunctionNDB
53+ , unsafeFunctionN
54+ , functionN
55+ , PGSubset (..)
56+ , PGIntersect (..)
18157 -- * Re-export
18258 , (&)
183− , NP ((:*), Nil)
59+ , K (..)
60+ , unK
18461 ) where
18562
18663import Control.Category
18764import Control.DeepSeq
18865import Data.ByteString (ByteString)
189−import Data.ByteString.Lazy (toStrict)
19066import Data.Function ((&))
19167import Data.Semigroup hiding (All)
192−import qualified Data.Aeson as JSON
193−import Data.Ratio
19468import Data.String
195−import Data.Word
196−import Generics.SOP hiding (from)
69+import Generics.SOP hiding (All, from)
19770import GHC.OverloadedLabels
19871import GHC.TypeLits
72+import Numeric
19973import Prelude hiding (id, (.))
20074
20175import qualified GHC.Generics as GHC
20276
77+import Squeal.PostgreSQL.Alias
78+import Squeal.PostgreSQL.List
20379import Squeal.PostgreSQL.Render
20480import Squeal.PostgreSQL.Schema
20581
82+-- $setup
83+-- >>> import Squeal.PostgreSQL
84+
20685{-----------------------------------------
20786column expressions
20887-----------------------------------------}
20988
21089{- | `Expression`s are used in a variety of contexts,
211−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,
21292as new column values in `Squeal.PostgreSQL.Manipulation.insertRow` or
21393`Squeal.PostgreSQL.Manipulation.update`,
214−or in search `Condition`s in a number of commands.
94+or in search `Squeal.PostgreSQL.Logic.Condition`s in a number of commands.
21595
21696The expression syntax allows the calculation of
21797values from primitive expression using arithmetic, logical,
21898and 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`.
219113-}
220114newtype Expression
115+ (outer :: FromType)
221116 (commons :: FromType)
117+ (grp :: Grouping)
222118 (schemas :: SchemasType)
223119 (params :: [NullityType])
224− (grp :: Grouping)
225120 (from :: FromType)
226121 (ty :: NullityType)
227122 = UnsafeExpression { renderExpression :: ByteString }
228123 deriving (GHC.Generic,Show,Eq,Ord,NFData)
229−
230−instance RenderSQL (Expression commons schemas params grp from ty) where
124+instance RenderSQL (Expression outer commons grp schemas params from ty) where
231125 renderSQL = renderExpression
232126
233−{- | A `HasParameter` constraint is used to indicate a value that is
234−supplied externally to a SQL statement.
235−`Squeal.PostgreSQL.PQ.manipulateParams`,
236−`Squeal.PostgreSQL.PQ.queryParams` and
237−`Squeal.PostgreSQL.PQ.traversePrepared` support specifying data values
238−separately from the SQL command string, in which case `param`s are used to
239−refer to the out-of-line data values.
127+-- | An `Expr` is a closed `Expression`.
128+-- It is a F@RankNType@ but don't be scared.
129+-- Think of it as an expression which sees no
130+-- namespaces, so you can't use parameters
131+-- or alias references. It can be used as
132+-- a simple piece of more complex `Expression`s.
133+type Expr x
134+ = forall outer commons grp schemas params from
135+ . Expression outer commons grp schemas params from x
136+ -- ^ cannot reference aliases
137+
138+-- | A @RankNType@ for binary operators.
139+type Operator x1 x2 y
140+ = forall outer commons grp schemas params from
141+ . Expression outer commons grp schemas params from x1
142+ -- ^ left input
143+ -> Expression outer commons grp schemas params from x2
144+ -- ^ right input
145+ -> Expression outer commons grp schemas params from y
146+ -- ^ output
147+
148+type OperatorDB schemas x1 x2 y
149+ = forall outer commons grp params from
150+ . Expression outer commons grp schemas params from x1
151+ -- ^ left input
152+ -> Expression outer commons grp schemas params from x2
153+ -- ^ right input
154+ -> Expression outer commons grp schemas params from y
155+ -- ^ output
156+
157+-- | A @RankNType@ for functions with a single argument.
158+-- These could be either function calls or unary operators.
159+-- This is a subtype of the usual Haskell function type `Prelude.->`,
160+-- indeed a subcategory as it is closed under the usual
161+-- `Prelude..` and `Prelude.id`.
162+type (-->) x y
163+ = forall outer commons grp schemas params from
164+ . Expression outer commons grp schemas params from x
165+ -- ^ input
166+ -> Expression outer commons grp schemas params from y
167+ -- ^ output
168+
169+type FunctionDB schemas x y
170+ = forall outer commons grp params from
171+ . Expression outer commons grp schemas params from x
172+ -- ^ input
173+ -> Expression outer commons grp schemas params from y
174+ -- ^ output
175+
176+{- | A @RankNType@ for functions with a fixed-length list of heterogeneous arguments.
177+Use the `*:` operator to end your argument lists, like so.
178+
179+>>> printSQL (unsafeFunctionN "fun" (true :* false :* localTime *: true))
180+fun(TRUE, FALSE, LOCALTIME, TRUE)
240181-}
241−class KnownNat n => HasParameter
242− (n :: Nat)
243− (params :: [NullityType])
244− (ty :: NullityType)
245− | n params -> ty where
246− -- | `parameter` takes a `Nat` using type application and a `TypeExpression`.
247− --
248− -- >>> let expr = parameter @1 int4 :: Expression '[] schemas '[ 'Null 'PGint4] grp from ('Null 'PGint4)
249− -- >>> printSQL expr
250− -- ($1 :: int4)
251− parameter
252− :: TypeExpression schemas ty
253− -> Expression commons schemas params grp from ty
254− parameter ty = UnsafeExpression $ parenthesized $
255− "$" <> renderNat @n <+> "::"
256− <+> renderSQL ty
257−instance {-# OVERLAPPING #-} HasParameter 1 (ty1:tys) ty1
258−instance {-# OVERLAPPABLE #-} (KnownNat n, HasParameter (n-1) params ty)
259− => HasParameter n (ty' : params) ty
260−
261−-- | `param` takes a `Nat` using type application and for basic types,
262−-- infers a `TypeExpression`.
263−--
264−-- >>> let expr = param @1 :: Expression commons schemas '[ 'Null 'PGint4] grp from ('Null 'PGint4)
265−-- >>> printSQL expr
266−-- ($1 :: int4)
267−param
268− :: forall n commons schemas params from grp ty
269− . (PGTyped schemas ty, HasParameter n params ty)
270− => Expression commons schemas params grp from ty -- ^ param
271−param = parameter @n (pgtype @schemas)
182+type (--->) xs y
183+ = forall outer commons grp schemas params from
184+ . NP (Expression outer commons grp schemas params from) xs
185+ -- ^ inputs
186+ -> Expression outer commons grp schemas params from y
187+ -- ^ output
188+
189+type FunctionNDB schemas xs y
190+ = forall outer commons grp params from
191+ . NP (Expression outer commons grp schemas params from) xs
192+ -- ^ inputs
193+ -> Expression outer commons grp schemas params from y
194+ -- ^ output
195+
196+{- | A @RankNType@ for functions with a variable-length list of
197+homogeneous arguments and at least 1 more argument.
198+-}
199+type FunctionVar x0 x1 y
200+ = forall outer commons grp schemas params from
201+ . [Expression outer commons grp schemas params from x0]
202+ -- ^ inputs
203+ -> Expression outer commons grp schemas params from x1
204+ -- ^ must have at least 1 input
205+ -> Expression outer commons grp schemas params from y
206+ -- ^ output
207+
208+{- | >>> printSQL (unsafeFunctionVar "greatest" [true, null_] false)
209+greatest(TRUE, NULL, FALSE)
210+-}
211+unsafeFunctionVar :: ByteString -> FunctionVar x0 x1 y
212+unsafeFunctionVar fun xs x = UnsafeExpression $ fun <> parenthesized
213+ (commaSeparated (renderSQL <$> xs) <> ", " <> renderSQL x)
272214
273−instance (HasUnique tab from row, Has col row ty)
274− => IsLabel col (Expression commons schemas params 'Ungrouped from ty) where
215+instance (HasUnique tab (Join outer from) row, Has col row ty)
216+ => IsLabel col (Expression outer commons 'Ungrouped schemas params from ty) where
275217 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
276−instance (HasUnique tab from row, Has col row ty, column ~ (col ::: ty))
218+instance (HasUnique tab (Join outer from) row, Has col row ty, tys ~ '[ty])
219+ => IsLabel col (NP (Expression outer commons 'Ungrouped schemas params from) tys) where
220+ fromLabel = fromLabel @col :* Nil
221+instance (HasUnique tab (Join outer from) row, Has col row ty, column ~ (col ::: ty))
277222 => IsLabel col
278− (Aliased (Expression commons schemas params 'Ungrouped from) column) where
223+ (Aliased (Expression outer commons 'Ungrouped schemas params from) column) where
279224 fromLabel = fromLabel @col `As` Alias
280−instance (HasUnique tab from row, Has col row ty, columns ~ '[col ::: ty])
225+instance (HasUnique tab (Join outer from) row, Has col row ty, columns ~ '[col ::: ty])
281226 => IsLabel col
282− (NP (Aliased (Expression commons schemas params 'Ungrouped from)) columns) where
227+ (NP (Aliased (Expression outer commons 'Ungrouped schemas params from)) columns) where
283228 fromLabel = fromLabel @col :* Nil
284229
285−instance (Has tab from row, Has col row ty)
286− => IsQualified tab col (Expression commons schemas params 'Ungrouped from ty) where
230+instance (Has tab (Join outer from) row, Has col row ty)
231+ => IsQualified tab col (Expression outer commons 'Ungrouped schemas params from ty) where
287232 tab ! col = UnsafeExpression $
288233 renderSQL tab <> "." <> renderSQL col
289−instance (Has tab from row, Has col row ty, column ~ (col ::: ty))
234+instance (Has tab (Join outer from) row, Has col row ty, tys ~ '[ty])
235+ => IsQualified tab col (NP (Expression outer commons 'Ungrouped schemas params from) tys) where
236+ tab ! col = tab ! col :* Nil
237+instance (Has tab (Join outer from) row, Has col row ty, column ~ (col ::: ty))
290238 => IsQualified tab col
291− (Aliased (Expression commons schemas params 'Ungrouped from) column) where
239+ (Aliased (Expression outer commons 'Ungrouped schemas params from) column) where
292240 tab ! col = tab ! col `As` col
293−instance (Has tab from row, Has col row ty, columns ~ '[col ::: ty])
241+instance (Has tab (Join outer from) row, Has col row ty, columns ~ '[col ::: ty])
294242 => IsQualified tab col
295− (NP (Aliased (Expression commons schemas params 'Ungrouped from)) columns) where
243+ (NP (Aliased (Expression outer commons 'Ungrouped schemas params from)) columns) where
296244 tab ! col = tab ! col :* Nil
297245
298246instance
299− ( HasUnique tab from row
247+ ( HasUnique tab (Join outer from) row
300248 , Has col row ty
301249 , GroupedBy tab col bys
302250 ) => IsLabel col
303− (Expression commons schemas params ('Grouped bys) from ty) where
251+ (Expression outer commons ('Grouped bys) schemas params from ty) where
304252 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
305253instance
306− ( HasUnique tab from row
254+ ( HasUnique tab (Join outer from) row
255+ , Has col row ty
256+ , GroupedBy tab col bys
257+ , tys ~ '[ty]
258+ ) => IsLabel col
259+ (NP (Expression outer commons ('Grouped bys) schemas params from) tys) where
260+ fromLabel = fromLabel @col :* Nil
261+instance
262+ ( HasUnique tab (Join outer from) row
307263 , Has col row ty
308264 , GroupedBy tab col bys
309265 , column ~ (col ::: ty)
310266 ) => IsLabel col
311− (Aliased (Expression commons schemas params ('Grouped bys) from) column) where
267+ (Aliased (Expression outer commons ('Grouped bys) schemas params from) column) where
312268 fromLabel = fromLabel @col `As` Alias
313269instance
314− ( HasUnique tab from row
270+ ( HasUnique tab (Join outer from) row
315271 , Has col row ty
316272 , GroupedBy tab col bys
317273 , columns ~ '[col ::: ty]
318274 ) => IsLabel col
319− (NP (Aliased (Expression commons schemas params ('Grouped bys) from)) columns) where
275+ (NP (Aliased (Expression outer commons ('Grouped bys) schemas params from)) columns) where
320276 fromLabel = fromLabel @col :* Nil
321277
322278instance
323− ( Has tab from row
279+ ( Has tab (Join outer from) row
324280 , Has col row ty
325281 , GroupedBy tab col bys
326282 ) => IsQualified tab col
327− (Expression commons schemas params ('Grouped bys) from ty) where
283+ (Expression outer commons ('Grouped bys) schemas params from ty) where
328284 tab ! col = UnsafeExpression $
329285 renderSQL tab <> "." <> renderSQL col
330286instance
331− ( Has tab from row
287+ ( Has tab (Join outer from) row
288+ , Has col row ty
289+ , GroupedBy tab col bys
290+ , tys ~ '[ty]
291+ ) => IsQualified tab col
292+ (NP (Expression outer commons ('Grouped bys) schemas params from) tys) where
293+ tab ! col = tab ! col :* Nil
294+instance
295+ ( Has tab (Join outer from) row
332296 , Has col row ty
333297 , GroupedBy tab col bys
334298 , column ~ (col ::: ty)
335299 ) => IsQualified tab col
336− (Aliased (Expression commons schemas params ('Grouped bys) from) column) where
300+ (Aliased (Expression outer commons ('Grouped bys) schemas params from) column) where
337301 tab ! col = tab ! col `As` col
338302instance
339− ( Has tab from row
303+ ( Has tab (Join outer from) row
340304 , Has col row ty
341305 , GroupedBy tab col bys
342306 , columns ~ '[col ::: ty]
343307 ) => IsQualified tab col
344− (NP (Aliased (Expression commons schemas params ('Grouped bys) from)) columns) where
308+ (NP (Aliased (Expression outer commons ('Grouped bys) schemas params from)) columns) where
345309 tab ! col = tab ! col :* Nil
346310
347−-- | analagous to `Nothing`
348−--
349−-- >>> printSQL null_
350−-- NULL
351−null_ :: Expression commons schemas rels grouping params ('Null ty)
352−null_ = UnsafeExpression "NULL"
353−
354−-- | analagous to `Just`
355−--
356−-- >>> printSQL $ notNull true
357−-- TRUE
358−notNull
359− :: Expression commons schemas rels grouping params ('NotNull ty)
360− -> Expression commons schemas rels grouping params ('Null ty)
361−notNull = UnsafeExpression . renderSQL
362−
363−-- | return the leftmost value which is not NULL
364−--
365−-- >>> printSQL $ coalesce [null_, true] false
366−-- COALESCE(NULL, TRUE, FALSE)
367−coalesce
368− :: [Expression commons schemas params grp from ('Null ty)]
369− -- ^ @NULL@s may be present
370− -> Expression commons schemas params grp from ('NotNull ty)
371− -- ^ @NULL@ is absent
372− -> Expression commons schemas params grp from ('NotNull ty)
373−coalesce nullxs notNullx = UnsafeExpression $
374− "COALESCE" <> parenthesized (commaSeparated
375− ((renderSQL <$> nullxs) <> [renderSQL notNullx]))
376−
377−-- | analagous to `Data.Maybe.fromMaybe` using @COALESCE@
378−--
379−-- >>> printSQL $ fromNull true null_
380−-- COALESCE(NULL, TRUE)
381−fromNull
382− :: Expression commons schemas params grp from ('NotNull ty)
383− -- ^ what to convert @NULL@ to
384− -> Expression commons schemas params grp from ('Null ty)
385− -> Expression commons schemas params grp from ('NotNull ty)
386−fromNull notNullx nullx = coalesce [nullx] notNullx
387−
388−-- | >>> printSQL $ null_ & isNull
389−-- NULL IS NULL
390−isNull
391− :: Expression commons schemas params grp from ('Null ty)
392− -- ^ possibly @NULL@
393− -> Condition commons schemas params grp from
394−isNull x = UnsafeExpression $ renderSQL x <+> "IS NULL"
395−
396−-- | >>> printSQL $ null_ & isNotNull
397−-- NULL IS NOT NULL
398−isNotNull
399− :: Expression commons schemas params grp from ('Null ty)
400− -- ^ possibly @NULL@
401− -> Condition commons schemas params grp from
402−isNotNull x = UnsafeExpression $ renderSQL x <+> "IS NOT NULL"
403−
404−-- | analagous to `maybe` using @IS NULL@
405−--
406−-- >>> printSQL $ matchNull true not_ null_
407−-- CASE WHEN NULL IS NULL THEN TRUE ELSE (NOT NULL) END
408−matchNull
409− :: Expression commons schemas params grp from (nullty)
410− -- ^ what to convert @NULL@ to
411− -> ( Expression commons schemas params grp from ('NotNull ty)
412− -> Expression commons schemas params grp from (nullty) )
413− -- ^ function to perform when @NULL@ is absent
414− -> Expression commons schemas params grp from ('Null ty)
415− -> Expression commons schemas params grp from (nullty)
416−matchNull y f x = ifThenElse (isNull x) y
417− (f (UnsafeExpression (renderSQL x)))
418−
419−{-| right inverse to `fromNull`, if its arguments are equal then
420−`nullIf` gives @NULL@.
421−
422−>>> :set -XTypeApplications -XDataKinds
423−>>> let expr = nullIf false (param @1) :: Expression commons schemas '[ 'NotNull 'PGbool] grp from ('Null 'PGbool)
424−>>> printSQL expr
425−NULL IF (FALSE, ($1 :: bool))
426−-}
427−nullIf
428− :: Expression commons schemas params grp from ('NotNull ty)
429− -- ^ @NULL@ is absent
430− -> Expression commons schemas params grp from ('NotNull ty)
431− -- ^ @NULL@ is absent
432− -> Expression commons schemas params grp from ('Null ty)
433−nullIf x y = UnsafeExpression $ "NULL IF" <+> parenthesized
434− (renderSQL x <> ", " <> renderSQL y)
435−
436−-- | >>> printSQL $ array [null_, false, true]
437−-- ARRAY[NULL, FALSE, TRUE]
438−array
439− :: [Expression commons schemas params grp from ty]
440− -- ^ array elements
441− -> Expression commons schemas params grp from (nullity ('PGvararray ty))
442−array xs = UnsafeExpression $
443− "ARRAY[" <> commaSeparated (renderSQL <$> xs) <> "]"
444−
445−-- | >>> printSQL $ array [null_, false, true] & index 2
446−-- (ARRAY[NULL, FALSE, TRUE])[2]
447−index
448− :: Word64 -- ^ index
449− -> Expression commons schemas params grp from (nullity ('PGvararray ty)) -- ^ array
450− -> Expression commons schemas params grp from (NullifyType ty)
451−index n expr = UnsafeExpression $
452− parenthesized (renderSQL expr) <> "[" <> fromString (show n) <> "]"
453−
454311instance (KnownSymbol label, label `In` labels) => IsPGlabel label
455− (Expression commons schemas params grp from (nullity ('PGenum labels))) where
312+ (Expression outer commons grp schemas params from (null ('PGenum labels))) where
456313 label = UnsafeExpression $ renderSQL (PGlabel @label)
457314
458−-- | A row constructor is an expression that builds a row value
459−-- (also called a composite value) using values for its member fields.
460−--
461−-- >>> :{
462−-- type Complex = 'PGcomposite
463−-- '[ "real" ::: 'NotNull 'PGfloat8
464−-- , "imaginary" ::: 'NotNull 'PGfloat8 ]
465−-- :}
466−--
467−-- >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression commons schemas from grp params ('NotNull Complex)
468−-- >>> printSQL i
469−-- ROW(0, 1)
470−row
471− :: SListI row
472− => NP (Aliased (Expression commons schemas params grp from)) row
473− -- ^ zero or more expressions for the row field values
474− -> Expression commons schemas params grp from (nullity ('PGcomposite row))
475−row exprs = UnsafeExpression $ "ROW" <> parenthesized
476− (renderCommaSeparated (\ (expr `As` _) -> renderSQL expr) exprs)
477−
478−-- | >>> :{
479−-- type Complex = 'PGcomposite
480−-- '[ "real" ::: 'NotNull 'PGfloat8
481−-- , "imaginary" ::: 'NotNull 'PGfloat8 ]
482−-- type Schema = '["complex" ::: 'Typedef Complex]
483−-- :}
484−--
485−-- >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression '[] (Public Schema) from grp params ('NotNull Complex)
486−-- >>> printSQL $ i & field #complex #imaginary
487−-- (ROW(0, 1)::"complex")."imaginary"
488−field
489− :: ( Has sch schemas schema
490− , Has tydef schema ('Typedef ('PGcomposite row))
491− , Has field row ty)
492− => QualifiedAlias sch tydef -- ^ row type
493− -> Alias field -- ^ field name
494− -> Expression commons schemas params grp from ('NotNull ('PGcomposite row))
495− -> Expression commons schemas params grp from ty
496−field td fld expr = UnsafeExpression $
497− parenthesized (renderSQL expr <> "::" <> renderSQL td)
498− <> "." <> renderSQL fld
499−
500−instance Semigroup
501− (Expression commons schemas params grp from (nullity ('PGvararray ty))) where
502− (<>) = unsafeBinaryOp "||"
503−
504−instance Monoid
505− (Expression commons schemas params grp from (nullity ('PGvararray ty))) where
506− mempty = array []
507− mappend = (<>)
508−
509−-- | >>> let expr = greatest currentTimestamp [param @1] :: Expression commons schemas '[ 'NotNull 'PGtimestamptz] grp from ('NotNull 'PGtimestamptz)
510−-- >>> printSQL expr
511−-- GREATEST(CURRENT_TIMESTAMP, ($1 :: timestamp with time zone))
512−greatest
513− :: Expression commons schemas params grp from (nullty)
514− -- ^ needs at least 1 argument
515− -> [Expression commons schemas params grp from (nullty)]
516− -- ^ or more
517− -> Expression commons schemas params grp from (nullty)
518−greatest x xs = UnsafeExpression $ "GREATEST("
519− <> commaSeparated (renderSQL <$> (x:xs)) <> ")"
520−
521−-- | >>> printSQL $ least currentTimestamp [null_]
522−-- LEAST(CURRENT_TIMESTAMP, NULL)
523−least
524− :: Expression commons schemas params grp from (nullty)
525− -- ^ needs at least 1 argument
526− -> [Expression commons schemas params grp from (nullty)]
527− -- ^ or more
528− -> Expression commons schemas params grp from (nullty)
529−least x xs = UnsafeExpression $ "LEAST("
530− <> commaSeparated (renderSQL <$> (x:xs)) <> ")"
531−
532315-- | >>> printSQL $ unsafeBinaryOp "OR" true false
533316-- (TRUE OR FALSE)
534−unsafeBinaryOp
535− :: ByteString
536− -- ^ operator
537− -> Expression commons schemas params grp from (ty0)
538− -> Expression commons schemas params grp from (ty1)
539− -> Expression commons schemas params grp from (ty2)
317+unsafeBinaryOp :: ByteString -> Operator ty0 ty1 ty2
540318unsafeBinaryOp op x y = UnsafeExpression $ parenthesized $
541319 renderSQL x <+> op <+> renderSQL y
542320
543−-- | >>> printSQL $ unsafeUnaryOp "NOT" true
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
327+
328+-- | >>> printSQL $ unsafeLeftOp "NOT" true
544329-- (NOT TRUE)
545−unsafeUnaryOp
546− :: ByteString
547− -- ^ operator
548− -> Expression commons schemas params grp from (ty0)
549− -> Expression commons schemas params grp from (ty1)
550−unsafeUnaryOp op x = UnsafeExpression $ parenthesized $
551− op <+> renderSQL x
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
552351
553352-- | >>> printSQL $ unsafeFunction "f" true
554353-- f(TRUE)
555−unsafeFunction
556− :: ByteString
557− -- ^ function
558− -> Expression commons schemas params grp from (xty)
559− -> Expression commons schemas params grp from (yty)
354+unsafeFunction :: ByteString -> x --> y
560355unsafeFunction fun x = UnsafeExpression $
561356 fun <> parenthesized (renderSQL x)
562357
563−-- | Helper for defining variadic functions.
564−unsafeVariadicFunction
565− :: SListI elems
566− => ByteString
567− -- ^ function
568− -> NP (Expression commons schemas params grp from) elems
569− -> Expression commons schemas params grp from ret
570−unsafeVariadicFunction fun x = UnsafeExpression $
571− fun <> parenthesized (commaSeparated (hcollapse (hmap (K . renderSQL) x)))
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 $
368+ fun <> parenthesized (renderCommaSeparated renderSQL xs)
369+
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
572377
573378instance ty `In` PGNum
574− => Num (Expression commons schemas params grp from (nullity ty)) where
379+ => Num (Expression outer commons grp schemas params from (null ty)) where
575380 (+) = unsafeBinaryOp "+"
576381 (-) = unsafeBinaryOp "-"
577382 (*) = unsafeBinaryOp "*"
@@ -583,12 +388,17 @@ instance ty `In` PGNum
583388 . show
584389
585390instance (ty `In` PGNum, ty `In` PGFloating) => Fractional
586− (Expression commons schemas params grp from (nullity ty)) where
391+ (Expression outer commons grp schemas params from (null ty)) where
587392 (/) = unsafeBinaryOp "/"
588− fromRational x = fromInteger (numerator x) / fromInteger (denominator x)
393+ fromRational
394+ = UnsafeExpression
395+ . fromString
396+ . ($ "")
397+ . showFFloat Nothing
398+ . fromRat @Double
589399
590400instance (ty `In` PGNum, ty `In` PGFloating) => Floating
591− (Expression commons schemas params grp from (nullity ty)) where
401+ (Expression outer commons grp schemas params from (null ty)) where
592402 pi = UnsafeExpression "pi()"
593403 exp = unsafeFunction "exp"
594404 log = unsafeFunction "ln"
@@ -609,1172 +419,54 @@ instance (ty `In` PGNum, ty `In` PGFloating) => Floating
609419 acosh x = log (x + sqrt (x*x - 1))
610420 atanh x = log ((1 + x) / (1 - x)) / 2
611421
612−-- | >>> :{
613−-- let
614−-- expression :: Expression commons schemas params grp from (nullity 'PGfloat4)
615−-- expression = atan2_ pi 2
616−-- in printSQL expression
617−-- :}
618−-- atan2(pi(), 2)
619−atan2_
620− :: float `In` PGFloating
621− => Expression commons schemas params grp from (nullity float)
622− -- ^ numerator
623− -> Expression commons schemas params grp from (nullity float)
624− -- ^ denominator
625− -> Expression commons schemas params grp from (nullity float)
626−atan2_ y x = UnsafeExpression $
627− "atan2(" <> renderSQL y <> ", " <> renderSQL x <> ")"
628−
629−-- When a `cast` is applied to an `Expression` of a known type, it
630−-- represents a run-time type conversion. The cast will succeed only if a
631−-- suitable type conversion operation has been defined.
632−--
633−-- | >>> printSQL $ true & cast int4
634−-- (TRUE :: int4)
635−cast
636− :: TypeExpression schemas ty1
637− -- ^ type to cast as
638− -> Expression commons schemas params grp from ty0
639− -- ^ value to convert
640− -> Expression commons schemas params grp from ty1
641−cast ty x = UnsafeExpression $ parenthesized $
642− renderSQL x <+> "::" <+> renderSQL ty
643−
644−-- | integer division, truncates the result
645−--
646−-- >>> :{
647−-- let
648−-- expression :: Expression commons schemas params grp from (nullity 'PGint2)
649−-- expression = 5 `quot_` 2
650−-- in printSQL expression
651−-- :}
652−-- (5 / 2)
653−quot_
654− :: int `In` PGIntegral
655− => Expression commons schemas params grp from (nullity int)
656− -- ^ numerator
657− -> Expression commons schemas params grp from (nullity int)
658− -- ^ denominator
659− -> Expression commons schemas params grp from (nullity int)
660−quot_ = unsafeBinaryOp "/"
661−
662−-- | remainder upon integer division
663−--
664−-- >>> :{
665−-- let
666−-- expression :: Expression commons schemas params grp from (nullity 'PGint2)
667−-- expression = 5 `rem_` 2
668−-- in printSQL expression
669−-- :}
670−-- (5 % 2)
671−rem_
672− :: int `In` PGIntegral
673− => Expression commons schemas params grp from (nullity int)
674− -- ^ numerator
675− -> Expression commons schemas params grp from (nullity int)
676− -- ^ denominator
677− -> Expression commons schemas params grp from (nullity int)
678−rem_ = unsafeBinaryOp "%"
679−
680−-- | >>> :{
681−-- let
682−-- expression :: Expression commons schemas params grp from (nullity 'PGfloat4)
683−-- expression = trunc pi
684−-- in printSQL expression
685−-- :}
686−-- trunc(pi())
687−trunc
688− :: frac `In` PGFloating
689− => Expression commons schemas params grp from (nullity frac)
690− -- ^ fractional number
691− -> Expression commons schemas params grp from (nullity frac)
692−trunc = unsafeFunction "trunc"
693−
694−-- | >>> :{
695−-- let
696−-- expression :: Expression commons schemas params grp from (nullity 'PGfloat4)
697−-- expression = round_ pi
698−-- in printSQL expression
699−-- :}
700−-- round(pi())
701−round_
702− :: frac `In` PGFloating
703− => Expression commons schemas params grp from (nullity frac)
704− -- ^ fractional number
705− -> Expression commons schemas params grp from (nullity frac)
706−round_ = unsafeFunction "round"
707−
708−-- | >>> :{
709−-- let
710−-- expression :: Expression commons schemas params grp from (nullity 'PGfloat4)
711−-- expression = ceiling_ pi
712−-- in printSQL expression
713−-- :}
714−-- ceiling(pi())
715−ceiling_
716− :: frac `In` PGFloating
717− => Expression commons schemas params grp from (nullity frac)
718− -- ^ fractional number
719− -> Expression commons schemas params grp from (nullity frac)
720−ceiling_ = unsafeFunction "ceiling"
721−
722−-- | A `Condition` is an `Expression`, which can evaluate
723−-- to `true`, `false` or `null_`. This is because SQL uses
724−-- a three valued logic.
725−type Condition commons schemas params grp from =
726− Expression commons schemas params grp from ('Null 'PGbool)
727−
728−-- | >>> printSQL true
729−-- TRUE
730−true :: Expression commons schemas params grp from (nullity 'PGbool)
731−true = UnsafeExpression "TRUE"
732−
733−-- | >>> printSQL false
734−-- FALSE
735−false :: Expression commons schemas params grp from (nullity 'PGbool)
736−false = UnsafeExpression "FALSE"
737−
738−-- | >>> printSQL $ not_ true
739−-- (NOT TRUE)
740−not_
741− :: Expression commons schemas params grp from (nullity 'PGbool)
742− -> Expression commons schemas params grp from (nullity 'PGbool)
743−not_ = unsafeUnaryOp "NOT"
744−
745−-- | >>> printSQL $ true .&& false
746−-- (TRUE AND FALSE)
747−(.&&)
748− :: Expression commons schemas params grp from (nullity 'PGbool)
749− -> Expression commons schemas params grp from (nullity 'PGbool)
750− -> Expression commons schemas params grp from (nullity 'PGbool)
751−infixr 3 .&&
752−(.&&) = unsafeBinaryOp "AND"
753−
754−-- | >>> printSQL $ true .|| false
755−-- (TRUE OR FALSE)
756−(.||)
757− :: Expression commons schemas params grp from (nullity 'PGbool)
758− -> Expression commons schemas params grp from (nullity 'PGbool)
759− -> Expression commons schemas params grp from (nullity 'PGbool)
760−infixr 2 .||
761−(.||) = unsafeBinaryOp "OR"
762−
763−-- | >>> :{
764−-- let
765−-- expression :: Expression commons schemas params grp from (nullity 'PGint2)
766−-- expression = caseWhenThenElse [(true, 1), (false, 2)] 3
767−-- in printSQL expression
768−-- :}
769−-- CASE WHEN TRUE THEN 1 WHEN FALSE THEN 2 ELSE 3 END
770−caseWhenThenElse
771− :: [ ( Condition commons schemas params grp from
772− , Expression commons schemas params grp from ty
773− ) ]
774− -- ^ whens and thens
775− -> Expression commons schemas params grp from ty
776− -- ^ else
777− -> Expression commons schemas params grp from ty
778−caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
779− [ "CASE"
780− , mconcat
781− [ mconcat
782− [ " WHEN ", renderSQL when_
783− , " THEN ", renderSQL then_
784− ]
785− | (when_,then_) <- whenThens
786− ]
787− , " ELSE ", renderSQL else_
788− , " END"
789− ]
790−
791−-- | >>> :{
792−-- let
793−-- expression :: Expression commons schemas params grp from (nullity 'PGint2)
794−-- expression = ifThenElse true 1 0
795−-- in printSQL expression
796−-- :}
797−-- CASE WHEN TRUE THEN 1 ELSE 0 END
798−ifThenElse
799− :: Condition commons schemas params grp from
800− -> Expression commons schemas params grp from ty -- ^ then
801− -> Expression commons schemas params grp from ty -- ^ else
802− -> Expression commons schemas params grp from ty
803−ifThenElse if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
804−
805−-- | Comparison operations like `.==`, `./=`, `.>`, `.>=`, `.<` and `.<=`
806−-- will produce @NULL@s if one of their arguments is @NULL@.
807−--
808−-- >>> printSQL $ true .== null_
809−-- (TRUE = NULL)
810−(.==)
811− :: Expression commons schemas params grp from (nullity0 ty) -- ^ lhs
812− -> Expression commons schemas params grp from (nullity1 ty) -- ^ rhs
813− -> Condition commons schemas params grp from
814−(.==) = unsafeBinaryOp "="
815−infix 4 .==
816−
817−-- | >>> printSQL $ true ./= null_
818−-- (TRUE <> NULL)
819−(./=)
820− :: Expression commons schemas params grp from (nullity0 ty) -- ^ lhs
821− -> Expression commons schemas params grp from (nullity1 ty) -- ^ rhs
822− -> Condition commons schemas params grp from
823−(./=) = unsafeBinaryOp "<>"
824−infix 4 ./=
825−
826−-- | >>> printSQL $ true .>= null_
827−-- (TRUE >= NULL)
828−(.>=)
829− :: Expression commons schemas params grp from (nullity0 ty) -- ^ lhs
830− -> Expression commons schemas params grp from (nullity1 ty) -- ^ rhs
831− -> Condition commons schemas params grp from
832−(.>=) = unsafeBinaryOp ">="
833−infix 4 .>=
834−
835−-- | >>> printSQL $ true .< null_
836−-- (TRUE < NULL)
837−(.<)
838− :: Expression commons schemas params grp from (nullity0 ty) -- ^ lhs
839− -> Expression commons schemas params grp from (nullity1 ty) -- ^ rhs
840− -> Condition commons schemas params grp from
841−(.<) = unsafeBinaryOp "<"
842−infix 4 .<
843−
844−-- | >>> printSQL $ true .<= null_
845−-- (TRUE <= NULL)
846−(.<=)
847− :: Expression commons schemas params grp from (nullity0 ty) -- ^ lhs
848− -> Expression commons schemas params grp from (nullity1 ty) -- ^ rhs
849− -> Condition commons schemas params grp from
850−(.<=) = unsafeBinaryOp "<="
851−infix 4 .<=
852−
853−-- | >>> printSQL $ true .> null_
854−-- (TRUE > NULL)
855−(.>)
856− :: Expression commons schemas params grp from (nullity0 ty) -- ^ lhs
857− -> Expression commons schemas params grp from (nullity1 ty) -- ^ rhs
858− -> Condition commons schemas params grp from
859−(.>) = unsafeBinaryOp ">"
860−infix 4 .>
861−
862−-- | >>> printSQL currentDate
863−-- CURRENT_DATE
864−currentDate
865− :: Expression commons schemas params grp from (nullity 'PGdate)
866−currentDate = UnsafeExpression "CURRENT_DATE"
867−
868−-- | >>> printSQL currentTime
869−-- CURRENT_TIME
870−currentTime
871− :: Expression commons schemas params grp from (nullity 'PGtimetz)
872−currentTime = UnsafeExpression "CURRENT_TIME"
873−
874−-- | >>> printSQL currentTimestamp
875−-- CURRENT_TIMESTAMP
876−currentTimestamp
877− :: Expression commons schemas params grp from (nullity 'PGtimestamptz)
878−currentTimestamp = UnsafeExpression "CURRENT_TIMESTAMP"
879−
880−-- | >>> printSQL localTime
881−-- LOCALTIME
882−localTime
883− :: Expression commons schemas params grp from (nullity 'PGtime)
884−localTime = UnsafeExpression "LOCALTIME"
885−
886−-- | >>> printSQL localTimestamp
887−-- LOCALTIMESTAMP
888−localTimestamp
889− :: Expression commons schemas params grp from (nullity 'PGtimestamp)
890−localTimestamp = UnsafeExpression "LOCALTIMESTAMP"
891−
892−{-----------------------------------------
893−text
894−-----------------------------------------}
422+-- | Contained by operators
423+class PGSubset ty where
424+ (@>) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
425+ (@>) = unsafeBinaryOp "@>"
426+ (<@) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
427+ (<@) = unsafeBinaryOp "<@"
428+instance PGSubset 'PGjsonb
429+instance PGSubset 'PGtsquery
430+instance PGSubset ('PGvararray ty)
431+instance PGSubset ('PGrange ty)
432+
433+class PGIntersect ty where
434+ (@&&) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
435+ (@&&) = unsafeBinaryOp "&&"
436+instance PGIntersect ('PGvararray ty)
437+instance PGIntersect ('PGrange ty)
895438
896439instance IsString
897− (Expression commons schemas params grp from (nullity 'PGtext)) where
440+ (Expression outer commons grp schemas params from (null 'PGtext)) where
898441 fromString str = UnsafeExpression $
899442 "E\'" <> fromString (escape =<< str) <> "\'"
900− where
901− escape = \case
902− '\NUL' -> "\\0"
903− '\'' -> "''"
904− '"' -> "\\\""
905− '\b' -> "\\b"
906− '\n' -> "\\n"
907− '\r' -> "\\r"
908− '\t' -> "\\t"
909− '\\' -> "\\\\"
910− c -> [c]
443+instance IsString
444+ (Expression outer commons grp schemas params from (null 'PGtsvector)) where
445+ fromString str = UnsafeExpression . parenthesized . (<> " :: tsvector") $
446+ "E\'" <> fromString (escape =<< str) <> "\'"
447+instance IsString
448+ (Expression outer commons grp schemas params from (null 'PGtsquery)) where
449+ fromString str = UnsafeExpression . parenthesized . (<> " :: tsquery") $
450+ "E\'" <> fromString (escape =<< str) <> "\'"
911451
912452instance Semigroup
913− (Expression commons schemas params grp from (nullity '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
460+ (<>) = unsafeBinaryOp "||"
461+instance Semigroup
462+ (Expression outer commons grp schemas params from (null 'PGtsvector)) where
914463 (<>) = unsafeBinaryOp "||"
915464
916465instance Monoid
917− (Expression commons schemas params grp from (nullity 'PGtext)) where
466+ (Expression outer commons grp schemas params from (null 'PGtext)) where
467+ mempty = fromString ""
468+ mappend = (<>)
469+instance Monoid
470+ (Expression outer commons grp schemas params from (null 'PGtsvector)) where
918471 mempty = fromString ""
919472 mappend = (<>)
920−
921−-- | >>> printSQL $ lower "ARRRGGG"
922−-- lower(E'ARRRGGG')
923−lower
924− :: Expression commons schemas params grp from (nullity 'PGtext)
925− -- ^ string to lower case
926− -> Expression commons schemas params grp from (nullity 'PGtext)
927−lower = unsafeFunction "lower"
928−
929−-- | >>> printSQL $ upper "eeee"
930−-- upper(E'eeee')
931−upper
932− :: Expression commons schemas params grp from (nullity 'PGtext)
933− -- ^ string to upper case
934− -> Expression commons schemas params grp from (nullity 'PGtext)
935−upper = unsafeFunction "upper"
936−
937−-- | >>> printSQL $ charLength "four"
938−-- char_length(E'four')
939−charLength
940− :: Expression commons schemas params grp from (nullity 'PGtext)
941− -- ^ string to measure
942− -> Expression commons schemas params grp from (nullity 'PGint4)
943−charLength = unsafeFunction "char_length"
944−
945−-- | The `like` expression returns true if the @string@ matches
946−-- the supplied @pattern@. If @pattern@ does not contain percent signs
947−-- or underscores, then the pattern only represents the string itself;
948−-- in that case `like` acts like the equals operator. An underscore (_)
949−-- in pattern stands for (matches) any single character; a percent sign (%)
950−-- matches any sequence of zero or more characters.
951−--
952−-- >>> printSQL $ "abc" `like` "a%"
953−-- (E'abc' LIKE E'a%')
954−like
955− :: Expression commons schemas params grp from (nullity 'PGtext)
956− -- ^ string
957− -> Expression commons schemas params grp from (nullity 'PGtext)
958− -- ^ pattern
959− -> Expression commons schemas params grp from (nullity 'PGbool)
960−like = unsafeBinaryOp "LIKE"
961−
962−-- | The key word ILIKE can be used instead of LIKE to make the
963−-- match case-insensitive according to the active locale.
964−--
965−-- >>> printSQL $ "abc" `ilike` "a%"
966−-- (E'abc' ILIKE E'a%')
967−ilike
968− :: Expression commons schemas params grp from (nullity 'PGtext)
969− -- ^ string
970− -> Expression commons schemas params grp from (nullity 'PGtext)
971− -- ^ pattern
972− -> Expression commons schemas params grp from (nullity 'PGbool)
973−ilike = unsafeBinaryOp "ILIKE"
974−
975−{-----------------------------------------
976− -- json and jsonb support
977−
978−See https://www.postgresql.org/docs/10/static/functions-json.html -- most
979−comments lifted directly from this page.
980−
981−Table 9.44: json and jsonb operators
982−-----------------------------------------}
983−
984−-- | Get JSON value (object field or array element) at a key.
985−(.->)
986− :: (json `In` PGJsonType, key `In` PGJsonKey)
987− => Expression commons schemas params grp from (nullity json)
988− -> Expression commons schemas params grp from (nullity key)
989− -> Expression commons schemas params grp from ('Null json)
990−infixl 8 .->
991−(.->) = unsafeBinaryOp "->"
992−
993−-- | Get JSON value (object field or array element) at a key, as text.
994−(.->>)
995− :: (json `In` PGJsonType, key `In` PGJsonKey)
996− => Expression commons schemas params grp from (nullity json)
997− -> Expression commons schemas params grp from (nullity key)
998− -> Expression commons schemas params grp from ('Null 'PGtext)
999−infixl 8 .->>
1000−(.->>) = unsafeBinaryOp "->>"
1001−
1002−-- | Get JSON value at a specified path.
1003−(.#>)
1004− :: (json `In` PGJsonType, PGTextArray "(.#>)" path)
1005− => Expression commons schemas params grp from (nullity json)
1006− -> Expression commons schemas params grp from (nullity path)
1007− -> Expression commons schemas params grp from ('Null json)
1008−infixl 8 .#>
1009−(.#>) = unsafeBinaryOp "#>"
1010−
1011−-- | Get JSON value at a specified path as text.
1012−(.#>>)
1013− :: (json `In` PGJsonType, PGTextArray "(.#>>)" path)
1014− => Expression commons schemas params grp from (nullity json)
1015− -> Expression commons schemas params grp from (nullity path)
1016− -> Expression commons schemas params grp from ('Null 'PGtext)
1017−infixl 8 .#>>
1018−(.#>>) = unsafeBinaryOp "#>>"
1019−
1020−-- Additional jsonb operators
1021−
1022−-- | Does the left JSON value contain the right JSON path/value entries at the
1023−-- top level?
1024−(.@>)
1025− :: Expression commons schemas params grp from (nullity 'PGjsonb)
1026− -> Expression commons schemas params grp from (nullity 'PGjsonb)
1027− -> Condition commons schemas params grp from
1028−infixl 9 .@>
1029−(.@>) = unsafeBinaryOp "@>"
1030−
1031−-- | Are the left JSON path/value entries contained at the top level within the
1032−-- right JSON value?
1033−(.<@)
1034− :: Expression commons schemas params grp from (nullity 'PGjsonb)
1035− -> Expression commons schemas params grp from (nullity 'PGjsonb)
1036− -> Condition commons schemas params grp from
1037−infixl 9 .<@
1038−(.<@) = unsafeBinaryOp "<@"
1039−
1040−-- | Does the string exist as a top-level key within the JSON value?
1041−(.?)
1042− :: Expression commons schemas params grp from (nullity 'PGjsonb)
1043− -> Expression commons schemas params grp from (nullity 'PGtext)
1044− -> Condition commons schemas params grp from
1045−infixl 9 .?
1046−(.?) = unsafeBinaryOp "?"
1047−
1048−-- | Do any of these array strings exist as top-level keys?
1049−(.?|)
1050− :: Expression commons schemas params grp from (nullity 'PGjsonb)
1051− -> Expression commons schemas params grp from (nullity ('PGvararray ('NotNull 'PGtext)))
1052− -> Condition commons schemas params grp from
1053−infixl 9 .?|
1054−(.?|) = unsafeBinaryOp "?|"
1055−
1056−-- | Do all of these array strings exist as top-level keys?
1057−(.?&)
1058− :: Expression commons schemas params grp from (nullity 'PGjsonb)
1059− -> Expression commons schemas params grp from (nullity ('PGvararray ('NotNull 'PGtext)))
1060− -> Condition commons schemas params grp from
1061−infixl 9 .?&
1062−(.?&) = unsafeBinaryOp "?&"
1063−
1064−-- | Concatenate two jsonb values into a new jsonb value.
1065−instance
1066− Semigroup (Expression commons schemas from grouping param (nullity 'PGjsonb)) where
1067− (<>) = unsafeBinaryOp "||"
1068−
1069−-- | Delete a key or keys from a JSON object, or remove an array element.
1070−--
1071−-- If the right operand is..
1072−--
1073−-- @ text @: Delete key/value pair or string element from left operand. Key/value pairs
1074−-- are matched based on their key value.
1075−--
1076−-- @ text[] @: Delete multiple key/value pairs or string elements
1077−-- from left operand. Key/value pairs are matched based on their key value.
1078−--
1079−-- @ integer @: Delete the array element with specified index (Negative integers
1080−-- count from the end). Throws an error if top level container is not an array.
1081−(.-.)
1082− :: (key `In` '[ 'PGtext, 'PGvararray ('NotNull 'PGtext), 'PGint4, 'PGint2 ]) -- hlint error without parens here
1083− => Expression commons schemas params grp from (nullity 'PGjsonb)
1084− -> Expression commons schemas params grp from (nullity key)
1085− -> Expression commons schemas params grp from (nullity 'PGjsonb)
1086−infixl 6 .-.
1087−(.-.) = unsafeBinaryOp "-"
1088−
1089−-- | Delete the field or element with specified path (for JSON arrays, negative
1090−-- integers count from the end)
1091−(#-.)
1092− :: PGTextArray "(#-.)" arrayty
1093− => Expression commons schemas params grp from (nullity 'PGjsonb)
1094− -> Expression commons schemas params grp from (nullity arrayty)
1095− -> Expression commons schemas params grp from (nullity 'PGjsonb)
1096−infixl 6 #-.
1097−(#-.) = unsafeBinaryOp "#-"
1098−
1099−{-----------------------------------------
1100−Table 9.45: JSON creation functions
1101−-----------------------------------------}
1102−
1103−-- | Literal binary JSON
1104−jsonbLit
1105− :: JSON.ToJSON x
1106− => x -> Expression commons schemas params grp from (nullity 'PGjsonb)
1107−jsonbLit = cast jsonb . UnsafeExpression
1108− . singleQuotedUtf8 . toStrict . JSON.encode
1109−
1110−-- | Literal JSON
1111−jsonLit
1112− :: JSON.ToJSON x
1113− => x -> Expression commons schemas params grp from (nullity 'PGjson)
1114−jsonLit = cast json . UnsafeExpression
1115− . singleQuotedUtf8 . toStrict . JSON.encode
1116−
1117−-- | Returns the value as json. Arrays and composites are converted
1118−-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1119−-- type to json, the cast function will be used to perform the conversion;
1120−-- otherwise, a scalar value is produced. For any scalar type other than a
1121−-- number, a Boolean, or a null value, the text representation will be used, in
1122−-- such a fashion that it is a valid json value.
1123−toJson
1124− :: Expression commons schemas params grp from (nullity ty)
1125− -> Expression commons schemas params grp from (nullity 'PGjson)
1126−toJson = unsafeFunction "to_json"
1127−
1128−-- | Returns the value as jsonb. Arrays and composites are converted
1129−-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1130−-- type to json, the cast function will be used to perform the conversion;
1131−-- otherwise, a scalar value is produced. For any scalar type other than a
1132−-- number, a Boolean, or a null value, the text representation will be used, in
1133−-- such a fashion that it is a valid jsonb value.
1134−toJsonb
1135− :: Expression commons schemas params grp from (nullity ty)
1136− -> Expression commons schemas params grp from (nullity 'PGjsonb)
1137−toJsonb = unsafeFunction "to_jsonb"
1138−
1139−-- | Returns the array as a JSON array. A PostgreSQL multidimensional array
1140−-- becomes a JSON array of arrays.
1141−arrayToJson
1142− :: PGArray "arrayToJson" arr
1143− => Expression commons schemas params grp from (nullity arr)
1144− -> Expression commons schemas params grp from (nullity 'PGjson)
1145−arrayToJson = unsafeFunction "array_to_json"
1146−
1147−-- | Returns the row as a JSON object.
1148−rowToJson
1149− :: Expression commons schemas params grp from (nullity ('PGcomposite ty))
1150− -> Expression commons schemas params grp from (nullity 'PGjson)
1151−rowToJson = unsafeFunction "row_to_json"
1152−
1153−-- | Builds a possibly-heterogeneously-typed JSON array out of a variadic
1154−-- argument list.
1155−jsonBuildArray
1156− :: SListI elems
1157− => NP (Expression commons schemas params grp from) elems
1158− -> Expression commons schemas params grp from (nullity 'PGjson)
1159−jsonBuildArray = unsafeVariadicFunction "json_build_array"
1160−
1161−-- | Builds a possibly-heterogeneously-typed (binary) JSON array out of a
1162−-- variadic argument list.
1163−jsonbBuildArray
1164− :: SListI elems
1165− => NP (Expression commons schemas params grp from) elems
1166− -> Expression commons schemas params grp from (nullity 'PGjsonb)
1167−jsonbBuildArray = unsafeVariadicFunction "jsonb_build_array"
1168−
1169−unsafeRowFunction
1170− :: All Top elems
1171− => NP (Aliased (Expression commons schemas params grp from)) elems
1172− -> [ByteString]
1173−unsafeRowFunction =
1174− (`appEndo` []) . hcfoldMap (Proxy :: Proxy Top)
1175− (\(col `As` name) -> Endo $ \xs ->
1176− renderAliasString name : renderSQL col : xs)
1177− where
1178− renderAliasString :: KnownSymbol alias => Alias alias -> ByteString
1179− renderAliasString = singleQuotedText . fromString . symbolVal
1180−
1181−-- | Builds a possibly-heterogeneously-typed JSON object out of a variadic
1182−-- argument list. The elements of the argument list must alternate between text
1183−-- and values.
1184−jsonBuildObject
1185− :: All Top elems
1186− => NP (Aliased (Expression commons schemas params grp from)) elems
1187− -> Expression commons schemas params grp from (nullity 'PGjson)
1188−jsonBuildObject
1189− = unsafeFunction "json_build_object"
1190− . UnsafeExpression
1191− . commaSeparated
1192− . unsafeRowFunction
1193−
1194−-- | Builds a possibly-heterogeneously-typed (binary) JSON object out of a
1195−-- variadic argument list. The elements of the argument list must alternate
1196−-- between text and values.
1197−jsonbBuildObject
1198− :: All Top elems
1199− => NP (Aliased (Expression commons schemas params grp from)) elems
1200− -> Expression commons schemas params grp from (nullity 'PGjsonb)
1201−jsonbBuildObject
1202− = unsafeFunction "jsonb_build_object"
1203− . UnsafeExpression
1204− . commaSeparated
1205− . unsafeRowFunction
1206−
1207−-- | Builds a JSON object out of a text array. The array must have either
1208−-- exactly one dimension with an even number of members, in which case they are
1209−-- taken as alternating key/value pairs, or two dimensions such that each inner
1210−-- array has exactly two elements, which are taken as a key/value pair.
1211−jsonObject
1212− :: PGArrayOf "jsonObject" arr ('NotNull 'PGtext)
1213− => Expression commons schemas params grp from (nullity arr)
1214− -> Expression commons schemas params grp from (nullity 'PGjson)
1215−jsonObject = unsafeFunction "json_object"
1216−
1217−-- | Builds a binary JSON object out of a text array. The array must have either
1218−-- exactly one dimension with an even number of members, in which case they are
1219−-- taken as alternating key/value pairs, or two dimensions such that each inner
1220−-- array has exactly two elements, which are taken as a key/value pair.
1221−jsonbObject
1222− :: PGArrayOf "jsonbObject" arr ('NotNull 'PGtext)
1223− => Expression commons schemas params grp from (nullity arr)
1224− -> Expression commons schemas params grp from (nullity 'PGjsonb)
1225−jsonbObject = unsafeFunction "jsonb_object"
1226−
1227−-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1228−-- keys and one for values, that are zipped pairwise to create a JSON object.
1229−jsonZipObject
1230− :: ( PGArrayOf "jsonZipObject" keysArray ('NotNull 'PGtext)
1231− , PGArrayOf "jsonZipObject" valuesArray ('NotNull 'PGtext))
1232− => Expression commons schemas params grp from (nullity keysArray)
1233− -> Expression commons schemas params grp from (nullity valuesArray)
1234− -> Expression commons schemas params grp from (nullity 'PGjson)
1235−jsonZipObject ks vs =
1236− unsafeVariadicFunction "json_object" (ks :* vs :* Nil)
1237−
1238−-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1239−-- keys and one for values, that are zipped pairwise to create a binary JSON
1240−-- object.
1241−jsonbZipObject
1242− :: ( PGArrayOf "jsonbZipObject" keysArray ('NotNull 'PGtext)
1243− , PGArrayOf "jsonbZipObject" valuesArray ('NotNull 'PGtext))
1244− => Expression commons schemas params grp from (nullity keysArray)
1245− -> Expression commons schemas params grp from (nullity valuesArray)
1246− -> Expression commons schemas params grp from (nullity 'PGjsonb)
1247−jsonbZipObject ks vs =
1248− unsafeVariadicFunction "jsonb_object" (ks :* vs :* Nil)
1249−
1250−{-----------------------------------------
1251−Table 9.46: JSON processing functions
1252−-----------------------------------------}
1253−
1254−-- | Returns the number of elements in the outermost JSON array.
1255−jsonArrayLength
1256− :: Expression commons schemas params grp from (nullity 'PGjson)
1257− -> Expression commons schemas params grp from (nullity 'PGint4)
1258−jsonArrayLength = unsafeFunction "json_array_length"
1259−
1260−-- | Returns the number of elements in the outermost binary JSON array.
1261−jsonbArrayLength
1262− :: Expression commons schemas params grp from (nullity 'PGjsonb)
1263− -> Expression commons schemas params grp from (nullity 'PGint4)
1264−jsonbArrayLength = unsafeFunction "jsonb_array_length"
1265−
1266−-- | Returns JSON value pointed to by the given path (equivalent to #>
1267−-- operator).
1268−jsonExtractPath
1269− :: SListI elems
1270− => Expression commons schemas params grp from (nullity 'PGjson)
1271− -> NP (Expression commons schemas params grp from) elems
1272− -> Expression commons schemas params grp from (nullity 'PGjsonb)
1273−jsonExtractPath x xs =
1274− unsafeVariadicFunction "json_extract_path" (x :* xs)
1275−
1276−-- | Returns JSON value pointed to by the given path (equivalent to #>
1277−-- operator).
1278−jsonbExtractPath
1279− :: SListI elems
1280− => Expression commons schemas params grp from (nullity 'PGjsonb)
1281− -> NP (Expression commons schemas params grp from) elems
1282− -> Expression commons schemas params grp from (nullity 'PGjsonb)
1283−jsonbExtractPath x xs =
1284− unsafeVariadicFunction "jsonb_extract_path" (x :* xs)
1285−
1286−-- | Returns JSON value pointed to by the given path (equivalent to #>
1287−-- operator), as text.
1288−jsonExtractPathAsText
1289− :: SListI elems
1290− => Expression commons schemas params grp from (nullity 'PGjson)
1291− -> NP (Expression commons schemas params grp from) elems
1292− -> Expression commons schemas params grp from (nullity 'PGjson)
1293−jsonExtractPathAsText x xs =
1294− unsafeVariadicFunction "json_extract_path_text" (x :* xs)
1295−
1296−-- | Returns JSON value pointed to by the given path (equivalent to #>
1297−-- operator), as text.
1298−jsonbExtractPathAsText
1299− :: SListI elems
1300− => Expression commons schemas params grp from (nullity 'PGjsonb)
1301− -> NP (Expression commons schemas params grp from) elems
1302− -> Expression commons schemas params grp from (nullity 'PGjsonb)
1303−jsonbExtractPathAsText x xs =
1304− unsafeVariadicFunction "jsonb_extract_path_text" (x :* xs)
1305−
1306−-- | Returns the type of the outermost JSON value as a text string. Possible
1307−-- types are object, array, string, number, boolean, and null.
1308−jsonTypeof
1309− :: Expression commons schemas params grp from (nullity 'PGjson)
1310− -> Expression commons schemas params grp from (nullity 'PGtext)
1311−jsonTypeof = unsafeFunction "json_typeof"
1312−
1313−-- | Returns the type of the outermost binary JSON value as a text string.
1314−-- Possible types are object, array, string, number, boolean, and null.
1315−jsonbTypeof
1316− :: Expression commons schemas params grp from (nullity 'PGjsonb)
1317− -> Expression commons schemas params grp from (nullity 'PGtext)
1318−jsonbTypeof = unsafeFunction "jsonb_typeof"
1319−
1320−-- | Returns its argument with all object fields that have null values omitted.
1321−-- Other null values are untouched.
1322−jsonStripNulls
1323− :: Expression commons schemas params grp from (nullity 'PGjson)
1324− -> Expression commons schemas params grp from (nullity 'PGjson)
1325−jsonStripNulls = unsafeFunction "json_strip_nulls"
1326−
1327−-- | Returns its argument with all object fields that have null values omitted.
1328−-- Other null values are untouched.
1329−jsonbStripNulls
1330− :: Expression commons schemas params grp from (nullity 'PGjsonb)
1331− -> Expression commons schemas params grp from (nullity 'PGjsonb)
1332−jsonbStripNulls = unsafeFunction "jsonb_strip_nulls"
1333−
1334−-- | @ jsonbSet target path new_value create_missing @
1335−--
1336−-- Returns target with the section designated by path replaced by new_value,
1337−-- or with new_value added if create_missing is true ( default is true) and the
1338−-- item designated by path does not exist. As with the path orientated
1339−-- operators, negative integers that appear in path count from the end of JSON
1340−-- arrays.
1341−jsonbSet
1342− :: PGTextArray "jsonbSet" arr
1343− => Expression commons schemas params grp from (nullity 'PGjsonb)
1344− -> Expression commons schemas params grp from (nullity arr)
1345− -> Expression commons schemas params grp from (nullity 'PGjsonb)
1346− -> Maybe (Expression commons schemas params grp from (nullity 'PGbool))
1347− -> Expression commons schemas params grp from (nullity 'PGjsonb)
1348−jsonbSet tgt path val createMissing = case createMissing of
1349− Just m -> unsafeVariadicFunction "jsonb_set" (tgt :* path :* val :* m :* Nil)
1350− Nothing -> unsafeVariadicFunction "jsonb_set" (tgt :* path :* val :* Nil)
1351−
1352−-- | @ jsonbInsert target path new_value insert_after @
1353−--
1354−-- Returns target with new_value inserted. If target section designated by
1355−-- path is in a JSONB array, new_value will be inserted before target or after
1356−-- if insert_after is true (default is false). If target section designated by
1357−-- path is in JSONB object, new_value will be inserted only if target does not
1358−-- exist. As with the path orientated operators, negative integers that appear
1359−-- in path count from the end of JSON arrays.
1360−jsonbInsert
1361− :: PGTextArray "jsonbInsert" arr
1362− => Expression commons schemas params grp from (nullity 'PGjsonb)
1363− -> Expression commons schemas params grp from (nullity arr)
1364− -> Expression commons schemas params grp from (nullity 'PGjsonb)
1365− -> Maybe (Expression commons schemas params grp from (nullity 'PGbool))
1366− -> Expression commons schemas params grp from (nullity 'PGjsonb)
1367−jsonbInsert tgt path val insertAfter = case insertAfter of
1368− Just i -> unsafeVariadicFunction "jsonb_insert" (tgt :* path :* val :* i :* Nil)
1369− Nothing -> unsafeVariadicFunction "jsonb_insert" (tgt :* path :* val :* Nil)
1370−
1371−-- | Returns its argument as indented JSON text.
1372−jsonbPretty
1373− :: Expression commons schemas params grp from (nullity 'PGjsonb)
1374− -> Expression commons schemas params grp from (nullity 'PGtext)
1375−jsonbPretty = unsafeFunction "jsonb_pretty"
1376−
1377−{-----------------------------------------
1378−aggregation
1379−-----------------------------------------}
1380−
1381−-- | escape hatch to define aggregate functions
1382−unsafeAggregate
1383− :: ByteString -- ^ aggregate function
1384− -> Expression commons schemas from 'Ungrouped params (xty)
1385− -> Expression commons schemas from ('Grouped bys) params (yty)
1386−unsafeAggregate fun x = UnsafeExpression $ mconcat
1387− [fun, "(", renderSQL x, ")"]
1388−
1389−-- | escape hatch to define aggregate functions over distinct values
1390−unsafeAggregateDistinct
1391− :: ByteString -- ^ aggregate function
1392− -> Expression commons schemas from 'Ungrouped params (xty)
1393− -> Expression commons schemas from ('Grouped bys) params (yty)
1394−unsafeAggregateDistinct fun x = UnsafeExpression $ mconcat
1395− [fun, "(DISTINCT ", renderSQL x, ")"]
1396−
1397−-- | >>> :{
1398−-- let
1399−-- expression :: Expression commons schemas params ('Grouped bys) '[tab ::: '["col" ::: 'Null 'PGnumeric]] ('Null 'PGnumeric)
1400−-- expression = sum_ #col
1401−-- in printSQL expression
1402−-- :}
1403−-- sum("col")
1404−sum_
1405− :: ty `In` PGNum
1406− => Expression commons schemas from 'Ungrouped params (nullity ty)
1407− -- ^ what to sum
1408− -> Expression commons schemas from ('Grouped bys) params (nullity ty)
1409−sum_ = unsafeAggregate "sum"
1410−
1411−-- | >>> :{
1412−-- let
1413−-- expression :: Expression commons schemas params ('Grouped bys) '[tab ::: '["col" ::: nullity 'PGnumeric]] (nullity 'PGnumeric)
1414−-- expression = sumDistinct #col
1415−-- in printSQL expression
1416−-- :}
1417−-- sum(DISTINCT "col")
1418−sumDistinct
1419− :: ty `In` PGNum
1420− => Expression commons schemas from 'Ungrouped params (nullity ty)
1421− -- ^ what to sum
1422− -> Expression commons schemas from ('Grouped bys) params (nullity ty)
1423−sumDistinct = unsafeAggregateDistinct "sum"
1424−
1425−-- | A constraint for `PGType`s that you can take averages of and the resulting
1426−-- `PGType`.
1427−class PGAvg ty avg | ty -> avg where
1428− avg, avgDistinct
1429− :: Expression commons schemas from 'Ungrouped params (nullity ty)
1430− -- ^ what to average
1431− -> Expression commons schemas from ('Grouped bys) params (nullity avg)
1432− avg = unsafeAggregate "avg"
1433− avgDistinct = unsafeAggregateDistinct "avg"
1434−instance PGAvg 'PGint2 'PGnumeric
1435−instance PGAvg 'PGint4 'PGnumeric
1436−instance PGAvg 'PGint8 'PGnumeric
1437−instance PGAvg 'PGnumeric 'PGnumeric
1438−instance PGAvg 'PGfloat4 'PGfloat8
1439−instance PGAvg 'PGfloat8 'PGfloat8
1440−instance PGAvg 'PGinterval 'PGinterval
1441−
1442−-- | >>> :{
1443−-- let
1444−-- expression :: Expression commons schemas params (Grouped bys) '[tab ::: '["col" ::: nullity 'PGint4]] (nullity 'PGint4)
1445−-- expression = bitAnd #col
1446−-- in printSQL expression
1447−-- :}
1448−-- bit_and("col")
1449−bitAnd
1450− :: int `In` PGIntegral
1451− => Expression commons schemas from 'Ungrouped params (nullity int)
1452− -- ^ what to aggregate
1453− -> Expression commons schemas from ('Grouped bys) params (nullity int)
1454−bitAnd = unsafeAggregate "bit_and"
1455−
1456−-- | >>> :{
1457−-- let
1458−-- expression :: Expression commons schemas params ('Grouped bys) '[tab ::: '["col" ::: nullity 'PGint4]] (nullity 'PGint4)
1459−-- expression = bitOr #col
1460−-- in printSQL expression
1461−-- :}
1462−-- bit_or("col")
1463−bitOr
1464− :: int `In` PGIntegral
1465− => Expression commons schemas from 'Ungrouped params (nullity int)
1466− -- ^ what to aggregate
1467− -> Expression commons schemas from ('Grouped bys) params (nullity int)
1468−bitOr = unsafeAggregate "bit_or"
1469−
1470−-- | >>> :{
1471−-- let
1472−-- expression :: Expression commons schemas params ('Grouped bys) '[tab ::: '["col" ::: nullity 'PGint4]] (nullity 'PGint4)
1473−-- expression = bitAndDistinct #col
1474−-- in printSQL expression
1475−-- :}
1476−-- bit_and(DISTINCT "col")
1477−bitAndDistinct
1478− :: int `In` PGIntegral
1479− => Expression commons schemas from 'Ungrouped params (nullity int)
1480− -- ^ what to aggregate
1481− -> Expression commons schemas from ('Grouped bys) params (nullity int)
1482−bitAndDistinct = unsafeAggregateDistinct "bit_and"
1483−
1484−-- | >>> :{
1485−-- let
1486−-- expression :: Expression commons schemas params (Grouped bys) '[tab ::: '["col" ::: nullity 'PGint4]] (nullity 'PGint4)
1487−-- expression = bitOrDistinct #col
1488−-- in printSQL expression
1489−-- :}
1490−-- bit_or(DISTINCT "col")
1491−bitOrDistinct
1492− :: int `In` PGIntegral
1493− => Expression commons schemas from 'Ungrouped params (nullity int)
1494− -- ^ what to aggregate
1495− -> Expression commons schemas from ('Grouped bys) params (nullity int)
1496−bitOrDistinct = unsafeAggregateDistinct "bit_or"
1497−
1498−-- | >>> :{
1499−-- let
1500−-- expression :: Expression commons schemas params (Grouped bys) '[tab ::: '["col" ::: nullity 'PGbool]] (nullity 'PGbool)
1501−-- expression = boolAnd #col
1502−-- in printSQL expression
1503−-- :}
1504−-- bool_and("col")
1505−boolAnd
1506− :: Expression commons schemas from 'Ungrouped params (nullity 'PGbool)
1507− -- ^ what to aggregate
1508− -> Expression commons schemas from ('Grouped bys) params (nullity 'PGbool)
1509−boolAnd = unsafeAggregate "bool_and"
1510−
1511−-- | >>> :{
1512−-- let
1513−-- expression :: Expression commons schemas params (Grouped bys) '[tab ::: '["col" ::: nullity 'PGbool]] (nullity 'PGbool)
1514−-- expression = boolOr #col
1515−-- in printSQL expression
1516−-- :}
1517−-- bool_or("col")
1518−boolOr
1519− :: Expression commons schemas from 'Ungrouped params (nullity 'PGbool)
1520− -- ^ what to aggregate
1521− -> Expression commons schemas from ('Grouped bys) params (nullity 'PGbool)
1522−boolOr = unsafeAggregate "bool_or"
1523−
1524−-- | >>> :{
1525−-- let
1526−-- expression :: Expression commons schemas params (Grouped bys) '[tab ::: '["col" ::: nullity 'PGbool]] (nullity 'PGbool)
1527−-- expression = boolAndDistinct #col
1528−-- in printSQL expression
1529−-- :}
1530−-- bool_and(DISTINCT "col")
1531−boolAndDistinct
1532− :: Expression commons schemas from 'Ungrouped params (nullity 'PGbool)
1533− -- ^ what to aggregate
1534− -> Expression commons schemas from ('Grouped bys) params (nullity 'PGbool)
1535−boolAndDistinct = unsafeAggregateDistinct "bool_and"
1536−
1537−-- | >>> :{
1538−-- let
1539−-- expression :: Expression commons schemas params (Grouped bys) '[tab ::: '["col" ::: nullity 'PGbool]] (nullity 'PGbool)
1540−-- expression = boolOrDistinct #col
1541−-- in printSQL expression
1542−-- :}
1543−-- bool_or(DISTINCT "col")
1544−boolOrDistinct
1545− :: Expression commons schemas from 'Ungrouped params (nullity 'PGbool)
1546− -- ^ what to aggregate
1547− -> Expression commons schemas from ('Grouped bys) params (nullity 'PGbool)
1548−boolOrDistinct = unsafeAggregateDistinct "bool_or"
1549−
1550−-- | A special aggregation that does not require an input
1551−--
1552−-- >>> printSQL countStar
1553−-- count(*)
1554−countStar
1555− :: Expression commons schemas from ('Grouped bys) params ('NotNull 'PGint8)
1556−countStar = UnsafeExpression $ "count(*)"
1557−
1558−-- | >>> :{
1559−-- let
1560−-- expression :: Expression commons schemas params (Grouped bys) '[tab ::: '["col" ::: nullity ty]] ('NotNull 'PGint8)
1561−-- expression = count #col
1562−-- in printSQL expression
1563−-- :}
1564−-- count("col")
1565−count
1566− :: Expression commons schemas from 'Ungrouped params ty
1567− -- ^ what to count
1568− -> Expression commons schemas from ('Grouped bys) params ('NotNull 'PGint8)
1569−count = unsafeAggregate "count"
1570−
1571−-- | >>> :{
1572−-- let
1573−-- expression :: Expression commons schemas params (Grouped bys) '[tab ::: '["col" ::: nullity ty]] ('NotNull 'PGint8)
1574−-- expression = countDistinct #col
1575−-- in printSQL expression
1576−-- :}
1577−-- count(DISTINCT "col")
1578−countDistinct
1579− :: Expression commons schemas from 'Ungrouped params ty
1580− -- ^ what to count
1581− -> Expression commons schemas from ('Grouped bys) params ('NotNull 'PGint8)
1582−countDistinct = unsafeAggregateDistinct "count"
1583−
1584−-- | synonym for `boolAnd`
1585−--
1586−-- >>> :{
1587−-- let
1588−-- expression :: Expression commons schemas params (Grouped bys) '[tab ::: '["col" ::: nullity 'PGbool]] (nullity 'PGbool)
1589−-- expression = every #col
1590−-- in printSQL expression
1591−-- :}
1592−-- every("col")
1593−every
1594− :: Expression commons schemas from 'Ungrouped params (nullity 'PGbool)
1595− -- ^ what to aggregate
1596− -> Expression commons schemas from ('Grouped bys) params (nullity 'PGbool)
1597−every = unsafeAggregate "every"
1598−
1599−-- | synonym for `boolAndDistinct`
1600−--
1601−-- >>> :{
1602−-- let
1603−-- expression :: Expression commons schemas params (Grouped bys) '[tab ::: '["col" ::: nullity 'PGbool]] (nullity 'PGbool)
1604−-- expression = everyDistinct #col
1605−-- in printSQL expression
1606−-- :}
1607−-- every(DISTINCT "col")
1608−everyDistinct
1609− :: Expression commons schemas from 'Ungrouped params (nullity 'PGbool)
1610− -- ^ what to aggregate
1611− -> Expression commons schemas from ('Grouped bys) params (nullity 'PGbool)
1612−everyDistinct = unsafeAggregateDistinct "every"
1613−
1614−-- | minimum and maximum aggregation
1615−max_, min_, maxDistinct, minDistinct
1616− :: Expression commons schemas from 'Ungrouped params (nullity ty)
1617− -- ^ what to aggregate
1618− -> Expression commons schemas from ('Grouped bys) params (nullity ty)
1619−max_ = unsafeAggregate "max"
1620−min_ = unsafeAggregate "min"
1621−maxDistinct = unsafeAggregateDistinct "max"
1622−minDistinct = unsafeAggregateDistinct "min"
1623−
1624−{-----------------------------------------
1625−type expressions
1626−-----------------------------------------}
1627−
1628−-- | `TypeExpression`s are used in `cast`s and `createTable` commands.
1629−newtype TypeExpression (schemas :: SchemasType) (ty :: NullityType)
1630− = UnsafeTypeExpression { renderTypeExpression :: ByteString }
1631− deriving (GHC.Generic,Show,Eq,Ord,NFData)
1632−instance RenderSQL (TypeExpression schemas ty) where
1633− renderSQL = renderTypeExpression
1634−
1635−-- | The enum or composite type in a `Typedef` can be expressed by its alias.
1636−typedef
1637− :: (Has sch schemas schema, Has td schema ('Typedef ty))
1638− => QualifiedAlias sch td
1639− -> TypeExpression schemas (nullity ty)
1640−typedef = UnsafeTypeExpression . renderSQL
1641−
1642−-- | The composite type corresponding to a `Table` definition can be expressed
1643−-- by its alias.
1644−typetable
1645− :: (Has sch schemas schema, Has tab schema ('Table table))
1646− => QualifiedAlias sch tab
1647− -> TypeExpression schemas (nullity ('PGcomposite (TableToRow table)))
1648−typetable = UnsafeTypeExpression . renderSQL
1649−
1650−-- | The composite type corresponding to a `View` definition can be expressed
1651−-- by its alias.
1652−typeview
1653− :: (Has sch schemas schema, Has vw schema ('View view))
1654− => QualifiedAlias sch vw
1655− -> TypeExpression schemas (nullity ('PGcomposite view))
1656−typeview = UnsafeTypeExpression . renderSQL
1657−
1658−-- | logical Boolean (true/false)
1659−bool :: TypeExpression schemas (nullity 'PGbool)
1660−bool = UnsafeTypeExpression "bool"
1661−-- | signed two-byte integer
1662−int2, smallint :: TypeExpression schemas (nullity 'PGint2)
1663−int2 = UnsafeTypeExpression "int2"
1664−smallint = UnsafeTypeExpression "smallint"
1665−-- | signed four-byte integer
1666−int4, int, integer :: TypeExpression schemas (nullity 'PGint4)
1667−int4 = UnsafeTypeExpression "int4"
1668−int = UnsafeTypeExpression "int"
1669−integer = UnsafeTypeExpression "integer"
1670−-- | signed eight-byte integer
1671−int8, bigint :: TypeExpression schemas (nullity 'PGint8)
1672−int8 = UnsafeTypeExpression "int8"
1673−bigint = UnsafeTypeExpression "bigint"
1674−-- | arbitrary precision numeric type
1675−numeric :: TypeExpression schemas (nullity 'PGnumeric)
1676−numeric = UnsafeTypeExpression "numeric"
1677−-- | single precision floating-point number (4 bytes)
1678−float4, real :: TypeExpression schemas (nullity 'PGfloat4)
1679−float4 = UnsafeTypeExpression "float4"
1680−real = UnsafeTypeExpression "real"
1681−-- | double precision floating-point number (8 bytes)
1682−float8, doublePrecision :: TypeExpression schemas (nullity 'PGfloat8)
1683−float8 = UnsafeTypeExpression "float8"
1684−doublePrecision = UnsafeTypeExpression "double precision"
1685−-- | variable-length character string
1686−text :: TypeExpression schemas (nullity 'PGtext)
1687−text = UnsafeTypeExpression "text"
1688−-- | fixed-length character string
1689−char, character
1690− :: forall n schemas nullity. (KnownNat n, 1 <= n)
1691− => TypeExpression schemas (nullity ('PGchar n))
1692−char = UnsafeTypeExpression $ "char(" <> renderNat @n <> ")"
1693−character = UnsafeTypeExpression $ "character(" <> renderNat @n <> ")"
1694−-- | variable-length character string
1695−varchar, characterVarying
1696− :: forall n schemas nullity. (KnownNat n, 1 <= n)
1697− => TypeExpression schemas (nullity ('PGvarchar n))
1698−varchar = UnsafeTypeExpression $ "varchar(" <> renderNat @n <> ")"
1699−characterVarying = UnsafeTypeExpression $
1700− "character varying(" <> renderNat @n <> ")"
1701−-- | binary data ("byte array")
1702−bytea :: TypeExpression schemas (nullity 'PGbytea)
1703−bytea = UnsafeTypeExpression "bytea"
1704−-- | date and time (no time zone)
1705−timestamp :: TypeExpression schemas (nullity 'PGtimestamp)
1706−timestamp = UnsafeTypeExpression "timestamp"
1707−-- | date and time, including time zone
1708−timestampWithTimeZone :: TypeExpression schemas (nullity 'PGtimestamptz)
1709−timestampWithTimeZone = UnsafeTypeExpression "timestamp with time zone"
1710−-- | calendar date (year, month, day)
1711−date :: TypeExpression schemas (nullity 'PGdate)
1712−date = UnsafeTypeExpression "date"
1713−-- | time of day (no time zone)
1714−time :: TypeExpression schemas (nullity 'PGtime)
1715−time = UnsafeTypeExpression "time"
1716−-- | time of day, including time zone
1717−timeWithTimeZone :: TypeExpression schemas (nullity 'PGtimetz)
1718−timeWithTimeZone = UnsafeTypeExpression "time with time zone"
1719−-- | time span
1720−interval :: TypeExpression schemas (nullity 'PGinterval)
1721−interval = UnsafeTypeExpression "interval"
1722−-- | universally unique identifier
1723−uuid :: TypeExpression schemas (nullity 'PGuuid)
1724−uuid = UnsafeTypeExpression "uuid"
1725−-- | IPv4 or IPv6 host address
1726−inet :: TypeExpression schemas (nullity 'PGinet)
1727−inet = UnsafeTypeExpression "inet"
1728−-- | textual JSON data
1729−json :: TypeExpression schemas (nullity 'PGjson)
1730−json = UnsafeTypeExpression "json"
1731−-- | binary JSON data, decomposed
1732−jsonb :: TypeExpression schemas (nullity 'PGjsonb)
1733−jsonb = UnsafeTypeExpression "jsonb"
1734−-- | variable length array
1735−vararray
1736− :: TypeExpression schemas pg
1737− -> TypeExpression schemas (nullity ('PGvararray pg))
1738−vararray ty = UnsafeTypeExpression $ renderSQL ty <> "[]"
1739−-- | fixed length array
1740−--
1741−-- >>> renderSQL (fixarray @2 json)
1742−-- "json[2]"
1743−fixarray
1744− :: forall n schemas nullity pg. KnownNat n
1745− => TypeExpression schemas pg
1746− -> TypeExpression schemas (nullity ('PGfixarray n pg))
1747−fixarray ty = UnsafeTypeExpression $
1748− renderSQL ty <> "[" <> renderNat @n <> "]"
1749−
1750−-- | `pgtype` is a demoted version of a `PGType`
1751−class PGTyped schemas (ty :: NullityType) where
1752− pgtype :: TypeExpression schemas ty
1753−instance PGTyped schemas (nullity 'PGbool) where pgtype = bool
1754−instance PGTyped schemas (nullity 'PGint2) where pgtype = int2
1755−instance PGTyped schemas (nullity 'PGint4) where pgtype = int4
1756−instance PGTyped schemas (nullity 'PGint8) where pgtype = int8
1757−instance PGTyped schemas (nullity 'PGnumeric) where pgtype = numeric
1758−instance PGTyped schemas (nullity 'PGfloat4) where pgtype = float4
1759−instance PGTyped schemas (nullity 'PGfloat8) where pgtype = float8
1760−instance PGTyped schemas (nullity 'PGtext) where pgtype = text
1761−instance (KnownNat n, 1 <= n)
1762− => PGTyped schemas (nullity ('PGchar n)) where pgtype = char @n
1763−instance (KnownNat n, 1 <= n)
1764− => PGTyped schemas (nullity ('PGvarchar n)) where pgtype = varchar @n
1765−instance PGTyped schemas (nullity 'PGbytea) where pgtype = bytea
1766−instance PGTyped schemas (nullity 'PGtimestamp) where pgtype = timestamp
1767−instance PGTyped schemas (nullity 'PGtimestamptz) where pgtype = timestampWithTimeZone
1768−instance PGTyped schemas (nullity 'PGdate) where pgtype = date
1769−instance PGTyped schemas (nullity 'PGtime) where pgtype = time
1770−instance PGTyped schemas (nullity 'PGtimetz) where pgtype = timeWithTimeZone
1771−instance PGTyped schemas (nullity 'PGinterval) where pgtype = interval
1772−instance PGTyped schemas (nullity 'PGuuid) where pgtype = uuid
1773−instance PGTyped schemas (nullity 'PGjson) where pgtype = json
1774−instance PGTyped schemas (nullity 'PGjsonb) where pgtype = jsonb
1775−instance PGTyped schemas ty
1776− => PGTyped schemas (nullity ('PGvararray ty)) where
1777− pgtype = vararray (pgtype @schemas @ty)
1778−instance (KnownNat n, PGTyped schemas ty)
1779− => PGTyped schemas (nullity ('PGfixarray n ty)) where
1780− pgtype = fixarray @n (pgtype @schemas @ty)