Skip to content

Commit 8dc9b7b

Browse files
[ES|QL] To_DatePeriod and To_TimeDuration return better error messages on union_type fields (#114934) (#116631)
* better error messages with union_type fields (cherry picked from commit eb6d47f)
1 parent 7427eb9 commit 8dc9b7b

File tree

4 files changed

+47
-1
lines changed

4 files changed

+47
-1
lines changed

docs/changelog/114934.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pr: 114934
2+
summary: "[ES|QL] To_DatePeriod and To_TimeDuration return better error messages on\
3+
\ `union_type` fields"
4+
area: ES|QL
5+
type: bug
6+
issues: []

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import org.elasticsearch.xpack.esql.expression.function.UnsupportedAttribute;
5252
import org.elasticsearch.xpack.esql.expression.function.scalar.EsqlScalarFunction;
5353
import org.elasticsearch.xpack.esql.expression.function.scalar.convert.AbstractConvertFunction;
54+
import org.elasticsearch.xpack.esql.expression.function.scalar.convert.FoldablesConvertFunction;
5455
import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToDouble;
5556
import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToInteger;
5657
import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToLong;
@@ -1226,6 +1227,16 @@ private Expression resolveConvertFunction(AbstractConvertFunction convert, List<
12261227
if (convert.field() instanceof FieldAttribute fa && fa.field() instanceof InvalidMappedField imf) {
12271228
HashMap<TypeResolutionKey, Expression> typeResolutions = new HashMap<>();
12281229
Set<DataType> supportedTypes = convert.supportedTypes();
1230+
if (convert instanceof FoldablesConvertFunction fcf) {
1231+
// FoldablesConvertFunction does not accept fields as inputs, they only accept constants
1232+
String unresolvedMessage = "argument of ["
1233+
+ fcf.sourceText()
1234+
+ "] must be a constant, received ["
1235+
+ Expressions.name(fa)
1236+
+ "]";
1237+
Expression ua = new UnresolvedAttribute(fa.source(), fa.name(), unresolvedMessage);
1238+
return fcf.replaceChildren(Collections.singletonList(ua));
1239+
}
12291240
imf.types().forEach(type -> {
12301241
if (supportedTypes.contains(type.widenSmallNumeric())) {
12311242
TypeResolutionKey key = new TypeResolutionKey(fa.name(), type);

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/FoldablesConvertFunction.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ protected final TypeResolution resolveType() {
5959

6060
@Override
6161
protected final Map<DataType, BuildFactory> factories() {
62-
// TODO if a union type field is provided as an input, the correct error message is not shown, #112668 is a follow up
62+
// This is used by ResolveUnionTypes, which is expected to be applied to ES fields only
63+
// FoldablesConvertFunction takes only constants as inputs, so this is empty
6364
return Map.of();
6465
}
6566

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,34 @@ public void testUnsupportedAndMultiTypedFields() {
244244
+ " [ip] in [test1, test2, test3] and [2] other indices, [keyword] in [test6]",
245245
error("from test* | where multi_typed is not null", analyzer)
246246
);
247+
248+
for (String functionName : List.of("to_timeduration", "to_dateperiod")) {
249+
String lineNumber = functionName.equalsIgnoreCase("to_timeduration") ? "47" : "45";
250+
String errorType = functionName.equalsIgnoreCase("to_timeduration") ? "time_duration" : "date_period";
251+
assertEquals(
252+
"1:" + lineNumber + ": Cannot use field [unsupported] with unsupported type [flattened]",
253+
error("from test* | eval x = now() + " + functionName + "(unsupported)", analyzer)
254+
);
255+
assertEquals(
256+
"1:" + lineNumber + ": argument of [" + functionName + "(multi_typed)] must be a constant, received [multi_typed]",
257+
error("from test* | eval x = now() + " + functionName + "(multi_typed)", analyzer)
258+
);
259+
assertThat(
260+
error("from test* | eval x = unsupported, y = now() + " + functionName + "(x)", analyzer),
261+
containsString("1:23: Cannot use field [unsupported] with unsupported type [flattened]")
262+
);
263+
assertThat(
264+
error("from test* | eval x = multi_typed, y = now() + " + functionName + "(x)", analyzer),
265+
containsString(
266+
"1:48: argument of ["
267+
+ functionName
268+
+ "(x)] must be ["
269+
+ errorType
270+
+ " or string], "
271+
+ "found value [x] type [unsupported]"
272+
)
273+
);
274+
}
247275
}
248276

249277
public void testRoundFunctionInvalidInputs() {

0 commit comments

Comments
 (0)