Nested relationships: Refactor capabilities, add engine test, fix docker compose engine metadata (#1341)

### What
This PR does three related things:
* Adds an execution test that tests that nested relationships work in
field selection in Postgres (taken from #935)
* Refactors the way capabilities are handled in metadata resolve to
account for difference between NDC 0.1.x and 0.2.x. Specifically, NDC
0.1.x connectors are assumed to support nested relationships in field
selection, but do not support them in filtering and ordering. Whereas in
NDC 0.2.x, a capability exists to indicate nested relationship support,
but then you must support them in filtering and ordering as well as
field selection.
* Updates the metadata used in the default docker compose so that it:
    * uses an up to date pg schema
    * uses BooleanExpressionType instead of ObjectBooleanExpression
    * removes commands that do not exist on the pg connector
* adds the Institutions model so that nested relationships can be tested

This PR does not add support for nested relationships in filtering or in
ordering. It also does not block nested relationships in field selection
for NDC 0.2.x connectors that do not support it. This will all come in
later PRs.

### How

In `metadata_resolve`, the resolved `DataConnector` used to contain a
copy of the `ndc_models::Capabilities`. This has been removed and
instead a `metadata_resolve` specific `DataConnectorCapabilities`
structure is used instead. This decouples `metadata_resolve` from
`ndc_models` and allows it to capture differences between NDC 0.1.x and
0.2.x properly.

There is now a specific function per NDC version that creates a
`DataConnectorCapabilities`. This removes the need for capabilities
migration code.

V3_GIT_ORIGIN_REV_ID: 0eb119aab0e5fa22977d84820025f75c6102036d
This commit is contained in:
Daniel Chambers 2024-11-13 23:05:42 +11:00 committed by hasura-bot
parent dd070be7fb
commit f255b5e48a
44 changed files with 11755 additions and 1114 deletions

View File

@ -1,3 +1,5 @@
name: v3-engine-tests
services:
postgres:
extends:

View File

@ -0,0 +1,57 @@
[
{
"data": {
"InstitutionMany": [
{
"name": "Queen Mary University of London",
"staff": [
{
"first_name": "Peter",
"last_name": "Landin",
"favourite_artist_id": 1,
"favourite_artist": {
"artist_id": 1,
"name": "AC/DC"
}
}
]
},
{
"name": "Chalmers University of Technology",
"staff": [
{
"first_name": "John",
"last_name": "Hughes",
"favourite_artist_id": 2,
"favourite_artist": {
"artist_id": 2,
"name": "Accept"
}
},
{
"first_name": "Koen",
"last_name": "Claessen",
"favourite_artist_id": 3,
"favourite_artist": {
"artist_id": 3,
"name": "Aerosmith"
}
}
]
},
{
"name": "University of Nowhere",
"staff": null
}
]
}
},
{
"data": null,
"errors": [
{
"message": "validation failed: no such field on type Artist: name"
}
]
}
]

View File

@ -0,0 +1,485 @@
{
"version": "v2",
"subgraphs": [
{
"name": "default",
"objects": [
{
"kind": "Model",
"version": "v1",
"definition": {
"name": "artist",
"objectType": "artist",
"source": {
"dataConnectorName": "db",
"collection": "Artist"
},
"orderableFields": [
{
"fieldName": "artist_id",
"orderByDirections": {
"enableAll": true
}
},
{
"fieldName": "name",
"orderByDirections": {
"enableAll": true
}
}
],
"graphql": {
"selectUniques": [
{
"queryRootField": "ArtistById",
"uniqueIdentifier": ["artist_id"]
}
],
"selectMany": {
"queryRootField": "Artists"
}
}
}
},
{
"kind": "ModelPermissions",
"version": "v1",
"definition": {
"modelName": "artist",
"permissions": [
{
"role": "admin",
"select": {
"filter": null
}
},
{
"role": "user1",
"select": {
"filter": null
}
}
]
}
},
{
"kind": "Model",
"version": "v1",
"definition": {
"name": "institutions",
"arguments": [],
"objectType": "institution",
"source": {
"dataConnectorName": "db",
"collection": "institution",
"argumentMapping": {}
},
"graphql": {
"selectUniques": [],
"selectMany": {
"queryRootField": "InstitutionMany"
}
},
"orderableFields": [
{
"fieldName": "id",
"orderByDirections": {
"enableAll": true
}
},
{
"fieldName": "name",
"orderByDirections": {
"enableAll": true
}
},
{
"fieldName": "location",
"orderByDirections": {
"enableAll": true
}
},
{
"fieldName": "staff",
"orderByDirections": {
"enableAll": true
}
},
{
"fieldName": "departments",
"orderByDirections": {
"enableAll": true
}
}
]
}
},
{
"kind": "ModelPermissions",
"version": "v1",
"definition": {
"modelName": "institutions",
"permissions": [
{
"role": "admin",
"select": {
"filter": null
}
},
{
"role": "user1",
"select": {
"filter": null
}
}
]
}
},
{
"kind": "ObjectType",
"version": "v1",
"definition": {
"name": "artist",
"fields": [
{
"name": "artist_id",
"type": "Int!"
},
{
"name": "name",
"type": "String!"
}
],
"graphql": {
"typeName": "Artist"
},
"dataConnectorTypeMapping": [
{
"dataConnectorName": "db",
"dataConnectorObjectType": "Artist",
"fieldMapping": {
"artist_id": {
"column": {
"name": "ArtistId"
}
},
"name": {
"column": {
"name": "Name"
}
}
}
}
]
}
},
{
"kind": "TypePermissions",
"version": "v1",
"definition": {
"typeName": "artist",
"permissions": [
{
"role": "admin",
"output": {
"allowedFields": ["artist_id", "name"]
}
},
{
"role": "user1",
"output": {
"allowedFields": ["artist_id"]
}
}
]
}
},
{
"kind": "ObjectType",
"version": "v1",
"definition": {
"name": "institution",
"fields": [
{
"name": "id",
"type": "Int!"
},
{
"name": "name",
"type": "String!"
},
{
"name": "location",
"type": "location"
},
{
"name": "staff",
"type": "[staff_member]"
},
{
"name": "departments",
"type": "[String]"
}
],
"graphql": {
"typeName": "Institution"
},
"dataConnectorTypeMapping": [
{
"dataConnectorName": "db",
"dataConnectorObjectType": "institution",
"fieldMapping": {
"id": {
"column": {
"name": "id"
}
},
"name": {
"column": {
"name": "name"
}
},
"location": {
"column": {
"name": "location"
}
},
"staff": {
"column": {
"name": "staff"
}
},
"departments": {
"column": {
"name": "departments"
}
}
}
}
]
}
},
{
"kind": "TypePermissions",
"version": "v1",
"definition": {
"typeName": "institution",
"permissions": [
{
"role": "admin",
"output": {
"allowedFields": [
"id",
"name",
"location",
"staff",
"departments"
]
}
},
{
"role": "user1",
"output": {
"allowedFields": [
"id",
"name",
"location",
"staff",
"departments"
]
}
}
]
}
},
{
"kind": "ObjectType",
"version": "v1",
"definition": {
"name": "staff_member",
"fields": [
{
"name": "first_name",
"type": "String"
},
{
"name": "last_name",
"type": "String"
},
{
"name": "specialities",
"type": "[String]"
},
{
"name": "favourite_artist_id",
"type": "Int"
}
],
"graphql": {
"typeName": "StaffMember"
},
"dataConnectorTypeMapping": [
{
"dataConnectorName": "db",
"dataConnectorObjectType": "staff",
"fieldMapping": {
"first_name": {
"column": {
"name": "first_name"
}
},
"last_name": {
"column": {
"name": "last_name"
}
},
"specialities": {
"column": {
"name": "specialities"
}
},
"favourite_artist_id": {
"column": {
"name": "favourite_artist_id"
}
}
}
}
]
}
},
{
"kind": "TypePermissions",
"version": "v1",
"definition": {
"typeName": "staff_member",
"permissions": [
{
"role": "admin",
"output": {
"allowedFields": [
"first_name",
"last_name",
"specialities",
"favourite_artist_id"
]
}
},
{
"role": "user1",
"output": {
"allowedFields": [
"first_name",
"last_name",
"specialities",
"favourite_artist_id"
]
}
}
]
}
},
{
"kind": "Relationship",
"version": "v1",
"definition": {
"sourceType": "staff_member",
"name": "favourite_artist",
"target": {
"model": {
"name": "artist",
"relationshipType": "Object"
}
},
"mapping": [
{
"source": {
"fieldPath": [
{
"fieldName": "favourite_artist_id"
}
]
},
"target": {
"modelField": [
{
"fieldName": "artist_id"
}
]
}
}
]
}
},
{
"kind": "ObjectType",
"version": "v1",
"definition": {
"name": "location",
"fields": [
{
"name": "city",
"type": "String"
},
{
"name": "country",
"type": "String"
},
{
"name": "campuses",
"type": "[String]"
}
],
"graphql": {
"typeName": "Location"
},
"dataConnectorTypeMapping": [
{
"dataConnectorName": "db",
"dataConnectorObjectType": "location",
"fieldMapping": {
"city": {
"column": {
"name": "city"
}
},
"country": {
"column": {
"name": "country"
}
},
"campuses": {
"column": {
"name": "campuses"
}
}
}
}
]
}
},
{
"kind": "TypePermissions",
"version": "v1",
"definition": {
"typeName": "location",
"permissions": [
{
"role": "admin",
"output": {
"allowedFields": ["city", "country", "campuses"]
}
},
{
"role": "user1",
"output": {
"allowedFields": ["city", "country", "campuses"]
}
}
]
}
}
]
}
]
}

View File

@ -0,0 +1,14 @@
query MyQuery {
InstitutionMany {
name
staff {
first_name
last_name
favourite_artist_id
favourite_artist {
artist_id
name
}
}
}
}

View File

@ -0,0 +1,8 @@
[
{
"x-hasura-role": "admin"
},
{
"x-hasura-role": "user1"
}
]

View File

@ -467,6 +467,17 @@ fn test_relationships_permissions_source_type_permission() -> anyhow::Result<()>
)
}
#[test]
fn test_relationships_nested_selection() -> anyhow::Result<()> {
let test_path_string = "execute/relationships/nested/selection";
let common_metadata_path_string = "execute/common_metadata/postgres_connector_schema.json";
common::test_execution_expectation(
test_path_string,
&[common_metadata_path_string],
common::TestOpenDDPipeline::Skip,
)
}
// Miscellaneous tests
// What is being tested?

