@@ -85,6 +85,7 @@ use std::collections::{VecDeque, HashMap};
8585use std:: fmt;
8686use std:: io;
8787use std:: mem;
88+ use std:: ops:: Range ;
8889use std:: result;
8990use std:: sync:: Arc ;
9091use std:: time:: Duration ;
@@ -488,7 +489,9 @@ impl InnerConnection {
488489 Ok ( ( param_types, columns) )
489490 }
490491
491- fn read_rows ( & mut self , buf : & mut VecDeque < Vec < Option < Vec < u8 > > > > ) -> Result < bool > {
492+ fn read_rows < F > ( & mut self , mut consumer : F ) -> Result < bool >
493+ where F : FnMut ( RowData )
494+ {
492495 let more_rows;
493496 loop {
494497 match try!( self . read_message ( ) ) {
@@ -502,8 +505,12 @@ impl InnerConnection {
502505 break ;
503506 }
504507 backend:: Message :: DataRow ( body) => {
505- let row = try!( body. values ( ) . map ( |v| v. map ( ToOwned :: to_owned) ) . collect ( ) ) ;
506- buf. push_back ( row) ;
508+ let mut row = RowData :: new ( ) ;
509+ let mut it = body. values ( ) ;
510+ while let Some ( value) = try!( it. next ( ) ) {
511+ row. push ( value) ;
512+ }
513+ consumer ( row) ;
507514 }
508515 backend:: Message :: ErrorResponse ( body) => {
509516 try!( self . wait_for_ready ( ) ) ;
@@ -694,12 +701,11 @@ impl InnerConnection {
694701 fn read_type ( & mut self , oid : Oid ) -> Result < Other > {
695702 try!( self . setup_typeinfo_query ( ) ) ;
696703 try!( self . raw_execute ( TYPEINFO_QUERY , "" , 0 , & [ Type :: Oid ] , & [ & oid] ) ) ;
697- let mut rows = VecDeque :: new ( ) ;
698- try!( self . read_rows ( & mut rows) ) ;
699- let row = rows. pop_front ( ) ;
704+ let mut row = None ;
705+ try!( self . read_rows ( |r| row = Some ( r) ) ) ;
700706
701707 let get_raw = |i : usize | {
702- row. as_ref ( ) . and_then ( |r| r. get ( i) ) . and_then ( |r| r . as_ref ( ) . map ( |r| & * * r ) )
708+ row. as_ref ( ) . and_then ( |r| r. get ( i) )
703709 } ;
704710
705711 let ( name, type_, elem_oid, rngsubtype, basetype, schema, relid) = {
@@ -770,14 +776,13 @@ impl InnerConnection {
770776 fn read_enum_variants ( & mut self , oid : Oid ) -> Result < Vec < String > > {
771777 try!( self . setup_typeinfo_enum_query ( ) ) ;
772778 try!( self . raw_execute ( TYPEINFO_ENUM_QUERY , "" , 0 , & [ Type :: Oid ] , & [ & oid] ) ) ;
773- let mut rows = VecDeque :: new ( ) ;
774- try!( self . read_rows ( & mut rows) ) ;
779+ let mut rows = vec ! [ ] ;
780+ try!( self . read_rows ( |row| rows. push ( row ) ) ) ;
775781
776782 let ctx = SessionInfo :: new ( & self . parameters ) ;
777783 let mut variants = vec ! [ ] ;
778784 for row in rows {
779- let raw = row. get ( 0 ) . and_then ( |r| r. as_ref ( ) . map ( |r| & * * r) ) ;
780- variants. push ( try!( String :: from_sql_nullable ( & Type :: Name , raw, & ctx)
785+ variants. push ( try!( String :: from_sql_nullable ( & Type :: Name , row. get ( 0 ) , & ctx)
781786 . map_err ( Error :: Conversion ) ) ) ;
782787 }
783788
@@ -804,17 +809,16 @@ impl InnerConnection {
804809 fn read_composite_fields ( & mut self , relid : Oid ) -> Result < Vec < Field > > {
805810 try!( self . setup_typeinfo_composite_query ( ) ) ;
806811 try!( self . raw_execute ( TYPEINFO_COMPOSITE_QUERY , "" , 0 , & [ Type :: Oid ] , & [ & relid] ) ) ;
807- let mut rows = VecDeque :: new ( ) ;
808- try!( self . read_rows ( & mut rows) ) ;
812+ let mut rows = vec ! [ ] ;
813+ try!( self . read_rows ( |row| rows. push ( row ) ) ) ;
809814
810815 let mut fields = vec ! [ ] ;
811816 for row in rows {
812817 let ( name, type_) = {
813- let get_raw = |i : usize | row. get ( i) . and_then ( |r| r. as_ref ( ) . map ( |r| & * * r) ) ;
814818 let ctx = SessionInfo :: new ( & self . parameters ) ;
815- let name = try!( String :: from_sql_nullable ( & Type :: Name , get_raw ( 0 ) , & ctx)
819+ let name = try!( String :: from_sql_nullable ( & Type :: Name , row . get ( 0 ) , & ctx)
816820 . map_err ( Error :: Conversion ) ) ;
817- let type_ = try!( Oid :: from_sql_nullable ( & Type :: Oid , get_raw ( 1 ) , & ctx)
821+ let type_ = try!( Oid :: from_sql_nullable ( & Type :: Oid , row . get ( 1 ) , & ctx)
818822 . map_err ( Error :: Conversion ) ) ;
819823 ( name, type_)
820824 } ;
@@ -1329,6 +1333,43 @@ impl<'a> GenericConnection for Transaction<'a> {
13291333 }
13301334}
13311335
1336+ struct RowData {
1337+ buf : Vec < u8 > ,
1338+ indices : Vec < Option < Range < usize > > > ,
1339+ }
1340+
1341+ impl RowData {
1342+ fn new ( ) -> RowData {
1343+ RowData {
1344+ buf : vec ! [ ] ,
1345+ indices : vec ! [ ] ,
1346+ }
1347+ }
1348+
1349+ fn push ( & mut self , cell : Option < & [ u8 ] > ) {
1350+ let index = match cell {
1351+ Some ( cell) => {
1352+ let base = self . buf . len ( ) ;
1353+ self . buf . extend_from_slice ( cell) ;
1354+ Some ( base..self . buf . len ( ) )
1355+ }
1356+ None => None ,
1357+ } ;
1358+ self . indices . push ( index) ;
1359+ }
1360+
1361+ fn len ( & self ) -> usize {
1362+ self . indices . len ( )
1363+ }
1364+
1365+ fn get ( & self , index : usize ) -> Option < & [ u8 ] > {
1366+ match & self . indices [ index] {
1367+ & Some ( ref range) => Some ( & self . buf [ range. clone ( ) ] ) ,
1368+ & None => None ,
1369+ }
1370+ }
1371+ }
1372+
13321373trait OtherNew {
13331374 fn new ( name : String , oid : Oid , kind : Kind , schema : String ) -> Other ;
13341375}
@@ -1340,13 +1381,13 @@ trait DbErrorNew {
13401381}
13411382
13421383trait RowsNew < ' a > {
1343- fn new ( stmt : & ' a Statement < ' a > , data : Vec < Vec < Option < Vec < u8 > > > > ) -> Rows < ' a > ;
1344- fn new_owned ( stmt : Statement < ' a > , data : Vec < Vec < Option < Vec < u8 > > > > ) -> Rows < ' a > ;
1384+ fn new ( stmt : & ' a Statement < ' a > , data : Vec < RowData > ) -> Rows < ' a > ;
1385+ fn new_owned ( stmt : Statement < ' a > , data : Vec < RowData > ) -> Rows < ' a > ;
13451386}
13461387
13471388trait LazyRowsNew < ' trans , ' stmt > {
13481389 fn new ( stmt : & ' stmt Statement < ' stmt > ,
1349- data : VecDeque < Vec < Option < Vec < u8 > > > > ,
1390+ data : VecDeque < RowData > ,
13501391 name : String ,
13511392 row_limit : i32 ,
13521393 more_rows : bool ,
0 commit comments