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

SQL Server cycle detection doesn't detect multiple paths correctly #8969

Closed
pimeys opened this issue Aug 27, 2021 · 0 comments · Fixed by prisma/prisma-engines#2192
Closed
Assignees
Labels
bug/2-confirmed Bug has been reproduced and confirmed. kind/bug A reported bug. tech/engines/datamodel Issue about parsing/validation/rendering of the Prisma schema topic: sql server Microsoft SQL Server

Comments

@pimeys
Copy link
Contributor

pimeys commented Aug 27, 2021

SQL Server and multiple cascade paths

Our original implementation of cycle detection has a problem: it only detects cycles, never multiple cascading paths correctly. By accident, all tests were green, until our introspection CI catched an issue that should validate and we can safely migrate to the database.

What are multiple cascading paths

A simple example from our current test setup demonstrates a data model that should not pass the validation:

model A {
  id     Int  @id @default(autoincrement())
  bId    Int
  b      B    @relation(fields: [bId], references: [id])
  cs     C[]
}

model B {
  id     Int  @id @default(autoincrement())
  as     A[]
  cs     C[]
}

model C {
  id     Int  @id @default(autoincrement())
  aId    Int
  bId    Int
  a      A    @relation(fields: [aId], references: [id])
  b      B    @relation(fields: [bId], references: [id])
}

Originally, our setup validated this by detecting a cycle: A.b -> B.cs -> C.a and so on. This is wrong. The actual validation error in the data model goes in two paths: C -> A -> B and C -> B.

By accident, our cycle detection algorithm validated this, but by looking into a more complex example, we see what is wrong with the current algorithm:

model order_items {
  order_id   Int
  item_id    Int
  product_id Int
  orders     orders   @relation(fields: [order_id], references: [order_id], onDelete: Cascade)
  products   products @relation(fields: [product_id], references: [product_id], onDelete: Cascade)

  @@id([order_id, item_id])
}

model orders {
  order_id      Int           @id @default(autoincrement())
  store_id      Int
  stores        stores        @relation(fields: [store_id], references: [store_id], onDelete: Cascade)
  order_items   order_items[]
}

model products {
  product_id   Int           @id @default(autoincrement())
  brand_id     Int
  order_items  order_items[]
  stocks       stocks[]
}

model stocks {
  store_id   Int
  product_id Int
  products   products @relation(fields: [product_id], references: [product_id], onDelete: Cascade)
  stores     stores   @relation(fields: [store_id], references: [store_id], onDelete: Cascade)

  @@id([store_id, product_id])
}

model stores {
  store_id   Int      @id @default(autoincrement())
  orders     orders[]
  stocks     stocks[]
}

Our current validation finds a cycle in it, as the algorithm is written:

order_items.orders → orders.stores → stores.stocks → stocks.products → products.order_items

Although when turning off the validation, SQL Server accepts the migration!

The first step is to stop jumping over back-relations and only look for @relation arguments with fields, references and (maybe implicitly) refererential actions defined. From this data model we can find several paths:

  • order_items -> orders -> stores
  • order_items -> products

From order_items there are no cascading paths.

  • stocks -> products
  • stocks -> stores

Again, no cascading paths.

From this point on we're done and we don't need to be looking into other paths.

@pimeys pimeys added the kind/bug A reported bug. label Aug 27, 2021
@pimeys pimeys added this to the 2.31.0 / 3.0.x milestone Aug 27, 2021
@pimeys pimeys added topic: sql server Microsoft SQL Server bug/2-confirmed Bug has been reproduced and confirmed. tech/engines/datamodel Issue about parsing/validation/rendering of the Prisma schema labels Aug 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug/2-confirmed Bug has been reproduced and confirmed. kind/bug A reported bug. tech/engines/datamodel Issue about parsing/validation/rendering of the Prisma schema topic: sql server Microsoft SQL Server
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants