2022-04-22 16:38:35 +03:00
|
|
|
-- | This module defines the top-level translation functions pertaining to
|
|
|
|
-- queries that use aggregation (i.e., /not/ so-called "simple" selects) into
|
|
|
|
-- Postgres AST.
|
|
|
|
module Hasura.Backends.Postgres.Translate.Select.Aggregate
|
|
|
|
( mkAggregateSelect,
|
|
|
|
selectAggregateQuerySQL,
|
|
|
|
)
|
|
|
|
where
|
|
|
|
|
|
|
|
import Control.Monad.Writer.Strict (runWriter)
|
2023-01-27 17:36:35 +03:00
|
|
|
import Database.PG.Query (Query)
|
2022-04-22 16:38:35 +03:00
|
|
|
import Hasura.Backends.Postgres.SQL.DML (BoolExp (BELit), Select)
|
2022-09-16 17:59:23 +03:00
|
|
|
import Hasura.Backends.Postgres.SQL.Types (IsIdentifier (toIdentifier))
|
2022-04-22 16:38:35 +03:00
|
|
|
import Hasura.Backends.Postgres.Translate.Select.AnnotatedFieldJSON
|
2022-04-22 20:18:20 +03:00
|
|
|
import Hasura.Backends.Postgres.Translate.Select.Internal.GenerateSelect (generateSQLSelectFromArrayNode)
|
2023-01-27 17:36:35 +03:00
|
|
|
import Hasura.Backends.Postgres.Translate.Select.Internal.Helpers (selectToSelectWith, toQuery)
|
2022-04-22 20:18:20 +03:00
|
|
|
import Hasura.Backends.Postgres.Translate.Select.Internal.Process (processAnnAggregateSelect)
|
2023-01-27 17:36:35 +03:00
|
|
|
import Hasura.Backends.Postgres.Translate.Types (CustomSQLCTEs, MultiRowSelectNode (MultiRowSelectNode), SelectNode (SelectNode), SelectWriter (..), SourcePrefixes (SourcePrefixes))
|
2022-04-22 16:38:35 +03:00
|
|
|
import Hasura.Prelude
|
2022-09-16 17:59:23 +03:00
|
|
|
import Hasura.RQL.IR.Select (AnnAggregateSelect, AnnSelectG (_asnStrfyNum))
|
2022-04-22 16:38:35 +03:00
|
|
|
import Hasura.RQL.Types.Backend (Backend)
|
2023-04-24 21:35:48 +03:00
|
|
|
import Hasura.RQL.Types.BackendType (BackendType (Postgres))
|
2022-04-22 16:38:35 +03:00
|
|
|
import Hasura.RQL.Types.Common (FieldName (FieldName))
|
|
|
|
|
|
|
|
-- | Translates IR to Postgres queries for aggregated SELECTs.
|
|
|
|
--
|
|
|
|
-- See 'mkAggregateSelect' for the Postgres AST.
|
|
|
|
selectAggregateQuerySQL ::
|
|
|
|
forall pgKind.
|
|
|
|
(Backend ('Postgres pgKind), PostgresAnnotatedFieldJSON pgKind) =>
|
|
|
|
AnnAggregateSelect ('Postgres pgKind) ->
|
|
|
|
Query
|
2023-01-27 17:36:35 +03:00
|
|
|
selectAggregateQuerySQL =
|
|
|
|
toQuery
|
|
|
|
. selectToSelectWith
|
|
|
|
. mkAggregateSelect
|
2022-04-22 16:38:35 +03:00
|
|
|
|
2022-09-22 16:56:50 +03:00
|
|
|
-- | We process aggregate queries differently because the types of aggregate queries are different.
|
|
|
|
-- In the '_asnFields' field of an 'AnnSelectG', we will have a 'TableAggregateFieldG' instead
|
|
|
|
-- of an 'AnnFieldG'.
|
2022-04-22 16:38:35 +03:00
|
|
|
mkAggregateSelect ::
|
2023-01-27 17:36:35 +03:00
|
|
|
forall pgKind m.
|
|
|
|
( Backend ('Postgres pgKind),
|
|
|
|
PostgresAnnotatedFieldJSON pgKind,
|
|
|
|
MonadWriter CustomSQLCTEs m
|
|
|
|
) =>
|
2022-04-22 16:38:35 +03:00
|
|
|
AnnAggregateSelect ('Postgres pgKind) ->
|
2023-01-27 17:36:35 +03:00
|
|
|
m Select
|
|
|
|
mkAggregateSelect annAggSel = do
|
|
|
|
let ( (selectSource, nodeExtractors, topExtractor),
|
|
|
|
SelectWriter {_swJoinTree = joinTree, _swCustomSQLCTEs = customSQLCTEs}
|
|
|
|
) =
|
2023-05-24 16:51:56 +03:00
|
|
|
runWriter
|
|
|
|
$ flip runReaderT strfyNum
|
|
|
|
$ processAnnAggregateSelect sourcePrefixes rootFieldName annAggSel
|
2022-09-22 16:56:50 +03:00
|
|
|
-- select the relevant columns and subquery we want to aggregate
|
2022-04-22 16:38:35 +03:00
|
|
|
selectNode = SelectNode nodeExtractors joinTree
|
2022-09-22 16:56:50 +03:00
|
|
|
-- aggregate the results into a top-level return value
|
2022-04-22 16:38:35 +03:00
|
|
|
arrayNode = MultiRowSelectNode [topExtractor] selectNode
|
2023-01-27 17:36:35 +03:00
|
|
|
tell customSQLCTEs
|
|
|
|
|
|
|
|
pure $ generateSQLSelectFromArrayNode selectSource arrayNode $ BELit True
|
2022-04-22 16:38:35 +03:00
|
|
|
where
|
|
|
|
strfyNum = _asnStrfyNum annAggSel
|
|
|
|
rootFieldName = FieldName "root"
|
|
|
|
rootIdentifier = toIdentifier rootFieldName
|
|
|
|
sourcePrefixes = SourcePrefixes rootIdentifier rootIdentifier
|