-- | This module defines functions that translate from the Postgres IR into
-- Postgres SQL AST.
--
-- NOTE: These functions 'processAnnAggregateSelect', 'processAnnSimpleSelect',
-- 'processConnectionSelect', are all mutually recursive.
--
-- These functions are generally called from the top level functions in
-- Translate.Select, and the call stack looks like:
--
--     * 'selectQuerySQL' -> 'mkSQLSelect' -> 'processAnnSimpleSelect' -> 'processSelectParams'/'processAnnFields'
--
--     * 'selectAggregateQuerySQL' -> 'mkAggregateSelect' -> 'processAnnAggregateSelect' -> 'processSelectParams'/'processAnnFields'
--
--     * 'connetionSelectQuerySQL' -> 'mkConnectionSelect' -> 'processConnectionSelection' -> 'processSelectParams'
--
-- 'SelectSource' consists of a prefix, a source, a boolean conditional
-- expression, and info on whether sorting or slicing is done (needed to handle
-- the LIMIT optimisation)
module Hasura.Backends.Postgres.Translate.Select.Internal.Process
  ( processAnnAggregateSelect,
    processAnnSimpleSelect,
    processConnectionSelect,
  )
where

import Data.HashMap.Strict qualified as HM
import Data.List.NonEmpty qualified as NE
import Data.Text.Extended (ToTxt (toTxt))
import Hasura.Backends.Postgres.SQL.DML qualified as S
import Hasura.Backends.Postgres.SQL.Types
  ( Identifier,
    IsIdentifier (toIdentifier),
    PGCol (..),
    QualifiedObject (QualifiedObject),
    QualifiedTable,
    SchemaName (getSchemaTxt),
  )
import Hasura.Backends.Postgres.Translate.BoolExp (toSQLBoolExp)
import Hasura.Backends.Postgres.Translate.Column (toJSONableExp)
import Hasura.Backends.Postgres.Translate.Select.AnnotatedFieldJSON
import Hasura.Backends.Postgres.Translate.Select.Internal.Aliases
  ( mkAnnOrderByAlias,
    mkArrayRelationAlias,
    mkArrayRelationSourcePrefix,
    mkBaseTableAlias,
    mkBaseTableColumnAlias,
    mkComputedFieldTableAlias,
    mkObjectRelationTableAlias,
    mkOrderByFieldName,
  )
import Hasura.Backends.Postgres.Translate.Select.Internal.Extractor
  ( aggregateFieldsToExtractorExps,
    asJsonAggExtr,
    withJsonAggExtr,
  )
import Hasura.Backends.Postgres.Translate.Select.Internal.Helpers
  ( cursorIdentifier,
    cursorsSelectAliasIdentifier,
    encodeBase64,
    endCursorIdentifier,
    fromTableRowArgs,
    functionToIdentifier,
    hasNextPageIdentifier,
    hasPreviousPageIdentifier,
    pageInfoSelectAliasIdentifier,
    selectFromToFromItem,
    startCursorIdentifier,
    withForceAggregation,
  )
import Hasura.Backends.Postgres.Translate.Select.Internal.JoinTree
  ( withWriteArrayConnection,
    withWriteArrayRelation,
    withWriteComputedFieldTableSet,
    withWriteObjectRelation,
  )
import Hasura.Backends.Postgres.Translate.Select.Internal.OrderBy (processOrderByItems)
import Hasura.Backends.Postgres.Translate.Types
import Hasura.GraphQL.Schema.NamingCase (NamingCase)
import Hasura.GraphQL.Schema.Node (currentNodeIdVersion, nodeIdVersionInt)
import Hasura.GraphQL.Schema.Options qualified as Options
import Hasura.Prelude
import Hasura.RQL.IR.BoolExp
import Hasura.RQL.IR.OrderBy (OrderByItemG (OrderByItemG, obiColumn))
import Hasura.RQL.IR.Select
import Hasura.RQL.Types.Backend
import Hasura.RQL.Types.Column
import Hasura.RQL.Types.Common
import Hasura.RQL.Types.Relationships.Local
import Hasura.SQL.Backend

