Fix realtime get of numeric fields (#58121)

Using realtime get on numeric fields when reading from the translog would yield a ClassCastException.

Closes #57462
This commit is contained in:
Yannick Welsch 2020-06-16 09:07:11 +02:00
parent 69d5e044af
commit e046b0a8fa
2 changed files with 24 additions and 13 deletions

View File

@ -262,12 +262,12 @@ public final class ShardGetService extends AbstractIndexShardComponent {
DocValuesType.NONE, -1, Collections.emptyMap(), 0, 0, 0, false);
StoredFieldVisitor.Status status = fieldVisitor.needsField(fieldInfo);
if (status == StoredFieldVisitor.Status.YES) {
if (indexableField.binaryValue() != null) {
if (indexableField.numericValue() != null) {
fieldVisitor.objectField(fieldInfo, indexableField.numericValue());
} else if (indexableField.binaryValue() != null) {
fieldVisitor.binaryField(fieldInfo, indexableField.binaryValue());
} else if (indexableField.stringValue() != null) {
fieldVisitor.objectField(fieldInfo, indexableField.stringValue());
} else if (indexableField.numericValue() != null) {
fieldVisitor.objectField(fieldInfo, indexableField.numericValue());
}
} else if (status == StoredFieldVisitor.Status.STOP) {
break;

View File

@ -91,19 +91,30 @@ public class ShardGetServiceTests extends IndexShardTestCase {
closeShards(primary);
}
public void testGetFromTranslogWithSourceMappingOptionsAndStoredFields() throws IOException {
public void testGetFromTranslogWithStringSourceMappingOptionsAndStoredFields() throws IOException {
String docToIndex = "{\"foo\" : \"foo\", \"bar\" : \"bar\"}";
boolean noSource = randomBoolean();
String sourceOptions = noSource ? "\"enabled\": false" : randomBoolean() ? "\"excludes\": [\"fo*\"]" : "\"includes\": [\"ba*\"]";
runGetFromTranslogWithOptions(docToIndex, sourceOptions, noSource ? "" : "{\"bar\":\"bar\"}", "\"text\"", "foo");
}
public void testGetFromTranslogWithLongSourceMappingOptionsAndStoredFields() throws IOException {
String docToIndex = "{\"foo\" : 7, \"bar\" : 42}";
boolean noSource = randomBoolean();
String sourceOptions = noSource ? "\"enabled\": false" : randomBoolean() ? "\"excludes\": [\"fo*\"]" : "\"includes\": [\"ba*\"]";
runGetFromTranslogWithOptions(docToIndex, sourceOptions, noSource ? "" : "{\"bar\":42}", "\"long\"", 7L);
}
private void runGetFromTranslogWithOptions(String docToIndex, String sourceOptions, String expectedResult, String fieldType,
Object expectedFooVal) throws IOException {
Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, Version.CURRENT)
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 1)
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1)
.build();
String docToIndex = "{\"foo\" : \"foo\", \"bar\" : \"bar\"}";
boolean noSource = randomBoolean();
String sourceOptions = noSource ? "\"enabled\": false" : randomBoolean() ? "\"excludes\": [\"fo*\"]" : "\"includes\": [\"ba*\"]";
String expectedResult = noSource ? "" : "{\"bar\":\"bar\"}";
IndexMetadata metadata = IndexMetadata.builder("test")
.putMapping("test", "{ \"properties\": { \"foo\": { \"type\": \"text\", \"store\": true }, " +
"\"bar\": { \"type\": \"text\"}}, \"_source\": { "
+ sourceOptions + "}}}")
.putMapping("test", "{ \"properties\": { \"foo\": { \"type\": " + fieldType + ", \"store\": true }, " +
"\"bar\": { \"type\": " + fieldType + "}}, \"_source\": { " + sourceOptions + "}}}")
.settings(settings)
.primaryTerm(0, 1).build();
IndexShard primary = newShard(new ShardId(metadata.getIndex(), 0), true, "n1", metadata, null);
@ -138,7 +149,7 @@ public class ShardGetServiceTests extends IndexShardTestCase {
assertEquals(new String(testGet2.source() == null ? new byte[0] : testGet2.source(), StandardCharsets.UTF_8), expectedResult);
assertTrue(testGet2.getFields().containsKey(RoutingFieldMapper.NAME));
assertTrue(testGet2.getFields().containsKey("foo"));
assertEquals("foo", testGet2.getFields().get("foo").getValue());
assertEquals(expectedFooVal, testGet2.getFields().get("foo").getValue());
try (Engine.Searcher searcher = primary.getEngine().acquireSearcher("test", Engine.SearcherScope.INTERNAL)) {
assertEquals(searcher.getIndexReader().maxDoc(), 2); // we read from the translog
}
@ -152,7 +163,7 @@ public class ShardGetServiceTests extends IndexShardTestCase {
assertEquals(new String(testGet2.source() == null ? new byte[0] : testGet2.source(), StandardCharsets.UTF_8), expectedResult);
assertTrue(testGet2.getFields().containsKey(RoutingFieldMapper.NAME));
assertTrue(testGet2.getFields().containsKey("foo"));
assertEquals("foo", testGet2.getFields().get("foo").getValue());
assertEquals(expectedFooVal, testGet2.getFields().get("foo").getValue());
closeShards(primary);
}