module Hasura.GraphQL.Execute.Query
  ( convertQuerySelSet,
    parseGraphQLQuery,
  )
where

import Data.Aeson qualified as J
import Data.Environment qualified as Env
import Data.HashMap.Strict qualified as HashMap
import Data.HashMap.Strict.InsOrd qualified as InsOrdHashMap
import Data.Tagged qualified as Tagged
import Data.Text.Extended ((<>>))
import Hasura.Base.Error
import Hasura.GraphQL.Context
import Hasura.GraphQL.Execute.Action
import Hasura.GraphQL.Execute.Backend
import Hasura.GraphQL.Execute.Common
import Hasura.GraphQL.Execute.Instances ()
import Hasura.GraphQL.Execute.Remote
import Hasura.GraphQL.Execute.RemoteJoin.Collect qualified as RJ
import Hasura.GraphQL.Execute.Resolve
import Hasura.GraphQL.Namespace
import Hasura.GraphQL.ParameterizedQueryHash
import Hasura.GraphQL.Parser.Directives
import Hasura.GraphQL.Schema.Parser
import Hasura.GraphQL.Transport.HTTP.Protocol qualified as GH
import Hasura.Logging qualified as L
import Hasura.Prelude
import Hasura.QueryTags
import Hasura.QueryTags.Types
import Hasura.RQL.IR
import Hasura.RQL.Types.Action
import Hasura.RQL.Types.Backend
import Hasura.RQL.Types.GraphqlSchemaIntrospection
import Hasura.SQL.AnyBackend qualified as AB
import Hasura.Server.Prometheus (PrometheusMetrics (..))
import Hasura.Server.Types (RequestId (..))
import Hasura.Services.Network
import Hasura.Session
import Hasura.Tracing (MonadTrace)
import Hasura.Tracing qualified as Tracing
import Language.GraphQL.Draft.Syntax qualified as G
import Network.HTTP.Types qualified as HTTP

parseGraphQLQuery ::
  (MonadError QErr m) =>
  GQLContext ->
  [G.VariableDefinition] ->
  Maybe (HashMap G.Name J.Value) ->
  [G.Directive G.Name] ->
  G.SelectionSet G.NoFragments G.Name ->
  m
    ( RootFieldMap (QueryRootField UnpreparedValue),
      [G.Directive Variable],
      G.SelectionSet G.NoFragments Variable
    )
parseGraphQLQuery :: forall (m :: * -> *).
MonadError QErr m =>
GQLContext
-> [VariableDefinition]
-> Maybe (HashMap Name Value)
-> [Directive Name]
-> SelectionSet NoFragments Name
-> m (RootFieldMap (QueryRootField UnpreparedValue),
      [Directive Variable], SelectionSet NoFragments Variable)
parseGraphQLQuery GQLContext
gqlContext [VariableDefinition]
varDefs Maybe (HashMap Name Value)
varValsM [Directive Name]
directives SelectionSet NoFragments Name
fields = do
  ([Directive Variable]
resolvedDirectives, SelectionSet NoFragments Variable
resolvedSelSet) <- [VariableDefinition]
-> HashMap Name Value
-> [Directive Name]
-> SelectionSet NoFragments Name
-> m ([Directive Variable], SelectionSet NoFragments Variable)
forall (m :: * -> *) (fragments :: * -> *).
(MonadError QErr m, Traversable fragments) =>
[VariableDefinition]
-> HashMap Name Value
-> [Directive Name]
-> SelectionSet fragments Name
-> m ([Directive Variable], SelectionSet fragments Variable)
resolveVariables [VariableDefinition]
varDefs (HashMap Name Value
-> Maybe (HashMap Name Value) -> HashMap Name Value
forall a. a -> Maybe a -> a
fromMaybe HashMap Name Value
forall k v. HashMap k v
HashMap.empty Maybe (HashMap Name Value)
varValsM) [Directive Name]
directives SelectionSet NoFragments Name
fields
  RootFieldMap (QueryRootField UnpreparedValue)
parsedQuery <- Either QErr (RootFieldMap (QueryRootField UnpreparedValue))
-> m (RootFieldMap (QueryRootField UnpreparedValue))
forall e (m :: * -> *) a. MonadError e m => Either e a -> m a
liftEither (Either QErr (RootFieldMap (QueryRootField UnpreparedValue))
 -> m (RootFieldMap (QueryRootField UnpreparedValue)))
