diff --git a/processing/src/main/java/io/druid/query/extraction/BucketExtractionFn.java b/processing/src/main/java/io/druid/query/extraction/BucketExtractionFn.java index 2e8d24fa007..55fee2e237b 100644 --- a/processing/src/main/java/io/druid/query/extraction/BucketExtractionFn.java +++ b/processing/src/main/java/io/druid/query/extraction/BucketExtractionFn.java @@ -56,8 +56,13 @@ public class BucketExtractionFn implements ExtractionFn } @Override - public String apply(Object value) + @Nullable + public String apply(@Nullable Object value) { + if (value == null) { + return null; + } + if (value instanceof Number) { return bucket(((Number) value).doubleValue()); } else if (value instanceof String) { @@ -67,8 +72,13 @@ public class BucketExtractionFn implements ExtractionFn } @Override - public String apply(String value) + @Nullable + public String apply(@Nullable String value) { + if (value == null) { + return null; + } + try { return bucket(Double.parseDouble(value)); } diff --git a/processing/src/main/java/io/druid/query/extraction/CascadeExtractionFn.java b/processing/src/main/java/io/druid/query/extraction/CascadeExtractionFn.java index 22e51b726c3..f9b5e604f40 100644 --- a/processing/src/main/java/io/druid/query/extraction/CascadeExtractionFn.java +++ b/processing/src/main/java/io/druid/query/extraction/CascadeExtractionFn.java @@ -25,6 +25,7 @@ import com.google.common.base.Joiner; import com.google.common.base.Preconditions; import com.google.common.primitives.Bytes; +import javax.annotation.Nullable; import java.util.Arrays; public class CascadeExtractionFn implements ExtractionFn @@ -40,14 +41,16 @@ public class CascadeExtractionFn implements ExtractionFn return new byte[0]; } + @Nullable @Override - public String apply(Object value) + public String apply(@Nullable Object value) { return null; } + @Nullable @Override - public String apply(String value) + public String apply(@Nullable String value) { return null; } @@ -113,13 +116,15 @@ public class CascadeExtractionFn implements ExtractionFn } @Override - public String apply(Object value) + @Nullable + public String apply(@Nullable Object value) { return chainedExtractionFn.apply(value); } @Override - public String apply(String value) + @Nullable + public String apply(@Nullable String value) { return chainedExtractionFn.apply(value); } @@ -195,12 +200,14 @@ public class CascadeExtractionFn implements ExtractionFn return (child != null) ? Bytes.concat(fnCacheKey, child.getCacheKey()) : fnCacheKey; } - public String apply(Object value) + @Nullable + public String apply(@Nullable Object value) { return fn.apply((child != null) ? child.apply(value) : value); } - public String apply(String value) + @Nullable + public String apply(@Nullable String value) { return fn.apply((child != null) ? child.apply(value) : value); } diff --git a/processing/src/main/java/io/druid/query/extraction/DimExtractionFn.java b/processing/src/main/java/io/druid/query/extraction/DimExtractionFn.java index 40c9d77b77a..7cfbe32c593 100644 --- a/processing/src/main/java/io/druid/query/extraction/DimExtractionFn.java +++ b/processing/src/main/java/io/druid/query/extraction/DimExtractionFn.java @@ -19,12 +19,14 @@ package io.druid.query.extraction; +import javax.annotation.Nullable; import java.util.Objects; public abstract class DimExtractionFn implements ExtractionFn { @Override - public String apply(Object value) + @Nullable + public String apply(@Nullable Object value) { return apply(Objects.toString(value, null)); } diff --git a/processing/src/main/java/io/druid/query/extraction/ExtractionFn.java b/processing/src/main/java/io/druid/query/extraction/ExtractionFn.java index 3a8820a4e5b..0bfe2033fc7 100644 --- a/processing/src/main/java/io/druid/query/extraction/ExtractionFn.java +++ b/processing/src/main/java/io/druid/query/extraction/ExtractionFn.java @@ -24,6 +24,8 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo; import io.druid.query.lookup.LookupExtractionFn; import io.druid.query.lookup.RegisteredLookupExtractionFn; +import javax.annotation.Nullable; + /** */ @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") @@ -75,7 +77,8 @@ public interface ExtractionFn * * @return a value that should be used instead of the original */ - public String apply(Object value); + @Nullable + public String apply(@Nullable Object value); /** * The "extraction" function. This should map a String value into some other String value. @@ -87,7 +90,8 @@ public interface ExtractionFn * * @return a value that should be used instead of the original */ - public String apply(String value); + @Nullable + public String apply(@Nullable String value); /** * The "extraction" function. This should map a long value into some String value. diff --git a/processing/src/main/java/io/druid/query/extraction/FunctionalExtraction.java b/processing/src/main/java/io/druid/query/extraction/FunctionalExtraction.java index a85b3827b98..bd762574efd 100644 --- a/processing/src/main/java/io/druid/query/extraction/FunctionalExtraction.java +++ b/processing/src/main/java/io/druid/query/extraction/FunctionalExtraction.java @@ -105,7 +105,8 @@ public abstract class FunctionalExtraction extends DimExtractionFn } @Override - public String apply(String value) + @Nullable + public String apply(@Nullable String value) { return extractionFunction.apply(value); } diff --git a/processing/src/main/java/io/druid/query/extraction/IdentityExtractionFn.java b/processing/src/main/java/io/druid/query/extraction/IdentityExtractionFn.java index 9d9153efabd..d0158e7f27e 100644 --- a/processing/src/main/java/io/druid/query/extraction/IdentityExtractionFn.java +++ b/processing/src/main/java/io/druid/query/extraction/IdentityExtractionFn.java @@ -21,6 +21,8 @@ package io.druid.query.extraction; import com.google.common.base.Strings; +import javax.annotation.Nullable; + public class IdentityExtractionFn implements ExtractionFn { private static final IdentityExtractionFn instance = new IdentityExtractionFn(); @@ -37,13 +39,15 @@ public class IdentityExtractionFn implements ExtractionFn } @Override - public String apply(Object value) + @Nullable + public String apply(@Nullable Object value) { return value == null ? null : Strings.emptyToNull(value.toString()); } @Override - public String apply(String value) + @Nullable + public String apply(@Nullable String value) { return Strings.emptyToNull(value); } diff --git a/processing/src/main/java/io/druid/query/extraction/JavaScriptExtractionFn.java b/processing/src/main/java/io/druid/query/extraction/JavaScriptExtractionFn.java index bfb7987b0d0..51efd136844 100644 --- a/processing/src/main/java/io/druid/query/extraction/JavaScriptExtractionFn.java +++ b/processing/src/main/java/io/druid/query/extraction/JavaScriptExtractionFn.java @@ -32,6 +32,7 @@ import org.mozilla.javascript.Context; import org.mozilla.javascript.ContextFactory; import org.mozilla.javascript.ScriptableObject; +import javax.annotation.Nullable; import java.nio.ByteBuffer; public class JavaScriptExtractionFn implements ExtractionFn @@ -111,7 +112,8 @@ public class JavaScriptExtractionFn implements ExtractionFn } @Override - public String apply(Object value) + @Nullable + public String apply(@Nullable Object value) { if (fn == null) { throw new ISE("JavaScript is disabled"); @@ -121,7 +123,8 @@ public class JavaScriptExtractionFn implements ExtractionFn } @Override - public String apply(String value) + @Nullable + public String apply(@Nullable String value) { return this.apply((Object) Strings.emptyToNull(value)); } diff --git a/processing/src/main/java/io/druid/query/extraction/LowerExtractionFn.java b/processing/src/main/java/io/druid/query/extraction/LowerExtractionFn.java index 3fb1d83d36d..da2a8e3bc70 100644 --- a/processing/src/main/java/io/druid/query/extraction/LowerExtractionFn.java +++ b/processing/src/main/java/io/druid/query/extraction/LowerExtractionFn.java @@ -50,7 +50,7 @@ public class LowerExtractionFn extends DimExtractionFn @Nullable @Override - public String apply(String key) + public String apply(@Nullable String key) { if (Strings.isNullOrEmpty(key)) { return null; diff --git a/processing/src/main/java/io/druid/query/extraction/MatchingDimExtractionFn.java b/processing/src/main/java/io/druid/query/extraction/MatchingDimExtractionFn.java index 384ff3fcee2..4d121be031f 100644 --- a/processing/src/main/java/io/druid/query/extraction/MatchingDimExtractionFn.java +++ b/processing/src/main/java/io/druid/query/extraction/MatchingDimExtractionFn.java @@ -25,6 +25,7 @@ import com.google.common.base.Preconditions; import com.google.common.base.Strings; import io.druid.java.util.common.StringUtils; +import javax.annotation.Nullable; import java.nio.ByteBuffer; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -57,8 +58,9 @@ public class MatchingDimExtractionFn extends DimExtractionFn .array(); } + @Nullable @Override - public String apply(String dimValue) + public String apply(@Nullable String dimValue) { if (Strings.isNullOrEmpty(dimValue)) { // We'd return null whether or not the pattern matched diff --git a/processing/src/main/java/io/druid/query/extraction/RegexDimExtractionFn.java b/processing/src/main/java/io/druid/query/extraction/RegexDimExtractionFn.java index 6919319675a..3a1b0a5cc29 100644 --- a/processing/src/main/java/io/druid/query/extraction/RegexDimExtractionFn.java +++ b/processing/src/main/java/io/druid/query/extraction/RegexDimExtractionFn.java @@ -26,6 +26,7 @@ import com.google.common.base.Strings; import com.google.common.primitives.Ints; import io.druid.java.util.common.StringUtils; +import javax.annotation.Nullable; import java.nio.ByteBuffer; import java.util.Objects; import java.util.regex.Matcher; @@ -100,8 +101,9 @@ public class RegexDimExtractionFn extends DimExtractionFn .array(); } + @Nullable @Override - public String apply(String dimValue) + public String apply(@Nullable String dimValue) { final String retVal; final Matcher matcher = pattern.matcher(Strings.nullToEmpty(dimValue)); diff --git a/processing/src/main/java/io/druid/query/extraction/SearchQuerySpecDimExtractionFn.java b/processing/src/main/java/io/druid/query/extraction/SearchQuerySpecDimExtractionFn.java index 77ba930680e..b80971ec2db 100644 --- a/processing/src/main/java/io/druid/query/extraction/SearchQuerySpecDimExtractionFn.java +++ b/processing/src/main/java/io/druid/query/extraction/SearchQuerySpecDimExtractionFn.java @@ -25,6 +25,7 @@ import com.google.common.base.Preconditions; import com.google.common.base.Strings; import io.druid.query.search.search.SearchQuerySpec; +import javax.annotation.Nullable; import java.nio.ByteBuffer; /** @@ -59,8 +60,9 @@ public class SearchQuerySpecDimExtractionFn extends DimExtractionFn .array(); } + @Nullable @Override - public String apply(String dimValue) + public String apply(@Nullable String dimValue) { return searchQuerySpec.accept(dimValue) ? Strings.emptyToNull(dimValue) : null; } diff --git a/processing/src/main/java/io/druid/query/extraction/StringFormatExtractionFn.java b/processing/src/main/java/io/druid/query/extraction/StringFormatExtractionFn.java index bad6f446a65..1b22d28abfc 100644 --- a/processing/src/main/java/io/druid/query/extraction/StringFormatExtractionFn.java +++ b/processing/src/main/java/io/druid/query/extraction/StringFormatExtractionFn.java @@ -26,6 +26,7 @@ import com.google.common.base.Preconditions; import com.google.common.base.Strings; import io.druid.java.util.common.StringUtils; +import javax.annotation.Nullable; import java.nio.ByteBuffer; /** @@ -94,8 +95,9 @@ public class StringFormatExtractionFn extends DimExtractionFn .array(); } + @Nullable @Override - public String apply(String value) + public String apply(@Nullable String value) { if (value == null) { if (nullHandling == NullHandling.RETURNNULL) { diff --git a/processing/src/main/java/io/druid/query/extraction/StrlenExtractionFn.java b/processing/src/main/java/io/druid/query/extraction/StrlenExtractionFn.java index d863a6dff76..5ad88fa38fc 100644 --- a/processing/src/main/java/io/druid/query/extraction/StrlenExtractionFn.java +++ b/processing/src/main/java/io/druid/query/extraction/StrlenExtractionFn.java @@ -21,6 +21,8 @@ package io.druid.query.extraction; import com.fasterxml.jackson.annotation.JsonCreator; +import javax.annotation.Nullable; + public class StrlenExtractionFn extends DimExtractionFn { private static final StrlenExtractionFn INSTANCE = new StrlenExtractionFn(); @@ -36,7 +38,7 @@ public class StrlenExtractionFn extends DimExtractionFn } @Override - public String apply(String value) + public String apply(@Nullable String value) { return String.valueOf(value == null ? 0 : value.length()); } diff --git a/processing/src/main/java/io/druid/query/extraction/SubstringDimExtractionFn.java b/processing/src/main/java/io/druid/query/extraction/SubstringDimExtractionFn.java index 6c4214b4c7e..2d38806ddd4 100644 --- a/processing/src/main/java/io/druid/query/extraction/SubstringDimExtractionFn.java +++ b/processing/src/main/java/io/druid/query/extraction/SubstringDimExtractionFn.java @@ -61,8 +61,9 @@ public class SubstringDimExtractionFn extends DimExtractionFn .array(); } + @Nullable @Override - public String apply(String dimValue) + public String apply(@Nullable String dimValue) { if (Strings.isNullOrEmpty(dimValue)) { return null; diff --git a/processing/src/main/java/io/druid/query/extraction/TimeDimExtractionFn.java b/processing/src/main/java/io/druid/query/extraction/TimeDimExtractionFn.java index 91a9c16f97b..0aa7fdeb8ac 100644 --- a/processing/src/main/java/io/druid/query/extraction/TimeDimExtractionFn.java +++ b/processing/src/main/java/io/druid/query/extraction/TimeDimExtractionFn.java @@ -22,9 +22,11 @@ package io.druid.query.extraction; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.google.common.base.Preconditions; +import com.google.common.base.Strings; import com.ibm.icu.text.SimpleDateFormat; import io.druid.java.util.common.StringUtils; +import javax.annotation.Nullable; import java.nio.ByteBuffer; import java.text.ParseException; import java.util.Date; @@ -71,9 +73,14 @@ public class TimeDimExtractionFn extends DimExtractionFn .array(); } + @Nullable @Override - public String apply(String dimValue) + public String apply(@Nullable String dimValue) { + if (Strings.isNullOrEmpty(dimValue)) { + return null; + } + Date date; try { date = timeFormatter.get().parse(dimValue); diff --git a/processing/src/main/java/io/druid/query/extraction/TimeFormatExtractionFn.java b/processing/src/main/java/io/druid/query/extraction/TimeFormatExtractionFn.java index 059d3079fc8..fa66b5c2d75 100644 --- a/processing/src/main/java/io/druid/query/extraction/TimeFormatExtractionFn.java +++ b/processing/src/main/java/io/druid/query/extraction/TimeFormatExtractionFn.java @@ -31,6 +31,7 @@ import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; import org.joda.time.format.ISODateTimeFormat; +import javax.annotation.Nullable; import java.nio.ByteBuffer; import java.util.Locale; @@ -128,8 +129,13 @@ public class TimeFormatExtractionFn implements ExtractionFn } @Override - public String apply(Object value) + @Nullable + public String apply(@Nullable Object value) { + if (value == null) { + return null; + } + if (asMillis && value instanceof String) { final Long theLong = GuavaUtils.tryParseLong((String) value); return theLong == null ? apply(new DateTime(value).getMillis()) : apply(theLong.longValue()); @@ -139,7 +145,8 @@ public class TimeFormatExtractionFn implements ExtractionFn } @Override - public String apply(String value) + @Nullable + public String apply(@Nullable String value) { return apply((Object) value); } diff --git a/processing/src/main/java/io/druid/query/extraction/UpperExtractionFn.java b/processing/src/main/java/io/druid/query/extraction/UpperExtractionFn.java index 3837433e389..34368f7f0fd 100644 --- a/processing/src/main/java/io/druid/query/extraction/UpperExtractionFn.java +++ b/processing/src/main/java/io/druid/query/extraction/UpperExtractionFn.java @@ -49,7 +49,7 @@ public class UpperExtractionFn extends DimExtractionFn */ @Nullable @Override - public String apply(String key) + public String apply(@Nullable String key) { if (Strings.isNullOrEmpty(key)) { return null; diff --git a/processing/src/main/java/io/druid/query/lookup/RegisteredLookupExtractionFn.java b/processing/src/main/java/io/druid/query/lookup/RegisteredLookupExtractionFn.java index 98de89cc8de..525f72dcb78 100644 --- a/processing/src/main/java/io/druid/query/lookup/RegisteredLookupExtractionFn.java +++ b/processing/src/main/java/io/druid/query/lookup/RegisteredLookupExtractionFn.java @@ -105,13 +105,15 @@ public class RegisteredLookupExtractionFn implements ExtractionFn } @Override - public String apply(Object value) + @Nullable + public String apply(@Nullable Object value) { return ensureDelegate().apply(value); } @Override - public String apply(String value) + @Nullable + public String apply(@Nullable String value) { return ensureDelegate().apply(value); } diff --git a/processing/src/main/java/io/druid/query/search/search/AllSearchQuerySpec.java b/processing/src/main/java/io/druid/query/search/search/AllSearchQuerySpec.java index 14350542921..4f64561fe94 100644 --- a/processing/src/main/java/io/druid/query/search/search/AllSearchQuerySpec.java +++ b/processing/src/main/java/io/druid/query/search/search/AllSearchQuerySpec.java @@ -19,6 +19,8 @@ package io.druid.query.search.search; +import javax.annotation.Nullable; + /** */ public class AllSearchQuerySpec implements SearchQuerySpec @@ -26,7 +28,7 @@ public class AllSearchQuerySpec implements SearchQuerySpec private static final byte CACHE_TYPE_ID = 0x7f; @Override - public boolean accept(String dimVal) + public boolean accept(@Nullable String dimVal) { return true; } diff --git a/processing/src/main/java/io/druid/query/search/search/ContainsSearchQuerySpec.java b/processing/src/main/java/io/druid/query/search/search/ContainsSearchQuerySpec.java index 98a776481d1..3ea9d0d0c70 100644 --- a/processing/src/main/java/io/druid/query/search/search/ContainsSearchQuerySpec.java +++ b/processing/src/main/java/io/druid/query/search/search/ContainsSearchQuerySpec.java @@ -24,6 +24,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.google.common.base.Objects; import io.druid.java.util.common.StringUtils; +import javax.annotation.Nullable; import java.nio.ByteBuffer; /** @@ -59,7 +60,7 @@ public class ContainsSearchQuerySpec implements SearchQuerySpec } @Override - public boolean accept(String dimVal) + public boolean accept(@Nullable String dimVal) { if (dimVal == null || value == null) { return false; diff --git a/processing/src/main/java/io/druid/query/search/search/FragmentSearchQuerySpec.java b/processing/src/main/java/io/druid/query/search/search/FragmentSearchQuerySpec.java index 19ed38533e9..9798bd30560 100644 --- a/processing/src/main/java/io/druid/query/search/search/FragmentSearchQuerySpec.java +++ b/processing/src/main/java/io/druid/query/search/search/FragmentSearchQuerySpec.java @@ -23,6 +23,7 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import io.druid.java.util.common.StringUtils; +import javax.annotation.Nullable; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.List; @@ -77,7 +78,7 @@ public class FragmentSearchQuerySpec implements SearchQuerySpec } @Override - public boolean accept(String dimVal) + public boolean accept(@Nullable String dimVal) { if (dimVal == null || values == null) { return false; diff --git a/processing/src/main/java/io/druid/query/search/search/RegexSearchQuerySpec.java b/processing/src/main/java/io/druid/query/search/search/RegexSearchQuerySpec.java index 847eb2f9a52..085a1216bcc 100644 --- a/processing/src/main/java/io/druid/query/search/search/RegexSearchQuerySpec.java +++ b/processing/src/main/java/io/druid/query/search/search/RegexSearchQuerySpec.java @@ -24,6 +24,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.google.common.base.Preconditions; import io.druid.java.util.common.StringUtils; +import javax.annotation.Nullable; import java.nio.ByteBuffer; import java.util.regex.Pattern; @@ -74,7 +75,7 @@ public class RegexSearchQuerySpec implements SearchQuerySpec } @Override - public boolean accept(String dimVal) + public boolean accept(@Nullable String dimVal) { if (dimVal == null) { return false; diff --git a/processing/src/main/java/io/druid/query/search/search/SearchQuerySpec.java b/processing/src/main/java/io/druid/query/search/search/SearchQuerySpec.java index 55c9c1a8551..b3429a3c8cb 100644 --- a/processing/src/main/java/io/druid/query/search/search/SearchQuerySpec.java +++ b/processing/src/main/java/io/druid/query/search/search/SearchQuerySpec.java @@ -22,6 +22,8 @@ package io.druid.query.search.search; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; +import javax.annotation.Nullable; + /** */ @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") @@ -34,7 +36,7 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo; }) public interface SearchQuerySpec { - public boolean accept(String dimVal); + public boolean accept(@Nullable String dimVal); public byte[] getCacheKey(); } diff --git a/processing/src/test/java/io/druid/query/extraction/TimeDimExtractionFnTest.java b/processing/src/test/java/io/druid/query/extraction/TimeDimExtractionFnTest.java index 23254e905a7..e8424c0314c 100644 --- a/processing/src/test/java/io/druid/query/extraction/TimeDimExtractionFnTest.java +++ b/processing/src/test/java/io/druid/query/extraction/TimeDimExtractionFnTest.java @@ -40,6 +40,16 @@ public class TimeDimExtractionFnTest "12/21/2012" }; + @Test + public void testEmptyAndNullExtraction() + { + Set testPeriod = Sets.newHashSet(); + ExtractionFn extractionFn = new TimeDimExtractionFn("MM/dd/yyyy", "MM/yyyy"); + + Assert.assertNull(extractionFn.apply(null)); + Assert.assertNull(extractionFn.apply("")); + } + @Test public void testMonthExtraction() { diff --git a/processing/src/test/java/io/druid/segment/filter/SelectorFilterTest.java b/processing/src/test/java/io/druid/segment/filter/SelectorFilterTest.java index 5eae5e1bdd0..e3bd81b4727 100644 --- a/processing/src/test/java/io/druid/segment/filter/SelectorFilterTest.java +++ b/processing/src/test/java/io/druid/segment/filter/SelectorFilterTest.java @@ -30,6 +30,7 @@ import io.druid.data.input.impl.TimeAndDimsParseSpec; import io.druid.data.input.impl.TimestampSpec; import io.druid.java.util.common.Pair; import io.druid.query.extraction.MapLookupExtractor; +import io.druid.query.extraction.TimeDimExtractionFn; import io.druid.query.filter.ExtractionDimFilter; import io.druid.query.filter.InDimFilter; import io.druid.query.filter.SelectorDimFilter; @@ -58,7 +59,7 @@ public class SelectorFilterTest extends BaseFilterTest new TimeAndDimsParseSpec( new TimestampSpec(TIMESTAMP_COLUMN, "iso", new DateTime("2000")), new DimensionsSpec( - DimensionsSpec.getDefaultSchemas(ImmutableList.of("dim0", "dim1", "dim2", "dim3")), + DimensionsSpec.getDefaultSchemas(ImmutableList.of("dim0", "dim1", "dim2", "dim3", "dim6")), null, null ) @@ -66,9 +67,9 @@ public class SelectorFilterTest extends BaseFilterTest ); private static final List ROWS = ImmutableList.of( - PARSER.parse(ImmutableMap.of("dim0", "0", "dim1", "", "dim2", ImmutableList.of("a", "b"))), - PARSER.parse(ImmutableMap.of("dim0", "1", "dim1", "10", "dim2", ImmutableList.of())), - PARSER.parse(ImmutableMap.of("dim0", "2", "dim1", "2", "dim2", ImmutableList.of(""))), + PARSER.parse(ImmutableMap.of("dim0", "0", "dim1", "", "dim2", ImmutableList.of("a", "b"), "dim6", "2017-07-25")), + PARSER.parse(ImmutableMap.of("dim0", "1", "dim1", "10", "dim2", ImmutableList.of(), "dim6", "2017-07-25")), + PARSER.parse(ImmutableMap.of("dim0", "2", "dim1", "2", "dim2", ImmutableList.of(""), "dim6", "2017-05-25")), PARSER.parse(ImmutableMap.of("dim0", "3", "dim1", "1", "dim2", ImmutableList.of("a"))), PARSER.parse(ImmutableMap.of("dim0", "4", "dim1", "def", "dim2", ImmutableList.of("c"))), PARSER.parse(ImmutableMap.of("dim0", "5", "dim1", "abc")) @@ -91,6 +92,15 @@ public class SelectorFilterTest extends BaseFilterTest BaseFilterTest.tearDown(SelectorFilterTest.class.getName()); } + @Test + public void testWithTimeExtractionFnNull() + { + assertFilterMatches(new SelectorDimFilter("dim0", null, new TimeDimExtractionFn("yyyy-mm-dd", "yyyy-mm")), ImmutableList.of()); + assertFilterMatches(new SelectorDimFilter("dim6", null, new TimeDimExtractionFn("yyyy-mm-dd", "yyyy-mm")), ImmutableList.of("3", "4", "5")); + assertFilterMatches(new SelectorDimFilter("dim6", "2017-07", new TimeDimExtractionFn("yyyy-mm-dd", "yyyy-mm")), ImmutableList.of("0", "1")); + assertFilterMatches(new SelectorDimFilter("dim6", "2017-05", new TimeDimExtractionFn("yyyy-mm-dd", "yyyy-mm")), ImmutableList.of("2")); + } + @Test public void testSingleValueStringColumnWithoutNulls() {