Skip to content

Commit 4d23bc0

Browse files
committed
Fix field resolution when one FORK branch is not bounded by a aggregation or project
1 parent af3b955 commit 4d23bc0

File tree

2 files changed

+83
-7
lines changed

2 files changed

+83
-7
lines changed

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlSession.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,29 @@ static PreAnalysisResult fieldNames(LogicalPlan parsed, Set<String> enrichPolicy
583583
}
584584
projectAll.set(true);
585585
});
586+
587+
if (projectAll.get()) {
588+
return result.withFieldNames(IndexResolver.ALL_FIELDS);
589+
}
590+
591+
Holder<Boolean> projectAfterFork = new Holder<>(false);
592+
Holder<Boolean> hasFork = new Holder<>(false);
593+
594+
parsed.forEachDown(plan -> {
595+
if (hasFork.get() == false && (plan instanceof Project || plan instanceof Aggregate)) {
596+
projectAfterFork.set(true);
597+
}
598+
599+
if (plan instanceof Fork fork && projectAfterFork.get() == false) {
600+
hasFork.set(true);
601+
fork.children().forEach(child -> {
602+
if (child.anyMatch(p -> p instanceof Project || p instanceof Aggregate) == false) {
603+
projectAll.set(true);
604+
}
605+
});
606+
}
607+
});
608+
586609
if (projectAll.get()) {
587610
return result.withFieldNames(IndexResolver.ALL_FIELDS);
588611
}

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

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1796,7 +1796,7 @@ public void testDropWildcardFields_WithLookupJoin() {
17961796
);
17971797
}
17981798

1799-
public void testForkFieldsWithKeep() {
1799+
public void testForkFieldsWithKeepAfterFork() {
18001800
assumeTrue("FORK available as snapshot only", EsqlCapabilities.Cap.FORK.isEnabled());
18011801

18021802
assertFieldNames("""
@@ -1810,6 +1810,20 @@ public void testForkFieldsWithKeep() {
18101810
""", Set.of("a", "a.*", "c", "c.*", "d", "d.*", "e", "e.*", "x", "x.*", "y", "y.*"));
18111811
}
18121812

1813+
public void testForkFieldsWithKeepBeforeFork() {
1814+
assumeTrue("FORK available as snapshot only", EsqlCapabilities.Cap.FORK.isEnabled());
1815+
1816+
assertFieldNames("""
1817+
FROM test
1818+
| KEEP a, b, c, d, x
1819+
| WHERE a > 2000
1820+
| EVAL b = a + 100
1821+
| FORK (WHERE c > 1 AND a < 10000 | EVAL d = a + 500)
1822+
(WHERE d > 1000 AND e == "aaa" | EVAL c = a + 200)
1823+
| WHERE x > y
1824+
""", Set.of("a", "a.*", "b", "b.*", "c", "c.*", "d", "d.*", "e", "e.*", "x", "x.*", "y", "y.*"));
1825+
}
1826+
18131827
public void testForkFieldsWithNoProjection() {
18141828
assumeTrue("FORK available as snapshot only", EsqlCapabilities.Cap.FORK.isEnabled());
18151829

@@ -1833,23 +1847,62 @@ public void testForkFieldsWithStatsInOneBranch() {
18331847
| FORK (WHERE c > 1 AND a < 10000 | EVAL d = a + 500)
18341848
(STATS x = count(*), y=min(z))
18351849
| WHERE x > y
1836-
""", Set.of("a", "a.*", "c", "c.*", "z", "z.*"));
1850+
""", ALL_FIELDS);
18371851
}
18381852

18391853
public void testForkFieldsWithEnrichAndLookupJoins() {
18401854
assumeTrue("FORK available as snapshot only", EsqlCapabilities.Cap.FORK.isEnabled());
18411855
assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V12.isEnabled());
18421856

1857+
assertFieldNames(
1858+
"""
1859+
FROM test
1860+
| KEEP a, b, abc, def, z, xyz
1861+
| ENRICH enrich_policy ON abc
1862+
| EVAL b = a + 100
1863+
| LOOKUP JOIN my_lookup_index ON def
1864+
| FORK (WHERE c > 1 AND a < 10000 | EVAL d = a + 500)
1865+
(STATS x = count(*), y=min(z))
1866+
| LOOKUP JOIN my_lookup_index ON xyz
1867+
| WHERE x > y OR _fork == "fork1"
1868+
""",
1869+
Set.of(
1870+
"x",
1871+
"y",
1872+
"_fork",
1873+
"a",
1874+
"c",
1875+
"abc",
1876+
"b",
1877+
"def",
1878+
"z",
1879+
"xyz",
1880+
"def.*",
1881+
"_fork.*",
1882+
"y.*",
1883+
"x.*",
1884+
"xyz.*",
1885+
"z.*",
1886+
"abc.*",
1887+
"a.*",
1888+
"c.*",
1889+
"b.*"
1890+
)
1891+
);
1892+
}
1893+
1894+
public void testForkWithStatsInAllBranches() {
1895+
assumeTrue("FORK available as snapshot only", EsqlCapabilities.Cap.FORK.isEnabled());
1896+
18431897
assertFieldNames("""
18441898
FROM test
1845-
| ENRICH enrich_policy ON abc
1899+
| WHERE a > 2000
18461900
| EVAL b = a + 100
1847-
| LOOKUP JOIN my_lookup_index ON def
1848-
| FORK (WHERE c > 1 AND a < 10000 | EVAL d = a + 500)
1901+
| FORK (WHERE c > 1 AND a < 10000 | STATS m = count(*))
1902+
(EVAL z = a * b | STATS m = max(z))
18491903
(STATS x = count(*), y=min(z))
1850-
| LOOKUP JOIN my_lookup_index ON xyz
18511904
| WHERE x > y
1852-
""", Set.of("a", "a.*", "abc", "abc.*", "c", "c.*", "def", "def.*", "x", "x.*", "xyz", "xyz.*", "y", "y.*", "z", "z.*"));
1905+
""", Set.of("a", "a.*", "b", "b.*", "c", "c.*", "z", "z.*"));
18531906
}
18541907

18551908
private Set<String> fieldNames(String query, Set<String> enrichPolicyMatchFields) {

0 commit comments

Comments
 (0)