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

Rework `CAST` expressions

Open Expurple opened this issue 4 months ago • 2 comments

See https://github.com/SeaQL/sea-query/issues/954.

I think, this version is more correct and easier to understand (regarding case-sensitivity, [] handling, etc). The summary is in the changelog, as always

Expurple avatar Aug 27 '25 12:08 Expurple

But now I'm stuck with this failing ExprTrait::as_enum doctest. I've read this explanation of AsEnum and I understand the need to separate quoted (case-sensitive) and unquoted (case-insensitive) casts, but I still don't understand why as_enum needs to do a cast only on Postgres and do nothing on MySQL and SQLite. This behavior is undocumented, seems very weird, and requires that special AsEnum node which I tried to remove.

Is this something that SeaORM needs? Perhaps, SeaORM itself should apply this DB-specific logic? I find it weird that I can explicitly call my_val.as_enum(my_type) (a seemingly low-level query builder method) and get no cast at all, depending on the database.

Expurple avatar Aug 27 '25 12:08 Expurple

To further explain, in Postgres a enum is a (user-defined) type that's created by the CREATE TYPE statement. MySQL is more relaxed, it's basically a string with some constraints. In SQLite it is just a string. The problem is when doing inserts for example, we can do INSERT INTO my_table VALUES ('my_enum_variant') in MySQL / SQLite, but has to cast it explicitly in Postgres INSERT INTO my_table VALUES (CAST 'my_enum_variant' as "my_enum").

The problem in SeaORM is that the frontend (query building stage) doesn't know about the backend yet. It's only known when we call exec, and I'd rather not walk the AST again and tweak the nodes.

tyt2y3 avatar Aug 29 '25 17:08 tyt2y3