-> Either QErr (RootFieldMap (QueryRootField UnpreparedValue))
-> m (RootFieldMap (QueryRootField UnpreparedValue))
forall a b. (a -> b) -> a -> b
$ GQLContext
-> ParserFn (RootFieldMap (QueryRootField UnpreparedValue))
gqlQueryParser GQLContext
gqlContext SelectionSet NoFragments Variable
resolvedSelSet
  (RootFieldMap (QueryRootField UnpreparedValue),
 [Directive Variable], SelectionSet NoFragments Variable)
-> m (RootFieldMap (QueryRootField UnpreparedValue),
      [Directive Variable], SelectionSet NoFragments Variable)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (RootFieldMap (QueryRootField UnpreparedValue)
parsedQuery, [Directive Variable]
resolvedDirectives, SelectionSet NoFragments Variable
resolvedSelSet)

-- | Construct an 'ExecutionPlan' from a 'G.SelectionSet'.
convertQuerySelSet ::
  forall m.
  ( MonadError QErr m,
    MonadTrace m,
    MonadIO m,
    MonadGQLExecutionCheck m,
    MonadQueryTags m,
    ProvidesNetwork m
  ) =>
  Env.Environment ->
  L.Logger L.Hasura ->
  PrometheusMetrics ->
  GQLContext ->
  UserInfo ->
  HTTP.RequestHeaders ->
  [G.Directive G.Name] ->
  G.SelectionSet G.NoFragments G.Name ->
  [G.VariableDefinition] ->
  GH.GQLReqUnparsed ->
  SetGraphqlIntrospectionOptions ->
  RequestId ->
  -- | Graphql Operation Name
  Maybe G.Name ->
  m (ExecutionPlan, [QueryRootField UnpreparedValue], DirectiveMap, ParameterizedQueryHash)
convertQuerySelSet :: forall (m :: * -> *).
(MonadError QErr m, MonadTrace m, MonadIO m,
 MonadGQLExecutionCheck m, MonadQueryTags m, ProvidesNetwork m) =>
Environment
-> Logger Hasura
-> PrometheusMetrics
-> GQLContext
-> UserInfo
-> RequestHeaders
-> [Directive Name]
-> SelectionSet NoFragments Name
-> [VariableDefinition]
-> GQLReqUnparsed
-> SetGraphqlIntrospectionOptions
-> RequestId
-> Maybe Name
-> m (ExecutionPlan, [QueryRootField UnpreparedValue],
      DirectiveMap, ParameterizedQueryHash)
convertQuerySelSet
  Environment
env
  Logger Hasura
logger
  PrometheusMetrics
prometheusMetrics
  GQLContext
gqlContext
  UserInfo
userInfo
  RequestHeaders
reqHeaders
  [Directive Name]
directives
  SelectionSet NoFragments Name
fields
  [VariableDefinition]
varDefs
  GQLReqUnparsed
gqlUnparsed
  SetGraphqlIntrospectionOptions
introspectionDisabledRoles
  RequestId
reqId
  Maybe Name
maybeOperationName = do
    -- 1. Parse the GraphQL query into the 'RootFieldMap' and a 'SelectionSet'
    (RootFieldMap (QueryRootField UnpreparedValue)
unpreparedQueries, [Directive Variable]
normalizedDirectives, SelectionSet NoFragments Variable
normalizedSelectionSet) <-
      Text
-> m (RootFieldMap (QueryRootField UnpreparedValue),
      [Directive Variable], SelectionSet NoFragments Variable)
-> m (RootFieldMap (QueryRootField UnpreparedValue),
      [Directive Variable], SelectionSet NoFragments Variable)
forall (m :: * -> *) a.
(MonadIO m, MonadTrace m) =>
Text -> m a -> m a
Tracing.newSpan Text
"Parse query IR" (m (RootFieldMap (QueryRootField UnpreparedValue),
    [Directive Variable], SelectionSet NoFragments Variable)
 -> m (RootFieldMap (QueryRootField UnpreparedValue),
       [Directive Variable], SelectionSet NoFragments Variable))
-> m (RootFieldMap (QueryRootField UnpreparedValue),
      [Directive Variable], SelectionSet NoFragments Variable)
-> m (RootFieldMap (QueryRootField UnpreparedValue),
      [Directive Variable], SelectionSet NoFragments Variable)
