Skip to content

Commit

Permalink
Added missing special casing for encoding embedded arrays of custom t…
Browse files Browse the repository at this point in the history
…ypes (#3603)

* Added missing special casing for encoding arrays of custom types

* Added the matching test

* Formatting
  • Loading branch information
nico-incubiq authored Jan 28, 2025
1 parent 6c2a29f commit 6ca52fe
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 4 deletions.
8 changes: 4 additions & 4 deletions sqlx-postgres/src/types/record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)?;
Expand Down
66 changes: 66 additions & 0 deletions tests/postgres/derives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
}

0 comments on commit 6ca52fe

Please sign in to comment.