@vitaly-t answer explain everything!
For implicit global conversion on postgree (solution 3) of @vitaly-t answer.
Here what you need to know:
const typesBuiltins = {
BOOL: 16,
BYTEA: 17,
CHAR: 18,
INT8: 20,
INT2: 21,
INT4: 23,
REGPROC: 24,
TEXT: 25,
OID: 26,
TID: 27,
XID: 28,
CID: 29,
JSON: 114,
XML: 142,
PG_NODE_TREE: 194,
SMGR: 210,
PATH: 602,
POLYGON: 604,
CIDR: 650,
FLOAT4: 700,
FLOAT8: 701,
ABSTIME: 702,
RELTIME: 703,
TINTERVAL: 704,
CIRCLE: 718,
MACADDR8: 774,
MONEY: 790,
MACADDR: 829,
INET: 869,
ACLITEM: 1033,
BPCHAR: 1042,
VARCHAR: 1043,
DATE: 1082,
TIME: 1083,
TIMESTAMP: 1114,
TIMESTAMPTZ: 1184,
INTERVAL: 1186,
TIMETZ: 1266,
BIT: 1560,
VARBIT: 1562,
NUMERIC: 1700,
REFCURSOR: 1790,
REGPROCEDURE: 2202,
REGOPER: 2203,
REGOPERATOR: 2204,
REGCLASS: 2205,
REGTYPE: 2206,
UUID: 2950,
TXID_SNAPSHOT: 2970,
PG_LSN: 3220,
PG_NDISTINCT: 3361,
PG_DEPENDENCIES: 3402,
TSVECTOR: 3614,
TSQUERY: 3615,
GTSVECTOR: 3642,
REGCONFIG: 3734,
REGDICTIONARY: 3769,
JSONB: 3802,
REGNAMESPACE: 4089,
REGROLE: 4096
};
Which you can find here
https://github.com/brianc/node-pg-types/blob/master/lib/builtins.js
Normaly you can access it this way
const pg = require('pg');
pg.types.setTypeParser(pg.types.builtins.INT8, (value: string) => {
return parseInt(value);
});
pg.types.setTypeParser(pg.types.builtins.FLOAT8, (value: string) => {
return parseFloat(value);
});
pg.types.setTypeParser(pg.types.builtins.NUMERIC, (value: string) => {
return parseFloat(value);
});
That normaly will handle all numeric data.
If for some reason pg.types.builtins is not accessible (in my case in typescript for some reason). You can just copy past it. Or use the corresponding mapped number directly.
update (to avoid confusion)
As by now "pg": "^7.11.0".
pg is using pg-types 2.0.1 which doesn't includes builtins at all.
And so does all the version before.
This lead to the access pg.types.builtins.
being not viable (in any of the version up to the one mentioned).
The solutions as i mentioned before is to copy past the mapping as i did in my current project. (check the snippet all above to copy it)
Or to use the corresponding mapping directly given the list.
pgp.pg.types.setTypeParser(20, parseInt);
Another solution as a workaround is to use the pg-types package directly. In it's latest version.
const types = require('pg-types');
// types.builtins.INT8
Otherwise a PR is filled by @vitaly-t which can be seen in the link bellow:
https://github.com/brianc/node-postgres/pull/1937/commits/c7666214833715ac2494b81865cfe1ea7cef9289
Which update the version of pg-types
withing pg
package (node-postgres) .
So once it's accepted. The initials examples will start working.
Note that my source initially was the official README of pg-types
:
https://github.com/brianc/node-pg-types
Another and last note:
This one concern the use of typescript.
pg-types
typescript typing doesn't include builtins as with the current version "pg-types": "^2.1.0"
. It's to be updated. So you either you add the typing yourself.
typeof types & {builtins: {[key in builtinsTypes]: number}}
where builtinsTypes is the union of all the properties names.
(however i just find copy pasting the hole object faster, shorter and cleaner).
You can do that with an enum as bellow
enum TypeId {
BOOL = 16,
BYTEA = 17,
CHAR = 18,
INT8 = 20,
INT2 = 21,
INT4 = 23,
REGPROC = 24,
TEXT = 25,
OID = 26,
TID = 27,
XID = 28,
CID = 29,
JSON = 114,
XML = 142,
PG_NODE_TREE = 194,
SMGR = 210,
PATH = 602,
POLYGON = 604,
CIDR = 650,
FLOAT4 = 700,
FLOAT8 = 701,
ABSTIME = 702,
RELTIME = 703,
TINTERVAL = 704,
CIRCLE = 718,
MACADDR8 = 774,
MONEY = 790,
MACADDR = 829,
INET = 869,
ACLITEM = 1033,
BPCHAR = 1042,
VARCHAR = 1043,
DATE = 1082,
TIME = 1083,
TIMESTAMP = 1114,
TIMESTAMPTZ = 1184,
INTERVAL = 1186,
TIMETZ = 1266,
BIT = 1560,
VARBIT = 1562,
NUMERIC = 1700,
REFCURSOR = 1790,
REGPROCEDURE = 2202,
REGOPER = 2203,
REGOPERATOR = 2204,
REGCLASS = 2205,
REGTYPE = 2206,
UUID = 2950,
TXID_SNAPSHOT = 2970,
PG_LSN = 3220,
PG_NDISTINCT = 3361,
PG_DEPENDENCIES = 3402,
TSVECTOR = 3614,
TSQUERY = 3615,
GTSVECTOR = 3642,
REGCONFIG = 3734,
REGDICTIONARY = 3769,
JSONB = 3802,
REGNAMESPACE = 4089,
REGROLE = 4096
}
as done within pg-promise
https://github.com/vitaly-t/pg-promise/blob/v9/typescript/pg-subset.d.ts#L103
Once everything updated. The use from pg is the way to go.
Update
The package was updated. And you can use it as expected.
import { types } from 'pg';
// data parsing
types.setTypeParser(types.builtins.INT8, (value: string) => {
return parseInt(value);
});
types.setTypeParser(types.builtins.FLOAT8, (value: string) => {
return parseFloat(value);
});
types.setTypeParser(types.builtins.NUMERIC, (value: string) => {
return parseFloat(value);
});
Also go check part UPDATE-2 of the above vitaly-t answer
https://mcmap.net/q/330998/-pg-promise-returns-integers-as-strings
Do not know how to serialize a BigInt
while dealing with queries withCOUNT(*)
. I see that simply typecasting in the query works fine. Something like'SELECT count(*)::int as value ...
. Would you recommend not doing so? – Fancied