node-postgres icon indicating copy to clipboard operation
node-postgres copied to clipboard

Inconsistent deserialization of numeric arrays

Open abernatskiy opened this issue 2 years ago • 2 comments

Hello! Hailing from @subsquid.

We've ran into an issue related to how pg handles numeric arrays. Unlike numeric scalars that are returned as strings, arrays are decoded into number s, truncating them if they are too long. This blocks support of wide numeric types in one of our projects.

The issue would be fixed by bumping the pg-types dependency to ^4.0.1. @brianc would you be willing to make this breaking change?


MRE: the following code

import pg from 'pg'
const { Client } = pg

const client = new Client()
await client.connect()

const createRes = await client.query(`
  create table "data" (
    "id" character varying NOT NULL,
    "big_integer" numeric,
    "big_integer_array" numeric array,
    "big_decimal" numeric,
    "big_decimal_array" numeric array)
`)

const insertRes = await client.query(
  "insert into data(id, big_integer, big_integer_array, big_decimal, big_decimal_array) values ($1, $2, $3, $4, $5)",
  [
    '1',
    '235432654766387365825634725462354632415634256415',
    '{548475672624564363467645852462356253653263526, 143624567463865374563526346235765275237625}',
    '3246256752463256257248426773526737567.3252356235435234',
    '{23113462547634523152345.3241261246, 234234656435432635275276143614521354231.23416514613456}'
  ]
)

const res = await client.query('select * from data')
console.log(res.rows)

await client.end()

outputs

[
  {
    id: '1',
    big_integer: '235432654766387365825634725462354632415634256415',
    big_integer_array: [ 5.484756726245644e+44, 1.4362456746386537e+41 ],
    big_decimal: '3246256752463256257248426773526737567.3252356235435234',
    big_decimal_array: [ 2.3113462547634524e+22, 2.3423465643543264e+38 ]
  }
]

Easy to spot the inconsistency in returned value types and the truncation. Adding

  "overrides": {
    "pg-types": "^4.0.1"
  }

to package.json solves the issue. New output:

[
  {
    id: '1',
    big_integer: '23543',
    big_integer_array: [
      '548475672624564363467645852462356253653263526',
      '143624567463865374563526346235765275237625'
    ],
    big_decimal: '3246256752463256257248426773526737567.3252356235435234',
    big_decimal_array: [
      '23113462547634523152345.3241261246',
      '234234656435432635275276143614521354231.23416514613456'
    ]
  }
]

abernatskiy avatar Nov 06 '23 16:11 abernatskiy

I've also been encountering this issue. I raised an issue in the pg-types repo (https://github.com/brianc/node-pg-types/issues/151) but was advised to raise it here as it has already been resolved in pg-types.

jamesopstad avatar Mar 06 '24 15:03 jamesopstad

@jamesopstad While waiting for a new major version of pg, you should be able to use the new version of pg-types manually by adding it to your own project’s dependencies and passing it as an option, like

const types = require('pg-types');

const pool = new pg.Pool({
    ⋮
    types,
});

charmander avatar Mar 10 '24 07:03 charmander