summaryrefslogtreecommitdiffstats
path: root/document
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2017-07-26 14:41:32 +0200
committerHenning Baldersheim <balder@yahoo-inc.com>2017-07-31 17:04:18 +0200
commit5f54fb77ef1e354f9919e92da7b22cbe68ee7fbd (patch)
tree87d3c5526a04e2b4e91f8eff5d8ed50d87d468a9 /document
parent50a275ebd8774a958418bbda4d127df1f420f1ad (diff)
Unify error handling to using exceptions only, not in combination with nullptr.
Diffstat (limited to 'document')
-rw-r--r--document/src/tests/datatype/referencedatatype_test.cpp12
-rw-r--r--document/src/tests/documenttestcase.cpp13
-rw-r--r--document/src/tests/fieldpathupdatetestcase.cpp10
-rw-r--r--document/src/vespa/document/base/fieldpath.cpp30
-rw-r--r--document/src/vespa/document/base/fieldpath.h32
-rw-r--r--document/src/vespa/document/datatype/annotationreferencedatatype.cpp4
-rw-r--r--document/src/vespa/document/datatype/annotationreferencedatatype.h3
-rw-r--r--document/src/vespa/document/datatype/arraydatatype.cpp20
-rw-r--r--document/src/vespa/document/datatype/arraydatatype.h2
-rw-r--r--document/src/vespa/document/datatype/datatype.cpp7
-rw-r--r--document/src/vespa/document/datatype/datatype.h5
-rw-r--r--document/src/vespa/document/datatype/documenttype.cpp7
-rw-r--r--document/src/vespa/document/datatype/mapdatatype.cpp49
-rw-r--r--document/src/vespa/document/datatype/mapdatatype.h12
-rw-r--r--document/src/vespa/document/datatype/primitivedatatype.cpp11
-rw-r--r--document/src/vespa/document/datatype/primitivedatatype.h2
-rw-r--r--document/src/vespa/document/datatype/referencedatatype.cpp18
-rw-r--r--document/src/vespa/document/datatype/referencedatatype.h3
-rw-r--r--document/src/vespa/document/datatype/structureddatatype.cpp25
-rw-r--r--document/src/vespa/document/datatype/structureddatatype.h2
-rw-r--r--document/src/vespa/document/datatype/weightedsetdatatype.cpp10
-rw-r--r--document/src/vespa/document/datatype/weightedsetdatatype.h2
-rw-r--r--document/src/vespa/document/select/bodyfielddetector.cpp10
-rw-r--r--document/src/vespa/document/select/valuenodes.cpp11
-rw-r--r--document/src/vespa/document/update/fieldpathupdate.cpp29
-rw-r--r--document/src/vespa/document/update/fieldpathupdate.h10
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
-
+}