fix(postgres): use the element type info from the protocol if available for array element decoding

fixes #537
This commit is contained in:
Ryan Leckey 2020-07-20 23:53:18 -07:00
parent 6a70780f45
commit ee4d9b5412
3 changed files with 23 additions and 2 deletions

View File

@ -80,7 +80,7 @@ where
Self: Type<Postgres>,
{
fn decode(value: PgValueRef<'r>) -> Result<Self, BoxDynError> {
let element_type_info = T::type_info();
let element_type_info;
let format = value.format();
match format {
@ -107,7 +107,10 @@ where
let _flags = buf.get_i32();
// the OID of the element
let _element_type = buf.get_u32();
let element_type_oid = buf.get_u32();
element_type_info = PgTypeInfo::try_from_oid(element_type_oid).unwrap_or_else(|| {
PgTypeInfo(PgType::DeclareWithOid(element_type_oid))
});
// length of the array axis
let len = buf.get_i32();
@ -133,6 +136,9 @@ where
}
PgValueFormat::Text => {
// no type is provided from the database for the element
element_type_info = T::type_info();
let s = value.as_str()?;
// https://github.com/postgres/postgres/blob/a995b371ae29de2d38c4b7881cf414b1560e9746/src/backend/utils/adt/arrayfuncs.c#L718

View File

@ -37,6 +37,10 @@ impl<T> Type<Postgres> for Vec<Json<T>> {
fn type_info() -> PgTypeInfo {
<[Json<T>] as Type<Postgres>>::type_info()
}
fn compatible(ty: &PgTypeInfo) -> bool {
<[Json<T>] as Type<Postgres>>::compatible(ty)
}
}
impl<'q, T> Encode<'q, Postgres> for Json<T>

View File

@ -298,6 +298,12 @@ mod json {
"'[\"Hello\", \"World!\"]'::json" == json!(["Hello", "World!"])
));
test_type!(json_array<Vec<JsonValue>>(
Postgres,
"SELECT ({0}::jsonb[] is not distinct from $1::jsonb[])::int4, {0} as _2, $2 as _3",
"array['\"😎\"'::json, '\"🙋‍♀️\"'::json]::json[]" == vec![json!("😎"), json!("🙋‍♀️")],
));
test_type!(jsonb<JsonValue>(
Postgres,
"'\"Hello, World\"'::jsonb" == json!("Hello, World"),
@ -306,6 +312,11 @@ mod json {
"'[\"Hello\", \"World!\"]'::jsonb" == json!(["Hello", "World!"])
));
test_type!(jsonb_array<Vec<JsonValue>>(
Postgres,
"array['\"😎\"'::jsonb, '\"🙋‍♀️\"'::jsonb]::jsonb[]" == vec![json!("😎"), json!("🙋‍♀️")],
));
#[derive(serde::Deserialize, serde::Serialize, Debug, PartialEq)]
struct Friend {
name: String,