summaryrefslogtreecommitdiffstats
path: root/document
diff options
context:
space:
mode:
Diffstat (limited to 'document')
-rw-r--r--document/src/main/java/com/yahoo/document/json/readers/ArrayReader.java4
-rw-r--r--document/src/main/java/com/yahoo/document/json/readers/StructReader.java8
-rw-r--r--document/src/test/java/com/yahoo/document/json/JsonReaderTestCase.java52
-rw-r--r--document/src/vespa/document/annotation/annotation.h2
-rw-r--r--document/src/vespa/document/annotation/spannode.h2
-rw-r--r--document/src/vespa/document/annotation/spantree.h4
-rw-r--r--document/src/vespa/document/fieldvalue/structfieldvalue.h6
-rw-r--r--document/src/vespa/document/fieldvalue/tensorfieldvalue.h2
-rw-r--r--document/src/vespa/document/predicate/predicate.h2
-rw-r--r--document/src/vespa/document/predicate/predicate_builder.h2
-rw-r--r--document/src/vespa/document/predicate/predicate_slime_visitor.h2
-rw-r--r--document/src/vespa/document/repo/configbuilder.h2
-rw-r--r--document/src/vespa/document/repo/documenttyperepo.h2
-rw-r--r--document/src/vespa/document/serialization/annotationserializer.h2
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 {