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
Firebird .NET Data Provider reads Guids incorrectly on little-endian systems [DNET509] #493
Comments
Commented by: Herman Schoenfeld (sphere10.com) Fixed typos. |
Modified by: Herman Schoenfeld (sphere10.com)description: On a little-endian systems Guids values are not being correctly hydrated by the Firebird http://ADO.NET provider. For example, a user may insert a Guid via a query of the form ..." INSERT INTO MyTable VALUES (UUID_TO_CHAR(" + guid.ToString() + " ))" But when that user loads the Guid back via the provider (on a little endian system), the value is different than the correct value stored on the database value. The problem is that Uuid & Guid vary in storage format but not it presentation format.The The CHAR(16) octets contain the Uuid bytes in big endian layout. When hydrating these bytes into a Guid, the provider does not compensate for the Guid's storage of certain parts as the native endian. The correct way to parse the uuid into a guid is:
Suspected location of bug is in class 'DbValue' method 'GetGuid'. As a work-around, I've written a wrapper for the FbDataReader which will correct the invalid guid value.
=> On little-endian systems Guid values are not being correctly hydrated by the Firebird http://ADO.NET provider. For example, a user may insert a Guid via a query of the form ..." INSERT INTO MyTable VALUES (UUID_TO_CHAR(" + guid.ToString() + " ))" But when that user loads the Guid back via the provider (on a little endian system), the value is different than the correct value stored on the database value. The problem is that Uuid & Guid vary in storage format but not it presentation format.The The CHAR(16) octets contain the Uuid bytes in big endian layout. When hydrating these bytes into a Guid, the provider does not compensate for the Guid's storage of certain parts as the native endian. The correct way to parse the uuid into a guid is:
Suspected location of bug is in class 'DbValue' method 'GetGuid'. As a work-around, I've written a wrapper for the FbDataReader which will correct the invalid guid value.
|
Commented by: damjan (damjan) Hi Jiri Is there a plan to fix this in the future? Or at lease some workaround? We have a char(16) field in the database table that is the ID of the entry. Is there a solution that would not imply converting the GUID after retrieval? Maybe using a different type of ID field in the database? Or downloading a different version of the provider? Our Firebird client version is 4.6.1.0 Thank you Damjan |
Commented by: @cincuranet The problem is that FirebirdClient had GUID support before Firebird and hence it was not clear how the binary data will be interpreted by Firebird (if ever, at that time). Changing this currently is a huge breaking change. That's why I'm kind of slow doing it. And also because when you store GUID from .NET and read it again from .NET the string representation is the same. So the only problem is mixing UUID_TO_CHAR (and inverse function) values and string values from .NET. Kind of wish there was a way to change this without breaking anything (or introducing API discrepancies). |
Commented by: damjan (damjan) The problem is the following: guid1 is original guid, guid2 is the one saved in DB 1. create entity with guid1 At point 4 we use a typical linq query with entity framework entities. Maybe the Firebird Entity framework provider doesn't take in account this particularity of changed guids, in the moment of materializing the "where" query. It doesn't happen with TSource commands like "FirstOrDefault" or "SingleOrDefault". Only with IQueryable like "Where". Maybe the problem lays in the Firebird Entity Framework Provider and not in Firebird http://Ado.Net Provider. We use Firebird Entity Framework Provider 4.6.1.0 and Firebird http://Ado.Net Provider 4.6.1.0. We would appreciate any suggestion on how to deal with that. |
Commented by: damjan (damjan) Hi again Jiri We have now more specific description of our problem. We are trying to dynamically create a query according to some property name and value metadata, but we are not retrieving the correct entities. Using normal LINQ query works as expected, and the generated SQL Query contains a parameter without the CHAR_TO_UUID function: SQL Query: WHERE "V"."LE_OID" = @p__linq__0) AS "B" Using a System.Linq.Expression the query contains the UUID function call with the GUID and returns no results: Here is a code snippet to create the Expression: public static Expression<Func<TItem, bool>> PropertyEquals<TItem, TValue>( Is it possible to generate a sql query like the first with a expression or is there any other solution to achieve this goal? Thank you |
Commented by: @cincuranet @herman Schoenfeld: @Damjan: |
Modified by: @cincuranetstatus: Open [ 1 ] => In Progress [ 3 ] |
Commented by: @cincuranet Let's make it happen: http://firebird.1100200.n4.nabble.com/About-GUIDs-in-Firebird-tp4645048p4645807.html . |
Commented by: @cincuranet Can you maybe any of you test this https://ci.appveyor.com/project/cincura_net/firebirdsql-data-firebirdclient/build/1171/job/ix1hjw5v8tg9hhuu/artifacts build. It should have the new Guid reading/writing. |
Modified by: @cincuranetFix Version: vNextBig [ 10850 ] |
Modified by: @cincuranetsummary: Firebird .NET Data Provider reads Guids incorrectly on little-endian systems => Firebird .NET Data Provider reads Guids incorrectly on little-endian systems #breaking |
Submitted by: Herman Schoenfeld (sphere10.com)
On little-endian systems Guid values are not being correctly hydrated by the Firebird http://ADO.NET provider.
For example, a user may insert a Guid via a query of the form
..." INSERT INTO MyTable VALUES (UUID_TO_CHAR(" + guid.ToString() + " ))"
But when that user loads the Guid back via the provider (on a little endian system), the value is different than the correct value stored on the database value.
The problem is that Uuid & Guid vary in storage format but not it presentation format.The The CHAR(16) octets contain the Uuid bytes in big endian layout. When hydrating these bytes into a Guid, the provider does not compensate for the Guid's storage of certain parts as the native endian. The correct way to parse the uuid into a guid is:
Suspected location of bug is in class 'DbValue' method 'GetGuid'.
As a work-around, I've written a wrapper for the FbDataReader which will correct the invalid guid value.
Commits: fdb00e0
The text was updated successfully, but these errors were encountered: