I had this problem once before, and maybe there’s a better way to do this, but I’ll share how I solved it.
If you look closely at the error, Postgrex is telling you that instead of an integer type (or multiple integers separated by a comma), e.g. ... IN (1,2,3)
it’s getting a list type, e.g. ... IN ([1,2,3])
. So to fix this, you’ll need to convert the list into a binary e.g. "1,2,3"
and modify your fragment SQL to have PostgreSQL convert the incoming binary to an array of integers using the PostgreSQL string_to_array()
function and casting it’s that to an integer type.
Here’s your example fragment with the changes:
...
fragment(
"EXISTS (SELECT NULL
FROM OBJECT_TAGS o_t
JOIN TAGS t ON t.id = o_t.tag_id
WHERE t.id = ANY(string_to_array(?, ',')::integer[]))
AND o_t.object_id = ?
GROUP BY o_t.object_id
HAVING COUNT(DISTINCT t.name) = ?)",
^Enum.join(tag_ids, ","), # [1, 3, 5] -> "1,3,5"
...
Of course I didn’t test that code, but it should work. The Enum.join(tag_ids, ",")
converts the list of integers into a binary e.g. “1,3,5” and that gets inserted into the string_to_array(?, ',')::integer[]
in the fragment.
PostgreSQL gets what it needs and everyone is happy