-
Notifications
You must be signed in to change notification settings - Fork 305
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
Balance SQLite expression tree for logical operators (AND/OR) to lower the depth #2565
Conversation
ae8187f
to
6b3d4c4
Compare
engine/src/main/java/com/google/android/fhir/search/filter/FilterCriterion.kt
Outdated
Show resolved
Hide resolved
engine/src/main/java/com/google/android/fhir/search/filter/FilterCriterion.kt
Outdated
Show resolved
Hide resolved
80c50de
to
0264816
Compare
d9e6d03
to
d764115
Compare
judging purely by the error message, my hypothesis is that the expression tree depth is O(n) for nested OR operators because the expression tree is constructed naively by parsing the OR operators sequentially. For example, for this expression
if the expression tree is constructed naively you'd get:
where each But what you really want is actually this:
where the tree is more "balanced" and this has depth 4. In other words, this is O(log(n)). If my hypothesis of what causes the problem is correct above, instead of trying to break the OR statements into chunks (and having to come up with a value), all you actually have to do is keep the tree balanced by splitting the top level OR statment at the middle of the list of params. Does this make sense? |
Yeah, it makes sense. |
there's no guarantee what i said is true @LZRS - i've done no testing or verification and depending on sqlite's implementation what i said could be complete garbage... so pls test and see if this is true :) (for example you could try to see if you'll hit the depth limit a bit later to bifurcate the tree instead of chunking the parameters) |
Alright, no problem. I'll test it out and get back |
@jingtang10 I tested this out for 1000, 2000 and upto 5000 parameters, and it worked perfectly. I also went ahead a drafted an implementation in the PR |
af4d912
to
821feab
Compare
engine/src/main/java/com/google/android/fhir/search/filter/FilterCriterion.kt
Outdated
Show resolved
Hide resolved
engine/src/main/java/com/google/android/fhir/search/filter/FilterCriterion.kt
Outdated
Show resolved
Hide resolved
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.
Can we add a DatabaseImplTest with
FORK - With unmerged PR #9 - WUP #13 SDK - WUP google#2178 - WUP google#2650 - WUP google#2663 PERF - WUP google#2669 - WUP google#2565 - WUP google#2561 - WUP google#2535
engine/src/main/java/com/google/android/fhir/search/filter/FilterCriterion.kt
Outdated
Show resolved
Hide resolved
engine/src/main/java/com/google/android/fhir/search/filter/FilterCriterion.kt
Outdated
Show resolved
Hide resolved
FORK - With unmerged PR #9 - WUP #13 SDK - WUP google#2178 - WUP google#2650 - WUP google#2663 PERF - WUP google#2669 - WUP google#2565 - WUP google#2561 - WUP google#2535
IMPORTANT: All PRs must be linked to an issue (except for extremely trivial and straightforward changes).
Fixes #2561
Description
Recursively bifurcates the conditional params expressions to prevent occurences of SQLite expression tree exceeding depth of 1000, as suggested in this comment
Alternative(s) considered
Chunking large expression list to limit 50 within parantheses to avoid crashing with
Expression tree is too large (maximum depth 1000)
, as described hereType
Enhancement Feature
Screenshots (if applicable)
Checklist
./gradlew spotlessApply
and./gradlew spotlessCheck
to check my code follows the style guide of this project../gradlew check
and./gradlew connectedCheck
to test my changes locally.