graphql-engine/server/src-lib/Hasura/Backends/Postgres/Translate/Select/Aggregate.hs
Abby Sassel 3056678e04 server/postgres: Implement execution of aggregation predicates
PR for the translation / execution step of [aggregation predicate filters](https://github.com/hasura/graphql-engine-mono/issues/5174).

[`translateAVAggregationPredicates`](translateAVAggregationPredicates) is the main change of note, everything else is a supporting or helper function. Please note this doesn't yet include [tests relating to permissions](https://hasurahq.slack.com/archives/C01RZPEPF0W/p1662560092197769); I decided to raise a PR without them for slightly faster feedback. I may include them in this PR or a separately if it's not trivial.

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/5724
GitOrigin-RevId: fcac258b64066e2bd45108372165a16fd957f5ab
2022-09-16 15:01:03 +00:00

55 lines
2.4 KiB
Haskell

-- | 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)
import Database.PG.Query (Query, fromBuilder)
import Hasura.Backends.Postgres.SQL.DML (BoolExp (BELit), Select)
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.GenerateSelect (generateSQLSelectFromArrayNode)
import Hasura.Backends.Postgres.Translate.Select.Internal.Process (processAnnAggregateSelect)
import Hasura.Backends.Postgres.Translate.Types (MultiRowSelectNode (MultiRowSelectNode), SelectNode (SelectNode), SourcePrefixes (SourcePrefixes))
import Hasura.Prelude
import Hasura.RQL.IR.Select (AnnAggregateSelect, AnnSelectG (_asnStrfyNum))
import Hasura.RQL.Types.Backend (Backend)
import Hasura.RQL.Types.Common (FieldName (FieldName))
import Hasura.SQL.Backend (BackendType (Postgres))
import Hasura.SQL.Types (ToSQL (toSQL))
-- | 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
selectAggregateQuerySQL = fromBuilder . toSQL . mkAggregateSelect
mkAggregateSelect ::
forall pgKind.
(Backend ('Postgres pgKind), PostgresAnnotatedFieldJSON pgKind) =>
AnnAggregateSelect ('Postgres pgKind) ->
Select
mkAggregateSelect annAggSel =
let ((selectSource, nodeExtractors, topExtractor), joinTree) =
runWriter $
flip runReaderT strfyNum $
processAnnAggregateSelect sourcePrefixes rootFieldName annAggSel
selectNode = SelectNode nodeExtractors joinTree
arrayNode = MultiRowSelectNode [topExtractor] selectNode
in renameIdentifiers $
generateSQLSelectFromArrayNode selectSource arrayNode $ BELit True
where
strfyNum = _asnStrfyNum annAggSel
rootFieldName = FieldName "root"
rootIdentifier = toIdentifier rootFieldName
sourcePrefixes = SourcePrefixes rootIdentifier rootIdentifier