diff --git a/sqlx-postgres/src/types/record.rs b/sqlx-postgres/src/types/record.rs index c4eb639368..6e37182c40 100644 --- a/sqlx-postgres/src/types/record.rs +++ b/sqlx-postgres/src/types/record.rs @@ -41,13 +41,13 @@ impl<'a> PgRecordEncoder<'a> { { let ty = value.produces().unwrap_or_else(T::type_info); - if let PgType::DeclareWithName(name) = ty.0 { + match ty.0 { // push a hole for this type ID // to be filled in on query execution - self.buf.patch_type_by_name(&name); - } else { + PgType::DeclareWithName(name) => self.buf.patch_type_by_name(&name), + PgType::DeclareArrayOf(array) => self.buf.patch_array_type(array), // write type id - self.buf.extend(&ty.0.oid().0.to_be_bytes()); + pg_type => self.buf.extend(&pg_type.oid().0.to_be_bytes()), } self.buf.encode(value)?; diff --git a/tests/postgres/derives.rs b/tests/postgres/derives.rs index dada74fe4d..13f9bf1d5d 100644 --- a/tests/postgres/derives.rs +++ b/tests/postgres/derives.rs @@ -810,3 +810,69 @@ async fn test_custom_pg_array() -> anyhow::Result<()> { } Ok(()) } + +#[sqlx_macros::test] +async fn test_record_array_type() -> anyhow::Result<()> { + let mut conn = new::().await?; + + conn.execute( + r#" +DROP TABLE IF EXISTS responses; + +DROP TYPE IF EXISTS http_response CASCADE; +DROP TYPE IF EXISTS header_pair CASCADE; + +CREATE TYPE header_pair AS ( + name TEXT, + value TEXT +); + +CREATE TYPE http_response AS ( + headers header_pair[] +); + +CREATE TABLE responses ( + response http_response NOT NULL +); + "#, + ) + .await?; + + #[derive(Debug, sqlx::Type)] + #[sqlx(type_name = "http_response")] + struct HttpResponseRecord { + headers: Vec, + } + + #[derive(Debug, sqlx::Type)] + #[sqlx(type_name = "header_pair")] + struct HeaderPairRecord { + name: String, + value: String, + } + + let value = HttpResponseRecord { + headers: vec![ + HeaderPairRecord { + name: "Content-Type".to_owned(), + value: "text/html; charset=utf-8".to_owned(), + }, + HeaderPairRecord { + name: "Cache-Control".to_owned(), + value: "max-age=0".to_owned(), + }, + ], + }; + + sqlx::query( + " +INSERT INTO responses (response) +VALUES ($1) + ", + ) + .bind(&value) + .execute(&mut conn) + .await?; + + Ok(()) +}