diff --git a/query-engine/core/src/interpreter/interpreter_impl.rs b/query-engine/core/src/interpreter/interpreter_impl.rs index 9840fe56333c..235536fe2ad9 100644 --- a/query-engine/core/src/interpreter/interpreter_impl.rs +++ b/query-engine/core/src/interpreter/interpreter_impl.rs @@ -67,7 +67,7 @@ impl ExpressionResult { // We always select IDs, the unwraps are safe. QueryResult::RecordSelection(Some(rs)) => Some( rs.records - .extract_selection_results(field_selection) + .extract_selection_results_from_db_name(field_selection) .expect("Expected record selection to contain required model ID fields.") .into_iter() .collect(), diff --git a/query-engine/core/src/interpreter/query_interpreters/inmemory_record_processor.rs b/query-engine/core/src/interpreter/query_interpreters/inmemory_record_processor.rs index fcb76f0155c4..7c60b89d7fb3 100644 --- a/query-engine/core/src/interpreter/query_interpreters/inmemory_record_processor.rs +++ b/query-engine/core/src/interpreter/query_interpreters/inmemory_record_processor.rs @@ -105,7 +105,7 @@ impl InMemoryRecordProcessor { .into_iter() .unique_by(|record| { record - .extract_selection_result(field_names, &distinct_selection) + .extract_selection_result_from_db_name(field_names, &distinct_selection) .unwrap() }) .collect(); @@ -119,7 +119,7 @@ impl InMemoryRecordProcessor { .into_iter() .unique_by(|record| { record - .extract_selection_result(field_names, &distinct_selection) + .extract_selection_result_from_db_name(field_names, &distinct_selection) .unwrap() }) .collect() @@ -144,7 +144,9 @@ impl InMemoryRecordProcessor { let mut cursor_seen = false; many_records.records.retain(|record| { - let cursor_comparator = record.extract_selection_result(field_names, &cursor_selection).unwrap(); + let cursor_comparator = record + .extract_selection_result_from_db_name(field_names, &cursor_selection) + .unwrap(); let record_values: Vec<_> = cursor_comparator.values().collect(); // Reset, new parent diff --git a/query-engine/core/src/interpreter/query_interpreters/nested_read.rs b/query-engine/core/src/interpreter/query_interpreters/nested_read.rs index 1238a35f1a24..790728104fd3 100644 --- a/query-engine/core/src/interpreter/query_interpreters/nested_read.rs +++ b/query-engine/core/src/interpreter/query_interpreters/nested_read.rs @@ -22,7 +22,7 @@ pub(crate) async fn m2m( let parent_model_id = query.parent_field.model().primary_identifier(); parent_result .expect("[ID retrieval] No parent results present in the query graph for reading related records.") - .extract_selection_results(&parent_model_id)? + .extract_selection_results_from_db_name(&parent_model_id)? } }; @@ -94,7 +94,7 @@ pub(crate) async fn m2m( let mut additional_records: Vec<(usize, Vec)> = vec![]; for (index, record) in scalars.records.iter_mut().enumerate() { - let record_id = record.extract_selection_result(fields, &child_model_id)?; + let record_id = record.extract_selection_result_from_db_name(fields, &child_model_id)?; let mut parent_ids = id_map.remove(&record_id).expect("1"); let first = parent_ids.pop().expect("2"); @@ -150,7 +150,7 @@ pub async fn one2m( let extractor = parent_model_id.clone().merge(parent_link_id.clone()); parent_result .expect("[ID retrieval] No parent results present in the query graph for reading related records.") - .extract_selection_results(&extractor)? + .extract_selection_results_from_db_name(&extractor)? } }; @@ -219,7 +219,8 @@ pub async fn one2m( let mut additional_records = vec![]; for record in scalars.records.iter_mut() { - let child_link: SelectionResult = record.extract_selection_result(&scalars.field_names, &child_link_id)?; + let child_link: SelectionResult = + record.extract_selection_result_from_db_name(&scalars.field_names, &child_link_id)?; let child_link_values: Vec = child_link.pairs.into_iter().map(|(_, v)| v).collect(); if let Some(parent_ids) = link_mapping.get_mut(&child_link_values) { @@ -244,7 +245,7 @@ pub async fn one2m( for record in scalars.records.iter_mut() { let child_link: SelectionResult = - record.extract_selection_result(&scalars.field_names, &child_link_fields)?; + record.extract_selection_result_from_db_name(&scalars.field_names, &child_link_fields)?; let child_link_values: Vec = child_link.pairs.into_iter().map(|(_, v)| v).collect(); if let Some(parent_ids) = link_mapping.get(&child_link_values) { diff --git a/query-engine/core/src/response_ir/internal.rs b/query-engine/core/src/response_ir/internal.rs index 46dbb66e2366..13be5bbd9d85 100644 --- a/query-engine/core/src/response_ir/internal.rs +++ b/query-engine/core/src/response_ir/internal.rs @@ -564,7 +564,8 @@ fn serialize_objects( // Write all fields, nested and list fields unordered into a map, afterwards order all into the final order. // If nothing is written to the object, write null instead. for record in result.records.records { - let record_id = Some(record.extract_selection_result(&db_field_names, &model.primary_identifier())?); + let record_id = + Some(record.extract_selection_result_from_db_name(&db_field_names, &model.primary_identifier())?); if !object_mapping.contains_key(&record.parent_id) { object_mapping.insert(record.parent_id.clone(), Vec::new()); diff --git a/query-engine/query-structure/src/record.rs b/query-engine/query-structure/src/record.rs index 880db9fe3dfa..cfa527d9f9bf 100644 --- a/query-engine/query-structure/src/record.rs +++ b/query-engine/query-structure/src/record.rs @@ -1,4 +1,6 @@ -use crate::{DomainError, FieldSelection, ModelProjection, OrderBy, PrismaValue, SelectionResult, SortOrder}; +use crate::{ + DomainError, FieldSelection, ModelProjection, OrderBy, PrismaValue, SelectedField, SelectionResult, SortOrder, +}; use itertools::Itertools; use std::collections::HashMap; @@ -24,7 +26,7 @@ impl SingleRecord { pub fn extract_selection_result(&self, extraction_selection: &FieldSelection) -> crate::Result { self.record - .extract_selection_result(&self.field_names, extraction_selection) + .extract_selection_result_from_db_name(&self.field_names, extraction_selection) } pub fn get_field_value(&self, field: &str) -> crate::Result<&PrismaValue> { @@ -91,15 +93,20 @@ impl ManyRecords { self.records.push(record); } - /// Builds `SelectionResults` from this `ManyRecords` based on the given FieldSelection. - pub fn extract_selection_results(&self, selections: &FieldSelection) -> crate::Result> { + /// Builds `SelectionResult`s from this `ManyRecords` based on the given `FieldSelection` + /// using the database field names. + pub fn extract_selection_results_from_db_name( + &self, + selections: &FieldSelection, + ) -> crate::Result> { self.records .iter() - .map(|record| record.extract_selection_result(&self.field_names, selections)) + .map(|record| record.extract_selection_result_from_db_name(&self.field_names, selections)) .collect() } - /// Builds `SelectionResults` from this `ManyRecords` based on the given FieldSelection. + /// Builds `SelectionResult`s from this `ManyRecords` based on the given `FieldSelection` + /// using the Prisma field names. pub fn extract_selection_results_from_prisma_name( &self, selections: &FieldSelection, @@ -172,34 +179,37 @@ impl Record { } } - /// Extract a `SelectionResult` from this `Record` + /// Extracts a `SelectionResult` from this `Record`. /// `field_names`: Database names of the fields contained in this `Record`. /// `selected_fields`: The selection to extract. - pub fn extract_selection_result( + pub fn extract_selection_result_from_db_name( &self, field_names: &[String], extraction_selection: &FieldSelection, ) -> crate::Result { - let pairs: Vec<_> = extraction_selection - .selections() - .map(|selection| { - self.get_field_value(field_names, &selection.db_name()) - .and_then(|val| Ok((selection.clone(), selection.coerce_value(val.clone())?))) - }) - .collect::>>()?; - - Ok(SelectionResult::new(pairs)) + self.extract_selection_result(field_names, extraction_selection, SelectedField::db_name) } + /// Extracts a `SelectionResult` from this `Record` using Prisma field names rather than + /// database names. pub fn extract_selection_result_from_prisma_name( &self, field_names: &[String], extraction_selection: &FieldSelection, + ) -> crate::Result { + self.extract_selection_result(field_names, extraction_selection, SelectedField::prisma_name) + } + + fn extract_selection_result<'a, S: AsRef + 'a>( + &self, + field_names: &[String], + extraction_selection: &'a FieldSelection, + map_name: impl Fn(&'a SelectedField) -> S, ) -> crate::Result { let pairs: Vec<_> = extraction_selection .selections() .map(|selection| { - self.get_field_value(field_names, &selection.prisma_name()) + self.get_field_value(field_names, map_name(selection).as_ref()) .and_then(|val| Ok((selection.clone(), selection.coerce_value(val.clone())?))) }) .collect::>>()?;