Change MySQL's number handling to be more permissive

MySQL is a bit more... lax with types than other backends. It's very
easy to accidentally get a 64 bit integer or decimal when other backends
would continue to give you a 32 bit integer. Right now we're relying on
conversion happening in `libmysqlclient` for `query_by_index`. If we
ever want to dump `libmysqlclient`, we will need to move those
conversions into Diesel.

However, I've opted to do this in such a way that it affects `sql_query`
as well. Right now there are many differences between what our query
builder says and what MySQL does. (32 bit addition/subtraction returns
64 bit, 32 bit multiplication/division/sum return decimal). Ideally you
should be able to have a struct that derives both `Queryable` and
`QueryableByName`, and have that work with the same query built using
the query builder or `sql_query`.

In order for that to happen, we can't do the conversions until we hit
`FromSql`, since for `sql_query` that is the first and only time we
learn what the expected type is.

Changing `RawValue` from `[u8]` to a new type is technically a breaking
change. However, I'm going to be a bit liberal with my interpretation of
[RFC 1150] and call it a minor breaking change.

[RFC 1150]: https://github.com/rust-lang/rfcs/blob/master/text/1105-api-evolution.md

Keep in mind that MySQL does not have extensions or user defined types
(enums are just strings). That means that there was really no reason for
any `FromSql` impl in the wild to ever inspect the bytes directly. Any
code which is just passing the value to another `FromSql` impl could
have been forwards compatibly written to use `<Mysql as
Backend>::RawValue` instead of `[u8]`. For that reason, I think this can
be considered a minor breaking change, the same way that adding a new
method to a trait is minor even though it can have a naming conflict
with another method implemented for a type.

With all that said, if any member of the core team is uncomfortable with
this change, we can defer this to 2.0.

However, in order to avoid changing the signature of `NamedRow` (which
would be a major breaking change), I had to do some fuckery with `Cell`
in the `MysqlValue` struct. We only ever get immutable access to that
value in `NamedRow`. We can't have `Cell<MysqlValue>` on the row either,
since the signature is `(&self) -> Option<&MysqlValue>`. We can't get an
`Option<&MysqlValue>` from a `Cell<Option<MysqlValue>>`. `RefCell` would
require returning `Option<Ref<'a, MysqlValue>>`
11 files changed
tree: f276c91648923340869c88a57cf2e8bc0e89c3cd
  1. .github/
  2. bin/
  3. diesel/
  4. diesel_cli/
  5. diesel_compile_tests/
  6. diesel_derives/
  7. diesel_infer_schema/
  8. diesel_migrations/
  9. diesel_tests/
  10. examples/
  11. guide_drafts/
  12. migrations/
  13. .appveyor.yml
  14. .editorconfig
  15. .env.sample
  16. .gitignore
  17. .rustfmt.toml
  18. .travis.yml
  19. Cargo.toml
  20. CHANGELOG.md
  21. clippy.toml
  22. code_of_conduct.md
  23. CONTRIBUTING.md
  24. LICENSE-APACHE
  25. LICENSE-MIT
  26. README.md
README.md

A safe, extensible ORM and Query Builder for Rust

Build Status Appveyor Build Status Gitter Crates.io

API Documentation: latest releasemaster branch

Homepage

Diesel gets rid of the boilerplate for database interaction and eliminates runtime errors without sacrificing performance. It takes full advantage of Rust's type system to create a low overhead query builder that “feels like Rust.”

Getting Started

Find our extensive Getting Started tutorial at https://diesel.rs/guides/getting-started. Guides on more specific features are coming soon.

Code of conduct

Anyone who interacts with Diesel in any space, including but not limited to this GitHub repository, must follow our code of conduct.

License

Licensed under either of these:

Contributing

Unless you explicitly state otherwise, any contribution you intentionally submit for inclusion in the work, as defined in the Apache-2.0 license, shall be dual-licensed as above, without any additional terms or conditions.