diff --git a/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/hll/HllSketchBuildAggregator.java b/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/hll/HllSketchBuildAggregator.java index 4f772608008a..66a51f7f9848 100644 --- a/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/hll/HllSketchBuildAggregator.java +++ b/extensions-core/datasketches/src/main/java/org/apache/druid/query/aggregation/datasketches/hll/HllSketchBuildAggregator.java @@ -107,6 +107,12 @@ static void updateSketch(final HllSketch sketch, final Object value) for (String v : list) { sketch.update(v.toCharArray()); } + } else if (value instanceof String[]) { + // noinspection unchecked + String[] list = (String[]) value; + for (String v : list) { + sketch.update(v.toCharArray()); + } } else if (value instanceof char[]) { sketch.update((char[]) value); } else if (value instanceof byte[]) { diff --git a/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/hll/HllSketchAggregatorTest.java b/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/hll/HllSketchAggregatorTest.java index e2c55be53552..7a37a1464373 100644 --- a/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/hll/HllSketchAggregatorTest.java +++ b/extensions-core/datasketches/src/test/java/org/apache/druid/query/aggregation/datasketches/hll/HllSketchAggregatorTest.java @@ -21,13 +21,16 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import org.apache.druid.java.util.common.granularity.Granularities; import org.apache.druid.java.util.common.guava.Sequence; +import org.apache.druid.math.expr.ExprMacroTable; import org.apache.druid.query.aggregation.AggregationTestHelper; import org.apache.druid.query.groupby.GroupByQueryConfig; import org.apache.druid.query.groupby.GroupByQueryRunnerTest; import org.apache.druid.query.groupby.ResultRow; +import org.apache.druid.segment.transform.ExpressionTransform; import org.junit.Assert; import org.junit.Rule; import org.junit.Test; @@ -42,6 +45,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; @RunWith(Parameterized.class) public class HllSketchAggregatorTest @@ -112,6 +116,34 @@ public void buildSketchesAtIngestionTime() throws Exception Assert.assertEquals(200, (double) row.get(0), 0.1); } + @Test + public void buildSketchesAtIngestionTimeMultiValueWithTransformations() throws Exception + { + Sequence seq = helper.createIndexAndRunQueryOnSegment( + new File(this.getClass().getClassLoader().getResource("hll/hll_raw.tsv").getFile()), + buildParserJson( + Collections.singletonList("dim"), + Arrays.asList("timestamp", "dim", "multiDim", "id"), + ImmutableList.of( + new ExpressionTransform( + "multiDimAppended", + "array_append(multiDim, '15')", + ExprMacroTable.nil() + ) + ) + ), + buildAggregatorJson("HLLSketchBuild", "multiDimAppended", !ROUND), + 0, // minTimestamp + Granularities.NONE, + 200, // maxRowCount + buildGroupByQueryJson("HLLSketchMerge", "sketch", !ROUND) + ); + List results = seq.toList(); + Assert.assertEquals(1, results.size()); + ResultRow row = results.get(0); + Assert.assertEquals(15, (double) row.get(0), 0.1); + } + @Test public void buildSketchesAtQueryTime() throws Exception { @@ -221,6 +253,48 @@ private static String buildParserJson(List dimensions, List colu return toJson(object); } + private static String buildParserJson( + List dimensions, + List columns, + List transforms + ) + { + List> transformsObjects = transforms.stream().map(transform -> + ImmutableMap.of( + "type", "expression", + "name", transform.getName(), + "expression", transform.getExpression() + ) + ).collect(Collectors.toList()); + + Map transformsObject = ImmutableMap.of( + "transforms", transformsObjects + ); + + Map timestampSpec = ImmutableMap.of( + "column", "timestamp", + "format", "yyyyMMdd" + ); + Map dimensionsSpec = ImmutableMap.of( + "dimensions", dimensions, + "dimensionExclusions", Collections.emptyList(), + "spatialDimensions", Collections.emptyList() + ); + Map parseSpec = ImmutableMap.of( + "format", "tsv", + "timestampSpec", timestampSpec, + "dimensionsSpec", dimensionsSpec, + "columns", columns, + "listDelimiter", "," + ); + Map object = ImmutableMap.of( + "type", "string", + "parseSpec", parseSpec, + "transformSpec", transformsObject + ); + return toJson(object); + } + private static String toJson(Object object) { final String json;