Skip to content

Commit 4c46f9f

Browse files
committed
Adjust Type::Enum to carry the variants
1 parent bdb8513 commit 4c46f9f

File tree

3 files changed

+45
-5
lines changed

3 files changed

+45
-5
lines changed

src/lib.rs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ pub mod types;
9898
pub mod notification;
9999

100100
const TYPEINFO_QUERY: &'static str = "__typeinfo";
101+
const TYPEINFO_ENUM_QUERY: &'static str = "__typeinfo_enum";
101102
const TYPEINFO_ARRAY_QUERY: &'static str = "__typeinfo_array";
102103

103104
/// A type alias of the result returned by many methods.
@@ -464,12 +465,23 @@ impl InnerConnection {
464465

465466
#[cfg_attr(rustfmt, rustfmt_skip)]
466467
fn setup_typeinfo_query(&mut self) -> result::Result<(), ConnectError> {
468+
match self.raw_prepare(TYPEINFO_ENUM_QUERY,
469+
"SELECT enumlabel \
470+
FROM pg_catalog.pg_enum \
471+
WHERE enumtypid = $1 \
472+
ORDER BY enumsortorder") {
473+
Ok(..) => {}
474+
Err(Error::Io(e)) => return Err(ConnectError::Io(e)),
475+
Err(Error::Db(e)) => return Err(ConnectError::Db(e)),
476+
Err(Error::Conversion(_)) => unreachable!(),
477+
}
478+
467479
match self.raw_prepare(TYPEINFO_ARRAY_QUERY,
468480
"SELECT attname, atttypid \
469481
FROM pg_catalog.pg_attribute \
470482
WHERE attrelid = $1 \
471-
AND NOT attisdropped \
472-
AND attnum > 0 \
483+
AND NOT attisdropped \
484+
AND attnum > 0 \
473485
ORDER BY attnum") {
474486
Ok(..) => {}
475487
Err(Error::Io(e)) => return Err(ConnectError::Io(e)),
@@ -865,7 +877,19 @@ impl InnerConnection {
865877
};
866878

867879
let kind = if type_ == b'e' as i8 {
868-
Kind::Enum
880+
try!(self.raw_execute(TYPEINFO_ENUM_QUERY, "", 0, &[Type::Oid], &[&oid]));
881+
let mut rows = VecDeque::new();
882+
try!(self.read_rows(&mut rows));
883+
884+
let ctx = SessionInfo::new(self);
885+
let mut variants = vec![];
886+
for row in rows {
887+
variants.push(try!(String::from_sql(&Type::Name,
888+
&mut &**row[0].as_ref().unwrap(),
889+
&ctx)));
890+
}
891+
892+
Kind::Enum(variants)
869893
} else if type_ == b'p' as i8 {
870894
Kind::Pseudo
871895
} else if basetype != 0 {

src/types/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,8 @@ pub type Oid = u32;
105105
pub enum Kind {
106106
/// A simple type like `VARCHAR` or `INTEGER`.
107107
Simple,
108-
/// An enumerated type.
109-
Enum,
108+
/// An enumerated type along with its variants.
109+
Enum(Vec<String>),
110110
/// A pseudo-type.
111111
Pseudo,
112112
/// An array type along with the type of its elements.

tests/types/mod.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,3 +307,19 @@ fn composite() {
307307
t => panic!("bad type {:?}", t),
308308
}
309309
}
310+
311+
#[test]
312+
fn enum_() {
313+
let conn = Connection::connect("postgres://postgres@localhost", SslMode::None).unwrap();
314+
conn.batch_execute("CREATE TYPE pg_temp.mood AS ENUM ('sad', 'ok', 'happy');").unwrap();
315+
316+
let stmt = conn.prepare("SELECT $1::mood").unwrap();
317+
let type_ = &stmt.param_types()[0];
318+
assert_eq!(type_.name(), "mood");
319+
match type_.kind() {
320+
&Kind::Enum(ref variants) => {
321+
assert_eq!(variants, &["sad".to_owned(), "ok".to_owned(), "happy".to_owned()]);
322+
}
323+
_ => panic!("bad type"),
324+
}
325+
}

0 commit comments

Comments
 (0)