diff --git a/query-engine/connector-test-kit-rs/query-engine-tests/tests/new/regressions/mod.rs b/query-engine/connector-test-kit-rs/query-engine-tests/tests/new/regressions/mod.rs index deaaa7e84313..4b4aa97479d6 100644 --- a/query-engine/connector-test-kit-rs/query-engine-tests/tests/new/regressions/mod.rs +++ b/query-engine/connector-test-kit-rs/query-engine-tests/tests/new/regressions/mod.rs @@ -30,3 +30,4 @@ mod prisma_7072; mod prisma_7434; mod prisma_8265; mod prisma_engines_4286; +mod team_orm_927; diff --git a/query-engine/connector-test-kit-rs/query-engine-tests/tests/new/regressions/team_orm_927.rs b/query-engine/connector-test-kit-rs/query-engine-tests/tests/new/regressions/team_orm_927.rs new file mode 100644 index 000000000000..45d7eba7aad9 --- /dev/null +++ b/query-engine/connector-test-kit-rs/query-engine-tests/tests/new/regressions/team_orm_927.rs @@ -0,0 +1,90 @@ +//! Regression test for https://github.com/prisma/team-orm/issues/927 + +use query_engine_tests::*; + +#[test_suite(schema(schema))] +mod count_before_relation { + fn schema() -> String { + indoc! { + r#" + model Parent { + #id(id, Int, @id) + children Child[] + } + + model Child { + #id(id, Int, @id) + parentId Int + parent Parent @relation(fields: [parentId], references: [id]) + } + "# + } + .to_owned() + } + + #[connector_test] + async fn find_unique(runner: Runner) -> TestResult<()> { + seed(&runner).await?; + + insta::assert_snapshot!( + run_query!( + runner, + r#" + query { + findUniqueParent( + where: { id: 1 } + ) { + _count { children } + children { id } + } + } + "# + ), + @r###"{"data":{"findUniqueParent":{"_count":{"children":1},"children":[{"id":1}]}}}"### + ); + + Ok(()) + } + + #[connector_test] + async fn find_many(runner: Runner) -> TestResult<()> { + seed(&runner).await?; + + insta::assert_snapshot!( + run_query!( + runner, + r#" + query { + findManyParent { + _count { children } + children { id } + } + } + "# + ), + @r###"{"data":{"findManyParent":[{"_count":{"children":1},"children":[{"id":1}]}]}}"### + ); + + Ok(()) + } + + async fn seed(runner: &Runner) -> TestResult<()> { + run_query!( + runner, + r#" + mutation { + createOneParent( + data: { + id: 1, + children: { + create: { id: 1 } + } + } + ) { id } + } + "# + ); + + Ok(()) + } +} 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 f9041c6dcd78..13206f560776 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 @@ -33,6 +33,7 @@ pub(crate) async fn get_single_record_joins( selected_fields: &FieldSelection, ctx: &Context<'_>, ) -> crate::Result> { + let selected_fields = selected_fields.to_virtuals_last(); let field_names: Vec<_> = selected_fields.db_names_grouping_virtuals().collect(); let idents = selected_fields.type_identifiers_with_arities_grouping_virtuals(); @@ -44,7 +45,7 @@ pub(crate) async fn get_single_record_joins( let query = query_builder::select::SelectBuilder::build( QueryArguments::from((model.clone(), filter.clone())), - selected_fields, + &selected_fields, ctx, ); @@ -130,6 +131,7 @@ pub(crate) async fn get_many_records_joins( selected_fields: &FieldSelection, ctx: &Context<'_>, ) -> crate::Result { + let selected_fields = selected_fields.to_virtuals_last(); let field_names: Vec<_> = selected_fields.db_names_grouping_virtuals().collect(); let idents = selected_fields.type_identifiers_with_arities_grouping_virtuals(); let meta = column_metadata::create(field_names.as_slice(), idents.as_slice()); @@ -155,7 +157,7 @@ pub(crate) async fn get_many_records_joins( _ => (), }; - let query = query_builder::select::SelectBuilder::build(query_arguments.clone(), selected_fields, ctx); + let query = query_builder::select::SelectBuilder::build(query_arguments.clone(), &selected_fields, ctx); for item in conn.filter(query.into(), meta.as_slice(), ctx).await?.into_iter() { let mut record = Record::from(item); diff --git a/query-engine/query-structure/src/field_selection.rs b/query-engine/query-structure/src/field_selection.rs index 086c80a2c785..b6d9bcb883e9 100644 --- a/query-engine/query-structure/src/field_selection.rs +++ b/query-engine/query-structure/src/field_selection.rs @@ -68,6 +68,10 @@ impl FieldSelection { FieldSelection::new(non_virtuals.into_iter().chain(virtuals).collect()) } + pub fn to_virtuals_last(&self) -> Self { + self.clone().into_virtuals_last() + } + /// Returns the selections, grouping the virtual fields that are wrapped into objects in the /// query (like `_count`) and returning only the first virtual field in each of those groups. /// This is useful when we want to treat the group as a whole but we don't need the information