summaryrefslogtreecommitdiffstats
path: root/searchcore
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@broadpark.no>2019-03-06 18:14:03 +0100
committerTor Egge <Tor.Egge@broadpark.no>2019-03-07 13:28:48 +0100
commit93c5cb44ba9f8fa36314b8a4d6d57b75422f8c29 (patch)
tree0aabf97b84256fe9c10d3d22de0b9ddcf73d9129 /searchcore
parent99bcfb517bd0b57c24f81478c3767f1b8d369fb3 (diff)
Check for assignable tensor type when setting tensor in TensorFieldValue.
Diffstat (limited to 'searchcore')
-rw-r--r--searchcore/src/tests/proton/attribute/attribute_test.cpp4
-rw-r--r--searchcore/src/tests/proton/docsummary/summaryfieldconverter_test.cpp8
-rw-r--r--searchcore/src/tests/proton/documentdb/feedhandler/feedhandler_test.cpp49
-rw-r--r--searchcore/src/vespa/searchcore/proton/persistenceengine/persistenceengine.cpp6
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp8
5 files changed, 69 insertions, 6 deletions
diff --git a/searchcore/src/tests/proton/attribute/attribute_test.cpp b/searchcore/src/tests/proton/attribute/attribute_test.cpp
index a643dda01c6..7b7d25d2d52 100644
--- a/searchcore/src/tests/proton/attribute/attribute_test.cpp
+++ b/searchcore/src/tests/proton/attribute/attribute_test.cpp
@@ -1,6 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <vespa/config-attributes.h>
+#include <vespa/document/datatype/tensor_data_type.h>
#include <vespa/document/fieldvalue/document.h>
#include <vespa/document/predicate/predicate_slime_builder.h>
#include <vespa/document/update/arithmeticvalueupdate.h>
@@ -683,7 +684,8 @@ TEST_F("require that attribute writer handles tensor assign update", Fixture)
DocumentUpdate upd(*builder.getDocumentTypeRepo(), dt, DocumentId("doc::1"));
auto new_tensor = createTensor({ {{{"x", "8"}, {"y", "9"}}, 11} },
{"x", "y"});
- TensorFieldValue new_value;
+ TensorDataType xySparseTensorDataType(vespalib::eval::ValueType::from_spec("tensor(x{},y{})"));
+ TensorFieldValue new_value(xySparseTensorDataType);
new_value = new_tensor->clone();
upd.addUpdate(FieldUpdate(upd.getType().getField("a1"))
.addUpdate(AssignValueUpdate(new_value)));
diff --git a/searchcore/src/tests/proton/docsummary/summaryfieldconverter_test.cpp b/searchcore/src/tests/proton/docsummary/summaryfieldconverter_test.cpp
index 73d071be96f..b82fec85d47 100644
--- a/searchcore/src/tests/proton/docsummary/summaryfieldconverter_test.cpp
+++ b/searchcore/src/tests/proton/docsummary/summaryfieldconverter_test.cpp
@@ -16,6 +16,7 @@
#include <vespa/document/datatype/urldatatype.h>
#include <vespa/document/datatype/weightedsetdatatype.h>
#include <vespa/document/datatype/referencedatatype.h>
+#include <vespa/document/datatype/tensor_data_type.h>
#include <vespa/document/fieldvalue/arrayfieldvalue.h>
#include <vespa/document/fieldvalue/bytefieldvalue.h>
#include <vespa/document/fieldvalue/document.h>
@@ -82,6 +83,7 @@ using document::SpanTree;
using document::StringFieldValue;
using document::StructDataType;
using document::StructFieldValue;
+using document::TensorDataType;
using document::TensorFieldValue;
using document::UrlDataType;
using document::WeightedSetDataType;
@@ -92,6 +94,7 @@ using search::linguistics::TERM;
using vespa::config::search::SummarymapConfig;
using vespa::config::search::SummarymapConfigBuilder;
using vespalib::Slime;
+using vespalib::eval::ValueType;
using vespalib::geo::ZCurve;
using vespalib::slime::Cursor;
using vespalib::string;
@@ -230,7 +233,7 @@ DocumenttypesConfig getDocumenttypesConfig() {
.addField("float", DataType::T_FLOAT)
.addField("chinese", DataType::T_STRING)
.addField("predicate", DataType::T_PREDICATE)
- .addField("tensor", DataType::T_TENSOR)
+ .addTensorField("tensor", "tensor(x{},y{})")
.addField("ref", ref_type_id)
.addField("nested", Struct("indexingdocument.header.nested")
.addField("inner_ref", ref_type_id)),
@@ -683,7 +686,8 @@ createTensor(const TensorCells &cells, const TensorDimensions &dimensions) {
void
Test::requireThatTensorIsNotConverted()
{
- TensorFieldValue tensorFieldValue;
+ TensorDataType tensorDataType(ValueType::from_spec("tensor(x{},y{})"));
+ TensorFieldValue tensorFieldValue(tensorDataType);
tensorFieldValue = createTensor({ {{{"x", "4"}, {"y", "5"}}, 7} },
{"x", "y"});
Document doc(getDocType(), DocumentId("doc:scheme:"));
diff --git a/searchcore/src/tests/proton/documentdb/feedhandler/feedhandler_test.cpp b/searchcore/src/tests/proton/documentdb/feedhandler/feedhandler_test.cpp
index a1bce7174bf..b17f13eaea0 100644
--- a/searchcore/src/tests/proton/documentdb/feedhandler/feedhandler_test.cpp
+++ b/searchcore/src/tests/proton/documentdb/feedhandler/feedhandler_test.cpp
@@ -1,9 +1,13 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <vespa/persistence/spi/result.h>
+#include <vespa/document/base/exceptions.h>
+#include <vespa/document/datatype/tensor_data_type.h>
#include <vespa/document/update/assignvalueupdate.h>
#include <vespa/document/repo/documenttyperepo.h>
#include <vespa/document/update/documentupdate.h>
+#include <vespa/eval/tensor/tensor.h>
+#include <vespa/eval/tensor/test/test_utils.h>
#include <vespa/searchcore/proton/bucketdb/bucketdbhandler.h>
#include <vespa/searchcore/proton/test/bucketfactory.h>
#include <vespa/searchcore/proton/common/feedtoken.h>
@@ -42,6 +46,8 @@ using document::DocumentType;
using document::DocumentTypeRepo;
using document::DocumentUpdate;
using document::GlobalId;
+using document::TensorDataType;
+using document::TensorFieldValue;
using search::IDestructorCallback;
using search::SerialNum;
using search::index::schema::CollectionType;
@@ -58,6 +64,10 @@ using vespalib::ThreadStackExecutor;
using vespalib::ThreadStackExecutorBase;
using vespalib::makeClosure;
using vespalib::makeTask;
+using vespalib::eval::TensorSpec;
+using vespalib::eval::ValueType;
+using vespalib::tensor::test::makeTensor;
+using vespalib::tensor::Tensor;
using namespace proton;
using namespace search::index;
@@ -281,6 +291,8 @@ SchemaContext::SchemaContext()
: schema(new Schema()),
builder()
{
+ schema->addAttributeField(Schema::AttributeField("tensor", DataType::TENSOR, CollectionType::SINGLE));
+ schema->addAttributeField(Schema::AttributeField("tensor2", DataType::TENSOR, CollectionType::SINGLE));
addField("i1");
}
@@ -312,6 +324,8 @@ struct TwoFieldsSchemaContext : public SchemaContext {
}
};
+TensorDataType tensor1DType(ValueType::from_spec("tensor(x{})"));
+
struct UpdateContext {
DocumentUpdate::SP update;
BucketId bucketId;
@@ -324,7 +338,19 @@ struct UpdateContext {
const auto &docType = update->getType();
const auto &field = docType.getField(fieldName);
auto fieldValue = field.createValue();
- fieldValue->assign(document::StringFieldValue("new value"));
+ if (fieldName == "tensor") {
+ dynamic_cast<TensorFieldValue &>(*fieldValue) =
+ makeTensor<Tensor>(TensorSpec("tensor(x{},y{})").
+ add({{"x","8"},{"y","9"}}, 11));
+ } else if (fieldName == "tensor2") {
+ auto tensorFieldValue = std::make_unique<TensorFieldValue>(tensor1DType);
+ *tensorFieldValue =
+ makeTensor<Tensor>(TensorSpec("tensor(x{})").
+ add({{"x","8"}}, 11));
+ fieldValue = std::move(tensorFieldValue);
+ } else {
+ fieldValue->assign(document::StringFieldValue("new value"));
+ }
document::AssignValueUpdate assignValueUpdate(*fieldValue);
document::FieldUpdate fieldUpdate(field);
fieldUpdate.addUpdate(assignValueUpdate);
@@ -711,8 +737,13 @@ checkUpdate(FeedHandlerFixture &f, SchemaContext &schemaContext,
if (expectReject) {
TEST_DO(f.feedView.checkCounts(0, 0u, 0, 0u));
EXPECT_EQUAL(Result::TRANSIENT_ERROR, token.getResult()->getErrorCode());
- EXPECT_EQUAL("Update operation rejected for document 'id:test:searchdocument::foo' of type 'searchdocument': 'Field not found'",
- token.getResult()->getErrorMessage());
+ if (fieldName == "tensor2") {
+ EXPECT_EQUAL("Update operation rejected for document 'id:test:searchdocument::foo' of type 'searchdocument': 'Wrong tensor type: Field tensor type is 'tensor(x{},y{})' but tensor type is 'tensor(x{})''",
+ token.getResult()->getErrorMessage());
+ } else {
+ EXPECT_EQUAL("Update operation rejected for document 'id:test:searchdocument::foo' of type 'searchdocument': 'Field not found'",
+ token.getResult()->getErrorMessage());
+ }
} else {
if (existing) {
TEST_DO(f.feedView.checkCounts(1, 16u, 0, 0u));
@@ -758,6 +789,18 @@ TEST_F("require that update with different document type repo can be rejected, p
checkUpdate(f, schema, "i2", true, false);
}
+TEST_F("require that tensor update with correct tensor type works", FeedHandlerFixture)
+{
+ TwoFieldsSchemaContext schema;
+ checkUpdate(f, schema, "tensor", false, true);
+}
+
+TEST_F("require that tensor update with wrong tensor type fails", FeedHandlerFixture)
+{
+ TwoFieldsSchemaContext schema;
+ checkUpdate(f, schema, "tensor2", true, true);
+}
+
TEST_F("require that put with different document type repo is ok", FeedHandlerFixture)
{
TwoFieldsSchemaContext schema;
diff --git a/searchcore/src/vespa/searchcore/proton/persistenceengine/persistenceengine.cpp b/searchcore/src/vespa/searchcore/proton/persistenceengine/persistenceengine.cpp
index 42790254e53..dc95f3ddc04 100644
--- a/searchcore/src/vespa/searchcore/proton/persistenceengine/persistenceengine.cpp
+++ b/searchcore/src/vespa/searchcore/proton/persistenceengine/persistenceengine.cpp
@@ -394,6 +394,12 @@ PersistenceEngine::update(const Bucket& b, Timestamp t, const DocumentUpdate::SP
make_string("Update operation rejected for document '%s' of type '%s'.",
upd->getId().toString().c_str(), e.getDocumentTypeName().c_str()));
+ } catch (document::WrongTensorTypeException &e) {
+ return UpdateResult(Result::TRANSIENT_ERROR,
+ make_string("Update operation rejected for document '%s' of type '%s': 'Wrong tensor type: %s'",
+ upd->getId().toString().c_str(),
+ upd->getType().getName().c_str(),
+ e.getMessage().c_str()));
}
std::shared_lock<std::shared_timed_mutex> rguard(_rwMutex);
DocTypeName docType(upd->getType());
diff --git a/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp b/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp
index a0d62f2052d..fd38b74f584 100644
--- a/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp
@@ -539,6 +539,14 @@ FeedHandler::considerUpdateOperationForRejection(FeedToken &token, UpdateOperati
token->setResult(make_unique<UpdateResult>(Result::TRANSIENT_ERROR, message), false);
token->fail();
return true;
+ } catch (document::WrongTensorTypeException &e) {
+ auto message = make_string("Update operation rejected for document '%s' of type '%s': 'Wrong tensor type: %s'",
+ update.getId().toString().c_str(),
+ _docTypeName.toString().c_str(),
+ e.getMessage().c_str());
+ token->setResult(make_unique<UpdateResult>(Result::TRANSIENT_ERROR, message), false);
+ token->fail();
+ return true;
}
}
return false;