This is an automated email from the ASF dual-hosted git repository.
junegunn pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hbase.git
The following commit(s) were added to refs/heads/master by this push:
new 0c113384906 HBASE-30033 Scan.setFilter() should validate against
existing batch setting (#7988)
0c113384906 is described below
commit 0c1133849063e75e8106ac9f63c58335c127b2a1
Author: Jeongmin Ju <[email protected]>
AuthorDate: Tue Apr 7 11:59:29 2026 +0900
HBASE-30033 Scan.setFilter() should validate against existing batch setting
(#7988)
Scan.setBatch() validates that the scan does not have a filter with
hasFilterRow()=true. However, Scan.setFilter() does not perform the
reverse check. This allows creating an invalid Scan by calling
setBatch() before setFilter(), bypassing the validation that
setBatch() was designed to enforce.
Added validation in setFilter() to throw IncompatibleFilterException
when a filter with hasFilterRow()=true is set on a scan that already
has batch configured.
Signed-off-by: Junegunn Choi <[email protected]>
Signed-off-by: Pankaj Kumar <[email protected]>
Signed-off-by: Xiao Liu <[email protected]>
Reviewed-by: Vaibhav Joshi <[email protected]>
---
.../java/org/apache/hadoop/hbase/client/Scan.java | 4 +++
.../apache/hadoop/hbase/client/TestOperation.java | 2 +-
.../org/apache/hadoop/hbase/client/TestScan.java | 33 ++++++++++++++++++++++
3 files changed, 38 insertions(+), 1 deletion(-)
diff --git
a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Scan.java
b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Scan.java
index 5cc0d0fac87..630edc4a6ff 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Scan.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Scan.java
@@ -554,6 +554,10 @@ public class Scan extends Query {
@Override
public Scan setFilter(Filter filter) {
+ if (filter != null && filter.hasFilterRow() && this.batch > 0) {
+ throw new IncompatibleFilterException(
+ "Cannot set a filter that returns true for filter.hasFilterRow on a
scan with batch set");
+ }
super.setFilter(filter);
return this;
}
diff --git
a/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestOperation.java
b/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestOperation.java
index 24dc93a9311..06b688a052a 100644
---
a/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestOperation.java
+++
b/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestOperation.java
@@ -371,7 +371,7 @@ public class TestOperation {
scan.setLimit(5);
scan.setReadType(Scan.ReadType.PREAD);
scan.setNeedCursorResult(true);
- scan.setFilter(SCV_FILTER);
+ scan.setFilter(VALUE_FILTER);
scan.setReplicaId(1);
scan.setConsistency(Consistency.STRONG);
scan.setLoadColumnFamiliesOnDemand(true);
diff --git
a/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestScan.java
b/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestScan.java
index dcc624ff112..05c1cc6bcf8 100644
--- a/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestScan.java
+++ b/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestScan.java
@@ -19,6 +19,7 @@ package org.apache.hadoop.hbase.client;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
@@ -29,6 +30,8 @@ import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.client.Scan.ReadType;
import org.apache.hadoop.hbase.filter.FilterList;
+import org.apache.hadoop.hbase.filter.IncompatibleFilterException;
+import org.apache.hadoop.hbase.filter.PageFilter;
import org.apache.hadoop.hbase.security.access.Permission;
import org.apache.hadoop.hbase.security.visibility.Authorizations;
import org.apache.hadoop.hbase.testclassification.ClientTests;
@@ -254,6 +257,36 @@ public class TestScan {
"Make sure copy constructor adds all the fields in the copied object");
}
+ @Test
+ public void testSetFilterWithBatchThrows() {
+ Scan scan = new Scan();
+ scan.setBatch(5);
+ assertThrows(IncompatibleFilterException.class, () -> scan.setFilter(new
PageFilter(10)));
+ }
+
+ @Test
+ public void testSetFilterWithoutBatchDoesNotThrow() {
+ Scan scan = new Scan();
+ scan.setFilter(new PageFilter(10));
+ // no exception expected
+ }
+
+ @Test
+ public void testSetFilterWithBatchAndNonFilterRowFilter() {
+ Scan scan = new Scan();
+ scan.setBatch(5);
+ scan.setFilter(new FilterList());
+ // FilterList.hasFilterRow() returns false, so no exception expected
+ }
+
+ @Test
+ public void testSetFilterWithBatchAndNullFilter() {
+ Scan scan = new Scan();
+ scan.setBatch(5);
+ scan.setFilter(null);
+ // null filter should not throw
+ }
+
@Test
public void testScanReadType() throws Exception {
Scan scan = new Scan();