herunkang2018 commented on code in PR #3373:
URL: https://github.com/apache/calcite/pull/3373#discussion_r1299185250


##########
core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java:
##########
@@ -831,6 +831,30 @@ public static String charFromUtf8(int n) {
     return String.valueOf(Character.toChars(n));
   }
 
+  /**
+   * SQL CODE_POINTS_TO_BYTES function.
+   */
+  public static @Nullable ByteString codePointsToBytes(List codePoints) {
+    int length = codePoints.size();
+    byte[] bytes = new byte[length];
+    for (int i = 0; i < length; i++) {
+      Object codePoint = codePoints.get(i);
+      if (codePoint == null) {
+        return null;
+      }
+      if (codePoint instanceof Number) {
+        long cp = ((Number) codePoint).longValue();
+        if (cp < 0 || cp > 255) {
+          throw new IllegalArgumentException(

Review Comment:
   I would use `CalciteResource` to store the exception string, this is a more 
uniform approach.



##########
core/src/main/java/org/apache/calcite/sql/type/OperandTypes.java:
##########
@@ -510,6 +510,30 @@ public static SqlOperandTypeChecker variadic(
         }
       };
 
+  public static final SqlSingleOperandTypeChecker ARRAY_OF_INTEGER =
+      new SqlSingleOperandTypeChecker() {
+        @Override public boolean checkSingleOperandType(SqlCallBinding 
callBinding, SqlNode operand,
+            int iFormalOperand, boolean throwOnFailure) {
+          assert 0 == iFormalOperand;
+          RelDataType type = SqlTypeUtil.deriveType(callBinding, operand);
+          RelDataType componentType =
+              requireNonNull(type.getComponentType(), "componentType");
+          if (SqlTypeUtil.isArray(type)
+              && SqlTypeUtil.isIntType(componentType)) {
+            return true;
+          }
+
+          if (throwOnFailure) {
+            throw callBinding.newValidationSignatureError();
+          }
+          return false;
+        }
+
+        @Override public String getAllowedSignatures(SqlOperator op, String 
opName) {
+          return opName + "(<INTEGER ARRAY>)";
+        }
+      };
+

Review Comment:
   Would you like to remove useless blank line?



##########
testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java:
##########
@@ -1804,6 +1804,28 @@ void testCastToBoolean(CastType castType, 
SqlOperatorFixture f) {
         consumer);
   }
 
+  @Test void testCodePointsToBytes() {
+    final SqlOperatorFixture f = fixture()
+        .setFor(SqlLibraryOperators.CODE_POINTS_TO_BYTES, VM_FENNEL, VM_JAVA)
+        .withLibrary(SqlLibrary.BIG_QUERY);
+    f.checkFails("^code_points_to_bytes('abc')^",

Review Comment:
   Would you like to change the `'abc'` to an array literal?



##########
testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java:
##########
@@ -1804,6 +1804,28 @@ void testCastToBoolean(CastType castType, 
SqlOperatorFixture f) {
         consumer);
   }
 
+  @Test void testCodePointsToBytes() {
+    final SqlOperatorFixture f = fixture()
+        .setFor(SqlLibraryOperators.CODE_POINTS_TO_BYTES, VM_FENNEL, VM_JAVA)
+        .withLibrary(SqlLibrary.BIG_QUERY);
+    f.checkFails("^code_points_to_bytes('abc')^",
+        "Cannot apply 'CODE_POINTS_TO_BYTES' to arguments of type "
+            + "'CODE_POINTS_TO_BYTES\\(<CHAR\\(3\\)>\\)'\\. "
+            + "Supported form\\(s\\): 'CODE_POINTS_TO_BYTES\\(<ARRAY>\\)'", 
false);
+    f.checkFails("code_points_to_bytes(array[-1])",
+        "Input arguments of CODE_POINTS_TO_BYTES out of range: -1", true);
+    f.checkFails("code_points_to_bytes(array[2147483648, 1])",
+        "Input arguments of CODE_POINTS_TO_BYTES out of range: 2147483648", 
true);
+
+    f.checkString("code_points_to_bytes(array[65,66,67,68])", "41424344", 
"VARBINARY NOT NULL");

Review Comment:
   Minor comment for code format, I would use `array[65, 66, 67, 68]` instead 
`array[65,66,67,68]` for better code readability.



##########
site/_docs/reference.md:
##########
@@ -2681,6 +2681,7 @@ BigQuery's type system uses confusingly different names 
for types and functions:
 | b | CEIL(value)                                    | Similar to standard 
`CEIL(value)` except if *value* is an integer type, the return type is a double
 | m s | CHAR(integer)                                | Returns the character 
whose ASCII code is *integer* % 256, or null if *integer* &lt; 0
 | b o p | CHR(integer)                               | Returns the character 
whose UTF-8 code is *integer*
+| b | CODE_POINTS_TO_BYTES(integers)                 | Converts *integers*, an 
array of integers between 0 and 255 inclusive, throws error if any element is 
out of range

Review Comment:
   Maybe a small typo, `an array of integers` -> `an array of integer`



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to