View File

@ -142,7 +142,15 @@
"capabilities": {
"supported_ndc_version": "V01",
"supports_explaining_queries": true,
"supports_nested_object_filtering": true
"supports_nested_object_filtering": true,
"supports_aggregates": {},
"supports_query_variables": true,
"supports_relationships": {
"supports_relation_comparisons": true,
"supports_nested_relationships": {
"supports_nested_array_selection": true
}
}
}
},
"collection": "Artist",

View File

@ -113,7 +113,15 @@
"capabilities": {
"supported_ndc_version": "V01",
"supports_explaining_queries": true,
"supports_nested_object_filtering": true
"supports_nested_object_filtering": true,
"supports_aggregates": {},
"supports_query_variables": true,
"supports_relationships": {
"supports_relation_comparisons": true,
"supports_nested_relationships": {
"supports_nested_array_selection": true
}
}
}
},
"collection": "article",

View File

@ -100,7 +100,15 @@
"capabilities": {
"supported_ndc_version": "V01",
"supports_explaining_queries": true,
"supports_nested_object_filtering": true
"supports_nested_object_filtering": true,
"supports_aggregates": {},
"supports_query_variables": true,
"supports_relationships": {
"supports_relation_comparisons": true,
"supports_nested_relationships": {
"supports_nested_array_selection": true
}
}
}
},
"collection": "article",

