module Hasura.Backends.DataConnector.Plan.QueryPlan
  ( -- Main external interface
    mkQueryPlan,
    -- Internals reused by other plan modules
    translateAnnSimpleSelectToQueryRequest,
    translateAnnAggregateSelectToQueryRequest,
    translateAnnFields,
    reshapeSimpleSelectRows,
    reshapeTableAggregateFields,
    reshapeAnnFields,
  )
where

--------------------------------------------------------------------------------

import Control.Monad.Trans.Writer.CPS qualified as CPS
import Data.Aeson qualified as J
import Data.Aeson.Encoding qualified as JE
import Data.Bifunctor (Bifunctor (bimap))
import Data.Has (Has)
import Data.HashMap.Strict qualified as HashMap
import Data.List.NonEmpty qualified as NE
import Data.Semigroup (Min (..))
import Data.Set qualified as Set
import Data.Text.Extended (toTxt)
import Hasura.Backends.DataConnector.API qualified as API
import Hasura.Backends.DataConnector.Adapter.Backend
import Hasura.Backends.DataConnector.Adapter.Types
import Hasura.Backends.DataConnector.Plan.Common
import Hasura.Base.Error
import Hasura.Function.Cache qualified as Function
import Hasura.Prelude
import Hasura.RQL.IR.BoolExp
import Hasura.RQL.IR.OrderBy
import Hasura.RQL.IR.Select
import Hasura.RQL.IR.Value
import Hasura.RQL.Types.BackendType
import Hasura.RQL.Types.Column
import Hasura.RQL.Types.Common
import Hasura.Session
import Language.GraphQL.Draft.Syntax qualified as G
import Witch qualified

--------------------------------------------------------------------------------

data FieldsAndAggregates = FieldsAndAggregates
  { FieldsAndAggregates -> Maybe (HashMap FieldName Field)
_faaFields :: Maybe (HashMap FieldName API.Field),
    FieldsAndAggregates -> Maybe (HashMap FieldName Aggregate)
_faaAggregates :: Maybe (HashMap FieldName API.Aggregate)
  }
  deriving stock (Int -> FieldsAndAggregates -> ShowS
[FieldsAndAggregates] -> ShowS
FieldsAndAggregates -> String
(Int -> FieldsAndAggregates -> ShowS)
-> (FieldsAndAggregates -> String)
-> ([FieldsAndAggregates] -> ShowS)
-> Show FieldsAndAggregates
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> FieldsAndAggregates -> ShowS
showsPrec :: Int -> FieldsAndAggregates -> ShowS
$cshow :: FieldsAndAggregates -> String
show :: FieldsAndAggregates -> String
$cshowList :: [FieldsAndAggregates] -> ShowS
showList :: [FieldsAndAggregates] -> ShowS
Show, FieldsAndAggregates -> FieldsAndAggregates -> Bool
(FieldsAndAggregates -> FieldsAndAggregates -> Bool)
-> (FieldsAndAggregates -> FieldsAndAggregates -> Bool)
-> Eq FieldsAndAggregates
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: FieldsAndAggregates -> FieldsAndAggregates -> Bool
== :: FieldsAndAggregates -> FieldsAndAggregates -> Bool
$c/= :: FieldsAndAggregates -> FieldsAndAggregates -> Bool
/= :: FieldsAndAggregates -> FieldsAndAggregates -> Bool
Eq)

instance Semigroup FieldsAndAggregates where
  FieldsAndAggregates
left <> :: FieldsAndAggregates -> FieldsAndAggregates -> FieldsAndAggregates
<> FieldsAndAggregates
right =
    Maybe (HashMap FieldName Field)
-> Maybe (HashMap FieldName Aggregate) -> FieldsAndAggregates
FieldsAndAggregates
      (FieldsAndAggregates -> Maybe (HashMap FieldName Field)
_faaFields FieldsAndAggregates
left Maybe (HashMap FieldName Field)
-> Maybe (HashMap FieldName Field)
-> Maybe (HashMap FieldName Field)
forall a. Semigroup a => a -> a -> a
<> FieldsAndAggregates -> Maybe (HashMap FieldName Field)
_faaFields FieldsAndAggregates
right)
      (FieldsAndAggregates -> Maybe (HashMap FieldName Aggregate)
_faaAggregates FieldsAndAggregates
left Maybe (HashMap FieldName Aggregate)
-> Maybe (HashMap FieldName Aggregate)
-> Maybe (HashMap FieldName Aggregate)
forall a. Semigroup a => a -> a -> a
<> FieldsAndAggregates -> Maybe (HashMap FieldName Aggregate)
_faaAggregates FieldsAndAggregates
right)

instance Monoid FieldsAndAggregates where
  mempty :: FieldsAndAggregates
mempty = Maybe (HashMap FieldName Field)
-> Maybe (HashMap FieldName Aggregate) -> FieldsAndAggregates
FieldsAndAggregates Maybe (HashMap FieldName Field)
forall a. Maybe a
Nothing Maybe (HashMap FieldName Aggregate)
forall a. Maybe a
Nothing

--------------------------------------------------------------------------------

-- | Map a 'QueryDB 'DataConnector' term into a 'Plan'
mkQueryPlan ::
  forall m r.
  (MonadError QErr m, MonadReader r m, Has API.ScalarTypesCapabilities r) =>
  SessionVariables ->
  QueryDB 'DataConnector Void (UnpreparedValue 'DataConnector) ->
  m (Plan API.QueryRequest API.QueryResponse)
mkQueryPlan :: forall (m :: * -> *) r.
(MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> QueryDB 'DataConnector Void (UnpreparedValue 'DataConnector)
-> m (Plan QueryRequest QueryResponse)
mkQueryPlan SessionVariables
sessionVariables QueryDB 'DataConnector Void (UnpreparedValue 'DataConnector)
ir = do
  QueryRequest
queryRequest <- QueryDB 'DataConnector Void (UnpreparedValue 'DataConnector)
-> m QueryRequest
translateQueryDB QueryDB 'DataConnector Void (UnpreparedValue 'DataConnector)
ir
  Plan QueryRequest QueryResponse
-> m (Plan QueryRequest QueryResponse)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Plan QueryRequest QueryResponse
 -> m (Plan QueryRequest QueryResponse))
-> Plan QueryRequest QueryResponse
-> m (Plan QueryRequest QueryResponse)
forall a b. (a -> b) -> a -> b
$ QueryRequest
-> (forall (m :: * -> *).
    MonadError QErr m =>
    QueryResponse -> m Encoding)
-> Plan QueryRequest QueryResponse
forall request response.
request
-> (forall (m :: * -> *).
    MonadError QErr m =>
    response -> m Encoding)
-> Plan request response
Plan QueryRequest
queryRequest (QueryDB 'DataConnector Void (UnpreparedValue 'DataConnector)
-> QueryResponse -> m Encoding
forall (m :: * -> *) v.
MonadError QErr m =>
QueryDB 'DataConnector Void v -> QueryResponse -> m Encoding
reshapeResponseToQueryShape QueryDB 'DataConnector Void (UnpreparedValue 'DataConnector)
ir)
  where
    translateQueryDB ::
      QueryDB 'DataConnector Void (UnpreparedValue 'DataConnector) ->
      m API.QueryRequest
    translateQueryDB :: QueryDB 'DataConnector Void (UnpreparedValue 'DataConnector)
-> m QueryRequest
translateQueryDB =
      \case
        QDBMultipleRows AnnSimpleSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
simpleSelect -> SessionVariables
-> AnnSimpleSelectG
     'DataConnector Void (UnpreparedValue 'DataConnector)
-> m QueryRequest
forall (m :: * -> *) r.
(MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> AnnSimpleSelectG
     'DataConnector Void (UnpreparedValue 'DataConnector)
-> m QueryRequest
translateAnnSimpleSelectToQueryRequest SessionVariables
sessionVariables AnnSimpleSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
simpleSelect
        QDBSingleRow AnnSimpleSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
simpleSelect -> SessionVariables
-> AnnSimpleSelectG
     'DataConnector Void (UnpreparedValue 'DataConnector)
-> m QueryRequest
forall (m :: * -> *) r.
(MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> AnnSimpleSelectG
     'DataConnector Void (UnpreparedValue 'DataConnector)
-> m QueryRequest
translateAnnSimpleSelectToQueryRequest SessionVariables
sessionVariables AnnSimpleSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
simpleSelect
        QDBAggregation AnnAggregateSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
aggregateSelect -> SessionVariables
-> AnnAggregateSelectG
     'DataConnector Void (UnpreparedValue 'DataConnector)
-> m QueryRequest
forall (m :: * -> *) r.
(MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> AnnAggregateSelectG
     'DataConnector Void (UnpreparedValue 'DataConnector)
-> m QueryRequest
translateAnnAggregateSelectToQueryRequest SessionVariables
sessionVariables AnnAggregateSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
aggregateSelect

translateAnnSimpleSelectToQueryRequest ::
  forall m r.
  (MonadError QErr m, MonadReader r m, Has API.ScalarTypesCapabilities r) =>
  SessionVariables ->
  AnnSimpleSelectG 'DataConnector Void (UnpreparedValue 'DataConnector) ->
  m API.QueryRequest
translateAnnSimpleSelectToQueryRequest :: forall (m :: * -> *) r.
(MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> AnnSimpleSelectG
     'DataConnector Void (UnpreparedValue 'DataConnector)
-> m QueryRequest
translateAnnSimpleSelectToQueryRequest SessionVariables
sessionVariables AnnSimpleSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
simpleSelect =
  SessionVariables
-> (TableRelationshipsKey
    -> Fields
         (AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
    -> WriterT TableRelationships m FieldsAndAggregates)
-> AnnSimpleSelectG
     'DataConnector Void (UnpreparedValue 'DataConnector)
