You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by ch...@apache.org on 2019/07/23 08:43:30 UTC
[calcite] branch master updated: [CALCITE-2510] Implement CHR
function (Sergey Tsvetkov, Chunwei Lei)
This is an automated email from the ASF dual-hosted git repository.
chunwei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/master by this push:
new 5754fa9 [CALCITE-2510] Implement CHR function (Sergey Tsvetkov, Chunwei Lei)
5754fa9 is described below
commit 5754fa95e20fb6a961b01c1c951fc47f21132923
Author: Sergei_Tsvetkov <93...@gmail.com>
AuthorDate: Mon Jun 10 17:26:26 2019 +0800
[CALCITE-2510] Implement CHR function (Sergey Tsvetkov, Chunwei Lei)
It follows oracle standard. Sergey started the work and Chunwei rebased and made some fixup.
Close apache/calcite#810
---
.../org/apache/calcite/adapter/enumerable/RexImpTable.java | 2 ++
.../main/java/org/apache/calcite/runtime/SqlFunctions.java | 5 +++++
.../org/apache/calcite/sql/fun/SqlLibraryOperators.java | 10 ++++++++++
.../main/java/org/apache/calcite/sql/type/ReturnTypes.java | 6 ++++++
.../org/apache/calcite/sql/test/SqlOperatorBaseTest.java | 13 +++++++++++++
site/_docs/reference.md | 1 +
6 files changed, 37 insertions(+)
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
index db1da06..24fd420 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
@@ -92,6 +92,7 @@ import static org.apache.calcite.linq4j.tree.ExpressionType.NotEqual;
import static org.apache.calcite.linq4j.tree.ExpressionType.OrElse;
import static org.apache.calcite.linq4j.tree.ExpressionType.Subtract;
import static org.apache.calcite.linq4j.tree.ExpressionType.UnaryPlus;
+import static org.apache.calcite.sql.fun.SqlLibraryOperators.CHR;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.DAYNAME;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.DIFFERENCE;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.FROM_BASE64;
@@ -294,6 +295,7 @@ public class RexImpTable {
defineMethod(RIGHT, BuiltInMethod.RIGHT.method, NullPolicy.ANY);
defineMethod(REPLACE, BuiltInMethod.REPLACE.method, NullPolicy.STRICT);
defineMethod(TRANSLATE3, BuiltInMethod.TRANSLATE3.method, NullPolicy.STRICT);
+ defineMethod(CHR, "chr", NullPolicy.STRICT);
defineMethod(CHARACTER_LENGTH, BuiltInMethod.CHAR_LENGTH.method,
NullPolicy.STRICT);
defineMethod(CHAR_LENGTH, BuiltInMethod.CHAR_LENGTH.method,
diff --git a/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java b/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
index a4fa957..68f6d94 100644
--- a/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
+++ b/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
@@ -355,6 +355,11 @@ public class SqlFunctions {
return s.substring(len - n);
}
+ /** SQL CHR(long) function. */
+ public static String chr(long n) {
+ return String.valueOf(Character.toChars((int) n));
+ }
+
/** SQL CHARACTER_LENGTH(string) function. */
public static int charLength(String s) {
return s.length();
diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java
index 15a7afc..93dc462 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java
@@ -253,6 +253,16 @@ public abstract class SqlLibraryOperators {
null,
OperandTypes.or(OperandTypes.STRING, OperandTypes.BINARY),
SqlFunctionCategory.STRING);
+
+ @LibraryOperator(libraries = {ORACLE})
+ public static final SqlFunction CHR =
+ new SqlFunction(
+ "CHR",
+ SqlKind.OTHER_FUNCTION,
+ ReturnTypes.CHAR,
+ null,
+ OperandTypes.INTEGER,
+ SqlFunctionCategory.STRING);
}
// End SqlLibraryOperators.java
diff --git a/core/src/main/java/org/apache/calcite/sql/type/ReturnTypes.java b/core/src/main/java/org/apache/calcite/sql/type/ReturnTypes.java
index aba475f..06a1648 100644
--- a/core/src/main/java/org/apache/calcite/sql/type/ReturnTypes.java
+++ b/core/src/main/java/org/apache/calcite/sql/type/ReturnTypes.java
@@ -252,6 +252,12 @@ public abstract class ReturnTypes {
cascade(DOUBLE, SqlTypeTransforms.TO_NULLABLE);
/**
+ * Type-inference strategy whereby the result type of a call is a Char.
+ */
+ public static final SqlReturnTypeInference CHAR =
+ explicit(SqlTypeName.CHAR);
+
+ /**
* Type-inference strategy whereby the result type of a call is an Integer.
*/
public static final SqlReturnTypeInference INTEGER =
diff --git a/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java b/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java
index 544e8ec..ee0ed1f 100644
--- a/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java
+++ b/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java
@@ -1985,6 +1985,19 @@ public abstract class SqlOperatorBaseTest {
}
+ @Test public void testChr() {
+ tester.setFor(SqlLibraryOperators.CHR, VM_FENNEL, VM_JAVA);
+ final SqlTester tester1 = oracleTester();
+ tester1.checkScalar("chr(97)",
+ "a", "CHAR(1) NOT NULL");
+ tester1.checkScalar("chr(48)",
+ "0", "CHAR(1) NOT NULL");
+ tester1.checkScalar("chr(0)",
+ String.valueOf('\u0000'), "CHAR(1) NOT NULL");
+ tester.checkFails("^chr(97.1)^",
+ "No match found for function signature CHR\\(<NUMERIC>\\)", false);
+ }
+
@Test public void testSelect() {
tester.check(
"select * from (values(1))",
diff --git a/site/_docs/reference.md b/site/_docs/reference.md
index d0a6bc2..d6f8a31 100644
--- a/site/_docs/reference.md
+++ b/site/_docs/reference.md
@@ -2088,6 +2088,7 @@ semantics.
| C | Operator syntax | Description
|:- |:-----------------------------------------------|:-----------
+| o | CHR(integer) | Returns the character having the binary equivalent to *integer* as a CHAR value
| o | DECODE(value, value1, result1 [, valueN, resultN ]* [, default ]) | Compares *value* to each *valueN* value one by one; if *value* is equal to a *valueN*, returns the corresponding *resultN*, else returns *default*, or NULL if *default* is not specified
| p | DIFFERENCE(string, string) | Returns a measure of the similarity of two strings, namely the number of character positions that their `SOUNDEX` values have in common: 4 if the `SOUNDEX` values are same and 0 if the `SOUNDEX` values are totally different
| o | GREATEST(expr [, expr ]*) | Returns the greatest of the expressions