diff --git a/CHANGELOG.md b/CHANGELOG.md index c53a4c6eca..368c2c74f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,10 @@ for Rust libraries in [RFC #1105](https://github.com/rust-lang/rfcs/blob/master/ [select-0.11.0]: http://docs.diesel.rs/diesel/fn.select.html [boxed-0.11.0]: http://docs.diesel.rs/diesel/prelude/trait.BoxedDsl.html +* Arrays containing null are now supported. `infer_schema!` will never infer an + array that contains null, but a `table!` definition which specifies a type of + `Array>` can now be deserialized to `Vec>` + ### Changed * It is no longer possible to exhaustively match against diff --git a/diesel/src/pg/types/array.rs b/diesel/src/pg/types/array.rs index 1679d0b312..1c48395ec8 100644 --- a/diesel/src/pg/types/array.rs +++ b/diesel/src/pg/types/array.rs @@ -134,10 +134,14 @@ impl<'a, ST, T> ToSql, Pg> for &'a [T] where let mut buffer = Vec::new(); for elem in self.iter() { let is_null = try!(elem.to_sql(&mut buffer)); - assert!(is_null == IsNull::No, "Arrays containing null are not supported"); - try!(out.write_i32::(buffer.len() as i32)); - try!(out.write_all(&buffer)); - buffer.clear(); + if let IsNull::No = is_null { + try!(out.write_i32::(buffer.len() as i32)); + try!(out.write_all(&buffer)); + buffer.clear(); + } else { + // https://github.com/postgres/postgres/blob/82f8107b92c9104ec9d9465f3f6a4c6dab4c124a/src/backend/utils/adt/arrayfuncs.c#L1461 + try!(out.write_i32::(-1)); + } } Ok(IsNull::No) diff --git a/diesel_tests/tests/types_roundtrip.rs b/diesel_tests/tests/types_roundtrip.rs index fdf46ec8f9..63605397c4 100644 --- a/diesel_tests/tests/types_roundtrip.rs +++ b/diesel_tests/tests/types_roundtrip.rs @@ -102,6 +102,7 @@ mod pg_types { test_round_trip!(array_of_int_roundtrips, Array, Vec); test_round_trip!(array_of_bigint_roundtrips, Array, Vec); test_round_trip!(array_of_dynamic_size_roundtrips, Array, Vec); + test_round_trip!(array_of_nullable_roundtrips, Array>, Vec>); fn mk_uuid(data: (u32, u16, u16, (u8, u8, u8, u8, u8, u8, u8, u8))) -> self::uuid::Uuid { let a = data.3; @@ -131,7 +132,7 @@ pub fn mk_naive_date(days: u32) -> NaiveDate { #[cfg(feature = "postgres")] mod unstable_types { - use super::{quickcheck, types, test_type_round_trips}; + use super::{quickcheck, test_type_round_trips}; use std::time::*; fn strip_nanosecond_precision(time: SystemTime) -> SystemTime {