-> m QueryRequest
forall (m :: * -> *) r (fieldType :: * -> *).
(MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> (TableRelationshipsKey
    -> Fields (fieldType (UnpreparedValue 'DataConnector))
    -> WriterT TableRelationships m FieldsAndAggregates)
-> AnnSelectG
     'DataConnector fieldType (UnpreparedValue 'DataConnector)
-> m QueryRequest
translateAnnSelectToQueryRequest SessionVariables
sessionVariables (SessionVariables
-> FieldPrefix
-> TableRelationshipsKey
-> Fields
     (AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
-> WriterT TableRelationships m FieldsAndAggregates
forall writerOutput (m :: * -> *) r.
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> FieldPrefix
-> TableRelationshipsKey
-> Fields
     (AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m FieldsAndAggregates
translateAnnFieldsWithNoAggregates SessionVariables
sessionVariables FieldPrefix
noPrefix) AnnSimpleSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
simpleSelect

translateAnnAggregateSelectToQueryRequest ::
  forall m r.
  (MonadError QErr m, MonadReader r m, Has API.ScalarTypesCapabilities r) =>
  SessionVariables ->
  AnnAggregateSelectG 'DataConnector Void (UnpreparedValue 'DataConnector) ->
  m API.QueryRequest
translateAnnAggregateSelectToQueryRequest :: forall (m :: * -> *) r.
(MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> AnnAggregateSelectG
     'DataConnector Void (UnpreparedValue 'DataConnector)
-> m QueryRequest
translateAnnAggregateSelectToQueryRequest SessionVariables
sessionVariables AnnAggregateSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
aggregateSelect =
  SessionVariables
-> (TableRelationshipsKey
    -> Fields
         (TableAggregateFieldG
            'DataConnector Void (UnpreparedValue 'DataConnector))
    -> WriterT TableRelationships m FieldsAndAggregates)
-> AnnAggregateSelectG
     'DataConnector Void (UnpreparedValue 'DataConnector)
-> m QueryRequest
forall (m :: * -> *) r (fieldType :: * -> *).
(MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> (TableRelationshipsKey
    -> Fields (fieldType (UnpreparedValue 'DataConnector))
    -> WriterT TableRelationships m FieldsAndAggregates)
-> AnnSelectG
     'DataConnector fieldType (UnpreparedValue 'DataConnector)
-> m QueryRequest
translateAnnSelectToQueryRequest SessionVariables
sessionVariables (SessionVariables
-> TableRelationshipsKey
-> Fields
     (TableAggregateFieldG
        'DataConnector Void (UnpreparedValue 'DataConnector))
-> WriterT TableRelationships m FieldsAndAggregates
forall writerOutput (m :: * -> *) r.
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> TableRelationshipsKey
-> Fields
     (TableAggregateFieldG
        'DataConnector Void (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m FieldsAndAggregates
translateTableAggregateFields SessionVariables
sessionVariables) AnnAggregateSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
aggregateSelect

translateAnnSelectToQueryRequest ::
  forall m r fieldType.
  (MonadError QErr m, MonadReader r m, Has API.ScalarTypesCapabilities r) =>
  SessionVariables ->
  (TableRelationshipsKey -> Fields (fieldType (UnpreparedValue 'DataConnector)) -> CPS.WriterT TableRelationships m FieldsAndAggregates) ->
  AnnSelectG 'DataConnector fieldType (UnpreparedValue 'DataConnector) ->
  m API.QueryRequest
translateAnnSelectToQueryRequest :: forall (m :: * -> *) r (fieldType :: * -> *).
(MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> (TableRelationshipsKey
    -> Fields (fieldType (UnpreparedValue 'DataConnector))
    -> WriterT TableRelationships m FieldsAndAggregates)
-> AnnSelectG
     'DataConnector fieldType (UnpreparedValue 'DataConnector)
-> m QueryRequest
translateAnnSelectToQueryRequest SessionVariables
sessionVariables TableRelationshipsKey
-> Fields (fieldType (UnpreparedValue 'DataConnector))
-> WriterT TableRelationships m FieldsAndAggregates
translateFieldsAndAggregates AnnSelectG
  'DataConnector fieldType (UnpreparedValue 'DataConnector)
selectG = do
  case AnnSelectG
  'DataConnector fieldType (UnpreparedValue 'DataConnector)
-> SelectFromG 'DataConnector (UnpreparedValue 'DataConnector)
forall (b :: BackendType) (f :: * -> *) v.
AnnSelectG b f v -> SelectFromG b v
_asnFrom AnnSelectG
  'DataConnector fieldType (UnpreparedValue 'DataConnector)
selectG of
    FromIdentifier FIIdentifier
_ -> Code -> Text -> m QueryRequest
forall (m :: * -> *) a. QErrM m => Code -> Text -> m a
throw400 Code
NotSupported Text
"AnnSelectG: FromIdentifier not supported"
    FromNativeQuery {} -> Code -> Text -> m QueryRequest
forall (m :: * -> *) a. QErrM m => Code -> Text -> m a
throw400 Code
NotSupported Text
"AnnSelectG: FromNativeQuery not supported"
    FromStoredProcedure {} -> Code -> Text -> m QueryRequest
forall (m :: * -> *) a. QErrM m => Code -> Text -> m a
throw400 Code
NotSupported Text
"AnnSelectG: FromStoredProcedure not supported"
    FromTable TableName 'DataConnector
tableName -> do
      (Query
query, TableRelationships HashMap
  TableRelationshipsKey (HashMap RelationshipName Relationship)
tableRelationships) <-
        WriterT TableRelationships m Query -> m (Query, TableRelationships)
forall w (m :: * -> *) a. Monoid w => WriterT w m a -> m (a, w)
CPS.runWriterT (SessionVariables
-> (TableRelationshipsKey
    -> Fields (fieldType (UnpreparedValue 'DataConnector))
    -> WriterT TableRelationships m FieldsAndAggregates)
-> TableRelationshipsKey
-> AnnSelectG
     'DataConnector fieldType (UnpreparedValue 'DataConnector)
-> WriterT TableRelationships m Query
forall writerOutput (m :: * -> *) r (fieldType :: * -> *).
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> (TableRelationshipsKey
    -> Fields (fieldType (UnpreparedValue 'DataConnector))
    -> WriterT writerOutput m FieldsAndAggregates)
-> TableRelationshipsKey
-> AnnSelectG
     'DataConnector fieldType (UnpreparedValue 'DataConnector)
-> WriterT writerOutput m Query
translateAnnSelect SessionVariables
sessionVariables TableRelationshipsKey
-> Fields (fieldType (UnpreparedValue 'DataConnector))
-> WriterT TableRelationships m FieldsAndAggregates
translateFieldsAndAggregates (TableName -> TableRelationshipsKey
TableNameKey (TableName -> TableName
forall target source. From source target => source -> target
Witch.into TableName 'DataConnector
TableName
tableName)) AnnSelectG
  'DataConnector fieldType (UnpreparedValue 'DataConnector)
selectG)
      let relationships :: [Relationships]
relationships = (TableRelationshipsKey, HashMap RelationshipName Relationship)
-> Relationships
mkRelationships ((TableRelationshipsKey, HashMap RelationshipName Relationship)
 -> Relationships)
-> [(TableRelationshipsKey, HashMap RelationshipName Relationship)]
-> [Relationships]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> HashMap
  TableRelationshipsKey (HashMap RelationshipName Relationship)
-> [(TableRelationshipsKey, HashMap RelationshipName Relationship)]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList HashMap
  TableRelationshipsKey (HashMap RelationshipName Relationship)
tableRelationships
      QueryRequest -> m QueryRequest
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
        (QueryRequest -> m QueryRequest) -> QueryRequest -> m QueryRequest
forall a b. (a -> b) -> a -> b
$ TableRequest -> QueryRequest
API.QRTable
          API.TableRequest
            { _trTable :: TableName
_trTable = TableName -> TableName
forall target source. From source target => source -> target
Witch.into TableName 'DataConnector
TableName
tableName,
              _trRelationships :: Set Relationships
_trRelationships = [Relationships] -> Set Relationships
forall a. Ord a => [a] -> Set a
Set.fromList [Relationships]
relationships,
              _trQuery :: Query
_trQuery = Query
query,
              _trForeach :: Maybe (NonEmpty (HashMap ColumnName ScalarValue))
_trForeach = Maybe (NonEmpty (HashMap ColumnName ScalarValue))
forall a. Maybe a
Nothing
            }
    FromFunction fn :: FunctionName 'DataConnector
fn@(FunctionName NonEmpty Text
functionName) FunctionArgsExp 'DataConnector (UnpreparedValue 'DataConnector)
argsExp Maybe [(Column 'DataConnector, ScalarType 'DataConnector)]
_dListM -> do
      [FunctionArgument]
args <- SessionVariables
-> FunctionArgsExpG (ArgumentExp (UnpreparedValue 'DataConnector))
-> FunctionName
-> m [FunctionArgument]
forall (m :: * -> *).
MonadError QErr m =>
SessionVariables
-> FunctionArgsExpG (ArgumentExp (UnpreparedValue 'DataConnector))
-> FunctionName
-> m [FunctionArgument]
mkArgs SessionVariables
sessionVariables FunctionArgsExp 'DataConnector (UnpreparedValue 'DataConnector)
FunctionArgsExpG (ArgumentExp (UnpreparedValue 'DataConnector))
argsExp FunctionName 'DataConnector
FunctionName
fn
      (Query
query, TableRelationships HashMap
  TableRelationshipsKey (HashMap RelationshipName Relationship)
tableRelationships) <-
        WriterT TableRelationships m Query -> m (Query, TableRelationships)
forall w (m :: * -> *) a. Monoid w => WriterT w m a -> m (a, w)
CPS.runWriterT (SessionVariables
-> (TableRelationshipsKey
    -> Fields (fieldType (UnpreparedValue 'DataConnector))
    -> WriterT TableRelationships m FieldsAndAggregates)
-> TableRelationshipsKey
-> AnnSelectG
     'DataConnector fieldType (UnpreparedValue 'DataConnector)
-> WriterT TableRelationships m Query
forall writerOutput (m :: * -> *) r (fieldType :: * -> *).
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> (TableRelationshipsKey
    -> Fields (fieldType (UnpreparedValue 'DataConnector))
    -> WriterT writerOutput m FieldsAndAggregates)
-> TableRelationshipsKey
-> AnnSelectG
     'DataConnector fieldType (UnpreparedValue 'DataConnector)
-> WriterT writerOutput m Query
translateAnnSelect SessionVariables
sessionVariables TableRelationshipsKey
-> Fields (fieldType (UnpreparedValue 'DataConnector))
-> WriterT TableRelationships m FieldsAndAggregates
translateFieldsAndAggregates (FunctionName -> TableRelationshipsKey
FunctionNameKey (NonEmpty Text -> FunctionName
forall target source. From source target => source -> target
Witch.into NonEmpty Text
functionName)) AnnSelectG
  'DataConnector fieldType (UnpreparedValue 'DataConnector)
selectG)
      let relationships :: [Relationships]
relationships = (TableRelationshipsKey, HashMap RelationshipName Relationship)
-> Relationships
mkRelationships ((TableRelationshipsKey, HashMap RelationshipName Relationship)
 -> Relationships)
-> [(TableRelationshipsKey, HashMap RelationshipName Relationship)]
-> [Relationships]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> HashMap
  TableRelationshipsKey (HashMap RelationshipName Relationship)
-> [(TableRelationshipsKey, HashMap RelationshipName Relationship)]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList HashMap
  TableRelationshipsKey (HashMap RelationshipName Relationship)
tableRelationships
      QueryRequest -> m QueryRequest
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
        (QueryRequest -> m QueryRequest) -> QueryRequest -> m QueryRequest
forall a b. (a -> b) -> a -> b
$ FunctionRequest -> QueryRequest
API.QRFunction
          API.FunctionRequest
            { _frFunction :: FunctionName
_frFunction = NonEmpty Text -> FunctionName
forall target source. From source target => source -> target
Witch.into NonEmpty Text
functionName,
              _frRelationships :: Set Relationships
_frRelationships = [Relationships] -> Set Relationships
forall a. Ord a => [a] -> Set a
Set.fromList [Relationships]
relationships,
              _frQuery :: Query
_frQuery = Query
query,
              _frFunctionArguments :: [FunctionArgument]
_frFunctionArguments = [FunctionArgument]
args
            }

mkRelationships :: (TableRelationshipsKey, (HashMap API.RelationshipName API.Relationship)) -> API.Relationships
mkRelationships :: (TableRelationshipsKey, HashMap RelationshipName Relationship)
-> Relationships
mkRelationships (FunctionNameKey FunctionName
functionName, HashMap RelationshipName Relationship
relationships) = FunctionRelationships -> Relationships
API.RFunction (FunctionName
-> HashMap RelationshipName Relationship -> FunctionRelationships
API.FunctionRelationships FunctionName
functionName HashMap RelationshipName Relationship
relationships)
mkRelationships (TableNameKey TableName
tableName, HashMap RelationshipName Relationship
relationships) = TableRelationships -> Relationships
API.RTable (TableName
-> HashMap RelationshipName Relationship -> TableRelationships
API.TableRelationships TableName
tableName HashMap RelationshipName Relationship
relationships)

mkArgs ::
  ( MonadError QErr m
  ) =>
  SessionVariables ->
  Function.FunctionArgsExpG (ArgumentExp (UnpreparedValue 'DataConnector)) ->
  FunctionName ->
  m [API.FunctionArgument]
mkArgs :: forall (m :: * -> *).
MonadError QErr m =>
SessionVariables
-> FunctionArgsExpG (ArgumentExp (UnpreparedValue 'DataConnector))
-> FunctionName
-> m [FunctionArgument]
mkArgs SessionVariables
sessionVariables (Function.FunctionArgsExp [ArgumentExp (UnpreparedValue 'DataConnector)]
ps HashMap Text (ArgumentExp (UnpreparedValue 'DataConnector))
ns) FunctionName
functionName = do
  Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ([ArgumentExp (UnpreparedValue 'DataConnector)] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [ArgumentExp (UnpreparedValue 'DataConnector)]
ps) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ Code -> Text -> m ()
forall (m :: * -> *) a. QErrM m => Code -> Text -> m a
throw400 Code
NotSupported (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ Text
"Positional arguments not supported in function " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> FunctionName -> Text
forall a. ToTxt a => a -> Text
toTxt FunctionName
functionName
  m [FunctionArgument]
getNamed
  where
    getNamed :: m [FunctionArgument]
getNamed = ((Text, ArgumentExp (UnpreparedValue 'DataConnector))
 -> m FunctionArgument)
-> [(Text, ArgumentExp (UnpreparedValue 'DataConnector))]
-> m [FunctionArgument]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (Text, ArgumentExp (UnpreparedValue 'DataConnector))
-> m FunctionArgument
mkArg (HashMap Text (ArgumentExp (UnpreparedValue 'DataConnector))
-> [(Text, ArgumentExp (UnpreparedValue 'DataConnector))]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList HashMap Text (ArgumentExp (UnpreparedValue 'DataConnector))
ns)
    mkArg :: (Text, ArgumentExp (UnpreparedValue 'DataConnector))
-> m FunctionArgument
mkArg (Text
n, ArgumentExp (UnpreparedValue 'DataConnector)
input) = (Text -> ArgumentValue -> FunctionArgument
API.NamedArgument Text
n (ArgumentValue -> FunctionArgument)
-> (ScalarValue -> ArgumentValue)
-> ScalarValue
-> FunctionArgument
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScalarValue -> ArgumentValue
API.ScalarArgumentValue) (ScalarValue -> FunctionArgument)
-> m ScalarValue -> m FunctionArgument
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ArgumentExp (UnpreparedValue 'DataConnector) -> m ScalarValue
getValue ArgumentExp (UnpreparedValue 'DataConnector)
input

    getValue :: ArgumentExp (UnpreparedValue 'DataConnector) -> m ScalarValue
getValue (AEInput UnpreparedValue 'DataConnector
x) = case UnpreparedValue 'DataConnector
x of
      UVLiteral SQLExpression 'DataConnector
_ -> Code -> Text -> m ScalarValue
forall (m :: * -> *) a. QErrM m => Code -> Text -> m a
throw400 Code
NotSupported Text
"Literal not supported in Data Connector function args."
      UVSessionVar SessionVarType 'DataConnector
_ SessionVariable
_ -> Code -> Text -> m ScalarValue
forall (m :: * -> *) a. QErrM m => Code -> Text -> m a
throw400 Code
NotSupported Text
"SessionVar not supported in Data Connector function args."
      UVParameter Provenance
_ (ColumnValue ColumnType 'DataConnector
t ScalarValue 'DataConnector
v) -> ScalarValue -> m ScalarValue
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Value -> ScalarType -> ScalarValue
API.ScalarValue Value
ScalarValue 'DataConnector
v (Text -> ScalarType
forall a b. Coercible a b => a -> b
coerce (ColumnType 'DataConnector -> Text
forall a. ToTxt a => a -> Text
toTxt ColumnType 'DataConnector
t)))
      UnpreparedValue 'DataConnector
UVSession -> ScalarValue -> m ScalarValue
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Value -> ScalarType -> ScalarValue
API.ScalarValue (SessionVariables -> Value
forall a. ToJSON a => a -> Value
J.toJSON SessionVariables
sessionVariables) (Text -> ScalarType
API.ScalarType Text
"json"))

translateAnnSelect ::
  ( Has TableRelationships writerOutput,
    Monoid writerOutput,
    MonadError QErr m,
    MonadReader r m,
    Has API.ScalarTypesCapabilities r
  ) =>
  SessionVariables ->
  (TableRelationshipsKey -> Fields (fieldType (UnpreparedValue 'DataConnector)) -> CPS.WriterT writerOutput m FieldsAndAggregates) ->
  TableRelationshipsKey ->
  AnnSelectG 'DataConnector fieldType (UnpreparedValue 'DataConnector) ->
  CPS.WriterT writerOutput m API.Query
translateAnnSelect :: forall writerOutput (m :: * -> *) r (fieldType :: * -> *).
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> (TableRelationshipsKey
    -> Fields (fieldType (UnpreparedValue 'DataConnector))
    -> WriterT writerOutput m FieldsAndAggregates)
-> TableRelationshipsKey
-> AnnSelectG
     'DataConnector fieldType (UnpreparedValue 'DataConnector)
-> WriterT writerOutput m Query
translateAnnSelect SessionVariables
sessionVariables TableRelationshipsKey
-> Fields (fieldType (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m FieldsAndAggregates
translateFieldsAndAggregates TableRelationshipsKey
entityName AnnSelectG
  'DataConnector fieldType (UnpreparedValue 'DataConnector)
selectG = do
  FieldsAndAggregates {Maybe (HashMap FieldName Aggregate)
Maybe (HashMap FieldName Field)
_faaFields :: FieldsAndAggregates -> Maybe (HashMap FieldName Field)
_faaAggregates :: FieldsAndAggregates -> Maybe (HashMap FieldName Aggregate)
_faaFields :: Maybe (HashMap FieldName Field)
_faaAggregates :: Maybe (HashMap FieldName Aggregate)
..} <- TableRelationshipsKey
-> Fields (fieldType (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m FieldsAndAggregates
translateFieldsAndAggregates TableRelationshipsKey
entityName (AnnSelectG
  'DataConnector fieldType (UnpreparedValue 'DataConnector)
-> Fields (fieldType (UnpreparedValue 'DataConnector))
forall (b :: BackendType) (f :: * -> *) v.
AnnSelectG b f v -> Fields (f v)
_asnFields AnnSelectG
  'DataConnector fieldType (UnpreparedValue 'DataConnector)
selectG)
  let whereClauseWithPermissions :: GBoolExp
  'DataConnector
  (AnnBoolExpFld 'DataConnector (UnpreparedValue 'DataConnector))
whereClauseWithPermissions =
        case SelectArgsG 'DataConnector (UnpreparedValue 'DataConnector)
-> Maybe
     (GBoolExp
        'DataConnector
        (AnnBoolExpFld 'DataConnector (UnpreparedValue 'DataConnector)))
forall (b :: BackendType) v.
SelectArgsG b v -> Maybe (AnnBoolExp b v)
_saWhere (AnnSelectG
  'DataConnector fieldType (UnpreparedValue 'DataConnector)
-> SelectArgsG 'DataConnector (UnpreparedValue 'DataConnector)
forall (b :: BackendType) (f :: * -> *) v.
AnnSelectG b f v -> SelectArgsG b v
_asnArgs AnnSelectG
  'DataConnector fieldType (UnpreparedValue 'DataConnector)
selectG) of
          Just GBoolExp
  'DataConnector
  (AnnBoolExpFld 'DataConnector (UnpreparedValue 'DataConnector))
expr -> [GBoolExp
   'DataConnector
   (AnnBoolExpFld 'DataConnector (UnpreparedValue 'DataConnector))]
-> GBoolExp
     'DataConnector
     (AnnBoolExpFld 'DataConnector (UnpreparedValue 'DataConnector))
forall (backend :: BackendType) field.
[GBoolExp backend field] -> GBoolExp backend field
BoolAnd [GBoolExp
  'DataConnector
  (AnnBoolExpFld 'DataConnector (UnpreparedValue 'DataConnector))
expr, TablePermG 'DataConnector (UnpreparedValue 'DataConnector)
-> GBoolExp
     'DataConnector
     (AnnBoolExpFld 'DataConnector (UnpreparedValue 'DataConnector))
forall (b :: BackendType) v. TablePermG b v -> AnnBoolExp b v
_tpFilter (AnnSelectG
  'DataConnector fieldType (UnpreparedValue 'DataConnector)
-> TablePermG 'DataConnector (UnpreparedValue 'DataConnector)
forall (b :: BackendType) (f :: * -> *) v.
AnnSelectG b f v -> TablePermG b v
_asnPerm AnnSelectG
  'DataConnector fieldType (UnpreparedValue 'DataConnector)
selectG)]
          Maybe
  (GBoolExp
     'DataConnector
     (AnnBoolExpFld 'DataConnector (UnpreparedValue 'DataConnector)))
Nothing -> TablePermG 'DataConnector (UnpreparedValue 'DataConnector)
-> GBoolExp
     'DataConnector
     (AnnBoolExpFld 'DataConnector (UnpreparedValue 'DataConnector))
forall (b :: BackendType) v. TablePermG b v -> AnnBoolExp b v
_tpFilter (AnnSelectG
  'DataConnector fieldType (UnpreparedValue 'DataConnector)
-> TablePermG 'DataConnector (UnpreparedValue 'DataConnector)
forall (b :: BackendType) (f :: * -> *) v.
AnnSelectG b f v -> TablePermG b v
_asnPerm AnnSelectG
  'DataConnector fieldType (UnpreparedValue 'DataConnector)
selectG)
  Maybe Expression
whereClause <- SessionVariables
-> TableRelationshipsKey
-> GBoolExp
     'DataConnector
     (AnnBoolExpFld 'DataConnector (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m (Maybe Expression)
forall writerOutput (m :: * -> *) r.
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> TableRelationshipsKey
-> GBoolExp
     'DataConnector
     (AnnBoolExpFld 'DataConnector (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m (Maybe Expression)
translateBoolExpToExpression SessionVariables
sessionVariables TableRelationshipsKey
entityName GBoolExp
  'DataConnector
  (AnnBoolExpFld 'DataConnector (UnpreparedValue 'DataConnector))
whereClauseWithPermissions
  Maybe OrderBy
orderBy <- (NonEmpty
   (AnnotatedOrderByItemG
      'DataConnector (UnpreparedValue 'DataConnector))
 -> WriterT writerOutput m OrderBy)
-> Maybe
     (NonEmpty
        (AnnotatedOrderByItemG
           'DataConnector (UnpreparedValue 'DataConnector)))
-> WriterT writerOutput m (Maybe OrderBy)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Maybe a -> f (Maybe b)
traverse (SessionVariables
-> TableRelationshipsKey
-> NonEmpty
     (AnnotatedOrderByItemG
        'DataConnector (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m OrderBy
forall writerOutput (m :: * -> *) r.
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> TableRelationshipsKey
-> NonEmpty
     (AnnotatedOrderByItemG
        'DataConnector (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m OrderBy
translateOrderBy SessionVariables
sessionVariables TableRelationshipsKey
entityName) (SelectArgsG 'DataConnector (UnpreparedValue 'DataConnector)
-> Maybe
     (NonEmpty
        (AnnotatedOrderByItemG
           'DataConnector (UnpreparedValue 'DataConnector)))
forall (b :: BackendType) v.
SelectArgsG b v -> Maybe (NonEmpty (AnnotatedOrderByItemG b v))
_saOrderBy (SelectArgsG 'DataConnector (UnpreparedValue 'DataConnector)
 -> Maybe
      (NonEmpty
         (AnnotatedOrderByItemG
            'DataConnector (UnpreparedValue 'DataConnector))))
-> SelectArgsG 'DataConnector (UnpreparedValue 'DataConnector)
-> Maybe
     (NonEmpty
        (AnnotatedOrderByItemG
           'DataConnector (UnpreparedValue 'DataConnector)))
forall a b. (a -> b) -> a -> b
$ AnnSelectG
  'DataConnector fieldType (UnpreparedValue 'DataConnector)
-> SelectArgsG 'DataConnector (UnpreparedValue 'DataConnector)
forall (b :: BackendType) (f :: * -> *) v.
AnnSelectG b f v -> SelectArgsG b v
_asnArgs AnnSelectG
  'DataConnector fieldType (UnpreparedValue 'DataConnector)
selectG)
  Query -> WriterT writerOutput m Query
forall a. a -> WriterT writerOutput m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
    API.Query
      { _qFields :: Maybe (HashMap FieldName Field)
_qFields = HashMap FieldName Field -> HashMap FieldName Field
forall v. HashMap FieldName v -> HashMap FieldName v
mapFieldNameHashMap (HashMap FieldName Field -> HashMap FieldName Field)
-> Maybe (HashMap FieldName Field)
-> Maybe (HashMap FieldName Field)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (HashMap FieldName Field)
_faaFields,
        _qAggregates :: Maybe (HashMap FieldName Aggregate)
_qAggregates = HashMap FieldName Aggregate -> HashMap FieldName Aggregate
forall v. HashMap FieldName v -> HashMap FieldName v
mapFieldNameHashMap (HashMap FieldName Aggregate -> HashMap FieldName Aggregate)
-> Maybe (HashMap FieldName Aggregate)
-> Maybe (HashMap FieldName Aggregate)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (HashMap FieldName Aggregate)
_faaAggregates,
        _qAggregatesLimit :: Maybe Int
_qAggregatesLimit = SelectArgsG 'DataConnector (UnpreparedValue 'DataConnector)
-> Maybe Int
forall (b :: BackendType) v. SelectArgsG b v -> Maybe Int
_saLimit (AnnSelectG
  'DataConnector fieldType (UnpreparedValue 'DataConnector)
-> SelectArgsG 'DataConnector (UnpreparedValue 'DataConnector)
forall (b :: BackendType) (f :: * -> *) v.
AnnSelectG b f v -> SelectArgsG b v
_asnArgs AnnSelectG
  'DataConnector fieldType (UnpreparedValue 'DataConnector)
selectG) Maybe Int -> Maybe (HashMap FieldName Aggregate) -> Maybe Int
forall a b. Maybe a -> Maybe b -> Maybe a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Maybe (HashMap FieldName Aggregate)
_faaAggregates, -- Only include the aggregates limit if we actually have aggregrates
        _qLimit :: Maybe Int
_qLimit =
          (Min Int -> Int) -> Maybe (Min Int) -> Maybe Int
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Min Int -> Int
forall a. Min a -> a
getMin
            (Maybe (Min Int) -> Maybe Int) -> Maybe (Min Int) -> Maybe Int
forall a b. (a -> b) -> a -> b
$ (Maybe Int -> Maybe (Min Int)) -> [Maybe Int] -> Maybe (Min Int)
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap
              ((Int -> Min Int) -> Maybe Int -> Maybe (Min Int)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> Min Int
forall a. a -> Min a
Min)
              [ SelectArgsG 'DataConnector (UnpreparedValue 'DataConnector)
-> Maybe Int
forall (b :: BackendType) v. SelectArgsG b v -> Maybe Int
_saLimit (AnnSelectG
  'DataConnector fieldType (UnpreparedValue 'DataConnector)
-> SelectArgsG 'DataConnector (UnpreparedValue 'DataConnector)
forall (b :: BackendType) (f :: * -> *) v.
AnnSelectG b f v -> SelectArgsG b v
_asnArgs AnnSelectG
  'DataConnector fieldType (UnpreparedValue 'DataConnector)
selectG),
                TablePermG 'DataConnector (UnpreparedValue 'DataConnector)
-> Maybe Int
forall (b :: BackendType) v. TablePermG b v -> Maybe Int
_tpLimit (AnnSelectG
  'DataConnector fieldType (UnpreparedValue 'DataConnector)
-> TablePermG 'DataConnector (UnpreparedValue 'DataConnector)
forall (b :: BackendType) (f :: * -> *) v.
AnnSelectG b f v -> TablePermG b v
_asnPerm AnnSelectG
  'DataConnector fieldType (UnpreparedValue 'DataConnector)
selectG)
              ],
        _qOffset :: Maybe Int
_qOffset = (Int64 -> Int) -> Maybe Int64 -> Maybe Int
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (SelectArgsG 'DataConnector (UnpreparedValue 'DataConnector)
-> Maybe Int64
forall (b :: BackendType) v. SelectArgsG b v -> Maybe Int64
_saOffset (AnnSelectG
  'DataConnector fieldType (UnpreparedValue 'DataConnector)
-> SelectArgsG 'DataConnector (UnpreparedValue 'DataConnector)
forall (b :: BackendType) (f :: * -> *) v.
AnnSelectG b f v -> SelectArgsG b v
_asnArgs AnnSelectG
  'DataConnector fieldType (UnpreparedValue 'DataConnector)
selectG)),
        _qWhere :: Maybe Expression