forall a b. (a -> b) -> a -> b
$ GQLContext
-> [VariableDefinition]
-> Maybe (HashMap Name Value)
-> [Directive Name]
-> SelectionSet NoFragments Name
-> m (RootFieldMap (QueryRootField UnpreparedValue),
      [Directive Variable], SelectionSet NoFragments Variable)
forall (m :: * -> *).
MonadError QErr m =>
GQLContext
-> [VariableDefinition]
-> Maybe (HashMap Name Value)
-> [Directive Name]
-> SelectionSet NoFragments Name
-> m (RootFieldMap (QueryRootField UnpreparedValue),
      [Directive Variable], SelectionSet NoFragments Variable)
parseGraphQLQuery GQLContext
gqlContext [VariableDefinition]
varDefs (GQLReqUnparsed -> Maybe (HashMap Name Value)
forall a. GQLReq a -> Maybe (HashMap Name Value)
GH._grVariables GQLReqUnparsed
gqlUnparsed) [Directive Name]
directives SelectionSet NoFragments Name
fields

    -- 2. Parse directives on the query
    DirectiveMap
dirMap <- Either ParseError DirectiveMap -> m DirectiveMap
forall (m :: * -> *) a.
MonadError QErr m =>
Either ParseError a -> m a
toQErr (Either ParseError DirectiveMap -> m DirectiveMap)
-> Either ParseError DirectiveMap -> m DirectiveMap
forall a b. (a -> b) -> a -> b
$ Parse DirectiveMap -> Either ParseError DirectiveMap
forall (m :: * -> *) a. MonadError ParseError m => Parse a -> m a
runParse ([Directive Any Parse]
-> DirectiveLocation -> [Directive Variable] -> Parse DirectiveMap
forall origin (m :: * -> *).
MonadParse m =>
[Directive origin m]
-> DirectiveLocation -> [Directive Variable] -> m DirectiveMap
parseDirectives [Directive Any Parse]
forall (m :: * -> *) origin. MonadParse m => [Directive origin m]
customDirectives (ExecutableDirectiveLocation -> DirectiveLocation
G.DLExecutable ExecutableDirectiveLocation
G.EDLQUERY) [Directive Variable]
normalizedDirectives)

    let parameterizedQueryHash :: ParameterizedQueryHash
parameterizedQueryHash = SelectionSet NoFragments Variable -> ParameterizedQueryHash
calculateParameterizedQueryHash SelectionSet NoFragments Variable
normalizedSelectionSet

        resolveExecutionSteps :: RootFieldAlias -> QueryRootField UnpreparedValue -> m ExecutionStep
resolveExecutionSteps RootFieldAlias
rootFieldName QueryRootField UnpreparedValue
rootFieldUnpreparedValue = Text -> m ExecutionStep -> m ExecutionStep
forall (m :: * -> *) a.
(MonadIO m, MonadTrace m) =>
Text -> m a -> m a
Tracing.newSpan (Text
"Resolve execution step for " Text -> RootFieldAlias -> Text
forall t. ToTxt t => Text -> t -> Text
<>> RootFieldAlias
rootFieldName) do
          case QueryRootField UnpreparedValue
rootFieldUnpreparedValue of
            RFMulti [QueryRootField UnpreparedValue]
lst -> do
              [ExecutionStep]
allSteps <- (QueryRootField UnpreparedValue -> m ExecutionStep)
-> [QueryRootField UnpreparedValue] -> m [ExecutionStep]
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 (RootFieldAlias -> QueryRootField UnpreparedValue -> m ExecutionStep
resolveExecutionSteps RootFieldAlias
rootFieldName) [QueryRootField UnpreparedValue]
lst
              ExecutionStep -> m ExecutionStep
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ExecutionStep -> m ExecutionStep)
-> ExecutionStep -> m ExecutionStep
forall a b. (a -> b) -> a -> b
$ [ExecutionStep] -> ExecutionStep
ExecStepMulti [ExecutionStep]
allSteps
            RFDB SourceName
sourceName AnyBackend
  (SourceConfigWith
     (QueryDBRoot
        (RemoteRelationshipField UnpreparedValue) UnpreparedValue))
exists ->
              forall (c :: BackendType -> Constraint) (i :: BackendType -> *) r.
AllBackendsSatisfy c =>
AnyBackend i -> (forall (b :: BackendType). c b => i b -> r) -> r
AB.dispatchAnyBackend @BackendExecute
                AnyBackend
  (SourceConfigWith
     (QueryDBRoot
        (RemoteRelationshipField UnpreparedValue) UnpreparedValue))
