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

lzljs3620320 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 c70edf2bbd [core] Unify TransformPredicate and LeafPredicate to one 
class (#7015)
c70edf2bbd is described below

commit c70edf2bbd32d101739bb2459c716ad4596ddced
Author: Jingsong Lee <[email protected]>
AuthorDate: Tue Jan 13 11:05:52 2026 +0800

    [core] Unify TransformPredicate and LeafPredicate to one class (#7015)
---
 .../paimon/fileindex/FileIndexPredicate.java       |  25 ++--
 .../apache/paimon/fileindex/FileIndexReader.java   |   4 +-
 .../paimon/globalindex/GlobalIndexEvaluator.java   |  15 +--
 .../paimon/globalindex/GlobalIndexReader.java      |   4 +-
 .../globalindex/btree/BTreeFileMetaSelector.java   |   4 +-
 .../org/apache/paimon/predicate/CastTransform.java |   5 +
 .../apache/paimon/predicate/ConcatTransform.java   |   5 +
 .../apache/paimon/predicate/ConcatWsTransform.java |   5 +
 .../java/org/apache/paimon/predicate/FieldRef.java |   2 +-
 .../apache/paimon/predicate/FieldTransform.java    |  13 +-
 .../apache/paimon/predicate/FunctionVisitor.java   |   9 +-
 .../org/apache/paimon/predicate/LeafPredicate.java | 148 ++++++++++++++++-----
 .../paimon/predicate/LeafPredicateExtractor.java   |  12 +-
 .../predicate/OnlyPartitionKeyEqualVisitor.java    |   2 +-
 .../predicate/PartitionPredicateVisitor.java       |  23 ++--
 .../apache/paimon/predicate/PredicateBuilder.java  |  18 +--
 .../predicate/PredicateProjectionConverter.java    |  41 +++---
 .../paimon/predicate/PredicateReplaceVisitor.java  |   5 -
 .../apache/paimon/predicate/PredicateVisitor.java  |   2 -
 .../paimon/predicate/RowIdPredicateVisitor.java    |  13 +-
 .../apache/paimon/predicate/StringTransform.java   |   5 +-
 .../org/apache/paimon/predicate/Transform.java     |   2 +
 .../paimon/predicate/TransformPredicate.java       | 144 --------------------
 .../apache/paimon/predicate/UpperTransform.java    |   5 +
 ...rmPredicateTest.java => LeafPredicateTest.java} |  16 +--
 .../org/apache/paimon/predicate/PredicateTest.java |   2 +-
 .../paimon/globalindex/DataEvolutionBatchScan.java |   2 +-
 .../paimon/operation/BucketSelectConverter.java    |  23 ++--
 .../apache/paimon/schema/SchemaEvolutionUtil.java  |  12 +-
 .../paimon/table/format/FormatTableScan.java       |  14 +-
 .../apache/paimon/table/system/AuditLogTable.java  |  14 +-
 .../paimon/schema/SchemaEvolutionUtilTest.java     |   6 +-
 .../orc/filter/OrcPredicateFunctionVisitor.java    |   4 +-
 .../parquet/filter2/predicate/ParquetFilters.java  |   4 +-
 .../format/orc/filter/OrcFilterConverterTest.java  |   5 +-
 35 files changed, 297 insertions(+), 316 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 05080128cc..0ad3238a4c 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
@@ -31,7 +31,6 @@ import org.apache.paimon.predicate.Predicate;
 import org.apache.paimon.predicate.PredicateVisitor;
 import org.apache.paimon.predicate.SortValue;
 import org.apache.paimon.predicate.TopN;
-import org.apache.paimon.predicate.TransformPredicate;
 import org.apache.paimon.types.RowType;
 
 import org.slf4j.Logger;
@@ -42,11 +41,11 @@ import javax.annotation.Nullable;
 import java.io.Closeable;
 import java.io.IOException;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 
 import static org.apache.paimon.fileindex.FileIndexResult.REMAIN;
@@ -121,7 +120,7 @@ public class FileIndexPredicate implements Closeable {
 
                     @Override
                     public Set<String> visit(LeafPredicate predicate) {
-                        return Collections.singleton(predicate.fieldName());
+                        return new HashSet<>(predicate.fieldNames());
                     }
 
                     @Override
@@ -133,11 +132,6 @@ public class FileIndexPredicate implements Closeable {
                         }
                         return result;
                     }
-
-                    @Override
-                    public Set<String> visit(TransformPredicate predicate) {
-                        return new HashSet<>(predicate.fieldNames());
-                    }
                 });
     }
 
