Closed
Description
Environment
- Erlang/OTP 20 [erts-9.0] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
- Elixir 1.5.1
- PostgreSQL 9.6.3 on x86_64-apple-darwin16.5.0, compiled by Apple LLVM version 8.1.0 (clang-802.0.42), 64-bit
- ecto 2.2.6
- postgrex 0.13.3
- mac OS X High Sierra 10.13 (17A405)
Current behavior
Given the following module:
defmodule MyApp.BlogPost
alias MyApp.Repo
use MyApp.Web, :model
schema "blog_posts" do
field :title, :string
field :body, :string
field :published_at, Calecto.DateTimeUTC
timestamps()
end
def newest_for_frontpage(limit) do
sq = from(
bp in (MyApp.BlogPost),
select: %{id: bp.id, row_number: fragment("row_number() OVER (PARTITION BY ? ORDER BY ? DESC)", bp.user_id, bp.published_at)}
)
from(
bp in (MyApp.BlogPost),
join: rn in subquery(sq), on: rn.id == bp.id,
where: rn.row_number == 1,
limit: ^limit
)
end
end
And the following calling code:
BlogPost.newest_for_frontpage(8)
|> Repo.all
Results in the following error:
** (Postgrex.Error) ERROR 42601 (syntax_error): syntax error at or near "."
(ecto) lib/ecto/adapters/sql.ex:431: Ecto.Adapters.SQL.execute_and_cache/7
(ecto) lib/ecto/repo/queryable.ex:133: Ecto.Repo.Queryable.execute/5
(ecto) lib/ecto/repo/queryable.ex:37: Ecto.Repo.Queryable.all/4
Expected behavior
Before the error is raised, the following debug output can be seen in the log:
[debug] QUERY ERROR source="blog_posts" db=0.4ms
SELECT b0."id", b0."title", b0."body", b0."visitor_count", b0."comment_count", b0."published", b0."published_at", b0."inserted_at", b0."updated_at", b0."user_id" FROM "blog_posts" AS b0 INNER JOIN (SELECT b0."id" AS "id", row_number() OVER (PARTITION BY b0."user_id" ORDER BY b0."published_at" DESC) AS "row_number" FROM "blog_posts" AS b0) AS s1 ON s1."id" = b0."id" WHERE (s1."row_number" = 1) LIMIT $1 [8]
[info] Sent 500 in 38ms
Running that query (replacing $1 [8]
with simply 8
) directly in the database, returns a set of records just fine.
The expected behaviour would thus be for Ecto to also return the records instead of raising an error.