@@ -11,6 +11,7 @@ Squeal expressions are the atoms used to build statements.
11{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
11{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
12{-# LANGUAGE
12{-# LANGUAGE
13 AllowAmbiguousTypes
13 AllowAmbiguousTypes
14 , DeriveGeneric
15 , DeriveGeneric
15 , FlexibleContexts
16 , FlexibleContexts
16 , FlexibleInstances
17 , FlexibleInstances
@@ -477,6 +478,14 @@ unsafeFunction
477unsafeFunction fun x = UnsafeExpression $
478unsafeFunction fun x = UnsafeExpression $
478 fun <> parenthesized (renderExpression x)
479 fun <> parenthesized (renderExpression x)
481+unsafeVariadicFunction
484+ -> [Expression schema relations grouping params xty]
485+ -> Expression schema relations grouping params (yty)
486+unsafeVariadicFunction fun x = UnsafeExpression $
487+ fun <> parenthesized (commaSeparated (map renderExpression x))
480instance PGNum ty
489instance PGNum ty
481 => Num (Expression schema relations grouping params (nullity ty)) where
490 => Num (Expression schema relations grouping params (nullity ty)) where
482 (+) = unsafeBinaryOp "+"
491 (+) = unsafeBinaryOp "+"
@@ -865,6 +874,168 @@ like
865 -> Expression schema relations grouping params (nullity 'PGbool)
874 -> Expression schema relations grouping params (nullity 'PGbool)
866like = unsafeBinaryOp "LIKE"
875like = unsafeBinaryOp "LIKE"
877+{-----------------------------------------
878+json and jsonb operators
879+see https://www.postgresql.org/docs/10/static/functions-json.html
880+-----------------------------------------}
882+type IsJSONKey key = key `In` '[ 'PGint2, 'PGint4, 'PGtext ]
883+type IsJSON json = json `In` '[ 'PGjson, 'PGjsonb ]
885+class IsArray arr => IsArrayOf arr ty
886+instance arrTy ~ expectTy => IsArrayOf ('PGvararray arrTy) expectTy
887+instance arrTy ~ expectTy => IsArrayOf ('PGfixarray n arrTy) expectTy
889+-- IsArray will generate nicer error messages when it is all that is required.
891+instance IsArray ('PGvararray x)
892+instance IsArray ('PGfixarray n x)
894+type IsPGtextArray arr = IsArrayOf arr 'PGtext
896+-- | Get JSON value (object field or array element) at a key.
898+ :: (IsJSON json, IsJSONKey key)
899+ => Expression schema relations grouping params (jnull json)
900+ -> Expression schema relations grouping params (knull key)
901+ -> Expression schema relations grouping params ('Null json)
902+(.->) = unsafeBinaryOp "->"
904+-- | Get JSON value (object field or array element) at a key, as text.
906+ :: (IsJSON json, IsJSONKey key)
907+ => Expression schema relations grouping params (jnull json)
908+ -> Expression schema relations grouping params (knull key)
909+ -> Expression schema relations grouping params ('Null 'PGtext)
910+(.->>) = unsafeBinaryOp "->>"
912+-- | Get JSON value at a specified path.
914+ :: (IsJSON json, IsPGtextArray path)
915+ => Expression schema relations grouping params (jnull json)
916+ -> Expression schema relations grouping params (knull path)
917+ -> Expression schema relations grouping params ('Null json)
918+(.#>) = unsafeBinaryOp "#>"
920+-- | Get JSON value at a specified path as text.
922+ :: (IsJSON json, IsPGtextArray path)
923+ => Expression schema relations grouping params (jnull json)
924+ -> Expression schema relations grouping params (knull path)
925+ -> Expression schema relations grouping params ('Null 'PGtext)
926+(.#>>) = unsafeBinaryOp "#>"
928+-- Additional jsonb operators
930+-- | Or operator for nulls; if either argument is null, then the result is null.
931+type family Null2 a b where
932+ Null2 'Null a = 'Null
933+ Null2 a 'Null = 'Null
934+ Null2 'NotNull 'NotNull = 'NotNull
937+type family NullOfN xs where
938+ NullOfN ('Null ty:xs) = 'Null
939+ NullOfN (x:xs) = NullOfN xs
940+ NullOfN '[] = 'NotNull
942+-- | Does the left JSON value contain the right JSON path/value entries at the
945+ :: Expression schema relations grouping params (null0 'PGjsonb)
946+ -> Expression schema relations grouping params (null1 'PGjsonb)
947+ -> Expression schema relations grouping params (Null2 null0 null1 'PGbool)
948+(.@>) = unsafeBinaryOp "@>"
950+-- | Are the left JSON path/value entries contained at the top level within the
953+ :: Expression schema relations grouping params (null0 'PGjsonb)
954+ -> Expression schema relations grouping params (null1 'PGjsonb)
955+ -> Expression schema relations grouping params (Null2 null0 null1 'PGbool)
956+(.<@) = unsafeBinaryOp "<@"
958+-- | Does the string exist as a top-level key within the JSON value?
960+ :: Expression schema relations grouping params (null0 'PGjsonb)
961+ -> Expression schema relations grouping params (null1 'PGtext)
962+ -> Expression schema relations grouping params (Null2 null0 null1 'PGbool)
963+(.?) = unsafeBinaryOp "?"
965+-- | Do any of these array strings exist as top-level keys?
967+ :: Expression schema relations grouping params (null0 'PGjsonb)
968+ -> Expression schema relations grouping params (null1 ('PGvararray 'PGtext))
969+ -> Expression schema relations grouping params (Null2 null0 null1 'PGbool)
970+(.?|) = unsafeBinaryOp "?|"
972+-- | Do all of these array strings exist as top-level keys?
974+ :: Expression schema relations grouping params (null0 'PGjsonb)
975+ -> Expression schema relations grouping params (null1 ('PGvararray 'PGtext))
976+ -> Expression schema relations grouping params (Null2 null0 null1 'PGbool)
977+(.?&) = unsafeBinaryOp "?&"
979+-- | Concatenate two jsonb values into a new jsonb value
981+ :: Expression schema relations grouping params (null0 'PGjsonb)
982+ -> Expression schema relations grouping params (null1 'PGjsonb)
983+ -> Expression schema relations grouping params (Null2 null0 null1 'PGjsonb)
984+(.||.) = unsafeBinaryOp "||"
986+-- | Delete a key or keys from a JSON object, or remove an array element.
988+-- If the right operand is..
990+-- @ text @: Delete key/value pair or string element from left operand. Key/value pairs
991+-- are matched based on their key value.
993+-- @ text[] @: Delete multiple key/value pairs or string elements
994+-- from left operand. Key/value pairs are matched based on their key value.
996+-- @ integer @: Delete the array element with specified index (Negative integers
997+-- count from the end). Throws an error if top level container is not an array.
999+ :: (key `In` '[ 'PGtext, 'PGvararray 'PGtext, 'PGint4, 'PGint2 ]) -- hlint error without parens here
1000+ => Expression schema relations grouping params (null0 'PGjsonb)
1001+ -> Expression schema relations grouping params (null1 key)
1002+ -> Expression schema relations grouping params (Null2 null0 null1 'PGjsonb)
1003+(.-.) = unsafeBinaryOp "-"
1005+-- | Delete the field or element with specified path (for JSON arrays, negative
1006+-- integers count from the end)
1008+ :: IsPGtextArray arrayty
1009+ => Expression schema relations grouping params (null0 'PGjsonb)
1010+ -> Expression schema relations grouping params (null1 arrayty)
1011+ -> Expression schema relations grouping params (Null2 null0 null1 'PGjsonb)
1012+(#-.) = unsafeBinaryOp "#-"
1015+ :: Expression schema relations grouping params (nullity ty)
1016+ -> Expression schema relations grouping params (nullity 'PGjson)
1017+toJson = unsafeFunction "to_json"
1020+ :: Expression schema relations grouping params (nullity ty)
1021+ -> Expression schema relations grouping params (nullity 'PGjsonb)
1022+toJsonb = unsafeUnaryOp "to_jsonb"
1026+ => Expression schema relations grouping params (nullity arr)
1027+ -> Expression schema relations grouping params (nullity 'PGjson)
1028+arrayToJson = unsafeFunction "array_to_json"
1031+ :: Expression schema relations grouping params (nullity ('PGcomposite ty))
1032+ -> Expression schema relations grouping params (nullity 'PGjson)
1033+rowToJson = unsafeFunction "row_to_json"
1035+-- TODO: jsonBuildArray, jsonbBuildArray, jsonObject, jsonbObject
1036+-- probably something like
1037+-- :: NP (Expression s r g p) xs -> Expression s r g p ('NotNull 'PGjson[b])
868{-----------------------------------------
1039{-----------------------------------------
869aggregation
1040aggregation
870-----------------------------------------}
1041-----------------------------------------}