-
-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Fix GeoPoint issues on PostgreSQL (#3285 & #3659) #3660
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
Conversation
@vitaly-t @kulshekhar and @cherukumilli - would you guys mind reviewing this PR? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apart from the comment, I think this needs a closer look by someone who uses GeoPoint (I don't) as the tests are failing. My suspicion is that the second set of change might not be necessary - this is just a guess though.
patterns.push(`ST_distance_sphere($${index}:name::geometry, POINT($${index + 1}, $${index + 2})::geometry) <= $${index + 3}`); | ||
sorts.push(`ST_distance_sphere($${index}:name::geometry, POINT($${index + 1}, $${index + 2})::geometry) ASC`) | ||
patterns.push(`ST_distance_sphere($${index}:name::geometry, POINT($${index + 2}, $${index + 1})::geometry) <= $${index + 3}`); | ||
sorts.push(`ST_distance_sphere($${index}:name::geometry, POINT($${index + 2}, $${index + 1})::geometry) ASC`) | ||
values.push(fieldName, point.longitude, point.latitude, distanceInKM); | ||
index += 4; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks fine.
Although I think it might be more readable to change the order of latitude/longitude when pushing them in values
.
So, leaving lines 328/329 as they originally were and replacing values.push(fieldName, point.longitude, point.latitude, distanceInKM);
with values.push(fieldName, point.latitude, point.longitude, distanceInKM);
on line 330
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
whenever in doubt about what pg-promise
outputs, you can always run it through pgp.as.format(query, values)
locally, throw the result into the console and see what's there ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I may have incomplete understanding in what that ST_distance_sphere
does, but just to make sure, the :name
formatting results in the value being wrapped into double quotes, as in ST_distance_sphere("value",
, as per the SQL Names formatting.
Are you guys sure this is what the function actually expects? 'Cos I'm not sure...
It looks very suspecious. Looks to me from the API documentation that it should be a string. Or am I wrong there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Original tests were passing, so I'd trust it. But I may be wrong
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Solution suggested by @kulshekhar also works actually. Just tried it on my local machine.
Not sure if this is what you meant @vitaly-t but as far as I can see, the results aren't wrapped in double quotes at all.
Yes, original tests were passing @flovilmart and it works fine so far on my app.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The best way to see what is really going on in terms of the queries being executed, is with pg-monitor. You can diagnose issues much quicker than.
For that just update PosgresClient.js like this:
- Add
var monitor = require('pg-monitor');
- Call
monitor.attach(dbOptions);
to attach to the pg options object - Optional, for best look:
monitor.setTheme('matrix');
And of course install it first npm install pg-monitor --save
Then you will be able to see every query the module executes 😉
@vferdiansyah what is very odd in your case, is that the test suite that covers what you describe fails with your changes. The same test suite is used against mongodb. Can you design a single test that would fail on PG currently and that shows what part is failing? Particularly have a look at that test suite Which specifically test the different use cases you describe here and here. To run the tests on your machine, I encourage you to use:
With a local PG database running. |
@vferdiansyah updated the pull request - view changes |
Committed new fix that passed all tests on my local machine. |
Tests seems to be passing ;) |
Yep. Hopefully this is gonna be released soon. |
The tests were passing even before this PR but the query wasn't behaving in the expected manner. @vferdiansyah would it be possible to add a test (similar to the existing ones) that would fail with the existing code but pass with this PR? I suspect it might be as simple as copying the existing test and plugging in the values that didn't work for you. This would ensure that any future changes to this part of the code won't inadvertently break what your PR fixes! |
So I've tried making a new test case which I think is gonna fail, that is returning nearest location since that is the one that breaks on my app. The test looks like this:
BUT, the test still PASSED on both the current version and the one with my PR. HOWEVER, when I tried it in my app, both returns a very different results. I'm querying a place nearby a location with coordinates (35.0056643, 135.7745649). As you can see in the picture above, the latitude returned by the current version is wrong. Latitude should be ranged from -90 to +90. And I have checked my database and can confirm that the latitude value is actually a longitude and vice versa. And with the current PR, it returns the desired value. The thing that I don't understand is, according to the test, it returns the desired results. So how can it breaks? Or maybe I miss something with my test case above? |
Any inputs on this @flovilmart @vitaly-t? |
Yeah, that's a bummer, I dont recall why I reversed latitudes and longitude in the point, but because this is against the 'natural' order, there's probably a good reason. Otherwise, it's good, as it reversing the points twice, but may break when updating the server. |
Codecov Report
@@ Coverage Diff @@
## master #3660 +/- ##
==========================================
+ Coverage 90.16% 90.45% +0.29%
==========================================
Files 114 114
Lines 7532 7406 -126
==========================================
- Hits 6791 6699 -92
+ Misses 741 707 -34
Continue to review full report at Codecov.
|
@vferdiansyah Can you add a test that shows the fix is effective? From what I can see, we flipped the order of the coordinates inside the storage but all tests are still good. |
@vferdiansyah I just ran the test locally alone, on the top of the master branch and it doesn'T seem to validate the error (it should fail) |
That's why I wrote this in my previous comment:
It fails on my app but it passed all tests. So something must be wrong down the road but I still can't find where. If you see the screenshots of the response on my previous comment, you'll know that it's a bug. |
That's what bugs me, it seems that we don't really understand where it fails and why. |
@flovilmart I've tried several things today (like exchanging latitude to longitude, etc), but this is the only one that works :/ |
I can understand your frustration, however, this bug seems to be critical, and without a proper test that makes an example out of it, I'm not really sure what to think. |
Yeah I know. Do you still can't recall why did you reverse the order when you first created this adapter? |
Because latitude / longitude translate to y/x more than x/y |
We can't find the actual underlying by creating proper reproduction in the tests. |
Hi. I've encountered the reversing issue. Since Postgres uses WGS84 Longitude goes first. If you want fix the reversing it happened on this line. updateObjectByQuery.
Old
It should be written like.
I can do a PR and test for this |
That would be good! Thanks! |
Closing as supersed by #3874 |
This is a small fix to the GeoPoint issues that I experienced on #3285 and #3659