@@ -97,6 +97,7 @@ mod util;
9797pub mod types;
9898
9999const CANARY : u32 = 0xdeadbeef ;
100+ const TYPENAME_QUERY : & ' static str = "t" ;
100101
101102/// A type alias of the result returned by many methods.
102103pub type Result < T > = result:: Result < T , Error > ;
@@ -441,6 +442,13 @@ impl InnerConnection {
441442 }
442443 }
443444
445+ match conn. raw_prepare ( TYPENAME_QUERY , "SELECT typname FROM pg_type WHERE oid = $1" ) {
446+ Ok ( ..) => { }
447+ Err ( Error :: IoError ( e) ) => return Err ( ConnectError :: IoError ( e) ) ,
448+ Err ( Error :: DbError ( e) ) => return Err ( ConnectError :: DbError ( e) ) ,
449+ _ => unreachable ! ( )
450+ }
451+
444452 Ok ( conn)
445453 }
446454
@@ -580,10 +588,10 @@ impl InnerConnection {
580588 try!( self . wait_for_ready ( ) ) ;
581589
582590 // now that the connection is ready again, get unknown type names,
583- // but not if stmt_name is "" since that'll blow away the statement
584- // and we don't care about result values anyway
591+ try!( self . set_type_names ( param_types. iter_mut ( ) ) ) ;
592+ // An empty statement name means we're calling execute, so we don't
593+ // care about result types
585594 if stmt_name != "" {
586- try!( self . set_type_names ( param_types. iter_mut ( ) ) ) ;
587595 try!( self . set_type_names ( result_desc. iter_mut ( ) . map ( |d| & mut d. ty ) ) ) ;
588596 }
589597
@@ -665,9 +673,45 @@ impl InnerConnection {
665673 if let Some ( name) = self . unknown_types . get ( & oid) {
666674 return Ok ( name. clone ( ) ) ;
667675 }
668- let name = try!( self . quick_query ( & * format ! ( "SELECT typname FROM pg_type WHERE oid={}" ,
669- oid) ) )
670- . into_iter ( ) . next ( ) . unwrap ( ) . into_iter ( ) . next ( ) . unwrap ( ) . unwrap ( ) ;
676+ // Ew @ doing this manually :(
677+ try!( self . write_messages ( & [
678+ Bind {
679+ portal : "" ,
680+ statement : TYPENAME_QUERY ,
681+ formats : & [ 1 ] ,
682+ values : & [ try!( oid. to_sql ( & Type :: Oid ) ) ] ,
683+ result_formats : & [ 1 ]
684+ } ,
685+ Execute {
686+ portal : "" ,
687+ max_rows : 0 ,
688+ } ,
689+ Sync ] ) ) ;
690+ match try!( self . read_message ( ) ) {
691+ BindComplete => { }
692+ ErrorResponse { fields } => {
693+ try!( self . wait_for_ready ( ) ) ;
694+ return DbError :: new ( fields) ;
695+ }
696+ _ => bad_response ! ( self )
697+ }
698+ let name: String = match try!( self . read_message ( ) ) {
699+ DataRow { row } => try!( FromSql :: from_sql ( & Type :: Name , & row[ 0 ] ) ) ,
700+ ErrorResponse { fields } => {
701+ try!( self . wait_for_ready ( ) ) ;
702+ return DbError :: new ( fields) ;
703+ }
704+ _ => bad_response ! ( self )
705+ } ;
706+ match try!( self . read_message ( ) ) {
707+ CommandComplete { .. } => { }
708+ ErrorResponse { fields } => {
709+ try!( self . wait_for_ready ( ) ) ;
710+ return DbError :: new ( fields) ;
711+ }
712+ _ => bad_response ! ( self )
713+ }
714+ try!( self . wait_for_ready ( ) ) ;
671715 self . unknown_types . insert ( oid, name. clone ( ) ) ;
672716 Ok ( name)
673717 }
0 commit comments