View File

@ -37,7 +37,15 @@
"capabilities": {
"supported_ndc_version": "V01",
"supports_explaining_queries": true,
"supports_nested_object_filtering": true
"supports_nested_object_filtering": true,
"supports_aggregates": {},
"supports_query_variables": true,
"supports_relationships": {
"supports_relation_comparisons": true,
"supports_nested_relationships": {
"supports_nested_array_selection": true
}
}
}
},
"collection": "article",
@ -206,7 +214,15 @@
"capabilities": {
"supported_ndc_version": "V01",
"supports_explaining_queries": true,
"supports_nested_object_filtering": true
"supports_nested_object_filtering": true,
"supports_aggregates": {},
"supports_query_variables": true,
"supports_relationships": {
"supports_relation_comparisons": true,
"supports_nested_relationships": {
"supports_nested_array_selection": true
}
}
}
},
"collection": "author",
@ -389,7 +405,15 @@
"capabilities": {
"supported_ndc_version": "V01",
"supports_explaining_queries": true,
"supports_nested_object_filtering": true
"supports_nested_object_filtering": true,
"supports_aggregates": {},
"supports_query_variables": true,
"supports_relationships": {
"supports_relation_comparisons": true,
"supports_nested_relationships": {
"supports_nested_array_selection": true
}
}
}
},
"collection": "article",
@ -665,7 +689,15 @@
"capabilities": {
"supported_ndc_version": "V01",
"supports_explaining_queries": true,
"supports_nested_object_filtering": true
"supports_nested_object_filtering": true,
"supports_aggregates": {},
"supports_query_variables": true,
"supports_relationships": {
"supports_relation_comparisons": true,
"supports_nested_relationships": {
"supports_nested_array_selection": true
}
}
}
},
"arguments": {},
@ -688,7 +720,15 @@
"capabilities": {
"supported_ndc_version": "V01",
"supports_explaining_queries": true,
"supports_nested_object_filtering": true
"supports_nested_object_filtering": true,
"supports_aggregates": {},
"supports_query_variables": true,
"supports_relationships": {
"supports_relation_comparisons": true,
"supports_nested_relationships": {
"supports_nested_array_selection": true
}
}
}
},
"collection": "article",
@ -722,7 +762,15 @@
"capabilities": {
"supported_ndc_version": "V01",
"supports_explaining_queries": true,
"supports_nested_object_filtering": true
"supports_nested_object_filtering": true,
"supports_aggregates": {},
"supports_query_variables": true,
"supports_relationships": {
"supports_relation_comparisons": true,
"supports_nested_relationships": {
"supports_nested_array_selection": true
}
}
}
},
"collection": "author",
@ -756,7 +804,15 @@
"capabilities": {
"supported_ndc_version": "V01",
"supports_explaining_queries": true,
"supports_nested_object_filtering": true
"supports_nested_object_filtering": true,
"supports_aggregates": {},
"supports_query_variables": true,
"supports_relationships": {
"supports_relation_comparisons": true,
"supports_nested_relationships": {
"supports_nested_array_selection": true
}
}
}
},
"collection": "article",
@ -812,7 +868,15 @@
"capabilities": {
"supported_ndc_version": "V01",
"supports_explaining_queries": true,
"supports_nested_object_filtering": true
"supports_nested_object_filtering": true,
"supports_aggregates": {},
"supports_query_variables": true,
"supports_relationships": {
"supports_relation_comparisons": true,
"supports_nested_relationships": {
"supports_nested_array_selection": true
}
}
}
},
"source_type_mappings": {
@ -933,7 +997,15 @@
"capabilities": {
"supported_ndc_version": "V01",
"supports_explaining_queries": true,
"supports_nested_object_filtering": true
"supports_nested_object_filtering": true,
"supports_aggregates": {},
"supports_query_variables": true,
"supports_relationships": {
"supports_relation_comparisons": true,
"supports_nested_relationships": {
"supports_nested_array_selection": true
}
}
}
},
"collection": "article",
@ -1081,7 +1153,15 @@
"capabilities": {
"supported_ndc_version": "V01",
"supports_explaining_queries": true,
"supports_nested_object_filtering": true
"supports_nested_object_filtering": true,
"supports_aggregates": {},
"supports_query_variables": true,
"supports_relationships": {
"supports_relation_comparisons": true,
"supports_nested_relationships": {
"supports_nested_array_selection": true
}
}
}
},
"source_type_mappings": {
@ -1182,7 +1262,15 @@
"capabilities": {
"supported_ndc_version": "V01",
"supports_explaining_queries": true,
"supports_nested_object_filtering": true
"supports_nested_object_filtering": true,
"supports_aggregates": {},
"supports_query_variables": true,
"supports_relationships": {
"supports_relation_comparisons": true,
"supports_nested_relationships": {
"supports_nested_array_selection": true
}
}
}
},
"collection": "author",
@ -1338,7 +1426,15 @@
"capabilities": {
"supported_ndc_version": "V01",
"supports_explaining_queries": true,
"supports_nested_object_filtering": true
"supports_nested_object_filtering": true,
"supports_aggregates": {},
"supports_query_variables": true,
"supports_relationships": {
"supports_relation_comparisons": true,
"supports_nested_relationships": {
"supports_nested_array_selection": true
}
}
}
},
"source_type_mappings": {
@ -1439,7 +1535,15 @@
"capabilities": {
"supported_ndc_version": "V01",
"supports_explaining_queries": true,
"supports_nested_object_filtering": true
"supports_nested_object_filtering": true,
"supports_aggregates": {},
"supports_query_variables": true,
"supports_relationships": {
"supports_relation_comparisons": true,
"supports_nested_relationships": {
"supports_nested_array_selection": true
}
}
}
},
"collection": "article",

