From 485a5d0ae3274a83a36788290b3bdc4d973387b4 Mon Sep 17 00:00:00 2001 From: Mihai Budiu Date: Thu, 12 Oct 2023 13:25:57 -0700 Subject: [PATCH] [CALCITE-6006] RelToSqlConverter loses charset information Signed-off-by: Mihai Budiu --- .../calcite/rel/rel2sql/SqlImplementor.java | 16 +++++++++++++++- .../rel/rel2sql/RelToSqlConverterTest.java | 12 ++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java b/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java index 16455ff2f622..573c497885f4 100644 --- a/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java +++ b/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java @@ -16,6 +16,7 @@ */ package org.apache.calcite.rel.rel2sql; +import org.apache.calcite.config.CalciteSystemProperty; import org.apache.calcite.linq4j.Ord; import org.apache.calcite.linq4j.tree.Expressions; import org.apache.calcite.plan.RelOptUtil; @@ -90,6 +91,7 @@ import org.apache.calcite.sql.validate.SqlValidatorUtil; import org.apache.calcite.util.DateString; import org.apache.calcite.util.ImmutableBitSet; +import org.apache.calcite.util.NlsString; import org.apache.calcite.util.Pair; import org.apache.calcite.util.RangeSets; import org.apache.calcite.util.Sarg; @@ -1409,8 +1411,20 @@ public static SqlNode toSql(RexLiteral literal) { () -> "literal " + literal + " has null SqlTypeFamily, and is SqlTypeName is " + typeName); switch (family) { - case CHARACTER: + case CHARACTER: { + final NlsString value = literal.getValueAs(NlsString.class); + if (value != null) { + final String defaultCharset = CalciteSystemProperty.DEFAULT_CHARSET.value(); + final String charsetName = value.getCharsetName(); + if (!defaultCharset.equals(charsetName)) { + // Set the charset only if it is not the same as the default charset + return SqlLiteral.createCharString( + castNonNull(value).getValue(), charsetName, POS); + } + } + // Create a string without specifying a charset return SqlLiteral.createCharString((String) castNonNull(literal.getValue2()), POS); + } case NUMERIC: case EXACT_NUMERIC: return SqlLiteral.createExactNumeric( diff --git a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java index 661f7163cb26..0e97580cb6fe 100644 --- a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java +++ b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java @@ -83,6 +83,7 @@ import org.apache.calcite.tools.RelBuilder; import org.apache.calcite.tools.RuleSet; import org.apache.calcite.tools.RuleSets; +import org.apache.calcite.util.ConversionUtil; import org.apache.calcite.util.ImmutableBitSet; import org.apache.calcite.util.TestUtil; import org.apache.calcite.util.Util; @@ -282,6 +283,17 @@ private static String toSql(RelNode root, SqlDialect dialect, sql(query).ok(expected); } + /** Test case for [CALCITE-6006] + * RelToSqlConverter loses charset information. */ + @Test void testCharset() { + sql("select _UTF8'\u4F60\u597D'") + .withMysql() // produces a simpler output query + .ok("SELECT _UTF-8'\u4F60\u597D'"); + sql("select _UTF16'" + ConversionUtil.TEST_UNICODE_STRING + "'") + .withMysql() + .ok("SELECT _UTF-16LE'" + ConversionUtil.TEST_UNICODE_STRING + "'"); + } + /** Test case for * [CALCITE-4321] * JDBC adapter omits FILTER (WHERE ...) expressions when generating SQL