Do not understand select statement generation
juandent opened this issue · 3 comments
I am returning from a long time not using sqlite_orm and found something peculiar:
why does this statement:
auto firstNames = storage.select(columns(m->*&Employee::firstName || " " || m->*&Employee::lastName,
&Employee::firstName || " " || &Employee::lastName),
inner_join<m>(on(m->*&Employee::reportsTo == &Employee::employeeId)));
produce this sql:
SELECT ("m"."FirstName" || ' ') || "m"."LastName", 1
FROM "employees"
INNER JOIN "employees" "m"
ON "m"."ReportsTo" = "employees"."EmployeeId"
-- taken from self_join.cpp
Regards,
Juan
I see that the problem is the literal 1
as the value of the second column.
This is because you are or'ing a pointer-to-member with a C string literal and its result with another pointer-to-member. sqlite_orm can overload the ||
-operator only for sqlite_orm types, not for C++ builtin types alone in an expression.
The first column expression works, because m->*&Employee::firstName
forms a type in the sqlite_orm namespace.
You have multiple options to help sqlite_orm to create an expression where overloaded operators work.
I would form a table reference as the canonical way in modern C++:
constexpr auto employee = c<Employee>();
// employee->*&Employee::firstName || " " || employee->*&Employee::lastName
auto firstNames = storage.select(columns(m->*&Employee::firstName || " " || m->*&Employee::lastName,
employee->*&Employee::firstName || " " || employee->*&Employee::lastName),
inner_join<m>(on(m->*&Employee::reportsTo == employee->*&Employee::employeeId)));
Technically you don't need the repeated employee->*
, but it's easier on the brain :)
Thanks!