This is an automated email from the ASF dual-hosted git repository.
JingsongLi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/paimon.git
The following commit(s) were added to refs/heads/master by this push:
new f59549f44a [common] Handle empty null counts in statistics filtering
(#10852)
f59549f44a is described below
commit f59549f44a0a2849f96d495691dcfaa0154b1290
Author: yuzelin <[email protected]>
AuthorDate: Thu Oct 29 11:55:19 2026 +0800
[common] Handle empty null counts in statistics filtering (#10852)
---
.../org/apache/paimon/predicate/LeafPredicate.java | 6 ++++-
.../apache/paimon/predicate/LeafPredicateTest.java | 28 ++++++++++++++++++++++
2 files changed, 33 insertions(+), 1 deletion(-)
diff --git
a/paimon-common/src/main/java/org/apache/paimon/predicate/LeafPredicate.java
b/paimon-common/src/main/java/org/apache/paimon/predicate/LeafPredicate.java
index 85a0485539..913c76f741 100644
--- a/paimon-common/src/main/java/org/apache/paimon/predicate/LeafPredicate.java
+++ b/paimon-common/src/main/java/org/apache/paimon/predicate/LeafPredicate.java
@@ -157,8 +157,12 @@ public class LeafPredicate implements Predicate {
Object min = get(minValues, index, type);
Object max = get(maxValues, index, type);
- Long nullCount = nullCounts.isNullAt(index) ? null :
nullCounts.getLong(index);
+ Long nullCount =
+ nullCounts.size() == 0 || nullCounts.isNullAt(index)
+ ? null
+ : nullCounts.getLong(index);
if (nullCount == null || rowCount != nullCount) {
+ // missing null counts
// not all null
// min or max is null
// unknown stats
diff --git
a/paimon-common/src/test/java/org/apache/paimon/predicate/LeafPredicateTest.java
b/paimon-common/src/test/java/org/apache/paimon/predicate/LeafPredicateTest.java
index a179753b0f..594e33ba79 100644
---
a/paimon-common/src/test/java/org/apache/paimon/predicate/LeafPredicateTest.java
+++
b/paimon-common/src/test/java/org/apache/paimon/predicate/LeafPredicateTest.java
@@ -18,9 +18,12 @@
package org.apache.paimon.predicate;
+import org.apache.paimon.data.BinaryArray;
+import org.apache.paimon.data.BinaryRow;
import org.apache.paimon.data.BinaryString;
import org.apache.paimon.data.GenericArray;
import org.apache.paimon.data.GenericRow;
+import org.apache.paimon.data.serializer.InternalRowSerializer;
import org.apache.paimon.types.DataTypes;
import org.apache.paimon.types.RowType;
import org.apache.paimon.utils.InstantiationUtil;
@@ -123,6 +126,31 @@ class LeafPredicateTest {
assertThat(InstantiationUtil.clone(containsAll).test(row)).isTrue();
}
+ @Test
+ public void testEmptyNullCountsWithCompleteBounds() {
+ RowType type = RowType.of(DataTypes.STRING(), DataTypes.STRING());
+ PredicateBuilder builder = new PredicateBuilder(type);
+ InternalRowSerializer serializer = new InternalRowSerializer(type);
+ BinaryRow bounds =
+ serializer
+ .toBinaryRow(
+ GenericRow.of(
+ BinaryString.fromString("sample"),
+ BinaryString.fromString("1")))
+ .copy();
+ BinaryArray nullCounts = BinaryArray.fromLongArray(new Long[0]);
+ Predicate first = builder.equal(0, BinaryString.fromString("other"));
+ Predicate second = builder.equal(1, BinaryString.fromString("1"));
+
+ assertThat(first.test(1, bounds, bounds, nullCounts)).isFalse();
+ assertThat(second.test(1, bounds, bounds, nullCounts)).isTrue();
+ assertThat(builder.isNull(0).test(1, bounds, bounds,
nullCounts)).isTrue();
+ assertThat(builder.isNotNull(1).test(1, bounds, bounds,
nullCounts)).isTrue();
+ assertThat(PredicateBuilder.and(first, second).test(1, bounds, bounds,
nullCounts))
+ .isFalse();
+ assertThat(PredicateBuilder.or(first, second).test(1, bounds, bounds,
nullCounts)).isTrue();
+ }
+
private LeafPredicate create() {
List<Object> inputs = new ArrayList<>();
inputs.add(new FieldRef(0, "f0", DataTypes.STRING()));