_qWhere = Maybe Expression
whereClause,
        _qOrderBy :: Maybe OrderBy
_qOrderBy = Maybe OrderBy
orderBy
      }

translateOrderBy ::
  ( Has TableRelationships writerOutput,
    Monoid writerOutput,
    MonadError QErr m,
    MonadReader r m,
    Has API.ScalarTypesCapabilities r
  ) =>
  SessionVariables ->
  TableRelationshipsKey ->
  NE.NonEmpty (AnnotatedOrderByItemG 'DataConnector (UnpreparedValue 'DataConnector)) ->
  CPS.WriterT writerOutput m API.OrderBy
translateOrderBy :: forall writerOutput (m :: * -> *) r.
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> TableRelationshipsKey
-> NonEmpty
     (AnnotatedOrderByItemG
        'DataConnector (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m OrderBy
translateOrderBy SessionVariables
sessionVariables TableRelationshipsKey
sourceName NonEmpty
  (AnnotatedOrderByItemG
     'DataConnector (UnpreparedValue 'DataConnector))
orderByItems = do
  NonEmpty (OrderByElement, HashMap RelationshipName OrderByRelation)
orderByElementsAndRelations <- NonEmpty
  (AnnotatedOrderByItemG
     'DataConnector (UnpreparedValue 'DataConnector))
-> (AnnotatedOrderByItemG
      'DataConnector (UnpreparedValue 'DataConnector)
    -> WriterT
         writerOutput
         m
         (OrderByElement, HashMap RelationshipName OrderByRelation))
-> WriterT
     writerOutput
     m
     (NonEmpty
        (OrderByElement, HashMap RelationshipName OrderByRelation))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
t a -> (a -> f b) -> f (t b)
for NonEmpty
  (AnnotatedOrderByItemG
     'DataConnector (UnpreparedValue 'DataConnector))
orderByItems \OrderByItemG {Maybe (BasicOrderType 'DataConnector)
Maybe (NullsOrderType 'DataConnector)
AnnotatedOrderByElement
  'DataConnector (UnpreparedValue 'DataConnector)
obiType :: Maybe (BasicOrderType 'DataConnector)
obiColumn :: AnnotatedOrderByElement
  'DataConnector (UnpreparedValue 'DataConnector)
obiNulls :: Maybe (NullsOrderType 'DataConnector)
obiType :: forall (b :: BackendType) a.
OrderByItemG b a -> Maybe (BasicOrderType b)
obiColumn :: forall (b :: BackendType) a. OrderByItemG b a -> a
obiNulls :: forall (b :: BackendType) a.
OrderByItemG b a -> Maybe (NullsOrderType b)
..} -> do
    let orderDirection :: OrderDirection
orderDirection = OrderDirection
-> (OrderDirection -> OrderDirection)
-> Maybe OrderDirection
-> OrderDirection
forall b a. b -> (a -> b) -> Maybe a -> b
maybe OrderDirection
API.Ascending OrderDirection -> OrderDirection
forall source target. From source target => source -> target
Witch.from Maybe (BasicOrderType 'DataConnector)
Maybe OrderDirection
obiType
    SessionVariables
-> TableRelationshipsKey
-> OrderDirection
-> [RelationshipName]
-> AnnotatedOrderByElement
     'DataConnector (UnpreparedValue 'DataConnector)
-> WriterT
     writerOutput
     m
     (OrderByElement, HashMap RelationshipName OrderByRelation)
forall writerOutput (m :: * -> *) r.
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> TableRelationshipsKey
-> OrderDirection
-> [RelationshipName]
-> AnnotatedOrderByElement
     'DataConnector (UnpreparedValue 'DataConnector)
-> WriterT
     writerOutput
     m
     (OrderByElement, HashMap RelationshipName OrderByRelation)
translateOrderByElement SessionVariables
sessionVariables TableRelationshipsKey
sourceName OrderDirection
orderDirection [] AnnotatedOrderByElement
  'DataConnector (UnpreparedValue 'DataConnector)
obiColumn
  HashMap RelationshipName OrderByRelation
relations <- m (HashMap RelationshipName OrderByRelation)
-> WriterT
     writerOutput m (HashMap RelationshipName OrderByRelation)
forall (m :: * -> *) a. Monad m => m a -> WriterT writerOutput m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (HashMap RelationshipName OrderByRelation)
 -> WriterT
      writerOutput m (HashMap RelationshipName OrderByRelation))
-> (NonEmpty (HashMap RelationshipName OrderByRelation)
    -> m (HashMap RelationshipName OrderByRelation))
-> NonEmpty (HashMap RelationshipName OrderByRelation)
-> WriterT
     writerOutput m (HashMap RelationshipName OrderByRelation)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty (HashMap RelationshipName OrderByRelation)
-> m (HashMap RelationshipName OrderByRelation)
forall (m :: * -> *) (f :: * -> *).
(MonadError QErr m, Foldable f) =>
f (HashMap RelationshipName OrderByRelation)
-> m (HashMap RelationshipName OrderByRelation)
mergeOrderByRelations (NonEmpty (HashMap RelationshipName OrderByRelation)
 -> WriterT
      writerOutput m (HashMap RelationshipName OrderByRelation))
-> NonEmpty (HashMap RelationshipName OrderByRelation)
-> WriterT
     writerOutput m (HashMap RelationshipName OrderByRelation)
forall a b. (a -> b) -> a -> b
$ (OrderByElement, HashMap RelationshipName OrderByRelation)
-> HashMap RelationshipName OrderByRelation
forall a b. (a, b) -> b
snd ((OrderByElement, HashMap RelationshipName OrderByRelation)
 -> HashMap RelationshipName OrderByRelation)
-> NonEmpty
     (OrderByElement, HashMap RelationshipName OrderByRelation)
-> NonEmpty (HashMap RelationshipName OrderByRelation)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty (OrderByElement, HashMap RelationshipName OrderByRelation)
orderByElementsAndRelations
  OrderBy -> WriterT writerOutput m OrderBy
forall a. a -> WriterT writerOutput m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
    API.OrderBy
      { _obRelations :: HashMap RelationshipName OrderByRelation
_obRelations = HashMap RelationshipName OrderByRelation
relations,
        _obElements :: NonEmpty OrderByElement
_obElements = (OrderByElement, HashMap RelationshipName OrderByRelation)
-> OrderByElement
forall a b. (a, b) -> a
fst ((OrderByElement, HashMap RelationshipName OrderByRelation)
 -> OrderByElement)
-> NonEmpty
     (OrderByElement, HashMap RelationshipName OrderByRelation)
-> NonEmpty OrderByElement
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty (OrderByElement, HashMap RelationshipName OrderByRelation)
orderByElementsAndRelations
      }

translateOrderByElement ::
  ( Has TableRelationships writerOutput,
    Monoid writerOutput,
    MonadError QErr m,
    MonadReader r m,
    Has API.ScalarTypesCapabilities r
  ) =>
  SessionVariables ->
  TableRelationshipsKey ->
  API.OrderDirection ->
  [API.RelationshipName] ->
  AnnotatedOrderByElement 'DataConnector (UnpreparedValue 'DataConnector) ->
  CPS.WriterT writerOutput m (API.OrderByElement, HashMap API.RelationshipName API.OrderByRelation)
translateOrderByElement :: forall writerOutput (m :: * -> *) r.
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> TableRelationshipsKey
-> OrderDirection
-> [RelationshipName]
-> AnnotatedOrderByElement
     'DataConnector (UnpreparedValue 'DataConnector)
-> WriterT
     writerOutput
     m
     (OrderByElement, HashMap RelationshipName OrderByRelation)
translateOrderByElement SessionVariables
sessionVariables TableRelationshipsKey
sourceName OrderDirection
orderDirection [RelationshipName]
targetReversePath = \case
  -- TODO(redactionExp): Deal with this redaction expressions
  AOCColumn ColumnInfo {Bool
Int
Maybe Description
Name
Column 'DataConnector
ColumnType 'DataConnector
ColumnMutability
ciColumn :: Column 'DataConnector
ciName :: Name
ciPosition :: Int
ciType :: ColumnType 'DataConnector
ciIsNullable :: Bool
ciDescription :: Maybe Description
ciMutability :: ColumnMutability
ciColumn :: forall (b :: BackendType). ColumnInfo b -> Column b
ciName :: forall (b :: BackendType). ColumnInfo b -> Name
ciPosition :: forall (b :: BackendType). ColumnInfo b -> Int
ciType :: forall (b :: BackendType). ColumnInfo b -> ColumnType b
ciIsNullable :: forall (b :: BackendType). ColumnInfo b -> Bool
ciDescription :: forall (b :: BackendType). ColumnInfo b -> Maybe Description
ciMutability :: forall (b :: BackendType). ColumnInfo b -> ColumnMutability
..} AnnRedactionExp 'DataConnector (UnpreparedValue 'DataConnector)
_redactionExp ->
    (OrderByElement, HashMap RelationshipName OrderByRelation)
-> WriterT
     writerOutput
     m
     (OrderByElement, HashMap RelationshipName OrderByRelation)
forall a. a -> WriterT writerOutput m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
      ( API.OrderByElement
          { _obeTargetPath :: [RelationshipName]
_obeTargetPath = [RelationshipName] -> [RelationshipName]
forall a. [a] -> [a]
reverse [RelationshipName]
targetReversePath,
            _obeTarget :: OrderByTarget
_obeTarget = ColumnName -> OrderByTarget
API.OrderByColumn (ColumnName -> OrderByTarget) -> ColumnName -> OrderByTarget
forall a b. (a -> b) -> a -> b
$ ColumnName -> ColumnName
forall source target. From source target => source -> target
Witch.from Column 'DataConnector
ColumnName
ciColumn,
            _obeOrderDirection :: OrderDirection
_obeOrderDirection = OrderDirection
orderDirection
          },
        HashMap RelationshipName OrderByRelation
forall a. Monoid a => a
mempty
      )
  AOCObjectRelation RelInfo 'DataConnector
relationshipInfo GBoolExp
  'DataConnector
  (AnnBoolExpFld 'DataConnector (UnpreparedValue 'DataConnector))
filterExp AnnotatedOrderByElement
  'DataConnector (UnpreparedValue 'DataConnector)
orderByElement -> do
    (RelationshipName
relationshipName, API.Relationship {HashMap ColumnName ColumnName
TableName
RelationshipType
_rTargetTable :: TableName
_rRelationshipType :: RelationshipType
_rColumnMapping :: HashMap ColumnName ColumnName
_rTargetTable :: Relationship -> TableName
_rRelationshipType :: Relationship -> RelationshipType
_rColumnMapping :: Relationship -> HashMap ColumnName ColumnName
..}) <- TableRelationshipsKey
-> RelInfo 'DataConnector
-> WriterT writerOutput m (RelationshipName, Relationship)
forall writerOutput (m :: * -> *).
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m) =>
TableRelationshipsKey
-> RelInfo 'DataConnector
-> WriterT writerOutput m (RelationshipName, Relationship)
recordTableRelationshipFromRelInfo TableRelationshipsKey
sourceName RelInfo 'DataConnector
relationshipInfo
    (OrderByElement
translatedOrderByElement, HashMap RelationshipName OrderByRelation
subOrderByRelations) <- SessionVariables
-> TableRelationshipsKey
-> OrderDirection
-> [RelationshipName]
-> AnnotatedOrderByElement
     'DataConnector (UnpreparedValue 'DataConnector)
-> WriterT
     writerOutput
     m
     (OrderByElement, HashMap RelationshipName OrderByRelation)
forall writerOutput (m :: * -> *) r.
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> TableRelationshipsKey
-> OrderDirection
-> [RelationshipName]
-> AnnotatedOrderByElement
     'DataConnector (UnpreparedValue 'DataConnector)
-> WriterT
     writerOutput
     m
     (OrderByElement, HashMap RelationshipName OrderByRelation)
translateOrderByElement SessionVariables
sessionVariables (TableName -> TableRelationshipsKey
TableNameKey TableName
_rTargetTable) OrderDirection
orderDirection (RelationshipName
relationshipName RelationshipName -> [RelationshipName] -> [RelationshipName]
forall a. a -> [a] -> [a]
: [RelationshipName]
targetReversePath) AnnotatedOrderByElement
  'DataConnector (UnpreparedValue 'DataConnector)
orderByElement

    Maybe Expression
targetTableWhereExp <- SessionVariables
-> TableRelationshipsKey
-> GBoolExp
     'DataConnector
     (AnnBoolExpFld 'DataConnector (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m (Maybe Expression)
forall writerOutput (m :: * -> *) r.
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> TableRelationshipsKey
-> GBoolExp
     'DataConnector
     (AnnBoolExpFld 'DataConnector (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m (Maybe Expression)
translateBoolExpToExpression SessionVariables
sessionVariables (TableName -> TableRelationshipsKey
TableNameKey TableName
_rTargetTable) GBoolExp
  'DataConnector
  (AnnBoolExpFld 'DataConnector (UnpreparedValue 'DataConnector))
filterExp
    let orderByRelations :: HashMap RelationshipName OrderByRelation
orderByRelations = [(RelationshipName, OrderByRelation)]
-> HashMap RelationshipName OrderByRelation
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HashMap.fromList [(RelationshipName
relationshipName, Maybe Expression
-> HashMap RelationshipName OrderByRelation -> OrderByRelation
API.OrderByRelation Maybe Expression
targetTableWhereExp HashMap RelationshipName OrderByRelation
subOrderByRelations)]

    (OrderByElement, HashMap RelationshipName OrderByRelation)
-> WriterT
     writerOutput
     m
     (OrderByElement, HashMap RelationshipName OrderByRelation)
forall a. a -> WriterT writerOutput m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (OrderByElement
translatedOrderByElement, HashMap RelationshipName OrderByRelation
orderByRelations)
  AOCArrayAggregation RelInfo 'DataConnector
relationshipInfo GBoolExp
  'DataConnector
  (AnnBoolExpFld 'DataConnector (UnpreparedValue 'DataConnector))
filterExp AnnotatedAggregateOrderBy
  'DataConnector (UnpreparedValue 'DataConnector)
aggregateOrderByElement -> do
    (RelationshipName
relationshipName, API.Relationship {HashMap ColumnName ColumnName
TableName
RelationshipType
_rTargetTable :: Relationship -> TableName
_rRelationshipType :: Relationship -> RelationshipType
_rColumnMapping :: Relationship -> HashMap ColumnName ColumnName
_rTargetTable :: TableName
_rRelationshipType :: RelationshipType
_rColumnMapping :: HashMap ColumnName ColumnName
..}) <- TableRelationshipsKey
-> RelInfo 'DataConnector
-> WriterT writerOutput m (RelationshipName, Relationship)
forall writerOutput (m :: * -> *).
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m) =>
TableRelationshipsKey
-> RelInfo 'DataConnector
-> WriterT writerOutput m (RelationshipName, Relationship)
recordTableRelationshipFromRelInfo TableRelationshipsKey
sourceName RelInfo 'DataConnector
relationshipInfo
    OrderByTarget
orderByTarget <- case AnnotatedAggregateOrderBy
  'DataConnector (UnpreparedValue 'DataConnector)
aggregateOrderByElement of
      AnnotatedAggregateOrderBy
  'DataConnector (UnpreparedValue 'DataConnector)
AAOCount ->
        OrderByTarget -> WriterT writerOutput m OrderByTarget
forall a. a -> WriterT writerOutput m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure OrderByTarget
API.OrderByStarCountAggregate
      AAOOp AggregateOrderByColumn {$sel:_aobcColumn:AggregateOrderByColumn :: forall (b :: BackendType) v.
AggregateOrderByColumn b v -> ColumnInfo b
_aobcColumn = ColumnInfo {Bool
Int
Maybe Description
Name
Column 'DataConnector
ColumnType 'DataConnector
ColumnMutability
ciColumn :: forall (b :: BackendType). ColumnInfo b -> Column b
ciName :: forall (b :: BackendType). ColumnInfo b -> Name
ciPosition :: forall (b :: BackendType). ColumnInfo b -> Int
ciType :: forall (b :: BackendType). ColumnInfo b -> ColumnType b
ciIsNullable :: forall (b :: BackendType). ColumnInfo b -> Bool
ciDescription :: forall (b :: BackendType). ColumnInfo b -> Maybe Description
ciMutability :: forall (b :: BackendType). ColumnInfo b -> ColumnMutability
ciColumn :: Column 'DataConnector
ciName :: Name
ciPosition :: Int
ciType :: ColumnType 'DataConnector
ciIsNullable :: Bool
ciDescription :: Maybe Description
ciMutability :: ColumnMutability
..}, Text
ColumnType 'DataConnector
AnnRedactionExp 'DataConnector (UnpreparedValue 'DataConnector)
_aobcAggregateFunctionName :: Text
_aobcAggregateFunctionReturnType :: ColumnType 'DataConnector
_aobcRedactionExpression :: AnnRedactionExp 'DataConnector (UnpreparedValue 'DataConnector)
$sel:_aobcAggregateFunctionName:AggregateOrderByColumn :: forall (b :: BackendType) v. AggregateOrderByColumn b v -> Text
$sel:_aobcAggregateFunctionReturnType:AggregateOrderByColumn :: forall (b :: BackendType) v.
AggregateOrderByColumn b v -> ColumnType b
$sel:_aobcRedactionExpression:AggregateOrderByColumn :: forall (b :: BackendType) v.
AggregateOrderByColumn b v -> AnnRedactionExp b v
..} -> do
        -- TODO(redactionExp): Deal with the redaction expression: _aobcRedactionExpression
        SingleColumnAggregateFunction
