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 77279da3a3 [core] Fix record comparator cache key for sort order 
(#7222)
77279da3a3 is described below

commit 77279da3a3ef34f9ef9b49fac1181f45174967e2
Author: Liulietong <[email protected]>
AuthorDate: Mon Feb 9 11:00:54 2026 +0800

    [core] Fix record comparator cache key for sort order (#7222)
    
    ## Problem
    The cache key for `recordComparator` only considered the sort key types
    but ignored the sort order (ascending/descending). This caused
    comparators with different sort orders to share the same cached class,
    leading to incorrect sorting behavior.
    
    ## Solution
    Include `SortOrder` in the cache key generation to ensure each unique
    sort order combination gets its own generated comparator class.
    
    ## Summary
    - Include sort order in the codegen cache key for record comparators
    - Add a regression test for ascending/descending comparator cache
    collisions
    
    ## Testing
    ```bash
    mvn -pl paimon-core -Dtest=CodeGenUtilsTest test
    ```
---
 .../org/apache/paimon/codegen/CodeGenUtils.java    | 23 ++++++++++++++++++----
 .../apache/paimon/codegen/CodeGenUtilsTest.java    | 18 +++++++++++++++++
 2 files changed, 37 insertions(+), 4 deletions(-)

diff --git 
a/paimon-core/src/main/java/org/apache/paimon/codegen/CodeGenUtils.java 
b/paimon-core/src/main/java/org/apache/paimon/codegen/CodeGenUtils.java
index 18f8e628f2..5270f92462 100644
--- a/paimon-core/src/main/java/org/apache/paimon/codegen/CodeGenUtils.java
+++ b/paimon-core/src/main/java/org/apache/paimon/codegen/CodeGenUtils.java
@@ -80,6 +80,7 @@ public class CodeGenUtils {
                 RecordComparator.class,
                 inputTypes,
                 sortFields,
+                isAscendingOrder,
                 () ->
                         getCodeGenerator()
                                 .generateRecordComparator(
@@ -103,7 +104,16 @@ public class CodeGenUtils {
             List<DataType> fields,
             int[] fieldsIndex,
             Supplier<GeneratedClass<T>> supplier) {
-        ClassKey classKey = new ClassKey(classType, fields, fieldsIndex);
+        return generate(classType, fields, fieldsIndex, null, supplier);
+    }
+
+    private static <T> T generate(
+            Class<?> classType,
+            List<DataType> fields,
+            int[] fieldsIndex,
+            Object extraKey,
+            Supplier<GeneratedClass<T>> supplier) {
+        ClassKey classKey = new ClassKey(classType, fields, fieldsIndex, 
extraKey);
 
         try {
             Pair<Class<?>, Object[]> result =
@@ -153,10 +163,14 @@ public class CodeGenUtils {
 
         private final int[] fieldsIndex;
 
-        public ClassKey(Class<?> classType, List<DataType> fields, int[] 
fieldsIndex) {
+        private final Object extraKey;
+
+        public ClassKey(
+                Class<?> classType, List<DataType> fields, int[] fieldsIndex, 
Object extraKey) {
             this.classType = classType;
             this.fields = fields;
             this.fieldsIndex = fieldsIndex;
+            this.extraKey = extraKey;
         }
 
         @Override
@@ -170,12 +184,13 @@ public class CodeGenUtils {
             ClassKey classKey = (ClassKey) o;
             return Objects.equals(classType, classKey.classType)
                     && Objects.equals(fields, classKey.fields)
-                    && Arrays.equals(fieldsIndex, classKey.fieldsIndex);
+                    && Arrays.equals(fieldsIndex, classKey.fieldsIndex)
+                    && Objects.equals(extraKey, classKey.extraKey);
         }
 
         @Override
         public int hashCode() {
-            int result = Objects.hash(classType, fields);
+            int result = Objects.hash(classType, fields, extraKey);
             result = 31 * result + Arrays.hashCode(fieldsIndex);
             return result;
         }
diff --git 
a/paimon-core/src/test/java/org/apache/paimon/codegen/CodeGenUtilsTest.java 
b/paimon-core/src/test/java/org/apache/paimon/codegen/CodeGenUtilsTest.java
index 5872750dd7..2d98596a28 100644
--- a/paimon-core/src/test/java/org/apache/paimon/codegen/CodeGenUtilsTest.java
+++ b/paimon-core/src/test/java/org/apache/paimon/codegen/CodeGenUtilsTest.java
@@ -18,6 +18,9 @@
 
 package org.apache.paimon.codegen;
 
+import org.apache.paimon.data.BinaryString;
+import org.apache.paimon.data.GenericRow;
+import org.apache.paimon.data.InternalRow;
 import org.apache.paimon.types.RowType;
 
 import org.junit.jupiter.api.Test;
@@ -101,6 +104,21 @@ class CodeGenUtilsTest {
                         Arrays.asList(STRING(), INT(), DOUBLE()), new int[] 
{0, 1, 2}, true));
     }
 
+    @Test
+    public void testRecordComparatorOrderCacheMiss() {
+        RecordComparator ascending =
+                newRecordComparator(Arrays.asList(STRING(), INT()), new int[] 
{0, 1}, true);
+        RecordComparator descending =
+                newRecordComparator(Arrays.asList(STRING(), INT()), new int[] 
{0, 1}, false);
+
+        InternalRow row1 = GenericRow.of(BinaryString.fromString("a"), 1);
+        InternalRow row2 = GenericRow.of(BinaryString.fromString("b"), 1);
+
+        assertThat(ascending.compare(row1, row2)).isLessThan(0);
+        assertThat(descending.compare(row1, row2)).isGreaterThan(0);
+        assertThat(ascending.getClass()).isNotEqualTo(descending.getClass());
+    }
+
     @Test
     public void testRecordEqualiserCodegenCache() {
         assertClassEquals(() -> newRecordEqualiser(Arrays.asList(STRING(), 
INT())));

Reply via email to