processSelectParams ::
  forall pgKind m.
  ( MonadReader Options.StringifyNumbers m,
    MonadWriter JoinTree m,
    Backend ('Postgres pgKind)
  ) =>
  SourcePrefixes ->
  FieldName ->
  SimilarArrayFields ->
  SelectFrom ('Postgres pgKind) ->
  PermissionLimitSubQuery ->
  TablePerm ('Postgres pgKind) ->
  SelectArgs ('Postgres pgKind) ->
  m
    ( SelectSource,
      [(S.ColumnAlias, S.SQLExp)],
      Maybe S.SQLExp -- Order by cursor
    )
processSelectParams :: SourcePrefixes
-> FieldName
-> SimilarArrayFields
-> SelectFrom ('Postgres pgKind)
-> PermissionLimitSubQuery
-> TablePerm ('Postgres pgKind)
-> SelectArgs ('Postgres pgKind)
-> m (SelectSource, [(ColumnAlias, SQLExp)], Maybe SQLExp)
processSelectParams
  SourcePrefixes
sourcePrefixes
  FieldName
fieldAlias
  SimilarArrayFields
similarArrFields
  SelectFrom ('Postgres pgKind)
selectFrom
  PermissionLimitSubQuery
permLimitSubQ
  TablePerm ('Postgres pgKind)
tablePermissions
  SelectArgs ('Postgres pgKind)
tableArgs = do
    ([(ColumnAlias, SQLExp)]
additionalExtrs, SelectSorting
selectSorting, Maybe SQLExp
cursorExp) <-
      Identifier
-> FieldName
-> SimilarArrayFields
-> Maybe (NonEmpty PGCol)
-> Maybe (NonEmpty (AnnotatedOrderByItem ('Postgres pgKind)))
-> m ([(ColumnAlias, SQLExp)], SelectSorting, Maybe SQLExp)
forall (pgKind :: PostgresKind) (m :: * -> *).
(MonadReader StringifyNumbers m, MonadWriter JoinTree m,
 Backend ('Postgres pgKind)) =>
Identifier
-> FieldName
-> SimilarArrayFields
-> Maybe (NonEmpty PGCol)
-> Maybe (NonEmpty (AnnotatedOrderByItem ('Postgres pgKind)))
-> m ([(ColumnAlias, SQLExp)], SelectSorting, Maybe SQLExp)
processOrderByItems Identifier
thisSourcePrefix FieldName
fieldAlias SimilarArrayFields
similarArrFields Maybe (NonEmpty (Column ('Postgres pgKind)))
Maybe (NonEmpty PGCol)
distM Maybe (NonEmpty (AnnotatedOrderByItem ('Postgres pgKind)))
Maybe (NonEmpty (AnnotatedOrderByItemG ('Postgres pgKind) SQLExp))
orderByM
    let fromItem :: FromItem
fromItem = Identifier -> SelectFrom ('Postgres pgKind) -> FromItem
forall (pgKind :: PostgresKind).
Identifier -> SelectFrom ('Postgres pgKind) -> FromItem
selectFromToFromItem (SourcePrefixes -> Identifier
_pfBase SourcePrefixes
sourcePrefixes) SelectFrom ('Postgres pgKind)
selectFrom
        finalWhere :: BoolExp
finalWhere =
          Qual -> AnnBoolExpSQL ('Postgres pgKind) -> BoolExp
forall (pgKind :: PostgresKind).
Backend ('Postgres pgKind) =>
Qual -> AnnBoolExpSQL ('Postgres pgKind) -> BoolExp
toSQLBoolExp (SelectFrom ('Postgres pgKind) -> Qual
selectFromToQual SelectFrom ('Postgres pgKind)
selectFrom) (AnnBoolExpSQL ('Postgres pgKind) -> BoolExp)
-> AnnBoolExpSQL ('Postgres pgKind) -> BoolExp
forall a b. (a -> b) -> a -> b
$
            AnnBoolExp ('Postgres pgKind) SQLExp
-> (AnnBoolExp ('Postgres pgKind) SQLExp
    -> AnnBoolExp ('Postgres pgKind) SQLExp)
-> Maybe (AnnBoolExp ('Postgres pgKind) SQLExp)
-> AnnBoolExp ('Postgres pgKind) SQLExp
forall b a. b -> (a -> b) -> Maybe a -> b
maybe AnnBoolExp ('Postgres pgKind) SQLExp
permFilter (AnnBoolExp ('Postgres pgKind) SQLExp
-> AnnBoolExp ('Postgres pgKind) SQLExp
-> AnnBoolExp ('Postgres pgKind) SQLExp
forall (backend :: BackendType) scalar.
AnnBoolExp backend scalar
-> AnnBoolExp backend scalar -> AnnBoolExp backend scalar
andAnnBoolExps AnnBoolExp ('Postgres pgKind) SQLExp
permFilter) Maybe (AnnBoolExp ('Postgres pgKind) SQLExp)
whereM
        sortingAndSlicing :: SortingAndSlicing
sortingAndSlicing = SelectSorting -> SelectSlicing -> SortingAndSlicing
SortingAndSlicing SelectSorting
selectSorting SelectSlicing
selectSlicing
        selectSource :: SelectSource
selectSource =
          Identifier
-> FromItem -> BoolExp -> SortingAndSlicing -> SelectSource
SelectSource
            Identifier
thisSourcePrefix
            FromItem
fromItem
            BoolExp
finalWhere
            SortingAndSlicing
sortingAndSlicing
    (SelectSource, [(ColumnAlias, SQLExp)], Maybe SQLExp)
-> m (SelectSource, [(ColumnAlias, SQLExp)], Maybe SQLExp)
forall (f :: * -> *) a. Applicative f => a -> f a
pure
      ( SelectSource
selectSource,
        [(ColumnAlias, SQLExp)]
additionalExtrs,
        Maybe SQLExp
cursorExp
      )
    where
      thisSourcePrefix :: Identifier
thisSourcePrefix = SourcePrefixes -> Identifier
_pfThis SourcePrefixes
sourcePrefixes
      SelectArgs Maybe (AnnBoolExp ('Postgres pgKind) SQLExp)
whereM Maybe (NonEmpty (AnnotatedOrderByItemG ('Postgres pgKind) SQLExp))
orderByM Maybe Int
inpLimitM Maybe Int64
offsetM Maybe (NonEmpty (Column ('Postgres pgKind)))
distM = SelectArgs ('Postgres pgKind)
SelectArgsG ('Postgres pgKind) SQLExp
tableArgs
      TablePerm AnnBoolExp ('Postgres pgKind) SQLExp
permFilter Maybe Int
permLimit = TablePerm ('Postgres pgKind)
TablePermG ('Postgres pgKind) SQLExp
tablePermissions
      selectSlicing :: SelectSlicing
selectSlicing = Maybe Int -> Maybe Int64 -> SelectSlicing
SelectSlicing Maybe Int
finalLimit Maybe Int64
offsetM
      finalLimit :: Maybe Int
finalLimit =
        -- if sub query is required, then only use input limit
        --    because permission limit is being applied in subquery
        -- else compare input and permission limits
        case PermissionLimitSubQuery
permLimitSubQ of
          PLSQRequired Int
_ -> Maybe Int
inpLimitM
          PermissionLimitSubQuery
PLSQNotRequired -> Maybe Int
compareLimits

      compareLimits :: Maybe Int
compareLimits =
        case (Maybe Int
inpLimitM, Maybe Int
permLimit) of
          (Maybe Int
inpLim, Maybe Int
Nothing) -> Maybe Int
inpLim
          (Maybe Int
Nothing, Maybe Int
permLim) -> Maybe Int
permLim
          (Just Int
inp, Just Int
perm) -> Int -> Maybe Int
forall a. a -> Maybe a
Just (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
inp Int
perm)

      -- You should be able to retrieve this information
      -- from the FromItem generated with selectFromToFromItem
      -- however given from S.FromItem is modelled, it is not
      -- possible currently.
      --
      -- More precisely, 'selectFromToFromItem' is injective but not surjective, so
      -- any S.FromItem -> S.Qual function would have to be partial.
      selectFromToQual :: SelectFrom ('Postgres pgKind) -> S.Qual
      selectFromToQual :: SelectFrom ('Postgres pgKind) -> Qual
selectFromToQual = \case
        FromTable TableName ('Postgres pgKind)
table -> QualifiedTable -> Qual
S.QualTable TableName ('Postgres pgKind)
QualifiedTable
table
        FromIdentifier FIIdentifier
i -> Identifier -> Maybe TypeAnn -> Qual
S.QualifiedIdentifier (FIIdentifier -> Identifier
forall a. IsIdentifier a => a -> Identifier
toIdentifier FIIdentifier
i) Maybe TypeAnn
forall a. Maybe a
Nothing
        FromFunction FunctionName ('Postgres pgKind)
qf FunctionArgsExp
  ('Postgres pgKind) (SQLExpression ('Postgres pgKind))
_ Maybe [(Column ('Postgres pgKind), ScalarType ('Postgres pgKind))]
_ -> Identifier -> Maybe TypeAnn -> Qual
S.QualifiedIdentifier (QualifiedFunction -> Identifier
functionToIdentifier FunctionName ('Postgres pgKind)
QualifiedFunction
qf) Maybe TypeAnn
forall a. Maybe a
Nothing

processAnnAggregateSelect ::
  forall pgKind m.
  ( MonadReader Options.StringifyNumbers m,
    MonadWriter JoinTree m,
    Backend ('Postgres pgKind),
    PostgresAnnotatedFieldJSON pgKind
  ) =>
  SourcePrefixes ->
  FieldName ->
  AnnAggregateSelect ('Postgres pgKind) ->
  m
    ( SelectSource,
      HM.HashMap S.ColumnAlias S.SQLExp,
      S.Extractor
    )
processAnnAggregateSelect :: SourcePrefixes
-> FieldName
-> AnnAggregateSelect ('Postgres pgKind)
-> m (SelectSource, HashMap ColumnAlias SQLExp, Extractor)
processAnnAggregateSelect SourcePrefixes
sourcePrefixes FieldName
fieldAlias AnnAggregateSelect ('Postgres pgKind)
annAggSel = do
  (SelectSource
selectSource, [(ColumnAlias, SQLExp)]
orderByAndDistinctExtrs, Maybe SQLExp
_) <-
    SourcePrefixes
-> FieldName
-> SimilarArrayFields
-> SelectFrom ('Postgres pgKind)
-> PermissionLimitSubQuery
-> TablePerm ('Postgres pgKind)
-> SelectArgs ('Postgres pgKind)
-> m (SelectSource, [(ColumnAlias, SQLExp)], Maybe SQLExp)
forall (pgKind :: PostgresKind) (m :: * -> *).
(MonadReader StringifyNumbers m, MonadWriter JoinTree m,
 Backend ('Postgres pgKind)) =>
SourcePrefixes
-> FieldName
-> SimilarArrayFields
-> SelectFrom ('Postgres pgKind)
-> PermissionLimitSubQuery
-> TablePerm ('Postgres pgKind)
-> SelectArgs ('Postgres pgKind)
-> m (SelectSource, [(ColumnAlias, SQLExp)], Maybe SQLExp)
processSelectParams
      SourcePrefixes
sourcePrefixes
      FieldName
fieldAlias
      SimilarArrayFields
similarArrayFields
      SelectFrom ('Postgres pgKind)
SelectFromG ('Postgres pgKind) SQLExp
tableFrom
      PermissionLimitSubQuery
permLimitSubQuery
      TablePerm ('Postgres pgKind)
TablePermG ('Postgres pgKind) SQLExp
tablePermissions
      SelectArgs ('Postgres pgKind)
SelectArgsG ('Postgres pgKind) SQLExp
tableArgs
  let thisSourcePrefix :: Identifier
thisSourcePrefix = SourcePrefixes -> Identifier
_pfThis SourcePrefixes
sourcePrefixes
  [(FieldName, ([(ColumnAlias, SQLExp)], SQLExp))]
processedFields <- [(FieldName, TableAggregateFieldG ('Postgres pgKind) Void SQLExp)]
-> ((FieldName,
     TableAggregateFieldG ('Postgres pgKind) Void SQLExp)
    -> m (FieldName, ([(ColumnAlias, SQLExp)], SQLExp)))
-> m [(FieldName, ([(ColumnAlias, SQLExp)], SQLExp))]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [(FieldName, TableAggregateFieldG ('Postgres pgKind) Void SQLExp)]
aggSelFields (((FieldName, TableAggregateFieldG ('Postgres pgKind) Void SQLExp)
  -> m (FieldName, ([(ColumnAlias, SQLExp)], SQLExp)))
 -> m [(FieldName, ([(ColumnAlias, SQLExp)], SQLExp))])
-> ((FieldName,
     TableAggregateFieldG ('Postgres pgKind) Void SQLExp)
    -> m (FieldName, ([(ColumnAlias, SQLExp)], SQLExp)))
-> m [(FieldName, ([(ColumnAlias, SQLExp)], SQLExp))]
forall a b. (a -> b) -> a -> b
$ \(FieldName
fieldName, TableAggregateFieldG ('Postgres pgKind) Void SQLExp
field) ->
    (FieldName
fieldName,)
      (([(ColumnAlias, SQLExp)], SQLExp)
 -> (FieldName, ([(ColumnAlias, SQLExp)], SQLExp)))
-> m ([(ColumnAlias, SQLExp)], SQLExp)
-> m (FieldName, ([(ColumnAlias, SQLExp)], SQLExp))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> case TableAggregateFieldG ('Postgres pgKind) Void SQLExp
field of
        TAFAgg AggregateFields ('Postgres pgKind)
aggFields ->
          ([(ColumnAlias, SQLExp)], SQLExp)
-> m ([(ColumnAlias, SQLExp)], SQLExp)
forall (f :: * -> *) a. Applicative f => a -> f a
pure
            ( Identifier
-> AggregateFields ('Postgres pgKind) -> [(ColumnAlias, SQLExp)]
forall (pgKind :: PostgresKind).
Identifier
-> AggregateFields ('Postgres pgKind) -> [(ColumnAlias, SQLExp)]
aggregateFieldsToExtractorExps Identifier
thisSourcePrefix AggregateFields ('Postgres pgKind)
aggFields,
              AggregateFields ('Postgres pgKind) -> StringifyNumbers -> SQLExp
forall (pgKind :: PostgresKind).
AggregateFields ('Postgres pgKind) -> StringifyNumbers -> SQLExp
aggregateFieldToExp AggregateFields ('Postgres pgKind)
aggFields StringifyNumbers
strfyNum
            )
        TAFNodes XNodesAgg ('Postgres pgKind)
_ AnnFieldsG ('Postgres pgKind) Void SQLExp
annFields -> do
          (ColumnAlias, SQLExp)
annFieldExtr <- Identifier
-> FieldName
-> SimilarArrayFields
-> AnnFields ('Postgres pgKind)
-> Maybe NamingCase
-> m (ColumnAlias, SQLExp)
forall (pgKind :: PostgresKind) (m :: * -> *).
(MonadReader StringifyNumbers m, MonadWriter JoinTree m,
 Backend ('Postgres pgKind), PostgresAnnotatedFieldJSON pgKind) =>
Identifier
-> FieldName
-> SimilarArrayFields
-> AnnFields ('Postgres pgKind)
-> Maybe NamingCase
-> m (ColumnAlias, SQLExp)
processAnnFields Identifier
thisSourcePrefix FieldName
fieldName SimilarArrayFields
similarArrayFields AnnFields ('Postgres pgKind)
AnnFieldsG ('Postgres pgKind) Void SQLExp
annFields Maybe NamingCase
tCase
          ([(ColumnAlias, SQLExp)], SQLExp)
-> m ([(ColumnAlias, SQLExp)], SQLExp)
forall (f :: * -> *) a. Applicative f => a -> f a
pure
            ( [(ColumnAlias, SQLExp)
annFieldExtr],
              PermissionLimitSubQuery
-> Maybe OrderByExp -> ColumnAlias -> SQLExp
withJsonAggExtr PermissionLimitSubQuery
permLimitSubQuery (SelectSource -> Maybe OrderByExp
orderByForJsonAgg SelectSource
selectSource) (ColumnAlias -> SQLExp) -> ColumnAlias -> SQLExp
forall a b. (a -> b) -> a -> b
$
                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
fieldName
            )
        TAFExp Text
e ->
          ([(ColumnAlias, SQLExp)], SQLExp)
-> m ([(ColumnAlias, SQLExp)], SQLExp)
forall (f :: * -> *) a. Applicative f => a -> f a
pure
            ( [],
              TypeAnn -> SQLExp -> SQLExp
withForceAggregation TypeAnn
S.textTypeAnn (SQLExp -> SQLExp) -> SQLExp -> SQLExp
forall a b. (a -> b) -> a -> b
$ Text -> SQLExp
S.SELit Text
e
            )

  let topLevelExtractor :: Extractor
topLevelExtractor =
        (SQLExp -> Maybe ColumnAlias -> Extractor)
-> Maybe ColumnAlias -> SQLExp -> Extractor
forall a b c. (a -> b -> c) -> b -> a -> c
flip SQLExp -> Maybe ColumnAlias -> Extractor
S.Extractor (ColumnAlias -> Maybe ColumnAlias
forall a. a -> Maybe a
Just (ColumnAlias -> Maybe ColumnAlias)
-> ColumnAlias -> Maybe ColumnAlias
forall a b. (a -> b) -> a -> b
$ 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
fieldAlias) (SQLExp -> Extractor) -> SQLExp -> Extractor
forall a b. (a -> b) -> a -> b
$
          [SQLExp] -> SQLExp
S.applyJsonBuildObj ([SQLExp] -> SQLExp) -> [SQLExp] -> SQLExp
forall a b. (a -> b) -> a -> b
$
            (((FieldName, SQLExp) -> [SQLExp])
 -> [(FieldName, SQLExp)] -> [SQLExp])
-> [(FieldName, SQLExp)]
-> ((FieldName, SQLExp) -> [SQLExp])
-> [SQLExp]
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((FieldName, SQLExp) -> [SQLExp])
-> [(FieldName, SQLExp)] -> [SQLExp]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (((FieldName, ([(ColumnAlias, SQLExp)], SQLExp))
 -> (FieldName, SQLExp))
-> [(FieldName, ([(ColumnAlias, SQLExp)], SQLExp))]
-> [(FieldName, SQLExp)]
forall a b. (a -> b) -> [a] -> [b]
map ((([(ColumnAlias, SQLExp)], SQLExp) -> SQLExp)
-> (FieldName, ([(ColumnAlias, SQLExp)], SQLExp))
-> (FieldName, SQLExp)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second ([(ColumnAlias, SQLExp)], SQLExp) -> SQLExp
forall a b. (a, b) -> b
snd) [(FieldName, ([(ColumnAlias, SQLExp)], SQLExp))]
processedFields) (((FieldName, SQLExp) -> [SQLExp]) -> [SQLExp])
-> ((FieldName, SQLExp) -> [SQLExp]) -> [SQLExp]
forall a b. (a -> b) -> a -> b
$
              \(FieldName Text
fieldText, SQLExp
fieldExp) -> [Text -> SQLExp
S.SELit Text
fieldText, SQLExp
fieldExp]
      nodeExtractors :: HashMap ColumnAlias SQLExp
nodeExtractors =
        [(ColumnAlias, SQLExp)] -> HashMap ColumnAlias SQLExp
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HM.fromList ([(ColumnAlias, SQLExp)] -> HashMap ColumnAlias SQLExp)
-> [(ColumnAlias, SQLExp)] -> HashMap ColumnAlias SQLExp
forall a b. (a -> b) -> a -> b
$
          ((FieldName, ([(ColumnAlias, SQLExp)], SQLExp))
 -> [(ColumnAlias, SQLExp)])
-> [(FieldName, ([(ColumnAlias, SQLExp)], SQLExp))]
-> [(ColumnAlias, SQLExp)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (([(ColumnAlias, SQLExp)], SQLExp) -> [(ColumnAlias, SQLExp)]
forall a b. (a, b) -> a
fst (([(ColumnAlias, SQLExp)], SQLExp) -> [(ColumnAlias, SQLExp)])
-> ((FieldName, ([(ColumnAlias, SQLExp)], SQLExp))
    -> ([(ColumnAlias, SQLExp)], SQLExp))
-> (FieldName, ([(ColumnAlias, SQLExp)], SQLExp))
-> [(ColumnAlias, SQLExp)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (FieldName, ([(ColumnAlias, SQLExp)], SQLExp))
-> ([(ColumnAlias, SQLExp)], SQLExp)
forall a b. (a, b) -> b
snd) [(FieldName, ([(ColumnAlias, SQLExp)], SQLExp))]
processedFields [(ColumnAlias, SQLExp)]
-> [(ColumnAlias, SQLExp)] -> [(ColumnAlias, SQLExp)]
forall a. Semigroup a => a -> a -> a
<> [(ColumnAlias, SQLExp)]
orderByAndDistinctExtrs

  (SelectSource, HashMap ColumnAlias SQLExp, Extractor)
-> m (SelectSource, HashMap ColumnAlias SQLExp, Extractor)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SelectSource
selectSource, HashMap ColumnAlias SQLExp
nodeExtractors, Extractor
topLevelExtractor)
  where
    AnnSelectG [(FieldName, TableAggregateFieldG ('Postgres pgKind) Void SQLExp)]
aggSelFields SelectFromG ('Postgres pgKind) SQLExp
tableFrom TablePermG ('Postgres pgKind) SQLExp
tablePermissions SelectArgsG ('Postgres pgKind) SQLExp
tableArgs StringifyNumbers
strfyNum Maybe NamingCase
tCase = AnnAggregateSelect ('Postgres pgKind)
AnnSelectG
  ('Postgres pgKind)
  (TableAggregateFieldG ('Postgres pgKind) Void)
  SQLExp
annAggSel
    permLimit :: Maybe Int
permLimit = TablePermG ('Postgres pgKind) SQLExp -> Maybe Int
forall (b :: BackendType) v. TablePermG b v -> Maybe Int
_tpLimit TablePermG ('Postgres pgKind) SQLExp
tablePermissions
    orderBy :: Maybe (NonEmpty (AnnotatedOrderByItemG ('Postgres pgKind) SQLExp))
orderBy = SelectArgsG ('Postgres pgKind) SQLExp
-> Maybe
     (NonEmpty (AnnotatedOrderByItemG ('Postgres pgKind) SQLExp))
forall (b :: BackendType) v.
SelectArgsG b v -> Maybe (NonEmpty (AnnotatedOrderByItemG b v))
_saOrderBy SelectArgsG ('Postgres pgKind) SQLExp
tableArgs
    permLimitSubQuery :: PermissionLimitSubQuery
permLimitSubQuery = Maybe Int
-> TableAggregateFields ('Postgres pgKind)
-> Maybe (NonEmpty (AnnotatedOrderByItem ('Postgres pgKind)))
-> PermissionLimitSubQuery
mkPermissionLimitSubQuery Maybe Int
permLimit TableAggregateFields ('Postgres pgKind)
[(FieldName, TableAggregateFieldG ('Postgres pgKind) Void SQLExp)]
aggSelFields Maybe (NonEmpty (AnnotatedOrderByItem ('Postgres pgKind)))
Maybe (NonEmpty (AnnotatedOrderByItemG ('Postgres pgKind) SQLExp))
orderBy
    similarArrayFields :: SimilarArrayFields
similarArrayFields = [SimilarArrayFields] -> SimilarArrayFields
forall k v. (Eq k, Hashable k) => [HashMap k v] -> HashMap k v
HM.unions ([SimilarArrayFields] -> SimilarArrayFields)
-> [SimilarArrayFields] -> SimilarArrayFields
forall a b. (a -> b) -> a -> b
$
      ((TableAggregateFieldG ('Postgres pgKind) Void SQLExp
  -> SimilarArrayFields)
 -> [TableAggregateFieldG ('Postgres pgKind) Void SQLExp]
 -> [SimilarArrayFields])
-> [TableAggregateFieldG ('Postgres pgKind) Void SQLExp]
-> (TableAggregateFieldG ('Postgres pgKind) Void SQLExp
    -> SimilarArrayFields)
-> [SimilarArrayFields]
forall a b c. (a -> b -> c) -> b -> a -> c
flip (TableAggregateFieldG ('Postgres pgKind) Void SQLExp
 -> SimilarArrayFields)
-> [TableAggregateFieldG ('Postgres pgKind) Void SQLExp]
-> [SimilarArrayFields]
forall a b. (a -> b) -> [a] -> [b]
map (((FieldName, TableAggregateFieldG ('Postgres pgKind) Void SQLExp)
 -> TableAggregateFieldG ('Postgres pgKind) Void SQLExp)
-> [(FieldName,
     TableAggregateFieldG ('Postgres pgKind) Void SQLExp)]
-> [TableAggregateFieldG ('Postgres pgKind) Void SQLExp]
forall a b. (a -> b) -> [a] -> [b]
map (FieldName, TableAggregateFieldG ('Postgres pgKind) Void SQLExp)
-> TableAggregateFieldG ('Postgres pgKind) Void SQLExp
forall a b. (a, b) -> b
snd [(FieldName, TableAggregateFieldG ('Postgres pgKind) Void SQLExp)]
aggSelFields) ((TableAggregateFieldG ('Postgres pgKind) Void SQLExp
  -> SimilarArrayFields)
 -> [SimilarArrayFields])
-> (TableAggregateFieldG ('Postgres pgKind) Void SQLExp
    -> SimilarArrayFields)
-> [SimilarArrayFields]
forall a b. (a -> b) -> a -> b
$ \case
        TAFAgg AggregateFields ('Postgres pgKind)
_ -> SimilarArrayFields
forall a. Monoid a => a
mempty
        TAFNodes XNodesAgg ('Postgres pgKind)
_ AnnFieldsG ('Postgres pgKind) Void SQLExp
annFlds ->
          AnnFieldsG ('Postgres pgKind) Void SQLExp
-> Maybe
     (NonEmpty (AnnotatedOrderByItemG ('Postgres pgKind) SQLExp))
-> SimilarArrayFields
forall (pgKind :: PostgresKind) v.
(Backend ('Postgres pgKind), Eq v) =>
AnnFieldsG ('Postgres pgKind) Void v
-> Maybe (NonEmpty (AnnotatedOrderByItemG ('Postgres pgKind) v))
-> SimilarArrayFields
mkSimilarArrayFields AnnFieldsG ('Postgres pgKind) Void SQLExp
annFlds Maybe (NonEmpty (AnnotatedOrderByItemG ('Postgres pgKind) SQLExp))
orderBy
        TAFExp Text
_ -> SimilarArrayFields
forall a. Monoid a => a
mempty

    mkPermissionLimitSubQuery ::
      Maybe Int ->
      TableAggregateFields ('Postgres pgKind) ->
      Maybe (NE.NonEmpty (AnnotatedOrderByItem ('Postgres pgKind))) ->
      PermissionLimitSubQuery
    mkPermissionLimitSubQuery :: Maybe Int
-> TableAggregateFields ('Postgres pgKind)
-> Maybe (NonEmpty (AnnotatedOrderByItem ('Postgres pgKind)))
-> PermissionLimitSubQuery
mkPermissionLimitSubQuery Maybe Int
permLimit' TableAggregateFields ('Postgres pgKind)
aggFields Maybe (NonEmpty (AnnotatedOrderByItem ('Postgres pgKind)))
orderBys =
      case Maybe Int
permLimit' of
        Maybe Int
Nothing -> PermissionLimitSubQuery
PLSQNotRequired
        Just Int
limit ->
          if Bool
hasAggregateField Bool -> Bool -> Bool
|| Bool
hasAggOrderBy
            then Int -> PermissionLimitSubQuery
PLSQRequired Int
limit
            else PermissionLimitSubQuery
PLSQNotRequired
      where
        hasAggregateField :: Bool
hasAggregateField = ((TableAggregateFieldG ('Postgres pgKind) Void SQLExp -> Bool)
 -> [TableAggregateFieldG ('Postgres pgKind) Void SQLExp] -> Bool)
-> [TableAggregateFieldG ('Postgres pgKind) Void SQLExp]
-> (TableAggregateFieldG ('Postgres pgKind) Void SQLExp -> Bool)
-> Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip (TableAggregateFieldG ('Postgres pgKind) Void SQLExp -> Bool)
-> [TableAggregateFieldG ('Postgres pgKind) Void SQLExp] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (((FieldName, TableAggregateFieldG ('Postgres pgKind) Void SQLExp)
 -> TableAggregateFieldG ('Postgres pgKind) Void SQLExp)
-> [(FieldName,
     TableAggregateFieldG ('Postgres pgKind) Void SQLExp)]
-> [TableAggregateFieldG ('Postgres pgKind) Void SQLExp]
forall a b. (a -> b) -> [a] -> [b]
map (FieldName, TableAggregateFieldG ('Postgres pgKind) Void SQLExp)
-> TableAggregateFieldG ('Postgres pgKind) Void SQLExp
forall a b. (a, b) -> b
snd TableAggregateFields ('Postgres pgKind)
[(FieldName, TableAggregateFieldG ('Postgres pgKind) Void SQLExp)]
aggFields) ((TableAggregateFieldG ('Postgres pgKind) Void SQLExp -> Bool)
 -> Bool)
-> (TableAggregateFieldG ('Postgres pgKind) Void SQLExp -> Bool)
-> Bool
forall a b. (a -> b) -> a -> b
$
          \case
            TAFAgg AggregateFields ('Postgres pgKind)
_ -> Bool
True
            TableAggregateFieldG ('Postgres pgKind) Void SQLExp
_ -> Bool
False

        hasAggOrderBy :: Bool
hasAggOrderBy = case Maybe (NonEmpty (AnnotatedOrderByItem ('Postgres pgKind)))
orderBys of
          Maybe (NonEmpty (AnnotatedOrderByItem ('Postgres pgKind)))
Nothing -> Bool
False
          Just NonEmpty (AnnotatedOrderByItem ('Postgres pgKind))
l -> ((AnnotatedOrderByElement ('Postgres pgKind) SQLExp -> Bool)
 -> [AnnotatedOrderByElement ('Postgres pgKind) SQLExp] -> Bool)
-> [AnnotatedOrderByElement ('Postgres pgKind) SQLExp]
-> (AnnotatedOrderByElement ('Postgres pgKind) SQLExp -> Bool)
-> Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip (AnnotatedOrderByElement ('Postgres pgKind) SQLExp -> Bool)
-> [AnnotatedOrderByElement ('Postgres pgKind) SQLExp] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any ((AnnotatedOrderByItemG ('Postgres pgKind) SQLExp
 -> [AnnotatedOrderByElement ('Postgres pgKind) SQLExp])
-> [AnnotatedOrderByItemG ('Postgres pgKind) SQLExp]
-> [AnnotatedOrderByElement ('Postgres pgKind) SQLExp]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap AnnotatedOrderByItemG ('Postgres pgKind) SQLExp
-> [AnnotatedOrderByElement ('Postgres pgKind) SQLExp]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList ([AnnotatedOrderByItemG ('Postgres pgKind) SQLExp]
 -> [AnnotatedOrderByElement ('Postgres pgKind) SQLExp])
-> [AnnotatedOrderByItemG ('Postgres pgKind) SQLExp]
-> [AnnotatedOrderByElement ('Postgres pgKind) SQLExp]
forall a b. (a -> b) -> a -> b
$ NonEmpty (AnnotatedOrderByItemG ('Postgres pgKind) SQLExp)
-> [AnnotatedOrderByItemG ('Postgres pgKind) SQLExp]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList NonEmpty (AnnotatedOrderByItem ('Postgres pgKind))
NonEmpty (AnnotatedOrderByItemG ('Postgres pgKind) SQLExp)
l) ((AnnotatedOrderByElement ('Postgres pgKind) SQLExp -> Bool)
 -> Bool)
-> (AnnotatedOrderByElement ('Postgres pgKind) SQLExp -> Bool)
-> Bool
forall a b. (a -> b) -> a -> b
$
            \case
              AOCArrayAggregation {} -> Bool
True
              AnnotatedOrderByElement ('Postgres pgKind) SQLExp
_ -> Bool
False

processAnnFields ::
  forall pgKind m.
  ( MonadReader Options.StringifyNumbers m,
    MonadWriter JoinTree m,
    Backend ('Postgres pgKind),
    PostgresAnnotatedFieldJSON pgKind
  ) =>
  Identifier ->
  FieldName ->
  SimilarArrayFields ->
  AnnFields ('Postgres pgKind) ->
  Maybe NamingCase ->
  m (S.ColumnAlias, S.SQLExp)
processAnnFields :: Identifier
-> FieldName
-> SimilarArrayFields
-> AnnFields ('Postgres pgKind)
-> Maybe NamingCase
-> m (ColumnAlias, SQLExp)
processAnnFields Identifier
sourcePrefix FieldName
fieldAlias SimilarArrayFields
similarArrFields AnnFields ('Postgres pgKind)
annFields Maybe NamingCase
tCase = do
  [(FieldName, SQLExp)]
fieldExps <- [(FieldName, AnnFieldG ('Postgres pgKind) Void SQLExp)]
-> ((FieldName, AnnFieldG ('Postgres pgKind) Void SQLExp)
    -> m (FieldName, SQLExp))
-> m [(FieldName, SQLExp)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM AnnFields ('Postgres pgKind)
[(FieldName, AnnFieldG ('Postgres pgKind) Void SQLExp)]
annFields (((FieldName, AnnFieldG ('Postgres pgKind) Void SQLExp)
  -> m (FieldName, SQLExp))
 -> m [(FieldName, SQLExp)])
-> ((FieldName, AnnFieldG ('Postgres pgKind) Void SQLExp)
    -> m (FieldName, SQLExp))
-> m [(FieldName, SQLExp)]
forall a b. (a -> b) -> a -> b
$ \(FieldName
fieldName, AnnFieldG ('Postgres pgKind) Void SQLExp
field) ->
    (FieldName
fieldName,)
      (SQLExp -> (FieldName, SQLExp))
-> m SQLExp -> m (FieldName, SQLExp)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> case AnnFieldG ('Postgres pgKind) Void SQLExp
field of
        AFExpression Text
t -> SQLExp -> m SQLExp
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SQLExp -> m SQLExp) -> SQLExp -> m SQLExp
forall a b. (a -> b) -> a -> b
$ Text -> SQLExp
S.SELit Text
t
        AFNodeId XRelay ('Postgres pgKind)
_ SourceName
sn TableName ('Postgres pgKind)
tn PrimaryKeyColumns ('Postgres pgKind)
pKeys -> SQLExp -> m SQLExp
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SQLExp -> m SQLExp) -> SQLExp -> m SQLExp
forall a b. (a -> b) -> a -> b
$ SourceName
-> QualifiedTable -> PrimaryKeyColumns ('Postgres pgKind) -> SQLExp
mkNodeId SourceName
sn TableName ('Postgres pgKind)
QualifiedTable
tn PrimaryKeyColumns ('Postgres pgKind)
pKeys
        AFColumn AnnColumnField ('Postgres pgKind) SQLExp
c -> AnnColumnField ('Postgres pgKind) SQLExp -> m SQLExp
toSQLCol AnnColumnField ('Postgres pgKind) SQLExp
c
        AFObjectRelation ObjectRelationSelectG ('Postgres pgKind) Void SQLExp
objSel -> m (ObjectRelationSource, HashMap ColumnAlias SQLExp, SQLExp)
-> m SQLExp
forall (m :: * -> *) a.
MonadWriter JoinTree m =>
m (ObjectRelationSource, HashMap ColumnAlias SQLExp, a) -> m a
withWriteObjectRelation (m (ObjectRelationSource, HashMap ColumnAlias SQLExp, SQLExp)
 -> m SQLExp)
-> m (ObjectRelationSource, HashMap ColumnAlias SQLExp, SQLExp)
-> m SQLExp
forall a b. (a -> b) -> a -> b
$ do
          let AnnRelationSelectG RelName
relName HashMap (Column ('Postgres pgKind)) (Column ('Postgres pgKind))
relMapping AnnObjectSelectG ('Postgres pgKind) Void SQLExp
annObjSel = ObjectRelationSelectG ('Postgres pgKind) Void SQLExp
objSel
              AnnObjectSelectG [(FieldName, AnnFieldG ('Postgres pgKind) Void SQLExp)]
objAnnFields TableName ('Postgres pgKind)
tableFrom AnnBoolExp ('Postgres pgKind) SQLExp
tableFilter = AnnObjectSelectG ('Postgres pgKind) Void SQLExp
annObjSel
              objRelSourcePrefix :: Identifier
objRelSourcePrefix = Identifier -> RelName -> Identifier
mkObjectRelationTableAlias Identifier
sourcePrefix RelName
relName
              sourcePrefixes :: SourcePrefixes
sourcePrefixes = Identifier -> SourcePrefixes
mkSourcePrefixes Identifier
objRelSourcePrefix
          (ColumnAlias, SQLExp)
annFieldsExtr <- Identifier
-> FieldName
-> SimilarArrayFields
-> AnnFields ('Postgres pgKind)
-> Maybe NamingCase
-> m (ColumnAlias, SQLExp)
forall (pgKind :: PostgresKind) (m :: * -> *).
(MonadReader StringifyNumbers m, MonadWriter JoinTree m,
 Backend ('Postgres pgKind), PostgresAnnotatedFieldJSON pgKind) =>
Identifier
-> FieldName
-> SimilarArrayFields
-> AnnFields ('Postgres pgKind)
-> Maybe NamingCase
-> m (ColumnAlias, SQLExp)
processAnnFields (SourcePrefixes -> Identifier
_pfThis SourcePrefixes
sourcePrefixes) FieldName
fieldName SimilarArrayFields
forall k v. HashMap k v
HM.empty AnnFields ('Postgres pgKind)
[(FieldName, AnnFieldG ('Postgres pgKind) Void SQLExp)]
objAnnFields Maybe NamingCase
tCase
          let selectSource :: ObjectSelectSource
selectSource =
                Identifier -> FromItem -> BoolExp -> ObjectSelectSource
ObjectSelectSource
                  (SourcePrefixes -> Identifier
_pfThis SourcePrefixes
sourcePrefixes)
                  (QualifiedTable -> Maybe TableAlias -> FromItem
S.FISimple TableName ('Postgres pgKind)
QualifiedTable
tableFrom Maybe TableAlias
forall a. Maybe a
Nothing)
                  (Qual -> AnnBoolExpSQL ('Postgres pgKind) -> BoolExp
forall (pgKind :: PostgresKind).
Backend ('Postgres pgKind) =>
Qual -> AnnBoolExpSQL ('Postgres pgKind) -> BoolExp
toSQLBoolExp (QualifiedTable -> Qual
S.QualTable TableName ('Postgres pgKind)
QualifiedTable
tableFrom) AnnBoolExpSQL ('Postgres pgKind)
AnnBoolExp ('Postgres pgKind) SQLExp
tableFilter)
              objRelSource :: ObjectRelationSource
objRelSource = RelName
-> HashMap PGCol PGCol
-> ObjectSelectSource
-> ObjectRelationSource
ObjectRelationSource RelName
relName HashMap (Column ('Postgres pgKind)) (Column ('Postgres pgKind))
HashMap PGCol PGCol
relMapping ObjectSelectSource
selectSource
          (ObjectRelationSource, HashMap ColumnAlias SQLExp, SQLExp)
-> m (ObjectRelationSource, HashMap ColumnAlias SQLExp, SQLExp)
forall (f :: * -> *) a. Applicative f => a -> f a
pure
            ( ObjectRelationSource
objRelSource,
              [(ColumnAlias, SQLExp)] -> HashMap ColumnAlias SQLExp
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HM.fromList [(ColumnAlias, SQLExp)
annFieldsExtr],
              Identifier -> FieldName -> SQLExp
forall a b. (IsIdentifier a, IsIdentifier b) => a -> b -> SQLExp
S.mkQIdenExp Identifier
objRelSourcePrefix FieldName
fieldName
            )
        AFArrayRelation ArraySelectG ('Postgres pgKind) Void SQLExp
arrSel -> do
          let arrRelSourcePrefix :: Identifier
arrRelSourcePrefix = Identifier
-> FieldName -> SimilarArrayFields -> FieldName -> Identifier
mkArrayRelationSourcePrefix Identifier
sourcePrefix FieldName
fieldAlias SimilarArrayFields
similarArrFields FieldName
fieldName
              arrRelAlias :: TableAlias
arrRelAlias = FieldName -> SimilarArrayFields -> FieldName -> TableAlias
mkArrayRelationAlias FieldName
fieldAlias SimilarArrayFields
similarArrFields FieldName
fieldName
          SourcePrefixes
-> FieldName
-> TableAlias
-> ArraySelect ('Postgres pgKind)
-> Maybe NamingCase
-> m ()
forall (pgKind :: PostgresKind) (m :: * -> *).
(MonadReader StringifyNumbers m, MonadWriter JoinTree m,
 Backend ('Postgres pgKind), PostgresAnnotatedFieldJSON pgKind) =>
SourcePrefixes
-> FieldName
-> TableAlias
-> ArraySelect ('Postgres pgKind)
-> Maybe NamingCase
-> m ()
processArrayRelation (Identifier -> SourcePrefixes
mkSourcePrefixes Identifier
arrRelSourcePrefix) FieldName
fieldName TableAlias
arrRelAlias ArraySelect ('Postgres pgKind)
ArraySelectG ('Postgres pgKind) Void SQLExp
arrSel Maybe NamingCase
tCase
          SQLExp -> m SQLExp
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SQLExp -> m SQLExp) -> SQLExp -> m SQLExp
forall a b. (a -> b) -> a -> b
$ Identifier -> FieldName -> SQLExp
forall a b. (IsIdentifier a, IsIdentifier b) => a -> b -> SQLExp
S.mkQIdenExp Identifier
arrRelSourcePrefix FieldName
fieldName
        AFComputedField XComputedField ('Postgres pgKind)
_ ComputedFieldName
_ (CFSScalar ComputedFieldScalarSelect ('Postgres pgKind) SQLExp
scalar Maybe (AnnColumnCaseBoolExp ('Postgres pgKind) SQLExp)
caseBoolExpMaybe) -> do
          SQLExp
computedFieldSQLExp <- ComputedFieldScalarSelect ('Postgres pgKind) SQLExp -> m SQLExp
fromScalarComputedField ComputedFieldScalarSelect ('Postgres pgKind) SQLExp
scalar
          -- The computed field is conditionally outputed depending
          -- on the presence of `caseBoolExpMaybe` and the value it
          -- evaluates to. `caseBoolExpMaybe` will be set only in the
          -- case of an inherited role.
          -- See [SQL generation for inherited role]
          case Maybe (AnnColumnCaseBoolExp ('Postgres pgKind) SQLExp)
caseBoolExpMaybe of
            Maybe (AnnColumnCaseBoolExp ('Postgres pgKind) SQLExp)
Nothing -> SQLExp -> m SQLExp
forall (f :: * -> *) a. Applicative f => a -> f a
pure SQLExp
computedFieldSQLExp
            Just AnnColumnCaseBoolExp ('Postgres pgKind) SQLExp
caseBoolExp ->
              let boolExp :: BoolExp
boolExp =
                    BoolExp -> BoolExp
S.simplifyBoolExp (BoolExp -> BoolExp) -> BoolExp -> BoolExp
forall a b. (a -> b) -> a -> b
$
                      Qual -> AnnBoolExpSQL ('Postgres pgKind) -> BoolExp
forall (pgKind :: PostgresKind).
Backend ('Postgres pgKind) =>
Qual -> AnnBoolExpSQL ('Postgres pgKind) -> BoolExp
toSQLBoolExp (Identifier -> Maybe TypeAnn -> Qual
S.QualifiedIdentifier Identifier
baseTableIdentifier Maybe TypeAnn
forall a. Maybe a
Nothing) (AnnBoolExpSQL ('Postgres pgKind) -> BoolExp)
-> AnnBoolExpSQL ('Postgres pgKind) -> BoolExp
forall a b. (a -> b) -> a -> b
$
                        AnnColumnCaseBoolExpField ('Postgres pgKind) SQLExp
-> AnnBoolExpFld ('Postgres pgKind) SQLExp
forall (backend :: BackendType) field.
AnnColumnCaseBoolExpField backend field
-> AnnBoolExpFld backend field
_accColCaseBoolExpField (AnnColumnCaseBoolExpField ('Postgres pgKind) SQLExp
 -> AnnBoolExpFld ('Postgres pgKind) SQLExp)
-> AnnColumnCaseBoolExp ('Postgres pgKind) SQLExp
-> AnnBoolExp ('Postgres pgKind) SQLExp
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AnnColumnCaseBoolExp ('Postgres pgKind) SQLExp
caseBoolExp
               in SQLExp -> m SQLExp
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SQLExp -> m SQLExp) -> SQLExp -> m SQLExp
forall a b. (a -> b) -> a -> b
$ BoolExp -> SQLExp -> SQLExp -> SQLExp
S.SECond BoolExp
boolExp SQLExp
computedFieldSQLExp SQLExp
S.SENull
        AFComputedField XComputedField ('Postgres pgKind)
_ ComputedFieldName
_ (CFSTable JsonAggSelect
selectTy AnnSimpleSelectG ('Postgres pgKind) Void SQLExp
sel) -> m (ComputedFieldTableSetSource, Extractor,
   HashMap ColumnAlias SQLExp, SQLExp)
-> m SQLExp
forall (m :: * -> *) a.
MonadWriter JoinTree m =>
m (ComputedFieldTableSetSource, Extractor,
   HashMap ColumnAlias SQLExp, a)
-> m a
withWriteComputedFieldTableSet (m (ComputedFieldTableSetSource, Extractor,
    HashMap ColumnAlias SQLExp, SQLExp)
 -> m SQLExp)
-> m (ComputedFieldTableSetSource, Extractor,
      HashMap ColumnAlias SQLExp, SQLExp)
-> m SQLExp
forall a b. (a -> b) -> a -> b
$ do
          let computedFieldSourcePrefix :: Identifier
computedFieldSourcePrefix =
                Identifier -> FieldName -> Identifier
mkComputedFieldTableAlias Identifier
sourcePrefix FieldName
fieldName
          (SelectSource
selectSource, HashMap ColumnAlias SQLExp
nodeExtractors) <-
            SourcePrefixes
-> FieldName
-> PermissionLimitSubQuery
-> AnnSimpleSelect ('Postgres pgKind)
-> m (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
              (Identifier -> SourcePrefixes
mkSourcePrefixes Identifier
computedFieldSourcePrefix)
              FieldName
fieldName
              PermissionLimitSubQuery
PLSQNotRequired
              AnnSimpleSelect ('Postgres pgKind)
AnnSimpleSelectG ('Postgres pgKind) Void SQLExp
sel
          let computedFieldTableSetSource :: ComputedFieldTableSetSource
computedFieldTableSetSource = FieldName -> SelectSource -> ComputedFieldTableSetSource
ComputedFieldTableSetSource FieldName
fieldName SelectSource
selectSource
              extractor :: Extractor
extractor =
                JsonAggSelect
-> ColumnAlias
-> PermissionLimitSubQuery
-> Maybe OrderByExp
-> Extractor
asJsonAggExtr JsonAggSelect
selectTy (FieldName -> ColumnAlias
forall a. IsIdentifier a => a -> ColumnAlias
S.toColumnAlias FieldName
fieldName) PermissionLimitSubQuery
PLSQNotRequired (Maybe OrderByExp -> Extractor) -> Maybe OrderByExp -> Extractor
forall a b. (a -> b) -> a -> b
$
                  SelectSource -> Maybe OrderByExp
orderByForJsonAgg SelectSource
selectSource
          (ComputedFieldTableSetSource, Extractor,
 HashMap ColumnAlias SQLExp, SQLExp)
-> m (ComputedFieldTableSetSource, Extractor,
      HashMap ColumnAlias SQLExp, SQLExp)
forall (f :: * -> *) a. Applicative f => a -> f a
pure
            ( ComputedFieldTableSetSource
computedFieldTableSetSource,
              Extractor
extractor,
              HashMap ColumnAlias SQLExp
nodeExtractors,
              Identifier -> FieldName -> SQLExp
forall a b. (IsIdentifier a, IsIdentifier b) => a -> b -> SQLExp
S.mkQIdenExp Identifier
computedFieldSourcePrefix FieldName
fieldName
            )

  (ColumnAlias, SQLExp) -> m (ColumnAlias, SQLExp)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((ColumnAlias, SQLExp) -> m (ColumnAlias, SQLExp))
-> (ColumnAlias, SQLExp) -> m (ColumnAlias, SQLExp)
forall a b. (a -> b) -> a -> b
$ FieldName -> [(FieldName, SQLExp)] -> (ColumnAlias, SQLExp)
forall (pgKind :: PostgresKind).
PostgresAnnotatedFieldJSON pgKind =>
FieldName -> [(FieldName, SQLExp)] -> (ColumnAlias, SQLExp)
annRowToJson @pgKind FieldName
fieldAlias [(FieldName, SQLExp)]
fieldExps
  where
    mkSourcePrefixes :: Identifier -> SourcePrefixes
mkSourcePrefixes Identifier
newPrefix = Identifier -> Identifier -> SourcePrefixes
SourcePrefixes Identifier
newPrefix Identifier
sourcePrefix

    baseTableIdentifier :: Identifier
baseTableIdentifier = TableAlias -> Identifier
forall a. IsIdentifier a => a -> Identifier
toIdentifier (TableAlias -> Identifier) -> TableAlias -> Identifier
forall a b. (a -> b) -> a -> b
$ Identifier -> TableAlias
mkBaseTableAlias Identifier
sourcePrefix

    toSQLCol :: AnnColumnField ('Postgres pgKind) S.SQLExp -> m S.SQLExp
    toSQLCol :: AnnColumnField ('Postgres pgKind) SQLExp -> m SQLExp
toSQLCol (AnnColumnField Column ('Postgres pgKind)
col ColumnType ('Postgres pgKind)
typ Bool
asText Maybe (ScalarSelectionArguments ('Postgres pgKind))
colOpM Maybe (AnnColumnCaseBoolExp ('Postgres pgKind) SQLExp)
caseBoolExpMaybe) = do
      StringifyNumbers
strfyNum <- m StringifyNumbers
forall r (m :: * -> *). MonadReader r m => m r
ask
      let sqlExpression :: SQLExp
sqlExpression =
            Maybe ColumnOp -> SQLExp -> SQLExp
withColumnOp Maybe (ScalarSelectionArguments ('Postgres pgKind))
Maybe ColumnOp
colOpM (SQLExp -> SQLExp) -> SQLExp -> SQLExp
forall a b. (a -> b) -> a -> b
$
              Identifier -> PGCol -> SQLExp
forall a b. (IsIdentifier a, IsIdentifier b) => a -> b -> SQLExp
S.mkQIdenExp Identifier
baseTableIdentifier Column ('Postgres pgKind)
PGCol
col
          finalSQLExpression :: SQLExp
finalSQLExpression =
            -- Check out [SQL generation for inherited role]
            case Maybe (AnnColumnCaseBoolExp ('Postgres pgKind) SQLExp)
caseBoolExpMaybe of
              Maybe (AnnColumnCaseBoolExp ('Postgres pgKind) SQLExp)
Nothing -> SQLExp
sqlExpression
              Just AnnColumnCaseBoolExp ('Postgres pgKind) SQLExp
caseBoolExp ->
                let boolExp :: BoolExp
boolExp =
                      BoolExp -> BoolExp
S.simplifyBoolExp (BoolExp -> BoolExp) -> BoolExp -> BoolExp
forall a b. (a -> b) -> a -> b
$
                        Qual -> AnnBoolExpSQL ('Postgres pgKind) -> BoolExp
forall (pgKind :: PostgresKind).
Backend ('Postgres pgKind) =>
Qual -> AnnBoolExpSQL ('Postgres pgKind) -> BoolExp
toSQLBoolExp (Identifier -> Maybe TypeAnn -> Qual
S.QualifiedIdentifier Identifier
baseTableIdentifier Maybe TypeAnn
forall a. Maybe a
Nothing) (AnnBoolExpSQL ('Postgres pgKind) -> BoolExp)
-> AnnBoolExpSQL ('Postgres pgKind) -> BoolExp
forall a b. (a -> b) -> a -> b
$
                          AnnColumnCaseBoolExpField ('Postgres pgKind) SQLExp
-> AnnBoolExpFld ('Postgres pgKind) SQLExp
forall (backend :: BackendType) field.
AnnColumnCaseBoolExpField backend field
-> AnnBoolExpFld backend field
_accColCaseBoolExpField (AnnColumnCaseBoolExpField ('Postgres pgKind) SQLExp
 -> AnnBoolExpFld ('Postgres pgKind) SQLExp)
-> AnnColumnCaseBoolExp ('Postgres pgKind) SQLExp
-> AnnBoolExp ('Postgres pgKind) SQLExp
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AnnColumnCaseBoolExp ('Postgres pgKind) SQLExp
caseBoolExp
                 in BoolExp -> SQLExp -> SQLExp -> SQLExp
S.SECond BoolExp
boolExp SQLExp
sqlExpression SQLExp
S.SENull
      SQLExp -> m SQLExp
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SQLExp -> m SQLExp) -> SQLExp -> m SQLExp
forall a b. (a -> b) -> a -> b
$ StringifyNumbers
-> ColumnType ('Postgres pgKind)
-> Bool
-> Maybe NamingCase
-> SQLExp
-> SQLExp
forall (pgKind :: PostgresKind).
StringifyNumbers
-> ColumnType ('Postgres pgKind)
-> Bool
-> Maybe NamingCase
-> SQLExp
-> SQLExp
toJSONableExp StringifyNumbers
strfyNum ColumnType ('Postgres pgKind)
typ Bool
asText Maybe NamingCase
tCase SQLExp
finalSQLExpression

    fromScalarComputedField :: ComputedFieldScalarSelect ('Postgres pgKind) S.SQLExp -> m S.SQLExp
    fromScalarComputedField :: ComputedFieldScalarSelect ('Postgres pgKind) SQLExp -> m SQLExp
fromScalarComputedField ComputedFieldScalarSelect ('Postgres pgKind) SQLExp
computedFieldScalar = do
      StringifyNumbers
strfyNum <- m StringifyNumbers
forall r (m :: * -> *). MonadReader r m => m r
ask
      SQLExp -> m SQLExp
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SQLExp -> m SQLExp) -> SQLExp -> m SQLExp
forall a b. (a -> b) -> a -> b
$
        StringifyNumbers
-> ColumnType ('Postgres Any)
-> Bool
-> Maybe NamingCase
-> SQLExp
-> SQLExp
forall (pgKind :: PostgresKind).
StringifyNumbers
-> ColumnType ('Postgres pgKind)
-> Bool
-> Maybe NamingCase
-> SQLExp
-> SQLExp
toJSONableExp StringifyNumbers
strfyNum (ScalarType ('Postgres Any) -> ColumnType ('Postgres Any)
forall (b :: BackendType). ScalarType b -> ColumnType b
ColumnScalar ScalarType ('Postgres pgKind)
ScalarType ('Postgres Any)
ty) Bool
False Maybe NamingCase
forall a. Maybe a
Nothing (SQLExp -> SQLExp) -> SQLExp -> SQLExp
forall a b. (a -> b) -> a -> b
$
          Maybe ColumnOp -> SQLExp -> SQLExp
withColumnOp Maybe (ScalarSelectionArguments ('Postgres pgKind))
Maybe ColumnOp
colOpM (SQLExp -> SQLExp) -> SQLExp -> SQLExp
forall a b. (a -> b) -> a -> b
$
            FunctionExp -> SQLExp
S.SEFunction (FunctionExp -> SQLExp) -> FunctionExp -> SQLExp
forall a b. (a -> b) -> a -> b
$ QualifiedFunction
-> FunctionArgs -> Maybe FunctionAlias -> FunctionExp
S.FunctionExp FunctionName ('Postgres pgKind)
QualifiedFunction
fn (Identifier -> FunctionArgsExpG (ArgumentExp SQLExp) -> FunctionArgs
fromTableRowArgs Identifier
sourcePrefix FunctionArgsExp ('Postgres pgKind) SQLExp
FunctionArgsExpG (ArgumentExp SQLExp)
args) Maybe FunctionAlias
forall a. Maybe a
Nothing
      where
        ComputedFieldScalarSelect FunctionName ('Postgres pgKind)
fn FunctionArgsExp ('Postgres pgKind) SQLExp
args ScalarType ('Postgres pgKind)
ty Maybe (ScalarSelectionArguments ('Postgres pgKind))
colOpM = ComputedFieldScalarSelect ('Postgres pgKind) SQLExp
computedFieldScalar

    withColumnOp :: Maybe S.ColumnOp -> S.SQLExp -> S.SQLExp
    withColumnOp :: Maybe ColumnOp -> SQLExp -> SQLExp
withColumnOp Maybe ColumnOp
colOpM SQLExp
sqlExp = case Maybe ColumnOp
colOpM of
      Maybe ColumnOp
Nothing -> SQLExp
sqlExp
      Just (S.ColumnOp SQLOp
opText SQLExp
cExp) -> SQLOp -> SQLExp -> SQLExp -> SQLExp
S.mkSQLOpExp SQLOp
opText SQLExp
sqlExp SQLExp
cExp

    mkNodeId :: SourceName -> QualifiedTable -> PrimaryKeyColumns ('Postgres pgKind) -> S.SQLExp
    mkNodeId :: SourceName
-> QualifiedTable -> PrimaryKeyColumns ('Postgres pgKind) -> SQLExp
mkNodeId SourceName
_sourceName (QualifiedObject SchemaName
tableSchema TableName
tableName) PrimaryKeyColumns ('Postgres pgKind)
pkeyColumns =
      let columnInfoToSQLExp :: ColumnInfo ('Postgres pgKind) -> SQLExp
columnInfoToSQLExp ColumnInfo ('Postgres pgKind)
pgColumnInfo =
            StringifyNumbers
-> ColumnType ('Postgres pgKind)
-> Bool
-> Maybe NamingCase
-> SQLExp
-> SQLExp
forall (pgKind :: PostgresKind).
StringifyNumbers
-> ColumnType ('Postgres pgKind)
-> Bool
-> Maybe NamingCase
-> SQLExp
-> SQLExp
toJSONableExp StringifyNumbers
Options.Don'tStringifyNumbers (ColumnInfo ('Postgres pgKind) -> ColumnType ('Postgres pgKind)
forall (b :: BackendType). ColumnInfo b -> ColumnType b
ciType ColumnInfo ('Postgres pgKind)
pgColumnInfo) Bool
False Maybe NamingCase
forall a. Maybe a
Nothing (SQLExp -> SQLExp) -> SQLExp -> SQLExp
forall a b. (a -> b) -> a -> b
$
              TableAlias -> PGCol -> SQLExp
forall a b. (IsIdentifier a, IsIdentifier b) => a -> b -> SQLExp
S.mkQIdenExp (Identifier -> TableAlias
mkBaseTableAlias Identifier
sourcePrefix) (PGCol -> SQLExp) -> PGCol -> SQLExp
forall a b. (a -> b) -> a -> b
$ ColumnInfo ('Postgres pgKind) -> Column ('Postgres pgKind)
forall (b :: BackendType). ColumnInfo b -> Column b
ciColumn ColumnInfo ('Postgres pgKind)
pgColumnInfo
       in -- See Note [Relay Node id].
          SQLExp -> SQLExp
encodeBase64 (SQLExp -> SQLExp) -> SQLExp -> SQLExp
forall a b. (a -> b) -> a -> b
$
            (SQLExp -> TypeAnn -> SQLExp) -> TypeAnn -> SQLExp -> SQLExp
forall a b c. (a -> b -> c) -> b -> a -> c
flip SQLExp -> TypeAnn -> SQLExp
S.SETyAnn TypeAnn
S.textTypeAnn (SQLExp -> SQLExp) -> SQLExp -> SQLExp
forall a b. (a -> b) -> a -> b
$
              [SQLExp] -> SQLExp
S.applyJsonBuildArray ([SQLExp] -> SQLExp) -> [SQLExp] -> SQLExp
forall a b. (a -> b) -> a -> b
$
                [ Int -> SQLExp
S.intToSQLExp (Int -> SQLExp) -> Int -> SQLExp
forall a b. (a -> b) -> a -> b
$ NodeIdVersion -> Int
nodeIdVersionInt NodeIdVersion
currentNodeIdVersion,
                  Text -> SQLExp
S.SELit (SchemaName -> Text
getSchemaTxt SchemaName
tableSchema),
                  Text -> SQLExp
S.SELit (TableName -> Text
forall a. ToTxt a => a -> Text
toTxt TableName
tableName)
                ]
                  [SQLExp] -> [SQLExp] -> [SQLExp]
forall a. Semigroup a => a -> a -> a
<> (ColumnInfo ('Postgres pgKind) -> SQLExp)
-> [ColumnInfo ('Postgres pgKind)] -> [SQLExp]
forall a b. (a -> b) -> [a] -> [b]
map ColumnInfo ('Postgres pgKind) -> SQLExp
columnInfoToSQLExp (PrimaryKeyColumns ('Postgres pgKind)
-> [ColumnInfo ('Postgres pgKind)]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList PrimaryKeyColumns ('Postgres pgKind)
pkeyColumns)

mkSimilarArrayFields ::
  forall pgKind v.
  (Backend ('Postgres pgKind), Eq v) =>
  AnnFieldsG ('Postgres pgKind) Void v ->
  Maybe (NE.NonEmpty (AnnotatedOrderByItemG ('Postgres pgKind) v)) ->
  SimilarArrayFields
mkSimilarArrayFields :: AnnFieldsG ('Postgres pgKind) Void v
-> Maybe (NonEmpty (AnnotatedOrderByItemG ('Postgres pgKind) v))
-> SimilarArrayFields
mkSimilarArrayFields AnnFieldsG ('Postgres pgKind) Void v
annFields Maybe (NonEmpty (AnnotatedOrderByItemG ('Postgres pgKind) v))
maybeOrderBys =
  [(FieldName, [FieldName])] -> SimilarArrayFields
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HM.fromList ([(FieldName, [FieldName])] -> SimilarArrayFields)
-> [(FieldName, [FieldName])] -> SimilarArrayFields
forall a b. (a -> b) -> a -> b
$
    ((((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)
  -> (FieldName, [FieldName]))
 -> [((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)]
 -> [(FieldName, [FieldName])])
-> [((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)]
-> (((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)
    -> (FieldName, [FieldName]))
-> [(FieldName, [FieldName])]
forall a b c. (a -> b -> c) -> b -> a -> c
flip (((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)
 -> (FieldName, [FieldName]))
-> [((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)]
-> [(FieldName, [FieldName])]
forall a b. (a -> b) -> [a] -> [b]
map [((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)]
allTuples ((((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)
  -> (FieldName, [FieldName]))
 -> [(FieldName, [FieldName])])
-> (((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)
    -> (FieldName, [FieldName]))
-> [(FieldName, [FieldName])]
forall a b. (a -> b) -> a -> b
$
      \((RelName, SelectArgsG ('Postgres pgKind) v)
relNameAndArgs, FieldName
fieldName) -> (FieldName
fieldName, (RelName, SelectArgsG ('Postgres pgKind) v) -> [FieldName]
getSimilarFields (RelName, SelectArgsG ('Postgres pgKind) v)
relNameAndArgs)
  where
    getSimilarFields :: (RelName, SelectArgsG ('Postgres pgKind) v) -> [FieldName]
getSimilarFields (RelName, SelectArgsG ('Postgres pgKind) v)
relNameAndArgs = (((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)
 -> FieldName)
-> [((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)]
-> [FieldName]
forall a b. (a -> b) -> [a] -> [b]
map ((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)
-> FieldName
forall a b. (a, b) -> b
snd ([((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)]
 -> [FieldName])
-> [((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)]
-> [FieldName]
forall a b. (a -> b) -> a -> b
$ (((RelName, SelectArgsG ('Postgres pgKind) v), FieldName) -> Bool)
-> [((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)]
-> [((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)]
forall a. (a -> Bool) -> [a] -> [a]
filter (((RelName, SelectArgsG ('Postgres pgKind) v)
-> (RelName, SelectArgsG ('Postgres pgKind) v) -> Bool
forall a. Eq a => a -> a -> Bool
== (RelName, SelectArgsG ('Postgres pgKind) v)
relNameAndArgs) ((RelName, SelectArgsG ('Postgres pgKind) v) -> Bool)
-> (((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)
    -> (RelName, SelectArgsG ('Postgres pgKind) v))
-> ((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)
-> (RelName, SelectArgsG ('Postgres pgKind) v)
forall a b. (a, b) -> a
fst) [((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)]
allTuples
    allTuples :: [((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)]
allTuples = [((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)]
arrayRelationTuples [((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)]
-> [((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)]
-> [((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)]
forall a. Semigroup a => a -> a -> a
<> [((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)]
aggOrderByRelationTuples
    arrayRelationTuples :: [((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)]
arrayRelationTuples =
      let arrayFields :: [(FieldName, ArraySelectG ('Postgres pgKind) Void v)]
arrayFields = ((FieldName, AnnFieldG ('Postgres pgKind) Void v)
 -> Maybe (FieldName, ArraySelectG ('Postgres pgKind) Void v))
-> AnnFieldsG ('Postgres pgKind) Void v
-> [(FieldName, ArraySelectG ('Postgres pgKind) Void v)]
forall (f :: * -> *) a b.
Filterable f =>
(a -> Maybe b) -> f a -> f b
mapMaybe (FieldName, AnnFieldG ('Postgres pgKind) Void v)
-> Maybe (FieldName, ArraySelectG ('Postgres pgKind) Void v)
forall a r.
(a, AnnFieldG ('Postgres pgKind) r v)
-> Maybe (a, ArraySelectG ('Postgres pgKind) r v)
getAnnArr AnnFieldsG ('Postgres pgKind) Void v
annFields
       in (((FieldName, ArraySelectG ('Postgres pgKind) Void v)
  -> ((RelName, SelectArgsG ('Postgres pgKind) v), FieldName))
 -> [(FieldName, ArraySelectG ('Postgres pgKind) Void v)]
 -> [((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)])
-> [(FieldName, ArraySelectG ('Postgres pgKind) Void v)]
-> ((FieldName, ArraySelectG ('Postgres pgKind) Void v)
    -> ((RelName, SelectArgsG ('Postgres pgKind) v), FieldName))
-> [((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)]
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((FieldName, ArraySelectG ('Postgres pgKind) Void v)
 -> ((RelName, SelectArgsG ('Postgres pgKind) v), FieldName))
-> [(FieldName, ArraySelectG ('Postgres pgKind) Void v)]
-> [((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)]
forall a b. (a -> b) -> [a] -> [b]
map [(FieldName, ArraySelectG ('Postgres pgKind) Void v)]
arrayFields (((FieldName, ArraySelectG ('Postgres pgKind) Void v)
  -> ((RelName, SelectArgsG ('Postgres pgKind) v), FieldName))
 -> [((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)])
-> ((FieldName, ArraySelectG ('Postgres pgKind) Void v)
    -> ((RelName, SelectArgsG ('Postgres pgKind) v), FieldName))
-> [((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)]
forall a b. (a -> b) -> a -> b
$
            \(FieldName
f, ArraySelectG ('Postgres pgKind) Void v
relSel) -> (ArraySelectG ('Postgres pgKind) Void v
-> (RelName, SelectArgsG ('Postgres pgKind) v)
forall r.
ArraySelectG ('Postgres pgKind) r v
-> (RelName, SelectArgsG ('Postgres pgKind) v)
getArrayRelNameAndSelectArgs ArraySelectG ('Postgres pgKind) Void v
relSel, FieldName
f)

    getAnnArr ::
      (a, AnnFieldG ('Postgres pgKind) r v) ->
      Maybe (a, ArraySelectG ('Postgres pgKind) r v)
    getAnnArr :: (a, AnnFieldG ('Postgres pgKind) r v)
-> Maybe (a, ArraySelectG ('Postgres pgKind) r v)
getAnnArr (a
f, AnnFieldG ('Postgres pgKind) r v
annFld) = case AnnFieldG ('Postgres pgKind) r v
annFld of
      AFArrayRelation (ASConnection ArrayConnectionSelect ('Postgres pgKind) r v
_) -> Maybe (a, ArraySelectG ('Postgres pgKind) r v)
forall a. Maybe a
Nothing
      AFArrayRelation ArraySelectG ('Postgres pgKind) r v
ar -> (a, ArraySelectG ('Postgres pgKind) r v)
-> Maybe (a, ArraySelectG ('Postgres pgKind) r v)
forall a. a -> Maybe a
Just (a
f, ArraySelectG ('Postgres pgKind) r v
ar)
      AnnFieldG ('Postgres pgKind) r v
_ -> Maybe (a, ArraySelectG ('Postgres pgKind) r v)
forall a. Maybe a
Nothing

    aggOrderByRelationTuples :: [((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)]
aggOrderByRelationTuples =
      let mkItem :: (a, b) -> ((a, SelectArgsG backend v), b)
mkItem (a
relName, b
fieldName) =
            ( (a
relName, SelectArgsG backend v
forall (backend :: BackendType) v. SelectArgsG backend v
noSelectArgs),
              b
fieldName
            )
       in ((RelName, FieldName)
 -> ((RelName, SelectArgsG ('Postgres pgKind) v), FieldName))
-> [(RelName, FieldName)]
-> [((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)]
forall a b. (a -> b) -> [a] -> [b]
map (RelName, FieldName)
-> ((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)
forall a b (backend :: BackendType) v.
(a, b) -> ((a, SelectArgsG backend v), b)
mkItem ([(RelName, FieldName)]
 -> [((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)])
-> [(RelName, FieldName)]
-> [((RelName, SelectArgsG ('Postgres pgKind) v), FieldName)]
forall a b. (a -> b) -> a -> b
$
            [(RelName, FieldName)]
-> (NonEmpty (AnnotatedOrderByItemG ('Postgres pgKind) v)
    -> [(RelName, FieldName)])
-> Maybe (NonEmpty (AnnotatedOrderByItemG ('Postgres pgKind) v))
-> [(RelName, FieldName)]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
              []
              ((AnnotatedOrderByItemG ('Postgres pgKind) v
 -> Maybe (RelName, FieldName))
-> [AnnotatedOrderByItemG ('Postgres pgKind) v]
-> [(RelName, FieldName)]
forall (f :: * -> *) a b.
Filterable f =>
(a -> Maybe b) -> f a -> f b
mapMaybe (AnnotatedOrderByElement ('Postgres pgKind) v
-> Maybe (RelName, FieldName)
forall (b :: BackendType) v.
AnnotatedOrderByElement b v -> Maybe (RelName, FieldName)
fetchAggOrderByRels (AnnotatedOrderByElement ('Postgres pgKind) v
 -> Maybe (RelName, FieldName))
-> (AnnotatedOrderByItemG ('Postgres pgKind) v
    -> AnnotatedOrderByElement ('Postgres pgKind) v)
-> AnnotatedOrderByItemG ('Postgres pgKind) v
-> Maybe (RelName, FieldName)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AnnotatedOrderByItemG ('Postgres pgKind) v
-> AnnotatedOrderByElement ('Postgres pgKind) v
forall (b :: BackendType) a. OrderByItemG b a -> a
obiColumn) ([AnnotatedOrderByItemG ('Postgres pgKind) v]
 -> [(RelName, FieldName)])
-> (NonEmpty (AnnotatedOrderByItemG ('Postgres pgKind) v)
    -> [AnnotatedOrderByItemG ('Postgres pgKind) v])
-> NonEmpty (AnnotatedOrderByItemG ('Postgres pgKind) v)
-> [(RelName, FieldName)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty (AnnotatedOrderByItemG ('Postgres pgKind) v)
-> [AnnotatedOrderByItemG ('Postgres pgKind) v]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList)
              Maybe (NonEmpty (AnnotatedOrderByItemG ('Postgres pgKind) v))
maybeOrderBys

    fetchAggOrderByRels :: AnnotatedOrderByElement b v -> Maybe (RelName, FieldName)
fetchAggOrderByRels (AOCArrayAggregation RelInfo b
ri AnnBoolExp b v
_ AnnotatedAggregateOrderBy b
_) =
      (RelName, FieldName) -> Maybe (RelName, FieldName)
forall a. a -> Maybe a
Just (RelInfo b -> RelName
forall (b :: BackendType). RelInfo b -> RelName
riName RelInfo b
ri, RelName -> FieldName
forall a. ToTxt a => a -> FieldName
mkOrderByFieldName (RelName -> FieldName) -> RelName -> FieldName
forall a b. (a -> b) -> a -> b
$ RelInfo b -> RelName
forall (b :: BackendType). RelInfo b -> RelName
riName RelInfo b
ri)
    fetchAggOrderByRels AnnotatedOrderByElement b v
_ = Maybe (RelName, FieldName)
forall a. Maybe a
Nothing

    getArrayRelNameAndSelectArgs ::
      ArraySelectG ('Postgres pgKind) r v ->
      (RelName, SelectArgsG ('Postgres pgKind) v)
    getArrayRelNameAndSelectArgs :: ArraySelectG ('Postgres pgKind) r v
-> (RelName, SelectArgsG ('Postgres pgKind) v)
getArrayRelNameAndSelectArgs = \case
      ASSimple ArrayRelationSelectG ('Postgres pgKind) r v
r -> (ArrayRelationSelectG ('Postgres pgKind) r v -> RelName
forall (b :: BackendType) a. AnnRelationSelectG b a -> RelName
_aarRelationshipName ArrayRelationSelectG ('Postgres pgKind) r v
r, AnnSelectG ('Postgres pgKind) (AnnFieldG ('Postgres pgKind) r) v
-> SelectArgsG ('Postgres pgKind) v
forall (b :: BackendType) (f :: * -> *) v.
AnnSelectG b f v -> SelectArgsG b v
_asnArgs (AnnSelectG ('Postgres pgKind) (AnnFieldG ('Postgres pgKind) r) v
 -> SelectArgsG ('Postgres pgKind) v)
-> AnnSelectG ('Postgres pgKind) (AnnFieldG ('Postgres pgKind) r) v
-> SelectArgsG ('Postgres pgKind) v
forall a b. (a -> b) -> a -> b
$ ArrayRelationSelectG ('Postgres pgKind) r v
-> AnnSelectG ('Postgres pgKind) (AnnFieldG ('Postgres pgKind) r) v
forall (b :: BackendType) a. AnnRelationSelectG b a -> a
_aarAnnSelect ArrayRelationSelectG ('Postgres pgKind) r v
r)
      ASAggregate ArrayAggregateSelectG ('Postgres pgKind) r v
r -> (ArrayAggregateSelectG ('Postgres pgKind) r v -> RelName
forall (b :: BackendType) a. AnnRelationSelectG b a -> RelName
_aarRelationshipName ArrayAggregateSelectG ('Postgres pgKind) r v
r, AnnSelectG
  ('Postgres pgKind) (TableAggregateFieldG ('Postgres pgKind) r) v
-> SelectArgsG ('Postgres pgKind) v
forall (b :: BackendType) (f :: * -> *) v.
AnnSelectG b f v -> SelectArgsG b v
_asnArgs (AnnSelectG
   ('Postgres pgKind) (TableAggregateFieldG ('Postgres pgKind) r) v
 -> SelectArgsG ('Postgres pgKind) v)
-> AnnSelectG
     ('Postgres pgKind) (TableAggregateFieldG ('Postgres pgKind) r) v
-> SelectArgsG ('Postgres pgKind) v
forall a b. (a -> b) -> a -> b
$ ArrayAggregateSelectG ('Postgres pgKind) r v
-> AnnSelectG
     ('Postgres pgKind) (TableAggregateFieldG ('Postgres pgKind) r) v
forall (b :: BackendType) a. AnnRelationSelectG b a -> a
_aarAnnSelect ArrayAggregateSelectG ('Postgres pgKind) r v
r)
      ASConnection ArrayConnectionSelect ('Postgres pgKind) r v
r -> (ArrayConnectionSelect ('Postgres pgKind) r v -> RelName
forall (b :: BackendType) a. AnnRelationSelectG b a -> RelName
_aarRelationshipName ArrayConnectionSelect ('Postgres pgKind) r v
r, AnnSelectG
  ('Postgres pgKind) (ConnectionField ('Postgres pgKind) r) v
-> SelectArgsG ('Postgres pgKind) v
forall (b :: BackendType) (f :: * -> *) v.
AnnSelectG b f v -> SelectArgsG b v
_asnArgs (AnnSelectG
   ('Postgres pgKind) (ConnectionField ('Postgres pgKind) r) v
 -> SelectArgsG ('Postgres pgKind) v)
-> AnnSelectG
     ('Postgres pgKind) (ConnectionField ('Postgres pgKind) r) v
-> SelectArgsG ('Postgres pgKind) v
forall a b. (a -> b) -> a -> b
$ ConnectionSelect ('Postgres pgKind) r v
-> AnnSelectG
     ('Postgres pgKind) (ConnectionField ('Postgres pgKind) r) v
forall (b :: BackendType) r v.
ConnectionSelect b r v -> AnnSelectG b (ConnectionField b r) v
_csSelect (ConnectionSelect ('Postgres pgKind) r v
 -> AnnSelectG
      ('Postgres pgKind) (ConnectionField ('Postgres pgKind) r) v)
-> ConnectionSelect ('Postgres pgKind) r v
-> AnnSelectG
     ('Postgres pgKind) (ConnectionField ('Postgres pgKind) r) v
forall a b. (a -> b) -> a -> b
$ ArrayConnectionSelect ('Postgres pgKind) r v
-> ConnectionSelect ('Postgres pgKind) r v
forall (b :: BackendType) a. AnnRelationSelectG b a -> a
_aarAnnSelect ArrayConnectionSelect ('Postgres pgKind) r v
r)

processArrayRelation ::
  forall pgKind m.
  ( MonadReader Options.StringifyNumbers m,
    MonadWriter JoinTree m,
    Backend ('Postgres pgKind),
    PostgresAnnotatedFieldJSON pgKind
  ) =>
  SourcePrefixes ->
  FieldName ->
  S.TableAlias ->
  ArraySelect ('Postgres pgKind) ->
  Maybe NamingCase ->
  m ()
processArrayRelation :: SourcePrefixes
-> FieldName
-> TableAlias
-> ArraySelect ('Postgres pgKind)
-> Maybe NamingCase
-> m ()
processArrayRelation SourcePrefixes
sourcePrefixes FieldName
fieldAlias TableAlias
relAlias ArraySelect ('Postgres pgKind)
arrSel Maybe NamingCase
_tCase =
  case ArraySelect ('Postgres pgKind)
arrSel of
    ASSimple ArrayRelationSelectG
  ('Postgres pgKind) Void (SQLExpression ('Postgres pgKind))
annArrRel -> m (ArrayRelationSource, Extractor, HashMap ColumnAlias SQLExp, ())
-> m ()
forall (m :: * -> *) a.
MonadWriter JoinTree m =>
m (ArrayRelationSource, Extractor, HashMap ColumnAlias SQLExp, a)
-> m a
withWriteArrayRelation (m (ArrayRelationSource, Extractor, HashMap ColumnAlias SQLExp, ())
 -> m ())
-> m (ArrayRelationSource, Extractor, HashMap ColumnAlias SQLExp,
      ())
-> m ()
forall a b. (a -> b) -> a -> b
$ do
      let AnnRelationSelectG RelName
_ HashMap (Column ('Postgres pgKind)) (Column ('Postgres pgKind))
colMapping AnnSelectG
  ('Postgres pgKind) (AnnFieldG ('Postgres pgKind) Void) SQLExp
sel = ArrayRelationSelectG
  ('Postgres pgKind) Void (SQLExpression ('Postgres pgKind))
AnnRelationSelectG
  ('Postgres pgKind)
  (AnnSelectG
     ('Postgres pgKind) (AnnFieldG ('Postgres pgKind) Void) SQLExp)
annArrRel
          permLimitSubQuery :: PermissionLimitSubQuery
permLimitSubQuery =
            PermissionLimitSubQuery
-> (Int -> PermissionLimitSubQuery)
-> Maybe Int
-> PermissionLimitSubQuery
forall b a. b -> (a -> b) -> Maybe a -> b
maybe PermissionLimitSubQuery
PLSQNotRequired Int -> PermissionLimitSubQuery
PLSQRequired (Maybe Int -> PermissionLimitSubQuery)
-> Maybe Int -> PermissionLimitSubQuery
forall a b. (a -> b) -> a -> b
$ TablePermG ('Postgres pgKind) SQLExp -> Maybe Int
forall (b :: BackendType) v. TablePermG b v -> Maybe Int
_tpLimit (TablePermG ('Postgres pgKind) SQLExp -> Maybe Int)
-> TablePermG ('Postgres pgKind) SQLExp -> Maybe Int
forall a b. (a -> b) -> a -> b
$ AnnSelectG
  ('Postgres pgKind) (AnnFieldG ('Postgres pgKind) Void) SQLExp
-> TablePermG ('Postgres pgKind) SQLExp
forall (b :: BackendType) (f :: * -> *) v.
AnnSelectG b f v -> TablePermG b v
_asnPerm AnnSelectG
  ('Postgres pgKind) (AnnFieldG ('Postgres pgKind) Void) SQLExp
sel
      (SelectSource
source, HashMap ColumnAlias SQLExp
nodeExtractors) <-
        SourcePrefixes
-> FieldName
-> PermissionLimitSubQuery
-> AnnSimpleSelect ('Postgres pgKind)
-> m (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
fieldAlias PermissionLimitSubQuery
permLimitSubQuery AnnSimpleSelect ('Postgres pgKind)
AnnSelectG
  ('Postgres pgKind) (AnnFieldG ('Postgres pgKind) Void) SQLExp
sel
      let topExtr :: Extractor
topExtr =
            JsonAggSelect
-> ColumnAlias
-> PermissionLimitSubQuery
-> Maybe OrderByExp
-> Extractor
asJsonAggExtr
              JsonAggSelect
JASMultipleRows
              (FieldName -> ColumnAlias
forall a. IsIdentifier a => a -> ColumnAlias
S.toColumnAlias FieldName
fieldAlias)
              PermissionLimitSubQuery
permLimitSubQuery
              (Maybe OrderByExp -> Extractor) -> Maybe OrderByExp -> Extractor
forall a b. (a -> b) -> a -> b
$ SelectSource -> Maybe OrderByExp
orderByForJsonAgg SelectSource
source
      (ArrayRelationSource, Extractor, HashMap ColumnAlias SQLExp, ())
-> m (ArrayRelationSource, Extractor, HashMap ColumnAlias SQLExp,
      ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure
        ( TableAlias
-> HashMap PGCol PGCol -> SelectSource -> ArrayRelationSource
ArrayRelationSource TableAlias
relAlias HashMap (Column ('Postgres pgKind)) (Column ('Postgres pgKind))
HashMap PGCol PGCol
colMapping SelectSource
source,
          Extractor
topExtr,
          HashMap ColumnAlias SQLExp
nodeExtractors,
          ()
        )
    ASAggregate ArrayAggregateSelectG
  ('Postgres pgKind) Void (SQLExpression ('Postgres pgKind))
aggSel -> m (ArrayRelationSource, Extractor, HashMap ColumnAlias SQLExp, ())
-> m ()
forall (m :: * -> *) a.
MonadWriter JoinTree m =>
m (ArrayRelationSource, Extractor, HashMap ColumnAlias SQLExp, a)
-> m a
withWriteArrayRelation (m (ArrayRelationSource, Extractor, HashMap ColumnAlias SQLExp, ())
 -> m ())
-> m (ArrayRelationSource, Extractor, HashMap ColumnAlias SQLExp,
      ())
-> m ()
forall a b. (a -> b) -> a -> b
$ do
      let AnnRelationSelectG RelName
_ HashMap (Column ('Postgres pgKind)) (Column ('Postgres pgKind))
colMapping AnnAggregateSelectG ('Postgres pgKind) Void SQLExp
sel = ArrayAggregateSelectG
  ('Postgres pgKind) Void (SQLExpression ('Postgres pgKind))
AnnRelationSelectG
  ('Postgres pgKind)
  (AnnAggregateSelectG ('Postgres pgKind) Void SQLExp)
aggSel
      (SelectSource
source, HashMap ColumnAlias SQLExp
nodeExtractors, Extractor
topExtr) <-
        SourcePrefixes
-> FieldName
-> AnnAggregateSelect ('Postgres pgKind)
-> m (SelectSource, HashMap ColumnAlias SQLExp, Extractor)
forall (pgKind :: PostgresKind) (m :: * -> *).
(MonadReader StringifyNumbers m, MonadWriter JoinTree m,
 Backend ('Postgres pgKind), PostgresAnnotatedFieldJSON pgKind) =>
SourcePrefixes
-> FieldName
-> AnnAggregateSelect ('Postgres pgKind)
-> m (SelectSource, HashMap ColumnAlias SQLExp, Extractor)
processAnnAggregateSelect SourcePrefixes
sourcePrefixes FieldName
fieldAlias AnnAggregateSelect ('Postgres pgKind)
AnnAggregateSelectG ('Postgres pgKind) Void SQLExp
sel
      (ArrayRelationSource, Extractor, HashMap ColumnAlias SQLExp, ())
-> m (ArrayRelationSource, Extractor, HashMap ColumnAlias SQLExp,
      ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure
        ( TableAlias
-> HashMap PGCol PGCol -> SelectSource -> ArrayRelationSource
ArrayRelationSource TableAlias
relAlias HashMap (Column ('Postgres pgKind)) (Column ('Postgres pgKind))
HashMap PGCol PGCol
colMapping SelectSource
source,
          Extractor
topExtr,
          HashMap ColumnAlias SQLExp
nodeExtractors,
          ()
        )
    ASConnection ArrayConnectionSelect
  ('Postgres pgKind) Void (SQLExpression ('Postgres pgKind))
connSel -> m (ArrayConnectionSource, Extractor, HashMap ColumnAlias SQLExp,
   ())
-> m ()
forall (m :: * -> *) a.
MonadWriter JoinTree m =>
m (ArrayConnectionSource, Extractor, HashMap ColumnAlias SQLExp, a)
-> m a
withWriteArrayConnection (m (ArrayConnectionSource, Extractor, HashMap ColumnAlias SQLExp,
    ())
 -> m ())
-> m (ArrayConnectionSource, Extractor, HashMap ColumnAlias SQLExp,
      ())
-> m ()
forall a b. (a -> b) -> a -> b
$ do
      let AnnRelationSelectG RelName
_ HashMap (Column ('Postgres pgKind)) (Column ('Postgres pgKind))
colMapping ConnectionSelect ('Postgres pgKind) Void SQLExp
sel = ArrayConnectionSelect
  ('Postgres pgKind) Void (SQLExpression ('Postgres pgKind))
AnnRelationSelectG
  ('Postgres pgKind)
  (ConnectionSelect ('Postgres pgKind) Void SQLExp)
connSel
      (ArrayConnectionSource
source, Extractor
topExtractor, HashMap ColumnAlias SQLExp
nodeExtractors) <-
        SourcePrefixes
-> FieldName
-> TableAlias
-> HashMap PGCol PGCol
-> ConnectionSelect ('Postgres pgKind) Void SQLExp
-> m (ArrayConnectionSource, Extractor, HashMap ColumnAlias SQLExp)
forall (pgKind :: PostgresKind) (m :: * -> *).
(MonadReader StringifyNumbers m, MonadWriter JoinTree m,
 Backend ('Postgres pgKind), PostgresAnnotatedFieldJSON pgKind) =>
SourcePrefixes
-> FieldName
-> TableAlias
-> HashMap PGCol PGCol
-> ConnectionSelect ('Postgres pgKind) Void SQLExp
-> m (ArrayConnectionSource, Extractor, HashMap ColumnAlias SQLExp)
processConnectionSelect SourcePrefixes
sourcePrefixes FieldName
fieldAlias TableAlias
relAlias HashMap (Column ('Postgres pgKind)) (Column ('Postgres pgKind))
HashMap PGCol PGCol
colMapping ConnectionSelect ('Postgres pgKind) Void SQLExp
sel
      (ArrayConnectionSource, Extractor, HashMap ColumnAlias SQLExp, ())
-> m (ArrayConnectionSource, Extractor, HashMap ColumnAlias SQLExp,
      ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure
        ( ArrayConnectionSource
source,
          Extractor
topExtractor,
          HashMap ColumnAlias SQLExp
nodeExtractors,
          ()
        )

aggregateFieldToExp :: AggregateFields ('Postgres pgKind) -> Options.StringifyNumbers -> S.SQLExp
aggregateFieldToExp :: AggregateFields ('Postgres pgKind) -> StringifyNumbers -> SQLExp
aggregateFieldToExp AggregateFields ('Postgres pgKind)
aggFlds StringifyNumbers
strfyNum = SQLExp
jsonRow
  where
    jsonRow :: SQLExp
jsonRow = [SQLExp] -> SQLExp
S.applyJsonBuildObj (((FieldName, AggregateField ('Postgres pgKind)) -> [SQLExp])
-> AggregateFields ('Postgres pgKind) -> [SQLExp]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (FieldName, AggregateField ('Postgres pgKind)) -> [SQLExp]
aggToFlds AggregateFields ('Postgres pgKind)
aggFlds)
    withAls :: Text -> SQLExp -> [SQLExp]
withAls Text
fldName SQLExp
sqlExp = [Text -> SQLExp
S.SELit Text
fldName, SQLExp
sqlExp]
    aggToFlds :: (FieldName, AggregateField ('Postgres pgKind)) -> [SQLExp]
aggToFlds (FieldName Text
t, AggregateField ('Postgres pgKind)
fld) = Text -> SQLExp -> [SQLExp]
withAls Text
t (SQLExp -> [SQLExp]) -> SQLExp -> [SQLExp]
forall a b. (a -> b) -> a -> b
$ case AggregateField ('Postgres pgKind)
fld of
      AFCount CountType ('Postgres pgKind)
cty -> CountType -> SQLExp
S.SECount CountType ('Postgres pgKind)
CountType
cty
      AFOp AggregateOp ('Postgres pgKind)
aggOp -> AggregateOp ('Postgres pgKind) -> SQLExp
aggOpToObj AggregateOp ('Postgres pgKind)
aggOp
      AFExp Text
e -> Text -> SQLExp
S.SELit Text
e

    aggOpToObj :: AggregateOp ('Postgres pgKind) -> SQLExp
aggOpToObj (AggregateOp Text
opText ColumnFields ('Postgres pgKind)
flds) =
      [SQLExp] -> SQLExp
S.applyJsonBuildObj ([SQLExp] -> SQLExp) -> [SQLExp] -> SQLExp
forall a b. (a -> b) -> a -> b
$ ((FieldName, ColFld ('Postgres pgKind)) -> [SQLExp])
-> ColumnFields ('Postgres pgKind) -> [SQLExp]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Text -> (FieldName, ColFld ('Postgres pgKind)) -> [SQLExp]
colFldsToExtr Text
opText) ColumnFields ('Postgres pgKind)
flds

    colFldsToExtr :: Text -> (FieldName, ColFld ('Postgres pgKind)) -> [SQLExp]
colFldsToExtr Text
opText (FieldName Text
t, CFCol Column ('Postgres pgKind)
col ColumnType ('Postgres pgKind)
ty) =
      [ Text -> SQLExp
S.SELit Text
t,
        StringifyNumbers
-> ColumnType ('Postgres pgKind)
-> Bool
-> Maybe NamingCase
-> SQLExp
-> SQLExp
forall (pgKind :: PostgresKind).
StringifyNumbers
-> ColumnType ('Postgres pgKind)
-> Bool
-> Maybe NamingCase
-> SQLExp
-> SQLExp
toJSONableExp StringifyNumbers
strfyNum ColumnType ('Postgres pgKind)
ty Bool
False Maybe NamingCase
forall a. Maybe a
Nothing (SQLExp -> SQLExp) -> SQLExp -> SQLExp
forall a b. (a -> b) -> a -> b
$
          Text -> [SQLExp] -> Maybe OrderByExp -> SQLExp
S.SEFnApp Text
opText [Identifier -> SQLExp
S.SEIdentifier (Identifier -> SQLExp) -> Identifier -> SQLExp
forall a b. (a -> b) -> a -> b
$ PGCol -> Identifier
forall a. IsIdentifier a => a -> Identifier
toIdentifier Column ('Postgres pgKind)
PGCol
col] Maybe OrderByExp
forall a. Maybe a
Nothing
      ]
    colFldsToExtr Text
_ (FieldName Text
t, CFExp Text
e) =
      [Text -> SQLExp
S.SELit Text
t, Text -> SQLExp
S.SELit Text
e]

processAnnSimpleSelect ::
  forall pgKind m.
  ( MonadReader Options.StringifyNumbers m,
    MonadWriter JoinTree m,
    Backend ('Postgres pgKind),
    PostgresAnnotatedFieldJSON pgKind
  ) =>
  SourcePrefixes ->
  FieldName ->
  PermissionLimitSubQuery ->
  AnnSimpleSelect ('Postgres pgKind) ->
  m
    ( SelectSource,
      HM.HashMap S.ColumnAlias S.SQLExp
    )
processAnnSimpleSelect :: SourcePrefixes
-> FieldName
-> PermissionLimitSubQuery
-> AnnSimpleSelect ('Postgres pgKind)
-> m (SelectSource, HashMap ColumnAlias SQLExp)
processAnnSimpleSelect SourcePrefixes
sourcePrefixes FieldName
fieldAlias PermissionLimitSubQuery
permLimitSubQuery AnnSimpleSelect ('Postgres pgKind)
annSimpleSel = do
  (SelectSource
selectSource, [(ColumnAlias, SQLExp)]
orderByAndDistinctExtrs, Maybe SQLExp
_) <-
    SourcePrefixes
-> FieldName
-> SimilarArrayFields
-> SelectFrom ('Postgres pgKind)
-> PermissionLimitSubQuery
-> TablePerm ('Postgres pgKind)
-> SelectArgs ('Postgres pgKind)
-> m (SelectSource, [(ColumnAlias, SQLExp)], Maybe SQLExp)
forall (pgKind :: PostgresKind) (m :: * -> *).
(MonadReader StringifyNumbers m, MonadWriter JoinTree m,
 Backend ('Postgres pgKind)) =>
SourcePrefixes
-> FieldName
-> SimilarArrayFields
-> SelectFrom ('Postgres pgKind)
-> PermissionLimitSubQuery
-> TablePerm ('Postgres pgKind)
-> SelectArgs ('Postgres pgKind)
-> m (SelectSource, [(ColumnAlias, SQLExp)], Maybe SQLExp)
processSelectParams
      SourcePrefixes
sourcePrefixes
      FieldName
fieldAlias
      SimilarArrayFields
similarArrayFields
      SelectFrom ('Postgres pgKind)
SelectFromG ('Postgres pgKind) SQLExp
tableFrom
      PermissionLimitSubQuery
permLimitSubQuery
      TablePerm ('Postgres pgKind)
TablePermG ('Postgres pgKind) SQLExp
tablePermissions
      SelectArgs ('Postgres pgKind)
SelectArgsG ('Postgres pgKind) SQLExp
tableArgs
  (ColumnAlias, SQLExp)
annFieldsExtr <- Identifier
-> FieldName
-> SimilarArrayFields
-> AnnFields ('Postgres pgKind)
-> Maybe NamingCase
-> m (ColumnAlias, SQLExp)
forall (pgKind :: PostgresKind) (m :: * -> *).
(MonadReader StringifyNumbers m, MonadWriter JoinTree m,
 Backend ('Postgres pgKind), PostgresAnnotatedFieldJSON pgKind) =>
Identifier
-> FieldName
-> SimilarArrayFields
-> AnnFields ('Postgres pgKind)
-> Maybe NamingCase
-> m (ColumnAlias, SQLExp)
processAnnFields (SourcePrefixes -> Identifier
_pfThis SourcePrefixes
sourcePrefixes) FieldName
fieldAlias SimilarArrayFields
similarArrayFields AnnFields ('Postgres pgKind)
Fields (AnnFieldG ('Postgres pgKind) Void SQLExp)
annSelFields Maybe NamingCase
tCase
  let allExtractors :: HashMap ColumnAlias SQLExp
allExtractors = [(ColumnAlias, SQLExp)] -> HashMap ColumnAlias SQLExp
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HM.fromList ([(ColumnAlias, SQLExp)] -> HashMap ColumnAlias SQLExp)
-> [(ColumnAlias, SQLExp)] -> HashMap ColumnAlias SQLExp
forall a b. (a -> b) -> a -> b
$ (ColumnAlias, SQLExp)
annFieldsExtr (ColumnAlias, SQLExp)
-> [(ColumnAlias, SQLExp)] -> [(ColumnAlias, SQLExp)]
forall a. a -> [a] -> [a]
: [(ColumnAlias, SQLExp)]
orderByAndDistinctExtrs
  (SelectSource, HashMap ColumnAlias SQLExp)
-> m (SelectSource, HashMap ColumnAlias SQLExp)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SelectSource
selectSource, HashMap ColumnAlias SQLExp
allExtractors)
  where
    AnnSelectG Fields (AnnFieldG ('Postgres pgKind) Void SQLExp)
annSelFields SelectFromG ('Postgres pgKind) SQLExp
tableFrom TablePermG ('Postgres pgKind) SQLExp
tablePermissions SelectArgsG ('Postgres pgKind) SQLExp
tableArgs StringifyNumbers
_ Maybe NamingCase
tCase = AnnSimpleSelect ('Postgres pgKind)
AnnSelectG
  ('Postgres pgKind) (AnnFieldG ('Postgres pgKind) Void) SQLExp
annSimpleSel
    similarArrayFields :: SimilarArrayFields
similarArrayFields =
      Fields (AnnFieldG ('Postgres pgKind) Void SQLExp)
-> Maybe
     (NonEmpty (AnnotatedOrderByItemG ('Postgres pgKind) SQLExp))
-> SimilarArrayFields
forall (pgKind :: PostgresKind) v.
(Backend ('Postgres pgKind), Eq v) =>
AnnFieldsG ('Postgres pgKind) Void v
-> Maybe (NonEmpty (AnnotatedOrderByItemG ('Postgres pgKind) v))
-> SimilarArrayFields
mkSimilarArrayFields Fields (AnnFieldG ('Postgres pgKind) Void SQLExp)
annSelFields (Maybe (NonEmpty (AnnotatedOrderByItemG ('Postgres pgKind) SQLExp))
 -> SimilarArrayFields)
-> Maybe
     (NonEmpty (AnnotatedOrderByItemG ('Postgres pgKind) SQLExp))
-> SimilarArrayFields
forall a b. (a -> b) -> a -> b
$ SelectArgsG ('Postgres pgKind) SQLExp
-> Maybe
     (NonEmpty (AnnotatedOrderByItemG ('Postgres pgKind) SQLExp))
forall (b :: BackendType) v.
SelectArgsG b v -> Maybe (NonEmpty (AnnotatedOrderByItemG b v))
_saOrderBy SelectArgsG ('Postgres pgKind) SQLExp
tableArgs

processConnectionSelect ::
  forall pgKind m.
  ( MonadReader Options.StringifyNumbers m,
    MonadWriter JoinTree m,
    Backend ('Postgres pgKind),
    PostgresAnnotatedFieldJSON pgKind
  ) =>
  SourcePrefixes ->
  FieldName ->
  S.TableAlias ->
  HM.HashMap PGCol PGCol ->
  ConnectionSelect ('Postgres pgKind) Void S.SQLExp ->
  m
    ( ArrayConnectionSource,
      S.Extractor,
      HM.HashMap S.ColumnAlias S.SQLExp
    )
processConnectionSelect :: SourcePrefixes
-> FieldName
-> TableAlias
-> HashMap PGCol PGCol
-> ConnectionSelect ('Postgres pgKind) Void SQLExp
-> m (ArrayConnectionSource, Extractor, HashMap ColumnAlias SQLExp)
processConnectionSelect SourcePrefixes
sourcePrefixes FieldName
fieldAlias TableAlias
relAlias HashMap PGCol PGCol
colMapping ConnectionSelect ('Postgres pgKind) Void SQLExp
connectionSelect = do
  (SelectSource
selectSource, [(ColumnAlias, SQLExp)]
orderByAndDistinctExtrs, Maybe SQLExp
maybeOrderByCursor) <-
    SourcePrefixes
-> FieldName
-> SimilarArrayFields
-> SelectFrom ('Postgres pgKind)
-> PermissionLimitSubQuery
-> TablePerm ('Postgres pgKind)
-> SelectArgs ('Postgres pgKind)
-> m (SelectSource, [(ColumnAlias, SQLExp)], Maybe SQLExp)
forall (pgKind :: PostgresKind) (m :: * -> *).
(MonadReader StringifyNumbers m, MonadWriter JoinTree m,
 Backend ('Postgres pgKind)) =>
SourcePrefixes
-> FieldName
-> SimilarArrayFields
-> SelectFrom ('Postgres pgKind)
-> PermissionLimitSubQuery
-> TablePerm ('Postgres pgKind)
-> SelectArgs ('Postgres pgKind)
-> m (SelectSource, [(ColumnAlias, SQLExp)], Maybe SQLExp)
processSelectParams
      SourcePrefixes
sourcePrefixes
      FieldName
fieldAlias
      SimilarArrayFields
similarArrayFields
      SelectFrom ('Postgres pgKind)
SelectFromG ('Postgres pgKind) SQLExp
selectFrom
      PermissionLimitSubQuery
permLimitSubQuery
      TablePerm ('Postgres pgKind)
TablePermG ('Postgres pgKind) SQLExp
tablePermissions
      SelectArgs ('Postgres pgKind)
SelectArgsG ('Postgres pgKind) SQLExp
tableArgs

  let mkCursorExtractor :: SQLExp -> (ColumnAlias, SQLExp)
mkCursorExtractor = (Identifier -> ColumnAlias
forall a. IsIdentifier a => a -> ColumnAlias
S.toColumnAlias Identifier
cursorIdentifier,) (SQLExp -> (ColumnAlias, SQLExp))
-> (SQLExp -> SQLExp) -> SQLExp -> (ColumnAlias, SQLExp)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SQLExp -> TypeAnn -> SQLExp
`S.SETyAnn` TypeAnn
S.textTypeAnn)
      cursorExtractors :: [(ColumnAlias, SQLExp)]
cursorExtractors = case Maybe SQLExp
maybeOrderByCursor of
        Just SQLExp
orderByCursor -> [SQLExp -> (ColumnAlias, SQLExp)
mkCursorExtractor SQLExp
orderByCursor]
        Maybe SQLExp
Nothing ->
          -- Extract primary key columns from base select along with cursor expression.
          -- Those columns are required to perform connection split via a WHERE clause.
          SQLExp -> (ColumnAlias, SQLExp)
mkCursorExtractor SQLExp
primaryKeyColumnsObjectExp (ColumnAlias, SQLExp)
-> [(ColumnAlias, SQLExp)] -> [(ColumnAlias, SQLExp)]
forall a. a -> [a] -> [a]
: [(ColumnAlias, SQLExp)]
primaryKeyColumnExtractors
  (SQLExp
topExtractorExp, [(ColumnAlias, SQLExp)]
exps) <- (StateT [(ColumnAlias, SQLExp)] m SQLExp
 -> [(ColumnAlias, SQLExp)] -> m (SQLExp, [(ColumnAlias, SQLExp)]))
-> [(ColumnAlias, SQLExp)]
-> StateT [(ColumnAlias, SQLExp)] m SQLExp
-> m (SQLExp, [(ColumnAlias, SQLExp)])
forall a b c. (a -> b -> c) -> b -> a -> c
flip StateT [(ColumnAlias, SQLExp)] m SQLExp
-> [(ColumnAlias, SQLExp)] -> m (SQLExp, [(ColumnAlias, SQLExp)])
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
runStateT [] (StateT [(ColumnAlias, SQLExp)] m SQLExp
 -> m (SQLExp, [(ColumnAlias, SQLExp)]))
-> StateT [(ColumnAlias, SQLExp)] m SQLExp
-> m (SQLExp, [(ColumnAlias, SQLExp)])
forall a b. (a -> b) -> a -> b
$ SelectSource -> StateT [(ColumnAlias, SQLExp)] m SQLExp
forall (n :: * -> *).
(MonadReader StringifyNumbers n, MonadWriter JoinTree n,
 MonadState [(ColumnAlias, SQLExp)] n) =>
SelectSource -> n SQLExp
processFields SelectSource
selectSource
  let topExtractor :: Extractor
topExtractor = SQLExp -> Maybe ColumnAlias -> Extractor
S.Extractor SQLExp
topExtractorExp (Maybe ColumnAlias -> Extractor) -> Maybe ColumnAlias -> Extractor
forall a b. (a -> b) -> a -> b
$ ColumnAlias -> Maybe ColumnAlias
forall a. a -> Maybe a
Just (ColumnAlias -> Maybe ColumnAlias)
-> ColumnAlias -> Maybe ColumnAlias
forall a b. (a -> b) -> a -> b
$ Identifier -> ColumnAlias
forall a. IsIdentifier a => a -> ColumnAlias
S.toColumnAlias Identifier
fieldIdentifier
      allExtractors :: HashMap ColumnAlias SQLExp
allExtractors = [(ColumnAlias, SQLExp)] -> HashMap ColumnAlias SQLExp
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HM.fromList ([(ColumnAlias, SQLExp)] -> HashMap ColumnAlias SQLExp)
-> [(ColumnAlias, SQLExp)] -> HashMap ColumnAlias SQLExp
forall a b. (a -> b) -> a -> b
$ [(ColumnAlias, SQLExp)]
cursorExtractors [(ColumnAlias, SQLExp)]
-> [(ColumnAlias, SQLExp)] -> [(ColumnAlias, SQLExp)]
forall a. Semigroup a => a -> a -> a
<> [(ColumnAlias, SQLExp)]
exps [(ColumnAlias, SQLExp)]
-> [(ColumnAlias, SQLExp)] -> [(ColumnAlias, SQLExp)]
forall a. Semigroup a => a -> a -> a
<> [(ColumnAlias, SQLExp)]
orderByAndDistinctExtrs
      arrayConnectionSource :: ArrayConnectionSource
arrayConnectionSource =
        TableAlias
-> HashMap PGCol PGCol
-> Maybe BoolExp
-> Maybe ConnectionSlice
-> SelectSource
-> ArrayConnectionSource
ArrayConnectionSource
          TableAlias
relAlias
          HashMap PGCol PGCol
colMapping
          (NonEmpty (ConnectionSplit ('Postgres pgKind) SQLExp) -> BoolExp
mkSplitBoolExp (NonEmpty (ConnectionSplit ('Postgres pgKind) SQLExp) -> BoolExp)
-> Maybe (NonEmpty (ConnectionSplit ('Postgres pgKind) SQLExp))
-> Maybe BoolExp
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (NonEmpty (ConnectionSplit ('Postgres pgKind) SQLExp))
maybeSplit)
          Maybe ConnectionSlice
maybeSlice
          SelectSource
selectSource
  (ArrayConnectionSource, Extractor, HashMap ColumnAlias SQLExp)
-> m (ArrayConnectionSource, Extractor, HashMap ColumnAlias SQLExp)
forall (f :: * -> *) a. Applicative f => a -> f a
pure
    ( ArrayConnectionSource
arrayConnectionSource,
      Extractor
topExtractor,
      HashMap ColumnAlias SQLExp
allExtractors
    )
  where
    ConnectionSelect XRelay ('Postgres pgKind)
_ PrimaryKeyColumns ('Postgres pgKind)
primaryKeyColumns Maybe (NonEmpty (ConnectionSplit ('Postgres pgKind) SQLExp))
maybeSplit Maybe ConnectionSlice
maybeSlice AnnSelectG
  ('Postgres pgKind) (ConnectionField ('Postgres pgKind) Void) SQLExp
select = ConnectionSelect ('Postgres pgKind) Void SQLExp
connectionSelect
    AnnSelectG Fields (ConnectionField ('Postgres pgKind) Void SQLExp)
fields SelectFromG ('Postgres pgKind) SQLExp
selectFrom TablePermG ('Postgres pgKind) SQLExp
tablePermissions SelectArgsG ('Postgres pgKind) SQLExp
tableArgs StringifyNumbers
_ Maybe NamingCase
tCase = AnnSelectG
  ('Postgres pgKind) (ConnectionField ('Postgres pgKind) Void) SQLExp
select
    fieldIdentifier :: Identifier
fieldIdentifier = FieldName -> Identifier
forall a. IsIdentifier a => a -> Identifier
toIdentifier FieldName
fieldAlias
    thisPrefix :: Identifier
thisPrefix = SourcePrefixes -> Identifier
_pfThis SourcePrefixes
sourcePrefixes
    permLimitSubQuery :: PermissionLimitSubQuery
permLimitSubQuery = PermissionLimitSubQuery
PLSQNotRequired

    primaryKeyColumnsObjectExp :: SQLExp
primaryKeyColumnsObjectExp =
      [SQLExp] -> SQLExp
S.applyJsonBuildObj ([SQLExp] -> SQLExp) -> [SQLExp] -> SQLExp
forall a b. (a -> b) -> a -> b
$
        ((ColumnInfo ('Postgres pgKind) -> [SQLExp])
 -> [ColumnInfo ('Postgres pgKind)] -> [SQLExp])
-> [ColumnInfo ('Postgres pgKind)]
-> (ColumnInfo ('Postgres pgKind) -> [SQLExp])
-> [SQLExp]
forall a b c. (a -> b -> c) -> b -> a -> c
flip (ColumnInfo ('Postgres pgKind) -> [SQLExp])
-> [ColumnInfo ('Postgres pgKind)] -> [SQLExp]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (PrimaryKeyColumns ('Postgres pgKind)
-> [ColumnInfo ('Postgres pgKind)]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList PrimaryKeyColumns ('Postgres pgKind)
primaryKeyColumns) ((ColumnInfo ('Postgres pgKind) -> [SQLExp]) -> [SQLExp])
-> (ColumnInfo ('Postgres pgKind) -> [SQLExp]) -> [SQLExp]
forall a b. (a -> b) -> a -> b
$
          \ColumnInfo ('Postgres pgKind)
pgColumnInfo ->
            [ Text -> SQLExp
S.SELit (Text -> SQLExp) -> Text -> SQLExp
forall a b. (a -> b) -> a -> b
$ PGCol -> Text
getPGColTxt (PGCol -> Text) -> PGCol -> Text
forall a b. (a -> b) -> a -> b
$ ColumnInfo ('Postgres pgKind) -> Column ('Postgres pgKind)
forall (b :: BackendType). ColumnInfo b -> Column b
ciColumn ColumnInfo ('Postgres pgKind)
pgColumnInfo,
              StringifyNumbers
-> ColumnType ('Postgres pgKind)
-> Bool
-> Maybe NamingCase
-> SQLExp
-> SQLExp
forall (pgKind :: PostgresKind).
StringifyNumbers
-> ColumnType ('Postgres pgKind)
-> Bool
-> Maybe NamingCase
-> SQLExp
-> SQLExp
toJSONableExp StringifyNumbers
Options.Don'tStringifyNumbers (ColumnInfo ('Postgres pgKind) -> ColumnType ('Postgres pgKind)
forall (b :: BackendType). ColumnInfo b -> ColumnType b
ciType ColumnInfo ('Postgres pgKind)
pgColumnInfo) Bool
False Maybe NamingCase
tCase (SQLExp -> SQLExp) -> SQLExp -> SQLExp
forall a b. (a -> b) -> a -> b
$
                TableAlias -> PGCol -> SQLExp
forall a b. (IsIdentifier a, IsIdentifier b) => a -> b -> SQLExp
S.mkQIdenExp (Identifier -> TableAlias
mkBaseTableAlias Identifier
thisPrefix) (PGCol -> SQLExp) -> PGCol -> SQLExp
forall a b. (a -> b) -> a -> b
$ ColumnInfo ('Postgres pgKind) -> Column ('Postgres pgKind)
forall (b :: BackendType). ColumnInfo b -> Column b
ciColumn ColumnInfo ('Postgres pgKind)
pgColumnInfo
            ]

    primaryKeyColumnExtractors :: [(ColumnAlias, SQLExp)]
primaryKeyColumnExtractors =
      ((ColumnInfo ('Postgres pgKind) -> (ColumnAlias, SQLExp))
 -> [ColumnInfo ('Postgres pgKind)] -> [(ColumnAlias, SQLExp)])
-> [ColumnInfo ('Postgres pgKind)]
-> (ColumnInfo ('Postgres pgKind) -> (ColumnAlias, SQLExp))
-> [(ColumnAlias, SQLExp)]
forall a b c. (a -> b -> c) -> b -> a -> c
flip (ColumnInfo ('Postgres pgKind) -> (ColumnAlias, SQLExp))
-> [ColumnInfo ('Postgres pgKind)] -> [(ColumnAlias, SQLExp)]
forall a b. (a -> b) -> [a] -> [b]
map (PrimaryKeyColumns ('Postgres pgKind)
-> [ColumnInfo ('Postgres pgKind)]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList PrimaryKeyColumns ('Postgres pgKind)
primaryKeyColumns) ((ColumnInfo ('Postgres pgKind) -> (ColumnAlias, SQLExp))
 -> [(ColumnAlias, SQLExp)])
-> (ColumnInfo ('Postgres pgKind) -> (ColumnAlias, SQLExp))
-> [(ColumnAlias, SQLExp)]
forall a b. (a -> b) -> a -> b
$
        \ColumnInfo ('Postgres pgKind)
pgColumnInfo ->
          let pgColumn :: Column ('Postgres pgKind)
pgColumn = ColumnInfo ('Postgres pgKind) -> Column ('Postgres pgKind)
forall (b :: BackendType). ColumnInfo b -> Column b
ciColumn ColumnInfo ('Postgres pgKind)
pgColumnInfo
           in ( Identifier -> PGCol -> ColumnAlias
mkBaseTableColumnAlias Identifier
thisPrefix Column ('Postgres pgKind)
PGCol
pgColumn,
                TableAlias -> PGCol -> SQLExp
forall a b. (IsIdentifier a, IsIdentifier b) => a -> b -> SQLExp
S.mkQIdenExp (Identifier -> TableAlias
mkBaseTableAlias Identifier
thisPrefix) Column ('Postgres pgKind)
PGCol
pgColumn
              )

    mkSplitBoolExp :: NonEmpty (ConnectionSplit ('Postgres pgKind) SQLExp) -> BoolExp
mkSplitBoolExp (ConnectionSplit ('Postgres pgKind) SQLExp
firstSplit NE.:| [ConnectionSplit ('Postgres pgKind) SQLExp]
rest) =
      BinOp -> BoolExp -> BoolExp -> BoolExp
S.BEBin BinOp
S.OrOp (ConnectionSplit ('Postgres pgKind) SQLExp -> BoolExp
mkSplitCompareExp ConnectionSplit ('Postgres pgKind) SQLExp
firstSplit) (BoolExp -> BoolExp) -> BoolExp -> BoolExp
forall a b. (a -> b) -> a -> b
$ ConnectionSplit ('Postgres pgKind) SQLExp
-> [ConnectionSplit ('Postgres pgKind) SQLExp] -> BoolExp
mkBoolExpFromRest ConnectionSplit ('Postgres pgKind) SQLExp
firstSplit [ConnectionSplit ('Postgres pgKind) SQLExp]
rest
      where
        mkBoolExpFromRest :: ConnectionSplit ('Postgres pgKind) SQLExp
-> [ConnectionSplit ('Postgres pgKind) SQLExp] -> BoolExp
mkBoolExpFromRest ConnectionSplit ('Postgres pgKind) SQLExp
previousSplit =
          BinOp -> BoolExp -> BoolExp -> BoolExp
S.BEBin BinOp
S.AndOp (ConnectionSplit ('Postgres pgKind) SQLExp -> BoolExp
mkEqualityCompareExp ConnectionSplit ('Postgres pgKind) SQLExp
previousSplit) (BoolExp -> BoolExp)
-> ([ConnectionSplit ('Postgres pgKind) SQLExp] -> BoolExp)
-> [ConnectionSplit ('Postgres pgKind) SQLExp]
-> BoolExp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. \case
            [] -> Bool -> BoolExp
S.BELit Bool
False
            (ConnectionSplit ('Postgres pgKind) SQLExp
thisSplit : [ConnectionSplit ('Postgres pgKind) SQLExp]
remainingSplit) -> NonEmpty (ConnectionSplit ('Postgres pgKind) SQLExp) -> BoolExp
mkSplitBoolExp (ConnectionSplit ('Postgres pgKind) SQLExp
thisSplit ConnectionSplit ('Postgres pgKind) SQLExp
-> [ConnectionSplit ('Postgres pgKind) SQLExp]
-> NonEmpty (ConnectionSplit ('Postgres pgKind) SQLExp)
forall a. a -> [a] -> NonEmpty a
NE.:| [ConnectionSplit ('Postgres pgKind) SQLExp]
remainingSplit)

        mkSplitCompareExp :: ConnectionSplit ('Postgres pgKind) SQLExp -> BoolExp
mkSplitCompareExp (ConnectionSplit ConnectionSplitKind
kind SQLExp
v (OrderByItemG Maybe (BasicOrderType ('Postgres pgKind))
obTyM AnnotatedOrderByElement ('Postgres pgKind) SQLExp
obCol Maybe (NullsOrderType ('Postgres pgKind))
_)) =
          let obAlias :: ColumnAlias
obAlias = Identifier
-> FieldName
-> SimilarArrayFields
-> AnnotatedOrderByElement ('Postgres pgKind) SQLExp
-> ColumnAlias
forall (pgKind :: PostgresKind) v.
Identifier
-> FieldName
-> SimilarArrayFields
-> AnnotatedOrderByElement ('Postgres pgKind) v
-> ColumnAlias
mkAnnOrderByAlias Identifier
thisPrefix FieldName
fieldAlias SimilarArrayFields
similarArrayFields AnnotatedOrderByElement ('Postgres pgKind) SQLExp
obCol
              obTy :: OrderType
obTy = OrderType -> Maybe OrderType -> OrderType
forall a. a -> Maybe a -> a
fromMaybe OrderType
S.OTAsc Maybe (BasicOrderType ('Postgres pgKind))
Maybe OrderType
obTyM
              compareOp :: CompareOp
compareOp = case (ConnectionSplitKind
kind, OrderType
obTy) of
                (ConnectionSplitKind
CSKAfter, OrderType
S.OTAsc) -> CompareOp
S.SGT
                (ConnectionSplitKind
CSKAfter, OrderType
S.OTDesc) -> CompareOp
S.SLT
                (ConnectionSplitKind
CSKBefore, OrderType
S.OTAsc) -> CompareOp
S.SLT
                (ConnectionSplitKind
CSKBefore, OrderType
S.OTDesc) -> CompareOp
S.SGT
           in CompareOp -> SQLExp -> SQLExp -> BoolExp
S.BECompare CompareOp
compareOp (Identifier -> SQLExp
S.SEIdentifier (Identifier -> SQLExp) -> Identifier -> SQLExp
forall a b. (a -> b) -> a -> b
$ ColumnAlias -> Identifier
forall a. IsIdentifier a => a -> Identifier
toIdentifier ColumnAlias
obAlias) SQLExp
v

        mkEqualityCompareExp :: ConnectionSplit ('Postgres pgKind) SQLExp -> BoolExp
mkEqualityCompareExp (ConnectionSplit ConnectionSplitKind
_ SQLExp
v OrderByItemG
  ('Postgres pgKind)
  (AnnotatedOrderByElement ('Postgres pgKind) SQLExp)
orderByItem) =
          let obAlias :: ColumnAlias
obAlias =
                Identifier
-> FieldName
-> SimilarArrayFields
-> AnnotatedOrderByElement ('Postgres pgKind) SQLExp
-> ColumnAlias
forall (pgKind :: PostgresKind) v.
Identifier
-> FieldName
-> SimilarArrayFields
-> AnnotatedOrderByElement ('Postgres pgKind) v
-> ColumnAlias
mkAnnOrderByAlias Identifier
thisPrefix FieldName
fieldAlias SimilarArrayFields
similarArrayFields (AnnotatedOrderByElement ('Postgres pgKind) SQLExp -> ColumnAlias)
-> AnnotatedOrderByElement ('Postgres pgKind) SQLExp -> ColumnAlias
forall a b. (a -> b) -> a -> b
$
                  OrderByItemG
  ('Postgres pgKind)
  (AnnotatedOrderByElement ('Postgres pgKind) SQLExp)
-> AnnotatedOrderByElement ('Postgres pgKind) SQLExp
forall (b :: BackendType) a. OrderByItemG b a -> a
obiColumn OrderByItemG
  ('Postgres pgKind)
  (AnnotatedOrderByElement ('Postgres pgKind) SQLExp)
orderByItem
           in CompareOp -> SQLExp -> SQLExp -> BoolExp
S.BECompare CompareOp
S.SEQ (Identifier -> SQLExp
S.SEIdentifier (Identifier -> SQLExp) -> Identifier -> SQLExp
forall a b. (a -> b) -> a -> b
$ ColumnAlias -> Identifier
forall a. IsIdentifier a => a -> Identifier
toIdentifier ColumnAlias
obAlias) SQLExp
v

    similarArrayFields :: SimilarArrayFields
similarArrayFields = [SimilarArrayFields] -> SimilarArrayFields
forall k v. (Eq k, Hashable k) => [HashMap k v] -> HashMap k v
HM.unions ([SimilarArrayFields] -> SimilarArrayFields)
-> [SimilarArrayFields] -> SimilarArrayFields
forall a b. (a -> b) -> a -> b
$
      ((ConnectionField ('Postgres pgKind) Void SQLExp
  -> SimilarArrayFields)
 -> [ConnectionField ('Postgres pgKind) Void SQLExp]
 -> [SimilarArrayFields])
-> [ConnectionField ('Postgres pgKind) Void SQLExp]
-> (ConnectionField ('Postgres pgKind) Void SQLExp
    -> SimilarArrayFields)
-> [SimilarArrayFields]
forall a b c. (a -> b -> c) -> b -> a -> c
flip (ConnectionField ('Postgres pgKind) Void SQLExp
 -> SimilarArrayFields)
-> [ConnectionField ('Postgres pgKind) Void SQLExp]
-> [SimilarArrayFields]
forall a b. (a -> b) -> [a] -> [b]
map (((FieldName, ConnectionField ('Postgres pgKind) Void SQLExp)
 -> ConnectionField ('Postgres pgKind) Void SQLExp)
-> Fields (ConnectionField ('Postgres pgKind) Void SQLExp)
-> [ConnectionField ('Postgres pgKind) Void SQLExp]
forall a b. (a -> b) -> [a] -> [b]
map (FieldName, ConnectionField ('Postgres pgKind) Void SQLExp)
-> ConnectionField ('Postgres pgKind) Void SQLExp
forall a b. (a, b) -> b
snd Fields (ConnectionField ('Postgres pgKind) Void SQLExp)
fields) ((ConnectionField ('Postgres pgKind) Void SQLExp
  -> SimilarArrayFields)
 -> [SimilarArrayFields])
-> (ConnectionField ('Postgres pgKind) Void SQLExp
    -> SimilarArrayFields)
-> [SimilarArrayFields]
forall a b. (a -> b) -> a -> b
$ \case
        ConnectionTypename {} -> SimilarArrayFields
forall a. Monoid a => a
mempty
        ConnectionPageInfo {} -> SimilarArrayFields
forall a. Monoid a => a
mempty
        ConnectionEdges EdgeFields ('Postgres pgKind) Void SQLExp
edges -> [SimilarArrayFields] -> SimilarArrayFields
forall k v. (Eq k, Hashable k) => [HashMap k v] -> HashMap k v
HM.unions ([SimilarArrayFields] -> SimilarArrayFields)
-> [SimilarArrayFields] -> SimilarArrayFields
forall a b. (a -> b) -> a -> b
$
          ((EdgeField ('Postgres pgKind) Void SQLExp -> SimilarArrayFields)
 -> [EdgeField ('Postgres pgKind) Void SQLExp]
 -> [SimilarArrayFields])
-> [EdgeField ('Postgres pgKind) Void SQLExp]
-> (EdgeField ('Postgres pgKind) Void SQLExp -> SimilarArrayFields)
-> [SimilarArrayFields]
forall a b c. (a -> b -> c) -> b -> a -> c
flip (EdgeField ('Postgres pgKind) Void SQLExp -> SimilarArrayFields)
-> [EdgeField ('Postgres pgKind) Void SQLExp]
-> [SimilarArrayFields]
forall a b. (a -> b) -> [a] -> [b]
map (((FieldName, EdgeField ('Postgres pgKind) Void SQLExp)
 -> EdgeField ('Postgres pgKind) Void SQLExp)
-> EdgeFields ('Postgres pgKind) Void SQLExp
-> [EdgeField ('Postgres pgKind) Void SQLExp]
forall a b. (a -> b) -> [a] -> [b]
map (FieldName, EdgeField ('Postgres pgKind) Void SQLExp)
-> EdgeField ('Postgres pgKind) Void SQLExp
forall a b. (a, b) -> b
snd EdgeFields ('Postgres pgKind) Void SQLExp
edges) ((EdgeField ('Postgres pgKind) Void SQLExp -> SimilarArrayFields)
 -> [SimilarArrayFields])
-> (EdgeField ('Postgres pgKind) Void SQLExp -> SimilarArrayFields)
-> [SimilarArrayFields]
forall a b. (a -> b) -> a -> b
$ \case
            EdgeTypename {} -> SimilarArrayFields
forall a. Monoid a => a
mempty
            EdgeCursor {} -> SimilarArrayFields
forall a. Monoid a => a
mempty
            EdgeNode AnnFieldsG ('Postgres pgKind) Void SQLExp
annFields ->
              AnnFieldsG ('Postgres pgKind) Void SQLExp
-> Maybe
     (NonEmpty
        (OrderByItemG
           ('Postgres pgKind)
           (AnnotatedOrderByElement ('Postgres pgKind) SQLExp)))
-> SimilarArrayFields
forall (pgKind :: PostgresKind) v.
(Backend ('Postgres pgKind), Eq v) =>
AnnFieldsG ('Postgres pgKind) Void v
-> Maybe (NonEmpty (AnnotatedOrderByItemG ('Postgres pgKind) v))
-> SimilarArrayFields
mkSimilarArrayFields AnnFieldsG ('Postgres pgKind) Void SQLExp
annFields (Maybe
   (NonEmpty
      (OrderByItemG
         ('Postgres pgKind)
         (AnnotatedOrderByElement ('Postgres pgKind) SQLExp)))
 -> SimilarArrayFields)
-> Maybe
     (NonEmpty
        (OrderByItemG
           ('Postgres pgKind)
           (AnnotatedOrderByElement ('Postgres pgKind) SQLExp)))
-> SimilarArrayFields
forall a b. (a -> b) -> a -> b
$ SelectArgsG ('Postgres pgKind) SQLExp
-> Maybe
     (NonEmpty
        (OrderByItemG
           ('Postgres pgKind)
           (AnnotatedOrderByElement ('Postgres pgKind) SQLExp)))
forall (b :: BackendType) v.
SelectArgsG b v -> Maybe (NonEmpty (AnnotatedOrderByItemG b v))
_saOrderBy SelectArgsG ('Postgres pgKind) SQLExp
tableArgs

    mkSimpleJsonAgg :: SQLExp -> Maybe OrderByExp -> SQLExp
mkSimpleJsonAgg SQLExp
rowExp Maybe OrderByExp
ob =
      let jsonAggExp :: SQLExp
jsonAggExp = Text -> [SQLExp] -> Maybe OrderByExp -> SQLExp
S.SEFnApp Text
"json_agg" [SQLExp
rowExp] Maybe OrderByExp
ob
       in Text -> [SQLExp] -> Maybe OrderByExp -> SQLExp
S.SEFnApp Text
"coalesce" [SQLExp
jsonAggExp, Text -> SQLExp
S.SELit Text
"[]"] Maybe OrderByExp
forall a. Maybe a
Nothing

    processFields ::
      forall n.
      ( MonadReader Options.StringifyNumbers n,
        MonadWriter JoinTree n,
        MonadState [(S.ColumnAlias, S.SQLExp)] n
      ) =>
      SelectSource ->
      n S.SQLExp
    processFields :: SelectSource -> n SQLExp
processFields SelectSource
selectSource =
      ([[SQLExp]] -> SQLExp) -> n [[SQLExp]] -> n SQLExp
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([SQLExp] -> SQLExp
S.applyJsonBuildObj ([SQLExp] -> SQLExp)
-> ([[SQLExp]] -> [SQLExp]) -> [[SQLExp]] -> SQLExp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[SQLExp]] -> [SQLExp]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat) (n [[SQLExp]] -> n SQLExp) -> n [[SQLExp]] -> n SQLExp
forall a b. (a -> b) -> a -> b
$
        Fields (ConnectionField ('Postgres pgKind) Void SQLExp)
-> ((FieldName, ConnectionField ('Postgres pgKind) Void SQLExp)
    -> n [SQLExp])
-> n [[SQLExp]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM Fields (ConnectionField ('Postgres pgKind) Void SQLExp)
fields (((FieldName, ConnectionField ('Postgres pgKind) Void SQLExp)
  -> n [SQLExp])
 -> n [[SQLExp]])
-> ((FieldName, ConnectionField ('Postgres pgKind) Void SQLExp)
    -> n [SQLExp])
-> n [[SQLExp]]
forall a b. (a -> b) -> a -> b
$
          \(FieldName Text
fieldText, ConnectionField ('Postgres pgKind) Void SQLExp
field) ->
            (Text -> SQLExp
S.SELit Text
fieldText SQLExp -> [SQLExp] -> [SQLExp]
forall a. a -> [a] -> [a]
:) ([SQLExp] -> [SQLExp])
-> (SQLExp -> [SQLExp]) -> SQLExp -> [SQLExp]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SQLExp -> [SQLExp]
forall (f :: * -> *) a. Applicative f => a -> f a
pure
              (SQLExp -> [SQLExp]) -> n SQLExp -> n [SQLExp]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> case ConnectionField ('Postgres pgKind) Void SQLExp
field of
                ConnectionTypename Text
t -> SQLExp -> n SQLExp
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SQLExp -> n SQLExp) -> SQLExp -> n SQLExp
forall a b. (a -> b) -> a -> b
$ TypeAnn -> SQLExp -> SQLExp
withForceAggregation TypeAnn
S.textTypeAnn (SQLExp -> SQLExp) -> SQLExp -> SQLExp
forall a b. (a -> b) -> a -> b
$ Text -> SQLExp
S.SELit Text
t
                ConnectionPageInfo PageInfoFields
pageInfoFields -> SQLExp -> n SQLExp
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SQLExp -> n SQLExp) -> SQLExp -> n SQLExp
forall a b. (a -> b) -> a -> b
$ PageInfoFields -> SQLExp
forall (t :: * -> *).
Foldable t =>
t (FieldName, PageInfoField) -> SQLExp
processPageInfoFields PageInfoFields
pageInfoFields
                ConnectionEdges EdgeFields ('Postgres pgKind) Void SQLExp
edges ->
                  ([[SQLExp]] -> SQLExp) -> n [[SQLExp]] -> n SQLExp
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((SQLExp -> Maybe OrderByExp -> SQLExp)
-> Maybe OrderByExp -> SQLExp -> SQLExp
forall a b c. (a -> b -> c) -> b -> a -> c
flip SQLExp -> Maybe OrderByExp -> SQLExp
mkSimpleJsonAgg (SelectSource -> Maybe OrderByExp
orderByForJsonAgg SelectSource
selectSource) (SQLExp -> SQLExp)
-> ([[SQLExp]] -> SQLExp) -> [[SQLExp]] -> SQLExp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [SQLExp] -> SQLExp
S.applyJsonBuildObj ([SQLExp] -> SQLExp)
-> ([[SQLExp]] -> [SQLExp]) -> [[SQLExp]] -> SQLExp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[SQLExp]] -> [SQLExp]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat) (n [[SQLExp]] -> n SQLExp) -> n [[SQLExp]] -> n SQLExp
forall a b. (a -> b) -> a -> b
$
                    EdgeFields ('Postgres pgKind) Void SQLExp
-> ((FieldName, EdgeField ('Postgres pgKind) Void SQLExp)
    -> n [SQLExp])
-> n [[SQLExp]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM EdgeFields ('Postgres pgKind) Void SQLExp
edges (((FieldName, EdgeField ('Postgres pgKind) Void SQLExp)
  -> n [SQLExp])
 -> n [[SQLExp]])
-> ((FieldName, EdgeField ('Postgres pgKind) Void SQLExp)
    -> n [SQLExp])
-> n [[SQLExp]]
forall a b. (a -> b) -> a -> b
$
                      \(FieldName Text
edgeText, EdgeField ('Postgres pgKind) Void SQLExp
edge) ->
                        (Text -> SQLExp
S.SELit Text
edgeText SQLExp -> [SQLExp] -> [SQLExp]
forall a. a -> [a] -> [a]
:) ([SQLExp] -> [SQLExp])
-> (SQLExp -> [SQLExp]) -> SQLExp -> [SQLExp]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SQLExp -> [SQLExp]
forall (f :: * -> *) a. Applicative f => a -> f a
pure
                          (SQLExp -> [SQLExp]) -> n SQLExp -> n [SQLExp]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> case EdgeField ('Postgres pgKind) Void SQLExp
edge of
                            EdgeTypename Text
t -> SQLExp -> n SQLExp
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SQLExp -> n SQLExp) -> SQLExp -> n SQLExp
forall a b. (a -> b) -> a -> b
$ Text -> SQLExp
S.SELit Text
t
                            EdgeField ('Postgres pgKind) Void SQLExp
EdgeCursor -> SQLExp -> n SQLExp
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SQLExp -> n SQLExp) -> SQLExp -> n SQLExp
forall a b. (a -> b) -> a -> b
$ SQLExp -> SQLExp
encodeBase64 (SQLExp -> SQLExp) -> SQLExp -> SQLExp
forall a b. (a -> b) -> a -> b
$ Identifier -> SQLExp
S.SEIdentifier (Identifier -> Identifier
forall a. IsIdentifier a => a -> Identifier
toIdentifier Identifier
cursorIdentifier)
                            EdgeNode AnnFieldsG ('Postgres pgKind) Void SQLExp
annFields -> do
                              let edgeFieldName :: FieldName
edgeFieldName =
                                    Text -> FieldName
FieldName (Text -> FieldName) -> Text -> FieldName
forall a b. (a -> b) -> a -> b
$
                                      FieldName -> Text
getFieldNameTxt FieldName
fieldAlias Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"." Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
fieldText Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"." Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
edgeText
                                  edgeFieldIdentifier :: Identifier
edgeFieldIdentifier = FieldName -> Identifier
forall a. IsIdentifier a => a -> Identifier
toIdentifier FieldName
edgeFieldName
                              (ColumnAlias, SQLExp)
annFieldsExtrExp <- Identifier
-> FieldName
-> SimilarArrayFields
-> AnnFields ('Postgres pgKind)
-> Maybe NamingCase
-> n (ColumnAlias, SQLExp)
forall (pgKind :: PostgresKind) (m :: * -> *).
(MonadReader StringifyNumbers m, MonadWriter JoinTree m,
 Backend ('Postgres pgKind), PostgresAnnotatedFieldJSON pgKind) =>
Identifier
-> FieldName
-> SimilarArrayFields
-> AnnFields ('Postgres pgKind)
-> Maybe NamingCase
-> m (ColumnAlias, SQLExp)
processAnnFields Identifier
thisPrefix FieldName
edgeFieldName SimilarArrayFields
similarArrayFields AnnFields ('Postgres pgKind)
AnnFieldsG ('Postgres pgKind) Void SQLExp
annFields Maybe NamingCase
tCase
                              ([(ColumnAlias, SQLExp)] -> [(ColumnAlias, SQLExp)]) -> n ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify' ([(ColumnAlias, SQLExp)]
-> [(ColumnAlias, SQLExp)] -> [(ColumnAlias, SQLExp)]
forall a. Semigroup a => a -> a -> a
<> [(ColumnAlias, SQLExp)
annFieldsExtrExp])
                              SQLExp -> n SQLExp
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SQLExp -> n SQLExp) -> SQLExp -> n SQLExp
forall a b. (a -> b) -> a -> b
$ Identifier -> SQLExp
S.SEIdentifier Identifier
edgeFieldIdentifier

    processPageInfoFields :: t (FieldName, PageInfoField) -> SQLExp
processPageInfoFields t (FieldName, PageInfoField)
infoFields =
      [SQLExp] -> SQLExp
S.applyJsonBuildObj ([SQLExp] -> SQLExp) -> [SQLExp] -> SQLExp
forall a b. (a -> b) -> a -> b
$
        (((FieldName, PageInfoField) -> [SQLExp])
 -> t (FieldName, PageInfoField) -> [SQLExp])
-> t (FieldName, PageInfoField)
-> ((FieldName, PageInfoField) -> [SQLExp])
-> [SQLExp]
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((FieldName, PageInfoField) -> [SQLExp])
-> t (FieldName, PageInfoField) -> [SQLExp]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap t (FieldName, PageInfoField)
infoFields (((FieldName, PageInfoField) -> [SQLExp]) -> [SQLExp])
-> ((FieldName, PageInfoField) -> [SQLExp]) -> [SQLExp]
forall a b. (a -> b) -> a -> b
$
          \(FieldName Text
fieldText, PageInfoField
field) -> (:) (Text -> SQLExp
S.SELit Text
fieldText) ([SQLExp] -> [SQLExp]) -> [SQLExp] -> [SQLExp]
forall a b. (a -> b) -> a -> b
$ SQLExp -> [SQLExp]
forall (f :: * -> *) a. Applicative f => a -> f a
pure case PageInfoField
field of
            PageInfoTypename Text
t -> TypeAnn -> SQLExp -> SQLExp
withForceAggregation TypeAnn
S.textTypeAnn (SQLExp -> SQLExp) -> SQLExp -> SQLExp
forall a b. (a -> b) -> a -> b
$ Text -> SQLExp
S.SELit Text
t
            PageInfoField
PageInfoHasNextPage ->
              TypeAnn -> SQLExp -> SQLExp
withForceAggregation TypeAnn
S.boolTypeAnn (SQLExp -> SQLExp) -> SQLExp -> SQLExp
forall a b. (a -> b) -> a -> b
$
                SQLExp -> Identifier -> SQLExp
mkSingleFieldSelect (Identifier -> SQLExp
S.SEIdentifier Identifier
hasNextPageIdentifier) Identifier
pageInfoSelectAliasIdentifier
            PageInfoField
PageInfoHasPreviousPage ->
              TypeAnn -> SQLExp -> SQLExp
withForceAggregation TypeAnn
S.boolTypeAnn (SQLExp -> SQLExp) -> SQLExp -> SQLExp
forall a b. (a -> b) -> a -> b
$
                SQLExp -> Identifier -> SQLExp
mkSingleFieldSelect (Identifier -> SQLExp
S.SEIdentifier Identifier
hasPreviousPageIdentifier) Identifier
pageInfoSelectAliasIdentifier
            PageInfoField
PageInfoStartCursor ->
              TypeAnn -> SQLExp -> SQLExp
withForceAggregation TypeAnn
S.textTypeAnn (SQLExp -> SQLExp) -> SQLExp -> SQLExp
forall a b. (a -> b) -> a -> b
$
                SQLExp -> SQLExp
encodeBase64 (SQLExp -> SQLExp) -> SQLExp -> SQLExp
forall a b. (a -> b) -> a -> b
$ SQLExp -> Identifier -> SQLExp
mkSingleFieldSelect (Identifier -> SQLExp
S.SEIdentifier Identifier
startCursorIdentifier) Identifier
cursorsSelectAliasIdentifier
            PageInfoField
PageInfoEndCursor ->
              TypeAnn -> SQLExp -> SQLExp
withForceAggregation TypeAnn
S.textTypeAnn (SQLExp -> SQLExp) -> SQLExp -> SQLExp
forall a b. (a -> b) -> a -> b
$
                SQLExp -> SQLExp
encodeBase64 (SQLExp -> SQLExp) -> SQLExp -> SQLExp
forall a b. (a -> b) -> a -> b
$ SQLExp -> Identifier -> SQLExp
mkSingleFieldSelect (Identifier -> SQLExp
S.SEIdentifier Identifier
endCursorIdentifier) Identifier
cursorsSelectAliasIdentifier
      where
        mkSingleFieldSelect :: SQLExp -> Identifier -> SQLExp
mkSingleFieldSelect SQLExp
field Identifier
fromIdentifier =
          Select -> SQLExp
S.SESelect
            Select
S.mkSelect
              { selExtr :: [Extractor]
S.selExtr = [SQLExp -> Maybe ColumnAlias -> Extractor
S.Extractor SQLExp
field Maybe ColumnAlias
forall a. Maybe a
Nothing],
                selFrom :: Maybe FromExp
S.selFrom = FromExp -> Maybe FromExp
forall a. a -> Maybe a
Just (FromExp -> Maybe FromExp) -> FromExp -> Maybe FromExp
forall a b. (a -> b) -> a -> b
$ [FromItem] -> FromExp
S.FromExp [Identifier -> FromItem
S.FIIdentifier Identifier
fromIdentifier]
              }