Repository: googleapis/java-datastore (java)

Issue:
README contains broken links and inaccurate information
The `.readme-partials.yaml` file is out-of-date and is creating broken links in the main README file: https://github.com/googleapis/java-datastore/blob/main/.readme-partials.yaml

Specifically, the "Testing" section points to a broken link, as does the "Complete source code" section. There may be other errors as well. 

Pull request:
docs: fix broken README links
Fixes #1000

update links, inline TESTING.md content (used to be located in google-cloud-java, the file has since been removed)

Patch:
diff --git a/.readme-partials.yaml b/.readme-partials.yaml
index 97161677..9823b5c7 100644
--- a/.readme-partials.yaml
+++ b/.readme-partials.yaml
@@ -81,7 +81,7 @@ custom_content: |
   #### Updating data
   Another thing you'll probably want to do is update your data. The following snippet shows how to update a Datastore entity if it exists.
 
-  ``` java
+  ```java
   KeyFactory keyFactory = datastore.newKeyFactory().setKind("keyKind");
   Key key = keyFactory.newKey("keyName");
   Entity entity = datastore.get(key);
@@ -95,12 +95,12 @@ custom_content: |
   ```
 
   The complete source code can be found at
-  [UpdateEntity.java](../../google-cloud-examples/src/main/java/com/google/cloud/examples/datastore/snippets/UpdateEntity.java).
+  [UpdateEntity.java](https://github.com/googleapis/google-cloud-java/blob/2c1850d4f82f3fbd7b4a50582384c008085aa1a8/google-cloud-examples/src/main/java/com/google/cloud/examples/datastore/snippets/UpdateEntity.java).
 
   #### Complete source code
 
   In
-  [AddEntitiesAndRunQuery.java](../../google-cloud-examples/src/main/java/com/google/cloud/examples/datastore/snippets/AddEntitiesAndRunQuery.java)
+  [AddEntitiesAndRunQuery.java](https://github.com/googleapis/google-cloud-java/blob/2c1850d4f82f3fbd7b4a50582384c008085aa1a8/google-cloud-examples/src/main/java/com/google/cloud/examples/datastore/snippets/AddEntitiesAndRunQuery.java)
   we put together all the code to store data and run queries into one program. The program assumes that you are
   running on Compute Engine or from your own desktop. To run the example on App Engine, simply move
   the code from the main method to your application's servlet class and change the print statements to
@@ -110,8 +110,34 @@ custom_content: |
   -------
 
   This library has tools to help write tests for code that uses the Datastore.
+  
+  #### On your machine
+
+  You can test against a temporary local Datastore by following these steps:
 
-  See [TESTING.md](https://github.com/googleapis/google-cloud-java/blob/main/TESTING.md#testing-code-that-uses-datastore) to read more about testing.
+  1. [Install Cloud SDK and start the emulator](https://cloud.google.com/datastore/docs/tools/datastore-emulator)
+
+  To determine which host/port the emulator is running on:
+  
+  ```
+  $ gcloud beta emulators datastore env-init
+  
+  # Sample output:
+  #   export DATASTORE_EMULATOR_HOST=localhost:8759
+  ```
+  
+  3. Point your client to the emulator
+  
+  ```java
+  DatastoreOptions options = DatastoreOptions.newBuilder()
+  .setProjectId(DatastoreOptions.getDefaultProjectId())
+  .setHost(System.getenv("DATASTORE_EMULATOR_HOST"))
+  .setCredentials(NoCredentials.getInstance())
+  .setRetrySettings(ServiceOptions.getNoRetrySettings())
+  .build();
+  Datastore datastore = options.getService();
+  ```
+  4. Run your tests
 
   Example Applications
   --------------------
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..dbd8a583 100644
--- a/README.md
+++ b/README.md
@@ -19,7 +19,7 @@ If you are using Maven with [BOM][libraries-bom], add this to your pom.xml file:
     <dependency>
       <groupId>com.google.cloud</groupId>
       <artifactId>libraries-bom</artifactId>
-      <version>26.9.0</version>
+      <version>26.10.0</version>
       <type>pom</type>
       <scope>import</scope>
     </dependency>
@@ -41,7 +41,7 @@ If you are using Maven without BOM, add this to your dependencies:
 <dependency>
   <groupId>com.google.cloud</groupId>
   <artifactId>google-cloud-datastore</artifactId>
-  <version>2.13.6</version>
+  <version>2.14.0</version>
 </dependency>
 
 ```
@@ -49,20 +49,20 @@ 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'
 ```
 If you are using Gradle without BOM, add this to your dependencies:
 
 ```Groovy
-implementation 'com.google.cloud:google-cloud-datastore:2.13.6'
+implementation 'com.google.cloud:google-cloud-datastore:2.14.0'
 ```
 
 If you are using SBT, add this to your dependencies:
 
 ```Scala
-libraryDependencies += "com.google.cloud" % "google-cloud-datastore" % "2.13.6"
+libraryDependencies += "com.google.cloud" % "google-cloud-datastore" % "2.14.0"
 ```
 
 ## Authentication
@@ -183,7 +183,7 @@ Cloud Datastore relies on indexing to run queries. Indexing is turned on by defa
 #### Updating data
 Another thing you'll probably want to do is update your data. The following snippet shows how to update a Datastore entity if it exists.
 
-``` java
+```java
 KeyFactory keyFactory = datastore.newKeyFactory().setKind("keyKind");
 Key key = keyFactory.newKey("keyName");
 Entity entity = datastore.get(key);
@@ -197,12 +197,12 @@ if (entity != null) {
 ```
 
 The complete source code can be found at
-[UpdateEntity.java](../../google-cloud-examples/src/main/java/com/google/cloud/examples/datastore/snippets/UpdateEntity.java).
+[UpdateEntity.java](https://github.com/googleapis/google-cloud-java/blob/2c1850d4f82f3fbd7b4a50582384c008085aa1a8/google-cloud-examples/src/main/java/com/google/cloud/examples/datastore/snippets/UpdateEntity.java).
 
 #### Complete source code
 
 In
-[AddEntitiesAndRunQuery.java](../../google-cloud-examples/src/main/java/com/google/cloud/examples/datastore/snippets/AddEntitiesAndRunQuery.java)
+[AddEntitiesAndRunQuery.java](https://github.com/googleapis/google-cloud-java/blob/2c1850d4f82f3fbd7b4a50582384c008085aa1a8/google-cloud-examples/src/main/java/com/google/cloud/examples/datastore/snippets/AddEntitiesAndRunQuery.java)
 we put together all the code to store data and run queries into one program. The program assumes that you are
 running on Compute Engine or from your own desktop. To run the example on App Engine, simply move
 the code from the main method to your application's servlet class and change the print statements to
@@ -213,7 +213,33 @@ Testing
 
 This library has tools to help write tests for code that uses the Datastore.
 
-See [TESTING.md](https://github.com/googleapis/google-cloud-java/blob/main/TESTING.md#testing-code-that-uses-datastore) to read more about testing.
+#### On your machine
+
+You can test against a temporary local Datastore by following these steps:
+
+1. [Install Cloud SDK and start the emulator](https://cloud.google.com/datastore/docs/tools/datastore-emulator)
+
+To determine which host/port the emulator is running on:
+
+```
+$ gcloud beta emulators datastore env-init
+
+# Sample output:
+#   export DATASTORE_EMULATOR_HOST=localhost:8759
+```
+
+3. Point your client to the emulator
+
+```java
+DatastoreOptions options = DatastoreOptions.newBuilder()
+.setProjectId(DatastoreOptions.getDefaultProjectId())
+.setHost(System.getenv("DATASTORE_EMULATOR_HOST"))
+.setCredentials(NoCredentials.getInstance())
+.setRetrySettings(ServiceOptions.getNoRetrySettings())
+.build();
+Datastore datastore = options.getService();
+```
+4. Run your tests
 
 Example Applications
 --------------------
diff --git a/datastore-v1-proto-client/pom.xml b/datastore-v1-proto-client/pom.xml
index 43f0e064..6800c188 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.1-SNAPSHOT</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.1-SNAPSHOT</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..b62a7166 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.1-SNAPSHOT</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.1-SNAPSHOT</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.1-SNAPSHOT</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.1-SNAPSHOT</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.1-SNAPSHOT</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..f4f25225 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.1-SNAPSHOT</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.1-SNAPSHOT</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..d1d691aa 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.1-SNAPSHOT</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.1-SNAPSHOT</version><!-- {x-version-update:google-cloud-datastore:current} -->
   </parent>
   <dependencies>
     <dependency>
diff --git a/pom.xml b/pom.xml
index f288f7db..20ada404 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.1-SNAPSHOT</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.1-SNAPSHOT</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.1-SNAPSHOT</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.1-SNAPSHOT</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.1-SNAPSHOT</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.1-SNAPSHOT</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..02d62015 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.1-SNAPSHOT</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.1-SNAPSHOT</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..a6a51600 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.1-SNAPSHOT</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.1-SNAPSHOT</version><!-- {x-version-update:google-cloud-datastore:current} -->
   </parent>
   <dependencies>
     <dependency>
diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml
index bcfc25e9..55263138 100644
--- a/samples/install-without-bom/pom.xml
+++ b/samples/install-without-bom/pom.xml
@@ -29,7 +29,7 @@
     <dependency>
       <groupId>com.google.cloud</groupId>
       <artifactId>google-cloud-datastore</artifactId>
-      <version>2.13.6</version>
+      <version>2.14.0</version>
     </dependency>
     <!-- [END datastore_install_without_bom] -->
 
diff --git a/samples/native-image-sample/pom.xml b/samples/native-image-sample/pom.xml
index 4b6a7c12..4bf5bf10 100644
--- a/samples/native-image-sample/pom.xml
+++ b/samples/native-image-sample/pom.xml
@@ -28,7 +28,7 @@
       <dependency>
         <groupId>com.google.cloud</groupId>
         <artifactId>libraries-bom</artifactId>
-        <version>26.9.0</version>
+        <version>26.10.0</version>
         <type>pom</type>
         <scope>import</scope>
       </dependency>
diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml
index a17839a0..023a84ab 100644
--- a/samples/snapshot/pom.xml
+++ b/samples/snapshot/pom.xml
@@ -28,7 +28,7 @@
     <dependency>
       <groupId>com.google.cloud</groupId>
       <artifactId>google-cloud-datastore</artifactId>
-      <version>2.13.6</version>
+      <version>2.14.0</version>
     </dependency>
 
     <dependency>
diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml
index dd85dbe7..1929a106 100644
--- a/samples/snippets/pom.xml
+++ b/samples/snippets/pom.xml
@@ -30,7 +30,7 @@
       <dependency>
         <groupId>com.google.cloud</groupId>
         <artifactId>libraries-bom</artifactId>
-        <version>26.9.0</version>
+        <version>26.10.0</version>
         <type>pom</type>
         <scope>import</scope>
       </dependency>
diff --git a/versions.txt b/versions.txt
index afff0e27..c8e599aa 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.1-SNAPSHOT
+google-cloud-datastore-bom:2.14.0:2.14.1-SNAPSHOT
+proto-google-cloud-datastore-v1:0.105.0:0.105.1-SNAPSHOT
+datastore-v1-proto-client:2.14.0:2.14.1-SNAPSHOT
+proto-google-cloud-datastore-admin-v1:2.14.0:2.14.1-SNAPSHOT
+grpc-google-cloud-datastore-admin-v1:2.14.0:2.14.1-SNAPSHOT


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);