diff --git a/paimon-common/src/main/java/org/apache/paimon/predicate/SubstringTransform.java b/paimon-common/src/main/java/org/apache/paimon/predicate/SubstringTransform.java index 9094837d72f1..483ff5515cf3 100644 --- a/paimon-common/src/main/java/org/apache/paimon/predicate/SubstringTransform.java +++ b/paimon-common/src/main/java/org/apache/paimon/predicate/SubstringTransform.java @@ -75,21 +75,21 @@ public final Object transform(InternalRow row) { return null; } - String sourceJavaString = sourceString.toString(); + int sourceLength = sourceString.numChars(); int beginIndex = readPosition(inputs.get(1), row); - if (beginIndex > sourceJavaString.length()) { + if (beginIndex > sourceLength) { return BinaryString.EMPTY_UTF8; } - int endIndex = sourceJavaString.length(); + int endIndex = sourceLength; if (hasLength) { endIndex = beginIndex + readPosition(inputs.get(2), row) - 1; } - endIndex = Math.min(endIndex, sourceJavaString.length()); + endIndex = Math.min(endIndex, sourceLength); beginIndex--; checkArgument(beginIndex < endIndex); - return BinaryString.fromString(sourceJavaString.substring(beginIndex, endIndex)); + return sourceString.substring(beginIndex, endIndex); } private static boolean isNullPosition(Object position, InternalRow row) { diff --git a/paimon-common/src/test/java/org/apache/paimon/predicate/SubstringTransformTest.java b/paimon-common/src/test/java/org/apache/paimon/predicate/SubstringTransformTest.java index 9dd80a5f94e8..8c66ee306629 100644 --- a/paimon-common/src/test/java/org/apache/paimon/predicate/SubstringTransformTest.java +++ b/paimon-common/src/test/java/org/apache/paimon/predicate/SubstringTransformTest.java @@ -25,6 +25,7 @@ import org.junit.jupiter.api.Test; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; @@ -82,6 +83,14 @@ public void testNormalInputs() { assertThat(result).isEqualTo(BinaryString.fromString("")); } + @Test + public void testSubstringWithSupplementaryCharacter() { + SubstringTransform transform = + new SubstringTransform(Arrays.asList(BinaryString.fromString("A😀B"), 2, 1)); + + assertThat(transform.transform(GenericRow.of())).isEqualTo(BinaryString.fromString("😀")); + } + @Test public void testSubstringRefInputs() { List inputs = new ArrayList<>();