Skip to content

Commit 3ce51a1

Browse files
committed
Check that sort fields on all indices are compatible
Close #73146
1 parent 67b7fd4 commit 3ce51a1

File tree

2 files changed

+56
-6
lines changed

2 files changed

+56
-6
lines changed

server/src/internalClusterTest/java/org/elasticsearch/search/sort/FieldSortIT.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.apache.lucene.util.TestUtil;
1313
import org.apache.lucene.util.UnicodeUtil;
1414
import org.elasticsearch.ElasticsearchException;
15+
import org.elasticsearch.ExceptionsHelper;
1516
import org.elasticsearch.action.admin.indices.alias.Alias;
1617
import org.elasticsearch.action.bulk.BulkRequestBuilder;
1718
import org.elasticsearch.action.index.IndexRequestBuilder;
@@ -64,6 +65,7 @@
6465
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertFirstHit;
6566
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
6667
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
68+
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertOrderedSearchHits;
6769
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
6870
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSecondHit;
6971
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.hasId;
@@ -1935,4 +1937,50 @@ public void testLongSortOptimizationCorrectResults() {
19351937
}
19361938
}
19371939

1940+
public void testIssue73146() throws Exception {
1941+
assertAcked(client().admin().indices().prepareCreate("index1")
1942+
.setMapping("date", "type=keyword", "num_field", "type=integer", "str_field", "type=keyword").get());
1943+
assertAcked(client().admin().indices().prepareCreate("index2")
1944+
.setMapping("date", "type=date", "num_field", "type=integer", "str_field", "type=keyword").get());
1945+
ensureGreen();
1946+
1947+
indexRandom(true,
1948+
client().prepareIndex("index1").setId("1").setSource("date", "2021-05-17", "num_field", 42, "str_field", "aaa"),
1949+
client().prepareIndex("index2").setId("2").setSource("date", "2021-05-18", "num_field", 43, "str_field", "aaa")
1950+
);
1951+
1952+
try {
1953+
client().prepareSearch("index*")
1954+
.addSort("date", SortOrder.DESC)
1955+
.get();
1956+
fail("should fail because of conflicting sort types");
1957+
} catch (SearchPhaseExecutionException e) {
1958+
assertThat(
1959+
ExceptionsHelper.stackTrace(e),
1960+
e.getCause().toString(),
1961+
containsString("Can't do sort across indices, as a field has [raw] type")
1962+
);
1963+
}
1964+
1965+
try {
1966+
client().prepareSearch("index*")
1967+
.addSort("str_field", SortOrder.DESC)
1968+
.addSort("date", SortOrder.DESC)
1969+
.get();
1970+
fail("should fail because of conflicting sort types");
1971+
} catch (SearchPhaseExecutionException e) {
1972+
assertThat(
1973+
ExceptionsHelper.stackTrace(e),
1974+
e.getCause().toString(),
1975+
containsString("Can't do sort across indices, as a field has [raw] type")
1976+
);
1977+
}
1978+
1979+
final SearchResponse response = client().prepareSearch("index*")
1980+
.addSort("str_field", SortOrder.DESC)
1981+
.addSort("num_field", SortOrder.DESC)
1982+
.get();
1983+
assertOrderedSearchHits(response, "2", "1");
1984+
}
1985+
19381986
}

server/src/main/java/org/elasticsearch/action/search/SearchPhaseController.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -488,23 +488,25 @@ private static InternalAggregations reduceAggs(InternalAggregation.ReduceContext
488488
* //TODO: instead of throwing error, find a way to sort long and unsigned_long together
489489
*/
490490
private static void validateMergeSortValueFormats(Collection<? extends SearchPhaseResult> queryResults) {
491-
boolean[] ulFormats = null;
491+
String[] ulFormats = null;
492492
boolean firstResult = true;
493493
for (SearchPhaseResult entry : queryResults) {
494494
DocValueFormat[] formats = entry.queryResult().sortValueFormats();
495495
if (formats == null) return;
496496
if (firstResult) {
497497
firstResult = false;
498-
ulFormats = new boolean[formats.length];
498+
ulFormats = new String[formats.length];
499499
for (int i = 0; i < formats.length; i++) {
500-
ulFormats[i] = formats[i] == DocValueFormat.UNSIGNED_LONG_SHIFTED ? true : false;
500+
ulFormats[i] = formats[i].getWriteableName();
501501
}
502502
} else {
503503
for (int i = 0; i < formats.length; i++) {
504504
// if the format is unsigned_long in one shard, and something different in another shard
505-
if (ulFormats[i] ^ (formats[i] == DocValueFormat.UNSIGNED_LONG_SHIFTED)) {
506-
throw new IllegalArgumentException("Can't do sort across indices, as a field has [unsigned_long] type " +
507-
"in one index, and different type in another index!");
505+
if (ulFormats[i].equals(formats[i].getWriteableName()) == false) {
506+
throw new IllegalArgumentException(String.format(
507+
"Can't do sort across indices, as a field has [%s] type in one index, and different type in another index!",
508+
ulFormats[i]
509+
));
508510
}
509511
}
510512
}

0 commit comments

Comments
 (0)