diff options
Diffstat (limited to 'document')
14 files changed, 76 insertions, 16 deletions
diff --git a/document/src/main/java/com/yahoo/document/json/readers/ArrayReader.java b/document/src/main/java/com/yahoo/document/json/readers/ArrayReader.java index 779d706ac3c..824a3073515 100644 --- a/document/src/main/java/com/yahoo/document/json/readers/ArrayReader.java +++ b/document/src/main/java/com/yahoo/document/json/readers/ArrayReader.java @@ -1,6 +1,8 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.document.json.readers; +import com.fasterxml.jackson.core.JsonToken; +import com.google.common.base.Preconditions; import com.yahoo.document.DataType; import com.yahoo.document.datatypes.CollectionFieldValue; import com.yahoo.document.datatypes.FieldValue; @@ -14,6 +16,7 @@ import static com.yahoo.document.json.readers.SingleValueReader.readSingleValue; public class ArrayReader { public static void fillArrayUpdate(TokenBuffer buffer, int initNesting, DataType valueType, List<FieldValue> arrayContents) { while (buffer.nesting() >= initNesting) { + Preconditions.checkArgument(buffer.currentToken() != JsonToken.VALUE_NULL, "Illegal null value for array entry"); arrayContents.add(readSingleValue(buffer, valueType)); buffer.next(); } @@ -25,6 +28,7 @@ public class ArrayReader { expectArrayStart(buffer.currentToken()); buffer.next(); while (buffer.nesting() >= initNesting) { + Preconditions.checkArgument(buffer.currentToken() != JsonToken.VALUE_NULL, "Illegal null value for array entry"); parent.add(readSingleValue(buffer, valueType)); buffer.next(); } diff --git a/document/src/main/java/com/yahoo/document/json/readers/StructReader.java b/document/src/main/java/com/yahoo/document/json/readers/StructReader.java index 3d2d08842dc..cab55903b76 100644 --- a/document/src/main/java/com/yahoo/document/json/readers/StructReader.java +++ b/document/src/main/java/com/yahoo/document/json/readers/StructReader.java @@ -1,6 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.document.json.readers; +import com.fasterxml.jackson.core.JsonToken; import com.yahoo.document.Field; import com.yahoo.document.datatypes.FieldValue; import com.yahoo.document.datatypes.StructuredFieldValue; @@ -18,8 +19,11 @@ public class StructReader { while (buffer.nesting() >= initNesting) { Field f = getField(buffer, parent); try { - FieldValue v = readSingleValue(buffer, f.getDataType()); - parent.setFieldValue(f, v); + // skip fields set to null + if (buffer.currentToken() != JsonToken.VALUE_NULL) { + FieldValue v = readSingleValue(buffer, f.getDataType()); + parent.setFieldValue(f, v); + } buffer.next(); } catch (IllegalArgumentException e) { throw new JsonReaderException(f, e); diff --git a/document/src/test/java/com/yahoo/document/json/JsonReaderTestCase.java b/document/src/test/java/com/yahoo/document/json/JsonReaderTestCase.java index 9afebc16a3b..1ef671d90c0 100644 --- a/document/src/test/java/com/yahoo/document/json/JsonReaderTestCase.java +++ b/document/src/test/java/com/yahoo/document/json/JsonReaderTestCase.java @@ -167,6 +167,16 @@ public class JsonReaderTestCase { x.addField(new Field("integerfield", DataType.INT)); types.registerDocumentType(x); } + { + DocumentType x = new DocumentType("testnull"); + x.addField(new Field("intfield", DataType.INT)); + x.addField(new Field("stringfield", DataType.STRING)); + x.addField(new Field("arrayfield", new ArrayDataType(DataType.STRING))); + x.addField(new Field("weightedsetfield", new WeightedSetDataType(DataType.STRING, true, true))); + x.addField(new Field("mapfield", new MapDataType(DataType.STRING, DataType.STRING))); + x.addField(new Field("tensorfield", new TensorDataType(new TensorType.Builder().indexed("x").build()))); + types.registerDocumentType(x); + } } @After @@ -1166,6 +1176,48 @@ public class JsonReaderTestCase { } } + @Test + public void testNullValues() { + JsonReader r = createReader(inputJson("{ 'put': 'id:unittest:testnull::doc1',", + " 'fields': {", + " 'intfield': null,", + " 'stringfield': null,", + " 'arrayfield': null,", + " 'weightedsetfield': null,", + " 'mapfield': null,", + " 'tensorfield': null", + " }", + "}")); + DocumentPut put = (DocumentPut) r.readSingleDocument(DocumentParser.SupportedOperation.PUT, + "id:unittest:testnull::doc1"); + Document doc = put.getDocument(); + assertFieldValueNull(doc, "intfield"); + assertFieldValueNull(doc, "stringfield"); + assertFieldValueNull(doc, "arrayfield"); + assertFieldValueNull(doc, "weightedsetfield"); + assertFieldValueNull(doc, "mapfield"); + assertFieldValueNull(doc, "tensorfield"); + } + + @Test(expected=JsonReaderException.class) + public void testNullArrayElement() { + JsonReader r = createReader(inputJson("{ 'put': 'id:unittest:testnull::doc1',", + " 'fields': {", + " 'arrayfield': [ null ]", + " }", + "}")); + r.readSingleDocument(DocumentParser.SupportedOperation.PUT, "id:unittest:testnull::doc1"); + fail(); + } + + private void assertFieldValueNull(Document doc, String fieldName) { + Field field = doc.getField(fieldName); + assertNotNull(field); + FieldValue fieldValue = doc.getFieldValue(field); + assertNull(fieldValue); + } + + static ByteArrayInputStream jsonToInputStream(String json) { return new ByteArrayInputStream(Utf8.toBytes(json)); } diff --git a/document/src/vespa/document/annotation/annotation.h b/document/src/vespa/document/annotation/annotation.h index f0cb8088b1f..94ffe12eb85 100644 --- a/document/src/vespa/document/annotation/annotation.h +++ b/document/src/vespa/document/annotation/annotation.h @@ -7,7 +7,7 @@ #include <memory> namespace document { -class SpanNode; +struct SpanNode; class Annotation { const AnnotationType * _type; diff --git a/document/src/vespa/document/annotation/spannode.h b/document/src/vespa/document/annotation/spannode.h index 742b1534a33..0a5bbdcaab8 100644 --- a/document/src/vespa/document/annotation/spannode.h +++ b/document/src/vespa/document/annotation/spannode.h @@ -5,7 +5,7 @@ #include <vespa/vespalib/stllike/string.h> namespace document { -class SpanTreeVisitor; +struct SpanTreeVisitor; struct SpanNode { typedef std::unique_ptr<SpanNode> UP; diff --git a/document/src/vespa/document/annotation/spantree.h b/document/src/vespa/document/annotation/spantree.h index 4acd39b4793..d181d755fae 100644 --- a/document/src/vespa/document/annotation/spantree.h +++ b/document/src/vespa/document/annotation/spantree.h @@ -7,8 +7,8 @@ #include <cassert> namespace document { -class SpanNode; -class SpanTreeVisitor; +struct SpanNode; +struct SpanTreeVisitor; class SpanTree { typedef std::vector<Annotation> AnnotationVector; diff --git a/document/src/vespa/document/fieldvalue/structfieldvalue.h b/document/src/vespa/document/fieldvalue/structfieldvalue.h index 8025365be26..0a288aeb69d 100644 --- a/document/src/vespa/document/fieldvalue/structfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/structfieldvalue.h @@ -17,7 +17,7 @@ namespace document { class Document; class DocumentType; class DocumentTypeRepo; -class FieldValueWriter; +struct FieldValueWriter; class FixedTypeRepo; class FieldSet; class StructDataType; @@ -123,8 +123,8 @@ private: VESPA_DLL_LOCAL const StructDataType & getStructType() const; // Iterator implementation - class FieldIterator; - friend class FieldIterator; + struct FieldIterator; + friend struct FieldIterator; StructuredIterator::UP getIterator(const Field* toFind) const override; diff --git a/document/src/vespa/document/fieldvalue/tensorfieldvalue.h b/document/src/vespa/document/fieldvalue/tensorfieldvalue.h index 5c831601d1a..49088c587c6 100644 --- a/document/src/vespa/document/fieldvalue/tensorfieldvalue.h +++ b/document/src/vespa/document/fieldvalue/tensorfieldvalue.h @@ -4,7 +4,7 @@ #include "fieldvalue.h" -namespace vespalib { namespace tensor { class Tensor; } } +namespace vespalib { namespace tensor { struct Tensor; } } namespace document { diff --git a/document/src/vespa/document/predicate/predicate.h b/document/src/vespa/document/predicate/predicate.h index 97823a3ad2b..4c6351f5e4c 100644 --- a/document/src/vespa/document/predicate/predicate.h +++ b/document/src/vespa/document/predicate/predicate.h @@ -8,7 +8,7 @@ namespace vespalib { class Slime; -namespace slime { class Inspector; } +namespace slime { struct Inspector; } } // namespace vespalib namespace document { diff --git a/document/src/vespa/document/predicate/predicate_builder.h b/document/src/vespa/document/predicate/predicate_builder.h index 14cb9eb6496..3750e3aa615 100644 --- a/document/src/vespa/document/predicate/predicate_builder.h +++ b/document/src/vespa/document/predicate/predicate_builder.h @@ -7,7 +7,7 @@ #include <vector> namespace document { -class PredicateNode; +struct PredicateNode; class PredicateBuilder : private PredicateSlimeVisitor { std::vector<PredicateNode *>_nodes; diff --git a/document/src/vespa/document/predicate/predicate_slime_visitor.h b/document/src/vespa/document/predicate/predicate_slime_visitor.h index 5727a4d4269..394c72fe8dd 100644 --- a/document/src/vespa/document/predicate/predicate_slime_visitor.h +++ b/document/src/vespa/document/predicate/predicate_slime_visitor.h @@ -3,7 +3,7 @@ #pragma once namespace vespalib { -namespace slime { class Inspector; } +namespace slime { struct Inspector; } } // namespace vespalib namespace document { diff --git a/document/src/vespa/document/repo/configbuilder.h b/document/src/vespa/document/repo/configbuilder.h index c389fd3b09e..856ffaeda08 100644 --- a/document/src/vespa/document/repo/configbuilder.h +++ b/document/src/vespa/document/repo/configbuilder.h @@ -11,7 +11,7 @@ namespace document::config_builder { -class TypeOrId; +struct TypeOrId; struct DatatypeConfig : DocumenttypesConfig::Documenttype::Datatype { static int32_t id_counter; diff --git a/document/src/vespa/document/repo/documenttyperepo.h b/document/src/vespa/document/repo/documenttyperepo.h index 68e4087ca49..f0c59918a74 100644 --- a/document/src/vespa/document/repo/documenttyperepo.h +++ b/document/src/vespa/document/repo/documenttyperepo.h @@ -15,7 +15,7 @@ namespace internal { class AnnotationType; class DataType; -class DataTypeRepo; +struct DataTypeRepo; class DocumentType; class DocumentTypeRepo { diff --git a/document/src/vespa/document/serialization/annotationserializer.h b/document/src/vespa/document/serialization/annotationserializer.h index a84087ce6d1..d8cdd833939 100644 --- a/document/src/vespa/document/serialization/annotationserializer.h +++ b/document/src/vespa/document/serialization/annotationserializer.h @@ -13,7 +13,7 @@ class Annotation; class Span; class SpanList; class SimpleSpanList; -class SpanNode; +struct SpanNode; class SpanTree; class AnnotationSerializer : private SpanTreeVisitor { |