This is an automated email from the ASF dual-hosted git repository.

rubenql pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git


The following commit(s) were added to refs/heads/main by this push:
     new febd06b2cc [CALCITE-5642] Add SHA256, SHA512 functions (enabled in 
BigQuery and PostgreSQL libraries)
febd06b2cc is described below

commit febd06b2cc7815895c4d6aafc3712a63fe1c335f
Author: zoudan <zou...@bytedance.com>
AuthorDate: Thu Apr 13 22:38:43 2023 +0800

    [CALCITE-5642] Add SHA256, SHA512 functions (enabled in BigQuery and 
PostgreSQL libraries)
---
 .../calcite/adapter/enumerable/RexImpTable.java    |  4 ++
 .../org/apache/calcite/runtime/SqlFunctions.java   | 20 ++++++++
 .../calcite/sql/fun/SqlLibraryOperators.java       | 16 ++++++
 .../org/apache/calcite/util/BuiltInMethod.java     |  2 +
 .../org/apache/calcite/test/SqlFunctionsTest.java  | 40 +++++++++++++++
 site/_docs/reference.md                            |  2 +
 .../org/apache/calcite/test/SqlOperatorTest.java   | 58 ++++++++++++++++++++++
 7 files changed, 142 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 02525cd38f..92b874ee11 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
@@ -170,6 +170,8 @@ import static 
org.apache.calcite.sql.fun.SqlLibraryOperators.RLIKE;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.RPAD;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.SAFE_CAST;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.SHA1;
+import static org.apache.calcite.sql.fun.SqlLibraryOperators.SHA256;
+import static org.apache.calcite.sql.fun.SqlLibraryOperators.SHA512;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.SINH;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.SOUNDEX;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.SPACE;
@@ -432,6 +434,8 @@ public class RexImpTable {
       defineMethod(FROM_BASE64, BuiltInMethod.FROM_BASE64.method, 
NullPolicy.STRICT);
       defineMethod(MD5, BuiltInMethod.MD5.method, NullPolicy.STRICT);
       defineMethod(SHA1, BuiltInMethod.SHA1.method, NullPolicy.STRICT);
+      defineMethod(SHA256, BuiltInMethod.SHA256.method, NullPolicy.STRICT);
+      defineMethod(SHA512, BuiltInMethod.SHA512.method, NullPolicy.STRICT);
       defineMethod(SUBSTRING, BuiltInMethod.SUBSTRING.method, 
NullPolicy.STRICT);
       defineMethod(LEFT, BuiltInMethod.LEFT.method, NullPolicy.ANY);
       defineMethod(RIGHT, BuiltInMethod.RIGHT.method, NullPolicy.ANY);
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 cfd462ceaf..8f726822fd 100644
--- a/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
+++ b/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
@@ -273,6 +273,26 @@ public class SqlFunctions {
     return DigestUtils.sha1Hex(string.getBytes());
   }
 
+  /** SQL SHA256(string) function. */
+  public static String sha256(String string)  {
+    return DigestUtils.sha256Hex(string.getBytes(UTF_8));
+  }
+
+  /** SQL SHA256(string) function for binary string. */
+  public static String sha256(ByteString string)  {
+    return DigestUtils.sha256Hex(string.getBytes());
+  }
+
+  /** SQL SHA512(string) function. */
+  public static String sha512(String string)  {
+    return DigestUtils.sha512Hex(string.getBytes(UTF_8));
+  }
+
+  /** SQL SHA512(string) function for binary string. */
+  public static String sha512(ByteString string)  {
+    return DigestUtils.sha512Hex(string.getBytes());
+  }
+
   /** SQL {@code REGEXP_REPLACE} function with 3 arguments. */
   public static String regexpReplace(String s, String regex,
       String replacement) {
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 c090845f58..ed3ebd5ff8 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
@@ -1188,6 +1188,22 @@ public abstract class SqlLibraryOperators {
           OperandTypes.STRING.or(OperandTypes.BINARY),
           SqlFunctionCategory.STRING);
 
+  @LibraryOperator(libraries = {BIG_QUERY, POSTGRESQL})
+  public static final SqlFunction SHA256 =
+      SqlBasicFunction.create("SHA256",
+          ReturnTypes.explicit(SqlTypeName.VARCHAR)
+              .andThen(SqlTypeTransforms.TO_NULLABLE),
+          OperandTypes.STRING.or(OperandTypes.BINARY),
+          SqlFunctionCategory.STRING);
+
+  @LibraryOperator(libraries = {BIG_QUERY, POSTGRESQL})
+  public static final SqlFunction SHA512 =
+      SqlBasicFunction.create("SHA512",
+          ReturnTypes.explicit(SqlTypeName.VARCHAR)
+              .andThen(SqlTypeTransforms.TO_NULLABLE),
+          OperandTypes.STRING.or(OperandTypes.BINARY),
+          SqlFunctionCategory.STRING);
+
   /** The "LOG(value [, value2])" function.
    *
    * @see SqlStdOperatorTable#LN
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 251cdcfce3..afc56eb0d0 100644
--- a/core/src/main/java/org/apache/calcite/util/BuiltInMethod.java
+++ b/core/src/main/java/org/apache/calcite/util/BuiltInMethod.java
@@ -361,6 +361,8 @@ public enum BuiltInMethod {
   FROM_BASE64(SqlFunctions.class, "fromBase64", String.class),
   MD5(SqlFunctions.class, "md5", String.class),
   SHA1(SqlFunctions.class, "sha1", String.class),
+  SHA256(SqlFunctions.class, "sha256", String.class),
+  SHA512(SqlFunctions.class, "sha512", String.class),
   THROW_UNLESS(SqlFunctions.class, "throwUnless", boolean.class, String.class),
   COMPRESS(CompressionFunctions.class, "compress", String.class),
   EXTRACT_VALUE(XmlFunctions.class, "extractValue", String.class, 
String.class),
diff --git a/core/src/test/java/org/apache/calcite/test/SqlFunctionsTest.java 
b/core/src/test/java/org/apache/calcite/test/SqlFunctionsTest.java
index 700b2a5944..2d44371722 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlFunctionsTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlFunctionsTest.java
@@ -57,6 +57,8 @@ import static 
org.apache.calcite.runtime.SqlFunctions.posixRegex;
 import static org.apache.calcite.runtime.SqlFunctions.regexpReplace;
 import static org.apache.calcite.runtime.SqlFunctions.rtrim;
 import static org.apache.calcite.runtime.SqlFunctions.sha1;
+import static org.apache.calcite.runtime.SqlFunctions.sha256;
+import static org.apache.calcite.runtime.SqlFunctions.sha512;
 import static org.apache.calcite.runtime.SqlFunctions.toBase64;
 import static org.apache.calcite.runtime.SqlFunctions.toChar;
 import static org.apache.calcite.runtime.SqlFunctions.toInt;
@@ -1015,6 +1017,44 @@ class SqlFunctionsTest {
     }
   }
 
+  @Test void testSha256() {
+    
assertThat("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+        is(sha256("")));
+    
assertThat("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+        is(sha256(ByteString.of("", 16))));
+    
assertThat("a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e",
+        is(sha256("Hello World")));
+    
assertThat("a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e",
+        is(sha256(new ByteString("Hello World".getBytes(UTF_8)))));
+    try {
+      String o = sha256((String) null);
+      fail("Expected NPE, got " + o);
+    } catch (NullPointerException e) {
+      // ok
+    }
+  }
+
+  @Test void testSha512() {
+    
assertThat("cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5"
+            + "d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e",
+        is(sha512("")));
+    
assertThat("cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5"
+            + "d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e",
+        is(sha512(ByteString.of("", 16))));
+    
assertThat("2c74fd17edafd80e8447b0d46741ee243b7eb74dd2149a0ab1b9246fb30382f27e853d858"
+            + "5719e0e67cbda0daa8f51671064615d645ae27acb15bfb1447f459b",
+        is(sha512("Hello World")));
+    
assertThat("2c74fd17edafd80e8447b0d46741ee243b7eb74dd2149a0ab1b9246fb30382f27e853d858"
+            + "5719e0e67cbda0daa8f51671064615d645ae27acb15bfb1447f459b",
+        is(sha512(new ByteString("Hello World".getBytes(UTF_8)))));
+    try {
+      String o = sha512((String) null);
+      fail("Expected NPE, got " + o);
+    } catch (NullPointerException e) {
+      // ok
+    }
+  }
+
   /**
    * Tests that a date in the local time zone converts to a Unix timestamp in
    * UTC.
diff --git a/site/_docs/reference.md b/site/_docs/reference.md
index 5507fbe476..d90178f42c 100644
--- a/site/_docs/reference.md
+++ b/site/_docs/reference.md
@@ -2727,6 +2727,8 @@ BigQuery's type system uses confusingly different names 
for types and functions:
 | b o | RTRIM(string)                                | Returns *string* with 
all blanks removed from the end
 | b | SAFE_CAST(value AS type)                       | Converts *value* to 
*type*, returning NULL if conversion fails
 | b m p | SHA1(string)                               | Calculates a SHA-1 hash 
value of *string* and returns it as a hex string
+| b p | SHA256(string)                               | Calculates a SHA-256 
hash value of *string* and returns it as a hex string
+| b p | SHA512(string)                               | Calculates a SHA-512 
hash value of *string* and returns it as a hex string
 | * | SINH(numeric)                                  | Returns the hyperbolic 
sine of *numeric*
 | b m o p | SOUNDEX(string)                          | Returns the phonetic 
representation of *string*; throws if *string* is encoded with multi-byte 
encoding such as UTF-8
 | m | SPACE(integer)                                 | Returns a string of 
*integer* spaces; returns an empty string if *integer* is less than 1
diff --git a/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java 
b/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
index 9d4c2a424a..43b322a19f 100644
--- a/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
+++ b/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.calcite.test;
 
+import org.apache.calcite.avatica.util.ByteString;
 import org.apache.calcite.avatica.util.DateTimeUtils;
 import org.apache.calcite.config.CalciteConnectionProperty;
 import org.apache.calcite.linq4j.Linq4j;
@@ -135,6 +136,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.fail;
 import static org.junit.jupiter.api.Assumptions.assumeTrue;
 
+import static java.nio.charset.StandardCharsets.UTF_8;
+
 /**
  * Contains unit tests for all operators. Each of the methods is named after an
  * operator.
@@ -3899,6 +3902,61 @@ public class SqlOperatorTest {
     f0.forEachLibrary(libraries, consumer);
   }
 
+  @Test void testSha256() {
+    final SqlOperatorFixture f0 = fixture().setFor(SqlLibraryOperators.SHA1);
+    f0.checkFails("^sha256(x'')^",
+        "No match found for function signature SHA256\\(<BINARY>\\)",
+        false);
+
+    final List<SqlLibrary> libraries =
+        ImmutableList.of(SqlLibrary.BIG_QUERY, SqlLibrary.POSTGRESQL);
+    final Consumer<SqlOperatorFixture> consumer = f -> {
+      f.checkString("sha256('')",
+          "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+          "VARCHAR NOT NULL");
+      f.checkString("sha256(x'')",
+          "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+          "VARCHAR NOT NULL");
+      f.checkString("sha256('Hello World')",
+          "a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e",
+          "VARCHAR NOT NULL");
+      f.checkString("sha256(x'48656c6c6f20576f726c64')",
+          "a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e",
+          "VARCHAR NOT NULL");
+    };
+    f0.forEachLibrary(libraries, consumer);
+  }
+
+  @Test void testSha512() {
+    final SqlOperatorFixture f0 = fixture().setFor(SqlLibraryOperators.SHA1);
+    f0.checkFails("^sha512(x'')^",
+        "No match found for function signature SHA512\\(<BINARY>\\)",
+        false);
+
+    final List<SqlLibrary> libraries =
+        ImmutableList.of(SqlLibrary.BIG_QUERY, SqlLibrary.POSTGRESQL);
+    final Consumer<SqlOperatorFixture> consumer = f -> {
+      f.checkString("sha512('')",
+          
"cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2"
+              + "b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e",
+          "VARCHAR NOT NULL");
+      f.checkString("sha512(x'')",
+          
"cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b"
+              + "0ff8318d2877eec2f63b931bd47417a81a538327af927da3e",
+          "VARCHAR NOT NULL");
+      f.checkString("sha512('Hello World')",
+          
"2c74fd17edafd80e8447b0d46741ee243b7eb74dd2149a0ab1b9246fb30382f27e853d8585719e0"
+              + "e67cbda0daa8f51671064615d645ae27acb15bfb1447f459b",
+          "VARCHAR NOT NULL");
+      String hexString = new ByteString("Hello 
World".getBytes(UTF_8)).toString();
+      f.checkString("sha512(x'" + hexString + "')",
+          
"2c74fd17edafd80e8447b0d46741ee243b7eb74dd2149a0ab1b9246fb30382f27e853d8585719e0"
+              + "e67cbda0daa8f51671064615d645ae27acb15bfb1447f459b",
+          "VARCHAR NOT NULL");
+    };
+    f0.forEachLibrary(libraries, consumer);
+  }
+
   @Test void testRepeatFunc() {
     final SqlOperatorFixture f0 = fixture().setFor(SqlLibraryOperators.REPEAT);
     f0.checkFails("^repeat('a', -100)^",

Reply via email to