-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Optimize more entity filter expressions #6539
base: master
Are you sure you want to change the base?
Conversation
e0f54c1
to
440d248
Compare
The issue outlines four filter expressions that need optimization. It seems we need to discuss how to handle the following cases:
Specifically:
Another question, not directly related to any of the filter types: @seadowg, feel free to not only answer these questions but also take over if you don't have other pressing tasks. You might have intended to work on this yourself, and I took it on without asking. If that's the case, I hope at least what I’ve done will be helpful. |
It's supported, but not optimized (compared to
For this issue, I'd only intended that we add support for those exact expressions. If it feels easier to you at this point to make the solution more general though, that'd be a bonus.
Interesting! I'll have a look at that as soon as I can.
Everything will "work" without
No I think it's actually a good idea to swap over on this one as I'm worried I'm a silo on how the entities stuff all works (especially the optimizations). It'll be good to spread the knowledge out a bit! |
809b104
to
56489ec
Compare
e80f541
to
9e0e041
Compare
9e0e041
to
9bd7962
Compare
d96b0c8
to
c228b3c
Compare
@seadowg If you take a look at the first couple of commits, you'll see that I added support for While this worked well initially, I found that adding new methods like I believe the best solution to address this, while also reducing the amount of code, would be to generate SQLite selection and selection arguments directly in LocalEntitiesFilterStrategy.
Please take a quick look to make sure you agree with it before I continue. |
I do think you're right that we're going to need something more versatile to support all the kinds of expressions we want to optimize, and I think you're going in the right direction. It is probably the right time to consider generalizing so we don't end up with loads of methods on entitiesRepository.query(Eq("age", "34"))
entitiesRepository.query(NotEq("age", "52"))
entitiesRepository.query(And(Eq("age", "34"), NotEq("name", "Callum")) I guess that would require a type hierarchy like: sealed interface Query {
class Eq(val column: String, val value: String): Query
class NotEq(val column: String, val value: String): Query
class And(val query1: Query, val query2: Query): Query
class Or(val query1: Query, val query2: Query): Query
} This would mean we'd support any length/depth of sealed interface Query {
class And(val comparison1: Comparison, val comparison2: Comparison): Query
class Or(val comparison1: Comparison, val comparison2: Comparison): Query
sealed interface Comparison : Query {
class Eq(val column: String, val value: String): Comparison
class NotEq(val column: String, val value: String): Comparison
}
} What do you think? |
c228b3c
to
a5eba56
Compare
It looks nice but I'm not sure if generating expressions with multiple AND/OR would be easy. I will try to add support for it with the current approach and then introduce such an interface at the end of the process. |
Do you mean generating
That's fine, but I really do think we should make sure we end up with something structured rather than passing string SQL queries to the repository (but it doesn't have to be this type based tree representation approach - that's just one possibility). I'd be tempted to start with just replacing with the current |
5a2d685
to
bd4b88e
Compare
1a9ffe4
to
d1c2405
Compare
676585f
to
e315c73
Compare
e315c73
to
8e9c25f
Compare
Yes but never mind I figured it out.
I agree and it has been implemented.
Yes but I didn't want to waste time and this pull request should handle complex cases as well. |
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 is looking really cool! I wanted to dig into Query
mainly at first. Two things:
- I think we should make sure to separate the
Query
"language" from the "compiler" that turns it into SQL(ite) here.Query
could live outside thesqlite
package and then insqlite
(or somewhere else) we could have the logic that translatesQuery
object to SQL. - We could theoretically get rid of the
getByX
methods onEntitiesRepository
now right? They can just be replaced withquery
as far as I can see. Maybe that's better as a follow-up though?
One more thing is that it looks to me like you've added support for nested expressions here (like value = thing and (value != blah and value != other)
) due to the recursion in LocalEntitiesFilterStrategy#xPathExpressionToQuery
. That's very cool, but not something we need right now so if it makes 1 harder, I'd happily drop it for now.
entities/src/main/java/org/odk/collect/entities/storage/EntitiesRepository.kt
Outdated
Show resolved
Hide resolved
4ad9e03
to
3766a57
Compare
3766a57
to
52a4baf
Compare
Done.
I think it would be better to do that in a separate pull request.
That doesn't seem to be a problem and I still think it's easier to implement a complete and versatile solution in one pull request. |
Closes #6498
Why is this the best possible solution? Were any other approaches considered?
I decided to come up with a versatile solution right away, one that supports complex expressions with multiple AND/OR conditions, so we don’t waste time addressing this in two separate pull requests. The way I pass filters to the database repository using the Query class is a result of the discussion below.
How does this change affect users? Describe intentional changes to behavior and behavior that could have accidentally been affected by code changes. In other words, what are the regression risks?
Testing should focus on filtering entities, ensuring that both simple and complex expressions are handled correctly. You can use the form attached below as a starting point and modify it to include a variety of edge cases, such as nested conditions, combinations of AND/OR operators, etc. This will help identify potential risks, such as incorrect query logic, unexpected behavior with complex filters, or performance issues when processing large datasets.
Do we need any specific form for testing your changes? If so, please attach one.
I used this one: people.zip
Does this change require updates to documentation? If so, please file an issue here and include the link below.
No.
Before submitting this PR, please make sure you have:
./gradlew connectedAndroidTest
(or./gradlew testLab
) and confirmed all checks still passDateFormatsTest