diff --git a/muted-tests.yml b/muted-tests.yml index 0be1dac2a8e7c..fe2a7115e1c68 100644 --- a/muted-tests.yml +++ b/muted-tests.yml @@ -354,9 +354,6 @@ tests: - class: org.elasticsearch.index.shard.StoreRecoveryTests method: testAddIndices issue: https://github.com/elastic/elasticsearch/issues/124104 -- class: org.elasticsearch.xpack.esql.parser.StatementParserTests - method: testInvalidJoinPatterns - issue: https://github.com/elastic/elasticsearch/issues/125536 - class: org.elasticsearch.xpack.inference.registry.ModelRegistryMetadataTests method: testUpgrade issue: https://github.com/elastic/elasticsearch/issues/125554 diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LogicalPlanBuilder.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LogicalPlanBuilder.java index 9666abbe7e69d..5b7026877a7ae 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LogicalPlanBuilder.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LogicalPlanBuilder.java @@ -11,6 +11,7 @@ import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.tree.ParseTree; import org.elasticsearch.Build; +import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.common.Strings; import org.elasticsearch.core.Tuple; import org.elasticsearch.dissect.DissectException; @@ -568,6 +569,13 @@ public PlanFactory visitJoinCommand(EsqlBaseParser.JoinCommandContext ctx) { rightPattern ); } + if (rightPattern.contains(IndexNameExpressionResolver.SelectorResolver.SELECTOR_SEPARATOR)) { + throw new ParsingException( + source(target), + "invalid index pattern [{}], index pattern selectors are not supported in LOOKUP JOIN", + rightPattern + ); + } UnresolvedRelation right = new UnresolvedRelation( source(target), diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/StatementParserTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/StatementParserTests.java index 561b260114358..6e605e68428de 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/StatementParserTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/StatementParserTests.java @@ -80,6 +80,7 @@ import static org.elasticsearch.xpack.esql.EsqlTestUtils.paramAsPattern; import static org.elasticsearch.xpack.esql.EsqlTestUtils.referenceAttribute; import static org.elasticsearch.xpack.esql.IdentifierGenerator.Features.CROSS_CLUSTER; +import static org.elasticsearch.xpack.esql.IdentifierGenerator.Features.DATE_MATH; import static org.elasticsearch.xpack.esql.IdentifierGenerator.Features.INDEX_SELECTOR; import static org.elasticsearch.xpack.esql.IdentifierGenerator.Features.WILDCARD_PATTERN; import static org.elasticsearch.xpack.esql.IdentifierGenerator.randomIndexPattern; @@ -3142,18 +3143,21 @@ public void testInvalidJoinPatterns() { if (EsqlCapabilities.Cap.INDEX_COMPONENT_SELECTORS.isEnabled()) { { // Selectors are not supported on the left of the join query if used with cluster ids. - var fromPatterns = randomIndexPatterns(CROSS_CLUSTER); + // Unquoted case: The language specification does not allow mixing `:` and `::` characters in an index expression + var fromPatterns = randomIndexPatterns(CROSS_CLUSTER, without(DATE_MATH)); // We do different validation based on the quotation of the pattern // Autogenerated patterns will not mix cluster ids with selectors. Unquote it to ensure stable tests fromPatterns = unquoteIndexPattern(fromPatterns) + "::data"; var joinPattern = randomIndexPattern(without(CROSS_CLUSTER), without(WILDCARD_PATTERN), without(INDEX_SELECTOR)); expectError( "FROM " + fromPatterns + " | LOOKUP JOIN " + joinPattern + " ON " + randomIdentifier(), - "mismatched input '::' expecting {, '|', ',', 'metadata'}" + "mismatched input '::' expecting {" ); } { // Selectors are not supported on the left of the join query if used with cluster ids. + // Quoted case: The language specification allows mixing `:` and `::` characters in a quoted expression, but this usage + // must cause a validation exception in the non-generated code. var fromPatterns = randomIndexPatterns(CROSS_CLUSTER, without(INDEX_SELECTOR)); // We do different validation based on the quotation of the pattern // Autogenerated patterns will not mix cluster ids with selectors. Unquote, modify, and requote it to ensure stable tests @@ -3166,12 +3170,31 @@ public void testInvalidJoinPatterns() { } { // Selectors are not yet supported in join patterns on the right. - var joinPattern = randomIndexPattern(without(CROSS_CLUSTER), without(WILDCARD_PATTERN), INDEX_SELECTOR); + // Unquoted case: The language specification does not allow mixing `:` and `::` characters in an index expression + var joinPattern = randomIndexPattern(without(CROSS_CLUSTER), without(WILDCARD_PATTERN), without(DATE_MATH), INDEX_SELECTOR); + // We do different validation based on the quotation of the pattern, so forcefully unquote the expression instead of leaving + // it to chance. + joinPattern = unquoteIndexPattern(joinPattern); expectError( - "FROM " + randomIndexPatterns() + " | LOOKUP JOIN " + joinPattern + " ON " + randomIdentifier(), + "FROM " + randomIndexPatterns(without(CROSS_CLUSTER)) + " | LOOKUP JOIN " + joinPattern + " ON " + randomIdentifier(), "extraneous input ':' expecting {QUOTED_STRING, UNQUOTED_SOURCE}" ); } + { + // Selectors are not yet supported in join patterns on the right. + // Quoted case: The language specification allows `::` characters in a quoted expression, but this usage + // must cause a validation exception in the non-generated code. + var joinPattern = randomIndexPattern(without(CROSS_CLUSTER), without(WILDCARD_PATTERN), without(DATE_MATH), INDEX_SELECTOR); + // We do different validation based on the quotation of the pattern, so forcefully quote the expression instead of leaving + // it to chance. + joinPattern = "\"" + unquoteIndexPattern(joinPattern) + "\""; + expectError( + "FROM " + randomIndexPatterns(without(CROSS_CLUSTER)) + " | LOOKUP JOIN " + joinPattern + " ON " + randomIdentifier(), + "invalid index pattern [" + + unquoteIndexPattern(joinPattern) + + "], index pattern selectors are not supported in LOOKUP JOIN" + ); + } } }