I've got a Chunk schema where each Chunk belongs_to a Sortable, so I'm fetching all Chunks with a given sortable_id:
iex> import Ecto.Query, only: [from: 2]
iex> alias Crowdsort.{Repo, Sortable, Chunk}
iex> query = from(c in Chunk, select: c.id, where: c.sortable_id == 12)
#Ecto.Query<from c in Crowdsort.Chunk, where: c.sortable_id == 12, select: c.id>
iex> chunk_ids = Repo.all(query)
[debug] QUERY OK source="chunks" db=1.3ms
SELECT c0."id" FROM "chunks" AS c0 WHERE (c0."sortable_id" = 12) []
'='
iex> chunk_ids
'='
The real id should have been 61, and 61 is the ascii code for '='
This happens for any query returning a single id (for example, returning the string '3' when the real id was 51). When there are multiple values, it correctly returns a list of integers. Also, Repo.one(query) correctly returns 61, but fails if there are multiple ids.
It should have returned a list of ids matching my query. Like this: [61]. I can confirm that the data in the database is correct by running the resulting SQL:
crowdsort_dev=# SELECT c0."id" FROM "chunks" AS c0 WHERE (c0."sortable_id" = 12);
id
----
61
(1 row)
The code for my schema is here: https://gitlab.com/mac-chaffee/crowdsort/tree/master/lib/crowdsort/data
My migrations are here: https://gitlab.com/mac-chaffee/crowdsort/tree/master/priv/repo/migrations
And the important bits of mix ecto.dump:
CREATE TABLE sortables (
id bigint NOT NULL,
inserted_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL
);
CREATE TABLE chunks (
id bigint NOT NULL,
data jsonb,
sortable_id bigint,
inserted_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL
);
I tried extending a test case to catch this bug, but I wasn't able to replicate it:
test "works with primary key value" do
schema = %MySchema{id: 1, x: "abc"}
TestRepo.get(MySchema, 123)
TestRepo.get_by(MySchema, x: "abc")
# Test that the id is not interpreted as an ascii character
q = from(c in MySchema, select: c.id, where: c.id == 1)
assert [1] == TestRepo.all(q)
TestRepo.update!(schema |> Ecto.Changeset.change, force: true)
TestRepo.delete!(schema)
end
Could it be an issue with the schema I wrote?
It is not a bug, when Elixir sees a list of integers, it prints that between single quotes as it may be a list of characters. Try this on IEx:
iex> i '='
And it will tell you more about it.
Most helpful comment
It is not a bug, when Elixir sees a list of integers, it prints that between single quotes as it may be a list of characters. Try this on IEx:
And it will tell you more about it.