aggFunction <- m SingleColumnAggregateFunction
-> WriterT writerOutput m SingleColumnAggregateFunction
forall (m :: * -> *) a. Monad m => m a -> WriterT writerOutput m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m SingleColumnAggregateFunction
 -> WriterT writerOutput m SingleColumnAggregateFunction)
-> m SingleColumnAggregateFunction
-> WriterT writerOutput m SingleColumnAggregateFunction
forall a b. (a -> b) -> a -> b
$ Text -> m SingleColumnAggregateFunction
forall (m :: * -> *).
MonadError QErr m =>
Text -> m SingleColumnAggregateFunction
translateSingleColumnAggregateFunction Text
_aobcAggregateFunctionName
        let resultScalarType :: ScalarType
resultScalarType = ScalarType -> ScalarType
forall source target. From source target => source -> target
Witch.from (ScalarType -> ScalarType) -> ScalarType -> ScalarType
forall a b. (a -> b) -> a -> b
$ ColumnType 'DataConnector -> ScalarType
columnTypeToScalarType ColumnType 'DataConnector
_aobcAggregateFunctionReturnType
        OrderByTarget -> WriterT writerOutput m OrderByTarget
forall a. a -> WriterT writerOutput m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (OrderByTarget -> WriterT writerOutput m OrderByTarget)
-> (SingleColumnAggregate -> OrderByTarget)
-> SingleColumnAggregate
-> WriterT writerOutput m OrderByTarget
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SingleColumnAggregate -> OrderByTarget
API.OrderBySingleColumnAggregate (SingleColumnAggregate -> WriterT writerOutput m OrderByTarget)
-> SingleColumnAggregate -> WriterT writerOutput m OrderByTarget
forall a b. (a -> b) -> a -> b
$ SingleColumnAggregateFunction
-> ColumnName -> ScalarType -> SingleColumnAggregate
API.SingleColumnAggregate SingleColumnAggregateFunction
aggFunction (ColumnName -> ColumnName
forall source target. From source target => source -> target
Witch.from Column 'DataConnector
ColumnName
ciColumn) ScalarType
resultScalarType

    let translatedOrderByElement :: OrderByElement
translatedOrderByElement =
          API.OrderByElement
            { _obeTargetPath :: [RelationshipName]
_obeTargetPath = [RelationshipName] -> [RelationshipName]
forall a. [a] -> [a]
reverse (RelationshipName
relationshipName RelationshipName -> [RelationshipName] -> [RelationshipName]
forall a. a -> [a] -> [a]
: [RelationshipName]
targetReversePath),
              _obeTarget :: OrderByTarget
_obeTarget = OrderByTarget
orderByTarget,
              _obeOrderDirection :: OrderDirection
_obeOrderDirection = OrderDirection
orderDirection
            }

    Maybe Expression
targetTableWhereExp <- SessionVariables
-> TableRelationshipsKey
-> GBoolExp
     'DataConnector
     (AnnBoolExpFld 'DataConnector (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m (Maybe Expression)
forall writerOutput (m :: * -> *) r.
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> TableRelationshipsKey
-> GBoolExp
     'DataConnector
     (AnnBoolExpFld 'DataConnector (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m (Maybe Expression)
translateBoolExpToExpression SessionVariables
sessionVariables (TableName -> TableRelationshipsKey
TableNameKey TableName
_rTargetTable) GBoolExp
  'DataConnector
  (AnnBoolExpFld 'DataConnector (UnpreparedValue 'DataConnector))
filterExp
    let orderByRelations :: HashMap RelationshipName OrderByRelation
orderByRelations = [(RelationshipName, OrderByRelation)]
-> HashMap RelationshipName OrderByRelation
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HashMap.fromList [(RelationshipName
relationshipName, Maybe Expression
-> HashMap RelationshipName OrderByRelation -> OrderByRelation
API.OrderByRelation Maybe Expression
targetTableWhereExp HashMap RelationshipName OrderByRelation
forall a. Monoid a => a
mempty)]
    (OrderByElement, HashMap RelationshipName OrderByRelation)
-> WriterT
     writerOutput
     m
     (OrderByElement, HashMap RelationshipName OrderByRelation)
forall a. a -> WriterT writerOutput m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (OrderByElement
translatedOrderByElement, HashMap RelationshipName OrderByRelation
orderByRelations)

mergeOrderByRelations ::
  forall m f.
  (MonadError QErr m, Foldable f) =>
  f (HashMap API.RelationshipName API.OrderByRelation) ->
  m (HashMap API.RelationshipName API.OrderByRelation)
mergeOrderByRelations :: forall (m :: * -> *) (f :: * -> *).
(MonadError QErr m, Foldable f) =>
f (HashMap RelationshipName OrderByRelation)
-> m (HashMap RelationshipName OrderByRelation)
mergeOrderByRelations f (HashMap RelationshipName OrderByRelation)
orderByRelationsList =
  (HashMap RelationshipName OrderByRelation
 -> HashMap RelationshipName OrderByRelation
 -> m (HashMap RelationshipName OrderByRelation))
-> HashMap RelationshipName OrderByRelation
-> f (HashMap RelationshipName OrderByRelation)
-> m (HashMap RelationshipName OrderByRelation)
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM HashMap RelationshipName OrderByRelation
-> HashMap RelationshipName OrderByRelation
-> m (HashMap RelationshipName OrderByRelation)
mergeMap HashMap RelationshipName OrderByRelation
forall a. Monoid a => a
mempty f (HashMap RelationshipName OrderByRelation)
orderByRelationsList
  where
    mergeMap :: HashMap API.RelationshipName API.OrderByRelation -> HashMap API.RelationshipName API.OrderByRelation -> m (HashMap API.RelationshipName API.OrderByRelation)
    mergeMap :: HashMap RelationshipName OrderByRelation
-> HashMap RelationshipName OrderByRelation
-> m (HashMap RelationshipName OrderByRelation)
mergeMap HashMap RelationshipName OrderByRelation
left HashMap RelationshipName OrderByRelation
right = (HashMap RelationshipName OrderByRelation
 -> (RelationshipName, OrderByRelation)
 -> m (HashMap RelationshipName OrderByRelation))
-> HashMap RelationshipName OrderByRelation
-> [(RelationshipName, OrderByRelation)]
-> m (HashMap RelationshipName OrderByRelation)
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM (\HashMap RelationshipName OrderByRelation
targetMap (RelationshipName
relName, OrderByRelation
orderByRel) -> (Maybe OrderByRelation -> m (Maybe OrderByRelation))
-> RelationshipName
-> HashMap RelationshipName OrderByRelation
-> m (HashMap RelationshipName OrderByRelation)
forall (f :: * -> *) k v.
(Functor f, Eq k, Hashable k) =>
(Maybe v -> f (Maybe v)) -> k -> HashMap k v -> f (HashMap k v)
HashMap.alterF (m (Maybe OrderByRelation)
-> (OrderByRelation -> m (Maybe OrderByRelation))
-> Maybe OrderByRelation
-> m (Maybe OrderByRelation)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Maybe OrderByRelation -> m (Maybe OrderByRelation)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe OrderByRelation -> m (Maybe OrderByRelation))
-> Maybe OrderByRelation -> m (Maybe OrderByRelation)
forall a b. (a -> b) -> a -> b
$ OrderByRelation -> Maybe OrderByRelation
forall a. a -> Maybe a
Just OrderByRelation
orderByRel) ((OrderByRelation -> Maybe OrderByRelation)
-> m OrderByRelation -> m (Maybe OrderByRelation)
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap OrderByRelation -> Maybe OrderByRelation
forall a. a -> Maybe a
Just (m OrderByRelation -> m (Maybe OrderByRelation))
-> (OrderByRelation -> m OrderByRelation)
-> OrderByRelation
-> m (Maybe OrderByRelation)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OrderByRelation -> OrderByRelation -> m OrderByRelation
mergeOrderByRelation OrderByRelation
orderByRel)) RelationshipName
relName HashMap RelationshipName OrderByRelation
targetMap) HashMap RelationshipName OrderByRelation
left ([(RelationshipName, OrderByRelation)]
 -> m (HashMap RelationshipName OrderByRelation))
-> [(RelationshipName, OrderByRelation)]
-> m (HashMap RelationshipName OrderByRelation)
forall a b. (a -> b) -> a -> b
$ HashMap RelationshipName OrderByRelation
-> [(RelationshipName, OrderByRelation)]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList HashMap RelationshipName OrderByRelation
right

    mergeOrderByRelation :: API.OrderByRelation -> API.OrderByRelation -> m API.OrderByRelation
    mergeOrderByRelation :: OrderByRelation -> OrderByRelation -> m OrderByRelation
mergeOrderByRelation OrderByRelation
right OrderByRelation
left =
      if OrderByRelation -> Maybe Expression
API._obrWhere OrderByRelation
left Maybe Expression -> Maybe Expression -> Bool
forall a. Eq a => a -> a -> Bool
== OrderByRelation -> Maybe Expression
API._obrWhere OrderByRelation
right
        then do
          HashMap RelationshipName OrderByRelation
mergedSubrelations <- HashMap RelationshipName OrderByRelation
-> HashMap RelationshipName OrderByRelation
-> m (HashMap RelationshipName OrderByRelation)
mergeMap (OrderByRelation -> HashMap RelationshipName OrderByRelation
API._obrSubrelations OrderByRelation
left) (OrderByRelation -> HashMap RelationshipName OrderByRelation
API._obrSubrelations OrderByRelation
right)
          OrderByRelation -> m OrderByRelation
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (OrderByRelation -> m OrderByRelation)
-> OrderByRelation -> m OrderByRelation
forall a b. (a -> b) -> a -> b
$ Maybe Expression
-> HashMap RelationshipName OrderByRelation -> OrderByRelation
API.OrderByRelation (OrderByRelation -> Maybe Expression
API._obrWhere OrderByRelation
left) HashMap RelationshipName OrderByRelation
mergedSubrelations
        else Text -> m OrderByRelation
forall (m :: * -> *) a. QErrM m => Text -> m a
throw500 Text
"mergeOrderByRelations: Differing filter expressions found for the same table"

translateAnnFieldsWithNoAggregates ::
  ( Has TableRelationships writerOutput,
    Monoid writerOutput,
    MonadError QErr m,
    MonadReader r m,
    Has API.ScalarTypesCapabilities r
  ) =>
  SessionVariables ->
  FieldPrefix ->
  TableRelationshipsKey ->
  AnnFieldsG 'DataConnector Void (UnpreparedValue 'DataConnector) ->
  CPS.WriterT writerOutput m FieldsAndAggregates
translateAnnFieldsWithNoAggregates :: forall writerOutput (m :: * -> *) r.
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> FieldPrefix
-> TableRelationshipsKey
-> Fields
     (AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m FieldsAndAggregates
translateAnnFieldsWithNoAggregates SessionVariables
sessionVariables FieldPrefix
fieldNamePrefix TableRelationshipsKey
sourceName Fields
  (AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
fields =
  (\HashMap FieldName Field
fields' -> Maybe (HashMap FieldName Field)
-> Maybe (HashMap FieldName Aggregate) -> FieldsAndAggregates
FieldsAndAggregates (HashMap FieldName Field -> Maybe (HashMap FieldName Field)
forall a. a -> Maybe a
Just HashMap FieldName Field
fields') Maybe (HashMap FieldName Aggregate)
forall a. Maybe a
Nothing) (HashMap FieldName Field -> FieldsAndAggregates)
-> WriterT writerOutput m (HashMap FieldName Field)
-> WriterT writerOutput m FieldsAndAggregates
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SessionVariables
-> FieldPrefix
-> TableRelationshipsKey
-> Fields
     (AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m (HashMap FieldName Field)
forall writerOutput (m :: * -> *) r.
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> FieldPrefix
-> TableRelationshipsKey
-> Fields
     (AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m (HashMap FieldName Field)
translateAnnFields SessionVariables
sessionVariables FieldPrefix
fieldNamePrefix TableRelationshipsKey
sourceName Fields
  (AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
fields

translateAnnFields ::
  ( Has TableRelationships writerOutput,
    Monoid writerOutput,
    MonadError QErr m,
    MonadReader r m,
    Has API.ScalarTypesCapabilities r
  ) =>
  SessionVariables ->
  FieldPrefix ->
  TableRelationshipsKey ->
  AnnFieldsG 'DataConnector Void (UnpreparedValue 'DataConnector) ->
  CPS.WriterT writerOutput m (HashMap FieldName API.Field)
translateAnnFields :: forall writerOutput (m :: * -> *) r.
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> FieldPrefix
-> TableRelationshipsKey
-> Fields
     (AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m (HashMap FieldName Field)
translateAnnFields SessionVariables
sessionVariables FieldPrefix
fieldNamePrefix TableRelationshipsKey
sourceName Fields
  (AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
fields = do
  [(FieldName, Maybe Field)]
translatedFields <- ((FieldName,
  AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
 -> WriterT writerOutput m (FieldName, Maybe Field))
-> Fields
     (AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m [(FieldName, Maybe Field)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector)
 -> WriterT writerOutput m (Maybe Field))
-> (FieldName,
    AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m (FieldName, Maybe Field)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> (FieldName, a) -> f (FieldName, b)
traverse (SessionVariables
-> TableRelationshipsKey
-> AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector)
-> WriterT writerOutput m (Maybe Field)
forall writerOutput (m :: * -> *) r.
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> TableRelationshipsKey
-> AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector)
-> WriterT writerOutput m (Maybe Field)
translateAnnField SessionVariables
sessionVariables TableRelationshipsKey
sourceName)) Fields
  (AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
fields
  HashMap FieldName Field
-> WriterT writerOutput m (HashMap FieldName Field)
forall a. a -> WriterT writerOutput m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (HashMap FieldName Field
 -> WriterT writerOutput m (HashMap FieldName Field))
-> HashMap FieldName Field
-> WriterT writerOutput m (HashMap FieldName Field)
forall a b. (a -> b) -> a -> b
$ [(FieldName, Field)] -> HashMap FieldName Field
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HashMap.fromList (((FieldName, Maybe Field) -> Maybe (FieldName, Field))
-> [(FieldName, Maybe Field)] -> [(FieldName, Field)]
forall a b. (a -> Maybe b) -> [a] -> [b]
forall (f :: * -> *) a b.
Filterable f =>
(a -> Maybe b) -> f a -> f b
mapMaybe (\(FieldName
fieldName, Maybe Field
field) -> (FieldPrefix -> FieldName -> FieldName
applyPrefix FieldPrefix
fieldNamePrefix FieldName
fieldName,) (Field -> (FieldName, Field))
-> Maybe Field -> Maybe (FieldName, Field)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Field
field) [(FieldName, Maybe Field)]
translatedFields)

translateAnnField ::
  ( Has TableRelationships writerOutput,
    Monoid writerOutput,
    MonadError QErr m,
    MonadReader r m,
    Has API.ScalarTypesCapabilities r
  ) =>
  SessionVariables ->
  TableRelationshipsKey ->
  AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector) ->
  CPS.WriterT writerOutput m (Maybe API.Field)
translateAnnField :: forall writerOutput (m :: * -> *) r.
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> TableRelationshipsKey
-> AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector)
-> WriterT writerOutput m (Maybe Field)
translateAnnField SessionVariables
sessionVariables TableRelationshipsKey
sourceTableName = \case
  AFNestedObject AnnNestedObjectSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
nestedObj ->
    Field -> Maybe Field
forall a. a -> Maybe a
Just
      (Field -> Maybe Field) -> (Query -> Field) -> Query -> Maybe Field
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ColumnName -> Query -> Field
API.NestedObjField (ColumnName -> ColumnName
forall source target. From source target => source -> target
Witch.from (ColumnName -> ColumnName) -> ColumnName -> ColumnName
forall a b. (a -> b) -> a -> b
$ AnnNestedObjectSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
-> Column 'DataConnector
forall (b :: BackendType) r v.
AnnNestedObjectSelectG b r v -> Column b
_anosColumn AnnNestedObjectSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
nestedObj)
      (Query -> Maybe Field)
-> WriterT writerOutput m Query
-> WriterT writerOutput m (Maybe Field)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SessionVariables
-> TableRelationshipsKey
-> AnnNestedObjectSelectG
     'DataConnector Void (UnpreparedValue 'DataConnector)
-> WriterT writerOutput m Query
forall writerOutput (m :: * -> *) r.
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> TableRelationshipsKey
-> AnnNestedObjectSelectG
     'DataConnector Void (UnpreparedValue 'DataConnector)
-> WriterT writerOutput m Query
translateNestedObjectSelect SessionVariables
sessionVariables TableRelationshipsKey
sourceTableName AnnNestedObjectSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
nestedObj
  AFNestedArray XNestedObjects 'DataConnector
_ (ANASSimple AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector)
field) ->
    (Field -> Field) -> Maybe Field -> Maybe Field
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Field -> Field
mkArrayField (Maybe Field -> Maybe Field)
-> WriterT writerOutput m (Maybe Field)
-> WriterT writerOutput m (Maybe Field)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SessionVariables
-> TableRelationshipsKey
-> AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector)
-> WriterT writerOutput m (Maybe Field)
forall writerOutput (m :: * -> *) r.
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> TableRelationshipsKey
-> AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector)
-> WriterT writerOutput m (Maybe Field)
translateAnnField SessionVariables
sessionVariables TableRelationshipsKey
sourceTableName AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector)
field
    where
      mkArrayField :: Field -> Field
mkArrayField Field
nestedField =
        ArrayField -> Field
API.NestedArrayField (Field
-> Maybe Int
-> Maybe Int
-> Maybe Expression
-> Maybe OrderBy
-> ArrayField
API.ArrayField Field
nestedField Maybe Int
forall a. Maybe a
Nothing Maybe Int
forall a. Maybe a
Nothing Maybe Expression
forall a. Maybe a
Nothing Maybe OrderBy
forall a. Maybe a
Nothing)
  -- TODO(dmoverton): support limit, offset, where and order_by in ArrayField
  AFNestedArray XNestedObjects 'DataConnector
_ (ANASAggregate AnnAggregateSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
_) ->
    Maybe Field -> WriterT writerOutput m (Maybe Field)
forall a. a -> WriterT writerOutput m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Field
forall a. Maybe a
Nothing -- TODO(dmoverton): support nested array aggregates
  AFColumn AnnColumnField 'DataConnector (UnpreparedValue 'DataConnector)
colField ->
    -- TODO(redactionExp): Deal with the redaction expression: _acfRedactionExpression
    -- TODO: make sure certain fields in colField are not in use, since we don't support them
    Maybe Field -> WriterT writerOutput m (Maybe Field)
