select * from table_1
join table_2 on
table_1.some_id = table_2.some_id AND
table_2.type = key1 AND table_2.value = value1 OR
table_2.type = key2 AND table_2.value = value2
"table_2.type = ? AND table_2.value = ? OR table_2.type = ? AND table_2.value = ?"
[key1, value1, key2, value2]
query |> where([], fragment(^[sql_chunk | args])) |> Repo.one
"SELECT m0.`id`, m0.`x`, m0.`y`, m0.`z` FROM `model` AS m0 INNER JOIN `model2` AS m1 ON m0.`x` = m1.`id` WHERE ((m0.x = ? and m0.y = ?) or (m1.id = ? and m1.id = ?))"
so all seems to work as expected. In ecto source tree there is plenty of tests to cover fragments. I do not see how your case differs from some of the existing tests in there. I based my trials on
https://github.com/elixir-lang/ecto/blob/master/test/ecto/adapters/mysql_test.exs#L369
Cheers,
Alex.
iex(14)> query = from e in Model, where: fragment("1 = 1")
#Ecto.Query<from e in Model, where: fragment("1 = 1")>
iex(15)> sql = "1 = 1"
"1 = 1"
iex(16)> query = from e in Model, where: fragment(^sql)
#Ecto.Query<from e in Model, where: fragment(^"1 = 1")>
iex(17)> Repo.one(query)
** (Ecto.QueryError) MySQL adapter does not support keyword or interpolated fragments in query:
from e in Model,
where: fragment(^...),
select: e
--
You received this message because you are subscribed to the Google Groups "elixir-ecto" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-ecto...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-ecto/5c96536e-3156-481a-a294-df4805b7b97d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
SELECT m0.`id`, m0.`x`, m0.`y`, m0.`z` FROM `model` AS m0 WHERE ((m0.x || m0.y) in ?)
I do not work with MySQL, so you will need to verify that concatenation operator is || in mysql and that in ? param works.
The real solution would be - as Jose mentioned - to allow ORs while compositing queries. Something like this would be really nice:
base = from t in Table, select: t
query = params |> Enum.reduce(fun({key,val}, q) -> (from q0 in q, where: q0.type == ^key and q0.value == ^val) end, base)
but that currently produces ANDs between reduce iterations. It would be nice to have something like:
query = params |> Enum.reduce(fun({key,val}, q) -> (from q0 in q, where_or: q0.type == ^key and q0.value == ^val) end, base)
Cheers,
Alex.