aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@oath.com>2017-09-27 14:29:25 +0000
committerTor Egge <Tor.Egge@oath.com>2017-09-27 14:29:25 +0000
commit392b29e382adf48f94f549a32f37ea8b68b5551b (patch)
tree4a5fb47c3021954ea817c7b9573121bc392e0cd9
parent47e00fae7c892362ac5c47a6ee96220f3d831ba1 (diff)
Validate data type as part of validating blueprint parameters.
-rw-r--r--searchlib/src/tests/fef/parameter/parameter_test.cpp6
-rw-r--r--searchlib/src/vespa/searchlib/fef/parameterdescriptions.h53
-rw-r--r--searchlib/src/vespa/searchlib/fef/parametervalidator.cpp14
-rw-r--r--searchlib/src/vespa/searchlib/fef/parametervalidator.h2
4 files changed, 71 insertions, 4 deletions
diff --git a/searchlib/src/tests/fef/parameter/parameter_test.cpp b/searchlib/src/tests/fef/parameter/parameter_test.cpp
index 5fa0633f56e..2cff534d289 100644
--- a/searchlib/src/tests/fef/parameter/parameter_test.cpp
+++ b/searchlib/src/tests/fef/parameter/parameter_test.cpp
@@ -9,6 +9,7 @@ LOG_SETUP("parameter_test");
using namespace search::fef::test;
using CollectionType = search::fef::FieldInfo::CollectionType;
+using DataType = search::fef::FieldInfo::DataType;
namespace search {
namespace fef {
@@ -135,6 +136,7 @@ ParameterTest::testValidator()
IndexEnvironmentBuilder builder(env);
builder.addField(FieldType::INDEX, CollectionType::SINGLE, "foo")
.addField(FieldType::ATTRIBUTE, CollectionType::SINGLE, "bar")
+ .addField(FieldType::ATTRIBUTE, CollectionType::SINGLE, DataType::TENSOR, "tbar")
.addField(FieldType::INDEX, CollectionType::ARRAY, "afoo")
.addField(FieldType::INDEX, CollectionType::WEIGHTEDSET, "wfoo")
.addField(FieldType::INDEX, CollectionType::SINGLE, "hybrid");
@@ -156,6 +158,8 @@ ParameterTest::testValidator()
EXPECT_TRUE(validate(env, SL().add("baz"), PDS().desc().feature()));
EXPECT_TRUE(validate(env, SL().add("123"), PDS().desc().number()));
EXPECT_TRUE(validate(env, SL().add("baz"), PDS().desc().string()));
+ EXPECT_TRUE(validate(env, SL().add("tbar"), PDS().desc().attributeField(ParameterCollection::ANY)));
+ EXPECT_TRUE(validate(env, SL().add("tbar"), PDS().desc().attribute(ParameterCollection::ANY)));
// first fail but second pass
EXPECT_TRUE(validate(env, SL().add("baz"), PDS().desc().field().desc().string()));
@@ -180,6 +184,8 @@ ParameterTest::testValidator()
EXPECT_FALSE(validate(env, SL().add("hybrid"), PDS().desc().attributeField(ParameterCollection::ANY)));
EXPECT_FALSE(validate(env, SL().add("12a"), PDS().desc().number()));
EXPECT_FALSE(validate(env, SL().add("a12"), PDS().desc().number()));
+ EXPECT_FALSE(validate(env, SL().add("tbar"), PDS().desc().attributeField(ParameterDataTypeSet::normalTypeSet(), ParameterCollection::ANY)));
+ EXPECT_FALSE(validate(env, SL().add("tbar"), PDS().desc().attribute(ParameterDataTypeSet::normalTypeSet(), ParameterCollection::ANY)));
// test repeat
PDS d1 = PDS().desc().field().repeat();
diff --git a/searchlib/src/vespa/searchlib/fef/parameterdescriptions.h b/searchlib/src/vespa/searchlib/fef/parameterdescriptions.h
index d0e29cfa318..030581d10ee 100644
--- a/searchlib/src/vespa/searchlib/fef/parameterdescriptions.h
+++ b/searchlib/src/vespa/searchlib/fef/parameterdescriptions.h
@@ -2,6 +2,7 @@
#pragma once
+#include <vespa/searchcommon/common/datatype.h>
#include <vector>
#include <cstddef>
@@ -37,16 +38,55 @@ struct ParameterCollection {
};
};
+/*
+ * A set of accepted data types for a parameter.
+ */
+struct ParameterDataTypeSet
+{
+ using DataType = search::index::schema::DataType;
+
+ uint32_t typeMask;
+
+ static uint32_t asMask(DataType dataType) {
+ return (1u << static_cast<unsigned int>(dataType));
+ }
+ static uint32_t allTypesMask() {
+ return (asMask(DataType::REFERENCE) << 1) - 1;
+ }
+ static uint32_t normalTypesMask() {
+ return asMask(DataType::BOOLEANTREE) - 1;
+ }
+ ParameterDataTypeSet(uint32_t typeMask_in)
+ : typeMask(typeMask_in)
+ {
+ }
+ ParameterDataTypeSet()
+ : ParameterDataTypeSet(allTypesMask())
+ {
+ }
+ static ParameterDataTypeSet normalTypeSet() {
+ return ParameterDataTypeSet(normalTypesMask());
+ }
+ bool allowedType(DataType dataType) const {
+ return ((asMask(dataType) & typeMask) != 0);
+ }
+};
+
/**
* The description of a single parameter within a single
* ParameterDescription object.
**/
struct ParamDescItem {
ParameterType::Enum type;
+ ParameterDataTypeSet dataTypeSet;
ParameterCollection::Enum collection;
ParamDescItem(ParameterType::Enum t,
ParameterCollection::Enum c)
- : type(t), collection(c) {}
+ : type(t), dataTypeSet(), collection(c) {}
+ ParamDescItem(ParameterType::Enum t,
+ ParameterDataTypeSet dts,
+ ParameterCollection::Enum c)
+ : type(t), dataTypeSet(dts), collection(c) {}
};
/**
@@ -101,6 +141,9 @@ private:
Description & getCurrent() { return _descriptions.back(); }
void addParameter(const ParamDescItem &param);
+ void addParameter(ParameterType::Enum type, ParameterDataTypeSet dataTypeSet, ParameterCollection::Enum collection) {
+ addParameter(ParamDescItem(type, dataTypeSet, collection));
+ }
void addParameter(ParameterType::Enum type, ParameterCollection::Enum collection) {
addParameter(ParamDescItem(type, collection));
}
@@ -141,6 +184,10 @@ public:
addParameter(ParameterType::ATTRIBUTE_FIELD, collection);
return *this;
}
+ ParameterDescriptions & attributeField(ParameterDataTypeSet dataTypeSet, ParameterCollection::Enum collection) {
+ addParameter(ParameterType::ATTRIBUTE_FIELD, dataTypeSet, collection);
+ return *this;
+ }
/**
* Adds an attribute parameter to the current description.
*/
@@ -148,6 +195,10 @@ public:
addParameter(ParameterType::ATTRIBUTE, collection);
return *this;
}
+ ParameterDescriptions & attribute(ParameterDataTypeSet dataTypeSet, ParameterCollection::Enum collection) {
+ addParameter(ParameterType::ATTRIBUTE, dataTypeSet, collection);
+ return *this;
+ }
/**
* Adds a feature parameter to the current description.
*/
diff --git a/searchlib/src/vespa/searchlib/fef/parametervalidator.cpp b/searchlib/src/vespa/searchlib/fef/parametervalidator.cpp
index 62c9efc6739..dda5ec0b719 100644
--- a/searchlib/src/vespa/searchlib/fef/parametervalidator.cpp
+++ b/searchlib/src/vespa/searchlib/fef/parametervalidator.cpp
@@ -25,6 +25,10 @@ bool checkCollectionType(ParameterCollection::Enum accept, CollectionType actual
return false;
}
+bool checkDataType(ParameterDataTypeSet accept, search::index::schema::DataType actual) {
+ return accept.allowedType(actual);
+}
+
class ValidateException
{
public:
@@ -50,7 +54,9 @@ ParameterValidator::Result & ParameterValidator::Result::operator=(const Result
ParameterValidator::Result::~Result() { }
void
-ParameterValidator::validateField(ParameterType::Enum type, ParameterCollection::Enum collection,
+ParameterValidator::validateField(ParameterType::Enum type,
+ ParameterDataTypeSet dataTypeSet,
+ ParameterCollection::Enum collection,
size_t i, Result & result)
{
const FieldInfo * field = _indexEnv.getFieldByName(_params[i]);
@@ -74,6 +80,10 @@ ParameterValidator::validateField(ParameterType::Enum type, ParameterCollection:
i, _params[i].c_str()));
}
}
+ if (!checkDataType(dataTypeSet, field->get_data_type())) {
+ throw ValidateException(make_string("Param[%zu]: field '%s' has inappropriate data type",
+ i, _params[i].c_str()));
+ }
if (!checkCollectionType(collection, field->collection())) {
throw ValidateException(make_string("Param[%zu]: field '%s' has inappropriate collection type",
i, _params[i].c_str()));
@@ -116,7 +126,7 @@ ParameterValidator::validate(const ParameterDescriptions::Description & desc)
case ParameterType::INDEX_FIELD:
case ParameterType::ATTRIBUTE_FIELD:
case ParameterType::ATTRIBUTE:
- validateField(type, param.collection, i, result);
+ validateField(type, param.dataTypeSet, param.collection, i, result);
break;
case ParameterType::NUMBER:
validateNumber(type, i, result);
diff --git a/searchlib/src/vespa/searchlib/fef/parametervalidator.h b/searchlib/src/vespa/searchlib/fef/parametervalidator.h
index 25dc5296988..6bde59641da 100644
--- a/searchlib/src/vespa/searchlib/fef/parametervalidator.h
+++ b/searchlib/src/vespa/searchlib/fef/parametervalidator.h
@@ -59,7 +59,7 @@ private:
const StringVector & _params;
const ParameterDescriptions & _descs;
- void validateField(ParameterType::Enum type, ParameterCollection::Enum collection,
+ void validateField(ParameterType::Enum type, ParameterDataTypeSet dataTypeSet, ParameterCollection::Enum collection,
size_t i, Result & result);
void validateNumber(ParameterType::Enum type, size_t i, Result & result);
Result validate(const ParameterDescriptions::Description & desc);