From f551a86c0f43193e87a5fb4e2ad7bb02ce77cbff Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 26 Sep 2015 13:23:55 -0700 Subject: [PATCH] Expose containing schema for custom types --- src/lib.rs | 21 ++++++++++++++------- src/types/mod.rs | 9 ++++++++- tests/test.rs | 1 + 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 917d8176..b0d40ba3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -455,10 +455,12 @@ impl InnerConnection { fn setup_typeinfo_query(&mut self) -> result::Result<(), ConnectError> { match self.raw_prepare(TYPEINFO_QUERY, - "SELECT t.typname, t.typelem, r.rngsubtype \ + "SELECT t.typname, t.typelem, r.rngsubtype, n.nspname \ FROM pg_catalog.pg_type t \ LEFT OUTER JOIN pg_catalog.pg_range r \ ON r.rngtypid = t.oid \ + INNER JOIN pg_catalog.pg_namespace n \ + ON t.typnamespace = n.oid \ WHERE t.oid = $1") { Ok(..) => return Ok(()), Err(Error::IoError(e)) => return Err(ConnectError::IoError(e)), @@ -469,9 +471,11 @@ impl InnerConnection { } match self.raw_prepare(TYPEINFO_QUERY, - "SELECT typname, typelem, NULL::OID \ - FROM pg_catalog.pg_type \ - WHERE oid = $1") { + "SELECT t.typname, t.typelem, NULL::OID, n.nspname \ + FROM pg_catalog.pg_type t \ + INNER JOIN pg_catalog.pg_namespace n \ + ON t.typnamespace = n.oid \ + WHERE t.oid = $1") { Ok(..) => Ok(()), Err(Error::IoError(e)) => Err(ConnectError::IoError(e)), Err(Error::DbError(e)) => Err(ConnectError::DbError(e)), @@ -696,7 +700,7 @@ impl InnerConnection { } _ => bad_response!(self) } - let (name, elem_oid, rngsubtype): (String, Oid, Option) = + let (name, elem_oid, rngsubtype, schema): (String, Oid, Option, String) = match try!(self.read_message()) { DataRow { row } => { let ctx = SessionInfo::new(self); @@ -708,6 +712,9 @@ impl InnerConnection { &ctx)), try!(FromSql::from_sql_nullable(&Type::Oid, row[2].as_ref().map(|r| &**r).as_mut(), + &ctx)), + try!(FromSql::from_sql_nullable(&Type::Name, + row[3].as_ref().map(|r| &**r).as_mut(), &ctx))) } ErrorResponse { fields } => { @@ -735,7 +742,7 @@ impl InnerConnection { } }; - let type_ = Type::Other(Box::new(Other::new(name, oid, kind))); + let type_ = Type::Other(Box::new(Other::new(name, oid, kind, schema))); self.unknown_types.insert(oid, type_.clone()); Ok(type_) } @@ -1337,7 +1344,7 @@ impl<'a> GenericConnection for Transaction<'a> { } trait OtherNew { - fn new(name: String, oid: Oid, kind: Kind) -> Other; + fn new(name: String, oid: Oid, kind: Kind, schema: String) -> Other; } trait DbErrorNew { diff --git a/src/types/mod.rs b/src/types/mod.rs index 9fc9bf82..85ebcec8 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -476,14 +476,16 @@ pub struct Other { name: String, oid: Oid, kind: Kind, + schema: String, } impl OtherNew for Other { - fn new(name: String, oid: Oid, kind: Kind) -> Other { + fn new(name: String, oid: Oid, kind: Kind, schema: String) -> Other { Other { name: name, oid: oid, kind: kind, + schema: schema, } } } @@ -503,6 +505,11 @@ impl Other { pub fn kind(&self) -> &Kind { &self.kind } + + /// The schema of this type. + pub fn schema(&self) -> &str { + &self.schema + } } /// An error indicating that a `NULL` Postgres value was passed to a `FromSql` diff --git a/tests/test.rs b/tests/test.rs index 35459f4c..4c1a034f 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -812,6 +812,7 @@ fn test_custom_range_element_type() { &Type::Other(ref u) => { assert_eq!("floatrange", u.name()); assert_eq!(&Kind::Range(Type::Float8), u.kind()); + assert_eq!("public", u.schema()); } t => panic!("Unexpected type {:?}", t) }