summaryrefslogtreecommitdiffstats
path: root/searchlib
diff options
context:
space:
mode:
authorHåvard Pettersen <havardpe@oath.com>2019-04-10 09:50:06 +0000
committerHåvard Pettersen <havardpe@oath.com>2019-04-25 12:24:03 +0000
commit974a0f2d3c588e35165177ac556e08cfdcc0e26f (patch)
tree46551c364a6cd1ee3cf88292f30537870f2956b4 /searchlib
parentb186ca34ab5df612a463334772788752e1deec3c (diff)
avoid abstract value types
remove basic value type ANY remove concept of tensors with unknown dimensions disallow value types with unbound indexed dimensions remove predicates talking about abstract types type of unknown values are now ERROR (was ANY) require that overlapping indexed dimensions are of equal size type unification now requires types to be equal ('if' expressions) creating a tensor type without dimensions now gives a double type make rank feature setup fail on invalid types (query/attribute)
Diffstat (limited to 'searchlib')
-rw-r--r--searchlib/src/tests/attribute/tensorattribute/tensorattribute_test.cpp35
-rw-r--r--searchlib/src/tests/features/ranking_expression/ranking_expression_test.cpp13
-rw-r--r--searchlib/src/tests/tensor/dense_tensor_store/dense_tensor_store_test.cpp49
-rw-r--r--searchlib/src/vespa/searchlib/features/attributefeature.cpp11
-rw-r--r--searchlib/src/vespa/searchlib/features/constant_feature.cpp4
-rw-r--r--searchlib/src/vespa/searchlib/features/queryfeature.cpp11
-rw-r--r--searchlib/src/vespa/searchlib/features/rankingexpressionfeature.cpp3
7 files changed, 20 insertions, 106 deletions
diff --git a/searchlib/src/tests/attribute/tensorattribute/tensorattribute_test.cpp b/searchlib/src/tests/attribute/tensorattribute/tensorattribute_test.cpp
index bd814b0ad32..cbbaa518b16 100644
--- a/searchlib/src/tests/attribute/tensorattribute/tensorattribute_test.cpp
+++ b/searchlib/src/tests/attribute/tensorattribute/tensorattribute_test.cpp
@@ -40,9 +40,6 @@ static bool operator==(const Tensor &lhs, const Tensor &rhs)
vespalib::string sparseSpec("tensor(x{},y{})");
vespalib::string denseSpec("tensor(x[2],y[3])");
-vespalib::string denseAbstractSpec_xy("tensor(x[],y[])");
-vespalib::string denseAbstractSpec_x("tensor(x[2],y[])");
-vespalib::string denseAbstractSpec_y("tensor(x[],y[3])");
struct Fixture
{
@@ -307,7 +304,7 @@ Fixture::testSaveLoad()
void
Fixture::testCompaction()
{
- if (_useDenseTensorAttribute && _denseTensors && !_cfg.tensorType().is_abstract()) {
+ if (_useDenseTensorAttribute && _denseTensors) {
LOG(info, "Skipping compaction test for tensor '%s' which is using free-lists", _cfg.tensorType().to_spec().c_str());
return;
}
@@ -411,34 +408,4 @@ TEST("Test dense tensors with dense tensor attribute")
testAll([]() { return std::make_shared<Fixture>(denseSpec, true); });
}
-TEST("Test dense tensors with generic tensor attribute with unbound x and y dims")
-{
- testAll([]() { return std::make_shared<Fixture>(denseAbstractSpec_xy); });
-}
-
-TEST("Test dense tensors with dense tensor attribute with unbound x and y dims")
-{
- testAll([]() { return std::make_shared<Fixture>(denseAbstractSpec_xy, true); });
-}
-
-TEST("Test dense tensors with generic tensor attribute with unbound x dim")
-{
- testAll([]() { return std::make_shared<Fixture>(denseAbstractSpec_x); });
-}
-
-TEST("Test dense tensors with dense tensor attribute with unbound x dim")
-{
- testAll([]() { return std::make_shared<Fixture>(denseAbstractSpec_x, true); });
-}
-
-TEST("Test dense tensors with generic tensor attribute with unbound y dim")
-{
- testAll([]() { return std::make_shared<Fixture>(denseAbstractSpec_y); });
-}
-
-TEST("Test dense tensors with dense tensor attribute with unbound y dim")
-{
- testAll([]() { return std::make_shared<Fixture>(denseAbstractSpec_y, true); });
-}
-
TEST_MAIN() { TEST_RUN_ALL(); vespalib::unlink("test.dat"); }
diff --git a/searchlib/src/tests/features/ranking_expression/ranking_expression_test.cpp b/searchlib/src/tests/features/ranking_expression/ranking_expression_test.cpp
index 2419f450950..c7c3447a4cc 100644
--- a/searchlib/src/tests/features/ranking_expression/ranking_expression_test.cpp
+++ b/searchlib/src/tests/features/ranking_expression/ranking_expression_test.cpp
@@ -54,7 +54,7 @@ ExpressionReplacer::SP make_replacer() {
auto replacer = std::make_shared<ListExpressionReplacer>();
replacer->add(std::make_unique<NullExpressionReplacer>());
replacer->add(std::make_unique<DummyReplacer>("foo", FeatureType::number()));
- replacer->add(std::make_unique<DummyReplacer>("bar", FeatureType::object(ValueType::from_spec("tensor(x[])"))));
+ replacer->add(std::make_unique<DummyReplacer>("bar", FeatureType::object(ValueType::from_spec("tensor(x[5])"))));
return replacer;
}
@@ -124,15 +124,6 @@ TEST("require that ranking expression can resolve to concrete complex type") {
FeatureType::object(ValueType::from_spec("tensor(x{},y{},z{})"))));
}
-TEST("require that ranking expression can resolve to abstract complex type") {
- TEST_DO(verify_output_type({{"a", "tensor"}}, "a*b", FeatureType::object(ValueType::from_spec("tensor"))));
-}
-
-TEST("require that ranking expression can resolve to 'any' type") {
- TEST_DO(verify_output_type({{"a", "tensor(x{},y{})"}, {"b", "tensor"}}, "a*b",
- FeatureType::object(ValueType::from_spec("any"))));
-}
-
TEST("require that setup fails for incompatible types") {
TEST_DO(verify_setup_fail({{"a", "tensor(x{},y{})"}, {"b", "tensor(y[10],z{})"}}, "a*b"));
}
@@ -150,7 +141,7 @@ TEST("require that replaced expressions override result type") {
TEST_DO(verify_output_type({{"b", "tensor(z{})"}}, "foo*b*c",
FeatureType::number()));
TEST_DO(verify_output_type({{"b", "tensor(z{})"}}, "a*b*bar",
- FeatureType::object(ValueType::from_spec("tensor(x[])"))));
+ FeatureType::object(ValueType::from_spec("tensor(x[5])"))));
TEST_DO(verify_output_type({{"b", "tensor(z{})"}}, "foo*b*bar",
FeatureType::number()));
}
diff --git a/searchlib/src/tests/tensor/dense_tensor_store/dense_tensor_store_test.cpp b/searchlib/src/tests/tensor/dense_tensor_store/dense_tensor_store_test.cpp
index 9f47dede46a..1d80fec720a 100644
--- a/searchlib/src/tests/tensor/dense_tensor_store/dense_tensor_store_test.cpp
+++ b/searchlib/src/tests/tensor/dense_tensor_store/dense_tensor_store_test.cpp
@@ -60,34 +60,6 @@ TEST_F("require that we can store 1d bound tensor", Fixture("tensor(x[3])"))
add({{"x", 2}}, 5));
}
-TEST_F("require that we can store 1d un-bound tensor", Fixture("tensor(x[])"))
-{
- f.assertSetAndGetTensor(TensorSpec("tensor(x[3])").
- add({{"x", 0}}, 2).
- add({{"x", 1}}, 3).
- add({{"x", 2}}, 5));
-}
-
-TEST_F("require that un-bound dimension is concrete in returned 2d tensor", Fixture("tensor(x[3],y[])"))
-{
- f.assertSetAndGetTensor(TensorSpec("tensor(x[3],y[2])").
- add({{"x", 0}, {"y", 0}}, 2).
- add({{"x", 0}, {"y", 1}}, 3).
- add({{"x", 1}, {"y", 0}}, 5).
- add({{"x", 1}, {"y", 1}}, 7).
- add({{"x", 2}, {"y", 0}}, 11).
- add({{"x", 2}, {"y", 1}}, 13));
-}
-
-TEST_F("require that un-bound dimensions are concrete in returned 3d tensor", Fixture("tensor(x[],y[2],z[])"))
-{
- f.assertSetAndGetTensor(TensorSpec("tensor(x[1],y[2],z[2])").
- add({{"x", 0}, {"y", 0}, {"z", 0}}, 2).
- add({{"x", 0}, {"y", 0}, {"z", 1}}, 3).
- add({{"x", 0}, {"y", 1}, {"z", 0}}, 5).
- add({{"x", 0}, {"y", 1}, {"z", 1}}, 7));
-}
-
TEST_F("require that correct empty tensor is returned for 1d bound tensor", Fixture("tensor(x[3])"))
{
f.assertEmptyTensor(TensorSpec("tensor(x[3])").
@@ -96,21 +68,6 @@ TEST_F("require that correct empty tensor is returned for 1d bound tensor", Fixt
add({{"x", 2}}, 0));
}
-TEST_F("require that empty 2d tensor has size 1 in un-bound dimension", Fixture("tensor(x[3],y[])"))
-{
- f.assertEmptyTensor(TensorSpec("tensor(x[3],y[1])").
- add({{"x", 0}, {"y", 0}}, 0).
- add({{"x", 1}, {"y", 0}}, 0).
- add({{"x", 2}, {"y", 0}}, 0));
-}
-
-TEST_F("require that empty 3d tensor has size 1 in un-bound dimensions", Fixture("tensor(x[],y[2],z[])"))
-{
- f.assertEmptyTensor(TensorSpec("tensor(x[1],y[2],z[1])").
- add({{"x", 0}, {"y", 0}, {"z", 0}}, 0).
- add({{"x", 0}, {"y", 1}, {"z", 0}}, 0));
-}
-
void
assertArraySize(const vespalib::string &tensorType, uint32_t expArraySize) {
Fixture f(tensorType);
@@ -122,13 +79,7 @@ TEST("require that array size is calculated correctly")
TEST_DO(assertArraySize("tensor(x[1])", 32));
TEST_DO(assertArraySize("tensor(x[10])", 96));
TEST_DO(assertArraySize("tensor(x[3])", 32));
- TEST_DO(assertArraySize("tensor(x[3],y[])", 32));
- TEST_DO(assertArraySize("tensor(x[3],y[],z[])", 32));
- TEST_DO(assertArraySize("tensor(x[3],y[],z[],z2[])", 64));
TEST_DO(assertArraySize("tensor(x[10],y[10])", 800));
- TEST_DO(assertArraySize("tensor(x[])", 32));
- TEST_DO(assertArraySize("tensor(x[],x2[],x3[],x4[],x5[],x6[])", 32));
- TEST_DO(assertArraySize("tensor(x[],x2[],x3[],x4[],x5[],x6[],x7[])", 64));
}
TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/searchlib/src/vespa/searchlib/features/attributefeature.cpp b/searchlib/src/vespa/searchlib/features/attributefeature.cpp
index b3ebd0f3822..56d02ce6d4e 100644
--- a/searchlib/src/vespa/searchlib/features/attributefeature.cpp
+++ b/searchlib/src/vespa/searchlib/features/attributefeature.cpp
@@ -295,10 +295,13 @@ AttributeBlueprint::setup(const search::fef::IIndexEnvironment & env,
vespalib::string attrType = type::Attribute::lookup(env.getProperties(), _attrName);
if (!attrType.empty()) {
_tensorType = ValueType::from_spec(attrType);
+ if (_tensorType.is_error()) {
+ LOG(error, "%s: invalid type: '%s'", getName().c_str(), attrType.c_str());
+ }
}
- FeatureType output_type = _tensorType.is_tensor()
- ? FeatureType::object(_tensorType)
- : FeatureType::number();
+ FeatureType output_type = _tensorType.is_double()
+ ? FeatureType::number()
+ : FeatureType::object(_tensorType);
describeOutput("value", "The value of a single value attribute, "
"the value at the given index of an array attribute, "
"the given key of a weighted set attribute, or"
@@ -309,7 +312,7 @@ AttributeBlueprint::setup(const search::fef::IIndexEnvironment & env,
describeOutput("count", "Returns the number of elements in this array or weighted set attribute.");
}
env.hintAttributeAccess(_attrName);
- return true;
+ return !_tensorType.is_error();
}
search::fef::Blueprint::UP
diff --git a/searchlib/src/vespa/searchlib/features/constant_feature.cpp b/searchlib/src/vespa/searchlib/features/constant_feature.cpp
index 4d76512ab00..ced9d95fb33 100644
--- a/searchlib/src/vespa/searchlib/features/constant_feature.cpp
+++ b/searchlib/src/vespa/searchlib/features/constant_feature.cpp
@@ -63,8 +63,10 @@ ConstantBlueprint::setup(const IIndexEnvironment &env,
{
_key = params[0].getValue();
_value = env.getConstantValue(_key);
- if (!_value || _value->type().is_error()) {
+ if (!_value) {
LOG(error, "Constant '%s' not found", _key.c_str());
+ } else if (_value->type().is_error()) {
+ LOG(error, "Constant '%s' has invalid type", _key.c_str());
}
FeatureType output_type = _value ?
FeatureType::object(_value->type()) :
diff --git a/searchlib/src/vespa/searchlib/features/queryfeature.cpp b/searchlib/src/vespa/searchlib/features/queryfeature.cpp
index eb7eb427283..b9041901ced 100644
--- a/searchlib/src/vespa/searchlib/features/queryfeature.cpp
+++ b/searchlib/src/vespa/searchlib/features/queryfeature.cpp
@@ -98,12 +98,15 @@ QueryBlueprint::setup(const IIndexEnvironment &env, const ParameterList &params)
vespalib::string queryFeatureType = type::QueryFeature::lookup(env.getProperties(), _key);
if (!queryFeatureType.empty()) {
_valueType = ValueType::from_spec(queryFeatureType);
+ if (_valueType.is_error()) {
+ LOG(error, "%s: invalid type: '%s'", getName().c_str(), queryFeatureType.c_str());
+ }
}
- FeatureType output_type = _valueType.is_tensor()
- ? FeatureType::object(_valueType)
- : FeatureType::number();
+ FeatureType output_type = _valueType.is_double()
+ ? FeatureType::number()
+ : FeatureType::object(_valueType);
describeOutput("out", "The value looked up in query properties using the given key.", output_type);
- return true;
+ return !_valueType.is_error();
}
namespace {
diff --git a/searchlib/src/vespa/searchlib/features/rankingexpressionfeature.cpp b/searchlib/src/vespa/searchlib/features/rankingexpressionfeature.cpp
index 72865d042e7..b2c8c64d55a 100644
--- a/searchlib/src/vespa/searchlib/features/rankingexpressionfeature.cpp
+++ b/searchlib/src/vespa/searchlib/features/rankingexpressionfeature.cpp
@@ -239,9 +239,6 @@ RankingExpressionBlueprint::setup(const fef::IIndexEnvironment &env,
LOG(error, "rank expression contains type errors: %s\n", script.c_str());
return false;
}
- if (root_type.is_any()) {
- LOG(warning, "rank expression could produce run-time type errors: %s\n", script.c_str());
- }
auto compile_issues = CompiledFunction::detect_issues(rank_function);
auto interpret_issues = InterpretedFunction::detect_issues(rank_function);
if (do_compile && compile_issues && !interpret_issues) {