2

I'm using Knex, which itself uses package "pg" (aka "node-postgres").

If you SELECT some rows from a table with a TEXT[] column, all is well... in JS you get an array of strings.

But if you're using a CITEXT[] column, instead you just get back a string in JS like:

"{First-element,Second-element}"

Normally when you want to instruct the pg package on how to return specific postgres types, you can do something like this:

import {types} from 'pg';
types.setTypeParser(types.builtins.TIMESTAMPTZ, 'text');
types.setTypeParser(types.builtins.TIMESTAMP, 'text');
types.setTypeParser(types.builtins.DATE, 'text');
types.setTypeParser(types.builtins.TIME, 'text');
types.setTypeParser(types.builtins.TIMETZ, 'text');

The types.builtins.* constants have values that are hardcoded OID numbers for the known built-in types in postgres. Those OID numbers are the same across all postgres installations.

However due to the fact that CITEXT[] is an extension, the OID numbers for the CITEXT + CITEXT[] types will be different on every server, e.g. with the following SQL query:

SELECT typname, oid, typarray FROM pg_type WHERE typname like '%citext%';

On my development server I get:

typname|oid  |typarray|
-------|-----|--------|
citext |17459|17464   |
_citext|17464|0       |

But on my production server I get:

typname|oid  |typarray|
-------|-----|--------|
citext |18618|18623   |
_citext|18623|0       |

How can I solve this?

Some hacky options that I really don't want to do are:

  1. Find out all the different OID values for all my servers and hard code them in - very hacky and really don't want to do this.
  2. Write code specifically for every table/column that manually converts the strings to array - also hacky and repetitive
  3. When the node process initializes, get the server's OID value for the server and then call the types.setTypeParser() function with that dynamic value - also not very good

How can I solve this for all tables/columns without these hacky solutions?

0

1 Answer 1

1

I don't believe there is any way how to do it without querying DB.

I would probably query the correct OID number before starting the node app and store it to an environment variable and then initialize pg types with the value from process.env.

That is also a bit hacky, but at least the hack is mostly encapsulated out of the application code.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.