Skip to content

Commit

Permalink
[CALCITE-6063] ARRAY subquery with OrderBy loses Sort
Browse files Browse the repository at this point in the history
  • Loading branch information
chucheng92 committed Jan 24, 2024
1 parent aca7f02 commit 23099a6
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5538,7 +5538,7 @@ ImmutableList<RelNode> retrieveCursors() {
case ARRAY_QUERY_CONSTRUCTOR:
call = (SqlCall) expr;
query = Iterables.getOnlyElement(call.getOperandList());
root = convertQueryRecursive(query, false, null);
root = convertQueryRecursive(query, true, null);
return RexSubQuery.array(root.rel);

case MAP_QUERY_CONSTRUCTOR:
Expand Down
48 changes: 48 additions & 0 deletions core/src/test/resources/sql/sub-query.iq
Original file line number Diff line number Diff line change
Expand Up @@ -3726,4 +3726,52 @@ SELECT map(SELECT empno, deptno from emp where false);

!ok

# [CALCITE-6063] ARRAY subquery with OrderBy loses Sort
# normal behavior
SELECT array(SELECT empno FROM emp);
+--------------------------------------------------------------------------------------+
| EXPR$0 |
+--------------------------------------------------------------------------------------+
| [7369, 7499, 7521, 7566, 7654, 7698, 7782, 7788, 7839, 7844, 7876, 7900, 7902, 7934] |
+--------------------------------------------------------------------------------------+
(1 row)

!ok

# [CALCITE-6063] ARRAY subquery with OrderBy loses Sort
# with filter
SELECT array(SELECT empno FROM emp WHERE empno > 7800);
+--------------------------------------+
| EXPR$0 |
+--------------------------------------+
| [7839, 7844, 7876, 7900, 7902, 7934] |
+--------------------------------------+
(1 row)

!ok

# [CALCITE-6063] ARRAY subquery with OrderBy loses Sort
# with filter and order by
SELECT array(SELECT empno FROM emp WHERE empno > 7800 ORDER BY empno DESC);
+--------------------------------------+
| EXPR$0 |
+--------------------------------------+
| [7934, 7902, 7900, 7876, 7844, 7839] |
+--------------------------------------+
(1 row)

!ok

# [CALCITE-6063] ARRAY subquery with OrderBy loses Sort
# with filter and order by and limit
SELECT array(SELECT empno FROM emp WHERE empno > 7800 ORDER BY empno DESC LIMIT 2);
+--------------+
| EXPR$0 |
+--------------+
| [7934, 7902] |
+--------------+
(1 row)

!ok

# End sub-query.iq
8 changes: 8 additions & 0 deletions site/_docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -1643,6 +1643,14 @@ Implicit type coercion of following cases are ignored:
| ARRAY '[' value [, value ]* ']' | Creates an array from a list of values.
| MAP '[' key, value [, key, value ]* ']' | Creates a map from a list of key-value pairs.

### Value constructors by query

| Operator syntax | Description |
|:-----------------------------------|:------------|
| ARRAY (sub-query) | Creates an array from the result of a sub-query. Example: `ARRAY(SELECT empno FROM emp)` |
| MAP (sub-query) | Creates a map from the result of a key-value pair sub-query. Example: `MAP(SELECT empno, deptno FROM emp)` |
| MULTISET (sub-query) | Creates a multiset from the result of a sub-query. Example: `MULTISET(SELECT empno FROM emp)` |

### Collection functions

| Operator syntax | Description
Expand Down
33 changes: 27 additions & 6 deletions testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -10697,20 +10697,41 @@ private static void checkArrayConcatAggFuncFails(SqlOperatorFixture t) {
"[1 , 2 , Hi , null]", "CHAR(10) ARRAY NOT NULL");
}

/**
* Test case for
* <a href="https://issues.apache.org/jira/browse/CALCITE-4999">[CALCITE-4999]
* ARRAY, MULTISET functions should return an collection of scalars
* if a sub-query returns 1 column</a>.
*/
@Test void testArrayQueryConstructor() {
final SqlOperatorFixture f = fixture();
f.setFor(SqlStdOperatorTable.ARRAY_QUERY, SqlOperatorFixture.VmName.EXPAND);

// Test case for [CALCITE-4999] ARRAY, MULTISET functions should
// return a collection of scalars if a sub-query returns 1 column
f.checkScalar("array(select 1)", "[1]",
"INTEGER NOT NULL ARRAY NOT NULL");
f.check("select array(select ROW(1,2))",
"RecordType(INTEGER NOT NULL EXPR$0, INTEGER NOT NULL EXPR$1) NOT NULL ARRAY NOT NULL",
"[{1, 2}]");

// single sub-clause test
f.check("select array(select x from unnest(array[1,2,3,4]) as t(x))",
"INTEGER NOT NULL ARRAY NOT NULL", "[1, 2, 3, 4]");
f.check("select array(select x from unnest(array[1,2,3,4]) as t(x) where x > 1)",
"INTEGER NOT NULL ARRAY NOT NULL", "[2, 3, 4]");
f.check("select array(select x from unnest(array[1,2,3,4]) as t(x) limit 2)",
"INTEGER NOT NULL ARRAY NOT NULL", "[1, 2]");
f.check("select array(select x from unnest(array[1,2,3,4]) as t(x) where x > 1 limit 2)",
"INTEGER NOT NULL ARRAY NOT NULL", "[2, 3]");

// combined tests
f.check("select array(select x from unnest(array[1,2,3,4]) as t(x) "
+ "order by x asc)", "INTEGER NOT NULL ARRAY NOT NULL", "[1, 2, 3, 4]");
f.check("select array(select x from unnest(array[1,2,3,4]) as t(x) "
+ "where x > 1 order by x asc)", "INTEGER NOT NULL ARRAY NOT NULL", "[2, 3, 4]");
f.check("select array(select x from unnest(array[1,2,3,4]) as t(x) "
+ "where x > 1 order by x asc limit 2)", "INTEGER NOT NULL ARRAY NOT NULL", "[2, 3]");
f.check("select array(select x from unnest(array[1,2,3,4]) as t(x) "
+ "order by x desc)", "INTEGER NOT NULL ARRAY NOT NULL", "[4, 3, 2, 1]");
f.check("select array(select x from unnest(array[1,2,3,4]) as t(x) "
+ "where x > 1 order by x desc)", "INTEGER NOT NULL ARRAY NOT NULL", "[4, 3, 2]");
f.check("select array(select x from unnest(array[1,2,3,4]) as t(x) "
+ "where x > 1 order by x desc limit 2)", "INTEGER NOT NULL ARRAY NOT NULL", "[4, 3]");
}

/**
Expand Down

0 comments on commit 23099a6

Please sign in to comment.