diff --git a/packages/pg/lib/client.js b/packages/pg/lib/client.js index 2b13c1de7..7d0cbda31 100644 --- a/packages/pg/lib/client.js +++ b/packages/pg/lib/client.js @@ -438,6 +438,12 @@ class Client extends EventEmitter { if (activeQuery.name) { delete this.connection.submittedNamedStatements[activeQuery.name] } + // A paged query drives the portal with flush instead of sync, so on error + // the backend is still ignoring everything until a sync arrives. Send it + // here or ReadyForQuery never comes and the connection stays wedged. + if (activeQuery.rows) { + this.connection.sync() + } activeQuery.handleError(msg, this.connection) } diff --git a/packages/pg/test/integration/gh-issues/3707-tests.js b/packages/pg/test/integration/gh-issues/3707-tests.js new file mode 100644 index 000000000..f01641e9c --- /dev/null +++ b/packages/pg/test/integration/gh-issues/3707-tests.js @@ -0,0 +1,27 @@ +const helper = require('../test-helper') +const assert = require('assert') + +const suite = new helper.Suite() + +// the rows option drives the portal with flush instead of sync, which the native client does not do +if (helper.args.native) { + return +} + +suite.test('an error during a rows-limited query does not wedge the connection', async () => { + const client = new helper.pg.Client() + await client.connect() + + await assert.rejects( + client.query({ + text: 'select 10 / (5 - i) as v from generate_series(1, 7) g(i)', + rows: 2, + }), + /division by zero/ + ) + + const { rows } = await client.query('select 1 as v') + assert.equal(rows[0].v, 1) + + await client.end() +})