Skip to content

Commit f06b7a2

Browse files
remove subquery merging in parser, add tests for subqueries with request filter
1 parent b31154f commit f06b7a2

File tree

5 files changed

+414
-92
lines changed

5 files changed

+414
-92
lines changed

x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/RestEsqlTestCase.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,6 +1317,23 @@ public void testTopLevelFilterBoolMerged() throws IOException {
13171317
}
13181318
}
13191319

1320+
public void testTopLevelFilterWithSubqueriesInFromCommand() throws IOException {
1321+
bulkLoadTestData(10);
1322+
1323+
String query = format(null, "FROM {} , (FROM {} | WHERE integer < 8) | STATS count(*)", testIndexName(), testIndexName());
1324+
1325+
RequestObjectBuilder builder = requestObjectBuilder().filter(b -> {
1326+
b.startObject("range");
1327+
{
1328+
b.startObject("integer").field("gte", "5").endObject();
1329+
}
1330+
b.endObject();
1331+
}).query(query);
1332+
1333+
Map<String, Object> result = runEsql(builder);
1334+
assertResultMap(result, matchesList().item(matchesMap().entry("name", "count(*)").entry("type", "long")), List.of(List.of(8)));
1335+
}
1336+
13201337
private static String queryWithComplexFieldNames(int field) {
13211338
StringBuilder query = new StringBuilder();
13221339
query.append(" | keep ").append(randomAlphaOfLength(10)).append(1);

x-pack/plugin/esql/qa/testFixtures/src/main/resources/subquery.csv-spec

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// CSV spec for subqueries
33
//
44

5-
subqueryInFromMergeToMainIndexPattern
5+
subqueryInFrom
66
required_capability: fork_v9
77
required_capability: subquery_in_from_command
88

@@ -25,6 +25,25 @@ null | null | 172.21.3.15
2525
null | null | 172.21.3.15
2626
;
2727

28+
subqueryInFromWithIdenticalIndexPatternsInMainAndSubquery
29+
required_capability: fork_v9
30+
required_capability: subquery_in_from_command
31+
32+
FROM employees, (FROM employees)
33+
| WHERE emp_no >= 10091 AND emp_no < 10094
34+
| SORT emp_no
35+
| KEEP emp_no, languages
36+
;
37+
38+
emp_no:integer | languages:integer
39+
10091 | 3
40+
10091 | 3
41+
10092 | 1
42+
10092 | 1
43+
10093 | 3
44+
10093 | 3
45+
;
46+
2847
subqueryInFromWithEvalInSubquery
2948
required_capability: fork_v9
3049
required_capability: subquery_in_from_command

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/PreAnalyzer.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,6 @@ private void collectSubqueryIndexPattern(
116116
Set<IndexPattern> subqueryIndices,
117117
IndexPattern mainIndexPattern
118118
) {
119-
if (relation.preAnalyzed()) {
120-
return;
121-
}
122-
123119
IndexPattern pattern = relation.indexPattern();
124120
boolean isLookup = relation.indexMode() == IndexMode.LOOKUP;
125121
boolean isMainIndexPattern = pattern == mainIndexPattern;

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

Lines changed: 3 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -356,58 +356,24 @@ private LogicalPlan visitRelation(Source source, IndexMode indexMode, EsqlBasePa
356356
if (indexMode == IndexMode.TIME_SERIES) {
357357
throw new ParsingException(source, "Subqueries are not supported in TS command");
358358
}
359-
// If the subquery has only from command, combine the subquery index patterns into the main index pattern
360-
// from idx1, idx2, (from idx3), (from idx4) => from idx1, idx2, idx3, idx4
361-
List<Subquery> remainingSubqueries = new ArrayList<>(subqueries.size());
362-
for (Subquery subquery : subqueries) {
363-
String subqueryIndexPattern = getIndexPatternIfOnlyFrom(subquery);
364-
boolean canCombine = subqueryIndexPattern != null && metadataFields.isEmpty();
365-
if (canCombine) {
366-
// the subquery has only from command without metadata fields, combine the index patterns
367-
// as how or whether combining metadata fields is unclear yet
368-
String existingIndexPattern = table.indexPattern();
369-
String combinedPattern = existingIndexPattern.isEmpty()
370-
? subqueryIndexPattern
371-
: existingIndexPattern + "," + subqueryIndexPattern;
372-
table = new IndexPattern(table.source(), combinedPattern);
373-
unresolvedRelation = new UnresolvedRelation(source, table, false, metadataFields, indexMode, null, commandName);
374-
} else {
375-
remainingSubqueries.add(subquery);
376-
}
377-
}
378-
379-
if (remainingSubqueries.isEmpty()) {
380-
return unresolvedRelation;
381-
}
382359

383-
List<LogicalPlan> mainQueryAndSubqueries = new ArrayList<>(remainingSubqueries.size() + 1);
360+
List<LogicalPlan> mainQueryAndSubqueries = new ArrayList<>(subqueries.size() + 1);
384361
if (table.indexPattern().isEmpty() == false) {
385362
mainQueryAndSubqueries.add(unresolvedRelation);
386363
telemetryAccounting(unresolvedRelation);
387364
}
388-
mainQueryAndSubqueries.addAll(remainingSubqueries);
365+
mainQueryAndSubqueries.addAll(subqueries);
389366

390367
if (mainQueryAndSubqueries.size() == 1) {
391368
// if there is only one child, return it directly, no need for UnionAll
392-
return table.indexPattern().isEmpty() ? remainingSubqueries.get(0).plan() : unresolvedRelation;
369+
return table.indexPattern().isEmpty() ? subqueries.get(0).plan() : unresolvedRelation;
393370
} else {
394371
// the output of UnionAll is resolved by analyzer
395372
return new UnionAll(source, mainQueryAndSubqueries, List.of());
396373
}
397374
}
398375
}
399376

400-
/**
401-
* If the subquery plan is only a from command, return the index pattern; otherwise return null.
402-
*/
403-
private String getIndexPatternIfOnlyFrom(Subquery subquery) {
404-
LogicalPlan plan = subquery.plan();
405-
if (plan instanceof UnresolvedRelation ur) {
406-
return ur.indexPattern().indexPattern();
407-
}
408-
return null;
409-
}
410-
411377
private List<Subquery> visitSubqueriesInFromCommand(List<EsqlBaseParser.SubqueryContext> ctxs) {
412378
if (EsqlCapabilities.Cap.SUBQUERY_IN_FROM_COMMAND.isEnabled() == false) {
413379
return List.of();

0 commit comments

Comments
 (0)