This is an automated email from the ASF dual-hosted git repository.
jiajunxie 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 48f51ea5d9 [CALCITE-5700] Add ARRAY_SIZE, ARRAY_REPEAT function
(enabled in Spark library).
48f51ea5d9 is described below
commit 48f51ea5d9443fb11e070eea094bf551c8ff22fc
Author: yongen.ly <[email protected]>
AuthorDate: Fri May 12 15:06:00 2023 +0800
[CALCITE-5700] Add ARRAY_SIZE, ARRAY_REPEAT function (enabled in Spark
library).
---
.../calcite/adapter/enumerable/RexImpTable.java | 4 +++
.../org/apache/calcite/runtime/SqlFunctions.java | 12 ++++++++
.../main/java/org/apache/calcite/sql/SqlKind.java | 6 ++++
.../calcite/sql/fun/SqlLibraryOperators.java | 16 ++++++++++
.../org/apache/calcite/util/BuiltInMethod.java | 1 +
site/_docs/reference.md | 2 ++
.../org/apache/calcite/test/SqlOperatorTest.java | 36 ++++++++++++++++++++++
7 files changed, 77 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 bf835c0d18..16a9df8632 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
@@ -118,7 +118,9 @@ import static
org.apache.calcite.sql.fun.SqlLibraryOperators.ARRAY_CONCAT;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.ARRAY_CONCAT_AGG;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.ARRAY_DISTINCT;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.ARRAY_LENGTH;
+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.BOOL_AND;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.BOOL_OR;
import static org.apache.calcite.sql.fun.SqlLibraryOperators.CHAR;
@@ -671,7 +673,9 @@ public class RexImpTable {
defineMethod(STRUCT_ACCESS, BuiltInMethod.STRUCT_ACCESS.method,
NullPolicy.ANY);
defineMethod(MEMBER_OF, BuiltInMethod.MEMBER_OF.method, NullPolicy.NONE);
defineMethod(ARRAY_DISTINCT, BuiltInMethod.ARRAY_DISTINCT.method,
NullPolicy.STRICT);
+ 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);
map.put(ARRAY_CONCAT, new ArrayConcatImplementor());
final MethodImplementor isEmptyImplementor =
new MethodImplementor(BuiltInMethod.IS_EMPTY.method, NullPolicy.NONE,
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 75ced53c9a..52c2da6878 100644
--- a/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
+++ b/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
@@ -3797,6 +3797,18 @@ public class SqlFunctions {
return new ArrayList<>(result);
}
+ /** Support the ARRAY_REPEAT function. */
+ public static @Nullable List<Object> repeat(Object element, Object count) {
+ if (count == null) {
+ return null;
+ }
+ int numberOfElement = (int) count;
+ if (numberOfElement < 0) {
+ numberOfElement = 0;
+ }
+ return Collections.nCopies(numberOfElement, element);
+ }
+
/** Support the SLICE function. */
public static List slice(List list) {
List result = new ArrayList(list.size());
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 44cd4cd02d..9104af350c 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlKind.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlKind.java
@@ -683,9 +683,15 @@ public enum SqlKind {
/** {@code ARRAY_DISTINCT} function (Spark semantics). */
ARRAY_DISTINCT,
+ /** {@code ARRAY_REPEAT} function (Spark semantics). */
+ ARRAY_REPEAT,
+
/** {@code ARRAY_REVERSE} function (BigQuery semantics). */
ARRAY_REVERSE,
+ /** {@code ARRAY_SIZE} function (Spark semantics). */
+ ARRAY_SIZE,
+
/** {@code REVERSE} function (SQL Server, MySQL). */
REVERSE,
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 7eedae2918..4ae48490e5 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
@@ -858,6 +858,15 @@ public abstract class SqlLibraryOperators {
ReturnTypes.INTEGER_NULLABLE,
OperandTypes.ARRAY);
+ /** The "ARRAY_REPEAT(element, count)" function. */
+ @LibraryOperator(libraries = {SPARK})
+ public static final SqlFunction ARRAY_REPEAT =
+ SqlBasicFunction.create(SqlKind.ARRAY_REPEAT,
+ ReturnTypes.TO_ARRAY,
+ OperandTypes.sequence(
+ "ARRAY_REPEAT(ANY, INTEGER)",
+ OperandTypes.ANY, OperandTypes.typeName(SqlTypeName.INTEGER)));
+
/** The "ARRAY_REVERSE(array)" function. */
@LibraryOperator(libraries = {BIG_QUERY})
public static final SqlFunction ARRAY_REVERSE =
@@ -865,6 +874,13 @@ public abstract class SqlLibraryOperators {
ReturnTypes.ARG0_NULLABLE,
OperandTypes.ARRAY);
+ /** The "ARRAY_SIZE(array)" function. */
+ @LibraryOperator(libraries = {SPARK})
+ public static final SqlFunction ARRAY_SIZE =
+ SqlBasicFunction.create(SqlKind.ARRAY_SIZE,
+ ReturnTypes.INTEGER_NULLABLE,
+ OperandTypes.ARRAY);
+
/** The "ARRAY_CONCAT(array [, array]*)" function. */
@LibraryOperator(libraries = {BIG_QUERY})
public static final SqlFunction ARRAY_CONCAT =
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 90eb4df0fc..13bc6ec051 100644
--- a/core/src/main/java/org/apache/calcite/util/BuiltInMethod.java
+++ b/core/src/main/java/org/apache/calcite/util/BuiltInMethod.java
@@ -629,6 +629,7 @@ public enum BuiltInMethod {
SUBMULTISET_OF(SqlFunctions.class, "submultisetOf", Collection.class,
Collection.class),
ARRAY_DISTINCT(SqlFunctions.class, "distinct", List.class),
+ ARRAY_REPEAT(SqlFunctions.class, "repeat", Object.class, Integer.class),
ARRAY_REVERSE(SqlFunctions.class, "reverse", List.class),
SELECTIVITY(Selectivity.class, "getSelectivity", RexNode.class),
UNIQUE_KEYS(UniqueKeys.class, "getUniqueKeys", boolean.class),
diff --git a/site/_docs/reference.md b/site/_docs/reference.md
index 30631bee36..47262a2d71 100644
--- a/site/_docs/reference.md
+++ b/site/_docs/reference.md
@@ -2654,7 +2654,9 @@ BigQuery's type system uses confusingly different names
for types and functions:
| b | ARRAY_CONCAT(array [, array ]*) | Concatenates one or
more arrays. If any input argument is `NULL` the function returns `NULL`
| s | ARRAY_DISTINCT(array) | Returns unique elements
of *array*. Keeps ordering of elements.
| b | ARRAY_LENGTH(array) | Synonym for
`CARDINALITY`
+| 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`
| m s | CHAR(integer) | Returns the character
whose ASCII code is *integer* % 256, or null if *integer* < 0
| b o p | CHR(integer) | Returns the character
whose UTF-8 code is *integer*
| o | CONCAT(string, string) | Concatenates two strings
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 338ac1bebe..fe4a8cac0c 100644
--- a/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
+++ b/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
@@ -5336,6 +5336,27 @@ public class SqlOperatorTest {
f.checkNull("array_distinct(null)");
}
+ /** Tests {@code ARRAY_REPEAT} function from Spark. */
+ @Test void testArrayRepeatFunc() {
+ final SqlOperatorFixture f0 = fixture();
+ f0.setFor(SqlLibraryOperators.ARRAY_REPEAT);
+ f0.checkFails("^array_repeat(1, 2)^",
+ "No match found for function signature ARRAY_REPEAT\\(<NUMERIC>,
<NUMERIC>\\)", false);
+
+ final SqlOperatorFixture f = f0.withLibrary(SqlLibrary.SPARK);
+ f.checkScalar("array_repeat(1, 2)", "[1, 1]",
+ "INTEGER NOT NULL ARRAY NOT NULL");
+ f.checkScalar("array_repeat(1, -2)", "[]",
+ "INTEGER NOT NULL ARRAY NOT NULL");
+ f.checkScalar("array_repeat(array[1, 2], 2)", "[[1, 2], [1, 2]]",
+ "INTEGER NOT NULL ARRAY NOT NULL ARRAY NOT NULL");
+ f.checkScalar("array_repeat(map[1, 'a', 2, 'b'], 2)", "[{1=a, 2=b}, {1=a,
2=b}]",
+ "(INTEGER NOT NULL, CHAR(1) NOT NULL) MAP NOT NULL ARRAY NOT NULL");
+ f.checkScalar("array_repeat(cast(null as integer), 2)", "[null, null]",
+ "INTEGER ARRAY NOT NULL");
+ f.checkNull("array_repeat(1, null)");
+ }
+
/** Tests {@code ARRAY_REVERSE} function from BigQuery. */
@Test void testArrayReverseFunc() {
SqlOperatorFixture f = fixture()
@@ -5349,6 +5370,21 @@ public class SqlOperatorTest {
"INTEGER ARRAY NOT NULL");
}
+ /** Tests {@code ARRAY_SIZE} function from Spark. */
+ @Test void testArraySizeFunc() {
+ final SqlOperatorFixture f0 = fixture();
+ f0.setFor(SqlLibraryOperators.ARRAY_SIZE);
+ f0.checkFails("^array_size(array[1])^",
+ "No match found for function signature ARRAY_SIZE\\(<INTEGER
ARRAY>\\)", false);
+
+ final SqlOperatorFixture f = f0.withLibrary(SqlLibrary.SPARK);
+ f.checkScalar("array_size(array[1])", "1",
+ "INTEGER NOT NULL");
+ f.checkScalar("array_size(array[1, 2, null])", "3",
+ "INTEGER NOT NULL");
+ f.checkNull("array_size(null)");
+ }
+
/** Tests {@code ARRAY_LENGTH} function from BigQuery. */
@Test void testArrayLengthFunc() {
SqlOperatorFixture f = fixture()