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

abhishek pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git


The following commit(s) were added to refs/heads/master by this push:
     new 9f9faeec81 object[] handling for DimensionHandlers for arrays (#12552)
9f9faeec81 is described below

commit 9f9faeec816fee7bc8936dc3cb4aa1b91450e6c3
Author: Karan Kumar <[email protected]>
AuthorDate: Wed May 25 15:24:18 2022 +0530

    object[] handling for DimensionHandlers for arrays (#12552)
    
    Description
    Fixes a bug when running q's like
    
     SELECT cntarray,
           Count(*)
    FROM   (SELECT dim1,
                   dim2,
                   Array_agg(cnt) AS cntarray
            FROM   (SELECT dim1,
                           dim2,
                           dim3,
                           Count(*) AS cnt
                    FROM   foo
                    GROUP  BY 1,
                              2,
                              3)
            GROUP  BY 1,
                      2)
    GROUP  BY 1
    This generates an error:
    
    org.apache.druid.java.util.common.ISE: Unable to convert type 
[Ljava.lang.Object; to org.apache.druid.segment.data.ComparableList
            at 
org.apache.druid.segment.DimensionHandlerUtils.convertToList(DimensionHandlerUtils.java:405)
 ~[druid-xx]
    Because it's an array of numbers it looks like it does the convertToList 
call, which looks like:
    
      @Nullable
      public static ComparableList convertToList(Object obj)
      {
        if (obj == null) {
          return null;
        }
        if (obj instanceof List) {
          return new ComparableList((List) obj);
        }
        if (obj instanceof ComparableList) {
          return (ComparableList) obj;
        }
        throw new ISE("Unable to convert type %s to %s", 
obj.getClass().getName(), ComparableList.class.getName());
      }
    I.e. it doesn't know about arrays. Added the array handling as part of this 
PR.
---
 .../apache/druid/query/groupby/GroupByQuery.java   |   4 +-
 .../epinephelinae/RowBasedGrouperHelper.java       |  13 +-
 .../query/groupby/orderby/DefaultLimitSpec.java    |   5 +-
 .../druid/segment/DimensionHandlerUtils.java       |  82 ++++++--
 .../query/groupby/GroupByQueryRunnerTest.java      | 143 +++++++++++++-
 .../druid/segment/DimensionHandlerUtilsTest.java   | 176 ++++++++++++++++-
 .../java/org/apache/druid/segment/TestHelper.java  |   6 +-
 .../druid/sql/calcite/CalciteArraysQueryTest.java  | 218 ++++++++++++++++++++-
 8 files changed, 609 insertions(+), 38 deletions(-)

diff --git 
a/processing/src/main/java/org/apache/druid/query/groupby/GroupByQuery.java 
b/processing/src/main/java/org/apache/druid/query/groupby/GroupByQuery.java
index 3f0b9a163a..0493145cf3 100644
--- a/processing/src/main/java/org/apache/druid/query/groupby/GroupByQuery.java
+++ b/processing/src/main/java/org/apache/druid/query/groupby/GroupByQuery.java
@@ -787,8 +787,8 @@ public class GroupByQuery extends BaseQuery<ResultRow>
         dimCompare = 
Comparators.<Comparable>naturalNullsFirst().compare(lhsArr, rhsArr);
       } else if (dimensionType.equals(ColumnType.LONG_ARRAY)
                  || dimensionType.equals(ColumnType.DOUBLE_ARRAY)) {
-        final ComparableList lhsArr = 
DimensionHandlerUtils.convertToList(lhsObj);
-        final ComparableList rhsArr = 
DimensionHandlerUtils.convertToList(rhsObj);
+        final ComparableList lhsArr = 
DimensionHandlerUtils.convertToList(lhsObj, 
dimensionType.getElementType().getType());
+        final ComparableList rhsArr = 
DimensionHandlerUtils.convertToList(rhsObj, 
dimensionType.getElementType().getType());
         dimCompare = 
Comparators.<Comparable>naturalNullsFirst().compare(lhsArr, rhsArr);
       } else {
         dimCompare = comparator.compare((String) lhsObj, (String) rhsObj);
diff --git 
a/processing/src/main/java/org/apache/druid/query/groupby/epinephelinae/RowBasedGrouperHelper.java
 
b/processing/src/main/java/org/apache/druid/query/groupby/epinephelinae/RowBasedGrouperHelper.java
index 3381a9192e..bdf930f3e2 100644
--- 
a/processing/src/main/java/org/apache/druid/query/groupby/epinephelinae/RowBasedGrouperHelper.java
+++ 
b/processing/src/main/java/org/apache/druid/query/groupby/epinephelinae/RowBasedGrouperHelper.java
@@ -760,7 +760,8 @@ public class RowBasedGrouperHelper
             case DOUBLE:
               return 
(InputRawSupplierColumnSelectorStrategy<ColumnValueSelector>)
                   columnSelector ->
-                      () -> 
DimensionHandlerUtils.convertToList(columnSelector.getObject());
+                      () -> 
DimensionHandlerUtils.convertToList(columnSelector.getObject(),
+                                                                
capabilities.getElementType().getType());
             default:
               throw new IAE(
                   "Cannot create query type helper from invalid type [%s]",
@@ -1049,8 +1050,10 @@ public class RowBasedGrouperHelper
           cmp = Comparators.<Comparable>naturalNullsFirst().compare(lhs, rhs);
         } else if (fieldTypes.get(i - dimStart).equals(ColumnType.LONG_ARRAY)
                    || fieldTypes.get(i - 
dimStart).equals(ColumnType.DOUBLE_ARRAY)) {
-          final ComparableList lhs = 
DimensionHandlerUtils.convertToList(key1.getKey()[i]);
-          final ComparableList rhs = 
DimensionHandlerUtils.convertToList(key2.getKey()[i]);
+          final ComparableList lhs = 
DimensionHandlerUtils.convertToList(key1.getKey()[i],
+                                                                         
fieldTypes.get(i - dimStart).getElementType().getType());
+          final ComparableList rhs = 
DimensionHandlerUtils.convertToList(key2.getKey()[i],
+                                                                         
fieldTypes.get(i - dimStart).getElementType().getType());
           cmp = Comparators.<Comparable>naturalNullsFirst().compare(lhs, rhs);
         } else {
           cmp = Comparators.<Comparable>naturalNullsFirst().compare(
@@ -1128,8 +1131,8 @@ public class RowBasedGrouperHelper
 
           cmp = ComparableList.compareWithComparator(
               comparator,
-              DimensionHandlerUtils.convertToList(lhs),
-              DimensionHandlerUtils.convertToList(rhs)
+              DimensionHandlerUtils.convertToList(lhs, 
fieldType.getElementType().getType()),
+              DimensionHandlerUtils.convertToList(rhs, 
fieldType.getElementType().getType())
           );
 
         } else {
diff --git 
a/processing/src/main/java/org/apache/druid/query/groupby/orderby/DefaultLimitSpec.java
 
b/processing/src/main/java/org/apache/druid/query/groupby/orderby/DefaultLimitSpec.java
index 5597dcf597..c52c14bae7 100644
--- 
a/processing/src/main/java/org/apache/druid/query/groupby/orderby/DefaultLimitSpec.java
+++ 
b/processing/src/main/java/org/apache/druid/query/groupby/orderby/DefaultLimitSpec.java
@@ -440,11 +440,12 @@ public class DefaultLimitSpec implements LimitSpec
   {
     Comparator arrayComparator = null;
     if (columnType.isArray()) {
+      final ValueType elementType = columnType.getElementType().getType();
       if (columnType.getElementType().isNumeric()) {
         arrayComparator = (Comparator<Object>) (o1, o2) -> 
ComparableList.compareWithComparator(
             comparator,
-            DimensionHandlerUtils.convertToList(o1),
-            DimensionHandlerUtils.convertToList(o2)
+            DimensionHandlerUtils.convertToList(o1, elementType),
+            DimensionHandlerUtils.convertToList(o2, elementType)
         );
       } else if (columnType.getElementType().equals(ColumnType.STRING)) {
         arrayComparator = (Comparator<Object>) (o1, o2) -> 
ComparableStringArray.compareWithComparator(
diff --git 
a/processing/src/main/java/org/apache/druid/segment/DimensionHandlerUtils.java 
b/processing/src/main/java/org/apache/druid/segment/DimensionHandlerUtils.java
index 4d05ecb089..309e14b3e2 100644
--- 
a/processing/src/main/java/org/apache/druid/segment/DimensionHandlerUtils.java
+++ 
b/processing/src/main/java/org/apache/druid/segment/DimensionHandlerUtils.java
@@ -42,6 +42,7 @@ import org.apache.druid.segment.column.ValueType;
 import org.apache.druid.segment.data.ComparableList;
 import org.apache.druid.segment.data.ComparableStringArray;
 
+import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import java.math.BigDecimal;
 import java.util.ArrayList;
@@ -381,8 +382,12 @@ public final class DimensionHandlerUtils
         switch (type.getElementType().getType()) {
           case STRING:
             return convertToComparableStringArray(obj);
-          default:
-            return convertToList(obj);
+          case LONG:
+            return convertToListWithObjectFunction(obj, 
DimensionHandlerUtils::convertObjectToLong);
+          case FLOAT:
+            return convertToListWithObjectFunction(obj, 
DimensionHandlerUtils::convertObjectToFloat);
+          case DOUBLE:
+            return convertToListWithObjectFunction(obj, 
DimensionHandlerUtils::convertObjectToDouble);
         }
 
       default:
@@ -391,18 +396,57 @@ public final class DimensionHandlerUtils
   }
 
   @Nullable
-  public static ComparableList convertToList(Object obj)
+  public static ComparableList convertToList(Object obj, ValueType elementType)
+  {
+    switch (elementType) {
+      case LONG:
+        return convertToListWithObjectFunction(obj, 
DimensionHandlerUtils::convertObjectToLong);
+      case FLOAT:
+        return convertToListWithObjectFunction(obj, 
DimensionHandlerUtils::convertObjectToFloat);
+      case DOUBLE:
+        return convertToListWithObjectFunction(obj, 
DimensionHandlerUtils::convertObjectToDouble);
+    }
+    throw new ISE(
+        "Unable to convert object of type[%s] to [%s]",
+        obj.getClass().getName(),
+        ComparableList.class.getName()
+    );
+  }
+
+
+  private static <T> ComparableList convertToListWithObjectFunction(Object 
obj, Function<Object, T> convertFunction)
   {
     if (obj == null) {
       return null;
     }
     if (obj instanceof List) {
-      return new ComparableList((List) obj);
+      return convertToComparableList((List) obj, convertFunction);
     }
     if (obj instanceof ComparableList) {
-      return (ComparableList) obj;
+      return convertToComparableList(((ComparableList) obj).getDelegate(), 
convertFunction);
+    }
+    if (obj instanceof Object[]) {
+      final List<T> delegateList = new ArrayList<>();
+      for (Object eachObj : (Object[]) obj) {
+        delegateList.add(convertFunction.apply(eachObj));
+      }
+      return new ComparableList(delegateList);
+    }
+    throw new ISE(
+        "Unable to convert object of type[%s] to [%s]",
+        obj.getClass().getName(),
+        ComparableList.class.getName()
+    );
+  }
+
+  @Nonnull
+  private static <T> ComparableList convertToComparableList(List obj, 
Function<Object, T> convertFunction)
+  {
+    final List<T> delegateList = new ArrayList<>();
+    for (Object eachObj : obj) {
+      delegateList.add(convertFunction.apply(eachObj));
     }
-    throw new ISE("Unable to convert type %s to %s", obj.getClass().getName(), 
ComparableList.class.getName());
+    return new ComparableList(delegateList);
   }
 
 
@@ -415,19 +459,27 @@ public final class DimensionHandlerUtils
     if (obj instanceof ComparableStringArray) {
       return (ComparableStringArray) obj;
     }
-    if (obj instanceof String[]) {
-      return ComparableStringArray.of((String[]) obj);
-    }
     // Jackson converts the serialized array into a list. Converting it back 
to a string array
     if (obj instanceof List) {
-      return ComparableStringArray.of((String[]) ((List) obj).toArray(new 
String[0]));
+      String[] delegate = new String[((List) obj).size()];
+      for (int i = 0; i < delegate.length; i++) {
+        delegate[i] = convertObjectToString(((List) obj).get(i));
+      }
+      return ComparableStringArray.of(delegate);
     }
-    Objects[] objects = (Objects[]) obj;
-    String[] delegate = new String[objects.length];
-    for (int i = 0; i < objects.length; i++) {
-      delegate[i] = convertObjectToString(objects[i]);
+    if (obj instanceof Object[]) {
+      Object[] objects = (Object[]) obj;
+      String[] delegate = new String[objects.length];
+      for (int i = 0; i < objects.length; i++) {
+        delegate[i] = convertObjectToString(objects[i]);
+      }
+      return ComparableStringArray.of(delegate);
     }
-    return ComparableStringArray.of(delegate);
+    throw new ISE(
+        "Unable to convert object of type[%s] to [%s]",
+        obj.getClass().getName(),
+        ComparableStringArray.class.getName()
+    );
   }
 
   public static int compareObjectsAsType(
diff --git 
a/processing/src/test/java/org/apache/druid/query/groupby/GroupByQueryRunnerTest.java
 
b/processing/src/test/java/org/apache/druid/query/groupby/GroupByQueryRunnerTest.java
index 1511750bca..5426f48302 100644
--- 
a/processing/src/test/java/org/apache/druid/query/groupby/GroupByQueryRunnerTest.java
+++ 
b/processing/src/test/java/org/apache/druid/query/groupby/GroupByQueryRunnerTest.java
@@ -2055,6 +2055,141 @@ public class GroupByQueryRunnerTest extends 
InitializedNullHandlingTest
         .build();
 
 
+    List<ResultRow> expectedResults = Arrays.asList(
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(78L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(97L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(109L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(110L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(112L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(113L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(114L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(118L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(119L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(120L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(121L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(126L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(135L)), "rows", 2L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(144L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(147L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(158L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(166L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(1049L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(1144L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(1193L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(1234L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(1314L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(1321L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(1447L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(1522L)), "rows", 1L)
+    );
+
+    Iterable<ResultRow> results = 
GroupByQueryRunnerTestHelper.runQuery(factory, runner, outer);
+    TestHelper.assertExpectedObjects(expectedResults, results, 
"long-groupby-arrays");
+  }
+
+  @Test
+  public void testGroupByWithLongArraysDesc()
+  {
+    if 
(config.getDefaultStrategy().equals(GroupByStrategySelector.STRATEGY_V1)) {
+      expectedException.expect(UnsupportedOperationException.class);
+      expectedException.expectMessage("GroupBy v1 only supports dimensions 
with an outputType of STRING");
+    }
+    cannotVectorize();
+    GroupByQuery outer = makeQueryBuilder()
+        .setDataSource(QueryRunnerTestHelper.DATA_SOURCE)
+        .setQuerySegmentSpec(QueryRunnerTestHelper.FIRST_TO_THIRD)
+        .setVirtualColumns(new ExpressionVirtualColumn(
+            "v0",
+            "array(index)",
+            ColumnType.LONG_ARRAY,
+            ExprMacroTable.nil()
+        ))
+        .setDimensions(
+            new DefaultDimensionSpec("v0", "alias_outer", 
ColumnType.LONG_ARRAY)
+        )
+        .setLimitSpec(new DefaultLimitSpec(
+            ImmutableList.of(new OrderByColumnSpec(
+                "alias_outer",
+                OrderByColumnSpec.Direction.DESCENDING,
+                StringComparators.NUMERIC
+            )),
+            Integer.MAX_VALUE - 1
+        ))
+        .setAggregatorSpecs(
+            QueryRunnerTestHelper.ROWS_COUNT
+        )
+        .setGranularity(QueryRunnerTestHelper.ALL_GRAN)
+        .build();
+
+
+    List<ResultRow> expectedResults = Arrays.asList(
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(78L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(97L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(109L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(110L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(112L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(113L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(114L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(118L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(119L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(120L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(121L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(126L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(135L)), "rows", 2L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(144L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(147L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(158L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(166L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(1049L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(1144L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(1193L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(1234L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(1314L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(1321L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(1447L)), "rows", 1L),
+        makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(1522L)), "rows", 1L)
+    );
+    // reversing list
+    Collections.reverse(expectedResults);
+    Iterable<ResultRow> results = 
GroupByQueryRunnerTestHelper.runQuery(factory, runner, outer);
+    TestHelper.assertExpectedObjects(expectedResults, results, 
"long-groupby-arrays");
+  }
+
+  @Test
+  public void testGroupByWithDoubleArrays()
+  {
+    if 
(config.getDefaultStrategy().equals(GroupByStrategySelector.STRATEGY_V1)) {
+      expectedException.expect(UnsupportedOperationException.class);
+      expectedException.expectMessage("GroupBy v1 only supports dimensions 
with an outputType of STRING");
+    }
+    cannotVectorize();
+    GroupByQuery outer = makeQueryBuilder()
+        .setDataSource(QueryRunnerTestHelper.DATA_SOURCE)
+        .setQuerySegmentSpec(QueryRunnerTestHelper.FIRST_TO_THIRD)
+        .setVirtualColumns(new ExpressionVirtualColumn(
+            "v0",
+            "array(index)",
+            ColumnType.DOUBLE_ARRAY,
+            ExprMacroTable.nil()
+        ))
+        .setDimensions(
+            new DefaultDimensionSpec("v0", "alias_outer", 
ColumnType.DOUBLE_ARRAY)
+        )
+        .setLimitSpec(new DefaultLimitSpec(
+            ImmutableList.of(new OrderByColumnSpec(
+                "alias_outer",
+                OrderByColumnSpec.Direction.ASCENDING,
+                StringComparators.NUMERIC
+            )),
+            Integer.MAX_VALUE - 1
+        ))
+        .setAggregatorSpecs(
+            QueryRunnerTestHelper.ROWS_COUNT
+        )
+        .setGranularity(QueryRunnerTestHelper.ALL_GRAN)
+        .build();
+
+
     List<ResultRow> expectedResults = Arrays.asList(
         makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(78.622547)), "rows", 1L),
         makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(97.387433)), "rows", 1L),
@@ -2083,13 +2218,13 @@ public class GroupByQueryRunnerTest extends 
InitializedNullHandlingTest
         makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(1447.34116)), "rows", 1L),
         makeRow(outer, "2011-04-01", "alias_outer", new 
ComparableList(ImmutableList.of(1522.043733)), "rows", 1L)
     );
-
     Iterable<ResultRow> results = 
GroupByQueryRunnerTestHelper.runQuery(factory, runner, outer);
     TestHelper.assertExpectedObjects(expectedResults, results, 
"long-groupby-arrays");
   }
 
+
   @Test
-  public void testGroupByWithLongArraysDesc()
+  public void testGroupByWithDoubleArraysDesc()
   {
     if 
(config.getDefaultStrategy().equals(GroupByStrategySelector.STRATEGY_V1)) {
       expectedException.expect(UnsupportedOperationException.class);
@@ -2102,11 +2237,11 @@ public class GroupByQueryRunnerTest extends 
InitializedNullHandlingTest
         .setVirtualColumns(new ExpressionVirtualColumn(
             "v0",
             "array(index)",
-            ColumnType.LONG_ARRAY,
+            ColumnType.DOUBLE_ARRAY,
             ExprMacroTable.nil()
         ))
         .setDimensions(
-            new DefaultDimensionSpec("v0", "alias_outer", 
ColumnType.LONG_ARRAY)
+            new DefaultDimensionSpec("v0", "alias_outer", 
ColumnType.DOUBLE_ARRAY)
         )
         .setLimitSpec(new DefaultLimitSpec(
             ImmutableList.of(new OrderByColumnSpec(
diff --git 
a/processing/src/test/java/org/apache/druid/segment/DimensionHandlerUtilsTest.java
 
b/processing/src/test/java/org/apache/druid/segment/DimensionHandlerUtilsTest.java
index 088783e89f..53b598a0cd 100644
--- 
a/processing/src/test/java/org/apache/druid/segment/DimensionHandlerUtilsTest.java
+++ 
b/processing/src/test/java/org/apache/druid/segment/DimensionHandlerUtilsTest.java
@@ -19,6 +19,7 @@
 
 package org.apache.druid.segment;
 
+import com.google.common.collect.ImmutableList;
 import org.apache.druid.data.input.impl.DimensionSchema;
 import org.apache.druid.data.input.impl.DoubleDimensionSchema;
 import org.apache.druid.data.input.impl.FloatDimensionSchema;
@@ -28,6 +29,9 @@ import org.apache.druid.java.util.common.ISE;
 import org.apache.druid.segment.column.ColumnCapabilities;
 import org.apache.druid.segment.column.ColumnCapabilitiesImpl;
 import org.apache.druid.segment.column.ColumnType;
+import org.apache.druid.segment.column.ValueType;
+import org.apache.druid.segment.data.ComparableList;
+import org.apache.druid.segment.data.ComparableStringArray;
 import org.apache.druid.testing.InitializedNullHandlingTest;
 import org.junit.Assert;
 import org.junit.BeforeClass;
@@ -44,12 +48,19 @@ public class DimensionHandlerUtilsTest extends 
InitializedNullHandlingTest
   @Rule
   public ExpectedException expectedException = ExpectedException.none();
 
+  private static final ComparableList<Long> LONG_COMPARABLE_LIST = new 
ComparableList<>(ImmutableList.of(1L, 2L));
+  private static final ComparableList<Double> DOUBLE_COMPARABLE_LIST = new 
ComparableList<>(ImmutableList.of(1.0, 2.0));
+  private static final ComparableList<Float> FLOAT_COMPARABLE_LIST = new 
ComparableList<>(ImmutableList.of(1F, 2F));
+  private static final ComparableStringArray COMPARABLE_STRING_ARRAY = 
ComparableStringArray.of("1", "2");
+  private static final ComparableStringArray COMPARABLE_STRING_ARRAY_DECIMAL = 
ComparableStringArray.of("1.0", "2.0");
+
   @BeforeClass
   public static void setupTests()
   {
     DimensionHandlerUtils.registerDimensionHandlerProvider(
         TYPE,
-        d -> new DoubleDimensionHandler(d) {
+        d -> new DoubleDimensionHandler(d)
+        {
           @Override
           public DimensionSchema getDimensionSchema(ColumnCapabilities 
capabilities)
           {
@@ -145,6 +156,169 @@ public class DimensionHandlerUtilsTest extends 
InitializedNullHandlingTest
     Assert.assertTrue(handler.getDimensionSchema(capabilities) instanceof 
LongDimensionSchema);
   }
 
+  @Test
+  public void testComparableLongList()
+  {
+    Assert.assertEquals(null, DimensionHandlerUtils.convertToList(null, 
ValueType.LONG));
+    Assert.assertEquals(
+        LONG_COMPARABLE_LIST,
+        DimensionHandlerUtils.convertToList(ImmutableList.of(1L, 2L), 
ValueType.LONG)
+    );
+    Assert.assertEquals(
+        LONG_COMPARABLE_LIST,
+        DimensionHandlerUtils.convertToList(
+            new ComparableList(ImmutableList.of(1L, 2L)),
+            ValueType.LONG
+        )
+    );
+
+    assertArrayCases(LONG_COMPARABLE_LIST, ValueType.LONG);
+
+    Assert.assertThrows(
+        "Unable to convert object of type[Long] to [ComparableList]",
+        ISE.class,
+        () -> DimensionHandlerUtils.convertToList(1L, ValueType.LONG)
+    );
+
+    Assert.assertThrows(
+        "Unable to convert object of type[Long] to [ComparableList]",
+        ISE.class,
+        () -> DimensionHandlerUtils.convertToList(1L, ValueType.ARRAY)
+    );
+
+    Assert.assertThrows(
+        "Unable to convert object of type[Long] to [ComparableList]",
+        ISE.class,
+        () -> DimensionHandlerUtils.convertToList(1L, ValueType.STRING)
+    );
+  }
+
+  @Test
+  public void testComparableFloatList()
+  {
+    Assert.assertEquals(null, DimensionHandlerUtils.convertToList(null, 
ValueType.FLOAT));
+    Assert.assertEquals(
+        FLOAT_COMPARABLE_LIST,
+        DimensionHandlerUtils.convertToList(ImmutableList.of(1.0F, 2.0F), 
ValueType.FLOAT)
+    );
+    Assert.assertEquals(
+        FLOAT_COMPARABLE_LIST,
+        DimensionHandlerUtils.convertToList(
+            new ComparableList(ImmutableList.of(1.0F, 2.0F)),
+            ValueType.FLOAT
+        )
+    );
+
+    assertArrayCases(FLOAT_COMPARABLE_LIST, ValueType.FLOAT);
+
+    Assert.assertThrows(
+        "Unable to convert object of type[Float] to [ComparableList]",
+        ISE.class,
+        () -> DimensionHandlerUtils.convertToList(1.0F, ValueType.FLOAT)
+    );
+
+    Assert.assertThrows(
+        "Unable to convert object of type[Float] to [ComparableList]",
+        ISE.class,
+        () -> DimensionHandlerUtils.convertToList(1.0F, ValueType.ARRAY)
+    );
+
+    Assert.assertThrows(
+        "Unable to convert object of type[Float] to [ComparableList]",
+        ISE.class,
+        () -> DimensionHandlerUtils.convertToList(1.0F, ValueType.STRING)
+    );
+  }
+
+  @Test
+  public void testComparableDoubleList()
+  {
+    Assert.assertEquals(null, DimensionHandlerUtils.convertToList(null, 
ValueType.DOUBLE));
+    Assert.assertEquals(
+        DOUBLE_COMPARABLE_LIST,
+        DimensionHandlerUtils.convertToList(ImmutableList.of(1.0D, 2.0D), 
ValueType.DOUBLE)
+    );
+    Assert.assertEquals(
+        DOUBLE_COMPARABLE_LIST,
+        DimensionHandlerUtils.convertToList(
+            new ComparableList(ImmutableList.of(1.0D, 2.0D)),
+            ValueType.DOUBLE
+        )
+    );
+
+    assertArrayCases(DOUBLE_COMPARABLE_LIST, ValueType.DOUBLE);
+
+    Assert.assertThrows(
+        "Unable to convert object of type[Double] to [ComparableList]",
+        ISE.class,
+        () -> DimensionHandlerUtils.convertToList(1.0D, ValueType.DOUBLE)
+    );
+
+    Assert.assertThrows(
+        "Unable to convert object of type[Double] to [ComparableList]",
+        ISE.class,
+        () -> DimensionHandlerUtils.convertToList(1.0D, ValueType.ARRAY)
+    );
+
+    Assert.assertThrows(
+        "Unable to convert object of type[Double] to [ComparableList]",
+        ISE.class,
+        () -> DimensionHandlerUtils.convertToList(1.0D, ValueType.STRING)
+    );
+  }
+
+  @Test
+  public void testComparableStringArrayList()
+  {
+    Assert.assertEquals(null, 
DimensionHandlerUtils.convertToComparableStringArray(null));
+    Assert.assertEquals(
+        COMPARABLE_STRING_ARRAY,
+        
DimensionHandlerUtils.convertToComparableStringArray(ImmutableList.of("1", "2"))
+    );
+
+    Assert.assertEquals(
+        COMPARABLE_STRING_ARRAY,
+        DimensionHandlerUtils.convertToComparableStringArray(new Object[]{1L, 
2L})
+    );
+    Assert.assertEquals(
+        COMPARABLE_STRING_ARRAY,
+        DimensionHandlerUtils.convertToComparableStringArray(new Long[]{1L, 
2L})
+    );
+    Assert.assertEquals(
+        COMPARABLE_STRING_ARRAY_DECIMAL,
+        DimensionHandlerUtils.convertToComparableStringArray(new 
String[]{"1.0", "2.0"})
+    );
+    Assert.assertEquals(
+        COMPARABLE_STRING_ARRAY_DECIMAL,
+        DimensionHandlerUtils.convertToComparableStringArray(new Double[]{1.0, 
2.0})
+    );
+    Assert.assertEquals(
+        COMPARABLE_STRING_ARRAY_DECIMAL,
+        DimensionHandlerUtils.convertToComparableStringArray(new Float[]{1F, 
2F})
+    );
+
+    Assert.assertThrows(
+        "Unable to convert object of type[String] to 
[ComparablComparableStringArray]",
+        ISE.class,
+        () -> DimensionHandlerUtils.convertToComparableStringArray("1")
+    );
+  }
+
+  private static void assertArrayCases(ComparableList expectedComparableList, 
ValueType elementType)
+  {
+    Assert.assertEquals(expectedComparableList, 
DimensionHandlerUtils.convertToList(new Object[]{1L, 2L}, elementType));
+    Assert.assertEquals(expectedComparableList, 
DimensionHandlerUtils.convertToList(new Long[]{1L, 2L}, elementType));
+    Assert.assertEquals(
+        expectedComparableList,
+        DimensionHandlerUtils.convertToList(new String[]{"1.0", "2.0"}, 
elementType)
+    );
+    Assert.assertEquals(
+        expectedComparableList,
+        DimensionHandlerUtils.convertToList(new Double[]{1.0, 2.0}, 
elementType)
+    );
+    Assert.assertEquals(expectedComparableList, 
DimensionHandlerUtils.convertToList(new Float[]{1F, 2F}, elementType));
+  }
+
   private static class TestDimensionSchema extends DimensionSchema
   {
 
diff --git a/processing/src/test/java/org/apache/druid/segment/TestHelper.java 
b/processing/src/test/java/org/apache/druid/segment/TestHelper.java
index 8a913a5790..4ee90243dd 100644
--- a/processing/src/test/java/org/apache/druid/segment/TestHelper.java
+++ b/processing/src/test/java/org/apache/druid/segment/TestHelper.java
@@ -416,9 +416,9 @@ public class TestHelper
             ExprEval.coerceListToArray((List) actualValue, true).rhs
         );
       } else if (expectedValue instanceof ComparableList && actualValue 
instanceof List) {
-        Assert.assertEquals(
-            ((ComparableList) expectedValue).getDelegate(),
-            (List) actualValue
+        Assert.assertArrayEquals(
+            ((ComparableList) expectedValue).getDelegate().toArray(new 
Object[0]),
+            ExprEval.coerceListToArray((List) actualValue, true).rhs
         );
       } else {
         Assert.assertEquals(
diff --git 
a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteArraysQueryTest.java 
b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteArraysQueryTest.java
index d18a6c1676..fd9915d67d 100644
--- a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteArraysQueryTest.java
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteArraysQueryTest.java
@@ -1069,15 +1069,15 @@ public class CalciteArraysQueryTest extends 
BaseCalciteQueryTest
                         .build()
         ),
         useDefault ? ImmutableList.of(
-            new Object[]{ImmutableList.of(0.0), 4L},
-            new Object[]{ImmutableList.of(0.10000000149011612), 1L},
-            new Object[]{ImmutableList.of(1.0), 1L}
+            new Object[]{ImmutableList.of(0.0F), 4L},
+            new Object[]{ImmutableList.of(0.10000000149011612F), 1L},
+            new Object[]{ImmutableList.of(1.0F), 1L}
         ) :
         ImmutableList.of(
             new Object[]{Collections.singletonList(null), 3L},
-            new Object[]{ImmutableList.of(0.0), 1L},
-            new Object[]{ImmutableList.of(0.10000000149011612), 1L},
-            new Object[]{ImmutableList.of(1.0), 1L}
+            new Object[]{ImmutableList.of(0.0F), 1L},
+            new Object[]{ImmutableList.of(0.10000000149011612F), 1L},
+            new Object[]{ImmutableList.of(1.0F), 1L}
         )
     );
   }
@@ -2177,6 +2177,212 @@ public class CalciteArraysQueryTest extends 
BaseCalciteQueryTest
     );
   }
 
+  @Test
+  public void testArrayAggGroupByArrayAggOfLongsFromSubquery() throws Exception
+  {
+    requireMergeBuffers(3);
+    cannotVectorize();
+    testQuery(
+        "select cntarray, count(*) from ( select dim1, dim2, ARRAY_AGG(cnt) as 
cntarray from ( select dim1, dim2, dim3, count(*) as cnt from foo group by 1, 
2, 3 ) group by 1, 2 ) group by 1",
+        QUERY_CONTEXT_NO_STRINGIFY_ARRAY,
+        ImmutableList.of(
+            GroupByQuery.builder()
+                        .setDataSource(new QueryDataSource(
+                            GroupByQuery.builder()
+                                        .setDataSource(new QueryDataSource(
+                                            GroupByQuery.builder()
+                                                        .setDataSource(new 
TableDataSource(CalciteTests.DATASOURCE1))
+                                                        
.setQuerySegmentSpec(querySegmentSpec(Filtration.eternity()))
+                                                        
.setGranularity(Granularities.ALL)
+                                                        
.setInterval(querySegmentSpec(Filtration.eternity()))
+                                                        
.setContext(QUERY_CONTEXT_NO_STRINGIFY_ARRAY)
+                                                        .setDimensions(
+                                                            new 
DefaultDimensionSpec("dim1", "d0"),
+                                                            new 
DefaultDimensionSpec("dim2", "d1"),
+                                                            new 
DefaultDimensionSpec("dim3", "d2"
+                                                            )
+                                                        )
+                                                        .setAggregatorSpecs(
+                                                            new 
CountAggregatorFactory("a0"))
+                                                        .build()))
+                                        .setQuerySegmentSpec(
+                                            
querySegmentSpec(Filtration.eternity()))
+                                        .setGranularity(Granularities.ALL)
+                                        .setDimensions(
+                                            new DefaultDimensionSpec(
+                                                "d0",
+                                                "_d0"
+                                            ),
+                                            new DefaultDimensionSpec(
+                                                "d1",
+                                                "_d1"
+                                            )
+                                        )
+                                        .setAggregatorSpecs(new 
ExpressionLambdaAggregatorFactory(
+                                            "_a0",
+                                            ImmutableSet.of("a0"),
+                                            "__acc",
+                                            "ARRAY<LONG>[]",
+                                            "ARRAY<LONG>[]",
+                                            true,
+                                            true,
+                                            false,
+                                            "array_append(\"__acc\", \"a0\")",
+                                            "array_concat(\"__acc\", \"_a0\")",
+                                            null,
+                                            null,
+                                            new HumanReadableBytes(1024),
+                                            ExprMacroTable.nil()
+                                        ))
+                                        .build()))
+                        
.setQuerySegmentSpec(querySegmentSpec(Filtration.eternity()))
+                        .setGranularity(Granularities.ALL)
+                        .setInterval(querySegmentSpec(Filtration.eternity()))
+                        .setContext(QUERY_CONTEXT_NO_STRINGIFY_ARRAY)
+                        .setDimensions(new DefaultDimensionSpec("_a0", "d0", 
ColumnType.LONG_ARRAY))
+                        .setAggregatorSpecs(new CountAggregatorFactory("a0"))
+                        .build()
+        ),
+        ImmutableList.of(
+            new Object[]{ImmutableList.of(1L), 4L},
+            new Object[]{ImmutableList.of(1L, 1L), 2L}
+        )
+    );
+  }
+
+  @Test
+  public void testArrayAggGroupByArrayAggOfStringsFromSubquery() throws 
Exception
+  {
+    requireMergeBuffers(3);
+    cannotVectorize();
+    testQuery(
+        "select cntarray, count(*) from ( select dim1, dim2, ARRAY_AGG(cnt) as 
cntarray from ( select dim1, dim2, dim3, cast( count(*) as VARCHAR ) as cnt 
from foo group by 1, 2, 3 ) group by 1, 2 ) group by 1",
+        QUERY_CONTEXT_NO_STRINGIFY_ARRAY,
+        ImmutableList.of(
+            GroupByQuery.builder()
+                        .setDataSource(new QueryDataSource(
+                            GroupByQuery.builder()
+                                        .setDataSource(new QueryDataSource(
+                                            GroupByQuery.builder()
+                                                        .setDataSource(new 
TableDataSource(CalciteTests.DATASOURCE1))
+                                                        
.setQuerySegmentSpec(querySegmentSpec(Filtration.eternity()))
+                                                        
.setGranularity(Granularities.ALL)
+                                                        
.setInterval(querySegmentSpec(Filtration.eternity()))
+                                                        
.setContext(QUERY_CONTEXT_NO_STRINGIFY_ARRAY)
+                                                        .setDimensions(
+                                                            new 
DefaultDimensionSpec("dim1", "d0"),
+                                                            new 
DefaultDimensionSpec("dim2", "d1"),
+                                                            new 
DefaultDimensionSpec("dim3", "d2"
+                                                            )
+                                                        )
+                                                        .setAggregatorSpecs(
+                                                            new 
CountAggregatorFactory("a0"))
+                                                        .build()))
+                                        
.setQuerySegmentSpec(querySegmentSpec(Filtration.eternity()))
+                                        .setGranularity(Granularities.ALL)
+                                        .setDimensions(
+                                            new DefaultDimensionSpec("d0", 
"_d0"),
+                                            new DefaultDimensionSpec("d1", 
"_d1")
+                                        )
+                                        .setAggregatorSpecs(new 
ExpressionLambdaAggregatorFactory(
+                                            "_a0",
+                                            ImmutableSet.of("a0"),
+                                            "__acc",
+                                            "ARRAY<STRING>[]",
+                                            "ARRAY<STRING>[]",
+                                            true,
+                                            true,
+                                            false,
+                                            "array_append(\"__acc\", \"a0\")",
+                                            "array_concat(\"__acc\", \"_a0\")",
+                                            null,
+                                            null,
+                                            new HumanReadableBytes(1024),
+                                            ExprMacroTable.nil()
+                                        ))
+                                        .build()))
+                        
.setQuerySegmentSpec(querySegmentSpec(Filtration.eternity()))
+                        .setGranularity(Granularities.ALL)
+                        .setInterval(querySegmentSpec(Filtration.eternity()))
+                        .setContext(QUERY_CONTEXT_NO_STRINGIFY_ARRAY)
+                        .setDimensions(new DefaultDimensionSpec("_a0", "d0", 
ColumnType.STRING_ARRAY))
+                        .setAggregatorSpecs(new CountAggregatorFactory("a0"))
+                        .build()
+        ),
+        ImmutableList.of(
+            new Object[]{ImmutableList.of("1"), 4L},
+            new Object[]{ImmutableList.of("1", "1"), 2L}
+        )
+    );
+  }
+
+  @Test
+  public void testArrayAggGroupByArrayAggOfDoubleFromSubquery() throws 
Exception
+  {
+    requireMergeBuffers(3);
+    cannotVectorize();
+    testQuery(
+        "select cntarray, count(*) from ( select dim1, dim2, ARRAY_AGG(cnt) as 
cntarray from ( select dim1, dim2, dim3, cast( count(*) as DOUBLE ) as cnt from 
foo group by 1, 2, 3 ) group by 1, 2 ) group by 1",
+        QUERY_CONTEXT_NO_STRINGIFY_ARRAY,
+        ImmutableList.of(
+            GroupByQuery
+                .builder()
+                .setDataSource(new QueryDataSource(
+                    GroupByQuery.builder()
+                                .setDataSource(new QueryDataSource(
+                                    GroupByQuery.builder()
+                                                .setDataSource(new 
TableDataSource(CalciteTests.DATASOURCE1))
+                                                
.setQuerySegmentSpec(querySegmentSpec(Filtration.eternity()))
+                                                
.setGranularity(Granularities.ALL)
+                                                
.setInterval(querySegmentSpec(Filtration.eternity()))
+                                                
.setContext(QUERY_CONTEXT_NO_STRINGIFY_ARRAY)
+                                                .setDimensions(
+                                                    new 
DefaultDimensionSpec("dim1", "d0"),
+                                                    new 
DefaultDimensionSpec("dim2", "d1"),
+                                                    new 
DefaultDimensionSpec("dim3", "d2"
+                                                    )
+                                                )
+                                                .setAggregatorSpecs(
+                                                    new 
CountAggregatorFactory("a0"))
+                                                .build()))
+                                
.setQuerySegmentSpec(querySegmentSpec(Filtration.eternity()))
+                                .setGranularity(Granularities.ALL)
+                                .setDimensions(
+                                    new DefaultDimensionSpec("d0", "_d0"),
+                                    new DefaultDimensionSpec("d1", "_d1")
+                                )
+                                .setAggregatorSpecs(new 
ExpressionLambdaAggregatorFactory(
+                                    "_a0",
+                                    ImmutableSet.of("a0"),
+                                    "__acc",
+                                    "ARRAY<DOUBLE>[]",
+                                    "ARRAY<DOUBLE>[]",
+                                    true,
+                                    true,
+                                    false,
+                                    "array_append(\"__acc\", \"a0\")",
+                                    "array_concat(\"__acc\", \"_a0\")",
+                                    null,
+                                    null,
+                                    new HumanReadableBytes(1024),
+                                    ExprMacroTable.nil()
+                                ))
+                                .build()))
+                .setQuerySegmentSpec(querySegmentSpec(Filtration.eternity()))
+                .setGranularity(Granularities.ALL)
+                .setInterval(querySegmentSpec(Filtration.eternity()))
+                .setContext(QUERY_CONTEXT_NO_STRINGIFY_ARRAY)
+                .setDimensions(new DefaultDimensionSpec("_a0", "d0", 
ColumnType.DOUBLE_ARRAY))
+                .setAggregatorSpecs(new CountAggregatorFactory("a0"))
+                .build()
+        ),
+        ImmutableList.of(
+            new Object[]{ImmutableList.of(1.0), 4L},
+            new Object[]{ImmutableList.of(1.0, 1.0), 2L}
+        )
+    );
+  }
+
   @Test
   public void testArrayAggArrayContainsSubquery() throws Exception
   {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to