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

Not possible to insert arrays of custom types. #906

Closed
vicky5124 opened this issue Dec 16, 2020 · 1 comment
Closed

Not possible to insert arrays of custom types. #906

vicky5124 opened this issue Dec 16, 2020 · 1 comment

Comments

@vicky5124
Copy link

If a custom PgSql type is made, such as an enum, and a table column needs an array of that custom type, there's currently no way to be able to insert to that column.

Reproduceable example:

CREATE TYPE CATEGORIES AS ENUM (
    'API',
    'Editor'
);

CREATE TABLE test (categories CATEGORIES[]);
#[derive(Debug, sqlx::Type)]
#[sqlx(rename = "categories")]
pub enum Categories {
    #[sqlx(rename = "API")]
    Api,
    Editor,
}

let categories: Vec<Categories> = vec![Categories::Api, Categories::Editor];

sqlx::query!("INSERT INTO mods (categories) VALUES ($1)", &categories)
    .execute(&pool)
    .await?;

This fails to compile with:

error[E0277]: the trait bound `Vec<Categories>: Type<Postgres>` is not satisfied
...
    = help: the following implementations were found:
              <Vec<&[u8]> as Type<Postgres>>
              <Vec<&str> as Type<Postgres>>
              <Vec<(T1, T2)> as Type<Postgres>>
              <Vec<(T1, T2, T3)> as Type<Postgres>>
            and 30 others
    = note: required because of the requirements on the impl of `Encode<'_, Postgres>` for `Vec<Categories>`
    = note: required because of the requirements on the impl of `Encode<'_, Postgres>` for `&Vec<Categories>`
    = note: required by `sqlx::Encode::size_hint`

And currently trying to manually implement this type is impossible due to having required fields are private.

#[derive(Debug, Clone)]
pub struct CategoriesList(Vec<Categories>);

impl Type<Postgres> for CategoriesList {
    fn type_info() -> PgTypeInfo {
        PgTypeInfo(
            PgType::Custom(
                Arc::new(PgCustomType {
                    // fields are private
                })
            )
        )
    }

    fn compatible(ty: &PgTypeInfo) -> bool {
        ...
    }
}

impl Encode<'_, Postgres> for CategoriesList {
    fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> IsNull {
        <CategoriesList as Encode<Postgres>>::encode(self.clone(), buf)
    }
}
@abonander
Copy link
Collaborator

Duplicate of #298

@abonander abonander marked this as a duplicate of #298 Dec 18, 2020
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

No branches or pull requests

2 participants