diff --git a/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java b/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java index c1dead0bb3e..344e65097ad 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java @@ -432,11 +432,7 @@ class DocumentParser implements Closeable { // we can only handle null values if we have mappings for them Mapper mapper = parentMapper.getMapper(lastFieldName); if (mapper != null) { - if (mapper instanceof FieldMapper) { - if (!((FieldMapper) mapper).supportsNullValue()) { - throw new MapperParsingException("no object mapping found for null value in [" + lastFieldName + "]"); - } - } + // TODO: passing null to an object seems bogus? parseObjectOrField(context, mapper); } else if (parentMapper.dynamic() == ObjectMapper.Dynamic.STRICT) { throw new StrictDynamicMappingException(parentMapper.fullPath(), lastFieldName); diff --git a/core/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java index 02f6459b76b..4f7abb8c2b7 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java @@ -96,8 +96,6 @@ public interface FieldMapper extends Mapper { boolean isSortable(); - boolean supportsNullValue(); - /** * Fields might not be available before indexing, for example _all, token_count,... * When get is called and these fields are requested, this case needs special treatment. diff --git a/core/src/main/java/org/elasticsearch/index/mapper/MappedFieldType.java b/core/src/main/java/org/elasticsearch/index/mapper/MappedFieldType.java index 216a308a306..ca586474a12 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/MappedFieldType.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/MappedFieldType.java @@ -25,6 +25,7 @@ import org.apache.lucene.document.FieldType; import org.apache.lucene.index.Term; import org.apache.lucene.index.Terms; import org.apache.lucene.queries.TermsQuery; +import org.apache.lucene.search.ConstantScoreQuery; import org.apache.lucene.search.FuzzyQuery; import org.apache.lucene.search.MultiTermQuery; import org.apache.lucene.search.PrefixQuery; @@ -175,6 +176,8 @@ public class MappedFieldType extends FieldType { private SimilarityProvider similarity; private Loading normsLoading; private FieldDataType fieldDataType; + private Object nullValue; + private String nullValueAsString; // for sending null value to _all field protected MappedFieldType(MappedFieldType ref) { super(ref); @@ -187,6 +190,8 @@ public class MappedFieldType extends FieldType { this.similarity = ref.similarity(); this.normsLoading = ref.normsLoading(); this.fieldDataType = ref.fieldDataType(); + this.nullValue = ref.nullValue(); + this.nullValueAsString = ref.nullValueAsString(); } public MappedFieldType() {} @@ -286,6 +291,20 @@ public class MappedFieldType extends FieldType { this.similarity = similarity; } + public Object nullValue() { + return nullValue; + } + + public String nullValueAsString() { + return nullValueAsString; + } + + public void setNullValue(Object nullValue) { + checkIfFrozen(); + this.nullValue = nullValue; + this.nullValueAsString = nullValue == null ? null : nullValue.toString(); + } + /** Returns the actual value of the field. */ public Object value(Object value) { return value; @@ -353,6 +372,13 @@ public class MappedFieldType extends FieldType { return query; } + public Query nullValueQuery() { + if (nullValue == null) { + return null; + } + return new ConstantScoreQuery(termQuery(nullValue, null)); + } + /** * @return a {@link FieldStats} instance that maps to the type of this field based on the provided {@link Terms} instance. */ diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/AbstractFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/AbstractFieldMapper.java index 5182ea23a8d..b801307c923 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/core/AbstractFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/core/AbstractFieldMapper.java @@ -228,6 +228,11 @@ public abstract class AbstractFieldMapper implements FieldMapper { return builder; } + public Builder nullValue(Object nullValue) { + this.fieldType.setNullValue(nullValue); + return this; + } + public T multiFieldPathType(ContentPath.Type pathType) { multiFieldsBuilder.pathType(pathType); return builder; @@ -440,8 +445,8 @@ public abstract class AbstractFieldMapper implements FieldMapper { } @Override - public Query nullValueFilter() { - return null; + public final Query nullValueFilter() { + return fieldType().nullValueQuery(); } @Override @@ -689,11 +694,6 @@ public abstract class AbstractFieldMapper implements FieldMapper { return fieldType().isSortable(); } - @Override - public boolean supportsNullValue() { - return true; - } - public static class MultiFields { public static MultiFields empty() { diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/BooleanFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/BooleanFieldMapper.java index f33a24d15e1..f51514c48a2 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/core/BooleanFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/core/BooleanFieldMapper.java @@ -22,8 +22,6 @@ package org.elasticsearch.index.mapper.core; import org.apache.lucene.document.Field; import org.apache.lucene.document.SortedNumericDocValuesField; import org.apache.lucene.index.IndexOptions; -import org.apache.lucene.search.ConstantScoreQuery; -import org.apache.lucene.search.Query; import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.Booleans; import org.elasticsearch.common.Nullable; @@ -39,7 +37,6 @@ import org.elasticsearch.index.mapper.MapperParsingException; import org.elasticsearch.index.mapper.MergeMappingException; import org.elasticsearch.index.mapper.MergeResult; import org.elasticsearch.index.mapper.ParseContext; -import org.elasticsearch.index.similarity.SimilarityProvider; import java.io.IOException; import java.util.Iterator; @@ -68,8 +65,6 @@ public class BooleanFieldMapper extends AbstractFieldMapper { FIELD_TYPE.setSearchAnalyzer(Lucene.KEYWORD_ANALYZER); FIELD_TYPE.freeze(); } - - public static final Boolean NULL_VALUE = null; } public static class Values { @@ -79,18 +74,11 @@ public class BooleanFieldMapper extends AbstractFieldMapper { public static class Builder extends AbstractFieldMapper.Builder { - private Boolean nullValue = Defaults.NULL_VALUE; - public Builder(String name) { super(name, Defaults.FIELD_TYPE); this.builder = this; } - public Builder nullValue(boolean nullValue) { - this.nullValue = nullValue; - return this; - } - @Override public Builder tokenized(boolean tokenized) { if (tokenized) { @@ -102,7 +90,7 @@ public class BooleanFieldMapper extends AbstractFieldMapper { @Override public BooleanFieldMapper build(BuilderContext context) { setupFieldType(context); - return new BooleanFieldMapper(fieldType, docValues, nullValue, + return new BooleanFieldMapper(fieldType, docValues, fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo); } } @@ -143,6 +131,11 @@ public class BooleanFieldMapper extends AbstractFieldMapper { return new BooleanFieldType(this); } + @Override + public Boolean nullValue() { + return (Boolean)super.nullValue(); + } + @Override public BytesRef indexedValueForSearch(Object value) { if (value == null) { @@ -198,12 +191,14 @@ public class BooleanFieldMapper extends AbstractFieldMapper { } } - private Boolean nullValue; - - protected BooleanFieldMapper(MappedFieldType fieldType, Boolean docValues, Boolean nullValue, + protected BooleanFieldMapper(MappedFieldType fieldType, Boolean docValues, @Nullable Settings fieldDataSettings, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) { super(fieldType, docValues, fieldDataSettings, indexSettings, multiFields, copyTo); - this.nullValue = nullValue; + } + + @Override + public BooleanFieldType fieldType() { + return (BooleanFieldType)fieldType; } @Override @@ -217,14 +212,6 @@ public class BooleanFieldMapper extends AbstractFieldMapper { return new FieldDataType(CONTENT_TYPE); } - @Override - public Query nullValueFilter() { - if (nullValue == null) { - return null; - } - return new ConstantScoreQuery(termQuery(nullValue, null)); - } - @Override protected void parseCreateField(ParseContext context, List fields) throws IOException { if (fieldType().indexOptions() == IndexOptions.NONE && !fieldType().stored() && !fieldType().hasDocValues()) { @@ -235,8 +222,8 @@ public class BooleanFieldMapper extends AbstractFieldMapper { if (value == null) { XContentParser.Token token = context.parser().currentToken(); if (token == XContentParser.Token.VALUE_NULL) { - if (nullValue != null) { - value = nullValue; + if (fieldType().nullValue() != null) { + value = fieldType().nullValue(); } } else { value = context.parser().booleanValue(); @@ -260,7 +247,9 @@ public class BooleanFieldMapper extends AbstractFieldMapper { } if (!mergeResult.simulate()) { - this.nullValue = ((BooleanFieldMapper) mergeWith).nullValue; + this.fieldType = this.fieldType.clone(); + this.fieldType.setNullValue(((BooleanFieldMapper) mergeWith).fieldType().nullValue()); + this.fieldType.freeze(); } } @@ -272,8 +261,8 @@ public class BooleanFieldMapper extends AbstractFieldMapper { @Override protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException { super.doXContentBody(builder, includeDefaults, params); - if (includeDefaults || nullValue != null) { - builder.field("null_value", nullValue); + if (includeDefaults || fieldType().nullValue() != null) { + builder.field("null_value", fieldType().nullValue()); } } } diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/ByteFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/ByteFieldMapper.java index f9800ce9ffa..32ef17420bf 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/core/ByteFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/core/ByteFieldMapper.java @@ -70,28 +70,19 @@ public class ByteFieldMapper extends NumberFieldMapper { static { FIELD_TYPE.freeze(); } - - public static final Byte NULL_VALUE = null; } public static class Builder extends NumberFieldMapper.Builder { - protected Byte nullValue = Defaults.NULL_VALUE; - public Builder(String name) { super(name, Defaults.FIELD_TYPE, Defaults.PRECISION_STEP_8_BIT); builder = this; } - public Builder nullValue(byte nullValue) { - this.nullValue = nullValue; - return this; - } - @Override public ByteFieldMapper build(BuilderContext context) { setupFieldType(context); - ByteFieldMapper fieldMapper = new ByteFieldMapper(fieldType, docValues, nullValue, ignoreMalformed(context), + ByteFieldMapper fieldMapper = new ByteFieldMapper(fieldType, docValues, ignoreMalformed(context), coerce(context), fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo); fieldMapper.includeInAll(includeInAll); return fieldMapper; @@ -142,6 +133,11 @@ public class ByteFieldMapper extends NumberFieldMapper { return new ByteFieldType(this); } + @Override + public Byte nullValue() { + return (Byte)super.nullValue(); + } + @Override public Byte value(Object value) { if (value == null) { @@ -191,16 +187,15 @@ public class ByteFieldMapper extends NumberFieldMapper { } } - private Byte nullValue; - - private String nullValueAsString; - protected ByteFieldMapper(MappedFieldType fieldType, Boolean docValues, - Byte nullValue, Explicit ignoreMalformed, Explicit coerce, + Explicit ignoreMalformed, Explicit coerce, @Nullable Settings fieldDataSettings, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) { super(fieldType, docValues, ignoreMalformed, coerce, fieldDataSettings, indexSettings, multiFields, copyTo); - this.nullValue = nullValue; - this.nullValueAsString = nullValue == null ? null : nullValue.toString(); + } + + @Override + public ByteFieldType fieldType() { + return (ByteFieldType)fieldType; } @Override @@ -223,14 +218,6 @@ public class ByteFieldMapper extends NumberFieldMapper { return Byte.parseByte(value.toString()); } - @Override - public Query nullValueFilter() { - if (nullValue == null) { - return null; - } - return new ConstantScoreQuery(termQuery(nullValue, null)); - } - @Override protected boolean customBoost() { return true; @@ -243,17 +230,17 @@ public class ByteFieldMapper extends NumberFieldMapper { if (context.externalValueSet()) { Object externalValue = context.externalValue(); if (externalValue == null) { - if (nullValue == null) { + if (fieldType().nullValue() == null) { return; } - value = nullValue; + value = fieldType().nullValue(); } else if (externalValue instanceof String) { String sExternalValue = (String) externalValue; if (sExternalValue.length() == 0) { - if (nullValue == null) { + if (fieldType().nullValue() == null) { return; } - value = nullValue; + value = fieldType().nullValue(); } else { value = Byte.parseByte(sExternalValue); } @@ -267,17 +254,17 @@ public class ByteFieldMapper extends NumberFieldMapper { XContentParser parser = context.parser(); if (parser.currentToken() == XContentParser.Token.VALUE_NULL || (parser.currentToken() == XContentParser.Token.VALUE_STRING && parser.textLength() == 0)) { - if (nullValue == null) { + if (fieldType().nullValue() == null) { return; } - value = nullValue; - if (nullValueAsString != null && (context.includeInAll(includeInAll, this))) { - context.allEntries().addText(fieldType.names().fullName(), nullValueAsString, boost); + value = fieldType().nullValue(); + if (fieldType().nullValueAsString() != null && (context.includeInAll(includeInAll, this))) { + context.allEntries().addText(fieldType.names().fullName(), fieldType().nullValueAsString(), boost); } } else if (parser.currentToken() == XContentParser.Token.START_OBJECT) { XContentParser.Token token; String currentFieldName = null; - Byte objValue = nullValue; + Byte objValue = fieldType().nullValue(); while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { if (token == XContentParser.Token.FIELD_NAME) { currentFieldName = parser.currentName(); @@ -327,8 +314,9 @@ public class ByteFieldMapper extends NumberFieldMapper { return; } if (!mergeResult.simulate()) { - this.nullValue = ((ByteFieldMapper) mergeWith).nullValue; - this.nullValueAsString = ((ByteFieldMapper) mergeWith).nullValueAsString; + this.fieldType = this.fieldType.clone(); + this.fieldType.setNullValue(((ByteFieldMapper) mergeWith).fieldType().nullValue()); + this.fieldType.freeze(); } } @@ -339,8 +327,8 @@ public class ByteFieldMapper extends NumberFieldMapper { if (includeDefaults || fieldType.numericPrecisionStep() != Defaults.PRECISION_STEP_8_BIT) { builder.field("precision_step", fieldType.numericPrecisionStep()); } - if (includeDefaults || nullValue != null) { - builder.field("null_value", nullValue); + if (includeDefaults || fieldType().nullValue() != null) { + builder.field("null_value", fieldType().nullValue()); } if (includeInAll != null) { builder.field("include_in_all", includeInAll); diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/CompletionFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/CompletionFieldMapper.java index d229d6a9b6f..6dbea13c531 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/core/CompletionFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/core/CompletionFieldMapper.java @@ -297,6 +297,9 @@ public class CompletionFieldMapper extends AbstractFieldMapper { public Mapper parse(ParseContext context) throws IOException { XContentParser parser = context.parser(); XContentParser.Token token = parser.currentToken(); + if (token == XContentParser.Token.VALUE_NULL) { + throw new MapperParsingException("completion field [" + fieldType().names().fullName() + "] does not support null values"); + } String surfaceForm = null; BytesRef payload = null; @@ -524,11 +527,6 @@ public class CompletionFieldMapper extends AbstractFieldMapper { return CONTENT_TYPE; } - @Override - public boolean supportsNullValue() { - return false; - } - @Override public MappedFieldType defaultFieldType() { return Defaults.FIELD_TYPE; diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/DateFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/DateFieldMapper.java index 510e068464d..a8ba8a2bf0b 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/core/DateFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/core/DateFieldMapper.java @@ -115,8 +115,9 @@ public class DateFieldMapper extends NumberFieldMapper { @Override public DateFieldMapper build(BuilderContext context) { setupFieldType(context); + fieldType.setNullValue(nullValue); DateFieldMapper fieldMapper = new DateFieldMapper(fieldType, - docValues, nullValue, ignoreMalformed(context), coerce(context), + docValues, ignoreMalformed(context), coerce(context), fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo); fieldMapper.includeInAll(includeInAll); return fieldMapper; @@ -374,12 +375,9 @@ public class DateFieldMapper extends NumberFieldMapper { } } - private String nullValue; - - protected DateFieldMapper(MappedFieldType fieldType, Boolean docValues, String nullValue, Explicit ignoreMalformed,Explicit coerce, + protected DateFieldMapper(MappedFieldType fieldType, Boolean docValues, Explicit ignoreMalformed,Explicit coerce, @Nullable Settings fieldDataSettings, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) { super(fieldType, docValues, ignoreMalformed, coerce, fieldDataSettings, indexSettings, multiFields, copyTo); - this.nullValue = nullValue; } @Override @@ -409,15 +407,6 @@ public class DateFieldMapper extends NumberFieldMapper { }; } - @Override - public Query nullValueFilter() { - if (nullValue == null) { - return null; - } - return new ConstantScoreQuery(termQuery(nullValue, null)); - } - - @Override protected boolean customBoost() { return true; @@ -431,13 +420,13 @@ public class DateFieldMapper extends NumberFieldMapper { Object externalValue = context.externalValue(); dateAsString = (String) externalValue; if (dateAsString == null) { - dateAsString = nullValue; + dateAsString = fieldType.nullValueAsString(); } } else { XContentParser parser = context.parser(); XContentParser.Token token = parser.currentToken(); if (token == XContentParser.Token.VALUE_NULL) { - dateAsString = nullValue; + dateAsString = fieldType.nullValueAsString(); } else if (token == XContentParser.Token.VALUE_NUMBER) { dateAsString = parser.text(); } else if (token == XContentParser.Token.START_OBJECT) { @@ -448,7 +437,7 @@ public class DateFieldMapper extends NumberFieldMapper { } else { if ("value".equals(currentFieldName) || "_value".equals(currentFieldName)) { if (token == XContentParser.Token.VALUE_NULL) { - dateAsString = nullValue; + dateAsString = fieldType.nullValueAsString(); } else { dateAsString = parser.text(); } @@ -496,9 +485,9 @@ public class DateFieldMapper extends NumberFieldMapper { return; } if (!mergeResult.simulate()) { - this.nullValue = ((DateFieldMapper) mergeWith).nullValue; this.fieldType = this.fieldType.clone(); fieldType().setDateTimeFormatter(((DateFieldMapper) mergeWith).fieldType().dateTimeFormatter()); + this.fieldType.setNullValue(((DateFieldMapper) mergeWith).fieldType().nullValue()); this.fieldType.freeze(); } } @@ -511,8 +500,8 @@ public class DateFieldMapper extends NumberFieldMapper { builder.field("precision_step", fieldType.numericPrecisionStep()); } builder.field("format", fieldType().dateTimeFormatter().format()); - if (includeDefaults || nullValue != null) { - builder.field("null_value", nullValue); + if (includeDefaults || fieldType.nullValueAsString() != null) { + builder.field("null_value", fieldType.nullValueAsString()); } if (includeInAll != null) { builder.field("include_in_all", includeInAll); diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/DoubleFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/DoubleFieldMapper.java index 63f0c87939b..5c9b7fe69f0 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/core/DoubleFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/core/DoubleFieldMapper.java @@ -23,10 +23,8 @@ import com.carrotsearch.hppc.DoubleArrayList; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.document.Field; -import org.apache.lucene.document.FieldType; import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.Terms; -import org.apache.lucene.search.ConstantScoreQuery; import org.apache.lucene.search.NumericRangeQuery; import org.apache.lucene.search.Query; import org.apache.lucene.util.BytesRef; @@ -76,28 +74,19 @@ public class DoubleFieldMapper extends NumberFieldMapper { static { FIELD_TYPE.freeze(); } - - public static final Double NULL_VALUE = null; } public static class Builder extends NumberFieldMapper.Builder { - protected Double nullValue = Defaults.NULL_VALUE; - public Builder(String name) { super(name, Defaults.FIELD_TYPE, Defaults.PRECISION_STEP_64_BIT); builder = this; } - public Builder nullValue(double nullValue) { - this.nullValue = nullValue; - return this; - } - @Override public DoubleFieldMapper build(BuilderContext context) { setupFieldType(context); - DoubleFieldMapper fieldMapper = new DoubleFieldMapper(fieldType, docValues, nullValue, ignoreMalformed(context), coerce(context), + DoubleFieldMapper fieldMapper = new DoubleFieldMapper(fieldType, docValues, ignoreMalformed(context), coerce(context), fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo); fieldMapper.includeInAll(includeInAll); return fieldMapper; @@ -148,6 +137,11 @@ public class DoubleFieldMapper extends NumberFieldMapper { return new DoubleFieldType(this); } + @Override + public Double nullValue() { + return (Double)super.nullValue(); + } + @Override public Double value(Object value) { if (value == null) { @@ -198,15 +192,14 @@ public class DoubleFieldMapper extends NumberFieldMapper { } } - private Double nullValue; - - private String nullValueAsString; - - protected DoubleFieldMapper(MappedFieldType fieldType, Boolean docValues, Double nullValue, Explicit ignoreMalformed, Explicit coerce, + protected DoubleFieldMapper(MappedFieldType fieldType, Boolean docValues, Explicit ignoreMalformed, Explicit coerce, @Nullable Settings fieldDataSettings, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) { super(fieldType, docValues, ignoreMalformed, coerce, fieldDataSettings, indexSettings, multiFields, copyTo); - this.nullValue = nullValue; - this.nullValueAsString = nullValue == null ? null : nullValue.toString(); + } + + @Override + public DoubleFieldType fieldType() { + return (DoubleFieldType)fieldType; } @Override @@ -219,18 +212,6 @@ public class DoubleFieldMapper extends NumberFieldMapper { return new FieldDataType("double"); } - public Query rangeFilter(Double lowerTerm, Double upperTerm, boolean includeLower, boolean includeUpper) { - return NumericRangeQuery.newDoubleRange(fieldType.names().indexName(), fieldType.numericPrecisionStep(), lowerTerm, upperTerm, includeLower, includeUpper); - } - - @Override - public Query nullValueFilter() { - if (nullValue == null) { - return null; - } - return new ConstantScoreQuery(termQuery(nullValue, null)); - } - @Override protected boolean customBoost() { return true; @@ -243,17 +224,17 @@ public class DoubleFieldMapper extends NumberFieldMapper { if (context.externalValueSet()) { Object externalValue = context.externalValue(); if (externalValue == null) { - if (nullValue == null) { + if (fieldType().nullValue() == null) { return; } - value = nullValue; + value = fieldType().nullValue(); } else if (externalValue instanceof String) { String sExternalValue = (String) externalValue; if (sExternalValue.length() == 0) { - if (nullValue == null) { + if (fieldType().nullValue() == null) { return; } - value = nullValue; + value = fieldType().nullValue(); } else { value = Double.parseDouble(sExternalValue); } @@ -267,17 +248,17 @@ public class DoubleFieldMapper extends NumberFieldMapper { XContentParser parser = context.parser(); if (parser.currentToken() == XContentParser.Token.VALUE_NULL || (parser.currentToken() == XContentParser.Token.VALUE_STRING && parser.textLength() == 0)) { - if (nullValue == null) { + if (fieldType().nullValue() == null) { return; } - value = nullValue; - if (nullValueAsString != null && (context.includeInAll(includeInAll, this))) { - context.allEntries().addText(fieldType.names().fullName(), nullValueAsString, boost); + value = fieldType().nullValue(); + if (fieldType().nullValueAsString() != null && (context.includeInAll(includeInAll, this))) { + context.allEntries().addText(fieldType.names().fullName(), fieldType().nullValueAsString(), boost); } } else if (parser.currentToken() == XContentParser.Token.START_OBJECT) { XContentParser.Token token; String currentFieldName = null; - Double objValue = nullValue; + Double objValue = fieldType().nullValue(); while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { if (token == XContentParser.Token.FIELD_NAME) { currentFieldName = parser.currentName(); @@ -338,8 +319,9 @@ public class DoubleFieldMapper extends NumberFieldMapper { return; } if (!mergeResult.simulate()) { - this.nullValue = ((DoubleFieldMapper) mergeWith).nullValue; - this.nullValueAsString = ((DoubleFieldMapper) mergeWith).nullValueAsString; + this.fieldType = this.fieldType.clone(); + this.fieldType.setNullValue(((DoubleFieldMapper) mergeWith).fieldType().nullValue()); + this.fieldType.freeze(); } } @@ -350,8 +332,8 @@ public class DoubleFieldMapper extends NumberFieldMapper { if (includeDefaults || fieldType.numericPrecisionStep() != Defaults.PRECISION_STEP_64_BIT) { builder.field("precision_step", fieldType.numericPrecisionStep()); } - if (includeDefaults || nullValue != null) { - builder.field("null_value", nullValue); + if (includeDefaults || fieldType().nullValue() != null) { + builder.field("null_value", fieldType().nullValue()); } if (includeInAll != null) { builder.field("include_in_all", includeInAll); diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/FloatFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/FloatFieldMapper.java index 1a7996befe7..6ac91c3401c 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/core/FloatFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/core/FloatFieldMapper.java @@ -77,28 +77,19 @@ public class FloatFieldMapper extends NumberFieldMapper { static { FIELD_TYPE.freeze(); } - - public static final Float NULL_VALUE = null; } public static class Builder extends NumberFieldMapper.Builder { - protected Float nullValue = Defaults.NULL_VALUE; - public Builder(String name) { super(name, Defaults.FIELD_TYPE, Defaults.PRECISION_STEP_32_BIT); builder = this; } - public Builder nullValue(float nullValue) { - this.nullValue = nullValue; - return this; - } - @Override public FloatFieldMapper build(BuilderContext context) { setupFieldType(context); - FloatFieldMapper fieldMapper = new FloatFieldMapper(fieldType, docValues, nullValue, ignoreMalformed(context), coerce(context), + FloatFieldMapper fieldMapper = new FloatFieldMapper(fieldType, docValues, ignoreMalformed(context), coerce(context), fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo); fieldMapper.includeInAll(includeInAll); return fieldMapper; @@ -149,6 +140,11 @@ public class FloatFieldMapper extends NumberFieldMapper { return new FloatFieldType(this); } + @Override + public Float nullValue() { + return (Float)super.nullValue(); + } + @Override public Float value(Object value) { if (value == null) { @@ -199,16 +195,15 @@ public class FloatFieldMapper extends NumberFieldMapper { } } - private Float nullValue; - - private String nullValueAsString; - protected FloatFieldMapper(MappedFieldType fieldType, Boolean docValues, - Float nullValue, Explicit ignoreMalformed, Explicit coerce, + Explicit ignoreMalformed, Explicit coerce, @Nullable Settings fieldDataSettings, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) { super(fieldType, docValues, ignoreMalformed, coerce, fieldDataSettings, indexSettings, multiFields, copyTo); - this.nullValue = nullValue; - this.nullValueAsString = nullValue == null ? null : nullValue.toString(); + } + + @Override + public FloatFieldType fieldType() { + return (FloatFieldType)fieldType; } @Override @@ -231,14 +226,6 @@ public class FloatFieldMapper extends NumberFieldMapper { return Float.parseFloat(value.toString()); } - @Override - public Query nullValueFilter() { - if (nullValue == null) { - return null; - } - return new ConstantScoreQuery(termQuery(nullValue, null)); - } - @Override protected boolean customBoost() { return true; @@ -251,17 +238,17 @@ public class FloatFieldMapper extends NumberFieldMapper { if (context.externalValueSet()) { Object externalValue = context.externalValue(); if (externalValue == null) { - if (nullValue == null) { + if (fieldType().nullValue() == null) { return; } - value = nullValue; + value = fieldType().nullValue(); } else if (externalValue instanceof String) { String sExternalValue = (String) externalValue; if (sExternalValue.length() == 0) { - if (nullValue == null) { + if (fieldType().nullValue() == null) { return; } - value = nullValue; + value = fieldType().nullValue(); } else { value = Float.parseFloat(sExternalValue); } @@ -275,17 +262,17 @@ public class FloatFieldMapper extends NumberFieldMapper { XContentParser parser = context.parser(); if (parser.currentToken() == XContentParser.Token.VALUE_NULL || (parser.currentToken() == XContentParser.Token.VALUE_STRING && parser.textLength() == 0)) { - if (nullValue == null) { + if (fieldType().nullValue() == null) { return; } - value = nullValue; - if (nullValueAsString != null && (context.includeInAll(includeInAll, this))) { - context.allEntries().addText(fieldType.names().fullName(), nullValueAsString, boost); + value = fieldType().nullValue(); + if (fieldType().nullValueAsString() != null && (context.includeInAll(includeInAll, this))) { + context.allEntries().addText(fieldType.names().fullName(), fieldType().nullValueAsString(), boost); } } else if (parser.currentToken() == XContentParser.Token.START_OBJECT) { XContentParser.Token token; String currentFieldName = null; - Float objValue = nullValue; + Float objValue = fieldType().nullValue(); while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { if (token == XContentParser.Token.FIELD_NAME) { currentFieldName = parser.currentName(); @@ -346,8 +333,9 @@ public class FloatFieldMapper extends NumberFieldMapper { return; } if (!mergeResult.simulate()) { - this.nullValue = ((FloatFieldMapper) mergeWith).nullValue; - this.nullValueAsString = ((FloatFieldMapper) mergeWith).nullValueAsString; + this.fieldType = this.fieldType.clone(); + this.fieldType.setNullValue(((FloatFieldMapper) mergeWith).fieldType().nullValue()); + this.fieldType.freeze(); } } @@ -359,8 +347,8 @@ public class FloatFieldMapper extends NumberFieldMapper { if (includeDefaults || fieldType.numericPrecisionStep() != Defaults.PRECISION_STEP_32_BIT) { builder.field("precision_step", fieldType.numericPrecisionStep()); } - if (includeDefaults || nullValue != null) { - builder.field("null_value", nullValue); + if (includeDefaults || fieldType().nullValue() != null) { + builder.field("null_value", fieldType().nullValue()); } if (includeInAll != null) { builder.field("include_in_all", includeInAll); diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/IntegerFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/IntegerFieldMapper.java index 0f9eb053fbf..292f271650a 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/core/IntegerFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/core/IntegerFieldMapper.java @@ -42,6 +42,7 @@ import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.index.analysis.NamedAnalyzer; import org.elasticsearch.index.analysis.NumericIntegerAnalyzer; import org.elasticsearch.index.fielddata.FieldDataType; +import org.elasticsearch.index.mapper.FieldMapper; import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.Mapper; import org.elasticsearch.index.mapper.MapperParsingException; @@ -72,21 +73,17 @@ public class IntegerFieldMapper extends NumberFieldMapper { static { FIELD_TYPE.freeze(); } - - public static final Integer NULL_VALUE = null; } public static class Builder extends NumberFieldMapper.Builder { - protected Integer nullValue = Defaults.NULL_VALUE; - public Builder(String name) { super(name, Defaults.FIELD_TYPE, Defaults.PRECISION_STEP_32_BIT); builder = this; } public Builder nullValue(int nullValue) { - this.nullValue = nullValue; + this.fieldType.setNullValue(nullValue); return this; } @@ -94,7 +91,7 @@ public class IntegerFieldMapper extends NumberFieldMapper { public IntegerFieldMapper build(BuilderContext context) { setupFieldType(context); IntegerFieldMapper fieldMapper = new IntegerFieldMapper(fieldType, docValues, - nullValue, ignoreMalformed(context), coerce(context), fieldDataSettings, + ignoreMalformed(context), coerce(context), fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo); fieldMapper.includeInAll(includeInAll); return fieldMapper; @@ -132,7 +129,7 @@ public class IntegerFieldMapper extends NumberFieldMapper { } } - static final class IntegerFieldType extends NumberFieldType { + public static final class IntegerFieldType extends NumberFieldType { public IntegerFieldType() {} @@ -145,6 +142,11 @@ public class IntegerFieldMapper extends NumberFieldMapper { return new IntegerFieldType(this); } + @Override + public Integer nullValue() { + return (Integer)super.nullValue(); + } + @Override public Integer value(Object value) { if (value == null) { @@ -194,17 +196,16 @@ public class IntegerFieldMapper extends NumberFieldMapper { } } - private Integer nullValue; - - private String nullValueAsString; - protected IntegerFieldMapper(MappedFieldType fieldType, Boolean docValues, - Integer nullValue, Explicit ignoreMalformed, Explicit coerce, + Explicit ignoreMalformed, Explicit coerce, @Nullable Settings fieldDataSettings, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) { super(fieldType, docValues, ignoreMalformed, coerce, fieldDataSettings, indexSettings, multiFields, copyTo); - this.nullValue = nullValue; - this.nullValueAsString = nullValue == null ? null : nullValue.toString(); + } + + @Override + public IntegerFieldType fieldType() { + return (IntegerFieldType)fieldType; } @Override @@ -217,8 +218,6 @@ public class IntegerFieldMapper extends NumberFieldMapper { return new FieldDataType("int"); } - - private static int parseValue(Object value) { if (value instanceof Number) { return ((Number) value).intValue(); @@ -229,14 +228,6 @@ public class IntegerFieldMapper extends NumberFieldMapper { return Integer.parseInt(value.toString()); } - @Override - public Query nullValueFilter() { - if (nullValue == null) { - return null; - } - return new ConstantScoreQuery(termQuery(nullValue, null)); - } - @Override protected boolean customBoost() { return true; @@ -249,17 +240,17 @@ public class IntegerFieldMapper extends NumberFieldMapper { if (context.externalValueSet()) { Object externalValue = context.externalValue(); if (externalValue == null) { - if (nullValue == null) { + if (fieldType.nullValue() == null) { return; } - value = nullValue; + value = fieldType().nullValue(); } else if (externalValue instanceof String) { String sExternalValue = (String) externalValue; if (sExternalValue.length() == 0) { - if (nullValue == null) { + if (fieldType().nullValue() == null) { return; } - value = nullValue; + value = fieldType().nullValue(); } else { value = Integer.parseInt(sExternalValue); } @@ -273,17 +264,17 @@ public class IntegerFieldMapper extends NumberFieldMapper { XContentParser parser = context.parser(); if (parser.currentToken() == XContentParser.Token.VALUE_NULL || (parser.currentToken() == XContentParser.Token.VALUE_STRING && parser.textLength() == 0)) { - if (nullValue == null) { + if (fieldType.nullValue() == null) { return; } - value = nullValue; - if (nullValueAsString != null && (context.includeInAll(includeInAll, this))) { - context.allEntries().addText(fieldType.names().fullName(), nullValueAsString, boost); + value = fieldType().nullValue(); + if (fieldType.nullValueAsString() != null && (context.includeInAll(includeInAll, this))) { + context.allEntries().addText(fieldType.names().fullName(), fieldType.nullValueAsString(), boost); } } else if (parser.currentToken() == XContentParser.Token.START_OBJECT) { XContentParser.Token token; String currentFieldName = null; - Integer objValue = nullValue; + Integer objValue = fieldType().nullValue(); while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { if (token == XContentParser.Token.FIELD_NAME) { currentFieldName = parser.currentName(); @@ -316,7 +307,7 @@ public class IntegerFieldMapper extends NumberFieldMapper { protected void addIntegerFields(ParseContext context, List fields, int value, float boost) { if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored()) { - CustomIntegerNumericField field = new CustomIntegerNumericField(this, value, (NumberFieldType)fieldType); + CustomIntegerNumericField field = new CustomIntegerNumericField(this, value, fieldType); field.setBoost(boost); fields.add(field); } @@ -325,10 +316,6 @@ public class IntegerFieldMapper extends NumberFieldMapper { } } - protected Integer nullValue() { - return nullValue; - } - @Override protected String contentType() { return CONTENT_TYPE; @@ -341,8 +328,9 @@ public class IntegerFieldMapper extends NumberFieldMapper { return; } if (!mergeResult.simulate()) { - this.nullValue = ((IntegerFieldMapper) mergeWith).nullValue; - this.nullValueAsString = ((IntegerFieldMapper) mergeWith).nullValueAsString; + this.fieldType = this.fieldType.clone(); + this.fieldType.setNullValue(((FieldMapper)mergeWith).fieldType().nullValue()); + this.fieldType.freeze(); } } @@ -353,8 +341,8 @@ public class IntegerFieldMapper extends NumberFieldMapper { if (includeDefaults || fieldType.numericPrecisionStep() != Defaults.PRECISION_STEP_32_BIT) { builder.field("precision_step", fieldType.numericPrecisionStep()); } - if (includeDefaults || nullValue != null) { - builder.field("null_value", nullValue); + if (includeDefaults || fieldType.nullValue() != null) { + builder.field("null_value", fieldType.nullValue()); } if (includeInAll != null) { builder.field("include_in_all", includeInAll); diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/LongFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/LongFieldMapper.java index ccf20f976f1..2970deeea1a 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/core/LongFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/core/LongFieldMapper.java @@ -72,28 +72,24 @@ public class LongFieldMapper extends NumberFieldMapper { static { FIELD_TYPE.freeze(); } - - public static final Long NULL_VALUE = null; } public static class Builder extends NumberFieldMapper.Builder { - protected Long nullValue = Defaults.NULL_VALUE; - public Builder(String name) { super(name, Defaults.FIELD_TYPE, Defaults.PRECISION_STEP_64_BIT); builder = this; } public Builder nullValue(long nullValue) { - this.nullValue = nullValue; + this.fieldType.setNullValue(nullValue); return this; } @Override public LongFieldMapper build(BuilderContext context) { setupFieldType(context); - LongFieldMapper fieldMapper = new LongFieldMapper(fieldType, docValues, nullValue, + LongFieldMapper fieldMapper = new LongFieldMapper(fieldType, docValues, ignoreMalformed(context), coerce(context), fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo); fieldMapper.includeInAll(includeInAll); return fieldMapper; @@ -144,6 +140,11 @@ public class LongFieldMapper extends NumberFieldMapper { return new LongFieldType(this); } + @Override + public Long nullValue() { + return (Long)super.nullValue(); + } + @Override public Long value(Object value) { if (value == null) { @@ -193,17 +194,16 @@ public class LongFieldMapper extends NumberFieldMapper { } } - private Long nullValue; - - private String nullValueAsString; - protected LongFieldMapper(MappedFieldType fieldType, Boolean docValues, - Long nullValue, Explicit ignoreMalformed, Explicit coerce, + Explicit ignoreMalformed, Explicit coerce, @Nullable Settings fieldDataSettings, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) { super(fieldType, docValues, ignoreMalformed, coerce, fieldDataSettings, indexSettings, multiFields, copyTo); - this.nullValue = nullValue; - this.nullValueAsString = nullValue == null ? null : nullValue.toString(); + } + + @Override + public LongFieldType fieldType() { + return (LongFieldType)fieldType; } @Override @@ -216,14 +216,6 @@ public class LongFieldMapper extends NumberFieldMapper { return new FieldDataType("long"); } - @Override - public Query nullValueFilter() { - if (nullValue == null) { - return null; - } - return new ConstantScoreQuery(termQuery(nullValue, null)); - } - @Override protected boolean customBoost() { return true; @@ -236,17 +228,17 @@ public class LongFieldMapper extends NumberFieldMapper { if (context.externalValueSet()) { Object externalValue = context.externalValue(); if (externalValue == null) { - if (nullValue == null) { + if (fieldType().nullValue() == null) { return; } - value = nullValue; + value = fieldType().nullValue(); } else if (externalValue instanceof String) { String sExternalValue = (String) externalValue; if (sExternalValue.length() == 0) { - if (nullValue == null) { + if (fieldType().nullValue() == null) { return; } - value = nullValue; + value = fieldType().nullValue(); } else { value = Long.parseLong(sExternalValue); } @@ -260,17 +252,17 @@ public class LongFieldMapper extends NumberFieldMapper { XContentParser parser = context.parser(); if (parser.currentToken() == XContentParser.Token.VALUE_NULL || (parser.currentToken() == XContentParser.Token.VALUE_STRING && parser.textLength() == 0)) { - if (nullValue == null) { + if (fieldType().nullValue() == null) { return; } - value = nullValue; - if (nullValueAsString != null && (context.includeInAll(includeInAll, this))) { - context.allEntries().addText(fieldType.names().fullName(), nullValueAsString, boost); + value = fieldType().nullValue(); + if (fieldType().nullValueAsString() != null && (context.includeInAll(includeInAll, this))) { + context.allEntries().addText(fieldType.names().fullName(), fieldType().nullValueAsString(), boost); } } else if (parser.currentToken() == XContentParser.Token.START_OBJECT) { XContentParser.Token token; String currentFieldName = null; - Long objValue = nullValue; + Long objValue = fieldType().nullValue(); while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { if (token == XContentParser.Token.FIELD_NAME) { currentFieldName = parser.currentName(); @@ -320,8 +312,9 @@ public class LongFieldMapper extends NumberFieldMapper { return; } if (!mergeResult.simulate()) { - this.nullValue = ((LongFieldMapper) mergeWith).nullValue; - this.nullValueAsString = ((LongFieldMapper) mergeWith).nullValueAsString; + this.fieldType = this.fieldType.clone(); + this.fieldType.setNullValue(((LongFieldMapper) mergeWith).fieldType().nullValue()); + this.fieldType.freeze(); } } @@ -332,8 +325,8 @@ public class LongFieldMapper extends NumberFieldMapper { if (includeDefaults || fieldType.numericPrecisionStep() != Defaults.PRECISION_STEP_64_BIT) { builder.field("precision_step", fieldType.numericPrecisionStep()); } - if (includeDefaults || nullValue != null) { - builder.field("null_value", nullValue); + if (includeDefaults || fieldType().nullValue() != null) { + builder.field("null_value", fieldType().nullValue()); } if (includeInAll != null) { builder.field("include_in_all", includeInAll); diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/Murmur3FieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/Murmur3FieldMapper.java index 9401081a79f..67acfcbddfd 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/core/Murmur3FieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/core/Murmur3FieldMapper.java @@ -60,7 +60,7 @@ public class Murmur3FieldMapper extends LongFieldMapper { @Override public Murmur3FieldMapper build(BuilderContext context) { setupFieldType(context); - Murmur3FieldMapper fieldMapper = new Murmur3FieldMapper(fieldType, docValues, null, + Murmur3FieldMapper fieldMapper = new Murmur3FieldMapper(fieldType, docValues, ignoreMalformed(context), coerce(context), fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo); fieldMapper.includeInAll(includeInAll); @@ -105,10 +105,10 @@ public class Murmur3FieldMapper extends LongFieldMapper { } protected Murmur3FieldMapper(MappedFieldType fieldType, Boolean docValues, - Long nullValue, Explicit ignoreMalformed, Explicit coerce, + Explicit ignoreMalformed, Explicit coerce, @Nullable Settings fieldDataSettings, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) { - super(fieldType, docValues, nullValue, ignoreMalformed, coerce, + super(fieldType, docValues, ignoreMalformed, coerce, fieldDataSettings, indexSettings, multiFields, copyTo); } diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/ShortFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/ShortFieldMapper.java index 3eefdaf1b6d..1ff63f2a78d 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/core/ShortFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/core/ShortFieldMapper.java @@ -73,28 +73,19 @@ public class ShortFieldMapper extends NumberFieldMapper { static { FIELD_TYPE.freeze(); } - - public static final Short NULL_VALUE = null; } public static class Builder extends NumberFieldMapper.Builder { - protected Short nullValue = Defaults.NULL_VALUE; - public Builder(String name) { super(name, Defaults.FIELD_TYPE, DEFAULT_PRECISION_STEP); builder = this; } - public Builder nullValue(short nullValue) { - this.nullValue = nullValue; - return this; - } - @Override public ShortFieldMapper build(BuilderContext context) { setupFieldType(context); - ShortFieldMapper fieldMapper = new ShortFieldMapper(fieldType, docValues, nullValue, + ShortFieldMapper fieldMapper = new ShortFieldMapper(fieldType, docValues, ignoreMalformed(context), coerce(context), fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo); fieldMapper.includeInAll(includeInAll); @@ -147,6 +138,11 @@ public class ShortFieldMapper extends NumberFieldMapper { return new ShortFieldType(this); } + @Override + public Short nullValue() { + return (Short)super.nullValue(); + } + @Override public Short value(Object value) { if (value == null) { @@ -196,18 +192,17 @@ public class ShortFieldMapper extends NumberFieldMapper { } } - private Short nullValue; - - private String nullValueAsString; - protected ShortFieldMapper(MappedFieldType fieldType, Boolean docValues, - Short nullValue, Explicit ignoreMalformed, Explicit coerce, + Explicit ignoreMalformed, Explicit coerce, @Nullable Settings fieldDataSettings, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) { super(fieldType, docValues, ignoreMalformed, coerce, fieldDataSettings, indexSettings, multiFields, copyTo); - this.nullValue = nullValue; - this.nullValueAsString = nullValue == null ? null : nullValue.toString(); + } + + @Override + public ShortFieldType fieldType() { + return (ShortFieldType)fieldType; } @Override @@ -230,14 +225,6 @@ public class ShortFieldMapper extends NumberFieldMapper { return Short.parseShort(value.toString()); } - @Override - public Query nullValueFilter() { - if (nullValue == null) { - return null; - } - return new ConstantScoreQuery(termQuery(nullValue, null)); - } - @Override protected boolean customBoost() { return true; @@ -250,17 +237,17 @@ public class ShortFieldMapper extends NumberFieldMapper { if (context.externalValueSet()) { Object externalValue = context.externalValue(); if (externalValue == null) { - if (nullValue == null) { + if (fieldType().nullValue() == null) { return; } - value = nullValue; + value = fieldType().nullValue(); } else if (externalValue instanceof String) { String sExternalValue = (String) externalValue; if (sExternalValue.length() == 0) { - if (nullValue == null) { + if (fieldType().nullValue() == null) { return; } - value = nullValue; + value = fieldType().nullValue(); } else { value = Short.parseShort(sExternalValue); } @@ -274,17 +261,17 @@ public class ShortFieldMapper extends NumberFieldMapper { XContentParser parser = context.parser(); if (parser.currentToken() == XContentParser.Token.VALUE_NULL || (parser.currentToken() == XContentParser.Token.VALUE_STRING && parser.textLength() == 0)) { - if (nullValue == null) { + if (fieldType().nullValue() == null) { return; } - value = nullValue; - if (nullValueAsString != null && (context.includeInAll(includeInAll, this))) { - context.allEntries().addText(fieldType.names().fullName(), nullValueAsString, boost); + value = fieldType().nullValue(); + if (fieldType().nullValueAsString() != null && (context.includeInAll(includeInAll, this))) { + context.allEntries().addText(fieldType.names().fullName(), fieldType().nullValueAsString(), boost); } } else if (parser.currentToken() == XContentParser.Token.START_OBJECT) { XContentParser.Token token; String currentFieldName = null; - Short objValue = nullValue; + Short objValue = fieldType().nullValue(); while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { if (token == XContentParser.Token.FIELD_NAME) { currentFieldName = parser.currentName(); @@ -334,8 +321,9 @@ public class ShortFieldMapper extends NumberFieldMapper { return; } if (!mergeResult.simulate()) { - this.nullValue = ((ShortFieldMapper) mergeWith).nullValue; - this.nullValueAsString = ((ShortFieldMapper) mergeWith).nullValueAsString; + this.fieldType = this.fieldType.clone(); + this.fieldType.setNullValue(((ShortFieldMapper) mergeWith).fieldType().nullValue()); + this.fieldType.freeze(); } } @@ -346,8 +334,8 @@ public class ShortFieldMapper extends NumberFieldMapper { if (includeDefaults || fieldType.numericPrecisionStep() != DEFAULT_PRECISION_STEP) { builder.field("precision_step", fieldType.numericPrecisionStep()); } - if (includeDefaults || nullValue != null) { - builder.field("null_value", nullValue); + if (includeDefaults || fieldType().nullValue() != null) { + builder.field("null_value", fieldType().nullValue()); } if (includeInAll != null) { builder.field("include_in_all", includeInAll); diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/StringFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/StringFieldMapper.java index 52458fffb00..eadf2985bdf 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/core/StringFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/core/StringFieldMapper.java @@ -83,11 +83,6 @@ public class StringFieldMapper extends AbstractFieldMapper implements AllFieldMa builder = this; } - public Builder nullValue(String nullValue) { - this.nullValue = nullValue; - return this; - } - @Override public Builder searchAnalyzer(NamedAnalyzer searchAnalyzer) { super.searchAnalyzer(searchAnalyzer); @@ -135,7 +130,7 @@ public class StringFieldMapper extends AbstractFieldMapper implements AllFieldMa defaultFieldType.freeze(); setupFieldType(context); StringFieldMapper fieldMapper = new StringFieldMapper( - fieldType, defaultFieldType, docValues, nullValue, positionOffsetGap, ignoreAbove, + fieldType, defaultFieldType, docValues, positionOffsetGap, ignoreAbove, fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo); fieldMapper.includeInAll(includeInAll); return fieldMapper; @@ -210,23 +205,29 @@ public class StringFieldMapper extends AbstractFieldMapper implements AllFieldMa } return value.toString(); } + + @Override + public Query nullValueQuery() { + if (nullValue() == null) { + return null; + } + return termQuery(nullValue(), null); + } } - private String nullValue; private Boolean includeInAll; private int positionOffsetGap; private int ignoreAbove; private final MappedFieldType defaultFieldType; protected StringFieldMapper(MappedFieldType fieldType, MappedFieldType defaultFieldType, Boolean docValues, - String nullValue, int positionOffsetGap, int ignoreAbove, @Nullable Settings fieldDataSettings, + int positionOffsetGap, int ignoreAbove, @Nullable Settings fieldDataSettings, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) { super(fieldType, docValues, fieldDataSettings, indexSettings, multiFields, copyTo); if (fieldType.tokenized() && fieldType.indexOptions() != NONE && fieldType().hasDocValues()) { throw new MapperParsingException("Field [" + fieldType.names().fullName() + "] cannot be analyzed and have doc values"); } this.defaultFieldType = defaultFieldType; - this.nullValue = nullValue; this.positionOffsetGap = positionOffsetGap; this.ignoreAbove = ignoreAbove; } @@ -273,17 +274,9 @@ public class StringFieldMapper extends AbstractFieldMapper implements AllFieldMa return ignoreAbove; } - @Override - public Query nullValueFilter() { - if (nullValue == null) { - return null; - } - return termQuery(nullValue, null); - } - @Override protected void parseCreateField(ParseContext context, List fields) throws IOException { - ValueAndBoost valueAndBoost = parseCreateFieldForString(context, nullValue, fieldType.boost()); + ValueAndBoost valueAndBoost = parseCreateFieldForString(context, fieldType().nullValueAsString(), fieldType.boost()); if (valueAndBoost.value() == null) { return; } @@ -359,8 +352,10 @@ public class StringFieldMapper extends AbstractFieldMapper implements AllFieldMa } if (!mergeResult.simulate()) { this.includeInAll = ((StringFieldMapper) mergeWith).includeInAll; - this.nullValue = ((StringFieldMapper) mergeWith).nullValue; this.ignoreAbove = ((StringFieldMapper) mergeWith).ignoreAbove; + this.fieldType = this.fieldType.clone(); + this.fieldType.setNullValue(((StringFieldMapper) mergeWith).fieldType().nullValue()); + this.fieldType.freeze(); } } @@ -368,8 +363,8 @@ public class StringFieldMapper extends AbstractFieldMapper implements AllFieldMa protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException { super.doXContentBody(builder, includeDefaults, params); - if (includeDefaults || nullValue != null) { - builder.field("null_value", nullValue); + if (includeDefaults || fieldType().nullValue() != null) { + builder.field("null_value", fieldType().nullValue()); } if (includeInAll != null) { builder.field("include_in_all", includeInAll); diff --git a/core/src/main/java/org/elasticsearch/index/mapper/core/TokenCountFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/core/TokenCountFieldMapper.java index eb53c172df4..827f186cf5b 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/core/TokenCountFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/core/TokenCountFieldMapper.java @@ -60,7 +60,6 @@ public class TokenCountFieldMapper extends IntegerFieldMapper { } public static class Builder extends NumberFieldMapper.Builder { - private Integer nullValue = Defaults.NULL_VALUE; private NamedAnalyzer analyzer; public Builder(String name) { @@ -68,11 +67,6 @@ public class TokenCountFieldMapper extends IntegerFieldMapper { builder = this; } - public Builder nullValue(int nullValue) { - this.nullValue = nullValue; - return this; - } - public Builder analyzer(NamedAnalyzer analyzer) { this.analyzer = analyzer; return this; @@ -85,7 +79,7 @@ public class TokenCountFieldMapper extends IntegerFieldMapper { @Override public TokenCountFieldMapper build(BuilderContext context) { setupFieldType(context); - TokenCountFieldMapper fieldMapper = new TokenCountFieldMapper(fieldType, docValues, nullValue, + TokenCountFieldMapper fieldMapper = new TokenCountFieldMapper(fieldType, docValues, ignoreMalformed(context), coerce(context), fieldDataSettings, context.indexSettings(), analyzer, multiFieldsBuilder.build(this, context), copyTo); fieldMapper.includeInAll(includeInAll); @@ -134,26 +128,24 @@ public class TokenCountFieldMapper extends IntegerFieldMapper { private NamedAnalyzer analyzer; - protected TokenCountFieldMapper(MappedFieldType fieldType, Boolean docValues, Integer nullValue, - Explicit ignoreMalformed, Explicit coerce, Settings fieldDataSettings, Settings indexSettings, NamedAnalyzer analyzer, - MultiFields multiFields, CopyTo copyTo) { - super(fieldType, docValues, nullValue, ignoreMalformed, coerce, - fieldDataSettings, indexSettings, multiFields, copyTo); - + protected TokenCountFieldMapper(MappedFieldType fieldType, Boolean docValues, Explicit ignoreMalformed, + Explicit coerce, Settings fieldDataSettings, Settings indexSettings, + NamedAnalyzer analyzer, MultiFields multiFields, CopyTo copyTo) { + super(fieldType, docValues, ignoreMalformed, coerce, fieldDataSettings, indexSettings, multiFields, copyTo); this.analyzer = analyzer; } @Override protected void parseCreateField(ParseContext context, List fields) throws IOException { ValueAndBoost valueAndBoost = StringFieldMapper.parseCreateFieldForString(context, null /* Out null value is an int so we convert*/, fieldType.boost()); - if (valueAndBoost.value() == null && nullValue() == null) { + if (valueAndBoost.value() == null && fieldType().nullValue() == null) { return; } if (fieldType.indexOptions() != NONE || fieldType.stored() || fieldType().hasDocValues()) { int count; if (valueAndBoost.value() == null) { - count = nullValue(); + count = fieldType().nullValue(); } else { count = countPositions(analyzer.analyzer().tokenStream(fieldType().names().shortName(), valueAndBoost.value())); } diff --git a/core/src/main/java/org/elasticsearch/index/mapper/internal/SizeFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/internal/SizeFieldMapper.java index a9435c5a1da..023c56a6a52 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/internal/SizeFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/internal/SizeFieldMapper.java @@ -123,7 +123,7 @@ public class SizeFieldMapper extends IntegerFieldMapper implements RootMapper { } public SizeFieldMapper(EnabledAttributeMapper enabled, MappedFieldType fieldType, @Nullable Settings fieldDataSettings, Settings indexSettings) { - super(fieldType, false, Defaults.NULL_VALUE, + super(fieldType, false, Defaults.IGNORE_MALFORMED, Defaults.COERCE, fieldDataSettings, indexSettings, MultiFields.empty(), null); this.enabledState = enabled; diff --git a/core/src/main/java/org/elasticsearch/index/mapper/internal/TTLFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/internal/TTLFieldMapper.java index 81f24ada779..aa487ce81da 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/internal/TTLFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/internal/TTLFieldMapper.java @@ -174,7 +174,7 @@ public class TTLFieldMapper extends LongFieldMapper implements RootMapper { protected TTLFieldMapper(MappedFieldType fieldType, EnabledAttributeMapper enabled, long defaultTTL, Explicit ignoreMalformed, Explicit coerce, @Nullable Settings fieldDataSettings, Settings indexSettings) { - super(fieldType, false, Defaults.NULL_VALUE, ignoreMalformed, coerce, + super(fieldType, false, ignoreMalformed, coerce, fieldDataSettings, indexSettings, MultiFields.empty(), null); this.enabledState = enabled; this.defaultTTL = defaultTTL; diff --git a/core/src/main/java/org/elasticsearch/index/mapper/internal/TimestampFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/internal/TimestampFieldMapper.java index 149cac7f1aa..28fd13890a2 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/internal/TimestampFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/internal/TimestampFieldMapper.java @@ -251,7 +251,7 @@ public class TimestampFieldMapper extends DateFieldMapper implements RootMapper protected TimestampFieldMapper(MappedFieldType fieldType, Boolean docValues, EnabledAttributeMapper enabledState, String path, String defaultTimestamp, Boolean ignoreMissing, Explicit ignoreMalformed, Explicit coerce, @Nullable Settings fieldDataSettings, Settings indexSettings) { - super(fieldType, docValues, Defaults.NULL_VALUE, ignoreMalformed, coerce, fieldDataSettings, + super(fieldType, docValues, ignoreMalformed, coerce, fieldDataSettings, indexSettings, MultiFields.empty(), null); this.enabledState = enabledState; this.path = path; diff --git a/core/src/main/java/org/elasticsearch/index/mapper/ip/IpFieldMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/ip/IpFieldMapper.java index 8bc1f3eeecf..87bed23318b 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/ip/IpFieldMapper.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/ip/IpFieldMapper.java @@ -115,15 +115,10 @@ public class IpFieldMapper extends NumberFieldMapper { builder = this; } - public Builder nullValue(String nullValue) { - this.nullValue = nullValue; - return this; - } - @Override public IpFieldMapper build(BuilderContext context) { setupFieldType(context); - IpFieldMapper fieldMapper = new IpFieldMapper(fieldType, docValues, nullValue, ignoreMalformed(context), coerce(context), + IpFieldMapper fieldMapper = new IpFieldMapper(fieldType, docValues, ignoreMalformed(context), coerce(context), fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo); fieldMapper.includeInAll(includeInAll); return fieldMapper; @@ -232,15 +227,12 @@ public class IpFieldMapper extends NumberFieldMapper { } } - private String nullValue; - protected IpFieldMapper(MappedFieldType fieldType, Boolean docValues, - String nullValue, Explicit ignoreMalformed, Explicit coerce, + Explicit ignoreMalformed, Explicit coerce, @Nullable Settings fieldDataSettings, Settings indexSettings, MultiFields multiFields, CopyTo copyTo) { super(fieldType, docValues, ignoreMalformed, coerce, fieldDataSettings, indexSettings, multiFields, copyTo); - this.nullValue = nullValue; } @Override @@ -263,25 +255,17 @@ public class IpFieldMapper extends NumberFieldMapper { return ipToLong(value.toString()); } - @Override - public Query nullValueFilter() { - if (nullValue == null) { - return null; - } - return new ConstantScoreQuery(termQuery(nullValue, null)); - } - @Override protected void innerParseCreateField(ParseContext context, List fields) throws IOException { String ipAsString; if (context.externalValueSet()) { ipAsString = (String) context.externalValue(); if (ipAsString == null) { - ipAsString = nullValue; + ipAsString = fieldType().nullValueAsString(); } } else { if (context.parser().currentToken() == XContentParser.Token.VALUE_NULL) { - ipAsString = nullValue; + ipAsString = fieldType().nullValueAsString(); } else { ipAsString = context.parser().text(); } @@ -317,7 +301,8 @@ public class IpFieldMapper extends NumberFieldMapper { return; } if (!mergeResult.simulate()) { - this.nullValue = ((IpFieldMapper) mergeWith).nullValue; + this.fieldType = this.fieldType.clone(); + this.fieldType.setNullValue(((IpFieldMapper) mergeWith).fieldType().nullValue()); } } @@ -328,8 +313,8 @@ public class IpFieldMapper extends NumberFieldMapper { if (includeDefaults || fieldType.numericPrecisionStep() != Defaults.PRECISION_STEP_64_BIT) { builder.field("precision_step", fieldType.numericPrecisionStep()); } - if (includeDefaults || nullValue != null) { - builder.field("null_value", nullValue); + if (includeDefaults || fieldType().nullValueAsString() != null) { + builder.field("null_value", fieldType().nullValueAsString()); } if (includeInAll != null) { builder.field("include_in_all", includeInAll);