NPE fix for alphaNumericTopN when pervious stop is not specified

This commit is contained in:
Parag Jain 2015-06-02 13:04:09 -05:00
parent 600b30566c
commit a7b09e857c
4 changed files with 96 additions and 7 deletions

View File

@ -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() + '\'' +
'}'; '}';
} }
} }

View File

@ -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);
}
} }

View File

@ -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>()));
}
} }

View File

@ -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);
}
} }