You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In postgres, when utilizing arrays of a custom type, the driver rejects retrieving a column from a row if the PgTypeInfo for PgHasArrayType is implemented using the [] syntax. The underlying implementation in postgres stores this array implementation on custom types using a underscore prefix. This does not occur when reading the array out through the query macro.
I get the following failure:
thread 'main' panicked at /Users/vegardgs/.cargo/registry/src/index.crates.io-6f17d22bba15001f/sqlx-core-0.7.4/src/row.rs:72:37:
called `Result::unwrap()` on an `Err` value: ColumnDecode { index: "\"tags\"", source: "mismatched types; Rust type `alloc::vec::Vec<sqlx_postgres_array::Tag>` (as SQL type `tag[]`) is not compatible with SQL type `_tag`" }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
It was quite surprising behavior, as I was unaware of the actual type name of the postgres enum array - I've always referred to it through the [] syntax. I neither saw any traces of this scenario mentioned in the Types nor PgHasArrayType documentation.
Is this expected behavior? Could this scenario be attempted auto-detected for postgres? Or perhaps only a clarification in the documentation of postgres enums when implementing PgHasArrayType?
Minimal Reproduction
use sqlx::postgres::{PgHasArrayType,PgTypeInfo};use sqlx::Row;#[derive(Debug, sqlx::Type)]#[sqlx(type_name = "tag", rename_all = "UPPERCASE")]enumTag{Test,Internal,}implPgHasArrayTypeforTag{fnarray_type_info() -> PgTypeInfo{// NOTE: Changing `tag[]` to `_tag` resolves the issue.PgTypeInfo::with_name("tag[]")}}#[tokio::main]asyncfnmain() -> sqlx::Result<()>{
dotenvy::dotenv().ok();let database = sqlx::PgPool::connect(&std::env::var("DATABASE_URL").unwrap()).await?;
sqlx::query!(r#" INSERT INTO Items (tags) VALUES ($1), ($2) "#,
&vec![Tag::Test]as _,
&vec![Tag::Internal, Tag::Test]as _,
).execute(&database).await?;let by_macro:Vec<Vec<Tag>> = sqlx::query!(r#" SELECT tags as "tags: Vec<Tag>" from Items "#).fetch_all(&database).await?
.into_iter().map(|r| r.tags).collect();assert!(by_macro.len() >= 2);let by_query:Vec<Vec<Tag>> = sqlx::query("SELECT tags FROM Items").fetch_all(&database).await?
.into_iter()// NOTE: This fails.map(|r| r.get("tags")).collect();assert!(by_query.len() >= 2);Ok(())}
[dependencies]
dotenvy = "0.15.7"sqlx = { version = "0.7.4", features = ["postgres", "runtime-tokio"] }
tokio = { version = "1.37.0", features = ["macros", "rt", "rt-multi-thread"] }
Got the same problem with the requirement of an underscore infront of the actual type name... don't know why this is necessary and would be good to know why.
Edit: Found the answer + one message above + some below: #1004 (comment)
It's Postgres' default naming convention for array types.
Bug Description
In postgres, when utilizing arrays of a custom type, the driver rejects retrieving a column from a row if the
PgTypeInfo
forPgHasArrayType
is implemented using the[]
syntax. The underlying implementation in postgres stores this array implementation on custom types using a underscore prefix. This does not occur when reading the array out through the query macro.I get the following failure:
It was quite surprising behavior, as I was unaware of the actual type name of the postgres enum array - I've always referred to it through the
[]
syntax. I neither saw any traces of this scenario mentioned in the Types nor PgHasArrayType documentation.Is this expected behavior? Could this scenario be attempted auto-detected for postgres? Or perhaps only a clarification in the documentation of postgres enums when implementing
PgHasArrayType
?Minimal Reproduction
This is the debug print of the column info for the select query:
Info
rustc --version
: rustc 1.77.1 (7cf61ebde 2024-03-27)The text was updated successfully, but these errors were encountered: