2121import java .util .ArrayList ;
2222import java .util .Arrays ;
2323import java .util .Collections ;
24+ import java .util .HashMap ;
2425import java .util .List ;
2526import java .util .Map ;
27+ import java .util .StringJoiner ;
2628import java .util .function .Supplier ;
2729
2830import static java .util .Arrays .asList ;
@@ -47,7 +49,7 @@ protected Reader<FieldHitExtractor> instanceReader() {
4749 }
4850
4951 @ Override
50- protected FieldHitExtractor mutateInstance (FieldHitExtractor instance ) throws IOException {
52+ protected FieldHitExtractor mutateInstance (FieldHitExtractor instance ) {
5153 return new FieldHitExtractor (instance .fieldName () + "mutated" , null , true , instance .hitName ());
5254 }
5355
@@ -237,7 +239,104 @@ public void testMultiValuedSource() {
237239 assertThat (ex .getMessage (), is ("Arrays (returned by [a]) are not supported" ));
238240 }
239241
240- public Object randomValue () {
242+ public void testFieldWithDots () {
243+ FieldHitExtractor fe = new FieldHitExtractor ("a.b" , null , false );
244+ Object value = randomValue ();
245+ Map <String , Object > map = singletonMap ("a.b" , value );
246+ assertEquals (value , fe .extractFromSource (map ));
247+ }
248+
249+ public void testNestedFieldWithDots () {
250+ FieldHitExtractor fe = new FieldHitExtractor ("a.b.c" , null , false );
251+ Object value = randomValue ();
252+ Map <String , Object > map = singletonMap ("a" , singletonMap ("b.c" , value ));
253+ assertEquals (value , fe .extractFromSource (map ));
254+ }
255+
256+ public void testNestedFieldWithDotsWithNestedField () {
257+ FieldHitExtractor fe = new FieldHitExtractor ("a.b.c.d" , null , false );
258+ Object value = randomValue ();
259+ Map <String , Object > map = singletonMap ("a" , singletonMap ("b.c" , singletonMap ("d" , value )));
260+ assertEquals (value , fe .extractFromSource (map ));
261+ }
262+
263+ public void testNestedFieldWithDotsWithNestedFieldWithDots () {
264+ FieldHitExtractor fe = new FieldHitExtractor ("a.b.c.d.e" , null , false );
265+ Object value = randomValue ();
266+ Map <String , Object > map = singletonMap ("a" , singletonMap ("b.c" , singletonMap ("d.e" , value )));
267+ assertEquals (value , fe .extractFromSource (map ));
268+ }
269+
270+ public void testNestedFieldsWithDotsAndRandomHiearachy () {
271+ String [] path = new String [100 ];
272+ StringJoiner sj = new StringJoiner ("." );
273+ for (int i = 0 ; i < 100 ; i ++) {
274+ path [i ] = randomAlphaOfLength (randomIntBetween (1 , 10 ));
275+ sj .add (path [i ]);
276+ }
277+ FieldHitExtractor fe = new FieldHitExtractor (sj .toString (), null , false );
278+
279+ List <String > paths = new ArrayList <>(path .length );
280+ int start = 0 ;
281+ while (start < path .length ) {
282+ int end = randomIntBetween (start + 1 , path .length );
283+ sj = new StringJoiner ("." );
284+ for (int j = start ; j < end ; j ++) {
285+ sj .add (path [j ]);
286+ }
287+ paths .add (sj .toString ());
288+ start = end ;
289+ }
290+
291+ Object value = randomValue ();
292+ Map <String , Object > map = singletonMap (paths .get (paths .size () - 1 ), value );
293+ for (int i = paths .size () - 2 ; i >= 0 ; i --) {
294+ map = singletonMap (paths .get (i ), map );
295+ }
296+ assertEquals (value , fe .extractFromSource (map ));
297+ }
298+
299+ public void testExtractSourceIncorrectPathWithFieldWithDots () {
300+ FieldHitExtractor fe = new FieldHitExtractor ("a.b.c.d.e" , null , false );
301+ Object value = randomNonNullValue ();
302+ Map <String , Object > map = singletonMap ("a" , singletonMap ("b.c" , singletonMap ("d" , value )));
303+ SqlException ex = expectThrows (SqlException .class , () -> fe .extractFromSource (map ));
304+ assertThat (ex .getMessage (), is ("Cannot extract value [a.b.c.d.e] from source" ));
305+ }
306+
307+ public void testFieldWithDotsAndCommonPrefix () {
308+ FieldHitExtractor fe1 = new FieldHitExtractor ("a.d" , null , false );
309+ FieldHitExtractor fe2 = new FieldHitExtractor ("a.b.c" , null , false );
310+ Object value = randomNonNullValue ();
311+ Map <String , Object > map = new HashMap <>();
312+ map .put ("a" , singletonMap ("d" , value ));
313+ map .put ("a.b" , singletonMap ("c" , value ));
314+ assertEquals (value , fe1 .extractFromSource (map ));
315+ assertEquals (value , fe2 .extractFromSource (map ));
316+ }
317+
318+ public void testFieldWithDotsAndCommonPrefixes () {
319+ FieldHitExtractor fe1 = new FieldHitExtractor ("a1.b.c.d1.e.f.g1" , null , false );
320+ FieldHitExtractor fe2 = new FieldHitExtractor ("a2.b.c.d2.e.f.g2" , null , false );
321+ Object value = randomNonNullValue ();
322+ Map <String , Object > map = new HashMap <>();
323+ map .put ("a1" , singletonMap ("b.c" , singletonMap ("d1" , singletonMap ("e.f" , singletonMap ("g1" , value )))));
324+ map .put ("a2" , singletonMap ("b.c" , singletonMap ("d2" , singletonMap ("e.f" , singletonMap ("g2" , value )))));
325+ assertEquals (value , fe1 .extractFromSource (map ));
326+ assertEquals (value , fe2 .extractFromSource (map ));
327+ }
328+
329+ public void testFieldWithDotsAndSamePathButDifferentHierarchy () {
330+ FieldHitExtractor fe = new FieldHitExtractor ("a.b.c.d.e.f.g" , null , false );
331+ Object value = randomNonNullValue ();
332+ Map <String , Object > map = new HashMap <>();
333+ map .put ("a.b" , singletonMap ("c" , singletonMap ("d.e" , singletonMap ("f.g" , value ))));
334+ map .put ("a" , singletonMap ("b.c" , singletonMap ("d.e" , singletonMap ("f" , singletonMap ("g" , value )))));
335+ SqlException ex = expectThrows (SqlException .class , () -> fe .extractFromSource (map ));
336+ assertThat (ex .getMessage (), is ("Multiple values (returned by [a.b.c.d.e.f.g]) are not supported" ));
337+ }
338+
339+ private Object randomValue () {
241340 Supplier <Object > value = randomFrom (Arrays .asList (
242341 () -> randomAlphaOfLength (10 ),
243342 ESTestCase ::randomLong ,
@@ -246,7 +345,7 @@ public Object randomValue() {
246345 return value .get ();
247346 }
248347
249- public Object randomNonNullValue () {
348+ private Object randomNonNullValue () {
250349 Supplier <Object > value = randomFrom (Arrays .asList (
251350 () -> randomAlphaOfLength (10 ),
252351 ESTestCase ::randomLong ,
0 commit comments