From 155199b84f16b0f61443784811975cfbd5cc5027 Mon Sep 17 00:00:00 2001 From: Jesse Hallett Date: Fri, 26 Apr 2024 17:21:55 -0700 Subject: [PATCH 1/5] translate mutation response according to requested fields --- crates/integration-tests/src/lib.rs | 2 +- .../src/tests/native_procedure.rs | 30 ++++++- .../mongodb-connector/src/mongo_connector.rs | 5 +- crates/mongodb-connector/src/mutation.rs | 73 ++++++++++++----- .../mongodb-connector/src/query_response.rs | 80 +++++++++---------- 5 files changed, 122 insertions(+), 68 deletions(-) diff --git a/crates/integration-tests/src/lib.rs b/crates/integration-tests/src/lib.rs index 6f06b61d..46038622 100644 --- a/crates/integration-tests/src/lib.rs +++ b/crates/integration-tests/src/lib.rs @@ -70,7 +70,7 @@ impl From<&str> for GraphQLRequest { } } -#[derive(Clone, Debug, Deserialize, Serialize)] +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] pub struct GraphQLResponse { data: Value, errors: Option>, diff --git a/crates/integration-tests/src/tests/native_procedure.rs b/crates/integration-tests/src/tests/native_procedure.rs index 916076fa..3aa26b35 100644 --- a/crates/integration-tests/src/tests/native_procedure.rs +++ b/crates/integration-tests/src/tests/native_procedure.rs @@ -1,4 +1,4 @@ -use crate::query; +use crate::{query, GraphQLResponse}; use insta::assert_yaml_snapshot; use serde_json::json; @@ -9,21 +9,43 @@ async fn updates_with_native_procedure() -> anyhow::Result<()> { let mutation = r#" mutation InsertArtist($id: Int!, $name: String!) { insertArtist(id: $id, name: $name) { - n + number_of_docs_inserted: n ok } } "#; - query(mutation) + let res1 = query(mutation) .variables(json!({ "id": id_1, "name": "Regina Spektor" })) .run() .await?; - query(mutation) + let res2 = query(mutation) .variables(json!({ "id": id_2, "name": "Ok Go" })) .run() .await?; + assert_eq!( + res1, + GraphQLResponse { + data: json!({ + "number_of_docs_inserted": 1, + "ok": 1, + }), + errors: None, + } + ); + + assert_eq!( + res2, + GraphQLResponse { + data: json!({ + "number_of_docs_inserted": 1, + "ok": 1, + }), + errors: None, + } + ); + assert_yaml_snapshot!( query( r#" diff --git a/crates/mongodb-connector/src/mongo_connector.rs b/crates/mongodb-connector/src/mongo_connector.rs index 892c8741..be2e2866 100644 --- a/crates/mongodb-connector/src/mongo_connector.rs +++ b/crates/mongodb-connector/src/mongo_connector.rs @@ -122,7 +122,7 @@ impl Connector for MongoConnector { _request: MutationRequest, ) -> Result, ExplainError> { Err(ExplainError::UnsupportedOperation( - "The MongoDB agent does not yet support mutations".to_owned(), + "Explain for mutations is not implemented yet".to_owned(), )) } @@ -132,7 +132,8 @@ impl Connector for MongoConnector { state: &Self::State, request: MutationRequest, ) -> Result, MutationError> { - handle_mutation_request(configuration, state, request).await + let query_context = get_query_context(configuration); + handle_mutation_request(configuration, query_context, state, request).await } #[instrument(err, skip_all)] diff --git a/crates/mongodb-connector/src/mutation.rs b/crates/mongodb-connector/src/mutation.rs index 9a6ec86e..1c0d8d81 100644 --- a/crates/mongodb-connector/src/mutation.rs +++ b/crates/mongodb-connector/src/mutation.rs @@ -1,6 +1,6 @@ use std::collections::BTreeMap; -use configuration::{schema::ObjectType, Configuration}; +use configuration::Configuration; use futures::future::try_join_all; use itertools::Itertools; use mongodb::Database; @@ -10,42 +10,59 @@ use mongodb_agent_common::{ use ndc_sdk::{ connector::MutationError, json_response::JsonResponse, - models::{MutationOperation, MutationOperationResults, MutationRequest, MutationResponse}, + models::{ + MutationOperation, MutationOperationResults, MutationRequest, MutationResponse, + NestedField, Relationship, + }, +}; + +use crate::{ + api_type_conversions::QueryContext, + query_response::{extend_configured_object_types, prune_type_to_field_selection}, }; pub async fn handle_mutation_request( config: &Configuration, + query_context: QueryContext<'_>, state: &ConnectorState, mutation_request: MutationRequest, ) -> Result, MutationError> { tracing::debug!(?config, mutation_request = %serde_json::to_string(&mutation_request).unwrap(), "executing mutation"); let database = state.database(); - let jobs = look_up_procedures(config, mutation_request)?; - let operation_results = try_join_all( - jobs.into_iter() - .map(|procedure| execute_procedure(&config.object_types, database.clone(), procedure)), - ) + let jobs = look_up_procedures(config, &mutation_request)?; + let operation_results = try_join_all(jobs.into_iter().map(|(procedure, requested_fields)| { + execute_procedure( + &query_context, + database.clone(), + &mutation_request.collection_relationships, + procedure, + requested_fields, + ) + })) .await?; Ok(JsonResponse::Value(MutationResponse { operation_results })) } /// Looks up procedures according to the names given in the mutation request, and pairs them with /// arguments and requested fields. Returns an error if any procedures cannot be found. -fn look_up_procedures( - config: &Configuration, - mutation_request: MutationRequest, -) -> Result>, MutationError> { - let (procedures, not_found): (Vec, Vec) = mutation_request +fn look_up_procedures<'a, 'b>( + config: &'a Configuration, + mutation_request: &'b MutationRequest, +) -> Result, Option<&'b NestedField>)>, MutationError> { + let (procedures, not_found): (Vec<_>, Vec) = mutation_request .operations - .into_iter() + .iter() .map(|operation| match operation { MutationOperation::Procedure { - name, arguments, .. + name, + arguments, + fields, } => { - let native_procedure = config.native_procedures.get(&name); - native_procedure.ok_or(name).map(|native_procedure| { - Procedure::from_native_procedure(native_procedure, arguments) - }) + let native_procedure = config.native_procedures.get(name); + let procedure = native_procedure.ok_or(name).map(|native_procedure| { + Procedure::from_native_procedure(native_procedure, arguments.clone()) + })?; + Ok((procedure, fields.as_ref())) } }) .partition_result(); @@ -61,16 +78,30 @@ fn look_up_procedures( } async fn execute_procedure( - object_types: &BTreeMap, + query_context: &QueryContext<'_>, database: Database, + relationships: &BTreeMap, procedure: Procedure<'_>, + requested_fields: Option<&NestedField>, ) -> Result { let (result, result_type) = procedure - .execute(object_types, database.clone()) + .execute(&query_context.object_types, database.clone()) .await .map_err(|err| MutationError::InvalidRequest(err.to_string()))?; - let json_result = bson_to_json(&result_type, object_types, result.into()) + + let (requested_result_type, temp_object_types) = prune_type_to_field_selection( + query_context, + relationships, + &[], + &result_type, + requested_fields, + ) + .map_err(|err| MutationError::Other(Box::new(err)))?; + let object_types = extend_configured_object_types(query_context, temp_object_types); + + let json_result = bson_to_json(&requested_result_type, &object_types, result.into()) .map_err(|err| MutationError::Other(Box::new(err)))?; + Ok(MutationOperationResults::Procedure { result: json_result, }) diff --git a/crates/mongodb-connector/src/query_response.rs b/crates/mongodb-connector/src/query_response.rs index 0643dc52..6ece4aa7 100644 --- a/crates/mongodb-connector/src/query_response.rs +++ b/crates/mongodb-connector/src/query_response.rs @@ -7,7 +7,7 @@ use mongodb::bson::{self, Bson}; use mongodb_agent_common::query::serialization::{bson_to_json, BsonToJsonError}; use ndc_sdk::models::{ self as ndc, Aggregate, Field, NestedField, NestedObject, Query, QueryRequest, QueryResponse, - RowFieldValue, RowSet, + Relationship, RowFieldValue, RowSet, }; use serde::Deserialize; use thiserror::Error; @@ -78,7 +78,7 @@ pub fn serialize_query_response( .map(|docs| { serialize_row_set( query_context, - query_request, + &query_request.collection_relationships, &[collection_name], collection_name, &query_request.query, @@ -89,7 +89,7 @@ pub fn serialize_query_response( } else { Ok(vec![serialize_row_set( query_context, - query_request, + &query_request.collection_relationships, &[], collection_name, &query_request.query, @@ -103,7 +103,7 @@ pub fn serialize_query_response( fn serialize_row_set( query_context: &QueryContext<'_>, - query_request: &QueryRequest, + relationships: &BTreeMap, path: &[&str], collection_name: &str, query: &Query, @@ -117,7 +117,7 @@ fn serialize_row_set( .map(|fields| { serialize_rows( query_context, - query_request, + relationships, path, collection_name, fields, @@ -149,7 +149,7 @@ fn serialize_row_set( .map(|fields| { serialize_rows( query_context, - query_request, + relationships, path, collection_name, fields, @@ -187,7 +187,7 @@ fn serialize_aggregates( fn serialize_rows( query_context: &QueryContext<'_>, - query_request: &QueryRequest, + relationships: &BTreeMap, path: &[&str], collection_name: &str, query_fields: &IndexMap, @@ -195,7 +195,7 @@ fn serialize_rows( ) -> Result>> { let (row_type, temp_object_types) = type_for_row( query_context, - query_request, + relationships, path, collection_name, query_fields, @@ -222,7 +222,7 @@ fn serialize_rows( fn type_for_row_set( query_context: &QueryContext<'_>, - query_request: &QueryRequest, + relationships: &BTreeMap, path: &[&str], collection_name: &str, query: &Query, @@ -245,7 +245,7 @@ fn type_for_row_set( if let Some(query_fields) = &query.fields { let (row_type, nested_object_types) = type_for_row( query_context, - query_request, + relationships, path, collection_name, query_fields, @@ -277,7 +277,7 @@ fn type_for_aggregates() -> Result<(Type, ObjectTypes)> { fn type_for_row( query_context: &QueryContext<'_>, - query_request: &QueryRequest, + relationships: &BTreeMap, path: &[&str], collection_name: &str, query_fields: &IndexMap, @@ -289,7 +289,7 @@ fn type_for_row( .map(|(field_name, field_definition)| { let (field_type, nested_object_types) = type_for_field( query_context, - query_request, + relationships, &append_to_path(path, [field_name.as_ref()]), collection_name, field_definition, @@ -317,7 +317,7 @@ fn type_for_row( fn type_for_field( query_context: &QueryContext<'_>, - query_request: &QueryRequest, + relationships: &BTreeMap, path: &[&str], collection_name: &str, field_definition: &ndc::Field, @@ -328,7 +328,7 @@ fn type_for_field( let (requested_type, temp_object_types) = prune_type_to_field_selection( query_context, - query_request, + relationships, path, field_type, fields.as_ref(), @@ -343,7 +343,7 @@ fn type_for_field( .. } => { let (requested_type, temp_object_types) = - type_for_relation_field(query_context, query_request, path, query, relationship)?; + type_for_relation_field(query_context, relationships, path, query, relationship)?; Ok((requested_type, temp_object_types)) } @@ -375,26 +375,26 @@ fn find_field_type<'a>( /// /// Returns a reference to the pruned type, and a list of newly-computed object types with /// generated names. -fn prune_type_to_field_selection( +pub fn prune_type_to_field_selection( query_context: &QueryContext<'_>, - query_request: &QueryRequest, + relationships: &BTreeMap, path: &[&str], - field_type: &Type, + input_type: &Type, fields: Option<&NestedField>, ) -> Result<(Type, Vec<(String, ObjectType)>)> { - match (field_type, fields) { + match (input_type, fields) { (t, None) => Ok((t.clone(), Default::default())), (t @ Type::Scalar(_) | t @ Type::ExtendedJSON, _) => Ok((t.clone(), Default::default())), (Type::Nullable(t), _) => { let (underlying_type, object_types) = - prune_type_to_field_selection(query_context, query_request, path, t, fields)?; + prune_type_to_field_selection(query_context, relationships, path, t, fields)?; Ok((Type::Nullable(Box::new(underlying_type)), object_types)) } (Type::ArrayOf(t), Some(NestedField::Array(nested))) => { let (element_type, object_types) = prune_type_to_field_selection( query_context, - query_request, + relationships, path, t, Some(&nested.fields), @@ -402,7 +402,7 @@ fn prune_type_to_field_selection( Ok((Type::ArrayOf(Box::new(element_type)), object_types)) } (Type::Object(t), Some(NestedField::Object(nested))) => { - object_type_for_field_subset(query_context, query_request, path, t, nested) + object_type_for_field_subset(query_context, relationships, path, t, nested) } (_, Some(NestedField::Array(_))) => Err(QueryResponseError::ExpectedArray { @@ -422,7 +422,7 @@ fn prune_type_to_field_selection( /// generated names including the newly-generated object type, and types for any nested objects. fn object_type_for_field_subset( query_context: &QueryContext<'_>, - query_request: &QueryRequest, + relationships: &BTreeMap, path: &[&str], object_type_name: &str, requested_fields: &NestedObject, @@ -434,7 +434,7 @@ fn object_type_for_field_subset( .map(|(name, requested_field)| { let (object_field, object_types) = requested_field_definition( query_context, - query_request, + relationships, &append_to_path(path, [name.as_ref()]), object_type_name, object_type, @@ -462,7 +462,7 @@ fn object_type_for_field_subset( /// name of the requested field maps to a different name on the underlying type. fn requested_field_definition( query_context: &QueryContext<'_>, - query_request: &QueryRequest, + relationships: &BTreeMap, path: &[&str], object_type_name: &str, object_type: &ObjectType, @@ -479,7 +479,7 @@ fn requested_field_definition( })?; let (field_type, object_types) = prune_type_to_field_selection( query_context, - query_request, + relationships, path, &field_def.r#type, fields.as_ref(), @@ -496,7 +496,7 @@ fn requested_field_definition( .. } => { let (relation_type, temp_object_types) = - type_for_relation_field(query_context, query_request, path, query, relationship)?; + type_for_relation_field(query_context, relationships, path, query, relationship)?; let relation_field = ObjectField { r#type: relation_type, description: None, @@ -508,28 +508,28 @@ fn requested_field_definition( fn type_for_relation_field( query_context: &QueryContext<'_>, - query_request: &QueryRequest, + relationships: &BTreeMap, path: &[&str], query: &Query, relationship: &str, ) -> Result<(Type, Vec<(String, ObjectType)>)> { - let relationship_def = query_request - .collection_relationships - .get(relationship) - .ok_or_else(|| ConversionError::UnknownRelationship { - relationship_name: relationship.to_owned(), - path: path_to_owned(path), - })?; + let relationship_def = + relationships + .get(relationship) + .ok_or_else(|| ConversionError::UnknownRelationship { + relationship_name: relationship.to_owned(), + path: path_to_owned(path), + })?; type_for_row_set( query_context, - query_request, + relationships, path, &relationship_def.target_collection, query, ) } -fn extend_configured_object_types<'a>( +pub fn extend_configured_object_types<'a>( query_context: &QueryContext<'a>, object_types: ObjectTypes, ) -> Cow<'a, BTreeMap> { @@ -588,7 +588,7 @@ mod tests { use configuration::schema::{ObjectType, Type}; use mongodb::bson::{self, Bson}; use mongodb_support::BsonScalarType; - use ndc_sdk::models::{QueryResponse, RowFieldValue, RowSet}; + use ndc_sdk::models::{QueryRequest, QueryResponse, RowFieldValue, RowSet}; use ndc_test_helpers::{ array, collection, field, object, query, query_request, relation_field, relationship, }; @@ -847,7 +847,7 @@ mod tests { fn uses_field_path_to_guarantee_distinct_type_names() -> anyhow::Result<()> { let query_context = make_nested_schema(); let collection_name = "appearances"; - let request = query_request() + let request: QueryRequest = query_request() .collection(collection_name) .relationships([("author", relationship("authors", [("authorId", "id")]))]) .query( @@ -869,7 +869,7 @@ mod tests { let (row_set_type, object_types) = type_for_row_set( &query_context, - &request, + &request.collection_relationships, &path, collection_name, &request.query, From 8d16734b8bbb322631cbbf5587b194783323f9d6 Mon Sep 17 00:00:00 2001 From: Jesse Hallett Date: Fri, 26 Apr 2024 18:07:49 -0700 Subject: [PATCH 2/5] propagate errors to user --- crates/mongodb-connector/src/mutation.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/mongodb-connector/src/mutation.rs b/crates/mongodb-connector/src/mutation.rs index 1c0d8d81..7f849fc2 100644 --- a/crates/mongodb-connector/src/mutation.rs +++ b/crates/mongodb-connector/src/mutation.rs @@ -87,7 +87,7 @@ async fn execute_procedure( let (result, result_type) = procedure .execute(&query_context.object_types, database.clone()) .await - .map_err(|err| MutationError::InvalidRequest(err.to_string()))?; + .map_err(|err| MutationError::UnprocessableContent(err.to_string()))?; let (requested_result_type, temp_object_types) = prune_type_to_field_selection( query_context, @@ -100,7 +100,7 @@ async fn execute_procedure( let object_types = extend_configured_object_types(query_context, temp_object_types); let json_result = bson_to_json(&requested_result_type, &object_types, result.into()) - .map_err(|err| MutationError::Other(Box::new(err)))?; + .map_err(|err| MutationError::UnprocessableContent(err.to_string()))?; Ok(MutationOperationResults::Procedure { result: json_result, From 58bc4c1c4b061673edcf33a84854699c9013bafd Mon Sep 17 00:00:00 2001 From: Jesse Hallett Date: Fri, 26 Apr 2024 18:50:16 -0700 Subject: [PATCH 3/5] rewrite mutation response to apply aliases --- .../src/tests/native_procedure.rs | 19 ++--- crates/mongodb-connector/src/mutation.rs | 74 ++++++++++++++++++- 2 files changed, 75 insertions(+), 18 deletions(-) diff --git a/crates/integration-tests/src/tests/native_procedure.rs b/crates/integration-tests/src/tests/native_procedure.rs index 3aa26b35..7c9e26a1 100644 --- a/crates/integration-tests/src/tests/native_procedure.rs +++ b/crates/integration-tests/src/tests/native_procedure.rs @@ -19,7 +19,7 @@ async fn updates_with_native_procedure() -> anyhow::Result<()> { .variables(json!({ "id": id_1, "name": "Regina Spektor" })) .run() .await?; - let res2 = query(mutation) + query(mutation) .variables(json!({ "id": id_2, "name": "Ok Go" })) .run() .await?; @@ -28,19 +28,10 @@ async fn updates_with_native_procedure() -> anyhow::Result<()> { res1, GraphQLResponse { data: json!({ - "number_of_docs_inserted": 1, - "ok": 1, - }), - errors: None, - } - ); - - assert_eq!( - res2, - GraphQLResponse { - data: json!({ - "number_of_docs_inserted": 1, - "ok": 1, + "insertArtist": { + "number_of_docs_inserted": 1, + "ok": 1, + } }), errors: None, } diff --git a/crates/mongodb-connector/src/mutation.rs b/crates/mongodb-connector/src/mutation.rs index 7f849fc2..c98e812f 100644 --- a/crates/mongodb-connector/src/mutation.rs +++ b/crates/mongodb-connector/src/mutation.rs @@ -3,7 +3,10 @@ use std::collections::BTreeMap; use configuration::Configuration; use futures::future::try_join_all; use itertools::Itertools; -use mongodb::Database; +use mongodb::{ + bson::{self, Bson}, + Database, +}; use mongodb_agent_common::{ procedure::Procedure, query::serialization::bson_to_json, state::ConnectorState, }; @@ -11,8 +14,8 @@ use ndc_sdk::{ connector::MutationError, json_response::JsonResponse, models::{ - MutationOperation, MutationOperationResults, MutationRequest, MutationResponse, - NestedField, Relationship, + Field, MutationOperation, MutationOperationResults, MutationRequest, MutationResponse, + NestedArray, NestedField, NestedObject, Relationship, }, }; @@ -89,6 +92,8 @@ async fn execute_procedure( .await .map_err(|err| MutationError::UnprocessableContent(err.to_string()))?; + let rewritten_result = rewrite_response(requested_fields, result.into())?; + let (requested_result_type, temp_object_types) = prune_type_to_field_selection( query_context, relationships, @@ -99,10 +104,71 @@ async fn execute_procedure( .map_err(|err| MutationError::Other(Box::new(err)))?; let object_types = extend_configured_object_types(query_context, temp_object_types); - let json_result = bson_to_json(&requested_result_type, &object_types, result.into()) + let json_result = bson_to_json(&requested_result_type, &object_types, rewritten_result) .map_err(|err| MutationError::UnprocessableContent(err.to_string()))?; Ok(MutationOperationResults::Procedure { result: json_result, }) } + +/// We need to traverse requested fields to rename any fields that are aliased in the GraphQL +/// request +fn rewrite_response( + requested_fields: Option<&NestedField>, + value: Bson, +) -> Result { + match (requested_fields, value) { + (None, value) => Ok(value), + + (Some(NestedField::Object(fields)), Bson::Document(doc)) => { + Ok(rewrite_doc(fields, doc)?.into()) + } + (Some(NestedField::Array(fields)), Bson::Array(values)) => { + Ok(rewrite_array(fields, values)?.into()) + } + + (Some(NestedField::Object(_)), _) => Err(MutationError::UnprocessableContent( + "expected an object".to_owned(), + )), + (Some(NestedField::Array(_)), _) => Err(MutationError::UnprocessableContent( + "expected an array".to_owned(), + )), + } +} + +fn rewrite_doc( + fields: &NestedObject, + mut doc: bson::Document, +) -> Result { + fields + .fields + .iter() + .map(|(name, field)| { + let field_value = match field { + Field::Column { column, fields } => { + let orig_value = doc.remove(column).ok_or_else(|| { + MutationError::UnprocessableContent(format!( + "missing expected field from response: {name}" + )) + })?; + rewrite_response(fields.as_ref(), orig_value) + } + Field::Relationship { .. } => Err(MutationError::UnsupportedOperation( + "The MongoDB connector does not support relationship references in mutations" + .to_owned(), + )), + }?; + + Ok((name.clone(), field_value)) + }) + .try_collect() +} + +fn rewrite_array(fields: &NestedArray, values: Vec) -> Result, MutationError> { + let nested = &fields.fields; + values + .into_iter() + .map(|value| rewrite_response(Some(nested), value)) + .try_collect() +} From 87d1b90fd02ff46485fb71026a00a295288a52af Mon Sep 17 00:00:00 2001 From: Jesse Hallett Date: Fri, 26 Apr 2024 19:05:24 -0700 Subject: [PATCH 4/5] mongodb is sending `ok` as a double for some reason --- crates/integration-tests/src/tests/native_procedure.rs | 2 +- fixtures/connector/chinook/native_procedures/insert_artist.json | 2 +- fixtures/ddn/chinook/commands/InsertArtist.hml | 2 +- fixtures/ddn/chinook/dataconnectors/chinook.hml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/integration-tests/src/tests/native_procedure.rs b/crates/integration-tests/src/tests/native_procedure.rs index 7c9e26a1..15cdfef8 100644 --- a/crates/integration-tests/src/tests/native_procedure.rs +++ b/crates/integration-tests/src/tests/native_procedure.rs @@ -30,7 +30,7 @@ async fn updates_with_native_procedure() -> anyhow::Result<()> { data: json!({ "insertArtist": { "number_of_docs_inserted": 1, - "ok": 1, + "ok": 1.0, } }), errors: None, diff --git a/fixtures/connector/chinook/native_procedures/insert_artist.json b/fixtures/connector/chinook/native_procedures/insert_artist.json index 17b5dfc7..f2b809a4 100644 --- a/fixtures/connector/chinook/native_procedures/insert_artist.json +++ b/fixtures/connector/chinook/native_procedures/insert_artist.json @@ -21,7 +21,7 @@ "fields": { "ok": { "type": { - "scalar": "int" + "scalar": "double" } }, "n": { diff --git a/fixtures/ddn/chinook/commands/InsertArtist.hml b/fixtures/ddn/chinook/commands/InsertArtist.hml index 115a31bb..d199e171 100644 --- a/fixtures/ddn/chinook/commands/InsertArtist.hml +++ b/fixtures/ddn/chinook/commands/InsertArtist.hml @@ -38,7 +38,7 @@ definition: typeName: InsertArtist fields: - name: ok - type: Int! + type: Float! - name: n type: Int! dataConnectorTypeMapping: diff --git a/fixtures/ddn/chinook/dataconnectors/chinook.hml b/fixtures/ddn/chinook/dataconnectors/chinook.hml index 40c6b0a3..32e9c0e8 100644 --- a/fixtures/ddn/chinook/dataconnectors/chinook.hml +++ b/fixtures/ddn/chinook/dataconnectors/chinook.hml @@ -827,7 +827,7 @@ definition: InsertArtist: fields: ok: - type: { type: named, name: Int } + type: { type: named, name: Double } n: type: { type: named, name: Int } collections: From 940327f09c1f3489f3b579542d96c8cb0e744c96 Mon Sep 17 00:00:00 2001 From: Jesse Hallett Date: Fri, 26 Apr 2024 19:13:26 -0700 Subject: [PATCH 5/5] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fdc7763a..430ff6f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ This changelog documents the changes between release versions. - In the CLI update command, if the database URI is not provided the error message now mentions the correct environment variable to use (`MONGODB_DATABASE_URI`) ([#50](https://github.com/hasura/ndc-mongodb/pull/50)) - Update to latest NDC SDK ([#51](https://github.com/hasura/ndc-mongodb/pull/51)) - Update `rustls` dependency to fix https://github.com/hasura/ndc-mongodb/security/dependabot/1 ([#51](https://github.com/hasura/ndc-mongodb/pull/51)) +- Serialize query and mutation response fields with known types using simple JSON instead of Extended JSON (#53) (#59) ## [0.0.4] - 2024-04-12 - Queries that attempt to compare a column to a column in the query root table, or a related table, will now fail instead of giving the incorrect result ([#22](https://github.com/hasura/ndc-mongodb/pull/22))