This is an automated email from the ASF dual-hosted git repository.
xiong 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 71c161df81 [CALCITE-6831] Add ARRAY_SLICE function(enabled in Hive
Library)
71c161df81 is described below
commit 71c161df817d0093ccd97e8191c30bb68e38ff66
Author: xuyu <[email protected]>
AuthorDate: Thu Feb 13 20:13:38 2025 +0800
[CALCITE-6831] Add ARRAY_SLICE function(enabled in Hive Library)
---
.../calcite/adapter/enumerable/RexImpTable.java | 2 +
.../org/apache/calcite/runtime/SqlFunctions.java | 9 +++++
.../main/java/org/apache/calcite/sql/SqlKind.java | 4 ++
.../calcite/sql/fun/SqlLibraryOperators.java | 9 +++++
.../org/apache/calcite/util/BuiltInMethod.java | 1 +
site/_docs/reference.md | 1 +
.../org/apache/calcite/test/SqlOperatorTest.java | 43 ++++++++++++++++++++++
7 files changed, 69 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 da79c96c0f..d5b752dace 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
@@ -152,6 +152,7 @@
import static org.apache.calcite.sql.fun.SqlLibraryOperators.ARRAY_REPEAT;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.ARRAY_REVERSE;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.ARRAY_SIZE;
+import static org.apache.calcite.sql.fun.SqlLibraryOperators.ARRAY_SLICE;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.ARRAY_TO_STRING;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.ARRAY_UNION;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.ASIND;
@@ -1065,6 +1066,7 @@ void populate2() {
defineMethod(ARRAY_REPEAT, BuiltInMethod.ARRAY_REPEAT.method,
NullPolicy.NONE);
defineMethod(ARRAY_REVERSE, BuiltInMethod.ARRAY_REVERSE.method,
NullPolicy.STRICT);
defineMethod(ARRAY_SIZE, BuiltInMethod.COLLECTION_SIZE.method,
NullPolicy.STRICT);
+ defineMethod(ARRAY_SLICE, BuiltInMethod.ARRAY_SLICE.method,
NullPolicy.STRICT);
defineMethod(ARRAY_TO_STRING, BuiltInMethod.ARRAY_TO_STRING.method,
NullPolicy.STRICT);
defineMethod(ARRAY_UNION, BuiltInMethod.ARRAY_UNION.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 9fa031c313..5cef5efeb2 100644
--- a/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
+++ b/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
@@ -6524,6 +6524,15 @@ public static List reverse(List list) {
return list;
}
+ /** SQL {@code ARRAY_SLICE(array, start, length)} function. */
+ public static List arraySlice(List list, int start, int length) {
+ // return empty list if start/length are out of range of the array
+ if (start + length > list.size()) {
+ return Collections.emptyList();
+ }
+ return list.subList(start, start + length);
+ }
+
/** SQL {@code ARRAY_TO_STRING(array, delimiter)} function. */
public static String arrayToString(List list, String delimiter) {
return arrayToString(list, delimiter, null);
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlKind.java
b/core/src/main/java/org/apache/calcite/sql/SqlKind.java
index 84744b4c62..a870757ef7 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlKind.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlKind.java
@@ -830,6 +830,9 @@ public enum SqlKind {
/** {@code ARRAY_SIZE} function (Spark semantics). */
ARRAY_SIZE,
+ /** {@code ARRAY_SLICE} function (Hive semantics). */
+ ARRAY_SLICE,
+
/** {@code ARRAY_TO_STRING} function (BigQuery semantics). */
ARRAY_TO_STRING,
@@ -1824,6 +1827,7 @@ public SqlKind getFunctionKind() {
case ARRAY_REPEAT:
case ARRAY_REVERSE:
case ARRAY_SIZE:
+ case ARRAY_SLICE:
case ARRAY_TO_STRING:
case ARRAY_UNION:
case ARRAYS_OVERLAP:
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 c617bac014..fce4d0bdc4 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
@@ -1653,6 +1653,15 @@ private static RelDataType
arrayInsertReturnType(SqlOperatorBinding opBinding) {
ReturnTypes.INTEGER_NULLABLE,
OperandTypes.ARRAY);
+ /** The "ARRAY_SLICE(array, start, length)" function. */
+ @LibraryOperator(libraries = {HIVE})
+ public static final SqlFunction ARRAY_SLICE =
+ SqlBasicFunction.create(SqlKind.ARRAY_SLICE,
+ ReturnTypes.ARG0_NULLABLE,
+ OperandTypes.sequence(
+ "ARRAY_SLICE(ARRAY, INTEGER, INTEGER)",
+ OperandTypes.ARRAY, OperandTypes.INTEGER, OperandTypes.INTEGER));
+
/** The "ARRAY_UNION(array1, array2)" function. */
@LibraryOperator(libraries = {SPARK})
public static final SqlFunction ARRAY_UNION =
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 fbbbbc980d..c1f5d7e440 100644
--- a/core/src/main/java/org/apache/calcite/util/BuiltInMethod.java
+++ b/core/src/main/java/org/apache/calcite/util/BuiltInMethod.java
@@ -866,6 +866,7 @@ public enum BuiltInMethod {
ARRAY_INTERSECT(SqlFunctions.class, "arrayIntersect", List.class,
List.class),
ARRAY_UNION(SqlFunctions.class, "arrayUnion", List.class, List.class),
ARRAY_REVERSE(SqlFunctions.class, "reverse", List.class),
+ ARRAY_SLICE(SqlFunctions.class, "arraySlice", List.class, int.class,
int.class),
ARRAYS_OVERLAP(SqlFunctions.class, "arraysOverlap", List.class, List.class),
ARRAYS_ZIP(SqlFunctions.class, "arraysZip", List.class, List.class),
EXISTS(SqlFunctions.class, "exists", List.class, Function1.class),
diff --git a/site/_docs/reference.md b/site/_docs/reference.md
index 480a19e867..811cddc025 100644
--- a/site/_docs/reference.md
+++ b/site/_docs/reference.md
@@ -2800,6 +2800,7 @@ ### Dialect-specific Operators
| s | ARRAY_REPEAT(element, count) | Returns the array
containing element count times.
| b | ARRAY_REVERSE(array) | Reverses elements of
*array*
| s | ARRAY_SIZE(array) | Synonym for
`CARDINALITY`
+| h | ARRAY_SLICE(array, start, length) | Returns the subset or
range of elements.
| b | ARRAY_TO_STRING(array, delimiter [, nullText ])| Returns a concatenation
of the elements in *array* as a STRING and take *delimiter* as the delimiter.
If the *nullText* parameter is used, the function replaces any `NULL` values in
the array with the value of *nullText*. If the *nullText* parameter is not
used, the function omits the `NULL` value and its preceding delimiter. Returns
`NULL` if any argument is `NULL`
| s | ARRAY_UNION(array1, array2) | Returns an array of the
elements in the union of *array1* and *array2*, without duplicates
| s | ARRAYS_OVERLAP(array1, array2) | Returns true if *array1
contains at least a non-null element present also in *array2*. If the arrays
have no common element and they are both non-empty and either of them contains
a null element null is returned, false otherwise
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 a76d9f3065..9bd07895d5 100644
--- a/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
+++ b/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
@@ -8204,6 +8204,49 @@ void checkRegexpExtract(SqlOperatorFixture f0,
FunctionAlias functionAlias) {
"DECIMAL(19, 0)");
}
+ /** Test case for
+ * <a
href="https://issues.apache.org/jira/browse/CALCITE-6831">[CALCITE-6831]
+ * Add ARRAR_SLICE function (enabled in Hive library)</a>. */
+ @Test void testArraySlice() {
+ SqlOperatorFixture f0 = fixture().setFor(SqlLibraryOperators.ARRAY_SLICE);
+ final List<SqlLibrary> libraries =
+ ImmutableList.of(SqlLibrary.HIVE);
+ final Consumer<SqlOperatorFixture> consumer = f -> {
+ f.checkString("array_slice(array[1,2,3], 1, 2)",
+ "[2, 3]",
+ "INTEGER NOT NULL ARRAY NOT NULL");
+ f.checkString("array_slice(array[1,null,3], 1, 2)",
+ "[null, 3]",
+ "INTEGER ARRAY NOT NULL");
+ f.checkString("array_slice(array[1,2,3], 1, 10)",
+ "[]",
+ "INTEGER NOT NULL ARRAY NOT NULL");
+ f.checkString("array_slice(array['a','b','c','d'], 1, 3)",
+ "[b, c, d]",
+ "CHAR(1) NOT NULL ARRAY NOT NULL");
+ f.checkString("array_slice(array[null,null,null], 1, 2)",
+ "[null, null]",
+ "NULL ARRAY NOT NULL");
+ f.checkString("array_slice(array[1,2.2,3], 1, 2)",
+ "[2.2, 3.0]",
+ "DECIMAL(11, 1) NOT NULL ARRAY NOT NULL");
+ f.checkString("array_slice(array[1,cast(2 as double),3], 1, 2)",
+ "[2.0, 3.0]",
+ "DOUBLE NOT NULL ARRAY NOT NULL");
+ f.checkString("array_slice(array[1,2.2,3,null], 1, 3)",
+ "[2.2, 3.0, null]",
+ "DECIMAL(11, 1) ARRAY NOT NULL");
+ f.checkFails("array_slice(^array[1,2.2,'c']^, 1, 2)",
+ "Parameters must be of the same type", false);
+ f.checkFails("array_slice(array[null,null,null], -1, 2)",
+ "fromIndex = -1", true);
+ f.checkNull("array_slice(array[1,2,3], null, 2)");
+ f.checkNull("array_slice(array[1,2,3], null, null)");
+ f.checkNull("array_slice(array[1,2,3], 1, null)");
+ };
+ f0.forEachLibrary(libraries, consumer);
+ }
+
/** Tests {@code ARRAY_POSITION} function from Spark. */
@Test void testArrayPositionFunc() {
final SqlOperatorFixture f0 = fixture();