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

Precision loss on numbers close to MAX_SAFE_INTEGER on Postgres < 12 #3092

Open
SevInf opened this issue Nov 6, 2023 · 0 comments · May be fixed by #3093
Open

Precision loss on numbers close to MAX_SAFE_INTEGER on Postgres < 12 #3092

SevInf opened this issue Nov 6, 2023 · 0 comments · May be fixed by #3093

Comments

@SevInf
Copy link

SevInf commented Nov 6, 2023

To reproduce:

const assert = require("assert");
const { Client } = require("pg");
const pg = new Client("postgres://prisma:prisma@localhost:5432/tests");

async function main() {
  await pg.connect();

  try {
    const result = await pg.query({
      text: "SELECT $1::FLOAT8",
      values: [Number.MAX_SAFE_INTEGER],
    });
    assert.strictEqual(result.rows[0].float8, Number.MAX_SAFE_INTEGER);
  } finally {
    await pg.end();
  }
}

main();

If used with Postgres < 12, this fails with:

AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
+ actual - expected

+ 9007199254740990
- 9007199254740991

Postgres 12+ is fine.

This value can be correctly stored in both JS and Postgress without precision loss. I believe the problem is default extra_float_digits settings: pre-12, postgres rounded floats to 15 digits when outputting them as text, starting from 12 they switched default to outputting as many digits as necessary to preserve the precision. Setting extra_float_digits to 1 fixes the problem.

There was a similar issue, #730 that is marked as fixed. Might just not be the case for extremely large numbers.

SevInf added a commit to SevInf/node-postgres that referenced this issue Nov 6, 2023
Sets `extra_float_digits` setting to 1 when connecting to DB. For older
(<12) Postgres, this should be enough to cover all values JS can store
preciesely. For 12+ postgres this setting should have no effect.

Fix brianc#3092
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant