Skip to content

Commit a581962

Browse files
Update logic and tests to conform to the new grammar
1 parent 31177ad commit a581962

File tree

10 files changed

+1322
-1221
lines changed

10 files changed

+1322
-1221
lines changed

x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/EsqlActionIT.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,8 +1071,6 @@ public void testDataStreamPatterns() throws Exception {
10711071
testCases.put("test_ds_patterns*::data,test_ds_patterns*::failures,-test_ds_patterns_2*::data", 19L);
10721072
testCases.put("test_ds_patterns*::data,test_ds_patterns*::failures,-test_ds_patterns_2*::failures", 21L);
10731073

1074-
testCases.put("\"test_ds_patterns_1,test_ds_patterns_2\"::failures", 8L);
1075-
10761074
runDataStreamTest(testCases, new String[] { "test_ds_patterns_1", "test_ds_patterns_2", "test_ds_patterns_3" }, (key, value) -> {
10771075
try (var results = run("from " + key + " | stats count(@timestamp)")) {
10781076
assertEquals(key, 1, getValuesList(results).size());
@@ -1097,7 +1095,7 @@ public void testDataStreamInvalidPatterns() throws Exception {
10971095
// Only one selector separator is allowed per expression
10981096
testCases.put("::::data", "mismatched input '::' expecting {QUOTED_STRING, UNQUOTED_SOURCE}");
10991097
// Suffix case is not supported because there is no component named with the empty string
1100-
testCases.put("index::", "missing {QUOTED_STRING, UNQUOTED_SOURCE} at '|'");
1098+
testCases.put("index::", "missing UNQUOTED_SOURCE at '|'");
11011099

11021100
runDataStreamTest(testCases, new String[] { "test_ds_patterns_1" }, (key, value) -> {
11031101
logger.info(key);

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.interp

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.java

Lines changed: 1207 additions & 1190 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseListener.java

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseVisitor.java

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserListener.java

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserVisitor.java

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

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

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,8 @@ protected static String quoteIdString(String unquotedString) {
5858
public String visitClusterString(EsqlBaseParser.ClusterStringContext ctx) {
5959
if (ctx == null) {
6060
return null;
61-
} else if (ctx.UNQUOTED_SOURCE() != null) {
62-
return ctx.UNQUOTED_SOURCE().getText();
6361
} else {
64-
return unquote(ctx.QUOTED_STRING().getText());
62+
return ctx.UNQUOTED_SOURCE().getText();
6563
}
6664
}
6765

@@ -78,18 +76,16 @@ public String visitIndexString(IndexStringContext ctx) {
7876
public String visitSelectorString(EsqlBaseParser.SelectorStringContext ctx) {
7977
if (ctx == null) {
8078
return null;
81-
} else if (ctx.UNQUOTED_SOURCE() != null) {
82-
return ctx.UNQUOTED_SOURCE().getText();
8379
} else {
84-
return unquote(ctx.QUOTED_STRING().getText());
80+
return ctx.UNQUOTED_SOURCE().getText();
8581
}
8682
}
8783

8884
public String visitIndexPattern(List<EsqlBaseParser.IndexPatternContext> ctx) {
8985
List<String> patterns = new ArrayList<>(ctx.size());
9086
Holder<Boolean> hasSeenStar = new Holder<>(false);
9187
ctx.forEach(c -> {
92-
String indexPattern = visitIndexString(c.indexString());
88+
String indexPattern = c.unquotedIndexString() != null ? c.unquotedIndexString().getText() : visitIndexString(c.indexString());
9389
String clusterString = visitClusterString(c.clusterString());
9490
String selectorString = visitSelectorString(c.selectorString());
9591
// skip validating index on remote cluster, because the behavior of remote cluster is not consistent with local cluster

x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/IdentifierGenerator.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,18 +80,23 @@ public static String randomIndexPattern(Feature... features) {
8080
index.insert(0, "-");
8181
}
8282

83+
boolean requiresQuote = false;
8384
var pattern = index.toString();
8485
if (pattern.contains("|")) {
85-
pattern = quote(pattern);
86+
requiresQuote = true;
8687
}
87-
pattern = maybeQuote(pattern);
8888

8989
if (canAdd(Features.CROSS_CLUSTER, features)) {
90-
var cluster = maybeQuote(randomIdentifier());
91-
pattern = maybeQuote(cluster + ":" + pattern);
90+
var cluster = randomIdentifier();
91+
pattern = cluster + ":" + pattern;
9292
} else if (EsqlCapabilities.Cap.INDEX_COMPONENT_SELECTORS.isEnabled() && canAdd(Features.INDEX_SELECTOR, features)) {
93-
pattern = maybeQuote(pattern + "::" + randomFrom(IndexComponentSelector.values()).getKey());
93+
pattern = pattern + "::" + randomFrom(IndexComponentSelector.values()).getKey();
9494
}
95+
96+
if (requiresQuote) {
97+
pattern = quote(pattern);
98+
}
99+
95100
return pattern;
96101
}
97102

x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/parser/StatementParserTests.java

Lines changed: 64 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,13 @@ public void testStringAsIndexPattern() {
483483
assertStringAsIndexPattern("`backtick`,``multiple`back``ticks```", command + " `backtick`, ``multiple`back``ticks```");
484484
assertStringAsIndexPattern("test,metadata,metaata,.metadata", command + " test,\"metadata\", metaata, .metadata");
485485
assertStringAsIndexPattern(".dot", command + " .dot");
486-
assertStringAsIndexPattern("cluster:index|pattern", command + " cluster:\"index|pattern\"");
486+
String lineNumber = command.equals("FROM") ? "line 1:14: " : "line 1:12: ";
487+
expectErrorWithLineNumber(
488+
command + " cluster:\"index|pattern\"",
489+
" cluster:\"index|pattern\"",
490+
lineNumber,
491+
"mismatched input '\"index|pattern\"' expecting UNQUOTED_SOURCE"
492+
);
487493
assertStringAsIndexPattern("*:index|pattern", command + " \"*:index|pattern\"");
488494
clusterAndIndexAsIndexPattern(command, "cluster:index");
489495
clusterAndIndexAsIndexPattern(command, "cluster:.index");
@@ -496,13 +502,37 @@ public void testStringAsIndexPattern() {
496502
if (EsqlCapabilities.Cap.INDEX_COMPONENT_SELECTORS.isEnabled()) {
497503
assertStringAsIndexPattern("foo::data", command + " foo::data");
498504
assertStringAsIndexPattern("foo::failures", command + " foo::failures");
499-
assertStringAsIndexPattern("cluster:foo::failures", command + " cluster:\"foo::failures\"");
500-
assertStringAsIndexPattern("*,-foo::data", command + " *, \"-foo\"::data");
505+
expectErrorWithLineNumber(
506+
command + " cluster:\"foo::data\"",
507+
" cluster:\"foo::data\"",
508+
lineNumber,
509+
"mismatched input '\"foo::data\"' expecting UNQUOTED_SOURCE"
510+
);
511+
expectErrorWithLineNumber(
512+
command + " cluster:\"foo::failures\"",
513+
" cluster:\"foo::failures\"",
514+
lineNumber,
515+
"mismatched input '\"foo::failures\"' expecting UNQUOTED_SOURCE"
516+
);
517+
lineNumber = command.equals("FROM") ? "line 1:15: " : "line 1:13: ";
518+
expectErrorWithLineNumber(
519+
command + " *, \"-foo\"::data",
520+
" *, \"-foo\"::data",
521+
lineNumber,
522+
"mismatched input '::' expecting {<EOF>, '|', ',', 'metadata'}"
523+
);
501524
assertStringAsIndexPattern("*,-foo::data", command + " *, \"-foo::data\"");
502525
assertStringAsIndexPattern("*::data", command + " *::data");
526+
lineNumber = command.equals("FROM") ? "line 1:79: " : "line 1:77: ";
527+
expectErrorWithLineNumber(
528+
command + " \"<logstash-{now/M{yyyy.MM}}>::data,<logstash-{now/d{yyyy.MM.dd|+12:00}}>\"::failures",
529+
" \"<logstash-{now/M{yyyy.MM}}>::data,<logstash-{now/d{yyyy.MM.dd|+12:00}}>\"::failures",
530+
lineNumber,
531+
"mismatched input '::' expecting {<EOF>, '|', ',', 'metadata'}"
532+
);
503533
assertStringAsIndexPattern(
504534
"<logstash-{now/M{yyyy.MM}}>::data,<logstash-{now/d{yyyy.MM.dd|+12:00}}>::failures",
505-
command + " <logstash-{now/M{yyyy.MM}}>::data, \"<logstash-{now/d{yyyy.MM.dd|+12:00}}>\"::failures"
535+
command + " <logstash-{now/M{yyyy.MM}}>::data, \"<logstash-{now/d{yyyy.MM.dd|+12:00}}>::failures\""
506536
);
507537
}
508538
}
@@ -595,8 +625,19 @@ public void testInvalidCharacterInIndexPattern() {
595625
expectDoubleColonErrorWithLineNumber(command, "cluster:foo::data", parseLineNumber + 11);
596626
expectDoubleColonErrorWithLineNumber(command, "cluster:foo::failures", parseLineNumber + 11);
597627

598-
expectDoubleColonErrorWithLineNumber(command, "cluster:\"foo\"::data", parseLineNumber + 13);
599-
expectDoubleColonErrorWithLineNumber(command, "cluster:\"foo\"::failures", parseLineNumber + 13);
628+
// Index pattern cannot be quoted if cluster string is present.
629+
expectErrorWithLineNumber(
630+
command,
631+
"cluster:\"foo\"::data",
632+
"line 1:14: ",
633+
"mismatched input '\"foo\"' expecting UNQUOTED_SOURCE"
634+
);
635+
expectErrorWithLineNumber(
636+
command,
637+
"cluster:\"foo\"::failures",
638+
"line 1:14: ",
639+
"mismatched input '\"foo\"' expecting UNQUOTED_SOURCE"
640+
);
600641

601642
// TODO: Edge case that will be invalidated in follow up (https://github.com/elastic/elasticsearch/issues/122651)
602643
// expectDoubleColonErrorWithLineNumber(command, "\"cluster:foo\"::data", parseLineNumber + 13);
@@ -641,8 +682,12 @@ public void testInvalidCharacterInIndexPattern() {
641682
"Invalid usage of :: separator"
642683
);
643684

644-
// TODO: Edge case that will be invalidated in follow up (https://github.com/elastic/elasticsearch/issues/122651)
645-
expectDoubleColonErrorWithLineNumber(command, "cluster:\"index,index2\"::failures", parseLineNumber + 22);
685+
expectErrorWithLineNumber(
686+
command,
687+
"cluster:\"index,index2\"::failures",
688+
"line 1:14: ",
689+
"mismatched input '\"index,index2\"' expecting UNQUOTED_SOURCE"
690+
);
646691
}
647692
}
648693

@@ -669,12 +714,11 @@ public void testInvalidCharacterInIndexPattern() {
669714
"-index",
670715
"must not start with '_', '-', or '+'"
671716
);
672-
expectInvalidIndexNameErrorWithLineNumber(
717+
expectErrorWithLineNumber(
673718
command,
674719
"indexpattern, \"--index\"::data",
675-
lineNumber,
676-
"-index",
677-
"must not start with '_', '-', or '+'"
720+
"line 1:29: ",
721+
"mismatched input '::' expecting {<EOF>, '|', ',', 'metadata'}"
678722
);
679723
expectInvalidIndexNameErrorWithLineNumber(
680724
command,
@@ -709,7 +753,12 @@ public void testInvalidCharacterInIndexPattern() {
709753
clustersAndIndices(command, "*", "-<--logstash-{now/M{yyyy.MM}}>::data");
710754
clustersAndIndices(command, "index*", "-<--logstash#-{now/M{yyyy.MM}}>::data");
711755
// Throw on invalid date math
712-
expectDateMathErrorWithLineNumber(command, "*, \"-<-logstash-{now/D}>\"::data", lineNumber, dateMathError);
756+
expectDateMathErrorWithLineNumber(
757+
command,
758+
"*, \"-<-logstash-{now/D}>\"::data",
759+
"line 1:31: ",
760+
"mismatched input '::' expecting {<EOF>, '|', ',', 'metadata'}"
761+
);
713762
expectDateMathErrorWithLineNumber(command, "*, -<-logstash-{now/D}>::data", lineNumber, dateMathError);
714763
// Check that invalid selectors throw (they're resolved first in /_search, and always validated)
715764
expectInvalidIndexNameErrorWithLineNumber(
@@ -2450,7 +2499,7 @@ public void testInvalidAlias() {
24502499
}
24512500

24522501
public void testInvalidRemoteClusterPattern() {
2453-
expectError("from \"rem:ote\":index", "cluster string [rem:ote] must not contain ':'");
2502+
expectError("from \"rem:ote\":index", "mismatched input ':' expecting {<EOF>, '|', ',', 'metadata'}");
24542503
}
24552504

24562505
private LogicalPlan unresolvedRelation(String index) {
@@ -3174,7 +3223,7 @@ public void testInvalidJoinPatterns() {
31743223
joinPattern = unquoteIndexPattern(joinPattern);
31753224
expectError(
31763225
"FROM " + randomIndexPatterns(without(CROSS_CLUSTER)) + " | LOOKUP JOIN " + joinPattern + " ON " + randomIdentifier(),
3177-
"extraneous input ':' expecting {QUOTED_STRING, UNQUOTED_SOURCE}"
3226+
"extraneous input ':' expecting UNQUOTED_SOURCE"
31783227
);
31793228
}
31803229
{

0 commit comments

Comments
 (0)