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 c44b9e7df0 [common] Fix duplicate file index predicate traversal 
(#8338)
c44b9e7df0 is described below

commit c44b9e7df0c7e4e6669087caedd8609b16f7d8a4
Author: hutiefang76 <[email protected]>
AuthorDate: Wed Jun 24 09:13:21 2026 +0800

    [common] Fix duplicate file index predicate traversal (#8338)
---
 .../paimon/fileindex/FileIndexPredicate.java       | 20 +----
 .../paimon/fileindex/FileIndexPredicateTest.java   | 92 ++++++++++++++++++++++
 2 files changed, 93 insertions(+), 19 deletions(-)

diff --git 
a/paimon-common/src/main/java/org/apache/paimon/fileindex/FileIndexPredicate.java
 
b/paimon-common/src/main/java/org/apache/paimon/fileindex/FileIndexPredicate.java
index 0ad3238a4c..1cd4a8b01c 100644
--- 
a/paimon-common/src/main/java/org/apache/paimon/fileindex/FileIndexPredicate.java
+++ 
b/paimon-common/src/main/java/org/apache/paimon/fileindex/FileIndexPredicate.java
@@ -42,7 +42,6 @@ import java.io.Closeable;
 import java.io.IOException;
 import java.util.Collection;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
@@ -115,24 +114,7 @@ public class FileIndexPredicate implements Closeable {
     }
 
     private Set<String> getRequiredNames(Predicate filePredicate) {
-        return filePredicate.visit(
-                new PredicateVisitor<Set<String>>() {
-
-                    @Override
-                    public Set<String> visit(LeafPredicate predicate) {
-                        return new HashSet<>(predicate.fieldNames());
-                    }
-
-                    @Override
-                    public Set<String> visit(CompoundPredicate predicate) {
-                        Set<String> result = new HashSet<>();
-                        for (Predicate child : predicate.children()) {
-                            child.visit(this);
-                            result.addAll(child.visit(this));
-                        }
-                        return result;
-                    }
-                });
+        return PredicateVisitor.collectFieldNames(filePredicate);
     }
 
     @Override
diff --git 
a/paimon-common/src/test/java/org/apache/paimon/fileindex/FileIndexPredicateTest.java
 
b/paimon-common/src/test/java/org/apache/paimon/fileindex/FileIndexPredicateTest.java
new file mode 100644
index 0000000000..e2d4d7b578
--- /dev/null
+++ 
b/paimon-common/src/test/java/org/apache/paimon/fileindex/FileIndexPredicateTest.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.paimon.fileindex;
+
+import org.apache.paimon.predicate.CompoundPredicate;
+import org.apache.paimon.predicate.Equal;
+import org.apache.paimon.predicate.LeafPredicate;
+import org.apache.paimon.predicate.Or;
+import org.apache.paimon.predicate.Predicate;
+import org.apache.paimon.predicate.PredicateVisitor;
+import org.apache.paimon.types.DataTypes;
+import org.apache.paimon.types.RowType;
+
+import org.junit.jupiter.api.Test;
+
+import java.io.ByteArrayOutputStream;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Set;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/** Test for {@link FileIndexPredicate}. */
+public class FileIndexPredicateTest {
+
+    @Test
+    public void testGetRequiredNamesVisitsEachChildOnce() throws Exception {
+        CountingLeafPredicate left = new CountingLeafPredicate(0, "a");
+        CountingLeafPredicate right = new CountingLeafPredicate(1, "b");
+        Predicate predicate = new CompoundPredicate(Or.INSTANCE, 
Arrays.asList(left, right));
+
+        Set<String> requiredNames = getRequiredNames(predicate);
+
+        assertThat(requiredNames).containsExactlyInAnyOrder("a", "b");
+        assertThat(left.visitCount).isEqualTo(1);
+        assertThat(right.visitCount).isEqualTo(1);
+    }
+
+    @SuppressWarnings("unchecked")
+    private static Set<String> getRequiredNames(Predicate predicate) throws 
Exception {
+        Method method =
+                FileIndexPredicate.class.getDeclaredMethod("getRequiredNames", 
Predicate.class);
+        method.setAccessible(true);
+        return (Set<String>) method.invoke(emptyFileIndexPredicate(), 
predicate);
+    }
+
+    private static FileIndexPredicate emptyFileIndexPredicate() throws 
Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        FileIndexFormat.Writer writer = FileIndexFormat.createWriter(baos);
+        writer.writeColumnIndexes(new HashMap<String, java.util.Map<String, 
byte[]>>());
+        writer.close();
+        return new FileIndexPredicate(baos.toByteArray(), 
RowType.builder().build());
+    }
+
+    private static class CountingLeafPredicate extends LeafPredicate {
+
+        private int visitCount;
+
+        private CountingLeafPredicate(int fieldIndex, String fieldName) {
+            super(
+                    Equal.INSTANCE,
+                    DataTypes.INT(),
+                    fieldIndex,
+                    fieldName,
+                    Collections.singletonList(1));
+        }
+
+        @Override
+        public <T> T visit(PredicateVisitor<T> visitor) {
+            visitCount++;
+            return super.visit(visitor);
+        }
+    }
+}

Reply via email to