From 47b0c69d356277d9cf28fa85ddf3997579915021 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 13 Feb 2016 21:51:37 -0800 Subject: [PATCH] Add enum and pseudo type kinds --- src/lib.rs | 27 ++++++++++++++++++--------- src/types/mod.rs | 36 ++++++++++++++++++++---------------- 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 7509fa39..5c2f9376 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -464,7 +464,8 @@ impl InnerConnection { #[cfg_attr(rustfmt, rustfmt_skip)] fn setup_typeinfo_query(&mut self) -> result::Result<(), ConnectError> { match self.raw_prepare(TYPEINFO_QUERY, - "SELECT t.typname, t.typelem, r.rngsubtype, t.typbasetype, n.nspname \ + "SELECT t.typname, t.typtype, t.typelem, r.rngsubtype, \ + t.typbasetype, n.nspname \ FROM pg_catalog.pg_type t \ LEFT OUTER JOIN pg_catalog.pg_range r ON \ r.rngtypid = t.oid \ @@ -480,7 +481,8 @@ impl InnerConnection { } match self.raw_prepare(TYPEINFO_QUERY, - "SELECT t.typname, t.typelem, NULL::OID, t.typbasetype, n.nspname \ + "SELECT t.typname, t.typtype, t.typelem, NULL::OID, t.typbasetype, \ + n.nspname \ FROM pg_catalog.pg_type t \ INNER JOIN pg_catalog.pg_namespace n \ ON t.typnamespace = n.oid \ @@ -751,26 +753,29 @@ impl InnerConnection { } _ => bad_response!(self), } - let (name, elem_oid, rngsubtype, basetype, schema) = match try!(self.read_message()) { + let (name, type_, elem_oid, rngsubtype, basetype, schema) = match try!(self.read_message()) { DataRow { row } => { let ctx = SessionInfo::new(self); let name = try!(String::from_sql(&Type::Name, &mut &**row[0].as_ref().unwrap(), &ctx)); + let type_ = try!(i8::from_sql(&Type::Char, + &mut &**row[1].as_ref().unwrap(), + &ctx)); let elem_oid = try!(Oid::from_sql(&Type::Oid, - &mut &**row[1].as_ref().unwrap(), + &mut &**row[2].as_ref().unwrap(), &ctx)); - let rngsubtype = match row[2] { + let rngsubtype = match row[3] { Some(ref data) => try!(Option::::from_sql(&Type::Oid, &mut &**data, &ctx)), None => try!(Option::::from_sql_null(&Type::Oid, &ctx)), }; let basetype = try!(Oid::from_sql(&Type::Oid, - &mut &**row[3].as_ref().unwrap(), + &mut &**row[4].as_ref().unwrap(), &ctx)); let schema = try!(String::from_sql(&Type::Name, - &mut &**row[4].as_ref().unwrap(), + &mut &**row[5].as_ref().unwrap(), &ctx)); - (name, elem_oid, rngsubtype, basetype, schema) + (name, type_, elem_oid, rngsubtype, basetype, schema) } ErrorResponse { fields } => { try!(self.wait_for_ready()); @@ -788,7 +793,11 @@ impl InnerConnection { } try!(self.wait_for_ready()); - let kind = if basetype != 0 { + let kind = if type_ == b'e' as i8 { + Kind::Enum + } else if type_ == b'p' as i8 { + Kind::Pseudo + } else if basetype != 0 { Kind::Domain(try!(self.get_type(basetype))) } else if elem_oid != 0 { Kind::Array(try!(self.get_type(elem_oid))) diff --git a/src/types/mod.rs b/src/types/mod.rs index 5094da2c..ced7fbcf 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -105,6 +105,10 @@ pub type Oid = u32; pub enum Kind { /// A simple type like `VARCHAR` or `INTEGER`. Simple, + /// An enumerated type. + Enum, + /// A pseudo-type. + Pseudo, /// An array type along with the type of its elements. Array(Type), /// A range type along with the type of its elements. @@ -431,29 +435,29 @@ make_postgres_type! { /// REGTYPE[] 2211: "_regtype" => RegtypeArray: Kind::Array(Type::Regtype), /// RECORD - 2249: "record" => Record: Kind::Simple, + 2249: "record" => Record: Kind::Pseudo, /// CSTRING - 2275: "cstring" => Cstring: Kind::Simple, + 2275: "cstring" => Cstring: Kind::Pseudo, /// ANY - 2276: "any" => Any: Kind::Simple, + 2276: "any" => Any: Kind::Pseudo, /// ANYARRAY - 2277: "anyarray" => AnyArray: Kind::Array(Type::Any), + 2277: "anyarray" => AnyArray: Kind::Pseudo, /// VOID - 2278: "void" => Void: Kind::Simple, + 2278: "void" => Void: Kind::Pseudo, /// TRIGGER - 2279: "trigger" => Trigger: Kind::Simple, + 2279: "trigger" => Trigger: Kind::Pseudo, /// LANGUAGE_HANDLER - 2280: "language_handler" => LanguageHandler: Kind::Simple, + 2280: "language_handler" => LanguageHandler: Kind::Pseudo, /// INTERNAL - 2281: "internal" => Internal: Kind::Simple, + 2281: "internal" => Internal: Kind::Pseudo, /// OPAQUE - 2282: "opaque" => Opaque: Kind::Simple, + 2282: "opaque" => Opaque: Kind::Pseudo, /// ANYELEMENT - 2283: "anyelement" => Anyelement: Kind::Simple, + 2283: "anyelement" => Anyelement: Kind::Pseudo, /// RECORD[] - 2287: "_record" => RecordArray: Kind::Array(Type::Record), + 2287: "_record" => RecordArray: Kind::Pseudo, /// ANYNONARRAY - 2776: "anynonarray" => Anynonarray: Kind::Simple, + 2776: "anynonarray" => Anynonarray: Kind::Pseudo, /// TXID_SNAPSHOT[] 2949: "_txid_snapshot" => TxidSnapshotArray: Kind::Array(Type::TxidSnapshot), /// UUID - UUID datatype @@ -463,13 +467,13 @@ make_postgres_type! { /// UUID[] 2951: "_uuid" => UuidArray: Kind::Array(Type::Uuid), /// FDW_HANDLER - 3115: "fdw_handler" => FdwHandler: Kind::Simple, + 3115: "fdw_handler" => FdwHandler: Kind::Pseudo, /// PG_LSN - PostgreSQL LSN datatype 3220: "pg_lsn" => PgLsn: Kind::Simple, /// PG_LSN[] 3221: "_pg_lsn" => PgLsnArray: Kind::Array(Type::PgLsn), /// ANYENUM - 3500: "anyenum" => Anyenum: Kind::Simple, + 3500: "anyenum" => Anyenum: Kind::Pseudo, /// TSVECTOR - text representation for text search 3614: "tsvector" => Tsvector: Kind::Simple, /// TSQUERY - query representation for text search @@ -493,7 +497,7 @@ make_postgres_type! { /// JSONB 3802: "jsonb" => Jsonb: Kind::Simple, /// ANYRANGE - 3831: "anyrange" => Anyrange: Kind::Simple, + 3831: "anyrange" => Anyrange: Kind::Pseudo, /// JSONB[] 3807: "_jsonb" => JsonbArray: Kind::Array(Type::Jsonb), /// INT4RANGE - range of integers @@ -521,7 +525,7 @@ make_postgres_type! { /// INT8RANGE[] 3927: "_int8range" => Int8RangeArray: Kind::Array(Type::Int8Range), /// EVENT_TRIGGER - 3838: "event_trigger" => EventTrigger: Kind::Simple + 3838: "event_trigger" => EventTrigger: Kind::Pseudo } /// Information about an unknown type.