Skip to content

Commit 69b778f

Browse files
authored
Fix empty array compare in PostgreSQL (#452)
1 parent add3442 commit 69b778f

File tree

3 files changed

+30
-0
lines changed

3 files changed

+30
-0
lines changed

integration_test/sql/sql.exs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ defmodule Ecto.Integration.SQLTest do
66
alias Ecto.Integration.Barebone
77
alias Ecto.Integration.Post
88
alias Ecto.Integration.CorruptedPk
9+
alias Ecto.Integration.Tag
910
import Ecto.Query, only: [from: 2]
1011

1112
test "fragmented types" do
@@ -28,6 +29,18 @@ defmodule Ecto.Integration.SQLTest do
2829
assert result.rows == [[[text1, text2]]]
2930
end
3031

32+
@tag :array_type
33+
test "Converts empty array correctly" do
34+
result = TestRepo.query!("SELECT array[1,2,3] = $1", [[]])
35+
assert result.rows == [[false]]
36+
37+
result = TestRepo.query!("SELECT array[]::integer[] = $1", [[]])
38+
assert result.rows == [[true]]
39+
40+
query = from t in Tag, where: t.items == []
41+
assert [] == TestRepo.all(query)
42+
end
43+
3144
test "query!/4 with dynamic repo" do
3245
TestRepo.put_dynamic_repo(:unknown)
3346
assert_raise RuntimeError, ~r/:unknown/, fn -> TestRepo.query!("SELECT 1") end

lib/ecto/adapters/postgres/connection.ex

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,20 @@ if Code.ensure_loaded?(Postgrex) do
746746
end
747747
end
748748

749+
defp expr([], _sources, _query) do
750+
# We cannot compare in postgres with the empty array
751+
# i. e. `where array_column = ARRAY[];`
752+
# as that will result in an error:
753+
# ERROR: cannot determine type of empty array
754+
# HINT: Explicitly cast to the desired type, for example ARRAY[]::integer[].
755+
#
756+
# On the other side comparing with '{}' works
757+
# because '{}' represents the pseudo-type "unknown"
758+
# and thus the type gets inferred based on the column
759+
# it is being compared to so `where array_column = '{}';` works.
760+
"'{}'"
761+
end
762+
749763
defp expr(list, sources, query) when is_list(list) do
750764
["ARRAY[", intersperse_map(list, ?,, &expr(&1, sources, query)), ?]]
751765
end

test/ecto/adapters/postgres_test.exs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,9 @@ defmodule Ecto.Adapters.PostgresTest do
752752

753753
query = Schema |> select([], fragment("?", ~w(abc def))) |> plan()
754754
assert all(query) == ~s{SELECT ARRAY['abc','def'] FROM "schema" AS s0}
755+
756+
query = Schema |> where([s], s.w == []) |> select([s], s.w) |> plan()
757+
assert all(query) == ~s{SELECT s0."w" FROM "schema" AS s0 WHERE (s0."w" = '\{\}')}
755758
end
756759

757760
test "interpolated values" do

0 commit comments

Comments
 (0)