Skip to content

Commit 224123b

Browse files
committed
Merge pull request #242 from GoogleCloudPlatform/swast-ds
Fix "surprising queries" samples.
2 parents b7a60d0 + 0f11a9f commit 224123b

File tree

1 file changed

+36
-27
lines changed

1 file changed

+36
-27
lines changed

appengine/datastore/src/test/java/com/example/appengine/QueriesTest.java

+36-27
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444

4545
import java.io.PrintWriter;
4646
import java.io.StringWriter;
47-
import java.util.ArrayList;
4847
import java.util.Arrays;
4948
import java.util.List;
5049

@@ -685,24 +684,24 @@ public void queryRestrictions_sortWrongOrderOnInequality_isInvalid() throws Exce
685684
public void queryRestrictions_surprisingMultipleValuesAllMustMatch_returnsNoEntities()
686685
throws Exception {
687686
Entity a = new Entity("Widget", "a");
688-
ArrayList<Long> xs = new ArrayList<>();
689-
xs.add(1L);
690-
xs.add(2L);
687+
List<Long> xs = Arrays.asList(1L, 2L);
691688
a.setProperty("x", xs);
692689
datastore.put(a);
693690

694691
// [START surprising_behavior_example_1]
695692
Query q =
696693
new Query("Widget")
697-
.setFilter(new FilterPredicate("x", FilterOperator.GREATER_THAN, 1))
698-
.setFilter(new FilterPredicate("x", FilterOperator.LESS_THAN, 2));
694+
.setFilter(
695+
CompositeFilterOperator.and(
696+
new FilterPredicate("x", FilterOperator.GREATER_THAN, 1),
697+
new FilterPredicate("x", FilterOperator.LESS_THAN, 2)));
699698
// [END surprising_behavior_example_1]
700699

701-
// Note: The documentation describes that the entity "a" will not match
702-
// because no value matches all filters. When run with the local test
703-
// runner, the entity "a" *is* matched. This may be a difference in
704-
// behavior between the local devserver and Cloud Datastore, so there
705-
// aren't any assertions we can make in this test.
700+
// Entity "a" will not match because no individual value matches all filters.
701+
// See the documentation for more details:
702+
// https://cloud.google.com/appengine/docs/java/datastore/query-restrictions#properties_with_multiple_values_can_behave_in_surprising_ways
703+
List<Entity> results = datastore.prepare(q).asList(FetchOptions.Builder.withDefaults());
704+
assertThat(results).named("query results").isEmpty();
706705
}
707706

708707
@Test
@@ -716,21 +715,24 @@ public void queryRestrictions_surprisingMultipleValuesEquals_returnsMatchedEntit
716715
c.setProperty("x", ImmutableList.<Long>of(-6L, 2L));
717716
Entity d = new Entity("Widget", "d");
718717
d.setProperty("x", ImmutableList.<Long>of(-6L, 4L));
719-
datastore.put(ImmutableList.<Entity>of(a, b, c, d));
718+
Entity e = new Entity("Widget", "e");
719+
e.setProperty("x", ImmutableList.<Long>of(1L, 2L, 3L));
720+
datastore.put(ImmutableList.<Entity>of(a, b, c, d, e));
720721

721722
// [START surprising_behavior_example_2]
722723
Query q =
723724
new Query("Widget")
724-
.setFilter(new FilterPredicate("x", FilterOperator.EQUAL, 1))
725-
.setFilter(new FilterPredicate("x", FilterOperator.EQUAL, 2));
725+
.setFilter(
726+
CompositeFilterOperator.and(
727+
new FilterPredicate("x", FilterOperator.EQUAL, 1),
728+
new FilterPredicate("x", FilterOperator.EQUAL, 2)));
726729
// [END surprising_behavior_example_2]
727730

731+
// Only "a" and "e" have both 1 and 2 in the "x" array-valued property.
732+
// See the documentation for more details:
733+
// https://cloud.google.com/appengine/docs/java/datastore/query-restrictions#properties_with_multiple_values_can_behave_in_surprising_ways
728734
List<Entity> results = datastore.prepare(q).asList(FetchOptions.Builder.withDefaults());
729-
assertThat(getKeys(results)).named("query result keys").contains(a.getKey());
730-
731-
// Note: When run in the test server, this matches "c" as expected and does
732-
// not match "d" as expected. For some reason it does *not* match "b".
733-
// The behavior of queries on repeated values is definitely surprising.
735+
assertThat(getKeys(results)).named("query result keys").containsExactly(a.getKey(), e.getKey());
734736
}
735737

736738
@Test
@@ -752,6 +754,9 @@ public void queryRestrictions_surprisingMultipleValuesNotEquals_returnsMatchedEn
752754
Query q = new Query("Widget").setFilter(new FilterPredicate("x", FilterOperator.NOT_EQUAL, 1));
753755
// [END surprising_behavior_example_3]
754756

757+
// The query matches any entity that has a some value other than 1. Only
758+
// entity "e" is not matched. See the documentation for more details:
759+
// https://cloud.google.com/appengine/docs/java/datastore/query-restrictions#properties_with_multiple_values_can_behave_in_surprising_ways
755760
List<Entity> results = datastore.prepare(q).asList(FetchOptions.Builder.withDefaults());
756761
assertThat(getKeys(results))
757762
.named("query result keys")
@@ -770,17 +775,21 @@ public void queryRestrictions_surprisingMultipleValuesTwoNotEquals_returnsMatche
770775
// [START surprising_behavior_example_4]
771776
Query q =
772777
new Query("Widget")
773-
.setFilter(new FilterPredicate("x", FilterOperator.NOT_EQUAL, 1))
774-
.setFilter(new FilterPredicate("x", FilterOperator.NOT_EQUAL, 2));
778+
.setFilter(
779+
CompositeFilterOperator.and(
780+
new FilterPredicate("x", FilterOperator.NOT_EQUAL, 1),
781+
new FilterPredicate("x", FilterOperator.NOT_EQUAL, 2)));
775782
// [END surprising_behavior_example_4]
776783

784+
// The two NOT_EQUAL filters in the query become like the combination of queries:
785+
// x < 1 OR (x > 1 AND x < 2) OR x > 2
786+
//
787+
// Only "b" has some value which matches the "x > 2" portion of this query.
788+
//
789+
// See the documentation for more details:
790+
// https://cloud.google.com/appengine/docs/java/datastore/query-restrictions#properties_with_multiple_values_can_behave_in_surprising_ways
777791
List<Entity> results = datastore.prepare(q).asList(FetchOptions.Builder.withDefaults());
778-
assertThat(getKeys(results)).named("query result keys").contains(b.getKey());
779-
780-
// Note: The documentation describes that the entity "a" will not match.
781-
// When run with the local test runner, the entity "a" *is* matched. This
782-
// may be a difference in behavior between the local devserver and Cloud
783-
// Datastore.
792+
assertThat(getKeys(results)).named("query result keys").containsExactly(b.getKey());
784793
}
785794

786795
private Entity retrievePersonWithLastName(String targetLastName) {

0 commit comments

Comments
 (0)