-
-
Notifications
You must be signed in to change notification settings - Fork 4.8k
fix: mongo explain queries should always return as an array of results #7440
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
Closed
+8
−7
Closed
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
865e323
failing testcases
cbaker6 74cb902
fix explain
cbaker6 7710f64
pass without modification to JS SDK
cbaker6 65941a1
add changelog entry
cbaker6 86f6863
Revert comment changes
cbaker6 5721b03
Merge branch 'master' into explain
cbaker6 7a40fa0
Merge branch 'master' into explain
cbaker6 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Just to understand, will this array ever have more than one item?
Uh oh!
There was an error while loading. Please reload this page.
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 will let @cbaker6 answer this, but to throw in my observation:
Although MongoDB has changed the structure of the explain output in the past, they did not change the root which is a dictionary with key
queryPlanner
. Also see https://docs.mongodb.com/manual/reference/explain-results/The more likely reason this result array could contain more than 1 item is if we have a use case in Parse Server in the future where we may want to return more than 1 item.
I tend to think that this is a symptom of a conceptual flaw in our
explain
implementation. The underlying issue is thatexplain
does not return the same type asfind
. That means that anexplain
operation should not be executed withfind
andexplain
as an option. It should be a distinct command which returns a distinct type, which is object.Uh oh!
There was an error while loading. Please reload this page.
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.
@davimacedo Not to my knowledge, but I think it can be possible in the future. @mtrezza’s explanation works here:
This causes an issue for strongly typed languages because find on the parse server is expected to always return an array, not a single object. Currently, there is no way to run explain in the Swift SDK when using Mongo because of this flaw. A dev will have to run an afterFind trigger in Cloud Code and modify the results for it work. This isn’t the case for the Postgres implementation because it follows the rules of find.
@mtrezza comment about is a possible solution, but this will cause for additional complicated code on the server and Client SDKs (currently JS and Swift, none of the others seem to have this implemented). I recommend just making Mongo explain follow the rules of find (this PR) so explain can be used as an option in a find/first query.
Uh oh!
There was an error while loading. Please reload this page.
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.
@mtrezza’s comment above also is reasonable. I didn’t include it because it’s separate from the Mongo Adapter not following the current rules of find, but is still a plus when moving in direction of accepting this PR
Uh oh!
There was an error while loading. Please reload this page.
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’ll note, a few of the fixes I’ve added to the server have been due to:
Since the JS SDK seems to be the only other client SDK that seems to be at feature parity (the Flutter SDK has more features than the others but doesn’t seem to have adequate testcases from what I can find, so I don’t count it), it causes some mistakes because both JS don’t rely on the 2 items I listed above.
To be fair, I think all of the features added without testing against the 2 items above have been implemented well. There’s just some minor bugs in which I submitted PRs for, this Mongo explain PR being one of them.
Uh oh!
There was an error while loading. Please reload this page.
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 bug fix will only break the explain portion of SDKs that use explain (I don't believe there are many, maybe just JS from what I can find), Swift will work. The feature add of 7637 will break query's in general across all SDKs. I don't place these types of breaks in the same category. Plus, one is finished while the other seems to be in a conceptual phase from what I can see.
I think you are asking if the Swift SDK the only SDK that doesn't conform to a known bug. The answer here is, "yes" I don't program anything to conform to bugs I know about. I consider bugs to be things coded on accidents or unintentional, not coded on purpose.
Uh oh!
There was an error while loading. Please reload this page.
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.
Currently, mongo's
explain
returns anobject
, Postgres returns an array ofobjects
. Even in 7637, you are going to have to make a design decision with Mongo because of strongly typed languages;explain: [object]
orexplain: object
. If it's the former, then it's an adjustment of this PR, which makes it closer to an incremental change. If you modify Postgres, you will have to pull the first item out of the array to make the explain property work asexplain: object
. IMO, an array of objects gives you the most flexibility...Postgres reference (Look in
Example
section,FORMAT JSON
): https://www.postgresql.org/docs/current/sql-explain.htmlUh oh!
There was an error while loading. Please reload this page.
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.
A breaking change won't be introduced until 2023. If we change to retuning an object instead of an array in 2022, any other "intermediary" effort (i.e. returning an array for
explain
) will be practically unreleased.To evaluate any intermediary steps, we would have to be know where we ultimately want to go. I'm starting to repeat myself, but in my opinion, the sustainable way forward is to return something like:
Because how else would we return results and meta data? Do we agree on that?
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 way you have the meta data looks good, just need to decide if cursor and explain will be an array of objects or an object.
Uh oh!
There was an error while loading. Please reload this page.
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.
They will be objects for the same reason as we want to return an object on the root level: We cannot know how the results of
explain
orcursor
may change in the future. Once we use an array, we are confining the subsequent structure to be items in a list. We only want to do that if we have a strong reason to assume that we will always expect a list of items, such asresults
, which will likely always be a list of objects.Object and array can of course be used interchangeably, but if we use an array, we'd have to remember what information we expect at which index. And the problems begin when a response is supposed to not contain any value on an intermediary index. In that sense, we want to push the use of arrays as far out as possible and necessary in the response structure.