From 611ef41d254bd5f503e74eb1d34110ec8bd1731c Mon Sep 17 00:00:00 2001 From: Alexey Orlenko Date: Mon, 2 Sep 2024 12:26:40 +0200 Subject: [PATCH 1/2] fix(qe): forward join fields for nested filters in m2m (#4994) * test(query-engine): add regression test for prisma/prisma#25103 * Fix the IDs in schema_25103 * Add the actual failing query in prisma_25103 * Add repro for 25104 * Support m2m in join_fields * Exclude mongodb for now * Add a test with different pk names * Update the test to be closer to the user's query Co-authored-by: Alberto Schiabel --------- Co-authored-by: jkomyno Co-authored-by: Alberto Schiabel --- .../tests/queries/filters/many_relation.rs | 247 +++++++++++++++++- .../src/query_builder/select/mod.rs | 11 +- 2 files changed, 248 insertions(+), 10 deletions(-) diff --git a/query-engine/connector-test-kit-rs/query-engine-tests/tests/queries/filters/many_relation.rs b/query-engine/connector-test-kit-rs/query-engine-tests/tests/queries/filters/many_relation.rs index 3e179e8a4e2b..30e390785275 100644 --- a/query-engine/connector-test-kit-rs/query-engine-tests/tests/queries/filters/many_relation.rs +++ b/query-engine/connector-test-kit-rs/query-engine-tests/tests/queries/filters/many_relation.rs @@ -514,6 +514,186 @@ mod many_relation { Ok(()) } + fn schema_25103() -> String { + let schema = indoc! { + r#"model Contact { + #id(id, String, @id) + identities Identity[] + } + + model Identity { + #id(id, String, @id) + contactId String + contact Contact @relation(fields: [contactId], references: [id]) + subscriptions Subscription[] + } + + model Subscription { + #id(id, String, @id) + identityId String + audienceId String + optedOutAt DateTime? + audience Audience @relation(fields: [audienceId], references: [id]) + identity Identity @relation(fields: [identityId], references: [id]) + } + + model Audience { + #id(id, String, @id) + deletedAt DateTime? + subscriptions Subscription[] + }"# + }; + + schema.to_owned() + } + + // Regression test for https://github.com/prisma/prisma/issues/25103 + // SQL Server excluded because the m2m fragment does not support onUpdate/onDelete args which are needed. + #[connector_test(schema(schema_25103), exclude(SqlServer))] + async fn prisma_25103(runner: Runner) -> TestResult<()> { + // Create some sample audiences + run_query!( + &runner, + r#"mutation { + createOneAudience(data: { + id: "audience1", + deletedAt: null + }) { + id + }}"# + ); + run_query!( + &runner, + r#"mutation { + createOneAudience(data: { + id: "audience2", + deletedAt: null + }) { + id + }}"# + ); + // Create a contact with identities and subscriptions + insta::assert_snapshot!( + run_query!( + &runner, + r#"mutation { + createOneContact(data: { + id: "contact1", + identities: { + create: [ + { + id: "identity1", + subscriptions: { + create: [ + { + id: "subscription1", + audienceId: "audience1", + optedOutAt: null + }, + { + id: "subscription2", + audienceId: "audience2", + optedOutAt: null + } + ] + } + } + ] + } + }) { + id, + identities (orderBy: { id: asc }) { + id, + subscriptions (orderBy: { id: asc }) { + id, + audienceId + } + } + }}"# + ), + @r###"{"data":{"createOneContact":{"id":"contact1","identities":[{"id":"identity1","subscriptions":[{"id":"subscription1","audienceId":"audience1"},{"id":"subscription2","audienceId":"audience2"}]}]}}}"### + ); + // Find contacts that include identities whose subscriptions have `optedOutAt = null` and include audiences with `deletedAt = null`` + insta::assert_snapshot!( + run_query!( + &runner, + r#"query { + findManyContact(orderBy: { id: asc }) { + id, + identities(orderBy: { id: asc }) { + id, + subscriptions(orderBy: { id: asc }, where: { optedOutAt: null, audience: { deletedAt: null } }) { + id, + identityId, + audience { + id, + deletedAt + } + } + } + } + }"# + ), + @r###"{"data":{"findManyContact":[{"id":"contact1","identities":[{"id":"identity1","subscriptions":[{"id":"subscription1","identityId":"identity1","audience":{"id":"audience1","deletedAt":null}},{"id":"subscription2","identityId":"identity1","audience":{"id":"audience2","deletedAt":null}}]}]}]}}"### + ); + + Ok(()) + } + + fn schema_25104() -> String { + let schema = indoc! { + r#" + model A { + #id(id, String, @id) + bs B[] + } + + model B { + #id(id, String, @id) + a A @relation(fields: [aId], references: [id]) + aId String + + cs C[] + } + + model C { + #id(id, String, @id) + name String + bs B[] + } + "# + }; + + schema.to_owned() + } + + #[connector_test(schema(schema_25104), exclude(MongoDb))] + async fn prisma_25104(runner: Runner) -> TestResult<()> { + insta::assert_snapshot!( + run_query!( + &runner, + r#" + query { + findManyA { + bs(where: { + cs: { + every: { + name: { equals: "a" } + } + } + }) { + id + } + } + } + "# + ), + @r###"{"data":{"findManyA":[]}}"### + ); + + Ok(()) + } + fn schema_23742() -> String { let schema = indoc! { r#"model Top { @@ -522,7 +702,7 @@ mod many_relation { middleId Int? middle Middle? @relation(fields: [middleId], references: [id]) - #m2m(bottoms, Bottom[], id, Int) + #m2m(bottoms, Bottom[], id, Int) } model Middle { @@ -579,6 +759,71 @@ mod many_relation { Ok(()) } + fn schema_nested_some_filter_m2m_different_pk() -> String { + let schema = indoc! { + r#" + model Top { + #id(topId, Int, @id) + + relatedMiddleId Int? + middle Middle? @relation(fields: [relatedMiddleId], references: [middleId]) + + #m2m(bottoms, Bottom[], bottomId, Int) + } + + model Middle { + #id(middleId, Int, @id) + + bottoms Bottom[] + tops Top[] + } + + model Bottom { + #id(bottomId, Int, @id) + + relatedMiddleId Int? + middle Middle? @relation(fields: [relatedMiddleId], references: [middleId]) + + #m2m(tops, Top[], topId, Int) + } + "# + }; + + schema.to_owned() + } + + #[connector_test(schema(schema_nested_some_filter_m2m_different_pk), exclude(SqlServer))] + async fn nested_some_filter_m2m_different_pk(runner: Runner) -> TestResult<()> { + run_query!( + &runner, + r#"mutation { + createOneTop(data: { + topId: 1, + middle: { create: { middleId: 1, bottoms: { create: { bottomId: 1, tops: { create: { topId: 2 } } } } } } + }) { + topId + }}"# + ); + + insta::assert_snapshot!( + run_query!(&runner, r#"{ + findUniqueTop(where: { topId: 1 }) { + middle { + bottoms( + where: { tops: { some: { topId: 2 } } } + ) { + bottomId + } + } + } + } + "#), + @r###"{"data":{"findUniqueTop":{"middle":{"bottoms":[{"bottomId":1}]}}}}"### + ); + + Ok(()) + } + async fn test_data(runner: &Runner) -> TestResult<()> { runner .query(indoc! { r#" diff --git a/query-engine/connectors/sql-query-connector/src/query_builder/select/mod.rs b/query-engine/connectors/sql-query-connector/src/query_builder/select/mod.rs index c7c49ed3bc3f..9c0139c6cd81 100644 --- a/query-engine/connectors/sql-query-connector/src/query_builder/select/mod.rs +++ b/query-engine/connectors/sql-query-connector/src/query_builder/select/mod.rs @@ -648,20 +648,13 @@ fn extract_filter_scalars(f: &Filter) -> Vec { Filter::Scalar(x) => x.scalar_fields().into_iter().map(ToOwned::to_owned).collect(), Filter::ScalarList(x) => vec![x.field.clone()], Filter::OneRelationIsNull(x) => join_fields(&x.field), - Filter::Relation(x) => vec![join_fields(&x.field), extract_filter_scalars(&x.nested_filter)] - .into_iter() - .flatten() - .collect(), + Filter::Relation(x) => join_fields(&x.field), _ => Vec::new(), } } fn join_fields(rf: &RelationField) -> Vec { - if rf.is_inlined_on_enclosing_model() { - rf.scalar_fields() - } else { - rf.related_field().referenced_fields() - } + rf.linking_fields().as_scalar_fields().unwrap_or_default() } fn join_alias_name(rf: &RelationField) -> String { From f2561ec470647d6a14db84d3c1dc6fc1c2414386 Mon Sep 17 00:00:00 2001 From: Alberto Schiabel Date: Mon, 2 Sep 2024 12:42:54 +0200 Subject: [PATCH 2/2] Revert "chore(deps): bump openssl from 0.10.60 to 0.10.66" (#4995) * Revert "chore(deps): bump openssl from 0.10.60 to 0.10.66 (#4965)" This reverts commit ae18f9165678fc6c7b7b107340ca0435be434765. * chore(ci): stop showing commit message to avoid bad substitutions like https://github.com/prisma/prisma-engines/actions/runs/10664988277/job/29557431036\?pr\=4995\#step:4:13 --- .github/workflows/build-engines.yml | 2 +- Cargo.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-engines.yml b/.github/workflows/build-engines.yml index 6e931fedd224..9ca6940c8c54 100644 --- a/.github/workflows/build-engines.yml +++ b/.github/workflows/build-engines.yml @@ -53,7 +53,7 @@ jobs: echo "Repository Owner: $${{ github.repository_owner }}" echo "Pull Request Author: ${{ github.actor }}" echo "Pull Request Author Association: ${{ github.event.pull_request.author_association }}" - echo "Commit message:${{ steps.commit-msg.outputs.commit-msg }}" + # echo "Commit message:${{ steps.commit-msg.outputs.commit-msg }}" echo "Commit message contains [integration]: ${{ contains(steps.commit-msg.outputs.commit-msg, '[integration]') }}" - name: 'Check if commit message conatains `[integration]` and the PR author has permissions to trigger the workflow' diff --git a/Cargo.lock b/Cargo.lock index 626842538144..14a95793bddb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3067,9 +3067,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.66" +version = "0.10.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +checksum = "79a4c6c3a2b158f7f8f2a2fc5a969fa3a068df6fc9dbb4a43845436e3af7c800" dependencies = [ "bitflags 2.4.0", "cfg-if", @@ -3099,18 +3099,18 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "300.3.1+3.3.1" +version = "300.1.6+3.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7259953d42a81bf137fbbd73bd30a8e1914d6dce43c2b90ed575783a22608b91" +checksum = "439fac53e092cd7442a3660c85dde4643ab3b5bd39040912388dcdabf6b88085" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.103" +version = "0.9.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +checksum = "3812c071ba60da8b5677cc12bcb1d42989a65553772897a7e0355545a819838f" dependencies = [ "cc", "libc",