forall a. a -> WriterT writerOutput m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Field -> WriterT writerOutput m (Maybe Field))
-> (Field -> Maybe Field)
-> Field
-> WriterT writerOutput m (Maybe Field)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Field -> Maybe Field
forall a. a -> Maybe a
Just (Field -> WriterT writerOutput m (Maybe Field))
-> Field -> WriterT writerOutput m (Maybe Field)
forall a b. (a -> b) -> a -> b
$ ColumnName -> ScalarType -> Field
API.ColumnField (ColumnName -> ColumnName
forall source target. From source target => source -> target
Witch.from (ColumnName -> ColumnName) -> ColumnName -> ColumnName
forall a b. (a -> b) -> a -> b
$ AnnColumnField 'DataConnector (UnpreparedValue 'DataConnector)
-> Column 'DataConnector
forall (b :: BackendType) v. AnnColumnField b v -> Column b
_acfColumn AnnColumnField 'DataConnector (UnpreparedValue 'DataConnector)
colField) (ScalarType -> ScalarType
forall source target. From source target => source -> target
Witch.from (ScalarType -> ScalarType)
-> (ColumnType 'DataConnector -> ScalarType)
-> ColumnType 'DataConnector
-> ScalarType
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ColumnType 'DataConnector -> ScalarType
columnTypeToScalarType (ColumnType 'DataConnector -> ScalarType)
-> ColumnType 'DataConnector -> ScalarType
forall a b. (a -> b) -> a -> b
$ AnnColumnField 'DataConnector (UnpreparedValue 'DataConnector)
-> ColumnType 'DataConnector
forall (b :: BackendType) v. AnnColumnField b v -> ColumnType b
_acfType AnnColumnField 'DataConnector (UnpreparedValue 'DataConnector)
colField)
  AFObjectRelation ObjectRelationSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
objRel ->
    case AnnObjectSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
-> SelectFromG 'DataConnector (UnpreparedValue 'DataConnector)
forall (b :: BackendType) r v.
AnnObjectSelectG b r v -> SelectFromG b v
_aosTarget (ObjectRelationSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
-> AnnObjectSelectG
     'DataConnector Void (UnpreparedValue 'DataConnector)
forall (b :: BackendType) a. AnnRelationSelectG b a -> a
_aarAnnSelect ObjectRelationSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
objRel) of
      FromTable TableName 'DataConnector
tableName -> do
        let targetTable :: TableName
targetTable = TableName -> TableName
forall source target. From source target => source -> target
Witch.from TableName 'DataConnector
TableName
tableName
        let relationshipName :: RelationshipName
relationshipName = RelName -> RelationshipName
mkRelationshipName (RelName -> RelationshipName) -> RelName -> RelationshipName
forall a b. (a -> b) -> a -> b
$ ObjectRelationSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
-> RelName
forall (b :: BackendType) a. AnnRelationSelectG b a -> RelName
_aarRelationshipName ObjectRelationSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
objRel
        HashMap FieldName Field
fields <- SessionVariables
-> FieldPrefix
-> TableRelationshipsKey
-> Fields
     (AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m (HashMap FieldName Field)
forall writerOutput (m :: * -> *) r.
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> FieldPrefix
-> TableRelationshipsKey
-> Fields
     (AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m (HashMap FieldName Field)
translateAnnFields SessionVariables
sessionVariables FieldPrefix
noPrefix (TableName -> TableRelationshipsKey
TableNameKey TableName
targetTable) (AnnObjectSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
-> Fields
     (AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
forall (b :: BackendType) r v.
AnnObjectSelectG b r v -> AnnFieldsG b r v
_aosFields (ObjectRelationSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
-> AnnObjectSelectG
     'DataConnector Void (UnpreparedValue 'DataConnector)
forall (b :: BackendType) a. AnnRelationSelectG b a -> a
_aarAnnSelect ObjectRelationSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
objRel))
        Maybe Expression
whereClause <- SessionVariables
-> TableRelationshipsKey
-> GBoolExp
     'DataConnector
     (AnnBoolExpFld 'DataConnector (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m (Maybe Expression)
forall writerOutput (m :: * -> *) r.
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> TableRelationshipsKey
-> GBoolExp
     'DataConnector
     (AnnBoolExpFld 'DataConnector (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m (Maybe Expression)
translateBoolExpToExpression SessionVariables
sessionVariables (TableName -> TableRelationshipsKey
TableNameKey TableName
targetTable) (AnnObjectSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
-> GBoolExp
     'DataConnector
     (AnnBoolExpFld 'DataConnector (UnpreparedValue 'DataConnector))
forall (b :: BackendType) r v.
AnnObjectSelectG b r v -> AnnBoolExp b v
_aosTargetFilter (ObjectRelationSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
-> AnnObjectSelectG
     'DataConnector Void (UnpreparedValue 'DataConnector)
forall (b :: BackendType) a. AnnRelationSelectG b a -> a
_aarAnnSelect ObjectRelationSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
objRel))

        TableRelationshipsKey
-> RelationshipName -> Relationship -> WriterT writerOutput m ()
forall writerOutput (m :: * -> *).
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m) =>
TableRelationshipsKey
-> RelationshipName -> Relationship -> WriterT writerOutput m ()
recordTableRelationship
          TableRelationshipsKey
sourceTableName
          RelationshipName
relationshipName
          API.Relationship
            { _rTargetTable :: TableName
_rTargetTable = TableName
targetTable,
              _rRelationshipType :: RelationshipType
_rRelationshipType = RelationshipType
API.ObjectRelationship,
              _rColumnMapping :: HashMap ColumnName ColumnName
_rColumnMapping = [(ColumnName, ColumnName)] -> HashMap ColumnName ColumnName
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HashMap.fromList ([(ColumnName, ColumnName)] -> HashMap ColumnName ColumnName)
-> [(ColumnName, ColumnName)] -> HashMap ColumnName ColumnName
forall a b. (a -> b) -> a -> b
$ (ColumnName -> ColumnName)
-> (ColumnName -> ColumnName)
-> (ColumnName, ColumnName)
-> (ColumnName, ColumnName)
forall a b c d. (a -> b) -> (c -> d) -> (a, c) -> (b, d)
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap ColumnName -> ColumnName
forall source target. From source target => source -> target
Witch.from ColumnName -> ColumnName
forall source target. From source target => source -> target
Witch.from ((ColumnName, ColumnName) -> (ColumnName, ColumnName))
-> [(ColumnName, ColumnName)] -> [(ColumnName, ColumnName)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> HashMap ColumnName ColumnName -> [(ColumnName, ColumnName)]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList (ObjectRelationSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
-> HashMap (Column 'DataConnector) (Column 'DataConnector)
forall (b :: BackendType) a.
AnnRelationSelectG b a -> HashMap (Column b) (Column b)
_aarColumnMapping ObjectRelationSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
objRel)
            }

        Maybe Field -> WriterT writerOutput m (Maybe Field)
forall a. a -> WriterT writerOutput m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
          (Maybe Field -> WriterT writerOutput m (Maybe Field))
-> (RelationshipField -> Maybe Field)
-> RelationshipField
-> WriterT writerOutput m (Maybe Field)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Field -> Maybe Field
forall a. a -> Maybe a
Just
          (Field -> Maybe Field)
-> (RelationshipField -> Field) -> RelationshipField -> Maybe Field
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RelationshipField -> Field
API.RelField
          (RelationshipField -> WriterT writerOutput m (Maybe Field))
-> RelationshipField -> WriterT writerOutput m (Maybe Field)
forall a b. (a -> b) -> a -> b
$ RelationshipName -> Query -> RelationshipField
API.RelationshipField
            RelationshipName
relationshipName
            ( API.Query
                { _qFields :: Maybe (HashMap FieldName Field)
_qFields = HashMap FieldName Field -> Maybe (HashMap FieldName Field)
forall a. a -> Maybe a
Just (HashMap FieldName Field -> Maybe (HashMap FieldName Field))
-> HashMap FieldName Field -> Maybe (HashMap FieldName Field)
forall a b. (a -> b) -> a -> b
$ HashMap FieldName Field -> HashMap FieldName Field
forall v. HashMap FieldName v -> HashMap FieldName v
mapFieldNameHashMap HashMap FieldName Field
fields,
                  _qAggregates :: Maybe (HashMap FieldName Aggregate)
_qAggregates = Maybe (HashMap FieldName Aggregate)
forall a. Monoid a => a
mempty,
                  _qWhere :: Maybe Expression
_qWhere = Maybe Expression
whereClause,
                  _qAggregatesLimit :: Maybe Int
_qAggregatesLimit = Maybe Int
forall a. Maybe a
Nothing,
                  _qLimit :: Maybe Int
_qLimit = Maybe Int
forall a. Maybe a
Nothing,
                  _qOffset :: Maybe Int
_qOffset = Maybe Int
forall a. Maybe a
Nothing,
                  _qOrderBy :: Maybe OrderBy
_qOrderBy = Maybe OrderBy
forall a. Maybe a
Nothing
                }
            )
      SelectFromG 'DataConnector (UnpreparedValue 'DataConnector)
other -> String -> WriterT writerOutput m (Maybe Field)
forall a. HasCallStack => String -> a
error (String -> WriterT writerOutput m (Maybe Field))
-> String -> WriterT writerOutput m (Maybe Field)
forall a b. (a -> b) -> a -> b
$ String
"translateAnnField: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> SelectFromG 'DataConnector (UnpreparedValue 'DataConnector)
-> String
forall a. Show a => a -> String
show SelectFromG 'DataConnector (UnpreparedValue 'DataConnector)
other
  AFArrayRelation (ASSimple ArrayRelationSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
arrayRelationSelect) -> do
    Field -> Maybe Field
forall a. a -> Maybe a
Just (Field -> Maybe Field)
-> WriterT writerOutput m Field
-> WriterT writerOutput m (Maybe Field)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SessionVariables
-> TableRelationshipsKey
-> (TableRelationshipsKey
    -> Fields
         (AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
    -> WriterT writerOutput m FieldsAndAggregates)
-> ArrayRelationSelectG
     'DataConnector Void (UnpreparedValue 'DataConnector)
-> WriterT writerOutput m Field
forall writerOutput (m :: * -> *) r (fieldType :: * -> *).
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> TableRelationshipsKey
-> (TableRelationshipsKey
    -> Fields (fieldType (UnpreparedValue 'DataConnector))
    -> WriterT writerOutput m FieldsAndAggregates)
-> AnnRelationSelectG
     'DataConnector
     (AnnSelectG
        'DataConnector fieldType (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m Field
translateArrayRelationSelect SessionVariables
sessionVariables TableRelationshipsKey
sourceTableName (SessionVariables
-> FieldPrefix
-> TableRelationshipsKey
-> Fields
     (AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m FieldsAndAggregates
forall writerOutput (m :: * -> *) r.
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> FieldPrefix
-> TableRelationshipsKey
-> Fields
     (AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m FieldsAndAggregates
translateAnnFieldsWithNoAggregates SessionVariables
sessionVariables FieldPrefix
noPrefix) ArrayRelationSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
arrayRelationSelect
  AFArrayRelation (ASAggregate ArrayAggregateSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
arrayRelationSelect) ->
    Field -> Maybe Field
forall a. a -> Maybe a
Just (Field -> Maybe Field)
-> WriterT writerOutput m Field
-> WriterT writerOutput m (Maybe Field)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SessionVariables
-> TableRelationshipsKey
-> (TableRelationshipsKey
    -> Fields
         (TableAggregateFieldG
            'DataConnector Void (UnpreparedValue 'DataConnector))
    -> WriterT writerOutput m FieldsAndAggregates)
-> ArrayAggregateSelectG
     'DataConnector Void (UnpreparedValue 'DataConnector)
-> WriterT writerOutput m Field
forall writerOutput (m :: * -> *) r (fieldType :: * -> *).
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> TableRelationshipsKey
-> (TableRelationshipsKey
    -> Fields (fieldType (UnpreparedValue 'DataConnector))
    -> WriterT writerOutput m FieldsAndAggregates)
-> AnnRelationSelectG
     'DataConnector
     (AnnSelectG
        'DataConnector fieldType (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m Field
translateArrayRelationSelect SessionVariables
sessionVariables TableRelationshipsKey
sourceTableName (SessionVariables
-> TableRelationshipsKey
-> Fields
     (TableAggregateFieldG
        'DataConnector Void (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m FieldsAndAggregates
forall writerOutput (m :: * -> *) r.
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> TableRelationshipsKey
-> Fields
     (TableAggregateFieldG
        'DataConnector Void (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m FieldsAndAggregates
translateTableAggregateFields SessionVariables
sessionVariables) ArrayAggregateSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
arrayRelationSelect
  AFExpression Text
_literal ->
    -- We ignore literal text fields (we don't send them to the data connector agent)
    -- and add them back to the response JSON when we reshape what the agent returns
    -- to us
    Maybe Field -> WriterT writerOutput m (Maybe Field)
forall a. a -> WriterT writerOutput m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Field
forall a. Maybe a
Nothing

translateArrayRelationSelect ::
  ( Has TableRelationships writerOutput,
    Monoid writerOutput,
    MonadError QErr m,
    MonadReader r m,
    Has API.ScalarTypesCapabilities r
  ) =>
  SessionVariables ->
  TableRelationshipsKey ->
  (TableRelationshipsKey -> Fields (fieldType (UnpreparedValue 'DataConnector)) -> CPS.WriterT writerOutput m FieldsAndAggregates) ->
  AnnRelationSelectG 'DataConnector (AnnSelectG 'DataConnector fieldType (UnpreparedValue 'DataConnector)) ->
  CPS.WriterT writerOutput m API.Field
translateArrayRelationSelect :: forall writerOutput (m :: * -> *) r (fieldType :: * -> *).
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> TableRelationshipsKey
-> (TableRelationshipsKey
    -> Fields (fieldType (UnpreparedValue 'DataConnector))
    -> WriterT writerOutput m FieldsAndAggregates)
-> AnnRelationSelectG
     'DataConnector
     (AnnSelectG
        'DataConnector fieldType (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m Field
translateArrayRelationSelect SessionVariables
sessionVariables TableRelationshipsKey
sourceName TableRelationshipsKey
-> Fields (fieldType (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m FieldsAndAggregates
translateFieldsAndAggregates AnnRelationSelectG
  'DataConnector
  (AnnSelectG
     'DataConnector fieldType (UnpreparedValue 'DataConnector))
arrRel = do
  case AnnSelectG
  'DataConnector fieldType (UnpreparedValue 'DataConnector)
-> SelectFromG 'DataConnector (UnpreparedValue 'DataConnector)
forall (b :: BackendType) (f :: * -> *) v.
AnnSelectG b f v -> SelectFromG b v
_asnFrom (AnnRelationSelectG
  'DataConnector
  (AnnSelectG
     'DataConnector fieldType (UnpreparedValue 'DataConnector))
-> AnnSelectG
     'DataConnector fieldType (UnpreparedValue 'DataConnector)
forall (b :: BackendType) a. AnnRelationSelectG b a -> a
_aarAnnSelect AnnRelationSelectG
  'DataConnector
  (AnnSelectG
     'DataConnector fieldType (UnpreparedValue 'DataConnector))
arrRel) of
    FromIdentifier FIIdentifier
_ -> m Field -> WriterT writerOutput m Field
forall (m :: * -> *) a. Monad m => m a -> WriterT writerOutput m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m Field -> WriterT writerOutput m Field)
-> m Field -> WriterT writerOutput m Field
forall a b. (a -> b) -> a -> b
$ Code -> Text -> m Field
forall (m :: * -> *) a. QErrM m => Code -> Text -> m a
throw400 Code
NotSupported Text
"AnnSelectG: FromIdentifier not supported"
    FromNativeQuery {} -> m Field -> WriterT writerOutput m Field
forall (m :: * -> *) a. Monad m => m a -> WriterT writerOutput m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m Field -> WriterT writerOutput m Field)
-> m Field -> WriterT writerOutput m Field
forall a b. (a -> b) -> a -> b
$ Code -> Text -> m Field
forall (m :: * -> *) a. QErrM m => Code -> Text -> m a
throw400 Code
NotSupported Text
"AnnSelectG: FromNativeQuery not supported"
    FromStoredProcedure {} -> m Field -> WriterT writerOutput m Field
forall (m :: * -> *) a. Monad m => m a -> WriterT writerOutput m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m Field -> WriterT writerOutput m Field)
-> m Field -> WriterT writerOutput m Field
forall a b. (a -> b) -> a -> b
$ Code -> Text -> m Field
forall (m :: * -> *) a. QErrM m => Code -> Text -> m a
throw400 Code
NotSupported Text
"AnnSelectG: FromStoredProcedure not supported"
    FromFunction {} -> m Field -> WriterT writerOutput m Field
forall (m :: * -> *) a. Monad m => m a -> WriterT writerOutput m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m Field -> WriterT writerOutput m Field)
-> m Field -> WriterT writerOutput m Field
forall a b. (a -> b) -> a -> b
$ Code -> Text -> m Field
forall (m :: * -> *) a. QErrM m => Code -> Text -> m a
throw400 Code
NotSupported Text
"translateArrayRelationSelect: FromFunction not currently supported"
    FromTable TableName 'DataConnector
targetTable -> do
      Query
query <- SessionVariables
-> (TableRelationshipsKey
    -> Fields (fieldType (UnpreparedValue 'DataConnector))
    -> WriterT writerOutput m FieldsAndAggregates)
-> TableRelationshipsKey
-> AnnSelectG
     'DataConnector fieldType (UnpreparedValue 'DataConnector)
-> WriterT writerOutput m Query
forall writerOutput (m :: * -> *) r (fieldType :: * -> *).
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> (TableRelationshipsKey
    -> Fields (fieldType (UnpreparedValue 'DataConnector))
    -> WriterT writerOutput m FieldsAndAggregates)
-> TableRelationshipsKey
-> AnnSelectG
     'DataConnector fieldType (UnpreparedValue 'DataConnector)
-> WriterT writerOutput m Query
translateAnnSelect SessionVariables
sessionVariables TableRelationshipsKey
-> Fields (fieldType (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m FieldsAndAggregates
translateFieldsAndAggregates (TableName -> TableRelationshipsKey
TableNameKey (TableName -> TableName
forall target source. From source target => source -> target
Witch.into TableName 'DataConnector
TableName
targetTable)) (AnnRelationSelectG
  'DataConnector
  (AnnSelectG
     'DataConnector fieldType (UnpreparedValue 'DataConnector))
-> AnnSelectG
     'DataConnector fieldType (UnpreparedValue 'DataConnector)
forall (b :: BackendType) a. AnnRelationSelectG b a -> a
_aarAnnSelect AnnRelationSelectG
  'DataConnector
  (AnnSelectG
     'DataConnector fieldType (UnpreparedValue 'DataConnector))
arrRel)
      let relationshipName :: RelationshipName
relationshipName = RelName -> RelationshipName
mkRelationshipName (RelName -> RelationshipName) -> RelName -> RelationshipName
forall a b. (a -> b) -> a -> b
$ AnnRelationSelectG
  'DataConnector
  (AnnSelectG
     'DataConnector fieldType (UnpreparedValue 'DataConnector))
-> RelName
forall (b :: BackendType) a. AnnRelationSelectG b a -> RelName
_aarRelationshipName AnnRelationSelectG
  'DataConnector
  (AnnSelectG
     'DataConnector fieldType (UnpreparedValue 'DataConnector))
arrRel

      TableRelationshipsKey
-> RelationshipName -> Relationship -> WriterT writerOutput m ()
forall writerOutput (m :: * -> *).
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m) =>
TableRelationshipsKey
-> RelationshipName -> Relationship -> WriterT writerOutput m ()
recordTableRelationship
        TableRelationshipsKey
sourceName
        RelationshipName
relationshipName
        API.Relationship
          { _rTargetTable :: TableName
_rTargetTable = TableName -> TableName
forall target source. From source target => source -> target
Witch.into TableName 'DataConnector
TableName
targetTable,
            _rRelationshipType :: RelationshipType
_rRelationshipType = RelationshipType
API.ArrayRelationship,
            _rColumnMapping :: HashMap ColumnName ColumnName
_rColumnMapping = [(ColumnName, ColumnName)] -> HashMap ColumnName ColumnName
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HashMap.fromList ([(ColumnName, ColumnName)] -> HashMap ColumnName ColumnName)
-> [(ColumnName, ColumnName)] -> HashMap ColumnName ColumnName
forall a b. (a -> b) -> a -> b
$ (ColumnName -> ColumnName)
-> (ColumnName -> ColumnName)
-> (ColumnName, ColumnName)
-> (ColumnName, ColumnName)
forall a b c d. (a -> b) -> (c -> d) -> (a, c) -> (b, d)
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap ColumnName -> ColumnName
forall source target. From source target => source -> target
Witch.from ColumnName -> ColumnName
forall source target. From source target => source -> target
Witch.from ((ColumnName, ColumnName) -> (ColumnName, ColumnName))
-> [(ColumnName, ColumnName)] -> [(ColumnName, ColumnName)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> HashMap ColumnName ColumnName -> [(ColumnName, ColumnName)]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList (AnnRelationSelectG
  'DataConnector
  (AnnSelectG
     'DataConnector fieldType (UnpreparedValue 'DataConnector))
-> HashMap (Column 'DataConnector) (Column 'DataConnector)
forall (b :: BackendType) a.
AnnRelationSelectG b a -> HashMap (Column b) (Column b)
_aarColumnMapping AnnRelationSelectG
  'DataConnector
  (AnnSelectG
     'DataConnector fieldType (UnpreparedValue 'DataConnector))
arrRel)
          }

      Field -> WriterT writerOutput m Field
forall a. a -> WriterT writerOutput m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
        (Field -> WriterT writerOutput m Field)
-> (RelationshipField -> Field)
-> RelationshipField
-> WriterT writerOutput m Field
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RelationshipField -> Field
API.RelField
        (RelationshipField -> WriterT writerOutput m Field)
-> RelationshipField -> WriterT writerOutput m Field
forall a b. (a -> b) -> a -> b
$ RelationshipName -> Query -> RelationshipField
API.RelationshipField
          RelationshipName
relationshipName
          Query
query

translateTableAggregateFields ::
  ( Has TableRelationships writerOutput,
    Monoid writerOutput,
    MonadError QErr m,
    MonadReader r m,
    Has API.ScalarTypesCapabilities r
  ) =>
  SessionVariables ->
  TableRelationshipsKey ->
  TableAggregateFieldsG 'DataConnector Void (UnpreparedValue 'DataConnector) ->
  CPS.WriterT writerOutput m FieldsAndAggregates
translateTableAggregateFields :: forall writerOutput (m :: * -> *) r.
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> TableRelationshipsKey
-> Fields
     (TableAggregateFieldG
        'DataConnector Void (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m FieldsAndAggregates
translateTableAggregateFields SessionVariables
sessionVariables TableRelationshipsKey
sourceName Fields
  (TableAggregateFieldG
     'DataConnector Void (UnpreparedValue 'DataConnector))
fields = do
  [FieldsAndAggregates] -> FieldsAndAggregates
forall a. Monoid a => [a] -> a
mconcat ([FieldsAndAggregates] -> FieldsAndAggregates)
-> WriterT writerOutput m [FieldsAndAggregates]
-> WriterT writerOutput m FieldsAndAggregates
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((FieldName,
  TableAggregateFieldG
    'DataConnector Void (UnpreparedValue 'DataConnector))
 -> WriterT writerOutput m FieldsAndAggregates)
-> Fields
     (TableAggregateFieldG
        'DataConnector Void (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m [FieldsAndAggregates]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((FieldName
 -> TableAggregateFieldG
      'DataConnector Void (UnpreparedValue 'DataConnector)
 -> WriterT writerOutput m FieldsAndAggregates)
-> (FieldName,
    TableAggregateFieldG
      'DataConnector Void (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m FieldsAndAggregates
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (SessionVariables
-> TableRelationshipsKey
-> FieldName
-> TableAggregateFieldG
     'DataConnector Void (UnpreparedValue 'DataConnector)
-> WriterT writerOutput m FieldsAndAggregates
forall writerOutput (m :: * -> *) r.
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> TableRelationshipsKey
-> FieldName
-> TableAggregateFieldG
     'DataConnector Void (UnpreparedValue 'DataConnector)
-> WriterT writerOutput m FieldsAndAggregates
translateTableAggregateField SessionVariables
sessionVariables TableRelationshipsKey
sourceName)) Fields
  (TableAggregateFieldG
     'DataConnector Void (UnpreparedValue 'DataConnector))
