This is an automated email from the ASF dual-hosted git repository.

junegunn pushed a commit to branch branch-2.6
in repository https://gitbox.apache.org/repos/asf/hbase.git


The following commit(s) were added to refs/heads/branch-2.6 by this push:
     new fe82853f052 HBASE-30033 Scan.setFilter() should validate against 
existing batch setting (#7988)
fe82853f052 is described below

commit fe82853f0523dad82d98f9a87f52d74c0efe5038
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 c37ee1e35a5..cb35f665d69 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
@@ -711,6 +711,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 170a569d5ba..d019bba4216 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
@@ -370,7 +370,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 4bc1ad2c8b1..16bf7379dec 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
@@ -20,6 +20,7 @@ package org.apache.hadoop.hbase.client;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 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;
 
@@ -30,6 +31,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;
@@ -255,6 +258,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();

Reply via email to