-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Description
I have found these related issues/pull requests
This issue persists even with the above fix
Description
When writing SELECT and INSERT queries on the examples below, the query macro appears to behave inconsistently with regards to type checking.
In certain situations it will recognize that the SQL NewType type_created_at
and the Rust NewType CreatedAt
are distinct types from the SQL type timestamptz
and the Rust type OffsetDateTime
. Other times it will treat them as equivalent. The OffsetDateTime::type_into()::type_compatible(...)
and CreatedAt::type_into()::type_compatible(...)
functions correctly reports that they are different and incompatible types. Checking on the SQL side seems to sometimes but not always check the custom type name/domain name (perhaps via pg_catalog.pg_type.typname
or alternatively via information_schema.columns.domain_name
and information_schema.columns.udt_name
).
The inconsistent behavior seems like a bug.
let created_at_type = CreatedAt::type_info();
let datetime_type = OffsetDateTime::type_info();
println!("{:?}", created_at_type.type_compatible(&datetime_type));
println!("{:?}", datetime_type.type_compatible(&created_at_type));
//---- types::tests::check_compatible stdout ----
//false
//false
I also found that I can insert a newtype (struct MyNewType(OffsetDateTime)
) as if it was a different composite type (struct MyCompositeType { time: OffsetDateTime }
). It appears using the as
operator in macro bindings effectively turns off type checking entirely in postgres even if a type is supplied.
//swapping out the commented values do not result in errors on a table using MyCompositeType/my_composite_type
let inserted_id = sqlx::query_file_scalar!("queries/my_insert.sql",
my_newtype as MyNewType, //my_composite_type as MyCompositeType
).fetch_one(&mut *conn).await?;
Reproduction steps
CREATE DOMAIN type_created_at AS timestamptz;
CRATE TYPE type_created_at2 AS ( created_at2 timestamptz);
CREATE TABLE my_service.table_mytest (
created_at type_created_at NULL,
created_at2 type_created_at2 NULL,
random_timestamp timestamptz NULL
);
#[derive(sqlx::Type, PartialEq, Eq, Debug, Clone)]
#[sqlx(type_name = "type_created_at")]
pub struct CreatedAt(pub OffsetDateTime);
#[derive(sqlx::Type, PartialEq, Eq, Debug, Clone)]
#[sqlx(type_name = "type_created_at2")]
pub struct CreatedAt2{ pub created_at2: OffsetDateTime }
todo: various examples of the different types of select and insert queries failing (behaving differently)
particularly the as
operator for insert statements
and implicit conversion for select statements
SQLx version
0.9 - head as of a few days ago
Enabled SQLx features
["postgres", "runtime-tokio", "time", "json", "uuid"]
Database server and version
Postgres
Operating system
Linux
Rust version
rustc 1.90.0-nightly
extra tags for search: information_schema, columns, udt_name, domain_name, typname, pg_type. pg_catalog