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

zhehu 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 9f531455f1 [CALCITE-6812] Support base64 and unbase64 functions for 
Hive
9f531455f1 is described below

commit 9f531455f1de60b56b684219ef92080e16d04870
Author: xuyu <[email protected]>
AuthorDate: Sat Feb 1 17:19:22 2025 +0800

    [CALCITE-6812] Support base64 and unbase64 functions for Hive
---
 .../calcite/adapter/enumerable/RexImpTable.java    |  4 +++
 .../org/apache/calcite/runtime/SqlFunctions.java   |  6 ++--
 .../calcite/sql/fun/SqlLibraryOperators.java       | 13 ++++++++
 site/_docs/reference.md                            |  4 ++-
 .../org/apache/calcite/test/SqlOperatorTest.java   | 38 ++++++++++++++++++++++
 5 files changed, 61 insertions(+), 4 deletions(-)

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 88166ba14a..ebc9c6d9da 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
@@ -158,6 +158,7 @@
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.ASINH;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.ATAND;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.ATANH;
+import static org.apache.calcite.sql.fun.SqlLibraryOperators.BASE64;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.BITAND_AGG;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.BITOR_AGG;
 import static 
org.apache.calcite.sql.fun.SqlLibraryOperators.BIT_COUNT_BIG_QUERY;
@@ -335,6 +336,7 @@
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.UNIX_MICROS;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.UNIX_MILLIS;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.UNIX_SECONDS;
+import static org.apache.calcite.sql.fun.SqlLibraryOperators.UN_BASE64;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.URL_DECODE;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.URL_ENCODE;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.XML_TRANSFORM;
@@ -685,6 +687,8 @@ void populate1() {
       defineMethod(INITCAP, BuiltInMethod.INITCAP.method, NullPolicy.STRICT);
       defineMethod(TO_BASE64, BuiltInMethod.TO_BASE64.method, 
NullPolicy.STRICT);
       defineMethod(FROM_BASE64, BuiltInMethod.FROM_BASE64.method, 
NullPolicy.STRICT);
+      defineMethod(BASE64, BuiltInMethod.TO_BASE64.method, NullPolicy.STRICT);
+      defineMethod(UN_BASE64, BuiltInMethod.FROM_BASE64.method, 
NullPolicy.STRICT);
       defineMethod(TO_BASE32, BuiltInMethod.TO_BASE32.method, 
NullPolicy.STRICT);
       defineMethod(FROM_BASE32, BuiltInMethod.FROM_BASE32.method, 
NullPolicy.STRICT);
       defineMethod(HEX, BuiltInMethod.HEX.method, NullPolicy.STRICT);
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 2b5f9f0dee..eeee51eecd 100644
--- a/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
+++ b/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
@@ -300,12 +300,12 @@ public static ByteString uuidToBinary(UUID uuid) {
     return new ByteString(dest);
   }
 
-  /** SQL TO_BASE64(string) function. */
+  /** SQL TO_BASE64(string)/BASE64(string) function. */
   public static String toBase64(String string) {
     return toBase64_(string.getBytes(UTF_8));
   }
 
-  /** SQL TO_BASE64(string) function for binary string. */
+  /** SQL TO_BASE64(string)/BASE64(string) function for binary string. */
   public static String toBase64(ByteString string) {
     return toBase64_(string.getBytes());
   }
@@ -320,7 +320,7 @@ private static String toBase64_(byte[] bytes) {
     return str.substring(0, str.length() - 1);
   }
 
-  /** SQL FROM_BASE64(string) function. */
+  /** SQL FROM_BASE64(string)/UNBASE64(string) function. */
   public static @Nullable ByteString fromBase64(String base64) {
     try {
       base64 = FROM_BASE64_REGEXP.matcher(base64).replaceAll("");
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 14ea74815f..b3fa3585aa 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
@@ -1855,6 +1855,19 @@ private static RelDataType 
deriveTypeMapFromEntries(SqlOperatorBinding opBinding
           OperandTypes.STRING.or(OperandTypes.BINARY),
           SqlFunctionCategory.STRING);
 
+  @LibraryOperator(libraries = {HIVE})
+  public static final SqlFunction BASE64 =
+      SqlBasicFunction.create("BASE64",
+          ReturnTypes.VARCHAR_NULLABLE,
+          OperandTypes.STRING.or(OperandTypes.BINARY),
+          SqlFunctionCategory.STRING);
+
+  @LibraryOperator(libraries = {HIVE})
+  public static final SqlFunction UN_BASE64 =
+      SqlBasicFunction.create("UNBASE64",
+          ReturnTypes.VARBINARY_FORCE_NULLABLE,
+          OperandTypes.STRING, SqlFunctionCategory.STRING);
+
   @LibraryOperator(libraries = {BIG_QUERY})
   public static final SqlFunction FROM_BASE32 =
       SqlBasicFunction.create("FROM_BASE32",
diff --git a/site/_docs/reference.md b/site/_docs/reference.md
index 2da0234810..2fd932e57f 100644
--- a/site/_docs/reference.md
+++ b/site/_docs/reference.md
@@ -2922,7 +2922,9 @@ ### Dialect-specific Operators
 | b | FROM_BASE32(string)                            | Returns the decoded 
result of a base-32 *string* as a string
 | m | TO_BASE64(string)                              | Converts the *string* 
to base-64 encoded form and returns a encoded string
 | b m | FROM_BASE64(string)                          | Returns the decoded 
result of a base-64 *string* as a string. If the input argument is an invalid 
base-64 *string* the function returns `NULL`
-| h s | HEX(string)                                   | Converts *string* into 
a hexadecimal varchar
+| h | BASE64(string)                                 | Converts the *string* 
to base-64 encoded form and returns a encoded string
+| h | UNBASE64(string)                               | Returns the decoded 
result of a base-64 *string* as a string. If the input argument is an invalid 
base-64 *string* the function returns `NULL`
+| h s | HEX(string)                                  | Converts *string* into 
a hexadecimal varchar
 | b | TO_HEX(binary)                                 | Converts *binary* into 
a hexadecimal varchar
 | b | FROM_HEX(varchar)                              | Converts a 
hexadecimal-encoded *varchar* into bytes
 | b o p r s h | LTRIM(string)                        | Returns *string* with 
all blanks removed from the start
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 f11bf01a12..dab42ffdac 100644
--- a/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
+++ b/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
@@ -5173,6 +5173,44 @@ void testBitGetFunc(SqlOperatorFixture f, String 
functionName) {
     f.checkString("to_base64(x'61')", "YQ==", "VARCHAR NOT NULL");
   }
 
+  /** Test case for
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-6812";>[CALCITE-6812]
+   * Add base64 function (enabled in Hive library)</a>. */
+  @Test void testBase64() {
+    final SqlOperatorFixture f = fixture().withLibrary(SqlLibrary.HIVE);
+    f.setFor(SqlLibraryOperators.BASE64);
+    f.checkString("base64(cast('a' as binary))", "YQ==", "VARCHAR NOT NULL");
+    f.checkString("base64('')", "", "VARCHAR NOT NULL");
+    f.checkNull("base64(null)");
+    f.checkString("base64('This is a test String.')",
+        "VGhpcyBpcyBhIHRlc3QgU3RyaW5nLg==",
+        "VARCHAR NOT NULL");
+  }
+
+  @Test void testUnBase64() {
+    final SqlOperatorFixture f0 = fixture()
+        .setFor(SqlLibraryOperators.UN_BASE64);
+    final Consumer<SqlOperatorFixture> consumer = f -> {
+      f.checkString("unbase64('VGhpcyBpcyBhIHRlc3QgU3RyaW5nLg==')",
+          "546869732069732061207465737420537472696e672e",
+          "VARBINARY");
+      f.checkString("unbase64('VGhpcyBpcyBhIHRlc\t3QgU3RyaW5nLg==')",
+          "546869732069732061207465737420537472696e672e",
+          "VARBINARY");
+      f.checkString("unbase64('VGhpcyBpcyBhIHRlc\t3QgU3\nRyaW5nLg==')",
+          "546869732069732061207465737420537472696e672e",
+          "VARBINARY");
+      f.checkString("unbase64('VGhpcyB  pcyBhIHRlc3Qg\tU3Ry\naW5nLg==')",
+          "546869732069732061207465737420537472696e672e",
+          "VARBINARY");
+      f.checkNull("unbase64('-1')");
+      f.checkNull("unbase64('-100')");
+      f.checkNull("unbase64(null)");
+    };
+    f0.forEachLibrary(list(SqlLibrary.HIVE), consumer);
+
+  }
+
   @Test void testToChar() {
     final SqlOperatorFixture f0 = 
fixture().setFor(SqlLibraryOperators.TO_CHAR);
     final Consumer<SqlOperatorFixture> consumer = f -> {

Reply via email to