diff --git a/server/src/internalClusterTest/java/org/elasticsearch/search/sort/FieldSortIT.java b/server/src/internalClusterTest/java/org/elasticsearch/search/sort/FieldSortIT.java index 53c0431f083bf..f0662454011c9 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/search/sort/FieldSortIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/search/sort/FieldSortIT.java @@ -1762,7 +1762,6 @@ public void testCastNumericType() throws Exception { } } - @AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/63719") public void testCastDate() throws Exception { assertAcked(prepareCreate("index_date") .setMapping("field", "type=date")); @@ -1780,7 +1779,7 @@ public void testCastDate() throws Exception { { SearchResponse response = client().prepareSearch() .setQuery(matchAllQuery()) - .setSize(builders.size()) + .setSize(2) .addSort(SortBuilders.fieldSort("field").setNumericType("date")) .get(); SearchHits hits = response.getHits(); @@ -1791,12 +1790,36 @@ public void testCastDate() throws Exception { } assertEquals(1712879236854L, hits.getAt(0).getSortValues()[0]); assertEquals(1712879237000L, hits.getAt(1).getSortValues()[0]); + + response = client().prepareSearch() + .setMaxConcurrentShardRequests(1) + .setQuery(matchAllQuery()) + .setSize(1) + .addSort(SortBuilders.fieldSort("field").setNumericType("date")) + .get(); + hits = response.getHits(); + + assertEquals(1, hits.getHits().length); + assertThat(hits.getAt(0).getSortValues()[0].getClass(), equalTo(Long.class)); + assertEquals(1712879236854L, hits.getAt(0).getSortValues()[0]); + + response = client().prepareSearch() + .setMaxConcurrentShardRequests(1) + .setQuery(matchAllQuery()) + .setSize(1) + .addSort(SortBuilders.fieldSort("field").order(SortOrder.DESC).setNumericType("date")) + .get(); + hits = response.getHits(); + + assertEquals(1, hits.getHits().length); + assertThat(hits.getAt(0).getSortValues()[0].getClass(), equalTo(Long.class)); + assertEquals(1712879237000L, hits.getAt(0).getSortValues()[0]); } { SearchResponse response = client().prepareSearch() .setQuery(matchAllQuery()) - .setSize(builders.size()) + .setSize(2) .addSort(SortBuilders.fieldSort("field").setNumericType("date_nanos")) .get(); SearchHits hits = response.getHits(); @@ -1806,6 +1829,28 @@ public void testCastDate() throws Exception { } assertEquals(1712879236854775807L, hits.getAt(0).getSortValues()[0]); assertEquals(1712879237000000000L, hits.getAt(1).getSortValues()[0]); + + response = client().prepareSearch() + .setMaxConcurrentShardRequests(1) + .setQuery(matchAllQuery()) + .setSize(1) + .addSort(SortBuilders.fieldSort("field").setNumericType("date_nanos")) + .get(); + hits = response.getHits(); + assertEquals(1, hits.getHits().length); + assertThat(hits.getAt(0).getSortValues()[0].getClass(), equalTo(Long.class)); + assertEquals(1712879236854775807L, hits.getAt(0).getSortValues()[0]); + + response = client().prepareSearch() + .setMaxConcurrentShardRequests(1) + .setQuery(matchAllQuery()) + .setSize(1) + .addSort(SortBuilders.fieldSort("field").order(SortOrder.DESC).setNumericType("date_nanos")) + .get(); + hits = response.getHits(); + assertEquals(1, hits.getHits().length); + assertThat(hits.getAt(0).getSortValues()[0].getClass(), equalTo(Long.class)); + assertEquals(1712879237000000000L, hits.getAt(0).getSortValues()[0]); } { @@ -1813,15 +1858,14 @@ public void testCastDate() throws Exception { builders.add(client().prepareIndex("index_date") .setSource("field", "1905-04-11T23:47:17")); indexRandom(true, true, builders); - SearchPhaseExecutionException exc = expectThrows(SearchPhaseExecutionException.class, - () -> client().prepareSearch() + SearchResponse response = client().prepareSearch() .setQuery(matchAllQuery()) - .setSize(builders.size()) - .setAllowPartialSearchResults(false) + .setSize(1) .addSort(SortBuilders.fieldSort("field").setNumericType("date_nanos")) - .get() - ); - assertThat(exc.toString(), containsString("are before the epoch in 1970")); + .get(); + assertNotNull(response.getShardFailures()); + assertThat(response.getShardFailures().length, equalTo(1)); + assertThat(response.getShardFailures()[0].toString(), containsString("are before the epoch in 1970")); } { @@ -1829,15 +1873,14 @@ public void testCastDate() throws Exception { builders.add(client().prepareIndex("index_date") .setSource("field", "2346-04-11T23:47:17")); indexRandom(true, true, builders); - SearchPhaseExecutionException exc = expectThrows(SearchPhaseExecutionException.class, - () -> client().prepareSearch() + SearchResponse response = client().prepareSearch() .setQuery(QueryBuilders.rangeQuery("field").gt("1970-01-01")) - .setSize(builders.size()) - .setAllowPartialSearchResults(false) + .setSize(10) .addSort(SortBuilders.fieldSort("field").setNumericType("date_nanos")) - .get() - ); - assertThat(exc.toString(), containsString("are after 2262")); + .get(); + assertNotNull(response.getShardFailures()); + assertThat(response.getShardFailures().length, equalTo(1)); + assertThat(response.getShardFailures()[0].toString(), containsString("are after 2262")); } } diff --git a/server/src/main/java/org/elasticsearch/search/sort/FieldSortBuilder.java b/server/src/main/java/org/elasticsearch/search/sort/FieldSortBuilder.java index 694188094a041..7f197d3398038 100644 --- a/server/src/main/java/org/elasticsearch/search/sort/FieldSortBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/sort/FieldSortBuilder.java @@ -347,6 +347,7 @@ public SortFieldAndFormat build(QueryShardContext context) throws IOException { IndexNumericFieldData numericFieldData = (IndexNumericFieldData) fieldData; NumericType resolvedType = resolveNumericType(numericType); field = numericFieldData.sortField(resolvedType, missing, localSortMode(), nested, reverse); + isNanosecond = resolvedType == NumericType.DATE_NANOSECONDS; } else { field = fieldData.sortField(missing, localSortMode(), nested, reverse); if (fieldData instanceof IndexNumericFieldData) { @@ -387,11 +388,6 @@ public boolean isBottomSortShardDisjoint(QueryShardContext context, SearchSortVa DocValueFormat docValueFormat = bottomSortValues.getSortValueFormats()[0]; final DateMathParser dateMathParser; if (docValueFormat instanceof DocValueFormat.DateTime) { - if (fieldType instanceof DateFieldType && ((DateFieldType) fieldType).resolution() == NANOSECONDS) { - // we parse the formatted value with the resolution of the local field because - // the provided format can use a different one (date vs date_nanos). - docValueFormat = DocValueFormat.withNanosecondResolution(docValueFormat); - } dateMathParser = ((DocValueFormat.DateTime) docValueFormat).getDateMathParser(); } else { dateMathParser = null; diff --git a/server/src/test/java/org/elasticsearch/search/sort/FieldSortBuilderTests.java b/server/src/test/java/org/elasticsearch/search/sort/FieldSortBuilderTests.java index 89be4d563be2e..89d6aa235f1df 100644 --- a/server/src/test/java/org/elasticsearch/search/sort/FieldSortBuilderTests.java +++ b/server/src/test/java/org/elasticsearch/search/sort/FieldSortBuilderTests.java @@ -117,7 +117,7 @@ public FieldSortBuilder randomFieldSortBuilder() { builder.setNestedSort(createRandomNestedSort(3)); } if (randomBoolean()) { - builder.setNumericType(randomFrom(random(), "long", "double", "date", "date_nanos")); + builder.setNumericType(randomFrom(random(), "long", "double")); } return builder; } @@ -147,7 +147,7 @@ protected FieldSortBuilder mutate(FieldSortBuilder original) throws IOException break; case 5: mutated.setNumericType(randomValueOtherThan(original.getNumericType(), - () -> randomFrom("long", "double", "date", "date_nanos"))); + () -> randomFrom("long", "double"))); break; default: throw new IllegalStateException("Unsupported mutation.");