Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1054,7 +1054,13 @@ private LogicalPlan resolveFuse(Fuse fuse, List<Attribute> childrenOutput) {
if (attr.name().equals(score.name())) {
continue;
}
aggregates.add(new Alias(source, attr.name(), new Values(source, attr, aggFilter)));
var valuesAgg = new Values(source, attr, aggFilter);
// Use VALUES only on supported fields.
// FuseScoreEval will check that the input contains only columns with supported data types
// and will fail with an appropriate error message if it doesn't.
if (valuesAgg.resolved()) {
aggregates.add(new Alias(source, attr.name(), valuesAgg));
}
}

return resolveAggregate(new Aggregate(source, scoreEval, new ArrayList<>(keys), aggregates), childrenOutput);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.elasticsearch.xpack.esql.core.tree.NodeInfo;
import org.elasticsearch.xpack.esql.core.tree.Source;
import org.elasticsearch.xpack.esql.core.type.DataType;
import org.elasticsearch.xpack.esql.expression.function.aggregate.Values;
import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan;
import org.elasticsearch.xpack.esql.plan.logical.UnaryPlan;

Expand Down Expand Up @@ -122,6 +123,8 @@ public boolean licenseCheck(XPackLicenseState state) {

@Override
public void postAnalysisVerification(Failures failures) {
validateInput(failures);

if (options == null) {
return;
}
Expand All @@ -132,6 +135,26 @@ public void postAnalysisVerification(Failures failures) {
}
}

private void validateInput(Failures failures) {
// Since we use STATS BY to merge rows together, we need to make sure that all columns can be used in STATS BY.
// When the input of FUSE contains unsupported columns, we don't want to fail with a STATS BY validation error,
// but with an error specific to FUSE.
Expression aggFilter = new Literal(source(), true, DataType.BOOLEAN);

for (Attribute attr : child().output()) {
var valuesAgg = new Values(source(), attr, aggFilter);

if (valuesAgg.resolved() == false) {
failures.add(
new Failure(
this,
"cannot use [" + attr.name() + "] as an input of FUSE. Consider using [DROP " + attr.name() + "] before FUSE."
)
);
}
}
}

private void validateRrfOptions(Failures failures) {
options.keyFoldedMap().forEach((key, value) -> {
if (key.equals(RrfConfig.RANK_CONSTANT)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,13 @@ public void testUnsupportedAndMultiTypedFields() {
)
);
}

if (EsqlCapabilities.Cap.FUSE_V6.isEnabled()) {
assertEquals(
"1:76: cannot use [double] as an input of FUSE. Consider using [DROP double] before FUSE.",
error("from test* METADATA _id, _index, _score | FORK (where true) (where true) | FUSE", analyzer)
);
}
}

public void testRoundFunctionInvalidInputs() {
Expand Down