mirror of https://github.com/apache/druid.git
NPE fix for alphaNumericTopN when pervious stop is not specified
This commit is contained in:
parent
600b30566c
commit
a7b09e857c
|
@ -38,7 +38,11 @@ public class AlphaNumericTopNMetricSpec extends LexicographicTopNMetricSpec
|
||||||
{
|
{
|
||||||
int[] pos = {0, 0};
|
int[] pos = {0, 0};
|
||||||
|
|
||||||
if (str1.length() == 0) {
|
if (str1 == null) {
|
||||||
|
return -1;
|
||||||
|
} else if (str2 == null) {
|
||||||
|
return 1;
|
||||||
|
} else if (str1.length() == 0) {
|
||||||
return str2.length() == 0 ? 0 : -1;
|
return str2.length() == 0 ? 0 : -1;
|
||||||
} else if (str2.length() == 0) {
|
} else if (str2.length() == 0) {
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -179,15 +183,12 @@ public class AlphaNumericTopNMetricSpec extends LexicographicTopNMetricSpec
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private final String previousStop;
|
|
||||||
|
|
||||||
@JsonCreator
|
@JsonCreator
|
||||||
public AlphaNumericTopNMetricSpec(
|
public AlphaNumericTopNMetricSpec(
|
||||||
@JsonProperty("previousStop") String previousStop
|
@JsonProperty("previousStop") String previousStop
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
super(previousStop);
|
super(previousStop);
|
||||||
this.previousStop = (previousStop == null) ? "" : previousStop;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -199,7 +200,7 @@ public class AlphaNumericTopNMetricSpec extends LexicographicTopNMetricSpec
|
||||||
@Override
|
@Override
|
||||||
public byte[] getCacheKey()
|
public byte[] getCacheKey()
|
||||||
{
|
{
|
||||||
byte[] previousStopBytes = StringUtils.toUtf8(previousStop);
|
byte[] previousStopBytes = getPreviousStop() == null ? new byte[]{} : StringUtils.toUtf8(getPreviousStop());
|
||||||
|
|
||||||
return ByteBuffer.allocate(1 + previousStopBytes.length)
|
return ByteBuffer.allocate(1 + previousStopBytes.length)
|
||||||
.put(CACHE_TYPE_ID)
|
.put(CACHE_TYPE_ID)
|
||||||
|
@ -217,7 +218,7 @@ public class AlphaNumericTopNMetricSpec extends LexicographicTopNMetricSpec
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return "AlphaNumericTopNMetricSpec{" +
|
return "AlphaNumericTopNMetricSpec{" +
|
||||||
"previousStop='" + previousStop + '\'' +
|
"previousStop='" + getPreviousStop() + '\'' +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,11 +17,15 @@
|
||||||
|
|
||||||
package io.druid.query.topn;
|
package io.druid.query.topn;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import io.druid.jackson.DefaultObjectMapper;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
public class AlphaNumericTopNMetricSpecTest
|
public class AlphaNumericTopNMetricSpecTest
|
||||||
{
|
{
|
||||||
|
@ -60,4 +64,22 @@ public class AlphaNumericTopNMetricSpecTest
|
||||||
assertTrue(comparator.compare("1.3", "1.15") < 0);
|
assertTrue(comparator.compare("1.3", "1.15") < 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSerdeAlphaNumericTopNMetricSpec() throws IOException{
|
||||||
|
AlphaNumericTopNMetricSpec expectedMetricSpec = new AlphaNumericTopNMetricSpec(null);
|
||||||
|
AlphaNumericTopNMetricSpec expectedMetricSpec1 = new AlphaNumericTopNMetricSpec("test");
|
||||||
|
String jsonSpec = "{\n"
|
||||||
|
+ " \"type\": \"alphaNumeric\"\n"
|
||||||
|
+ "}";
|
||||||
|
String jsonSpec1 = "{\n"
|
||||||
|
+ " \"type\": \"alphaNumeric\",\n"
|
||||||
|
+ " \"previousStop\": \"test\"\n"
|
||||||
|
+ "}";
|
||||||
|
ObjectMapper jsonMapper = new DefaultObjectMapper();
|
||||||
|
TopNMetricSpec actualMetricSpec = jsonMapper.readValue(jsonMapper.writeValueAsString(jsonMapper.readValue(jsonSpec, TopNMetricSpec.class)), AlphaNumericTopNMetricSpec.class);
|
||||||
|
TopNMetricSpec actualMetricSpec1 = jsonMapper.readValue(jsonMapper.writeValueAsString(jsonMapper.readValue(jsonSpec1, TopNMetricSpec.class)), AlphaNumericTopNMetricSpec.class);
|
||||||
|
assertEquals(expectedMetricSpec, actualMetricSpec);
|
||||||
|
assertEquals(expectedMetricSpec1, actualMetricSpec1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2524,4 +2524,34 @@ public class TopNQueryRunnerTest
|
||||||
);
|
);
|
||||||
TestHelper.assertExpectedResults(expectedResults, runner.run(query, new HashMap<String, Object>()));
|
TestHelper.assertExpectedResults(expectedResults, runner.run(query, new HashMap<String, Object>()));
|
||||||
}
|
}
|
||||||
|
@Test
|
||||||
|
public void testAlphaNumericTopNWithNullPreviousStop(){
|
||||||
|
TopNQuery query = new TopNQueryBuilder()
|
||||||
|
.dataSource(QueryRunnerTestHelper.dataSource)
|
||||||
|
.granularity(QueryGranularity.ALL)
|
||||||
|
.dimension(QueryRunnerTestHelper.marketDimension)
|
||||||
|
.metric(new AlphaNumericTopNMetricSpec(null))
|
||||||
|
.threshold(2)
|
||||||
|
.intervals(QueryRunnerTestHelper.secondOnly)
|
||||||
|
.aggregators(Lists.<AggregatorFactory>newArrayList(QueryRunnerTestHelper.rowsCount))
|
||||||
|
.build();
|
||||||
|
List<Result<TopNResultValue>> expectedResults = Arrays.asList(
|
||||||
|
new Result<>(
|
||||||
|
new DateTime("2011-04-02T00:00:00.000Z"),
|
||||||
|
new TopNResultValue(
|
||||||
|
Arrays.asList(
|
||||||
|
ImmutableMap.<String, Object>of(
|
||||||
|
"market", "spot",
|
||||||
|
"rows", 9L
|
||||||
|
),
|
||||||
|
ImmutableMap.<String, Object>of(
|
||||||
|
"market", "total_market",
|
||||||
|
"rows", 2L
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
TestHelper.assertExpectedResults(expectedResults, runner.run(query, new HashMap<String, Object>()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ import io.druid.query.aggregation.AggregatorFactory;
|
||||||
import io.druid.query.aggregation.DoubleMaxAggregatorFactory;
|
import io.druid.query.aggregation.DoubleMaxAggregatorFactory;
|
||||||
import io.druid.query.aggregation.DoubleMinAggregatorFactory;
|
import io.druid.query.aggregation.DoubleMinAggregatorFactory;
|
||||||
import io.druid.query.aggregation.PostAggregator;
|
import io.druid.query.aggregation.PostAggregator;
|
||||||
|
import io.druid.query.dimension.LegacyDimensionSpec;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -39,6 +40,7 @@ import static io.druid.query.QueryRunnerTestHelper.dataSource;
|
||||||
import static io.druid.query.QueryRunnerTestHelper.fullOnInterval;
|
import static io.druid.query.QueryRunnerTestHelper.fullOnInterval;
|
||||||
import static io.druid.query.QueryRunnerTestHelper.indexMetric;
|
import static io.druid.query.QueryRunnerTestHelper.indexMetric;
|
||||||
import static io.druid.query.QueryRunnerTestHelper.marketDimension;
|
import static io.druid.query.QueryRunnerTestHelper.marketDimension;
|
||||||
|
import static io.druid.query.QueryRunnerTestHelper.rowsCount;
|
||||||
|
|
||||||
public class TopNQueryTest
|
public class TopNQueryTest
|
||||||
{
|
{
|
||||||
|
@ -74,4 +76,38 @@ public class TopNQueryTest
|
||||||
Assert.assertEquals(query, serdeQuery);
|
Assert.assertEquals(query, serdeQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testQuerySerdeWithAlphaNumericTopNMetricSpec() throws IOException{
|
||||||
|
TopNQuery expectedQuery = new TopNQueryBuilder()
|
||||||
|
.dataSource(dataSource)
|
||||||
|
.granularity(allGran)
|
||||||
|
.dimension(new LegacyDimensionSpec(marketDimension))
|
||||||
|
.metric(new AlphaNumericTopNMetricSpec(null))
|
||||||
|
.threshold(2)
|
||||||
|
.intervals(fullOnInterval.getIntervals())
|
||||||
|
.aggregators(Lists.<AggregatorFactory>newArrayList(rowsCount))
|
||||||
|
.build();
|
||||||
|
String jsonQuery = "{\n"
|
||||||
|
+ " \"queryType\": \"topN\",\n"
|
||||||
|
+ " \"dataSource\": \"testing\",\n"
|
||||||
|
+ " \"dimension\": \"market\",\n"
|
||||||
|
+ " \"threshold\": 2,\n"
|
||||||
|
+ " \"metric\": {\n"
|
||||||
|
+ " \"type\": \"alphaNumeric\"\n"
|
||||||
|
+ " },\n"
|
||||||
|
+ " \"granularity\": \"all\",\n"
|
||||||
|
+ " \"aggregations\": [\n"
|
||||||
|
+ " {\n"
|
||||||
|
+ " \"type\": \"count\",\n"
|
||||||
|
+ " \"name\": \"rows\"\n"
|
||||||
|
+ " }\n"
|
||||||
|
+ " ],\n"
|
||||||
|
+ " \"intervals\": [\n"
|
||||||
|
+ " \"1970-01-01T00:00:00.000Z/2020-01-01T00:00:00.000Z\"\n"
|
||||||
|
+ " ]\n"
|
||||||
|
+ "}";
|
||||||
|
TopNQuery actualQuery = jsonMapper.readValue(jsonMapper.writeValueAsString(jsonMapper.readValue(jsonQuery, TopNQuery.class)), TopNQuery.class);
|
||||||
|
Assert.assertEquals(expectedQuery, actualQuery);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue