Skip to content

Commit

Permalink
fix(qe) Don't use native upserts with nested selection (#3377)
Browse files Browse the repository at this point in the history
(cherry picked from commit 379f9d3)
  • Loading branch information
garrensmith authored and Jolg42 committed Nov 9, 2022
1 parent d49d858 commit 694eea2
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,60 @@ mod native_upsert {
Ok(())
}

pub fn relations() -> String {
let schema = indoc! {
"
model User {
#id(id, Int, @id)
first_name String
last_name String
email String @unique
birthday DateTime?
location Location?
}
model Location {
#id(id, Int, @id)
userId Int @unique
user User @relation(fields: [userId], references: [id])
}
"
};

schema.to_owned()
}

#[connector_test(schema(relations))]
async fn should_not_if_has_nested_select(mut runner: Runner) -> TestResult<()> {
insta::assert_snapshot!(
run_query!(&runner, r#"mutation {
upsertOneUser(
where: {email: "email1"}
create: {
id: 1,
first_name: "first",
last_name: "last",
email: "email1",
}
update: {
email: "email1-updated",
}
){
id,
email,
location {
id
}
}
}"#),
@r###"{"data":{"upsertOneUser":{"id":1,"email":"email1","location":null}}}"###
);

assert_not_used_native_upsert(&mut runner).await;
Ok(())
}

pub fn compound_id() -> String {
let schema = indoc! {
"model TestModel {
Expand Down
19 changes: 18 additions & 1 deletion query-engine/core/src/query_graph_builder/write/upsert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use super::{write_args_parser::WriteArgsParser, *};
use crate::{
query_ast::*,
query_graph::{Flow, Node, QueryGraph, QueryGraphDependency},
ParsedField, ParsedInputMap, ParsedInputValue,
ParsedField, ParsedInputMap, ParsedInputValue, ParsedObject,
};
use connector::IntoFilter;
use prisma_models::ModelRef;
Expand Down Expand Up @@ -60,12 +60,14 @@ pub fn upsert_record(
let where_argument = field.where_arg()?.unwrap();
let create_argument = field.create_arg()?.unwrap();
let update_argument = field.update_arg()?.unwrap();
let selection = &field.nested_fields;

let can_use_native_upsert = can_use_connector_native_upsert(
&model,
&where_argument,
&create_argument,
&update_argument,
selection,
connector_ctx,
);

Expand Down Expand Up @@ -204,8 +206,11 @@ fn can_use_connector_native_upsert(
where_field: &ParsedInputMap,
create_argument: &ParsedInputMap,
update_argument: &ParsedInputMap,
selection: &Option<ParsedObject>,
connector_ctx: &ConnectorContext,
) -> bool {
let has_nested_selects = has_nested_selects(selection);

let has_nested_create = create_argument
.iter()
.any(|(field_name, _)| model.fields().find_from_relation_fields(&field_name).is_ok());
Expand All @@ -231,6 +236,7 @@ fn can_use_connector_native_upsert(
&& !has_nested_create
&& !has_nested_update
&& !empty_update
&& !has_nested_selects
&& where_values_same_as_create
}

Expand All @@ -241,6 +247,17 @@ fn is_unique_field(field_name: &String, model: &ModelRef) -> bool {
}
}

fn has_nested_selects(selection: &Option<ParsedObject>) -> bool {
if let Some(parsed_object) = selection {
parsed_object
.fields
.iter()
.any(|field| field.parsed_field.nested_fields.is_some())
} else {
false
}
}

/// Make sure the unique fields defined in the where clause have the same values
/// as in the create of the upsert.
fn where_and_create_equal(field_name: &str, where_value: &ParsedInputValue, create_map: &ParsedInputMap) -> bool {
Expand Down

0 comments on commit 694eea2

Please sign in to comment.