summaryrefslogtreecommitdiffstats
path: root/document
diff options
context:
space:
mode:
authorVegard Sjonfjell <vegard@yahoo-inc.com>2016-11-02 16:31:36 +0100
committerVegard Sjonfjell <vegard@yahoo-inc.com>2016-11-02 16:31:36 +0100
commita7a95bb4d0096bb9a3fa88feb3efb27174b89bec (patch)
tree859b7f1b8f002c6317754de7d0de8fad4d5c4894 /document
parent32fa3c0ae67b2fdd8961b3dc28c5b6c1287f6e7e (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.cpp25
-rw-r--r--document/src/vespa/document/select/valuenode.cpp27
-rw-r--r--document/src/vespa/document/select/valuenode.h13
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
{