Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error when loading specific values in fields of type {:map, :float} #2637

Closed
tallysmartins opened this issue Aug 2, 2018 · 8 comments
Closed

Comments

@tallysmartins
Copy link
Contributor

tallysmartins commented Aug 2, 2018

Environment

  • Elixir version (elixir -v): Elixir 1.6.4
  • Database and version (PostgreSQL 9.4, MongoDB 3.2, etc.): PostgreSQL 9.6.7
  • Ecto version (mix deps): master branch
  • Database adapter and version (mix deps): postgrex 0.14.0-dev
  • Operating system: Debian Jessie

Current behavior

When I have a schema with a field of type {:map, :array}, some values are parsed to exponential floats and are saved as integers in the database.

For example, %{"50" => 416500.0} fails, because it is saved as an integer 416500, even after Float.parse(416500), which returns an exponential form for it. I don't know if it has something to do with the jsonb fields, but for simple floatfields it works.

Float.parse("416500")
{4.165e5, ""}

I've added an example to ecto integration tests that shows the break point. See this commit tallysmartins@5048199 and the correspondent build on Travis-ci

     ** (ArgumentError) cannot load `%{"50" => 416500}` as type {:map, :float} for field `scores` in schema Ecto.Integration.Post
     code: assert [_] = TestRepo.all from p in Post, where: p.title not in []
     stacktrace:
       (ecto) lib/ecto/schema.ex:1794: Ecto.Schema.load!/5
       (ecto) lib/ecto/schema.ex:1742: Ecto.Schema.safe_load_zip/4
       (ecto) lib/ecto/schema.ex:1743: Ecto.Schema.safe_load_zip/4
       (ecto) lib/ecto/schema.ex:1730: Ecto.Schema.__safe_load__/6
       (ecto) lib/ecto/repo/queryable.ex:316: Ecto.Repo.Queryable.process_source/6
       (ecto) lib/ecto/repo/queryable.ex:191: anonymous fn/6 in Ecto.Repo.Queryable.preprocessor/3
       (elixir) lib/enum.ex:1294: Enum."-map/2-lists^map/1-0-"/2
       (ecto) lib/ecto/repo/queryable.ex:152: Ecto.Repo.Queryable.execute/4
       (ecto) lib/ecto/repo/queryable.ex:18: Ecto.Repo.Queryable.all/3
       integration_test/cases/repo.exs:44: (test)

Expected behavior

Save and load the field the same way as simple float field.

@tallysmartins tallysmartins changed the title Loading error with specific values in fields of type {:map, :float} Error when loading specific values in fields of type {:map, :float} Aug 2, 2018
@wojtekmach
Copy link
Member

It's curious that the integration test fails on pg but passes on mysql.

@tallysmartins
Copy link
Contributor Author

@wojtekmach good point! but actually I didn't add a value for field to a test case for mysql, just for pg 🤔

@wojtekmach
Copy link
Member

@tallysmartins integration_test/cases/repo.exs and others are shared between different adapters, see e.g.: https://github.com/elixir-ecto/ecto/blob/master/integration_test/mysql/all_test.exs#L12

@michalmuskala
Copy link
Member

It seems this is an issue with how postgresql handles JSON with floats in exponential notation.

# create table foo(map jsonb);
CREATE TABLE
# insert into foo(map) VALUES ('{"foo": 416500.0}');
INSERT 0 1
# insert into foo(map) VALUES ('{"foo": 4.165e5}');
INSERT 0 1
# SELECT * FROM foo;
        map
-------------------
 {"foo": 416500.0}
 {"foo": 416500}
(2 rows)

@josevalim
Copy link
Member

@michalmuskala the worst part is that Postgres is semantically correct, there are no integers/floats in JSON. I guess we need to do casting here on Ecto side.

@michalmuskala
Copy link
Member

Should we do for {:map, _} type the same thing we do for {:embed, _} in here? https://github.com/elixir-ecto/ecto/blob/master/lib/ecto/adapters/sql.ex#L47

@josevalim
Copy link
Member

@michalmuskala if it fixes the bug, sure. :) We may need to do a couple extra things though.

@hoarf
Copy link

hoarf commented Feb 19, 2019

Any chance that this problem is also happening with {:array, :float}? I have a issue with an array of floats sometimes failing to be inserted. (Elixir 1.7.3, ecto, 2.2)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants