Skip to content

Commit

Permalink
Fix relation_fields validation to accept primary key indexes (#4376)
Browse files Browse the repository at this point in the history
* Fix `relation_fields` validation to accept primary key indexes

This resolves prisma/language-tools#1387

---------

Co-authored-by: Jan Piotrowski <piotrowski+github@gmail.com>
  • Loading branch information
yubrot and janpio committed Mar 19, 2024
1 parent 93f79ec commit 973c18a
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -267,23 +267,27 @@ pub(super) fn validate_missing_relation_indexes(relation_field: RelationFieldWal
// Considers all groups of indexes explicitly declared in the given model.
// An index group can be:
// - a singleton (@unique or @id)
// - an ordered set (@@unique or @@index)
let index_field_groups = model.indexes();

let referencing_fields_appear_in_index = index_field_groups
.map(|index_walker| index_walker.fields().map(|index| index.field_id()))
.any(|index_fields_it| {
let fields_it = referencing_fields_it.clone();
is_leftwise_included_it(fields_it, index_fields_it)
});

if !referencing_fields_appear_in_index {
let ast_field = relation_field.ast_field();
let span = ast_field
.span_for_attribute("relation")
.unwrap_or_else(|| ast_field.span());
ctx.push_warning(DatamodelWarning::new_missing_index_on_emulated_relation(span));
// - an ordered set (@@unique, @@index, or @@id)
for index_walker in model.indexes() {
let index_fields_it = index_walker.fields().map(|col| col.field_id());
let referencing_fields_it = referencing_fields_it.clone();
if is_leftwise_included_it(referencing_fields_it, index_fields_it) {
return;
}
}

if let Some(primary_key_walker) = model.primary_key() {
let primary_key_fields_it = primary_key_walker.fields().map(|col| col.field_id());
if is_leftwise_included_it(referencing_fields_it, primary_key_fields_it) {
return;
}
}

let ast_field = relation_field.ast_field();
let span = ast_field
.span_for_attribute("relation")
.unwrap_or_else(|| ast_field.span());
ctx.push_warning(DatamodelWarning::new_missing_index_on_emulated_relation(span));
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// no relation index validation warning on relationMode = "prisma" when a referenced field is already in @@id.

datasource db {
provider = "mysql"
url = env("TEST_DATABASE_URL")
relationMode = "prisma"
}

model SomeUser {
id Int @id
profile Profile?
}

model Profile {
id Int
user SomeUser? @relation(fields: [id], references: [id])
@@id([id])
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// no relation index validation warning on relationMode = "prisma" when a referenced field is already in @id.

datasource db {
provider = "mysql"
url = env("TEST_DATABASE_URL")
relationMode = "prisma"
}

model SomeUser {
id Int @id
profile Profile?
}

model Profile {
id Int @id
user SomeUser? @relation(fields: [id], references: [id])
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// add missing relation index validation warning on relationMode = "prisma".

datasource db {
provider = "mysql"
url = env("TEST_DATABASE_URL")
relationMode = "prisma"
}

model SomeUser {
idA Int
idB Int
idC Int
posts Post[]
@@id([idA, idB, idC])
}

model Post {
userIdA Int @unique
userIdB Int
userIdC Int @unique
user SomeUser @relation(fields: [userIdA, userIdB, userIdC], references: [idA, idB, idC])
@@id([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-prisma-indexes" 
// --> schema.prisma:22
//  | 
// 21 |  userIdC Int @unique
// 22 |  user SomeUser @relation(fields: [userIdA, userIdB, userIdC], references: [idA, idB, idC])
//  | 

0 comments on commit 973c18a

Please sign in to comment.