silverqx / TinyORM

Modern C++ ORM library
https://www.tinyorm.org
MIT License
210 stars 22 forks source link

Column and Table alias assigning #41

Closed SchaichAlonso closed 8 months ago

SchaichAlonso commented 8 months ago

For non-trivial queries, it is often advantageous - if not required - to be able to assign aliases.

While TinyORM does not explicitly mention supporting alias assignments, the first example in the Select Statement Documentation, namely

auto users = DB::table("users")
    ->select({"name", "email as user_email"})
    .get();

hints the email column is to be assigned the user_email alias, as the statement could be imagined to become something like

SELECT name, email as user_email FROM "users"

However, TinyORM escapes the column specifiers that were passed through the initializer list, resulting in

SELECT "name", "email as user_email" FROM "users"

being generated, which selects the name along with echo-ing the escaped string constant provided in the second argument.

This Test executes the line that is provided in the Select Statement Documentation , then iterates the returned query result to emit this diagnostic indicating SQLite is echo-ing the SELECT parameter rather then assigning a column alias.

While cosmetic in trivial select statements like the one in the example, the ability to assign aliases in JOIN queries is crucial. For example, a user might "follow" other users, which could be implemented using a transitioning table storing follows and followers in twitter-speak, identifying a user's followers with a statement like

SELECT follower.name, follow.name FROM users AS follower JOIN follow_relationship ON follow_relationship.follower_id=follower.id JOIN users AS follow ON follow_relationship.id=follow.id

where the alias assignments are non-optional, as the follow and the followers are both users and need to be distinguished by using their aliases. However, as TinyORM escapes the string, it will cause an invalid SQL query if an "alias assignment" is used in a select query to a join expression.

I don't think "pasting" sql code into a column or table specifier is a scalable solution in case it was intentional. Instead, TinyORM should provide an API to specify aliases in a safe and backend independent way.

silverqx commented 8 months ago
SELECT "name", "email as user_email" FROM "users"

If this is happening then is a bug of course, it should look like this:

select "name", "email" as "user_email" from "users"
silverqx commented 8 months ago

Currently, the as keyword must be lowercase to be correctly detected, if it is the AS then this bug you are describing can happen, I will make it case-insensitive, and I will further investigate it, it was only a fast 5 min lookup what's up.

silverqx commented 8 months ago

Should be fixed in v0.36.4

silverqx commented 8 months ago

Thx for reporting it