fields

translateTableAggregateField ::
  ( Has TableRelationships writerOutput,
    Monoid writerOutput,
    MonadError QErr m,
    MonadReader r m,
    Has API.ScalarTypesCapabilities r
  ) =>
  SessionVariables ->
  TableRelationshipsKey ->
  FieldName ->
  TableAggregateFieldG 'DataConnector Void (UnpreparedValue 'DataConnector) ->
  CPS.WriterT writerOutput m FieldsAndAggregates
translateTableAggregateField :: forall writerOutput (m :: * -> *) r.
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> TableRelationshipsKey
-> FieldName
-> TableAggregateFieldG
     'DataConnector Void (UnpreparedValue 'DataConnector)
-> WriterT writerOutput m FieldsAndAggregates
translateTableAggregateField SessionVariables
sessionVariables TableRelationshipsKey
sourceName FieldName
fieldName = \case
  TAFAgg AggregateFields 'DataConnector (UnpreparedValue 'DataConnector)
aggregateFields -> do
    let fieldNamePrefix :: FieldPrefix
fieldNamePrefix = FieldName -> FieldPrefix
prefixWith FieldName
fieldName
    HashMap FieldName Aggregate
translatedAggregateFields <- m (HashMap FieldName Aggregate)
-> WriterT writerOutput m (HashMap FieldName Aggregate)
forall (m :: * -> *) a. Monad m => m a -> WriterT writerOutput m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (HashMap FieldName Aggregate)
 -> WriterT writerOutput m (HashMap FieldName Aggregate))
-> m (HashMap FieldName Aggregate)
-> WriterT writerOutput m (HashMap FieldName Aggregate)
forall a b. (a -> b) -> a -> b
$ [HashMap FieldName Aggregate] -> HashMap FieldName Aggregate
forall a. Monoid a => [a] -> a
mconcat ([HashMap FieldName Aggregate] -> HashMap FieldName Aggregate)
-> m [HashMap FieldName Aggregate]
-> m (HashMap FieldName Aggregate)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((FieldName,
  AggregateField 'DataConnector (UnpreparedValue 'DataConnector))
 -> m (HashMap FieldName Aggregate))
-> AggregateFields 'DataConnector (UnpreparedValue 'DataConnector)
-> m [HashMap FieldName Aggregate]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((FieldName
 -> AggregateField 'DataConnector (UnpreparedValue 'DataConnector)
 -> m (HashMap FieldName Aggregate))
-> (FieldName,
    AggregateField 'DataConnector (UnpreparedValue 'DataConnector))
-> m (HashMap FieldName Aggregate)
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (FieldPrefix
-> FieldName
-> AggregateField 'DataConnector (UnpreparedValue 'DataConnector)
-> m (HashMap FieldName Aggregate)
forall (m :: * -> *).
MonadError QErr m =>
FieldPrefix
-> FieldName
-> AggregateField 'DataConnector (UnpreparedValue 'DataConnector)
-> m (HashMap FieldName Aggregate)
translateAggregateField FieldPrefix
fieldNamePrefix)) AggregateFields 'DataConnector (UnpreparedValue 'DataConnector)
aggregateFields
    FieldsAndAggregates -> WriterT writerOutput m FieldsAndAggregates
forall a. a -> WriterT writerOutput m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
      (FieldsAndAggregates -> WriterT writerOutput m FieldsAndAggregates)
-> FieldsAndAggregates
-> WriterT writerOutput m FieldsAndAggregates
forall a b. (a -> b) -> a -> b
$ Maybe (HashMap FieldName Field)
-> Maybe (HashMap FieldName Aggregate) -> FieldsAndAggregates
FieldsAndAggregates
        Maybe (HashMap FieldName Field)
forall a. Maybe a
Nothing
        (HashMap FieldName Aggregate -> Maybe (HashMap FieldName Aggregate)
forall a. a -> Maybe a
Just HashMap FieldName Aggregate
translatedAggregateFields)
  TAFNodes XNodesAgg 'DataConnector
_ Fields
  (AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
fields ->
    SessionVariables
-> FieldPrefix
-> TableRelationshipsKey
-> Fields
     (AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m FieldsAndAggregates
forall writerOutput (m :: * -> *) r.
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> FieldPrefix
-> TableRelationshipsKey
-> Fields
     (AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m FieldsAndAggregates
translateAnnFieldsWithNoAggregates SessionVariables
sessionVariables (FieldName -> FieldPrefix
prefixWith FieldName
fieldName) TableRelationshipsKey
sourceName Fields
  (AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
fields
  TAFExp Text
_txt ->
    -- We ignore literal text fields (we don't send them to the data connector agent)
    -- and add them back to the response JSON when we reshape what the agent returns
    -- to us
    FieldsAndAggregates -> WriterT writerOutput m FieldsAndAggregates
forall a. a -> WriterT writerOutput m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure FieldsAndAggregates
forall a. Monoid a => a
mempty

translateAggregateField ::
  (MonadError QErr m) =>
  FieldPrefix ->
  FieldName ->
  AggregateField 'DataConnector (UnpreparedValue 'DataConnector) ->
  m (HashMap FieldName API.Aggregate)
translateAggregateField :: forall (m :: * -> *).
MonadError QErr m =>
FieldPrefix
-> FieldName
-> AggregateField 'DataConnector (UnpreparedValue 'DataConnector)
-> m (HashMap FieldName Aggregate)
translateAggregateField FieldPrefix
fieldPrefix FieldName
fieldName = \case
  AFCount CountType 'DataConnector (UnpreparedValue 'DataConnector)
countAggregate ->
    let aggregate :: Aggregate
aggregate =
          case CountType 'DataConnector (UnpreparedValue 'DataConnector)
countAggregate of
            CountType 'DataConnector (UnpreparedValue 'DataConnector)
CountAggregate (UnpreparedValue 'DataConnector)
StarCount -> Aggregate
API.StarCount
            -- TODO(redactionExp): Do something with these redaction expressions
            ColumnCount (ColumnName
column, AnnRedactionExp 'DataConnector (UnpreparedValue 'DataConnector)
_redactionExp) -> ColumnCountAggregate -> Aggregate
API.ColumnCount (ColumnCountAggregate -> Aggregate)
-> ColumnCountAggregate -> Aggregate
forall a b. (a -> b) -> a -> b
$ API.ColumnCountAggregate {_ccaColumn :: ColumnName
_ccaColumn = ColumnName -> ColumnName
forall source target. From source target => source -> target
Witch.from ColumnName
column, _ccaDistinct :: Bool
_ccaDistinct = Bool
False}
            ColumnDistinctCount (ColumnName
column, AnnRedactionExp 'DataConnector (UnpreparedValue 'DataConnector)
_redactionExp) -> ColumnCountAggregate -> Aggregate
API.ColumnCount (ColumnCountAggregate -> Aggregate)
-> ColumnCountAggregate -> Aggregate
forall a b. (a -> b) -> a -> b
$ API.ColumnCountAggregate {_ccaColumn :: ColumnName
_ccaColumn = ColumnName -> ColumnName
forall source target. From source target => source -> target
Witch.from ColumnName
column, _ccaDistinct :: Bool
_ccaDistinct = Bool
True}
     in HashMap FieldName Aggregate -> m (HashMap FieldName Aggregate)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (HashMap FieldName Aggregate -> m (HashMap FieldName Aggregate))
-> HashMap FieldName Aggregate -> m (HashMap FieldName Aggregate)
forall a b. (a -> b) -> a -> b
$ FieldName -> Aggregate -> HashMap FieldName Aggregate
forall k v. Hashable k => k -> v -> HashMap k v
HashMap.singleton (FieldPrefix -> FieldName -> FieldName
applyPrefix FieldPrefix
fieldPrefix FieldName
fieldName) Aggregate
aggregate
  AFOp AggregateOp {SelectionFields 'DataConnector (UnpreparedValue 'DataConnector)
Text
_aoOp :: Text
_aoFields :: SelectionFields 'DataConnector (UnpreparedValue 'DataConnector)
$sel:_aoOp:AggregateOp :: forall (b :: BackendType) v. AggregateOp b v -> Text
$sel:_aoFields:AggregateOp :: forall (b :: BackendType) v. AggregateOp b v -> SelectionFields b v
..} -> do
    let fieldPrefix' :: FieldPrefix
fieldPrefix' = FieldPrefix
fieldPrefix FieldPrefix -> FieldPrefix -> FieldPrefix
forall a. Semigroup a => a -> a -> a
<> FieldName -> FieldPrefix
prefixWith FieldName
fieldName
    SingleColumnAggregateFunction
aggFunction <- Text -> m SingleColumnAggregateFunction
forall (m :: * -> *).
MonadError QErr m =>
Text -> m SingleColumnAggregateFunction
translateSingleColumnAggregateFunction Text
_aoOp

    ([Maybe (FieldName, Aggregate)] -> HashMap FieldName Aggregate)
-> m [Maybe (FieldName, Aggregate)]
-> m (HashMap FieldName Aggregate)
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([(FieldName, Aggregate)] -> HashMap FieldName Aggregate
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HashMap.fromList ([(FieldName, Aggregate)] -> HashMap FieldName Aggregate)
-> ([Maybe (FieldName, Aggregate)] -> [(FieldName, Aggregate)])
-> [Maybe (FieldName, Aggregate)]
-> HashMap FieldName Aggregate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Maybe (FieldName, Aggregate)] -> [(FieldName, Aggregate)]
forall a. [Maybe a] -> [a]
forall (f :: * -> *) a. Filterable f => f (Maybe a) -> f a
catMaybes) (m [Maybe (FieldName, Aggregate)]
 -> m (HashMap FieldName Aggregate))
-> (((FieldName,
      SelectionField 'DataConnector (UnpreparedValue 'DataConnector))
     -> m (Maybe (FieldName, Aggregate)))
    -> m [Maybe (FieldName, Aggregate)])
-> ((FieldName,
     SelectionField 'DataConnector (UnpreparedValue 'DataConnector))
    -> m (Maybe (FieldName, Aggregate)))
-> m (HashMap FieldName Aggregate)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SelectionFields 'DataConnector (UnpreparedValue 'DataConnector)
-> ((FieldName,
     SelectionField 'DataConnector (UnpreparedValue 'DataConnector))
    -> m (Maybe (FieldName, Aggregate)))
-> m [Maybe (FieldName, Aggregate)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM SelectionFields 'DataConnector (UnpreparedValue 'DataConnector)
_aoFields (((FieldName,
   SelectionField 'DataConnector (UnpreparedValue 'DataConnector))
  -> m (Maybe (FieldName, Aggregate)))
 -> m (HashMap FieldName Aggregate))
-> ((FieldName,
     SelectionField 'DataConnector (UnpreparedValue 'DataConnector))
    -> m (Maybe (FieldName, Aggregate)))
-> m (HashMap FieldName Aggregate)
forall a b. (a -> b) -> a -> b
$ \(FieldName
columnFieldName, SelectionField 'DataConnector (UnpreparedValue 'DataConnector)
columnField) ->
      case SelectionField 'DataConnector (UnpreparedValue 'DataConnector)
columnField of
        -- TODO(redactionExp): Do something with the redactionExp
        SFCol Column 'DataConnector
column ColumnType 'DataConnector
resultType AnnRedactionExp 'DataConnector (UnpreparedValue 'DataConnector)
_redactionExp ->
          let resultScalarType :: ScalarType
resultScalarType = ScalarType -> ScalarType
forall source target. From source target => source -> target
Witch.from (ScalarType -> ScalarType) -> ScalarType -> ScalarType
forall a b. (a -> b) -> a -> b
$ ColumnType 'DataConnector -> ScalarType
columnTypeToScalarType ColumnType 'DataConnector
resultType
           in Maybe (FieldName, Aggregate) -> m (Maybe (FieldName, Aggregate))
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe (FieldName, Aggregate) -> m (Maybe (FieldName, Aggregate)))
-> ((FieldName, Aggregate) -> Maybe (FieldName, Aggregate))
-> (FieldName, Aggregate)
-> m (Maybe (FieldName, Aggregate))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (FieldName, Aggregate) -> Maybe (FieldName, Aggregate)
forall a. a -> Maybe a
Just ((FieldName, Aggregate) -> m (Maybe (FieldName, Aggregate)))
-> (FieldName, Aggregate) -> m (Maybe (FieldName, Aggregate))
forall a b. (a -> b) -> a -> b
$ (FieldPrefix -> FieldName -> FieldName
applyPrefix FieldPrefix
fieldPrefix' FieldName
columnFieldName, SingleColumnAggregate -> Aggregate
API.SingleColumn (SingleColumnAggregate -> Aggregate)
-> SingleColumnAggregate -> Aggregate
forall a b. (a -> b) -> a -> b
$ SingleColumnAggregateFunction
-> ColumnName -> ScalarType -> SingleColumnAggregate
API.SingleColumnAggregate SingleColumnAggregateFunction
aggFunction (ColumnName -> ColumnName
forall source target. From source target => source -> target
Witch.from Column 'DataConnector
ColumnName
column) ScalarType
resultScalarType)
        SFExp Text
_txt ->
          -- We ignore literal text fields (we don't send them to the data connector agent)
          -- and add them back to the response JSON when we reshape what the agent returns
          -- to us
          Maybe (FieldName, Aggregate) -> m (Maybe (FieldName, Aggregate))
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (FieldName, Aggregate)
forall a. Maybe a
Nothing
        -- See Hasura.RQL.Types.Backend.supportsAggregateComputedFields
        SFComputedField ComputedFieldName
_ ComputedFieldScalarSelect
  'DataConnector (UnpreparedValue 'DataConnector)
_ -> String -> m (Maybe (FieldName, Aggregate))
forall a. HasCallStack => String -> a
error String
"Aggregate computed fields aren't currently supported for Data Connectors!"
  AFExp Text
_txt ->
    -- We ignore literal text fields (we don't send them to the data connector agent)
    -- and add them back to the response JSON when we reshape what the agent returns
    -- to us
    HashMap FieldName Aggregate -> m (HashMap FieldName Aggregate)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure HashMap FieldName Aggregate
forall a. Monoid a => a
mempty

translateSingleColumnAggregateFunction :: (MonadError QErr m) => Text -> m API.SingleColumnAggregateFunction
translateSingleColumnAggregateFunction :: forall (m :: * -> *).
MonadError QErr m =>
Text -> m SingleColumnAggregateFunction
translateSingleColumnAggregateFunction Text
functionName =
  (Name -> SingleColumnAggregateFunction)
-> Maybe Name -> Maybe SingleColumnAggregateFunction
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Name -> SingleColumnAggregateFunction
API.SingleColumnAggregateFunction (Text -> Maybe Name
G.mkName Text
functionName)
    Maybe SingleColumnAggregateFunction
-> m SingleColumnAggregateFunction
-> m SingleColumnAggregateFunction
forall (m :: * -> *) a. Applicative m => Maybe a -> m a -> m a
`onNothing` Text -> m SingleColumnAggregateFunction
forall (m :: * -> *) a. QErrM m => Text -> m a
throw500 (Text
"translateSingleColumnAggregateFunction: Invalid aggregate function encountered: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
functionName)

translateNestedObjectSelect ::
  ( Has TableRelationships writerOutput,
    Monoid writerOutput,
    MonadError QErr m,
    MonadReader r m,
    Has API.ScalarTypesCapabilities r
  ) =>
  SessionVariables ->
  TableRelationshipsKey ->
  AnnNestedObjectSelectG 'DataConnector Void (UnpreparedValue 'DataConnector) ->
  CPS.WriterT writerOutput m API.Query
translateNestedObjectSelect :: forall writerOutput (m :: * -> *) r.
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> TableRelationshipsKey
-> AnnNestedObjectSelectG
     'DataConnector Void (UnpreparedValue 'DataConnector)
-> WriterT writerOutput m Query
translateNestedObjectSelect SessionVariables
sessionVariables TableRelationshipsKey
relationshipKey AnnNestedObjectSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
selectG = do
  FieldsAndAggregates {Maybe (HashMap FieldName Aggregate)
Maybe (HashMap FieldName Field)
_faaFields :: FieldsAndAggregates -> Maybe (HashMap FieldName Field)
_faaAggregates :: FieldsAndAggregates -> Maybe (HashMap FieldName Aggregate)
_faaFields :: Maybe (HashMap FieldName Field)
_faaAggregates :: Maybe (HashMap FieldName Aggregate)
..} <- SessionVariables
-> FieldPrefix
-> TableRelationshipsKey
-> Fields
     (AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m FieldsAndAggregates
forall writerOutput (m :: * -> *) r.
(Has TableRelationships writerOutput, Monoid writerOutput,
 MonadError QErr m, MonadReader r m,
 Has ScalarTypesCapabilities r) =>
SessionVariables
-> FieldPrefix
-> TableRelationshipsKey
-> Fields
     (AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m FieldsAndAggregates
translateAnnFieldsWithNoAggregates SessionVariables
sessionVariables FieldPrefix
noPrefix TableRelationshipsKey
relationshipKey (Fields
   (AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
 -> WriterT writerOutput m FieldsAndAggregates)
-> Fields
     (AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
-> WriterT writerOutput m FieldsAndAggregates
forall a b. (a -> b) -> a -> b
$ AnnNestedObjectSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
-> Fields
     (AnnFieldG 'DataConnector Void (UnpreparedValue 'DataConnector))
forall (b :: BackendType) r v.
AnnNestedObjectSelectG b r v -> AnnFieldsG b r v
_anosFields AnnNestedObjectSelectG
  'DataConnector Void (UnpreparedValue 'DataConnector)
selectG
  Query -> WriterT writerOutput m Query
forall a. a -> WriterT writerOutput m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
    API.Query
      { _qFields :: Maybe (HashMap FieldName Field)
_qFields = HashMap FieldName Field -> HashMap FieldName Field
forall v. HashMap FieldName v -> HashMap FieldName v
mapFieldNameHashMap (HashMap FieldName Field -> HashMap FieldName Field)
-> Maybe (HashMap FieldName Field)
-> Maybe (HashMap FieldName Field)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (HashMap FieldName Field)
_faaFields,
        _qAggregates :: Maybe (HashMap FieldName Aggregate)
_qAggregates = Maybe (HashMap FieldName Aggregate)
forall a. Maybe a
Nothing,
        _qAggregatesLimit :: Maybe Int
_qAggregatesLimit = Maybe Int
forall a. Maybe a
Nothing,
        _qLimit :: Maybe Int
_qLimit = Maybe Int
forall a. Maybe a
Nothing,
        _qOffset :: Maybe Int
_qOffset = Maybe Int
forall a. Maybe a
Nothing,
        _qWhere :: Maybe Expression
_qWhere = Maybe Expression
forall a. Maybe a
Nothing,
        _qOrderBy :: Maybe OrderBy
_qOrderBy = Maybe OrderBy
forall a. Maybe a
Nothing
      }

--------------------------------------------------------------------------------

reshapeResponseToQueryShape ::
  (MonadError QErr m) =>
  QueryDB 'DataConnector Void v ->
  API.QueryResponse ->
  m J.Encoding
reshapeResponseToQueryShape :: forall (m :: * -> *) v.
MonadError QErr m =>
QueryDB 'DataConnector Void v -> QueryResponse -> m Encoding
reshapeResponseToQueryShape QueryDB 'DataConnector Void v
queryDb QueryResponse
response =
  case QueryDB 'DataConnector Void v
queryDb of
    QDBMultipleRows AnnSimpleSelectG 'DataConnector Void v
simpleSelect -> Cardinality
-> AnnFieldsG 'DataConnector Void v -> QueryResponse -> m Encoding
forall (m :: * -> *) v.
MonadError QErr m =>
Cardinality
-> AnnFieldsG 'DataConnector Void v -> QueryResponse -> m Encoding
reshapeSimpleSelectRows Cardinality
Many (AnnSimpleSelectG 'DataConnector Void v
-> AnnFieldsG 'DataConnector Void v
forall (b :: BackendType) (f :: * -> *) v.
AnnSelectG b f v -> Fields (f v)
_asnFields AnnSimpleSelectG 'DataConnector Void v
simpleSelect) QueryResponse
response
    QDBSingleRow AnnSimpleSelectG 'DataConnector Void v
simpleSelect -> Cardinality
-> AnnFieldsG 'DataConnector Void v -> QueryResponse -> m Encoding
forall (m :: * -> *) v.
MonadError QErr m =>
Cardinality
-> AnnFieldsG 'DataConnector Void v -> QueryResponse -> m Encoding
reshapeSimpleSelectRows Cardinality
Single (AnnSimpleSelectG 'DataConnector Void v
-> AnnFieldsG 'DataConnector Void v
forall (b :: BackendType) (f :: * -> *) v.
AnnSelectG b f v -> Fields (f v)
_asnFields AnnSimpleSelectG 'DataConnector Void v
simpleSelect) QueryResponse
response
    QDBAggregation AnnAggregateSelectG 'DataConnector Void v
aggregateSelect -> TableAggregateFieldsG 'DataConnector Void v
-> QueryResponse -> m Encoding
forall (m :: * -> *) v.
MonadError QErr m =>
TableAggregateFieldsG 'DataConnector Void v
-> QueryResponse -> m Encoding
reshapeTableAggregateFields (AnnAggregateSelectG 'DataConnector Void v
-> TableAggregateFieldsG 'DataConnector Void v
forall (b :: BackendType) (f :: * -> *) v.
AnnSelectG b f v -> Fields (f v)
_asnFields AnnAggregateSelectG 'DataConnector Void v
aggregateSelect) QueryResponse
response

reshapeSimpleSelectRows ::
  (MonadError QErr m) =>
  Cardinality ->
  AnnFieldsG 'DataConnector Void v ->
  API.QueryResponse ->
  m J.Encoding
reshapeSimpleSelectRows :: forall (m :: * -> *) v.
MonadError QErr m =>
Cardinality
-> AnnFieldsG 'DataConnector Void v -> QueryResponse -> m Encoding
reshapeSimpleSelectRows Cardinality
cardinality AnnFieldsG 'DataConnector Void v
fields API.QueryResponse {Maybe [HashMap FieldName FieldValue]
Maybe (HashMap FieldName Value)
_qrRows :: Maybe [HashMap FieldName FieldValue]
_qrAggregates :: Maybe (HashMap FieldName Value)
_qrRows :: QueryResponse -> Maybe [HashMap FieldName FieldValue]
_qrAggregates :: QueryResponse -> Maybe (HashMap FieldName Value)
..} =
  case Cardinality
cardinality of
    Cardinality
Single ->
      case [HashMap FieldName FieldValue]
rows of
        [] -> Encoding -> m Encoding
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Encoding -> m Encoding) -> Encoding -> m Encoding
forall a b. (a -> b) -> a -> b
$ Value -> Encoding
forall a. ToJSON a => a -> Encoding
J.toEncoding Value
J.Null
        [HashMap FieldName FieldValue
singleRow] -> FieldPrefix
-> AnnFieldsG 'DataConnector Void v
-> HashMap FieldName FieldValue
-> m Encoding
forall (m :: * -> *) v.
MonadError QErr m =>
FieldPrefix
-> AnnFieldsG 'DataConnector Void v
-> HashMap FieldName FieldValue
-> m Encoding
reshapeAnnFields FieldPrefix
noPrefix AnnFieldsG 'DataConnector Void v
fields HashMap FieldName FieldValue
singleRow
        [HashMap FieldName FieldValue]
_multipleRows ->
          Text -> m Encoding
forall (m :: * -> *) a. QErrM m => Text -> m a
throw500 Text
"Data Connector agent returned multiple rows when only one was expected" -- TODO(dchambers): Add pathing information for error clarity
    Cardinality
Many -> do
      [Encoding]
reshapedRows <- (HashMap FieldName FieldValue -> m Encoding)
-> [HashMap FieldName FieldValue] -> m [Encoding]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse (FieldPrefix
-> AnnFieldsG 'DataConnector Void v
-> HashMap FieldName FieldValue
-> m Encoding
forall (m :: * -> *) v.
MonadError QErr m =>
FieldPrefix
-> AnnFieldsG 'DataConnector Void v
-> HashMap FieldName FieldValue
-> m Encoding
reshapeAnnFields FieldPrefix
noPrefix AnnFieldsG 'DataConnector Void v
fields) [HashMap FieldName FieldValue]
rows
      Encoding -> m Encoding
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Encoding -> m Encoding) -> Encoding -> m Encoding
forall a b. (a -> b) -> a -> b
$ (Encoding -> Encoding) -> [Encoding] -> Encoding
forall a. (a -> Encoding) -> [a] -> Encoding
JE.list Encoding -> Encoding
forall a. a -> a
id [Encoding]
reshapedRows
  where
    rows :: [HashMap FieldName FieldValue]
rows = [HashMap FieldName FieldValue]
-> Maybe [HashMap FieldName FieldValue]
-> [HashMap FieldName FieldValue]
forall a. a -> Maybe a -> a
fromMaybe [HashMap FieldName FieldValue]
forall a. Monoid a => a
mempty Maybe [HashMap FieldName FieldValue]
_qrRows

reshapeTableAggregateFields ::
  (MonadError QErr m) =>
  TableAggregateFieldsG 'DataConnector Void v ->
  API.QueryResponse ->
  m J.Encoding
reshapeTableAggregateFields :: forall (m :: * -> *) v.
MonadError QErr m =>
TableAggregateFieldsG 'DataConnector Void v
-> QueryResponse -> m Encoding
reshapeTableAggregateFields TableAggregateFieldsG 'DataConnector Void v
tableAggregateFields API.QueryResponse {Maybe [HashMap FieldName FieldValue]
Maybe (HashMap FieldName Value)
_qrRows :: QueryResponse -> Maybe [HashMap FieldName FieldValue]
_qrAggregates :: QueryResponse -> Maybe (HashMap FieldName Value)
_qrRows :: Maybe [HashMap FieldName FieldValue]
_qrAggregates :: Maybe (HashMap FieldName Value)
..} = do
  [(Text, Encoding)]
