laravel / framework

The Laravel Framework.
https://laravel.com
MIT License
32.5k stars 11.01k forks source link

Float incorrectly casted to PDO::PARAM_INT in MySQL, should be: PDO::PARAM_STRING #25818

Closed stemis closed 6 years ago

stemis commented 6 years ago

Description:

When issuing the following command: User::where('rating', '>', 2.5)->get() The query that actually goes to the database is: WHERE rating > 2 What should go to the database in order for correct behavior: WHERE rating > '2.5'

This is caused by the MysqlConnection using PDO::PARAM_INT According to this wiki article by PHP it should use PDO::PARAM_STRING https://wiki.php.net/rfc/pdo_float_type

The PDO extension does not have a type to represent floating point values.

The current recommended practice is to use PDO::PARAM_STR

The line that causes the issue is: https://github.com/laravel/framework/blob/59a045343e0994b45b66fd6afa9199c2d566e0ba/src/Illuminate/Database/MySqlConnection.php#L80

It should be edited to:

is_int($value) ? PDO::PARAM_INT : PDO::PARAM_STR 

@themsaid this is something you have touched before. If this is intentional, could you maybe explain why floating point values are not converted to strings, as per the wiki article.

staudenmeir commented 6 years ago

See also #23850.

stemis commented 6 years ago

@staudenmeir Thanks for referencing that. I have a read a couple of more issue topics but am still uncertain about why it is not cast to string.

The one that really matters is: #16063 , which highlights the issues with JSON comparison

However, I think it is safe to say that we should not solve one issue by introducing another.

This should at least be mentioned on the Database/Eloquent documentation page that when using a float in the where query, it should first be casted to string. This should already prevent a lot of people having headaches!

staudenmeir commented 6 years ago

I just tested this on the latest MariaDB 10.3.9 (in Homestead) and it works for me.

laurencei commented 6 years ago

Thanks - I'll close this.

@stemis - feel free to submit a PR to the docs with your idea above.

ionutantohi commented 6 years ago

@stemis do you have PDO::ATTR_EMULATE_PREPARES = true ?

I noticed that this option causes this behaviour. Please check #23850