Skip to content

Commit

Permalink
qe: Fix filter inversion on Mongo's NOT filter (#4754)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
SevInf committed Mar 6, 2024
1 parent 4308b70 commit 6795ad9
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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(())
}
}
8 changes: 6 additions & 2 deletions query-engine/connectors/mongodb-query-connector/src/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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! {}),
Expand Down

0 comments on commit 6795ad9

Please sign in to comment.