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 54079dbd34407f73f131cdc4dfd6aa49283fff48 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..24d110ebd5 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 such that the result has the specified size. + * + * @param resultSize Expected size for result string. If negative, it indicates + * that no trimming should be done. + */ + public NlsString rtrim(int resultSize) { + String value = getValue(); + if (value.length() <= resultSize || resultSize < 0) { + return this; + } + String left = value.substring(0, resultSize); + String right = value.substring(resultSize); + String trimmed = SqlFunctions.rtrim(left + right.trim()); + 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>. */
