-
Notifications
You must be signed in to change notification settings - Fork 1.4k
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Preload many_to_many through preload query discards my data #2785
Comments
Hi @chingan-tsc! For many_to_many preload queries, you need the first join to be the association table, otherwise it works completely by chance. Something like this:
I will improve the docs to make this clear. |
Actually, I think this should work as is as well. I am investigating it further. |
Hi @josevalim, thanks for the prompt reply. I have added another test case on my repo as such:
In this test case both routine returns expected result, but only when post1 and post2 don't have any overlapping |
Ok, I have dug deeper into this and the issue is that when using joins such as Here is the query that we run internally: from t in PreloadTest.Tag, join: c in assoc(t, :comment),
join: p0 in PreloadTest.Post, on: p0.id in ^[16, 15], join: p1 in "post_tags",
on: p1.post_id == p0.id, where: p1.tag_id == t.id, order_by: [asc: p0.id],
select: {p0.id, t}, preload: [comment: c] In the overlapping case, it is supposed to return three entries, but you can see it returns only 2. This would actually be an overall bug with joins that happens to manifest via preloads. |
I am guessing its a bug too but what baffles me is that both raw SQL queries seen on the debug log actually yields the same number of rows (well of course |
It should be fixed in master. :) |
Precheck
Environment
Current behavior
I have created a sample app to simulate this behavior here: https://github.com/chingan-tsc/ecto_preload_test forked from #2534 as our issue is similar but yet different.
So first things first, the schema, we have a many to many relationship between Post and Tag, where Tag schema has a
belongs_to
with Comment (the schema might not makes sense in terms of actual practicality but it'll simulate the behavior). I have two queries to list all Post(s) along with all its associated Tag (and the parent Comment attached to the Tag).Now I have written a test case in my sample app:
Lets talk about the second query,
Query.list_posts_b()
it returns 2 Posts (post1 and post2) where post1 has 1 Tag object undertags
key and post2 has 2 Tag objects undertags
key. All is fine.But the first query,
Query.list_posts_a()
returns post1 as before but post2 with empty array ontags
key. Now it doesn't makes any sense to me as two routines are actually almost the same.What I did was I copied the actual SQL query used for preloading from the debug log and both returns 3 Tag objects but the second query "distribute" them nicely into two Post(s) nicely where the first query just drop 1 of the Tag object.
Please advise.
Expected behavior
Both queries should return the same result.
The text was updated successfully, but these errors were encountered: