diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/Query.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/Query.java index 8924556127..765fa01205 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/Query.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/Query.java @@ -17,6 +17,7 @@ import com.google.api.core.InternalApi; import com.google.bigtable.v2.ReadRowsRequest; +import com.google.bigtable.v2.RowFilter; import com.google.bigtable.v2.RowRange; import com.google.bigtable.v2.RowSet; import com.google.cloud.bigtable.data.v2.internal.ByteStringComparator; @@ -42,6 +43,9 @@ public final class Query implements Serializable { private static final long serialVersionUID = -316972783499434755L; + // bigtable can server the largest filter size of 20MB. + private static final int MAX_FILTER_SIZE = 20 * 1024 * 1024; + private final String tableId; private transient ReadRowsRequest.Builder builder = ReadRowsRequest.newBuilder(); @@ -162,7 +166,13 @@ public Query range(ByteStringRange range) { * filters, please use {@link Filters#interleave()} or {@link Filters#chain()}. */ public Query filter(Filters.Filter filter) { - builder.setFilter(filter.toProto()); + Preconditions.checkNotNull(filter, "filter can't be null"); + + RowFilter rowFilter = filter.toProto(); + Preconditions.checkArgument( + rowFilter.getSerializedSize() < MAX_FILTER_SIZE, "filter size can't be more than 20MB"); + + builder.setFilter(rowFilter); return this; } diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/models/QueryTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/models/QueryTest.java index b073f979ba..bf6abcd168 100644 --- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/models/QueryTest.java +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/models/QueryTest.java @@ -112,6 +112,28 @@ public void rowRangeTest() { assertThat(actualProto).isEqualTo(expectedProto.build()); } + @Test + public void filterTestWithExceptions() { + Exception actualException = null; + try { + Query.create(TABLE_ID).filter(null); + } catch (Exception ex) { + actualException = ex; + } + assertThat(actualException).isInstanceOf(NullPointerException.class); + + actualException = null; + int maxFilterSize = 20 * 1024 * 1024; + ByteString largeValue = ByteString.copyFrom(new byte[maxFilterSize + 1]); + + try { + Query.create(TABLE_ID).filter(FILTERS.value().exactMatch(largeValue)); + } catch (Exception ex) { + actualException = ex; + } + assertThat(actualException).hasMessageThat().contains("filter size can't be more than 20MB"); + } + @Test public void filterTest() { Query query = Query.create(TABLE_ID).filter(FILTERS.key().regex(".*"));