Move TypeMapping and FieldMapping to data_connector_type_mappings stage (#510)

<!-- Thank you for submitting this PR! :) -->

## Description

As everything is taking shape we're finding more loose bits and pieces
around, this moves `TypeMappings` and `FieldMappings` into the
`data_connector_type_mappings` stage. Functional no-op.

V3_GIT_ORIGIN_REV_ID: 2357e47b68d361b373f9fa886683ceb1fcff7cc3
This commit is contained in:
Daniel Harvey 2024-04-26 09:03:13 +01:00 committed by hasura-bot
parent 9d25ee2075
commit d8846328c4
16 changed files with 101 additions and 245 deletions

View File

@ -12,7 +12,7 @@ use crate::execute::ir::arguments;
use crate::metadata::resolved::subgraph::{
Qualified, QualifiedBaseType, QualifiedTypeName, QualifiedTypeReference,
};
use crate::metadata::resolved::types::TypeMapping;
use crate::metadata::resolved::TypeMapping;
use crate::schema::types::{
Annotation, ArgumentNameAndPath, ArgumentPresets, InputAnnotation, ModelInputAnnotation,
};

View File

@ -87,7 +87,7 @@ pub(crate) fn model_selection_ir<'s>(
.type_mappings
.get(data_type)
.map(|type_mapping| {
let resolved::types::TypeMapping::Object { field_mappings, .. } = type_mapping;
let resolved::TypeMapping::Object { field_mappings, .. } = type_mapping;
field_mappings
})
.ok_or_else(|| error::InternalEngineError::InternalGeneric {

View File

@ -51,7 +51,7 @@ pub(crate) struct LocalModelRelationshipInfo<'s> {
pub source_type: &'s Qualified<CustomTypeName>,
pub source_data_connector: &'s resolved::data_connector::DataConnectorLink,
#[serde(serialize_with = "serialize_qualified_btreemap")]
pub source_type_mappings: &'s BTreeMap<Qualified<CustomTypeName>, resolved::types::TypeMapping>,
pub source_type_mappings: &'s BTreeMap<Qualified<CustomTypeName>, resolved::TypeMapping>,
pub target_source: &'s ModelTargetSource,
pub target_type: &'s Qualified<CustomTypeName>,
pub mappings: &'s Vec<resolved::relationship::RelationshipModelMapping>,
@ -62,7 +62,7 @@ pub(crate) struct LocalCommandRelationshipInfo<'s> {
pub annotation: &'s CommandRelationshipAnnotation,
pub source_data_connector: &'s resolved::data_connector::DataConnectorLink,
#[serde(serialize_with = "serialize_qualified_btreemap")]
pub source_type_mappings: &'s BTreeMap<Qualified<CustomTypeName>, resolved::types::TypeMapping>,
pub source_type_mappings: &'s BTreeMap<Qualified<CustomTypeName>, resolved::TypeMapping>,
pub target_source: &'s CommandTargetSource,
}
@ -71,7 +71,7 @@ pub struct RemoteModelRelationshipInfo<'s> {
pub annotation: &'s ModelRelationshipAnnotation,
/// This contains processed information about the mappings.
/// `RelationshipMapping` only contains mapping of field names. This
/// contains mapping of field names and `resolved::types::FieldMapping`.
/// contains mapping of field names and `resolved::FieldMapping`.
/// Also see `build_remote_relationship`.
pub join_mapping: Vec<(SourceField, TargetField)>,
}
@ -82,7 +82,7 @@ pub(crate) struct RemoteCommandRelationshipInfo<'s> {
pub join_mapping: Vec<(SourceField, ArgumentName)>,
}
pub type SourceField = (FieldName, resolved::types::FieldMapping);
pub type SourceField = (FieldName, resolved::FieldMapping);
pub type TargetField = (FieldName, resolved::types::NdcColumnForComparison);
pub(crate) fn process_model_relationship_definition(
@ -216,7 +216,7 @@ pub(crate) fn generate_model_relationship_ir<'s>(
field: &Field<'s, GDS>,
annotation: &'s ModelRelationshipAnnotation,
source_data_connector: &'s resolved::data_connector::DataConnectorLink,
type_mappings: &'s BTreeMap<Qualified<CustomTypeName>, resolved::types::TypeMapping>,
type_mappings: &'s BTreeMap<Qualified<CustomTypeName>, resolved::TypeMapping>,
session_variables: &SessionVariables,
usage_counts: &mut UsagesCounts,
) -> Result<FieldSelection<'s>, error::Error> {
@ -332,7 +332,7 @@ pub(crate) fn generate_command_relationship_ir<'s>(
field: &Field<'s, GDS>,
annotation: &'s CommandRelationshipAnnotation,
source_data_connector: &'s resolved::data_connector::DataConnectorLink,
type_mappings: &'s BTreeMap<Qualified<CustomTypeName>, resolved::types::TypeMapping>,
type_mappings: &'s BTreeMap<Qualified<CustomTypeName>, resolved::TypeMapping>,
session_variables: &SessionVariables,
usage_counts: &mut UsagesCounts,
) -> Result<FieldSelection<'s>, error::Error> {
@ -384,7 +384,7 @@ pub(crate) fn build_local_model_relationship<'s>(
field_call: &normalized_ast::FieldCall<'s, GDS>,
annotation: &'s ModelRelationshipAnnotation,
data_connector: &'s resolved::data_connector::DataConnectorLink,
type_mappings: &'s BTreeMap<Qualified<CustomTypeName>, resolved::types::TypeMapping>,
type_mappings: &'s BTreeMap<Qualified<CustomTypeName>, resolved::TypeMapping>,
target_source: &'s ModelTargetSource,
filter_clause: ResolvedFilterExpression<'s>,
limit: Option<u32>,
@ -430,7 +430,7 @@ pub(crate) fn build_local_command_relationship<'s>(
field_call: &normalized_ast::FieldCall<'s, GDS>,
annotation: &'s CommandRelationshipAnnotation,
data_connector: &'s resolved::data_connector::DataConnectorLink,
type_mappings: &'s BTreeMap<Qualified<CustomTypeName>, resolved::types::TypeMapping>,
type_mappings: &'s BTreeMap<Qualified<CustomTypeName>, resolved::TypeMapping>,
target_source: &'s CommandTargetSource,
session_variables: &SessionVariables,
) -> Result<FieldSelection<'s>, error::Error> {
@ -471,7 +471,7 @@ pub(crate) fn build_remote_relationship<'n, 's>(
field: &'n normalized_ast::Field<'s, GDS>,
field_call: &'n normalized_ast::FieldCall<'s, GDS>,
annotation: &'s ModelRelationshipAnnotation,
type_mappings: &'s BTreeMap<Qualified<CustomTypeName>, resolved::types::TypeMapping>,
type_mappings: &'s BTreeMap<Qualified<CustomTypeName>, resolved::TypeMapping>,
target_source: &'s ModelTargetSource,
filter_clause: ResolvedFilterExpression<'s>,
limit: Option<u32>,
@ -556,7 +556,7 @@ pub(crate) fn build_remote_command_relationship<'n, 's>(
field: &'n normalized_ast::Field<'s, GDS>,
field_call: &'n normalized_ast::FieldCall<'s, GDS>,
annotation: &'s CommandRelationshipAnnotation,
type_mappings: &'s BTreeMap<Qualified<CustomTypeName>, resolved::types::TypeMapping>,
type_mappings: &'s BTreeMap<Qualified<CustomTypeName>, resolved::TypeMapping>,
target_source: &'s CommandTargetSource,
session_variables: &SessionVariables,
) -> Result<FieldSelection<'s>, error::Error> {
@ -606,11 +606,11 @@ pub(crate) fn build_remote_command_relationship<'n, 's>(
}
fn get_field_mapping_of_field_name(
type_mappings: &BTreeMap<Qualified<CustomTypeName>, resolved::types::TypeMapping>,
type_mappings: &BTreeMap<Qualified<CustomTypeName>, resolved::TypeMapping>,
type_name: &Qualified<CustomTypeName>,
relationship_name: &RelationshipName,
field_name: &FieldName,
) -> Result<resolved::types::FieldMapping, error::Error> {
) -> Result<resolved::FieldMapping, error::Error> {
let type_mapping = type_mappings.get(type_name).ok_or_else(|| {
error::InternalDeveloperError::TypeMappingNotFoundForRelationship {
type_name: type_name.clone(),
@ -618,7 +618,7 @@ fn get_field_mapping_of_field_name(
}
})?;
match type_mapping {
resolved::types::TypeMapping::Object { field_mappings, .. } => Ok(field_mappings
resolved::TypeMapping::Object { field_mappings, .. } => Ok(field_mappings
.get(field_name)
.ok_or_else(
|| error::InternalDeveloperError::FieldMappingNotFoundForRelationship {

View File

@ -22,7 +22,6 @@ use crate::metadata::resolved;
use crate::metadata::resolved::subgraph::{
Qualified, QualifiedBaseType, QualifiedTypeName, QualifiedTypeReference,
};
use crate::metadata::resolved::types::FieldMapping;
use crate::schema::types::TypeKind;
use crate::schema::{
types::{Annotation, OutputAnnotation, RootFieldAnnotation},
@ -108,7 +107,7 @@ pub(crate) struct ResultSelectionSet<'s> {
impl<'s> ResultSelectionSet<'s> {
/// Takes a 'FieldMapping' and returns the alias, if the field is found in
/// existing fields
pub(crate) fn contains(&self, other_field: &FieldMapping) -> Option<String> {
pub(crate) fn contains(&self, other_field: &resolved::FieldMapping) -> Option<String> {
self.fields.iter().find_map(|(alias, field)| match field {
FieldSelection::Column { column, .. } => {
if *column == other_field.column {
@ -124,7 +123,7 @@ impl<'s> ResultSelectionSet<'s> {
fn build_global_id_fields(
global_id_fields: &Vec<FieldName>,
field_mappings: &BTreeMap<FieldName, resolved::types::FieldMapping>,
field_mappings: &BTreeMap<FieldName, resolved::FieldMapping>,
field_alias: &Alias,
fields: &mut IndexMap<String, FieldSelection>,
) -> Result<(), error::Error> {
@ -156,7 +155,7 @@ pub(crate) fn generate_nested_selection<'s>(
field_base_type_kind: TypeKind,
field: &normalized_ast::Field<'s, GDS>,
data_connector: &'s resolved::data_connector::DataConnectorLink,
type_mappings: &'s BTreeMap<Qualified<CustomTypeName>, resolved::types::TypeMapping>,
type_mappings: &'s BTreeMap<Qualified<CustomTypeName>, resolved::TypeMapping>,
session_variables: &SessionVariables,
usage_counts: &mut UsagesCounts,
) -> Result<Option<NestedSelection<'s>>, error::Error> {
@ -179,14 +178,11 @@ pub(crate) fn generate_nested_selection<'s>(
QualifiedTypeName::Custom(data_type) => match field_base_type_kind {
TypeKind::Scalar => Ok(None),
TypeKind::Object => {
let resolved::types::TypeMapping::Object { field_mappings, .. } =
type_mappings.get(data_type).ok_or(
error::InternalEngineError::InternalGeneric {
description: format!(
"no type mapping found for type {data_type}"
),
},
)?;
let resolved::TypeMapping::Object { field_mappings, .. } = type_mappings
.get(data_type)
.ok_or(error::InternalEngineError::InternalGeneric {
description: format!("no type mapping found for type {data_type}"),
})?;
let nested_selection = generate_selection_set_ir(
&field.selection_set,
data_connector,
@ -210,8 +206,8 @@ pub(crate) fn generate_nested_selection<'s>(
pub(crate) fn generate_selection_set_ir<'s>(
selection_set: &normalized_ast::SelectionSet<'s, GDS>,
data_connector: &'s resolved::data_connector::DataConnectorLink,
type_mappings: &'s BTreeMap<Qualified<CustomTypeName>, resolved::types::TypeMapping>,
field_mappings: &BTreeMap<FieldName, resolved::types::FieldMapping>,
type_mappings: &'s BTreeMap<Qualified<CustomTypeName>, resolved::TypeMapping>,
field_mappings: &BTreeMap<FieldName, resolved::FieldMapping>,
session_variables: &SessionVariables,
usage_counts: &mut UsagesCounts,
) -> Result<ResultSelectionSet<'s>, error::Error> {

View File

@ -13,7 +13,7 @@ use crate::execute::remote_joins::types::{
JoinLocations, JoinNode, LocationKind, MonotonicCounter, RemoteJoinType, TargetField,
};
use crate::execute::remote_joins::types::{Location, RemoteJoin};
use crate::metadata::resolved::types::FieldMapping;
use crate::metadata::resolved::FieldMapping;
pub(crate) fn process_nested_selection<'s, 'ir>(
nested_selection: &'ir NestedSelection<'s>,

View File

@ -13,4 +13,5 @@ pub mod subgraph;
mod typecheck;
pub mod types;
pub use stages::data_connector_type_mappings::{FieldMapping, TypeMapping};
pub use stages::resolve;

View File

@ -1,4 +1,4 @@
use super::stages::data_connector_scalar_types;
use super::stages::{data_connector_scalar_types, data_connector_type_mappings};
use crate::metadata::resolved::data_connector;
@ -8,8 +8,6 @@ use crate::metadata::resolved::model;
use crate::metadata::resolved::stages::graphql_config::GraphqlConfig;
use crate::metadata::resolved::subgraph::{Qualified, QualifiedTypeReference};
use crate::metadata::resolved::types::TypeMapping;
use lang_graphql::ast::common::{self as ast};
use ndc_models;
@ -52,7 +50,7 @@ pub fn resolve_boolean_expression(
where_type_name: ast::TypeName,
subgraph: &str,
data_connectors: &data_connector_scalar_types::DataConnectorsWithScalars,
type_mappings: &TypeMapping,
type_mappings: &data_connector_type_mappings::TypeMapping,
graphql_config: &GraphqlConfig,
) -> Result<BooleanExpression, Error> {
let mut scalar_fields = HashMap::new();
@ -69,7 +67,7 @@ pub fn resolve_boolean_expression(
})?
.scalars;
let TypeMapping::Object { field_mappings, .. } = type_mappings;
let data_connector_type_mappings::TypeMapping::Object { field_mappings, .. } = type_mappings;
let filter_graphql_config = graphql_config
.query

View File

@ -1,4 +1,6 @@
use super::stages::{data_connector_scalar_types, scalar_types, type_permissions};
use super::stages::{
data_connector_scalar_types, data_connector_type_mappings, scalar_types, type_permissions,
};
use crate::metadata::resolved::argument::get_argument_mappings;
use crate::metadata::resolved::data_connector::DataConnectorLink;
use crate::metadata::resolved::error::Error;
@ -7,10 +9,10 @@ use crate::metadata::resolved::subgraph::{
deserialize_qualified_btreemap, mk_qualified_type_reference, serialize_qualified_btreemap,
ArgumentInfo, Qualified, QualifiedTypeReference,
};
use crate::metadata::resolved::types::mk_name;
use crate::metadata::resolved::types::{
get_type_representation, object_type_exists, unwrap_custom_type_name,
};
use crate::metadata::resolved::types::{mk_name, TypeMapping};
use indexmap::IndexMap;
use lang_graphql::ast::common as ast;
use open_dds::arguments::ArgumentName;
@ -24,7 +26,6 @@ use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashMap};
use super::permission::{resolve_value_expression, ValueExpression};
use super::stages::data_connector_type_mappings;
use super::typecheck;
use super::types::{
collect_type_mapping_for_source, TypeMappingCollectionError, TypeMappingToCollect,
@ -45,7 +46,8 @@ pub struct CommandSource {
serialize_with = "serialize_qualified_btreemap",
deserialize_with = "deserialize_qualified_btreemap"
)]
pub type_mappings: BTreeMap<Qualified<CustomTypeName>, TypeMapping>,
pub type_mappings:
BTreeMap<Qualified<CustomTypeName>, data_connector_type_mappings::TypeMapping>,
pub argument_mappings: HashMap<ArgumentName, String>,
}

View File

@ -22,8 +22,8 @@ use crate::metadata::resolved::subgraph::{
serialize_qualified_btreemap, ArgumentInfo, Qualified, QualifiedBaseType,
QualifiedTypeReference,
};
use crate::metadata::resolved::types::mk_name;
use crate::metadata::resolved::types::store_new_graphql_type;
use crate::metadata::resolved::types::{mk_name, TypeMapping};
use crate::schema::types::output_type::relationship::{
ModelTargetSource, PredicateRelationshipAnnotation,
};
@ -112,7 +112,8 @@ pub struct ModelSource {
serialize_with = "serialize_qualified_btreemap",
deserialize_with = "deserialize_qualified_btreemap"
)]
pub type_mappings: BTreeMap<Qualified<CustomTypeName>, TypeMapping>,
pub type_mappings:
BTreeMap<Qualified<CustomTypeName>, data_connector_type_mappings::TypeMapping>,
pub argument_mappings: HashMap<ArgumentName, String>,
}
@ -519,14 +520,14 @@ fn resolve_model_predicate(
// TODO: resolve the "in" operator too (ndc_models::BinaryArrayComparisonOperator)
if let Some(model_source) = &model.source {
// Get field mappings of model data type
let TypeMapping::Object { field_mappings, .. } = model_source
.type_mappings
.get(&model.data_type)
.ok_or(Error::TypeMappingRequired {
model_name: model.name.clone(),
type_name: model.data_type.clone(),
data_connector: model_source.data_connector.name.clone(),
})?;
let data_connector_type_mappings::TypeMapping::Object { field_mappings, .. } =
model_source.type_mappings.get(&model.data_type).ok_or(
Error::TypeMappingRequired {
model_name: model.name.clone(),
type_name: model.data_type.clone(),
data_connector: model_source.data_connector.name.clone(),
},
)?;
// Determine field_mapping for the predicate field
let field_mapping = field_mappings.get(field).ok_or_else(|| {
@ -584,14 +585,14 @@ fn resolve_model_predicate(
permissions::ModelPredicate::FieldIsNull(FieldIsNullPredicate { field }) => {
if let Some(model_source) = &model.source {
// Get field mappings of model data type
let TypeMapping::Object { field_mappings, .. } = model_source
.type_mappings
.get(&model.data_type)
.ok_or(Error::TypeMappingRequired {
model_name: model.name.clone(),
type_name: model.data_type.clone(),
data_connector: model_source.data_connector.name.clone(),
})?;
let data_connector_type_mappings::TypeMapping::Object { field_mappings, .. } =
model_source.type_mappings.get(&model.data_type).ok_or(
Error::TypeMappingRequired {
model_name: model.name.clone(),
type_name: model.data_type.clone(),
data_connector: model_source.data_connector.name.clone(),
},
)?;
// Determine field_mapping for the predicate field
let field_mapping = field_mappings.get(field).ok_or_else(|| {
Error::UnknownFieldInSelectPermissionsDefinition {
@ -852,7 +853,7 @@ pub(crate) fn get_ndc_column_for_comparison<F: Fn() -> String>(
comparison_location: F,
) -> Result<NdcColumnForComparison, Error> {
// Get field mappings of model data type
let TypeMapping::Object { field_mappings, .. } = model_source
let data_connector_type_mappings::TypeMapping::Object { field_mappings, .. } = model_source
.type_mappings
.get(model_data_type)
.ok_or(Error::TypeMappingRequired {
@ -1009,14 +1010,16 @@ pub fn resolve_model_graphql_api(
)?;
order_by_expression_type_name
.map(|order_by_type_name| {
let TypeMapping::Object { field_mappings, .. } = model_source
.type_mappings
.get(&model.data_type)
.ok_or(Error::TypeMappingRequired {
let data_connector_type_mappings::TypeMapping::Object {
field_mappings,
..
} = model_source.type_mappings.get(&model.data_type).ok_or(
Error::TypeMappingRequired {
model_name: model_name.clone(),
type_name: model.data_type.clone(),
data_connector: model_source.data_connector.name.clone(),
})?;
},
)?;
let mut order_by_fields = HashMap::new();
for (field_name, field_mapping) in field_mappings.iter() {

View File

@ -171,7 +171,7 @@ pub fn validate_ndc(
NDCValidationError::NoSuchType(collection.collection_type.clone()),
)?;
let super::types::TypeMapping::Object { field_mappings, .. } = model_source
let super::TypeMapping::Object { field_mappings, .. } = model_source
.type_mappings
.get(&model.data_type)
.ok_or_else(|| NDCValidationError::UnknownModelTypeMapping {
@ -333,7 +333,7 @@ pub fn validate_ndc_command(
// Check if the command.output_type is available in schema.object_types
Some(command_source_ndc_type) => {
// Check if the command.output_type has typeMappings
let super::types::TypeMapping::Object { field_mappings, .. } = command_source
let super::TypeMapping::Object { field_mappings, .. } = command_source
.type_mappings
.get(custom_type)
.ok_or_else(|| NDCValidationError::UnknownCommandTypeMapping {

View File

@ -2,15 +2,13 @@ use std::collections::{BTreeMap, HashMap, HashSet};
pub mod types;
use open_dds::types::CustomTypeName;
pub use types::{
DataConnectorTypeMappings, DataConnectorTypeMappingsOutput, FieldDefinition,
DataConnectorTypeMappings, DataConnectorTypeMappingsOutput, FieldDefinition, FieldMapping,
ObjectTypeRepresentation, ResolvedApolloFederationObjectKey,
ResolvedObjectApolloFederationConfig,
ResolvedObjectApolloFederationConfig, TypeMapping,
};
use crate::metadata::resolved::stages::data_connectors;
use crate::metadata::resolved::types::{
mk_name, store_new_graphql_type, FieldMapping, TypeMapping,
};
use crate::metadata::resolved::types::{mk_name, store_new_graphql_type};
use crate::metadata::resolved::error::{Error, TypeMappingValidationError};
use crate::metadata::resolved::subgraph::{mk_qualified_type_reference, Qualified};

View File

@ -6,12 +6,10 @@ use indexmap::IndexMap;
use open_dds::types::{CustomTypeName, Deprecated, FieldName};
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};
use std::collections::{BTreeMap, HashMap, HashSet};
use open_dds::models::ModelName;
use crate::metadata::resolved::types::TypeMapping;
use crate::metadata::resolved::subgraph::Qualified;
use lang_graphql::ast::common as ast;
@ -121,3 +119,17 @@ pub struct ResolvedObjectApolloFederationConfig {
pub struct ResolvedApolloFederationObjectKey {
pub fields: nonempty::NonEmpty<FieldName>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Hash)]
pub struct FieldMapping {
pub column: String,
pub column_type: ndc_models::Type,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
pub enum TypeMapping {
Object {
ndc_object_type_name: String,
field_mappings: BTreeMap<FieldName, FieldMapping>,
},
}

View File

@ -11,7 +11,6 @@ use crate::metadata::resolved::subgraph::{
QualifiedTypeReference,
};
use lang_graphql::ast::common as ast;
use ndc_models;
use open_dds::data_connector::DataConnectorName;
use open_dds::models::EnableAllOrSpecific;
use open_dds::types::{self, CustomTypeName, FieldName, ObjectBooleanExpressionTypeV1};
@ -27,20 +26,6 @@ pub struct NdcColumnForComparison {
pub equal_operator: String,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Hash)]
pub struct FieldMapping {
pub column: String,
pub column_type: ndc_models::Type,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
pub enum TypeMapping {
Object {
ndc_object_type_name: String,
field_mappings: BTreeMap<FieldName, FieldMapping>,
},
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
pub struct ObjectBooleanExpressionType {
pub name: Qualified<CustomTypeName>,
@ -48,7 +33,8 @@ pub struct ObjectBooleanExpressionType {
pub data_connector_name: Qualified<DataConnectorName>,
pub data_connector_link: data_connector::DataConnectorLink,
pub data_connector_object_type: String,
pub type_mappings: BTreeMap<Qualified<types::CustomTypeName>, TypeMapping>,
pub type_mappings:
BTreeMap<Qualified<types::CustomTypeName>, data_connector_type_mappings::TypeMapping>,
pub graphql: Option<boolean_expression::BooleanExpression>,
}
@ -80,148 +66,6 @@ pub fn resolve_field(
})
}
/*
pub fn resolve_object_type(
object_type_definition: &ObjectTypeV1,
existing_graphql_types: &mut HashSet<ast::TypeName>,
qualified_type_name: &Qualified<CustomTypeName>,
subgraph: &str,
global_id_enabled_types: &mut HashMap<
Qualified<CustomTypeName>,
Vec<Qualified<open_dds::models::ModelName>>,
>,
apollo_federation_entity_enabled_types: &mut HashMap<
Qualified<CustomTypeName>,
Option<Qualified<open_dds::models::ModelName>>,
>,
) -> Result<data_connector_type_mappings::ObjectTypeRepresentation, Error> {
let mut resolved_fields = IndexMap::new();
let mut resolved_global_id_fields = Vec::new();
for field in &object_type_definition.fields {
if resolved_fields
.insert(field.name.clone(), resolve_field(field, subgraph)?)
.is_some()
{
return Err(Error::DuplicateFieldDefinition {
type_name: qualified_type_name.clone(),
field_name: field.name.clone(),
});
}
}
match &object_type_definition.global_id_fields {
Some(global_id_fields) => {
if !global_id_fields.is_empty() {
// Throw error if the object type has a field called id" and has global fields configured.
// Because, when the global id fields are configured, the `id` field will be auto-generated.
if resolved_fields.contains_key(&FieldName(identifier!("id"))) {
return Err(Error::IdFieldConflictingGlobalId {
type_name: qualified_type_name.clone(),
});
}
// To check if global_id_fields are defined in object type but no model has global_id_source set to
// true:
// - If the object type has globalIdFields configured, add the object type to the
// global_id_enabled_types map.
global_id_enabled_types.insert(qualified_type_name.clone(), Vec::new());
};
for global_id_field in global_id_fields {
if !resolved_fields.contains_key(global_id_field) {
return Err(Error::UnknownFieldInGlobalId {
field_name: global_id_field.clone(),
type_name: qualified_type_name.clone(),
});
} else {
resolved_global_id_fields.push(global_id_field.clone())
}
}
}
None => {}
}
let (graphql_type_name, graphql_input_type_name, apollo_federation_config) =
match object_type_definition.graphql.as_ref() {
None => Ok::<_, Error>((None, None, None)),
Some(graphql) => {
let graphql_type_name = graphql
.type_name
.as_ref()
.map(|type_name| mk_name(type_name.0.as_ref()).map(ast::TypeName))
.transpose()?;
let graphql_input_type_name = graphql
.input_type_name
.as_ref()
.map(|input_type_name| mk_name(input_type_name.0.as_ref()).map(ast::TypeName))
.transpose()?;
// To check if apolloFederation.keys are defined in object type but no model has
// apollo_federation_entity_source set to true:
// - If the object type has apolloFederation.keys configured, add the object type to the
// apollo_federation_entity_enabled_types map.
let resolved_apollo_federation_config = match &graphql.apollo_federation {
None => Ok(None),
Some(apollo_federation) => {
// Validate that the fields in the apollo federation keys are defined in the object type
let mut resolved_keys: Vec<
data_connector_type_mappings::ResolvedApolloFederationObjectKey,
> = Vec::new();
for key in &apollo_federation.keys {
let mut resolved_key_fields = Vec::new();
for field in &key.fields {
if !resolved_fields.contains_key(field) {
return Err(Error::UnknownFieldInApolloFederationKey {
field_name: field.clone(),
object_type: qualified_type_name.clone(),
});
}
resolved_key_fields.push(field.clone());
}
let resolved_key =
match nonempty::NonEmpty::from_vec(resolved_key_fields) {
None => {
return Err(
Error::EmptyFieldsInApolloFederationConfigForObject {
object_type: qualified_type_name.clone(),
},
)
}
Some(fields) => data_connector_type_mappings::ResolvedApolloFederationObjectKey { fields },
};
resolved_keys.push(resolved_key);
}
apollo_federation_entity_enabled_types
.insert(qualified_type_name.clone(), None);
match nonempty::NonEmpty::from_vec(resolved_keys) {
None => Err(Error::EmptyKeysInApolloFederationConfigForObject {
object_type: qualified_type_name.clone(),
}),
Some(keys) => Ok(Some(data_connector_type_mappings
::ResolvedObjectApolloFederationConfig { keys })),
}
}
}?;
Ok((
graphql_type_name,
graphql_input_type_name,
resolved_apollo_federation_config,
))
}
}?;
store_new_graphql_type(existing_graphql_types, graphql_type_name.as_ref())?;
store_new_graphql_type(existing_graphql_types, graphql_input_type_name.as_ref())?;
Ok(data_connector_type_mappings::ObjectTypeRepresentation {
fields: resolved_fields,
relationships: IndexMap::new(),
global_id_fields: resolved_global_id_fields,
type_output_permissions: HashMap::new(),
type_input_permissions: HashMap::new(),
graphql_output_type_name: graphql_type_name,
graphql_input_type_name,
description: object_type_definition.description.clone(),
apollo_federation_config,
})
}
*/
#[derive(Debug)]
/// we do not want to store our types like this, but occasionally it is useful
/// for pattern matching
@ -534,7 +378,10 @@ pub(crate) fn collect_type_mapping_for_source(
data_connector_name: &Qualified<DataConnectorName>,
object_types: &HashMap<Qualified<CustomTypeName>, type_permissions::ObjectTypeWithPermissions>,
scalar_types: &HashMap<Qualified<CustomTypeName>, scalar_types::ScalarTypeRepresentation>,
collected_mappings: &mut BTreeMap<Qualified<CustomTypeName>, TypeMapping>,
collected_mappings: &mut BTreeMap<
Qualified<CustomTypeName>,
data_connector_type_mappings::TypeMapping,
>,
) -> Result<(), TypeMappingCollectionError> {
let type_mapping = data_connector_type_mappings
.get(
@ -552,7 +399,7 @@ pub(crate) fn collect_type_mapping_for_source(
if let Some(inserted_mapping) =
collected_mappings.insert(mapping_to_collect.type_name.clone(), type_mapping.clone())
{
let TypeMapping::Object {
let data_connector_type_mappings::TypeMapping::Object {
ndc_object_type_name,
..
} = inserted_mapping;
@ -571,7 +418,8 @@ pub(crate) fn collect_type_mapping_for_source(
match object_types.get(mapping_to_collect.type_name) {
Some(object_type_representation) => {
let TypeMapping::Object { field_mappings, .. } = type_mapping;
let data_connector_type_mappings::TypeMapping::Object { field_mappings, .. } =
type_mapping;
// For each field in the ObjectType, if that field is using an ObjectType in its type,
// resolve the type mappings for that ObjectType too
for (field_name, field_definition) in &object_type_representation.object_type.fields {

View File

@ -3,11 +3,9 @@ use std::collections::{BTreeMap, HashMap};
use crate::metadata::resolved::model::FilterPermission;
use crate::metadata::resolved::permission::resolve_value_expression;
use crate::metadata::resolved::stages::type_permissions;
use crate::metadata::resolved::stages::{data_connector_type_mappings, type_permissions};
use crate::metadata::resolved::subgraph::{Qualified, QualifiedTypeReference};
use crate::metadata::resolved::types::{
object_type_exists, unwrap_custom_type_name, FieldMapping, TypeMapping,
};
use crate::metadata::resolved::types::{object_type_exists, unwrap_custom_type_name};
use crate::metadata::resolved::{self};
use crate::schema::Role;
use crate::schema::{self, types};
@ -228,7 +226,7 @@ fn build_annotations_from_input_object_type_permissions(
type_reference: &QualifiedTypeReference,
ndc_argument_name: &Option<String>,
object_types: &HashMap<Qualified<CustomTypeName>, type_permissions::ObjectTypeWithPermissions>,
type_mappings: &BTreeMap<Qualified<CustomTypeName>, TypeMapping>,
type_mappings: &BTreeMap<Qualified<CustomTypeName>, data_connector_type_mappings::TypeMapping>,
role_presets_map: &mut HashMap<Role, types::ArgumentPresets>,
) -> Result<(), schema::Error> {
if let Some(custom_typename) = unwrap_custom_type_name(type_reference) {
@ -238,7 +236,7 @@ fn build_annotations_from_input_object_type_permissions(
type_mappings
.get(&object_type)
.map(|type_mapping| match type_mapping {
TypeMapping::Object {
data_connector_type_mappings::TypeMapping::Object {
ndc_object_type_name: _,
field_mappings,
} => field_mappings,
@ -296,7 +294,7 @@ fn build_annotations_from_input_object_type_permissions(
/// `Map<("person", ["address", "country"]), ValueExpression(SessionVariable("x-hasura-user-country"))>`
fn build_preset_map_from_input_object_type_permission(
permission: &type_permissions::TypeInputPermission,
field_mappings: Option<&BTreeMap<FieldName, FieldMapping>>,
field_mappings: Option<&BTreeMap<FieldName, data_connector_type_mappings::FieldMapping>>,
type_reference: &QualifiedTypeReference,
field_path: &[String],
ndc_argument_name: &Option<String>,

View File

@ -28,7 +28,7 @@ use crate::{
},
schema::types::resolved::{
subgraph::{deserialize_qualified_btreemap, serialize_qualified_btreemap},
types::TypeMapping,
TypeMapping,
},
utils::HashMapWithJsonKey,
};

View File

@ -44,7 +44,7 @@ pub struct FilterRelationshipAnnotation {
serialize_with = "serialize_qualified_btreemap",
deserialize_with = "deserialize_qualified_btreemap"
)]
pub source_type_mappings: BTreeMap<Qualified<CustomTypeName>, resolved::types::TypeMapping>,
pub source_type_mappings: BTreeMap<Qualified<CustomTypeName>, resolved::TypeMapping>,
pub target_source: ModelTargetSource,
pub target_type: Qualified<CustomTypeName>,
pub target_model_name: Qualified<ModelName>,
@ -61,7 +61,7 @@ pub struct OrderByRelationshipAnnotation {
serialize_with = "serialize_qualified_btreemap",
deserialize_with = "deserialize_qualified_btreemap"
)]
pub source_type_mappings: BTreeMap<Qualified<CustomTypeName>, resolved::types::TypeMapping>,
pub source_type_mappings: BTreeMap<Qualified<CustomTypeName>, resolved::TypeMapping>,
pub target_source: ModelTargetSource,
pub target_type: Qualified<CustomTypeName>,
pub target_model_name: Qualified<ModelName>,
@ -78,7 +78,7 @@ pub struct PredicateRelationshipAnnotation {
serialize_with = "serialize_qualified_btreemap",
deserialize_with = "deserialize_qualified_btreemap"
)]
pub source_type_mappings: BTreeMap<Qualified<CustomTypeName>, resolved::types::TypeMapping>,
pub source_type_mappings: BTreeMap<Qualified<CustomTypeName>, resolved::TypeMapping>,
pub target_source: ModelTargetSource,
pub target_type: Qualified<CustomTypeName>,
pub target_model_name: Qualified<ModelName>,