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

findMany with a select argument errors out with models with self-relations (sometimes) #2442

Closed
sdnts opened this issue May 14, 2020 · 4 comments
Assignees
Labels
bug/2-confirmed Bug has been reproduced and confirmed. kind/bug A reported bug. tech/engines Issue for tech Engines.
Milestone

Comments

@sdnts
Copy link
Contributor

sdnts commented May 14, 2020

Bug description

The "sometimes" is dependent on the order of scalars with respect to the self relation in the select argument. Details follow.
@kunovsky originally discovered this in their schema, I've managed to narrow down the problem.

How to reproduce

  1. In a new folder, place this schema:
generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = "postgresql://siddhant@localhost:5432/throwaway"
}

model User {
  id                  String   @default(cuid()) @id
  createdAt           DateTime @default(now())
  updatedAt           DateTime @updatedAt
  updatedBy           String?
  updatedByUser       User?    @relation("UserUpdatedByToUser", fields: [updatedBy], references: [id])
  active              Boolean  @default(true)
  email               String   @unique
  name                String?
  registryAccessToken String   @unique
  User                User[]   @relation("UserUpdatedByToUser")
}

(Note that the User field was automatically added by the VSCode extension)

  1. Run prisma migrate save --experimental && prisma migrate up --experimental
  2. In an index.ts file in the folder, paste this:
Expand
import { PrismaClient } from "@prisma/client";

const prisma = new PrismaClient();

const main = async () => {
  console.log(
    await prisma.user.create({
      data: {
        email: "test@example.com",
        registryAccessToken: "",
      },
    })
  );

  console.log(
    await prisma.user.findMany({
      first: 100,
      select: {
        updatedBy: true,
        updatedByUser: true,
        active: true,
      },
    })
};

main()
  .catch(async (e) => console.log(e))
  .finally(async () => await prisma.disconnect());
  1. Run the script using ts-node index.ts.
  2. You should see this error:
PrismaClientUnknownRequestError:
Invalid `prisma.user.findMany()` invocation in
/Users/siddhant/Code/Tests/tmp/index.ts:16:23

  12   })
  13 );
  14 console.log(
→ 15   await prisma.user.findMany(Attempted to serialize scalar 'null' with incompatible type 'String'
    at PrismaClientFetcher.message (/Users/siddhant/Code/Tests/tmp/node_modules/@prisma/client/src/runtime/getPrismaClient.ts:649:46)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)

Okay I needed you to copy & paste the script above because the issue seems to only happen when a scalar field is after the self-relation in the select argument. Yeah...

A few other things of value:

  1. If you remove the select argument entirely, then the script does not crash
  2. If you remove the select.updatedByUser argument, then the script does not crash
  3. If you remove the select.updatedBy argument, then the script does not crash
  4. If you move the select.registryAccessToken argument above the select.updatedByUser argument, then the script does not crash :P
  5. If you replace select.registryAccessToken with select.name or select.active, then the script DOES crash, albeit with a different error message (it looks similar though).
  6. This only happens with self-relations. I tried doing the same thing with two models and they behave as expected.

Here are the GraphQL queries generated:

  1. For select: { updatedBy: true, updatedByUser: true, active: true } (Crashes)
query {
  findManyUser(first: 100) {
    updatedBy
    updatedByUser {
      id
      createdAt
      updatedAt
      updatedBy
      active
      email
      name
      registryAccessToken
    }
    active
  }
}
  1. For select: { updatedBy: true, updatedByUser: true, active: true } (Scalar before relation, does not crash)
query {
  findManyUser(first: 100) {
    updatedBy
    active
    updatedByUser {
      id
      createdAt
      updatedAt
      updatedBy
      active
      email
      name
      registryAccessToken
    }
  }
}
  1. For select: { updatedBy: true, active: true } (Removed relation, does not crash)
query {
  findManyUser(first: 100) {
    updatedBy
    active
  }
}

Expected behavior

  1. The script should not crash
  2. The order of select arguments should not determine if the script crashes or not

Environment & setup

  • OS: macOS
  • Database: Postgres
  • Prisma version:
@prisma/cli          : 2.0.0-beta.5
Current platform     : darwin
Query Engine         : query-engine 0c2ec197653b278b2978845ef958db88824cd82e
Migration Engine     : migration-engine-cli 0c2ec197653b278b2978845ef958db88824cd82e
Introspection Engine : introspection-core 0c2ec197653b278b2978845ef958db88824cd82e
Format Binary        : prisma-fmt 0c2ec197653b278b2978845ef958db88824cd82e
  • Node.js version: v12.16.3
@janpio janpio added bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. kind/bug A reported bug. labels May 14, 2020
@pantharshit00 pantharshit00 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 May 16, 2020
@pantharshit00
Copy link
Contributor

Thanks for the detailed write up Sid! I can confirm this.

image

@janpio
Copy link
Member

janpio commented May 25, 2020

Please add the SQL to the issue, so usage of Migrate is not required to reproduce this.

@janpio janpio added the tech/engines Issue for tech Engines. label May 25, 2020
@janpio janpio added this to the Beta 7 milestone May 25, 2020
@pantharshit00
Copy link
Contributor

CREATE TABLE "public"."User" (
"active" boolean  NOT NULL DEFAULT true,"createdAt" timestamp(3)  NOT NULL DEFAULT CURRENT_TIMESTAMP,"email" text  NOT NULL ,"id" text  NOT NULL ,"name" text   ,"registryAccessToken" text  NOT NULL ,"updatedAt" timestamp(3)  NOT NULL ,"updatedBy" text   ,
    PRIMARY KEY ("id"))

CREATE UNIQUE INDEX "User.email" ON "public"."User"("email")

CREATE UNIQUE INDEX "User.registryAccessToken" ON "public"."User"("registryAccessToken")

ALTER TABLE "public"."User" ADD FOREIGN KEY ("updatedBy")REFERENCES "public"."User"("id") ON DELETE SET NULL  ON UPDATE CASCADE

@dpetrick dpetrick self-assigned this May 26, 2020
@dpetrick
Copy link
Contributor

Fixed with 2.0.0-alpha.1205 onwards.

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 Issue for tech Engines.
Projects
None yet
Development

No branches or pull requests

4 participants