diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/topN.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/topN.csv-spec index e7bf953f5e08d..19c68f74f2022 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/topN.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/topN.csv-spec @@ -168,3 +168,21 @@ FROM employees avg_worked_seconds:long | birth_date:date | emp_no:i | gender:k | height:d | height.float:d | height.half_float:d | height.scaled_float:d | hire_date:date | is_rehired:bool | job_positions:k | languages:i | languages.byte:i | languages.long:l | languages.short:short | salary:i | salary_change:d | salary_change.int:i | salary_change.keyword:k | salary_change.long:l | still_hired:bool | name:k | first_name:k | last_name:k 349086555 | 1961-09-01T00:00:00Z | 10056 | F | 1.57 | 1.5700000524520874 | 1.5703125 | 1.57 | 1990-02-01T00:00:00Z | [false, false, true] | [Senior Team Lead] | 2 | 2 | 2 | 2 | 33370 | [-5.17, 10.99] | [-5, 10] | [-5.17, 10.99] | [-5, 10] | true | Brendon | Bernini | Brendon ; + +sortingByTsidMetadataField +required_capability: ts_command_v0 +required_capability: metadata_tsid_field + +TS k8s METADATA _tsid +| SORT events_received ASC +| LIMIT 5 +| KEEP events_received, @timestamp, cluster, pod +; + +events_received:long | @timestamp:datetime | cluster:keyword | pod:keyword +1 | 2024-05-10T00:00:00.000Z | qa | one +1 | 2024-05-10T00:00:00.000Z | qa | two +1 | 2024-05-10T00:00:00.000Z | qa | three +1 | 2024-05-10T00:00:00.000Z | prod | one +1 | 2024-05-10T00:00:00.000Z | prod | two +; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/PositionToXContent.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/PositionToXContent.java index e1e5422c57123..d03ae628f6fc6 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/PositionToXContent.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/PositionToXContent.java @@ -28,6 +28,7 @@ import org.elasticsearch.xcontent.XContentParser; import org.elasticsearch.xcontent.XContentParserConfiguration; import org.elasticsearch.xcontent.XContentType; +import org.elasticsearch.xpack.esql.core.expression.MetadataAttribute; import java.io.IOException; @@ -108,6 +109,10 @@ protected XContentBuilder valueToXContent(XContentBuilder builder, ToXContent.Pa // https://github.com/FasterXML/jackson-dataformats-binary/issues/366 val = BytesRef.deepCopyOf(scratch); } + + if (columnInfo.name().equalsIgnoreCase(MetadataAttribute.TSID_FIELD)) { + return builder.value(TimeSeriesIdFieldMapper.encodeTsid(val)); + } return builder.utf8Value(val.bytes, val.offset, val.length); } }; diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/action/EsqlQueryResponseTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/action/EsqlQueryResponseTests.java index edac6b1c5b3eb..cb231485b852c 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/action/EsqlQueryResponseTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/action/EsqlQueryResponseTests.java @@ -49,6 +49,7 @@ import org.elasticsearch.geometry.utils.Geohash; import org.elasticsearch.h3.H3; import org.elasticsearch.index.mapper.BlockLoader; +import org.elasticsearch.index.mapper.TimeSeriesIdFieldMapper; import org.elasticsearch.rest.action.RestActions; import org.elasticsearch.search.aggregations.bucket.geogrid.GeoTileUtils; import org.elasticsearch.test.AbstractChunkedSerializingTestCase; @@ -64,6 +65,7 @@ import org.elasticsearch.xcontent.XContentType; import org.elasticsearch.xcontent.json.JsonXContent; import org.elasticsearch.xpack.esql.EsqlTestUtils; +import org.elasticsearch.xpack.esql.core.expression.MetadataAttribute; import org.elasticsearch.xpack.esql.core.type.DataType; import org.elasticsearch.xpack.esql.planner.PlannerUtils; import org.elasticsearch.xpack.esql.type.UnsupportedEsFieldTests; @@ -1086,6 +1088,36 @@ public void testProfileXContent() { } } + public void testKeywordTsidFieldEncoding() { + BytesRef tsidValue = (BytesRef) EsqlTestUtils.randomLiteral(DataType.TSID_DATA_TYPE).value(); + Object expectedEncoded = TimeSeriesIdFieldMapper.encodeTsid(tsidValue); + + for (String columnName : List.of( + MetadataAttribute.TSID_FIELD.toLowerCase(Locale.ROOT), + MetadataAttribute.TSID_FIELD.toUpperCase(Locale.ROOT) + )) { + for (String dataType : List.of(DataType.KEYWORD.esType(), DataType.TEXT.esType())) { + try ( + BytesRefBlock.Builder refBlockBuilder = blockFactory.newBytesRefBlockBuilder(1); + + EsqlQueryResponse response = new EsqlQueryResponse( + List.of(new ColumnInfoImpl(columnName, dataType, null)), + List.of(new Page(refBlockBuilder.appendBytesRef(tsidValue).build())), + 1, + 1, + null, + false, + false, + null + ) + ) { + String json = Strings.toString(wrapAsToXContent(response), true, false); + assertThat(json, org.hamcrest.Matchers.containsString("\"" + expectedEncoded + "\"")); + } + } + } + } + @Override protected void dispose(EsqlQueryResponse esqlQueryResponse) { esqlQueryResponse.close();