diff --git a/processing/src/main/java/org/apache/druid/segment/AutoTypeColumnIndexer.java b/processing/src/main/java/org/apache/druid/segment/AutoTypeColumnIndexer.java index 3e47ef2da9e1..a2230cb2972c 100644 --- a/processing/src/main/java/org/apache/druid/segment/AutoTypeColumnIndexer.java +++ b/processing/src/main/java/org/apache/druid/segment/AutoTypeColumnIndexer.java @@ -281,7 +281,7 @@ public StructuredData getMaxValue() @Override public int getCardinality() { - return globalDictionary.getCardinality(); + return DimensionDictionarySelector.CARDINALITY_UNKNOWN; } @Override diff --git a/processing/src/main/java/org/apache/druid/segment/serde/NestedCommonFormatColumnPartSerde.java b/processing/src/main/java/org/apache/druid/segment/serde/NestedCommonFormatColumnPartSerde.java index a80bebf129fb..7a0ea7437846 100644 --- a/processing/src/main/java/org/apache/druid/segment/serde/NestedCommonFormatColumnPartSerde.java +++ b/processing/src/main/java/org/apache/druid/segment/serde/NestedCommonFormatColumnPartSerde.java @@ -203,6 +203,7 @@ public void read(ByteBuffer buffer, ColumnBuilder builder, ColumnConfig columnCo capabilitiesBuilder.setDictionaryValuesSorted(true); capabilitiesBuilder.setDictionaryValuesUnique(true); builder.setType(logicalType); + builder.setHasNulls(hasNulls); builder.setNestedCommonFormatColumnSupplier(supplier); builder.setIndexSupplier(supplier, true, false); builder.setColumnFormat(new NestedCommonFormatColumn.Format(logicalType, capabilitiesBuilder.hasNulls().isTrue(), enforceLogicalType)); @@ -225,6 +226,7 @@ public void read(ByteBuffer buffer, ColumnBuilder builder, ColumnConfig columnCo // technically, these columns are dictionary encoded, however they do not implement the DictionaryEncodedColumn // interface, so do not make the claim in the ColumnCapabilities builder.setType(logicalType); + builder.setHasNulls(hasNulls); builder.setNestedCommonFormatColumnSupplier(supplier); builder.setIndexSupplier(supplier, true, false); builder.setColumnFormat(new NestedCommonFormatColumn.Format(logicalType, capabilitiesBuilder.hasNulls().isTrue(), enforceLogicalType)); @@ -247,6 +249,7 @@ public void read(ByteBuffer buffer, ColumnBuilder builder, ColumnConfig columnCo // technically, these columns are dictionary encoded, however they do not implement the DictionaryEncodedColumn // interface, so do not make the claim in the ColumnCapabilities builder.setType(logicalType); + builder.setHasNulls(hasNulls); builder.setNestedCommonFormatColumnSupplier(supplier); builder.setIndexSupplier(supplier, true, false); builder.setColumnFormat(new NestedCommonFormatColumn.Format(logicalType, capabilitiesBuilder.hasNulls().isTrue(), enforceLogicalType)); @@ -275,6 +278,7 @@ public void read(ByteBuffer buffer, ColumnBuilder builder, ColumnConfig columnCo capabilitiesBuilder.setDictionaryValuesUnique(true); } builder.setType(logicalType); + builder.setHasNulls(hasNulls); builder.setNestedCommonFormatColumnSupplier(supplier); builder.setIndexSupplier(supplier, true, false); builder.setColumnFormat(new NestedCommonFormatColumn.Format( @@ -306,6 +310,7 @@ public void read(ByteBuffer buffer, ColumnBuilder builder, ColumnConfig columnCo ColumnType simpleType = supplier.getLogicalType(); ColumnType logicalType = simpleType == null ? ColumnType.NESTED_DATA : simpleType; builder.setType(logicalType); + builder.setHasNulls(hasNulls); builder.setNestedCommonFormatColumnSupplier(supplier); // in default value mode, SQL planning by default uses selector filters for things like 'is null', which does // not work correctly for complex types (or arrays). so, only hook up this index in sql compatible mode so that diff --git a/processing/src/test/java/org/apache/druid/query/groupby/NestedDataGroupByQueryTest.java b/processing/src/test/java/org/apache/druid/query/groupby/NestedDataGroupByQueryTest.java index 12bf586527ab..77f86bdc4c50 100644 --- a/processing/src/test/java/org/apache/druid/query/groupby/NestedDataGroupByQueryTest.java +++ b/processing/src/test/java/org/apache/druid/query/groupby/NestedDataGroupByQueryTest.java @@ -622,6 +622,30 @@ public void testGroupBySomeFieldOnLongColumnFilterNil() ); } + @Test + public void testGroupByRootAuto() + { + GroupByQuery groupQuery = GroupByQuery.builder() + .setDataSource("test_datasource") + .setGranularity(Granularities.ALL) + .setInterval(Intervals.ETERNITY) + .setDimensions(DefaultDimensionSpec.of("dim")) + .setAggregatorSpecs(new CountAggregatorFactory("count")) + .setContext(getContext()) + .build(); + + + runResults( + groupQuery, + ImmutableList.of( + new Object[]{"100", 2L}, + new Object[]{"hello", 12L}, + new Object[]{"world", 2L} + ) + ); + } + + private void runResults( GroupByQuery groupQuery, List expectedResults diff --git a/processing/src/test/java/org/apache/druid/segment/AutoTypeColumnIndexerTest.java b/processing/src/test/java/org/apache/druid/segment/AutoTypeColumnIndexerTest.java index 59aedff5dbe5..3b0e4ec74feb 100644 --- a/processing/src/test/java/org/apache/druid/segment/AutoTypeColumnIndexerTest.java +++ b/processing/src/test/java/org/apache/druid/segment/AutoTypeColumnIndexerTest.java @@ -70,69 +70,69 @@ public void testKeySizeEstimation() { AutoTypeColumnIndexer indexer = new AutoTypeColumnIndexer("test", null); int baseCardinality = NullHandling.sqlCompatible() ? 0 : 2; - Assert.assertEquals(baseCardinality, indexer.getCardinality()); + Assert.assertEquals(baseCardinality, indexer.globalDictionary.getCardinality()); EncodedKeyComponent key; // new raw value, new field, new dictionary entry key = indexer.processRowValsToUnsortedEncodedKeyComponent(ImmutableMap.of("x", "foo"), false); Assert.assertEquals(228, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality + 1, indexer.getCardinality()); + Assert.assertEquals(baseCardinality + 1, indexer.globalDictionary.getCardinality()); // adding same value only adds estimated size of value itself key = indexer.processRowValsToUnsortedEncodedKeyComponent(ImmutableMap.of("x", "foo"), false); Assert.assertEquals(112, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality + 1, indexer.getCardinality()); + Assert.assertEquals(baseCardinality + 1, indexer.globalDictionary.getCardinality()); // new raw value, new field, new dictionary entry key = indexer.processRowValsToUnsortedEncodedKeyComponent(10L, false); Assert.assertEquals(94, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality + 2, indexer.getCardinality()); + Assert.assertEquals(baseCardinality + 2, indexer.globalDictionary.getCardinality()); // adding same value only adds estimated size of value itself key = indexer.processRowValsToUnsortedEncodedKeyComponent(10L, false); Assert.assertEquals(16, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality + 2, indexer.getCardinality()); + Assert.assertEquals(baseCardinality + 2, indexer.globalDictionary.getCardinality()); // new raw value, new dictionary entry key = indexer.processRowValsToUnsortedEncodedKeyComponent(11L, false); Assert.assertEquals(48, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality + 3, indexer.getCardinality()); + Assert.assertEquals(baseCardinality + 3, indexer.globalDictionary.getCardinality()); // new raw value, new fields key = indexer.processRowValsToUnsortedEncodedKeyComponent(ImmutableList.of(1L, 2L, 10L), false); Assert.assertEquals(168, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality + 6, indexer.getCardinality()); + Assert.assertEquals(baseCardinality + 6, indexer.globalDictionary.getCardinality()); // new raw value, re-use fields and dictionary key = indexer.processRowValsToUnsortedEncodedKeyComponent(ImmutableList.of(1L, 2L, 10L), false); Assert.assertEquals(104, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality + 6, indexer.getCardinality()); + Assert.assertEquals(baseCardinality + 6, indexer.globalDictionary.getCardinality()); // new raw value, new fields key = indexer.processRowValsToUnsortedEncodedKeyComponent( ImmutableMap.of("x", ImmutableList.of(1L, 2L, 10L)), false ); Assert.assertEquals(166, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality + 6, indexer.getCardinality()); + Assert.assertEquals(baseCardinality + 6, indexer.globalDictionary.getCardinality()); // new raw value key = indexer.processRowValsToUnsortedEncodedKeyComponent( ImmutableMap.of("x", ImmutableList.of(1L, 2L, 10L)), false ); Assert.assertEquals(166, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality + 6, indexer.getCardinality()); + Assert.assertEquals(baseCardinality + 6, indexer.globalDictionary.getCardinality()); key = indexer.processRowValsToUnsortedEncodedKeyComponent("", false); if (NullHandling.replaceWithDefault()) { Assert.assertEquals(0, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality + 7, indexer.getCardinality()); + Assert.assertEquals(baseCardinality + 7, indexer.globalDictionary.getCardinality()); } else { Assert.assertEquals(104, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality + 7, indexer.getCardinality()); + Assert.assertEquals(baseCardinality + 7, indexer.globalDictionary.getCardinality()); } key = indexer.processRowValsToUnsortedEncodedKeyComponent(0L, false); if (NullHandling.replaceWithDefault()) { Assert.assertEquals(16, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality + 7, indexer.getCardinality()); + Assert.assertEquals(baseCardinality + 7, indexer.globalDictionary.getCardinality()); } else { Assert.assertEquals(48, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality + 8, indexer.getCardinality()); + Assert.assertEquals(baseCardinality + 8, indexer.globalDictionary.getCardinality()); } } @@ -673,14 +673,14 @@ public void testConstantNull() key = indexer.processRowValsToUnsortedEncodedKeyComponent(null, true); Assert.assertEquals(0, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality, indexer.getCardinality()); + Assert.assertEquals(baseCardinality, indexer.globalDictionary.getCardinality()); key = indexer.processRowValsToUnsortedEncodedKeyComponent(null, true); Assert.assertEquals(0, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality, indexer.getCardinality()); + Assert.assertEquals(baseCardinality, indexer.globalDictionary.getCardinality()); key = indexer.processRowValsToUnsortedEncodedKeyComponent(null, true); Assert.assertEquals(0, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality, indexer.getCardinality()); + Assert.assertEquals(baseCardinality, indexer.globalDictionary.getCardinality()); Assert.assertTrue(indexer.hasNulls); @@ -698,14 +698,14 @@ public void testConstantString() key = indexer.processRowValsToUnsortedEncodedKeyComponent("abcd", true); Assert.assertEquals(166, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality + 1, indexer.getCardinality()); + Assert.assertEquals(baseCardinality + 1, indexer.globalDictionary.getCardinality()); key = indexer.processRowValsToUnsortedEncodedKeyComponent("abcd", true); Assert.assertEquals(52, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality + 1, indexer.getCardinality()); + Assert.assertEquals(baseCardinality + 1, indexer.globalDictionary.getCardinality()); key = indexer.processRowValsToUnsortedEncodedKeyComponent("abcd", true); Assert.assertEquals(52, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality + 1, indexer.getCardinality()); + Assert.assertEquals(baseCardinality + 1, indexer.globalDictionary.getCardinality()); Assert.assertFalse(indexer.hasNulls); Assert.assertFalse(indexer.hasNestedData); @@ -722,14 +722,14 @@ public void testConstantLong() key = indexer.processRowValsToUnsortedEncodedKeyComponent(1234L, true); Assert.assertEquals(94, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality + 1, indexer.getCardinality()); + Assert.assertEquals(baseCardinality + 1, indexer.globalDictionary.getCardinality()); key = indexer.processRowValsToUnsortedEncodedKeyComponent(1234L, true); Assert.assertEquals(16, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality + 1, indexer.getCardinality()); + Assert.assertEquals(baseCardinality + 1, indexer.globalDictionary.getCardinality()); key = indexer.processRowValsToUnsortedEncodedKeyComponent(1234L, true); Assert.assertEquals(16, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality + 1, indexer.getCardinality()); + Assert.assertEquals(baseCardinality + 1, indexer.globalDictionary.getCardinality()); Assert.assertFalse(indexer.hasNulls); Assert.assertFalse(indexer.hasNestedData); @@ -746,14 +746,14 @@ public void testConstantEmptyArray() key = indexer.processRowValsToUnsortedEncodedKeyComponent(ImmutableList.of(), true); Assert.assertEquals(54, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality + 1, indexer.getCardinality()); + Assert.assertEquals(baseCardinality + 1, indexer.globalDictionary.getCardinality()); key = indexer.processRowValsToUnsortedEncodedKeyComponent(ImmutableList.of(), true); Assert.assertEquals(8, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality + 1, indexer.getCardinality()); + Assert.assertEquals(baseCardinality + 1, indexer.globalDictionary.getCardinality()); key = indexer.processRowValsToUnsortedEncodedKeyComponent(ImmutableList.of(), true); Assert.assertEquals(8, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality + 1, indexer.getCardinality()); + Assert.assertEquals(baseCardinality + 1, indexer.globalDictionary.getCardinality()); Assert.assertFalse(indexer.hasNulls); Assert.assertFalse(indexer.hasNestedData); @@ -770,14 +770,14 @@ public void testConstantArray() key = indexer.processRowValsToUnsortedEncodedKeyComponent(ImmutableList.of(1L, 2L, 3L), true); Assert.assertEquals(246, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality + 4, indexer.getCardinality()); + Assert.assertEquals(baseCardinality + 4, indexer.globalDictionary.getCardinality()); key = indexer.processRowValsToUnsortedEncodedKeyComponent(ImmutableList.of(1L, 2L, 3L), true); Assert.assertEquals(104, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality + 4, indexer.getCardinality()); + Assert.assertEquals(baseCardinality + 4, indexer.globalDictionary.getCardinality()); key = indexer.processRowValsToUnsortedEncodedKeyComponent(ImmutableList.of(1L, 2L, 3L), true); Assert.assertEquals(104, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality + 4, indexer.getCardinality()); + Assert.assertEquals(baseCardinality + 4, indexer.globalDictionary.getCardinality()); Assert.assertFalse(indexer.hasNulls); Assert.assertFalse(indexer.hasNestedData); @@ -794,14 +794,14 @@ public void testConstantEmptyObject() key = indexer.processRowValsToUnsortedEncodedKeyComponent(ImmutableMap.of(), true); Assert.assertEquals(16, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality, indexer.getCardinality()); + Assert.assertEquals(baseCardinality, indexer.globalDictionary.getCardinality()); key = indexer.processRowValsToUnsortedEncodedKeyComponent(ImmutableMap.of(), true); Assert.assertEquals(16, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality, indexer.getCardinality()); + Assert.assertEquals(baseCardinality, indexer.globalDictionary.getCardinality()); key = indexer.processRowValsToUnsortedEncodedKeyComponent(ImmutableMap.of(), true); Assert.assertEquals(16, key.getEffectiveSizeBytes()); - Assert.assertEquals(baseCardinality, indexer.getCardinality()); + Assert.assertEquals(baseCardinality, indexer.globalDictionary.getCardinality()); Assert.assertFalse(indexer.hasNulls); Assert.assertTrue(indexer.hasNestedData); diff --git a/server/src/test/java/org/apache/druid/server/SpecificSegmentsQuerySegmentWalker.java b/server/src/test/java/org/apache/druid/server/SpecificSegmentsQuerySegmentWalker.java index cf301ceb81e7..4f70f01cf54d 100644 --- a/server/src/test/java/org/apache/druid/server/SpecificSegmentsQuerySegmentWalker.java +++ b/server/src/test/java/org/apache/druid/server/SpecificSegmentsQuerySegmentWalker.java @@ -36,6 +36,7 @@ import org.apache.druid.query.lookup.LookupExtractorFactoryContainer; import org.apache.druid.query.lookup.LookupExtractorFactoryContainerProvider; import org.apache.druid.segment.FrameBasedInlineSegmentWrangler; +import org.apache.druid.segment.IncrementalIndexSegment; import org.apache.druid.segment.InlineSegmentWrangler; import org.apache.druid.segment.LookupSegmentWrangler; import org.apache.druid.segment.MapSegmentWrangler; @@ -44,6 +45,7 @@ import org.apache.druid.segment.ReferenceCountingSegment; import org.apache.druid.segment.Segment; import org.apache.druid.segment.SegmentWrangler; +import org.apache.druid.segment.incremental.IncrementalIndex; import org.apache.druid.segment.join.JoinableFactory; import org.apache.druid.segment.join.JoinableFactoryWrapper; import org.apache.druid.server.initialization.ServerConfig; @@ -196,6 +198,11 @@ public SpecificSegmentsQuerySegmentWalker add(final DataSegment descriptor, fina return add(descriptor, new QueryableIndexSegment(index, descriptor.getId())); } + public SpecificSegmentsQuerySegmentWalker add(final DataSegment descriptor, final IncrementalIndex index) + { + return add(descriptor, new IncrementalIndexSegment(index, descriptor.getId())); + } + public List getSegments() { return segments; diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteNestedDataQueryTest.java b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteNestedDataQueryTest.java index ea1888caf541..00cf3a58b6e6 100644 --- a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteNestedDataQueryTest.java +++ b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteNestedDataQueryTest.java @@ -66,6 +66,7 @@ import org.apache.druid.segment.QueryableIndex; import org.apache.druid.segment.column.ColumnType; import org.apache.druid.segment.column.RowSignature; +import org.apache.druid.segment.incremental.IncrementalIndex; import org.apache.druid.segment.incremental.IncrementalIndexSchema; import org.apache.druid.segment.join.JoinableFactoryWrapper; import org.apache.druid.segment.virtual.ExpressionVirtualColumn; @@ -96,6 +97,7 @@ public class CalciteNestedDataQueryTest extends BaseCalciteQueryTest public static final String DATA_SOURCE_MIXED_2 = "nested_mix_2"; public static final String DATA_SOURCE_ARRAYS = "arrays"; public static final String DATA_SOURCE_ALL = "all_auto"; + public static final String DATA_SOURCE_ALL_REALTIME = "all_auto_realtime"; public static final List> RAW_ROWS = ImmutableList.of( ImmutableMap.builder() @@ -334,6 +336,30 @@ public SpecificSegmentsQuerySegmentWalker createQuerySegmentWalker( .inputTmpDir(tempDirProducer.newTempFolder()) .buildMMappedIndex(); + final IncrementalIndex indexAllTypesAutoRealtime = + IndexBuilder.create() + .tmpDir(tempDirProducer.newTempFolder()) + .segmentWriteOutMediumFactory(OffHeapMemorySegmentWriteOutMediumFactory.instance()) + .schema( + new IncrementalIndexSchema.Builder() + .withTimestampSpec(NestedDataTestUtils.AUTO_SCHEMA.getTimestampSpec()) + .withDimensionsSpec(NestedDataTestUtils.AUTO_SCHEMA.getDimensionsSpec()) + .withMetrics( + new CountAggregatorFactory("cnt") + ) + .withRollup(false) + .build() + ) + .inputSource( + ResourceInputSource.of( + NestedDataTestUtils.class.getClassLoader(), + NestedDataTestUtils.ALL_TYPES_TEST_DATA_FILE + ) + ) + .inputFormat(TestDataBuilder.DEFAULT_JSON_INPUT_FORMAT) + .inputTmpDir(tempDirProducer.newTempFolder()) + .buildIncrementalIndex(); + SpecificSegmentsQuerySegmentWalker walker = SpecificSegmentsQuerySegmentWalker.createWalker(injector, conglomerate); walker.add( @@ -399,6 +425,15 @@ public SpecificSegmentsQuerySegmentWalker createQuerySegmentWalker( .size(0) .build(), indexAllTypesAuto + ).add( + DataSegment.builder() + .dataSource(DATA_SOURCE_ALL_REALTIME) + .version("1") + .interval(indexAllTypesAutoRealtime.getInterval()) + .shardSpec(new LinearShardSpec(1)) + .size(0) + .build(), + indexAllTypesAutoRealtime ); return walker; @@ -7322,4 +7357,215 @@ public void testNvlJsonValueDoubleSometimesMissingEqualityFilter() .build() ); } + + @Test + public void testGroupByAutoString() + { + final List expected; + if (NullHandling.sqlCompatible()) { + expected = ImmutableList.of( + new Object[]{null, 1L}, + new Object[]{"", 1L}, + new Object[]{"a", 1L}, + new Object[]{"b", 1L}, + new Object[]{"c", 1L}, + new Object[]{"d", 1L}, + new Object[]{"null", 1L} + ); + } else { + expected = ImmutableList.of( + new Object[]{NullHandling.defaultStringValue(), 2L}, + new Object[]{"a", 1L}, + new Object[]{"b", 1L}, + new Object[]{"c", 1L}, + new Object[]{"d", 1L}, + new Object[]{"null", 1L} + ); + } + testQuery( + "SELECT " + + "str, " + + "SUM(cnt) " + + "FROM druid.all_auto GROUP BY 1", + ImmutableList.of( + GroupByQuery.builder() + .setDataSource(DATA_SOURCE_ALL) + .setInterval(querySegmentSpec(Filtration.eternity())) + .setGranularity(Granularities.ALL) + .setDimensions( + dimensions( + new DefaultDimensionSpec("str", "d0") + ) + ) + .setAggregatorSpecs(aggregators(new LongSumAggregatorFactory("a0", "cnt"))) + .setContext(QUERY_CONTEXT_DEFAULT) + .build() + ), + expected, + RowSignature.builder() + .add("str", ColumnType.STRING) + .add("EXPR$1", ColumnType.LONG) + .build() + ); + + cannotVectorize(); + msqIncompatible(); + testQuery( + "SELECT " + + "str, " + + "SUM(cnt) " + + "FROM druid.all_auto_realtime GROUP BY 1", + ImmutableList.of( + GroupByQuery.builder() + .setDataSource(DATA_SOURCE_ALL_REALTIME) + .setInterval(querySegmentSpec(Filtration.eternity())) + .setGranularity(Granularities.ALL) + .setDimensions( + dimensions( + new DefaultDimensionSpec("str", "d0") + ) + ) + .setAggregatorSpecs(aggregators(new LongSumAggregatorFactory("a0", "cnt"))) + .setContext(QUERY_CONTEXT_DEFAULT) + .build() + ), + expected, + RowSignature.builder() + .add("str", ColumnType.STRING) + .add("EXPR$1", ColumnType.LONG) + .build() + ); + } + + @Test + public void testGroupByAutoLong() + { + final List expected = ImmutableList.of( + new Object[]{NullHandling.defaultLongValue(), 2L}, + new Object[]{1L, 1L}, + new Object[]{2L, 1L}, + new Object[]{3L, 1L}, + new Object[]{4L, 1L}, + new Object[]{5L, 1L} + ); + testQuery( + "SELECT " + + "long, " + + "SUM(cnt) " + + "FROM druid.all_auto GROUP BY 1", + ImmutableList.of( + GroupByQuery.builder() + .setDataSource(DATA_SOURCE_ALL) + .setInterval(querySegmentSpec(Filtration.eternity())) + .setGranularity(Granularities.ALL) + .setDimensions( + dimensions( + new DefaultDimensionSpec("long", "d0", ColumnType.LONG) + ) + ) + .setAggregatorSpecs(aggregators(new LongSumAggregatorFactory("a0", "cnt"))) + .setContext(QUERY_CONTEXT_DEFAULT) + .build() + ), + expected, + RowSignature.builder() + .add("long", ColumnType.LONG) + .add("EXPR$1", ColumnType.LONG) + .build() + ); + + cannotVectorize(); + msqIncompatible(); + testQuery( + "SELECT " + + "long, " + + "SUM(cnt) " + + "FROM druid.all_auto_realtime GROUP BY 1", + ImmutableList.of( + GroupByQuery.builder() + .setDataSource(DATA_SOURCE_ALL_REALTIME) + .setInterval(querySegmentSpec(Filtration.eternity())) + .setGranularity(Granularities.ALL) + .setDimensions( + dimensions( + new DefaultDimensionSpec("long", "d0", ColumnType.LONG) + ) + ) + .setAggregatorSpecs(aggregators(new LongSumAggregatorFactory("a0", "cnt"))) + .setContext(QUERY_CONTEXT_DEFAULT) + .build() + ), + expected, + RowSignature.builder() + .add("long", ColumnType.LONG) + .add("EXPR$1", ColumnType.LONG) + .build() + ); + } + + @Test + public void testGroupByAutoDouble() + { + final List expected = ImmutableList.of( + new Object[]{NullHandling.defaultDoubleValue(), 2L}, + new Object[]{1.0D, 1L}, + new Object[]{2.0D, 1L}, + new Object[]{3.3D, 1L}, + new Object[]{4.4D, 1L}, + new Object[]{5.9D, 1L} + ); + testQuery( + "SELECT " + + "\"double\", " + + "SUM(cnt) " + + "FROM druid.all_auto GROUP BY 1", + ImmutableList.of( + GroupByQuery.builder() + .setDataSource(DATA_SOURCE_ALL) + .setInterval(querySegmentSpec(Filtration.eternity())) + .setGranularity(Granularities.ALL) + .setDimensions( + dimensions( + new DefaultDimensionSpec("double", "d0", ColumnType.DOUBLE) + ) + ) + .setAggregatorSpecs(aggregators(new LongSumAggregatorFactory("a0", "cnt"))) + .setContext(QUERY_CONTEXT_DEFAULT) + .build() + ), + expected, + RowSignature.builder() + .add("double", ColumnType.DOUBLE) + .add("EXPR$1", ColumnType.LONG) + .build() + ); + + cannotVectorize(); + msqIncompatible(); + testQuery( + "SELECT " + + "\"double\", " + + "SUM(cnt) " + + "FROM druid.all_auto_realtime GROUP BY 1", + ImmutableList.of( + GroupByQuery.builder() + .setDataSource(DATA_SOURCE_ALL_REALTIME) + .setInterval(querySegmentSpec(Filtration.eternity())) + .setGranularity(Granularities.ALL) + .setDimensions( + dimensions( + new DefaultDimensionSpec("double", "d0", ColumnType.DOUBLE) + ) + ) + .setAggregatorSpecs(aggregators(new LongSumAggregatorFactory("a0", "cnt"))) + .setContext(QUERY_CONTEXT_DEFAULT) + .build() + ), + expected, + RowSignature.builder() + .add("double", ColumnType.DOUBLE) + .add("EXPR$1", ColumnType.LONG) + .build() + ); + } }