As a result of trying to make a Slick query more readable, I have this query constructor, which works
val q = Users.filter(_.id === userId) join People on {
case (u, p) => u.personId === p.id
} joinLeft Addresses on {
case ((u, p), a) => p.addressId === a.id
} joinLeft Businesses on {
case (((u, p), a), b) => p.businessId === b.id
} joinLeft Addresses on {
case ((((u, p), a), b), ba) => b.flatMap(_.addressId) === ba.id
} map {
case ((((u, p), a), b), ba) => (p, a, b, ba)
}
And this one I thought would be equivalent, but doesn't work:
val q = Users.filter(_.id === userId) join People joinLeft Addresses joinLeft Businesses joinLeft Addresses on {
case ((((u, p), a), b), ba) =>
u.personId === p.id &&
p.addressId === a.flatMap(_.id) &&
p.businessId === b.flatMap(_.id) &&
b.flatMap(_.addressId) === ba.id
} map {
case ((((u, p), a), b), ba) => (p, a, b, ba)
}
The second one appears to be returning a list of profiles that includes more than the target one.
Why aren't they the same?
The "equivalent" SQL (IE the goal of this construction) is:
select p.*, a1.*, b.*, a2.* from Users u
innerJoin People p on (u.personId == p.id)
leftJoin Addresses a1 on (p.addressId == a1.id)
leftJoin Businesses b on (p.businessId == b.id)
leftJoin Addresses a2 on ( b.addressId == a2.id)