7272 * The main index contains a field called {@code main_byte} and the lookup index has {@code lookup_integer}. To test the pair, we run
7373 * {@code FROM main_index | RENAME main_byte AS lookup_integer | LOOKUP JOIN lookup_index ON lookup_integer | KEEP other}
7474 * and assert that the result exists and is equal to "value".
75+ * For tests using union types, the same applies but there are additional main indices so that we have actual mapping conflicts.
76+ * E.g. the field {@code main_byte} will occur another time in the index {@code main_byte_as_short} when we're testing a byte-short union
77+ * type.
7578 */
7679@ ClusterScope (scope = SUITE , numClientNodes = 1 , numDataNodes = 1 )
7780public class LookupJoinTypesIT extends ESIntegTestCase {
@@ -237,12 +240,13 @@ protected Collection<Class<? extends Plugin>> nodePlugins() {
237240 }
238241 }
239242
240- // Make sure we have never added two configurations with the same index name
243+ // Make sure we have never added two configurations with the same lookup index name.
244+ // This prevents accidentally adding the same test config to two different groups.
241245 Set <String > knownTypes = new HashSet <>();
242246 for (TestConfigs configs : testConfigurations .values ()) {
243247 for (TestConfig config : configs .configs .values ()) {
244248 if (knownTypes .contains (config .lookupIndexName ())) {
245- throw new IllegalArgumentException ("Duplicate index name: " + config .lookupIndexName ());
249+ throw new IllegalArgumentException ("Duplicate lookup index name: " + config .lookupIndexName ());
246250 }
247251 knownTypes .add (config .lookupIndexName ());
248252 }
@@ -300,7 +304,7 @@ private void testLookupJoinTypes(String group) {
300304 }
301305 config .validateMainIndex ();
302306 config .validateLookupIndex ();
303- config .validateAdditionalIndexes ();
307+ config .validateAdditionalMainIndexes ();
304308
305309 config .doTest ();
306310 }
@@ -409,9 +413,11 @@ public List<TestMapping> indices() {
409413 // The main index will have many fields, one of each type to use in later type specific joins
410414 List <TestMapping > mainIndices = new ArrayList <>();
411415 for (TestConfig config : configs .values ()) {
412- results .addAll (config .additionalIndexes ());
413-
414416 mainIndices .add (config .mainIndex ());
417+ TestMapping otherIndex = config .additionalMainIndex ();
418+ if (otherIndex != null ) {
419+ results .add (otherIndex );
420+ }
415421 }
416422 TestMapping mainIndex = TestMapping .mergeProperties (mainIndices );
417423
@@ -452,16 +458,16 @@ public List<TestDocument> docs() {
452458 """ , String .join (",\n " , mainProperties ))));
453459
454460 for (TestConfig config : configs .values ()) {
455- for (TestMapping addtionalIndex : config .additionalIndexes ()) {
461+ TestMapping additionalIndex = config .additionalMainIndex ();
462+ if (additionalIndex != null ) {
456463 String doc = String .format (Locale .ROOT , """
457464 {
458- %s,
459- "other": "value"
465+ %s
460466 }
461467 """ , propertyFor (config .mainFieldName (), ((TestConfigPassesUnionType ) config ).otherMainType ()));
462- // Casting to TestConfigPassesUnionType is an ugly hack; better to derive the test data from the TestMapping or from the
463- // TestConfig.
464- results .add (new TestDocument (addtionalIndex .indexName , "1" , doc ));
468+ // TODO: Casting to TestConfigPassesUnionType is an ugly hack; better to derive the test data from the TestMapping or
469+ // from the TestConfig.
470+ results .add (new TestDocument (additionalIndex .indexName , "1" , doc ));
465471 }
466472 }
467473
@@ -535,42 +541,38 @@ interface TestConfig {
535541
536542 DataType lookupType ();
537543
544+ default TestMapping mainIndex () {
545+ return new TestMapping (MAIN_INDEX , List .of (propertySpecFor (mainFieldName (), mainType ())), null );
546+ }
547+
548+ /** Make sure the left index has the expected fields and types */
549+ default void validateMainIndex () {
550+ validateIndex (MAIN_INDEX , mainFieldName (), sampleDataFor (mainType ()));
551+ }
552+
538553 /**
539554 * The same across main indices (necessary for union types).
540555 */
541556 default String mainFieldName () {
542557 return MAIN_INDEX_PREFIX + mainType ().esType ();
543558 }
544559
545- default TestMapping mainIndex () {
546- return new TestMapping (MAIN_INDEX , List .of (propertySpecFor (mainFieldName (), mainType ())), null );
547- }
548-
549560 /**
550- * Used for union types. Will have the same main field name, but using different types .
561+ * Used for union types. Will have the same main field name, but using a different type .
551562 */
552- default List < TestMapping > additionalIndexes () {
553- return List . of () ;
563+ default TestMapping additionalMainIndex () {
564+ return null ;
554565 }
555566
556- /** Make sure the lookup index has the expected fields and types */
557- default void validateAdditionalIndexes () {
567+ /** Make sure the additional indexes have the expected fields and types */
568+ default void validateAdditionalMainIndexes () {
558569 return ;
559570 }
560571
561- /** Make sure the left indices have the expected fields and types */
562- default void validateMainIndex () {
563- validateIndex (MAIN_INDEX , mainFieldName (), sampleDataFor (mainType ()));
564- }
565-
566572 default String lookupIndexName () {
567573 return LOOKUP_INDEX_PREFIX + mainType ().esType () + "_" + lookupType ().esType ();
568574 }
569575
570- default String lookupFieldName () {
571- return LOOKUP_INDEX_PREFIX + lookupType ().esType ();
572- }
573-
574576 default TestMapping lookupIndex () {
575577 return new TestMapping (
576578 lookupIndexName (),
@@ -584,6 +586,10 @@ default void validateLookupIndex() {
584586 validateIndex (lookupIndexName (), lookupFieldName (), sampleDataFor (lookupType ()));
585587 }
586588
589+ default String lookupFieldName () {
590+ return LOOKUP_INDEX_PREFIX + lookupType ().esType ();
591+ }
592+
587593 default String testQuery () {
588594 String mainField = mainFieldName ();
589595 String lookupField = lookupFieldName ();
@@ -628,6 +634,9 @@ private static void validateIndex(String indexName, String fieldName, Object exp
628634 }
629635 }
630636
637+ /**
638+ * Test case for a pair of types that can successfully be used in {@code LOOKUP JOIN}.
639+ */
631640 private record TestConfigPasses (DataType mainType , DataType lookupType ) implements TestConfig {
632641 @ Override
633642 public void doTest () {
@@ -641,6 +650,9 @@ public void doTest() {
641650 }
642651 }
643652
653+ /**
654+ * Test case for a {@code LOOKUP JOIN} where a field with a mapping conflict is cast to the type of the lookup field.
655+ */
644656 private record TestConfigPassesUnionType (DataType mainType , DataType otherMainType , DataType lookupType ) implements TestConfig {
645657 @ Override
646658 public String lookupIndexName () {
@@ -649,16 +661,16 @@ public String lookupIndexName() {
649661 }
650662
651663 private String additionalIndexName () {
652- return MAIN_INDEX + "_" + mainFieldName () + "_as_" + otherMainType ().typeName ();
664+ return mainFieldName () + "_as_" + otherMainType ().typeName ();
653665 }
654666
655667 @ Override
656- public List < TestMapping > additionalIndexes () {
657- return List . of ( new TestMapping (additionalIndexName (), List .of (propertySpecFor (mainFieldName (), otherMainType )), null ) );
668+ public TestMapping additionalMainIndex () {
669+ return new TestMapping (additionalIndexName (), List .of (propertySpecFor (mainFieldName (), otherMainType )), null );
658670 }
659671
660672 @ Override
661- public void validateAdditionalIndexes () {
673+ public void validateAdditionalMainIndexes () {
662674 validateIndex (additionalIndexName (), mainFieldName (), sampleDataFor (otherMainType ));
663675 }
664676
@@ -698,6 +710,9 @@ public void doTest() {
698710 }
699711 }
700712
713+ /**
714+ * Test case for a pair of types that generate an error message when used in {@code LOOKUP JOIN}.
715+ */
701716 private record TestConfigFails <E extends Exception >(DataType mainType , DataType lookupType , Class <E > exception , Consumer <E > assertion )
702717 implements
703718 TestConfig {
0 commit comments