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

Too many records are returned in 4.11.0 when using nested include and @unique field is null #18351

Closed
johanforslund opened this issue Mar 16, 2023 · 6 comments · Fixed by prisma/prisma-engines#3762
Labels
bug/2-confirmed Bug has been reproduced and confirmed. kind/bug A reported bug. team/client Issue for team Client. topic: findUnique()
Milestone

Comments

@johanforslund
Copy link

johanforslund commented Mar 16, 2023

Bug description

We have noticed a bug in Prisma since upgrading from 4.10.1 to 4.11.0. In our database we have a top-down relation between three tables (A->B->C) where the middle table (B) includes an optional @unique string. When this field is null, it seems to cause issues when Prisma joins the tables on findUnique since we get duplicate data from the bottom table (C).

The bug disappears if I move the @unique constraint from the line where the optional string is declared, and instead place it under my other @@unique constraints.

How to reproduce

Call findUnique and include two other tables where the second table includes an optional @unique constraint. The problem happens when this optional field is null.

Expected behavior

No response

Prisma information

The schema looks something like:

model A {
  a1    String
  a2    String
  bs    B[]

  @@unique([a1, a2])
}

model B {
  b1    String
  b2    String
  b3    String?   @unique
  a     A         @relation(fields: [a1, a2], references: [a1, a2])
  a1    String
  a2    String
  cs    C[]

  @@unique([b1, b2])
}

model C {
  c   String    @unique
  b    B         @relation(fields: [b1, b2], references: [b1, b2])
  b1   String
  b2   String
}

I query the data as

await prisma.a.findUnique({
      where: { a1_a2: { a1: 'a1', a2: 'a2', } },
      include: { b: { include: { c: true } } },
    });

This gives me data looking like:

{
    a1: 'a1',
    a2: 'a2',
    bs: [
      {
        b1: 'b11',
        b2: 'b21',
        b3: null,
        a1: 'a1',
        a2: 'a2',
        cs: [
          {
            c: 'c1',
            b1: 'b11',
            b2: 'b21',
          },
          {
            c: 'c2',
            b1: 'b12',
            b2: 'b22',
          },
        ],
      },
      {
        b1: 'b12',
        b2: 'b22',
        b3: null,
        a1: 'a1',
        a2: 'a2',
        cs: [
          {
            c: 'c1',
            b1: 'b11',
            b2: 'b21',
          },
          {
            c: 'c2',
            b1: 'b12',
            b2: 'b22',
          },
        ],
      },
    ],
  }

I only expect one element in each of the cs arrays.

Again, the problem is solved if I change model B to

model B {
  b1    String
  b2    String
  b3    String?
  a     A         @relation(fields: [a1, a2], references: [a1, a2])
  a1    String
  a2    String
  cs    C[]

  @@unique([b1, b2])
  @@unique([b3])
}

which makes me think that the ordering of the unique constraints matter internally in Prisma. Because it does not work if I do

  @@unique([b3])
  @@unique([b1, b2])

Environment & setup

  • OS: macOS
  • Database: PostgresQL
  • Node.js version: 18.12.1

Prisma Version

4.11.0

@johanforslund johanforslund added the kind/bug A reported bug. label Mar 16, 2023
@janpio janpio added bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. team/client Issue for team Client. topic: findUnique() labels Mar 16, 2023
@aqrln aqrln added bug/2-confirmed Bug has been reproduced and confirmed. and removed bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. labels Mar 16, 2023
@aqrln
Copy link
Member

aqrln commented Mar 16, 2023

Thanks for the report @johanforslund, I can reproduce and confirm this.

FWIW, I couldn't even recreate your db structure correctly with the latest Prisma since c2 was being connected to the wrong B, so I had to use Prisma 4.10.1 to seed the data — not sure if it has the same root cause or if it's a separate bug.

I'll bisect the commit where this starts happening and tag the appropriate people.

@aqrln
Copy link
Member

aqrln commented Mar 17, 2023

git bisect points at prisma/prisma-engines#3748, cc @tomhoule

@tomhoule
Copy link
Contributor

@Weakky could it be the prisma/prisma-engines#3762 problem?

@Weakky
Copy link
Member

Weakky commented Mar 17, 2023

@tom It does look very similar indeed!

@aqrln
Copy link
Member

aqrln commented Mar 17, 2023

FWIW, I couldn't even recreate your db structure correctly with the latest Prisma since c2 was being connected to the wrong B, so I had to use Prisma 4.10.1 to seed the data — not sure if it has the same root cause or if it's a separate bug.

I realized I had only posted about it in internal slack but not here, but yes, git bisect points at the same commit for that problem too.

As a specific example of a query that writes wrong data to the database:

  await prisma.b.update({
    where: {
      b1_b2: { b1: 'b11', b2: 'b21' },
    },
    data: {
      cs: {
        create: {
          c: 'c1',
        },
      },
    },
  })

@aqrln
Copy link
Member

aqrln commented Mar 17, 2023

@Weakky @tomhoule prisma/prisma-engines#3762 indeed fixes both issues, I just tested it.

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. team/client Issue for team Client. topic: findUnique()
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants