diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2017-07-26 14:41:32 +0200 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2017-07-31 17:04:18 +0200 |
commit | 5f54fb77ef1e354f9919e92da7b22cbe68ee7fbd (patch) | |
tree | 87d3c5526a04e2b4e91f8eff5d8ed50d87d468a9 /document | |
parent | 50a275ebd8774a958418bbda4d127df1f420f1ad (diff) |
Unify error handling to using exceptions only, not in combination with nullptr.
Diffstat (limited to 'document')
26 files changed, 137 insertions, 202 deletions
diff --git a/document/src/tests/datatype/referencedatatype_test.cpp b/document/src/tests/datatype/referencedatatype_test.cpp index 496295275fe..104a3c03135 100644 --- a/document/src/tests/datatype/referencedatatype_test.cpp +++ b/document/src/tests/datatype/referencedatatype_test.cpp @@ -56,16 +56,16 @@ TEST_F("print() emits type name and id", Fixture) { } TEST_F("buildFieldPath returns empty path for empty input", Fixture) { - auto fp = f.refType.buildFieldPath(""); - ASSERT_TRUE(fp.get() != nullptr); - EXPECT_TRUE(fp->empty()); + FieldPath fp; + f.refType.buildFieldPath(fp, ""); + EXPECT_TRUE(fp.empty()); } TEST_F("buildFieldPath throws IllegalArgumentException for non-empty input", Fixture) { - EXPECT_EXCEPTION(f.refType.buildFieldPath("herebedragons"), + FieldPath fp; + EXPECT_EXCEPTION(f.refType.buildFieldPath(fp, "herebedragons"), vespalib::IllegalArgumentException, - "Reference data type does not support further field " - "recursion: 'herebedragons'"); + "Reference data type does not support further field recursion: 'herebedragons'"); } TEST_MAIN() { TEST_RUN_ALL(); } diff --git a/document/src/tests/documenttestcase.cpp b/document/src/tests/documenttestcase.cpp index 4a93d45831d..643dc03018c 100644 --- a/document/src/tests/documenttestcase.cpp +++ b/document/src/tests/documenttestcase.cpp @@ -84,8 +84,6 @@ void DocumentTest::testSizeOf() void DocumentTest::testFieldPath() { - FieldPathEntry empty; - empty.asString(); const vespalib::string testValues[] = { "{}", "", "", "{}r", "", "r", "{{}}", "{", "}", @@ -234,8 +232,9 @@ DocumentTest::testVariables() { VariableIteratorHandler handler; - FieldPath::UP path = type.buildFieldPath("iiiarray[$x][$y][$z]"); - doc.iterateNested(path->getFullRange(), handler); + FieldPath path; + type.buildFieldPath(path, "iiiarray[$x][$y][$z]"); + doc.iterateNested(path.getFullRange(), handler); std::string fasit = "x: 0,y: 0,z: 0, - 1\n" @@ -390,9 +389,9 @@ DocumentTest::testModifyDocument() ModifyIteratorHandler handler; - FieldPath::UP path - = doc->getDataType()->buildFieldPath("l1s1.structmap.value.smap{leonardo}"); - doc->iterateNested(path->getFullRange(), handler); + FieldPath path; + doc->getDataType()->buildFieldPath(path, "l1s1.structmap.value.smap{leonardo}"); + doc->iterateNested(path.getFullRange(), handler); doc->print(std::cerr, true, ""); } diff --git a/document/src/tests/fieldpathupdatetestcase.cpp b/document/src/tests/fieldpathupdatetestcase.cpp index e37b8c4f2b9..a8c0f547a69 100644 --- a/document/src/tests/fieldpathupdatetestcase.cpp +++ b/document/src/tests/fieldpathupdatetestcase.cpp @@ -1,21 +1,19 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include <vespa/document/base/testdocman.h> -#include <vespa/document/fieldvalue/fieldvalues.h> #include <vespa/document/fieldvalue/iteratorhandler.h> #include <vespa/document/select/node.h> +#include <vespa/document/base/exceptions.h> + #include <vespa/vespalib/io/fileutil.h> #include <vespa/vdstestlib/cppunit/macros.h> #include <vespa/document/update/fieldpathupdates.h> #include <vespa/document/update/documentupdate.h> #include <vespa/document/repo/configbuilder.h> -#include <vespa/vespalib/objects/identifiable.h> #include <vespa/vespalib/testkit/testapp.h> #include <vespa/document/serialization/vespadocumentserializer.h> #include <vespa/vespalib/objects/nbostream.h> -#include <vespa/vespalib/util/exceptions.h> -#include <fstream> -#include <sstream> + using vespalib::Identifiable; using namespace document::config_builder; @@ -608,7 +606,7 @@ FieldPathUpdateTestCase::testApplyAssignFieldNotExistingInPath() new AssignFieldPathUpdate(*_repo, *doc->getDataType(), "nosuchnum", "", "foobar.num + $value"))); CPPUNIT_ASSERT(false); - } catch (const vespalib::IllegalArgumentException&) { + } catch (const FieldNotFoundException&) { } } diff --git a/document/src/vespa/document/base/fieldpath.cpp b/document/src/vespa/document/base/fieldpath.cpp index c7aa55caab4..2af7a6315f7 100644 --- a/document/src/vespa/document/base/fieldpath.cpp +++ b/document/src/vespa/document/base/fieldpath.cpp @@ -14,8 +14,8 @@ using vespalib::make_string; namespace document { -IMPLEMENT_IDENTIFIABLE_NS(document, FieldPathEntry, vespalib::Identifiable) - +FieldPathEntry::FieldPathEntry(const FieldPathEntry &) = default; +FieldPathEntry & FieldPathEntry::operator=(const FieldPathEntry & ) = default; FieldPathEntry::~FieldPathEntry() { } FieldPathEntry::FieldPathEntry() : @@ -174,30 +174,19 @@ FieldPath::FieldPath() : _path() { } -FieldPath::FieldPath(const FieldPath& other) - : _path(other._path) -{ } - +FieldPath::FieldPath(const FieldPath &) = default; +FieldPath & FieldPath::operator=(const FieldPath &) = default; FieldPath::~FieldPath() { } -FieldPath& -FieldPath::operator=(const FieldPath& rhs) -{ - if (&rhs != this) { - _path = rhs._path; - } - return *this; -} - FieldPath::iterator -FieldPath::insert(iterator pos, const FieldPathEntry& entry) +FieldPath::insert(iterator pos, FieldPathEntry && entry) { - return _path.insert(pos, entry); + return _path.insert(pos, std::move(entry)); } void -FieldPath::push_back(const FieldPathEntry& entry) +FieldPath::push_back(FieldPathEntry && entry) { - _path.push_back(entry); + _path.push_back(std::move(entry)); } void @@ -215,8 +204,9 @@ FieldPath::clear() void FieldPath::visitMembers(vespalib::ObjectVisitor& visitor) const { + (void) visitor; for (uint32_t i = 0; i < _path.size(); ++i) { - visit(visitor, vespalib::make_string("[%u]", i), _path[i]); +// visit(visitor, vespalib::make_string("[%u]", i), _path[i]); } } diff --git a/document/src/vespa/document/base/fieldpath.h b/document/src/vespa/document/base/fieldpath.h index 822c6971435..22fa1979427 100644 --- a/document/src/vespa/document/base/fieldpath.h +++ b/document/src/vespa/document/base/fieldpath.h @@ -17,9 +17,8 @@ class MapDataType; class WeightedSetDataType; class ArrayDataType; -class FieldPathEntry : public vespalib::Identifiable { +class FieldPathEntry { public: - DECLARE_IDENTIFIABLE_NS(document, FieldPathEntry); enum Type { STRUCT_FIELD, ARRAY_INDEX, @@ -36,6 +35,11 @@ public: */ FieldPathEntry(); + FieldPathEntry(FieldPathEntry &&) = default; + FieldPathEntry & operator=(FieldPathEntry &&) = default; + FieldPathEntry(const FieldPathEntry &); + FieldPathEntry & operator=(const FieldPathEntry &); + /** Creates a field path entry for a struct field lookup. */ @@ -80,7 +84,7 @@ public: FieldValue * getFieldValueToSetPtr() const { return _fillInVal.get(); } FieldValue & getFieldValueToSet() const { return *_fillInVal; } std::unique_ptr<FieldValue> stealFieldValueToSet() const; - void visitMembers(vespalib::ObjectVisitor &visitor) const override; + void visitMembers(vespalib::ObjectVisitor &visitor) const; /** * Parses a string of the format {["]escaped string["]} to its unescaped value. * @param key is the incoming value, and contains what is left when done. @@ -113,10 +117,10 @@ public: typedef std::unique_ptr<FieldPath> UP; FieldPath(); - FieldPath(const FieldPath& other); - FieldPath& operator=(const FieldPath& rhs); - FieldPath(FieldPath && other) noexcept = default; - FieldPath& operator=(FieldPath && rhs) noexcept = default; + FieldPath(const FieldPath &); + FieldPath & operator=(const FieldPath &); + FieldPath(FieldPath &&) = default; + FieldPath & operator=(FieldPath &&) = default; ~FieldPath(); template <typename InputIterator> @@ -124,10 +128,8 @@ public: : _path(first, last) { } - FieldPath * clone() const { return new FieldPath(*this); } - - iterator insert(iterator pos, const FieldPathEntry& entry); - void push_back(const FieldPathEntry& entry); + iterator insert(iterator pos, FieldPathEntry && entry); + void push_back(FieldPathEntry && entry); iterator begin() { return _path.begin(); } iterator end() { return _path.end(); } @@ -148,13 +150,9 @@ public: Container::size_type size() const { return _path.size(); } bool empty() const { return _path.empty(); } - reference operator[](Container::size_type i) { - return _path[i]; - } + reference operator[](Container::size_type i) { return _path[i]; } - const_reference operator[](Container::size_type i) const { - return _path[i]; - } + const_reference operator[](Container::size_type i) const { return _path[i]; } void visitMembers(vespalib::ObjectVisitor &visitor) const; diff --git a/document/src/vespa/document/datatype/annotationreferencedatatype.cpp b/document/src/vespa/document/datatype/annotationreferencedatatype.cpp index 1d64e85f619..9a787f943a5 100644 --- a/document/src/vespa/document/datatype/annotationreferencedatatype.cpp +++ b/document/src/vespa/document/datatype/annotationreferencedatatype.cpp @@ -37,9 +37,7 @@ unique_ptr<FieldValue> AnnotationReferenceDataType::createFieldValue() const { return FieldValue::UP(new AnnotationReferenceFieldValue(*this, 0)); } -unique_ptr<FieldPath> AnnotationReferenceDataType::onBuildFieldPath( const vespalib::stringref &) const { - return unique_ptr<FieldPath>(new FieldPath); -} +void AnnotationReferenceDataType::onBuildFieldPath(FieldPath &, const vespalib::stringref &) const { } } // namespace document diff --git a/document/src/vespa/document/datatype/annotationreferencedatatype.h b/document/src/vespa/document/datatype/annotationreferencedatatype.h index bbbc03e904f..424d1e19736 100644 --- a/document/src/vespa/document/datatype/annotationreferencedatatype.h +++ b/document/src/vespa/document/datatype/annotationreferencedatatype.h @@ -20,10 +20,9 @@ public: void print(std::ostream &out, bool verbose, const std::string &indent) const override; AnnotationReferenceDataType *clone() const override; std::unique_ptr<FieldValue> createFieldValue() const override; - FieldPath::UP onBuildFieldPath(const vespalib::stringref &remainFieldName) const override; + void onBuildFieldPath(FieldPath & path, const vespalib::stringref &remainFieldName) const override; DECLARE_IDENTIFIABLE(AnnotationReferenceDataType); }; } // namespace document - diff --git a/document/src/vespa/document/datatype/arraydatatype.cpp b/document/src/vespa/document/datatype/arraydatatype.cpp index 58c37b96d65..8a4b39ecbff 100644 --- a/document/src/vespa/document/datatype/arraydatatype.cpp +++ b/document/src/vespa/document/datatype/arraydatatype.cpp @@ -42,8 +42,8 @@ ArrayDataType::operator==(const DataType& other) const return other.inherits(ArrayDataType::classId); } -FieldPath::UP -ArrayDataType::onBuildFieldPath(const vespalib::stringref & remainFieldName) const +void +ArrayDataType::onBuildFieldPath(FieldPath & path, const vespalib::stringref & remainFieldName) const { if (remainFieldName[0] == '[') { size_t endPos = remainFieldName.find(']'); @@ -55,21 +55,17 @@ ArrayDataType::onBuildFieldPath(const vespalib::stringref & remainFieldName) con pos++; } - FieldPath::UP path = getNestedType().buildFieldPath(remainFieldName.substr(pos)); - if (!path.get()) { - return FieldPath::UP(); - } + getNestedType().buildFieldPath(path, remainFieldName.substr(pos)); + if (remainFieldName[1] == '$') { - path->insert(path->begin(), FieldPathEntry(getNestedType(), remainFieldName.substr(2, endPos - 2))); + path.insert(path.begin(), FieldPathEntry(getNestedType(), remainFieldName.substr(2, endPos - 2))); } else { - path->insert(path->begin(), FieldPathEntry(getNestedType(), atoi(remainFieldName.substr(1, endPos - 1).c_str()))); + path.insert(path.begin(), FieldPathEntry(getNestedType(), atoi(remainFieldName.substr(1, endPos - 1).c_str()))); } - - return path; } + } else { + getNestedType().buildFieldPath(path, remainFieldName); } - - return getNestedType().buildFieldPath(remainFieldName); } } // document diff --git a/document/src/vespa/document/datatype/arraydatatype.h b/document/src/vespa/document/datatype/arraydatatype.h index ab0c7206b6c..6be50302c3d 100644 --- a/document/src/vespa/document/datatype/arraydatatype.h +++ b/document/src/vespa/document/datatype/arraydatatype.h @@ -27,7 +27,7 @@ public: void print(std::ostream&, bool verbose, const std::string& indent) const override; bool operator==(const DataType& other) const override; ArrayDataType* clone() const override { return new ArrayDataType(*this); } - FieldPath::UP onBuildFieldPath(const vespalib::stringref & remainFieldName) const override; + void onBuildFieldPath(FieldPath & path, const vespalib::stringref & remainFieldName) const override; DECLARE_IDENTIFIABLE(ArrayDataType); }; diff --git a/document/src/vespa/document/datatype/datatype.cpp b/document/src/vespa/document/datatype/datatype.cpp index 4d29f870431..ede084f8962 100644 --- a/document/src/vespa/document/datatype/datatype.cpp +++ b/document/src/vespa/document/datatype/datatype.cpp @@ -170,13 +170,12 @@ DataType::operator<(const DataType& other) const return (_dataTypeId < other._dataTypeId); } -FieldPath::UP -DataType::buildFieldPath(const vespalib::stringref & remainFieldName) const +void +DataType::buildFieldPath(FieldPath & path, const vespalib::stringref & remainFieldName) const { if ( !remainFieldName.empty() ) { - return onBuildFieldPath(remainFieldName); + onBuildFieldPath(path,remainFieldName); } - return FieldPath::UP(new FieldPath()); } } // document diff --git a/document/src/vespa/document/datatype/datatype.h b/document/src/vespa/document/datatype/datatype.h index 61927ed1ae8..11c321f29e6 100644 --- a/document/src/vespa/document/datatype/datatype.h +++ b/document/src/vespa/document/datatype/datatype.h @@ -129,12 +129,11 @@ public: * @param remainFieldName. The remaining part of the fieldname that you want the path of. * @return pointer to field path or null if an error occured */ - FieldPath::UP buildFieldPath( - const vespalib::stringref & remainFieldName) const; + void buildFieldPath(FieldPath & fieldPath, const vespalib::stringref & remainFieldName) const; DECLARE_IDENTIFIABLE_ABSTRACT(DataType); private: - virtual FieldPath::UP onBuildFieldPath( const vespalib::stringref & remainFieldName) const = 0; + virtual void onBuildFieldPath(FieldPath & fieldPath, const vespalib::stringref & remainFieldName) const = 0; }; } // document diff --git a/document/src/vespa/document/datatype/documenttype.cpp b/document/src/vespa/document/datatype/documenttype.cpp index 952ad7a25d5..61bfba3b028 100644 --- a/document/src/vespa/document/datatype/documenttype.cpp +++ b/document/src/vespa/document/datatype/documenttype.cpp @@ -6,6 +6,7 @@ #include <vespa/vespalib/util/stringfmt.h> #include <iomanip> #include <vespa/log/log.h> +#include <vespa/document/base/exceptions.h> LOG_SETUP(".document.datatype.document"); @@ -76,8 +77,10 @@ DocumentType::addFieldSet(const vespalib::string & name, const FieldSet::Fields { for (FieldSet::Fields::const_iterator it(fields.begin()), mt(fields.end()); it != mt; it++) { if ( ! _fields->hasField(*it) ) { - FieldPath::UP fieldPath = _fields->buildFieldPath(*it); - if (fieldPath.get() == nullptr) { + FieldPath fieldPath; + try { + _fields->buildFieldPath(fieldPath, *it); + } catch (FieldNotFoundException & e) { throw IllegalArgumentException("Fieldset '" + name + "': No field with name '" + *it + "' in document type '" + getName() + "'.", VESPA_STRLOC); } diff --git a/document/src/vespa/document/datatype/mapdatatype.cpp b/document/src/vespa/document/datatype/mapdatatype.cpp index a11ea085931..2d77a6b3eef 100644 --- a/document/src/vespa/document/datatype/mapdatatype.cpp +++ b/document/src/vespa/document/datatype/mapdatatype.cpp @@ -55,66 +55,51 @@ MapDataType::operator==(const DataType& other) const return (*_keyType == *w->_keyType) && (*_valueType == *w->_valueType); } -FieldPath::UP -MapDataType::buildFieldPathImpl(const DataType &dataType, +void +MapDataType::buildFieldPathImpl(FieldPath & path, const DataType &dataType, const vespalib::stringref &remainFieldName, - const DataType &keyType, - const DataType &valueType) + const DataType &keyType, const DataType &valueType) { if (!remainFieldName.empty() && remainFieldName[0] == '{') { vespalib::string rest = remainFieldName; vespalib::string keyValue = FieldPathEntry::parseKey(rest); - FieldPath::UP path = valueType.buildFieldPath((rest[0] == '.') ? rest.substr(1) : rest); - if (!path) { - return FieldPath::UP(); - } + valueType.buildFieldPath(path, (rest[0] == '.') ? rest.substr(1) : rest); if (remainFieldName[1] == '$') { - path->insert(path->begin(), FieldPathEntry(valueType, keyValue.substr(1))); + path.insert(path.begin(), FieldPathEntry(valueType, keyValue.substr(1))); } else { FieldValue::UP fv = keyType.createFieldValue(); *fv = keyValue; - path->insert(path->begin(), - FieldPathEntry(valueType, dataType, - vespalib::CloneablePtr<FieldValue>(fv.release()))); + path.insert(path.begin(), FieldPathEntry(valueType, dataType, vespalib::CloneablePtr<FieldValue>(fv.release()))); } - - return path; } else if (memcmp(remainFieldName.c_str(), "key", 3) == 0) { size_t endPos = 3; if (remainFieldName[endPos] == '.') { endPos++; } - FieldPath::UP path = keyType.buildFieldPath(remainFieldName.substr(endPos)); - if (!path) { - return FieldPath::UP(); - } - path->insert(path->begin(), FieldPathEntry(dataType, keyType, valueType, true, false)); - return path; + keyType.buildFieldPath(path, remainFieldName.substr(endPos)); + + path.insert(path.begin(), FieldPathEntry(dataType, keyType, valueType, true, false)); } else if (memcmp(remainFieldName.c_str(), "value", 5) == 0) { size_t endPos = 5; if (remainFieldName[endPos] == '.') { endPos++; } - FieldPath::UP path = valueType.buildFieldPath(remainFieldName.substr(endPos)); - if (!path) { - return FieldPath::UP(); - } - path->insert(path->begin(), FieldPathEntry(dataType, keyType, valueType, false, true)); - return path; - } + valueType.buildFieldPath(path, remainFieldName.substr(endPos)); - return keyType.buildFieldPath(remainFieldName); + path.insert(path.begin(), FieldPathEntry(dataType, keyType, valueType, false, true)); + } else { + keyType.buildFieldPath(path, remainFieldName); + } } -FieldPath::UP -MapDataType::onBuildFieldPath(const vespalib::stringref &remainFieldName) const +void +MapDataType::onBuildFieldPath(FieldPath & fieldPath, const vespalib::stringref &remainFieldName) const { - return buildFieldPathImpl(*this, remainFieldName, - getKeyType(), getValueType()); + buildFieldPathImpl(fieldPath, *this, remainFieldName, getKeyType(), getValueType()); } } // namespace document diff --git a/document/src/vespa/document/datatype/mapdatatype.h b/document/src/vespa/document/datatype/mapdatatype.h index e575ff3195e..9e7a32e29c0 100644 --- a/document/src/vespa/document/datatype/mapdatatype.h +++ b/document/src/vespa/document/datatype/mapdatatype.h @@ -28,16 +28,12 @@ public: bool operator==(const DataType& other) const override; MapDataType* clone() const override { return new MapDataType(*this); } - FieldPath::UP onBuildFieldPath( - const vespalib::stringref &remainFieldName) const override; - static FieldPath::UP buildFieldPathImpl( - const DataType& dataType, - const vespalib::stringref &remainFieldName, - const DataType &keyType, - const DataType &valueType); + void onBuildFieldPath(FieldPath & path, const vespalib::stringref &remainFieldName) const override; + static void buildFieldPathImpl(FieldPath & path, const DataType& dataType, + const vespalib::stringref &remainFieldName, + const DataType &keyType, const DataType &valueType); DECLARE_IDENTIFIABLE(MapDataType); }; } // document - diff --git a/document/src/vespa/document/datatype/primitivedatatype.cpp b/document/src/vespa/document/datatype/primitivedatatype.cpp index cc3909f0099..fef0e532e44 100644 --- a/document/src/vespa/document/datatype/primitivedatatype.cpp +++ b/document/src/vespa/document/datatype/primitivedatatype.cpp @@ -71,23 +71,20 @@ PrimitiveDataType::createFieldValue() const } void -PrimitiveDataType::print(std::ostream& out, bool verbose, - const std::string& indent) const +PrimitiveDataType::print(std::ostream& out, bool verbose, const std::string& indent) const { (void) verbose; (void) indent; out << "PrimitiveDataType(" << getName() << ", id " << getId() << ")"; } -FieldPath::UP -PrimitiveDataType::onBuildFieldPath(const vespalib::stringref & rest) const +void +PrimitiveDataType::onBuildFieldPath(FieldPath &, const vespalib::stringref & rest) const { - if (rest.length()) { + if ( ! rest.empty()) { std::ostringstream ost; ost << "Datatype " << *this << " does not support further recursive structure: " << rest; throw vespalib::IllegalArgumentException(ost.str()); } - - return FieldPath::UP(new FieldPath()); } diff --git a/document/src/vespa/document/datatype/primitivedatatype.h b/document/src/vespa/document/datatype/primitivedatatype.h index 37dec78d616..0d7e5c0c826 100644 --- a/document/src/vespa/document/datatype/primitivedatatype.h +++ b/document/src/vespa/document/datatype/primitivedatatype.h @@ -20,7 +20,7 @@ namespace document { class PrimitiveDataType : public DataType { - FieldPath::UP onBuildFieldPath(const vespalib::stringref & remainFieldName) const override; + void onBuildFieldPath(FieldPath & path, const vespalib::stringref & remainFieldName) const override; public: PrimitiveDataType(Type _type); diff --git a/document/src/vespa/document/datatype/referencedatatype.cpp b/document/src/vespa/document/datatype/referencedatatype.cpp index 7587b0c5610..d02793edd3a 100644 --- a/document/src/vespa/document/datatype/referencedatatype.cpp +++ b/document/src/vespa/document/datatype/referencedatatype.cpp @@ -3,8 +3,9 @@ #include "referencedatatype.h" #include <vespa/document/fieldvalue/referencefieldvalue.h> #include <vespa/vespalib/util/exceptions.h> -#include <vespa/vespalib/util/stringfmt.h> -#include <ostream> + +using vespalib::make_string; +using vespalib::IllegalArgumentException; namespace document { @@ -32,15 +33,12 @@ ReferenceDataType* ReferenceDataType::clone() const { return new ReferenceDataType(_targetDocType, getId()); } -std::unique_ptr<FieldPath> ReferenceDataType::onBuildFieldPath( - const vespalib::stringref& remainingFieldName) const { - if (!remainingFieldName.empty()) { - throw vespalib::IllegalArgumentException( - vespalib::make_string("Reference data type does not support " - "further field recursion: '%s'", - remainingFieldName.c_str()), VESPA_STRLOC); +void ReferenceDataType::onBuildFieldPath(FieldPath &, const vespalib::stringref& remainingFieldName) const { + if ( ! remainingFieldName.empty() ) { + throw IllegalArgumentException(make_string("Reference data type does not support further field recursion: '%s'", + remainingFieldName.c_str()), VESPA_STRLOC); } - return std::make_unique<FieldPath>(); + } } // document diff --git a/document/src/vespa/document/datatype/referencedatatype.h b/document/src/vespa/document/datatype/referencedatatype.h index 52f896024de..f3e385c1614 100644 --- a/document/src/vespa/document/datatype/referencedatatype.h +++ b/document/src/vespa/document/datatype/referencedatatype.h @@ -23,8 +23,7 @@ public: std::unique_ptr<FieldValue> createFieldValue() const override; void print(std::ostream&, bool verbose, const std::string& indent) const override; ReferenceDataType* clone() const override; - std::unique_ptr<FieldPath> onBuildFieldPath( - const vespalib::stringref& remainingFieldName) const override; + void onBuildFieldPath(FieldPath & path, const vespalib::stringref& remainingFieldName) const override; }; } // document diff --git a/document/src/vespa/document/datatype/structureddatatype.cpp b/document/src/vespa/document/datatype/structureddatatype.cpp index 34063c7d7e4..748da0efa50 100644 --- a/document/src/vespa/document/datatype/structureddatatype.cpp +++ b/document/src/vespa/document/datatype/structureddatatype.cpp @@ -2,6 +2,9 @@ #include "structureddatatype.h" #include <vespa/vespalib/stllike/asciistream.h> +#include <vespa/document/base/exceptions.h> + +using vespalib::make_string; namespace document { @@ -17,8 +20,7 @@ StructuredDataType::StructuredDataType(const vespalib::stringref &name) { } -StructuredDataType::StructuredDataType(const vespalib::stringref &name, - int dataTypeId) +StructuredDataType::StructuredDataType(const vespalib::stringref &name, int dataTypeId) : DataType(name, dataTypeId) { } @@ -53,8 +55,8 @@ int32_t StructuredDataType::createId(const vespalib::stringref &name) return crappyJavaStringHash(ost.str()); } -FieldPath::UP -StructuredDataType::onBuildFieldPath(const vespalib::stringref & remainFieldName) const +void +StructuredDataType::onBuildFieldPath(FieldPath & path, const vespalib::stringref & remainFieldName) const { vespalib::stringref currFieldName(remainFieldName); vespalib::stringref subFieldName; @@ -71,17 +73,16 @@ StructuredDataType::onBuildFieldPath(const vespalib::stringref & remainFieldName } } - // LOG(debug, "Field %s of datatype %s split into %s and %s", remainFieldName.c_str(), getName().c_str(), currFieldName.c_str(), subFieldName.c_str()); + // LOG(debug, "Field %s of datatype %s split into %s and %s", + // remainFieldName.c_str(), getName().c_str(), currFieldName.c_str(), subFieldName.c_str()); if (hasField(currFieldName)) { const document::Field &fp = getField(currFieldName); - FieldPath::UP fieldPath = fp.getDataType().buildFieldPath(subFieldName); - if (!fieldPath) { - return FieldPath::UP(); - } - fieldPath->insert(fieldPath->begin(), FieldPathEntry(fp)); - return fieldPath; + fp.getDataType().buildFieldPath(path, subFieldName); + + path.insert(path.begin(), FieldPathEntry(fp)); } else { - return FieldPath::UP(); + throw FieldNotFoundException(currFieldName, make_string("Invalid field path '%s', no field named '%s'", + remainFieldName.c_str(), currFieldName.c_str())); } } diff --git a/document/src/vespa/document/datatype/structureddatatype.h b/document/src/vespa/document/datatype/structureddatatype.h index 635ee906d64..1454f16d517 100644 --- a/document/src/vespa/document/datatype/structureddatatype.h +++ b/document/src/vespa/document/datatype/structureddatatype.h @@ -16,7 +16,7 @@ namespace document { class StructuredDataType : public DataType { - FieldPath::UP onBuildFieldPath(const vespalib::stringref & remainFieldName) const override; + void onBuildFieldPath(FieldPath & path, const vespalib::stringref & remainFieldName) const override; protected: StructuredDataType(); diff --git a/document/src/vespa/document/datatype/weightedsetdatatype.cpp b/document/src/vespa/document/datatype/weightedsetdatatype.cpp index 16561580928..7f607caec1e 100644 --- a/document/src/vespa/document/datatype/weightedsetdatatype.cpp +++ b/document/src/vespa/document/datatype/weightedsetdatatype.cpp @@ -77,17 +77,15 @@ WeightedSetDataType::operator==(const DataType& other) const { if (this == &other) return true; if (!CollectionDataType::operator==(other)) return false; - const WeightedSetDataType* w( - dynamic_cast<const WeightedSetDataType*>(&other)); + const WeightedSetDataType* w(dynamic_cast<const WeightedSetDataType*>(&other)); return (w != 0 && _createIfNonExistent == w->_createIfNonExistent && _removeIfZero == w->_removeIfZero); } -FieldPath::UP -WeightedSetDataType::onBuildFieldPath(const vespalib::stringref & remainFieldName) const +void +WeightedSetDataType::onBuildFieldPath(FieldPath & path, const vespalib::stringref & remainFieldName) const { - return MapDataType::buildFieldPathImpl( - *this, remainFieldName, getNestedType(), *DataType::INT); + MapDataType::buildFieldPathImpl(path, *this, remainFieldName, getNestedType(), *DataType::INT); } } // document diff --git a/document/src/vespa/document/datatype/weightedsetdatatype.h b/document/src/vespa/document/datatype/weightedsetdatatype.h index 90350dee74c..91917ec990f 100644 --- a/document/src/vespa/document/datatype/weightedsetdatatype.h +++ b/document/src/vespa/document/datatype/weightedsetdatatype.h @@ -40,7 +40,7 @@ public: void print(std::ostream&, bool verbose, const std::string& indent) const override; bool operator==(const DataType& other) const override; WeightedSetDataType* clone() const override { return new WeightedSetDataType(*this); } - FieldPath::UP onBuildFieldPath(const vespalib::stringref &remainFieldName) const override; + void onBuildFieldPath(FieldPath & path, const vespalib::stringref &remainFieldName) const override; DECLARE_IDENTIFIABLE(WeightedSetDataType); }; diff --git a/document/src/vespa/document/select/bodyfielddetector.cpp b/document/src/vespa/document/select/bodyfielddetector.cpp index c699a1e1789..228fec26277 100644 --- a/document/src/vespa/document/select/bodyfielddetector.cpp +++ b/document/src/vespa/document/select/bodyfielddetector.cpp @@ -9,16 +9,16 @@ namespace document::select { void -BodyFieldDetector::detectFieldType(const FieldValueNode *expr, - const DocumentType &type) +BodyFieldDetector::detectFieldType(const FieldValueNode *expr, const DocumentType &type) { if (type.getName() != expr->getDocType()) { return; } try { - FieldPath::UP path(type.buildFieldPath(expr->getFieldName())); - if (path.get() && path->size() != 0) { - if ((*path)[0].getFieldRef().isHeaderField()) { + FieldPath path; + type.buildFieldPath(path, expr->getFieldName()); + if ( ! path.empty() ) { + if (path[0].getFieldRef().isHeaderField()) { foundHeaderField = true; } else { foundBodyField = true; diff --git a/document/src/vespa/document/select/valuenodes.cpp b/document/src/vespa/document/select/valuenodes.cpp index 3b6fa9a7bbd..b6c2bf551c0 100644 --- a/document/src/vespa/document/select/valuenodes.cpp +++ b/document/src/vespa/document/select/valuenodes.cpp @@ -340,15 +340,8 @@ IteratorHandler::getInternalValue(const FieldValue& fval) const void FieldValueNode::initFieldPath(const DocumentType& type) const { - if (_fieldPath.size() == 0) { - FieldPath::UP path(type.buildFieldPath(_fieldExpression)); - if (!path.get()) { - throw FieldNotFoundException( - vespalib::make_string("Could not create field path for doc type: '%s' field: '%s'", - type.toString().c_str(), _fieldExpression.c_str()), - VESPA_STRLOC); - } - _fieldPath = *path; + if (_fieldPath.empty()) { + type.buildFieldPath(_fieldPath, _fieldExpression); } } diff --git a/document/src/vespa/document/update/fieldpathupdate.cpp b/document/src/vespa/document/update/fieldpathupdate.cpp index bbe38aaeac0..29fee6063aa 100644 --- a/document/src/vespa/document/update/fieldpathupdate.cpp +++ b/document/src/vespa/document/update/fieldpathupdate.cpp @@ -47,16 +47,12 @@ FieldPathUpdate::FieldPathUpdate(const DocumentTypeRepo& repo, const DataType& t stringref fieldPath, stringref whereClause) : _originalFieldPath(fieldPath), _originalWhereClause(whereClause), - _fieldPath(type.buildFieldPath(_originalFieldPath).release()), + _fieldPath(), _whereClause(!_originalWhereClause.empty() ? parseDocumentSelection(_originalWhereClause, repo) : std::unique_ptr<select::Node>()) { - if (!_fieldPath) { - throw IllegalArgumentException( - make_string("Could not create field path update for: path='%s', where='%s'", - fieldPath.c_str(), whereClause.c_str()), VESPA_STRLOC); - } + type.buildFieldPath(_fieldPath, _originalFieldPath); } FieldPathUpdate::~FieldPathUpdate() { } @@ -74,16 +70,14 @@ FieldPathUpdate::applyTo(Document& doc) const std::unique_ptr<IteratorHandler> handler(getIteratorHandler(doc)); if (!_whereClause) { - doc.iterateNested(*_fieldPath, *handler); + doc.iterateNested(_fieldPath, *handler); } else { select::ResultList results = _whereClause->contains(doc); - for (select::ResultList::const_iterator i = results.begin(); - i != results.end(); ++i) - { + for (select::ResultList::const_iterator i = results.begin(); i != results.end(); ++i) { LOG(spam, "vars = %s", handler->getVariables().toString().c_str()); if (*i->second == select::Result::True) { handler->setVariables(i->first); - doc.iterateNested(*_fieldPath, *handler); + doc.iterateNested(_fieldPath, *handler); } } } @@ -92,8 +86,8 @@ FieldPathUpdate::applyTo(Document& doc) const bool FieldPathUpdate::affectsDocumentBody() const { - if (_fieldPath->empty() || !(*_fieldPath)[0].hasField()) return false; - const Field& field = (*_fieldPath)[0].getFieldRef(); + if (_fieldPath.empty() || !_fieldPath[0].hasField()) return false; + const Field& field = _fieldPath[0].getFieldRef(); return !field.isHeaderField(); } @@ -119,10 +113,10 @@ FieldPathUpdate::checkCompatibility(const FieldValue& fv) const const DataType& FieldPathUpdate::getResultingDataType() const { - if (_fieldPath->empty()) { + if (_fieldPath.empty()) { throw vespalib::IllegalStateException("Cannot get resulting data type from an empty field path", VESPA_STRLOC); } - return _fieldPath->rbegin()->getDataType(); + return _fieldPath.rbegin()->getDataType(); } vespalib::string @@ -144,10 +138,7 @@ FieldPathUpdate::deserialize(const DocumentTypeRepo& repo, _originalWhereClause = getString(buffer); try { - _fieldPath = type.buildFieldPath(_originalFieldPath).release(); - if (!_fieldPath) { - throw DeserializeException(make_string("Invalid field path: '%s'", _originalFieldPath.c_str()), VESPA_STRLOC); - } + type.buildFieldPath(_fieldPath, _originalFieldPath); _whereClause = !_originalWhereClause.empty() ? parseDocumentSelection(_originalWhereClause, repo) : std::unique_ptr<select::Node>(); diff --git a/document/src/vespa/document/update/fieldpathupdate.h b/document/src/vespa/document/update/fieldpathupdate.h index 49f11a5c3f2..5dac15c12f1 100644 --- a/document/src/vespa/document/update/fieldpathupdate.h +++ b/document/src/vespa/document/update/fieldpathupdate.h @@ -2,11 +2,11 @@ #pragma once #include "updatevisitor.h" +#include <vespa/document/base/fieldpath.h> #include <vespa/document/util/printable.h> #include <vespa/document/util/identifiableid.h> #include <vespa/vespalib/objects/identifiable.h> #include <vespa/vespalib/objects/cloneable.h> -#include <vespa/vespalib/stllike/string.h> namespace document { @@ -17,7 +17,6 @@ class FieldValue; class BucketIdFactory; class Document; class DataType; -class FieldPath; namespace select { class Node; } namespace fieldvalue { class IteratorHandler; } @@ -58,7 +57,7 @@ public: return ! (*this == other); } - const FieldPath& getFieldPath() const { return *_fieldPath; } + const FieldPath& getFieldPath() const { return _fieldPath; } const select::Node& getWhereClause() const { return *_whereClause; } const vespalib::string& getOriginalFieldPath() const { return _originalFieldPath; } @@ -111,9 +110,8 @@ private: vespalib::string _originalFieldPath; vespalib::string _originalWhereClause; - vespalib::CloneablePtr<FieldPath> _fieldPath; + FieldPath _fieldPath; std::shared_ptr<select::Node> _whereClause; }; -} // ns document - +} |