Restore v7 support in DateFieldMapper and IPFieldMapper (#119050)

This restores deprecation warnings previously removed with #113023 and
restores some additional tests due to N-2 read-only support.
This commit is contained in:
Christoph Büscher 2024-12-19 16:02:23 +01:00 committed by GitHub
parent 5f293f34f7
commit e43cdf744a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 98 additions and 2 deletions

View file

@ -25,6 +25,8 @@ import org.apache.lucene.search.IndexSortSortedNumericDocValuesRangeQuery;
import org.apache.lucene.search.Query;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.geo.ShapeRelation;
import org.elasticsearch.common.logging.DeprecationCategory;
import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.common.lucene.BytesRefs;
import org.elasticsearch.common.time.DateFormatter;
import org.elasticsearch.common.time.DateFormatters;
@ -34,6 +36,7 @@ import org.elasticsearch.common.util.LocaleUtils;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.index.IndexVersion;
import org.elasticsearch.index.IndexVersions;
import org.elasticsearch.index.fielddata.FieldDataContext;
import org.elasticsearch.index.fielddata.IndexFieldData;
import org.elasticsearch.index.fielddata.IndexNumericFieldData.NumericType;
@ -76,6 +79,7 @@ import static org.elasticsearch.common.time.DateUtils.toLong;
/** A {@link FieldMapper} for dates. */
public final class DateFieldMapper extends FieldMapper {
private static final DeprecationLogger DEPRECATION_LOGGER = DeprecationLogger.getLogger(DateFieldMapper.class);
private static final Logger logger = LogManager.getLogger(DateFieldMapper.class);
public static final String CONTENT_TYPE = "date";
@ -342,7 +346,20 @@ public final class DateFieldMapper extends FieldMapper {
try {
return fieldType.parse(nullValue.getValue());
} catch (Exception e) {
throw new MapperParsingException("Error parsing [null_value] on field [" + leafName() + "]: " + e.getMessage(), e);
if (indexCreatedVersion.onOrAfter(IndexVersions.V_8_0_0)) {
throw new MapperParsingException("Error parsing [null_value] on field [" + leafName() + "]: " + e.getMessage(), e);
} else {
DEPRECATION_LOGGER.warn(
DeprecationCategory.MAPPINGS,
"date_mapper_null_field",
"Error parsing ["
+ nullValue.getValue()
+ "] as date in [null_value] on field ["
+ leafName()
+ "]); [null_value] will be ignored"
);
return null;
}
}
}

View file

@ -23,11 +23,14 @@ import org.apache.lucene.search.PointRangeQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.automaton.CompiledAutomaton;
import org.elasticsearch.common.logging.DeprecationCategory;
import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.common.network.InetAddresses;
import org.elasticsearch.common.network.NetworkAddress;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.core.Tuple;
import org.elasticsearch.index.IndexVersion;
import org.elasticsearch.index.IndexVersions;
import org.elasticsearch.index.fielddata.FieldDataContext;
import org.elasticsearch.index.fielddata.IndexFieldData;
import org.elasticsearch.index.fielddata.plain.SortedSetOrdinalsIndexFieldData;
@ -59,6 +62,8 @@ import static org.elasticsearch.index.mapper.IpPrefixAutomatonUtil.buildIpPrefix
*/
public class IpFieldMapper extends FieldMapper {
private static final DeprecationLogger DEPRECATION_LOGGER = DeprecationLogger.getLogger(IpFieldMapper.class);
public static final String CONTENT_TYPE = "ip";
private static IpFieldMapper toType(FieldMapper in) {
@ -129,7 +134,20 @@ public class IpFieldMapper extends FieldMapper {
try {
return InetAddresses.forString(nullValueAsString);
} catch (Exception e) {
throw new MapperParsingException("Error parsing [null_value] on field [" + leafName() + "]: " + e.getMessage(), e);
if (indexCreatedVersion.onOrAfter(IndexVersions.V_8_0_0)) {
throw new MapperParsingException("Error parsing [null_value] on field [" + leafName() + "]: " + e.getMessage(), e);
} else {
DEPRECATION_LOGGER.warn(
DeprecationCategory.MAPPINGS,
"ip_mapper_null_field",
"Error parsing ["
+ nullValue.getValue()
+ "] as IP in [null_value] on field ["
+ leafName()
+ "]); [null_value] will be ignored"
);
return null;
}
}
}

View file

@ -20,7 +20,9 @@ import org.elasticsearch.index.IndexVersion;
import org.elasticsearch.index.IndexVersions;
import org.elasticsearch.index.mapper.DateFieldMapper.DateFieldType;
import org.elasticsearch.script.DateFieldScript;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.search.DocValueFormat;
import org.elasticsearch.test.index.IndexVersionUtils;
import org.elasticsearch.xcontent.XContentBuilder;
import java.io.IOException;
@ -44,6 +46,7 @@ import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.lessThan;
import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.hamcrest.Matchers.notNullValue;
import static org.mockito.Mockito.mock;
public class DateFieldMapperTests extends MapperTestCase {
@ -245,6 +248,10 @@ public class DateFieldMapperTests extends MapperTestCase {
+ "failed to parse date field [foo] with format [strict_date_optional_time||epoch_millis]"
)
);
createDocumentMapper(IndexVersions.V_7_9_0, fieldMapping(b -> b.field("type", "date").field("null_value", "foo")));
assertWarnings("Error parsing [foo] as date in [null_value] on field [field]); [null_value] will be ignored");
}
public void testNullConfigValuesFail() {
@ -757,4 +764,51 @@ public class DateFieldMapperTests extends MapperTestCase {
assertNotEquals(DEFAULT_DATE_TIME_FORMATTER, ((DateFieldType) service.fieldType("mydate")).dateTimeFormatter);
}
public void testLegacyDateFormatName() {
DateFieldMapper.Builder builder = new DateFieldMapper.Builder(
"format",
DateFieldMapper.Resolution.MILLISECONDS,
null,
mock(ScriptService.class),
true,
// BWC compatible index, e.g 7.x
IndexVersionUtils.randomVersionBetween(
random(),
IndexVersions.V_7_0_0,
IndexVersionUtils.getPreviousVersion(IndexVersions.V_8_0_0)
)
);
// Check that we allow the use of camel case date formats on 7.x indices
@SuppressWarnings("unchecked")
FieldMapper.Parameter<String> formatParam = (FieldMapper.Parameter<String>) builder.getParameters()[3];
formatParam.parse("date_time_format", mock(MappingParserContext.class), "strictDateOptionalTime");
builder.buildFormatter(); // shouldn't throw exception
formatParam.parse("date_time_format", mock(MappingParserContext.class), "strictDateOptionalTime||strictDateOptionalTimeNanos");
builder.buildFormatter(); // shouldn't throw exception
DateFieldMapper.Builder newFieldBuilder = new DateFieldMapper.Builder(
"format",
DateFieldMapper.Resolution.MILLISECONDS,
null,
mock(ScriptService.class),
true,
IndexVersion.current()
);
@SuppressWarnings("unchecked")
final FieldMapper.Parameter<String> newFormatParam = (FieldMapper.Parameter<String>) newFieldBuilder.getParameters()[3];
// Check that we don't allow the use of camel case date formats on 8.x indices
assertEquals(
"Error parsing [format] on field [format]: Invalid format: [strictDateOptionalTime]: Unknown pattern letter: t",
expectThrows(IllegalArgumentException.class, () -> {
newFormatParam.parse("date_time_format", mock(MappingParserContext.class), "strictDateOptionalTime");
assertEquals("strictDateOptionalTime", newFormatParam.getValue());
newFieldBuilder.buildFormatter();
}).getMessage()
);
}
}

View file

@ -21,6 +21,7 @@ import org.elasticsearch.common.network.NetworkAddress;
import org.elasticsearch.core.Tuple;
import org.elasticsearch.index.IndexMode;
import org.elasticsearch.index.IndexVersion;
import org.elasticsearch.index.IndexVersions;
import org.elasticsearch.script.IpFieldScript;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xcontent.XContentBuilder;
@ -208,6 +209,12 @@ public class IpFieldMapperTests extends MapperTestCase {
e.getMessage(),
"Failed to parse mapping: Error parsing [null_value] on field [field]: ':1' is not an IP string literal."
);
createDocumentMapper(IndexVersions.V_7_9_0, fieldMapping(b -> {
b.field("type", "ip");
b.field("null_value", ":1");
}));
assertWarnings("Error parsing [:1] as IP in [null_value] on field [field]); [null_value] will be ignored");
}
public void testDimension() throws IOException {