Skip to content

Commit 0c11a2a

Browse files
committed
detect time series mode when resolving field names
1 parent 980a99a commit 0c11a2a

File tree

3 files changed

+43
-5
lines changed

3 files changed

+43
-5
lines changed

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/UnresolvedRelation.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,4 +166,12 @@ public List<Object> nodeProperties() {
166166
public String toString() {
167167
return UNRESOLVED_PREFIX + indexPattern.indexPattern();
168168
}
169+
170+
/**
171+
* @return true if and only if this relation is being loaded in "time series mode",
172+
* which changes a number of behaviors in the planner.
173+
*/
174+
public boolean isTimeSeriesMode() {
175+
return commandName.equalsIgnoreCase("TS");
176+
}
169177
}

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

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.elasticsearch.xpack.esql.plan.logical.Aggregate;
2727
import org.elasticsearch.xpack.esql.plan.logical.Drop;
2828
import org.elasticsearch.xpack.esql.plan.logical.Enrich;
29+
import org.elasticsearch.xpack.esql.plan.logical.EsRelation;
2930
import org.elasticsearch.xpack.esql.plan.logical.Eval;
3031
import org.elasticsearch.xpack.esql.plan.logical.Filter;
3132
import org.elasticsearch.xpack.esql.plan.logical.Fork;
@@ -71,10 +72,19 @@ public static PreAnalysisResult resolveFieldNames(LogicalPlan parsed, EnrichReso
7172
inlinestatsAggs.add(((InlineStats) i).aggregate());
7273
}
7374

75+
boolean shouldCollectAllDimensions = false;
76+
// Detect if we are in TS mode
77+
List<LogicalPlan> relations = parsed.collect(UnresolvedRelation.class::isInstance);
78+
for (LogicalPlan i : relations) {
79+
if (((UnresolvedRelation) i).isTimeSeriesMode()) {
80+
shouldCollectAllDimensions = true;
81+
}
82+
}
83+
7484
if (false == parsed.anyMatch(p -> shouldCollectReferencedFields(p, inlinestatsAggs))) {
7585
// no explicit columns selection, for example "from employees"
7686
// also, inlinestats only adds columns to the existent output, its Aggregate shouldn't interfere with potentially using "*"
77-
return new PreAnalysisResult(enrichResolution, IndexResolver.ALL_FIELDS, Set.of(), false);
87+
return new PreAnalysisResult(enrichResolution, IndexResolver.ALL_FIELDS, Set.of(), shouldCollectAllDimensions);
7888
}
7989

8090
Holder<Boolean> projectAll = new Holder<>(false);
@@ -86,7 +96,7 @@ public static PreAnalysisResult resolveFieldNames(LogicalPlan parsed, EnrichReso
8696
});
8797

8898
if (projectAll.get()) {
89-
return new PreAnalysisResult(enrichResolution, IndexResolver.ALL_FIELDS, Set.of(), false);
99+
return new PreAnalysisResult(enrichResolution, IndexResolver.ALL_FIELDS, Set.of(), shouldCollectAllDimensions);
90100
}
91101

92102
var referencesBuilder = new Holder<>(AttributeSet.builder());
@@ -221,7 +231,7 @@ public static PreAnalysisResult resolveFieldNames(LogicalPlan parsed, EnrichReso
221231
parsed.forEachDownMayReturnEarly(forEachDownProcessor.get());
222232

223233
if (projectAll.get()) {
224-
return new PreAnalysisResult(enrichResolution, IndexResolver.ALL_FIELDS, Set.of(), false);
234+
return new PreAnalysisResult(enrichResolution, IndexResolver.ALL_FIELDS, Set.of(), shouldCollectAllDimensions);
225235
}
226236

227237
// Add JOIN ON column references afterward to avoid Alias removal
@@ -235,7 +245,12 @@ public static PreAnalysisResult resolveFieldNames(LogicalPlan parsed, EnrichReso
235245

236246
if (fieldNames.isEmpty() && enrichPolicyMatchFields.isEmpty()) {
237247
// there cannot be an empty list of fields, we'll ask the simplest and lightest one instead: _index
238-
return new PreAnalysisResult(enrichResolution, IndexResolver.INDEX_METADATA_FIELD, wildcardJoinIndices, false);
248+
return new PreAnalysisResult(
249+
enrichResolution,
250+
IndexResolver.INDEX_METADATA_FIELD,
251+
wildcardJoinIndices,
252+
shouldCollectAllDimensions
253+
);
239254
} else {
240255
fieldNames.addAll(subfields(fieldNames));
241256
fieldNames.addAll(enrichPolicyMatchFields);

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.elasticsearch.xpack.esql.plan.logical.Enrich;
1919

2020
import java.util.List;
21+
import java.util.Locale;
2122
import java.util.Map;
2223
import java.util.Set;
2324

@@ -2969,9 +2970,23 @@ private void assertFieldNames(String query, Set<String> expected, Set<String> wi
29692970
}
29702971

29712972
private void assertFieldNames(String query, EnrichResolution enrichResolution, Set<String> expected, Set<String> wildCardIndices) {
2972-
var preAnalysisResult = FieldNameUtils.resolveFieldNames(parser.createStatement(query, EsqlTestUtils.TEST_CFG), enrichResolution);
2973+
EsqlSession.PreAnalysisResult preAnalysisResult = FieldNameUtils.resolveFieldNames(
2974+
parser.createStatement(query, EsqlTestUtils.TEST_CFG),
2975+
enrichResolution
2976+
);
2977+
assertThat("Query-wide field names", preAnalysisResult.fieldNames(), equalTo(expected));
2978+
assertThat("Lookup Indices that expect wildcard lookups", preAnalysisResult.wildcardJoinIndices(), equalTo(wildCardIndices));
2979+
assertThat(preAnalysisResult.collectAllDimensions(), equalTo(false));
2980+
2981+
// try again with TS command
2982+
String tsQuery = query.toLowerCase(Locale.ROOT).replaceFirst("^from", "ts");
2983+
if (tsQuery.equals(query)) {
2984+
return;
2985+
}
2986+
preAnalysisResult = FieldNameUtils.resolveFieldNames(parser.createStatement(tsQuery, EsqlTestUtils.TEST_CFG), enrichResolution);
29732987
assertThat("Query-wide field names", preAnalysisResult.fieldNames(), equalTo(expected));
29742988
assertThat("Lookup Indices that expect wildcard lookups", preAnalysisResult.wildcardJoinIndices(), equalTo(wildCardIndices));
2989+
assertThat(preAnalysisResult.collectAllDimensions(), equalTo(true));
29752990
}
29762991

29772992
private static EnrichResolution enrichResolutionWith(String enrichPolicyMatchField) {

0 commit comments

Comments
 (0)