-
-
Notifications
You must be signed in to change notification settings - Fork 623
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
[Bug?] node-mysql2 seems to swap x
and y
values of a geographic Point (SRID 4326) stored in mysql8
#2959
Comments
I am happy to help you track down and fix this bug if you can verify that this is indeed a bug, and not some misunderstanding on my part. |
I think I found out an explanation for this problem. I will quote MySQL documentation to try to explain it. I have used DataGrip to make queries. How does MySQL (5 and 8 at least) store a geometric value?MySQL uses an internal binary format to store geometric data as explained here, which is a sequence of bytes in the following order:
where:
Side-note: Interpreting hex representation of coords valuesSide-note: Interpreting hex representation of coords valuesThe hex representation of coords values look a bit unconventional because they are stored in little-endian, 8-byte, double-precision format. For example, Thus, I might be off in the explanation, but the details are not relevant to our topic. How does
|
Right. I need to go for a walk. |
x
and y
values of a geographic Point (SRID 4326) stored in mysql8x
and y
values of a geographic Point (SRID 4326) stored in mysql8
I am not sure anymore whether this can qualify as a bug for node-mysql2. In MySQL 8, the semantics of XCoord and YCoord have changed, or rather gotten stronger for a subset of geometric values – SRID 4326 among them. XCoord now explicitly maps to longitude, and YCoord maps to latitude. But the behaviour of node-mysql2 is still the same. It still maps XCoord to But, due to all this churn, the ground (lat-long) has surely shifted beneath the user. Either the library-level (node-mysql2) or the application-level code has to be modified to reflect the new state. I will wait for a couple of days to see if anyone chimes in. Otherwise, I wil adapt to this problem through a change at the application-level code. |
I looked into what other drivers do with a geometric Point. MySQL's jdbc connectorjdbc provides only the option to retrieve the byte array that represents a stored Point. Its parsing is left to the user. Now, in case of MySQL 8, this byte array stores first longitude, then latitude. So, if it is parsed such that the first byte segment is read into MySQL's official nodejs connectorIt does the same thing as jdbc – it does not parse the retrieved byte array and return it to the caller as-is. The parsing is left to the user. I have updated the My ConclusionWhen
On the other hand, other drivers have simply adopted a hands-off approach, preferring to return the byte array of a geometric Point as-is instead of parsing it before returning it. If this byte array were to be parsed in the manner similar to how I believe that, because For now, I have chosen to use |
Problem
node-mysql2 seems to swap x and y values of a geographic Point stored in mysql8 when it is retrieved through node-mysql2 without special parsing.
Repository that demonstrates the bug
https://github.com/justbhoot/poc-buggy-geographic-point-parsing-by-node-mysql2/
How to reproduce
feat/demo
.db.sql
exists..env
file according to the.env.template
.npm ci
MYSQL_VERSION=8 node index.js
.The last step above – script execution – should produce the following output:
Expected result
For all the rows:
x
column in the second table should show the value inst_x
column of first table.y
column in the second table should show the value inst_y
column of first table.To demonstrate the same from MySQL CLI Shell:
In the above query result,
st_x()
andst_latitude()
point to the first value in the Point, which is in accordance with how SRID 4326 is defined in MySQL.Actual result
For the first row 0 (containing data for SRID 4326):
x
column in the second table shows the value inst_y
column of first table.y
column in the second table shows the value inst_x
column of first table.In other words, node-msyql2 apparently swaps the values for x and y in a retrieved geographic point.
Relevant observations
node-mysql2 behaves as expected, i.e., no swapped x and y, for a point with SRID 0.
node-mysql2 also behaves correctly for both SRIDs in mysql5 (probably because mysql5 ignores SRID anyway).
The text was updated successfully, but these errors were encountered: