This is an automated email from the ASF dual-hosted git repository. jhyde pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/calcite.git
commit 48c0db1206b17c571d477d912d193d32b5be1eff Author: jackyWoo <[email protected]> AuthorDate: Tue Jul 30 20:15:26 2019 +0800 [CALCITE-3220] JDBC adapter now transforms TRIM to TRIM, LTRIM or RTRIM when target is Hive (Jacky Woo) Close apache/calcite#1342 --- .../apache/calcite/sql/dialect/HiveSqlDialect.java | 34 ++++++++++++++++++-- .../calcite/rel/rel2sql/RelToSqlConverterTest.java | 36 ++++++++++++++++++++++ 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/apache/calcite/sql/dialect/HiveSqlDialect.java b/core/src/main/java/org/apache/calcite/sql/dialect/HiveSqlDialect.java index 9d72626..2525460 100644 --- a/core/src/main/java/org/apache/calcite/sql/dialect/HiveSqlDialect.java +++ b/core/src/main/java/org/apache/calcite/sql/dialect/HiveSqlDialect.java @@ -19,11 +19,13 @@ package org.apache.calcite.sql.dialect; import org.apache.calcite.config.NullCollation; import org.apache.calcite.sql.SqlCall; import org.apache.calcite.sql.SqlDialect; +import org.apache.calcite.sql.SqlLiteral; import org.apache.calcite.sql.SqlNode; import org.apache.calcite.sql.SqlOperator; import org.apache.calcite.sql.SqlSyntax; import org.apache.calcite.sql.SqlWriter; import org.apache.calcite.sql.fun.SqlStdOperatorTable; +import org.apache.calcite.sql.fun.SqlTrimFunction; /** * A <code>SqlDialect</code> implementation for the Apache Hive database. @@ -64,8 +66,8 @@ public class HiveSqlDialect extends SqlDialect { return null; } - @Override public void unparseCall(final SqlWriter writer, final SqlCall call, final int leftPrec, - final int rightPrec) { + @Override public void unparseCall(final SqlWriter writer, final SqlCall call, + final int leftPrec, final int rightPrec) { switch (call.getKind()) { case POSITION: final SqlWriter.Frame frame = writer.startFunCall("INSTR"); @@ -82,11 +84,39 @@ public class HiveSqlDialect extends SqlDialect { SqlOperator op = SqlStdOperatorTable.PERCENT_REMAINDER; SqlSyntax.BINARY.unparse(writer, op, call, leftPrec, rightPrec); break; + case TRIM: + unparseTrim(writer, call, leftPrec, rightPrec); + break; default: super.unparseCall(writer, call, leftPrec, rightPrec); } } + /** + * For usage of TRIM, LTRIM and RTRIM in Hive, see + * <a href="https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF">Hive UDF usage</a>. + */ + private void unparseTrim(SqlWriter writer, SqlCall call, int leftPrec, + int rightPrec) { + assert call.operand(0) instanceof SqlLiteral : call.operand(0); + SqlLiteral flag = call.operand(0); + final String operatorName; + switch (flag.getValueAs(SqlTrimFunction.Flag.class)) { + case LEADING: + operatorName = "LTRIM"; + break; + case TRAILING: + operatorName = "RTRIM"; + break; + default: + operatorName = call.getOperator().getName(); + break; + } + final SqlWriter.Frame frame = writer.startFunCall(operatorName); + call.operand(2).unparse(writer, leftPrec, rightPrec); + writer.endFunCall(frame); + } + @Override public boolean supportsCharSet() { return false; } 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 f013e1f..5bebccc 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 @@ -804,6 +804,42 @@ public class RelToSqlConverterTest { } /** Test case for + * <a href="https://issues.apache.org/jira/browse/CALCITE-3220">[CALCITE-3220] + * HiveSqlDialect should transform the SQL-standard TRIM function to TRIM, + * LTRIM or RTRIM</a>. */ + @Test public void testHiveTrim() { + final String query = "SELECT TRIM(' str ')\n" + + "from \"foodmart\".\"reserve_employee\""; + final String expected = "SELECT TRIM(' str ')\n" + + "FROM foodmart.reserve_employee"; + sql(query).withHive().ok(expected); + } + + @Test public void testHiveTrimWithBoth() { + final String query = "SELECT TRIM(both ' ' from ' str ')\n" + + "from \"foodmart\".\"reserve_employee\""; + final String expected = "SELECT TRIM(' str ')\n" + + "FROM foodmart.reserve_employee"; + sql(query).withHive().ok(expected); + } + + @Test public void testHiveTrimWithLeading() { + final String query = "SELECT TRIM(LEADING ' ' from ' str ')\n" + + "from \"foodmart\".\"reserve_employee\""; + final String expected = "SELECT LTRIM(' str ')\n" + + "FROM foodmart.reserve_employee"; + sql(query).withHive().ok(expected); + } + + @Test public void testHiveTrimWithTailing() { + final String query = "SELECT TRIM(TRAILING ' ' from ' str ')\n" + + "from \"foodmart\".\"reserve_employee\""; + final String expected = "SELECT RTRIM(' str ')\n" + + "FROM foodmart.reserve_employee"; + sql(query).withHive().ok(expected); + } + + /** Test case for * <a href="https://issues.apache.org/jira/browse/CALCITE-2715">[CALCITE-2715] * MS SQL Server does not support character set as part of data type</a>. */ @Test public void testMssqlCharacterSet() {
