-
Notifications
You must be signed in to change notification settings - Fork 624
Add != and NOT_IN queries (not public) #1872
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
Conversation
Binary Size ReportAffected SDKs
Test Logs
NotesHead commit (6324327b) is created by Prow via merging commits: ed8977b cc4397b. |
Coverage ReportAffected SDKs
Test Logs
NotesHTML coverage reports can be produced locally with Head commit (6324327b) is created by Prow via merging commits: ed8977b cc4397b. |
* @param <T> The type of the values of in common between the expected list and actual set. | ||
*/ | ||
// PORTING NOTE: JUnit and XCTest use reversed conventions on expected and actual values :-(. | ||
public static <T> void assertArrayEquals(List<T> expected, List<T> actual) { |
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 name doesn't seem right. Neither argument is an array and the ordered-container property of arrays is explicitly ignored in the implementation.
assertSetEquals
above are essentially asserting the two containers are equal without regard for ordering. I think you probably could use the same name here, since that's what you're doing.
However, I think you can combine this with the one above. Make it:
public static <T> void assertSetEquals(Iterable<T> expected, Iterable<T> actual) {
Set<T> expectedSet = Sets.newHashSet(expected);
Set<T> actualSet = Sets.newHashSet(actual);
assertEquals(expectedSet, actualSet);
}
This has the added benefit of allowing Collection<T>
to be passed as an argument directly, which will eliminate all the Lists.newArrayList
in your callers.
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.
Done. Thanks for the explanation!
|
||
QuerySnapshot snapshot = waitFor(collection.whereNotEqualTo("zip", 98101L).get()); | ||
assertArrayEquals( | ||
Lists.newArrayList(expectedDocsMap.values()), querySnapshotToValues(snapshot)); |
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.
As noted on assertArrayEquals
, remove this Lists.newArrayList
, here and throughout.
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.
Removed here and throughout.
/** | ||
* Given an operator, returns the set of operators that cannot be used with it. | ||
* | ||
* <p>Operators in a query must adhere to the following set of rules: 1. Only one array operator |
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.
To make a list use
<ol>
<li>Only one array operator ...
<li>One one disjunctive ...
</ol>
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.
done.
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 list wrapper element is required (<ol>
indicates an ordered list (aka numbered); use <ul>
for unordered (aka bulleted)).
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.
Done for reals.
} else { | ||
hardAssert( | ||
operator != Operator.ARRAY_CONTAINS && operator != Operator.ARRAY_CONTAINS_ANY, | ||
operator.toString() + "queries don't make sense on document keys"); | ||
return new KeyFieldFilter(path, operator, value); | ||
} | ||
} else if (Values.isNullValue(value)) { | ||
if (operator != Filter.Operator.EQUAL) { | ||
// TODO(ne-queries): Update error message to include != operator. | ||
if (operator != Filter.Operator.EQUAL && operator != Filter.Operator.NOT_EQUAL) { |
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.
Operator
must already be imported here (see references to Operator.ARRAY_CONTAINS
) so you can drop the Filter
in Filter.Operator
.
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.
done.
@@ -0,0 +1,39 @@ | |||
// Copyright 2019 Google LLC |
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.
2020
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.
done.
@@ -234,4 +240,22 @@ public static int compareByteStrings(ByteString left, ByteString right) { | |||
} | |||
return Util.compareIntegers(left.size(), right.size()); | |||
} | |||
|
|||
public static List<DocumentKey> extractDocumentKeysFromArrayValue( |
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 isn't likely to be a widely used or general utility. Better to make this a package private static member of e.g. KeyFieldInFilter
and just call it from the other one.
(Another clue that this doesn't belong here is that you're referring to KeyFieldInFilter
in the error message. This is therefore pretty specific to those classes.)
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.
Done. Thanks for pointing out the code smell, that's a helpful check I'll keep in mind.
"bb", docD); | ||
CollectionReference collection = testCollectionWithDocs(testDocs); | ||
QuerySnapshot docs = waitFor(collection.whereNotEqualTo(FieldPath.documentId(), "aa").get()); | ||
assertEquals(asList(docB, docC, docD), querySnapshotToValues(docs)); |
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.
Apologies for what's going to be an irritating question (since I didn't pick up on this earlier), but why do you assertSetEquals(x, expected)
in the test above but assertEquals(asList(x), expected)
here when we're testing the same underlying operator?
To me it seems like either the ordering matters or it doesn't. If ordering of query results is predictable, assertSetEquals
seems wrong because it allows the result to be unordered when our customers really care that it's ordered. The reverse is also true: if ordering doesn't matter, then this test is too strict, and could create a false positive.
To my understanding, query results always have a well defined ordering (breaking ties on key ordering). This seems to point to assertSetEquals
being wrong above.
What's your take on this? Why the discrepancy?
(The same concern applies to the whereNotIn
, below).
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.
Thanks for catching this actually! I originally ran into an issue where I was converting the snapshots into a HashSet in order to easily remove the unneeded documents, but converting them back into a List resulted in an ordering that didn't match the query snapshots from the query. Instead of trying to create the expectedDocsMap
in the correct order, I took the "shortcut" of comparing them as sets to avoid the ordering errors without realizing that order matters in query results.
I took a look at the code, and realized that Using Maps.newHashMap()
keeps the documents in the correct order. Switched back to using assertEquals
with Lists.newArrayList()
.
/** | ||
* Given an operator, returns the set of operators that cannot be used with it. | ||
* | ||
* <p>Operators in a query must adhere to the following set of rules: 1. Only one array operator |
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 list wrapper element is required (<ol>
indicates an ordered list (aka numbered); use <ul>
for unordered (aka bulleted)).
@@ -0,0 +1,36 @@ | |||
// Copyright 2019 Google LLC |
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.
2020 here too
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.
done.
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.
LGTM
Porting from web.