1
1
//! Conversions to and from Postgres's binary format for various types.
2
- use byteorder:: { ReadBytesExt , WriteBytesExt , BigEndian } ;
2
+ use byteorder:: { BigEndian , ByteOrder , ReadBytesExt , WriteBytesExt } ;
3
3
use fallible_iterator:: FallibleIterator ;
4
4
use std:: error:: Error ;
5
5
use std:: str;
6
6
use std:: boxed:: Box as StdBox ;
7
7
8
- use { Oid , IsNull , write_nullable , FromUsize } ;
8
+ use { write_nullable , FromUsize , IsNull , Oid } ;
9
9
10
10
const RANGE_UPPER_UNBOUNDED : u8 = 0b0001_0000 ;
11
11
const RANGE_LOWER_UNBOUNDED : u8 = 0b0000_1000 ;
@@ -189,9 +189,7 @@ where
189
189
}
190
190
191
191
let count = i32:: from_usize ( count) ?;
192
- ( & mut buf[ base..base + 4 ] )
193
- . write_i32 :: < BigEndian > ( count)
194
- . unwrap ( ) ;
192
+ BigEndian :: write_i32 ( & mut buf[ base..] , count) ;
195
193
196
194
Ok ( ( ) )
197
195
}
@@ -421,10 +419,11 @@ pub fn uuid_from_sql(buf: &[u8]) -> Result<[u8; 16], StdBox<Error + Sync + Send>
421
419
}
422
420
423
421
/// Serializes an array value.
422
+ // FIXME get rid of has_nulls argument (or make an option?)
424
423
#[ inline]
425
424
pub fn array_to_sql < T , I , J , F > (
426
425
dimensions : I ,
427
- has_nulls : bool ,
426
+ _has_nulls : bool ,
428
427
element_type : Oid ,
429
428
elements : J ,
430
429
mut serializer : F ,
@@ -437,7 +436,8 @@ where
437
436
{
438
437
let dimensions_idx = buf. len ( ) ;
439
438
buf. extend_from_slice ( & [ 0 ; 4 ] ) ;
440
- buf. write_i32 :: < BigEndian > ( has_nulls as i32 ) . unwrap ( ) ;
439
+ let has_nulls_idx = buf. len ( ) ;
440
+ buf. extend_from_slice ( & [ 0 ; 4 ] ) ;
441
441
buf. write_u32 :: < BigEndian > ( element_type) . unwrap ( ) ;
442
442
443
443
let mut num_dimensions = 0 ;
@@ -448,14 +448,26 @@ where
448
448
}
449
449
450
450
let num_dimensions = i32:: from_usize ( num_dimensions) ?;
451
- ( & mut buf[ dimensions_idx..dimensions_idx + 4 ] )
452
- . write_i32 :: < BigEndian > ( num_dimensions)
453
- . unwrap ( ) ;
451
+ BigEndian :: write_i32 ( & mut buf[ dimensions_idx..] , num_dimensions) ;
454
452
453
+ let mut has_nulls = false ;
455
454
for element in elements {
456
- write_nullable ( |buf| serializer ( element, buf) , buf) ?;
455
+ write_nullable (
456
+ |buf| match serializer ( element, buf) {
457
+ // this is kind of weird, but we want to only set has_nulls if we do actually have
458
+ // nulls to support arrays of non-null values on Postgres < 8.2
459
+ Ok ( IsNull :: Yes ) => {
460
+ has_nulls = true ;
461
+ Ok ( IsNull :: Yes )
462
+ }
463
+ r => r,
464
+ } ,
465
+ buf,
466
+ ) ?;
457
467
}
458
468
469
+ BigEndian :: write_i32 ( & mut buf[ has_nulls_idx..] , has_nulls as i32 ) ;
470
+
459
471
Ok ( ( ) )
460
472
}
461
473
@@ -674,9 +686,7 @@ where
674
686
IsNull :: No => i32:: from_usize ( buf. len ( ) - base - 4 ) ?,
675
687
IsNull :: Yes => -1 ,
676
688
} ;
677
- ( & mut buf[ base..base + 4 ] )
678
- . write_i32 :: < BigEndian > ( len)
679
- . unwrap ( ) ;
689
+ BigEndian :: write_i32 ( & mut buf[ base..] , len) ;
680
690
}
681
691
None => buf. truncate ( base) ,
682
692
}
@@ -862,9 +872,7 @@ where
862
872
}
863
873
864
874
let num_points = i32:: from_usize ( num_points) ?;
865
- ( & mut buf[ points_idx..] )
866
- . write_i32 :: < BigEndian > ( num_points)
867
- . unwrap ( ) ;
875
+ BigEndian :: write_i32 ( & mut buf[ points_idx..] , num_points) ;
868
876
869
877
Ok ( ( ) )
870
878
}
0 commit comments