drewolson / scrivener

Pagination for the Elixir ecosystem

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

grouping error with 1.1.3

hamann opened this issue · comments

The following statement works with 1.1.1

iex(1)> (from c in Comment, join: u in assoc(c, :user), order_by: [desc: u.inserted_at]) |> Repo.paginate(page: 1, page_size: 10)
[22:43:12.618] [debug]  SELECT count('*') FROM "comments" AS c0 INNER JOIN "users" AS u1 ON u1."id" = c0."user_id" [] OK query=41.0ms
[22:43:12.679] [debug]  SELECT c0."id", c0."content", c0."username", c0."email", c0."deleted", c0."approved", c0."inserted_at", c0."updated_at", c0."user_id", c0."post_id", c0."parent_id" FROM "comments" AS c0 INNER JOIN "users" AS u1 ON u1."id" = c0."user_id" ORDER BY u1."inserted_at" DESC LIMIT $1 OFFSET $2 [10, 0] OK query=60.7ms queue=0.1ms

but raises an error with 1.1.3

iex(4)> (from c in Comment, join: u in assoc(c, :user), order_by: [desc: u.inserted_at]) |> Repo.paginate(page: 1, page_size: 10)
[22:55:14.153] [debug]  SELECT count(DISTINCT c0."id") FROM "comments" AS c0 INNER JOIN "users" AS u1 ON u1."id" = c0."user_id" [] OK query=69.8ms
[22:55:14.160] [debug]  SELECT c0."id" FROM "comments" AS c0 INNER JOIN "users" AS u1 ON u1."id" = c0."user_id" GROUP BY c0."id" ORDER BY u1."inserted_at" DESC LIMIT $1 OFFSET $2 [10, 0] ERROR query=6.8ms queue=0.1ms
** (Postgrex.Error) ERROR (grouping_error): column "u1.inserted_at" must appear in the GROUP BY clause or be used in an aggregate function
         (ecto) lib/ecto/adapters/sql.ex:185: Ecto.Adapters.SQL.query!/5
         (ecto) lib/ecto/adapters/sql.ex:481: Ecto.Adapters.SQL.execute/6
         (ecto) lib/ecto/repo/queryable.ex:95: Ecto.Repo.Queryable.execute/5
         (ecto) lib/ecto/repo/queryable.ex:15: Ecto.Repo.Queryable.all/4
    (scrivener) lib/scrivener.ex:153: Scrivener.entries/4
    (scrivener) lib/scrivener.ex:102: Scrivener.paginate/2

Thanks for the issue, this is most likely related to the new pagination code we added to handle nested joins. I'll take a look sometime this week.

@hamann What database are you using? I wrote a test to try to reproduce this and it works for me. The generated SQL looks very similar to yours but runs fine. Here's the query in the test:

page = Post
      |> join(:left, [p], c in assoc(p, :comments))
      |> group_by([p], p.id)
      |> order_by([p], desc: p.body)
      |> Scrivener.Repo.paginate

And here's the test run output with logging:

#Ecto.Query<from p in Scrivener.Post, left_join: c in assoc(p, :comments),
 group_by: [p.id], order_by: [desc: p.body]>

{"SELECT p0.\"id\" FROM \"posts\" AS p0 LEFT OUTER JOIN \"comments\" AS c1 ON c1.\"post_id\" = p0.\"id\" GROUP BY p0.\"id\" ORDER BY p0.\"body\" DESC LIMIT $1 OFFSET $2",
 [5, 0]}
.

Finished in 0.3 seconds (0.1s on load, 0.1s on tests)
10 tests, 0 failures, 9 skipped

@drewolson Postgres 9.5

You have to order by comments, ordering by post works

iex(11)> (from p in Post, join: c in assoc(p, :comments), order_by: [desc: c.id]) |> Repo.paginate
[17:24:06.764] [debug]  SELECT count(DISTINCT p0."id") FROM "posts" AS p0 INNER JOIN "comments" AS c1 ON c1."post_id" = p0."id" [] OK query=213.7ms
[17:24:06.765] [debug]  SELECT p0."id" FROM "posts" AS p0 INNER JOIN "comments" AS c1 ON c1."post_id" = p0."id" GROUP BY p0."id" ORDER BY c1."id" DESC LIMIT $1 OFFSET $2 [10, 0] ERROR query=0.7ms
** (Postgrex.Error) ERROR (grouping_error): column "c1.id" must appear in the GROUP BY clause or be used in an aggregate function
         (ecto) lib/ecto/adapters/sql.ex:185: Ecto.Adapters.SQL.query!/5
         (ecto) lib/ecto/adapters/sql.ex:481: Ecto.Adapters.SQL.execute/6
         (ecto) lib/ecto/repo/queryable.ex:95: Ecto.Repo.Queryable.execute/5
         (ecto) lib/ecto/repo/queryable.ex:15: Ecto.Repo.Queryable.all/4
    (scrivener) lib/scrivener.ex:153: Scrivener.entries/4
    (scrivener) lib/scrivener.ex:102: Scrivener.paginate/2

I can confirm I am getting the same issue after upgrading scrivener:

Here is the query:

#Ecto.Query<from c in ChannelUser,
 join: u in User, on: u.id == c.user_id,
 where: c.channel_id in ^["c737266d-dab8-4d76-86b1-ffe0e926eeca"],
 order_by: [asc: u.name, asc: u.email]>

And the error:

     ** (Postgrex.Error) ERROR (grouping_error): column "u1.name" must appear in the GROUP BY clause or be used in an aggregate function

@Gazler thanks for reporting as well. I'm struggling to fix this bug while retaining the functionality to support deeply nested joins. I'm going to put some more work in on it this weekend, but in the meantime if folks have ideas, please let me know.

My current thought is that on moving to 2.0 (for ecto 2.0 support) I'll drop support of nested joins to reintroduce support for these queries.

@drewolson I'm sure you had your suspicions, but I just ran a bisect and my tests start failing at this commit cd60ec0

@Gazler yes, I figured as much. As I said above, I'm going to remove support for nested joins when moving to support ecto 2.0 so this problem should be solved. If we can figure out a way to support nested joins that doesn't cause this bug in the future, we'll pull it back in.

I'm closing this issue as the ecto-specific functionality has moved to scrivener_ecto and we've opted to have user's use subqueries to handle these problems.