Skip to content

Commit 591d47a

Browse files
authored
Recreate prepared statements if invalidated (porsager#195)
fixes porsager#120 ...
1 parent 8e675a3 commit 591d47a

File tree

3 files changed

+48
-2
lines changed

3 files changed

+48
-2
lines changed

lib/connection.js

+13-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const tls = require('tls')
33
const frontend = require('./frontend.js')
44
const Backend = require('./backend.js')
55
const Queue = require('./queue.js')
6-
const { END } = require('./types.js')
6+
const { END, retryRoutines } = require('./types.js')
77
const { errors } = require('./errors.js')
88

99
module.exports = Connection
@@ -128,8 +128,17 @@ function Connection(options = {}) {
128128
q.reject(err)
129129
}
130130

131+
function retry(query) {
132+
query.retried = true
133+
delete statements[query.sig]
134+
ready = true
135+
backend.query = backend.error = null
136+
send(query, { sig: query.sig, str: query.str, args: query.args })
137+
}
138+
131139
function send(query, { sig, str, args = [] }) {
132140
try {
141+
query.sig = sig
133142
query.str = str
134143
query.args = args
135144
query.result = []
@@ -204,6 +213,9 @@ function Connection(options = {}) {
204213
clearTimeout(connect_timer)
205214
if (err) {
206215
if (backend.query) {
216+
if (!backend.query.retried && retryRoutines[err.routine])
217+
return retry(backend.query)
218+
207219
err.stack += backend.query.origin.replace(/.*\n/, '\n')
208220
Object.defineProperty(err, 'query', {
209221
value: backend.query.str,

lib/types.js

+6
Original file line numberDiff line numberDiff line change
@@ -192,3 +192,9 @@ module.exports.errorFields = entries({
192192
L: 'line',
193193
R: 'routine'
194194
}).reduce(char, {})
195+
196+
module.exports.retryRoutines = {
197+
FetchPreparedStatement: true,
198+
RevalidateCachedQuery: true,
199+
transformAssignedExpr: true
200+
}

tests/index.js

+29-1
Original file line numberDiff line numberDiff line change
@@ -1421,6 +1421,7 @@ t('Copy from works in transaction', async() => {
14211421
})
14221422

14231423
t('Copy from abort works', async() => {
1424+
const sql = postgres(options)
14241425
const controller = new AbortController()
14251426
const readable = fs.createReadStream('copy.csv')
14261427

@@ -1438,5 +1439,32 @@ t('Copy from abort works', async() => {
14381439
controller.abort()
14391440
await sql.end()
14401441

1441-
return [aborted, true]
1442+
return [
1443+
aborted,
1444+
true,
1445+
await postgres(options)`drop table test`
1446+
]
1447+
})
1448+
1449+
t('Recreate prepared statements on transformAssignedExpr error', async() => {
1450+
const insert = () => sql`insert into test (name) values (${ '1' }) returning name`
1451+
await sql`create table test (name text)`
1452+
await insert()
1453+
await sql`alter table test alter column name type int using name::integer`
1454+
return [
1455+
1, (await insert())[0].name,
1456+
await sql`drop table test`
1457+
]
1458+
})
1459+
1460+
t('Recreate prepared statements on RevalidateCachedQuery error', async() => {
1461+
const select = () => sql`select name from test`
1462+
await sql`create table test (name text)`
1463+
await sql`insert into test values ('1')`
1464+
await select()
1465+
await sql`alter table test alter column name type int using name::integer`
1466+
return [
1467+
1, (await select())[0].name,
1468+
await sql`drop table test`
1469+
]
14421470
})

0 commit comments

Comments
 (0)