compare prepared statement text with previous to prevent incorrect queries (#1814)

* compare prepared statement text with previous to prevent incorrect queries - fixes #1813

* make suggested changes to error message
This commit is contained in:
Rich Harris 2019-03-06 10:35:30 -05:00 committed by Brian C
parent 4c6c0e9b77
commit e6a878cbb5
4 changed files with 21 additions and 2 deletions

View File

@ -276,7 +276,7 @@ Client.prototype._attachListeners = function (con) {
// it again on the same client
con.on('parseComplete', function (msg) {
if (self.activeQuery.name) {
con.parsedStatements[self.activeQuery.name] = true
con.parsedStatements[self.activeQuery.name] = self.activeQuery.text
}
})

View File

@ -139,12 +139,16 @@ NativeQuery.prototype.submit = function (client) {
// check if the client has already executed this named query
// if so...just execute it again - skip the planning phase
if (client.namedQueries[this.name]) {
if (this.text && client.namedQueries[this.name] !== this.text) {
const err = new Error(`Prepared statements must be unique - '${this.name}' was used for a different statement`)
return after(err)
}
return client.native.execute(this.name, values, after)
}
// plan the named query the first time, then execute it
return client.native.prepare(this.name, this.text, values.length, function (err) {
if (err) return after(err)
client.namedQueries[self.name] = true
client.namedQueries[self.name] = self.text
return self.native.execute(self.name, values, after)
})
} else if (this.values) {

View File

@ -148,6 +148,10 @@ Query.prototype.submit = function (connection) {
if (typeof this.text !== 'string' && typeof this.name !== 'string') {
return new Error('A query must have either text or a name. Supplying neither is unsupported.')
}
const previous = connection.parsedStatements[this.name]
if (this.text && previous && this.text !== previous) {
return new Error(`Prepared statements must be unique - '${this.name}' was used for a different statement`)
}
if (this.values && !Array.isArray(this.values)) {
return new Error('Query values must be an array')
}

View File

@ -56,6 +56,17 @@ var suite = new helper.Suite()
q.on('end', () => done())
})
suite.test('with same name, but with different text', function (done) {
client.query(new Query({
text: 'select name from person where age >= $1 and name LIKE $2',
name: queryName,
values: [30, '%n%']
}), assert.calls(err => {
assert.equal(err.message, `Prepared statements must be unique - '${queryName}' was used for a different statement`)
done()
}))
})
})()
;(function () {