@@ -36,7 +36,15 @@ module Squeal.PostgreSQL.Expression
3636 Expression (..)
3737 , Expr
3838 , Operator
39+ , unsafeBinaryOp
3940 , (:-->)
41+ , unsafeUnaryOpL
42+ , unsafeUnaryOpR
43+ , unsafeFunction
44+ , FunctionHom
45+ , unsafeFunctionHom
46+ , FunctionHet
47+ , unsafeFunctionHet
4048 , HasParameter (parameter)
4149 , param
4250 -- ** Null
@@ -56,11 +64,6 @@ module Squeal.PostgreSQL.Expression
5664 , field
5765 , PGSubset (..)
5866 -- ** Functions
59− , unsafeBinaryOp
60− , unsafeUnaryOpL
61− , unsafeUnaryOpR
62− , unsafeFunction
63− , unsafeFunctionHet
6467 , atan2_
6568 , cast
6669 , quot_
@@ -329,6 +332,12 @@ type (:-->) x y
329332 -> Expression outer grp commons schemas params from y
330333 -- ^ output
331334
335+{- | A `RankNType` for functions with a fixed-length list of heterogeneous arguments.
336+Use the `:*` operator to end your argument lists, like so.
337+
338+>>> printSQL (unsafeFunctionHet "fun" (true :* false :* localTime *: true))
339+fun(TRUE, FALSE, LOCALTIME, TRUE)
340+-}
332341type FunctionHet xs y
333342 = forall outer grp commons schemas params from
334343 . NP (Expression outer grp commons schemas params from) xs
@@ -336,6 +345,9 @@ type FunctionHet xs y
336345 -> Expression outer grp commons schemas params from y
337346 -- ^ output
338347
348+{- | A `RankNType` for functions with a variable-length list of
349+homogeneous arguments and at least 1 more argument.
350+-}
339351type FunctionHom x0 x1 y
340352 = forall outer grp commons schemas params from
341353 . [Expression outer grp commons schemas params from x0]
@@ -345,6 +357,9 @@ type FunctionHom x0 x1 y
345357 -> Expression outer grp commons schemas params from y
346358 -- ^ output
347359
360+{- | >>> printSQL (unsafeFunctionHom "greatest" [true, null_] false)
361+greatest(TRUE, NULL, FALSE)
362+-}
348363unsafeFunctionHom :: ByteString -> FunctionHom x0 x1 y
349364unsafeFunctionHom fun xs x = UnsafeExpression $ fun <> parenthesized
350365 (commaSeparated (renderSQL <$> xs) <> ", " <> renderSQL x)
@@ -654,6 +669,8 @@ unsafeBinaryOp op x y = UnsafeExpression $ parenthesized $
654669unsafeUnaryOpL :: ByteString {- ^ operator -} -> x :--> y
655670unsafeUnaryOpL op x = UnsafeExpression $ parenthesized $ op <+> renderSQL x
656671
672+-- | >>> printSQL $ true & unsafeUnaryOpR "IS NOT TRUE"
673+-- (TRUE IS NOT TRUE)
657674unsafeUnaryOpR :: ByteString {- ^ operator -} -> x :--> y
658675unsafeUnaryOpR op x = UnsafeExpression $ parenthesized $ renderSQL x <+> op
659676
@@ -663,6 +680,8 @@ unsafeFunction :: ByteString {- ^ function -} -> x :--> y
663680unsafeFunction fun x = UnsafeExpression $
664681 fun <> parenthesized (renderSQL x)
665682
683+-- | >>> printSQL $ unsafeFunctionHet "f" (currentTime :* localTimestamp :* false *: litChar 'a')
684+-- f(CURRENT_TIME, LOCALTIMESTAMP, FALSE, E'a')
666685unsafeFunctionHet
667686 :: SListI xs
668687 => ByteString {- ^ function -}