Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

nico-incubiq
Copy link

@nico-incubiq nico-incubiq commented Nov 19, 2024

fixes #1672 - or at least my last comment on the ticket, as I now realise the person originally reported a decoding issue, and this is about encoding, as decoding already worked fine. My specific scenario has been added to the test suite to confirm this fixes it.

This fix is inspired by this similar bit of code:

match type_info.0 {
PgType::DeclareWithName(name) => buf.patch_type_by_name(&name),
PgType::DeclareArrayOf(array) => buf.patch_array_type(array),
ty => {
buf.extend(&ty.oid().0.to_be_bytes());
}
}

With this fix in, it's now perfectly fine to store (and retrieve) nested structures in Postgres, without any additional boilerplate, such as:

#[derive(Debug, sqlx::Type)]
#[sqlx(type_name = "http_response")]
struct HttpResponseRecord {
    status_code: i16,
    headers: Vec<HeaderPairRecord>,
    body: Vec<u8>,
}

#[derive(Debug, sqlx::Type)]
#[sqlx(type_name = "header_pair")]
struct HeaderPairRecord {
    name: String,
    value: Vec<u8>,
}

[...]

sqlx::query!(
    r#"
    INSERT INTO idempotency (user_id, idempotency_key, response, created_at)
    VALUES ($1, $2, $3, NOW())
    "#,
    &user_id,
    &idempotency_key,
    &http_response_record as _,
)
.execute(connection)
.await?;

let saved_response = sqlx::query!(
    r#"
    SELECT response AS "response: HttpResponseRecord"
    FROM idempotency
    WHERE user_id = $1
    AND idempotency_key = $2
    "#,
    &user_id,
    &idempotency_key
)
.fetch_optional(connection)
.await?;

By the way, I've seen comments pointing to using the newtype pattern to map embedded arrays of custom types; but it's no longer necessary after this fix, so it might be worth updating the official documentation with an example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Can't decode PostgreSQL arrays of custom types
1 participant