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 86134d7250b5e..fae3dc1efcd60 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/search/sort/FieldSortIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/search/sort/FieldSortIT.java @@ -12,6 +12,7 @@ import org.apache.lucene.util.TestUtil; import org.apache.lucene.util.UnicodeUtil; import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.action.admin.indices.alias.Alias; import org.elasticsearch.action.bulk.BulkRequestBuilder; import org.elasticsearch.action.index.IndexRequestBuilder; @@ -64,6 +65,7 @@ import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertFirstHit; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertOrderedSearchHits; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSecondHit; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.hasId; @@ -1935,4 +1937,50 @@ public void testLongSortOptimizationCorrectResults() { } } + public void testIssue73146() throws Exception { + assertAcked(client().admin().indices().prepareCreate("index1") + .setMapping("date", "type=keyword", "num_field", "type=integer", "str_field", "type=keyword").get()); + assertAcked(client().admin().indices().prepareCreate("index2") + .setMapping("date", "type=date", "num_field", "type=integer", "str_field", "type=keyword").get()); + ensureGreen(); + + indexRandom(true, + client().prepareIndex("index1").setId("1").setSource("date", "2021-05-17", "num_field", 42, "str_field", "aaa"), + client().prepareIndex("index2").setId("2").setSource("date", "2021-05-18", "num_field", 43, "str_field", "aaa") + ); + + try { + client().prepareSearch("index*") + .addSort("date", SortOrder.DESC) + .get(); + fail("should fail because of conflicting sort types"); + } catch (SearchPhaseExecutionException e) { + assertThat( + ExceptionsHelper.stackTrace(e), + e.getCause().toString(), + containsString("Can't do sort across indices, as a field has [raw] type") + ); + } + + try { + client().prepareSearch("index*") + .addSort("str_field", SortOrder.DESC) + .addSort("date", SortOrder.DESC) + .get(); + fail("should fail because of conflicting sort types"); + } catch (SearchPhaseExecutionException e) { + assertThat( + ExceptionsHelper.stackTrace(e), + e.getCause().toString(), + containsString("Can't do sort across indices, as a field has [raw] type") + ); + } + + final SearchResponse response = client().prepareSearch("index*") + .addSort("str_field", SortOrder.DESC) + .addSort("num_field", SortOrder.DESC) + .get(); + assertOrderedSearchHits(response, "2", "1"); + } + } diff --git a/server/src/main/java/org/elasticsearch/action/search/SearchPhaseController.java b/server/src/main/java/org/elasticsearch/action/search/SearchPhaseController.java index 17aa182be56bb..e3cc2381ca4b0 100644 --- a/server/src/main/java/org/elasticsearch/action/search/SearchPhaseController.java +++ b/server/src/main/java/org/elasticsearch/action/search/SearchPhaseController.java @@ -488,23 +488,25 @@ private static InternalAggregations reduceAggs(InternalAggregation.ReduceContext * //TODO: instead of throwing error, find a way to sort long and unsigned_long together */ private static void validateMergeSortValueFormats(Collection queryResults) { - boolean[] ulFormats = null; + String[] ulFormats = null; boolean firstResult = true; for (SearchPhaseResult entry : queryResults) { DocValueFormat[] formats = entry.queryResult().sortValueFormats(); if (formats == null) return; if (firstResult) { firstResult = false; - ulFormats = new boolean[formats.length]; + ulFormats = new String[formats.length]; for (int i = 0; i < formats.length; i++) { - ulFormats[i] = formats[i] == DocValueFormat.UNSIGNED_LONG_SHIFTED ? true : false; + ulFormats[i] = formats[i].getWriteableName(); } } else { for (int i = 0; i < formats.length; i++) { // if the format is unsigned_long in one shard, and something different in another shard - if (ulFormats[i] ^ (formats[i] == DocValueFormat.UNSIGNED_LONG_SHIFTED)) { - throw new IllegalArgumentException("Can't do sort across indices, as a field has [unsigned_long] type " + - "in one index, and different type in another index!"); + if (ulFormats[i].equals(formats[i].getWriteableName()) == false) { + throw new IllegalArgumentException(String.format( + "Can't do sort across indices, as a field has [%s] type in one index, and different type in another index!", + ulFormats[i] + )); } } }