module Hasura.Backends.Postgres.Translate.Select.Internal.Helpers
( mkFirstElementExp,
mkLastElementExp,
cursorIdentifier,
startCursorIdentifier,
endCursorIdentifier,
hasNextPageIdentifier,
hasPreviousPageIdentifier,
pageInfoSelectAliasIdentifier,
cursorsSelectAliasIdentifier,
encodeBase64,
fromTableRowArgs,
selectFromToFromItem,
functionToIdentifier,
withJsonBuildObj,
withForceAggregation,
)
where
import Hasura.Backends.Postgres.SQL.DML qualified as S
import Hasura.Backends.Postgres.SQL.Types (Identifier (..), QualifiedFunction, qualifiedObjectToText, toIdentifier)
import Hasura.Backends.Postgres.Translate.Select.Internal.Aliases
import Hasura.Backends.Postgres.Types.Function
import Hasura.Prelude
import Hasura.RQL.IR
import Hasura.RQL.Types.Common (FieldName)
import Hasura.RQL.Types.Function
import Hasura.SQL.Backend
mkFirstElementExp :: S.SQLExp -> S.SQLExp
mkFirstElementExp :: SQLExp -> SQLExp
mkFirstElementExp SQLExp
expIdentifier =
SQLExp -> SQLExp -> SQLExp
S.SEArrayIndex (Text -> [SQLExp] -> Maybe OrderByExp -> SQLExp
S.SEFnApp Text
"array_agg" [SQLExp
expIdentifier] Maybe OrderByExp
forall a. Maybe a
Nothing) (Int -> SQLExp
S.intToSQLExp Int
1)
mkLastElementExp :: S.SQLExp -> S.SQLExp
mkLastElementExp :: SQLExp -> SQLExp
mkLastElementExp SQLExp
expIdentifier =
let arrayExp :: SQLExp
arrayExp = Text -> [SQLExp] -> Maybe OrderByExp -> SQLExp
S.SEFnApp Text
"array_agg" [SQLExp
expIdentifier] Maybe OrderByExp
forall a. Maybe a
Nothing
in SQLExp -> SQLExp -> SQLExp
S.SEArrayIndex SQLExp
arrayExp (SQLExp -> SQLExp) -> SQLExp -> SQLExp
forall a b. (a -> b) -> a -> b
$
Text -> [SQLExp] -> Maybe OrderByExp -> SQLExp
S.SEFnApp Text
"array_length" [SQLExp
arrayExp, Int -> SQLExp
S.intToSQLExp Int
1] Maybe OrderByExp
forall a. Maybe a
Nothing
cursorIdentifier :: Identifier
cursorIdentifier :: Identifier
cursorIdentifier = Text -> Identifier
Identifier Text
"__cursor"
startCursorIdentifier :: Identifier
startCursorIdentifier :: Identifier
startCursorIdentifier = Text -> Identifier
Identifier Text
"__start_cursor"
endCursorIdentifier :: Identifier
endCursorIdentifier :: Identifier
endCursorIdentifier = Text -> Identifier
Identifier Text
"__end_cursor"
hasPreviousPageIdentifier :: Identifier
hasPreviousPageIdentifier :: Identifier
hasPreviousPageIdentifier = Text -> Identifier
Identifier Text
"__has_previous_page"
hasNextPageIdentifier :: Identifier
hasNextPageIdentifier :: Identifier
hasNextPageIdentifier = Text -> Identifier
Identifier Text
"__has_next_page"
pageInfoSelectAliasIdentifier :: Identifier
pageInfoSelectAliasIdentifier :: Identifier
pageInfoSelectAliasIdentifier = Text -> Identifier
Identifier Text
"__page_info"
cursorsSelectAliasIdentifier :: Identifier
= Text -> Identifier
Identifier Text
"__cursors_select"
encodeBase64 :: S.SQLExp -> S.SQLExp
encodeBase64 :: SQLExp -> SQLExp
encodeBase64 =
SQLExp -> SQLExp
removeNewline (SQLExp -> SQLExp) -> (SQLExp -> SQLExp) -> SQLExp -> SQLExp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SQLExp -> SQLExp
bytesToBase64Text (SQLExp -> SQLExp) -> (SQLExp -> SQLExp) -> SQLExp -> SQLExp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SQLExp -> SQLExp
convertToBytes
where
convertToBytes :: SQLExp -> SQLExp
convertToBytes SQLExp
e =
Text -> [SQLExp] -> Maybe OrderByExp -> SQLExp
S.SEFnApp Text
"convert_to" [SQLExp
e, Text -> SQLExp
S.SELit Text
"UTF8"] Maybe OrderByExp
forall a. Maybe a
Nothing
bytesToBase64Text :: SQLExp -> SQLExp
bytesToBase64Text SQLExp
e =
Text -> [SQLExp] -> Maybe OrderByExp -> SQLExp
S.SEFnApp Text
"encode" [SQLExp
e, Text -> SQLExp
S.SELit Text
"base64"] Maybe OrderByExp
forall a. Maybe a
Nothing
removeNewline :: SQLExp -> SQLExp
removeNewline SQLExp
e =
Text -> [SQLExp] -> Maybe OrderByExp -> SQLExp
S.SEFnApp Text
"regexp_replace" [SQLExp
e, Text -> SQLExp
S.SELit Text
"\\n", Text -> SQLExp
S.SELit Text
"", Text -> SQLExp
S.SELit Text
"g"] Maybe OrderByExp
forall a. Maybe a
Nothing
fromTableRowArgs ::
Identifier -> FunctionArgsExpG (ArgumentExp S.SQLExp) -> S.FunctionArgs
fromTableRowArgs :: Identifier -> FunctionArgsExpG (ArgumentExp SQLExp) -> FunctionArgs
fromTableRowArgs Identifier
prefix = FunctionArgsExpG SQLExp -> FunctionArgs
toFunctionArgs (FunctionArgsExpG SQLExp -> FunctionArgs)
-> (FunctionArgsExpG (ArgumentExp SQLExp)
-> FunctionArgsExpG SQLExp)
-> FunctionArgsExpG (ArgumentExp SQLExp)
-> FunctionArgs
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ArgumentExp SQLExp -> SQLExp)
-> FunctionArgsExpG (ArgumentExp SQLExp) -> FunctionArgsExpG SQLExp
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ArgumentExp SQLExp -> SQLExp
toSQLExp
where
toFunctionArgs :: FunctionArgsExpG SQLExp -> FunctionArgs
toFunctionArgs (FunctionArgsExp [SQLExp]
positional HashMap Text SQLExp
named) =
[SQLExp] -> HashMap Text SQLExp -> FunctionArgs
S.FunctionArgs [SQLExp]
positional HashMap Text SQLExp
named
toSQLExp :: ArgumentExp SQLExp -> SQLExp
toSQLExp =
SQLExp -> (Text -> SQLExp) -> ArgumentExp SQLExp -> SQLExp
forall a. a -> (Text -> a) -> ArgumentExp a -> a
onArgumentExp
(Identifier -> SQLExp
S.SERowIdentifier Identifier
alias)
(Identifier -> Identifier -> SQLExp
forall a b. (IsIdentifier a, IsIdentifier b) => a -> b -> SQLExp
S.mkQIdenExp Identifier
alias (Identifier -> SQLExp) -> (Text -> Identifier) -> Text -> SQLExp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Identifier
Identifier)
alias :: Identifier
alias = TableAlias -> Identifier
forall a. IsIdentifier a => a -> Identifier
toIdentifier (TableAlias -> Identifier) -> TableAlias -> Identifier
forall a b. (a -> b) -> a -> b
$ Identifier -> TableAlias
mkBaseTableAlias Identifier
prefix
selectFromToFromItem :: Identifier -> SelectFrom ('Postgres pgKind) -> S.FromItem
selectFromToFromItem :: Identifier -> SelectFrom ('Postgres pgKind) -> FromItem
selectFromToFromItem Identifier
pfx = \case
FromTable TableName ('Postgres pgKind)
tn -> QualifiedTable -> Maybe TableAlias -> FromItem
S.FISimple TableName ('Postgres pgKind)
QualifiedTable
tn Maybe TableAlias
forall a. Maybe a
Nothing
FromIdentifier FIIdentifier
i -> Identifier -> FromItem
S.FIIdentifier (Identifier -> FromItem) -> Identifier -> FromItem
forall a b. (a -> b) -> a -> b
$ FIIdentifier -> Identifier
forall a. IsIdentifier a => a -> Identifier
toIdentifier FIIdentifier
i
FromFunction FunctionName ('Postgres pgKind)
qf FunctionArgsExp
('Postgres pgKind) (SQLExpression ('Postgres pgKind))
args Maybe [(Column ('Postgres pgKind), ScalarType ('Postgres pgKind))]
defListM ->
FunctionExp -> FromItem
S.FIFunc (FunctionExp -> FromItem) -> FunctionExp -> FromItem
forall a b. (a -> b) -> a -> b
$
QualifiedFunction
-> FunctionArgs -> Maybe FunctionAlias -> FunctionExp
S.FunctionExp FunctionName ('Postgres pgKind)
QualifiedFunction
qf (Identifier -> FunctionArgsExpG (ArgumentExp SQLExp) -> FunctionArgs
fromTableRowArgs Identifier
pfx FunctionArgsExp
('Postgres pgKind) (SQLExpression ('Postgres pgKind))
FunctionArgsExpG (ArgumentExp SQLExp)
args) (Maybe FunctionAlias -> FunctionExp)
-> Maybe FunctionAlias -> FunctionExp
forall a b. (a -> b) -> a -> b
$
FunctionAlias -> Maybe FunctionAlias
forall a. a -> Maybe a
Just (FunctionAlias -> Maybe FunctionAlias)
-> FunctionAlias -> Maybe FunctionAlias
forall a b. (a -> b) -> a -> b
$
TableAlias -> Maybe [(ColumnAlias, PGScalarType)] -> FunctionAlias
S.mkFunctionAlias
(Identifier -> TableAlias
forall a. IsIdentifier a => a -> TableAlias
S.toTableAlias (Identifier -> TableAlias) -> Identifier -> TableAlias
forall a b. (a -> b) -> a -> b
$ QualifiedFunction -> Identifier
functionToIdentifier FunctionName ('Postgres pgKind)
QualifiedFunction
qf)
(([(PGCol, PGScalarType)] -> [(ColumnAlias, PGScalarType)])
-> Maybe [(PGCol, PGScalarType)]
-> Maybe [(ColumnAlias, PGScalarType)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((PGCol, PGScalarType) -> (ColumnAlias, PGScalarType))
-> [(PGCol, PGScalarType)] -> [(ColumnAlias, PGScalarType)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((PGCol -> ColumnAlias)
-> (PGCol, PGScalarType) -> (ColumnAlias, PGScalarType)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first PGCol -> ColumnAlias
forall a. IsIdentifier a => a -> ColumnAlias
S.toColumnAlias)) Maybe [(Column ('Postgres pgKind), ScalarType ('Postgres pgKind))]
Maybe [(PGCol, PGScalarType)]
defListM)
functionToIdentifier :: QualifiedFunction -> Identifier
functionToIdentifier :: QualifiedFunction -> Identifier
functionToIdentifier = Text -> Identifier
Identifier (Text -> Identifier)
-> (QualifiedFunction -> Text) -> QualifiedFunction -> Identifier
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QualifiedFunction -> Text
forall a. ToTxt a => QualifiedObject a -> Text
qualifiedObjectToText
withJsonBuildObj ::
FieldName -> [S.SQLExp] -> (S.ColumnAlias, S.SQLExp)
withJsonBuildObj :: FieldName -> [SQLExp] -> (ColumnAlias, SQLExp)
withJsonBuildObj FieldName
parAls [SQLExp]
exps =
(FieldName -> ColumnAlias
forall a. IsIdentifier a => a -> ColumnAlias
S.toColumnAlias FieldName
parAls, SQLExp
jsonRow)
where
jsonRow :: SQLExp
jsonRow = [SQLExp] -> SQLExp
S.applyJsonBuildObj [SQLExp]
exps
withForceAggregation :: S.TypeAnn -> S.SQLExp -> S.SQLExp
withForceAggregation :: TypeAnn -> SQLExp -> SQLExp
withForceAggregation TypeAnn
tyAnn SQLExp
e =
Text -> [SQLExp] -> Maybe OrderByExp -> SQLExp
S.SEFnApp Text
"coalesce" [SQLExp
e, SQLExp -> TypeAnn -> SQLExp
S.SETyAnn (Text -> SQLExp
S.SEUnsafe Text
"bool_or('true')") TypeAnn
tyAnn] Maybe OrderByExp
forall a. Maybe a
Nothing