From 6795ad985c527cdaf71c052574c604901054bdc8 Mon Sep 17 00:00:00 2001 From: Serhii Tatarintsev Date: Wed, 6 Mar 2024 12:44:50 +0100 Subject: [PATCH] qe: Fix filter inversion on Mongo's `NOT` filter (#4754) For mongodb, when we encountered `NOT` filter, we flipped nested condition. However, we did not restore `inverted` flag after we are done processing the filter. So, if there were any subsequent sibling filters after `NOT`, they'll also will be incorrectly inverted. Fix prisma/prisma#22007 --- .../tests/new/regressions/mod.rs | 1 + .../tests/new/regressions/prisma_22007.rs | 51 +++++++++++++++++++ .../mongodb-query-connector/src/filter.rs | 8 ++- 3 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 query-engine/connector-test-kit-rs/query-engine-tests/tests/new/regressions/prisma_22007.rs 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 be0b5441c217..b1b5aae44ca4 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 @@ -23,6 +23,7 @@ mod prisma_20799; mod prisma_21182; mod prisma_21369; mod prisma_21901; +mod prisma_22007; mod prisma_22298; mod prisma_22971; mod prisma_5952; diff --git a/query-engine/connector-test-kit-rs/query-engine-tests/tests/new/regressions/prisma_22007.rs b/query-engine/connector-test-kit-rs/query-engine-tests/tests/new/regressions/prisma_22007.rs new file mode 100644 index 000000000000..518cb459b5cc --- /dev/null +++ b/query-engine/connector-test-kit-rs/query-engine-tests/tests/new/regressions/prisma_22007.rs @@ -0,0 +1,51 @@ +use query_engine_tests::*; + +#[test_suite(schema(schema), only(MongoDb))] +mod prisma_2207 { + + fn schema() -> String { + r#" + model Test { + #id(id, Int, @id) + title String + } + + "# + .to_owned() + } + #[connector_test] + async fn filters_render_correctly(runner: Runner) -> TestResult<()> { + let query = r#" + mutation { + createManyTest( + data: [ + {id: 1, title: "a"}, + {id: 2, title: "b"}, + {id: 3, title: "c"} + ] + ) { + count + } + }"#; + insta::assert_snapshot!(run_query!(runner, query), @r###"{"data":{"createManyTest":{"count":3}}}"###); + + let query = r#" + query { + findManyTest( + where: { + OR: [ + { NOT: { title: "b" } }, + { title: "c" } + ], + } + ) { + id + title + } + }"#; + + insta::assert_snapshot!(run_query!(runner, query), @r###"{"data":{"findManyTest":[{"id":1,"title":"a"},{"id":3,"title":"c"}]}}"###); + + Ok(()) + } +} diff --git a/query-engine/connectors/mongodb-query-connector/src/filter.rs b/query-engine/connectors/mongodb-query-connector/src/filter.rs index 64bdadafd6a9..cd8cb967b155 100644 --- a/query-engine/connectors/mongodb-query-connector/src/filter.rs +++ b/query-engine/connectors/mongodb-query-connector/src/filter.rs @@ -76,11 +76,15 @@ impl MongoFilterVisitor { Filter::Not(filters) if self.invert() => { self.flip_invert(); - self.visit_boolean_operator("$or", filters, false)? + let result = self.visit_boolean_operator("$or", filters, false)?; + self.flip_invert(); + result } Filter::Not(filters) => { self.flip_invert(); - self.visit_boolean_operator("$and", filters, true)? + let result = self.visit_boolean_operator("$and", filters, true)?; + self.flip_invert(); + result } Filter::Scalar(sf) => self.visit_scalar_filter(sf)?, Filter::Empty => MongoFilter::Scalar(doc! {}),