View File

@ -113,7 +113,15 @@
"capabilities": {
"supported_ndc_version": "V01",
"supports_explaining_queries": true,
"supports_nested_object_filtering": true
"supports_nested_object_filtering": true,
"supports_aggregates": {},
"supports_query_variables": true,
"supports_relationships": {
"supports_relation_comparisons": true,
"supports_nested_relationships": {
"supports_nested_array_selection": true
}
}
}
},
"collection": "article",

View File

@ -100,7 +100,15 @@
"capabilities": {
"supported_ndc_version": "V01",
"supports_explaining_queries": true,
"supports_nested_object_filtering": true
"supports_nested_object_filtering": true,
"supports_aggregates": {},
"supports_query_variables": true,
"supports_relationships": {
"supports_relation_comparisons": true,
"supports_nested_relationships": {
"supports_nested_array_selection": true
}
}
}
},
"collection": "article",
@ -293,7 +301,15 @@
"capabilities": {
"supported_ndc_version": "V01",
"supports_explaining_queries": true,
"supports_nested_object_filtering": true
"supports_nested_object_filtering": true,
"supports_aggregates": {},
"supports_query_variables": true,
"supports_relationships": {
"supports_relation_comparisons": true,
"supports_nested_relationships": {
"supports_nested_array_selection": true
}
}
}
},
"collection": "author",

View File

@ -326,114 +326,6 @@ fn migrate_procedure_info_from_v01(
}
}
pub fn migrate_capabilities_from_v01(
old_capabilities: ndc_models_v01::Capabilities,
) -> ndc_models_v02::Capabilities {
ndc_models_v02::Capabilities {
query: migrate_query_capabilities_from_v01(old_capabilities.query),
mutation: migrate_mutation_capabilities_from_v01(old_capabilities.mutation),
relationships: old_capabilities
.relationships
.map(migrate_relationship_capabilities_from_v01),
}
}
fn migrate_query_capabilities_from_v01(
old_query_capabilities: ndc_models_v01::QueryCapabilities,
) -> ndc_models_v02::QueryCapabilities {
ndc_models_v02::QueryCapabilities {
aggregates: old_query_capabilities
.aggregates
.map(migrate_aggregate_capabilities_from_v01),
variables: old_query_capabilities
.variables
.map(migrate_leaf_capability_from_v01),
explain: old_query_capabilities
.explain
.map(migrate_leaf_capability_from_v01),
nested_fields: migrate_nested_field_capabilities_from_v01(
old_query_capabilities.nested_fields,
),
exists: migrate_exists_capabilities_from_v01(old_query_capabilities.exists),
}
}
#[allow(clippy::needless_pass_by_value)] // We want the value to be consumed and discarded here
fn migrate_aggregate_capabilities_from_v01(
_old_leaf_capability: ndc_models_v01::LeafCapability,
) -> ndc_models_v02::AggregateCapabilities {
ndc_models_v02::AggregateCapabilities {
filter_by: None, // v0.1.x does not support filtering by aggregate predicates
group_by: None, // v0.1.x does not support group by
}
}
#[allow(clippy::needless_pass_by_value)] // We want the value to be consumed and discarded here
fn migrate_leaf_capability_from_v01(
_old_leaf_capability: ndc_models_v01::LeafCapability,
) -> ndc_models_v02::LeafCapability {
ndc_models_v02::LeafCapability {}
}
fn migrate_exists_capabilities_from_v01(
old_exists_capabilities: ndc_models_v01::ExistsCapabilities,
) -> ndc_models_v02::ExistsCapabilities {
ndc_models_v02::ExistsCapabilities {
named_scopes: None, // v0.1.x does not have named scopes
unrelated: Some(ndc_models_v02::LeafCapability {}), // v0.1.x assumed this capability
nested_collections: old_exists_capabilities
.nested_collections
.map(migrate_leaf_capability_from_v01),
nested_scalar_collections: None,
}
}
fn migrate_nested_field_capabilities_from_v01(
old_nested_field_capabilities: ndc_models_v01::NestedFieldCapabilities,
) -> ndc_models_v02::NestedFieldCapabilities {
ndc_models_v02::NestedFieldCapabilities {
filter_by: old_nested_field_capabilities.filter_by.map(|_leaf| {
ndc_models_v02::NestedFieldFilterByCapabilities {
nested_arrays: None,
}
}),
order_by: old_nested_field_capabilities
.order_by
.map(migrate_leaf_capability_from_v01),
aggregates: old_nested_field_capabilities
.aggregates
.map(migrate_leaf_capability_from_v01),
nested_collections: None, // v0.1.x does not support nested field collections
}
}
fn migrate_mutation_capabilities_from_v01(
old_mutation_capabilities: ndc_models_v01::MutationCapabilities,
) -> ndc_models_v02::MutationCapabilities {
ndc_models_v02::MutationCapabilities {
transactional: old_mutation_capabilities
.transactional
.map(migrate_leaf_capability_from_v01),
explain: old_mutation_capabilities
.explain
.map(migrate_leaf_capability_from_v01),
}
}
fn migrate_relationship_capabilities_from_v01(
old_relationship_capabilities: ndc_models_v01::RelationshipCapabilities,
) -> ndc_models_v02::RelationshipCapabilities {
ndc_models_v02::RelationshipCapabilities {
relation_comparisons: old_relationship_capabilities
.relation_comparisons
.map(migrate_leaf_capability_from_v01),
order_by_aggregate: old_relationship_capabilities
.order_by_aggregate
.map(migrate_leaf_capability_from_v01),
nested: None,
}
}
fn migrate_scalar_type_name_from_v01(
old_name: ndc_models_v01::ScalarTypeName,
) -> ndc_models_v02::ScalarTypeName {

View File

@ -400,7 +400,7 @@ fn resolve_aggregation_function(
name: aggregate_expression_name.clone(),
data_connector_name: data_connector_name.clone(),
})?;
if data_connector.capabilities.query.aggregates.is_none() {
if data_connector.capabilities.supports_aggregates.is_none() {
return Err(AggregateExpressionError::AggregateOperandDataConnectorNotSupported {
name: aggregate_expression_name.clone(),
data_connector_name: data_connector_name.clone(),

View File

@ -56,8 +56,7 @@ pub struct DataConnectorContext<'a> {
pub url: &'a data_connector::DataConnectorUrl,
pub headers: IndexMap<String, String>,
pub schema: DataConnectorSchema,
pub capabilities: ndc_models::Capabilities,
pub supported_ndc_version: NdcVersion,
pub capabilities: DataConnectorCapabilities,
pub argument_presets: Vec<ArgumentPreset>,
pub response_headers: Option<CommandsResponseConfig>,
}
@ -68,9 +67,7 @@ impl<'a> DataConnectorContext<'a> {
data_connector: &'a data_connector::DataConnectorLinkV1,
unstable_features: &UnstableFeatures,
) -> Result<(Self, Vec<DataConnectorIssue>), DataConnectorError> {
let (resolved_schema, capabilities, supported_ndc_version, issues) = match &data_connector
.schema
{
let (resolved_schema, capabilities, issues) = match &data_connector.schema {
VersionedSchemaAndCapabilities::V01(schema_and_capabilities) => {
let issues = validate_ndc_version(
NdcVersion::V01,
@ -80,10 +77,9 @@ impl<'a> DataConnectorContext<'a> {
DataConnectorSchema::new(ndc_migration::v02::migrate_schema_response_from_v01(
schema_and_capabilities.schema.clone(),
));
let capabilities = ndc_migration::v02::migrate_capabilities_from_v01(
schema_and_capabilities.capabilities.capabilities.clone(),
);
(schema, capabilities, NdcVersion::V01, issues)
let capabilities =
mk_ndc_01_capabilities(&schema_and_capabilities.capabilities.capabilities);
(schema, capabilities, issues)
}
VersionedSchemaAndCapabilities::V02(schema_and_capabilities) => {
let issues = validate_ndc_version(
@ -91,12 +87,15 @@ impl<'a> DataConnectorContext<'a> {
&schema_and_capabilities.capabilities.version,
)?;
let schema = DataConnectorSchema::new(schema_and_capabilities.schema.clone());
let capabilities = schema_and_capabilities.capabilities.capabilities.clone();
(schema, capabilities, NdcVersion::V02, issues)
let capabilities =
mk_ndc_02_capabilities(&schema_and_capabilities.capabilities.capabilities);
(schema, capabilities, issues)
}
};
if !unstable_features.enable_ndc_v02_support && supported_ndc_version == NdcVersion::V02 {
if !unstable_features.enable_ndc_v02_support
&& capabilities.supported_ndc_version == NdcVersion::V02
{
return Err(DataConnectorError::NdcV02DataConnectorNotSupported);
}
@ -134,7 +133,6 @@ impl<'a> DataConnectorContext<'a> {
.collect(),
schema: resolved_schema,
capabilities,
supported_ndc_version,
argument_presets,
response_headers,
};
@ -296,34 +294,11 @@ impl DataConnectorLink {
data_connector_name: name.clone(),
error: to_error(e),
})?;
let capabilities = DataConnectorCapabilities {
supported_ndc_version: context.supported_ndc_version,
supports_explaining_queries: context.capabilities.query.explain.is_some(),
supports_explaining_mutations: context.capabilities.mutation.explain.is_some(),
supports_nested_object_filtering: context
.capabilities
.query
.nested_fields
.filter_by
.is_some(),
supports_nested_array_filtering: context
.capabilities
.query
.exists
.nested_collections
.is_some(),
supports_nested_object_aggregations: context
.capabilities
.query
.nested_fields
.aggregates
.is_some(),
};
Ok(Self {
name,
url,
headers,
capabilities,
capabilities: context.capabilities.clone(),
response_config: context.response_headers.clone().map(Arc::new),
})
}
@ -463,30 +438,158 @@ impl CommandsResponseConfig {
#[allow(clippy::struct_excessive_bools)]
pub struct DataConnectorCapabilities {
pub supported_ndc_version: NdcVersion,
/// Whether not explaining queries is supported
#[serde(default = "serde_ext::ser_default")]
#[serde(skip_serializing_if = "serde_ext::is_ser_default")]
pub supports_explaining_queries: bool,
/// Whether not explaining mutations is supported
#[serde(default = "serde_ext::ser_default")]
#[serde(skip_serializing_if = "serde_ext::is_ser_default")]
pub supports_explaining_mutations: bool,
/// Whether not filtering by nested object fields is supported
#[serde(default = "serde_ext::ser_default")]
#[serde(skip_serializing_if = "serde_ext::is_ser_default")]
pub supports_nested_object_filtering: bool,
#[serde(default = "serde_ext::ser_default")]
#[serde(skip_serializing_if = "serde_ext::is_ser_default")]
pub supports_nested_object_aggregations: bool,
/// Whether not filtering using 'exists' over nested object arrays is supported
#[serde(default = "serde_ext::ser_default")]
#[serde(skip_serializing_if = "serde_ext::is_ser_default")]
pub supports_nested_array_filtering: bool,
/// Whether or not aggregates are supported
#[serde(default = "serde_ext::ser_default")]
#[serde(skip_serializing_if = "serde_ext::is_ser_default")]
pub supports_aggregates: Option<DataConnectorAggregateCapabilities>,
/// Whether or not query variables are supported
#[serde(default = "serde_ext::ser_default")]
#[serde(skip_serializing_if = "serde_ext::is_ser_default")]
pub supports_query_variables: bool,
/// Whether or not relationships are supported
#[serde(default = "serde_ext::ser_default")]
#[serde(skip_serializing_if = "serde_ext::is_ser_default")]
pub supports_relationships: Option<DataConnectorRelationshipCapabilities>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
pub struct DataConnectorAggregateCapabilities {
/// Whether not aggregating over nested object fields is supported
#[serde(default = "serde_ext::ser_default")]
#[serde(skip_serializing_if = "serde_ext::is_ser_default")]
pub supports_nested_object_aggregations: bool,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
pub struct DataConnectorRelationshipCapabilities {
/// Whether or not filters can compare a column against another column that is across a relationship
#[serde(default = "serde_ext::ser_default")]
#[serde(skip_serializing_if = "serde_ext::is_ser_default")]
pub supports_relation_comparisons: bool,
/// Whether or not relationships can start from or end with columns in nested objects. Implies support in field selection.
#[serde(default = "serde_ext::ser_default")]
#[serde(skip_serializing_if = "serde_ext::is_ser_default")]
pub supports_nested_relationships: Option<DataConnectorNestedRelationshipCapabilities>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
pub struct DataConnectorNestedRelationshipCapabilities {
/// Whether or not relationships can start from columns inside nested objects inside nested arrays
#[serde(default = "serde_ext::ser_default")]
#[serde(skip_serializing_if = "serde_ext::is_ser_default")]
pub supports_nested_array_selection: bool,
/// Whether or not nested relationships can be used in filtering
#[serde(default = "serde_ext::ser_default")]
#[serde(skip_serializing_if = "serde_ext::is_ser_default")]
pub supports_nested_in_filtering: bool,
/// Whether or not nested relationships can be used in ordering
#[serde(default = "serde_ext::ser_default")]
#[serde(skip_serializing_if = "serde_ext::is_ser_default")]
pub supports_nested_in_ordering: bool,
}
fn mk_ndc_01_capabilities(
capabilities: &ndc_models_v01::Capabilities,
) -> DataConnectorCapabilities {
DataConnectorCapabilities {
supported_ndc_version: NdcVersion::V01,
supports_explaining_queries: capabilities.query.explain.is_some(),
supports_explaining_mutations: capabilities.mutation.explain.is_some(),
supports_nested_object_filtering: capabilities.query.nested_fields.filter_by.is_some(),
supports_nested_array_filtering: capabilities.query.exists.nested_collections.is_some(),
supports_aggregates: capabilities.query.aggregates.as_ref().map(|_agg| {
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: capabilities
.query
.nested_fields
.aggregates
.is_some(),
}
}),
supports_query_variables: capabilities.query.variables.is_some(),
supports_relationships: capabilities.relationships.as_ref().map(|rel| {
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: rel.relation_comparisons.is_some(),
// Selection of nested relationships is assumed supported in NDC 0.1.x
supports_nested_relationships: Some(DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
// Selection of nested filtering/ordering is not supported in NDC 0.1.x
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
}),
}
}),
}
}
fn mk_ndc_02_capabilities(capabilities: &ndc_models::Capabilities) -> DataConnectorCapabilities {
DataConnectorCapabilities {
supported_ndc_version: NdcVersion::V02,
supports_explaining_queries: capabilities.query.explain.is_some(),
supports_explaining_mutations: capabilities.mutation.explain.is_some(),
supports_nested_object_filtering: capabilities.query.nested_fields.filter_by.is_some(),
supports_nested_array_filtering: capabilities.query.exists.nested_collections.is_some(),
supports_aggregates: capabilities.query.aggregates.as_ref().map(|_agg| {
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: capabilities
.query
.nested_fields
.aggregates
.is_some(),
}
}),
supports_query_variables: capabilities.query.variables.is_some(),
supports_relationships: capabilities.relationships.as_ref().map(|rel| {
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: rel.relation_comparisons.is_some(),
supports_nested_relationships: rel.nested.as_ref().map(|n| {
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: n.array.is_some(),
supports_nested_in_filtering: true,
supports_nested_in_ordering: true,
}
}),
}
}),
}
}
#[cfg(test)]
mod tests {
use ndc_models;
use open_dds::{accessor::MetadataAccessor, data_connector::DataConnectorLinkV1, Metadata};
use strum::IntoEnumIterator;
use crate::{
configuration::UnstableFeatures,
data_connectors::{error::DataConnectorIssue, types::NdcVersion},
data_connectors::{
error::DataConnectorIssue, types::NdcVersion, DataConnectorCapabilities,
},
stages::data_connectors::types::DataConnectorContext,
};
@ -530,11 +633,16 @@ mod tests {
), jsonpath::JSONPath::new())
.unwrap();
let explicit_capabilities: ndc_models::Capabilities =
serde_json::from_value(serde_json::json!(
{ "query": { "nested_fields": {}, "exists": { "unrelated": {} } }, "mutation": {} }
))
.unwrap();
let data_connector_capabilities = DataConnectorCapabilities {
supported_ndc_version: NdcVersion::V01,
supports_explaining_queries: false,
supports_explaining_mutations: false,
supports_nested_object_filtering: false,
supports_nested_array_filtering: false,
supports_aggregates: None,
supports_query_variables: false,
supports_relationships: None,
};
// With explicit capabilities specified, we should use them
let unstable_features = UnstableFeatures {
@ -548,8 +656,7 @@ mod tests {
&unstable_features,
)
.unwrap();
assert_eq!(context.capabilities, explicit_capabilities);
assert_eq!(context.supported_ndc_version, NdcVersion::V01);
assert_eq!(context.capabilities, data_connector_capabilities);
assert_eq!(issues.len(), 0, "Issues: {issues:#?}");
}
@ -575,11 +682,16 @@ mod tests {
), jsonpath::JSONPath::new())
.unwrap();
let explicit_capabilities: ndc_models::Capabilities =
serde_json::from_value(serde_json::json!(
{ "query": { "nested_fields": {}, "exists": {} }, "mutation": {} }
))
.unwrap();
let data_connector_capabilities = DataConnectorCapabilities {
supported_ndc_version: NdcVersion::V02,
supports_explaining_queries: false,
supports_explaining_mutations: false,
supports_nested_object_filtering: false,
supports_nested_array_filtering: false,
supports_aggregates: None,
supports_query_variables: false,
supports_relationships: None,
};
// With explicit capabilities specified, we should use them
let unstable_features = UnstableFeatures {
@ -593,8 +705,7 @@ mod tests {
&unstable_features,
)
.unwrap();
assert_eq!(context.capabilities, explicit_capabilities);
assert_eq!(context.supported_ndc_version, NdcVersion::V02);
assert_eq!(context.capabilities, data_connector_capabilities);
assert_eq!(issues.len(), 0, "Issues: {issues:#?}");
}

View File

@ -179,7 +179,11 @@ fn resolve_aggregate_expression_data_connector_mapping(
// If our field contains a nested object type
if let Some(field_object_type_name) = field_object_type_name {
// Check that the data connector supports aggregation over nested object fields
if !data_connector_capabilities.supports_nested_object_aggregations {
if !data_connector_capabilities
.supports_aggregates
.as_ref()
.is_some_and(|agg| agg.supports_nested_object_aggregations)
{
return Err(aggregates::AggregateExpressionError::NestedObjectAggregatesNotSupportedByDataConnector {
name: aggregate_expression.name.clone(),
data_connector_name: data_connector_name.clone(),

View File

@ -420,7 +420,7 @@ fn get_relationship_capabilities(
let capabilities = &resolved_data_connector.capabilities;
// if relationship is remote, error if `foreach` capability is not available
if capabilities.query.variables.is_none()
if capabilities.supports_query_variables
&& Some(&data_connector.name) != target_data_connector.as_ref()
{
return Err(Error::ObjectRelationshipError {
@ -432,11 +432,11 @@ fn get_relationship_capabilities(
});
};
let relationships = capabilities.relationships.is_some();
let relationships = capabilities.supports_relationships.is_some();
let relationship_comparison = capabilities
.relationships
.supports_relationships
.as_ref()
.is_some_and(|r| r.relation_comparisons.is_some());
.is_some_and(|r| r.supports_relation_comparisons);
Ok(Some(RelationshipCapabilities {
foreach: (),

View File

@ -560,8 +560,25 @@ input_file: crates/metadata-resolve/tests/passing/aggregate_boolean_expressions/
supports_explaining_queries: false,
supports_explaining_mutations: false,
supports_nested_object_filtering: false,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: false,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: false,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
collection: CollectionName(
@ -839,8 +856,25 @@ input_file: crates/metadata-resolve/tests/passing/aggregate_boolean_expressions/
supports_explaining_queries: false,
supports_explaining_mutations: false,
supports_nested_object_filtering: false,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: false,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: false,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
collection: CollectionName(

View File

@ -560,8 +560,25 @@ input_file: crates/metadata-resolve/tests/passing/aggregate_boolean_expressions/
supports_explaining_queries: false,
supports_explaining_mutations: false,
supports_nested_object_filtering: false,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: false,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: false,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
collection: CollectionName(
@ -839,8 +856,25 @@ input_file: crates/metadata-resolve/tests/passing/aggregate_boolean_expressions/
supports_explaining_queries: false,
supports_explaining_mutations: false,
supports_nested_object_filtering: false,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: false,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: false,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
collection: CollectionName(

View File

@ -351,8 +351,25 @@ input_file: crates/metadata-resolve/tests/passing/aggregate_boolean_expressions/
supports_explaining_queries: false,
supports_explaining_mutations: false,
supports_nested_object_filtering: false,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: false,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: false,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
collection: CollectionName(

View File

@ -560,8 +560,25 @@ input_file: crates/metadata-resolve/tests/passing/aggregate_boolean_expressions/
supports_explaining_queries: false,
supports_explaining_mutations: false,
supports_nested_object_filtering: false,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: false,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: false,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
collection: CollectionName(
@ -839,8 +856,25 @@ input_file: crates/metadata-resolve/tests/passing/aggregate_boolean_expressions/
supports_explaining_queries: false,
supports_explaining_mutations: false,
supports_nested_object_filtering: false,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: false,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: false,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
collection: CollectionName(

View File

@ -1315,8 +1315,25 @@ input_file: crates/metadata-resolve/tests/passing/aggregate_expressions/missing_
supports_explaining_queries: true,
supports_explaining_mutations: true,
supports_nested_object_filtering: false,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: true,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: true,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
collection: CollectionName(

View File

@ -1930,8 +1930,25 @@ input_file: crates/metadata-resolve/tests/passing/aggregate_expressions/relation
supports_explaining_queries: true,
supports_explaining_mutations: true,
supports_nested_object_filtering: false,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: true,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: true,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
collection: CollectionName(
@ -2997,8 +3014,25 @@ input_file: crates/metadata-resolve/tests/passing/aggregate_expressions/relation
supports_explaining_queries: true,
supports_explaining_mutations: true,
supports_nested_object_filtering: false,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: true,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: true,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
collection: CollectionName(

View File

@ -1315,8 +1315,25 @@ input_file: crates/metadata-resolve/tests/passing/aggregate_expressions/root_fie
supports_explaining_queries: true,
supports_explaining_mutations: true,
supports_nested_object_filtering: false,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: true,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: true,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
collection: CollectionName(

View File

@ -1002,8 +1002,25 @@ input_file: crates/metadata-resolve/tests/passing/boolean_expression_type/nested
supports_explaining_queries: true,
supports_explaining_mutations: false,
supports_nested_object_filtering: true,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: true,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: true,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
collection: CollectionName(

View File

@ -501,8 +501,25 @@ input_file: crates/metadata-resolve/tests/passing/boolean_expression_type/partia
supports_explaining_queries: true,
supports_explaining_mutations: false,
supports_nested_object_filtering: true,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: true,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: true,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
collection: CollectionName(

View File

@ -578,8 +578,25 @@ input_file: crates/metadata-resolve/tests/passing/boolean_expression_type/range/
supports_explaining_queries: true,
supports_explaining_mutations: false,
supports_nested_object_filtering: true,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: true,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: true,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
collection: CollectionName(

View File

@ -372,8 +372,25 @@ input_file: crates/metadata-resolve/tests/passing/command_permissions/nullable_p
supports_explaining_queries: true,
supports_explaining_mutations: true,
supports_nested_object_filtering: false,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: true,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: true,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
source: Function(

View File

@ -372,8 +372,25 @@ input_file: crates/metadata-resolve/tests/passing/command_permissions/predicate_
supports_explaining_queries: true,
supports_explaining_mutations: true,
supports_nested_object_filtering: false,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: true,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: true,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
source: Function(

View File

@ -171,8 +171,25 @@ input_file: crates/metadata-resolve/tests/passing/commands/functions/all_args_ar
supports_explaining_queries: true,
supports_explaining_mutations: true,
supports_nested_object_filtering: false,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: true,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: true,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
source: Function(

View File

@ -171,8 +171,25 @@ input_file: crates/metadata-resolve/tests/passing/commands/functions/issue_when_
supports_explaining_queries: true,
supports_explaining_mutations: true,
supports_nested_object_filtering: false,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: true,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: true,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
source: Function(

View File

@ -171,8 +171,25 @@ input_file: crates/metadata-resolve/tests/passing/commands/procedures/all_args_a
supports_explaining_queries: true,
supports_explaining_mutations: true,
supports_nested_object_filtering: false,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: true,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: true,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
source: Procedure(

View File

@ -171,8 +171,25 @@ input_file: crates/metadata-resolve/tests/passing/commands/procedures/issue_when
supports_explaining_queries: true,
supports_explaining_mutations: true,
supports_nested_object_filtering: false,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: true,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: true,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
source: Procedure(

View File

@ -501,8 +501,25 @@ input_file: crates/metadata-resolve/tests/passing/missing_subgraph_when_ignoring
supports_explaining_queries: true,
supports_explaining_mutations: false,
supports_nested_object_filtering: true,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: true,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: true,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
collection: CollectionName(

View File

@ -420,8 +420,25 @@ input_file: crates/metadata-resolve/tests/passing/model_permissions/nullable_pre
supports_explaining_queries: true,
supports_explaining_mutations: true,
supports_nested_object_filtering: false,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: true,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: true,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
collection: CollectionName(

View File

@ -420,8 +420,25 @@ input_file: crates/metadata-resolve/tests/passing/model_permissions/predicate_ar
supports_explaining_queries: true,
supports_explaining_mutations: true,
supports_nested_object_filtering: false,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: true,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: true,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
collection: CollectionName(

View File

@ -297,8 +297,25 @@ input_file: crates/metadata-resolve/tests/passing/models/all_args_are_set_includ
supports_explaining_queries: true,
supports_explaining_mutations: true,
supports_nested_object_filtering: false,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: true,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: true,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
collection: CollectionName(

View File

@ -297,8 +297,25 @@ input_file: crates/metadata-resolve/tests/passing/models/issue_when_not_all_argu
supports_explaining_queries: true,
supports_explaining_mutations: true,
supports_nested_object_filtering: false,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: true,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: true,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
collection: CollectionName(

View File

@ -230,8 +230,25 @@ input_file: crates/metadata-resolve/tests/passing/order_by_expressions/model_v1_
supports_explaining_queries: true,
supports_explaining_mutations: true,
supports_nested_object_filtering: false,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: true,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: true,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
collection: CollectionName(

View File

@ -230,8 +230,25 @@ input_file: crates/metadata-resolve/tests/passing/order_by_expressions/model_v2_
supports_explaining_queries: true,
supports_explaining_mutations: true,
supports_nested_object_filtering: false,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: true,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: true,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
collection: CollectionName(

View File

@ -230,8 +230,25 @@ input_file: crates/metadata-resolve/tests/passing/order_by_expressions/model_v2_
supports_explaining_queries: true,
supports_explaining_mutations: true,
supports_nested_object_filtering: false,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: true,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: true,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
collection: CollectionName(

View File

@ -329,8 +329,25 @@ input_file: crates/metadata-resolve/tests/passing/order_by_expressions/nested/me
supports_explaining_queries: true,
supports_explaining_mutations: true,
supports_nested_object_filtering: false,
supports_nested_object_aggregations: false,
supports_nested_array_filtering: false,
supports_aggregates: Some(
DataConnectorAggregateCapabilities {
supports_nested_object_aggregations: false,
},
),
supports_query_variables: true,
supports_relationships: Some(
DataConnectorRelationshipCapabilities {
supports_relation_comparisons: true,
supports_nested_relationships: Some(
DataConnectorNestedRelationshipCapabilities {
supports_nested_array_selection: true,
supports_nested_in_filtering: false,
supports_nested_in_ordering: false,
},
),
},
),
},
},
collection: CollectionName(

View File

@ -95,6 +95,7 @@ services:
ports:
- 8080:8080
environment:
HASURA_SERVICE_TOKEN_SECRET: super sekret
CONNECTION_URI: "postgresql://postgres:password@postgres"
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: "http://jaeger:4317"
OTEL_SERVICE_NAME: "ndc-postgres"

File diff suppressed because it is too large Load Diff