Added missing special casing for encoding embedded arrays of custom types (#3603)

* Added missing special casing for encoding arrays of custom types

* Added the matching test

* Formatting
This commit is contained in:
Nicolas Séverin 2025-01-28 01:30:02 +00:00 committed by GitHub
parent 6c2a29f67e
commit 6ca52fe80c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 70 additions and 4 deletions

View File

@ -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)?;

View File

@ -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::<Postgres>().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<HeaderPairRecord>,
}
#[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(())
}