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

mbudiu pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git

commit 4906ef2c6176c68eb7a090ecf8ebc43466457837
Author: Mihai Budiu <[email protected]>
AuthorDate: Fri Nov 1 11:43:07 2024 -0700

    [CALCITE-4590] Incorrect query result with fixed-length string
    
    Signed-off-by: Mihai Budiu <[email protected]>
---
 .../java/org/apache/calcite/rex/RexBuilder.java     |  2 +-
 .../java/org/apache/calcite/util/NlsString.java     | 21 +++++++++++++++++++++
 .../test/java/org/apache/calcite/test/JdbcTest.java | 15 +++++++++++++++
 3 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/core/src/main/java/org/apache/calcite/rex/RexBuilder.java 
b/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
index e6d7b1bd3b..4eb443fa3e 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
@@ -2001,7 +2001,7 @@ public class RexBuilder {
     case CHAR:
       final NlsString nlsString = (NlsString) value;
       if (trim) {
-        return makeCharLiteral(nlsString.rtrim());
+        return makeCharLiteral(nlsString.rtrim(type.getPrecision()));
       } else {
         return makeCharLiteral(padRight(nlsString, type.getPrecision()));
       }
diff --git a/core/src/main/java/org/apache/calcite/util/NlsString.java 
b/core/src/main/java/org/apache/calcite/util/NlsString.java
index 4660ded383..e4e9d8e632 100644
--- a/core/src/main/java/org/apache/calcite/util/NlsString.java
+++ b/core/src/main/java/org/apache/calcite/util/NlsString.java
@@ -227,6 +227,27 @@ public class NlsString implements Comparable<NlsString>, 
Cloneable {
     return this;
   }
 
+  /**
+   * Returns a string the same as this but with spaces trimmed from the
+   * right.  The result is never shorter than minResultSize.
+   *
+   * @param minResultSize Expected size for result string.  If negative, it 
indicates
+   *                   that no trimming should be done.
+   */
+  public NlsString rtrim(int minResultSize) {
+    String value = getValue();
+    if (value.length() <= minResultSize || minResultSize < 0) {
+      return this;
+    }
+    String left = value.substring(0, minResultSize);
+    String right = value.substring(minResultSize);
+    String trimmed = left + SqlFunctions.rtrim(right);
+    if (!trimmed.equals(value)) {
+      return new NlsString(trimmed, charsetName, collation);
+    }
+    return this;
+  }
+
   /** As {@link #asSql(boolean, boolean, SqlDialect)} but with SQL standard
    * dialect. */
   public String asSql(boolean prefix, boolean suffix) {
diff --git a/core/src/test/java/org/apache/calcite/test/JdbcTest.java 
b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
index 7ec62b28fb..2bbff3f6ed 100644
--- a/core/src/test/java/org/apache/calcite/test/JdbcTest.java
+++ b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
@@ -575,6 +575,21 @@ public class JdbcTest {
     connection.close();
   }
 
+  /** Test case for
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-4590";>[CALCITE-4590]
+   * Incorrect query result with fixed-length string</a>. */
+  @Test void testTrimLiteral() {
+    CalciteAssert.that()
+        .query("with t(x, y) as (values (1, 'a'), (2, 'abc'))"
+            + "select * from t where y = 'a'")
+        .returns("X=1; Y=a  \n");
+    CalciteAssert.that()
+        .query("with t(x, y) as (values (1, 'a'), (2, 'abc'))"
+            + "select * from t where y = 'a' or y = 'abc'")
+        .returns("X=1; Y=a  \n"
+            + "X=2; Y=abc\n");
+  }
+
   /** Test case for
    * <a 
href="https://issues.apache.org/jira/browse/CALCITE-3423";>[CALCITE-3423]
    * Support using CAST operation and BOOLEAN type value in table macro</a>. */

Reply via email to