Skip to content

Commit 64de6ab

Browse files
committed
Look up column names case insensitively
It tries a case sensitive comparison first so all existing uses should continue to be OK. It should really have some form of unicode awarenes but it's unclear exactly what. The JDBC driver uses the US locale when lowercasing and libpq uses tolower with the system locale. Closes #136
1 parent cb6a408 commit 64de6ab

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

src/rows.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Query result rows.
22
3+
use std::ascii::AsciiExt;
34
use std::fmt;
45
use std::collections::VecDeque;
56
use debug_builders::DebugStruct;
@@ -274,7 +275,14 @@ impl RowIndex for usize {
274275
impl<'a> RowIndex for &'a str {
275276
#[inline]
276277
fn idx(&self, stmt: &Statement) -> Option<usize> {
277-
stmt.columns().iter().position(|d| d.name == *self)
278+
if let Some(idx) = stmt.columns().iter().position(|d| d.name == *self) {
279+
return Some(idx);
280+
};
281+
282+
// FIXME ASCII-only case insensitivity isn't really the right thing to
283+
// do. Postgres itself uses a dubious wrapper around tolower and JDBC
284+
// uses the US locale.
285+
stmt.columns().iter().position(|d| d.name.eq_ignore_ascii_case(*self))
278286
}
279287
}
280288

tests/test.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use postgres::error::SqlState::{SyntaxError,
2525
InvalidPassword,
2626
CardinalityViolation};
2727
use postgres::error::ErrorPosition::Normal;
28+
use postgres::rows::RowIndex;
2829

2930
macro_rules! or_panic {
3031
($e:expr) => (
@@ -886,3 +887,15 @@ fn test_rows_index() {
886887
assert_eq!(3, rows.len());
887888
assert_eq!(2i32, rows.get(1).get(0));
888889
}
890+
891+
#[test]
892+
fn test_row_case_insensitive() {
893+
let conn = Connection::connect("postgres://postgres@localhost", &SslMode::None).unwrap();
894+
conn.batch_execute("CREATE TEMPORARY TABLE foo (foo INT, \"bAr\" INT, \"Bar\" INT);").unwrap();
895+
let stmt = conn.prepare("SELECT * FROM foo").unwrap();
896+
assert_eq!(Some(0), "foo".idx(&stmt));
897+
assert_eq!(Some(0), "FOO".idx(&stmt));
898+
assert_eq!(Some(1), "bar".idx(&stmt));
899+
assert_eq!(Some(1), "bAr".idx(&stmt));
900+
assert_eq!(Some(2), "Bar".idx(&stmt));
901+
}

0 commit comments

Comments
 (0)