server: add IR support for DB-to-DB joins

GJ IR changes cherry-picked from the original GJ branch. There is a separate (can be merged independently) PR for metadata changes (#1727) and there will be a different PR upcoming PR for execution changes.

https://github.com/hasura/graphql-engine-mono/pull/1810

Co-authored-by: Vamshi Surabhi <6562944+0x777@users.noreply.github.com>
GitOrigin-RevId: c31956af29dc9c9b75d002aba7d93c230697c5f4
This commit is contained in:
Evie Ciobanu 2021-07-26 16:03:51 +03:00 committed by hasura-bot
parent b8cd59551f
commit 4b0f5f09c9
24 changed files with 200 additions and 184 deletions

View File

@ -791,17 +791,6 @@ fromAnnFieldsG existingJoins stringifyNumbers (Rql.FieldName name, field) =
(\aliasedThing ->
JoinFieldSource (Aliased {aliasedThing, aliasedAlias = name}))
(fromArraySelectG arraySelectG)
-- this will be gone once the code which collects remote joins from the IR
-- emits a modified IR where remote relationships can't be reached
Ir.AFRemote _ ->
pure
(ExpressionFieldSource
Aliased
{ aliasedThing = BigQuery.ValueExpression (StringValue "null: remote field selected")
, aliasedAlias = name
})
-- TODO: implement this
Ir.AFDBRemote _ -> error "FIXME"
-- | Here is where we project a field as a column expression. If

View File

@ -77,7 +77,7 @@ bqBuildTableRelayQueryFields
-> G.Name
-> NESeq (ColumnInfo 'BigQuery)
-> SelPermInfo 'BigQuery
-> m [FieldParser n (QueryRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (QueryRootField UnpreparedValue)]
bqBuildTableRelayQueryFields _sourceName _sourceInfo _tableName _tableInfo _gqlName _pkeyColumns _selPerms =
pure []
@ -91,7 +91,7 @@ bqBuildTableInsertMutationFields
-> InsPermInfo 'BigQuery
-> Maybe (SelPermInfo 'BigQuery)
-> Maybe (UpdPermInfo 'BigQuery)
-> m [FieldParser n (MutationRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (MutationRootField UnpreparedValue)]
bqBuildTableInsertMutationFields _sourceName _sourceInfo _tableName _tableInfo _gqlName _insPerms _selPerms _updPerms =
pure []
@ -104,7 +104,7 @@ bqBuildTableUpdateMutationFields
-> G.Name
-> UpdPermInfo 'BigQuery
-> Maybe (SelPermInfo 'BigQuery)
-> m [FieldParser n (MutationRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (MutationRootField UnpreparedValue)]
bqBuildTableUpdateMutationFields _sourceName _sourceInfo _tableName _tableInfo _gqlName _updPerns _selPerms =
pure []
@ -117,7 +117,7 @@ bqBuildTableDeleteMutationFields
-> G.Name
-> DelPermInfo 'BigQuery
-> Maybe (SelPermInfo 'BigQuery)
-> m [FieldParser n (MutationRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (MutationRootField UnpreparedValue)]
bqBuildTableDeleteMutationFields _sourceName _sourceInfo _tableName _tableInfo _gqlName _delPerns _selPerms =
pure []
@ -129,7 +129,7 @@ bqBuildFunctionQueryFields
-> FunctionInfo 'BigQuery
-> TableName 'BigQuery
-> SelPermInfo 'BigQuery
-> m [FieldParser n (QueryRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (QueryRootField UnpreparedValue)]
bqBuildFunctionQueryFields _ _ _ _ _ _ =
pure []
@ -142,7 +142,7 @@ bqBuildFunctionRelayQueryFields
-> TableName 'BigQuery
-> NESeq (ColumnInfo 'BigQuery)
-> SelPermInfo 'BigQuery
-> m [FieldParser n (QueryRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (QueryRootField UnpreparedValue)]
bqBuildFunctionRelayQueryFields _sourceName _sourceInfo _functionName _functionInfo _tableName _pkeyColumns _selPerms =
pure []
@ -154,7 +154,7 @@ bqBuildFunctionMutationFields
-> FunctionInfo 'BigQuery
-> TableName 'BigQuery
-> SelPermInfo 'BigQuery
-> m [FieldParser n (MutationRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (MutationRootField UnpreparedValue)]
bqBuildFunctionMutationFields _ _ _ _ _ _ =
pure []

View File

@ -727,18 +727,6 @@ fromAnnFieldsG existingJoins stringifyNumbers (IR.FieldName name, field) =
(\aliasedThing ->
JoinFieldSource (Aliased {aliasedThing, aliasedAlias = name}))
(fromArraySelectG arraySelectG)
-- this will be gone once the code which collects remote joins from the IR
-- emits a modified IR where remote relationships can't be reached
IR.AFRemote _ ->
pure
(ExpressionFieldSource
Aliased
{ aliasedThing = TSQL.ValueExpression
(ODBC.TextValue "null: remote field selected")
, aliasedAlias = name
})
-- TODO: implement this
IR.AFDBRemote _ -> error "FIXME"
-- | Here is where we project a field as a column expression. If
-- number stringification is on, then we wrap it in a

View File

@ -79,7 +79,7 @@ msBuildTableRelayQueryFields
-> G.Name
-> NESeq (ColumnInfo 'MSSQL)
-> SelPermInfo 'MSSQL
-> m [FieldParser n (QueryRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (QueryRootField UnpreparedValue)]
msBuildTableRelayQueryFields _sourceName _sourceInfo _tableName _tableInfo _gqlName _pkeyColumns _selPerms =
pure []
@ -93,7 +93,7 @@ msBuildTableInsertMutationFields
-> InsPermInfo 'MSSQL
-> Maybe (SelPermInfo 'MSSQL)
-> Maybe (UpdPermInfo 'MSSQL)
-> m [FieldParser n (MutationRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (MutationRootField UnpreparedValue)]
msBuildTableInsertMutationFields _sourceName _sourceInfo _tableName _tableInfo _gqlName _insPerms _selPerms _updPerms =
pure []
@ -106,7 +106,7 @@ msBuildTableUpdateMutationFields
-> G.Name
-> UpdPermInfo 'MSSQL
-> Maybe (SelPermInfo 'MSSQL)
-> m [FieldParser n (MutationRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (MutationRootField UnpreparedValue)]
msBuildTableUpdateMutationFields _sourceName _sourceInfo _tableName _tableInfo _gqlName _updPerns _selPerms =
pure []
@ -119,7 +119,7 @@ msBuildTableDeleteMutationFields
-> G.Name
-> DelPermInfo 'MSSQL
-> Maybe (SelPermInfo 'MSSQL)
-> m [FieldParser n (MutationRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (MutationRootField UnpreparedValue)]
msBuildTableDeleteMutationFields _sourceName _sourceInfo _tableName _tableInfo _gqlName _delPerns _selPerms =
pure []
@ -131,7 +131,7 @@ msBuildFunctionQueryFields
-> FunctionInfo 'MSSQL
-> TableName 'MSSQL
-> SelPermInfo 'MSSQL
-> m [FieldParser n (QueryRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (QueryRootField UnpreparedValue)]
msBuildFunctionQueryFields _ _ _ _ _ _ =
pure []
@ -144,7 +144,7 @@ msBuildFunctionRelayQueryFields
-> TableName 'MSSQL
-> NESeq (ColumnInfo 'MSSQL)
-> SelPermInfo 'MSSQL
-> m [FieldParser n (QueryRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (QueryRootField UnpreparedValue)]
msBuildFunctionRelayQueryFields _sourceName _sourceInfo _functionName _functionInfo _tableName _pkeyColumns _selPerms =
pure []
@ -156,7 +156,7 @@ msBuildFunctionMutationFields
-> FunctionInfo 'MSSQL
-> TableName 'MSSQL
-> SelPermInfo 'MSSQL
-> m [FieldParser n (MutationRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (MutationRootField UnpreparedValue)]
msBuildFunctionMutationFields _ _ _ _ _ _ =
pure []

View File

@ -79,7 +79,7 @@ buildTableRelayQueryFields' ::
G.Name ->
NESeq (ColumnInfo 'MySQL) ->
SelPermInfo 'MySQL ->
m [FieldParser n (QueryRootField UnpreparedValue UnpreparedValue)]
m [FieldParser n (QueryRootField UnpreparedValue)]
buildTableRelayQueryFields' _sourceName _sourceInfo _tableName _tableInfo _gqlName _pkeyColumns _selPerms =
pure []
@ -94,7 +94,7 @@ buildTableInsertMutationFields' ::
InsPermInfo 'MySQL ->
Maybe (SelPermInfo 'MySQL) ->
Maybe (UpdPermInfo 'MySQL) ->
m [FieldParser n (MutationRootField UnpreparedValue UnpreparedValue)]
m [FieldParser n (MutationRootField UnpreparedValue)]
buildTableInsertMutationFields' _sourceName _sourceInfo _tableName _tableInfo _gqlName _insPerms _selPerms _updPerms =
pure []
@ -108,7 +108,7 @@ buildTableUpdateMutationFields' ::
G.Name ->
UpdPermInfo 'MySQL ->
Maybe (SelPermInfo 'MySQL) ->
m [FieldParser n (MutationRootField UnpreparedValue UnpreparedValue)]
m [FieldParser n (MutationRootField UnpreparedValue)]
buildTableUpdateMutationFields' _sourceName _sourceInfo _tableName _tableInfo _gqlName _updPerns _selPerms =
pure []
@ -122,7 +122,7 @@ buildTableDeleteMutationFields' ::
G.Name ->
DelPermInfo 'MySQL ->
Maybe (SelPermInfo 'MySQL) ->
m [FieldParser n (MutationRootField UnpreparedValue UnpreparedValue)]
m [FieldParser n (MutationRootField UnpreparedValue)]
buildTableDeleteMutationFields' _sourceName _sourceInfo _tableName _tableInfo _gqlName _delPerns _selPerms =
pure []
@ -135,7 +135,7 @@ buildFunctionQueryFields' ::
FunctionInfo 'MySQL ->
RQL.TableName 'MySQL ->
SelPermInfo 'MySQL ->
m [FieldParser n (QueryRootField UnpreparedValue UnpreparedValue)]
m [FieldParser n (QueryRootField UnpreparedValue)]
buildFunctionQueryFields' _ _ _ _ _ _ =
pure []
@ -149,7 +149,7 @@ buildFunctionRelayQueryFields' ::
RQL.TableName 'MySQL ->
NESeq (ColumnInfo 'MySQL) ->
SelPermInfo 'MySQL ->
m [(FieldParser n (QueryRootField UnpreparedValue UnpreparedValue))]
m [FieldParser n (QueryRootField UnpreparedValue)]
buildFunctionRelayQueryFields' _sourceName _sourceInfo _functionName _functionInfo _tableName _pkeyColumns _selPerms =
pure []
@ -162,7 +162,7 @@ buildFunctionMutationFields' ::
FunctionInfo 'MySQL ->
RQL.TableName 'MySQL ->
SelPermInfo 'MySQL ->
m [FieldParser n (MutationRootField UnpreparedValue UnpreparedValue)]
m [FieldParser n (MutationRootField UnpreparedValue)]
buildFunctionMutationFields' _ _ _ _ _ _ =
pure []

View File

@ -67,7 +67,7 @@ class PostgresSchema (pgKind :: PostgresKind) where
-> G.Name
-> NESeq (ColumnInfo ('Postgres pgKind))
-> SelPermInfo ('Postgres pgKind)
-> m [FieldParser n (QueryRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (QueryRootField UnpreparedValue)]
pgkBuildFunctionRelayQueryFields
:: BS.MonadBuildSchema ('Postgres pgKind) r m n
=> SourceName
@ -77,7 +77,7 @@ class PostgresSchema (pgKind :: PostgresKind) where
-> TableName ('Postgres pgKind)
-> NESeq (ColumnInfo ('Postgres pgKind))
-> SelPermInfo ('Postgres pgKind)
-> m [FieldParser n (QueryRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (QueryRootField UnpreparedValue)]
pgkRelayExtension
:: Maybe (XRelay ('Postgres pgKind))
pgkNode
@ -161,7 +161,7 @@ buildTableRelayQueryFields
-> G.Name
-> NESeq (ColumnInfo ('Postgres pgKind))
-> SelPermInfo ('Postgres pgKind)
-> m [FieldParser n (QueryRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (QueryRootField UnpreparedValue)]
buildTableRelayQueryFields sourceName sourceInfo tableName tableInfo gqlName pkeyColumns selPerms = do
let
mkRF = RFDB sourceName
@ -184,7 +184,7 @@ buildFunctionRelayQueryFields
-> TableName ('Postgres pgKind)
-> NESeq (ColumnInfo ('Postgres pgKind))
-> SelPermInfo ('Postgres pgKind)
-> m [FieldParser n (QueryRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (QueryRootField UnpreparedValue)]
buildFunctionRelayQueryFields sourceName sourceInfo functionName functionInfo tableName pkeyColumns selPerms = do
funcName <- functionGraphQLName @('Postgres pgKind) functionName `onLeft` throwError
let

View File

@ -876,10 +876,6 @@ processAnnFields sourcePrefix fieldAlias similarArrFields annFields = do
AFColumn c -> toSQLCol c
-- this will be gone once the code which collects remote joins from the IR
-- emits a modified IR where remote relationships can't be reached
AFRemote _ -> pure $ S.SELit "null: remote field selected"
AFObjectRelation objSel -> withWriteObjectRelation $ do
let AnnRelationSelectG relName relMapping annObjSel = objSel
AnnObjectSelectG objAnnFields tableFrom tableFilter = annObjSel
@ -928,9 +924,6 @@ processAnnFields sourcePrefix fieldAlias similarArrFields annFields = do
, S.mkQIdenExp computedFieldSourcePrefix fieldName
)
-- TODO: implement this
AFDBRemote _ -> error "FIXME"
pure $ annRowToJson @pgKind fieldAlias fieldExps

View File

@ -30,8 +30,8 @@ data RoleContext a
$(deriveToJSON hasuraJSON ''RoleContext)
data GQLContext = GQLContext
{ gqlQueryParser :: ParserFn (InsOrdHashMap G.Name (IR.QueryRootField UnpreparedValue UnpreparedValue))
, gqlMutationParser :: Maybe (ParserFn (InsOrdHashMap G.Name (IR.MutationRootField UnpreparedValue UnpreparedValue)))
{ gqlQueryParser :: ParserFn (InsOrdHashMap G.Name (IR.QueryRootField UnpreparedValue))
, gqlMutationParser :: Maybe (ParserFn (InsOrdHashMap G.Name (IR.MutationRootField UnpreparedValue)))
}
instance J.ToJSON GQLContext where

View File

@ -131,7 +131,7 @@ getExecPlanPartial userInfo sc queryType req =
-- The graphql query is resolved into a sequence of execution operations
data ResolvedExecutionPlan
= QueryExecutionPlan EB.ExecutionPlan [IR.QueryRootField UnpreparedValue UnpreparedValue] DirectiveMap
= QueryExecutionPlan EB.ExecutionPlan [IR.QueryRootField UnpreparedValue] DirectiveMap
-- ^ query execution; remote schemas and introspection possible
| MutationExecutionPlan EB.ExecutionPlan
-- ^ mutation execution; only __typename introspection supported
@ -157,7 +157,7 @@ data SubscriptionExecution
buildSubscriptionPlan
:: (MonadError QErr m)
=> UserInfo
-> InsOrdHashMap G.Name (IR.QueryRootField UnpreparedValue UnpreparedValue)
-> InsOrdHashMap G.Name (IR.QueryRootField UnpreparedValue)
-> m SubscriptionExecution
buildSubscriptionPlan userInfo rootFields = do
(onSourceFields, noRelationActionFields) <- foldlM go (mempty, mempty) (OMap.toList rootFields)

View File

@ -84,7 +84,7 @@ convertMutationSelectionSet env logger gqlContext SQLGenCtx{stringifyNum} userIn
(resolvedDirectives, resolvedSelSet) <- resolveVariables varDefs (fromMaybe Map.empty varValsM) directives fields
-- Parse the GraphQL query into the RQL AST
(unpreparedQueries, _reusability)
:: (OMap.InsOrdHashMap G.Name (MutationRootField UnpreparedValue UnpreparedValue), QueryReusability)
:: (OMap.InsOrdHashMap G.Name (MutationRootField UnpreparedValue), QueryReusability)
<-(mutationParser >>> (`onLeft` reportParseErrors)) resolvedSelSet
-- Process directives on the mutation
@ -95,7 +95,7 @@ convertMutationSelectionSet env logger gqlContext SQLGenCtx{stringifyNum} userIn
txs <- for unpreparedQueries \case
RFDB sourceName exists ->
AB.dispatchAnyBackend @BackendExecute exists
\(SourceConfigWith sourceConfig (MDBR db :: MutationDBRoot UnpreparedValue UnpreparedValue b)) -> do
\(SourceConfigWith (sourceConfig :: SourceConfig b) (MDBR db)) -> do
let (noRelsDBAST, remoteJoins) = RJ.getRemoteJoinsMutationDB db
dbStepInfo <- mkDBMutationPlan @b userInfo stringifyNum sourceName sourceConfig noRelsDBAST
pure $ ExecStepDB [] (AB.mkAnyBackend dbStepInfo) remoteJoins

View File

@ -41,7 +41,7 @@ parseGraphQLQuery
-> Maybe (HashMap G.Name J.Value)
-> [G.Directive G.Name]
-> G.SelectionSet G.NoFragments G.Name
-> m ( InsOrdHashMap G.Name (QueryRootField UnpreparedValue UnpreparedValue)
-> m ( InsOrdHashMap G.Name (QueryRootField UnpreparedValue)
, QueryReusability
, [G.Directive Variable]
, G.SelectionSet G.NoFragments Variable
@ -69,7 +69,7 @@ convertQuerySelSet
-> [G.VariableDefinition]
-> Maybe GH.VariableValues
-> SetGraphqlIntrospectionOptions
-> m (ExecutionPlan, [QueryRootField UnpreparedValue UnpreparedValue], G.SelectionSet G.NoFragments Variable, DirectiveMap)
-> m (ExecutionPlan, [QueryRootField UnpreparedValue], G.SelectionSet G.NoFragments Variable, DirectiveMap)
convertQuerySelSet env logger gqlContext userInfo manager reqHeaders directives fields varDefs varValsM
introspectionDisabledRoles = do
-- Parse the GraphQL query into the RQL AST
@ -86,7 +86,7 @@ convertQuerySelSet env logger gqlContext userInfo manager reqHeaders directives
executionPlan <- for unpreparedQueries \case
RFDB sourceName exists ->
AB.dispatchAnyBackend @BackendExecute exists
\(SourceConfigWith sourceConfig (QDBR db :: QueryDBRoot UnpreparedValue UnpreparedValue b)) -> do
\(SourceConfigWith (sourceConfig :: (SourceConfig b)) (QDBR db)) -> do
let (noRelsDBAST, remoteJoins) = RJ.getRemoteJoins db
dbStepInfo <- mkDBQueryPlan @b userInfo sourceName sourceConfig noRelsDBAST
pure $ ExecStepDB [] (AB.mkAnyBackend dbStepInfo) remoteJoins

View File

@ -52,8 +52,8 @@ import Hasura.RQL.Types
-- | Collects remote joins from the AST and also adds the necessary join fields
getRemoteJoins
:: (Backend b)
=> QueryDB b r (UnpreparedValue b)
:: Backend b
=> QueryDB b (RemoteSelect UnpreparedValue) (UnpreparedValue b)
-> (QueryDB b (Const Void) (UnpreparedValue b), Maybe RemoteJoins)
getRemoteJoins = \case
QDBMultipleRows s -> first QDBMultipleRows $ getRemoteJoinsSelect s
@ -63,32 +63,32 @@ getRemoteJoins = \case
-- | Traverse through 'AnnSimpleSel' and collect remote join fields (if any).
getRemoteJoinsSelect
:: (Backend b)
=> AnnSimpleSelectG b r (UnpreparedValue b)
:: Backend b
=> AnnSimpleSelectG b (RemoteSelect UnpreparedValue) (UnpreparedValue b)
-> (AnnSimpleSelectG b (Const Void) (UnpreparedValue b), Maybe RemoteJoins)
getRemoteJoinsSelect =
second mapToNonEmpty . flip runState mempty . transformSelect mempty
-- | Traverse through @'AnnAggregateSelect' and collect remote join fields (if any).
getRemoteJoinsAggregateSelect
:: (Backend b)
=> AnnAggregateSelectG b r (UnpreparedValue b)
:: Backend b
=> AnnAggregateSelectG b (RemoteSelect UnpreparedValue) (UnpreparedValue b)
-> (AnnAggregateSelectG b (Const Void) (UnpreparedValue b), Maybe RemoteJoins)
getRemoteJoinsAggregateSelect =
second mapToNonEmpty . flip runState mempty . transformAggregateSelect mempty
-- | Traverse through @'ConnectionSelect' and collect remote join fields (if any).
getRemoteJoinsConnectionSelect
:: (Backend b)
=> ConnectionSelect b r (UnpreparedValue b)
:: Backend b
=> ConnectionSelect b (RemoteSelect UnpreparedValue) (UnpreparedValue b)
-> (ConnectionSelect b (Const Void) (UnpreparedValue b), Maybe RemoteJoins)
getRemoteJoinsConnectionSelect =
second mapToNonEmpty . flip runState mempty . transformConnectionSelect mempty
-- | Traverse through 'MutationOutput' and collect remote join fields (if any)
getRemoteJoinsMutationOutput
:: (Backend b)
=> MutationOutputG b r (UnpreparedValue b)
:: Backend b
=> MutationOutputG b (RemoteSelect UnpreparedValue) (UnpreparedValue b)
-> (MutationOutputG b (Const Void) (UnpreparedValue b), Maybe RemoteJoins)
getRemoteJoinsMutationOutput =
second mapToNonEmpty . flip runState mempty . transformMutationOutput mempty
@ -111,15 +111,15 @@ getRemoteJoinsMutationOutput =
-- local helpers
getRemoteJoinsAnnFields
:: (Backend b)
=> AnnFieldsG b r (UnpreparedValue b)
:: Backend b
=> AnnFieldsG b (RemoteSelect UnpreparedValue) (UnpreparedValue b)
-> (AnnFieldsG b (Const Void) (UnpreparedValue b), Maybe RemoteJoins)
getRemoteJoinsAnnFields =
second mapToNonEmpty . flip runState mempty . transformAnnFields mempty
getRemoteJoinsMutationDB
:: (Backend b)
=> MutationDB b r (UnpreparedValue b)
:: Backend b
=> MutationDB b (RemoteSelect UnpreparedValue) (UnpreparedValue b)
-> (MutationDB b (Const Void) (UnpreparedValue b), Maybe RemoteJoins)
getRemoteJoinsMutationDB = \case
MDBInsert insert ->
@ -145,7 +145,7 @@ getRemoteJoinsMutationDB = \case
getRemoteJoinsSyncAction
:: (Backend b)
=> AnnActionExecution b r (UnpreparedValue b)
=> AnnActionExecution b (RemoteSelect UnpreparedValue) (UnpreparedValue b)
-> (AnnActionExecution b (Const Void) (UnpreparedValue b), Maybe RemoteJoins)
getRemoteJoinsSyncAction actionExecution =
let (fields', remoteJoins) = getRemoteJoinsAnnFields $ _aaeFields actionExecution
@ -153,7 +153,7 @@ getRemoteJoinsSyncAction actionExecution =
getRemoteJoinsActionQuery
:: (Backend b)
=> ActionQuery b r (UnpreparedValue b)
=> ActionQuery b (RemoteSelect UnpreparedValue) (UnpreparedValue b)
-> (ActionQuery b (Const Void) (UnpreparedValue b), Maybe RemoteJoins)
getRemoteJoinsActionQuery = \case
AQQuery sync ->
@ -180,7 +180,7 @@ getRemoteJoinsActionQuery = \case
getRemoteJoinsActionMutation
:: (Backend b)
=> ActionMutation b r (UnpreparedValue b)
=> ActionMutation b (RemoteSelect UnpreparedValue) (UnpreparedValue b)
-> (ActionMutation b (Const Void) (UnpreparedValue b), Maybe RemoteJoins)
getRemoteJoinsActionMutation = \case
AMSync sync -> first AMSync $ getRemoteJoinsSyncAction sync
@ -190,7 +190,7 @@ getRemoteJoinsActionMutation = \case
transformSelect
:: (Backend b)
=> FieldPath
-> AnnSimpleSelectG b r (UnpreparedValue b)
-> AnnSimpleSelectG b (RemoteSelect UnpreparedValue) (UnpreparedValue b)
-> State RemoteJoinMap (AnnSimpleSelectG b (Const Void) (UnpreparedValue b))
transformSelect path sel = do
let fields = _asnFields sel
@ -201,7 +201,7 @@ transformSelect path sel = do
transformAggregateSelect
:: (Backend b)
=> FieldPath
-> AnnAggregateSelectG b r (UnpreparedValue b)
-> AnnAggregateSelectG b (RemoteSelect UnpreparedValue) (UnpreparedValue b)
-> State RemoteJoinMap (AnnAggregateSelectG b (Const Void) (UnpreparedValue b))
transformAggregateSelect path sel = do
let aggFields = _asnFields sel
@ -215,7 +215,7 @@ transformAggregateSelect path sel = do
transformConnectionSelect
:: (Backend b)
=> FieldPath
-> ConnectionSelect b r (UnpreparedValue b)
-> ConnectionSelect b (RemoteSelect UnpreparedValue) (UnpreparedValue b)
-> State RemoteJoinMap (ConnectionSelect b (Const Void) (UnpreparedValue b))
transformConnectionSelect path ConnectionSelect{..} = do
let connectionFields = _asnFields _csSelect
@ -238,7 +238,7 @@ transformConnectionSelect path ConnectionSelect{..} = do
transformObjectSelect
:: (Backend b)
=> FieldPath
-> AnnObjectSelectG b r (UnpreparedValue b)
-> AnnObjectSelectG b (RemoteSelect UnpreparedValue) (UnpreparedValue b)
-> State RemoteJoinMap (AnnObjectSelectG b (Const Void) (UnpreparedValue b))
transformObjectSelect path sel = do
let fields = _aosFields sel
@ -246,10 +246,9 @@ transformObjectSelect path sel = do
pure sel{_aosFields = transformedFields}
transformAnnFields
:: forall b r
. (Backend b)
:: forall b . Backend b
=> FieldPath
-> AnnFieldsG b r (UnpreparedValue b)
-> AnnFieldsG b (RemoteSelect UnpreparedValue) (UnpreparedValue b)
-> State RemoteJoinMap (AnnFieldsG b (Const Void) (UnpreparedValue b))
transformAnnFields path fields = do
@ -260,9 +259,14 @@ transformAnnFields path fields = do
let columnsInSelSet = HS.fromList $ map (pgiColumn . _acfInfo . snd) $ getFields _AFColumn fields
scalarComputedFieldsInSelSet = HS.fromList $ map ((^. _2) . snd) $ getFields _AFComputedField fields
remoteSelects = getFields (_AFRemote) fields
remoteSelects = getFields (_AFRemote.to getRemoteSchemaSelect) fields
getRemoteSchemaSelect = \case
RemoteSelectRemoteSchema s -> s
RemoteSelectSource _s -> error "remote source relationshsip found"
remoteJoins = remoteSelects <&> \(fieldName, remoteSelect) ->
let RemoteSelect argsMap selSet hasuraFields remoteFields rsi = remoteSelect
let RemoteSchemaSelect argsMap selSet hasuraFields remoteFields rsi = remoteSelect
hasuraFieldNames = HS.map dbJoinFieldToName hasuraFields
-- See Note [Phantom fields in Remote Joins]
@ -291,10 +295,11 @@ transformAnnFields path fields = do
AFComputedField x n <$> case computedField of
CFSScalar cfss cbe -> pure $ CFSScalar cfss cbe
CFSTable jas annSel -> CFSTable jas <$> transformSelect fieldPath annSel
AFRemote rs -> pure $ AFRemote rs
-- we generate this so that the response has a key with the relationship,
-- without which preserving the order of fields in the final response
-- would require a lot of bookkeeping
AFRemote _rs -> pure $ AFExpression "remote relationship placeholder"
AFExpression t -> pure $ AFExpression t
-- TODO: implement this
AFDBRemote _ -> error "FIXME"
case NE.nonEmpty remoteJoins of
Nothing -> pure transformedFields

View File

@ -53,7 +53,7 @@ explainQueryField
)
=> UserInfo
-> G.Name
-> QueryRootField UnpreparedValue UnpreparedValue
-> QueryRootField UnpreparedValue
-> m EncJSON
explainQueryField userInfo fieldName rootField = do
case rootField of

View File

@ -207,9 +207,9 @@ buildRoleContext
getMutationRemotes = concatMap (concat . piMutation)
buildSource :: forall b. BackendSchema b => SourceInfo b ->
ConcreteSchemaT m ( [FieldParser (P.ParseT Identity) (QueryRootField UnpreparedValue UnpreparedValue)]
, [FieldParser (P.ParseT Identity) (MutationRootField UnpreparedValue UnpreparedValue)]
, [FieldParser (P.ParseT Identity) (MutationRootField UnpreparedValue UnpreparedValue)]
ConcreteSchemaT m ( [FieldParser (P.ParseT Identity) (QueryRootField UnpreparedValue)]
, [FieldParser (P.ParseT Identity) (MutationRootField UnpreparedValue)]
, [FieldParser (P.ParseT Identity) (MutationRootField UnpreparedValue)]
)
buildSource (SourceInfo sourceName tables functions sourceConfig) = do
let validFunctions = takeValidFunctions functions
@ -276,9 +276,9 @@ buildRelayRoleContext
where
buildSource :: forall b. BackendSchema b => SourceInfo b ->
ConcreteSchemaT m ( [FieldParser (P.ParseT Identity) (QueryRootField UnpreparedValue UnpreparedValue)]
, [FieldParser (P.ParseT Identity) (MutationRootField UnpreparedValue UnpreparedValue)]
, [FieldParser (P.ParseT Identity) (MutationRootField UnpreparedValue UnpreparedValue)]
ConcreteSchemaT m ( [FieldParser (P.ParseT Identity) (QueryRootField UnpreparedValue)]
, [FieldParser (P.ParseT Identity) (MutationRootField UnpreparedValue)]
, [FieldParser (P.ParseT Identity) (MutationRootField UnpreparedValue)]
)
buildSource (SourceInfo sourceName tables functions sourceConfig) = do
let validFunctions = takeValidFunctions functions
@ -296,8 +296,8 @@ buildFullestDBSchema
-> SourceCache
-> [ActionInfo]
-> NonObjectTypeMap
-> m ( Parser 'Output (P.ParseT Identity) (OMap.InsOrdHashMap G.Name (QueryRootField UnpreparedValue UnpreparedValue))
, Maybe (Parser 'Output (P.ParseT Identity) (OMap.InsOrdHashMap G.Name (MutationRootField UnpreparedValue UnpreparedValue)))
-> m ( Parser 'Output (P.ParseT Identity) (OMap.InsOrdHashMap G.Name (QueryRootField UnpreparedValue))
, Maybe (Parser 'Output (P.ParseT Identity) (OMap.InsOrdHashMap G.Name (MutationRootField UnpreparedValue)))
)
buildFullestDBSchema queryContext sources allActionInfos nonObjectCustomTypes =
runMonadSchema adminRoleName queryContext sources do
@ -317,8 +317,8 @@ buildFullestDBSchema queryContext sources allActionInfos nonObjectCustomTypes =
where
buildSource :: forall b. BackendSchema b => SourceInfo b ->
ConcreteSchemaT m ( [FieldParser (P.ParseT Identity) (QueryRootField UnpreparedValue UnpreparedValue)]
, [FieldParser (P.ParseT Identity) (MutationRootField UnpreparedValue UnpreparedValue)]
ConcreteSchemaT m ( [FieldParser (P.ParseT Identity) (QueryRootField UnpreparedValue)]
, [FieldParser (P.ParseT Identity) (MutationRootField UnpreparedValue)]
)
buildSource (SourceInfo sourceName tables functions sourceConfig) = do
let validFunctions = takeValidFunctions functions
@ -432,7 +432,7 @@ buildQueryFields
-> SourceConfig b
-> TableCache b
-> FunctionCache b
-> m [P.FieldParser n (QueryRootField UnpreparedValue UnpreparedValue)]
-> m [P.FieldParser n (QueryRootField UnpreparedValue)]
buildQueryFields sourceName sourceConfig tables (takeExposedAs FEAQuery -> functions) = do
roleName <- askRoleName
functionPermsCtx <- asks $ qcFunctionPermsContext . getter
@ -459,7 +459,7 @@ buildRelayQueryFields
-> SourceConfig b
-> TableCache b
-> FunctionCache b
-> m [P.FieldParser n (QueryRootField UnpreparedValue UnpreparedValue)]
-> m [P.FieldParser n (QueryRootField UnpreparedValue)]
buildRelayQueryFields sourceName sourceConfig tables (takeExposedAs FEAQuery -> functions) = do
tableConnectionFields <- for (Map.toList tables) \(tableName, tableInfo) -> runMaybeT do
tableGQLName <- getTableGQLName @b tableInfo
@ -484,7 +484,7 @@ buildMutationFields
-> SourceConfig b
-> TableCache b
-> FunctionCache b
-> m [P.FieldParser n (MutationRootField UnpreparedValue UnpreparedValue)]
-> m [P.FieldParser n (MutationRootField UnpreparedValue)]
buildMutationFields scenario sourceName sourceConfig tables (takeExposedAs FEAMutation -> functions) = do
roleName <- askRoleName
tableMutations <- for (Map.toList tables) \(tableName, tableInfo) -> do
@ -540,13 +540,13 @@ buildQueryParser
, MonadRole r m
, Has QueryContext r
)
=> [P.FieldParser n (QueryRootField UnpreparedValue UnpreparedValue)]
=> [P.FieldParser n (QueryRootField UnpreparedValue)]
-> [P.FieldParser n RemoteField]
-> [ActionInfo]
-> NonObjectTypeMap
-> Maybe (Parser 'Output n (OMap.InsOrdHashMap G.Name (MutationRootField UnpreparedValue UnpreparedValue)))
-> Parser 'Output n (OMap.InsOrdHashMap G.Name (QueryRootField UnpreparedValue UnpreparedValue))
-> m (Parser 'Output n (OMap.InsOrdHashMap G.Name (QueryRootField UnpreparedValue UnpreparedValue)))
-> Maybe (Parser 'Output n (OMap.InsOrdHashMap G.Name (MutationRootField UnpreparedValue)))
-> Parser 'Output n (OMap.InsOrdHashMap G.Name (QueryRootField UnpreparedValue))
-> m (Parser 'Output n (OMap.InsOrdHashMap G.Name (QueryRootField UnpreparedValue)))
buildQueryParser pgQueryFields remoteFields allActions nonObjectCustomTypes mutationParser subscriptionParser = do
actionQueryFields <- concat <$> traverse (buildActionQueryFields nonObjectCustomTypes) allActions
let allQueryFields = pgQueryFields <> actionQueryFields <> map (fmap RFRemote) remoteFields
@ -554,10 +554,10 @@ buildQueryParser pgQueryFields remoteFields allActions nonObjectCustomTypes muta
queryWithIntrospectionHelper
:: forall n m. (MonadSchema n m, MonadError QErr m)
=> [P.FieldParser n (QueryRootField UnpreparedValue UnpreparedValue)]
-> Maybe (Parser 'Output n (OMap.InsOrdHashMap G.Name (MutationRootField UnpreparedValue UnpreparedValue)))
-> Parser 'Output n (OMap.InsOrdHashMap G.Name (QueryRootField UnpreparedValue UnpreparedValue))
-> m (Parser 'Output n (OMap.InsOrdHashMap G.Name (QueryRootField UnpreparedValue UnpreparedValue)))
=> [P.FieldParser n (QueryRootField UnpreparedValue)]
-> Maybe (Parser 'Output n (OMap.InsOrdHashMap G.Name (MutationRootField UnpreparedValue)))
-> Parser 'Output n (OMap.InsOrdHashMap G.Name (QueryRootField UnpreparedValue))
-> m (Parser 'Output n (OMap.InsOrdHashMap G.Name (QueryRootField UnpreparedValue)))
queryWithIntrospectionHelper basicQueryFP mutationP subscriptionP = do
basicQueryP <- queryRootFromFields basicQueryFP
emptyIntro <- emptyIntrospection
@ -588,15 +588,15 @@ queryWithIntrospectionHelper basicQueryFP mutationP subscriptionP = do
queryRootFromFields
:: forall n m
. (MonadError QErr m, MonadParse n)
=> [P.FieldParser n (QueryRootField UnpreparedValue UnpreparedValue)]
-> m (Parser 'Output n (OMap.InsOrdHashMap G.Name (QueryRootField UnpreparedValue UnpreparedValue)))
=> [P.FieldParser n (QueryRootField UnpreparedValue)]
-> m (Parser 'Output n (OMap.InsOrdHashMap G.Name (QueryRootField UnpreparedValue)))
queryRootFromFields fps =
P.safeSelectionSet queryRoot Nothing fps <&> fmap (fmap typenameToRawRF)
emptyIntrospection
:: forall m n
. (MonadSchema n m, MonadError QErr m)
=> m [P.FieldParser n (QueryRootField UnpreparedValue UnpreparedValue)]
=> m [P.FieldParser n (QueryRootField UnpreparedValue)]
emptyIntrospection = do
emptyQueryP <- queryRootFromFields @n []
introspectionTypes <- collectTypes (P.parserType emptyQueryP)
@ -630,9 +630,9 @@ buildSubscriptionParser
, MonadRole r m
, Has QueryContext r
)
=> [P.FieldParser n (QueryRootField UnpreparedValue UnpreparedValue)]
=> [P.FieldParser n (QueryRootField UnpreparedValue)]
-> [ActionInfo]
-> m (Parser 'Output n (OMap.InsOrdHashMap G.Name (QueryRootField UnpreparedValue UnpreparedValue)))
-> m (Parser 'Output n (OMap.InsOrdHashMap G.Name (QueryRootField UnpreparedValue)))
buildSubscriptionParser queryFields allActions = do
actionSubscriptionFields <- concat <$> traverse buildActionSubscriptionFields allActions
let subscriptionFields = queryFields <> actionSubscriptionFields
@ -648,8 +648,8 @@ buildMutationParser
=> [P.FieldParser n RemoteField]
-> [ActionInfo]
-> NonObjectTypeMap
-> [P.FieldParser n (MutationRootField UnpreparedValue UnpreparedValue)]
-> m (Maybe (Parser 'Output n (OMap.InsOrdHashMap G.Name (MutationRootField UnpreparedValue UnpreparedValue))))
-> [P.FieldParser n (MutationRootField UnpreparedValue)]
-> m (Maybe (Parser 'Output n (OMap.InsOrdHashMap G.Name (MutationRootField UnpreparedValue))))
buildMutationParser allRemotes allActions nonObjectCustomTypes mutationFields = do
actionParsers <- concat <$> traverse (buildActionMutationFields nonObjectCustomTypes) allActions
let mutationFieldsParser =

View File

@ -47,7 +47,7 @@ actionExecute
. MonadBuildSchema ('Postgres 'Vanilla) r m n
=> NonObjectTypeMap
-> ActionInfo
-> m (Maybe (FieldParser n (AnnActionExecution ('Postgres 'Vanilla) UnpreparedValue (UnpreparedValue ('Postgres 'Vanilla)))))
-> m (Maybe (FieldParser n (AnnActionExecution ('Postgres 'Vanilla) (RQL.RemoteSelect UnpreparedValue) (UnpreparedValue ('Postgres 'Vanilla)))))
actionExecute nonObjectTypeMap actionInfo = runMaybeT do
roleName <- askRoleName
guard (roleName == adminRoleName || roleName `Map.member` permissions)
@ -113,7 +113,7 @@ actionAsyncQuery
:: forall r m n
. MonadBuildSchema ('Postgres 'Vanilla) r m n
=> ActionInfo
-> m (Maybe (FieldParser n (AnnActionAsyncQuery ('Postgres 'Vanilla) UnpreparedValue (UnpreparedValue ('Postgres 'Vanilla)))))
-> m (Maybe (FieldParser n (AnnActionAsyncQuery ('Postgres 'Vanilla) (RQL.RemoteSelect UnpreparedValue) (UnpreparedValue ('Postgres 'Vanilla)))))
actionAsyncQuery actionInfo = runMaybeT do
roleName <- askRoleName
guard $ roleName == adminRoleName || roleName `Map.member` permissions
@ -172,7 +172,7 @@ actionOutputFields
. MonadBuildSchema ('Postgres 'Vanilla) r m n
=> G.GType
-> AnnotatedObjectType
-> m (Parser 'Output n (RQL.AnnFieldsG ('Postgres 'Vanilla) UnpreparedValue (UnpreparedValue ('Postgres 'Vanilla))))
-> m (Parser 'Output n (AnnotatedFields ('Postgres 'Vanilla)))
actionOutputFields outputType annotatedObject = do
let outputObject = _aotDefinition annotatedObject
scalarOrEnumFields = map outputFieldParser $ toList $ _otdFields outputObject
@ -194,7 +194,7 @@ actionOutputFields outputType annotatedObject = do
outputFieldParser
:: ObjectFieldDefinition (G.GType, AnnotatedObjectFieldType)
-> FieldParser n (RQL.AnnFieldG ('Postgres 'Vanilla) UnpreparedValue (UnpreparedValue ('Postgres 'Vanilla)))
-> FieldParser n (AnnotatedField ('Postgres 'Vanilla))
outputFieldParser (ObjectFieldDefinition name _ description (gType, objectFieldType)) =
let fieldName = unObjectFieldName name
selection = P.selection_ fieldName description $ case objectFieldType of
@ -211,7 +211,7 @@ actionOutputFields outputType annotatedObject = do
relationshipFieldParser
:: TypeRelationship (TableInfo ('Postgres 'Vanilla)) (ColumnInfo ('Postgres 'Vanilla))
-> m (Maybe [FieldParser n (RQL.AnnFieldG ('Postgres 'Vanilla) UnpreparedValue (UnpreparedValue ('Postgres 'Vanilla)))])
-> m (Maybe [FieldParser n (AnnotatedField ('Postgres 'Vanilla))])
relationshipFieldParser (TypeRelationship relName relType sourceName tableInfo fieldMapping) = runMaybeT do
let tableName = _tciName $ _tiCoreInfo tableInfo
fieldName = unRelationshipName relName

View File

@ -72,7 +72,7 @@ class Backend b => BackendSchema (b :: BackendType) where
-> TableInfo b
-> G.Name
-> SelPermInfo b
-> m [FieldParser n (QueryRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (QueryRootField UnpreparedValue)]
buildTableRelayQueryFields
:: MonadBuildSchema b r m n
=> SourceName
@ -82,7 +82,7 @@ class Backend b => BackendSchema (b :: BackendType) where
-> G.Name
-> NESeq (ColumnInfo b)
-> SelPermInfo b
-> m [FieldParser n (QueryRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (QueryRootField UnpreparedValue)]
buildTableInsertMutationFields
:: MonadBuildSchema b r m n
=> SourceName
@ -93,7 +93,7 @@ class Backend b => BackendSchema (b :: BackendType) where
-> InsPermInfo b
-> Maybe (SelPermInfo b)
-> Maybe (UpdPermInfo b)
-> m [FieldParser n (MutationRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (MutationRootField UnpreparedValue)]
buildTableUpdateMutationFields
:: MonadBuildSchema b r m n
=> SourceName
@ -103,7 +103,7 @@ class Backend b => BackendSchema (b :: BackendType) where
-> G.Name
-> UpdPermInfo b
-> Maybe (SelPermInfo b)
-> m [FieldParser n (MutationRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (MutationRootField UnpreparedValue)]
buildTableDeleteMutationFields
:: MonadBuildSchema b r m n
=> SourceName
@ -113,7 +113,7 @@ class Backend b => BackendSchema (b :: BackendType) where
-> G.Name
-> DelPermInfo b
-> Maybe (SelPermInfo b)
-> m [FieldParser n (MutationRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (MutationRootField UnpreparedValue)]
buildFunctionQueryFields
:: MonadBuildSchema b r m n
=> SourceName
@ -122,7 +122,7 @@ class Backend b => BackendSchema (b :: BackendType) where
-> FunctionInfo b
-> TableName b
-> SelPermInfo b
-> m [FieldParser n (QueryRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (QueryRootField UnpreparedValue)]
buildFunctionRelayQueryFields
:: MonadBuildSchema b r m n
=> SourceName
@ -132,7 +132,7 @@ class Backend b => BackendSchema (b :: BackendType) where
-> TableName b
-> NESeq (ColumnInfo b)
-> SelPermInfo b
-> m [FieldParser n (QueryRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (QueryRootField UnpreparedValue)]
buildFunctionMutationFields
:: MonadBuildSchema b r m n
=> SourceName
@ -141,7 +141,7 @@ class Backend b => BackendSchema (b :: BackendType) where
-> FunctionInfo b
-> TableName b
-> SelPermInfo b
-> m [FieldParser n (MutationRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (MutationRootField UnpreparedValue)]
-- table components
tableArguments

View File

@ -30,7 +30,7 @@ buildTableQueryFields
-> TableInfo b
-> G.Name
-> SelPermInfo b
-> m [FieldParser n (QueryRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (QueryRootField UnpreparedValue)]
buildTableQueryFields sourceName sourceInfo tableName tableInfo gqlName selPerms = do
let
mkRF = RFDB sourceName
@ -64,7 +64,7 @@ buildTableInsertMutationFields
-> InsPermInfo b
-> Maybe (SelPermInfo b)
-> Maybe (UpdPermInfo b)
-> m [FieldParser n (MutationRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (MutationRootField UnpreparedValue)]
buildTableInsertMutationFields sourceName sourceInfo tableName tableInfo gqlName insPerms mSelPerms mUpdPerms = do
let
mkRF = RFDB sourceName
@ -96,7 +96,7 @@ buildTableUpdateMutationFields
-> G.Name
-> UpdPermInfo b
-> Maybe (SelPermInfo b)
-> m [FieldParser n (MutationRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (MutationRootField UnpreparedValue)]
buildTableUpdateMutationFields sourceName sourceInfo tableName tableInfo gqlName updPerms mSelPerms = do
let
mkRF = RFDB sourceName
@ -127,7 +127,7 @@ buildTableDeleteMutationFields
-> G.Name
-> DelPermInfo b
-> Maybe (SelPermInfo b)
-> m [FieldParser n (MutationRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (MutationRootField UnpreparedValue)]
buildTableDeleteMutationFields sourceName sourceInfo tableName tableInfo gqlName delPerms mSelPerms = do
let
mkRF = RFDB sourceName
@ -157,7 +157,7 @@ buildFunctionQueryFields
-> FunctionInfo b
-> TableName b
-> SelPermInfo b
-> m [FieldParser n (QueryRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (QueryRootField UnpreparedValue)]
buildFunctionQueryFields sourceName sourceInfo functionName functionInfo tableName selPerms = do
funcName <- functionGraphQLName @b functionName `onLeft` throwError
let
@ -188,7 +188,7 @@ buildFunctionMutationFields
-> FunctionInfo b
-> TableName b
-> SelPermInfo b
-> m [FieldParser n (MutationRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (MutationRootField UnpreparedValue)]
buildFunctionMutationFields sourceName sourceInfo functionName functionInfo tableName selPerms = do
funcName <- functionGraphQLName @b functionName `onLeft` throwError
let

View File

@ -21,13 +21,15 @@ import Hasura.GraphQL.Parser (UnpreparedValue)
import Hasura.RQL.Types
type SelectExp b = IR.AnnSimpleSelectG b UnpreparedValue (UnpreparedValue b)
type AggSelectExp b = IR.AnnAggregateSelectG b UnpreparedValue (UnpreparedValue b)
type ConnectionSelectExp b = IR.ConnectionSelect b UnpreparedValue (UnpreparedValue b)
type SelectArgs b = IR.SelectArgsG b (UnpreparedValue b)
type TablePerms b = IR.TablePermG b (UnpreparedValue b)
type AnnotatedFields b = IR.AnnFieldsG b UnpreparedValue (UnpreparedValue b)
type AnnotatedField b = IR.AnnFieldG b UnpreparedValue (UnpreparedValue b)
type SelectExp b = IR.AnnSimpleSelectG b (IR.RemoteSelect UnpreparedValue) (UnpreparedValue b)
type AggSelectExp b = IR.AnnAggregateSelectG b (IR.RemoteSelect UnpreparedValue) (UnpreparedValue b)
type ConnectionSelectExp b = IR.ConnectionSelect b (IR.RemoteSelect UnpreparedValue) (UnpreparedValue b)
type SelectArgs b = IR.SelectArgsG b (UnpreparedValue b)
type TablePerms b = IR.TablePermG b (UnpreparedValue b)
type AnnotatedFields b = IR.AnnFieldsG b (IR.RemoteSelect UnpreparedValue) (UnpreparedValue b)
type AnnotatedField b = IR.AnnFieldG b (IR.RemoteSelect UnpreparedValue) (UnpreparedValue b)
type ConnectionFields b = IR.ConnectionFields b (IR.RemoteSelect UnpreparedValue) (UnpreparedValue b)
type EdgeFields b = IR.EdgeFields b (IR.RemoteSelect UnpreparedValue) (UnpreparedValue b)
data QueryContext =
QueryContext

View File

@ -22,6 +22,7 @@ import qualified Hasura.GraphQL.Parser as P
import qualified Hasura.RQL.IR.Delete as IR
import qualified Hasura.RQL.IR.Insert as IR
import qualified Hasura.RQL.IR.Returning as IR
import qualified Hasura.RQL.IR.Select as IR
import qualified Hasura.RQL.IR.Update as IR
import Hasura.GraphQL.Parser (FieldParser, InputFieldsParser, Kind (..), Parser,
@ -48,7 +49,7 @@ insertIntoTable
-> InsPermInfo b -- ^ insert permissions of the table
-> Maybe (SelPermInfo b) -- ^ select permissions of the table (if any)
-> Maybe (UpdPermInfo b) -- ^ update permissions of the table (if any)
-> m (FieldParser n (IR.AnnInsert b UnpreparedValue (UnpreparedValue b)))
-> m (FieldParser n (IR.AnnInsert b (IR.RemoteSelect UnpreparedValue) (UnpreparedValue b)))
insertIntoTable sourceName tableInfo fieldName description insertPerms selectPerms updatePerms = do
let columns = tableColumns tableInfo
selectionParser <- mutationSelectionSet sourceName tableInfo selectPerms
@ -86,7 +87,7 @@ insertOneIntoTable
-> InsPermInfo b -- ^ insert permissions of the table
-> SelPermInfo b -- ^ select permissions of the table
-> Maybe (UpdPermInfo b) -- ^ update permissions of the table (if any)
-> m (FieldParser n (IR.AnnInsert b UnpreparedValue (UnpreparedValue b)))
-> m (FieldParser n (IR.AnnInsert b (IR.RemoteSelect UnpreparedValue) (UnpreparedValue b)))
insertOneIntoTable sourceName tableInfo fieldName description insertPerms selectPerms updatePerms = do
let columns = tableColumns tableInfo
selectionParser <- tableSelectionSet sourceName tableInfo selectPerms
@ -298,7 +299,7 @@ updateTable
-> Maybe G.Description -- ^ field description, if any
-> UpdPermInfo b -- ^ update permissions of the table
-> Maybe (SelPermInfo b) -- ^ select permissions of the table (if any)
-> m (Maybe (FieldParser n (IR.AnnUpdG b UnpreparedValue (UnpreparedValue b))))
-> m (Maybe (FieldParser n (IR.AnnUpdG b (IR.RemoteSelect UnpreparedValue) (UnpreparedValue b))))
updateTable sourceName tableInfo fieldName description updatePerms selectPerms = runMaybeT $ do
let whereName = $$(G.litName "where")
whereDesc = "filter the rows which have to be updated"
@ -324,7 +325,7 @@ updateTableByPk
-> Maybe G.Description -- ^ field description, if any
-> UpdPermInfo b -- ^ update permissions of the table
-> SelPermInfo b -- ^ select permissions of the table
-> m (Maybe (FieldParser n (IR.AnnUpdG b UnpreparedValue (UnpreparedValue b))))
-> m (Maybe (FieldParser n (IR.AnnUpdG b (IR.RemoteSelect UnpreparedValue) (UnpreparedValue b))))
updateTableByPk sourceName tableInfo fieldName description updatePerms selectPerms = runMaybeT $ do
tableGQLName <- getTableGQLName tableInfo
let columns = tableColumns tableInfo
@ -350,9 +351,9 @@ mkUpdateObject
-> ( ( [(Column b, IR.UpdOpExpG (UnpreparedValue b))]
, AnnBoolExp b (UnpreparedValue b)
)
, IR.MutationOutputG b UnpreparedValue (UnpreparedValue b)
, IR.MutationOutputG b (IR.RemoteSelect UnpreparedValue) (UnpreparedValue b)
)
-> IR.AnnUpdG b UnpreparedValue (UnpreparedValue b)
-> IR.AnnUpdG b (IR.RemoteSelect UnpreparedValue) (UnpreparedValue b)
mkUpdateObject table columns updatePerms ((opExps, whereExp), mutationOutput) =
IR.AnnUpd { IR.uqp1Table = table
, IR.uqp1OpExps = opExps
@ -379,7 +380,7 @@ deleteFromTable
-> Maybe G.Description -- ^ field description, if any
-> DelPermInfo b -- ^ delete permissions of the table
-> Maybe (SelPermInfo b) -- ^ select permissions of the table (if any)
-> m (FieldParser n (IR.AnnDelG b UnpreparedValue (UnpreparedValue b)))
-> m (FieldParser n (IR.AnnDelG b (IR.RemoteSelect UnpreparedValue) (UnpreparedValue b)))
deleteFromTable sourceName tableInfo fieldName description deletePerms selectPerms = do
let whereName = $$(G.litName "where")
whereDesc = "filter the rows which have to be deleted"
@ -401,7 +402,7 @@ deleteFromTableByPk
-> Maybe G.Description -- ^ field description, if any
-> DelPermInfo b -- ^ delete permissions of the table
-> SelPermInfo b -- ^ select permissions of the table
-> m (Maybe (FieldParser n (IR.AnnDelG b UnpreparedValue (UnpreparedValue b))))
-> m (Maybe (FieldParser n (IR.AnnDelG b (IR.RemoteSelect UnpreparedValue) (UnpreparedValue b))))
deleteFromTableByPk sourceName tableInfo fieldName description deletePerms selectPerms = runMaybeT $ do
let columns = tableColumns tableInfo
pkArgs <- MaybeT $ primaryKeysArguments tableInfo selectPerms
@ -414,8 +415,8 @@ mkDeleteObject
=> TableName b
-> [ColumnInfo b]
-> DelPermInfo b
-> (AnnBoolExp b (UnpreparedValue b), IR.MutationOutputG b UnpreparedValue (UnpreparedValue b))
-> IR.AnnDelG b UnpreparedValue (UnpreparedValue b)
-> (AnnBoolExp b (UnpreparedValue b), IR.MutationOutputG b (IR.RemoteSelect UnpreparedValue) (UnpreparedValue b))
-> IR.AnnDelG b (IR.RemoteSelect UnpreparedValue) (UnpreparedValue b)
mkDeleteObject table columns deletePerms (whereExp, mutationOutput) =
IR.AnnDel { IR.dqp1Table = table
, IR.dqp1Where = (permissionFilter, whereExp)
@ -436,7 +437,7 @@ mutationSelectionSet
=> SourceName
-> TableInfo b
-> Maybe (SelPermInfo b)
-> m (Parser 'Output n (IR.MutFldsG b UnpreparedValue (UnpreparedValue b)))
-> m (Parser 'Output n (IR.MutFldsG b (IR.RemoteSelect UnpreparedValue) (UnpreparedValue b)))
mutationSelectionSet sourceName tableInfo selectPerms =
memoizeOn 'mutationSelectionSet (sourceName, tableName) do
tableGQLName <- getTableGQLName tableInfo

View File

@ -20,7 +20,7 @@ buildActionQueryFields
:: MonadBuildSchema ('Postgres 'Vanilla) r m n
=> NonObjectTypeMap
-> ActionInfo
-> m [FieldParser n (QueryRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (QueryRootField UnpreparedValue)]
buildActionQueryFields nonObjectCustomTypes actionInfo =
maybeToList <$> case _adType (_aiDefinition actionInfo) of
ActionQuery ->
@ -33,7 +33,7 @@ buildActionMutationFields
:: MonadBuildSchema ('Postgres 'Vanilla) r m n
=> NonObjectTypeMap
-> ActionInfo
-> m [FieldParser n (MutationRootField UnpreparedValue UnpreparedValue)]
-> m [FieldParser n (MutationRootField UnpreparedValue)]
buildActionMutationFields nonObjectCustomTypes actionInfo =
maybeToList <$> case _adType (_aiDefinition actionInfo) of
ActionQuery -> pure Nothing
@ -45,8 +45,7 @@ buildActionMutationFields nonObjectCustomTypes actionInfo =
buildActionSubscriptionFields
:: MonadBuildSchema ('Postgres 'Vanilla) r m n
=> ActionInfo
-> m [FieldParser n (QueryRootField UnpreparedValue
UnpreparedValue)]
-> m [FieldParser n (QueryRootField UnpreparedValue)]
buildActionSubscriptionFields actionInfo =
maybeToList <$> case _adType (_aiDefinition actionInfo) of
ActionQuery -> pure Nothing

View File

@ -398,7 +398,7 @@ tableConnectionSelectionSet
=> SourceName
-> TableInfo b
-> SelPermInfo b
-> m (Parser 'Output n (IR.ConnectionFields b UnpreparedValue (UnpreparedValue b)))
-> m (Parser 'Output n (ConnectionFields b))
tableConnectionSelectionSet sourceName tableInfo selectPermissions = memoizeOn 'tableConnectionSelectionSet (sourceName, tableName) do
tableGQLName <- getTableGQLName tableInfo
edgesParser <- tableEdgesSelectionSet tableGQLName
@ -432,7 +432,7 @@ tableConnectionSelectionSet sourceName tableInfo selectPermissions = memoizeOn '
<&> parsedSelectionsToFields IR.PageInfoTypename
tableEdgesSelectionSet
:: G.Name -> m (Parser 'Output n (IR.EdgeFields b UnpreparedValue (UnpreparedValue b)))
:: G.Name -> m (Parser 'Output n (EdgeFields b))
tableEdgesSelectionSet tableGQLName = do
edgeNodeParser <- P.nonNullableParser <$> tableSelectionSet sourceName tableInfo selectPermissions
let edgesType = tableGQLName <> $$(G.litName "Edge")
@ -1155,7 +1155,7 @@ remoteRelationshipField remoteFieldInfo = runMaybeT do
`P.bindField` \G.Field{ G._fArguments = args, G._fSelectionSet = selSet } -> do
let remoteArgs =
Map.toList args <&> \(argName, argVal) -> IR.RemoteFieldArgument argName $ P.GraphQLValue $ argVal
pure $ IR.AFRemote $ IR.RemoteSelect
pure $ IR.AFRemote $ IR.RemoteSelectRemoteSchema $ IR.RemoteSchemaSelect
{ _rselArgs = remoteArgs
, _rselSelection = selSet
, _rselHasuraFields = _rfiHasuraFields remoteSchema
@ -1410,7 +1410,7 @@ nodePG = memoizeOn 'nodePG () do
nodeField
:: forall m n r
. MonadBuildSchema ('Postgres 'Vanilla) r m n
=> m (P.FieldParser n (IR.QueryRootField UnpreparedValue UnpreparedValue))
=> m (P.FieldParser n (IR.QueryRootField UnpreparedValue))
nodeField = do
let idDescription = G.Description "A globally unique id"
idArgument = P.field $$(G.litName "id") (Just idDescription) P.identifier

View File

@ -167,7 +167,7 @@ runSessVarPred = filterSessionVariables . unSessVarPred
-- | Filter out only those session variables used by the query AST provided
filterVariablesFromQuery
:: Backend backend
=> [RootField (QueryDBRoot UnpreparedValue UnpreparedValue) RemoteField (ActionQuery backend UnpreparedValue (UnpreparedValue backend)) d]
=> [RootField (QueryDBRoot (RemoteSelect UnpreparedValue) UnpreparedValue) RemoteField (ActionQuery backend (RemoteSelect UnpreparedValue) (UnpreparedValue backend)) d]
-> SessVarPred
filterVariablesFromQuery query = fold $ rootToSessVarPreds =<< query
where

View File

@ -72,7 +72,14 @@ data ActionMutation (b :: BackendType) (r :: BackendType -> Type) v
newtype QueryDBRoot r v b = QDBR (QueryDB b r (v b))
newtype MutationDBRoot r v b = MDBR (MutationDB b r (v b))
-- | Represents a query root field to an action
type QueryActionRoot v
= ActionQuery ('Postgres 'Vanilla) (RemoteSelect v) (v ('Postgres 'Vanilla))
type QueryRootField r v = RootField (QueryDBRoot r v) RQL.RemoteField (ActionQuery ('Postgres 'Vanilla) r (v ('Postgres 'Vanilla))) JO.Value
type MutationRootField r v = RootField (MutationDBRoot r v) RQL.RemoteField (ActionMutation ('Postgres 'Vanilla) r (v ('Postgres 'Vanilla))) JO.Value
type SubscriptionRootField r v = RootField (QueryDBRoot r v) Void Void Void
-- | Represents a mutation root field to an action
type MutationActionRoot v
= ActionMutation ('Postgres 'Vanilla) (RemoteSelect v) (v ('Postgres 'Vanilla))
type QueryRootField v = RootField (QueryDBRoot (RemoteSelect v) v) RQL.RemoteField (QueryActionRoot v) JO.Value
type MutationRootField v = RootField (MutationDBRoot (RemoteSelect v) v) RQL.RemoteField (MutationActionRoot v) JO.Value
type SubscriptionRootField v = RootField (QueryDBRoot (RemoteSelect v) v) Void Void Void

View File

@ -188,8 +188,11 @@ data AnnFieldG (b :: BackendType) (r :: BackendType -> Type) v
| AFObjectRelation !(ObjectRelationSelectG b r v)
| AFArrayRelation !(ArraySelectG b r v)
| AFComputedField !(XComputedField b) !ComputedFieldName !(ComputedFieldSelect b r v)
| AFRemote !(RemoteSelect b)
| AFDBRemote !(AB.AnyBackend (DBRemoteSelect b r))
-- | A relationship to a remote source/remote schema. Its kind is
-- (r :: BackendType -> Type) so that AFRemote can capture something
-- that is specific to the backend AnnFieldG. See RemoteSelect. When
-- remote joins are extracted from the structure, 'r' becomes 'Const Void'
| AFRemote !(r b)
| AFNodeId !(XRelay b) !(TableName b) !(PrimaryKeyColumns b)
| AFExpression !Text
deriving (Functor, Foldable, Traversable)
@ -361,7 +364,7 @@ type ArraySelect b = ArraySelectG b (Const Void) (SQLExpression b)
type ArraySelectFieldsG b r v = Fields (ArraySelectG b r v)
-- Remote schema relationship
-- Remote schema relationships
data RemoteFieldArgument
= RemoteFieldArgument
@ -369,8 +372,8 @@ data RemoteFieldArgument
, _rfaValue :: !(InputValue RemoteSchemaVariable)
} deriving (Eq,Show)
data RemoteSelect (b :: BackendType)
= RemoteSelect
data RemoteSchemaSelect (b :: BackendType)
= RemoteSchemaSelect
{ _rselArgs :: ![RemoteFieldArgument]
, _rselSelection :: !(G.SelectionSet G.NoFragments RemoteSchemaVariable)
, _rselHasuraFields :: !(HashSet (DBJoinField b))
@ -378,16 +381,45 @@ data RemoteSelect (b :: BackendType)
, _rselRemoteSchema :: !RemoteSchemaInfo
}
-- | Captures the selection set of a remote source relationship.
data SourceRelationshipSelection
(b :: BackendType)
(r :: BackendType -> Type)
(vf :: BackendType -> Type)
= SourceRelationshipObject !(AnnObjectSelectG b r (vf b))
| SourceRelationshipArray !(AnnSimpleSelectG b r (vf b))
| SourceRelationshipArrayAggregate !(AnnAggregateSelectG b r (vf b))
-- Remote db relationship
data DBRemoteSelect (src :: BackendType) (r :: BackendType -> Type) (tgt :: BackendType)
= DBRemoteSelect
{ _dbrselHasuraColumns :: ![(ColumnInfo src, ColumnInfo tgt)]
, _dbrselTargetQuery :: !(QueryDB tgt r (r tgt))
, _dbrselTargetConfig :: !(SourceConfig tgt)
}
-- | A relationship to a remote source. 'vf' (could use a better name) is
-- analogous to 'v' in other IR types such as 'AnnFieldG'. vf's kind is
-- (BackendType -> Type) instead of v's 'Type' so that 'v' of 'AnnFieldG' can
-- be specific to the backend that it captures ('b' of an AnnFieldG changes as
-- we walk down the IR branches which capture relationships to other databases)
data RemoteSourceSelect
(src :: BackendType)
(vf :: BackendType -> Type)
(tgt :: BackendType)
= RemoteSourceSelect
{ _rssSourceName :: !SourceName
, _rssSourceConfig :: !(SourceConfig tgt)
, _rssSelection :: !(SourceRelationshipSelection tgt (RemoteSelect vf) vf)
, _rssJoinMapping :: !(HM.HashMap FieldName (ColumnInfo src, ScalarType tgt, Column tgt))
-- ^ Additional information about the source's join columns:
-- (ColumnInfo src) so that we can add the join column to the AST
-- (ScalarType tgt) so that the remote can interpret the join values coming
-- from src
-- (Column tgt) so that an appropriate join condition / IN clause can be built
-- by the remote
}
-- | A remote relationship to either a remote schema or a remote source.
-- See RemoteSourceSelect for explanation on 'vf'.
data RemoteSelect
(vf :: BackendType -> Type)
(src :: BackendType)
= RemoteSelectRemoteSchema !(RemoteSchemaSelect src)
-- ^ AnyBackend is used here to capture a relationship to an arbitrary target
| RemoteSelectSource !(AB.AnyBackend (RemoteSourceSelect src vf))
-- Permissions