-
Notifications
You must be signed in to change notification settings - Fork 8
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
Detection of Float query parameter types is problematic #6
Comments
MySQL is interested in the types of the variables you are binding. It will convert to the appropriate type on the server if possible. If not possible to convert then mysql_stmt_bind_param() will return CR_UNSUPPORTED_PARAM_TYPE. I found this information on accepted type conversions between C and MySQL types: Some examples:
So I don't think we need to pull the column type so much as provide a conversion to an appropriate C type that can MySQL can work with. |
Thanks for the clarification; I was rather confused by the combination of the MySQLBindParameter>>detectParamType Float test and the byte-order issue in MySQLBindParameter>>doubleBytes:. The issue appears to be fixable by implementing the change to byte-ordering in doubleBytes: (above) and removing the test for typeFLOAT in detectParam, i.e. always returning typeDOUBLE for Floats/Fractions. With both these changes it's possible to successfully bind arbitrary Float values to FLOAT, DOUBLE, DECIMAL and INTEGER column parameters. |
MySQLBindParameter>>detectParamType handles Floats (and Fractions) as follows:
Firstly I'm not sure this is a valid test for floats versus doubles. For example, 4.25 is detected as typeFLOAT whereas 4.2 is detected as typeDOUBLE.
More generally, I think the approach of detecting the parameter type based on the value is incorrect. Test case (where c is a connected MySQLDriver):
This fails at the execute stage with an Out of Range error, since 4.2 is detected as typeDOUBLE, but is being assigned to a FLOAT parameter.
Fundamentally, I think it's flawed to try to deduce the parameter type based on the value being assigned; the type should come from the column definition for the parameter (I don't know if MySQL provides an easy way to do this however).
As a partial aside, running the above test with 4.25 (which is picked up as typeFLOAT) results in a returned value of 2.26562 - this looks to be due to an issue with MySQLBindParameter>>floatBytes which (I'm guessing) is due to a change in the internal representation of Floats in Pharo at some point in the past.
Running the test with a DOUBLE column also results in incorrect results even when using a typeDOUBLE value:
This issue can be fixed by reversing the order in which the paramValue's bytes are considered in MySQLBindParameter>>doubleBytes:
All tests carried out with 64bit Pharo 7.0 on OSX, connecting to MySQL (actually MariaDB) on Raspberry Pi 4.
The text was updated successfully, but these errors were encountered: