Repository: googleapis/java-datastore (java)

Issue:
com.google.datastore.snippets.ConceptsTest: testStaleReads failed
This test failed!

To configure my behavior, see [the Flaky Bot documentation](https://github.com/googleapis/repo-automation-bots/tree/main/packages/flakybot).

If I'm commenting on this issue too often, add the `flakybot: quiet` label and
I will stop commenting.

---

commit: 05aa0b1062993fb848e572eaceae3b717263e863
buildURL: [Build Status](https://source.cloud.google.com/results/invocations/2b9de248-15a1-4944-bf71-f60904bf0964), [Sponge](http://sponge2/2b9de248-15a1-4944-bf71-f60904bf0964)
status: failed
<details><summary>Test output</summary><br><pre>java.util.NoSuchElementException
	at com.google.common.collect.AbstractIterator.next(AbstractIterator.java:159)
	at com.google.datastore.snippets.ConceptsTest.testStaleReads(ConceptsTest.java:1171)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
	at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:258)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:364)
	at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:272)
	at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:237)
	at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:158)
	at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:428)
	at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162)
	at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:562)
	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:548)
</pre></details>

Pull request description:
fix: flaky test com.google.datastore.snippets.ConceptsTest: testStale…
Fixes #905  ☕️

Please follow the explanation in comment https://github.com/googleapis/java-datastore/issues/905#issuecomment-1460077763.



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c0983091..8c27d2c2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,12 @@
 # Changelog
 
+## [2.14.0](https://github.com/googleapis/java-datastore/compare/v2.13.6...v2.14.0) (2023-03-08)
+
+
+### Features
+
+* OR query support ([#993](https://github.com/googleapis/java-datastore/issues/993)) ([99b7843](https://github.com/googleapis/java-datastore/commit/99b784332919ccc813a94ba17beaaa11b02b1c8e))
+
 ## [2.13.6](https://github.com/googleapis/java-datastore/compare/v2.13.5...v2.13.6) (2023-03-02)
 
 
diff --git a/README.md b/README.md
index 3c41abbd..650f21f7 100644
--- a/README.md
+++ b/README.md
@@ -49,7 +49,7 @@ If you are using Maven without BOM, add this to your dependencies:
 If you are using Gradle 5.x or later, add this to your dependencies:
 
 ```Groovy
-implementation platform('com.google.cloud:libraries-bom:26.9.0')
+implementation platform('com.google.cloud:libraries-bom:26.10.0')
 
 implementation 'com.google.cloud:google-cloud-datastore'
 ```
diff --git a/datastore-v1-proto-client/pom.xml b/datastore-v1-proto-client/pom.xml
index 43f0e064..fb4b87df 100644
--- a/datastore-v1-proto-client/pom.xml
+++ b/datastore-v1-proto-client/pom.xml
@@ -19,12 +19,12 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.google.cloud.datastore</groupId>
   <artifactId>datastore-v1-proto-client</artifactId>
-  <version>2.13.7-SNAPSHOT</version><!-- {x-version-update:datastore-v1-proto-client:current} -->
+  <version>2.14.0</version><!-- {x-version-update:datastore-v1-proto-client:current} -->
 
   <parent>
     <groupId>com.google.cloud</groupId>
     <artifactId>google-cloud-datastore-parent</artifactId>
-    <version>2.13.7-SNAPSHOT</version><!-- {x-version-update:google-cloud-datastore:current} -->
+    <version>2.14.0</version><!-- {x-version-update:google-cloud-datastore:current} -->
   </parent>
 
   <packaging>jar</packaging>
diff --git a/google-cloud-datastore-bom/pom.xml b/google-cloud-datastore-bom/pom.xml
index 887ec025..d98acb0f 100644
--- a/google-cloud-datastore-bom/pom.xml
+++ b/google-cloud-datastore-bom/pom.xml
@@ -3,7 +3,7 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.google.cloud</groupId>
   <artifactId>google-cloud-datastore-bom</artifactId>
-  <version>2.13.7-SNAPSHOT</version><!-- {x-version-update:google-cloud-datastore-bom:current} -->
+  <version>2.14.0</version><!-- {x-version-update:google-cloud-datastore-bom:current} -->
   <packaging>pom</packaging>
   <parent>
     <groupId>com.google.cloud</groupId>
@@ -52,22 +52,22 @@
       <dependency>
         <groupId>com.google.cloud</groupId>
         <artifactId>google-cloud-datastore</artifactId>
-        <version>2.13.7-SNAPSHOT</version><!-- {x-version-update:google-cloud-datastore:current} -->
+        <version>2.14.0</version><!-- {x-version-update:google-cloud-datastore:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>grpc-google-cloud-datastore-admin-v1</artifactId>
-        <version>2.13.7-SNAPSHOT</version><!-- {x-version-update:grpc-google-cloud-datastore-admin-v1:current} -->
+        <version>2.14.0</version><!-- {x-version-update:grpc-google-cloud-datastore-admin-v1:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>proto-google-cloud-datastore-v1</artifactId>
-        <version>0.104.7-SNAPSHOT</version><!-- {x-version-update:proto-google-cloud-datastore-v1:current} -->
+        <version>0.105.0</version><!-- {x-version-update:proto-google-cloud-datastore-v1:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>proto-google-cloud-datastore-admin-v1</artifactId>
-        <version>2.13.7-SNAPSHOT</version><!-- {x-version-update:proto-google-cloud-datastore-admin-v1:current} -->
+        <version>2.14.0</version><!-- {x-version-update:proto-google-cloud-datastore-admin-v1:current} -->
       </dependency>
     </dependencies>
   </dependencyManagement>
diff --git a/google-cloud-datastore/pom.xml b/google-cloud-datastore/pom.xml
index 4b850a79..f12a5adf 100644
--- a/google-cloud-datastore/pom.xml
+++ b/google-cloud-datastore/pom.xml
@@ -2,7 +2,7 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <artifactId>google-cloud-datastore</artifactId>
-  <version>2.13.7-SNAPSHOT</version><!-- {x-version-update:google-cloud-datastore:current} -->
+  <version>2.14.0</version><!-- {x-version-update:google-cloud-datastore:current} -->
   <packaging>jar</packaging>
   <name>Google Cloud Datastore</name>
   <url>https://github.com/googleapis/java-datastore</url>
@@ -12,7 +12,7 @@
   <parent>
     <groupId>com.google.cloud</groupId>
     <artifactId>google-cloud-datastore-parent</artifactId>
-    <version>2.13.7-SNAPSHOT</version><!-- {x-version-update:google-cloud-datastore:current} -->
+    <version>2.14.0</version><!-- {x-version-update:google-cloud-datastore:current} -->
   </parent>
   <properties>
     <site.installationModule>google-cloud-datastore</site.installationModule>
diff --git a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/StructuredQuery.java b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/StructuredQuery.java
index b394dcd9..a6195ad2 100644
--- a/google-cloud-datastore/src/main/java/com/google/cloud/datastore/StructuredQuery.java
+++ b/google-cloud-datastore/src/main/java/com/google/cloud/datastore/StructuredQuery.java
@@ -26,6 +26,7 @@ import static com.google.cloud.datastore.TimestampValue.of;
 import static com.google.common.base.Preconditions.checkNotNull;
 
 import com.google.api.core.ApiFunction;
+import com.google.api.core.BetaApi;
 import com.google.api.core.InternalApi;
 import com.google.cloud.StringEnumType;
 import com.google.cloud.StringEnumValue;
@@ -151,6 +152,8 @@ public abstract class StructuredQuery<V> extends Query<V> implements RecordQuery
 
       static final Operator AND = type.createAndRegister("AND");
 
+      static final Operator OR = type.createAndRegister("OR");
+
       com.google.datastore.v1.CompositeFilter.Operator toPb() {
         return com.google.datastore.v1.CompositeFilter.Operator.valueOf(name());
       }
@@ -231,6 +234,11 @@ public abstract class StructuredQuery<V> extends Query<V> implements RecordQuery
       return new CompositeFilter(Operator.AND, first, other);
     }
 
+    @BetaApi
+    public static CompositeFilter or(Filter first, Filter... other) {
+      return new CompositeFilter(Operator.OR, first, other);
+    }
+
     @Override
     com.google.datastore.v1.Filter toPb() {
       com.google.datastore.v1.Filter.Builder filterPb = com.google.datastore.v1.Filter.newBuilder();
diff --git a/grpc-google-cloud-datastore-admin-v1/pom.xml b/grpc-google-cloud-datastore-admin-v1/pom.xml
index 4c333844..723047e6 100644
--- a/grpc-google-cloud-datastore-admin-v1/pom.xml
+++ b/grpc-google-cloud-datastore-admin-v1/pom.xml
@@ -4,13 +4,13 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.google.api.grpc</groupId>
   <artifactId>grpc-google-cloud-datastore-admin-v1</artifactId>
-  <version>2.13.7-SNAPSHOT</version><!-- {x-version-update:grpc-google-cloud-datastore-admin-v1:current} -->
+  <version>2.14.0</version><!-- {x-version-update:grpc-google-cloud-datastore-admin-v1:current} -->
   <name>grpc-google-cloud-datastore-admin-v1</name>
   <description>GRPC library for google-cloud-datastore</description>
   <parent>
     <groupId>com.google.cloud</groupId>
     <artifactId>google-cloud-datastore-parent</artifactId>
-    <version>2.13.7-SNAPSHOT</version><!-- {x-version-update:google-cloud-datastore:current} -->
+    <version>2.14.0</version><!-- {x-version-update:google-cloud-datastore:current} -->
   </parent>
   <dependencies>
     <dependency>
diff --git a/pom.xml b/pom.xml
index f288f7db..d37c7568 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
   <groupId>com.google.cloud</groupId>
   <artifactId>google-cloud-datastore-parent</artifactId>
   <packaging>pom</packaging>
-  <version>2.13.7-SNAPSHOT</version><!-- {x-version-update:google-cloud-datastore:current} -->
+  <version>2.14.0</version><!-- {x-version-update:google-cloud-datastore:current} -->
   <name>Google Cloud Datastore Parent</name>
   <url>https://github.com/googleapis/java-datastore</url>
   <description>
@@ -159,27 +159,27 @@
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>proto-google-cloud-datastore-admin-v1</artifactId>
-        <version>2.13.7-SNAPSHOT</version><!-- {x-version-update:proto-google-cloud-datastore-admin-v1:current} -->
+        <version>2.14.0</version><!-- {x-version-update:proto-google-cloud-datastore-admin-v1:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>grpc-google-cloud-datastore-admin-v1</artifactId>
-        <version>2.13.7-SNAPSHOT</version><!-- {x-version-update:grpc-google-cloud-datastore-admin-v1:current} -->
+        <version>2.14.0</version><!-- {x-version-update:grpc-google-cloud-datastore-admin-v1:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.cloud</groupId>
         <artifactId>google-cloud-datastore</artifactId>
-        <version>2.13.7-SNAPSHOT</version><!-- {x-version-update:google-cloud-datastore:current} -->
+        <version>2.14.0</version><!-- {x-version-update:google-cloud-datastore:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.api.grpc</groupId>
         <artifactId>proto-google-cloud-datastore-v1</artifactId>
-        <version>0.104.7-SNAPSHOT</version><!-- {x-version-update:proto-google-cloud-datastore-v1:current} -->
+        <version>0.105.0</version><!-- {x-version-update:proto-google-cloud-datastore-v1:current} -->
       </dependency>
       <dependency>
         <groupId>com.google.cloud.datastore</groupId>
         <artifactId>datastore-v1-proto-client</artifactId>
-        <version>2.13.7-SNAPSHOT</version><!-- {x-version-update:datastore-v1-proto-client:current} -->
+        <version>2.14.0</version><!-- {x-version-update:datastore-v1-proto-client:current} -->
         <exclusions>
           <exclusion>
             <groupId>com.google.api.grpc</groupId>
diff --git a/proto-google-cloud-datastore-admin-v1/pom.xml b/proto-google-cloud-datastore-admin-v1/pom.xml
index f408d15b..a3de14a2 100644
--- a/proto-google-cloud-datastore-admin-v1/pom.xml
+++ b/proto-google-cloud-datastore-admin-v1/pom.xml
@@ -4,13 +4,13 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.google.api.grpc</groupId>
   <artifactId>proto-google-cloud-datastore-admin-v1</artifactId>
-  <version>2.13.7-SNAPSHOT</version><!-- {x-version-update:proto-google-cloud-datastore-admin-v1:current} -->
+  <version>2.14.0</version><!-- {x-version-update:proto-google-cloud-datastore-admin-v1:current} -->
   <name>proto-google-cloud-datastore-admin-v1</name>
   <description>Proto library for google-cloud-datastore</description>
   <parent>
     <groupId>com.google.cloud</groupId>
     <artifactId>google-cloud-datastore-parent</artifactId>
-    <version>2.13.7-SNAPSHOT</version><!-- {x-version-update:google-cloud-datastore:current} -->
+    <version>2.14.0</version><!-- {x-version-update:google-cloud-datastore:current} -->
   </parent>
   <dependencies>
     <dependency>
diff --git a/proto-google-cloud-datastore-v1/pom.xml b/proto-google-cloud-datastore-v1/pom.xml
index 7e1e7f34..31d143ac 100644
--- a/proto-google-cloud-datastore-v1/pom.xml
+++ b/proto-google-cloud-datastore-v1/pom.xml
@@ -4,13 +4,13 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.google.api.grpc</groupId>
   <artifactId>proto-google-cloud-datastore-v1</artifactId>
-  <version>0.104.7-SNAPSHOT</version><!-- {x-version-update:proto-google-cloud-datastore-v1:current} -->
+  <version>0.105.0</version><!-- {x-version-update:proto-google-cloud-datastore-v1:current} -->
   <name>proto-google-cloud-datastore-v1</name>
   <description>PROTO library for proto-google-cloud-datastore-v1</description>
   <parent>
     <groupId>com.google.cloud</groupId>
     <artifactId>google-cloud-datastore-parent</artifactId>
-    <version>2.13.7-SNAPSHOT</version><!-- {x-version-update:google-cloud-datastore:current} -->
+    <version>2.14.0</version><!-- {x-version-update:google-cloud-datastore:current} -->
   </parent>
   <dependencies>
     <dependency>
diff --git a/versions.txt b/versions.txt
index afff0e27..c7c73410 100644
--- a/versions.txt
+++ b/versions.txt
@@ -1,9 +1,9 @@
 # Format:
 # module:released-version:current-version
 
-google-cloud-datastore:2.13.6:2.13.7-SNAPSHOT
-google-cloud-datastore-bom:2.13.6:2.13.7-SNAPSHOT
-proto-google-cloud-datastore-v1:0.104.6:0.104.7-SNAPSHOT
-datastore-v1-proto-client:2.13.6:2.13.7-SNAPSHOT
-proto-google-cloud-datastore-admin-v1:2.13.6:2.13.7-SNAPSHOT
-grpc-google-cloud-datastore-admin-v1:2.13.6:2.13.7-SNAPSHOT
+google-cloud-datastore:2.14.0:2.14.0
+google-cloud-datastore-bom:2.14.0:2.14.0
+proto-google-cloud-datastore-v1:0.105.0:0.105.0
+datastore-v1-proto-client:2.14.0:2.14.0
+proto-google-cloud-datastore-admin-v1:2.14.0:2.14.0
+grpc-google-cloud-datastore-admin-v1:2.14.0:2.14.0


Test patch:
diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/SerializationTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/SerializationTest.java
index 10538651..1b8186a5 100644
--- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/SerializationTest.java
+++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/SerializationTest.java
@@ -69,6 +69,19 @@ public class SerializationTest extends BaseSerializationTest {
           .addDistinctOn("p")
           .addOrderBy(OrderBy.asc("p"))
           .build();
+  private static final Query<ProjectionEntity> QUERY4 =
+      Query.newProjectionEntityQueryBuilder()
+          .setKind("k")
+          .setNamespace("ns1")
+          .addProjection("p")
+          .setLimit(100)
+          .setOffset(5)
+          .setStartCursor(CURSOR1)
+          .setEndCursor(CURSOR2)
+          .setFilter(CompositeFilter.or(PropertyFilter.gt("p1", 10), PropertyFilter.eq("a", "v")))
+          .addDistinctOn("p")
+          .addOrderBy(OrderBy.asc("p"))
+          .build();
   private static final KeyValue KEY_VALUE = KeyValue.of(KEY1);
   private static final NullValue NULL_VALUE =
       NullValue.newBuilder().setExcludeFromIndexes(true).build();
@@ -136,6 +149,7 @@ public class SerializationTest extends BaseSerializationTest {
       QUERY1,
       QUERY2,
       QUERY3,
+      QUERY4,
       NULL_VALUE,
       KEY_VALUE,
       STRING_VALUE,
diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/StructuredQueryTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/StructuredQueryTest.java
index b3f4b944..c5933758 100644
--- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/StructuredQueryTest.java
+++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/StructuredQueryTest.java
@@ -37,8 +37,10 @@ public class StructuredQueryTest {
   private static final Cursor END_CURSOR = Cursor.copyFrom(new byte[] {10});
   private static final int OFFSET = 42;
   private static final Integer LIMIT = 43;
-  private static final Filter FILTER =
+  private static final Filter AND_FILTER =
       CompositeFilter.and(PropertyFilter.gt("p1", 10), PropertyFilter.eq("a", "v"));
+  private static final Filter OR_FILTER =
+      CompositeFilter.or(PropertyFilter.gt("p1", 10), PropertyFilter.eq("a", "v"));
   private static final OrderBy ORDER_BY_1 = OrderBy.asc("p2");
   private static final OrderBy ORDER_BY_2 = OrderBy.desc("p3");
   private static final List<OrderBy> ORDER_BY = ImmutableList.of(ORDER_BY_1, ORDER_BY_2);
@@ -56,7 +58,7 @@ public class StructuredQueryTest {
           .setEndCursor(END_CURSOR)
           .setOffset(OFFSET)
           .setLimit(LIMIT)
-          .setFilter(FILTER)
+          .setFilter(AND_FILTER)
           .setOrderBy(ORDER_BY_1, ORDER_BY_2)
           .build();
   private static final KeyQuery KEY_QUERY =
@@ -67,7 +69,7 @@ public class StructuredQueryTest {
           .setEndCursor(END_CURSOR)
           .setOffset(OFFSET)
           .setLimit(LIMIT)
-          .setFilter(FILTER)
+          .setFilter(OR_FILTER)
           .setOrderBy(ORDER_BY_1, ORDER_BY_2)
           .build();
   private static final ProjectionEntityQuery PROJECTION_QUERY =
@@ -78,7 +80,7 @@ public class StructuredQueryTest {
           .setEndCursor(END_CURSOR)
           .setOffset(OFFSET)
           .setLimit(LIMIT)
-          .setFilter(FILTER)
+          .setFilter(AND_FILTER)
           .setOrderBy(ORDER_BY_1, ORDER_BY_2)
           .setProjection(PROJECTION1, PROJECTION2)
           .setDistinctOn(DISTINCT_ON1, DISTINCT_ON2)
@@ -93,7 +95,14 @@ public class StructuredQueryTest {
 
   @Test
   public void testKeyQueryBuilder() {
-    compareBaseBuilderFields(KEY_QUERY);
+    assertEquals(NAMESPACE, KEY_QUERY.getNamespace());
+    assertEquals(KIND, KEY_QUERY.getKind());
+    assertEquals(START_CURSOR, KEY_QUERY.getStartCursor());
+    assertEquals(END_CURSOR, KEY_QUERY.getEndCursor());
+    assertEquals(OFFSET, KEY_QUERY.getOffset());
+    assertEquals(LIMIT, KEY_QUERY.getLimit());
+    assertEquals(OR_FILTER, KEY_QUERY.getFilter());
+    assertEquals(ORDER_BY, KEY_QUERY.getOrderBy());
     assertEquals(ImmutableList.of(StructuredQuery.KEY_PROPERTY_NAME), KEY_QUERY.getProjection());
     assertTrue(KEY_QUERY.getDistinctOn().isEmpty());
   }
@@ -112,7 +121,7 @@ public class StructuredQueryTest {
     assertEquals(END_CURSOR, query.getEndCursor());
     assertEquals(OFFSET, query.getOffset());
     assertEquals(LIMIT, query.getLimit());
-    assertEquals(FILTER, query.getFilter());
+    assertEquals(AND_FILTER, query.getFilter());
     assertEquals(ORDER_BY, query.getOrderBy());
   }
 
diff --git a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java
index b8c3bb4b..f010d813 100644
--- a/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java
+++ b/google-cloud-datastore/src/test/java/com/google/cloud/datastore/it/ITDatastoreTest.java
@@ -59,6 +59,7 @@ import com.google.cloud.datastore.QueryResults;
 import com.google.cloud.datastore.ReadOption;
 import com.google.cloud.datastore.StringValue;
 import com.google.cloud.datastore.StructuredQuery;
+import com.google.cloud.datastore.StructuredQuery.CompositeFilter;
 import com.google.cloud.datastore.StructuredQuery.OrderBy;
 import com.google.cloud.datastore.StructuredQuery.PropertyFilter;
 import com.google.cloud.datastore.TimestampValue;
@@ -223,6 +224,85 @@ public class ITDatastoreTest {
     return results;
   }
 
+  @Test
+  public void orQuery() {
+    Key key = Key.newBuilder(KEY1, KIND2, 2).build();
+    Entity entity3 =
+        Entity.newBuilder(ENTITY1)
+            .setKey(key)
+            .remove("str")
+            .set("name", "Dan")
+            .setNull("null")
+            .set("age", 19)
+            .build();
+    DATASTORE.put(entity3);
+
+    // age == 19 || age == 20
+    CompositeFilter orFilter =
+        CompositeFilter.or(PropertyFilter.eq("age", 19), PropertyFilter.eq("age", 20));
+    Query<Entity> simpleOrQuery =
+        Query.newEntityQueryBuilder()
+            .setNamespace(NAMESPACE)
+            .setKind(KIND2)
+            .setFilter(orFilter)
+            .build();
+    QueryResults<Entity> results = DATASTORE.run(simpleOrQuery);
+    assertTrue(results.hasNext());
+    assertEquals(ENTITY2, results.next());
+    assertTrue(results.hasNext());
+    assertEquals(entity3, results.next());
+    assertFalse(results.hasNext());
+
+    // age == 19 || age == 20 with limit of 1
+    Query<Entity> simpleOrQueryLimit =
+        Query.newEntityQueryBuilder()
+            .setNamespace(NAMESPACE)
+            .setKind(KIND2)
+            .setFilter(orFilter)
+            .setLimit(1)
+            .build();
+    QueryResults<Entity> results2 = DATASTORE.run(simpleOrQueryLimit);
+    assertTrue(results2.hasNext());
+    assertEquals(ENTITY2, results2.next());
+    assertFalse(results2.hasNext());
+
+    // (age == 18 && name == Dan) || (age == 20 && name == Dan)
+    CompositeFilter nestedOr =
+        CompositeFilter.or(
+            CompositeFilter.and(PropertyFilter.eq("age", 18), PropertyFilter.eq("name", "Dan")),
+            CompositeFilter.and(PropertyFilter.eq("age", 20), PropertyFilter.eq("name", "Dan")));
+    CompositeFilter compositeFilter =
+        CompositeFilter.and(PropertyFilter.hasAncestor(ROOT_KEY), nestedOr);
+    Query<Entity> orQueryNested =
+        Query.newEntityQueryBuilder()
+            .setNamespace(NAMESPACE)
+            .setKind(KIND2)
+            .setFilter(compositeFilter)
+            .build();
+    QueryResults<Entity> results3 = DATASTORE.run(orQueryNested);
+    assertTrue(results3.hasNext());
+    assertEquals(ENTITY2, results3.next());
+    assertFalse(results3.hasNext());
+
+    // age == 20 && (name == Bob || name == Dan)
+    CompositeFilter nestedOr2 =
+        CompositeFilter.or(PropertyFilter.eq("name", "Dan"), PropertyFilter.eq("name", "Bob"));
+    CompositeFilter andFilter = CompositeFilter.and(PropertyFilter.eq("age", 20), nestedOr2);
+    CompositeFilter ancestorAndFilter =
+        CompositeFilter.and(PropertyFilter.hasAncestor(ROOT_KEY), andFilter);
+    Query<Entity> orQueryNested2 =
+        Query.newEntityQueryBuilder()
+            .setNamespace(NAMESPACE)
+            .setKind(KIND2)
+            .setFilter(ancestorAndFilter)
+            .setLimit(1)
+            .build();
+    QueryResults<Entity> results4 = DATASTORE.run(orQueryNested2);
+    assertTrue(results4.hasNext());
+    assertEquals(ENTITY2, results4.next());
+    assertFalse(results4.hasNext());
+  }
+
   @Test
   public void testNewTransactionCommit() {
     Transaction transaction = DATASTORE.newTransaction();
@@ -946,6 +1026,21 @@ public class ITDatastoreTest {
     assertEquals(e2, resultNeq.next());
     assertFalse(resultNeq.hasNext());
 
+    Query<Entity> scQueryInEqOr =
+        Query.newEntityQueryBuilder()
+            .setKind(KIND1)
+            .setFilter(
+                CompositeFilter.or(
+                    PropertyFilter.in("v_int", ListValue.of(10, 50000)),
+                    PropertyFilter.eq("v_int", 10000)))
+            .build();
+
+    QueryResults<Entity> run = DATASTORE.run(scQueryInEqOr);
+
+    assertTrue(run.hasNext());
+    assertEquals(e1, run.next());
+    assertFalse(run.hasNext());
+
     DATASTORE.delete(e1.getKey());
     DATASTORE.delete(e2.getKey());
   }
diff --git a/samples/snippets/src/test/java/com/google/datastore/snippets/ConceptsTest.java b/samples/snippets/src/test/java/com/google/datastore/snippets/ConceptsTest.java
index 4013dbe0..1397728b 100644
--- a/samples/snippets/src/test/java/com/google/datastore/snippets/ConceptsTest.java
+++ b/samples/snippets/src/test/java/com/google/datastore/snippets/ConceptsTest.java
@@ -34,6 +34,7 @@ import com.google.cloud.datastore.FullEntity;
 import com.google.cloud.datastore.IncompleteKey;
 import com.google.cloud.datastore.Key;
 import com.google.cloud.datastore.KeyFactory;
+import com.google.cloud.datastore.KeyQuery;
 import com.google.cloud.datastore.ListValue;
 import com.google.cloud.datastore.PathElement;
 import com.google.cloud.datastore.ProjectionEntity;
@@ -65,7 +66,9 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.TimeZone;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
+import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -129,6 +132,13 @@ public class ConceptsTest {
     datastoreRealBackend = DatastoreOptions.getDefaultInstance().getService();
   }
 
+  @After
+  public void tearDown() throws Exception {
+    KeyQuery taskQuery = Query.newKeyQueryBuilder().setKind("Task").build();
+    Key[] taskKeysToDelete = Iterators.toArray(datastoreRealBackend.run(taskQuery), Key.class);
+    datastoreRealBackend.delete(taskKeysToDelete);
+  }
+
   /**
    * Stops the local Datastore emulator.
    *
@@ -1147,8 +1157,10 @@ public class ConceptsTest {
   }
 
   @Test
-  public void testStaleReads() {
+  public void testStaleReads() throws InterruptedException {
     setUpQueryTestsRealBackend();
+    // waiting for 6 seconds, so that we can query with read time of 5 seconds ago
+    TimeUnit.SECONDS.sleep(6);
     Datastore datastoreClient = datastoreRealBackend;
     // [START datastore_stale_read]
     Key taskKey =
@@ -1158,10 +1170,10 @@ public class ConceptsTest {
             .addAncestors(PathElement.of("TaskList", "default"))
             .newKey("someTask");
 
-    Timestamp fifteenSecondsAgo =
-        Timestamp.ofTimeSecondsAndNanos(Timestamp.now().getSeconds() - 15L, 0);
-    // Create a readOption with read time fifteenSecondsAgo
-    ReadOption readOption = ReadOption.readTime(fifteenSecondsAgo);
+    Timestamp fiveSecondsAgo =
+        Timestamp.ofTimeSecondsAndNanos(Timestamp.now().getSeconds() - 5L, 0);
+    // Create a readOption with read time fiveSecondsAgo
+    ReadOption readOption = ReadOption.readTime(fiveSecondsAgo);
     // Use the readOption to Fetch entity
     Entity entity = datastoreClient.get(taskKey, readOption);