@@ -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
@@ -45,244 +44,35 @@ module Squeal.PostgreSQL.Expression
4544 , unsafeFunctionVar
4645 , FunctionN
4746 , unsafeFunctionN
48− , Literal (..)
49− , HasParameter (parameter)
50− , param
51− -- * Null
52− , null_
53− , notNull
54− , coalesce
55− , fromNull
56− , isNull
57− , isNotNull
58− , matchNull
59− , nullIf
60− -- * Collections
61− , array
62− , array1
63− , array2
64− , cardinality
65− , index
66− , row
67− , field
6847 , PGSubset (..)
69− -- * Numerical
70− , atan2_
71− , quot_
72− , rem_
73− , trunc
74− , round_
75− , ceiling_
76− -- * Logic
77− , Condition
78− , true
79− , false
80− , not_
81− , (.&&)
82− , (.||)
83− , caseWhenThenElse
84− , ifThenElse
85− -- * Comparison
86− , (.==)
87− , (./=)
88− , (.>=)
89− , (.<)
90− , (.<=)
91− , (.>)
92− , greatest
93− , least
94− , between
95− , notBetween
96− , betweenSymmetric
97− , notBetweenSymmetric
98− , isDistinctFrom
99− , isNotDistinctFrom
100− , isTrue
101− , isNotTrue
102− , isFalse
103− , isNotFalse
104− , isUnknown
105− , isNotUnknown
106− -- * Time
107− , TimeOp (..)
108− , currentDate
109− , currentTime
110− , currentTimestamp
111− , localTime
112− , localTimestamp
113− , now
114− , makeDate
115− , makeTime
116− , makeTimestamp
117− , makeTimestamptz
118− , interval_
119− , TimeUnit (..)
120− -- * Text
121− , lower
122− , upper
123− , charLength
124− , like
125− , ilike
126− -- * Json
127− -- ** Json and Jsonb operators
128− , (.->)
129− , (.->>)
130− , (.#>)
131− , (.#>>)
132− -- ** Jsonb operators
133− , (.?)
134− , (.?|)
135− , (.?&)
136− , (.-.)
137− , (#-.)
138− -- ** Functions
139− , toJson
140− , toJsonb
141− , arrayToJson
142− , rowToJson
143− , jsonBuildArray
144− , jsonbBuildArray
145− , PGBuildObject
146− , jsonBuildObject
147− , jsonbBuildObject
148− , jsonObject
149− , jsonbObject
150− , jsonZipObject
151− , jsonbZipObject
152− , jsonArrayLength
153− , jsonbArrayLength
154− , jsonExtractPath
155− , jsonbExtractPath
156− , jsonExtractPathAsText
157− , jsonbExtractPathAsText
158− , jsonTypeof
159− , jsonbTypeof
160− , jsonStripNulls
161− , jsonbStripNulls
162− , jsonbSet
163− , jsonbInsert
164− , jsonbPretty
165− -- * Text Search
166− , (@@)
167− , (.&)
168− , (.|)
169− , (.!)
170− , (<->)
171− , arrayToTSvector
172− , tsvectorLength
173− , numnode
174− , plainToTSquery
175− , phraseToTSquery
176− , websearchToTSquery
177− , queryTree
178− , toTSquery
179− , toTSvector
180− , setWeight
181− , strip
182− , jsonToTSvector
183− , jsonbToTSvector
184− , tsDelete
185− , tsFilter
186− , tsHeadline
187− -- * Aggregation
188− , Aggregate (..)
189− , Distinction (..)
190− , PGAvg
191− -- * Window Functions
192− , WindowDefinition (..)
193− , partitionBy
194− , WindowFunction (..)
195− , rank
196− , rowNumber
197− , denseRank
198− , percentRank
199− , cumeDist
200− , ntile
201− , lag
202− , lead
203− , firstValue
204− , lastValue
205− , nthValue
206− -- * Sorting
207− , SortExpression (..)
208− , OrderBy (..)
209− -- * Types
210− , TypeExpression (..)
211− , cast
212− , PGTyped (..)
213− , typedef
214− , typetable
215− , typeview
216− , bool
217− , int2
218− , smallint
219− , int4
220− , int
221− , integer
222− , int8
223− , bigint
224− , numeric
225− , float4
226− , real
227− , float8
228− , doublePrecision
229− , money
230− , text
231− , char
232− , character
233− , varchar
234− , characterVarying
235− , bytea
236− , timestamp
237− , timestampWithTimeZone
238− , date
239− , time
240− , timeWithTimeZone
241− , interval
242− , uuid
243− , inet
244− , json
245− , jsonb
246− , vararray
247− , fixarray
248− , tsvector
249− , tsquery
25048 -- * Re-export
25149 , (&)
252− , NP (..)
25350 , K (..)
51+ , unK
25452 ) where
25553
25654import Control.Category
25755import Control.DeepSeq
25856import Data.ByteString (ByteString)
259−import Data.ByteString.Lazy (toStrict)
260−import ByteString.StrictBuilder (builderBytes)
26157import Data.Function ((&))
262−import Data.Kind
26358import Data.Semigroup hiding (All)
264−import qualified Data.Aeson as JSON
265−import Data.Int
26659import Data.String
267−import Data.Text (Text)
268−import Data.Word
26960import Generics.SOP hiding (All, from)
27061import GHC.OverloadedLabels
27162import GHC.TypeLits
27263import Numeric
27364import Prelude hiding (id, (.))
27465
275−import qualified Data.ByteString as ByteString
276−import qualified Data.Text as Text
277−import qualified Data.Text.Lazy as Lazy (Text)
278−import qualified Data.Text.Lazy as Lazy.Text
27966import qualified GHC.Generics as GHC
280−import qualified Generics.SOP as SOP
28167
282−import Squeal.PostgreSQL.Binary
68+import Squeal.PostgreSQL.Alias
69+import Squeal.PostgreSQL.List
28370import Squeal.PostgreSQL.Render
28471import Squeal.PostgreSQL.Schema
28572
73+-- $setup
74+-- >>> import Squeal.PostgreSQL
75+
28676{-----------------------------------------
28777column expressions
28878-----------------------------------------}
@@ -292,7 +82,7 @@ such as in the target `Squeal.PostgreSQL.Query.List` of the
29282`Squeal.PostgreSQL.Query.select` command,
29383as new column values in `Squeal.PostgreSQL.Manipulation.insertRow` or
29484`Squeal.PostgreSQL.Manipulation.update`,
295−or in search `Condition`s in a number of commands.
85+or in search `Squeal.PostgreSQL.Logic.Condition`s in a number of commands.
29686
29787The expression syntax allows the calculation of
29888values from primitive expression using arithmetic, logical,
@@ -326,7 +116,7 @@ instance RenderSQL (Expression outer commons grp schemas params from ty) where
326116 renderSQL = renderExpression
327117
328118-- | An `Expr` is a closed `Expression`.
329−-- It is a F`RankNType` but don't be scared.
119+-- It is a F@RankNType@ but don't be scared.
330120-- Think of it as an expression which sees no
331121-- namespaces, so you can't use parameters
332122-- or alias references. It can be used as
@@ -336,7 +126,7 @@ type Expr x
336126 . Expression outer commons grp schemas params from x
337127 -- ^ cannot reference aliases
338128
339−-- | A `RankNType` for binary operators.
129+-- | A @RankNType@ for binary operators.
340130type Operator x1 x2 y
341131 = forall outer commons grp schemas params from
342132 . Expression outer commons grp schemas params from x1
@@ -346,7 +136,7 @@ type Operator x1 x2 y
346136 -> Expression outer commons grp schemas params from y
347137 -- ^ output
348138
349−-- | A `RankNType` for functions with a single argument.
139+-- | A @RankNType@ for functions with a single argument.
350140-- These could be either function calls or unary operators.
351141-- This is a subtype of the usual Haskell function type `Prelude.->`,
352142-- indeed a subcategory as it is closed under the usual
@@ -358,7 +148,7 @@ type (:-->) x y
358148 -> Expression outer commons grp schemas params from y
359149 -- ^ output
360150
361−{- | A `RankNType` for functions with a fixed-length list of heterogeneous arguments.
151+{- | A @RankNType@ for functions with a fixed-length list of heterogeneous arguments.
362152Use the `*:` operator to end your argument lists, like so.
363153
364154>>> printSQL (unsafeFunctionN "fun" (true :* false :* localTime *: true))
@@ -371,7 +161,7 @@ type FunctionN xs y
371161 -> Expression outer commons grp schemas params from y
372162 -- ^ output
373163
374−{- | A `RankNType` for functions with a variable-length list of
164+{- | A @RankNType@ for functions with a variable-length list of
375165homogeneous arguments and at least 1 more argument.
376166-}
377167type FunctionVar x0 x1 y
@@ -390,46 +180,6 @@ unsafeFunctionVar :: ByteString -> FunctionVar x0 x1 y
390180unsafeFunctionVar fun xs x = UnsafeExpression $ fun <> parenthesized
391181 (commaSeparated (renderSQL <$> xs) <> ", " <> renderSQL x)
392182
393−{- | A `HasParameter` constraint is used to indicate a value that is
394−supplied externally to a SQL statement.
395−`Squeal.PostgreSQL.PQ.manipulateParams`,
396−`Squeal.PostgreSQL.PQ.queryParams` and
397−`Squeal.PostgreSQL.PQ.traversePrepared` support specifying data values
398−separately from the SQL command string, in which case `param`s are used to
399−refer to the out-of-line data values.
400−-}
401−class KnownNat n => HasParameter
402− (n :: Nat)
403− (params :: [NullityType])
404− (ty :: NullityType)
405− | n params -> ty where
406− -- | `parameter` takes a `Nat` using type application and a `TypeExpression`.
407− --
408− -- >>> let expr = parameter @1 int4 :: Expression outer '[] grp schemas '[ 'Null 'PGint4] from ('Null 'PGint4)
409− -- >>> printSQL expr
410− -- ($1 :: int4)
411− parameter
412− :: TypeExpression schemas ty
413− -> Expression outer commons grp schemas params from ty
414− parameter ty = UnsafeExpression $ parenthesized $
415− "$" <> renderNat @n <+> "::"
416− <+> renderSQL ty
417−instance {-# OVERLAPPING #-} HasParameter 1 (ty1:tys) ty1
418−instance {-# OVERLAPPABLE #-} (KnownNat n, HasParameter (n-1) params ty)
419− => HasParameter n (ty' : params) ty
420−
421−-- | `param` takes a `Nat` using type application and for basic types,
422−-- infers a `TypeExpression`.
423−--
424−-- >>> let expr = param @1 :: Expression outer commons grp schemas '[ 'Null 'PGint4] from ('Null 'PGint4)
425−-- >>> printSQL expr
426−-- ($1 :: int4)
427−param
428− :: forall n outer commons schemas params from grp ty
429− . (PGTyped schemas ty, HasParameter n params ty)
430− => Expression outer commons grp schemas params from ty -- ^ param
431−param = parameter @n (pgtype @schemas)
432−
433183instance (HasUnique tab (Join outer from) row, Has col row ty)
434184 => IsLabel col (Expression outer commons 'Ungrouped schemas params from ty) where
435185 fromLabel = UnsafeExpression $ renderSQL (Alias @col)
@@ -526,214 +276,10 @@ instance
526276 (NP (Aliased (Expression outer commons ('Grouped bys) schemas params from)) columns) where
527277 tab ! col = tab ! col :* Nil
528278
529−-- | analagous to `Nothing`
530−--
531−-- >>> printSQL null_
532−-- NULL
533−null_ :: Expr ('Null ty)
534−null_ = UnsafeExpression "NULL"
535−
536−-- | analagous to `Just`
537−--
538−-- >>> printSQL $ notNull true
539−-- TRUE
540−notNull :: 'NotNull ty :--> 'Null ty
541−notNull = UnsafeExpression . renderSQL
542−
543−-- | return the leftmost value which is not NULL
544−--
545−-- >>> printSQL $ coalesce [null_, true] false
546−-- COALESCE(NULL, TRUE, FALSE)
547−coalesce :: FunctionVar ('Null ty) ('NotNull ty) ('NotNull ty)
548−coalesce nullxs notNullx = UnsafeExpression $
549− "COALESCE" <> parenthesized (commaSeparated
550− ((renderSQL <$> nullxs) <> [renderSQL notNullx]))
551−
552−-- | analagous to `Data.Maybe.fromMaybe` using @COALESCE@
553−--
554−-- >>> printSQL $ fromNull true null_
555−-- COALESCE(NULL, TRUE)
556−fromNull
557− :: Expression outer commons grp schemas params from ('NotNull ty)
558− -- ^ what to convert @NULL@ to
559− -> Expression outer commons grp schemas params from ('Null ty)
560− -> Expression outer commons grp schemas params from ('NotNull ty)
561−fromNull notNullx nullx = coalesce [nullx] notNullx
562−
563−-- | >>> printSQL $ null_ & isNull
564−-- NULL IS NULL
565−isNull :: 'Null ty :--> null 'PGbool
566−isNull x = UnsafeExpression $ renderSQL x <+> "IS NULL"
567−
568−-- | >>> printSQL $ null_ & isNotNull
569−-- NULL IS NOT NULL
570−isNotNull :: 'Null ty :--> null 'PGbool
571−isNotNull x = UnsafeExpression $ renderSQL x <+> "IS NOT NULL"
572−
573−-- | analagous to `maybe` using @IS NULL@
574−--
575−-- >>> printSQL $ matchNull true not_ null_
576−-- CASE WHEN NULL IS NULL THEN TRUE ELSE (NOT NULL) END
577−matchNull
578− :: Expression outer commons grp schemas params from (nullty)
579− -- ^ what to convert @NULL@ to
580− -> ( Expression outer commons grp schemas params from ('NotNull ty)
581− -> Expression outer commons grp schemas params from (nullty) )
582− -- ^ function to perform when @NULL@ is absent
583− -> Expression outer commons grp schemas params from ('Null ty)
584− -> Expression outer commons grp schemas params from (nullty)
585−matchNull y f x = ifThenElse (isNull x) y
586− (f (UnsafeExpression (renderSQL x)))
587−
588−{-| right inverse to `fromNull`, if its arguments are equal then
589−`nullIf` gives @NULL@.
590−
591−>>> :set -XTypeApplications -XDataKinds
592−>>> let expr = nullIf (false *: param @1) :: Expression outer commons grp schemas '[ 'NotNull 'PGbool] from ('Null 'PGbool)
593−>>> printSQL expr
594−NULLIF(FALSE, ($1 :: bool))
595−-}
596−nullIf :: FunctionN '[ 'NotNull ty, 'NotNull ty] ('Null ty)
597−nullIf = unsafeFunctionN "NULLIF"
598−
599−-- | >>> printSQL $ array [null_, false, true]
600−-- ARRAY[NULL, FALSE, TRUE]
601−array
602− :: [Expression outer commons grp schemas params from ty]
603− -- ^ array elements
604− -> Expression outer commons grp schemas params from (null ('PGvararray ty))
605−array xs = UnsafeExpression $ "ARRAY" <>
606− bracketed (commaSeparated (renderSQL <$> xs))
607−
608−{- | construct a 1-dimensional fixed length array
609−
610−>>> printSQL $ array1 (null_ :* false *: true)
611−ARRAY[NULL, FALSE, TRUE]
612−
613−>>> :type array1 (null_ :* false *: true)
614−array1 (null_ :* false *: true)
615− :: Expression
616− outer
617− commons
618− grp
619− schemas
620− params
621− from
622− (null ('PGfixarray '[3] ('Null 'PGbool)))
623−-}
624−array1
625− :: (n ~ Length tys, SOP.All ((~) ty) tys)
626− => NP (Expression outer commons grp schemas params from) tys
627− -> Expression outer commons grp schemas params from (null ('PGfixarray '[n] ty))
628−array1 xs = UnsafeExpression $ "ARRAY" <>
629− bracketed (renderCommaSeparated renderSQL xs)
630−
631−{- | construct a 2-dimensional fixed length array
632−
633−>>> printSQL $ array2 ((null_ :* false *: true) *: (false :* null_ *: true))
634−ARRAY[[NULL, FALSE, TRUE], [FALSE, NULL, TRUE]]
635−
636−>>> :type array2 ((null_ :* false *: true) *: (false :* null_ *: true))
637−array2 ((null_ :* false *: true) *: (false :* null_ *: true))
638− :: Expression
639− outer
640− commons
641− grp
642− schemas
643− params
644− from
645− (null ('PGfixarray '[2, 3] ('Null 'PGbool)))
646−-}
647−array2
648− :: ( SOP.All ((~) tys) tyss
649− , SOP.All SOP.SListI tyss
650− , Length tyss ~ n1
651− , SOP.All ((~) ty) tys
652− , Length tys ~ n2 )
653− => NP (NP (Expression outer commons grp schemas params from)) tyss
654− -> Expression outer commons grp schemas params from (null ('PGfixarray '[n1,n2] ty))
655−array2 xss = UnsafeExpression $ "ARRAY" <>
656− bracketed (renderCommaSeparatedConstraint @SOP.SListI (bracketed . renderCommaSeparated renderSQL) xss)
657−
658−-- | >>> printSQL $ cardinality (array [null_, false, true])
659−-- cardinality(ARRAY[NULL, FALSE, TRUE])
660−cardinality :: null ('PGvararray ty) :--> null 'PGint8
661−cardinality = unsafeFunction "cardinality"
662−
663−-- | >>> printSQL $ array [null_, false, true] & index 2
664−-- (ARRAY[NULL, FALSE, TRUE])[2]
665−index
666− :: Word64 -- ^ index
667− -> null ('PGvararray ty) :--> NullifyType ty
668−index n expr = UnsafeExpression $
669− parenthesized (renderSQL expr) <> "[" <> fromString (show n) <> "]"
670−
671279instance (KnownSymbol label, label `In` labels) => IsPGlabel label
672280 (Expression outer commons grp schemas params from (null ('PGenum labels))) where
673281 label = UnsafeExpression $ renderSQL (PGlabel @label)
674282
675−-- | A row constructor is an expression that builds a row value
676−-- (also called a composite value) using values for its member fields.
677−--
678−-- >>> :{
679−-- type Complex = 'PGcomposite
680−-- '[ "real" ::: 'NotNull 'PGfloat8
681−-- , "imaginary" ::: 'NotNull 'PGfloat8 ]
682−-- :}
683−--
684−-- >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression outer commons grp schemas params from ('NotNull Complex)
685−-- >>> printSQL i
686−-- ROW(0, 1)
687−row
688− :: SListI row
689− => NP (Aliased (Expression outer commons grp schemas params from)) row
690− -- ^ zero or more expressions for the row field values
691− -> Expression outer commons grp schemas params from (null ('PGcomposite row))
692−row exprs = UnsafeExpression $ "ROW" <> parenthesized
693− (renderCommaSeparated (\ (expr `As` _) -> renderSQL expr) exprs)
694−
695−-- | >>> :{
696−-- type Complex = 'PGcomposite
697−-- '[ "real" ::: 'NotNull 'PGfloat8
698−-- , "imaginary" ::: 'NotNull 'PGfloat8 ]
699−-- type Schema = '["complex" ::: 'Typedef Complex]
700−-- :}
701−--
702−-- >>> let i = row (0 `as` #real :* 1 `as` #imaginary) :: Expression outer '[] grp (Public Schema) from params ('NotNull Complex)
703−-- >>> printSQL $ i & field #complex #imaginary
704−-- (ROW(0, 1)::"complex")."imaginary"
705−field
706− :: ( Has sch schemas schema
707− , Has tydef schema ('Typedef ('PGcomposite row))
708− , Has field row ty)
709− => QualifiedAlias sch tydef -- ^ row type
710− -> Alias field -- ^ field name
711− -> Expression outer commons grp schemas params from ('NotNull ('PGcomposite row))
712− -> Expression outer commons grp schemas params from ty
713−field td fld expr = UnsafeExpression $
714− parenthesized (renderSQL expr <> "::" <> renderSQL td)
715− <> "." <> renderSQL fld
716−
717−instance Semigroup
718− (Expression outer commons grp schemas params from (null ('PGvararray ty))) where
719− (<>) = unsafeBinaryOp "||"
720−
721−instance Monoid
722− (Expression outer commons grp schemas params from (null ('PGvararray ty))) where
723− mempty = array []
724− mappend = (<>)
725−
726−-- | >>> let expr = greatest [param @1] currentTimestamp :: Expression outer commons grp schemas '[ 'NotNull 'PGtimestamptz] from ('NotNull 'PGtimestamptz)
727−-- >>> printSQL expr
728−-- GREATEST(($1 :: timestamp with time zone), CURRENT_TIMESTAMP)
729−greatest :: FunctionVar ty ty ty
730−greatest = unsafeFunctionVar "GREATEST"
731−
732−-- | >>> printSQL $ least [null_] currentTimestamp
733−-- LEAST(NULL, CURRENT_TIMESTAMP)
734−least :: FunctionVar ty ty ty
735−least = unsafeFunctionVar "LEAST"
736−
737283-- | >>> printSQL $ unsafeBinaryOp "OR" true false
738284-- (TRUE OR FALSE)
739285unsafeBinaryOp :: ByteString -> Operator ty0 ty1 ty2
@@ -806,364 +352,15 @@ instance (ty `In` PGNum, ty `In` PGFloating) => Floating
806352 acosh x = log (x + sqrt (x*x - 1))
807353 atanh x = log ((1 + x) / (1 - x)) / 2
808354
809−-- | >>> :{
810−-- let
811−-- expression :: Expr (null 'PGfloat4)
812−-- expression = atan2_ (pi *: 2)
813−-- in printSQL expression
814−-- :}
815−-- atan2(pi(), 2)
816−atan2_
817− :: float `In` PGFloating
818− => FunctionN '[ null float, null float] (null float)
819−atan2_ = unsafeFunctionN "atan2"
820−
821−-- When a `cast` is applied to an `Expression` of a known type, it
822−-- represents a run-time type conversion. The cast will succeed only if a
823−-- suitable type conversion operation has been defined.
824−--
825−-- | >>> printSQL $ true & cast int4
826−-- (TRUE :: int4)
827−cast
828− :: TypeExpression schemas ty1
829− -- ^ type to cast as
830− -> Expression outer commons grp schemas params from ty0
831− -- ^ value to convert
832− -> Expression outer commons grp schemas params from ty1
833−cast ty x = UnsafeExpression $ parenthesized $
834− renderSQL x <+> "::" <+> renderSQL ty
835−
836−-- | integer division, truncates the result
837−--
838−-- >>> :{
839−-- let
840−-- expression :: Expression outer commons grp schemas params from (null 'PGint2)
841−-- expression = 5 `quot_` 2
842−-- in printSQL expression
843−-- :}
844−-- (5 / 2)
845−quot_
846− :: int `In` PGIntegral
847− => Operator (null int) (null int) (null int)
848−quot_ = unsafeBinaryOp "/"
849−
850−-- | remainder upon integer division
851−--
852−-- >>> :{
853−-- let
854−-- expression :: Expression outer commons grp schemas params from (null 'PGint2)
855−-- expression = 5 `rem_` 2
856−-- in printSQL expression
857−-- :}
858−-- (5 % 2)
859−rem_
860− :: int `In` PGIntegral
861− => Operator (null int) (null int) (null int)
862−rem_ = unsafeBinaryOp "%"
863−
864−-- | >>> :{
865−-- let
866−-- expression :: Expression outer commons grp schemas params from (null 'PGfloat4)
867−-- expression = trunc pi
868−-- in printSQL expression
869−-- :}
870−-- trunc(pi())
871−trunc :: frac `In` PGFloating => null frac :--> null frac
872−trunc = unsafeFunction "trunc"
873−
874−-- | >>> :{
875−-- let
876−-- expression :: Expression outer commons grp schemas params from (null 'PGfloat4)
877−-- expression = round_ pi
878−-- in printSQL expression
879−-- :}
880−-- round(pi())
881−round_ :: frac `In` PGFloating => null frac :--> null frac
882−round_ = unsafeFunction "round"
883−
884−-- | >>> :{
885−-- let
886−-- expression :: Expression outer commons grp schemas params from (null 'PGfloat4)
887−-- expression = ceiling_ pi
888−-- in printSQL expression
889−-- :}
890−-- ceiling(pi())
891−ceiling_ :: frac `In` PGFloating => null frac :--> null frac
892−ceiling_ = unsafeFunction "ceiling"
893−
894−-- | A `Condition` is an `Expression`, which can evaluate
895−-- to `true`, `false` or `null_`. This is because SQL uses
896−-- a three valued logic.
897−type Condition outer commons grp schemas params from =
898− Expression outer commons grp schemas params from ('Null 'PGbool)
899−
900−-- | >>> printSQL true
901−-- TRUE
902−true :: Expr (null 'PGbool)
903−true = UnsafeExpression "TRUE"
904−
905−-- | >>> printSQL false
906−-- FALSE
907−false :: Expr (null 'PGbool)
908−false = UnsafeExpression "FALSE"
909−
910−-- | >>> printSQL $ not_ true
911−-- (NOT TRUE)
912−not_ :: null 'PGbool :--> null 'PGbool
913−not_ = unsafeUnaryOpL "NOT"
914−
915−-- | >>> printSQL $ true .&& false
916−-- (TRUE AND FALSE)
917−(.&&) :: Operator (null 'PGbool) (null 'PGbool) (null 'PGbool)
918−infixr 3 .&&
919−(.&&) = unsafeBinaryOp "AND"
920−
921−-- | >>> printSQL $ true .|| false
922−-- (TRUE OR FALSE)
923−(.||) :: Operator (null 'PGbool) (null 'PGbool) (null 'PGbool)
924−infixr 2 .||
925−(.||) = unsafeBinaryOp "OR"
926−
927−-- | >>> :{
928−-- let
929−-- expression :: Expression outer commons grp schemas params from (null 'PGint2)
930−-- expression = caseWhenThenElse [(true, 1), (false, 2)] 3
931−-- in printSQL expression
932−-- :}
933−-- CASE WHEN TRUE THEN 1 WHEN FALSE THEN 2 ELSE 3 END
934−caseWhenThenElse
935− :: [ ( Condition outer commons grp schemas params from
936− , Expression outer commons grp schemas params from ty
937− ) ]
938− -- ^ whens and thens
939− -> Expression outer commons grp schemas params from ty
940− -- ^ else
941− -> Expression outer commons grp schemas params from ty
942−caseWhenThenElse whenThens else_ = UnsafeExpression $ mconcat
943− [ "CASE"
944− , mconcat
945− [ mconcat
946− [ " WHEN ", renderSQL when_
947− , " THEN ", renderSQL then_
948− ]
949− | (when_,then_) <- whenThens
950− ]
951− , " ELSE ", renderSQL else_
952− , " END"
953− ]
954−
955−-- | >>> :{
956−-- let
957−-- expression :: Expression outer commons grp schemas params from (null 'PGint2)
958−-- expression = ifThenElse true 1 0
959−-- in printSQL expression
960−-- :}
961−-- CASE WHEN TRUE THEN 1 ELSE 0 END
962−ifThenElse
963− :: Condition outer commons grp schemas params from
964− -> Expression outer commons grp schemas params from ty -- ^ then
965− -> Expression outer commons grp schemas params from ty -- ^ else
966− -> Expression outer commons grp schemas params from ty
967−ifThenElse if_ then_ else_ = caseWhenThenElse [(if_,then_)] else_
968−
969−-- | Comparison operations like `.==`, `./=`, `.>`, `.>=`, `.<` and `.<=`
970−-- will produce @NULL@s if one of their arguments is @NULL@.
971−--
972−-- >>> printSQL $ true .== null_
973−-- (TRUE = NULL)
974−(.==) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
975−(.==) = unsafeBinaryOp "="
976−infix 4 .==
977−
978−-- | >>> printSQL $ true ./= null_
979−-- (TRUE <> NULL)
980−(./=) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
981−(./=) = unsafeBinaryOp "<>"
982−infix 4 ./=
983−
984−-- | >>> printSQL $ true .>= null_
985−-- (TRUE >= NULL)
986−(.>=) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
987−(.>=) = unsafeBinaryOp ">="
988−infix 4 .>=
989−
990−-- | >>> printSQL $ true .< null_
991−-- (TRUE < NULL)
992−(.<) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
993−(.<) = unsafeBinaryOp "<"
994−infix 4 .<
995−
996−-- | >>> printSQL $ true .<= null_
997−-- (TRUE <= NULL)
998−(.<=) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
999−(.<=) = unsafeBinaryOp "<="
1000−infix 4 .<=
1001−
1002−-- | >>> printSQL $ true .> null_
1003−-- (TRUE > NULL)
1004−(.>) :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
1005−(.>) = unsafeBinaryOp ">"
1006−infix 4 .>
1007−
1008−{- | >>> printSQL $ true `between` (null_, false)
1009−TRUE BETWEEN NULL AND FALSE
1010−-}
1011−between
1012− :: Expression outer commons grp schemas params from (null ty)
1013− -> ( Expression outer commons grp schemas params from (null ty)
1014− , Expression outer commons grp schemas params from (null ty) ) -- ^ bounds
1015− -> Condition outer commons grp schemas params from
1016−between a (x,y) = UnsafeExpression $ renderSQL a <+> "BETWEEN"
1017− <+> renderSQL x <+> "AND" <+> renderSQL y
1018−
1019−{- | >>> printSQL $ true `notBetween` (null_, false)
1020−TRUE NOT BETWEEN NULL AND FALSE
1021−-}
1022−notBetween
1023− :: Expression outer commons grp schemas params from (null ty)
1024− -> ( Expression outer commons grp schemas params from (null ty)
1025− , Expression outer commons grp schemas params from (null ty) ) -- ^ bounds
1026− -> Condition outer commons grp schemas params from
1027−notBetween a (x,y) = UnsafeExpression $ renderSQL a <+> "NOT BETWEEN"
1028− <+> renderSQL x <+> "AND" <+> renderSQL y
1029−
1030−{- | between, after sorting the comparison values
1031−
1032−>>> printSQL $ true `betweenSymmetric` (null_, false)
1033−TRUE BETWEEN SYMMETRIC NULL AND FALSE
1034−-}
1035−betweenSymmetric
1036− :: Expression outer commons grp schemas params from (null ty)
1037− -> ( Expression outer commons grp schemas params from (null ty)
1038− , Expression outer commons grp schemas params from (null ty) ) -- ^ bounds
1039− -> Condition outer commons grp schemas params from
1040−betweenSymmetric a (x,y) = UnsafeExpression $ renderSQL a
1041− <+> "BETWEEN SYMMETRIC" <+> renderSQL x <+> "AND" <+> renderSQL y
1042−
1043−{- | not between, after sorting the comparison values
1044−
1045−>>> printSQL $ true `notBetweenSymmetric` (null_, false)
1046−TRUE NOT BETWEEN SYMMETRIC NULL AND FALSE
1047−-}
1048−notBetweenSymmetric
1049− :: Expression outer commons grp schemas params from (null ty)
1050− -> ( Expression outer commons grp schemas params from (null ty)
1051− , Expression outer commons grp schemas params from (null ty) ) -- ^ bounds
1052− -> Condition outer commons grp schemas params from
1053−notBetweenSymmetric a (x,y) = UnsafeExpression $ renderSQL a
1054− <+> "NOT BETWEEN SYMMETRIC" <+> renderSQL x <+> "AND" <+> renderSQL y
1055−
1056−{- | not equal, treating null like an ordinary value
1057−
1058−>>> printSQL $ true `isDistinctFrom` null_
1059−(TRUE IS DISTINCT FROM NULL)
1060−-}
1061−isDistinctFrom :: Operator (null0 ty) (null1 ty) ('Null 'PGbool)
1062−isDistinctFrom = unsafeBinaryOp "IS DISTINCT FROM"
1063−
1064−{- | equal, treating null like an ordinary value
1065−
1066−>>> printSQL $ true `isNotDistinctFrom` null_
1067−(TRUE IS NOT DISTINCT FROM NULL)
1068−-}
1069−isNotDistinctFrom :: Operator (null0 ty) (null1 ty) ('NotNull 'PGbool)
1070−isNotDistinctFrom = unsafeBinaryOp "IS NOT DISTINCT FROM"
1071−
1072−{- | is true
1073−
1074−>>> printSQL $ true & isTrue
1075−(TRUE IS TRUE)
1076−-}
1077−isTrue :: null0 'PGbool :--> null1 'PGbool
1078−isTrue = unsafeUnaryOpR "IS TRUE"
1079−
1080−{- | is false or unknown
1081−
1082−>>> printSQL $ true & isNotTrue
1083−(TRUE IS NOT TRUE)
1084−-}
1085−isNotTrue :: null0 'PGbool :--> null1 'PGbool
1086−isNotTrue = unsafeUnaryOpR "IS NOT TRUE"
1087−
1088−{- | is false
1089−
1090−>>> printSQL $ true & isFalse
1091−(TRUE IS FALSE)
1092−-}
1093−isFalse :: null0 'PGbool :--> null1 'PGbool
1094−isFalse = unsafeUnaryOpR "IS FALSE"
1095−
1096−{- | is true or unknown
1097−
1098−>>> printSQL $ true & isNotFalse
1099−(TRUE IS NOT FALSE)
1100−-}
1101−isNotFalse :: null0 'PGbool :--> null1 'PGbool
1102−isNotFalse = unsafeUnaryOpR "IS NOT FALSE"
1103−
1104−{- | is unknown
1105−
1106−>>> printSQL $ true & isUnknown
1107−(TRUE IS UNKNOWN)
1108−-}
1109−isUnknown :: null0 'PGbool :--> null1 'PGbool
1110−isUnknown = unsafeUnaryOpR "IS UNKNOWN"
1111−
1112−{- | is true or false
1113−
1114−>>> printSQL $ true & isNotUnknown
1115−(TRUE IS NOT UNKNOWN)
1116−-}
1117−isNotUnknown :: null0 'PGbool :--> null1 'PGbool
1118−isNotUnknown = unsafeUnaryOpR "IS NOT UNKNOWN"
1119−
1120−-- | >>> printSQL currentDate
1121−-- CURRENT_DATE
1122−currentDate :: Expr (null 'PGdate)
1123−currentDate = UnsafeExpression "CURRENT_DATE"
1124−
1125−-- | >>> printSQL currentTime
1126−-- CURRENT_TIME
1127−currentTime :: Expr (null 'PGtimetz)
1128−currentTime = UnsafeExpression "CURRENT_TIME"
1129−
1130−-- | >>> printSQL currentTimestamp
1131−-- CURRENT_TIMESTAMP
1132−currentTimestamp :: Expr (null 'PGtimestamptz)
1133−currentTimestamp = UnsafeExpression "CURRENT_TIMESTAMP"
1134−
1135−-- | >>> printSQL localTime
1136−-- LOCALTIME
1137−localTime :: Expr (null 'PGtime)
1138−localTime = UnsafeExpression "LOCALTIME"
1139−
1140−-- | >>> printSQL localTimestamp
1141−-- LOCALTIMESTAMP
1142−localTimestamp :: Expr (null 'PGtimestamp)
1143−localTimestamp = UnsafeExpression "LOCALTIMESTAMP"
1144−
1145−-- | Current date and time (equivalent to `currentTimestamp`)
1146−--
1147−-- >>> printSQL now
1148−-- now()
1149−now :: Expr (null 'PGtimestamptz)
1150−now = UnsafeExpression "now()"
1151−
1152−{-----------------------------------------
1153−text
1154−-----------------------------------------}
1155−
1156−escape :: Char -> String
1157−escape = \case
1158− '\NUL' -> "\\0"
1159− '\'' -> "''"
1160− '"' -> "\\\""
1161− '\b' -> "\\b"
1162− '\n' -> "\\n"
1163− '\r' -> "\\r"
1164− '\t' -> "\\t"
1165− '\\' -> "\\\\"
1166− c -> [c]
355+-- | Contained by operators
356+class PGSubset container where
357+ (@>) :: Operator (null0 container) (null1 container) ('Null 'PGbool)
358+ (@>) = unsafeBinaryOp "@>"
359+ (<@) :: Operator (null0 container) (null1 container) ('Null 'PGbool)
360+ (<@) = unsafeBinaryOp "<@"
361+instance PGSubset 'PGjsonb
362+instance PGSubset 'PGtsquery
363+instance PGSubset ('PGvararray ty)
1167364
1168365instance IsString
1169366 (Expression outer commons grp schemas params from (null 'PGtext)) where
@@ -1171,13 +368,19 @@ instance IsString
1171368 "E\'" <> fromString (escape =<< str) <> "\'"
1172369instance IsString
1173370 (Expression outer commons grp schemas params from (null 'PGtsvector)) where
1174− fromString str = cast tsvector . UnsafeExpression $
371+ fromString str = UnsafeExpression . parenthesized . (<> " :: tsvector") $
1175372 "E\'" <> fromString (escape =<< str) <> "\'"
1176373instance IsString
1177374 (Expression outer commons grp schemas params from (null 'PGtsquery)) where
1178− fromString str = cast tsquery . UnsafeExpression $
375+ fromString str = UnsafeExpression . parenthesized . (<> " :: tsquery") $
1179376 "E\'" <> fromString (escape =<< str) <> "\'"
1180377
378+instance Semigroup
379+ (Expression outer commons grp schemas params from (null ('PGvararray ty))) where
380+ (<>) = unsafeBinaryOp "||"
381+instance Semigroup
382+ (Expression outer commons grp schemas params from (null 'PGjsonb)) where
383+ (<>) = unsafeBinaryOp "||"
1181384instance Semigroup
1182385 (Expression outer commons grp schemas params from (null 'PGtext)) where
1183386 (<>) = unsafeBinaryOp "||"
@@ -1193,1399 +396,3 @@ instance Monoid
1193396 (Expression outer commons grp schemas params from (null 'PGtsvector)) where
1194397 mempty = fromString ""
1195398 mappend = (<>)
1196−
1197−-- | >>> printSQL $ lower "ARRRGGG"
1198−-- lower(E'ARRRGGG')
1199−lower :: null 'PGtext :--> null 'PGtext
1200−lower = unsafeFunction "lower"
1201−
1202−-- | >>> printSQL $ upper "eeee"
1203−-- upper(E'eeee')
1204−upper :: null 'PGtext :--> null 'PGtext
1205−upper = unsafeFunction "upper"
1206−
1207−-- | >>> printSQL $ charLength "four"
1208−-- char_length(E'four')
1209−charLength :: null 'PGtext :--> null 'PGint4
1210−charLength = unsafeFunction "char_length"
1211−
1212−-- | The `like` expression returns true if the @string@ matches
1213−-- the supplied @pattern@. If @pattern@ does not contain percent signs
1214−-- or underscores, then the pattern only represents the string itself;
1215−-- in that case `like` acts like the equals operator. An underscore (_)
1216−-- in pattern stands for (matches) any single character; a percent sign (%)
1217−-- matches any sequence of zero or more characters.
1218−--
1219−-- >>> printSQL $ "abc" `like` "a%"
1220−-- (E'abc' LIKE E'a%')
1221−like :: Operator (null 'PGtext) (null 'PGtext) ('Null 'PGbool)
1222−like = unsafeBinaryOp "LIKE"
1223−
1224−-- | The key word ILIKE can be used instead of LIKE to make the
1225−-- match case-insensitive according to the active locale.
1226−--
1227−-- >>> printSQL $ "abc" `ilike` "a%"
1228−-- (E'abc' ILIKE E'a%')
1229−ilike :: Operator (null 'PGtext) (null 'PGtext) ('Null 'PGbool)
1230−ilike = unsafeBinaryOp "ILIKE"
1231−
1232−{-----------------------------------------
1233− -- json and jsonb support
1234−
1235−See https://www.postgresql.org/docs/10/static/functions-json.html -- most
1236−comments lifted directly from this page.
1237−
1238−Table 9.44: json and jsonb operators
1239−-----------------------------------------}
1240−
1241−-- | Get JSON value (object field or array element) at a key.
1242−(.->)
1243− :: (json `In` PGJsonType, key `In` PGJsonKey)
1244− => Operator (null json) (null key) ('Null json)
1245−infixl 8 .->
1246−(.->) = unsafeBinaryOp "->"
1247−
1248−-- | Get JSON value (object field or array element) at a key, as text.
1249−(.->>)
1250− :: (json `In` PGJsonType, key `In` PGJsonKey)
1251− => Operator (null json) (null key) ('Null 'PGtext)
1252−infixl 8 .->>
1253−(.->>) = unsafeBinaryOp "->>"
1254−
1255−-- | Get JSON value at a specified path.
1256−(.#>)
1257− :: json `In` PGJsonType
1258− => Operator (null json) (null ('PGvararray ('NotNull 'PGtext))) ('Null json)
1259−infixl 8 .#>
1260−(.#>) = unsafeBinaryOp "#>"
1261−
1262−-- | Get JSON value at a specified path as text.
1263−(.#>>)
1264− :: json `In` PGJsonType
1265− => Operator (null json) (null ('PGvararray ('NotNull 'PGtext))) ('Null 'PGtext)
1266−infixl 8 .#>>
1267−(.#>>) = unsafeBinaryOp "#>>"
1268−
1269−-- Additional jsonb operators
1270−
1271−class PGSubset container where
1272− (@>) :: Operator (null0 container) (null1 container) ('Null 'PGbool)
1273− (@>) = unsafeBinaryOp "@>"
1274− (<@) :: Operator (null0 container) (null1 container) ('Null 'PGbool)
1275− (<@) = unsafeBinaryOp "<@"
1276−instance PGSubset 'PGjsonb
1277−instance PGSubset 'PGtsquery
1278−instance PGSubset ('PGvararray ty)
1279−
1280−-- | Does the string exist as a top-level key within the JSON value?
1281−(.?) :: Operator (null 'PGjsonb) (null 'PGtext) ('Null 'PGbool)
1282−infixl 9 .?
1283−(.?) = unsafeBinaryOp "?"
1284−
1285−-- | Do any of these array strings exist as top-level keys?
1286−(.?|) :: Operator
1287− (null 'PGjsonb)
1288− (null ('PGvararray ('NotNull 'PGtext)))
1289− ('Null 'PGbool)
1290−infixl 9 .?|
1291−(.?|) = unsafeBinaryOp "?|"
1292−
1293−-- | Do all of these array strings exist as top-level keys?
1294−(.?&) :: Operator
1295− (null 'PGjsonb)
1296− (null ('PGvararray ('NotNull 'PGtext)))
1297− ('Null 'PGbool)
1298−infixl 9 .?&
1299−(.?&) = unsafeBinaryOp "?&"
1300−
1301−instance Semigroup
1302− (Expression outer commons grp schemas params from (null 'PGjsonb)) where
1303− (<>) = unsafeBinaryOp "||"
1304−
1305−-- | Delete a key or keys from a JSON object, or remove an array element.
1306−--
1307−-- If the right operand is..
1308−--
1309−-- @ text @: Delete key/value pair or string element from left operand. Key/value pairs
1310−-- are matched based on their key value.
1311−--
1312−-- @ text[] @: Delete multiple key/value pairs or string elements
1313−-- from left operand. Key/value pairs are matched based on their key value.
1314−--
1315−-- @ integer @: Delete the array element with specified index (Negative integers
1316−-- count from the end). Throws an error if top level container is not an array.
1317−(.-.)
1318− :: (key `In` '[ 'PGtext, 'PGvararray ('NotNull 'PGtext), 'PGint4, 'PGint2 ]) -- hlint error without parens here
1319− => Operator (null 'PGjsonb) (null key) (null 'PGjsonb)
1320−infixl 6 .-.
1321−(.-.) = unsafeBinaryOp "-"
1322−
1323−-- | Delete the field or element with specified path (for JSON arrays, negative
1324−-- integers count from the end)
1325−(#-.) :: Operator (null 'PGjsonb) (null ('PGvararray ('NotNull 'PGtext))) (null 'PGjsonb)
1326−infixl 6 #-.
1327−(#-.) = unsafeBinaryOp "#-"
1328−
1329−{-----------------------------------------
1330−Table 9.45: JSON creation functions
1331−-----------------------------------------}
1332−
1333−-- | Returns the value as json. Arrays and composites are converted
1334−-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1335−-- type to json, the cast function will be used to perform the conversion;
1336−-- otherwise, a scalar value is produced. For any scalar type other than a
1337−-- number, a Boolean, or a null value, the text representation will be used, in
1338−-- such a fashion that it is a valid json value.
1339−toJson :: null ty :--> null 'PGjson
1340−toJson = unsafeFunction "to_json"
1341−
1342−-- | Returns the value as jsonb. Arrays and composites are converted
1343−-- (recursively) to arrays and objects; otherwise, if there is a cast from the
1344−-- type to json, the cast function will be used to perform the conversion;
1345−-- otherwise, a scalar value is produced. For any scalar type other than a
1346−-- number, a Boolean, or a null value, the text representation will be used, in
1347−-- such a fashion that it is a valid jsonb value.
1348−toJsonb :: null ty :--> null 'PGjsonb
1349−toJsonb = unsafeFunction "to_jsonb"
1350−
1351−-- | Returns the array as a JSON array. A PostgreSQL multidimensional array
1352−-- becomes a JSON array of arrays.
1353−arrayToJson :: null ('PGvararray ty) :--> null 'PGjson
1354−arrayToJson = unsafeFunction "array_to_json"
1355−
1356−-- | Returns the row as a JSON object.
1357−rowToJson :: null ('PGcomposite ty) :--> null 'PGjson
1358−rowToJson = unsafeFunction "row_to_json"
1359−
1360−-- | Builds a possibly-heterogeneously-typed JSON array out of a variadic
1361−-- argument list.
1362−jsonBuildArray :: SListI tuple => FunctionN tuple (null 'PGjson)
1363−jsonBuildArray = unsafeFunctionN "json_build_array"
1364−
1365−-- | Builds a possibly-heterogeneously-typed (binary) JSON array out of a
1366−-- variadic argument list.
1367−jsonbBuildArray :: SListI tuple => FunctionN tuple (null 'PGjsonb)
1368−jsonbBuildArray = unsafeFunctionN "jsonb_build_array"
1369−
1370−class PGBuildObject tys where
1371−instance PGBuildObject '[]
1372−instance (PGBuildObject tys, key `In` PGJsonKey)
1373− => PGBuildObject ('NotNull key ': value ': tys)
1374−
1375−-- | Builds a possibly-heterogeneously-typed JSON object out of a variadic
1376−-- argument list. The elements of the argument list must alternate between text
1377−-- and values.
1378−jsonBuildObject
1379− :: (SListI elems, PGBuildObject elems)
1380− => FunctionN elems (null 'PGjson)
1381−jsonBuildObject = unsafeFunctionN "json_build_object"
1382−
1383−-- | Builds a possibly-heterogeneously-typed (binary) JSON object out of a
1384−-- variadic argument list. The elements of the argument list must alternate
1385−-- between keys and values.
1386−jsonbBuildObject
1387− :: (SListI elems, PGBuildObject elems)
1388− => FunctionN elems (null 'PGjsonb)
1389−jsonbBuildObject = unsafeFunctionN "jsonb_build_object"
1390−
1391−-- | Builds a JSON object out of a text array.
1392−-- The array must have two dimensions
1393−-- such that each inner array has exactly two elements,
1394−-- which are taken as a key/value pair.
1395−jsonObject
1396− :: null ('PGfixarray '[n,2] ('NotNull 'PGtext))
1397− :--> null 'PGjson
1398−jsonObject = unsafeFunction "json_object"
1399−
1400−-- | Builds a binary JSON object out of a text array.
1401−-- The array must have two dimensions
1402−-- such that each inner array has exactly two elements,
1403−-- which are taken as a key/value pair.
1404−jsonbObject
1405− :: null ('PGfixarray '[n,2] ('NotNull 'PGtext))
1406− :--> null 'PGjsonb
1407−jsonbObject = unsafeFunction "jsonb_object"
1408−
1409−-- | This is an alternate form of 'jsonObject' that takes two arrays; one for
1410−-- keys and one for values, that are zipped pairwise to create a JSON object.
1411−jsonZipObject :: FunctionN
1412− '[ null ('PGvararray ('NotNull 'PGtext))
1413− , null ('PGvararray ('NotNull 'PGtext)) ]
1414− ( null 'PGjson )
1415−jsonZipObject = unsafeFunctionN "json_object"
1416−
1417−-- | This is an alternate form of 'jsonbObject' that takes two arrays; one for
1418−-- keys and one for values, that are zipped pairwise to create a binary JSON
1419−-- object.
1420−jsonbZipObject :: FunctionN
1421− '[ null ('PGvararray ('NotNull 'PGtext))
1422− , null ('PGvararray ('NotNull 'PGtext)) ]
1423− ( null 'PGjsonb )
1424−jsonbZipObject = unsafeFunctionN "jsonb_object"
1425−
1426−{-----------------------------------------
1427−Table 9.46: JSON processing functions
1428−-----------------------------------------}
1429−
1430−-- | Returns the number of elements in the outermost JSON array.
1431−jsonArrayLength :: null 'PGjson :--> null 'PGint4
1432−jsonArrayLength = unsafeFunction "json_array_length"
1433−
1434−-- | Returns the number of elements in the outermost binary JSON array.
1435−jsonbArrayLength :: null 'PGjsonb :--> null 'PGint4
1436−jsonbArrayLength = unsafeFunction "jsonb_array_length"
1437−
1438−-- | Returns JSON value pointed to by the given path (equivalent to #>
1439−-- operator).
1440−jsonExtractPath
1441− :: SListI elems
1442− => Expression outer commons grp schemas params from (null 'PGjson)
1443− -> NP (Expression outer commons grp schemas params from) elems
1444− -> Expression outer commons grp schemas params from (null 'PGjsonb)
1445−jsonExtractPath x xs =
1446− unsafeFunctionN "json_extract_path" (x :* xs)
1447−
1448−-- | Returns JSON value pointed to by the given path (equivalent to #>
1449−-- operator).
1450−jsonbExtractPath
1451− :: SListI elems
1452− => Expression outer commons grp schemas params from (null 'PGjsonb)
1453− -> NP (Expression outer commons grp schemas params from) elems
1454− -> Expression outer commons grp schemas params from (null 'PGjsonb)
1455−jsonbExtractPath x xs =
1456− unsafeFunctionN "jsonb_extract_path" (x :* xs)
1457−
1458−-- | Returns JSON value pointed to by the given path (equivalent to #>
1459−-- operator), as text.
1460−jsonExtractPathAsText
1461− :: SListI elems
1462− => Expression outer commons grp schemas params from (null 'PGjson)
1463− -> NP (Expression outer commons grp schemas params from) elems
1464− -> Expression outer commons grp schemas params from (null 'PGjson)
1465−jsonExtractPathAsText x xs =
1466− unsafeFunctionN "json_extract_path_text" (x :* xs)
1467−
1468−-- | Returns JSON value pointed to by the given path (equivalent to #>
1469−-- operator), as text.
1470−jsonbExtractPathAsText
1471− :: SListI elems
1472− => Expression outer commons grp schemas params from (null 'PGjsonb)
1473− -> NP (Expression outer commons grp schemas params from) elems
1474− -> Expression outer commons grp schemas params from (null 'PGjsonb)
1475−jsonbExtractPathAsText x xs =
1476− unsafeFunctionN "jsonb_extract_path_text" (x :* xs)
1477−
1478−-- | Returns the type of the outermost JSON value as a text string. Possible
1479−-- types are object, array, string, number, boolean, and null.
1480−jsonTypeof :: null 'PGjson :--> null 'PGtext
1481−jsonTypeof = unsafeFunction "json_typeof"
1482−
1483−-- | Returns the type of the outermost binary JSON value as a text string.
1484−-- Possible types are object, array, string, number, boolean, and null.
1485−jsonbTypeof :: null 'PGjsonb :--> null 'PGtext
1486−jsonbTypeof = unsafeFunction "jsonb_typeof"
1487−
1488−-- | Returns its argument with all object fields that have null values omitted.
1489−-- Other null values are untouched.
1490−jsonStripNulls :: null 'PGjson :--> null 'PGjson
1491−jsonStripNulls = unsafeFunction "json_strip_nulls"
1492−
1493−-- | Returns its argument with all object fields that have null values omitted.
1494−-- Other null values are untouched.
1495−jsonbStripNulls :: null 'PGjsonb :--> null 'PGjsonb
1496−jsonbStripNulls = unsafeFunction "jsonb_strip_nulls"
1497−
1498−-- | @ jsonbSet target path new_value create_missing @
1499−--
1500−-- Returns target with the section designated by path replaced by new_value,
1501−-- or with new_value added if create_missing is true ( default is true) and the
1502−-- item designated by path does not exist. As with the path orientated
1503−-- operators, negative integers that appear in path count from the end of JSON
1504−-- arrays.
1505−jsonbSet
1506− :: Expression outer commons grp schemas params from (null 'PGjsonb)
1507− -> Expression outer commons grp schemas params from (null ('PGvararray ('NotNull 'PGtext)))
1508− -> Expression outer commons grp schemas params from (null 'PGjsonb)
1509− -> Maybe (Expression outer commons grp schemas params from (null 'PGbool))
1510− -> Expression outer commons grp schemas params from (null 'PGjsonb)
1511−jsonbSet tgt path val createMissing = case createMissing of
1512− Just m -> unsafeFunctionN "jsonb_set" (tgt :* path :* val :* m :* Nil)
1513− Nothing -> unsafeFunctionN "jsonb_set" (tgt :* path :* val :* Nil)
1514−
1515−-- | @ jsonbInsert target path new_value insert_after @
1516−--
1517−-- Returns target with new_value inserted. If target section designated by
1518−-- path is in a JSONB array, new_value will be inserted before target or after
1519−-- if insert_after is true (default is false). If target section designated by
1520−-- path is in JSONB object, new_value will be inserted only if target does not
1521−-- exist. As with the path orientated operators, negative integers that appear
1522−-- in path count from the end of JSON arrays.
1523−jsonbInsert
1524− :: Expression outer commons grp schemas params from (null 'PGjsonb)
1525− -> Expression outer commons grp schemas params from (null ('PGvararray ('NotNull 'PGtext)))
1526− -> Expression outer commons grp schemas params from (null 'PGjsonb)
1527− -> Maybe (Expression outer commons grp schemas params from (null 'PGbool))
1528− -> Expression outer commons grp schemas params from (null 'PGjsonb)
1529−jsonbInsert tgt path val insertAfter = case insertAfter of
1530− Just i -> unsafeFunctionN "jsonb_insert" (tgt :* path :* val :* i :* Nil)
1531− Nothing -> unsafeFunctionN "jsonb_insert" (tgt :* path :* val :* Nil)
1532−
1533−-- | Returns its argument as indented JSON text.
1534−jsonbPretty :: null 'PGjsonb :--> null 'PGtext
1535−jsonbPretty = unsafeFunction "jsonb_pretty"
1536−
1537−(@@) :: Operator (null 'PGtsvector) (null 'PGtsquery) ('Null 'PGbool)
1538−(@@) = unsafeBinaryOp "@@"
1539−
1540−(.&) :: Operator (null 'PGtsquery) (null 'PGtsquery) (null 'PGtsquery)
1541−(.&) = unsafeBinaryOp "&&"
1542−
1543−(.|) :: Operator (null 'PGtsquery) (null 'PGtsquery) (null 'PGtsquery)
1544−(.|) = unsafeBinaryOp "||"
1545−
1546−(.!) :: null 'PGtsquery :--> null 'PGtsquery
1547−(.!) = unsafeUnaryOpL "!!"
1548−
1549−(<->) :: Operator (null 'PGtsquery) (null 'PGtsquery) (null 'PGtsquery)
1550−(<->) = unsafeBinaryOp "<->"
1551−
1552−arrayToTSvector
1553− :: null ('PGvararray ('NotNull 'PGtext))
1554− :--> null 'PGtsvector
1555−arrayToTSvector = unsafeFunction "array_to_tsvector"
1556−
1557−tsvectorLength :: null 'PGtsvector :--> null 'PGint4
1558−tsvectorLength = unsafeFunction "length"
1559−
1560−numnode :: null 'PGtsquery :--> null 'PGint4
1561−numnode = unsafeFunction "numnode"
1562−
1563−plainToTSquery :: null 'PGtext :--> null 'PGtsquery
1564−plainToTSquery = unsafeFunction "plainto_tsquery"
1565−
1566−phraseToTSquery :: null 'PGtext :--> null 'PGtsquery
1567−phraseToTSquery = unsafeFunction "phraseto_tsquery"
1568−
1569−websearchToTSquery :: null 'PGtext :--> null 'PGtsquery
1570−websearchToTSquery = unsafeFunction "websearch_to_tsquery"
1571−
1572−queryTree :: null 'PGtsquery :--> null 'PGtext
1573−queryTree = unsafeFunction "query_tree"
1574−
1575−toTSquery :: null 'PGtext :--> null 'PGtsquery
1576−toTSquery = unsafeFunction "to_tsquery"
1577−
1578−toTSvector
1579− :: ty `In` '[ 'PGtext, 'PGjson, 'PGjsonb]
1580− => null ty :--> null 'PGtsvector
1581−toTSvector = unsafeFunction "to_tsvector"
1582−
1583−setWeight
1584− :: FunctionN '[null 'PGtsvector, null ('PGchar 1)] (null 'PGtsvector)
1585−setWeight = unsafeFunctionN "set_weight"
1586−
1587−strip :: null 'PGtsvector :--> null 'PGtsvector
1588−strip = unsafeFunction "strip"
1589−
1590−jsonToTSvector :: FunctionN '[null 'PGjson, null 'PGjson] (null 'PGtsvector)
1591−jsonToTSvector = unsafeFunctionN "json_to_tsvector"
1592−
1593−jsonbToTSvector :: FunctionN '[null 'PGjsonb, null 'PGjsonb] (null 'PGtsvector)
1594−jsonbToTSvector = unsafeFunctionN "jsonb_to_tsvector"
1595−
1596−tsDelete :: FunctionN
1597− '[null 'PGtsvector, null ('PGvararray ('NotNull 'PGtext))]
1598− (null 'PGtsvector)
1599−tsDelete = unsafeFunctionN "ts_delete"
1600−
1601−tsFilter :: FunctionN
1602− '[null 'PGtsvector, null ('PGvararray ('NotNull ('PGchar 1)))]
1603− (null 'PGtsvector)
1604−tsFilter = unsafeFunctionN "ts_filter"
1605−
1606−tsHeadline
1607− :: document `In` '[ 'PGtext, 'PGjson, 'PGjsonb]
1608− => FunctionN '[null document, null 'PGtsquery] (null 'PGtext)
1609−tsHeadline = unsafeFunctionN "ts_headline"
1610−{-----------------------------------------
1611−aggregation
1612−-----------------------------------------}
1613−
1614−unsafeAggregateN
1615− :: SOP.SListI xs
1616− => ByteString -- ^ function
1617− -> Distinction (NP (Expression outer commons 'Ungrouped schemas params from)) xs
1618− -> Expression outer commons ('Grouped bys) schemas params from y
1619−unsafeAggregateN fun xs = UnsafeExpression $ fun <> parenthesized (renderSQL xs)
1620−
1621−{- |
1622−`Aggregate` functions compute a single result from a set of input values.
1623−`Aggregate` functions can be used as `GroupedBy` `Expression`s as well
1624−as `WindowFunction`s.
1625−-}
1626−class Aggregate expr1 exprN aggr
1627− | aggr -> expr1, aggr -> exprN where
1628−
1629− -- | A special aggregation that does not require an input
1630− --
1631− -- >>> :{
1632− -- let
1633− -- expression :: Expression '[] commons ('Grouped bys) schemas params from ('NotNull 'PGint8)
1634− -- expression = countStar
1635− -- in printSQL expression
1636− -- :}
1637− -- count(*)
1638− countStar :: aggr ('NotNull 'PGint8)
1639−
1640− -- | >>> :{
1641− -- let
1642− -- expression :: Expression '[] commons ('Grouped bys) schemas params '[tab ::: '["col" ::: null ty]] ('NotNull 'PGint8)
1643− -- expression = count (All #col)
1644− -- in printSQL expression
1645− -- :}
1646− -- count(ALL "col")
1647− count
1648− :: expr1 ty
1649− -- ^ what to count
1650− -> aggr ('NotNull 'PGint8)
1651−
1652− -- | >>> :{
1653− -- let
1654− -- expression :: Expression '[] commons ('Grouped bys) schemas params '[tab ::: '["col" ::: 'Null 'PGnumeric]] ('NotNull 'PGnumeric)
1655− -- expression = sum_ (Distinct #col)
1656− -- in printSQL expression
1657− -- :}
1658− -- sum(DISTINCT "col")
1659− sum_
1660− :: ty `In` PGNum
1661− => expr1 (null ty)
1662− -> aggr ('NotNull ty)
1663−
1664− -- | input values, including nulls, concatenated into an array
1665− arrayAgg
1666− :: expr1 ty
1667− -> aggr ('Null ('PGvararray ty))
1668−
1669− -- | aggregates values as a JSON array
1670− jsonAgg
1671− :: expr1 ty
1672− -> aggr ('Null 'PGjson)
1673−
1674− -- | aggregates values as a JSON array
1675− jsonbAgg
1676− :: expr1 ty
1677− -> aggr ('Null 'PGjsonb)
1678−
1679− {- |
1680− the bitwise AND of all non-null input values, or null if none
1681− >>> :{
1682− let
1683− expression :: Expression '[] commons ('Grouped bys) schemas params '[tab ::: '["col" ::: null 'PGint4]] ('Null 'PGint4)
1684− expression = bitAnd (Distinct #col)
1685− in printSQL expression
1686− :}
1687− bit_and(DISTINCT "col")
1688− -}
1689− bitAnd
1690− :: int `In` PGIntegral
1691− => expr1 (null int)
1692− -- ^ what to aggregate
1693− -> aggr ('Null int)
1694−
1695− {- |
1696− the bitwise OR of all non-null input values, or null if none
1697−
1698− >>> :{
1699− let
1700− expression :: Expression '[] commons ('Grouped bys) schemas params '[tab ::: '["col" ::: null 'PGint4]] ('Null 'PGint4)
1701− expression = bitOr (All #col)
1702− in printSQL expression
1703− :}
1704− bit_or(ALL "col")
1705− -}
1706− bitOr
1707− :: int `In` PGIntegral
1708− => expr1 (null int)
1709− -- ^ what to aggregate
1710− -> aggr ('Null int)
1711−
1712− {- |
1713− true if all input values are true, otherwise false
1714−
1715− >>> :{
1716− let
1717− winFun :: WindowFunction '[] commons 'Ungrouped schemas params '[tab ::: '["col" ::: null 'PGbool]] ('Null 'PGbool)
1718− winFun = boolAnd #col
1719− in printSQL winFun
1720− :}
1721− bool_and("col")
1722− -}
1723− boolAnd
1724− :: expr1 (null 'PGbool)
1725− -- ^ what to aggregate
1726− -> aggr ('Null 'PGbool)
1727−
1728− {- |
1729− true if at least one input value is true, otherwise false
1730−
1731− >>> :{
1732− let
1733− expression :: Expression '[] commons ('Grouped bys) schemas params '[tab ::: '["col" ::: null 'PGbool]] ('Null 'PGbool)
1734− expression = boolOr (All #col)
1735− in printSQL expression
1736− :}
1737− bool_or(ALL "col")
1738− -}
1739− boolOr
1740− :: expr1 (null 'PGbool)
1741− -- ^ what to aggregate
1742− -> aggr ('Null 'PGbool)
1743−
1744− {- |
1745− equivalent to `boolAnd`
1746−
1747− >>> :{
1748− let
1749− expression :: Expression '[] commons ('Grouped bys) schemas params '[tab ::: '["col" ::: null 'PGbool]] ('Null 'PGbool)
1750− expression = every (Distinct #col)
1751− in printSQL expression
1752− :}
1753− every(DISTINCT "col")
1754− -}
1755− every
1756− :: expr1 (null 'PGbool)
1757− -- ^ what to aggregate
1758− -> aggr ('Null 'PGbool)
1759−
1760− {- |maximum value of expression across all input values-}
1761− max_
1762− :: expr1 (null ty)
1763− -- ^ what to maximize
1764− -> aggr ('Null ty)
1765−
1766− -- | minimum value of expression across all input values
1767− min_
1768− :: expr1 (null ty)
1769− -- ^ what to minimize
1770− -> aggr ('Null ty)
1771−
1772− -- | the average (arithmetic mean) of all input values
1773− avg
1774− :: expr1 (null ty)
1775− -- ^ what to average
1776− -> aggr ('Null (PGAvg ty))
1777−
1778− {- | correlation coefficient
1779− >>> :{
1780− let
1781− expression :: Expression '[] c ('Grouped g) s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1782− expression = corr (All (#y *: #x))
1783− in printSQL expression
1784− :}
1785− corr(ALL "y", "x")
1786− -}
1787− corr
1788− :: exprN '[null 'PGfloat8, null 'PGfloat8]
1789− -> aggr ('Null 'PGfloat8)
1790−
1791− {- | population covariance
1792− >>> :{
1793− let
1794− expression :: Expression '[] c ('Grouped g) s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1795− expression = covarPop (All (#y *: #x))
1796− in printSQL expression
1797− :}
1798− covar_pop(ALL "y", "x")
1799− -}
1800− covarPop
1801− :: exprN '[null 'PGfloat8, null 'PGfloat8]
1802− -> aggr ('Null 'PGfloat8)
1803−
1804− {- | sample covariance
1805− >>> :{
1806− let
1807− winFun :: WindowFunction '[] c 'Ungrouped s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1808− winFun = covarSamp (#y *: #x)
1809− in printSQL winFun
1810− :}
1811− covar_samp("y", "x")
1812− -}
1813− covarSamp
1814− :: exprN '[null 'PGfloat8, null 'PGfloat8]
1815− -> aggr ('Null 'PGfloat8)
1816−
1817− {- | average of the independent variable (sum(X)/N)
1818− >>> :{
1819− let
1820− expression :: Expression '[] c ('Grouped g) s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1821− expression = regrAvgX (All (#y *: #x))
1822− in printSQL expression
1823− :}
1824− regr_avgx(ALL "y", "x")
1825− -}
1826− regrAvgX
1827− :: exprN '[null 'PGfloat8, null 'PGfloat8]
1828− -> aggr ('Null 'PGfloat8)
1829−
1830− {- | average of the dependent variable (sum(Y)/N)
1831− >>> :{
1832− let
1833− winFun :: WindowFunction '[] c 'Ungrouped s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1834− winFun = regrAvgY (#y *: #x)
1835− in printSQL winFun
1836− :}
1837− regr_avgy("y", "x")
1838− -}
1839− regrAvgY
1840− :: exprN '[null 'PGfloat8, null 'PGfloat8]
1841− -> aggr ('Null 'PGfloat8)
1842−
1843− {- | number of input rows in which both expressions are nonnull
1844− >>> :{
1845− let
1846− winFun :: WindowFunction '[] c 'Ungrouped s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGint8)
1847− winFun = regrCount (#y *: #x)
1848− in printSQL winFun
1849− :}
1850− regr_count("y", "x")
1851− -}
1852− regrCount
1853− :: exprN '[null 'PGfloat8, null 'PGfloat8]
1854− -> aggr ('Null 'PGint8)
1855−
1856− {- | y-intercept of the least-squares-fit linear equation determined by the (X, Y) pairs
1857− >>> :{
1858− let
1859− expression :: Expression '[] c ('Grouped g) s p '[t ::: '["x" ::: 'NotNull 'PGfloat8, "y" ::: 'NotNull 'PGfloat8]] ('Null 'PGfloat8)
1860− expression = regrIntercept (All (#y *: #x))
1861− in printSQL expression
1862− :}
1863− regr_intercept(ALL "y", "x")
1864− -}
1865− regrIntercept
1866− :: exprN '[null 'PGfloat8, null 'PGfloat8]
1867− -> aggr ('Null 'PGfloat8)
1868−
1869− -- | @regr_r2(Y, X)@, square of the correlation coefficient
1870− regrR2
1871− :: exprN '[null 'PGfloat8, null 'PGfloat8]
1872− -> aggr ('Null 'PGfloat8)
1873−
1874− -- | @regr_slope(Y, X)@, slope of the least-squares-fit linear equation
1875− -- determined by the (X, Y) pairs
1876− regrSlope
1877− :: exprN '[null 'PGfloat8, null 'PGfloat8]
1878− -> aggr ('Null 'PGfloat8)
1879−
1880− -- | @regr_sxx(Y, X)@, sum(X^2) - sum(X)^2/N
1881− -- (“sum of squares” of the independent variable)
1882− regrSxx
1883− :: exprN '[null 'PGfloat8, null 'PGfloat8]
1884− -> aggr ('Null 'PGfloat8)
1885−
1886− -- | @regr_sxy(Y, X)@, sum(X*Y) - sum(X) * sum(Y)/N
1887− -- (“sum of products” of independent times dependent variable)
1888− regrSxy
1889− :: exprN '[null 'PGfloat8, null 'PGfloat8]
1890− -> aggr ('Null 'PGfloat8)
1891−
1892− -- | @regr_syy(Y, X)@, sum(Y^2) - sum(Y)^2/N
1893− -- (“sum of squares” of the dependent variable)
1894− regrSyy
1895− :: exprN '[null 'PGfloat8, null 'PGfloat8]
1896− -> aggr ('Null 'PGfloat8)
1897−
1898− -- | historical alias for `stddevSamp`
1899− stddev
1900− :: expr1 (null ty)
1901− -> aggr ('Null (PGAvg ty))
1902−
1903− -- | population standard deviation of the input values
1904− stddevPop
1905− :: expr1 (null ty)
1906− -> aggr ('Null (PGAvg ty))
1907−
1908− -- | sample standard deviation of the input values
1909− stddevSamp
1910− :: expr1 (null ty)
1911− -> aggr ('Null (PGAvg ty))
1912−
1913− -- | historical alias for `varSamp`
1914− variance
1915− :: expr1 (null ty)
1916− -> aggr ('Null (PGAvg ty))
1917−
1918− -- | population variance of the input values
1919− -- (square of the population standard deviation)
1920− varPop
1921− :: expr1 (null ty)
1922− -> aggr ('Null (PGAvg ty))
1923−
1924− -- | sample variance of the input values
1925− -- (square of the sample standard deviation)
1926− varSamp
1927− :: expr1 (null ty)
1928− -> aggr ('Null (PGAvg ty))
1929−
1930−{- |
1931−`Distinction`s are used for the input of `Aggregate` `Expression`s.
1932−`All` invokes the aggregate once for each input row.
1933−`Distinct` invokes the aggregate once for each distinct value of the expression
1934−(or distinct set of values, for multiple expressions) found in the input
1935−-}
1936−data Distinction (expr :: kind -> Type) (ty :: kind)
1937− = All (expr ty)
1938− | Distinct (expr ty)
1939− deriving (GHC.Generic,Show,Eq,Ord)
1940−instance NFData (Distinction (Expression outer commons grp schemas params from) ty)
1941−instance RenderSQL (Distinction (Expression outer commons grp schemas params from) ty) where
1942− renderSQL = \case
1943− All x -> "ALL" <+> renderSQL x
1944− Distinct x -> "DISTINCT" <+> renderSQL x
1945−instance SOP.SListI tys => RenderSQL
1946− (Distinction (NP (Expression outer commons grp schemas params from)) tys) where
1947− renderSQL = \case
1948− All xs -> "ALL" <+> renderCommaSeparated renderSQL xs
1949− Distinct xs -> "DISTINCT" <+> renderCommaSeparated renderSQL xs
1950−
1951−instance Aggregate
1952− (Distinction (Expression outer commons 'Ungrouped schemas params from))
1953− (Distinction (NP (Expression outer commons 'Ungrouped schemas params from)))
1954− (Expression outer commons ('Grouped bys) schemas params from) where
1955− countStar = UnsafeExpression "count(*)"
1956− count = unsafeAggregate1 "count"
1957− sum_ = unsafeAggregate1 "sum"
1958− arrayAgg = unsafeAggregate1 "array_agg"
1959− jsonAgg = unsafeAggregate1 "json_agg"
1960− jsonbAgg = unsafeAggregate1 "jsonb_agg"
1961− bitAnd = unsafeAggregate1 "bit_and"
1962− bitOr = unsafeAggregate1 "bit_or"
1963− boolAnd = unsafeAggregate1 "bool_and"
1964− boolOr = unsafeAggregate1 "bool_or"
1965− every = unsafeAggregate1 "every"
1966− max_ = unsafeAggregate1 "max"
1967− min_ = unsafeAggregate1 "min"
1968− avg = unsafeAggregate1 "avg"
1969− corr = unsafeAggregateN "corr"
1970− covarPop = unsafeAggregateN "covar_pop"
1971− covarSamp = unsafeAggregateN "covar_samp"
1972− regrAvgX = unsafeAggregateN "regr_avgx"
1973− regrAvgY = unsafeAggregateN "regr_avgy"
1974− regrCount = unsafeAggregateN "regr_count"
1975− regrIntercept = unsafeAggregateN "regr_intercept"
1976− regrR2 = unsafeAggregateN "regr_r2"
1977− regrSlope = unsafeAggregateN "regr_slope"
1978− regrSxx = unsafeAggregateN "regr_sxx"
1979− regrSxy = unsafeAggregateN "regr_sxy"
1980− regrSyy = unsafeAggregateN "regr_syy"
1981− stddev = unsafeAggregate1 "stddev"
1982− stddevPop = unsafeAggregate1 "stddev_pop"
1983− stddevSamp = unsafeAggregate1 "stddev_samp"
1984− variance = unsafeAggregate1 "variance"
1985− varPop = unsafeAggregate1 "var_pop"
1986− varSamp = unsafeAggregate1 "var_samp"
1987−instance Aggregate
1988− (Expression outer commons grp schemas params from)
1989− (NP (Expression outer commons grp schemas params from))
1990− (WindowFunction outer commons grp schemas params from) where
1991− countStar = UnsafeWindowFunction "count(*)"
1992− count = unsafeWindowFunction1 "count"
1993− sum_ = unsafeWindowFunction1 "sum"
1994− arrayAgg = unsafeWindowFunction1 "array_agg"
1995− jsonAgg = unsafeWindowFunction1 "json_agg"
1996− jsonbAgg = unsafeWindowFunction1 "jsonb_agg"
1997− bitAnd = unsafeWindowFunction1 "bit_and"
1998− bitOr = unsafeWindowFunction1 "bit_or"
1999− boolAnd = unsafeWindowFunction1 "bool_and"
2000− boolOr = unsafeWindowFunction1 "bool_or"
2001− every = unsafeWindowFunction1 "every"
2002− max_ = unsafeWindowFunction1 "max"
2003− min_ = unsafeWindowFunction1 "min"
2004− avg = unsafeWindowFunction1 "avg"
2005− corr = unsafeWindowFunctionN "corr"
2006− covarPop = unsafeWindowFunctionN "covar_pop"
2007− covarSamp = unsafeWindowFunctionN "covar_samp"
2008− regrAvgX = unsafeWindowFunctionN "regr_avgx"
2009− regrAvgY = unsafeWindowFunctionN "regr_avgy"
2010− regrCount = unsafeWindowFunctionN "regr_count"
2011− regrIntercept = unsafeWindowFunctionN "regr_intercept"
2012− regrR2 = unsafeWindowFunctionN "regr_r2"
2013− regrSlope = unsafeWindowFunctionN "regr_slope"
2014− regrSxx = unsafeWindowFunctionN "regr_sxx"
2015− regrSxy = unsafeWindowFunctionN "regr_sxy"
2016− regrSyy = unsafeWindowFunctionN "regr_syy"
2017− stddev = unsafeWindowFunction1 "stddev"
2018− stddevPop = unsafeWindowFunction1 "stddev_pop"
2019− stddevSamp = unsafeWindowFunction1 "stddev_samp"
2020− variance = unsafeWindowFunction1 "variance"
2021− varPop = unsafeWindowFunction1 "var_pop"
2022− varSamp = unsafeWindowFunction1 "var_samp"
2023−
2024−-- | escape hatch to define aggregate functions
2025−unsafeAggregate1
2026− :: ByteString -- ^ aggregate function
2027− -> Distinction (Expression outer commons 'Ungrouped schemas params from) x
2028− -> Expression outer commons ('Grouped bys) schemas params from y
2029−unsafeAggregate1 fun x = UnsafeExpression $ fun <> parenthesized (renderSQL x)
2030−
2031−-- | A type family that calculates `PGAvg` type of a `PGType`.
2032−type family PGAvg ty where
2033− PGAvg 'PGint2 = 'PGnumeric
2034− PGAvg 'PGint4 = 'PGnumeric
2035− PGAvg 'PGint8 = 'PGnumeric
2036− PGAvg 'PGnumeric = 'PGnumeric
2037− PGAvg 'PGfloat4 = 'PGfloat8
2038− PGAvg 'PGfloat8 = 'PGfloat8
2039− PGAvg 'PGinterval = 'PGinterval
2040− PGAvg pg = TypeError
2041− ('Text "Squeal type error: No average for " ':<>: 'ShowType pg)
2042−
2043−{-----------------------------------------
2044−type expressions
2045−-----------------------------------------}
2046−
2047−-- | `TypeExpression`s are used in `cast`s and
2048−-- `Squeal.PostgreSQL.Definition.createTable` commands.
2049−newtype TypeExpression (schemas :: SchemasType) (ty :: NullityType)
2050− = UnsafeTypeExpression { renderTypeExpression :: ByteString }
2051− deriving (GHC.Generic,Show,Eq,Ord,NFData)
2052−instance RenderSQL (TypeExpression schemas ty) where
2053− renderSQL = renderTypeExpression
2054−
2055−-- | The enum or composite type in a `Typedef` can be expressed by its alias.
2056−typedef
2057− :: (Has sch schemas schema, Has td schema ('Typedef ty))
2058− => QualifiedAlias sch td
2059− -> TypeExpression schemas (null ty)
2060−typedef = UnsafeTypeExpression . renderSQL
2061−
2062−-- | The composite type corresponding to a `Table` definition can be expressed
2063−-- by its alias.
2064−typetable
2065− :: (Has sch schemas schema, Has tab schema ('Table table))
2066− => QualifiedAlias sch tab
2067− -> TypeExpression schemas (null ('PGcomposite (TableToRow table)))
2068−typetable = UnsafeTypeExpression . renderSQL
2069−
2070−-- | The composite type corresponding to a `View` definition can be expressed
2071−-- by its alias.
2072−typeview
2073− :: (Has sch schemas schema, Has vw schema ('View view))
2074− => QualifiedAlias sch vw
2075− -> TypeExpression schemas (null ('PGcomposite view))
2076−typeview = UnsafeTypeExpression . renderSQL
2077−
2078−-- | logical Boolean (true/false)
2079−bool :: TypeExpression schemas (null 'PGbool)
2080−bool = UnsafeTypeExpression "bool"
2081−-- | signed two-byte integer
2082−int2, smallint :: TypeExpression schemas (null 'PGint2)
2083−int2 = UnsafeTypeExpression "int2"
2084−smallint = UnsafeTypeExpression "smallint"
2085−-- | signed four-byte integer
2086−int4, int, integer :: TypeExpression schemas (null 'PGint4)
2087−int4 = UnsafeTypeExpression "int4"
2088−int = UnsafeTypeExpression "int"
2089−integer = UnsafeTypeExpression "integer"
2090−-- | signed eight-byte integer
2091−int8, bigint :: TypeExpression schemas (null 'PGint8)
2092−int8 = UnsafeTypeExpression "int8"
2093−bigint = UnsafeTypeExpression "bigint"
2094−-- | arbitrary precision numeric type
2095−numeric :: TypeExpression schemas (null 'PGnumeric)
2096−numeric = UnsafeTypeExpression "numeric"
2097−-- | single precision floating-point number (4 bytes)
2098−float4, real :: TypeExpression schemas (null 'PGfloat4)
2099−float4 = UnsafeTypeExpression "float4"
2100−real = UnsafeTypeExpression "real"
2101−-- | double precision floating-point number (8 bytes)
2102−float8, doublePrecision :: TypeExpression schemas (null 'PGfloat8)
2103−float8 = UnsafeTypeExpression "float8"
2104−doublePrecision = UnsafeTypeExpression "double precision"
2105−-- | currency amount
2106−money :: TypeExpression schema (null 'PGmoney)
2107−money = UnsafeTypeExpression "money"
2108−-- | variable-length character string
2109−text :: TypeExpression schemas (null 'PGtext)
2110−text = UnsafeTypeExpression "text"
2111−-- | fixed-length character string
2112−char, character
2113− :: forall n schemas null. (KnownNat n, 1 <= n)
2114− => TypeExpression schemas (null ('PGchar n))
2115−char = UnsafeTypeExpression $ "char(" <> renderNat @n <> ")"
2116−character = UnsafeTypeExpression $ "character(" <> renderNat @n <> ")"
2117−-- | variable-length character string
2118−varchar, characterVarying
2119− :: forall n schemas null. (KnownNat n, 1 <= n)
2120− => TypeExpression schemas (null ('PGvarchar n))
2121−varchar = UnsafeTypeExpression $ "varchar(" <> renderNat @n <> ")"
2122−characterVarying = UnsafeTypeExpression $
2123− "character varying(" <> renderNat @n <> ")"
2124−-- | binary data ("byte array")
2125−bytea :: TypeExpression schemas (null 'PGbytea)
2126−bytea = UnsafeTypeExpression "bytea"
2127−-- | date and time (no time zone)
2128−timestamp :: TypeExpression schemas (null 'PGtimestamp)
2129−timestamp = UnsafeTypeExpression "timestamp"
2130−-- | date and time, including time zone
2131−timestampWithTimeZone :: TypeExpression schemas (null 'PGtimestamptz)
2132−timestampWithTimeZone = UnsafeTypeExpression "timestamp with time zone"
2133−-- | calendar date (year, month, day)
2134−date :: TypeExpression schemas (null 'PGdate)
2135−date = UnsafeTypeExpression "date"
2136−-- | time of day (no time zone)
2137−time :: TypeExpression schemas (null 'PGtime)
2138−time = UnsafeTypeExpression "time"
2139−-- | time of day, including time zone
2140−timeWithTimeZone :: TypeExpression schemas (null 'PGtimetz)
2141−timeWithTimeZone = UnsafeTypeExpression "time with time zone"
2142−-- | time span
2143−interval :: TypeExpression schemas (null 'PGinterval)
2144−interval = UnsafeTypeExpression "interval"
2145−-- | universally unique identifier
2146−uuid :: TypeExpression schemas (null 'PGuuid)
2147−uuid = UnsafeTypeExpression "uuid"
2148−-- | IPv4 or IPv6 host address
2149−inet :: TypeExpression schemas (null 'PGinet)
2150−inet = UnsafeTypeExpression "inet"
2151−-- | textual JSON data
2152−json :: TypeExpression schemas (null 'PGjson)
2153−json = UnsafeTypeExpression "json"
2154−-- | binary JSON data, decomposed
2155−jsonb :: TypeExpression schemas (null 'PGjsonb)
2156−jsonb = UnsafeTypeExpression "jsonb"
2157−-- | variable length array
2158−vararray
2159− :: TypeExpression schemas pg
2160− -> TypeExpression schemas (null ('PGvararray pg))
2161−vararray ty = UnsafeTypeExpression $ renderSQL ty <> "[]"
2162−-- | fixed length array
2163−--
2164−-- >>> renderSQL (fixarray @'[2] json)
2165−-- "json[2]"
2166−fixarray
2167− :: forall dims schemas null pg. SOP.All KnownNat dims
2168− => TypeExpression schemas pg
2169− -> TypeExpression schemas (null ('PGfixarray dims pg))
2170−fixarray ty = UnsafeTypeExpression $
2171− renderSQL ty <> renderDims @dims
2172− where
2173− renderDims :: forall ns. SOP.All KnownNat ns => ByteString
2174− renderDims =
2175− ("[" <>)
2176− . (<> "]")
2177− . ByteString.intercalate "]["
2178− . hcollapse
2179− $ hcmap (SOP.Proxy @KnownNat)
2180− (K . fromString . show . natVal)
2181− (hpure SOP.Proxy :: NP SOP.Proxy ns)
2182−tsvector :: TypeExpression schemas (null 'PGtsvector)
2183−tsvector = UnsafeTypeExpression "tsvector"
2184−tsquery :: TypeExpression schemas (null 'PGtsquery)
2185−tsquery = UnsafeTypeExpression "tsquery"
2186−
2187−-- | `pgtype` is a demoted version of a `PGType`
2188−class PGTyped schemas (ty :: NullityType) where
2189− pgtype :: TypeExpression schemas ty
2190−instance PGTyped schemas (null 'PGbool) where pgtype = bool
2191−instance PGTyped schemas (null 'PGint2) where pgtype = int2
2192−instance PGTyped schemas (null 'PGint4) where pgtype = int4
2193−instance PGTyped schemas (null 'PGint8) where pgtype = int8
2194−instance PGTyped schemas (null 'PGnumeric) where pgtype = numeric
2195−instance PGTyped schemas (null 'PGfloat4) where pgtype = float4
2196−instance PGTyped schemas (null 'PGfloat8) where pgtype = float8
2197−instance PGTyped schemas (null 'PGmoney) where pgtype = money
2198−instance PGTyped schemas (null 'PGtext) where pgtype = text
2199−instance (KnownNat n, 1 <= n)
2200− => PGTyped schemas (null ('PGchar n)) where pgtype = char @n
2201−instance (KnownNat n, 1 <= n)
2202− => PGTyped schemas (null ('PGvarchar n)) where pgtype = varchar @n
2203−instance PGTyped schemas (null 'PGbytea) where pgtype = bytea
2204−instance PGTyped schemas (null 'PGtimestamp) where pgtype = timestamp
2205−instance PGTyped schemas (null 'PGtimestamptz) where pgtype = timestampWithTimeZone
2206−instance PGTyped schemas (null 'PGdate) where pgtype = date
2207−instance PGTyped schemas (null 'PGtime) where pgtype = time
2208−instance PGTyped schemas (null 'PGtimetz) where pgtype = timeWithTimeZone
2209−instance PGTyped schemas (null 'PGinterval) where pgtype = interval
2210−instance PGTyped schemas (null 'PGuuid) where pgtype = uuid
2211−instance PGTyped schemas (null 'PGjson) where pgtype = json
2212−instance PGTyped schemas (null 'PGjsonb) where pgtype = jsonb
2213−instance PGTyped schemas ty
2214− => PGTyped schemas (null ('PGvararray ty)) where
2215− pgtype = vararray (pgtype @schemas @ty)
2216−instance (SOP.All KnownNat dims, PGTyped schemas ty)
2217− => PGTyped schemas (null ('PGfixarray dims ty)) where
2218− pgtype = fixarray @dims (pgtype @schemas @ty)
2219−instance PGTyped schemas (null 'PGtsvector) where pgtype = tsvector
2220−instance PGTyped schemas (null 'PGtsquery) where pgtype = tsquery
2221−
2222−{-----------------------------------------
2223−Sorting
2224−-----------------------------------------}
2225−
2226−-- | `SortExpression`s are used by `orderBy` to optionally sort the results
2227−-- of a `Squeal.PostgreSQL.Query.Query`. `Asc` or `Desc`
2228−-- set the sort direction of a `NotNull` result
2229−-- column to ascending or descending. Ascending order puts smaller values
2230−-- first, where "smaller" is defined in terms of the `.<` operator. Similarly,
2231−-- descending order is determined with the `.>` operator. `AscNullsFirst`,
2232−-- `AscNullsLast`, `DescNullsFirst` and `DescNullsLast` options are used to
2233−-- determine whether nulls appear before or after non-null values in the sort
2234−-- ordering of a `Null` result column.
2235−data SortExpression outer commons grp schemas params from where
2236− Asc
2237− :: Expression outer commons grp schemas params from ('NotNull ty)
2238− -> SortExpression outer commons grp schemas params from
2239− Desc
2240− :: Expression outer commons grp schemas params from ('NotNull ty)
2241− -> SortExpression outer commons grp schemas params from
2242− AscNullsFirst
2243− :: Expression outer commons grp schemas params from ('Null ty)
2244− -> SortExpression outer commons grp schemas params from
2245− AscNullsLast
2246− :: Expression outer commons grp schemas params from ('Null ty)
2247− -> SortExpression outer commons grp schemas params from
2248− DescNullsFirst
2249− :: Expression outer commons grp schemas params from ('Null ty)
2250− -> SortExpression outer commons grp schemas params from
2251− DescNullsLast
2252− :: Expression outer commons grp schemas params from ('Null ty)
2253− -> SortExpression outer commons grp schemas params from
2254−deriving instance Show (SortExpression outer commons grp schemas params from)
2255−
2256−{- |
2257−The `orderBy` clause causes the result rows of a `Squeal.PostgreSQL.Query.TableExpression`
2258−to be sorted according to the specified `SortExpression`(s).
2259−If two rows are equal according to the leftmost expression,
2260−they are compared according to the next expression and so on.
2261−If they are equal according to all specified expressions,
2262−they are returned in an implementation-dependent order.
2263−
2264−You can also control the order in which rows are processed by window functions
2265−using `orderBy` within `Squeal.PostgreSQL.Query.Over`.
2266−-}
2267−class OrderBy expr where
2268− orderBy
2269− :: [SortExpression outer commons grp schemas params from]
2270− -> expr outer commons grp schemas params from
2271− -> expr outer commons grp schemas params from
2272−
2273−-- | Render a `SortExpression`.
2274−instance RenderSQL (SortExpression outer commons grp schemas params from) where
2275− renderSQL = \case
2276− Asc expression -> renderSQL expression <+> "ASC"
2277− Desc expression -> renderSQL expression <+> "DESC"
2278− AscNullsFirst expression -> renderSQL expression
2279− <+> "ASC NULLS FIRST"
2280− DescNullsFirst expression -> renderSQL expression
2281− <+> "DESC NULLS FIRST"
2282− AscNullsLast expression -> renderSQL expression <+> "ASC NULLS LAST"
2283− DescNullsLast expression -> renderSQL expression <+> "DESC NULLS LAST"
2284−
2285−-- | A `WindowDefinition` is a set of table rows that are somehow related
2286−-- to the current row
2287−data WindowDefinition outer commons grp schemas params from where
2288− WindowDefinition
2289− :: SListI bys
2290− => NP (Expression outer commons grp schemas params from) bys
2291− -> [SortExpression outer commons grp schemas params from]
2292− -> WindowDefinition outer commons grp schemas params from
2293−
2294−instance OrderBy WindowDefinition where
2295− orderBy sortsR (WindowDefinition parts sortsL)
2296− = WindowDefinition parts (sortsL ++ sortsR)
2297−
2298−instance RenderSQL (WindowDefinition outer commons schemas from grp params) where
2299− renderSQL (WindowDefinition part ord) =
2300− renderPartitionByClause part <> renderOrderByClause ord
2301− where
2302− renderPartitionByClause = \case
2303− Nil -> ""
2304− parts -> "PARTITION" <+> "BY" <+> renderCommaSeparated renderExpression parts
2305− renderOrderByClause = \case
2306− [] -> ""
2307− srts -> " ORDER" <+> "BY"
2308− <+> commaSeparated (renderSQL <$> srts)
2309−
2310−{- |
2311−The `partitionBy` clause within `Squeal.PostgreSQL.Query.Over` divides the rows into groups,
2312−or partitions, that share the same values of the `partitionBy` `Expression`(s).
2313−For each row, the window function is computed across the rows that fall into
2314−the same partition as the current row.
2315−-}
2316−partitionBy
2317− :: SListI bys
2318− => NP (Expression outer commons grp schemas params from) bys
2319− -> WindowDefinition outer commons grp schemas params from
2320−partitionBy bys = WindowDefinition bys []
2321−
2322−{- |
2323−A window function performs a calculation across a set of table rows
2324−that are somehow related to the current row. This is comparable to the type
2325−of calculation that can be done with an aggregate function.
2326−However, window functions do not cause rows to become grouped into a single
2327−output row like non-window aggregate calls would.
2328−Instead, the rows retain their separate identities.
2329−Behind the scenes, the window function is able to access more than
2330−just the current row of the query result.
2331−-}
2332−newtype WindowFunction
2333− (outer :: FromType)
2334− (commons :: FromType)
2335− (grp :: Grouping)
2336− (schemas :: SchemasType)
2337− (params :: [NullityType])
2338− (from :: FromType)
2339− (ty :: NullityType)
2340− = UnsafeWindowFunction { renderWindowFunction :: ByteString }
2341− deriving (GHC.Generic,Show,Eq,Ord,NFData)
2342−
2343−instance RenderSQL (WindowFunction outer commons grp schemas params from ty) where
2344− renderSQL = renderWindowFunction
2345−
2346−type WinFun0 x
2347− = forall outer commons grp schemas params from
2348− . WindowFunction outer commons grp schemas params from x
2349− -- ^ cannot reference aliases
2350−
2351−type WinFun1 x y
2352− = forall outer commons grp schemas params from
2353− . Expression outer commons grp schemas params from x
2354− -- ^ input
2355− -> WindowFunction outer commons grp schemas params from y
2356− -- ^ output
2357−
2358−type WinFunN xs y
2359− = forall outer commons grp schemas params from
2360− . NP (Expression outer commons grp schemas params from) xs
2361− -- ^ inputs
2362− -> WindowFunction outer commons grp schemas params from y
2363− -- ^ output
2364−
2365−unsafeWindowFunction1 :: ByteString -> WinFun1 x y
2366−unsafeWindowFunction1 fun x
2367− = UnsafeWindowFunction $ fun <> parenthesized (renderSQL x)
2368−
2369−unsafeWindowFunctionN :: SOP.SListI xs => ByteString -> WinFunN xs y
2370−unsafeWindowFunctionN fun xs = UnsafeWindowFunction $ fun <>
2371− parenthesized (renderCommaSeparated renderSQL xs)
2372−
2373−{- | rank of the current row with gaps; same as `rowNumber` of its first peer
2374−>>> printSQL rank
2375−rank()
2376−-}
2377−rank :: WinFun0 ('NotNull 'PGint8)
2378−rank = UnsafeWindowFunction "rank()"
2379−
2380−{- | number of the current row within its partition, counting from 1
2381−>>> printSQL rowNumber
2382−row_number()
2383−-}
2384−rowNumber :: WinFun0 ('NotNull 'PGint8)
2385−rowNumber = UnsafeWindowFunction "row_number()"
2386−
2387−{- | rank of the current row without gaps; this function counts peer groups
2388−>>> printSQL denseRank
2389−dense_rank()
2390−-}
2391−denseRank :: WinFun0 ('NotNull 'PGint8)
2392−denseRank = UnsafeWindowFunction "dense_rank()"
2393−
2394−{- | relative rank of the current row: (rank - 1) / (total partition rows - 1)
2395−>>> printSQL percentRank
2396−percent_rank()
2397−-}
2398−percentRank :: WinFun0 ('NotNull 'PGfloat8)
2399−percentRank = UnsafeWindowFunction "percent_rank()"
2400−
2401−{- | cumulative distribution: (number of partition rows
2402−preceding or peer with current row) / total partition rows
2403−>>> printSQL cumeDist
2404−cume_dist()
2405−-}
2406−cumeDist :: WinFun0 ('NotNull 'PGfloat8)
2407−cumeDist = UnsafeWindowFunction "cume_dist()"
2408−
2409−{- | integer ranging from 1 to the argument value,
2410−dividing the partition as equally as possible
2411−-}
2412−ntile :: WinFun1 ('NotNull 'PGint4) ('NotNull 'PGint4)
2413−ntile = unsafeWindowFunction1 "ntile"
2414−
2415−{- | returns value evaluated at the row that is offset rows before the current
2416−row within the partition; if there is no such row, instead return default
2417−(which must be of the same type as value). Both offset and default are
2418−evaluated with respect to the current row.
2419−-}
2420−lag :: WinFunN '[ty, 'NotNull 'PGint4, ty] ty
2421−lag = unsafeWindowFunctionN "lag"
2422−
2423−{- | returns value evaluated at the row that is offset rows after the current
2424−row within the partition; if there is no such row, instead return default
2425−(which must be of the same type as value). Both offset and default are
2426−evaluated with respect to the current row.
2427−-}
2428−lead :: WinFunN '[ty, 'NotNull 'PGint4, ty] ty
2429−lead = unsafeWindowFunctionN "lag"
2430−
2431−{- | returns value evaluated at the row that is the
2432−first row of the window frame
2433−-}
2434−firstValue :: WinFun1 ty ty
2435−firstValue = unsafeWindowFunction1 "first_value"
2436−
2437−{- | returns value evaluated at the row that is the
2438−last row of the window frame
2439−-}
2440−lastValue :: WinFun1 ty ty
2441−lastValue = unsafeWindowFunction1 "last_value"
2442−
2443−{- | returns value evaluated at the row that is the nth
2444−row of the window frame (counting from 1); null if no such row
2445−-}
2446−nthValue :: WinFunN '[null ty, 'NotNull 'PGint4] ('Null ty)
2447−nthValue = unsafeWindowFunctionN "nth_value"
2448−
2449−{-|
2450−Create date from year, month and day fields
2451−
2452−>>> printSQL (makeDate (1984 :* 7 *: 3))
2453−make_date(1984, 7, 3)
2454−-}
2455−makeDate :: FunctionN
2456− '[ null 'PGint4, null 'PGint4, null 'PGint4 ]
2457− ( null 'PGdate )
2458−makeDate = unsafeFunctionN "make_date"
2459−
2460−{-|
2461−Create time from hour, minute and seconds fields
2462−
2463−>>> printSQL (makeTime (8 :* 15 *: 23.5))
2464−make_time(8, 15, 23.5)
2465−-}
2466−makeTime :: FunctionN
2467− '[ null 'PGint4, null 'PGint4, null 'PGfloat8 ]
2468− ( null 'PGtime )
2469−makeTime = unsafeFunctionN "make_time"
2470−
2471−{-|
2472−Create timestamp from year, month, day, hour, minute and seconds fields
2473−
2474−>>> printSQL (makeTimestamp (2013 :* 7 :* 15 :* 8 :* 15 *: 23.5))
2475−make_timestamp(2013, 7, 15, 8, 15, 23.5)
2476−-}
2477−makeTimestamp :: FunctionN
2478− '[ null 'PGint4, null 'PGint4, null 'PGint4
2479− , null 'PGint4, null 'PGint4, null 'PGfloat8 ]
2480− ( null 'PGtimestamp )
2481−makeTimestamp = unsafeFunctionN "make_timestamp"
2482−
2483−{-|
2484−Create timestamp with time zone from
2485−year, month, day, hour, minute and seconds fields;
2486−the current time zone is used
2487−
2488−>>> printSQL (makeTimestamptz (2013 :* 7 :* 15 :* 8 :* 15 *: 23.5))
2489−make_timestamptz(2013, 7, 15, 8, 15, 23.5)
2490−-}
2491−makeTimestamptz :: FunctionN
2492− '[ null 'PGint4, null 'PGint4, null 'PGint4
2493− , null 'PGint4, null 'PGint4, null 'PGfloat8 ]
2494− ( null 'PGtimestamptz )
2495−makeTimestamptz = unsafeFunctionN "make_timestamptz"
2496−
2497−{-|
2498−Affine space operations on time types.
2499−-}
2500−class TimeOp time diff | time -> diff where
2501− {-|
2502− >>> printSQL (makeDate (1984 :* 7 *: 3) !+ 365)
2503− (make_date(1984, 7, 3) + 365)
2504− -}
2505− (!+) :: Operator (null time) (null diff) (null time)
2506− (!+) = unsafeBinaryOp "+"
2507− {-|
2508− >>> printSQL (365 +! makeDate (1984 :* 7 *: 3))
2509− (365 + make_date(1984, 7, 3))
2510− -}
2511− (+!) :: Operator (null diff) (null time) (null time)
2512− (+!) = unsafeBinaryOp "+"
2513− {-|
2514− >>> printSQL (makeDate (1984 :* 7 *: 3) !- 365)
2515− (make_date(1984, 7, 3) - 365)
2516− -}
2517− (!-) :: Operator (null time) (null diff) (null time)
2518− (!-) = unsafeBinaryOp "-"
2519− {-|
2520− >>> printSQL (makeDate (1984 :* 7 *: 3) !-! currentDate)
2521− (make_date(1984, 7, 3) - CURRENT_DATE)
2522− -}
2523− (!-!) :: Operator (null time) (null time) (null diff)
2524− (!-!) = unsafeBinaryOp "-"
2525−instance TimeOp 'PGtimestamp 'PGinterval
2526−instance TimeOp 'PGtimestamptz 'PGinterval
2527−instance TimeOp 'PGtime 'PGinterval
2528−instance TimeOp 'PGtimetz 'PGinterval
2529−instance TimeOp 'PGinterval 'PGinterval
2530−instance TimeOp 'PGdate 'PGint4
2531−infixl 6 !+
2532−infixl 6 +!
2533−infixl 6 !-
2534−infixl 6 !-!
2535−
2536−data TimeUnit
2537− = Years | Months | Weeks | Days
2538− | Hours | Minutes | Seconds
2539− | Microseconds | Milliseconds
2540− | Decades | Centuries | Millennia
2541− deriving (Eq, Ord, Show, Read, Enum, GHC.Generic)
2542−instance SOP.Generic TimeUnit
2543−instance SOP.HasDatatypeInfo TimeUnit
2544−instance RenderSQL TimeUnit where
2545− renderSQL = \case
2546− Years -> "years"
2547− Months -> "months"
2548− Weeks -> "weeks"
2549− Days -> "days"
2550− Hours -> "hours"
2551− Minutes -> "minutes"
2552− Seconds -> "seconds"
2553− Microseconds -> "microseconds"
2554− Milliseconds -> "milliseconds"
2555− Decades -> "decades"
2556− Centuries -> "centuries"
2557− Millennia -> "millennia"
2558−
2559−-- | >>> printSQL $ interval_ 7 Days
2560−-- (INTERVAL '7.0 days')
2561−interval_ :: Double -> TimeUnit -> Expr (null 'PGinterval)
2562−interval_ num unit = UnsafeExpression . parenthesized $ "INTERVAL" <+>
2563− "'" <> fromString (show num) <+> renderSQL unit <> "'"
2564−
2565−class Literal hask where
2566− literal :: hask -> Expr (null (PG hask))
2567−instance JSON.ToJSON hask => Literal (Json hask) where
2568− literal = cast json . UnsafeExpression
2569− . singleQuotedUtf8 . toStrict . JSON.encode . getJson
2570−instance JSON.ToJSON hask => Literal (Jsonb hask) where
2571− literal = cast jsonb . UnsafeExpression
2572− . singleQuotedUtf8 . toStrict . JSON.encode . getJsonb
2573−instance Literal Char where
2574− literal chr = UnsafeExpression $
2575− "E\'" <> fromString (escape chr) <> "\'"
2576−instance Literal String where literal = fromString
2577−instance Literal Int16 where literal = fromIntegral
2578−instance Literal Int32 where literal = fromIntegral
2579−instance Literal Int64 where literal = fromIntegral
2580−instance Literal Float where literal = fromRational . toRational
2581−instance Literal Double where literal = fromRational . toRational
2582−instance Literal Text where literal = fromString . Text.unpack
2583−instance Literal Lazy.Text where literal = fromString . Lazy.Text.unpack
2584−instance ToParam (Enumerated enum) (PG (Enumerated enum))
2585− => Literal (Enumerated enum) where
2586− literal
2587− = UnsafeExpression
2588− . singleQuotedUtf8
2589− . builderBytes
2590− . unK
2591− . toParam @(Enumerated enum) @(PG (Enumerated enum))