Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(qe): NoAction should be alias of Restrict when relationMode = "prisma" #3276

Merged
2 changes: 2 additions & 0 deletions libs/dml/src/relation_info.rs
Expand Up @@ -57,6 +57,8 @@ pub enum ReferentialAction {
/// deferred, this makes it possible to temporarily violate integrity in a
/// transaction while making sure that subsequent operations in the
/// transaction restore integrity.
/// When using relationMode = "prisma", NoAction becomes an alias of
/// the emulated Restrict (when supported).
NoAction,
/// Sets relation scalar fields to null if the relation is deleted or
/// updated. This will always result in a runtime error if one or more of the
Expand Down
Expand Up @@ -45,22 +45,26 @@ mod one2one_req {
Ok(())
}

/// Deleting the parent leaves the data in a integrity-violating state.
/// Deleting the parent must fail if a child is connected.
#[connector_test(only(MongoDb))]
jkomyno marked this conversation as resolved.
Show resolved Hide resolved
async fn delete_parent_violation(runner: Runner) -> TestResult<()> {
insta::assert_snapshot!(
run_query!(&runner, r#"mutation { createOneParent(data: { id: 1, child: { create: { id: 1 }}}) { id }}"#),
@r###"{"data":{"createOneParent":{"id":1}}}"###
);

insta::assert_snapshot!(
run_query!(&runner, r#"mutation { deleteOneParent(where: { id: 1 }) { id }}"#),
@r###"{"data":{"deleteOneParent":{"id":1}}}"###
assert_error!(
runner,
"mutation { deleteOneParent(where: { id: 1 }) { id }}",
2014,
"The change you are trying to make would violate the required relation 'ChildToParent' between the `Child` and `Parent` models."
);

insta::assert_snapshot!(
run_query!(&runner, r#"query { findManyChild { parent_id }}"#),
@r###"{"data":{"findManyChild":[{"parent_id":1}]}}"###
assert_error!(
runner,
"mutation { deleteManyParent(where: { id: 1 }) { count }}",
2014,
"The change you are trying to make would violate the required relation 'ChildToParent' between the `Child` and `Parent` models."
);

Ok(())
Expand Down Expand Up @@ -145,9 +149,11 @@ mod one2one_opt {
@r###"{"data":{"createOneParent":{"id":1}}}"###
);

insta::assert_snapshot!(
run_query!(&runner, r#"mutation { deleteOneParent(where: { id: 1 }) { id }}"#),
@r###"{"data":{"deleteOneParent":{"id":1}}}"###
assert_error!(
runner,
"mutation { deleteOneParent(where: { id: 1 }) { id }}",
2014,
"The change you are trying to make would violate the required relation 'ChildToParent' between the `Child` and `Parent` models."
);

insta::assert_snapshot!(
Expand Down Expand Up @@ -237,9 +243,11 @@ mod one2many_req {
@r###"{"data":{"createOneParent":{"id":1}}}"###
);

insta::assert_snapshot!(
run_query!(&runner, r#"mutation { deleteOneParent(where: { id: 1 }) { id }}"#),
@r###"{"data":{"deleteOneParent":{"id":1}}}"###
assert_error!(
runner,
"mutation { deleteOneParent(where: { id: 1 }) { id }}",
2014,
"The change you are trying to make would violate the required relation 'ChildToParent' between the `Child` and `Parent` models."
);

insta::assert_snapshot!(
Expand Down Expand Up @@ -329,9 +337,11 @@ mod one2many_opt {
@r###"{"data":{"createOneParent":{"id":1}}}"###
);

insta::assert_snapshot!(
run_query!(&runner, r#"mutation { deleteOneParent(where: { id: 1 }) { id }}"#),
@r###"{"data":{"deleteOneParent":{"id":1}}}"###
assert_error!(
runner,
"mutation { deleteOneParent(where: { id: 1 }) { id }}",
2014,
"The change you are trying to make would violate the required relation 'ChildToParent' between the `Child` and `Parent` models."
);

insta::assert_snapshot!(
Expand Down
Expand Up @@ -47,17 +47,19 @@ mod one2one_req {
}

/// Updating the parent leaves the data in a integrity-violating state.
/// All supported dbs except mongo throw key violations.
/// All supported dbs throw key constraint violations.
#[connector_test(only(MongoDb))]
jkomyno marked this conversation as resolved.
Show resolved Hide resolved
async fn update_parent_violation(runner: Runner) -> TestResult<()> {
insta::assert_snapshot!(
run_query!(&runner, r#"mutation { createOneParent(data: { id: 1, uniq: "1", child: { create: { id: 1 }}}) { id }}"#),
@r###"{"data":{"createOneParent":{"id":1}}}"###
);

insta::assert_snapshot!(
run_query!(&runner, r#"mutation { updateOneParent(where: { id: 1 }, data: { uniq: "u1" }) { id }}"#),
@r###"{"data":{"updateOneParent":{"id":1}}}"###
assert_error!(
&runner,
r#"mutation { updateOneParent(where: { id: 1 }, data: { uniq: "u1" }) { id }}"#,
2014,
"The change you are trying to make would violate the required relation 'ChildToParent' between the `Child` and `Parent` models."
);

insta::assert_snapshot!(
Expand All @@ -69,17 +71,19 @@ mod one2one_req {
}

/// Updating the parent leaves the data in a integrity-violating state.
/// All supported dbs except mongo throw key violations.
/// All supported dbs throw key constraint violations.
#[connector_test(only(MongoDb))]
jkomyno marked this conversation as resolved.
Show resolved Hide resolved
async fn update_many_parent_violation(runner: Runner) -> TestResult<()> {
insta::assert_snapshot!(
run_query!(&runner, r#"mutation { createOneParent(data: { id: 1, uniq: "1", child: { create: { id: 1 }}}) { id }}"#),
@r###"{"data":{"createOneParent":{"id":1}}}"###
);

insta::assert_snapshot!(
run_query!(&runner, r#"mutation { updateManyParent(data: { uniq: "u1" }) { count }}"#),
@r###"{"data":{"updateManyParent":{"count":1}}}"###
assert_error!(
&runner,
r#"mutation { updateManyParent(data: { uniq: "u1" }) { count }}"#,
2014,
"The change you are trying to make would violate the required relation 'ChildToParent' between the `Child` and `Parent` models."
);

insta::assert_snapshot!(
Expand All @@ -91,17 +95,19 @@ mod one2one_req {
}

/// Updating the parent leaves the data in a integrity-violating state.
/// All supported dbs except mongo throw key violations.
/// All supported dbs throw key constraint violations.
#[connector_test(only(MongoDb))]
jkomyno marked this conversation as resolved.
Show resolved Hide resolved
async fn upsert_parent_violation(runner: Runner) -> TestResult<()> {
insta::assert_snapshot!(
run_query!(&runner, r#"mutation { createOneParent(data: { id: 1, uniq: "1", child: { create: { id: 1 }}}) { id }}"#),
@r###"{"data":{"createOneParent":{"id":1}}}"###
);

insta::assert_snapshot!(
run_query!(&runner, r#"mutation { upsertOneParent(where: { id: 1 }, update: { uniq: "u1" }, create: { id: 1, uniq: "1", child: { create: { id: 1 }}}) { id }}"#),
@r###"{"data":{"upsertOneParent":{"id":1}}}"###
assert_error!(
&runner,
r#"mutation { upsertOneParent(where: { id: 1 }, update: { uniq: "u1" }, create: { id: 1, uniq: "1", child: { create: { id: 1 }}}) { id }}"#,
2014,
"The change you are trying to make would violate the required relation 'ChildToParent' between the `Child` and `Parent` models."
);

insta::assert_snapshot!(
Expand Down Expand Up @@ -201,17 +207,19 @@ mod one2one_opt {
}

/// Updating the parent leaves the data in a integrity-violating state.
/// All supported dbs except mongo throw key violations.
/// All supported dbs throw key constraint violations.
#[connector_test(only(MongoDb))]
jkomyno marked this conversation as resolved.
Show resolved Hide resolved
async fn update_parent_violation(runner: Runner) -> TestResult<()> {
insta::assert_snapshot!(
run_query!(&runner, r#"mutation { createOneParent(data: { id: 1, uniq: "1", child: { create: { id: 1 }}}) { id }}"#),
@r###"{"data":{"createOneParent":{"id":1}}}"###
);

insta::assert_snapshot!(
run_query!(&runner, r#"mutation { updateOneParent(where: { id: 1 }, data: { uniq: "u1" }) { id }}"#),
@r###"{"data":{"updateOneParent":{"id":1}}}"###
assert_error!(
&runner,
r#"mutation { updateOneParent(where: { id: 1 }, data: { uniq: "u1" }) { id }}"#,
2014,
"The change you are trying to make would violate the required relation 'ChildToParent' between the `Child` and `Parent` models."
);

insta::assert_snapshot!(
Expand All @@ -223,17 +231,19 @@ mod one2one_opt {
}

/// Updating the parent leaves the data in a integrity-violating state.
/// All supported dbs except mongo throw key violations.
/// All supported dbs throw key constraint violations.
#[connector_test(only(MongoDb))]
jkomyno marked this conversation as resolved.
Show resolved Hide resolved
async fn update_many_parent_violation(runner: Runner) -> TestResult<()> {
insta::assert_snapshot!(
run_query!(&runner, r#"mutation { createOneParent(data: { id: 1, uniq: "1", child: { create: { id: 1 }}}) { id }}"#),
@r###"{"data":{"createOneParent":{"id":1}}}"###
);

insta::assert_snapshot!(
run_query!(&runner, r#"mutation { updateManyParent(data: { uniq: "u1" }) { count }}"#),
@r###"{"data":{"updateManyParent":{"count":1}}}"###
assert_error!(
&runner,
r#"mutation { updateManyParent(data: { uniq: "u1" }) { count }}"#,
2014,
"The change you are trying to make would violate the required relation 'ChildToParent' between the `Child` and `Parent` models."
);

insta::assert_snapshot!(
Expand All @@ -245,17 +255,19 @@ mod one2one_opt {
}

/// Updating the parent leaves the data in a integrity-violating state.
/// All supported dbs except mongo throw key violations.
/// All supported dbs throw key constraint violations.
#[connector_test(only(MongoDb))]
jkomyno marked this conversation as resolved.
Show resolved Hide resolved
async fn upsert_parent_violation(runner: Runner) -> TestResult<()> {
insta::assert_snapshot!(
run_query!(&runner, r#"mutation { createOneParent(data: { id: 1, uniq: "1", child: { create: { id: 1 }}}) { id }}"#),
@r###"{"data":{"createOneParent":{"id":1}}}"###
);

insta::assert_snapshot!(
run_query!(&runner, r#"mutation { upsertOneParent(where: { id: 1 }, update: { uniq: "u1" }, create: { id: 1, uniq: "1", child: { create: { id: 1 }}}) { id }}"#),
@r###"{"data":{"upsertOneParent":{"id":1}}}"###
assert_error!(
&runner,
r#"mutation { upsertOneParent(where: { id: 1 }, update: { uniq: "u1" }, create: { id: 1, uniq: "1", child: { create: { id: 1 }}}) { id }}"#,
2014,
"The change you are trying to make would violate the required relation 'ChildToParent' between the `Child` and `Parent` models."
);

insta::assert_snapshot!(
Expand Down Expand Up @@ -346,9 +358,11 @@ mod one2many_req {
@r###"{"data":{"createOneParent":{"id":1}}}"###
);

insta::assert_snapshot!(
run_query!(&runner, r#"mutation { updateOneParent(where: { id: 1 }, data: { uniq: "u1" }) { id }}"#),
@r###"{"data":{"updateOneParent":{"id":1}}}"###
assert_error!(
&runner,
r#"mutation { updateOneParent(where: { id: 1 }, data: { uniq: "u1" }) { id }}"#,
2014,
"The change you are trying to make would violate the required relation 'ChildToParent' between the `Child` and `Parent` models."
);

insta::assert_snapshot!(
Expand All @@ -360,17 +374,19 @@ mod one2many_req {
}

/// Updating the parent leaves the data in a integrity-violating state.
/// All supported dbs except mongo throw key violations.
/// All supported dbs throw key constraint violations.
#[connector_test(only(MongoDb))]
jkomyno marked this conversation as resolved.
Show resolved Hide resolved
async fn update_many_parent_violation(runner: Runner) -> TestResult<()> {
insta::assert_snapshot!(
run_query!(&runner, r#"mutation { createOneParent(data: { id: 1, uniq: "1", children: { create: { id: 1 }}}) { id }}"#),
@r###"{"data":{"createOneParent":{"id":1}}}"###
);

insta::assert_snapshot!(
run_query!(&runner, r#"mutation { updateManyParent(data: { uniq: "u1" }) { count }}"#),
@r###"{"data":{"updateManyParent":{"count":1}}}"###
assert_error!(
&runner,
r#"mutation { updateManyParent(data: { uniq: "u1" }) { count }}"#,
2014,
"The change you are trying to make would violate the required relation 'ChildToParent' between the `Child` and `Parent` models."
);

insta::assert_snapshot!(
Expand All @@ -382,17 +398,19 @@ mod one2many_req {
}

/// Updating the parent leaves the data in a integrity-violating state.
/// All supported dbs except mongo throw key violations.
/// All supported dbs throw key constraint violations.
#[connector_test(only(MongoDb))]
jkomyno marked this conversation as resolved.
Show resolved Hide resolved
async fn upsert_parent_violation(runner: Runner) -> TestResult<()> {
insta::assert_snapshot!(
run_query!(&runner, r#"mutation { createOneParent(data: { id: 1, uniq: "1", children: { create: { id: 1 }}}) { id }}"#),
@r###"{"data":{"createOneParent":{"id":1}}}"###
);

insta::assert_snapshot!(
run_query!(&runner, r#"mutation { upsertOneParent(where: { id: 1 }, update: { uniq: "u1" }, create: { id: 1, uniq: "1", children: { create: { id: 1 }}}) { id }}"#),
@r###"{"data":{"upsertOneParent":{"id":1}}}"###
assert_error!(
&runner,
r#"mutation { upsertOneParent(where: { id: 1 }, update: { uniq: "u1" }, create: { id: 1, uniq: "1", children: { create: { id: 1 }}}) { id }}"#,
2014,
"The change you are trying to make would violate the required relation 'ChildToParent' between the `Child` and `Parent` models."
);

insta::assert_snapshot!(
Expand Down Expand Up @@ -483,9 +501,11 @@ mod one2many_opt {
@r###"{"data":{"createOneParent":{"id":1}}}"###
);

insta::assert_snapshot!(
run_query!(&runner, r#"mutation { updateOneParent(where: { id: 1 }, data: { uniq: "u1" }) { id }}"#),
@r###"{"data":{"updateOneParent":{"id":1}}}"###
assert_error!(
&runner,
r#"mutation { updateOneParent(where: { id: 1 }, data: { uniq: "u1" }) { id }}"#,
2014,
"The change you are trying to make would violate the required relation 'ChildToParent' between the `Child` and `Parent` models."
);

insta::assert_snapshot!(
Expand All @@ -497,17 +517,19 @@ mod one2many_opt {
}

/// Updating the parent leaves the data in a integrity-violating state.
/// All supported dbs except mongo throw key violations.
/// All supported dbs throw key constraint violations.
#[connector_test(only(MongoDb))]
jkomyno marked this conversation as resolved.
Show resolved Hide resolved
async fn update_many_parent_violation(runner: Runner) -> TestResult<()> {
insta::assert_snapshot!(
run_query!(&runner, r#"mutation { createOneParent(data: { id: 1, uniq: "1", children: { create: { id: 1 }}}) { id }}"#),
@r###"{"data":{"createOneParent":{"id":1}}}"###
);

insta::assert_snapshot!(
run_query!(&runner, r#"mutation { updateManyParent(data: { uniq: "u1" }) { count }}"#),
@r###"{"data":{"updateManyParent":{"count":1}}}"###
assert_error!(
&runner,
r#"mutation { updateManyParent(data: { uniq: "u1" }) { count }}"#,
2014,
"The change you are trying to make would violate the required relation 'ChildToParent' between the `Child` and `Parent` models."
);

insta::assert_snapshot!(
Expand All @@ -519,17 +541,19 @@ mod one2many_opt {
}

/// Updating the parent leaves the data in a integrity-violating state.
/// All supported dbs except mongo throw key violations.
/// All supported dbs throw key constraint violations.
#[connector_test(only(MongoDb))]
jkomyno marked this conversation as resolved.
Show resolved Hide resolved
async fn upsert_parent_violation(runner: Runner) -> TestResult<()> {
insta::assert_snapshot!(
run_query!(&runner, r#"mutation { createOneParent(data: { id: 1, uniq: "1", children: { create: { id: 1 }}}) { id }}"#),
@r###"{"data":{"createOneParent":{"id":1}}}"###
);

insta::assert_snapshot!(
run_query!(&runner, r#"mutation { upsertOneParent(where: { id: 1 }, update: { uniq: "u1" }, create: { id: 1, uniq: "1", children: { create: { id: 1 }}}) { id }}"#),
@r###"{"data":{"upsertOneParent":{"id":1}}}"###
assert_error!(
&runner,
r#"mutation { upsertOneParent(where: { id: 1 }, update: { uniq: "u1" }, create: { id: 1, uniq: "1", children: { create: { id: 1 }}}) { id }}"#,
2014,
"The change you are trying to make would violate the required relation 'ChildToParent' between the `Child` and `Parent` models."
);

insta::assert_snapshot!(
Expand Down
11 changes: 9 additions & 2 deletions query-engine/prisma-models/src/builders/internal_dm_builder.rs
Expand Up @@ -8,7 +8,10 @@ use crate::{
IndexType, InlineRelation, InternalEnum, InternalEnumValue, RelationLinkManifestation, RelationSide, RelationTable,
TypeIdentifier,
};
use psl::dml::{self, CompositeTypeFieldType, Datamodel, Ignorable, WithDatabaseName};
use psl::{
datamodel_connector::RelationMode,
dml::{self, CompositeTypeFieldType, Datamodel, Ignorable, WithDatabaseName},
};

pub(crate) fn model_builders(
datamodel: &Datamodel,
Expand Down Expand Up @@ -136,7 +139,10 @@ fn composite_field_builders(datamodel: &Datamodel, composite: &dml::CompositeTyp
.collect()
}

pub(crate) fn relation_builders(placeholders: &[RelationPlaceholder]) -> Vec<RelationBuilder> {
pub(crate) fn relation_builders(
placeholders: &[RelationPlaceholder],
relation_mode: RelationMode,
) -> Vec<RelationBuilder> {
placeholders
.iter()
.filter(|r| r.model_a.is_relation_supported(&r.field_a) && r.model_b.is_relation_supported(&r.field_b))
Expand All @@ -145,6 +151,7 @@ pub(crate) fn relation_builders(placeholders: &[RelationPlaceholder]) -> Vec<Rel
manifestation: r.manifestation(),
model_a_name: r.model_a.name.clone(),
model_b_name: r.model_b.name.clone(),
relation_mode,
})
.collect()
}
Expand Down