mirror of
https://github.com/elastic/elasticsearch.git
synced 2025-06-28 09:28:55 -04:00
[ES|QL] To_DatePeriod and To_TimeDuration return better error messages on union_type fields (#114934)
* better error messages with union_type fields
This commit is contained in:
parent
dd32cb6439
commit
eb6d47f0f9
4 changed files with 47 additions and 1 deletions
6
docs/changelog/114934.yaml
Normal file
6
docs/changelog/114934.yaml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
pr: 114934
|
||||||
|
summary: "[ES|QL] To_DatePeriod and To_TimeDuration return better error messages on\
|
||||||
|
\ `union_type` fields"
|
||||||
|
area: ES|QL
|
||||||
|
type: bug
|
||||||
|
issues: []
|
|
@ -51,6 +51,7 @@ import org.elasticsearch.xpack.esql.expression.function.UnresolvedFunction;
|
||||||
import org.elasticsearch.xpack.esql.expression.function.UnsupportedAttribute;
|
import org.elasticsearch.xpack.esql.expression.function.UnsupportedAttribute;
|
||||||
import org.elasticsearch.xpack.esql.expression.function.scalar.EsqlScalarFunction;
|
import org.elasticsearch.xpack.esql.expression.function.scalar.EsqlScalarFunction;
|
||||||
import org.elasticsearch.xpack.esql.expression.function.scalar.convert.AbstractConvertFunction;
|
import org.elasticsearch.xpack.esql.expression.function.scalar.convert.AbstractConvertFunction;
|
||||||
|
import org.elasticsearch.xpack.esql.expression.function.scalar.convert.FoldablesConvertFunction;
|
||||||
import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToDouble;
|
import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToDouble;
|
||||||
import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToInteger;
|
import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToInteger;
|
||||||
import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToLong;
|
import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToLong;
|
||||||
|
@ -1226,6 +1227,16 @@ public class Analyzer extends ParameterizedRuleExecutor<LogicalPlan, AnalyzerCon
|
||||||
if (convert.field() instanceof FieldAttribute fa && fa.field() instanceof InvalidMappedField imf) {
|
if (convert.field() instanceof FieldAttribute fa && fa.field() instanceof InvalidMappedField imf) {
|
||||||
HashMap<TypeResolutionKey, Expression> typeResolutions = new HashMap<>();
|
HashMap<TypeResolutionKey, Expression> typeResolutions = new HashMap<>();
|
||||||
Set<DataType> supportedTypes = convert.supportedTypes();
|
Set<DataType> supportedTypes = convert.supportedTypes();
|
||||||
|
if (convert instanceof FoldablesConvertFunction fcf) {
|
||||||
|
// FoldablesConvertFunction does not accept fields as inputs, they only accept constants
|
||||||
|
String unresolvedMessage = "argument of ["
|
||||||
|
+ fcf.sourceText()
|
||||||
|
+ "] must be a constant, received ["
|
||||||
|
+ Expressions.name(fa)
|
||||||
|
+ "]";
|
||||||
|
Expression ua = new UnresolvedAttribute(fa.source(), fa.name(), unresolvedMessage);
|
||||||
|
return fcf.replaceChildren(Collections.singletonList(ua));
|
||||||
|
}
|
||||||
imf.types().forEach(type -> {
|
imf.types().forEach(type -> {
|
||||||
if (supportedTypes.contains(type.widenSmallNumeric())) {
|
if (supportedTypes.contains(type.widenSmallNumeric())) {
|
||||||
TypeResolutionKey key = new TypeResolutionKey(fa.name(), type);
|
TypeResolutionKey key = new TypeResolutionKey(fa.name(), type);
|
||||||
|
|
|
@ -59,7 +59,8 @@ public abstract class FoldablesConvertFunction extends AbstractConvertFunction i
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final Map<DataType, BuildFactory> factories() {
|
protected final Map<DataType, BuildFactory> factories() {
|
||||||
// TODO if a union type field is provided as an input, the correct error message is not shown, #112668 is a follow up
|
// This is used by ResolveUnionTypes, which is expected to be applied to ES fields only
|
||||||
|
// FoldablesConvertFunction takes only constants as inputs, so this is empty
|
||||||
return Map.of();
|
return Map.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -244,6 +244,34 @@ public class VerifierTests extends ESTestCase {
|
||||||
+ " [ip] in [test1, test2, test3] and [2] other indices, [keyword] in [test6]",
|
+ " [ip] in [test1, test2, test3] and [2] other indices, [keyword] in [test6]",
|
||||||
error("from test* | where multi_typed is not null", analyzer)
|
error("from test* | where multi_typed is not null", analyzer)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
for (String functionName : List.of("to_timeduration", "to_dateperiod")) {
|
||||||
|
String lineNumber = functionName.equalsIgnoreCase("to_timeduration") ? "47" : "45";
|
||||||
|
String errorType = functionName.equalsIgnoreCase("to_timeduration") ? "time_duration" : "date_period";
|
||||||
|
assertEquals(
|
||||||
|
"1:" + lineNumber + ": Cannot use field [unsupported] with unsupported type [flattened]",
|
||||||
|
error("from test* | eval x = now() + " + functionName + "(unsupported)", analyzer)
|
||||||
|
);
|
||||||
|
assertEquals(
|
||||||
|
"1:" + lineNumber + ": argument of [" + functionName + "(multi_typed)] must be a constant, received [multi_typed]",
|
||||||
|
error("from test* | eval x = now() + " + functionName + "(multi_typed)", analyzer)
|
||||||
|
);
|
||||||
|
assertThat(
|
||||||
|
error("from test* | eval x = unsupported, y = now() + " + functionName + "(x)", analyzer),
|
||||||
|
containsString("1:23: Cannot use field [unsupported] with unsupported type [flattened]")
|
||||||
|
);
|
||||||
|
assertThat(
|
||||||
|
error("from test* | eval x = multi_typed, y = now() + " + functionName + "(x)", analyzer),
|
||||||
|
containsString(
|
||||||
|
"1:48: argument of ["
|
||||||
|
+ functionName
|
||||||
|
+ "(x)] must be ["
|
||||||
|
+ errorType
|
||||||
|
+ " or string], "
|
||||||
|
+ "found value [x] type [unsupported]"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testRoundFunctionInvalidInputs() {
|
public void testRoundFunctionInvalidInputs() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue