|
@@ -26,6 +26,7 @@ import org.elasticsearch.xpack.esql.VerificationException;
|
|
|
import org.elasticsearch.xpack.esql.action.EsqlCapabilities;
|
|
|
import org.elasticsearch.xpack.esql.core.expression.Alias;
|
|
|
import org.elasticsearch.xpack.esql.core.expression.Attribute;
|
|
|
+import org.elasticsearch.xpack.esql.core.expression.AttributeSet;
|
|
|
import org.elasticsearch.xpack.esql.core.expression.Expressions;
|
|
|
import org.elasticsearch.xpack.esql.core.expression.FieldAttribute;
|
|
|
import org.elasticsearch.xpack.esql.core.expression.Literal;
|
|
@@ -2197,6 +2198,36 @@ public class AnalyzerTests extends ESTestCase {
|
|
|
assertThat(e.getMessage(), containsString(errorMessage3 + "right side of join"));
|
|
|
}
|
|
|
|
|
|
+ public void testMultipleLookupJoinsGiveDifferentAttributes() {
|
|
|
+ assumeTrue("requires LOOKUP JOIN capability", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled());
|
|
|
+
|
|
|
+ // The field attributes that get contributed by different LOOKUP JOIN commands must have different name ids,
|
|
|
+ // even if they have the same names. Otherwise, things like dependency analysis - like in PruneColumns - cannot work based on
|
|
|
+ // name ids and shadowing semantics proliferate into all kinds of optimizer code.
|
|
|
+
|
|
|
+ String query = "FROM test"
|
|
|
+ + "| EVAL language_code = languages"
|
|
|
+ + "| LOOKUP JOIN languages_lookup ON language_code"
|
|
|
+ + "| LOOKUP JOIN languages_lookup ON language_code";
|
|
|
+ LogicalPlan analyzedPlan = analyze(query);
|
|
|
+
|
|
|
+ List<AttributeSet> lookupFields = new ArrayList<>();
|
|
|
+ List<Set<String>> lookupFieldNames = new ArrayList<>();
|
|
|
+ analyzedPlan.forEachUp(EsRelation.class, esRelation -> {
|
|
|
+ if (esRelation.indexMode() == IndexMode.LOOKUP) {
|
|
|
+ lookupFields.add(esRelation.outputSet());
|
|
|
+ lookupFieldNames.add(esRelation.outputSet().stream().map(NamedExpression::name).collect(Collectors.toSet()));
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ assertEquals(lookupFieldNames.size(), 2);
|
|
|
+ assertEquals(lookupFieldNames.get(0), lookupFieldNames.get(1));
|
|
|
+
|
|
|
+ assertEquals(lookupFields.size(), 2);
|
|
|
+ AttributeSet intersection = lookupFields.get(0).intersect(lookupFields.get(1));
|
|
|
+ assertEquals(AttributeSet.EMPTY, intersection);
|
|
|
+ }
|
|
|
+
|
|
|
public void testLookupJoinIndexMode() {
|
|
|
assumeTrue("requires LOOKUP JOIN capability", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled());
|
|
|
|