@@ -161,10 +155,14 @@ public class FileIndexPredicate implements Closeable {
 
         @Override
         public FileIndexResult visit(LeafPredicate predicate) {
+            Optional<FieldRef> fieldRefOptional = predicate.fieldRefOptional();
+            if (!fieldRefOptional.isPresent()) {
+                return REMAIN;
+            }
+
             FileIndexResult compoundResult = REMAIN;
-            FieldRef fieldRef =
-                    new FieldRef(predicate.index(), predicate.fieldName(), 
predicate.type());
-            for (FileIndexReader fileIndexReader : 
columnIndexReaders.get(predicate.fieldName())) {
+            FieldRef fieldRef = fieldRefOptional.get();
+            for (FileIndexReader fileIndexReader : 
columnIndexReaders.get(fieldRef.name())) {
                 compoundResult =
                         compoundResult.and(
                                 predicate
@@ -204,10 +202,5 @@ public class FileIndexPredicate implements Closeable {
                 return compoundResult == null ? REMAIN : compoundResult;
             }
         }
-
-        @Override
-        public FileIndexResult visit(TransformPredicate predicate) {
-            return REMAIN;
-        }
     }
 }
diff --git 
a/paimon-common/src/main/java/org/apache/paimon/fileindex/FileIndexReader.java 
b/paimon-common/src/main/java/org/apache/paimon/fileindex/FileIndexReader.java
index 085971bb68..3b73e62d2b 100644
--- 
a/paimon-common/src/main/java/org/apache/paimon/fileindex/FileIndexReader.java
+++ 
b/paimon-common/src/main/java/org/apache/paimon/fileindex/FileIndexReader.java
@@ -20,8 +20,8 @@ package org.apache.paimon.fileindex;
 
 import org.apache.paimon.predicate.FieldRef;
 import org.apache.paimon.predicate.FunctionVisitor;
+import org.apache.paimon.predicate.LeafPredicate;
 import org.apache.paimon.predicate.TopN;
-import org.apache.paimon.predicate.TransformPredicate;
 
 import java.util.List;
 
@@ -132,7 +132,7 @@ public abstract class FileIndexReader implements 
FunctionVisitor<FileIndexResult
     }
 
     @Override
-    public FileIndexResult visit(TransformPredicate predicate) {
+    public FileIndexResult visitNonFieldLeaf(LeafPredicate predicate) {
         return REMAIN;
     }
 }
diff --git 
a/paimon-common/src/main/java/org/apache/paimon/globalindex/GlobalIndexEvaluator.java
 
b/paimon-common/src/main/java/org/apache/paimon/globalindex/GlobalIndexEvaluator.java
index 8f17c85503..0c66602730 100644
--- 
a/paimon-common/src/main/java/org/apache/paimon/globalindex/GlobalIndexEvaluator.java
+++ 
b/paimon-common/src/main/java/org/apache/paimon/globalindex/GlobalIndexEvaluator.java
@@ -24,7 +24,6 @@ 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.predicate.TransformPredicate;
 import org.apache.paimon.predicate.VectorSearch;
 import org.apache.paimon.types.RowType;
 import org.apache.paimon.utils.IOUtils;
@@ -90,10 +89,13 @@ public class GlobalIndexEvaluator
 
     @Override
     public Optional<GlobalIndexResult> visit(LeafPredicate predicate) {
+        Optional<FieldRef> fieldRefOptional = predicate.fieldRefOptional();
+        if (!fieldRefOptional.isPresent()) {
+            return Optional.empty();
+        }
         Optional<GlobalIndexResult> compoundResult = Optional.empty();
-        FieldRef fieldRef =
-                new FieldRef(predicate.index(), predicate.fieldName(), 
predicate.type());
-        int fieldId = rowType.getField(predicate.fieldName()).id();
+        FieldRef fieldRef = fieldRefOptional.get();
+        int fieldId = rowType.getField(fieldRef.name()).id();
         Collection<GlobalIndexReader> readers =
                 indexReadersCache.computeIfAbsent(fieldId, 
readersFunction::apply);
         for (GlobalIndexReader fileIndexReader : readers) {
@@ -158,11 +160,6 @@ public class GlobalIndexEvaluator
         }
     }
 
-    @Override
-    public Optional<GlobalIndexResult> visit(TransformPredicate predicate) {
-        return Optional.empty();
-    }
-
     public void close() {
         IOUtils.closeAllQuietly(
                 indexReadersCache.values().stream()
diff --git 
a/paimon-common/src/main/java/org/apache/paimon/globalindex/GlobalIndexReader.java
 
b/paimon-common/src/main/java/org/apache/paimon/globalindex/GlobalIndexReader.java
index d62c2a9f74..4cc4cfbbbb 100644
--- 
a/paimon-common/src/main/java/org/apache/paimon/globalindex/GlobalIndexReader.java
+++ 
b/paimon-common/src/main/java/org/apache/paimon/globalindex/GlobalIndexReader.java
@@ -19,7 +19,7 @@
 package org.apache.paimon.globalindex;
 
 import org.apache.paimon.predicate.FunctionVisitor;
-import org.apache.paimon.predicate.TransformPredicate;
+import org.apache.paimon.predicate.LeafPredicate;
 import org.apache.paimon.predicate.VectorSearch;
 
 import java.io.Closeable;
@@ -40,7 +40,7 @@ public interface GlobalIndexReader extends 
FunctionVisitor<Optional<GlobalIndexR
     }
 
     @Override
-    default Optional<GlobalIndexResult> visit(TransformPredicate predicate) {
+    default Optional<GlobalIndexResult> visitNonFieldLeaf(LeafPredicate 
predicate) {
         throw new UnsupportedOperationException();
     }
 
diff --git 
a/paimon-common/src/main/java/org/apache/paimon/globalindex/btree/BTreeFileMetaSelector.java
 
b/paimon-common/src/main/java/org/apache/paimon/globalindex/btree/BTreeFileMetaSelector.java
index babb0c3fd8..b0f83a2686 100644
--- 
a/paimon-common/src/main/java/org/apache/paimon/globalindex/btree/BTreeFileMetaSelector.java
+++ 
b/paimon-common/src/main/java/org/apache/paimon/globalindex/btree/BTreeFileMetaSelector.java
@@ -22,7 +22,7 @@ import org.apache.paimon.globalindex.GlobalIndexIOMeta;
 import org.apache.paimon.memory.MemorySlice;
 import org.apache.paimon.predicate.FieldRef;
 import org.apache.paimon.predicate.FunctionVisitor;
-import org.apache.paimon.predicate.TransformPredicate;
+import org.apache.paimon.predicate.LeafPredicate;
 import org.apache.paimon.utils.Pair;
 
 import java.util.ArrayList;
@@ -212,7 +212,7 @@ public class BTreeFileMetaSelector implements 
FunctionVisitor<Optional<List<Glob
     }
 
     @Override
-    public Optional<List<GlobalIndexIOMeta>> visit(TransformPredicate 
predicate) {
+    public Optional<List<GlobalIndexIOMeta>> visitNonFieldLeaf(LeafPredicate 
predicate) {
         return Optional.empty();
     }
 
diff --git 
a/paimon-common/src/main/java/org/apache/paimon/predicate/CastTransform.java 
b/paimon-common/src/main/java/org/apache/paimon/predicate/CastTransform.java
index 37141011f3..4f2e276067 100644
--- a/paimon-common/src/main/java/org/apache/paimon/predicate/CastTransform.java
+++ b/paimon-common/src/main/java/org/apache/paimon/predicate/CastTransform.java
@@ -61,6 +61,11 @@ public class CastTransform implements Transform {
         }
     }
 
+    @Override
+    public String name() {
+        return "CAST";
+    }
+
     @Override
     public List<Object> inputs() {
         return Collections.singletonList(fieldRef);
diff --git 
a/paimon-common/src/main/java/org/apache/paimon/predicate/ConcatTransform.java 
b/paimon-common/src/main/java/org/apache/paimon/predicate/ConcatTransform.java
index 40d51f075f..23e1aa0e1a 100644
--- 
a/paimon-common/src/main/java/org/apache/paimon/predicate/ConcatTransform.java
+++ 
b/paimon-common/src/main/java/org/apache/paimon/predicate/ConcatTransform.java
@@ -31,6 +31,11 @@ public class ConcatTransform extends StringTransform {
         super(inputs);
     }
 
+    @Override
+    public String name() {
+        return "CONCAT";
+    }
+
     @Override
     public BinaryString transform(List<BinaryString> inputs) {
         return BinaryString.concat(inputs);
diff --git 
a/paimon-common/src/main/java/org/apache/paimon/predicate/ConcatWsTransform.java
 
b/paimon-common/src/main/java/org/apache/paimon/predicate/ConcatWsTransform.java
index 197b1f34f0..52b490a92c 100644
--- 
a/paimon-common/src/main/java/org/apache/paimon/predicate/ConcatWsTransform.java
+++ 
b/paimon-common/src/main/java/org/apache/paimon/predicate/ConcatWsTransform.java
@@ -34,6 +34,11 @@ public class ConcatWsTransform extends StringTransform {
         checkArgument(inputs.size() >= 2);
     }
 
+    @Override
+    public String name() {
+        return "CONCAT_WS";
+    }
+
     @Override
     public BinaryString transform(List<BinaryString> inputs) {
         BinaryString separator = inputs.get(0);
diff --git 
a/paimon-common/src/main/java/org/apache/paimon/predicate/FieldRef.java 
b/paimon-common/src/main/java/org/apache/paimon/predicate/FieldRef.java
index a760ec2733..3d6811f864 100644
--- a/paimon-common/src/main/java/org/apache/paimon/predicate/FieldRef.java
+++ b/paimon-common/src/main/java/org/apache/paimon/predicate/FieldRef.java
@@ -71,6 +71,6 @@ public class FieldRef implements Serializable {
 
     @Override
     public String toString() {
-        return "FieldRef{" + "index=" + index + ", name='" + name + '\'' + ", 
type=" + type + '}';
+        return name;
     }
 }
diff --git 
a/paimon-common/src/main/java/org/apache/paimon/predicate/FieldTransform.java 
b/paimon-common/src/main/java/org/apache/paimon/predicate/FieldTransform.java
index 5b752950e1..b44c6039d2 100644
--- 
a/paimon-common/src/main/java/org/apache/paimon/predicate/FieldTransform.java
+++ 
b/paimon-common/src/main/java/org/apache/paimon/predicate/FieldTransform.java
@@ -26,6 +26,7 @@ import java.util.List;
 import java.util.Objects;
 
 import static org.apache.paimon.utils.InternalRowUtils.get;
+import static org.apache.paimon.utils.Preconditions.checkArgument;
 
 /** Transform that extracts a field from a row. */
 public class FieldTransform implements Transform {
@@ -38,6 +39,11 @@ public class FieldTransform implements Transform {
         this.fieldRef = fieldRef;
     }
 
+    @Override
+    public String name() {
+        return "FIELD_REF";
+    }
+
     public FieldRef fieldRef() {
         return fieldRef;
     }
@@ -59,7 +65,7 @@ public class FieldTransform implements Transform {
 
     @Override
     public Transform copyWithNewInputs(List<Object> inputs) {
-        assert inputs.size() == 1;
+        checkArgument(inputs.size() == 1);
         return new FieldTransform((FieldRef) inputs.get(0));
     }
 
@@ -76,4 +82,9 @@ public class FieldTransform implements Transform {
     public int hashCode() {
         return Objects.hashCode(fieldRef);
     }
+
+    @Override
+    public String toString() {
+        return fieldRef.name();
+    }
 }
diff --git 
a/paimon-common/src/main/java/org/apache/paimon/predicate/FunctionVisitor.java 
b/paimon-common/src/main/java/org/apache/paimon/predicate/FunctionVisitor.java
index 051a15367d..3edca0a459 100644
--- 
a/paimon-common/src/main/java/org/apache/paimon/predicate/FunctionVisitor.java
+++ 
b/paimon-common/src/main/java/org/apache/paimon/predicate/FunctionVisitor.java
@@ -19,6 +19,7 @@
 package org.apache.paimon.predicate;
 
 import java.util.List;
+import java.util.Optional;
 import java.util.stream.Collectors;
 
 /** A {@link PredicateVisitor} to visit functions. */
@@ -26,9 +27,15 @@ public interface FunctionVisitor<T> extends 
PredicateVisitor<T> {
 
     @Override
     default T visit(LeafPredicate predicate) {
-        return predicate.function().visit(this, predicate.fieldRef(), 
predicate.literals());
+        Optional<FieldRef> fieldRef = predicate.fieldRefOptional();
+        if (!fieldRef.isPresent()) {
+            return visitNonFieldLeaf(predicate);
+        }
+        return predicate.function().visit(this, fieldRef.get(), 
predicate.literals());
     }
 
+    T visitNonFieldLeaf(LeafPredicate leafPredicate);
+
     @Override
     default T visit(CompoundPredicate predicate) {
         return predicate
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 3ea68121c3..b75b2e11cd 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
@@ -31,7 +31,7 @@ import org.apache.paimon.utils.StringUtils;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
-import java.util.Collections;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
@@ -39,9 +39,13 @@ import java.util.Optional;
 import static org.apache.paimon.utils.InternalRowUtils.get;
 
 /** Leaf node of a {@link Predicate} tree. Compares a field in the row with 
literals. */
-public class LeafPredicate extends TransformPredicate {
+public class LeafPredicate implements Predicate {
 
-    private static final long serialVersionUID = 2L;
+    private static final long serialVersionUID = 3L;
+
+    private final Transform transform;
+    private final LeafFunction function;
+    private transient List<Object> literals;
 
     public LeafPredicate(
             LeafFunction function,
@@ -52,49 +56,70 @@ public class LeafPredicate extends TransformPredicate {
         this(new FieldTransform(new FieldRef(fieldIndex, fieldName, type)), 
function, literals);
     }
 
-    public LeafPredicate(
-            FieldTransform fieldTransform, LeafFunction function, List<Object> 
literals) {
-        super(fieldTransform, function, literals);
+    public LeafPredicate(Transform transform, LeafFunction function, 
List<Object> literals) {
+        this.transform = transform;
+        this.function = function;
+        this.literals = literals;
     }
 
-    public LeafFunction function() {
-        return function;
+    public static LeafPredicate of(
+            Transform transform, LeafFunction function, List<Object> literals) 
{
+        return new LeafPredicate(transform, function, literals);
     }
 
-    public DataType type() {
-        return fieldRef().type();
+    public LeafPredicate copyWithNewInputs(List<Object> newInputs) {
+        return new LeafPredicate(transform.copyWithNewInputs(newInputs), 
function, literals);
     }
 
-    public int index() {
-        return fieldRef().index();
+    public Transform transform() {
+        return transform;
     }
 
-    public String fieldName() {
-        return fieldRef().name();
+    public LeafFunction function() {
+        return function;
     }
 
     public List<String> fieldNames() {
-        return Collections.singletonList(fieldRef().name());
+        List<String> names = new ArrayList<>();
+        for (Object input : transform.inputs()) {
+            if (input instanceof FieldRef) {
+                names.add(((FieldRef) input).name());
+            }
+        }
+        return names;
     }
 
-    public FieldRef fieldRef() {
-        return ((FieldTransform) transform).fieldRef();
+    public Optional<FieldRef> fieldRefOptional() {
+        if (transform instanceof FieldTransform) {
+            return Optional.of(((FieldTransform) transform).fieldRef());
+        }
+        return Optional.empty();
     }
 
     public List<Object> literals() {
         return literals;
     }
 
-    public LeafPredicate copyWithNewIndex(int fieldIndex) {
-        return new LeafPredicate(function, type(), fieldIndex, fieldName(), 
literals);
+    @Override
+    public boolean test(InternalRow row) {
+        Object value = transform.transform(row);
+        return function.test(transform.outputType(), value, literals);
     }
 
     @Override
     public boolean test(
             long rowCount, InternalRow minValues, InternalRow maxValues, 
InternalArray nullCounts) {
-        Object min = get(minValues, index(), type());
-        Object max = get(maxValues, index(), type());
-        Long nullCount = nullCounts.isNullAt(index()) ? null : 
nullCounts.getLong(index());
+        Optional<FieldRef> fieldRefOptional = fieldRefOptional();
+        if (!fieldRefOptional.isPresent()) {
+            return true;
+        }
+        FieldRef fieldRef = fieldRefOptional.get();
+        int index = fieldRef.index();
+        DataType type = fieldRef.type();
+
+        Object min = get(minValues, index, type);
+        Object max = get(maxValues, index, type);
+        Long nullCount = nullCounts.isNullAt(index) ? null : 
nullCounts.getLong(index);
         if (nullCount == null || rowCount != nullCount) {
             // not all null
             // min or max is null
@@ -103,13 +128,25 @@ public class LeafPredicate extends TransformPredicate {
                 return true;
             }
         }
-        return function.test(type(), rowCount, min, max, nullCount, literals);
+        return function.test(type, rowCount, min, max, nullCount, literals);
     }
 
     @Override
     public Optional<Predicate> negate() {
+        Optional<FieldRef> fieldRefOptional = fieldRefOptional();
+        if (!fieldRefOptional.isPresent()) {
+            return Optional.empty();
+        }
+        FieldRef fieldRef = fieldRefOptional.get();
         return function.negate()
-                .map(negate -> new LeafPredicate(negate, type(), index(), 
fieldName(), literals));
+                .map(
+                        negate ->
+                                new LeafPredicate(
+                                        negate,
+                                        fieldRef.type(),
+                                        fieldRef.index(),
+                                        fieldRef.name(),
+                                        literals));
     }
 
     @Override
@@ -117,6 +154,22 @@ public class LeafPredicate extends TransformPredicate {
         return visitor.visit(this);
     }
 
+    @Override
+    public boolean equals(Object o) {
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        LeafPredicate that = (LeafPredicate) o;
+        return Objects.equals(transform, that.transform)
+                && Objects.equals(function, that.function)
+                && Objects.equals(literals, that.literals);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(transform, function, literals);
+    }
+
     @Override
     public String toString() {
         String literalsStr;
@@ -129,22 +182,57 @@ public class LeafPredicate extends TransformPredicate {
             literalsStr = StringUtils.truncatedString(literals, "[", ", ", 
"]");
         }
         return literalsStr.isEmpty()
-                ? function + "(" + fieldName() + ")"
-                : function + "(" + fieldName() + ", " + literalsStr + ")";
+                ? function + "(" + transform + ")"
+                : function + "(" + transform + ", " + literalsStr + ")";
     }
 
-    private ListSerializer<Object> objectsSerializer() {
+    private ListSerializer<Object> literalsSerializer() {
         return new ListSerializer<>(
-                
NullableSerializer.wrapIfNullIsNotSupported(InternalSerializers.create(type())));
+                NullableSerializer.wrapIfNullIsNotSupported(
+                        InternalSerializers.create(transform.outputType())));
     }
 
     private void writeObject(ObjectOutputStream out) throws IOException {
         out.defaultWriteObject();
-        objectsSerializer().serialize(literals, new 
DataOutputViewStreamWrapper(out));
+        literalsSerializer().serialize(literals, new 
DataOutputViewStreamWrapper(out));
     }
 
     private void readObject(ObjectInputStream in) throws IOException, 
ClassNotFoundException {
         in.defaultReadObject();
-        literals = objectsSerializer().deserialize(new 
DataInputViewStreamWrapper(in));
+        literals = literalsSerializer().deserialize(new 
DataInputViewStreamWrapper(in));
+    }
+
+    // ====================== Deprecated methods 
===============================
+    // ================ Will be removed in Next Version 
========================
+
+    /** Use {@link #fieldRefOptional()} instead. */
+    @Deprecated
+    public DataType type() {
+        return fieldRef().type();
+    }
+
+    /** Use {@link #fieldRefOptional()} instead. */
+    @Deprecated
+    public int index() {
+        return fieldRef().index();
+    }
+
+    /** Use {@link #fieldRefOptional()} instead. */
+    @Deprecated
+    public String fieldName() {
+        return fieldRef().name();
+    }
+
+    /** Use {@link #fieldRefOptional()} instead. */
+    @Deprecated
+    public FieldRef fieldRef() {
+        //noinspection OptionalGetWithoutIsPresent
+        return fieldRefOptional().get();
+    }
+
+    /** Use {@link #fieldRefOptional()} instead. */
+    @Deprecated
+    public LeafPredicate copyWithNewIndex(int fieldIndex) {
+        return new LeafPredicate(function, type(), fieldIndex, fieldName(), 
literals);
     }
 }
diff --git 
a/paimon-common/src/main/java/org/apache/paimon/predicate/LeafPredicateExtractor.java
 
b/paimon-common/src/main/java/org/apache/paimon/predicate/LeafPredicateExtractor.java
index 0d3b09778b..667c8f636c 100644
--- 
a/paimon-common/src/main/java/org/apache/paimon/predicate/LeafPredicateExtractor.java
+++ 
b/paimon-common/src/main/java/org/apache/paimon/predicate/LeafPredicateExtractor.java
@@ -21,6 +21,7 @@ package org.apache.paimon.predicate;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Optional;
 
 /** Extract leaf predicate for field names. */
 public class LeafPredicateExtractor implements PredicateVisitor<Map<String, 
LeafPredicate>> {
@@ -29,7 +30,11 @@ public class LeafPredicateExtractor implements 
PredicateVisitor<Map<String, Leaf
 
     @Override
     public Map<String, LeafPredicate> visit(LeafPredicate predicate) {
-        return Collections.singletonMap(predicate.fieldName(), predicate);
+        Optional<FieldRef> fieldRefOptional = predicate.fieldRefOptional();
+        if (!fieldRefOptional.isPresent()) {
+            throw new UnsupportedOperationException();
+        }
+        return Collections.singletonMap(fieldRefOptional.get().name(), 
predicate);
     }
 
     @Override
@@ -41,9 +46,4 @@ public class LeafPredicateExtractor implements 
PredicateVisitor<Map<String, Leaf
         }
         return Collections.emptyMap();
     }
-
-    @Override
-    public Map<String, LeafPredicate> visit(TransformPredicate predicate) {
-        throw new UnsupportedOperationException();
-    }
 }
diff --git 
a/paimon-common/src/main/java/org/apache/paimon/predicate/OnlyPartitionKeyEqualVisitor.java
 
b/paimon-common/src/main/java/org/apache/paimon/predicate/OnlyPartitionKeyEqualVisitor.java
index 3c74c52219..677b2fb74f 100644
--- 
a/paimon-common/src/main/java/org/apache/paimon/predicate/OnlyPartitionKeyEqualVisitor.java
+++ 
b/paimon-common/src/main/java/org/apache/paimon/predicate/OnlyPartitionKeyEqualVisitor.java
@@ -128,7 +128,7 @@ public class OnlyPartitionKeyEqualVisitor implements 
FunctionVisitor<Boolean> {
     }
 
     @Override
-    public Boolean visit(TransformPredicate predicate) {
+    public Boolean visitNonFieldLeaf(LeafPredicate predicate) {
         return false;
     }
 }
diff --git 
a/paimon-common/src/main/java/org/apache/paimon/predicate/PartitionPredicateVisitor.java
 
b/paimon-common/src/main/java/org/apache/paimon/predicate/PartitionPredicateVisitor.java
index fa180aa2f4..4db27bd1a1 100644
--- 
a/paimon-common/src/main/java/org/apache/paimon/predicate/PartitionPredicateVisitor.java
+++ 
b/paimon-common/src/main/java/org/apache/paimon/predicate/PartitionPredicateVisitor.java
@@ -31,7 +31,15 @@ public class PartitionPredicateVisitor implements 
PredicateVisitor<Boolean> {
 
     @Override
     public Boolean visit(LeafPredicate predicate) {
-        return partitionKeys.contains(predicate.fieldName());
+        Transform transform = predicate.transform();
+        for (Object input : transform.inputs()) {
+            if (input instanceof FieldRef) {
+                if (!partitionKeys.contains(((FieldRef) input).name())) {
+                    return false;
+                }
+            }
+        }
+        return true;
     }
 
     @Override
@@ -45,17 +53,4 @@ public class PartitionPredicateVisitor implements 
PredicateVisitor<Boolean> {
         }
         return true;
     }
-
-    @Override
-    public Boolean visit(TransformPredicate predicate) {
-        Transform transform = predicate.transform();
-        for (Object input : transform.inputs()) {
-            if (input instanceof FieldRef) {
-                if (!partitionKeys.contains(((FieldRef) input).name())) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
 }
diff --git 
a/paimon-common/src/main/java/org/apache/paimon/predicate/PredicateBuilder.java 
b/paimon-common/src/main/java/org/apache/paimon/predicate/PredicateBuilder.java
index 58634f3edf..665e8d5cc0 100644
--- 
a/paimon-common/src/main/java/org/apache/paimon/predicate/PredicateBuilder.java
+++ 
b/paimon-common/src/main/java/org/apache/paimon/predicate/PredicateBuilder.java
@@ -181,7 +181,7 @@ public class PredicateBuilder {
     }
 
     private Predicate leaf(LeafFunction function, Transform transform, Object 
literal) {
-        return TransformPredicate.of(transform, function, 
singletonList(literal));
+        return LeafPredicate.of(transform, function, singletonList(literal));
     }
 
     private Predicate leaf(LeafUnaryFunction function, int idx) {
@@ -191,7 +191,7 @@ public class PredicateBuilder {
     }
 
     private Predicate leaf(LeafFunction function, Transform transform) {
-        return TransformPredicate.of(transform, function, 
Collections.emptyList());
+        return LeafPredicate.of(transform, function, Collections.emptyList());
     }
 
     public Predicate in(int idx, List<Object> literals) {
@@ -213,7 +213,7 @@ public class PredicateBuilder {
         // In the IN predicate, 20 literals are critical for performance.
         // If there are more than 20 literals, the performance will decrease.
         if (literals.size() > 20) {
-            return TransformPredicate.of(transform, In.INSTANCE, literals);
+            return LeafPredicate.of(transform, In.INSTANCE, literals);
         }
 
         List<Predicate> equals = new ArrayList<>(literals.size());
@@ -441,9 +441,9 @@ public class PredicateBuilder {
                 }
             }
             return Optional.of(new 
CompoundPredicate(compoundPredicate.function(), children));
-        } else if (predicate instanceof TransformPredicate) {
-            TransformPredicate transformPredicate = (TransformPredicate) 
predicate;
-            List<Object> inputs = transformPredicate.transform.inputs();
+        } else if (predicate instanceof LeafPredicate) {
+            LeafPredicate leafPredicate = (LeafPredicate) predicate;
+            List<Object> inputs = leafPredicate.transform().inputs();
             List<Object> newInputs = new ArrayList<>(inputs.size());
             for (Object input : inputs) {
                 if (input instanceof FieldRef) {
@@ -458,7 +458,7 @@ public class PredicateBuilder {
                     newInputs.add(input);
                 }
             }
-            return 
Optional.of(transformPredicate.copyWithNewInputs(newInputs));
+            return Optional.of(leafPredicate.copyWithNewInputs(newInputs));
         } else {
             return Optional.empty();
         }
@@ -473,8 +473,8 @@ public class PredicateBuilder {
             }
             return false;
         } else {
-            TransformPredicate transformPredicate = (TransformPredicate) 
predicate;
-            return fields.containsAll(transformPredicate.fieldNames());
+            LeafPredicate leafPredicate = (LeafPredicate) predicate;
+            return fields.containsAll(leafPredicate.fieldNames());
         }
     }
 
diff --git 
a/paimon-common/src/main/java/org/apache/paimon/predicate/PredicateProjectionConverter.java
 
b/paimon-common/src/main/java/org/apache/paimon/predicate/PredicateProjectionConverter.java
index 47d6a63bc4..12b77cfe4b 100644
--- 
a/paimon-common/src/main/java/org/apache/paimon/predicate/PredicateProjectionConverter.java
+++ 
b/paimon-common/src/main/java/org/apache/paimon/predicate/PredicateProjectionConverter.java
@@ -42,13 +42,22 @@ public class PredicateProjectionConverter implements 
PredicateVisitor<Optional<P
 
     @Override
     public Optional<Predicate> visit(LeafPredicate predicate) {
-        int index = predicate.index();
-        Integer adjusted = reversed.get(index);
-        if (adjusted == null) {
-            return Optional.empty();
+        List<Object> inputs = predicate.transform().inputs();
+        List<Object> newInputs = new ArrayList<>(inputs.size());
+        for (Object input : inputs) {
+            if (input instanceof FieldRef) {
+                FieldRef fieldRef = (FieldRef) input;
+                Integer mappedIndex = reversed.get(fieldRef.index());
+                if (mappedIndex != null) {
+                    newInputs.add(new FieldRef(mappedIndex, fieldRef.name(), 
fieldRef.type()));
+                } else {
+                    return Optional.empty();
+                }
+            } else {
+                newInputs.add(input);
+            }
         }
-
-        return Optional.of(predicate.copyWithNewIndex(adjusted));
+        return Optional.of(predicate.copyWithNewInputs(newInputs));
     }
 
     @Override
@@ -67,24 +76,4 @@ public class PredicateProjectionConverter implements 
PredicateVisitor<Optional<P
         }
         return Optional.of(new CompoundPredicate(predicate.function(), 
converted));
     }
-
-    @Override
-    public Optional<Predicate> visit(TransformPredicate predicate) {
-        List<Object> inputs = predicate.transform.inputs();
-        List<Object> newInputs = new ArrayList<>(inputs.size());
-        for (Object input : inputs) {
-            if (input instanceof FieldRef) {
-                FieldRef fieldRef = (FieldRef) input;
-                Integer mappedIndex = reversed.get(fieldRef.index());
-                if (mappedIndex != null) {
-                    newInputs.add(new FieldRef(mappedIndex, fieldRef.name(), 
fieldRef.type()));
-                } else {
-                    return Optional.empty();
-                }
-            } else {
-                newInputs.add(input);
-            }
-        }
-        return Optional.of(predicate.copyWithNewInputs(newInputs));
-    }
 }
diff --git 
a/paimon-common/src/main/java/org/apache/paimon/predicate/PredicateReplaceVisitor.java
 
b/paimon-common/src/main/java/org/apache/paimon/predicate/PredicateReplaceVisitor.java
index 5cbd232896..aeaa5d5aee 100644
--- 
a/paimon-common/src/main/java/org/apache/paimon/predicate/PredicateReplaceVisitor.java
+++ 
b/paimon-common/src/main/java/org/apache/paimon/predicate/PredicateReplaceVisitor.java
@@ -39,9 +39,4 @@ public interface PredicateReplaceVisitor extends 
PredicateVisitor<Optional<Predi
         }
         return Optional.of(new CompoundPredicate(predicate.function(), 
converted));
     }
-
-    @Override
-    default Optional<Predicate> visit(TransformPredicate predicate) {
-        return Optional.empty();
-    }
 }
diff --git 
a/paimon-common/src/main/java/org/apache/paimon/predicate/PredicateVisitor.java 
b/paimon-common/src/main/java/org/apache/paimon/predicate/PredicateVisitor.java
index 9c0efe5c85..c741c05d46 100644
--- 
a/paimon-common/src/main/java/org/apache/paimon/predicate/PredicateVisitor.java
+++ 
b/paimon-common/src/main/java/org/apache/paimon/predicate/PredicateVisitor.java
@@ -24,6 +24,4 @@ public interface PredicateVisitor<T> {
     T visit(LeafPredicate predicate);
 
     T visit(CompoundPredicate predicate);
-
-    T visit(TransformPredicate predicate);
 }
diff --git 
a/paimon-common/src/main/java/org/apache/paimon/predicate/RowIdPredicateVisitor.java
 
b/paimon-common/src/main/java/org/apache/paimon/predicate/RowIdPredicateVisitor.java
index 953737dd9f..00622a5081 100644
--- 
a/paimon-common/src/main/java/org/apache/paimon/predicate/RowIdPredicateVisitor.java
+++ 
b/paimon-common/src/main/java/org/apache/paimon/predicate/RowIdPredicateVisitor.java
@@ -45,7 +45,12 @@ public class RowIdPredicateVisitor implements 
PredicateVisitor<Optional<List<Ran
 
     @Override
     public Optional<List<Range>> visit(LeafPredicate predicate) {
-        if (ROW_ID.name().equals(predicate.fieldName())) {
+        Optional<FieldRef> fieldRefOptional = predicate.fieldRefOptional();
+        if (!fieldRefOptional.isPresent()) {
+            return Optional.empty();
+        }
+        FieldRef fieldRef = fieldRefOptional.get();
+        if (ROW_ID.name().equals(fieldRef.name())) {
             LeafFunction function = predicate.function();
             if (function instanceof Equal || function instanceof In) {
                 ArrayList<Long> rowIds = new ArrayList<>();
@@ -99,10 +104,4 @@ public class RowIdPredicateVisitor implements 
PredicateVisitor<Optional<List<Ran
         }
         return rowIds;
     }
-
-    @Override
-    public Optional<List<Range>> visit(TransformPredicate predicate) {
-        // do not support transform predicate now.
-        return Optional.empty();
-    }
 }
diff --git 
a/paimon-common/src/main/java/org/apache/paimon/predicate/StringTransform.java 
b/paimon-common/src/main/java/org/apache/paimon/predicate/StringTransform.java
index c01d3bcb28..d858c02954 100644
--- 
a/paimon-common/src/main/java/org/apache/paimon/predicate/StringTransform.java
+++ 
b/paimon-common/src/main/java/org/apache/paimon/predicate/StringTransform.java
@@ -26,6 +26,7 @@ import org.apache.paimon.types.DataTypes;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
+import java.util.stream.Collectors;
 
 import static org.apache.paimon.types.DataTypeFamily.CHARACTER_STRING;
 import static org.apache.paimon.utils.Preconditions.checkArgument;
@@ -95,6 +96,8 @@ public abstract class StringTransform implements Transform {
 
     @Override
     public String toString() {
-        return getClass().getSimpleName() + "{" + "inputs=" + inputs + '}';
+        List<String> inputs =
+                
this.inputs.stream().map(Object::toString).collect(Collectors.toList());
+        return name() + "(" + String.join(", ", inputs) + ')';
     }
 }
diff --git 
a/paimon-common/src/main/java/org/apache/paimon/predicate/Transform.java 
b/paimon-common/src/main/java/org/apache/paimon/predicate/Transform.java
index 1b7caa1a89..dd76d53c0a 100644
--- a/paimon-common/src/main/java/org/apache/paimon/predicate/Transform.java
+++ b/paimon-common/src/main/java/org/apache/paimon/predicate/Transform.java
@@ -27,6 +27,8 @@ import java.util.List;
 /** Represents a transform function. */
 public interface Transform extends Serializable {
 
+    String name();
+
     List<Object> inputs();
 
     DataType outputType();
diff --git 
a/paimon-common/src/main/java/org/apache/paimon/predicate/TransformPredicate.java
 
b/paimon-common/src/main/java/org/apache/paimon/predicate/TransformPredicate.java
deleted file mode 100644
index 04549584a5..0000000000
--- 
a/paimon-common/src/main/java/org/apache/paimon/predicate/TransformPredicate.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * 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.predicate;
-
-import org.apache.paimon.data.InternalArray;
-import org.apache.paimon.data.InternalRow;
-import org.apache.paimon.data.serializer.InternalSerializers;
-import org.apache.paimon.data.serializer.ListSerializer;
-import org.apache.paimon.data.serializer.NullableSerializer;
-import org.apache.paimon.io.DataInputViewStreamWrapper;
-import org.apache.paimon.io.DataOutputViewStreamWrapper;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import java.util.Optional;
-
-/** A {@link Predicate} with {@link Transform}. */
-public class TransformPredicate implements Predicate {
-
-    private static final long serialVersionUID = 1L;
-
-    protected final Transform transform;
-    protected final LeafFunction function;
-    protected transient List<Object> literals;
-
-    protected TransformPredicate(
-            Transform transform, LeafFunction function, List<Object> literals) 
{
-        this.transform = transform;
-        this.function = function;
-        this.literals = literals;
-    }
-
-    public static TransformPredicate of(
-            Transform transform, LeafFunction function, List<Object> literals) 
{
-        if (transform instanceof FieldTransform) {
-            return new LeafPredicate((FieldTransform) transform, function, 
literals);
-        }
-        return new TransformPredicate(transform, function, literals);
-    }
-
-    public Transform transform() {
-        return transform;
-    }
-
-    public TransformPredicate copyWithNewInputs(List<Object> newInputs) {
-        return TransformPredicate.of(transform.copyWithNewInputs(newInputs), 
function, literals);
-    }
-
-    public List<String> fieldNames() {
-        List<String> names = new ArrayList<>();
-        for (Object input : transform.inputs()) {
-            if (input instanceof FieldRef) {
-                names.add(((FieldRef) input).name());
-            }
-        }
-        return names;
-    }
-
-    @Override
-    public boolean test(InternalRow row) {
-        Object value = transform.transform(row);
-        return function.test(transform.outputType(), value, literals);
-    }
-
-    @Override
-    public boolean test(
-            long rowCount, InternalRow minValues, InternalRow maxValues, 
InternalArray nullCounts) {
-        return true;
-    }
-
-    @Override
-    public Optional<Predicate> negate() {
-        return Optional.empty();
-    }
-
-    @Override
-    public <T> T visit(PredicateVisitor<T> visitor) {
-        return visitor.visit(this);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-        TransformPredicate that = (TransformPredicate) o;
-        return Objects.equals(transform, that.transform)
-                && Objects.equals(function, that.function)
-                && Objects.equals(literals, that.literals);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(transform, function, literals);
-    }
-
-    @Override
-    public String toString() {
-        return "TransformPredicate{"
-                + "transform="
-                + transform
-                + ", function="
-                + function
-                + ", literals="
-                + literals
-                + '}';
-    }
-
-    private ListSerializer<Object> objectsSerializer() {
-        return new ListSerializer<>(
-                NullableSerializer.wrapIfNullIsNotSupported(
-                        InternalSerializers.create(transform.outputType())));
-    }
-
-    private void writeObject(ObjectOutputStream out) throws IOException {
-        out.defaultWriteObject();
-        objectsSerializer().serialize(literals, new 
DataOutputViewStreamWrapper(out));
-    }
-
-    private void readObject(ObjectInputStream in) throws IOException, 
ClassNotFoundException {
-        in.defaultReadObject();
-        literals = objectsSerializer().deserialize(new 
DataInputViewStreamWrapper(in));
-    }
-}
diff --git 
a/paimon-common/src/main/java/org/apache/paimon/predicate/UpperTransform.java 
b/paimon-common/src/main/java/org/apache/paimon/predicate/UpperTransform.java
index ffdca627c1..86b3f3d657 100644
--- 
a/paimon-common/src/main/java/org/apache/paimon/predicate/UpperTransform.java
+++ 
b/paimon-common/src/main/java/org/apache/paimon/predicate/UpperTransform.java
@@ -34,6 +34,11 @@ public class UpperTransform extends StringTransform {
         checkArgument(inputs.size() == 1);
     }
 
+    @Override
+    public String name() {
+        return "UPPER";
+    }
+
     @Override
     public BinaryString transform(List<BinaryString> inputs) {
         BinaryString string = inputs.get(0);
diff --git 
a/paimon-common/src/test/java/org/apache/paimon/predicate/TransformPredicateTest.java
 
b/paimon-common/src/test/java/org/apache/paimon/predicate/LeafPredicateTest.java
similarity index 85%
rename from 
paimon-common/src/test/java/org/apache/paimon/predicate/TransformPredicateTest.java
rename to 
paimon-common/src/test/java/org/apache/paimon/predicate/LeafPredicateTest.java
index c2f6fa32be..1368611554 100644
--- 
a/paimon-common/src/test/java/org/apache/paimon/predicate/TransformPredicateTest.java
+++ 
b/paimon-common/src/test/java/org/apache/paimon/predicate/LeafPredicateTest.java
@@ -31,11 +31,11 @@ import java.util.List;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-class TransformPredicateTest {
+class LeafPredicateTest {
 
     @Test
     public void testReturnTrue() {
-        TransformPredicate predicate = create();
+        LeafPredicate predicate = create();
         boolean result =
                 predicate.test(
                         GenericRow.of(
@@ -45,7 +45,7 @@ class TransformPredicateTest {
 
     @Test
     public void testReturnFalse() {
-        TransformPredicate predicate = create();
+        LeafPredicate predicate = create();
         boolean result =
                 predicate.test(
                         GenericRow.of(
@@ -55,27 +55,27 @@ class TransformPredicateTest {
 
     @Test
     public void testMinMax() {
-        TransformPredicate predicate = create();
+        LeafPredicate predicate = create();
         boolean result = predicate.test(1, null, null, null);
         assertThat(result).isTrue();
     }
 
     @Test
     public void testClass() throws IOException, ClassNotFoundException {
-        TransformPredicate predicate = create();
-        TransformPredicate clone = InstantiationUtil.clone(predicate);
+        LeafPredicate predicate = create();
+        LeafPredicate clone = InstantiationUtil.clone(predicate);
         assertThat(clone).isEqualTo(predicate);
         assertThat(clone.hashCode()).isEqualTo(predicate.hashCode());
         assertThat(clone.toString()).isEqualTo(predicate.toString());
     }
 
-    private TransformPredicate create() {
+    private LeafPredicate create() {
         List<Object> inputs = new ArrayList<>();
         inputs.add(new FieldRef(0, "f0", DataTypes.STRING()));
         inputs.add(new FieldRef(1, "f1", DataTypes.STRING()));
         ConcatTransform transform = new ConcatTransform(inputs);
         List<Object> literals = new ArrayList<>();
         literals.add(BinaryString.fromString("ha-he"));
-        return TransformPredicate.of(transform, Equal.INSTANCE, literals);
+        return LeafPredicate.of(transform, Equal.INSTANCE, literals);
     }
 }
diff --git 
a/paimon-common/src/test/java/org/apache/paimon/predicate/PredicateTest.java 
b/paimon-common/src/test/java/org/apache/paimon/predicate/PredicateTest.java
index e8ad446387..5bece36654 100644
--- a/paimon-common/src/test/java/org/apache/paimon/predicate/PredicateTest.java
+++ b/paimon-common/src/test/java/org/apache/paimon/predicate/PredicateTest.java
@@ -568,7 +568,7 @@ public class PredicateTest {
     private LeafFunction getLikeFunc(String pattern) {
         PredicateBuilder builder = new PredicateBuilder(RowType.of(new 
VarCharType()));
         Predicate predicate = builder.like(0, fromString(pattern));
-        return ((LeafPredicate) predicate).function;
+        return ((LeafPredicate) predicate).function();
     }
 
     @Test
diff --git 
a/paimon-core/src/main/java/org/apache/paimon/globalindex/DataEvolutionBatchScan.java
 
b/paimon-core/src/main/java/org/apache/paimon/globalindex/DataEvolutionBatchScan.java
index 586fd61b00..b101229b97 100644
--- 
a/paimon-core/src/main/java/org/apache/paimon/globalindex/DataEvolutionBatchScan.java
+++ 
b/paimon-core/src/main/java/org/apache/paimon/globalindex/DataEvolutionBatchScan.java
@@ -88,7 +88,7 @@ public class DataEvolutionBatchScan implements DataTableScan {
 
     private Predicate removeRowIdFilter(Predicate filter) {
         if (filter instanceof LeafPredicate
-                && ROW_ID.name().equals(((LeafPredicate) filter).fieldName())) 
{
+                && ((LeafPredicate) 
filter).fieldNames().contains(ROW_ID.name())) {
             return null;
         } else if (filter instanceof CompoundPredicate) {
             CompoundPredicate compoundPredicate = (CompoundPredicate) filter;
diff --git 
a/paimon-core/src/main/java/org/apache/paimon/operation/BucketSelectConverter.java
 
b/paimon-core/src/main/java/org/apache/paimon/operation/BucketSelectConverter.java
index 6018a9a2f8..6577099aa8 100644
--- 
a/paimon-core/src/main/java/org/apache/paimon/operation/BucketSelectConverter.java
+++ 
b/paimon-core/src/main/java/org/apache/paimon/operation/BucketSelectConverter.java
@@ -25,6 +25,7 @@ import org.apache.paimon.data.BinaryRow;
 import org.apache.paimon.data.GenericRow;
 import org.apache.paimon.data.serializer.InternalRowSerializer;
 import org.apache.paimon.predicate.Equal;
+import org.apache.paimon.predicate.FieldRef;
 import org.apache.paimon.predicate.In;
 import org.apache.paimon.predicate.LeafPredicate;
 import org.apache.paimon.predicate.Predicate;
@@ -71,15 +72,19 @@ public interface BucketSelectConverter {
             for (Predicate orPredicate : splitOr(andPredicate)) {
                 if (orPredicate instanceof LeafPredicate) {
                     LeafPredicate leaf = (LeafPredicate) orPredicate;
-                    if (reference == null || reference == leaf.index()) {
-                        reference = leaf.index();
-                        if (leaf.function().equals(Equal.INSTANCE)
-                                || leaf.function().equals(In.INSTANCE)) {
-                            values.addAll(
-                                    leaf.literals().stream()
-                                            .filter(Objects::nonNull)
-                                            .collect(Collectors.toList()));
-                            continue;
+                    Optional<FieldRef> fieldRefOptional = 
leaf.fieldRefOptional();
+                    if (fieldRefOptional.isPresent()) {
+                        FieldRef fieldRef = fieldRefOptional.get();
+                        if (reference == null || reference == 
fieldRef.index()) {
+                            reference = fieldRef.index();
+                            if (leaf.function().equals(Equal.INSTANCE)
+                                    || leaf.function().equals(In.INSTANCE)) {
+                                values.addAll(
+                                        leaf.literals().stream()
+                                                .filter(Objects::nonNull)
+                                                .collect(Collectors.toList()));
+                                continue;
+                            }
                         }
                     }
                 }
diff --git 
a/paimon-core/src/main/java/org/apache/paimon/schema/SchemaEvolutionUtil.java 
b/paimon-core/src/main/java/org/apache/paimon/schema/SchemaEvolutionUtil.java
index a9075fb6f2..694d2b1a55 100644
--- 
a/paimon-core/src/main/java/org/apache/paimon/schema/SchemaEvolutionUtil.java
+++ 
b/paimon-core/src/main/java/org/apache/paimon/schema/SchemaEvolutionUtil.java
@@ -28,6 +28,7 @@ import org.apache.paimon.casting.CastedRow;
 import org.apache.paimon.data.InternalArray;
 import org.apache.paimon.data.InternalMap;
 import org.apache.paimon.data.InternalRow;
+import org.apache.paimon.predicate.FieldRef;
 import org.apache.paimon.predicate.LeafPredicate;
 import org.apache.paimon.predicate.Predicate;
 import org.apache.paimon.predicate.PredicateReplaceVisitor;
@@ -153,17 +154,22 @@ public class SchemaEvolutionUtil {
 
         PredicateReplaceVisitor visitor =
                 predicate -> {
+                    Optional<FieldRef> fieldRefOptional = 
predicate.fieldRefOptional();
+                    if (!fieldRefOptional.isPresent()) {
+                        return Optional.empty();
+                    }
+                    FieldRef fieldRef = fieldRefOptional.get();
                     DataField tableField =
                             checkNotNull(
-                                    
nameToTableFields.get(predicate.fieldName()),
-                                    String.format("Find no field %s", 
predicate.fieldName()));
+                                    nameToTableFields.get(fieldRef.name()),
+                                    String.format("Find no field %s", 
fieldRef.name()));
                     DataField dataField = idToDataFields.get(tableField.id());
                     if (dataField == null) {
                         return keepNewFieldFilter ? Optional.of(predicate) : 
Optional.empty();
                     }
 
                     return CastExecutors.castLiteralsWithEvolution(
-                                    predicate.literals(), predicate.type(), 
dataField.type())
+                                    predicate.literals(), fieldRef.type(), 
dataField.type())
                             .map(
                                     literals ->
                                             new LeafPredicate(
diff --git 
a/paimon-core/src/main/java/org/apache/paimon/table/format/FormatTableScan.java 
b/paimon-core/src/main/java/org/apache/paimon/table/format/FormatTableScan.java
index 20cbb9b31d..932f8e07c0 100644
--- 
a/paimon-core/src/main/java/org/apache/paimon/table/format/FormatTableScan.java
+++ 
b/paimon-core/src/main/java/org/apache/paimon/table/format/FormatTableScan.java
@@ -33,6 +33,7 @@ import org.apache.paimon.partition.PartitionPredicate;
 import 
org.apache.paimon.partition.PartitionPredicate.DefaultPartitionPredicate;
 import 
org.apache.paimon.partition.PartitionPredicate.MultiplePartitionPredicate;
 import org.apache.paimon.predicate.Equal;
+import org.apache.paimon.predicate.FieldRef;
 import org.apache.paimon.predicate.LeafFunction;
 import org.apache.paimon.predicate.LeafPredicate;
 import org.apache.paimon.predicate.Predicate;
@@ -55,6 +56,7 @@ import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 
 import static 
org.apache.paimon.format.text.HadoopCompressionUtils.isCompressed;
@@ -303,10 +305,14 @@ public class FormatTableScan implements InnerTableScan {
         Map<String, String> equals = new HashMap<>();
         for (Predicate sub : predicates) {
             if (sub instanceof LeafPredicate) {
-                LeafFunction function = ((LeafPredicate) sub).function();
-                String field = ((LeafPredicate) sub).fieldName();
-                if (function instanceof Equal && 
partitionKeys.contains(field)) {
-                    equals.put(field, ((LeafPredicate) 
sub).literals().get(0).toString());
+                Optional<FieldRef> fieldRefOptional = ((LeafPredicate) 
sub).fieldRefOptional();
+                if (fieldRefOptional.isPresent()) {
+                    FieldRef fieldRef = fieldRefOptional.get();
+                    LeafFunction function = ((LeafPredicate) sub).function();
+                    String field = fieldRef.name();
+                    if (function instanceof Equal && 
partitionKeys.contains(field)) {
+                        equals.put(field, ((LeafPredicate) 
sub).literals().get(0).toString());
+                    }
                 }
             }
         }
diff --git 
a/paimon-core/src/main/java/org/apache/paimon/table/system/AuditLogTable.java 
b/paimon-core/src/main/java/org/apache/paimon/table/system/AuditLogTable.java
index d590e1eb55..001e1543ee 100644
--- 
a/paimon-core/src/main/java/org/apache/paimon/table/system/AuditLogTable.java
+++ 
b/paimon-core/src/main/java/org/apache/paimon/table/system/AuditLogTable.java
@@ -35,6 +35,7 @@ import org.apache.paimon.manifest.PartitionEntry;
 import org.apache.paimon.metrics.MetricRegistry;
 import org.apache.paimon.operation.ManifestsReader;
 import org.apache.paimon.partition.PartitionPredicate;
+import org.apache.paimon.predicate.FieldRef;
 import org.apache.paimon.predicate.LeafPredicate;
 import org.apache.paimon.predicate.Predicate;
 import org.apache.paimon.predicate.PredicateBuilder;
@@ -90,15 +91,20 @@ public class AuditLogTable implements DataTable, 
ReadonlyTable {
 
     public static final PredicateReplaceVisitor PREDICATE_CONVERTER =
             p -> {
-                if (p.index() == 0) {
+                Optional<FieldRef> fieldRefOptional = p.fieldRefOptional();
+                if (!fieldRefOptional.isPresent()) {
+                    return Optional.empty();
+                }
+                FieldRef fieldRef = fieldRefOptional.get();
+                if (fieldRef.index() == 0) {
                     return Optional.empty();
                 }
                 return Optional.of(
                         new LeafPredicate(
                                 p.function(),
-                                p.type(),
-                                p.index() - 1,
-                                p.fieldName(),
+                                fieldRef.type(),
+                                fieldRef.index() - 1,
+                                fieldRef.name(),
                                 p.literals()));
             };
 
diff --git 
a/paimon-core/src/test/java/org/apache/paimon/schema/SchemaEvolutionUtilTest.java
 
b/paimon-core/src/test/java/org/apache/paimon/schema/SchemaEvolutionUtilTest.java
index 9466e69db3..11dec785bb 100644
--- 
a/paimon-core/src/test/java/org/apache/paimon/schema/SchemaEvolutionUtilTest.java
+++ 
b/paimon-core/src/test/java/org/apache/paimon/schema/SchemaEvolutionUtilTest.java
@@ -18,6 +18,7 @@
 
 package org.apache.paimon.schema;
 
+import org.apache.paimon.predicate.FieldRef;
 import org.apache.paimon.predicate.IsNotNull;
 import org.apache.paimon.predicate.IsNull;
 import org.apache.paimon.predicate.LeafPredicate;
@@ -97,7 +98,8 @@ public class SchemaEvolutionUtilTest {
 
         LeafPredicate child1 = (LeafPredicate) filters.get(0);
         assertThat(child1.function()).isEqualTo(IsNull.INSTANCE);
-        assertThat(child1.fieldName()).isEqualTo("b");
-        assertThat(child1.index()).isEqualTo(1);
+        FieldRef fieldRef = child1.fieldRefOptional().get();
+        assertThat(fieldRef.name()).isEqualTo("b");
+        assertThat(fieldRef.index()).isEqualTo(1);
     }
 }
diff --git 
a/paimon-format/src/main/java/org/apache/paimon/format/orc/filter/OrcPredicateFunctionVisitor.java
 
b/paimon-format/src/main/java/org/apache/paimon/format/orc/filter/OrcPredicateFunctionVisitor.java
index 6996f6a67b..bc32f5bd74 100644
--- 
a/paimon-format/src/main/java/org/apache/paimon/format/orc/filter/OrcPredicateFunctionVisitor.java
+++ 
b/paimon-format/src/main/java/org/apache/paimon/format/orc/filter/OrcPredicateFunctionVisitor.java
@@ -22,7 +22,7 @@ import org.apache.paimon.data.Decimal;
 import org.apache.paimon.data.Timestamp;
 import org.apache.paimon.predicate.FieldRef;
 import org.apache.paimon.predicate.FunctionVisitor;
-import org.apache.paimon.predicate.TransformPredicate;
+import org.apache.paimon.predicate.LeafPredicate;
 import org.apache.paimon.types.DataType;
 
 import org.apache.hadoop.hive.ql.io.sarg.PredicateLeaf;
@@ -245,7 +245,7 @@ public class OrcPredicateFunctionVisitor
     }
 
     @Override
-    public Optional<OrcFilters.Predicate> visit(TransformPredicate predicate) {
+    public Optional<OrcFilters.Predicate> visitNonFieldLeaf(LeafPredicate 
predicate) {
         return Optional.empty();
     }
 
diff --git 
a/paimon-format/src/main/java/org/apache/parquet/filter2/predicate/ParquetFilters.java
 
b/paimon-format/src/main/java/org/apache/parquet/filter2/predicate/ParquetFilters.java
index 6d9e6ccaae..1c2b2106b9 100644
--- 
a/paimon-format/src/main/java/org/apache/parquet/filter2/predicate/ParquetFilters.java
+++ 
b/paimon-format/src/main/java/org/apache/parquet/filter2/predicate/ParquetFilters.java
@@ -21,8 +21,8 @@ package org.apache.parquet.filter2.predicate;
 import org.apache.paimon.data.BinaryString;
 import org.apache.paimon.predicate.FieldRef;
 import org.apache.paimon.predicate.FunctionVisitor;
+import org.apache.paimon.predicate.LeafPredicate;
 import org.apache.paimon.predicate.Predicate;
-import org.apache.paimon.predicate.TransformPredicate;
 import org.apache.paimon.types.ArrayType;
 import org.apache.paimon.types.BigIntType;
 import org.apache.paimon.types.BinaryType;
@@ -208,7 +208,7 @@ public class ParquetFilters {
         }
 
         @Override
-        public FilterPredicate visit(TransformPredicate predicate) {
+        public FilterPredicate visitNonFieldLeaf(LeafPredicate predicate) {
             throw new UnsupportedOperationException();
         }
     }
diff --git 
a/paimon-format/src/test/java/org/apache/paimon/format/orc/filter/OrcFilterConverterTest.java
 
b/paimon-format/src/test/java/org/apache/paimon/format/orc/filter/OrcFilterConverterTest.java
index 78bd01be96..1e21578b2e 100644
--- 
a/paimon-format/src/test/java/org/apache/paimon/format/orc/filter/OrcFilterConverterTest.java
+++ 
b/paimon-format/src/test/java/org/apache/paimon/format/orc/filter/OrcFilterConverterTest.java
@@ -252,7 +252,10 @@ public class OrcFilterConverterTest {
                         (OrcFilters.ColumnPredicate) orcPredicate;
                 assertThat(
                                 OrcPredicateFunctionVisitor.toOrcType(
-                                        ((LeafPredicate) predicate).type()))
+                                        ((LeafPredicate) predicate)
+                                                .fieldRefOptional()
+                                                .get()
+                                                .type()))
                         .isEqualTo(columnPredicate.literalType);
             }
         } else {

Reply via email to