@@ -286,14 +286,15 @@ private void testLookupJoinTypes(String group) {
286286 }
287287 config .validateMainIndex ();
288288 config .validateLookupIndex ();
289+ config .validateAdditionalIndexes ();
289290
290291 config .doTest ();
291292 }
292293 }
293294
294295 private void initIndexes (TestConfigs configs ) {
295296 for (TestMapping mapping : configs .indices ()) {
296- CreateIndexRequestBuilder builder = prepareCreate (mapping .indexName ).setMapping (mapping .properties );
297+ CreateIndexRequestBuilder builder = prepareCreate (mapping .indexName ).setMapping (mapping .propertiesAsJson () );
297298 if (mapping .settings != null ) {
298299 builder = builder .setSettings (mapping .settings );
299300 }
@@ -348,7 +349,37 @@ private static Object sampleDataFor(DataType type) {
348349 };
349350 }
350351
351- private record TestMapping (String indexName , String properties , Settings settings ) {};
352+ public record TestMapping (String indexName , Collection <String > properties , Settings settings ) {
353+
354+ private static final String PROPERTY_PREFIX = "{\n \" properties\" : {\n " ;
355+ private static final String PROPERTY_SUFFIX = " }\n }\n " ;
356+
357+ /**
358+ * {@link TestMapping#indexName} and {@link TestMapping#settings} should be the same across the collection, otherwise they're
359+ * obtained from an arbitrary element.
360+ */
361+ public static TestMapping mergeProperties (Collection <TestMapping > mappings ) {
362+ TestMapping lastMapping = null ;
363+
364+ Set <String > properties = new HashSet <>();
365+ for (TestMapping mapping : mappings ) {
366+ properties .addAll (mapping .properties );
367+ lastMapping = mapping ;
368+ }
369+ String indexName = lastMapping == null ? null : lastMapping .indexName ;
370+ Settings settings = lastMapping == null ? null : lastMapping .settings ;
371+
372+ return new TestMapping (indexName , properties , settings );
373+ }
374+
375+ public static String propertiesAsJson (Collection <String > properties ) {
376+ return PROPERTY_PREFIX + String .join (", " , properties ) + PROPERTY_SUFFIX ;
377+ }
378+
379+ public String propertiesAsJson () {
380+ return propertiesAsJson (properties );
381+ }
382+ };
352383
353384 private record TestDocument (String indexName , String id , String source ) {};
354385
@@ -361,36 +392,30 @@ private static class TestConfigs {
361392 this .configs = new LinkedHashMap <>();
362393 }
363394
364- protected List <TestMapping > indices () {
395+ public List <TestMapping > indices () {
365396 List <TestMapping > results = new ArrayList <>();
366397
367- String propertyPrefix = "{\n \" properties\" : {\n " ;
368- String propertySuffix = " }\n }\n " ;
369398 // The main index will have many fields, one of each type to use in later type specific joins
370- String mainFields = propertyPrefix + configs .values ()
371- .stream ()
372- .map (TestConfig ::mainPropertySpec )
373- .distinct ()
374- .collect (Collectors .joining (",\n " )) + propertySuffix ;
399+ List <TestMapping > mainIndices = new ArrayList <>();
400+ for (TestConfig config : configs .values ()) {
401+ results .addAll (config .additionalIndexes ());
375402
376- results .add (new TestMapping (MAIN_INDEX , mainFields , null ));
403+ mainIndices .add (config .mainIndex ());
404+ }
405+ TestMapping mainIndex = TestMapping .mergeProperties (mainIndices );
406+
407+ results .add (mainIndex );
377408
378- Settings .Builder settings = Settings .builder ()
379- .put ("index.number_of_shards" , 1 )
380- .put ("index.number_of_replicas" , 0 )
381- .put ("index.mode" , "lookup" );
382409 configs .values ()
383410 .forEach (
384411 // Each lookup index will get a document with a field to join on, and a results field to get back
385- (c ) -> results .add (
386- new TestMapping (c .lookupIndexName (), propertyPrefix + c .lookupPropertySpec () + propertySuffix , settings .build ())
387- )
412+ (c ) -> results .add (c .lookupIndex ())
388413 );
389414
390415 return results ;
391416 }
392417
393- protected List <TestDocument > docs () {
418+ public List <TestDocument > docs () {
394419 List <TestDocument > results = new ArrayList <>();
395420
396421 int docId = 0 ;
@@ -475,43 +500,71 @@ private void addFailsUnsupported(DataType mainType, DataType lookupType) {
475500 }
476501 }
477502
503+ private static class UnionTypeTestConfigs extends TestConfigs {
504+ UnionTypeTestConfigs (String group ) {
505+ super (group );
506+ }
507+
508+ @ Override
509+ public List <TestMapping > indices () {
510+ return super .indices ();
511+ }
512+
513+ @ Override
514+ public List <TestDocument > docs () {
515+ return super .docs ();
516+ }
517+ }
518+
478519 interface TestConfig {
479520 DataType mainType ();
480521
481522 DataType lookupType ();
482523
483- default String lookupIndexName () {
484- return LOOKUP_INDEX_PREFIX + mainType ().esType () + "_" + lookupType ().esType ();
485- }
486-
524+ /**
525+ * The same across main indices (necessary for union types).
526+ */
487527 default String mainFieldName () {
488528 return MAIN_INDEX_PREFIX + mainType ().esType ();
489529 }
490530
491- default String lookupFieldName () {
492- return LOOKUP_INDEX_PREFIX + lookupType ().esType ();
493- }
494-
495- default String mainPropertySpec () {
496- return propertySpecFor (mainFieldName (), mainType (), "" );
531+ default TestMapping mainIndex () {
532+ return new TestMapping (MAIN_INDEX , List .of (propertySpecFor (mainFieldName (), mainType (), "" )), null );
497533 }
498534
499535 /**
500- * If the main field is supposed to be a union type, this will be the property spec for the second index .
536+ * Used for union types. Will have the same main field name, but using different types .
501537 */
502- default String secondMainPropertySpecForUnionTypes () {
503- return propertySpecFor ( mainFieldName (), mainType (), "" );
538+ default List < TestMapping > additionalIndexes () {
539+ return List . of ( );
504540 }
505541
506- default String lookupPropertySpec () {
507- return propertySpecFor (lookupFieldName (), lookupType (), ", \" other\" : { \" type\" : \" keyword\" }" );
542+ /** Make sure the lookup index has the expected fields and types */
543+ default void validateAdditionalIndexes () {
544+ return ;
508545 }
509546
510- /** Make sure the left index has the expected fields and types */
547+ /** Make sure the left indices have the expected fields and types */
511548 default void validateMainIndex () {
512549 validateIndex (MAIN_INDEX , mainFieldName (), sampleDataFor (mainType ()));
513550 }
514551
552+ default String lookupIndexName () {
553+ return LOOKUP_INDEX_PREFIX + mainType ().esType () + "_" + lookupType ().esType ();
554+ }
555+
556+ default String lookupFieldName () {
557+ return LOOKUP_INDEX_PREFIX + lookupType ().esType ();
558+ }
559+
560+ default TestMapping lookupIndex () {
561+ return new TestMapping (
562+ lookupIndexName (),
563+ List .of (propertySpecFor (lookupFieldName (), lookupType (), ", \" other\" : { \" type\" : \" keyword\" }" )),
564+ Settings .builder ().put ("index.number_of_shards" , 1 ).put ("index.number_of_replicas" , 0 ).put ("index.mode" , "lookup" ).build ()
565+ );
566+ }
567+
515568 /** Make sure the lookup index has the expected fields and types */
516569 default void validateLookupIndex () {
517570 validateIndex (lookupIndexName (), lookupFieldName (), sampleDataFor (lookupType ()));
0 commit comments