Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
6 changes: 6 additions & 0 deletions docs/changelog/118435.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pr: 118435
summary: '`_score` should not be a reserved attribute in ES|QL'
area: ES|QL
type: enhancement
issues:
- 118460
9 changes: 6 additions & 3 deletions muted-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -382,8 +382,11 @@ tests:
- class: "org.elasticsearch.xpack.esql.qa.mixed.MixedClusterEsqlSpecIT"
method: "test {scoring.*}"
issue: https://github.com/elastic/elasticsearch/issues/117641
- class: org.elasticsearch.xpack.esql.ccq.MultiClusterSpecIT
method: test {scoring.QstrWithFieldAndScoringSortedEval}
- class: "org.elasticsearch.xpack.esql.qa.mixed.MultilusterEsqlSpecIT"
method: "test {scoring.*}"
issue: https://github.com/elastic/elasticsearch/issues/118460
- class: "org.elasticsearch.xpack.esql.ccq.MultiClusterSpecIT"
method: "test {scoring.*}"
issue: https://github.com/elastic/elasticsearch/issues/117751
- class: org.elasticsearch.search.ccs.CrossClusterIT
method: testCancel
Expand Down Expand Up @@ -463,4 +466,4 @@ tests:
issue: https://github.com/elastic/elasticsearch/issues/118514
- class: org.elasticsearch.xpack.esql.qa.mixed.MixedClusterEsqlSpecIT
method: test {grok.OverwriteNameWhere SYNC}
issue: https://github.com/elastic/elasticsearch/issues/118638
issue: https://github.com/elastic/elasticsearch/issues/118638
Original file line number Diff line number Diff line change
Expand Up @@ -283,3 +283,33 @@ book_no:keyword | c_score:double
7350 | 2.0
7140 | 3.0
;

QstrScoreManipulation
required_capability: metadata_score
required_capability: qstr_function

from books metadata _score
| where qstr("title:rings")
| eval _score = _score + 1
| keep book_no, title, _score
| limit 2;

book_no:keyword | title:text | _score:double
4023 | A Tolkien Compass: Including J. R. R. Tolkien's Guide to the Names in The Lord of the Rings | 2.6404519081115723
2714 | Return of the King Being the Third Part of The Lord of the Rings | 2.9239964485168457
;

QstrScoreOverride
required_capability: metadata_score
required_capability: qstr_function

from books metadata _score
| where qstr("title:rings")
| eval _score = "foobar"
| keep book_no, title, _score
| limit 2;

book_no:keyword | title:text | _score:keyword
4023 | A Tolkien Compass: Including J. R. R. Tolkien's Guide to the Names in The Lord of the Rings | foobar
2714 | Return of the King Being the Third Part of The Lord of the Rings | foobar
;
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import org.elasticsearch.xpack.esql.core.expression.Expression;
import org.elasticsearch.xpack.esql.core.expression.Expressions;
import org.elasticsearch.xpack.esql.core.expression.FieldAttribute;
import org.elasticsearch.xpack.esql.core.expression.MetadataAttribute;
import org.elasticsearch.xpack.esql.core.expression.NamedExpression;
import org.elasticsearch.xpack.esql.core.expression.TypeResolutions;
import org.elasticsearch.xpack.esql.core.expression.function.Function;
Expand Down Expand Up @@ -208,7 +207,6 @@ else if (p instanceof Lookup lookup) {
checkJoin(p, failures);
});
checkRemoteEnrich(plan, failures);
checkMetadataScoreNameReserved(plan, failures);

if (failures.isEmpty()) {
checkLicense(plan, licenseState, failures);
Expand All @@ -222,13 +220,6 @@ else if (p instanceof Lookup lookup) {
return failures;
}

private static void checkMetadataScoreNameReserved(LogicalPlan p, Set<Failure> failures) {
// _score can only be set as metadata attribute
if (p.inputSet().stream().anyMatch(a -> MetadataAttribute.SCORE.equals(a.name()) && (a instanceof MetadataAttribute) == false)) {
failures.add(fail(p, "`" + MetadataAttribute.SCORE + "` is a reserved METADATA attribute"));
}
}

private void checkSort(LogicalPlan p, Set<Failure> failures) {
if (p instanceof OrderBy ob) {
ob.order().forEach(o -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.esql.VerificationException;
import org.elasticsearch.xpack.esql.action.EsqlCapabilities;
import org.elasticsearch.xpack.esql.core.expression.Attribute;
import org.elasticsearch.xpack.esql.core.type.DataType;
import org.elasticsearch.xpack.esql.core.type.EsField;
import org.elasticsearch.xpack.esql.core.type.InvalidMappedField;
Expand All @@ -22,7 +21,6 @@
import org.elasticsearch.xpack.esql.parser.EsqlParser;
import org.elasticsearch.xpack.esql.parser.QueryParam;
import org.elasticsearch.xpack.esql.parser.QueryParams;
import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan;

import java.util.ArrayList;
import java.util.LinkedHashMap;
Expand Down Expand Up @@ -1805,29 +1803,6 @@ public void testToDatePeriodToTimeDurationWithInvalidType() {
);
}

public void testNonMetadataScore() {
assumeTrue("'METADATA _score' is disabled", EsqlCapabilities.Cap.METADATA_SCORE.isEnabled());
assertEquals("1:12: `_score` is a reserved METADATA attribute", error("from foo | eval _score = 10"));

assertEquals(
"1:48: `_score` is a reserved METADATA attribute",
error("from foo metadata _score | where qstr(\"bar\") | eval _score = _score + 1")
);
}

public void testScoreRenaming() {
assumeTrue("'METADATA _score' is disabled", EsqlCapabilities.Cap.METADATA_SCORE.isEnabled());
assertEquals("1:33: `_score` is a reserved METADATA attribute", error("from foo METADATA _id, _score | rename _id as _score"));

assertTrue(passes("from foo metadata _score | rename _score as foo").stream().anyMatch(a -> a.name().equals("foo")));
}

private List<Attribute> passes(String query) {
LogicalPlan logicalPlan = defaultAnalyzer.analyze(parser.createStatement(query));
assertTrue(logicalPlan.resolved());
return logicalPlan.output();
}

public void testIntervalAsString() {
// DateTrunc
for (String interval : List.of("1 minu", "1 dy", "1.5 minutes", "0.5 days", "minutes 1", "day 5")) {
Expand Down