Skip to content

Commit 88fd547

Browse files
authored
Merge pull request diesel-rs#2652 from henryboisdequin/add-statement-pos-pg
Add the statement position for PostgreSQL errors
2 parents 113b523 + d1cdc0b commit 88fd547

4 files changed

Lines changed: 33 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ for Rust libraries in [RFC #1105](https://github.com/rust-lang/rfcs/blob/master/
5454

5555
* Added support for `UNION`, `UNION ALL`, `INTERSECT`, `INTERSECT ALL`, `EXCEPT`, `EXCEPT ALL` clauses
5656

57+
* Added the error position for PostgreSQL errors
58+
5759
### Removed
5860

5961
* All previously deprecated items have been removed.

diesel/src/pg/connection/mod.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,26 @@ mod tests {
185185
use super::*;
186186
use crate::dsl::sql;
187187
use crate::prelude::*;
188+
use crate::result::Error::DatabaseError;
188189
use crate::sql_types::{Integer, VarChar};
189190

191+
#[test]
192+
fn malformed_sql_query() {
193+
let connection = connection();
194+
let query =
195+
crate::sql_query("SELECT not_existent FROM also_not_there;").execute(&connection);
196+
if let Err(err) = query {
197+
match err {
198+
DatabaseError(_, string) => {
199+
assert_eq!(Some(26), string.statement_position());
200+
}
201+
_ => unreachable!(),
202+
}
203+
} else {
204+
unreachable!();
205+
}
206+
}
207+
190208
#[test]
191209
fn prepared_statements_are_cached() {
192210
let connection = connection();

diesel/src/pg/connection/result.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@ impl DatabaseErrorInformation for PgErrorInformation {
167167
fn constraint_name(&self) -> Option<&str> {
168168
get_result_field(self.0.as_ptr(), ResultField::ConstraintName)
169169
}
170+
171+
fn statement_position(&self) -> Option<i32> {
172+
let str_pos = get_result_field(self.0.as_ptr(), ResultField::StatementPosition)?;
173+
str_pos.parse::<i32>().ok()
174+
}
170175
}
171176

172177
/// Represents valid options to
@@ -182,6 +187,7 @@ enum ResultField {
182187
TableName = 't' as i32,
183188
ColumnName = 'c' as i32,
184189
ConstraintName = 'n' as i32,
190+
StatementPosition = 'P' as i32,
185191
}
186192

187193
fn get_result_field<'a>(res: *mut PGresult, field: ResultField) -> Option<&'a str> {

diesel/src/result.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,10 @@ pub trait DatabaseErrorInformation {
156156
/// Currently this method will return `None` for all backends other than
157157
/// PostgreSQL.
158158
fn constraint_name(&self) -> Option<&str>;
159+
160+
/// An optional integer indicating an error cursor position as an index into
161+
/// the original statement string.
162+
fn statement_position(&self) -> Option<i32>;
159163
}
160164

161165
impl fmt::Debug for dyn DatabaseErrorInformation + Send + Sync {
@@ -168,7 +172,6 @@ impl DatabaseErrorInformation for String {
168172
fn message(&self) -> &str {
169173
self
170174
}
171-
172175
fn details(&self) -> Option<&str> {
173176
None
174177
}
@@ -184,6 +187,9 @@ impl DatabaseErrorInformation for String {
184187
fn constraint_name(&self) -> Option<&str> {
185188
None
186189
}
190+
fn statement_position(&self) -> Option<i32> {
191+
None
192+
}
187193
}
188194

189195
/// Errors which can occur during [`Connection::establish`]

0 commit comments

Comments
 (0)