Skip to content

Commit b81cd48

Browse files
authored
Report correct error for value lists in joins (#156)
Some SQL syntax does not pass a table prefix (atom or string) In the case of `create_name`, then third param may be a string or atom prefix ... and in those cases should be treated as a prefix. However syntax such as `VALUES (...)` will pass in the values list information as the third tuple. this was causing spurious exceptions to be thrown, rather than creating the correct table name Introduce `assert_valid_join` which checks for unsupported join syntax This improves the error messages for `JOIN VALUES (...) AS` clauses which were being mistakenly tagged as a table prefixing issue. Now the user gets a more accurate message. It also puts all the join syntax checking into a single function which makes it a bit eaiser to reason about (e.g. that hints, values, etc. are not OK, but other join constructs are)
1 parent c32929c commit b81cd48

File tree

2 files changed

+40
-10
lines changed

2 files changed

+40
-10
lines changed

lib/ecto/adapters/sqlite3/connection.ex

+22-10
Original file line numberDiff line numberDiff line change
@@ -993,7 +993,8 @@ defmodule Ecto.Adapters.SQLite3.Connection do
993993
defp using_join(%{joins: joins} = query, _kind, prefix, sources) do
994994
froms =
995995
Enum.map_intersperse(joins, ", ", fn
996-
%JoinExpr{qual: _qual, ix: ix, source: source} ->
996+
%JoinExpr{qual: _qual, ix: ix, source: source} = join ->
997+
assert_valid_join(join, query)
997998
{join, name} = get_source(query, sources, ix, source)
998999
[join, " AS " | name]
9991000
end)
@@ -1014,14 +1015,9 @@ defmodule Ecto.Adapters.SQLite3.Connection do
10141015
on: %QueryExpr{expr: expression},
10151016
qual: qual,
10161017
ix: ix,
1017-
source: source,
1018-
hints: hints
1019-
} ->
1020-
if hints != [] do
1021-
raise Ecto.QueryError,
1022-
query: query,
1023-
message: "join hints are not supported by SQLite3"
1024-
end
1018+
source: source
1019+
} = join ->
1020+
assert_valid_join(join, query)
10251021

10261022
{join, name} = get_source(query, sources, ix, source)
10271023

@@ -1035,6 +1031,20 @@ defmodule Ecto.Adapters.SQLite3.Connection do
10351031
end)
10361032
end
10371033

1034+
defp assert_valid_join(%JoinExpr{hints: hints}, query) when hints != [] do
1035+
raise Ecto.QueryError,
1036+
query: query,
1037+
message: "join hints are not supported by SQLite3"
1038+
end
1039+
1040+
defp assert_valid_join(%JoinExpr{source: {:values, _, _}}, query) do
1041+
raise Ecto.QueryError,
1042+
query: query,
1043+
message: "SQLite3 adapter does not support values lists"
1044+
end
1045+
1046+
defp assert_valid_join(_join_expr, _query), do: :ok
1047+
10381048
defp join_on(:cross, true, _sources, _query), do: []
10391049

10401050
defp join_on(_qual, expression, sources, query),
@@ -1909,10 +1919,12 @@ defmodule Ecto.Adapters.SQLite3.Connection do
19091919

19101920
defp quote_table(nil, name), do: quote_entity(name)
19111921

1912-
defp quote_table(_prefix, _name) do
1922+
defp quote_table(prefix, _name) when is_atom(prefix) or is_binary(prefix) do
19131923
raise ArgumentError, "SQLite3 does not support table prefixes"
19141924
end
19151925

1926+
defp quote_table(_, name), do: quote_entity(name)
1927+
19161928
defp quote_entity(val) when is_atom(val) do
19171929
quote_entity(Atom.to_string(val))
19181930
end

test/ecto/adapters/sqlite3/connection/join_test.exs

+18
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,24 @@ defmodule Ecto.Adapters.SQLite3.Connection.JoinTest do
135135
end
136136
end
137137

138+
test "join with values is not supported" do
139+
assert_raise Ecto.QueryError, fn ->
140+
rows = [%{x: 1, y: 1}, %{x: 2, y: 2}]
141+
types = %{x: :integer, y: :integer}
142+
143+
Schema
144+
|> join(
145+
:inner,
146+
[p],
147+
q in values(rows, types),
148+
on: [x: p.x(), y: p.y()]
149+
)
150+
|> select([p, q], {p.id, q.x})
151+
|> plan()
152+
|> all()
153+
end
154+
end
155+
138156
test "join with fragment" do
139157
query =
140158
Schema

0 commit comments

Comments
 (0)