Skip capability check for local relationships (#805)

<!-- The PR description should answer 2 (maybe 3) important questions:
-->

### What

If the target data connector for a relationship does not have the
`foreach` capability, we threw an error, however we should allow this.

<!-- What is this PR trying to accomplish (and why, if it's not
obvious)? -->

<!-- Consider: do we need to add a changelog entry? -->

### How

<!-- How is it trying to accomplish it (what are the implementation
steps)? -->

Check data connector names for relationship target before throwing
capability error.

V3_GIT_ORIGIN_REV_ID: 157908f0077b7c3af67a77600e5f8c9fc65df7f2
This commit is contained in:
Daniel Harvey 2024-07-08 14:02:27 +01:00 committed by hasura-bot
parent aa77448b2f
commit 29ccf96784
3 changed files with 24 additions and 2 deletions

View File

@ -980,7 +980,6 @@
"query": {
"explain": {},
"aggregates": {},
"variables": {},
"nested_fields": {
"filter_by": {},
"order_by": {}

View File

@ -372,6 +372,8 @@ fn get_relationship_capabilities(
source_data_connector: Option<&data_connectors::DataConnectorLink>,
target_name: &RelationshipTargetName,
data_connectors: &data_connectors::DataConnectors,
models: &IndexMap<Qualified<ModelName>, models::Model>,
commands: &IndexMap<Qualified<CommandName>, commands::Command>,
) -> Result<Option<RelationshipCapabilities>, Error> {
let Some(data_connector) = source_data_connector else {
return Ok(None);
@ -394,9 +396,25 @@ fn get_relationship_capabilities(
}
})?;
// which data connector is the target using?
let target_data_connector = match target_name {
RelationshipTargetName::Model(model_name) => models
.get(model_name)
.as_ref()
.and_then(|model| model.source.as_ref())
.map(|source| source.data_connector.name.clone()),
RelationshipTargetName::Command(command_name) => commands
.get(command_name)
.and_then(|command| command.source.as_ref())
.map(|source| source.data_connector.name.clone()),
};
let capabilities = &resolved_data_connector.capabilities;
if capabilities.query.variables.is_none() {
// if relationship is remote, error if `foreach` capability is not available
if capabilities.query.variables.is_none()
&& Some(&data_connector.name) != target_data_connector.as_ref()
{
return Err(Error::RelationshipError {
relationship_error: RelationshipError::RelationshipTargetDoesNotSupportForEach {
type_name: type_name.clone(),
@ -555,6 +573,8 @@ fn resolve_model_relationship_fields(
source_data_connector,
&RelationshipTargetName::Model(resolved_target_model.name.clone()),
data_connectors,
models,
&IndexMap::new(),
)?;
let mappings = resolve_relationship_mappings_model(
@ -647,6 +667,8 @@ fn resolve_command_relationship_field(
source_data_connector,
&RelationshipTargetName::Command(resolved_target_command.name.clone()),
data_connectors,
&IndexMap::new(),
commands,
)?;
let field_name = mk_name(relationship.name.as_str())?;

View File

@ -180,6 +180,7 @@ pub fn build_model_order_by_input_schema(
target_source,
relationship,
)?;
// order_by expression with relationships is currently only supported for local relationships
if let metadata_resolve::RelationshipExecutionCategory::Local =
metadata_resolve::relationship_execution_category(