summaryrefslogtreecommitdiffstats
path: root/document
diff options
context:
space:
mode:
authorTor Brede Vekterli <vekterli@yahooinc.com>2022-03-15 12:40:17 +0000
committerTor Brede Vekterli <vekterli@yahooinc.com>2022-03-15 12:40:17 +0000
commitf69392b08a6edb37c88b3fba7197fa7904d0d1f2 (patch)
treee6dc91abbd9b06b021ee35078c8e1804270f0955 /document
parent8618500f10427d6414e1dabb02e34695cbd92e79 (diff)
Add basic support for BoolFieldValues in C++ document selection impl
Diffstat (limited to 'document')
-rw-r--r--document/src/tests/documentselectparsertest.cpp21
-rw-r--r--document/src/vespa/document/base/testdocrepo.cpp1
-rw-r--r--document/src/vespa/document/select/valuenodes.cpp25
3 files changed, 36 insertions, 11 deletions
diff --git a/document/src/tests/documentselectparsertest.cpp b/document/src/tests/documentselectparsertest.cpp
index d2fa969daa9..5c263daaa31 100644
--- a/document/src/tests/documentselectparsertest.cpp
+++ b/document/src/tests/documentselectparsertest.cpp
@@ -6,6 +6,7 @@
#include <vespa/document/update/assignvalueupdate.h>
#include <vespa/document/update/documentupdate.h>
#include <vespa/document/datatype/documenttype.h>
+#include <vespa/document/fieldvalue/boolfieldvalue.h>
#include <vespa/document/fieldvalue/bytefieldvalue.h>
#include <vespa/document/fieldvalue/intfieldvalue.h>
#include <vespa/document/fieldvalue/longfieldvalue.h>
@@ -43,7 +44,7 @@ protected:
std::vector<Document::SP > _doc;
std::vector<DocumentUpdate::SP > _update;
- ~DocumentSelectParserTest();
+ ~DocumentSelectParserTest() override;
Document::SP createDoc(
vespalib::stringref doctype, vespalib::stringref id, uint32_t hint,
@@ -237,6 +238,14 @@ DocumentSelectParserTest::createDocs()
_doc.push_back(createDoc(
"testdoctype1", "id:myspace:testdoctype1:g=xyzzy:foo",
10, 1.4, "inherited", "", 42)); // DOC 10
+ _doc.push_back(createDoc(
+ "testdoctype1", "id:myspace:testdoctype1::withtruebool",
+ 10, 1.4, "inherited", "", 42)); // DOC 11
+ _doc.back()->setValue("boolfield", BoolFieldValue(true));
+ _doc.push_back(createDoc(
+ "testdoctype1", "id:myspace:testdoctype1::withfalsebool",
+ 10, 1.4, "inherited", "", 42)); // DOC 12
+ _doc.back()->setValue("boolfield", BoolFieldValue(false));
_update.clear();
_update.push_back(createUpdate("testdoctype1", "id:myspace:testdoctype1::anything", 20, "hmm"));
@@ -914,6 +923,16 @@ TEST_F(DocumentSelectParserTest, operators_9)
PARSE("testdoctype1.structarray.key >= 17", *_doc[1], False);
}
+TEST_F(DocumentSelectParserTest, can_use_boolean_fields_in_expressions) {
+ createDocs();
+ PARSE("testdoctype1.boolfield == 1", *_doc[11], True); // has explicit field set to true
+ PARSE("testdoctype1.boolfield == 1", *_doc[12], False); // has explicit field set to false
+ PARSE("testdoctype1.boolfield == 0", *_doc[12], True);
+ // FIXME very un-intuitive behavior when nulls are implicitly returned:
+ PARSE("testdoctype1.boolfield == 1", *_doc[1], False); // Does not have field set in document
+ PARSE("testdoctype1.boolfield == 0", *_doc[1], False); // Does not have field set in document
+}
+
namespace {
class TestVisitor : public select::Visitor {
diff --git a/document/src/vespa/document/base/testdocrepo.cpp b/document/src/vespa/document/base/testdocrepo.cpp
index c1930de8551..8dcb2d66410 100644
--- a/document/src/vespa/document/base/testdocrepo.cpp
+++ b/document/src/vespa/document/base/testdocrepo.cpp
@@ -39,6 +39,7 @@ DocumenttypesConfig TestDocRepo::getDefaultConfig() {
.addField("key", DataType::T_INT)
.addField("value", DataType::T_STRING))
.addField("tags", Array(DataType::T_STRING))
+ .addField("boolfield", DataType::T_BOOL)
.addField("stringweightedset", Wset(DataType::T_STRING))
.addField("stringweightedset2", DataType::T_TAG)
.addField("byteweightedset", Wset(DataType::T_BYTE))
diff --git a/document/src/vespa/document/select/valuenodes.cpp b/document/src/vespa/document/select/valuenodes.cpp
index a34e90af383..52e6b2e4223 100644
--- a/document/src/vespa/document/select/valuenodes.cpp
+++ b/document/src/vespa/document/select/valuenodes.cpp
@@ -273,39 +273,44 @@ std::unique_ptr<Value>
IteratorHandler::getInternalValue(const FieldValue& fval) const
{
switch(fval.getClass().id()) {
+ case document::BoolFieldValue::classId:
+ {
+ const auto& val(dynamic_cast<const BoolFieldValue&>(fval));
+ return std::make_unique<IntegerValue>(val.getAsInt(), false);
+ }
case document::IntFieldValue::classId:
{
- const IntFieldValue& val(dynamic_cast<const IntFieldValue&>(fval));
+ const auto& val(dynamic_cast<const IntFieldValue&>(fval));
return std::make_unique<IntegerValue>(val.getAsInt(), false);
}
case document::ByteFieldValue::classId:
{
- const ByteFieldValue& val(dynamic_cast<const ByteFieldValue&>(fval));
+ const auto& val(dynamic_cast<const ByteFieldValue&>(fval));
return std::make_unique<IntegerValue>(val.getAsByte(), false);
}
case LongFieldValue::classId:
{
- const LongFieldValue& val(dynamic_cast<const LongFieldValue&>(fval));
+ const auto& val(dynamic_cast<const LongFieldValue&>(fval));
return std::make_unique<IntegerValue>(val.getAsLong(), false);
}
case FloatFieldValue::classId:
{
- const FloatFieldValue& val(dynamic_cast<const FloatFieldValue&>(fval));
+ const auto& val(dynamic_cast<const FloatFieldValue&>(fval));
return std::make_unique<FloatValue>(val.getAsFloat());
}
case DoubleFieldValue::classId:
{
- const DoubleFieldValue& val(dynamic_cast<const DoubleFieldValue&>(fval));
+ const auto& val(dynamic_cast<const DoubleFieldValue&>(fval));
return std::make_unique<FloatValue>(val.getAsDouble());
}
case StringFieldValue::classId:
{
- const StringFieldValue& val(dynamic_cast<const StringFieldValue&>(fval));
+ const auto& val(dynamic_cast<const StringFieldValue&>(fval));
return std::make_unique<StringValue>(val.getAsString());
}
case ReferenceFieldValue::classId:
{
- const ReferenceFieldValue& val(dynamic_cast<const ReferenceFieldValue&>(fval));
+ const auto& val(dynamic_cast<const ReferenceFieldValue&>(fval));
if (val.hasValidDocumentId()) {
return std::make_unique<StringValue>(val.getDocumentId().toString());
} else {
@@ -314,7 +319,7 @@ IteratorHandler::getInternalValue(const FieldValue& fval) const
}
case ArrayFieldValue::classId:
{
- const ArrayFieldValue& val(dynamic_cast<const ArrayFieldValue&>(fval));
+ const auto& val(dynamic_cast<const ArrayFieldValue&>(fval));
if (val.size() == 0) {
return std::make_unique<NullValue>();
} else {
@@ -325,7 +330,7 @@ IteratorHandler::getInternalValue(const FieldValue& fval) const
}
case StructFieldValue::classId:
{
- const StructFieldValue& val(dynamic_cast<const StructFieldValue&>(fval));
+ const auto& val(dynamic_cast<const StructFieldValue&>(fval));
if (val.empty()) {
return std::make_unique<NullValue>();
} else {
@@ -339,7 +344,7 @@ IteratorHandler::getInternalValue(const FieldValue& fval) const
}
case MapFieldValue::classId:
{
- const MapFieldValue& val(static_cast<const MapFieldValue&>(fval));
+ const auto& val(static_cast<const MapFieldValue&>(fval));
if (val.isEmpty()) {
return std::make_unique<NullValue>();
} else {