Repository: prisma/prisma
Pull request #27127: fix: fix various invalid results
Author: login: jacek-prisma
Labels: name: lgtm
description: This PR has been approved by a maintainer
Created: 2025-05-08T14:45:20Z | Merged: 2025-05-12T10:50:33Z

[ORM-916](https://linear.app/prisma-company/issue/ORM-916/investigate-invalid-result-structure)



Diff:
diff --git a/packages/adapter-pg/src/conversion.ts b/packages/adapter-pg/src/conversion.ts
index a6fbfdd1d1e4..cccc983d30c4 100644
--- a/packages/adapter-pg/src/conversion.ts
+++ b/packages/adapter-pg/src/conversion.ts
@@ -294,11 +294,11 @@ function normalize_date(date: string): string {
  */
 
 function normalize_timestamp(time: string): string {
-  return time
+  return new Date(`${time}Z`).toISOString().replace(/(\.000)?Z$/, '+00:00')
 }
 
 function normalize_timestampz(time: string): string {
-  return time.split('+')[0]
+  return new Date(time.replace(/[+-]\d{2}(:\d{2})?$/, 'Z')).toISOString().replace(/(\.000)?Z$/, '+00:00')
 }
 
 /*
@@ -312,7 +312,7 @@ function normalize_time(time: string): string {
 function normalize_timez(time: string): string {
   // Although it might be controversial, UTC is assumed in consistency with the behavior of rust postgres driver
   // in quaint. See quaint/src/connector/postgres/conversion.rs
-  return time.split('+')[0]
+  return time.replace(/[+-]\d{2}(:\d{2})?$/, '')
 }
 
 /******************/
diff --git a/packages/client-engine-runtime/package.json b/packages/client-engine-runtime/package.json
index 96d95b340225..c1d4e8bd0511 100644
--- a/packages/client-engine-runtime/package.json
+++ b/packages/client-engine-runtime/package.json
@@ -29,6 +29,7 @@
     "@paralleldrive/cuid2": "2.2.2",
     "@prisma/debug": "workspace:*",
     "@prisma/driver-adapter-utils": "workspace:*",
+    "decimal.js": "10.5.0",
     "nanoid": "5.1.5",
     "ulid": "3.0.0",
     "uuid": "11.1.0"
diff --git a/packages/client-engine-runtime/src/QueryPlan.ts b/packages/client-engine-runtime/src/QueryPlan.ts
index 777b382cc0d1..49b281fde12a 100644
--- a/packages/client-engine-runtime/src/QueryPlan.ts
+++ b/packages/client-engine-runtime/src/QueryPlan.ts
@@ -13,6 +13,15 @@ export function isPrismaValueGenerator(value: unknown): value is PrismaValueGene
   return typeof value === 'object' && value !== null && value['prisma__type'] === 'generatorCall'
 }
 
+export type PrismaValueBytes = {
+  prisma__type: 'bytes'
+  prisma__value: string
+}
+
+export function isPrismaValueBytes(value: unknown): value is PrismaValueBytes {
+  return typeof value === 'object' && value !== null && value['prisma__type'] === 'bytes'
+}
+
 export type PrismaValue =
   | string
   | boolean
@@ -22,6 +31,7 @@ export type PrismaValue =
   | Record<string, unknown>
   | PrismaValuePlaceholder
   | PrismaValueGenerator
+  | PrismaValueBytes
 
 export type PrismaValueType =
   | { type: 'Any' }
diff --git a/packages/client-engine-runtime/src/interpreter/DataMapper.ts b/packages/client-engine-runtime/src/interpreter/DataMapper.ts
index 5d02233c449e..5f3017456939 100644
--- a/packages/client-engine-runtime/src/interpreter/DataMapper.ts
+++ b/packages/client-engine-runtime/src/interpreter/DataMapper.ts
@@ -1,3 +1,5 @@
+import Decimal from 'decimal.js'
+
 import { PrismaValueType, ResultNode } from '../QueryPlan'
 import { assertNever } from '../utils'
 import { PrismaObject, Value } from './scope'
@@ -89,22 +91,21 @@ function mapValue(value: unknown, resultType: PrismaValueType): unknown {
     case 'Boolean':
       return typeof value === 'boolean' ? value : value !== '0'
     case 'Decimal':
-      return typeof value === 'number' ? value : parseFloat(`${value}`)
+      return typeof value === 'number' ? new Decimal(value) : new Decimal(`${value}`)
     case 'Date':
       return value instanceof Date ? value : new Date(`${value}`)
     case 'Array': {
       const values = value as unknown[]
-      return values.map((v) => {
-        mapValue(v, resultType.inner)
-      })
+      return values.map((v) => mapValue(v, resultType.inner))
     }
     case 'Object':
-      return typeof value === 'object' ? value : { value: value }
-    case 'Bytes':
-      if (typeof value !== 'string') {
-        throw new Error(`DataMapper: Bytes data is not a string, got: ${typeof value}`)
+      return typeof value === 'string' ? value : JSON.stringify(value)
+    case 'Bytes': {
+      if (!Array.isArray(value)) {
+        throw new Error(`DataMapper: Bytes data is invalid, got: ${typeof value}`)
       }
-      return value
+      return new Uint8Array(value)
+    }
     default:
       assertNever(resultType, `DataMapper: Unknown result type: ${(resultType as PrismaValueType).type}`)
   }
diff --git a/packages/client-engine-runtime/src/interpreter/generators.ts b/packages/client-engine-runtime/src/interpreter/generators.ts
index d76c5f0c4471..ec2268728430 100644
--- a/packages/client-engine-runtime/src/interpreter/generators.ts
+++ b/packages/client-engine-runtime/src/interpreter/generators.ts
@@ -4,8 +4,6 @@ import { nanoid } from 'nanoid'
 import { ulid } from 'ulid'
 import { v4 as uuidv4, v7 as uuidv7 } from 'uuid'
 
-import { PrismaValue } from '../QueryPlan'
-
 export class GeneratorRegistry {
   #generators: GeneratorRegistrySnapshot = {}
 
@@ -42,7 +40,7 @@ export interface GeneratorRegistrySnapshot {
 }
 
 export interface ValueGenerator {
-  generate(...args: PrismaValue[]): PrismaValue
+  generate(...args: unknown[]): unknown
 }
 
 class NowGenerator implements ValueGenerator {
@@ -54,7 +52,7 @@ class NowGenerator implements ValueGenerator {
 }
 
 class UuidGenerator implements ValueGenerator {
-  generate(arg: PrismaValue | undefined): string {
+  generate(arg: unknown): string {
     if (arg === 4) {
       return uuidv4()
     } else if (arg === 7) {
@@ -66,7 +64,7 @@ class UuidGenerator implements ValueGenerator {
 }
 
 class CuidGenerator implements ValueGenerator {
-  generate(arg: PrismaValue | undefined): string {
+  generate(arg: unknown): string {
     if (arg === 1) {
       return cuid1()
     } else if (arg === 2) {
@@ -84,7 +82,7 @@ class UlidGenerator implements ValueGenerator {
 }
 
 class NanoIdGenerator implements ValueGenerator {
-  generate(arg: PrismaValue | undefined): string {
+  generate(arg: unknown): string {
     if (typeof arg === 'number') {
       return nanoid(arg)
     } else if (arg === undefined) {
@@ -96,7 +94,7 @@ class NanoIdGenerator implements ValueGenerator {
 }
 
 class ProductGenerator implements ValueGenerator {
-  generate(lhs: PrismaValue | undefined, rhs: PrismaValue | undefined): PrismaValue[] {
+  generate(lhs: unknown, rhs: unknown): unknown[] {
     if (lhs === undefined || rhs === undefined) {
       throw new Error('Invalid Product generator arguments')
     }
diff --git a/packages/client-engine-runtime/src/interpreter/renderQuery.ts b/packages/client-engine-runtime/src/interpreter/renderQuery.ts
index 4dccec5eb3a8..30547639bc8d 100644
--- a/packages/client-engine-runtime/src/interpreter/renderQuery.ts
+++ b/packages/client-engine-runtime/src/interpreter/renderQuery.ts
@@ -8,7 +8,7 @@ import type {
   PrismaValuePlaceholder,
   QueryPlanDbQuery,
 } from '../QueryPlan'
-import { isPrismaValueGenerator, isPrismaValuePlaceholder } from '../QueryPlan'
+import { isPrismaValueBytes, isPrismaValueGenerator, isPrismaValuePlaceholder } from '../QueryPlan'
 import { assertNever } from '../utils'
 import { GeneratorRegistrySnapshot } from './generators'
 import { ScopeBindings } from './scope'
@@ -35,16 +35,12 @@ export function renderQuery(
   }
 }
 
-function evaluateParams(
-  params: PrismaValue[],
-  scope: ScopeBindings,
-  generators: GeneratorRegistrySnapshot,
-): PrismaValue[] {
+function evaluateParams(params: PrismaValue[], scope: ScopeBindings, generators: GeneratorRegistrySnapshot): unknown[] {
   return params.map((param) => evaluateParam(param, scope, generators))
 }
 
-function evaluateParam(param: PrismaValue, scope: ScopeBindings, generators: GeneratorRegistrySnapshot): PrismaValue {
-  let value = param
+function evaluateParam(param: PrismaValue, scope: ScopeBindings, generators: GeneratorRegistrySnapshot): unknown {
+  let value: unknown = param
 
   while (doesRequireEvaluation(value)) {
     if (isPrismaValuePlaceholder(value)) {
@@ -52,7 +48,7 @@ function evaluateParam(param: PrismaValue, scope: ScopeBindings, generators: Gen
       if (found === undefined) {
         throw new Error(`Missing value for query variable ${value.prisma__value.name}`)
       }
-      value = found as PrismaValue
+      value = found
     } else if (isPrismaValueGenerator(value)) {
       const { name, args } = value.prisma__value
       const generator = generators[name]
@@ -69,17 +65,17 @@ function evaluateParam(param: PrismaValue, scope: ScopeBindings, generators: Gen
     value = value.map((el) => evaluateParam(el, scope, generators))
   }
 
+  if (isPrismaValueBytes(value)) {
+    value = Buffer.from(value.prisma__value, 'base64')
+  }
+
   return value
 }
 
-function renderTemplateSql(
-  fragments: Fragment[],
-  placeholderFormat: PlaceholderFormat,
-  params: PrismaValue[],
-): SqlQuery {
+function renderTemplateSql(fragments: Fragment[], placeholderFormat: PlaceholderFormat, params: unknown[]): SqlQuery {
   let paramIndex = 0
   let placeholderNumber = 1
-  const flattenedParams: PrismaValue[] = []
+  const flattenedParams: unknown[] = []
   const sql = fragments
     .map((fragment) => {
       const fragmentType = fragment.type
@@ -156,7 +152,7 @@ function formatPlaceholder(placeholderFormat: PlaceholderFormat, placeholderNumb
   return placeholderFormat.hasNumbering ? `${placeholderFormat.prefix}${placeholderNumber}` : placeholderFormat.prefix
 }
 
-function renderRawSql(sql: string, params: PrismaValue[]): SqlQuery {
+function renderRawSql(sql: string, params: unknown[]): SqlQuery {
   const argTypes = params.map((param) => toArgType(param))
 
   return {
@@ -166,7 +162,7 @@ function renderRawSql(sql: string, params: PrismaValue[]): SqlQuery {
   }
 }
 
-function toArgType(value: PrismaValue): ArgType {
+function toArgType(value: unknown): ArgType {
   if (typeof value === 'string') {
     return 'Text'
   }
@@ -183,37 +179,13 @@ function toArgType(value: PrismaValue): ArgType {
     return 'Array'
   }
 
-  if (isPrismaValuePlaceholder(value)) {
-    return placeholderTypeToArgType(value.prisma__value.type)
+  if (Buffer.isBuffer(value)) {
+    return 'Bytes'
   }
 
   return 'Unknown'
 }
 
-function placeholderTypeToArgType(type: string): ArgType {
-  const typeMap = {
-    Any: 'Json',
-    String: 'Text',
-    Int: 'Int32',
-    BigInt: 'Int64',
-    Float: 'Double',
-    Boolean: 'Boolean',
-    Decimal: 'Numeric',
-    Date: 'DateTime',
-    Object: 'Json',
-    Bytes: 'Bytes',
-    Array: 'Array',
-  } satisfies Record<string, ArgType>
-
-  const mappedType = typeMap[type] as ArgType | undefined
-
-  if (!mappedType) {
-    throw new Error(`Unknown placeholder type: ${type}`)
-  }
-
-  return mappedType
-}
-
-function doesRequireEvaluation(param: PrismaValue): param is PrismaValuePlaceholder | PrismaValueGenerator {
+function doesRequireEvaluation(param: unknown): param is PrismaValuePlaceholder | PrismaValueGenerator {
   return isPrismaValuePlaceholder(param) || isPrismaValueGenerator(param)
 }
diff --git a/packages/client-engine-runtime/src/interpreter/validation.ts b/packages/client-engine-runtime/src/interpreter/validation.ts
index 17c0cae1be69..df3ed9d01010 100644
--- a/packages/client-engine-runtime/src/interpreter/validation.ts
+++ b/packages/client-engine-runtime/src/interpreter/validation.ts
@@ -36,7 +36,7 @@ function renderMessage(data: unknown, error: ValidationError): string {
     case 'RELATION_VIOLATION':
       return `The change you are trying to make would violate the required relation '${error.context.relation}' between the \`${error.context.modelA}\` and \`${error.context.modelB}\` models.`
     case 'MISSING_RECORD':
-      return `No record was found for ${error.context.operation}.`
+      return `An operation failed because it depends on one or more records that were required but not found. No record was found for ${error.context.operation}.`
     case 'MISSING_RELATED_RECORD': {
       const hint = error.context.neededFor ? ` (needed to ${error.context.neededFor})` : ''
       return `An operation failed because it depends on one or more records that were required but not found. No '${error.context.model}' record${hint} was found for ${error.context.operation} on ${error.context.relationType} relation '${error.context.relation}'.`
diff --git a/packages/client/src/runtime/core/jsonProtocol/deserializeJsonResponse.ts b/packages/client/src/runtime/core/jsonProtocol/deserializeJsonResponse.ts
index ce7b0e630da6..1ad25288983d 100644
--- a/packages/client/src/runtime/core/jsonProtocol/deserializeJsonResponse.ts
+++ b/packages/client/src/runtime/core/jsonProtocol/deserializeJsonResponse.ts
@@ -18,6 +18,16 @@ export function deserializeJsonResponse(result: unknown): unknown {
       return deserializeTaggedValue(result)
     }
 
+    // avoid mapping known class instances
+    if (
+      typeof result === 'bigint' ||
+      result instanceof Date ||
+      result instanceof Uint8Array ||
+      result instanceof Decimal
+    ) {
+      return result
+    }
+
     return mapObjectValues(result, deserializeJsonResponse)
   }
 
diff --git a/packages/client/tests/functional/client-engine-known-failures-js_pg.txt b/packages/client/tests/functional/client-engine-known-failures-js_pg.txt
index 269d18208e53..aca07ea16386 100644
--- a/packages/client/tests/functional/client-engine-known-failures-js_pg.txt
+++ b/packages/client/tests/functional/client-engine-known-failures-js_pg.txt
@@ -293,3 +293,8 @@ typed-sql.postgres-scalars.test (provider=postgresql, js_pg) xml - input
 typed-sql.postgres-scalars.test (provider=postgresql, js_pg) xml - output
 unsupported-action (provider=postgresql, js_pg) unsupported method
 upsert-relation-mode-prisma.test (provider=postgresql, js_pg) calling upsert two times in a row does nothing
+json-list-push (provider=postgresql, js_pg) push with array value
+json-list-push (provider=postgresql, js_pg) push with single element
+decimal.list (provider=postgresql, js_pg) create with strings
+decimal.list (provider=postgresql, js_pg) with decimal instances
+decimal.list (provider=postgresql, js_pg) with numbers
diff --git a/packages/client/tests/functional/methods/findFirstOrThrow/tests.ts b/packages/client/tests/functional/methods/findFirstOrThrow/tests.ts
index 029639f08d46..c798e8019b4d 100644
--- a/packages/client/tests/functional/methods/findFirstOrThrow/tests.ts
+++ b/packages/client/tests/functional/methods/findFirstOrThrow/tests.ts
@@ -51,7 +51,7 @@ testMatrix.setupTestSuite(
           40 const result = prisma.$transaction([
           41   prisma.user.create({ data: { email: newEmail } }),
         → 42   prisma.user.findFirstOrThrow(
-        An operation failed because it depends on one or more records that were required but not found. Expected a record, found none."
+        An operation failed because it depends on one or more records that were required but not found. No record was found for a query."
       `)
 
         const record = await prisma.user.findFirst({ where: { email: newEmail } })
@@ -77,7 +77,7 @@ testMatrix.setupTestSuite(
           66 const result = prisma.$transaction(async (prisma) => {
           67   await prisma.user.create({ data: { email: newEmail } })
         → 68   await prisma.user.findFirstOrThrow(
-        An operation failed because it depends on one or more records that were required but not found. Expected a record, found none."
+        An operation failed because it depends on one or more records that were required but not found. No record was found for a query."
       `)
 
         const record = await prisma.user.findFirst({ where: { email: newEmail } })
diff --git a/packages/client/tests/functional/methods/findUniqueOrThrow/tests.ts b/packages/client/tests/functional/methods/findUniqueOrThrow/tests.ts
index 6fbdcd79aa10..8725800eb2f9 100644
--- a/packages/client/tests/functional/methods/findUniqueOrThrow/tests.ts
+++ b/packages/client/tests/functional/methods/findUniqueOrThrow/tests.ts
@@ -50,7 +50,7 @@ testMatrix.setupTestSuite(
           39 const result = prisma.$transaction([
           40   prisma.user.create({ data: { email: newEmail } }),
         → 41   prisma.user.findUniqueOrThrow(
-        An operation failed because it depends on one or more records that were required but not found. Expected a record, found none."
+        An operation failed because it depends on one or more records that were required but not found. No record was found for a query."
       `)
 
         const record = await prisma.user.findUnique({ where: { email: newEmail } })
@@ -76,7 +76,7 @@ testMatrix.setupTestSuite(
           65 const result = prisma.$transaction(async (prisma) => {
           66   await prisma.user.create({ data: { email: newEmail } })
         → 67   await prisma.user.findUniqueOrThrow(
-        An operation failed because it depends on one or more records that were required but not found. Expected a record, found none."
+        An operation failed because it depends on one or more records that were required but not found. No record was found for a query."
       `)
 
         const record = await prisma.user.findUnique({ where: { email: newEmail } })
diff --git a/packages/client/tests/functional/query-error-logging/tests.ts b/packages/client/tests/functional/query-error-logging/tests.ts
index 47df7a4cb579..9c4ec05d679b 100644
--- a/packages/client/tests/functional/query-error-logging/tests.ts
+++ b/packages/client/tests/functional/query-error-logging/tests.ts
@@ -40,7 +40,7 @@ testMatrix.setupTestSuite(
 
       const errorEvent = errors[0]
       expect(errorEvent.message).toContain(
-        'An operation failed because it depends on one or more records that were required but not found. Expected a record, found none.',
+        'An operation failed because it depends on one or more records that were required but not found. No record was found for a query.',
       )
       expect(errorEvent.target).toContain('user.findUniqueOrThrow')
     })
@@ -61,7 +61,7 @@ testMatrix.setupTestSuite(
 
       const errorEvent = errors[0]
       expect(errorEvent.message).toContain(
-        'An operation failed because it depends on one or more records that were required but not found. Expected a record, found none.',
+        'An operation failed because it depends on one or more records that were required but not found. No record was found for a query.',
       )
       expect(errorEvent.target).toContain('user.findFirstOrThrow')
     })
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 7c33474b177d..ac19ec771c73 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -934,6 +934,9 @@ importers:
       '@prisma/driver-adapter-utils':
         specifier: workspace:*
         version: link:../driver-adapter-utils
+      decimal.js:
+        specifier: 10.5.0
+        version: 10.5.0
       nanoid:
         specifier: 5.1.5
         version: 5.1.5
@@ -5946,6 +5949,7 @@ packages:
 
   libsql@0.3.10:
     resolution: {integrity: sha512-/8YMTbwWFPmrDWY+YFK3kYqVPFkMgQre0DGmBaOmjogMdSe+7GHm1/q9AZ61AWkEub/vHmi+bA4tqIzVhKnqzg==}
+    cpu: [x64, arm64, wasm32]
     os: [darwin, linux, win32]
 
   lilconfig@3.1.3:


Reviews:
user: login: semoal
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-08T16:11:37Z
user: login: jacek-prisma
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-08T20:01:15Z
user: login: semoal
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-08T20:07:35Z
user: login: aqrln
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-12T09:51:04Z
user: login: jacek-prisma
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-12T09:59:46Z
user: login: aqrln
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-12T10:01:50Z

Review comments:
diff_hunk: @@ -89,22 +91,28 @@ function mapValue(value: unknown, resultType: PrismaValueType): unknown {
     case 'Boolean':
       return typeof value === 'boolean' ? value : value !== '0'
     case 'Decimal':
-      return typeof value === 'number' ? value : parseFloat(`${value}`)
+      return typeof value === 'number' ? new Decimal(value) : new Decimal(`${value}`)
path: packages/client-engine-runtime/src/interpreter/DataMapper.ts
user: login: semoal
body: probably big.js is a more lightweight alternative with the same feature, you want here that is precision.

decimal.js : 31.2kb
big.js: 6.8kb


created_at: 2025-05-08T16:11:37Z
author_association: NONE
diff_hunk: @@ -89,22 +91,28 @@ function mapValue(value: unknown, resultType: PrismaValueType): unknown {
     case 'Boolean':
       return typeof value === 'boolean' ? value : value !== '0'
     case 'Decimal':
-      return typeof value === 'number' ? value : parseFloat(`${value}`)
+      return typeof value === 'number' ? new Decimal(value) : new Decimal(`${value}`)
path: packages/client-engine-runtime/src/interpreter/DataMapper.ts
user: login: jacek-prisma
body: the prisma client package already pulls in decimal.js as a dependency, so I think most users will end up with the dependency anyway
https://github.com/prisma/prisma/blob/main/packages/client/package.json#L263
created_at: 2025-05-08T20:01:14Z
author_association: CONTRIBUTOR
diff_hunk: @@ -89,22 +91,28 @@ function mapValue(value: unknown, resultType: PrismaValueType): unknown {
     case 'Boolean':
       return typeof value === 'boolean' ? value : value !== '0'
     case 'Decimal':
-      return typeof value === 'number' ? value : parseFloat(`${value}`)
+      return typeof value === 'number' ? new Decimal(value) : new Decimal(`${value}`)
path: packages/client-engine-runtime/src/interpreter/DataMapper.ts
user: login: semoal
body: Ahh cool in that case, thought that was installed for the new qc 👌
created_at: 2025-05-08T20:07:35Z
author_association: NONE
diff_hunk: @@ -89,22 +91,22 @@ function mapValue(value: unknown, resultType: PrismaValueType): unknown {
     case 'Boolean':
       return typeof value === 'boolean' ? value : value !== '0'
     case 'Decimal':
-      return typeof value === 'number' ? value : parseFloat(`${value}`)
+      return typeof value === 'number' ? new Decimal(value) : new Decimal(`${value}`)
     case 'Date':
       return value instanceof Date ? value : new Date(`${value}`)
     case 'Array': {
       const values = value as unknown[]
-      return values.map((v) => {
-        mapValue(v, resultType.inner)
-      })
+      return values.map((v) => mapValue(v, resultType.inner))
     }
     case 'Object':
-      return typeof value === 'object' ? value : { value: value }
-    case 'Bytes':
-      if (typeof value !== 'string') {
-        throw new Error(`DataMapper: Bytes data is not a string, got: ${typeof value}`)
+      return typeof value === 'string' ? value : JSON.stringify(value)
+    case 'Bytes': {
+      if (!Array.isArray(value)) {
+        throw new Error(`DataMapper: Bytes data is invalid, got: ${typeof value}`)
       }
-      return value
+      const { buffer, byteOffset, byteLength } = Buffer.from(value)
+      return new Uint8Array(buffer, byteOffset, byteLength)
path: packages/client-engine-runtime/src/interpreter/DataMapper.ts
user: login: aqrln
body: You should be able to construct the `Uint8Array` directly in this case, the intermediate `Buffer` is only necessary to deserialize from base64
created_at: 2025-05-12T09:51:04Z
author_association: MEMBER
diff_hunk: @@ -89,22 +91,22 @@ function mapValue(value: unknown, resultType: PrismaValueType): unknown {
     case 'Boolean':
       return typeof value === 'boolean' ? value : value !== '0'
     case 'Decimal':
-      return typeof value === 'number' ? value : parseFloat(`${value}`)
+      return typeof value === 'number' ? new Decimal(value) : new Decimal(`${value}`)
     case 'Date':
       return value instanceof Date ? value : new Date(`${value}`)
     case 'Array': {
       const values = value as unknown[]
-      return values.map((v) => {
-        mapValue(v, resultType.inner)
-      })
+      return values.map((v) => mapValue(v, resultType.inner))
     }
     case 'Object':
-      return typeof value === 'object' ? value : { value: value }
-    case 'Bytes':
-      if (typeof value !== 'string') {
-        throw new Error(`DataMapper: Bytes data is not a string, got: ${typeof value}`)
+      return typeof value === 'string' ? value : JSON.stringify(value)
+    case 'Bytes': {
+      if (!Array.isArray(value)) {
+        throw new Error(`DataMapper: Bytes data is invalid, got: ${typeof value}`)
       }
-      return value
+      const { buffer, byteOffset, byteLength } = Buffer.from(value)
+      return new Uint8Array(buffer, byteOffset, byteLength)
path: packages/client-engine-runtime/src/interpreter/DataMapper.ts
user: login: jacek-prisma
body: done
created_at: 2025-05-12T09:59:46Z
author_association: CONTRIBUTOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-05-08T14:50:42Z
body: ## size-limit report 📦 
| Path                                                   | Size                   |
| ------------------------------------------------------ | ---------------------- |
| packages/client/runtime/library.js                     | 401.12 KB (+0.04% 🔺)  |
| packages/client/runtime/library.d.ts                   | 81 B (0%)              |
| packages/client/runtime/binary.js                      | 1.27 MB (+0.02% 🔺)    |
| packages/client/runtime/binary.d.ts                    | 26 B (0%)              |
| packages/client/runtime/edge.js                        | 335.86 KB (+0.05% 🔺)  |
| packages/client/runtime/edge-esm.js                    | 334.51 KB (+0.05% 🔺)  |
| packages/client/runtime/wasm.js                        | 281.49 KB (+0.06% 🔺)  |
| packages/client/runtime/index-browser.js               | 67.74 KB (0%)          |
| packages/client/runtime/index-browser.d.ts             | 89 B (0%)              |
| packages/cli/build/index.js                            | 2.97 MB (+0.01% 🔺)    |
| packages/client/prisma-client-0.0.0.tgz                | 5.93 MB (+0.01% 🔺)    |
| packages/cli/prisma-0.0.0.tgz                          | 6.19 MB (-0.01% 🔽)    |
| packages/bundle-size/da-workers-libsql/output.tgz      | 948.7 KB (+0.01% 🔺)   |
| packages/bundle-size/da-workers-neon/output.tgz        | 1 MB (+0.01% 🔺)       |
| packages/bundle-size/da-workers-pg/output.tgz          | 1.01 MB (+0.01% 🔺)    |
| packages/bundle-size/da-workers-pg-worker/output.tgz   | 1014.86 KB (+0.01% 🔺) |
| packages/bundle-size/da-workers-planetscale/output.tgz | 966.64 KB (+0.01% 🔺)  |
| packages/bundle-size/da-workers-d1/output.tgz          | 927.05 KB (+0.01% 🔺)  |
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-05-12T00:35:37Z
body: <!-- custom-engine -->
🔴 **CUSTOM ENGINE IS USED**
This PR is using custom engine:

Branch: [`fix/fixing-invalid-results`](https://github.com/prisma/prisma-engines/tree/fix/fixing-invalid-results)
Commit: [`cda67f2634ba0110562bdb90079a5d0855a37ae4`](https://github.com/prisma/prisma-engines/commit/cda67f2634ba0110562bdb90079a5d0855a37ae4).

Don't forget to remove `/engine-branch` command from PR body and re-run the tests with default engine before merging.
author_association: CONTRIBUTOR