exists
                \(SourceConfigWith (SourceConfig b
sourceConfig :: (SourceConfig b)) Maybe QueryTagsConfig
queryTagsConfig (QDBR QueryDB
  b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)
db)) -> do
                  forall (b :: BackendType) (m :: * -> *).
(HasSourceConfiguration b, MonadTrace m) =>
SourceConfig b -> m ()
Tracing.attachSourceConfigAttributes @b SourceConfig b
sourceConfig
                  let mReqId :: Maybe RequestId
mReqId =
                        case QueryTagsConfig -> Bool
_qtcOmitRequestId (QueryTagsConfig -> Bool) -> Maybe QueryTagsConfig -> Maybe Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe QueryTagsConfig
queryTagsConfig of
                          -- we include the request id only if a user explicitly wishes for it to be included.
                          Just Bool
False -> RequestId -> Maybe RequestId
forall a. a -> Maybe a
Just RequestId
reqId
                          Maybe Bool
_ -> Maybe RequestId
forall a. Maybe a
Nothing
                      queryTagsAttributes :: QueryTagsAttributes
queryTagsAttributes = QueryTags -> QueryTagsAttributes
encodeQueryTags (QueryTags -> QueryTagsAttributes)
-> QueryTags -> QueryTagsAttributes
forall a b. (a -> b) -> a -> b
$ QueryMetadata -> QueryTags
QTQuery (QueryMetadata -> QueryTags) -> QueryMetadata -> QueryTags
forall a b. (a -> b) -> a -> b
$ Maybe RequestId
-> Maybe Name
-> RootFieldAlias
-> ParameterizedQueryHash
-> QueryMetadata
QueryMetadata Maybe RequestId
mReqId Maybe Name
maybeOperationName RootFieldAlias
rootFieldName ParameterizedQueryHash
parameterizedQueryHash
                      queryTagsComment :: QueryTagsComment
queryTagsComment = Tagged m QueryTagsComment -> QueryTagsComment
forall {k} (s :: k) b. Tagged s b -> b
Tagged.untag (Tagged m QueryTagsComment -> QueryTagsComment)
-> Tagged m QueryTagsComment -> QueryTagsComment
forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
MonadQueryTags m =>
QueryTagsAttributes
-> Maybe QueryTagsConfig -> Tagged m QueryTagsComment
createQueryTags @m QueryTagsAttributes
queryTagsAttributes Maybe QueryTagsConfig
queryTagsConfig
                      (QueryDB b Void (UnpreparedValue b)
noRelsDBAST, Maybe RemoteJoins
remoteJoins) = QueryDB
  b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)
-> (QueryDB b Void (UnpreparedValue b), Maybe RemoteJoins)
forall (b :: BackendType).
Backend b =>
QueryDB
  b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)
-> (QueryDB b Void (UnpreparedValue b), Maybe RemoteJoins)
RJ.getRemoteJoinsQueryDB QueryDB
  b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b)
db
                  DBStepInfo b
dbStepInfo <- (ReaderT QueryTagsComment m (DBStepInfo b)
 -> QueryTagsComment -> m (DBStepInfo b))
-> QueryTagsComment
-> ReaderT QueryTagsComment m (DBStepInfo b)
-> m (DBStepInfo b)
forall a b c. (a -> b -> c) -> b -> a -> c
flip ReaderT QueryTagsComment m (DBStepInfo b)
-> QueryTagsComment -> m (DBStepInfo b)
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT QueryTagsComment
queryTagsComment (ReaderT QueryTagsComment m (DBStepInfo b) -> m (DBStepInfo b))
-> ReaderT QueryTagsComment m (DBStepInfo b) -> m (DBStepInfo b)
forall a b. (a -> b) -> a -> b
$ forall (b :: BackendType) (m :: * -> *).
(BackendExecute b, MonadError QErr m, MonadQueryTags m,
 MonadReader QueryTagsComment m) =>
UserInfo
-> SourceName
-> SourceConfig b
-> QueryDB b Void (UnpreparedValue b)
-> RequestHeaders
-> Maybe Name
-> m (DBStepInfo b)
mkDBQueryPlan @b UserInfo
userInfo SourceName
sourceName SourceConfig b
sourceConfig QueryDB b Void (UnpreparedValue b)
noRelsDBAST RequestHeaders
reqHeaders Maybe Name
maybeOperationName
                  ExecutionStep -> m ExecutionStep
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ExecutionStep -> m ExecutionStep)
-> ExecutionStep -> m ExecutionStep
forall a b. (a -> b) -> a -> b
$ RequestHeaders
-> AnyBackend DBStepInfo -> Maybe RemoteJoins -> ExecutionStep
ExecStepDB [] (DBStepInfo b -> AnyBackend DBStepInfo
forall (b :: BackendType) (i :: BackendType -> *).
HasTag b =>
i b -> AnyBackend i
AB.mkAnyBackend DBStepInfo b
dbStepInfo) Maybe RemoteJoins
remoteJoins
            RFRemote RemoteSchemaRootField
  (RemoteRelationshipField UnpreparedValue) RemoteSchemaVariable
rf -> do
              RemoteSchemaRootField RemoteSchemaInfo
remoteSchemaInfo ResultCustomizer
resultCustomizer GraphQLField (RemoteRelationshipField UnpreparedValue) Variable
remoteField <- StateT
  RemoteJSONVariableMap
  m
  (RemoteSchemaRootField
     (RemoteRelationshipField UnpreparedValue) Variable)
-> m (RemoteSchemaRootField
        (RemoteRelationshipField UnpreparedValue) Variable)
forall (m :: * -> *) a.
Monad m =>
StateT RemoteJSONVariableMap m a -> m a
runVariableCache (StateT
   RemoteJSONVariableMap
   m
   (RemoteSchemaRootField
      (RemoteRelationshipField UnpreparedValue) Variable)
 -> m (RemoteSchemaRootField
         (RemoteRelationshipField UnpreparedValue) Variable))
-> StateT
     RemoteJSONVariableMap
     m
     (RemoteSchemaRootField
        (RemoteRelationshipField UnpreparedValue) Variable)
-> m (RemoteSchemaRootField
        (RemoteRelationshipField UnpreparedValue) Variable)
forall a b. (a -> b) -> a -> b
$ RemoteSchemaRootField
  (RemoteRelationshipField UnpreparedValue) RemoteSchemaVariable
-> (RemoteSchemaVariable
    -> StateT RemoteJSONVariableMap m Variable)
-> StateT
     RemoteJSONVariableMap
     m
     (RemoteSchemaRootField
        (RemoteRelationshipField UnpreparedValue) Variable)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
t a -> (a -> f b) -> f (t b)
for RemoteSchemaRootField
  (RemoteRelationshipField UnpreparedValue) RemoteSchemaVariable
rf ((RemoteSchemaVariable -> StateT RemoteJSONVariableMap m Variable)
 -> StateT
      RemoteJSONVariableMap
      m
      (RemoteSchemaRootField
         (RemoteRelationshipField UnpreparedValue) Variable))
-> (RemoteSchemaVariable
    -> StateT RemoteJSONVariableMap m Variable)
-> StateT
     RemoteJSONVariableMap
     m
     (RemoteSchemaRootField
        (RemoteRelationshipField UnpreparedValue) Variable)
forall a b. (a -> b) -> a -> b
$ UserInfo
-> RemoteSchemaVariable -> StateT RemoteJSONVariableMap m Variable
forall (m :: * -> *).
MonadError QErr m =>
UserInfo
-> RemoteSchemaVariable -> StateT RemoteJSONVariableMap m Variable
resolveRemoteVariable UserInfo
userInfo
              let (GraphQLField Void Variable
noRelsRemoteField, Maybe RemoteJoins
remoteJoins) = GraphQLField (RemoteRelationshipField UnpreparedValue) Variable
-> (GraphQLField Void Variable, Maybe RemoteJoins)
forall var.
GraphQLField (RemoteRelationshipField UnpreparedValue) var
-> (GraphQLField Void var, Maybe RemoteJoins)
RJ.getRemoteJoinsGraphQLField GraphQLField (RemoteRelationshipField UnpreparedValue) Variable
remoteField
              ExecutionStep -> m ExecutionStep
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ExecutionStep -> m ExecutionStep)
-> ExecutionStep -> m ExecutionStep
forall a b. (a -> b) -> a -> b
$ RemoteSchemaInfo
-> ResultCustomizer
-> OperationType
-> GraphQLField Void Variable
-> Maybe RemoteJoins
-> Maybe OperationName
-> ExecutionStep
buildExecStepRemote RemoteSchemaInfo
remoteSchemaInfo ResultCustomizer
resultCustomizer OperationType
G.OperationTypeQuery GraphQLField Void Variable
noRelsRemoteField Maybe RemoteJoins
remoteJoins (GQLReqUnparsed -> Maybe OperationName
forall a. GQLReq a -> Maybe OperationName
GH._grOperationName GQLReqUnparsed
gqlUnparsed)
            RFAction ActionQuery (RemoteRelationshipField UnpreparedValue)
action -> do
              Manager
httpManager <- m Manager
forall (m :: * -> *). ProvidesNetwork m => m Manager
askHTTPManager
              let (ActionQuery Void
noRelsDBAST, Maybe RemoteJoins
remoteJoins) = ActionQuery (RemoteRelationshipField UnpreparedValue)
-> (ActionQuery Void, Maybe RemoteJoins)
RJ.getRemoteJoinsActionQuery ActionQuery (RemoteRelationshipField UnpreparedValue)
action
              (ActionExecutionPlan
actionExecution, ActionName
actionName, Bool
fch) <- (ActionExecutionPlan, ActionName, Bool)
-> m (ActionExecutionPlan, ActionName, Bool)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((ActionExecutionPlan, ActionName, Bool)
 -> m (ActionExecutionPlan, ActionName, Bool))
-> (ActionExecutionPlan, ActionName, Bool)
-> m (ActionExecutionPlan, ActionName, Bool)
forall a b. (a -> b) -> a -> b
$ case ActionQuery Void
noRelsDBAST of
                AQQuery AnnActionExecution Void
s ->
                  ( ActionExecution -> ActionExecutionPlan
AEPSync
                      (ActionExecution -> ActionExecutionPlan)
-> ActionExecution -> ActionExecutionPlan
forall a b. (a -> b) -> a -> b
$ Manager
-> Environment
-> Logger Hasura
-> PrometheusMetrics
-> AnnActionExecution Void
-> ActionExecContext
-> Maybe GQLQueryText
-> ActionExecution
resolveActionExecution
                        Manager
httpManager
                        Environment
env
                        Logger Hasura
logger
                        PrometheusMetrics
prometheusMetrics
                        AnnActionExecution Void
s
                        (RequestHeaders -> SessionVariables -> ActionExecContext
ActionExecContext RequestHeaders
reqHeaders (UserInfo -> SessionVariables
_uiSession UserInfo
userInfo))
                        (GQLQueryText -> Maybe GQLQueryText
forall a. a -> Maybe a
Just (GQLReqUnparsed -> GQLQueryText
forall a. GQLReq a -> a
GH._grQuery GQLReqUnparsed
gqlUnparsed)),
                    AnnActionExecution Void -> ActionName
forall r. AnnActionExecution r -> ActionName
_aaeName AnnActionExecution Void
s,
                    AnnActionExecution Void -> Bool
forall r. AnnActionExecution r -> Bool
_aaeForwardClientHeaders AnnActionExecution Void
s
                  )
                AQAsync AnnActionAsyncQuery ('Postgres 'Vanilla) Void
s -> (AsyncActionQueryExecutionPlan -> ActionExecutionPlan
AEPAsyncQuery (AsyncActionQueryExecutionPlan -> ActionExecutionPlan)
-> AsyncActionQueryExecutionPlan -> ActionExecutionPlan
forall a b. (a -> b) -> a -> b
$ ActionId
-> AsyncActionQueryExecution (UnpreparedValue ('Postgres 'Vanilla))
-> AsyncActionQueryExecutionPlan
AsyncActionQueryExecutionPlan (AnnActionAsyncQuery ('Postgres 'Vanilla) Void -> ActionId
forall (b :: BackendType) r. AnnActionAsyncQuery b r -> ActionId
_aaaqActionId AnnActionAsyncQuery ('Postgres 'Vanilla) Void
s) (AsyncActionQueryExecution (UnpreparedValue ('Postgres 'Vanilla))
 -> AsyncActionQueryExecutionPlan)
-> AsyncActionQueryExecution (UnpreparedValue ('Postgres 'Vanilla))
-> AsyncActionQueryExecutionPlan
forall a b. (a -> b) -> a -> b
$ UserInfo
-> AnnActionAsyncQuery ('Postgres 'Vanilla) Void
-> AsyncActionQueryExecution (UnpreparedValue ('Postgres 'Vanilla))
resolveAsyncActionQuery UserInfo
userInfo AnnActionAsyncQuery ('Postgres 'Vanilla) Void
s, AnnActionAsyncQuery ('Postgres 'Vanilla) Void -> ActionName
forall (b :: BackendType) r. AnnActionAsyncQuery b r -> ActionName
_aaaqName AnnActionAsyncQuery ('Postgres 'Vanilla) Void
s, AnnActionAsyncQuery ('Postgres 'Vanilla) Void -> Bool
forall (b :: BackendType) r. AnnActionAsyncQuery b r -> Bool
_aaaqForwardClientHeaders AnnActionAsyncQuery ('Postgres 'Vanilla) Void
s)
              ExecutionStep -> m ExecutionStep
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ExecutionStep -> m ExecutionStep)
-> ExecutionStep -> m ExecutionStep
forall a b. (a -> b) -> a -> b
$ ActionExecutionPlan
-> ActionsInfo -> Maybe RemoteJoins -> ExecutionStep
ExecStepAction ActionExecutionPlan
actionExecution (ActionName -> Bool -> ActionsInfo
ActionsInfo ActionName
actionName Bool
fch) Maybe RemoteJoins
remoteJoins
            RFRaw Value
