summaryrefslogtreecommitdiffstats
path: root/container-search
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@verizonmedia.com>2020-03-06 16:05:59 +0100
committerJon Bratseth <bratseth@verizonmedia.com>2020-03-06 16:05:59 +0100
commitc36e9392b5a7c397aee142737f477a54da9fd7b8 (patch)
tree69e47b00ee57f4026db921fd89c05e4360852f95 /container-search
parent16fee91e30976821b6bd3701219a2b014beab6d0 (diff)
Add temporary extra error info
Diffstat (limited to 'container-search')
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/Properties.java6
-rw-r--r--container-search/src/main/java/com/yahoo/search/searchers/ValidateNearestNeighborSearcher.java63
-rw-r--r--container-search/src/test/java/com/yahoo/search/searchers/ValidateNearestNeighborTestCase.java4
3 files changed, 62 insertions, 11 deletions
diff --git a/container-search/src/main/java/com/yahoo/search/query/Properties.java b/container-search/src/main/java/com/yahoo/search/query/Properties.java
index a1a70b4c3ba..a0cd4137e9f 100644
--- a/container-search/src/main/java/com/yahoo/search/query/Properties.java
+++ b/container-search/src/main/java/com/yahoo/search/query/Properties.java
@@ -30,8 +30,9 @@ public abstract class Properties extends com.yahoo.processing.request.Properties
return (Properties)super.clone();
}
- /** The query owning this property object.
- * Only guaranteed to work if this instance is accessible as query.properties()
+ /**
+ * Returns the query owning this property object.
+ * Only guaranteed to work if this instance is accessible as query.properties()
*/
public Query getParentQuery() {
if (chained() == null) {
@@ -48,4 +49,5 @@ public abstract class Properties extends com.yahoo.processing.request.Properties
if (chained() != null)
chained().setParentQuery(query);
}
+
}
diff --git a/container-search/src/main/java/com/yahoo/search/searchers/ValidateNearestNeighborSearcher.java b/container-search/src/main/java/com/yahoo/search/searchers/ValidateNearestNeighborSearcher.java
index ef46ee5e5ea..0f7f163dce0 100644
--- a/container-search/src/main/java/com/yahoo/search/searchers/ValidateNearestNeighborSearcher.java
+++ b/container-search/src/main/java/com/yahoo/search/searchers/ValidateNearestNeighborSearcher.java
@@ -8,9 +8,15 @@ import com.yahoo.prelude.query.Item;
import com.yahoo.prelude.query.NearestNeighborItem;
import com.yahoo.prelude.query.QueryCanonicalizer;
import com.yahoo.prelude.query.ToolBox;
+import com.yahoo.processing.request.CompoundName;
import com.yahoo.search.Query;
import com.yahoo.search.Result;
import com.yahoo.search.Searcher;
+import com.yahoo.search.query.profile.QueryProfileProperties;
+import com.yahoo.search.query.profile.compiled.CompiledQueryProfile;
+import com.yahoo.search.query.profile.types.FieldDescription;
+import com.yahoo.search.query.profile.types.QueryProfileFieldType;
+import com.yahoo.search.query.profile.types.QueryProfileType;
import com.yahoo.search.query.ranking.RankProperties;
import com.yahoo.search.result.ErrorMessage;
import com.yahoo.search.searchchain.Execution;
@@ -54,7 +60,7 @@ public class ValidateNearestNeighborSearcher extends Searcher {
}
private Optional<ErrorMessage> validate(Query query) {
- NNVisitor visitor = new NNVisitor(query.getRanking().getProperties(), validAttributes);
+ NNVisitor visitor = new NNVisitor(query.getRanking().getProperties(), validAttributes, query);
ToolBox.visit(visitor, query.getModel().getQueryTree().getRoot());
return visitor.errorMessage;
}
@@ -63,18 +69,20 @@ public class ValidateNearestNeighborSearcher extends Searcher {
public Optional<ErrorMessage> errorMessage = Optional.empty();
- private RankProperties rankProperties;
- private Map<String, TensorType> validAttributes;
+ private final RankProperties rankProperties;
+ private final Map<String, TensorType> validAttributes;
+ private final Query query;
- public NNVisitor(RankProperties rankProperties, Map<String, TensorType> validAttributes) {
+ public NNVisitor(RankProperties rankProperties, Map<String, TensorType> validAttributes, Query query) {
this.rankProperties = rankProperties;
this.validAttributes = validAttributes;
+ this.query = query;
}
@Override
public boolean visit(Item item) {
if (item instanceof NearestNeighborItem) {
- String error = validate((NearestNeighborItem) item);
+ String error = validate((NearestNeighborItem)item);
if (error != null)
errorMessage = Optional.of(ErrorMessage.createIllegalQuery(error));
}
@@ -105,8 +113,9 @@ public class ValidateNearestNeighborSearcher extends Searcher {
Object rankPropValue = rankPropValList.get(0);
if (! (rankPropValue instanceof Tensor)) {
- return item + " query tensor should be a tensor, was: " +
- (rankPropValue == null ? "null" : rankPropValue.getClass());
+ return item + " expected a query tensor but got " +
+ (rankPropValue == null ? "null" : rankPropValue.getClass()) +
+ resolvedTypeInfo();
}
String field = item.getIndexName();
@@ -125,6 +134,46 @@ public class ValidateNearestNeighborSearcher extends Searcher {
@Override
public void onExit() {}
+ // TODO: Remove
+ private String resolvedTypeInfo() {
+ StringBuilder b = new StringBuilder();
+ QueryProfileProperties properties = query.properties().getInstance(QueryProfileProperties.class);
+ if (properties == null) return b.toString();
+ CompiledQueryProfile profile = properties.getQueryProfile();
+ b.append(", profile: ").append(profile);
+
+ CompoundName name = new CompoundName("ranking.features.query(q_vec)");
+
+ if ( ! profile.getTypes().isEmpty()) {
+ QueryProfileType type = null;
+ for (int i = 0; i < name.size(); i++) {
+ if (type == null) // We're on the first iteration, or no type is explicitly specified
+ type = profile.getType(name.first(i), new HashMap<>());
+ if (type == null) continue;
+ String localName = name.get(i);
+ FieldDescription fieldDescription = type.getField(localName);
+ if (fieldDescription == null && type.isStrict())
+ throw new IllegalArgumentException("'" + localName + "' is not declared in " + type + ", and the type is strict");
+
+ // TODO: In addition to strictness, check legality along the way
+
+ if (fieldDescription != null) {
+ if (i == name.size() - 1) { // at the end of the path, check the assignment type
+ b.append(", field description: ").append(fieldDescription);
+ } else if (fieldDescription.getType() instanceof QueryProfileFieldType) {
+ // If a type is specified, use that instead of the type implied by the name
+ type = ((QueryProfileFieldType) fieldDescription.getType()).getQueryProfileType();
+ }
+ }
+
+ }
+ }
+ else {
+ b.append(", profile types is empty");
+ }
+ return b.toString();
+ }
+
}
}
diff --git a/container-search/src/test/java/com/yahoo/search/searchers/ValidateNearestNeighborTestCase.java b/container-search/src/test/java/com/yahoo/search/searchers/ValidateNearestNeighborTestCase.java
index 30a4943b24f..0abb8d281b4 100644
--- a/container-search/src/test/java/com/yahoo/search/searchers/ValidateNearestNeighborTestCase.java
+++ b/container-search/src/test/java/com/yahoo/search/searchers/ValidateNearestNeighborTestCase.java
@@ -164,9 +164,9 @@ public class ValidateNearestNeighborTestCase {
public void testQueryTensorWrongType() {
String q = makeQuery("dvector", "qvector");
Result r = doSearch(searcher, q, "tensor string");
- assertErrMsg(desc("dvector", "qvector", 1, "query tensor should be a tensor, was: class java.lang.String"), r);
+ assertErrMsg(desc("dvector", "qvector", 1, "expected a query tensor but got class java.lang.String"), r);
r = doSearch(searcher, q, null);
- assertErrMsg(desc("dvector", "qvector", 1, "query tensor should be a tensor, was: null"), r);
+ assertErrMsg(desc("dvector", "qvector", 1, "expected a query tensor but got null"), r);
}
@Test