Skip to content

Commit

Permalink
fix: idempotent nested connect
Browse files Browse the repository at this point in the history
When performing a noop update on MySQL & MongoDB, the returned "affected count" by the updateMany mutation was 0. This was breaking nested connect mutations which expect the mutation to have happened. MySQL & MongoDB were affected by this.

This commit updates mysql_async (prisma/mysql_async#1) so that it passes the CLIENT_FOUND_ROWS flag. This changes the behaviour of the affected count returned for mutations (UPDATE/INSERT etc). It makes MySQL return the FOUND rows instead of the AFFECTED rows.

It also updates the logic on MongoDB to rely on the `matched_count` instead of the `modified_count`.
  • Loading branch information
Weakky committed Feb 7, 2023
1 parent d026664 commit 27ca5c3
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ mod prisma_15264;
mod prisma_15467;
mod prisma_15581;
mod prisma_15607;
mod prisma_17103;
mod prisma_5952;
mod prisma_6173;
mod prisma_7010;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use indoc::indoc;
use query_engine_tests::*;

#[test_suite(schema(schema))]
mod prisma_17103 {
fn schema() -> String {
let schema = indoc! {
r#"model A {
#id(id, Int, @id)
b B? @relation(fields: [bId], references: [id])
bId Int?
}
model B {
#id(id, Int, @id)
a A[]
}
"#
};

schema.to_owned()
}

#[connector_test]
async fn regression(runner: Runner) -> TestResult<()> {
run_query!(
&runner,
r#"mutation {
createOneA(data: { id: 1, b: { create: { id: 1 } } }) {
id
}
}
"#
);

insta::assert_snapshot!(
run_query!(&runner, r#"mutation { updateOneB(where: { id: 1 }, data: { a: { connect: { id: 1 } } }) { id } }"#),
@r###"{"data":{"updateOneB":{"id":1}}}"###
);

Ok(())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,10 @@ pub async fn update_records<'conn>(
.instrument(span)
.await?;

if update_type == UpdateType::Many && res.modified_count == 0 {
// It's important we check the `matched_count` and not the `modified_count` here.
// MongoDB returns `modified_count: 0` when performing a noop update, which breaks
// nested connect mutations as it rely on the returned count to know whether the update happened.
if update_type == UpdateType::Many && res.matched_count == 0 {
return Ok(Vec::new());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ async fn update_records_from_filter(
ctx: &Context<'_>,
) -> crate::Result<usize> {
let update = build_update_and_set_query(model, args, ctx);
let filter_condition = record_filter.clone().filter.aliased_condition_from(None, false, ctx);
let filter_condition = record_filter.filter.aliased_condition_from(None, false, ctx);

let update = update.so_that(filter_condition);
let count = conn.execute(update.into()).await?;
Expand Down

0 comments on commit 27ca5c3

Please sign in to comment.