You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by se...@apache.org on 2019/03/11 02:48:39 UTC
[calcite] branch master updated: [CALCITE-2599] Implement SQL ASCII
function (Chunwei Lei)
This is an automated email from the ASF dual-hosted git repository.
sereda 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 a481357 [CALCITE-2599] Implement SQL ASCII function (Chunwei Lei)
a481357 is described below
commit a4813575ea8bfdb7dd65ddbf37d150835dad1d5d
Author: Chunwei Lei <ch...@alibaba-inc.com>
AuthorDate: Sun Mar 10 00:56:15 2019 +0800
[CALCITE-2599] Implement SQL ASCII function (Chunwei Lei)
It follows PostgreSQL standard which returns unicode code point for non-ASCII chars
---
.../org/apache/calcite/adapter/enumerable/RexImpTable.java | 2 ++
.../main/java/org/apache/calcite/runtime/SqlFunctions.java | 6 ++++++
.../org/apache/calcite/sql/fun/SqlStdOperatorTable.java | 9 +++++++++
.../main/java/org/apache/calcite/util/BuiltInMethod.java | 1 +
.../org/apache/calcite/sql/test/SqlOperatorBaseTest.java | 13 +++++++++++++
site/_docs/reference.md | 2 +-
6 files changed, 32 insertions(+), 1 deletion(-)
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 1237ad2..9554f80 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
@@ -97,6 +97,7 @@ import static org.apache.calcite.sql.fun.SqlStdOperatorTable.ACOS;
import static org.apache.calcite.sql.fun.SqlStdOperatorTable.AND;
import static org.apache.calcite.sql.fun.SqlStdOperatorTable.ANY_VALUE;
import static org.apache.calcite.sql.fun.SqlStdOperatorTable.ARRAY_VALUE_CONSTRUCTOR;
+import static org.apache.calcite.sql.fun.SqlStdOperatorTable.ASCII;
import static org.apache.calcite.sql.fun.SqlStdOperatorTable.ASIN;
import static org.apache.calcite.sql.fun.SqlStdOperatorTable.ATAN;
import static org.apache.calcite.sql.fun.SqlStdOperatorTable.ATAN2;
@@ -279,6 +280,7 @@ public class RexImpTable {
NullPolicy.STRICT);
defineMethod(OVERLAY, BuiltInMethod.OVERLAY.method, NullPolicy.STRICT);
defineMethod(POSITION, BuiltInMethod.POSITION.method, NullPolicy.STRICT);
+ defineMethod(ASCII, BuiltInMethod.ASCII.method, NullPolicy.STRICT);
final TrimImplementor trimImplementor = new TrimImplementor();
defineImplementor(TRIM, NullPolicy.STRICT, trimImplementor, false);
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 b475000..5e9d6df 100644
--- a/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
+++ b/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
@@ -237,6 +237,12 @@ public class SqlFunctions {
return newS.toString();
}
+ /** SQL ASCII(string) function. */
+ public static int ascii(String s) {
+ return s.isEmpty()
+ ? 0 : s.codePointAt(0);
+ }
+
/** 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/SqlStdOperatorTable.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java
index 3e66b9c..f514ccd 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java
@@ -1483,6 +1483,15 @@ public class SqlStdOperatorTable extends ReflectiveSqlOperatorTable {
OperandTypes.CHARACTER,
SqlFunctionCategory.STRING);
+ public static final SqlFunction ASCII =
+ new SqlFunction(
+ "ASCII",
+ SqlKind.OTHER_FUNCTION,
+ ReturnTypes.INTEGER_NULLABLE,
+ null,
+ OperandTypes.CHARACTER,
+ SqlFunctionCategory.STRING);
+
/**
* Uses SqlOperatorTable.useDouble for its return type since we don't know
* what the result type will be by just looking at the operand types. For
diff --git a/core/src/main/java/org/apache/calcite/util/BuiltInMethod.java b/core/src/main/java/org/apache/calcite/util/BuiltInMethod.java
index 3169b55..9a67e16 100644
--- a/core/src/main/java/org/apache/calcite/util/BuiltInMethod.java
+++ b/core/src/main/java/org/apache/calcite/util/BuiltInMethod.java
@@ -266,6 +266,7 @@ public enum BuiltInMethod {
ANY_ITEM(SqlFunctions.class, "itemOptional", Object.class, Object.class),
UPPER(SqlFunctions.class, "upper", String.class),
LOWER(SqlFunctions.class, "lower", String.class),
+ ASCII(SqlFunctions.class, "ascii", String.class),
JSONIZE(SqlFunctions.class, "jsonize", Object.class),
DEJSONIZE(SqlFunctions.class, "dejsonize", String.class),
JSON_VALUE_EXPRESSION(SqlFunctions.class, "jsonValueExpression",
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 0e876bc..fcf7fe9 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
@@ -4247,6 +4247,19 @@ public abstract class SqlOperatorBaseTest {
tester.checkNull("CHARACTER_LENGTH(cast(null as varchar(1)))");
}
+ @Test public void testAsciiFunc() {
+ tester.setFor(SqlStdOperatorTable.ASCII);
+ tester.checkScalarExact("ASCII('')", "0");
+ tester.checkScalarExact("ASCII('a')", "97");
+ tester.checkScalarExact("ASCII('1')", "49");
+ tester.checkScalarExact("ASCII('abc')", "97");
+ tester.checkScalarExact("ASCII('ABC')", "65");
+ tester.checkScalarExact("ASCII(_UTF8'\u0082')", "130");
+ tester.checkScalarExact("ASCII(_UTF8'\u5B57')", "23383");
+ tester.checkScalarExact("ASCII(_UTF8'Ω')", "937");
+ tester.checkNull("ASCII(cast(null as varchar(1)))");
+ }
+
@Test public void testUpperFunc() {
tester.setFor(SqlStdOperatorTable.UPPER);
tester.checkString("upper('a')", "A", "CHAR(1) NOT NULL");
diff --git a/site/_docs/reference.md b/site/_docs/reference.md
index 31508dd..e7e9282 100644
--- a/site/_docs/reference.md
+++ b/site/_docs/reference.md
@@ -1448,10 +1448,10 @@ period:
| {fn SUBSTRING(string, offset, length)} | Returns a character string that consists of *length* characters from *string* starting at the *offset* position
| {fn UCASE(string)} | Returns a string in which all alphabetic characters in *string* have been converted to upper case
| {fn REPLACE(string, search, replacement)} | Returns a string in which all the occurrences of *search* in *string* are replaced with *replacement*; if *replacement* is the empty string, the occurrences of *search* are removed
+| {fn ASCII(string)} | Returns the corresponding ASCII code of the first character of *string*; Returns 0 if *string* is empty; Returns NULL if *string* is NULL; Returns the Unicode code point for non-ASCII character
Not implemented:
-* {fn ASCII(string)} - Convert a single-character string to the corresponding ASCII code, an integer between 0 and 255
* {fn CHAR(string)}
* {fn DIFFERENCE(string, string)}
* {fn LEFT(string, integer)}