Skip to content

Serve OR queries from the index. #3368

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

Merged
merged 9 commits into from
Feb 6, 2022
Merged

Serve OR queries from the index. #3368

merged 9 commits into from
Feb 6, 2022

Conversation

ehsannas
Copy link
Contributor

No description provided.

@ehsannas ehsannas marked this pull request as draft January 25, 2022 22:42
@ehsannas ehsannas force-pushed the ehsann/or-queries-pr-6 branch from e023f88 to 81b6e16 Compare January 25, 2022 23:10
@google-oss-bot
Copy link
Contributor

google-oss-bot commented Jan 25, 2022

Coverage Report 1

Affected Products

  • firebase-firestore

    Overall coverage changed from 45.43% (41e38cb) to 45.52% (d8f2149) by +0.09%.

    FilenameBase (41e38cb)Merge (d8f2149)Diff
    AsyncQueue.java77.11%78.11%+1.00%
    Bound.java33.93%39.29%+5.36%
    DeleteMutation.java95.00%90.00%-5.00%
    IndexBackfiller.java80.00%76.19%-3.81%
    LogicUtils.java?50.00%?
    MemoryIndexManager.java74.07%66.67%-7.41%
    PatchMutation.java100.00%98.39%-1.61%
    QueryEngine.java98.51%98.48%-0.02%
    SetMutation.java97.14%94.29%-2.86%
    SQLiteIndexManager.java99.37%98.69%-0.68%

Test Logs

Notes

  • Commit (d8f2149) is created by Prow via merging PR base commit (41e38cb) and head commit (4b7858b).
  • Run gradle <product>:checkCoverage to produce HTML coverage reports locally. After gradle commands finished, report files can be found under <product-build-dir>/reports/jacoco/.

  1. https://storage.googleapis.com/firebase-sdk-metric-reports/xZ2UpYW9Pu.html

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Jan 25, 2022

Size Report 1

Affected Products

  • firebase-firestore

    TypeBase (41e38cb)Merge (d8f2149)Diff
    aar1.24 MB1.24 MB+2.05 kB (+0.2%)
    apk (release)3.33 MB3.33 MB-924 B (-0.0%)

Test Logs

Notes

  • Commit (d8f2149) is created by Prow via merging PR base commit (41e38cb) and head commit (4b7858b).

  1. https://storage.googleapis.com/firebase-sdk-metric-reports/itcSHXD8k4.html

@ehsannas
Copy link
Contributor Author

/retest

@ehsannas
Copy link
Contributor Author

the idea is that a DNF transform on a composite filter will result in a condition that looks like

condition1 || condition2 || ...

where each condition is an AND operation of 1 or more FieldFilters.

We can then run sub-queries for condition1, condition2, etc, and find the UNION of them. In order to simply use the existing code such as TargetIndexMatcher, getArrayValues, getNotInValues, getLowerBound, getUpperBound, etc, we create a new Target object (referred to as "sub-target" in the code) for each sub-query. Each "sub-target" contains only an AND operation of 1 or more FieldFilters (similar to good old queries).

@ehsannas ehsannas marked this pull request as ready for review January 26, 2022 20:22
@ehsannas ehsannas changed the title Serve or queries from the index. Serve OR queries from the index. Jan 26, 2022
* Iterates over all field indexes that are used to serve the given target, and returns the least
* recent offset of them all. Asserts that the target can be served from index.
*/
FieldIndex.IndexOffset getLeastRecentIndexOffset(Target target);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minOffset? You could alternatively also drop the LeastRecent/Min name altogether and just call this getOffset(Target target)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'd be more clear to keep a wording that signals to the caller that this method will do a min operation of a bunch of offsets, rather than just a getter method that retrieves one offset. I'll go with minOffset.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

FieldIndex.IndexOffset getLeastRecentIndexOffset(Target target);

/** Returns the lowest offset for the provided index group. */
FieldIndex.IndexOffset getLeastRecentIndexOffset(Collection<FieldIndex> fieldIndexes);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just pass the collection group? The index manager has all indices in memory.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also we should probably add a static import for IndexOffset or make IndexOffset a high level class.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -74,6 +74,18 @@
/** Returns all configured field indexes. */
Collection<FieldIndex> getFieldIndexes();

/** Returns whether we can serve the given target from the index. */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/the/an

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

import androidx.annotation.Nullable;
import com.google.common.collect.ObjectArrays;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a goal to kick our Guava dependency, as the Android build doesn't deal well with version conflicts for popular libraries. Hence, we should not directly use Guava and we eventually want to remove it altogether (it is used by GRPC).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

subQueries.get(0)
:
// Construct "subQuery1 UNION subQuery2 UNION ... LIMIT N"
TextUtils.join(" UNION ", subQueries) + " LIMIT " + target.getLimit();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to make sure that we do not pass more than 999 bind elements. The best way to do this probably to validate that the query only contains 100 DNF terms (or what we decide the limit is).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you also add parenthesis to indicate whether the LIMIT belongs to all statements or just the last one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add an assertion here, and when I post the DNF calculation code I'll throw an exception if the number of DNF terms exceeds a certain number.

Also updating this to SELECT * FROM (query1 UNION query2 UNION ...) LIMIT X.

* Iterates over all field indexes that are used to serve the given target, and returns the least
* recent offset of them all. Asserts that the target can be served from index.
*/
IndexOffset minOffset(Target target);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All Java methods should start with a verb: getMinOffset()

You should also align the two comments on their usage of "lowest" and "least recent" (which contrasts min).

return true;
}

private IndexOffset getLeastRecentIndexOffset(Collection<FieldIndex> fieldIndexes) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This name might still need an update.

@ehsannas
Copy link
Contributor Author

ehsannas commented Feb 5, 2022

/retest

@ehsannas ehsannas merged commit 69104c7 into master Feb 6, 2022
@ehsannas ehsannas deleted the ehsann/or-queries-pr-6 branch February 6, 2022 21:36
@firebase firebase locked and limited conversation to collaborators Mar 9, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants