diff --git a/packages/client/src/__tests__/__snapshots__/select.test.ts.snap b/packages/client/src/__tests__/__snapshots__/select.test.ts.snap index f1ab71659641..17e56b71ea19 100644 --- a/packages/client/src/__tests__/__snapshots__/select.test.ts.snap +++ b/packages/client/src/__tests__/__snapshots__/select.test.ts.snap @@ -476,7 +476,7 @@ query { age_gt: 10123123123 id_endsWith: "veryLongNameGoIntoaNewLineNow@gmail.com" name_contains: "hans" - name_gt: 2020123100000023 + name_gt: 2131203912039123 name_in: ["hans"] AND: [ { @@ -541,7 +541,7 @@ Invalid \`prisma.findManyUser()\` invocation: ~~~~~~~~~~~ name_contains: 'hans', ~~~~~~~~~~~~~ - name_gt: 2020123100000023, + name_gt: 2131203912039123, ~~~~~~~ name_in: [ ~~~~~~~ @@ -827,7 +827,7 @@ Invalid \`prisma.findManyUser()\` invocation: ~~~~~~~~~~~ name_contains: 'hans', ~~~~~~~~~~~~~ - name_gt: 2020123100000023, + name_gt: 2131203912039123, ~~~~~~~ name_in: [ ~~~~~~~ diff --git a/packages/client/src/__tests__/atomicOperationsUpdate.test.ts b/packages/client/src/__tests__/atomicOperationsUpdate.test.ts index 64f03505e008..31efda58b9d2 100644 --- a/packages/client/src/__tests__/atomicOperationsUpdate.test.ts +++ b/packages/client/src/__tests__/atomicOperationsUpdate.test.ts @@ -40,7 +40,7 @@ describe('minimal atomic update transformation', () => { mutation { updateOneUser( data: { - countFloat: 3.1415926 + countFloat: 3.1415926e+0 countInt1: 3 } ) { diff --git a/packages/client/src/__tests__/query/floats.test.ts b/packages/client/src/__tests__/query/floats.test.ts new file mode 100644 index 000000000000..3fce9d6d2a8a --- /dev/null +++ b/packages/client/src/__tests__/query/floats.test.ts @@ -0,0 +1,82 @@ +import { getDMMF } from '../../generation/getDMMF' +import { DMMFClass, makeDocument, transformDocument } from '../../runtime' + +const datamodel = /* Prisma */ ` + datasource my_db { + provider = "postgres" + url = env("POSTGRES_URL") + } + + model Floats { + id Int @id + value Float + } +` + +let dmmf + +function getTransformedDocument(select) { + const document = makeDocument({ + dmmf, + select, + rootTypeName: 'mutation', + rootField: 'createOneFloats', + }) + return String(transformDocument(document)) +} + +beforeAll(async () => { + dmmf = new DMMFClass(await getDMMF({ datamodel })) +}) + +test('serializes floats in exponential notation', () => { + const largeInt = getTransformedDocument({ + data: { + value: 100_000_000_000_000_000_000, + }, + }) + + expect(largeInt).toMatchInlineSnapshot(` + mutation { + createOneFloats(data: { + value: 1e+20 + }) { + id + value + } + } + `) + + const negativeInt = getTransformedDocument({ + data: { + value: Number.MIN_SAFE_INTEGER, + }, + }) + + expect(negativeInt).toMatchInlineSnapshot(` + mutation { + createOneFloats(data: { + value: -9.007199254740991e+15 + }) { + id + value + } + } + `) + + const otherFloat = getTransformedDocument({ + data: { + value: 13.37, + }, + }) + expect(otherFloat).toMatchInlineSnapshot(` + mutation { + createOneFloats(data: { + value: 1.337e+1 + }) { + id + value + } + } + `) +}) diff --git a/packages/client/src/__tests__/scalarListCreate.test.ts b/packages/client/src/__tests__/scalarListCreate.test.ts index 3fe24c0b8564..99fd27acaa63 100644 --- a/packages/client/src/__tests__/scalarListCreate.test.ts +++ b/packages/client/src/__tests__/scalarListCreate.test.ts @@ -54,7 +54,7 @@ describe('scalar where transformation', () => { } } someFloats: { - set: [1, 1.2] + set: [1e+0, 1.2e+0] } }) { id @@ -112,7 +112,7 @@ describe('scalar where transformation', () => { id: 5 } } - someFloats: [1, 1.2] + someFloats: [1e+0, 1.2e+0] }) { id name diff --git a/packages/client/src/runtime/query.ts b/packages/client/src/runtime/query.ts index 7094c8cd6eee..fb6049fb560d 100644 --- a/packages/client/src/runtime/query.ts +++ b/packages/client/src/runtime/query.ts @@ -651,6 +651,10 @@ function stringify(value: any, inputType?: DMMF.SchemaArgInputType) { return value } + if (typeof value === 'number' && inputType?.type === 'Float') { + return value.toExponential() + } + return JSON.stringify(value, null, 2) } diff --git a/packages/client/tests/functional/large-floats/_matrix.ts b/packages/client/tests/functional/large-floats/_matrix.ts new file mode 100644 index 000000000000..8f43b12d20b0 --- /dev/null +++ b/packages/client/tests/functional/large-floats/_matrix.ts @@ -0,0 +1,24 @@ +import { defineMatrix } from '../_utils/defineMatrix' + +export default defineMatrix(() => [ + [ + { + provider: 'sqlite', + }, + { + provider: 'postgresql', + }, + { + provider: 'mysql', + }, + { + provider: 'mongodb', + }, + { + provider: 'cockroachdb', + }, + { + provider: 'sqlserver', + }, + ], +]) diff --git a/packages/client/tests/functional/large-floats/prisma/_schema.ts b/packages/client/tests/functional/large-floats/prisma/_schema.ts new file mode 100644 index 000000000000..cf03c274492c --- /dev/null +++ b/packages/client/tests/functional/large-floats/prisma/_schema.ts @@ -0,0 +1,20 @@ +import { idForProvider } from '../../_utils/idForProvider' +import testMatrix from '../_matrix' + +export default testMatrix.setupSchema(({ provider }) => { + return /* Prisma */ ` + generator client { + provider = "prisma-client-js" + } + + datasource db { + provider = "${provider}" + url = env("DATABASE_URI_${provider}") + } + + model Floats { + id ${idForProvider(provider)} + value Float + } + ` +}) diff --git a/packages/client/tests/functional/large-floats/tests.ts b/packages/client/tests/functional/large-floats/tests.ts new file mode 100644 index 000000000000..66f1a002c7f7 --- /dev/null +++ b/packages/client/tests/functional/large-floats/tests.ts @@ -0,0 +1,32 @@ +// @ts-ignore +import type { PrismaClient } from '@prisma/client' + +import testMatrix from './_matrix' + +declare let prisma: PrismaClient + +testMatrix.setupTestSuite(() => { + test('floats', async () => { + const largeFloat = await prisma.floats.create({ + data: { value: 1e20 }, + }) + const negativeFloat = await prisma.floats.create({ + data: { value: -1e20 }, + }) + const largeInteger = await prisma.floats.create({ + data: { value: Number.MAX_SAFE_INTEGER }, + }) + const negativeInteger = await prisma.floats.create({ + data: { value: Number.MIN_SAFE_INTEGER }, + }) + const otherFloat = await prisma.floats.create({ + data: { value: 13.37 }, + }) + + expect(largeFloat.value).toEqual(1e20) + expect(negativeFloat.value).toEqual(-1e20) + expect(largeInteger.value).toEqual(Number.MAX_SAFE_INTEGER) + expect(negativeInteger.value).toEqual(Number.MIN_SAFE_INTEGER) + expect(otherFloat.value).toEqual(13.37) + }) +}) diff --git a/packages/internals/src/utils/jestSnapshotSerializer.js b/packages/internals/src/utils/jestSnapshotSerializer.js index acfa54ddbec6..f9a88bedb6e2 100644 --- a/packages/internals/src/utils/jestSnapshotSerializer.js +++ b/packages/internals/src/utils/jestSnapshotSerializer.js @@ -69,7 +69,7 @@ function normalizeBinaryFilePath(str) { } function normalizeMigrateTimestamps(str) { - return str.replace(/\d{14}/g, '20201231000000') + return str.replace(/(?