From b07eec1e7096032c3edd0ebc79ef524079956427 Mon Sep 17 00:00:00 2001 From: Alexey Orlenko Date: Sat, 17 Feb 2024 00:19:39 +0100 Subject: [PATCH] use extract_selection_result_from_prisma_name --- .../src/database/operations/coerce.rs | 71 ++++++++----------- .../src/database/operations/read.rs | 7 +- 2 files changed, 36 insertions(+), 42 deletions(-) diff --git a/query-engine/connectors/sql-query-connector/src/database/operations/coerce.rs b/query-engine/connectors/sql-query-connector/src/database/operations/coerce.rs index 0ad14a8098c1..77c22f027f0a 100644 --- a/query-engine/connectors/sql-query-connector/src/database/operations/coerce.rs +++ b/query-engine/connectors/sql-query-connector/src/database/operations/coerce.rs @@ -75,46 +75,37 @@ fn coerce_json_relation_to_pv(value: serde_json::Value, rs: &RelationSelection) false => Either::Right(iter), }; - let iter = if rs.args.requires_inmemory_distinct_with_joins() { - Either::Left(iter.unique_by(|maybe_value| { - // Mapping errors to a unit type here does not discard the error information - // from the final iterator because the result that we return from this closure - // is only a key for comparing the elements, we do not map the elements - // themselves here. We can't use the original errors in keys because `SqlError` - // is not Eq + Hash. The consequence is that only the first error will be kept, - // but the same thing will happen when collecting the iterator to - // `Result>` anyway. This also means we have to way to introduce a new - // error and return it out of `unique_by`, so we have to panic if an element is - // not an object, but this is fine because we know we already mapped the - // elements using `coerce_json_relation_to_pv` above, so they must be objects. - // We also panic if we can't find the distinct field in the result set, which - // is less desirable but also exactly what the in-memory record processor for - // the old query strategy does. - maybe_value.as_ref().map_err(|_| ()).map(|value| { - let object = value - .clone() - .into_object() - .expect("Expected coerced_json_relation_to_pv to return list of objects"); - rs.args - .distinct - .as_ref() - .map(|distinct| { - distinct - .scalars() - .map(|sf| { - object - .iter() - // TODO: Use name instead of db_name after https://github.com/prisma/prisma-engines/pull/4732 is merged - .find_map(|(key, value)| (key == sf.db_name()).then_some(value)) - .expect("Distinct field must be present in the result") - }) - .collect::>() - }) - .unwrap_or_default(); - }) - })) - } else { - Either::Right(iter) + let iter = match rs.args.distinct.as_ref() { + Some(distinct) if rs.args.requires_inmemory_distinct_with_joins() => { + Either::Left(iter.unique_by(|maybe_value| { + // Mapping errors to a unit type here does not discard the error information + // from the final iterator because the result that we return from this closure + // is only a key for comparing the elements, we do not map the elements + // themselves here. We can't use the original errors in keys because `SqlError` + // is not Eq + Hash. The consequence is that only the first error will be kept, + // but the same thing will happen when collecting the iterator to + // `Result>` anyway. This also means we have to way to introduce a new + // error and return it out of `unique_by`, so we have to panic if an element is + // not an object, but this is fine because we know we already mapped the + // elements using `coerce_json_relation_to_pv` above, so they must be objects. + // We also panic if the result set is malformed and we can't find the distinct + // fields in it, which is less desirable but also exactly what the in-memory + // record processor for the old query strategy does. + maybe_value.as_ref().map_err(|_| ()).map(|value| { + let object = value + .clone() + .into_object() + .expect("Expected coerced_json_relation_to_pv to return list of objects"); + + let (field_names, values): (Vec<_>, Vec<_>) = object.into_iter().unzip(); + + Record::new(values) + .extract_selection_result_from_prisma_name(&field_names, distinct) + .unwrap() + }) + })) + } + _ => Either::Right(iter), }; Ok(PrismaValue::List(iter.collect::>>()?)) diff --git a/query-engine/connectors/sql-query-connector/src/database/operations/read.rs b/query-engine/connectors/sql-query-connector/src/database/operations/read.rs index 54f52ef56330..4a01dbc1a4a1 100644 --- a/query-engine/connectors/sql-query-connector/src/database/operations/read.rs +++ b/query-engine/connectors/sql-query-connector/src/database/operations/read.rs @@ -183,8 +183,11 @@ pub(crate) async fn get_many_records_joins( records.records = records .records .into_iter() - // TODO: we will need a different method once https://github.com/prisma/prisma-engines/pull/4732 lands. - .unique_by(|record| record.extract_selection_result(&records.field_names, distinct).unwrap()) + .unique_by(|record| { + record + .extract_selection_result_from_prisma_name(&records.field_names, distinct) + .unwrap() + }) .collect(); }