diff options
author | Tor Egge <Tor.Egge@broadpark.no> | 2019-03-06 18:14:03 +0100 |
---|---|---|
committer | Tor Egge <Tor.Egge@broadpark.no> | 2019-03-07 13:28:48 +0100 |
commit | 93c5cb44ba9f8fa36314b8a4d6d57b75422f8c29 (patch) | |
tree | 0aabf97b84256fe9c10d3d22de0b9ddcf73d9129 /searchcore | |
parent | 99bcfb517bd0b57c24f81478c3767f1b8d369fb3 (diff) |
Check for assignable tensor type when setting tensor in TensorFieldValue.
Diffstat (limited to 'searchcore')
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; |