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

Float values around 2^63 get interpreted as invalid intergers and throw a graphql error #15551

Closed
paperdave opened this issue Sep 27, 2022 · 6 comments · Fixed by #15879
Closed
Labels
bug/2-confirmed Bug has been reproduced and confirmed. kind/bug A reported bug. team/client Issue for team Client. tech/typescript Issue for tech TypeScript. topic: floating point types Topic related to floating point types and precision loss
Milestone

Comments

@paperdave
Copy link

paperdave commented Sep 27, 2022

Bug description

Running the create method with any schema with a Float column with the value 2**64 fails.

After some digging, it seems that the graphql query stringifies the number to 18446744073709552000, which graphql wrongly interprets as an integer. Passing values around 2**70 function as it seems they get serialized as 1.1805916207174113e+21.

This means we cannot insert numbers from around ~2**63 to ~2**69 for our app. Can't insert them via prisma studio either.

I dont know the codebase much, but would this be fixed if ".0" was suffixed to numbers that the e notation doesn't have?

How to reproduce

  1. copy the schema below
  2. run the provided js on it. it is a single create query
  3. Query parsing failure: A number used in the query does not fit into a 64 bit signed integer. Consider using BigInt as field type if you're trying to store large integers

Expected behavior

The value 18446744073709552000 should be written to the database as a float.

Prisma information

prisma/schema.prisma

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "sqlite"
  url      = "file:./test.db"
}

model Test {
  id    Int   @id @default(autoincrement())
  value Float
}

test.mjs

import { PrismaClient } from '@prisma/client';

const client = new PrismaClient();

await client.test.create({
  data: {
    value: 2 ** 64,
  },
});

using DEBUG=* i found this graphql query

mutation {
  createOneTest(data: {
    value: 18446744073709552000
  }) {
    id
    value
  }
}

the value: n is what im referring to above about the stringified value

Environment & setup

  • OS: Debian Docker running on NixOS
  • Database: Sqlite
  • Node.js version: 16.17.0

Prisma Version

prisma                  : 4.3.1
@prisma/client          : 4.3.1
Current platform        : debian-openssl-1.1.x
Query Engine (Node-API) : libquery-engine c875e43600dfe042452e0b868f7a48b817b9640b (at node_modules/.pnpm/@prisma+engines@4.3.1/node_modules/@prisma/engines/libquery_engine-debian-openssl-1.1.x.so.node)
Migration Engine        : migration-engine-cli c875e43600dfe042452e0b868f7a48b817b9640b (at node_modules/.pnpm/@prisma+engines@4.3.1/node_modules/@prisma/engines/migration-engine-debian-openssl-1.1.x)
Introspection Engine    : introspection-core c875e43600dfe042452e0b868f7a48b817b9640b (at node_modules/.pnpm/@prisma+engines@4.3.1/node_modules/@prisma/engines/introspection-engine-debian-openssl-1.1.x)
Format Binary           : prisma-fmt c875e43600dfe042452e0b868f7a48b817b9640b (at node_modules/.pnpm/@prisma+engines@4.3.1/node_modules/@prisma/engines/prisma-fmt-debian-openssl-1.1.x)
Format Wasm             : @prisma/prisma-fmt-wasm 4.3.0-32.c875e43600dfe042452e0b868f7a48b817b9640b
Default Engines Hash    : c875e43600dfe042452e0b868f7a48b817b9640b
Studio                  : 0.473.0
@paperdave paperdave added the kind/bug A reported bug. label Sep 27, 2022
@millsp millsp added team/client Issue for team Client. bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. labels Sep 27, 2022
@annibuliful
Copy link

Could you try to use Decimal with precision to get more byte to store?
https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#decimal

@paperdave
Copy link
Author

Could you try to use Decimal with precision to get more byte to store? https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#decimal

updated model:

model Test {
  id    Int   @id @default(autoincrement())
  value Decimal
}

produces the same error:

/workspace/node_modules/@prisma/client/runtime/index.js:30851
      throw new PrismaClientKnownRequestError(message, error2.code, this.client._clientVersion, error2.meta);
            ^

PrismaClientKnownRequestError: 
Invalid `prisma.test.create()` invocation:


Query parsing failure: A number used in the query does not fit into a 64 bit signed integer. Consider using `BigInt` as field type if you're trying to store large integers.
    at RequestHandler.handleRequestError (/workspace/node_modules/@prisma/client/runtime/index.js:30851:13)
    at RequestHandler.request (/workspace/node_modules/@prisma/client/runtime/index.js:30834:12)
    at async PrismaClient._request (/workspace/node_modules/@prisma/client/runtime/index.js:31812:16)
    at async file:///workspace/test.js:5:1 {
  code: 'P2033',
  clientVersion: '4.4.0',
  meta: {
    details: "Query parsing failure: A number used in the query does not fit into a 64 bit signed integer. Consider using `BigInt` as field type if you're trying to store large integers."
  }
}

both Float and Decimal allow storage of these values, its just the query that fails to serialize.

@annibuliful
Copy link

It might be related to #14632 (comment)

@aqrln aqrln added the topic: floating point types Topic related to floating point types and precision loss label Oct 13, 2022
@aqrln aqrln self-assigned this Oct 13, 2022
@aqrln aqrln added bug/2-confirmed Bug has been reproduced and confirmed. tech/typescript Issue for tech TypeScript. and removed bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. labels Oct 13, 2022
@aqrln
Copy link
Member

aqrln commented Oct 13, 2022

I can reproduce this.

mutation {
  createOneTest(data: {
    value: 18446744073709552000
  }) {
    id
    value
  }
}
{
  "errors": [
    {
      "error": "Query parsing failure: A number used in the query does not fit into a 64 bit signed integer. Consider using `BigInt` as field type if you're trying to store large integers.",
      "user_facing_error": {
        "is_panic": false,
        "message": "Query parsing failure: A number used in the query does not fit into a 64 bit signed integer. Consider using `BigInt` as field type if you're trying to store large integers.",
        "meta": {
          "details": "Query parsing failure: A number used in the query does not fit into a 64 bit signed integer. Consider using `BigInt` as field type if you're trying to store large integers."
        },
        "error_code": "P2033"
      }
    }
  ]
}

When changing the number to have .0 at the end of the number and sending it to the Query Engine manually via playground the query succeeds:

mutation {
  createOneTest(data: {
    value: 18446744073709552000.0
  }) {
    id
    value
  }
}
{
  "data": {
    "createOneTest": {
      "id": 1,
      "value": 18446744073709550000
    }
  }
}

Since the client knows the expected type is Float, it could serialize the value accordingly.

@aqrln aqrln removed their assignment Oct 13, 2022
@paperdave
Copy link
Author

do you know where in the code that serialization happens, i'd like to take a look at exactly whats going on there; maybe could make a fix

@aqrln
Copy link
Member

aqrln commented Oct 19, 2022

@paperdave sorry, I didn't see your response! It looks like your issue is a duplicate of #12651 and #13317, and we got a pull request today that should fix all three issues, please take a look at it too if you are interested: #15879

@janpio janpio added this to the 4.6.0 milestone Oct 19, 2022
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. tech/typescript Issue for tech TypeScript. topic: floating point types Topic related to floating point types and precision loss
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants