mirror of https://github.com/apache/druid.git
NPE thrown when empty/null is passes to TimeDimExtractionFn (#4601)
* NPE thrown when empty/null is passes to TimeDimExtractionFn * Add @Nullable where ever applicable * Add @Nullable to SearchQuerySpec.apply() * Remove unused
This commit is contained in:
parent
5929066dfb
commit
da43f68e95
|
@ -56,8 +56,13 @@ public class BucketExtractionFn implements ExtractionFn
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String apply(Object value)
|
@Nullable
|
||||||
|
public String apply(@Nullable Object value)
|
||||||
{
|
{
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (value instanceof Number) {
|
if (value instanceof Number) {
|
||||||
return bucket(((Number) value).doubleValue());
|
return bucket(((Number) value).doubleValue());
|
||||||
} else if (value instanceof String) {
|
} else if (value instanceof String) {
|
||||||
|
@ -67,8 +72,13 @@ public class BucketExtractionFn implements ExtractionFn
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String apply(String value)
|
@Nullable
|
||||||
|
public String apply(@Nullable String value)
|
||||||
{
|
{
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return bucket(Double.parseDouble(value));
|
return bucket(Double.parseDouble(value));
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import com.google.common.base.Joiner;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.primitives.Bytes;
|
import com.google.common.primitives.Bytes;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class CascadeExtractionFn implements ExtractionFn
|
public class CascadeExtractionFn implements ExtractionFn
|
||||||
|
@ -40,14 +41,16 @@ public class CascadeExtractionFn implements ExtractionFn
|
||||||
return new byte[0];
|
return new byte[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public String apply(Object value)
|
public String apply(@Nullable Object value)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public String apply(String value)
|
public String apply(@Nullable String value)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -113,13 +116,15 @@ public class CascadeExtractionFn implements ExtractionFn
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String apply(Object value)
|
@Nullable
|
||||||
|
public String apply(@Nullable Object value)
|
||||||
{
|
{
|
||||||
return chainedExtractionFn.apply(value);
|
return chainedExtractionFn.apply(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String apply(String value)
|
@Nullable
|
||||||
|
public String apply(@Nullable String value)
|
||||||
{
|
{
|
||||||
return chainedExtractionFn.apply(value);
|
return chainedExtractionFn.apply(value);
|
||||||
}
|
}
|
||||||
|
@ -195,12 +200,14 @@ public class CascadeExtractionFn implements ExtractionFn
|
||||||
return (child != null) ? Bytes.concat(fnCacheKey, child.getCacheKey()) : fnCacheKey;
|
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);
|
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);
|
return fn.apply((child != null) ? child.apply(value) : value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,12 +19,14 @@
|
||||||
|
|
||||||
package io.druid.query.extraction;
|
package io.druid.query.extraction;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public abstract class DimExtractionFn implements ExtractionFn
|
public abstract class DimExtractionFn implements ExtractionFn
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public String apply(Object value)
|
@Nullable
|
||||||
|
public String apply(@Nullable Object value)
|
||||||
{
|
{
|
||||||
return apply(Objects.toString(value, null));
|
return apply(Objects.toString(value, null));
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,8 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||||
import io.druid.query.lookup.LookupExtractionFn;
|
import io.druid.query.lookup.LookupExtractionFn;
|
||||||
import io.druid.query.lookup.RegisteredLookupExtractionFn;
|
import io.druid.query.lookup.RegisteredLookupExtractionFn;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
|
@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
|
* @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.
|
* 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
|
* @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.
|
* The "extraction" function. This should map a long value into some String value.
|
||||||
|
|
|
@ -105,7 +105,8 @@ public abstract class FunctionalExtraction extends DimExtractionFn
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String apply(String value)
|
@Nullable
|
||||||
|
public String apply(@Nullable String value)
|
||||||
{
|
{
|
||||||
return extractionFunction.apply(value);
|
return extractionFunction.apply(value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@ package io.druid.query.extraction;
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class IdentityExtractionFn implements ExtractionFn
|
public class IdentityExtractionFn implements ExtractionFn
|
||||||
{
|
{
|
||||||
private static final IdentityExtractionFn instance = new IdentityExtractionFn();
|
private static final IdentityExtractionFn instance = new IdentityExtractionFn();
|
||||||
|
@ -37,13 +39,15 @@ public class IdentityExtractionFn implements ExtractionFn
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String apply(Object value)
|
@Nullable
|
||||||
|
public String apply(@Nullable Object value)
|
||||||
{
|
{
|
||||||
return value == null ? null : Strings.emptyToNull(value.toString());
|
return value == null ? null : Strings.emptyToNull(value.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String apply(String value)
|
@Nullable
|
||||||
|
public String apply(@Nullable String value)
|
||||||
{
|
{
|
||||||
return Strings.emptyToNull(value);
|
return Strings.emptyToNull(value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ import org.mozilla.javascript.Context;
|
||||||
import org.mozilla.javascript.ContextFactory;
|
import org.mozilla.javascript.ContextFactory;
|
||||||
import org.mozilla.javascript.ScriptableObject;
|
import org.mozilla.javascript.ScriptableObject;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
public class JavaScriptExtractionFn implements ExtractionFn
|
public class JavaScriptExtractionFn implements ExtractionFn
|
||||||
|
@ -111,7 +112,8 @@ public class JavaScriptExtractionFn implements ExtractionFn
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String apply(Object value)
|
@Nullable
|
||||||
|
public String apply(@Nullable Object value)
|
||||||
{
|
{
|
||||||
if (fn == null) {
|
if (fn == null) {
|
||||||
throw new ISE("JavaScript is disabled");
|
throw new ISE("JavaScript is disabled");
|
||||||
|
@ -121,7 +123,8 @@ public class JavaScriptExtractionFn implements ExtractionFn
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String apply(String value)
|
@Nullable
|
||||||
|
public String apply(@Nullable String value)
|
||||||
{
|
{
|
||||||
return this.apply((Object) Strings.emptyToNull(value));
|
return this.apply((Object) Strings.emptyToNull(value));
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ public class LowerExtractionFn extends DimExtractionFn
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public String apply(String key)
|
public String apply(@Nullable String key)
|
||||||
{
|
{
|
||||||
if (Strings.isNullOrEmpty(key)) {
|
if (Strings.isNullOrEmpty(key)) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -25,6 +25,7 @@ import com.google.common.base.Preconditions;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import io.druid.java.util.common.StringUtils;
|
import io.druid.java.util.common.StringUtils;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
@ -57,8 +58,9 @@ public class MatchingDimExtractionFn extends DimExtractionFn
|
||||||
.array();
|
.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public String apply(String dimValue)
|
public String apply(@Nullable String dimValue)
|
||||||
{
|
{
|
||||||
if (Strings.isNullOrEmpty(dimValue)) {
|
if (Strings.isNullOrEmpty(dimValue)) {
|
||||||
// We'd return null whether or not the pattern matched
|
// We'd return null whether or not the pattern matched
|
||||||
|
|
|
@ -26,6 +26,7 @@ import com.google.common.base.Strings;
|
||||||
import com.google.common.primitives.Ints;
|
import com.google.common.primitives.Ints;
|
||||||
import io.druid.java.util.common.StringUtils;
|
import io.druid.java.util.common.StringUtils;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
@ -100,8 +101,9 @@ public class RegexDimExtractionFn extends DimExtractionFn
|
||||||
.array();
|
.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public String apply(String dimValue)
|
public String apply(@Nullable String dimValue)
|
||||||
{
|
{
|
||||||
final String retVal;
|
final String retVal;
|
||||||
final Matcher matcher = pattern.matcher(Strings.nullToEmpty(dimValue));
|
final Matcher matcher = pattern.matcher(Strings.nullToEmpty(dimValue));
|
||||||
|
|
|
@ -25,6 +25,7 @@ import com.google.common.base.Preconditions;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import io.druid.query.search.search.SearchQuerySpec;
|
import io.druid.query.search.search.SearchQuerySpec;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,8 +60,9 @@ public class SearchQuerySpecDimExtractionFn extends DimExtractionFn
|
||||||
.array();
|
.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public String apply(String dimValue)
|
public String apply(@Nullable String dimValue)
|
||||||
{
|
{
|
||||||
return searchQuerySpec.accept(dimValue) ? Strings.emptyToNull(dimValue) : null;
|
return searchQuerySpec.accept(dimValue) ? Strings.emptyToNull(dimValue) : null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ import com.google.common.base.Preconditions;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import io.druid.java.util.common.StringUtils;
|
import io.druid.java.util.common.StringUtils;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -94,8 +95,9 @@ public class StringFormatExtractionFn extends DimExtractionFn
|
||||||
.array();
|
.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public String apply(String value)
|
public String apply(@Nullable String value)
|
||||||
{
|
{
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
if (nullHandling == NullHandling.RETURNNULL) {
|
if (nullHandling == NullHandling.RETURNNULL) {
|
||||||
|
|
|
@ -21,6 +21,8 @@ package io.druid.query.extraction;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class StrlenExtractionFn extends DimExtractionFn
|
public class StrlenExtractionFn extends DimExtractionFn
|
||||||
{
|
{
|
||||||
private static final StrlenExtractionFn INSTANCE = new StrlenExtractionFn();
|
private static final StrlenExtractionFn INSTANCE = new StrlenExtractionFn();
|
||||||
|
@ -36,7 +38,7 @@ public class StrlenExtractionFn extends DimExtractionFn
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String apply(String value)
|
public String apply(@Nullable String value)
|
||||||
{
|
{
|
||||||
return String.valueOf(value == null ? 0 : value.length());
|
return String.valueOf(value == null ? 0 : value.length());
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,8 +61,9 @@ public class SubstringDimExtractionFn extends DimExtractionFn
|
||||||
.array();
|
.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public String apply(String dimValue)
|
public String apply(@Nullable String dimValue)
|
||||||
{
|
{
|
||||||
if (Strings.isNullOrEmpty(dimValue)) {
|
if (Strings.isNullOrEmpty(dimValue)) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -22,9 +22,11 @@ package io.druid.query.extraction;
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.google.common.base.Strings;
|
||||||
import com.ibm.icu.text.SimpleDateFormat;
|
import com.ibm.icu.text.SimpleDateFormat;
|
||||||
import io.druid.java.util.common.StringUtils;
|
import io.druid.java.util.common.StringUtils;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
@ -71,9 +73,14 @@ public class TimeDimExtractionFn extends DimExtractionFn
|
||||||
.array();
|
.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public String apply(String dimValue)
|
public String apply(@Nullable String dimValue)
|
||||||
{
|
{
|
||||||
|
if (Strings.isNullOrEmpty(dimValue)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
Date date;
|
Date date;
|
||||||
try {
|
try {
|
||||||
date = timeFormatter.get().parse(dimValue);
|
date = timeFormatter.get().parse(dimValue);
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.joda.time.format.DateTimeFormat;
|
||||||
import org.joda.time.format.DateTimeFormatter;
|
import org.joda.time.format.DateTimeFormatter;
|
||||||
import org.joda.time.format.ISODateTimeFormat;
|
import org.joda.time.format.ISODateTimeFormat;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
@ -128,8 +129,13 @@ public class TimeFormatExtractionFn implements ExtractionFn
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String apply(Object value)
|
@Nullable
|
||||||
|
public String apply(@Nullable Object value)
|
||||||
{
|
{
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (asMillis && value instanceof String) {
|
if (asMillis && value instanceof String) {
|
||||||
final Long theLong = GuavaUtils.tryParseLong((String) value);
|
final Long theLong = GuavaUtils.tryParseLong((String) value);
|
||||||
return theLong == null ? apply(new DateTime(value).getMillis()) : apply(theLong.longValue());
|
return theLong == null ? apply(new DateTime(value).getMillis()) : apply(theLong.longValue());
|
||||||
|
@ -139,7 +145,8 @@ public class TimeFormatExtractionFn implements ExtractionFn
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String apply(String value)
|
@Nullable
|
||||||
|
public String apply(@Nullable String value)
|
||||||
{
|
{
|
||||||
return apply((Object) value);
|
return apply((Object) value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ public class UpperExtractionFn extends DimExtractionFn
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public String apply(String key)
|
public String apply(@Nullable String key)
|
||||||
{
|
{
|
||||||
if (Strings.isNullOrEmpty(key)) {
|
if (Strings.isNullOrEmpty(key)) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -105,13 +105,15 @@ public class RegisteredLookupExtractionFn implements ExtractionFn
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String apply(Object value)
|
@Nullable
|
||||||
|
public String apply(@Nullable Object value)
|
||||||
{
|
{
|
||||||
return ensureDelegate().apply(value);
|
return ensureDelegate().apply(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String apply(String value)
|
@Nullable
|
||||||
|
public String apply(@Nullable String value)
|
||||||
{
|
{
|
||||||
return ensureDelegate().apply(value);
|
return ensureDelegate().apply(value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
package io.druid.query.search.search;
|
package io.druid.query.search.search;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public class AllSearchQuerySpec implements SearchQuerySpec
|
public class AllSearchQuerySpec implements SearchQuerySpec
|
||||||
|
@ -26,7 +28,7 @@ public class AllSearchQuerySpec implements SearchQuerySpec
|
||||||
private static final byte CACHE_TYPE_ID = 0x7f;
|
private static final byte CACHE_TYPE_ID = 0x7f;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(String dimVal)
|
public boolean accept(@Nullable String dimVal)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
import io.druid.java.util.common.StringUtils;
|
import io.druid.java.util.common.StringUtils;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,7 +60,7 @@ public class ContainsSearchQuerySpec implements SearchQuerySpec
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(String dimVal)
|
public boolean accept(@Nullable String dimVal)
|
||||||
{
|
{
|
||||||
if (dimVal == null || value == null) {
|
if (dimVal == null || value == null) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -23,6 +23,7 @@ import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import io.druid.java.util.common.StringUtils;
|
import io.druid.java.util.common.StringUtils;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -77,7 +78,7 @@ public class FragmentSearchQuerySpec implements SearchQuerySpec
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(String dimVal)
|
public boolean accept(@Nullable String dimVal)
|
||||||
{
|
{
|
||||||
if (dimVal == null || values == null) {
|
if (dimVal == null || values == null) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -24,6 +24,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import io.druid.java.util.common.StringUtils;
|
import io.druid.java.util.common.StringUtils;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@ -74,7 +75,7 @@ public class RegexSearchQuerySpec implements SearchQuerySpec
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(String dimVal)
|
public boolean accept(@Nullable String dimVal)
|
||||||
{
|
{
|
||||||
if (dimVal == null) {
|
if (dimVal == null) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -22,6 +22,8 @@ package io.druid.query.search.search;
|
||||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
|
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
|
||||||
|
@ -34,7 +36,7 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||||
})
|
})
|
||||||
public interface SearchQuerySpec
|
public interface SearchQuerySpec
|
||||||
{
|
{
|
||||||
public boolean accept(String dimVal);
|
public boolean accept(@Nullable String dimVal);
|
||||||
|
|
||||||
public byte[] getCacheKey();
|
public byte[] getCacheKey();
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,16 @@ public class TimeDimExtractionFnTest
|
||||||
"12/21/2012"
|
"12/21/2012"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEmptyAndNullExtraction()
|
||||||
|
{
|
||||||
|
Set<String> testPeriod = Sets.newHashSet();
|
||||||
|
ExtractionFn extractionFn = new TimeDimExtractionFn("MM/dd/yyyy", "MM/yyyy");
|
||||||
|
|
||||||
|
Assert.assertNull(extractionFn.apply(null));
|
||||||
|
Assert.assertNull(extractionFn.apply(""));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMonthExtraction()
|
public void testMonthExtraction()
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,6 +30,7 @@ import io.druid.data.input.impl.TimeAndDimsParseSpec;
|
||||||
import io.druid.data.input.impl.TimestampSpec;
|
import io.druid.data.input.impl.TimestampSpec;
|
||||||
import io.druid.java.util.common.Pair;
|
import io.druid.java.util.common.Pair;
|
||||||
import io.druid.query.extraction.MapLookupExtractor;
|
import io.druid.query.extraction.MapLookupExtractor;
|
||||||
|
import io.druid.query.extraction.TimeDimExtractionFn;
|
||||||
import io.druid.query.filter.ExtractionDimFilter;
|
import io.druid.query.filter.ExtractionDimFilter;
|
||||||
import io.druid.query.filter.InDimFilter;
|
import io.druid.query.filter.InDimFilter;
|
||||||
import io.druid.query.filter.SelectorDimFilter;
|
import io.druid.query.filter.SelectorDimFilter;
|
||||||
|
@ -58,7 +59,7 @@ public class SelectorFilterTest extends BaseFilterTest
|
||||||
new TimeAndDimsParseSpec(
|
new TimeAndDimsParseSpec(
|
||||||
new TimestampSpec(TIMESTAMP_COLUMN, "iso", new DateTime("2000")),
|
new TimestampSpec(TIMESTAMP_COLUMN, "iso", new DateTime("2000")),
|
||||||
new DimensionsSpec(
|
new DimensionsSpec(
|
||||||
DimensionsSpec.getDefaultSchemas(ImmutableList.of("dim0", "dim1", "dim2", "dim3")),
|
DimensionsSpec.getDefaultSchemas(ImmutableList.of("dim0", "dim1", "dim2", "dim3", "dim6")),
|
||||||
null,
|
null,
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
|
@ -66,9 +67,9 @@ public class SelectorFilterTest extends BaseFilterTest
|
||||||
);
|
);
|
||||||
|
|
||||||
private static final List<InputRow> ROWS = ImmutableList.of(
|
private static final List<InputRow> ROWS = ImmutableList.of(
|
||||||
PARSER.parse(ImmutableMap.<String, Object>of("dim0", "0", "dim1", "", "dim2", ImmutableList.of("a", "b"))),
|
PARSER.parse(ImmutableMap.<String, Object>of("dim0", "0", "dim1", "", "dim2", ImmutableList.of("a", "b"), "dim6", "2017-07-25")),
|
||||||
PARSER.parse(ImmutableMap.<String, Object>of("dim0", "1", "dim1", "10", "dim2", ImmutableList.of())),
|
PARSER.parse(ImmutableMap.<String, Object>of("dim0", "1", "dim1", "10", "dim2", ImmutableList.of(), "dim6", "2017-07-25")),
|
||||||
PARSER.parse(ImmutableMap.<String, Object>of("dim0", "2", "dim1", "2", "dim2", ImmutableList.of(""))),
|
PARSER.parse(ImmutableMap.<String, Object>of("dim0", "2", "dim1", "2", "dim2", ImmutableList.of(""), "dim6", "2017-05-25")),
|
||||||
PARSER.parse(ImmutableMap.<String, Object>of("dim0", "3", "dim1", "1", "dim2", ImmutableList.of("a"))),
|
PARSER.parse(ImmutableMap.<String, Object>of("dim0", "3", "dim1", "1", "dim2", ImmutableList.of("a"))),
|
||||||
PARSER.parse(ImmutableMap.<String, Object>of("dim0", "4", "dim1", "def", "dim2", ImmutableList.of("c"))),
|
PARSER.parse(ImmutableMap.<String, Object>of("dim0", "4", "dim1", "def", "dim2", ImmutableList.of("c"))),
|
||||||
PARSER.parse(ImmutableMap.<String, Object>of("dim0", "5", "dim1", "abc"))
|
PARSER.parse(ImmutableMap.<String, Object>of("dim0", "5", "dim1", "abc"))
|
||||||
|
@ -91,6 +92,15 @@ public class SelectorFilterTest extends BaseFilterTest
|
||||||
BaseFilterTest.tearDown(SelectorFilterTest.class.getName());
|
BaseFilterTest.tearDown(SelectorFilterTest.class.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWithTimeExtractionFnNull()
|
||||||
|
{
|
||||||
|
assertFilterMatches(new SelectorDimFilter("dim0", null, new TimeDimExtractionFn("yyyy-mm-dd", "yyyy-mm")), ImmutableList.<String>of());
|
||||||
|
assertFilterMatches(new SelectorDimFilter("dim6", null, new TimeDimExtractionFn("yyyy-mm-dd", "yyyy-mm")), ImmutableList.<String>of("3", "4", "5"));
|
||||||
|
assertFilterMatches(new SelectorDimFilter("dim6", "2017-07", new TimeDimExtractionFn("yyyy-mm-dd", "yyyy-mm")), ImmutableList.<String>of("0", "1"));
|
||||||
|
assertFilterMatches(new SelectorDimFilter("dim6", "2017-05", new TimeDimExtractionFn("yyyy-mm-dd", "yyyy-mm")), ImmutableList.<String>of("2"));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSingleValueStringColumnWithoutNulls()
|
public void testSingleValueStringColumnWithoutNulls()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue