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

feat(psl): polish validation warnings before relationMode GA #3446

Merged
merged 8 commits into from
Nov 27, 2022
1 change: 1 addition & 0 deletions Cargo.lock

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

Expand Up @@ -58,13 +58,13 @@ async fn introspect_set_default_should_warn(api: &TestApi) -> TestResult {
.warnings_to_pretty_string("schema.prisma", &schema.db.source());

let expected_validation = expect![[r#"
warning: Using SetDefault on MySQL may yield to unexpected results, as the database will silently change the referential action to `NoAction`.
warning: MySQL does not actually support the `SetDefault` referential action, so using it may result in unexpected errors. Read more at https://pris.ly/d/mysql-set-default 
--> schema.prisma:14
 | 
13 |  userId Int? @default(3)
14 |  SomeUser SomeUser? @relation(fields: [userId], references: [id], onDelete: SetDefault, onUpdate: SetDefault)
 | 
warning: Using SetDefault on MySQL may yield to unexpected results, as the database will silently change the referential action to `NoAction`.
warning: MySQL does not actually support the `SetDefault` referential action, so using it may result in unexpected errors. Read more at https://pris.ly/d/mysql-set-default 
--> schema.prisma:14
 | 
13 |  userId Int? @default(3)
Expand Down
1 change: 1 addition & 0 deletions psl/builtin-connectors/Cargo.toml
Expand Up @@ -9,6 +9,7 @@ psl-core = { path = "../psl-core" }
connection-string = "0.1"
either = "1.6.1"
enumflags2 = "0.7"
indoc = "1"
lsp-types = "0.91.1"
once_cell = "1.3"
regex = "1"
@@ -1,3 +1,4 @@
use indoc::formatdoc;
use psl_core::diagnostics::{DatamodelWarning, Span};
use psl_core::parser_database::ast::WithSpan;
use psl_core::parser_database::ReferentialAction;
Expand Down Expand Up @@ -106,12 +107,14 @@ pub(crate) fn uses_native_referential_action_set_default(
};

let warning_msg = || {
format!(
"Using {set_default} on {connector} may yield to unexpected results, as the database will silently change the referential action to `{no_action}`.",
formatdoc!(
r#"
{connector_name} does not actually support the `{set_default}` referential action, so using it may result in unexpected errors.
Read more at https://pris.ly/d/mysql-set-default
"#,
connector_name = connector.name(),
set_default = ReferentialAction::SetDefault.as_str(),
connector = connector.name(),
no_action = ReferentialAction::NoAction.as_str(),
)
).replace('\n', " ")
};

if let Some(ReferentialAction::SetDefault) = field.explicit_on_delete() {
Expand Down
13 changes: 8 additions & 5 deletions psl/diagnostics/src/warning.rs
Expand Up @@ -28,12 +28,15 @@ impl DatamodelWarning {
}

pub fn new_missing_index_on_emulated_relation(span: Span) -> DatamodelWarning {
let message = indoc! {
r#"With `relationMode = \"prisma\"`, no foreign keys are used, so relation fields will not benefit from the index usually created by the relational database under the hood.
let message = indoc!(
r#"
With `relationMode = "prisma"`, no foreign keys are used, so relation fields will not benefit from the index usually created by the relational database under the hood.
This can lead to poor performance when querying these fields. We recommend adding an index manually.
Learn more at https://pris.ly/d/relation-mode#indexes"#
};
Self::new(message.to_owned(), span)
Learn more at https://pris.ly/d/relation-mode-prisma-indexes"
"#,
)
.replace('\n', " ");
Self::new(message, span)
}

/// The user-facing warning message.
Expand Down
Expand Up @@ -554,11 +554,14 @@ pub(crate) fn required_relation_cannot_use_set_null(relation: InlineRelationWalk
{
// the database allows SetNull on non-nullable fields, we add a validation warning to avoid breaking changes
let warning_template = |referential_action_type: &str| {
let set_null = ReferentialAction::SetNull.as_str();
let msg = formatdoc! {r#"
The `{referential_action_type}` referential action of a relation should not be set to `{set_null}` when a referenced field is required. We recommend either to choose another referential action, or to make the referenced fields optional. Read more at https://pris.ly/d/postgres-set-null
"#};
msg
formatdoc!(
r#"
The `{referential_action_type}` referential action of a relation should not be set to `{set_null}` when a referenced field is required.
We recommend either to choose another referential action, or to make the referenced fields optional.
Read more at https://pris.ly/d/postgres-set-null
"#,
set_null = ReferentialAction::SetNull.as_str(),
).replace('\n', " ")
};

if let Some(ReferentialAction::SetNull) = forward.explicit_on_delete() {
Expand Down
Expand Up @@ -16,9 +16,7 @@ model Post {
userId Int
user SomeUser @relation(fields: [userId], references: [id])
}
// warning: With `relationMode = \"prisma\"`, no foreign keys are used, so relation fields will not benefit from the index usually created by the relational database under the hood.
// This can lead to poor performance when querying these fields. We recommend adding an index manually.
// Learn more at https://pris.ly/d/relation-mode#indexes
// warning: With `relationMode = "prisma"`, no foreign keys are used, so relation fields will not benefit from the index usually created by the relational database under the hood. This can lead to poor performance when querying these fields. We recommend adding an index manually. Learn more at https://pris.ly/d/relation-mode-prisma-indexes" 
// --> schema.prisma:17
//  | 
// 16 |  userId Int
Expand Down
Expand Up @@ -24,9 +24,7 @@ model Post {

@@index([userIdA, userIdB])
}
// warning: With `relationMode = \"prisma\"`, no foreign keys are used, so relation fields will not benefit from the index usually created by the relational database under the hood.
// This can lead to poor performance when querying these fields. We recommend adding an index manually.
// Learn more at https://pris.ly/d/relation-mode#indexes
// warning: With `relationMode = "prisma"`, no foreign keys are used, so relation fields will not benefit from the index usually created by the relational database under the hood. This can lead to poor performance when querying these fields. We recommend adding an index manually. Learn more at https://pris.ly/d/relation-mode-prisma-indexes" 
// --> schema.prisma:23
//  | 
// 22 |  userIdC Int
Expand Down
Expand Up @@ -24,9 +24,7 @@ model Post {

@@index([userIdB, userIdC])
}
// warning: With `relationMode = \"prisma\"`, no foreign keys are used, so relation fields will not benefit from the index usually created by the relational database under the hood.
// This can lead to poor performance when querying these fields. We recommend adding an index manually.
// Learn more at https://pris.ly/d/relation-mode#indexes
// warning: With `relationMode = "prisma"`, no foreign keys are used, so relation fields will not benefit from the index usually created by the relational database under the hood. This can lead to poor performance when querying these fields. We recommend adding an index manually. Learn more at https://pris.ly/d/relation-mode-prisma-indexes" 
// --> schema.prisma:23
//  | 
// 22 |  userIdC Int
Expand Down
Expand Up @@ -24,9 +24,7 @@ model Post {

@@unique([userIdA, userIdB])
}
// warning: With `relationMode = \"prisma\"`, no foreign keys are used, so relation fields will not benefit from the index usually created by the relational database under the hood.
// This can lead to poor performance when querying these fields. We recommend adding an index manually.
// Learn more at https://pris.ly/d/relation-mode#indexes
// warning: With `relationMode = "prisma"`, no foreign keys are used, so relation fields will not benefit from the index usually created by the relational database under the hood. This can lead to poor performance when querying these fields. We recommend adding an index manually. Learn more at https://pris.ly/d/relation-mode-prisma-indexes" 
// --> schema.prisma:23
//  | 
// 22 |  userIdC Int @unique
Expand Down
Expand Up @@ -22,9 +22,7 @@ model Post {
userIdC Int
user SomeUser @relation(fields: [userIdA, userIdB, userIdC], references: [idA, idB, idC])
}
// warning: With `relationMode = \"prisma\"`, no foreign keys are used, so relation fields will not benefit from the index usually created by the relational database under the hood.
// This can lead to poor performance when querying these fields. We recommend adding an index manually.
// Learn more at https://pris.ly/d/relation-mode#indexes
// warning: With `relationMode = "prisma"`, no foreign keys are used, so relation fields will not benefit from the index usually created by the relational database under the hood. This can lead to poor performance when querying these fields. We recommend adding an index manually. Learn more at https://pris.ly/d/relation-mode-prisma-indexes" 
// --> schema.prisma:23
//  | 
// 22 |  userIdC Int
Expand Down
Expand Up @@ -18,9 +18,7 @@ model B {
aId Int? @default(3)
a A? @relation(fields: [aId], references: [id], onUpdate: SetDefault, onDelete: SetDefault)
}
// warning: With `relationMode = \"prisma\"`, no foreign keys are used, so relation fields will not benefit from the index usually created by the relational database under the hood.
// This can lead to poor performance when querying these fields. We recommend adding an index manually.
// Learn more at https://pris.ly/d/relation-mode#indexes
// warning: With `relationMode = "prisma"`, no foreign keys are used, so relation fields will not benefit from the index usually created by the relational database under the hood. This can lead to poor performance when querying these fields. We recommend adding an index manually. Learn more at https://pris.ly/d/relation-mode-prisma-indexes" 
// --> schema.prisma:19
//  | 
// 18 |  aId Int? @default(3)
Expand Down
4 changes: 2 additions & 2 deletions psl/psl/tests/validation/mysql/set_default_warning.prisma
Expand Up @@ -13,13 +13,13 @@ model B {
aId Int? @default(3)
a A? @relation(fields: [aId], references: [id], onUpdate: SetDefault, onDelete: SetDefault)
}
// warning: Using SetDefault on MySQL may yield to unexpected results, as the database will silently change the referential action to `NoAction`.
// warning: MySQL does not actually support the `SetDefault` referential action, so using it may result in unexpected errors. Read more at https://pris.ly/d/mysql-set-default 
// --> schema.prisma:14
//  | 
// 13 |  aId Int? @default(3)
// 14 |  a A? @relation(fields: [aId], references: [id], onUpdate: SetDefault, onDelete: SetDefault)
//  | 
// warning: Using SetDefault on MySQL may yield to unexpected results, as the database will silently change the referential action to `NoAction`.
// warning: MySQL does not actually support the `SetDefault` referential action, so using it may result in unexpected errors. Read more at https://pris.ly/d/mysql-set-default 
// --> schema.prisma:14
//  | 
// 13 |  aId Int? @default(3)
Expand Down
Expand Up @@ -18,13 +18,13 @@ model B {
aId Int? @default(3)
a A? @relation(fields: [aId], references: [id], onUpdate: SetDefault, onDelete: SetDefault)
}
// warning: Using SetDefault on MySQL may yield to unexpected results, as the database will silently change the referential action to `NoAction`.
// warning: MySQL does not actually support the `SetDefault` referential action, so using it may result in unexpected errors. Read more at https://pris.ly/d/mysql-set-default 
// --> schema.prisma:19
//  | 
// 18 |  aId Int? @default(3)
// 19 |  a A? @relation(fields: [aId], references: [id], onUpdate: SetDefault, onDelete: SetDefault)
//  | 
// warning: Using SetDefault on MySQL may yield to unexpected results, as the database will silently change the referential action to `NoAction`.
// warning: MySQL does not actually support the `SetDefault` referential action, so using it may result in unexpected errors. Read more at https://pris.ly/d/mysql-set-default 
// --> schema.prisma:19
//  | 
// 18 |  aId Int? @default(3)
Expand Down
Expand Up @@ -19,16 +19,14 @@ model Profile {

@@unique([user_id, user_ref])
}
// warning: The `onDelete` referential action of a relation should not be set to `SetNull` when a referenced field is required. We recommend either to choose another referential action, or to make the referenced fields optional. Read more at https://pris.ly/d/postgres-set-null
// 
// warning: The `onDelete` referential action of a relation should not be set to `SetNull` when a referenced field is required. We recommend either to choose another referential action, or to make the referenced fields optional. Read more at https://pris.ly/d/postgres-set-null 
// --> schema.prisma:16
//  | 
// 15 |  id Int @id
// 16 |  user SomeUser? @relation(fields: [user_id, user_ref], references: [id, ref], onUpdate: SetNull, onDelete: SetNull)
// 17 |  user_id Int?
//  | 
// warning: The `onUpdate` referential action of a relation should not be set to `SetNull` when a referenced field is required. We recommend either to choose another referential action, or to make the referenced fields optional. Read more at https://pris.ly/d/postgres-set-null
// 
// warning: The `onUpdate` referential action of a relation should not be set to `SetNull` when a referenced field is required. We recommend either to choose another referential action, or to make the referenced fields optional. Read more at https://pris.ly/d/postgres-set-null 
// --> schema.prisma:16
//  | 
// 15 |  id Int @id
Expand Down
Expand Up @@ -13,16 +13,14 @@ model Profile {
user SomeUser? @relation(fields: [user_id], references: [id], onUpdate: SetNull, onDelete: SetNull)
user_id Int @unique
}
// warning: The `onDelete` referential action of a relation should not be set to `SetNull` when a referenced field is required. We recommend either to choose another referential action, or to make the referenced fields optional. Read more at https://pris.ly/d/postgres-set-null
// 
// warning: The `onDelete` referential action of a relation should not be set to `SetNull` when a referenced field is required. We recommend either to choose another referential action, or to make the referenced fields optional. Read more at https://pris.ly/d/postgres-set-null 
// --> schema.prisma:13
//  | 
// 12 |  id Int @id
// 13 |  user SomeUser? @relation(fields: [user_id], references: [id], onUpdate: SetNull, onDelete: SetNull)
// 14 |  user_id Int @unique
//  | 
// warning: The `onUpdate` referential action of a relation should not be set to `SetNull` when a referenced field is required. We recommend either to choose another referential action, or to make the referenced fields optional. Read more at https://pris.ly/d/postgres-set-null
// 
// warning: The `onUpdate` referential action of a relation should not be set to `SetNull` when a referenced field is required. We recommend either to choose another referential action, or to make the referenced fields optional. Read more at https://pris.ly/d/postgres-set-null 
// --> schema.prisma:13
//  | 
// 12 |  id Int @id
Expand Down