Search code examples
sqlpostgresqlrustrust-sqlx

sqlx: Unsupported type _badge of column #6 ("badges")


I'm using Rust's sqlx crate, and trying to perform the following:

query_as!(User, r#"SELECT * FROM users WHERE name ILIKE $1"#, name)

Note that I am using Postgresql.

I am confronted with this error:

error: unsupported type _badge of column #6 ("badges")
  --> src\services.rs:16:11
   |
16 |     match query_as!(User, r#"SELECT * FROM users WHERE name ILIKE $1"#, name)
   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: this error originates in the macro `$crate::sqlx_macros::expand_query` which comes from the expansion of the macro `query_as` (in Nightly builds, run with -Z macro-backtrace for more info)

Here are my User and Badge definitions:

#[derive(sqlx::Type, Serialize, Deserialize, Display)]
#[sqlx(type_name = "badge")]
pub enum Badge {
    Sponsored,
    Founder,
    Developer,
}

#[derive(Serialize, Deserialize)]
pub struct User {
    uuid: Uuid,
    date_joined: DateTime<Utc>,
    name: String,
    badges: Vec<Badge>,
    articles: Vec<String>,
    followers: i64,
}

My table looks like this:

Column Type
uuid uuid
date_joined timestamp_tz
followers bigint
badges badge[]
name text
articles text[]

I've even tried to implement the PgHasArrayType trait for the Badge struct:

impl PgHasArrayType for Badge {
    fn array_type_info() -> PgTypeInfo {
        PgTypeInfo::with_name("_badge")
    }

    fn array_compatible(ty: &PgTypeInfo) -> bool {
        true
    }
}

Note: Using the non-macro version of query_as works for some reason.

Any help would be greatly appreciated!


Solution

  • Too late for answer but perhaps it will help someone else. Problem happens because compile-time sqlx query checker can't infer custom type (like Badge in this case) without help. When query macro used, you must declare which type is returning like:

    SELECT badge AS "badge: Vec<Badge>" FROM users;
    

    If you use query_as you can just put underscore instead of type and compiler will infer it:

    SELECT badge AS "badge: _" FROM users;