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