@@ -51,13 +51,13 @@ static Map<String, FieldSpecificMatcher> matchers(
5151 return new HashMap <>() {
5252 {
5353 put ("keyword" , new KeywordMatcher (actualMappings , actualSettings , expectedMappings , expectedSettings ));
54- put ("long" , new NumberMatcher ( "long" , actualMappings , actualSettings , expectedMappings , expectedSettings ));
54+ put ("long" , new LongMatcher ( actualMappings , actualSettings , expectedMappings , expectedSettings ));
5555 put ("unsigned_long" , new UnsignedLongMatcher (actualMappings , actualSettings , expectedMappings , expectedSettings ));
56- put ("integer" , new NumberMatcher ( "integer" , actualMappings , actualSettings , expectedMappings , expectedSettings ));
57- put ("short" , new NumberMatcher ( "short" , actualMappings , actualSettings , expectedMappings , expectedSettings ));
58- put ("byte" , new NumberMatcher ( "byte" , actualMappings , actualSettings , expectedMappings , expectedSettings ));
59- put ("double" , new NumberMatcher ( "double" , actualMappings , actualSettings , expectedMappings , expectedSettings ));
60- put ("float" , new NumberMatcher ( "float" , actualMappings , actualSettings , expectedMappings , expectedSettings ));
56+ put ("integer" , new IntegerMatcher ( actualMappings , actualSettings , expectedMappings , expectedSettings ));
57+ put ("short" , new ShortMatcher ( actualMappings , actualSettings , expectedMappings , expectedSettings ));
58+ put ("byte" , new ByteMatcher ( actualMappings , actualSettings , expectedMappings , expectedSettings ));
59+ put ("double" , new DoubleMatcher ( actualMappings , actualSettings , expectedMappings , expectedSettings ));
60+ put ("float" , new FloatMatcher ( actualMappings , actualSettings , expectedMappings , expectedSettings ));
6161 put ("half_float" , new HalfFloatMatcher (actualMappings , actualSettings , expectedMappings , expectedSettings ));
6262 put ("scaled_float" , new ScaledFloatMatcher (actualMappings , actualSettings , expectedMappings , expectedSettings ));
6363 put ("counted_keyword" , new CountedKeywordMatcher (actualMappings , actualSettings , expectedMappings , expectedSettings ));
@@ -327,9 +327,15 @@ Object convert(Object value, Object nullValue) {
327327 yield nullValueBigInt ;
328328 }
329329
330- yield s ;
330+ try {
331+ yield new BigInteger (s );
332+ } catch (NumberFormatException e ) {
333+ // malformed
334+ yield value ;
335+ }
331336 }
332337 case Long l -> BigInteger .valueOf (l );
338+ case Integer i -> BigInteger .valueOf (i );
333339 default -> value ;
334340 };
335341
@@ -356,31 +362,30 @@ Object convert(Object value, Object nullValue) {
356362 }
357363 }
358364
359- class NumberMatcher extends GenericMappingAwareMatcher {
365+ abstract class NumberMatcher extends GenericMappingAwareMatcher {
360366
361- private final FieldType fieldType ;
362367 private final NumberFieldMapper .NumberType numberType ;
363368
364- NumberMatcher (
365- String fieldType ,
369+ private NumberMatcher (
370+ FieldType fieldType ,
366371 XContentBuilder actualMappings ,
367372 Settings .Builder actualSettings ,
368373 XContentBuilder expectedMappings ,
369374 Settings .Builder expectedSettings
370375 ) {
371- super (fieldType , actualMappings , actualSettings , expectedMappings , expectedSettings );
372- this .fieldType = FieldType .tryParse (fieldType );
373- this .numberType = NumberFieldMapper .NumberType .valueOf (this .fieldType .name ());
376+ super (fieldType .toString (), actualMappings , actualSettings , expectedMappings , expectedSettings );
377+ this .numberType = NumberFieldMapper .NumberType .valueOf (fieldType .name ());
374378 }
375379
376380 @ Override
377381 Object convert (Object value , Object nullValue ) {
378382 if (value == null ) {
379- return nullValue ;
383+ return cast ( nullValue ) ;
380384 }
385+
381386 // Special case for number coercion from strings
382387 if (value instanceof String s && s .isEmpty ()) {
383- return nullValue ;
388+ return cast ( nullValue ) ;
384389 }
385390
386391 // Attempt to coerce string values into numbers
@@ -394,25 +399,111 @@ Object convert(Object value, Object nullValue) {
394399 }
395400 }
396401
397- // When a number mapping is coerced, the expected value will come from the above parser and will have the correct java type.
398- // Whereas, if it fits, the actual value will be in an Integer or a Double. To correctly treat expected and actual values as
399- // equal the actual value must be cast to the appropriate type.
400- if (value instanceof Integer v ) {
401- return switch (fieldType ) {
402- case LONG -> v .longValue ();
403- case SHORT -> v .shortValue ();
404- case BYTE -> v .byteValue ();
405- default -> value ;
406- };
407- }
408- if (value instanceof Double v ) {
409- return fieldType == FieldType .FLOAT ? v .floatValue () : value ;
410- }
402+ return cast (value );
403+ }
404+
405+ // When a number mapping is coerced, the expected value will come from the above parser and will have the correct java type.
406+ // Whereas, if it fits, the actual value will be in an Integer or a Double. To correctly treat expected and actual values as
407+ // equal the actual value must be cast to the appropriate type.
408+ abstract Object cast (Object value );
409+ }
410+
411+ class LongMatcher extends NumberMatcher {
412+ LongMatcher (
413+ XContentBuilder actualMappings ,
414+ Settings .Builder actualSettings ,
415+ XContentBuilder expectedMappings ,
416+ Settings .Builder expectedSettings
417+ ) {
418+ super (FieldType .LONG , actualMappings , actualSettings , expectedMappings , expectedSettings );
419+ }
420+
421+ @ Override
422+ protected Object cast (Object value ) {
423+ return value instanceof Integer v ? v .longValue () : value ;
424+ }
425+ }
426+
427+ class IntegerMatcher extends NumberMatcher {
428+ IntegerMatcher (
429+ XContentBuilder actualMappings ,
430+ Settings .Builder actualSettings ,
431+ XContentBuilder expectedMappings ,
432+ Settings .Builder expectedSettings
433+ ) {
434+ super (FieldType .INTEGER , actualMappings , actualSettings , expectedMappings , expectedSettings );
435+ }
436+
437+ @ Override
438+ protected Object cast (Object value ) {
439+ return value ;
440+ }
441+ }
442+
443+ class ShortMatcher extends NumberMatcher {
444+ ShortMatcher (
445+ XContentBuilder actualMappings ,
446+ Settings .Builder actualSettings ,
447+ XContentBuilder expectedMappings ,
448+ Settings .Builder expectedSettings
449+ ) {
450+ super (FieldType .SHORT , actualMappings , actualSettings , expectedMappings , expectedSettings );
451+ }
452+
453+ @ Override
454+ protected Object cast (Object value ) {
455+ return value instanceof Integer v ? v .shortValue () : value ;
456+ }
457+ }
458+
459+ class ByteMatcher extends NumberMatcher {
460+ ByteMatcher (
461+ XContentBuilder actualMappings ,
462+ Settings .Builder actualSettings ,
463+ XContentBuilder expectedMappings ,
464+ Settings .Builder expectedSettings
465+ ) {
466+ super (FieldType .BYTE , actualMappings , actualSettings , expectedMappings , expectedSettings );
467+ }
468+
469+ @ Override
470+ protected Object cast (Object value ) {
471+ return value instanceof Integer v ? v .byteValue () : value ;
472+ }
473+ }
411474
475+ class DoubleMatcher extends NumberMatcher {
476+ DoubleMatcher (
477+ XContentBuilder actualMappings ,
478+ Settings .Builder actualSettings ,
479+ XContentBuilder expectedMappings ,
480+ Settings .Builder expectedSettings
481+ ) {
482+ super (FieldType .DOUBLE , actualMappings , actualSettings , expectedMappings , expectedSettings );
483+ }
484+
485+ @ Override
486+ protected Object cast (Object value ) {
412487 return value ;
413488 }
414489 }
415490
491+ class FloatMatcher extends NumberMatcher {
492+ FloatMatcher (
493+ XContentBuilder actualMappings ,
494+ Settings .Builder actualSettings ,
495+ XContentBuilder expectedMappings ,
496+ Settings .Builder expectedSettings
497+ ) {
498+ super (FieldType .FLOAT , actualMappings , actualSettings , expectedMappings , expectedSettings );
499+ }
500+
501+ @ Override
502+ protected Object cast (Object value ) {
503+ return value instanceof Integer v ? v .floatValue () : value ;
504+ }
505+ }
506+
416507 class BooleanMatcher extends GenericMappingAwareMatcher {
417508 BooleanMatcher (
418509 XContentBuilder actualMappings ,
0 commit comments