Skip to content

Commit

Permalink
[CALCITE-6805] Support hex and unhex for Hive and Spark Libaray
Browse files Browse the repository at this point in the history
  • Loading branch information
xuzifu666 committed Jan 29, 2025
1 parent d83122b commit 97f7e9b
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@
import static org.apache.calcite.sql.fun.SqlLibraryOperators.FROM_BASE64;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.FROM_HEX;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.GETBIT;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.HEX;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.ILIKE;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.IS_INF;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.IS_NAN;
Expand Down Expand Up @@ -330,6 +331,7 @@
import static org.apache.calcite.sql.fun.SqlLibraryOperators.TRANSLATE3;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.TRUNC_BIG_QUERY;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.TRY_CAST;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.UNHEX;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.UNIX_DATE;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.UNIX_MICROS;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.UNIX_MILLIS;
Expand Down Expand Up @@ -686,6 +688,8 @@ void populate1() {
defineMethod(FROM_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);
defineMethod(UNHEX, BuiltInMethod.UNHEX.method, NullPolicy.STRICT);
defineMethod(TO_HEX, BuiltInMethod.TO_HEX.method, NullPolicy.STRICT);
defineMethod(FROM_HEX, BuiltInMethod.FROM_HEX.method, NullPolicy.STRICT);
defineMethod(MD5, BuiltInMethod.MD5.method, NullPolicy.STRICT);
Expand Down
16 changes: 16 additions & 0 deletions core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,22 @@ public static ByteString fromHex(String hex) {
}
}

/** SQL HEX(varchar) function. */
public static String hex(String value) {
return Hex.encodeHexString(value.getBytes(UTF_8));
}

/** SQL UNHEX(varchar) function. */
public static String unhex(String value) {
try {
//CHECKSTYLE: IGNORE 1
return new String(Hex.decodeHex(value), UTF_8);
} catch (DecoderException e) {
throw new IllegalArgumentException(
String.format(Locale.ROOT, "Failed to decode hex string: %s", value), e);
}
}

/** SQL TO_HEX(binary) function. */
public static String toHex(ByteString byteString) {
return Hex.encodeHexString(byteString.getBytes());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1890,6 +1890,26 @@ private static RelDataType deriveTypeMapFromEntries(SqlOperatorBinding opBinding
OperandTypes.BINARY,
SqlFunctionCategory.STRING);

/**
* The "HEX(string)" function; converts {@code string} into a hexadecimal varchar.
*/
@LibraryOperator(libraries = {HIVE, SPARK})
public static final SqlFunction HEX =
SqlBasicFunction.create("HEX",
ReturnTypes.VARCHAR_NULLABLE,
OperandTypes.CHARACTER,
SqlFunctionCategory.STRING);

/**
* The "UNHEX(string)" function; converts {@code string} into a hexadecimal varchar.
*/
@LibraryOperator(libraries = {HIVE, SPARK})
public static final SqlFunction UNHEX =
SqlBasicFunction.create("UNHEX",
ReturnTypes.VARCHAR_NULLABLE,
OperandTypes.CHARACTER,
SqlFunctionCategory.STRING);

/** The "FORMAT_NUMBER(value, decimalOrFormat)" function. */
@LibraryOperator(libraries = {HIVE, SPARK})
public static final SqlFunction FORMAT_NUMBER =
Expand Down
2 changes: 2 additions & 0 deletions core/src/main/java/org/apache/calcite/util/BuiltInMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,8 @@ public enum BuiltInMethod {
FROM_BASE64(SqlFunctions.class, "fromBase64", String.class),
TO_BASE32(SqlFunctions.class, "toBase32", String.class),
FROM_BASE32(SqlFunctions.class, "fromBase32", String.class),
HEX(SqlFunctions.class, "hex", String.class),
UNHEX(SqlFunctions.class, "unhex", String.class),
TO_HEX(SqlFunctions.class, "toHex", ByteString.class),
FROM_HEX(SqlFunctions.class, "fromHex", String.class),
MD5(SqlFunctions.class, "md5", String.class),
Expand Down
2 changes: 2 additions & 0 deletions site/_docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -2922,6 +2922,8 @@ In the following:
| 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 s | UNHEX(string) | Converts a hexadecimal-encoded *varchar* into 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 | LTRIM(string) | Returns *string* with all blanks removed from the start
Expand Down
32 changes: 32 additions & 0 deletions testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5823,6 +5823,38 @@ void testBitGetFunc(SqlOperatorFixture f, String functionName) {
f0.forEachLibrary(libraries, consumer);
}

@Test void testHex() {
SqlOperatorFixture sqlOperatorFixture = fixture();
final SqlOperatorFixture f0 = sqlOperatorFixture.setFor(SqlLibraryOperators.HEX);
f0.checkFails("^hex('')^",
"No match found for function signature HEX\\(<CHARACTER>\\)",
false);
final Consumer<SqlOperatorFixture> consumer = f -> {
f.checkString("hex('abc')",
"616263",
"VARCHAR NOT NULL");
f.checkString("hex('')", "", "VARCHAR NOT NULL");
f.checkNull("hex(cast(null as varbinary))");
};
f0.forEachLibrary(list(SqlLibrary.HIVE, SqlLibrary.SPARK), consumer);
}

@Test void testUnHex() {
SqlOperatorFixture sqlOperatorFixture = fixture();
final SqlOperatorFixture f0 = sqlOperatorFixture.setFor(SqlLibraryOperators.UNHEX);
f0.checkFails("^unhex('')^",
"No match found for function signature UNHEX\\(<CHARACTER>\\)",
false);
final Consumer<SqlOperatorFixture> consumer = f -> {
f.checkString("unhex('616263')",
"abc",
"VARCHAR NOT NULL");
f.checkString("unhex('')", "", "VARCHAR NOT NULL");
f.checkNull("unhex(cast(null as varbinary))");
};
f0.forEachLibrary(list(SqlLibrary.HIVE, SqlLibrary.SPARK), consumer);
}

@Test void testToHex() {
final SqlOperatorFixture f0 = fixture().setFor(SqlLibraryOperators.TO_HEX);
f0.checkFails("^to_hex(x'')^",
Expand Down

0 comments on commit 97f7e9b

Please sign in to comment.