Skip to content

Commit dc5aa99

Browse files
fred84cbuescher
authored andcommitted
Fix NPE in token_count datatype with null value (#25046)
Fixes an issue with the handling of null values for the token_count data type. Closes #24928
1 parent 8250aa4 commit dc5aa99

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

core/src/main/java/org/elasticsearch/index/mapper/TokenCountFieldMapper.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,10 @@ protected void parseCreateField(ParseContext context, List<IndexableField> field
134134
value = context.parser().textOrNull();
135135
}
136136

137+
if (value == null && fieldType().nullValue() == null) {
138+
return;
139+
}
140+
137141
final int tokenCount;
138142
if (value == null) {
139143
tokenCount = (Integer) fieldType().nullValue();

core/src/test/java/org/elasticsearch/index/mapper/TokenCountFieldMapperTests.java

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@
2424
import org.apache.lucene.analysis.MockTokenizer;
2525
import org.apache.lucene.analysis.Token;
2626
import org.apache.lucene.analysis.TokenStream;
27+
import org.elasticsearch.common.bytes.BytesReference;
2728
import org.elasticsearch.common.compress.CompressedXContent;
2829
import org.elasticsearch.common.xcontent.XContentFactory;
30+
import org.elasticsearch.common.xcontent.XContentType;
2931
import org.elasticsearch.index.IndexService;
3032
import org.elasticsearch.plugins.Plugin;
3133
import org.elasticsearch.test.ESSingleNodeTestCase;
@@ -144,4 +146,55 @@ public void testEmptyName() throws IOException {
144146
);
145147
assertThat(e.getMessage(), containsString("name cannot be empty string"));
146148
}
149+
150+
public void testParseNullValue() throws Exception {
151+
DocumentMapper mapper = createIndexWithTokenCountField();
152+
ParseContext.Document doc = parseDocument(mapper, createDocument(null));
153+
assertNull(doc.getField("test.tc"));
154+
}
155+
156+
public void testParseEmptyValue() throws Exception {
157+
DocumentMapper mapper = createIndexWithTokenCountField();
158+
ParseContext.Document doc = parseDocument(mapper, createDocument(""));
159+
assertEquals(0, doc.getField("test.tc").numericValue());
160+
}
161+
162+
public void testParseNotNullValue() throws Exception {
163+
DocumentMapper mapper = createIndexWithTokenCountField();
164+
ParseContext.Document doc = parseDocument(mapper, createDocument("three tokens string"));
165+
assertEquals(3, doc.getField("test.tc").numericValue());
166+
}
167+
168+
private DocumentMapper createIndexWithTokenCountField() throws IOException {
169+
final String content = XContentFactory.jsonBuilder().startObject()
170+
.startObject("person")
171+
.startObject("properties")
172+
.startObject("test")
173+
.field("type", "text")
174+
.startObject("fields")
175+
.startObject("tc")
176+
.field("type", "token_count")
177+
.field("analyzer", "standard")
178+
.endObject()
179+
.endObject()
180+
.endObject()
181+
.endObject()
182+
.endObject().endObject().string();
183+
184+
return createIndex("test").mapperService().documentMapperParser().parse("person", new CompressedXContent(content));
185+
}
186+
187+
private SourceToParse createDocument(String fieldValue) throws Exception {
188+
BytesReference request = XContentFactory.jsonBuilder()
189+
.startObject()
190+
.field("test", fieldValue)
191+
.endObject().bytes();
192+
193+
return SourceToParse.source("test", "person", "1", request, XContentType.JSON);
194+
}
195+
196+
private ParseContext.Document parseDocument(DocumentMapper mapper, SourceToParse request) {
197+
return mapper.parse(request)
198+
.docs().stream().findFirst().orElseThrow(() -> new IllegalStateException("Test object not parsed"));
199+
}
147200
}

0 commit comments

Comments
 (0)