r -> (Either QErr ExecutionStep
 -> (QErr -> m ExecutionStep) -> m ExecutionStep)
-> (QErr -> m ExecutionStep)
-> Either QErr ExecutionStep
-> m ExecutionStep
forall a b c. (a -> b -> c) -> b -> a -> c
flip Either QErr ExecutionStep
-> (QErr -> m ExecutionStep) -> m ExecutionStep
forall (m :: * -> *) e a.
Applicative m =>
Either e a -> (e -> m a) -> m a
onLeft QErr -> m ExecutionStep
forall a. QErr -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (Either QErr ExecutionStep -> m ExecutionStep)
-> m (Either QErr ExecutionStep) -> m ExecutionStep
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< UserInfo
-> Value
-> SetGraphqlIntrospectionOptions
-> m (Either QErr ExecutionStep)
forall (m :: * -> *).
MonadGQLExecutionCheck m =>
UserInfo
-> Value
-> SetGraphqlIntrospectionOptions
-> m (Either QErr ExecutionStep)
executeIntrospection UserInfo
userInfo Value
r SetGraphqlIntrospectionOptions
introspectionDisabledRoles
    -- 3. Transform the 'RootFieldMap' into an execution plan
    ExecutionPlan
executionPlan <- ((RootFieldAlias
  -> QueryRootField UnpreparedValue -> m ExecutionStep)
 -> RootFieldMap (QueryRootField UnpreparedValue)
 -> m ExecutionPlan)
-> RootFieldMap (QueryRootField UnpreparedValue)
-> (RootFieldAlias
    -> QueryRootField UnpreparedValue -> m ExecutionStep)
-> m ExecutionPlan
forall a b c. (a -> b -> c) -> b -> a -> c
flip (RootFieldAlias
 -> QueryRootField UnpreparedValue -> m ExecutionStep)
-> RootFieldMap (QueryRootField UnpreparedValue) -> m ExecutionPlan
forall (f :: * -> *) k a b.
Applicative f =>
(k -> a -> f b) -> InsOrdHashMap k a -> f (InsOrdHashMap k b)
InsOrdHashMap.traverseWithKey RootFieldMap (QueryRootField UnpreparedValue)
unpreparedQueries ((RootFieldAlias
  -> QueryRootField UnpreparedValue -> m ExecutionStep)
 -> m ExecutionPlan)
-> (RootFieldAlias
    -> QueryRootField UnpreparedValue -> m ExecutionStep)
-> m ExecutionPlan
forall a b. (a -> b) -> a -> b
$ RootFieldAlias -> QueryRootField UnpreparedValue -> m ExecutionStep
resolveExecutionSteps
    (ExecutionPlan, [QueryRootField UnpreparedValue], DirectiveMap,
 ParameterizedQueryHash)
-> m (ExecutionPlan, [QueryRootField UnpreparedValue],
      DirectiveMap, ParameterizedQueryHash)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ExecutionPlan
executionPlan, RootFieldMap (QueryRootField UnpreparedValue)
-> [QueryRootField UnpreparedValue]
forall k v. InsOrdHashMap k v -> [v]
InsOrdHashMap.elems RootFieldMap (QueryRootField UnpreparedValue)
unpreparedQueries, DirectiveMap
dirMap, ParameterizedQueryHash
parameterizedQueryHash)