reshapedFields <- TableAggregateFieldsG 'DataConnector Void v
-> ((FieldName, TableAggregateFieldG 'DataConnector Void v)
    -> m (Text, Encoding))
-> m [(Text, Encoding)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM TableAggregateFieldsG 'DataConnector Void v
tableAggregateFields (((FieldName, TableAggregateFieldG 'DataConnector Void v)
  -> m (Text, Encoding))
 -> m [(Text, Encoding)])
-> ((FieldName, TableAggregateFieldG 'DataConnector Void v)
    -> m (Text, Encoding))
-> m [(Text, Encoding)]
forall a b. (a -> b) -> a -> b
$ \(fieldName :: FieldName
fieldName@(FieldName Text
fieldNameText), TableAggregateFieldG 'DataConnector Void v
tableAggregateField) -> do
    case TableAggregateFieldG 'DataConnector Void v
tableAggregateField of
      TAFAgg AggregateFields 'DataConnector v
aggregateFields -> do
        Encoding
reshapedAggregateFields <- FieldPrefix
-> AggregateFields 'DataConnector v
-> HashMap FieldName Value
-> m Encoding
forall (m :: * -> *) v.
MonadError QErr m =>
FieldPrefix
-> AggregateFields 'DataConnector v
-> HashMap FieldName Value
-> m Encoding
reshapeAggregateFields (FieldName -> FieldPrefix
prefixWith FieldName
fieldName) AggregateFields 'DataConnector v
aggregateFields HashMap FieldName Value
responseAggregates
        (Text, Encoding) -> m (Text, Encoding)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((Text, Encoding) -> m (Text, Encoding))
-> (Text, Encoding) -> m (Text, Encoding)
forall a b. (a -> b) -> a -> b
$ (Text
fieldNameText, Encoding
reshapedAggregateFields)
      TAFNodes XNodesAgg 'DataConnector
_ AnnFieldsG 'DataConnector Void v
annFields -> do
        [Encoding]
reshapedRows <- (HashMap FieldName FieldValue -> m Encoding)
-> [HashMap FieldName FieldValue] -> m [Encoding]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse (FieldPrefix
-> AnnFieldsG 'DataConnector Void v
-> HashMap FieldName FieldValue
-> m Encoding
forall (m :: * -> *) v.
MonadError QErr m =>
FieldPrefix
-> AnnFieldsG 'DataConnector Void v
-> HashMap FieldName FieldValue
-> m Encoding
reshapeAnnFields (FieldName -> FieldPrefix
prefixWith FieldName
fieldName) AnnFieldsG 'DataConnector Void v
annFields) [HashMap FieldName FieldValue]
responseRows
        (Text, Encoding) -> m (Text, Encoding)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((Text, Encoding) -> m (Text, Encoding))
-> (Text, Encoding) -> m (Text, Encoding)
forall a b. (a -> b) -> a -> b
$ (Text
fieldNameText, (Encoding -> Encoding) -> [Encoding] -> Encoding
forall a. (a -> Encoding) -> [a] -> Encoding
JE.list Encoding -> Encoding
forall a. a -> a
id [Encoding]
reshapedRows)
      TAFExp Text
txt ->
        (Text, Encoding) -> m (Text, Encoding)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((Text, Encoding) -> m (Text, Encoding))
-> (Text, Encoding) -> m (Text, Encoding)
forall a b. (a -> b) -> a -> b
$ (Text
fieldNameText, Text -> Encoding
forall a. Text -> Encoding' a
JE.text Text
txt)
  Encoding -> m Encoding
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Encoding -> m Encoding) -> Encoding -> m Encoding
forall a b. (a -> b) -> a -> b
$ [(Text, Encoding)] -> Encoding
encodeAssocListAsObject [(Text, Encoding)]
reshapedFields
  where
    responseRows :: [HashMap FieldName FieldValue]
responseRows = [HashMap FieldName FieldValue]
-> Maybe [HashMap FieldName FieldValue]
-> [HashMap FieldName FieldValue]
forall a. a -> Maybe a -> a
fromMaybe [HashMap FieldName FieldValue]
forall a. Monoid a => a
mempty Maybe [HashMap FieldName FieldValue]
_qrRows
    responseAggregates :: HashMap FieldName Value
responseAggregates = HashMap FieldName Value
-> Maybe (HashMap FieldName Value) -> HashMap FieldName Value
forall a. a -> Maybe a -> a
fromMaybe HashMap FieldName Value
forall a. Monoid a => a
mempty Maybe (HashMap FieldName Value)
_qrAggregates

reshapeAggregateFields ::
  (MonadError QErr m) =>
  FieldPrefix ->
  AggregateFields 'DataConnector v ->
  HashMap API.FieldName J.Value ->
  m J.Encoding
reshapeAggregateFields :: forall (m :: * -> *) v.
MonadError QErr m =>
FieldPrefix
-> AggregateFields 'DataConnector v
-> HashMap FieldName Value
-> m Encoding
reshapeAggregateFields FieldPrefix
fieldPrefix AggregateFields 'DataConnector v
aggregateFields HashMap FieldName Value
responseAggregates = do
  [(Text, Encoding)]
reshapedFields <- AggregateFields 'DataConnector v
-> ((FieldName, AggregateField 'DataConnector v)
    -> m (Text, Encoding))
-> m [(Text, Encoding)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM AggregateFields 'DataConnector v
aggregateFields (((FieldName, AggregateField 'DataConnector v)
  -> m (Text, Encoding))
 -> m [(Text, Encoding)])
-> ((FieldName, AggregateField 'DataConnector v)
    -> m (Text, Encoding))
-> m [(Text, Encoding)]
forall a b. (a -> b) -> a -> b
$ \(fieldName :: FieldName
fieldName@(FieldName Text
fieldNameText), AggregateField 'DataConnector v
aggregateField) ->
    case AggregateField 'DataConnector v
aggregateField of
      AFCount CountType 'DataConnector v
_countAggregate -> do
        let fieldNameKey :: FieldName
fieldNameKey = Text -> FieldName
API.FieldName (Text -> FieldName)
-> (FieldName -> Text) -> FieldName -> FieldName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FieldName -> Text
getFieldNameTxt (FieldName -> FieldName) -> FieldName -> FieldName
forall a b. (a -> b) -> a -> b
$ FieldPrefix -> FieldName -> FieldName
applyPrefix FieldPrefix
fieldPrefix FieldName
fieldName
        Value
responseAggregateValue <-
          FieldName -> HashMap FieldName Value -> Maybe Value
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup FieldName
fieldNameKey HashMap FieldName Value
responseAggregates
            Maybe Value -> m Value -> m Value
forall (m :: * -> *) a. Applicative m => Maybe a -> m a -> m a
`onNothing` Text -> m Value
forall (m :: * -> *) a. QErrM m => Text -> m a
throw500 (Text
"Unable to find expected aggregate " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> FieldName -> Text
API.unFieldName FieldName
fieldNameKey Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" in aggregates returned by Data Connector agent") -- TODO(dchambers): Add pathing information for error clarity
        (Text, Encoding) -> m (Text, Encoding)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text
fieldNameText, Value -> Encoding
forall a. ToJSON a => a -> Encoding
J.toEncoding Value
responseAggregateValue)
      AFOp AggregateOp {SelectionFields 'DataConnector v
Text
$sel:_aoOp:AggregateOp :: forall (b :: BackendType) v. AggregateOp b v -> Text
$sel:_aoFields:AggregateOp :: forall (b :: BackendType) v. AggregateOp b v -> SelectionFields b v
_aoOp :: Text
_aoFields :: SelectionFields 'DataConnector v
..} -> do
        [(Text, Encoding)]
reshapedColumnFields <- SelectionFields 'DataConnector v
-> ((FieldName, SelectionField 'DataConnector v)
    -> m (Text, Encoding))
-> m [(Text, Encoding)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM SelectionFields 'DataConnector v
_aoFields (((FieldName, SelectionField 'DataConnector v)
  -> m (Text, Encoding))
 -> m [(Text, Encoding)])
-> ((FieldName, SelectionField 'DataConnector v)
    -> m (Text, Encoding))
-> m [(Text, Encoding)]
forall a b. (a -> b) -> a -> b
$ \(columnFieldName :: FieldName
columnFieldName@(FieldName Text
columnFieldNameText), SelectionField 'DataConnector v
columnField) ->
          case SelectionField 'DataConnector v
columnField of
            SFCol Column 'DataConnector
_column ColumnType 'DataConnector
_columnType AnnRedactionExp 'DataConnector v
_redactionExp -> do
              let fieldPrefix' :: FieldPrefix
fieldPrefix' = FieldPrefix
fieldPrefix FieldPrefix -> FieldPrefix -> FieldPrefix
forall a. Semigroup a => a -> a -> a
<> FieldName -> FieldPrefix
prefixWith FieldName
fieldName
              let columnFieldNameKey :: FieldName
columnFieldNameKey = Text -> FieldName
API.FieldName (Text -> FieldName)
-> (FieldName -> Text) -> FieldName -> FieldName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FieldName -> Text
getFieldNameTxt (FieldName -> FieldName) -> FieldName -> FieldName
forall a b. (a -> b) -> a -> b
$ FieldPrefix -> FieldName -> FieldName
applyPrefix FieldPrefix
fieldPrefix' FieldName
columnFieldName
              Value
responseAggregateValue <-
                FieldName -> HashMap FieldName Value -> Maybe Value
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup FieldName
columnFieldNameKey HashMap FieldName Value
responseAggregates
                  Maybe Value -> m Value -> m Value
forall (m :: * -> *) a. Applicative m => Maybe a -> m a -> m a
`onNothing` Text -> m Value
forall (m :: * -> *) a. QErrM m => Text -> m a
throw500 (Text
"Unable to find expected aggregate " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> FieldName -> Text
API.unFieldName FieldName
columnFieldNameKey Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" in aggregates returned by Data Connector agent") -- TODO(dchambers): Add pathing information for error clarity
              (Text, Encoding) -> m (Text, Encoding)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text
columnFieldNameText, Value -> Encoding
forall a. ToJSON a => a -> Encoding
J.toEncoding Value
responseAggregateValue)
            SFExp Text
txt ->
              (Text, Encoding) -> m (Text, Encoding)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text
columnFieldNameText, Text -> Encoding
forall a. Text -> Encoding' a
JE.text Text
txt)
            -- See Hasura.RQL.Types.Backend.supportsAggregateComputedFields
            SFComputedField ComputedFieldName
_ ComputedFieldScalarSelect 'DataConnector v
_ -> String -> m (Text, Encoding)
forall a. HasCallStack => String -> a
error String
"Aggregate computed fields aren't currently supported for Data Connectors!"

        (Text, Encoding) -> m (Text, Encoding)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text
fieldNameText, [(Text, Encoding)] -> Encoding
encodeAssocListAsObject [(Text, Encoding)]
reshapedColumnFields)
      AFExp Text
txt ->
        (Text, Encoding) -> m (Text, Encoding)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text
fieldNameText, Text -> Encoding
forall a. Text -> Encoding' a
JE.text Text
txt)
  Encoding -> m Encoding
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Encoding -> m Encoding) -> Encoding -> m Encoding
forall a b. (a -> b) -> a -> b
$ [(Text, Encoding)] -> Encoding
encodeAssocListAsObject [(Text, Encoding)]
reshapedFields

reshapeAnnFields ::
  (MonadError QErr m) =>
  FieldPrefix ->
  AnnFieldsG 'DataConnector Void v ->
  HashMap API.FieldName API.FieldValue ->
  m J.Encoding
reshapeAnnFields :: forall (m :: * -> *) v.
MonadError QErr m =>
FieldPrefix
-> AnnFieldsG 'DataConnector Void v
-> HashMap FieldName FieldValue
-> m Encoding
reshapeAnnFields FieldPrefix
fieldNamePrefix AnnFieldsG 'DataConnector Void v
fields HashMap FieldName FieldValue
responseRow = do
  [(Text, Encoding)]
reshapedFields <- AnnFieldsG 'DataConnector Void v
-> ((FieldName, AnnFieldG 'DataConnector Void v)
    -> m (Text, Encoding))
-> m [(Text, Encoding)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM AnnFieldsG 'DataConnector Void v
fields (((FieldName, AnnFieldG 'DataConnector Void v)
  -> m (Text, Encoding))
 -> m [(Text, Encoding)])
-> ((FieldName, AnnFieldG 'DataConnector Void v)
    -> m (Text, Encoding))
-> m [(Text, Encoding)]
forall a b. (a -> b) -> a -> b
$ \(fieldName :: FieldName
fieldName@(FieldName Text
fieldNameText), AnnFieldG 'DataConnector Void v
field) -> do
    let fieldNameKey :: FieldName
fieldNameKey = Text -> FieldName
API.FieldName (Text -> FieldName)
-> (FieldName -> Text) -> FieldName -> FieldName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FieldName -> Text
getFieldNameTxt (FieldName -> FieldName) -> FieldName -> FieldName
forall a b. (a -> b) -> a -> b
$ FieldPrefix -> FieldName -> FieldName
applyPrefix FieldPrefix
fieldNamePrefix FieldName
fieldName
    let responseField :: FieldValue
responseField = FieldValue -> Maybe FieldValue -> FieldValue
forall a. a -> Maybe a -> a
fromMaybe FieldValue
API.nullFieldValue (Maybe FieldValue -> FieldValue) -> Maybe FieldValue -> FieldValue
forall a b. (a -> b) -> a -> b
$ FieldName -> HashMap FieldName FieldValue -> Maybe FieldValue
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup FieldName
fieldNameKey HashMap FieldName FieldValue
responseRow
    Encoding
reshapedField <- AnnFieldG 'DataConnector Void v -> FieldValue -> m Encoding
forall (m :: * -> *) v.
MonadError QErr m =>
AnnFieldG 'DataConnector Void v -> FieldValue -> m Encoding
reshapeField AnnFieldG 'DataConnector Void v
field FieldValue
responseField
    (Text, Encoding) -> m (Text, Encoding)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text
fieldNameText, Encoding
reshapedField)

  Encoding -> m Encoding
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Encoding -> m Encoding) -> Encoding -> m Encoding
forall a b. (a -> b) -> a -> b
$ [(Text, Encoding)] -> Encoding
encodeAssocListAsObject [(Text, Encoding)]
reshapedFields

reshapeField ::
  (MonadError QErr m) =>
  AnnFieldG 'DataConnector Void v ->
  API.FieldValue ->
  m J.Encoding
reshapeField :: forall (m :: * -> *) v.
MonadError QErr m =>
AnnFieldG 'DataConnector Void v -> FieldValue -> m Encoding
reshapeField AnnFieldG 'DataConnector Void v
field FieldValue
responseFieldValue =
  case AnnFieldG 'DataConnector Void v
field of
    AFNestedObject AnnNestedObjectSelectG 'DataConnector Void v
nestedObj ->
      FieldValue -> m Encoding -> m Encoding
forall {f :: * -> *}.
Applicative f =>
FieldValue -> f Encoding -> f Encoding
handleNull FieldValue
responseFieldValue
        (m Encoding -> m Encoding) -> m Encoding -> m Encoding
forall a b. (a -> b) -> a -> b
$ case FieldValue -> Either Text (HashMap FieldName FieldValue)
API.deserializeAsNestedObjFieldValue FieldValue
responseFieldValue of
          Left Text
err -> Text -> m Encoding
forall (m :: * -> *) a. QErrM m => Text -> m a
throw500 (Text -> m Encoding) -> Text -> m Encoding
forall a b. (a -> b) -> a -> b
$ Text
"Expected object in field returned by Data Connector agent: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
err -- TODO(dmoverton): Add pathing information for error clarity
          Right HashMap FieldName FieldValue
nestedResponse ->
            FieldPrefix
-> AnnFieldsG 'DataConnector Void v
-> HashMap FieldName FieldValue
-> m Encoding
forall (m :: * -> *) v.
MonadError QErr m =>
FieldPrefix
-> AnnFieldsG 'DataConnector Void v
-> HashMap FieldName FieldValue
-> m Encoding
reshapeAnnFields FieldPrefix
noPrefix (AnnNestedObjectSelectG 'DataConnector Void v
-> AnnFieldsG 'DataConnector Void v
forall (b :: BackendType) r v.
AnnNestedObjectSelectG b r v -> AnnFieldsG b r v
_anosFields AnnNestedObjectSelectG 'DataConnector Void v
nestedObj) HashMap FieldName FieldValue
nestedResponse
    AFNestedArray XNestedObjects 'DataConnector
_ (ANASSimple AnnFieldG 'DataConnector Void v
arrayField) ->
      FieldValue -> m Encoding -> m Encoding
forall {f :: * -> *}.
Applicative f =>
FieldValue -> f Encoding -> f Encoding
handleNull FieldValue
responseFieldValue
        (m Encoding -> m Encoding) -> m Encoding -> m Encoding
forall a b. (a -> b) -> a -> b
$ case FieldValue -> Either Text [FieldValue]
API.deserializeAsNestedArrayFieldValue FieldValue
responseFieldValue of
          Left Text
err -> Text -> m Encoding
forall (m :: * -> *) a. QErrM m => Text -> m a
throw500 (Text -> m Encoding) -> Text -> m Encoding
forall a b. (a -> b) -> a -> b
$ Text
"Expected array in field returned by Data Connector agent: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
err -- TODO(dmoverton): Add pathing information for error clarity
          Right [FieldValue]
arrayResponse ->
            (Encoding -> Encoding) -> [Encoding] -> Encoding
forall a. (a -> Encoding) -> [a] -> Encoding
JE.list Encoding -> Encoding
forall a. a -> a
id ([Encoding] -> Encoding) -> m [Encoding] -> m Encoding
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (FieldValue -> m Encoding) -> [FieldValue] -> m [Encoding]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse (AnnFieldG 'DataConnector Void v -> FieldValue -> m Encoding
forall (m :: * -> *) v.
MonadError QErr m =>
AnnFieldG 'DataConnector Void v -> FieldValue -> m Encoding
reshapeField AnnFieldG 'DataConnector Void v
arrayField) [FieldValue]
arrayResponse
    AFNestedArray XNestedObjects 'DataConnector
_ (ANASAggregate AnnAggregateSelectG 'DataConnector Void v
_) ->
      Code -> Text -> m Encoding
forall (m :: * -> *) a. QErrM m => Code -> Text -> m a
throw400 Code
NotSupported Text
"Nested array aggregate not supported"
    AFColumn AnnColumnField 'DataConnector v
_columnField -> do
      let columnFieldValue :: Value
columnFieldValue = FieldValue -> Value
API.deserializeAsColumnFieldValue FieldValue
responseFieldValue
      Encoding -> m Encoding
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Encoding -> m Encoding) -> Encoding -> m Encoding
forall a b. (a -> b) -> a -> b
$ Value -> Encoding
forall a. ToJSON a => a -> Encoding
J.toEncoding Value
columnFieldValue
    AFObjectRelation ObjectRelationSelectG 'DataConnector Void v
objectRelationField -> do
      case FieldValue -> Either Text QueryResponse
API.deserializeAsRelationshipFieldValue FieldValue
responseFieldValue of
        Left Text
err -> Text -> m Encoding
forall (m :: * -> *) a. QErrM m => Text -> m a
throw500 (Text -> m Encoding) -> Text -> m Encoding
forall a b. (a -> b) -> a -> b
$ Text
"Found column field value where relationship field value was expected in field returned by Data Connector agent: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
err -- TODO(dchambers): Add pathing information for error clarity
        Right QueryResponse
subqueryResponse ->
          let fields :: AnnFieldsG 'DataConnector Void v
fields = AnnObjectSelectG 'DataConnector Void v
-> AnnFieldsG 'DataConnector Void v
forall (b :: BackendType) r v.
AnnObjectSelectG b r v -> AnnFieldsG b r v
_aosFields (AnnObjectSelectG 'DataConnector Void v
 -> AnnFieldsG 'DataConnector Void v)
-> AnnObjectSelectG 'DataConnector Void v
-> AnnFieldsG 'DataConnector Void v
forall a b. (a -> b) -> a -> b
$ ObjectRelationSelectG 'DataConnector Void v
-> AnnObjectSelectG 'DataConnector Void v
forall (b :: BackendType) a. AnnRelationSelectG b a -> a
_aarAnnSelect ObjectRelationSelectG 'DataConnector Void v
objectRelationField
           in Cardinality
-> AnnFieldsG 'DataConnector Void v -> QueryResponse -> m Encoding
forall (m :: * -> *) v.
MonadError QErr m =>
Cardinality
-> AnnFieldsG 'DataConnector Void v -> QueryResponse -> m Encoding
reshapeSimpleSelectRows Cardinality
Single AnnFieldsG 'DataConnector Void v
fields QueryResponse
subqueryResponse
    AFArrayRelation (ASSimple ArrayRelationSelectG 'DataConnector Void v
simpleArrayRelationField) ->
      (AnnFieldsG 'DataConnector Void v -> QueryResponse -> m Encoding)
-> ArrayRelationSelectG 'DataConnector Void v
-> FieldValue
-> m Encoding
forall (m :: * -> *) (fieldType :: * -> *) v.
MonadError QErr m =>
(Fields (fieldType v) -> QueryResponse -> m Encoding)
-> AnnRelationSelectG
     'DataConnector (AnnSelectG 'DataConnector fieldType v)
-> FieldValue
-> m Encoding
reshapeAnnRelationSelect (Cardinality
-> AnnFieldsG 'DataConnector Void v -> QueryResponse -> m Encoding
forall (m :: * -> *) v.
MonadError QErr m =>
Cardinality
-> AnnFieldsG 'DataConnector Void v -> QueryResponse -> m Encoding
reshapeSimpleSelectRows Cardinality
Many) ArrayRelationSelectG 'DataConnector Void v
simpleArrayRelationField FieldValue
responseFieldValue
    AFArrayRelation (ASAggregate ArrayAggregateSelectG 'DataConnector Void v
aggregateArrayRelationField) ->
      (Fields (TableAggregateFieldG 'DataConnector Void v)
 -> QueryResponse -> m Encoding)
-> ArrayAggregateSelectG 'DataConnector Void v
-> FieldValue
-> m Encoding
forall (m :: * -> *) (fieldType :: * -> *) v.
MonadError QErr m =>
(Fields (fieldType v) -> QueryResponse -> m Encoding)
-> AnnRelationSelectG
     'DataConnector (AnnSelectG 'DataConnector fieldType v)
-> FieldValue
-> m Encoding
reshapeAnnRelationSelect Fields (TableAggregateFieldG 'DataConnector Void v)
-> QueryResponse -> m Encoding
forall (m :: * -> *) v.
MonadError QErr m =>
TableAggregateFieldsG 'DataConnector Void v
-> QueryResponse -> m Encoding
reshapeTableAggregateFields ArrayAggregateSelectG 'DataConnector Void v
aggregateArrayRelationField FieldValue
responseFieldValue
    AFExpression Text
txt -> Encoding -> m Encoding
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Encoding -> m Encoding) -> Encoding -> m Encoding
forall a b. (a -> b) -> a -> b
$ Text -> Encoding
forall a. Text -> Encoding' a
JE.text Text
txt
  where
    handleNull :: FieldValue -> f Encoding -> f Encoding
handleNull FieldValue
v f Encoding
a =
      if FieldValue -> Bool
API.isNullFieldValue FieldValue
v
        then Encoding -> f Encoding
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Encoding
JE.null_
        else f Encoding
a

reshapeAnnRelationSelect ::
  (MonadError QErr m) =>
  (Fields (fieldType v) -> API.QueryResponse -> m J.Encoding) ->
  AnnRelationSelectG 'DataConnector (AnnSelectG 'DataConnector fieldType v) ->
  API.FieldValue ->
  m J.Encoding
reshapeAnnRelationSelect :: forall (m :: * -> *) (fieldType :: * -> *) v.
MonadError QErr m =>
(Fields (fieldType v) -> QueryResponse -> m Encoding)
-> AnnRelationSelectG
     'DataConnector (AnnSelectG 'DataConnector fieldType v)
-> FieldValue
-> m Encoding
reshapeAnnRelationSelect Fields (fieldType v) -> QueryResponse -> m Encoding
reshapeFields AnnRelationSelectG
  'DataConnector (AnnSelectG 'DataConnector fieldType v)
annRelationSelect FieldValue
fieldValue =
  case FieldValue -> Either Text QueryResponse
API.deserializeAsRelationshipFieldValue FieldValue
fieldValue of
    Left Text
err -> Text -> m Encoding
forall (m :: * -> *) a. QErrM m => Text -> m a
throw500 (Text -> m Encoding) -> Text -> m Encoding
forall a b. (a -> b) -> a -> b
$ Text
"Found column field value where relationship field value was expected in field returned by Data Connector agent: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
err -- TODO(dchambers): Add pathing information for error clarity
    Right QueryResponse
subqueryResponse ->
      let annSimpleSelect :: AnnSelectG 'DataConnector fieldType v
annSimpleSelect = AnnRelationSelectG
  'DataConnector (AnnSelectG 'DataConnector fieldType v)
-> AnnSelectG 'DataConnector fieldType v
forall (b :: BackendType) a. AnnRelationSelectG b a -> a
_aarAnnSelect AnnRelationSelectG
  'DataConnector (AnnSelectG 'DataConnector fieldType v)
annRelationSelect
       in Fields (fieldType v) -> QueryResponse -> m Encoding
reshapeFields (AnnSelectG 'DataConnector fieldType v -> Fields (fieldType v)
forall (b :: BackendType) (f :: * -> *) v.
AnnSelectG b f v -> Fields (f v)
_asnFields AnnSelectG 'DataConnector fieldType v
annSimpleSelect) QueryResponse
subqueryResponse