-
-
Notifications
You must be signed in to change notification settings - Fork 129
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
Add distinctOn to QueryBuilder #805
Conversation
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.
Please can you add a test that uses this functionality?
It's probably easiest to do so using our new testing framework (the one on v4
branch right now is a nightmare); if you branch off of the last good commit in #794 (currently 18b184d38d88f2b9cd7dbeb8bc47c358ec8cfee3
) and
Add a test similar to the "named_query_builder" test:
The line in the config
#> ToyCategoriesPlugin: true
is used here:
config.ToyCategoriesPlugin ? ToyCategoriesPlugin : null, |
to add the plugin that uses it. That's where you'd add a plugin that uses the distinctOn
. Then it's just a case of updating the assertions at the top of the test file and running the tests, doing so should auto-generate the SQL and JSON5 snapshots (if it doesn't, run it again with UPDATE_SNAPSHOTS=1
environmental variable set).
No need to base off that specific commit any more, I've merged #794 |
Co-authored-by: Benjie <benjie@jemjie.com>
I've found a bug with order by I will improve tests further and fix. |
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.
Excellent work on filling this out!
My main concerns right now are:
- connections - are they affected by distinctOn? Does changing the order break them? Will cursors work in all cases? Does totalCount still work as expected?
- relations - if we select a relation inside the selection set, will Postgres execute this efficiently for only the first match in the distinct on, or will it actually execute it for every match and then throw results away (which could be a significant performance cost)? Even if this is a cost, that can just be a cost related to distinctOn and we can document it, but it's important to understand it.
@@ -925,6 +950,7 @@ order by (row_number() over (partition by 1)) desc`; /* We don't need to factor | |||
this.lock("limit"); | |||
this.lock("first"); | |||
this.lock("last"); | |||
this.lock("distinctOn"); |
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'm concerned that because distinctOn
changes the order, it may break connections (specifically cursors) in some cases. This is one of the reasons that we lock orderBy when we do. E.g. if you order by [USERNAME_ASC, NAME_DESC, ID_ASC]
and then distinctOn: [NAME]
then the order would be changed to NAME_DESC, USERNAME_ASC, ID_ASC
and pagination would work differently.
If you don't want to dig into this, maybe the best bet is to forbid combining distinctOn with connections - e.g. before setting distinctOn you lock cursorComparator/selectCursor/etc and then you enforce that they aren't used (otherwise you throw).
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 have added the appropriate locks as I don't have the time to dig into it. I hope I got the locks correct.
From the little research I did cursors should work correctly with DISTINCT ON
packages/postgraphile-core/__tests__/queries/base/distinct_query_builder.toys.test.graphql
Show resolved
Hide resolved
packages/postgraphile-core/__tests__/queries/base/distinct_query_builder.toys.test.graphql
Show resolved
Hide resolved
packages/postgraphile-core/__tests__/queries/base/distinct_query_builder.toys.test.graphql
Show resolved
Hide resolved
Co-authored-by: Benjie <benjie@jemjie.com>
I'm struggling to answer these. But I have added a test that includes |
Would using distinctOn only in lists satisfy your needs? Then you don’t need to worry about aggregates, cursors, etc. (See docs on —simple-collections.) |
We need both cursors and aggregates. |
I spent some time tidying this up, but unfortunately it breaks very easily. I was expecting it to break when you combine
If you do [
{foo: 1, bar: a}, // cursor = C1
{foo: 2, bar: a} // cursor = C2
] But as soon as you do cursor pagination, this falls down. If you ask for the first record after cursor C1 then you don't get C2, instead what you actually get is the result To make |
Description
Adds the ability to provide
DISTINCT ON
to Query Builder.Performance impact
unknown
Security impact
unknown
Checklist
yarn lint:fix
passes.yarn test
passes.RELEASE_NOTES.md
file (if one exists).