From b95299e47ceb884bd18a3ec2a2821f6b44551306 Mon Sep 17 00:00:00 2001 From: Marko Tiikkaja Date: Fri, 25 Jul 2014 03:00:28 +0200 Subject: [PATCH] Correctly handle ErrorResponse after one or more DataRows Previously, if a query failed with an ErrorResponse after the server had sent one or more DataRows, stmt.query() incorrectly returned PgBadResponse. Fix by handling the error correctly and returning it to the caller. --- src/lib/lib.rs | 4 ++++ src/test/test.rs | 20 +++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/lib/lib.rs b/src/lib/lib.rs index 338eb439..332d36c6 100644 --- a/src/lib/lib.rs +++ b/src/lib/lib.rs @@ -1316,6 +1316,10 @@ impl<'stmt> PostgresRows<'stmt> { break; }, DataRow { row } => self.data.push_back(row), + ErrorResponse { fields } => { + try!(self.stmt.conn.wait_for_ready()); + return Err(PgDbError(PostgresDbError::new(fields))); + } _ => { self.stmt.conn.conn.borrow_mut().desynchronized = true; return Err(PgBadResponse); diff --git a/src/test/test.rs b/src/test/test.rs index a022b8ba..b3f299b7 100644 --- a/src/test/test.rs +++ b/src/test/test.rs @@ -39,7 +39,8 @@ use postgres::error::{PgConnectDbError, QueryCanceled, UndefinedTable, InvalidCatalogName, - PgWrongTransaction}; + PgWrongTransaction, + CardinalityViolation}; use postgres::types::{ToSql, FromSql, PgInt4, PgVarchar}; use postgres::types::array::{ArrayBase}; use postgres::types::range::{Range, Inclusive, Exclusive, RangeBound}; @@ -361,6 +362,23 @@ fn test_query() { assert_eq!(vec![1i64, 2], result.map(|row| row.get(0u)).collect()); } +#[test] +fn test_error_after_datarow() { + let conn = or_fail!(PostgresConnection::connect("postgres://postgres@localhost", &NoSsl)); + let stmt = or_fail!(conn.prepare(" +SELECT + (SELECT generate_series(1, ss.i)) +FROM (SELECT gs.i + FROM generate_series(1, 2) gs(i) + ORDER BY gs.i + LIMIT 2) ss")); + match stmt.query([]) { + Err(PgDbError(PostgresDbError { code: CardinalityViolation, .. })) => {} + Err(err) => fail!("Unexpected error {}", err), + Ok(_) => fail!("Expected failure"), + } +} + #[test] fn test_result_finish() { let conn = or_fail!(PostgresConnection::connect("postgres://postgres@localhost", &NoSsl));