Skip to content

Commit 299bf44

Browse files
authored
Support index pattern selector syntax in SQL (#120845)
Updates the SQL grammar to include the selector portion of an index pattern. The index() method has been updated to include selectors in the resulting expression.
1 parent 9ca38f9 commit 299bf44

File tree

5 files changed

+267
-92
lines changed

5 files changed

+267
-92
lines changed

x-pack/plugin/ql/src/test/java/org/elasticsearch/xpack/ql/analyzer/PreAnalyzerTests.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,15 @@ public void testBasicIndexWithCatalog() {
4242
assertThat(result.indices.get(0).id().index(), is("index"));
4343
}
4444

45+
public void testBasicIndexWithSelector() {
46+
LogicalPlan plan = new UnresolvedRelation(EMPTY, new TableIdentifier(EMPTY, null, "index::failures"), null, false);
47+
PreAnalysis result = preAnalyzer.preAnalyze(plan);
48+
assertThat(plan.preAnalyzed(), is(true));
49+
assertThat(result.indices, hasSize(1));
50+
assertThat(result.indices.get(0).id().cluster(), nullValue());
51+
assertThat(result.indices.get(0).id().index(), is("index::failures"));
52+
}
53+
4554
public void testComplicatedQuery() {
4655
LogicalPlan plan = new Limit(
4756
EMPTY,

x-pack/plugin/sql/src/main/antlr/SqlBase.g4

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,8 +340,8 @@ identifier
340340
;
341341

342342
tableIdentifier
343-
: (catalog=identifier ':')? TABLE_IDENTIFIER
344-
| (catalog=identifier ':')? name=identifier
343+
: (catalog=identifier ':')? TABLE_IDENTIFIER ('::' selector=identifier)?
344+
| (catalog=identifier ':')? name=identifier ('::' selector=identifier)?
345345
;
346346

347347
quoteIdentifier

x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/IdentifierBuilder.java

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
package org.elasticsearch.xpack.sql.parser;
88

99
import org.antlr.v4.runtime.tree.ParseTree;
10+
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
1011
import org.elasticsearch.common.Strings;
12+
import org.elasticsearch.core.Tuple;
1113
import org.elasticsearch.xpack.ql.plan.TableIdentifier;
1214
import org.elasticsearch.xpack.ql.tree.Source;
1315
import org.elasticsearch.xpack.sql.parser.SqlBaseParser.IdentifierContext;
@@ -29,7 +31,56 @@ public TableIdentifier visitTableIdentifier(TableIdentifierContext ctx) {
2931
ParseTree tree = ctx.name != null ? ctx.name : ctx.TABLE_IDENTIFIER();
3032
String index = tree.getText();
3133

32-
return new TableIdentifier(source, visitIdentifier(ctx.catalog), unquoteIdentifier(index));
34+
String cluster = visitIdentifier(ctx.catalog);
35+
String indexName = unquoteIdentifier(index);
36+
String selector = visitIdentifier(ctx.selector);
37+
38+
if (cluster != null && selector != null) {
39+
throw new ParsingException(
40+
source,
41+
"Invalid index name [{}:{}::{}], Selectors are not yet supported on remote cluster patterns",
42+
cluster,
43+
indexName,
44+
selector
45+
);
46+
}
47+
48+
if (selector != null) {
49+
try {
50+
IndexNameExpressionResolver.SelectorResolver.validateIndexSelectorString(indexName, selector);
51+
} catch (Exception e) {
52+
throw new ParsingException(source, e.getMessage());
53+
}
54+
}
55+
56+
if (indexName.contains(IndexNameExpressionResolver.SelectorResolver.SELECTOR_SEPARATOR)) {
57+
if (selector != null) {
58+
throw new ParsingException(
59+
source,
60+
"Invalid index name [{}::{}], Invalid usage of :: separator, only one :: separator is allowed per expression",
61+
indexName,
62+
selector
63+
);
64+
}
65+
try {
66+
Tuple<String, String> split = IndexNameExpressionResolver.splitSelectorExpression(indexName);
67+
indexName = split.v1();
68+
selector = split.v2();
69+
} catch (Exception e) {
70+
throw new ParsingException(source, e.getMessage());
71+
}
72+
if (selector != null) {
73+
try {
74+
IndexNameExpressionResolver.SelectorResolver.validateIndexSelectorString(indexName, selector);
75+
} catch (Exception e) {
76+
throw new ParsingException(source, "Invalid index name [{}::{}], {}", indexName, selector, e.getMessage());
77+
}
78+
}
79+
}
80+
81+
indexName = IndexNameExpressionResolver.combineSelectorExpression(indexName, selector);
82+
83+
return new TableIdentifier(source, cluster, indexName);
3384
}
3485

3586
@Override

0 commit comments

Comments
 (0)