summaryrefslogtreecommitdiffstats
path: root/searchlib/src
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@broadpark.no>2020-02-20 14:28:50 +0100
committerTor Egge <Tor.Egge@broadpark.no>2020-02-20 14:31:49 +0100
commit62ec6891944aa21747a1723358dea0a7768ad0d3 (patch)
tree41bb64e22c0414766e7b043c7e28eb1383fd2bb3 /searchlib/src
parent769784afbc958ca051f3ad8c6983749c41c31854 (diff)
Fixup feature map after blueprint setup failure.
Diffstat (limited to 'searchlib/src')
-rw-r--r--searchlib/src/tests/fef/resolver/resolver_test.cpp21
-rw-r--r--searchlib/src/vespa/searchlib/fef/blueprintresolver.cpp14
2 files changed, 35 insertions, 0 deletions
diff --git a/searchlib/src/tests/fef/resolver/resolver_test.cpp b/searchlib/src/tests/fef/resolver/resolver_test.cpp
index 955c072810f..7591d028620 100644
--- a/searchlib/src/tests/fef/resolver/resolver_test.cpp
+++ b/searchlib/src/tests/fef/resolver/resolver_test.cpp
@@ -4,10 +4,13 @@
#include <vespa/searchlib/fef/fef.h>
#include <vespa/searchlib/fef/test/indexenvironment.h>
#include <vespa/searchlib/features/valuefeature.h>
+#include <vespa/searchlib/features/rankingexpressionfeature.h>
#include <vespa/log/log.h>
LOG_SETUP("resolver_test");
+using search::features::RankingExpressionBlueprint;
+
namespace search {
namespace fef {
@@ -58,6 +61,7 @@ class Test : public vespalib::TestApp {
private:
BlueprintFactory _factory;
void requireThatWeGetUniqueBlueprints();
+ void require_that_bad_input_is_handled();
public:
Test();
~Test();
@@ -69,6 +73,7 @@ Test::Test() :
{
_factory.addPrototype(Blueprint::SP(new BaseBlueprint()));
_factory.addPrototype(Blueprint::SP(new CombineBlueprint()));
+ _factory.addPrototype(std::make_shared<RankingExpressionBlueprint>());
}
Test::~Test() {}
@@ -85,12 +90,28 @@ Test::requireThatWeGetUniqueBlueprints()
EXPECT_TRUE(dynamic_cast<CombineBlueprint *>(spec[1].blueprint.get()) != NULL);
}
+void
+Test::require_that_bad_input_is_handled()
+{
+ test::IndexEnvironment ienv;
+ ienv.getProperties().add(indexproperties::eval::LazyExpressions::NAME, "false");
+ ienv.getProperties().add("rankingExpression(badinput).rankingScript", "base.foobad + base.bar");
+ BlueprintResolver::SP res(new BlueprintResolver(_factory, ienv));
+ res->addSeed("rankingExpression(badinput)");
+ EXPECT_FALSE(res->compile());
+ const BlueprintResolver::ExecutorSpecList & spec = res->getExecutorSpecs();
+ EXPECT_EQUAL(2u, spec.size());
+ EXPECT_TRUE(dynamic_cast<BaseBlueprint *>(spec[0].blueprint.get()) != nullptr);
+ EXPECT_TRUE(dynamic_cast<RankingExpressionBlueprint *>(spec[1].blueprint.get()) != nullptr);
+}
+
int
Test::Main()
{
TEST_INIT("resolver_test");
requireThatWeGetUniqueBlueprints();
+ require_that_bad_input_is_handled();
TEST_DONE();
}
diff --git a/searchlib/src/vespa/searchlib/fef/blueprintresolver.cpp b/searchlib/src/vespa/searchlib/fef/blueprintresolver.cpp
index cd2cd949a91..7b87486b995 100644
--- a/searchlib/src/vespa/searchlib/fef/blueprintresolver.cpp
+++ b/searchlib/src/vespa/searchlib/fef/blueprintresolver.cpp
@@ -88,6 +88,17 @@ struct Compiler : public Blueprint::DependencyHandler {
return FeatureRef();
}
+ void fixup_feature_map() {
+ auto itr = feature_map.begin();
+ while (itr != feature_map.end()) {
+ if (itr->second.executor >= spec_list.size()) {
+ itr = feature_map.erase(itr);
+ } else {
+ ++itr;
+ }
+ }
+ }
+
FeatureRef verify_type(const FeatureNameParser &parser, FeatureRef ref, Accept accept_type) {
const auto &spec = spec_list[ref.executor];
bool is_object = spec.output_types[ref.output];
@@ -110,13 +121,16 @@ struct Compiler : public Blueprint::DependencyHandler {
self().spec.blueprint->setName(parser.executorName());
self().spec.blueprint->attach_dependency_handler(*this);
if (!self().spec.blueprint->setup(index_env, parser.parameters())) {
+ fixup_feature_map();
return failed(parser.featureName(), "invalid parameters");
}
if (parser.output().empty() && self().spec.output_types.empty()) {
+ fixup_feature_map();
return failed(parser.featureName(), "has no output value");
}
const auto &feature = feature_map.find(parser.featureName());
if (feature == feature_map.end()) {
+ fixup_feature_map();
return failed(parser.featureName(),
vespalib::make_string("unknown output: '%s'", parser.output().c_str()));
}