diff options
author | Vegard Sjonfjell <vegard@yahoo-inc.com> | 2016-11-02 16:31:36 +0100 |
---|---|---|
committer | Vegard Sjonfjell <vegard@yahoo-inc.com> | 2016-11-02 16:31:36 +0100 |
commit | a7a95bb4d0096bb9a3fa88feb3efb27174b89bec (patch) | |
tree | 859b7f1b8f002c6317754de7d0de8fad4d5c4894 /document | |
parent | 32fa3c0ae67b2fdd8961b3dc28c5b6c1287f6e7e (diff) |
Create a new member variable containing the real field name (without the other crap at the end)
Diffstat (limited to 'document')
-rw-r--r-- | document/src/tests/documentselectparsertest.cpp | 25 | ||||
-rw-r--r-- | document/src/vespa/document/select/valuenode.cpp | 27 | ||||
-rw-r--r-- | document/src/vespa/document/select/valuenode.h | 13 |
3 files changed, 54 insertions, 11 deletions
diff --git a/document/src/tests/documentselectparsertest.cpp b/document/src/tests/documentselectparsertest.cpp index 357e6eb2a68..037dc9bac28 100644 --- a/document/src/tests/documentselectparsertest.cpp +++ b/document/src/tests/documentselectparsertest.cpp @@ -34,6 +34,7 @@ class DocumentSelectParserTest : public CppUnit::TestFixture { CPPUNIT_TEST(testOperators); CPPUNIT_TEST(testVisitor); CPPUNIT_TEST(testUtf8); + CPPUNIT_TEST(testGetRealFieldName); CPPUNIT_TEST(testBodyFieldDetection); CPPUNIT_TEST(testDocumentUpdates); CPPUNIT_TEST_SUITE_END(); @@ -79,6 +80,7 @@ public: void testOperators9(); void testVisitor(); void testUtf8(); + void testGetRealFieldName(); void testBodyFieldDetection(); void testDocumentUpdates(); void testDocumentUpdates0(); @@ -1275,4 +1277,27 @@ void DocumentSelectParserTest::testUtf8() // PARSE("testdoctype1.hstringval =~ \"H.kon\"", *_doc[_doc.size()-1], True); } +static const select::FieldValueNode & leftFieldValueNodeFromCompNode(std::unique_ptr<select::Node> node) { + return dynamic_cast<const select::FieldValueNode &>( + dynamic_cast<const select::Compare &>(*node).getLeft()); +} + +void DocumentSelectParserTest::testGetRealFieldName() { + CPPUNIT_ASSERT_EQUAL( + vespalib::string("headerval"), + leftFieldValueNodeFromCompNode(_parser->parse("testdoctype1.headerval == 42")).getRealFieldName()); + + CPPUNIT_ASSERT_EQUAL( + vespalib::string("headerval"), + leftFieldValueNodeFromCompNode(_parser->parse("testdoctype1.headerval{test} == 42")).getRealFieldName()); + + CPPUNIT_ASSERT_EQUAL( + vespalib::string("headerval"), + leftFieldValueNodeFromCompNode(_parser->parse("testdoctype1.headerval[42] == 42")).getRealFieldName()); + + CPPUNIT_ASSERT_EQUAL( + vespalib::string("headerval"), + leftFieldValueNodeFromCompNode(_parser->parse("testdoctype1.headerval.meow.meow{test} == 42")).getRealFieldName()); +} + } // document diff --git a/document/src/vespa/document/select/valuenode.cpp b/document/src/vespa/document/select/valuenode.cpp index 94be21a1657..489a39b616e 100644 --- a/document/src/vespa/document/select/valuenode.cpp +++ b/document/src/vespa/document/select/valuenode.cpp @@ -12,6 +12,7 @@ #include <vespa/document/util/stringutil.h> #include <sys/time.h> #include <vespa/vespalib/text/lowercase.h> +#include <regex> LOG_SETUP(".document.select.valuenode"); @@ -192,22 +193,34 @@ FloatValueNode::print(std::ostream& out, bool verbose, } FieldValueNode::FieldValueNode(const vespalib::string& doctype, - const vespalib::string& field) + const vespalib::string& fieldExpression) : _doctype(doctype), - _field(field) + _fieldExpression(fieldExpression), + _fieldName(extractFieldName(fieldExpression)) { } +const vespalib::string FieldValueNode::extractFieldName(const std::string & fieldExpression) { + static const std::regex fieldNameRegex("^([_A-Za-z][_A-Za-z0-9]+).*"); + std::smatch match; + + if (std::regex_match(fieldExpression, match, fieldNameRegex) && match[1].matched) { + return vespalib::string(match[1].first, match[1].second); + } + + throw ParsingFailedException("Fatal: could not extract field name from field expression '" + fieldExpression + "'"); +} + void FieldValueNode::initFieldPath(const DocumentType& type) const { if (_fieldPath.size() == 0) { - FieldPath::UP path(type.buildFieldPath(_field)); + 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(), - _field.c_str()), + _fieldExpression.c_str()), VESPA_STRLOC); } _fieldPath = *path; @@ -248,7 +261,7 @@ FieldValueNode::getValue(const Context& context) const return std::unique_ptr<Value>(new InvalidValue()); } catch (FieldNotFoundException& e) { LOG(warning, "Tried to compare to field %s, not found in document type", - _field.c_str()); + _fieldExpression.c_str()); return std::unique_ptr<Value>(new InvalidValue()); } } @@ -386,7 +399,7 @@ FieldValueNode::print(std::ostream& out, bool verbose, { (void) verbose; (void) indent; if (hadParentheses()) out << '('; - out << _doctype << "." << _field; + out << _doctype << "." << _fieldExpression; if (hadParentheses()) out << ')'; } @@ -422,7 +435,7 @@ FieldValueNode::traceValue(const Context &context, std::ostream& out) const } } catch (FieldNotFoundException& e) { LOG(warning, "Tried to compare to field %s, not found in document type", - _field.c_str()); + _fieldExpression.c_str()); out << "Field not found in document type " << doc.getType() << ". Returning invalid.\n"; return std::unique_ptr<Value>(new InvalidValue()); diff --git a/document/src/vespa/document/select/valuenode.h b/document/src/vespa/document/select/valuenode.h index 37ccc26e3a3..60d0e3afbb3 100644 --- a/document/src/vespa/document/select/valuenode.h +++ b/document/src/vespa/document/select/valuenode.h @@ -235,16 +235,19 @@ public: class FieldValueNode : public ValueNode { vespalib::string _doctype; - vespalib::string _field; + vespalib::string _fieldExpression; + vespalib::string _fieldName; mutable FieldPath _fieldPath; public: FieldValueNode(const vespalib::string& doctype, - const vespalib::string& field); + const vespalib::string& fieldExpression); const vespalib::string& getDocType() const { return _doctype; } - const vespalib::string& getFieldName() const { return _field; } + const vespalib::string& getRealFieldName() const { return _fieldName; } + + const vespalib::string& getFieldName() const { return _fieldExpression; } virtual std::unique_ptr<Value> getValue(const Context& context) const; @@ -257,9 +260,11 @@ public: virtual void visit(Visitor& visitor) const; ValueNode::UP clone() const { - return wrapParens(new FieldValueNode(_doctype, _field)); + return wrapParens(new FieldValueNode(_doctype, _fieldExpression)); } + static const vespalib::string extractFieldName(const std::string & fieldExpression); + private: class IteratorHandler : public FieldValue::IteratorHandler { |