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

_types is sent both to query parser and result leading to crash

Open charles-toller opened this issue 5 years ago • 1 comments

pg version: 8.3.0

I've contrived the example a bit here, but let's say I wanted to run the following statement:

UPDATE users
SET settings = CASE
                   WHEN $1 IS NULL THEN settings
                   ELSE jsonb_set($1, '{setting}', '[2, 3, 4]'::jsonb) END

Assume users is a table with a field settings of type jsonb. If I just run this outright, I get an error: could not determine data type of parameter $1. One solution is to add explicit type casts, like this:

UPDATE users
SET settings = CASE
                   WHEN $1::jsonb IS NULL THEN settings
                   ELSE jsonb_set($1, '{setting}', '[2, 3, 4]'::jsonb) END

The alternative is to make this a prepared statement with types, like so in pg:

client.query({
    name: "updateSettings",
    text: statement,
    types: [types.builtins.JSONB],
    values: {a: 1}
});

This actually works just fine. The crash occurs when I add a "RETURNING" statement to that query, so that I get rows back, pg crashes with the following exception:


.../node_modules/pg/lib/result.js:98
      this._parsers[i] = this._types.getTypeParser(desc.dataTypeID, desc.format || 'text')
                                     ^
TypeError: this._types.getTypeParser is not a function
    at Result.addFields (.../node_modules/pg/lib/result.js:98:38)
    at Query.handleRowDescription (.../node_modules/pg/lib/query.js:82:18)
    at Connection.<anonymous> (.../node_modules/pg/lib/client.js:324:22)
    at Connection.emit (events.js:314:20)
    at .../node_modules/pg/lib/connection.js:109:10
    at Parser.parse (.../node_modules/pg-protocol/src/parser.ts:102:9)
    at Socket.<anonymous> (.../node_modules/pg-protocol/src/index.ts:7:48)
    at Socket.emit (events.js:314:20)
    at addChunk (_stream_readable.js:304:12)
    at readableAddChunk (_stream_readable.js:280:9)

I believe this is caused by this line where the same types array that is sent to the query serializer is sent to the result parser for parsing overrides.

Is there a different key I can use on QueryConfig to inform the connection of the types of the prepared statement?

charles-toller avatar Jul 17 '20 22:07 charles-toller

Oh yuck - two different things using the same name on the query config it looks like. Unfortunately fixing this will likely be a breaking change I think.

brianc avatar Jul 24 '20 17:07 brianc