@@ -26,6 +26,7 @@ Squeal expressions are the atoms used to build statements.
2626 , TypeInType
2727 , TypeOperators
2828 , UndecidableInstances
29+ , RankNTypes
2930#-}
3031
3132module Squeal.PostgreSQL.Expression
@@ -84,6 +85,27 @@ module Squeal.PostgreSQL.Expression
8485 , upper
8586 , charLength
8687 , like
88+ -- ** json or jsonb operators
89+ , PGarray
90+ , PGarrayOf
91+ , (.->)
92+ , (.->>)
93+ , (.#>)
94+ , (.#>>)
95+ -- *** jsonb only operators
96+ , (.@>)
97+ , (.<@)
98+ , (.?)
99+ , (.?|)
100+ , (.?&)
101+ , (.||.)
102+ , (.-.)
103+ , (#-.)
104+ -- *** Functions
105+ , toJson
106+ , toJsonb
107+ , arrayToJson
108+ , rowToJson
87109 -- ** Aggregation
88110 , unsafeAggregate, unsafeAggregateDistinct
89111 , sum_, sumDistinct
@@ -141,6 +163,7 @@ import Data.Semigroup
141163import Data.Ratio
142164import Data.String
143165import Generics.SOP hiding (from)
166+import GHC.Exts (Constraint)
144167import GHC.OverloadedLabels
145168import GHC.TypeLits
146169import Prelude hiding (id, (.))
@@ -882,16 +905,35 @@ see https://www.postgresql.org/docs/10/static/functions-json.html
882905type IsJSONKey key = key `In` '[ 'PGint2, 'PGint4, 'PGtext ]
883906type IsJSON json = json `In` '[ 'PGjson, 'PGjsonb ]
884907
885−class IsArray arr => IsArrayOf arr ty
886−instance arrTy ~ expectTy => IsArrayOf ('PGvararray arrTy) expectTy
887−instance arrTy ~ expectTy => IsArrayOf ('PGfixarray n arrTy) expectTy
888−
889−-- IsArray will generate nicer error messages when it is all that is required.
890−class IsArray arr
891−instance IsArray ('PGvararray x)
892−instance IsArray ('PGfixarray n x)
893−
894−type IsPGtextArray arr = IsArrayOf arr 'PGtext
908+type Placeholder k
909+ = 'Text "(_"
910+ ':<>: 'Text "::"
911+ ':<>: 'ShowType k ':<>:
912+ 'Text ")"
913+
914+type ErrArrayOf arr ty = arr ':<>: 'Text " " ':<>: ty
915+type ErrPGfixarrayOf t = ErrArrayOf ('ShowType 'PGfixarray ':<>: 'Text " " ':<>: Placeholder Nat) t
916+type ErrPGvararrayOf t = ErrArrayOf ('ShowType 'PGvararray) t
917+
918+type family PGarray arr :: Constraint where
919+ PGarray ('PGvararray x) = ()
920+ PGarray ('PGfixarray n x) = ()
921+ PGarray val = TypeError
922+ ('Text "Unsatisfied PGarrayOf constraint. Expected either: "
923+ ':$$: 'Text " • " ':<>: ErrPGvararrayOf (Placeholder PGType)
924+ ':$$: 'Text " • " ':<>: ErrPGfixarrayOf (Placeholder PGType)
925+ ':$$: 'Text "But got: " ':<>: 'ShowType val)
926+
927+type family PGarrayOf arr ty :: Constraint where
928+ PGarrayOf ('PGvararray x) ty = x ~ ty
929+ PGarrayOf ('PGfixarray n x) ty = x ~ ty
930+ PGarrayOf val ty = TypeError
931+ ('Text "Unsatisfied PGarrayOf constraint. Expected either: "
932+ ':$$: 'Text " • " ':<>: ErrPGvararrayOf ('ShowType ty)
933+ ':$$: 'Text " • " ':<>: ErrPGfixarrayOf ('ShowType ty)
934+ ':$$: 'Text "But got: " ':<>: 'ShowType val)
935+
936+type IsPGtextArray arr = PGarrayOf arr 'PGtext
895937
896938-- | Get JSON value (object field or array element) at a key.
897939(.->)
@@ -1022,7 +1064,7 @@ toJsonb
10221064toJsonb = unsafeUnaryOp "to_jsonb"
10231065
10241066arrayToJson
1025− :: IsArray arr
1067+ :: PGarray arr
10261068 => Expression schema relations grouping params (nullity arr)
10271069 -> Expression schema relations grouping params (nullity 'PGjson)
10281070arrayToJson = unsafeFunction "array_to_json"