ensure select statements in joined queries have access to parent bindings - #4653
ensure select statements in joined queries have access to parent bindings#4653zachdaniel wants to merge 1 commit into
Conversation
|
Thanks for the PR! I would like to hear @greg-rychlewski's opinion but my gut feeling is that the test should not pass indeed. In this case: The parent query of Forget subqueries for a second. Imagine you have In this case, Therefore, when you do this: Once again, |
|
Let me give another example: which one is now the actual parent? The query above doesn't work, because we only allow a subset of queries in joins, but we could allow the construct above in the future (it is not a technical limitation, it just wasn't implemented yet), and now there would be ambiguity, because you want the |
|
I could be wrong here, but don't i.e given your example: query =
from thing in Post,
as: :outer,
inner_lateral_join: sub in ^from(row in subquery(child), join: "outers", as: :outer),
on: true
|
|
The walking upwards does not matter, because, as per my first comment, there is no parent/child relationship between the You have three queries: QUERY 1 and 2 is regular query composition. There is no parent/child relationship in there. The same way |
|
In summary, you only have child/parent relationships if there is an explicit subquery call. That's exactly so people don't have to guess what is composition and what is parent/child. That's why I said it could only work if you did double nesting: (which in this case is obviously unnecessary) |
|
Yeah after looking at this I have the same opinion as @josevalim. I think the crux is these two things are not the same The subquery in the latter example doesn't know anything outside of I can understand the confusion though because if I was just writing the SQL by hand and joining on a query I would be forced to wrap the whole thing in a subquery or it would be invalid SQL. But with Ecto you have to think in terms of composition. |
|
Roger. It makes sense, but I think is a bit of a footgun. In a case like that when you're slotting an Ecto query into a place that can only ever be a subquery (lateral joins require a subquery) it feels like it should just treat the containing query as a "parent" for the purposes of Probably as simple as me not doing that or unwrapping it when I do the inner lateral join 🤷 |
|
I think the issue is that in raw SQL the joined query must be in a subquery whether it is lateral or not. Lateral just changes how the join is done and allows access to the outside. So when Ecto is allowing a join on a query under any circumstance, it is performing composition rather than an implicit subquery. Which, for the record, I agree is confusing at first. The first time I saw it I had to take a look at the actual query that was being generated to fully understand what was going on. But it is providing useful functionality to users. |
Ultimately, I don't fully understand how parent binding sources are managed well enough to really say if this is the most correct fix. Since
parent_asworks in other, non-select contexts using this formulation, it feels like there may be a more targeted/specific fix available?Regardless, the newly added test will fail without the fix, and the fix does not cause any additional test failures. Open to adjusting it if as needed.