vercel / storage

Vercel Postgres, KV, Blob, and Edge Config
https://vercel.com/storage
Apache License 2.0
485 stars 53 forks source link

Postgres: Cannot use type parser using `createPool` or `db.connect` #635

Open mattorchard opened 4 months ago

mattorchard commented 4 months ago

There seems to be no way to override the type parser other than createClient (which then requires manually closing connections).

I assume this is a bug for createPool, but also seems like the pg-types approach should work for compatibility sake.

Environment

Snippets

Supplying the type parser to createPool has no impact.

const pool = createPool({
  types: {
    getTypeParser: (typeId, format) => {
      console.log("This function is never invoked");
    },
  },
});

Calling setTypeParser has no impact

import types from "pg-types";
types.setTypeParser(types.builtins.INT8, () => {
  console.log("This function is never invoked");
});

Create client on the on the other hand, does work. But this option is unappealing in many cases because that then requires manually closing the client connection.

const client = createClient({
  types: {
    getTypeParser: (typeId, format) => {
      console.log("This function is called as expected")
    },
  },
});

Further context

My actual use case is to override the bigint parser with one that converts it to a JS-float rather than a string. The following snippet technically works. But my specific setup does not have a great spot to close the DB connection, making it rather unappealing.

import types from "pg-types";

const integerParser = (value: string): number => {
  const int = parseInt(value);
  if (isNaN(int)) throw new Error(`Unable to parse integer "${value}"`);
  if (int >= Number.MAX_SAFE_INTEGER)
    throw new Error(`Integer "${value}" exceeds maximum safe size`);
  return int;
};

const client = createClient({
  types: {
    getTypeParser: (typeId, format) => {
      switch (typeId) {
        case types.builtins.INT8:
          return integerParser;
        default:
          return types.getTypeParser(typeId, format) as unknown;
      }
    },
  },
});
mattorchard commented 4 months ago

Did find a workaround: going direct to neon by adding it as a peer dep in my package.json

  "peerDependencies": {
    "@neondatabase/serverless": "0.7.2"
  },

and then overwriting the type parser that it exports

import { types } from "@neondatabase/serverless";
types.setTypeParser(types.builtins.INT8, integerParser);

@vercel/postgres could probably re-export the types to make this slightly less janky