sea-orm icon indicating copy to clipboard operation
sea-orm copied to clipboard

`column_as()` breaks PostgreSQL enum

Open Scooter1337 opened this issue 2 years ago • 9 comments

Description

column_as() breaks PostgreSQL enum

I am now forced to use 'role' instead of 'user_role'

Steps to Reproduce

  1. Create Table which uses a native Postgres enum
  2. Query the table with the enum in a join, and use column_as to rename the column
  3. Use into_model or into_json

Expected Behavior

Returning the role when using either into_model and into_json

Actual Behavior

into_model && column_as

Err(
    Query(
        SqlxError(
            ColumnDecode {
                index: "\"user_role\"",
                source: "mismatched types; Rust type `core::option::Option<alloc::string::String>` (as SQL type `TEXT`) is not compatible with SQL type `Role`",
            },
        ),
    ),
)

into_json && column_as (It does not show up in the json)

Object {
            "id": Number(2),
            "membership_uuid": String("jpnaspkni45benpjstcons6q"),
            "name": String("Test"),
            "user_email": String("[email protected]"),
            "user_first_name": String("test3"),
            "user_last_name": String("test3"),
            "uuid": String("exr98cm55qdz5ckllk8vx0ni"),
        },

into_model && column

ManagementMember {
            user_first_name: "test3",
            user_last_name: "test3",
            user_email: "[email protected]",
            role: Viewer,
            membership_uuid: "jpnaspkni45benpjstcons6q",
        },

into_json && column

Object {
            "id": Number(2),
            "membership_uuid": String("jpnaspkni45benpjstcons6q"),
            "name": String("Test"),
            "role": String("VIEWER"),
            "user_email": String("[email protected]"),
            "user_first_name": String("test3"),
            "user_last_name": String("test3"),
            "uuid": String("exr98cm55qdz5ckllk8vx0ni"),
        },

Reproduces How Often

Always

Workarounds

Not using column_as but using column

Reproducible Example

Don't have time to open a PR, here is my faulty query:

#[derive(Debug, Serialize, FromQueryResult, Clone, PartialEq)]
pub struct ManagementMembers {
    pub user_first_name: String,
    pub user_last_name: String,
    pub user_email: String,
    pub user_role: Role,
    pub membership_uuid: String,
}

Management::find()
        .filter(management::Column::Uuid.contains(uuid))
        .column_as(user::Column::FirstName, "user_first_name")
        .column_as(user::Column::LastName, "user_last_name")
        .column_as(user::Column::Email, "user_email")
        .column_as(management_member::Column::Uuid, "membership_uuid")
        .column_as(management_member::Column::Role, "user_role")
        .join(
            sea_orm::JoinType::InnerJoin,
            management::Relation::ManagementMember.def(),
        )
        .join(
            sea_orm::JoinType::InnerJoin,
            management_member::Relation::User.def(),
        )
        .into_model::<ManagementMembers>()
        .all(db)
        .await;

Working query:

#[derive(Debug, Serialize, FromQueryResult, Clone, PartialEq)]
pub struct ManagementMembers {
    pub user_first_name: String,
    pub user_last_name: String,
    pub user_email: String,
    pub role: Role,
    pub membership_uuid: String,
}

Management::find()
        .filter(management::Column::Uuid.contains(uuid))
        .column_as(user::Column::FirstName, "user_first_name")
        .column_as(user::Column::LastName, "user_last_name")
        .column_as(user::Column::Email, "user_email")
        .column_as(management_member::Column::Uuid, "membership_uuid")
        .column(management_member::Column::Role)
        .join(
            sea_orm::JoinType::InnerJoin,
            management::Relation::ManagementMember.def(),
        )
        .join(
            sea_orm::JoinType::InnerJoin,
            management_member::Relation::User.def(),
        )
        .into_model::<ManagementMembers>()
        .all(db)
        .await;

Versions

├── sea-orm v0.12.3 │ ├── sea-orm-macros v0.12.3 (proc-macro) │ │ ├── sea-bae v0.2.0 (proc-macro) │ ├── sea-query v0.30.2 │ ├── sea-query-binder v0.5.0 │ │ ├── sea-query v0.30.2 (*)

Ubuntu 22.04.3 LTS x86_64 PostgreSQL v16

Scooter1337 avatar Oct 17 '23 19:10 Scooter1337

I believe this was discussed before, but I could not find the thread. A failing testcase that pinpoints the problem is like half way to fixing the bug.

I am guessing, into_model and into_json does not do the proper casting.

tyt2y3 avatar Oct 26 '23 14:10 tyt2y3

That'll be appreciated!

tyt2y3 avatar Oct 26 '23 15:10 tyt2y3

Facing the same issue, into_json breaks the select_as type and cast all fields as String.

jmelo11 avatar Mar 26 '24 02:03 jmelo11