module Hasura.Backends.Postgres.Translate.Select.Simple
( mkSQLSelect,
selectQuerySQL,
)
where
import Control.Monad.Writer.Strict (runWriter)
import Database.PG.Query (Query, fromBuilder)
import Hasura.Backends.Postgres.SQL.DML qualified as S
import Hasura.Backends.Postgres.SQL.RenameIdentifiers (renameIdentifiers)
import Hasura.Backends.Postgres.SQL.Types (IsIdentifier (toIdentifier))
import Hasura.Backends.Postgres.Translate.Select.AnnotatedFieldJSON
import Hasura.Backends.Postgres.Translate.Select.Internal.Extractor (asJsonAggExtr)
import Hasura.Backends.Postgres.Translate.Select.Internal.GenerateSelect (generateSQLSelectFromArrayNode)
import Hasura.Backends.Postgres.Translate.Select.Internal.Process (processAnnSimpleSelect)
import Hasura.Backends.Postgres.Translate.Types
import Hasura.Prelude
import Hasura.RQL.IR.Select
( AnnSelectG (_asnStrfyNum),
AnnSimpleSelect,
)
import Hasura.RQL.Types.Backend (Backend)
import Hasura.RQL.Types.Common
( FieldName (FieldName),
JsonAggSelect,
)
import Hasura.SQL.Backend (BackendType (Postgres))
import Hasura.SQL.Types (ToSQL (toSQL))
selectQuerySQL ::
forall pgKind.
(Backend ('Postgres pgKind), PostgresAnnotatedFieldJSON pgKind) =>
JsonAggSelect ->
AnnSimpleSelect ('Postgres pgKind) ->
Query
selectQuerySQL :: JsonAggSelect -> AnnSimpleSelect ('Postgres pgKind) -> Query
selectQuerySQL JsonAggSelect
jsonAggSelect AnnSimpleSelect ('Postgres pgKind)
sel =
Builder -> Query
fromBuilder (Builder -> Query) -> Builder -> Query
forall a b. (a -> b) -> a -> b
$ Select -> Builder
forall a. ToSQL a => a -> Builder
toSQL (Select -> Builder) -> Select -> Builder
forall a b. (a -> b) -> a -> b
$ JsonAggSelect -> AnnSimpleSelect ('Postgres pgKind) -> Select
forall (pgKind :: PostgresKind).
(Backend ('Postgres pgKind), PostgresAnnotatedFieldJSON pgKind) =>
JsonAggSelect -> AnnSimpleSelect ('Postgres pgKind) -> Select
mkSQLSelect JsonAggSelect
jsonAggSelect AnnSimpleSelect ('Postgres pgKind)
sel
mkSQLSelect ::
forall pgKind.
( Backend ('Postgres pgKind),
PostgresAnnotatedFieldJSON pgKind
) =>
JsonAggSelect ->
AnnSimpleSelect ('Postgres pgKind) ->
S.Select
mkSQLSelect :: JsonAggSelect -> AnnSimpleSelect ('Postgres pgKind) -> Select
mkSQLSelect JsonAggSelect
jsonAggSelect AnnSimpleSelect ('Postgres pgKind)
annSel =
let permLimitSubQuery :: PermissionLimitSubQuery
permLimitSubQuery = PermissionLimitSubQuery
PLSQNotRequired
((SelectSource
selectSource, HashMap ColumnAlias SQLExp
nodeExtractors), JoinTree
joinTree) =
Writer JoinTree (SelectSource, HashMap ColumnAlias SQLExp)
-> ((SelectSource, HashMap ColumnAlias SQLExp), JoinTree)
forall w a. Writer w a -> (a, w)
runWriter (Writer JoinTree (SelectSource, HashMap ColumnAlias SQLExp)
-> ((SelectSource, HashMap ColumnAlias SQLExp), JoinTree))
-> Writer JoinTree (SelectSource, HashMap ColumnAlias SQLExp)
-> ((SelectSource, HashMap ColumnAlias SQLExp), JoinTree)
forall a b. (a -> b) -> a -> b
$
(ReaderT
StringifyNumbers
(WriterT JoinTree Identity)
(SelectSource, HashMap ColumnAlias SQLExp)
-> StringifyNumbers
-> Writer JoinTree (SelectSource, HashMap ColumnAlias SQLExp))
-> StringifyNumbers
-> ReaderT
StringifyNumbers
(WriterT JoinTree Identity)
(SelectSource, HashMap ColumnAlias SQLExp)
-> Writer JoinTree (SelectSource, HashMap ColumnAlias SQLExp)
forall a b c. (a -> b -> c) -> b -> a -> c
flip ReaderT
StringifyNumbers
(WriterT JoinTree Identity)
(SelectSource, HashMap ColumnAlias SQLExp)
-> StringifyNumbers
-> Writer JoinTree (SelectSource, HashMap ColumnAlias SQLExp)
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT StringifyNumbers
strfyNum (ReaderT
StringifyNumbers
(WriterT JoinTree Identity)
(SelectSource, HashMap ColumnAlias SQLExp)
-> Writer JoinTree (SelectSource, HashMap ColumnAlias SQLExp))
-> ReaderT
StringifyNumbers
(WriterT JoinTree Identity)
(SelectSource, HashMap ColumnAlias SQLExp)
-> Writer JoinTree (SelectSource, HashMap ColumnAlias SQLExp)
forall a b. (a -> b) -> a -> b
$
SourcePrefixes
-> FieldName
-> PermissionLimitSubQuery
-> AnnSimpleSelect ('Postgres pgKind)
-> ReaderT
StringifyNumbers
(WriterT JoinTree Identity)
(SelectSource, HashMap ColumnAlias SQLExp)
forall (pgKind :: PostgresKind) (m :: * -> *).
(MonadReader StringifyNumbers m, MonadWriter JoinTree m,
Backend ('Postgres pgKind), PostgresAnnotatedFieldJSON pgKind) =>
SourcePrefixes
-> FieldName
-> PermissionLimitSubQuery
-> AnnSimpleSelect ('Postgres pgKind)
-> m (SelectSource, HashMap ColumnAlias SQLExp)
processAnnSimpleSelect SourcePrefixes
sourcePrefixes FieldName
rootFldName PermissionLimitSubQuery
permLimitSubQuery AnnSimpleSelect ('Postgres pgKind)
annSel
selectNode :: SelectNode
selectNode = HashMap ColumnAlias SQLExp -> JoinTree -> SelectNode
SelectNode HashMap ColumnAlias SQLExp
nodeExtractors JoinTree
joinTree
topExtractor :: Extractor
topExtractor =
JsonAggSelect
-> ColumnAlias
-> PermissionLimitSubQuery
-> Maybe OrderByExp
-> Extractor
asJsonAggExtr JsonAggSelect
jsonAggSelect ColumnAlias
rootFldAls PermissionLimitSubQuery
permLimitSubQuery (Maybe OrderByExp -> Extractor) -> Maybe OrderByExp -> Extractor
forall a b. (a -> b) -> a -> b
$
SelectSource -> Maybe OrderByExp
orderByForJsonAgg SelectSource
selectSource
arrayNode :: MultiRowSelectNode
arrayNode = [Extractor] -> SelectNode -> MultiRowSelectNode
MultiRowSelectNode [Extractor
topExtractor] SelectNode
selectNode
in Select -> Select
renameIdentifiers (Select -> Select) -> Select -> Select
forall a b. (a -> b) -> a -> b
$
SelectSource -> MultiRowSelectNode -> BoolExp -> Select
generateSQLSelectFromArrayNode SelectSource
selectSource MultiRowSelectNode
arrayNode (BoolExp -> Select) -> BoolExp -> Select
forall a b. (a -> b) -> a -> b
$ Bool -> BoolExp
S.BELit Bool
True
where
strfyNum :: StringifyNumbers
strfyNum = AnnSelectG
('Postgres pgKind) (AnnFieldG ('Postgres pgKind) Void) SQLExp
-> StringifyNumbers
forall (b :: BackendType) (f :: * -> *) v.
AnnSelectG b f v -> StringifyNumbers
_asnStrfyNum AnnSimpleSelect ('Postgres pgKind)
AnnSelectG
('Postgres pgKind) (AnnFieldG ('Postgres pgKind) Void) SQLExp
annSel
rootFldIdentifier :: Identifier
rootFldIdentifier = FieldName -> Identifier
forall a. IsIdentifier a => a -> Identifier
toIdentifier FieldName
rootFldName
sourcePrefixes :: SourcePrefixes
sourcePrefixes = Identifier -> Identifier -> SourcePrefixes
SourcePrefixes Identifier
rootFldIdentifier Identifier
rootFldIdentifier
rootFldName :: FieldName
rootFldName = Text -> FieldName
FieldName Text
"root"
rootFldAls :: ColumnAlias
rootFldAls = Identifier -> ColumnAlias
forall a. IsIdentifier a => a -> ColumnAlias
S.toColumnAlias (Identifier -> ColumnAlias) -> Identifier -> ColumnAlias
forall a b. (a -> b) -> a -> b
$ FieldName -> Identifier
forall a. IsIdentifier a => a -> Identifier
toIdentifier FieldName
rootFldName