aboutsummaryrefslogtreecommitdiffstats
path: root/container-search/src/main/java/com/yahoo/search
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@gmail.com>2023-01-25 21:07:20 +0100
committerJon Bratseth <bratseth@gmail.com>2023-01-25 21:07:20 +0100
commit8509fd404dbfe90349072bfbe5e7cc7164023725 (patch)
treec1d55c230ffed72c75f80a644f5e1b40daa07734 /container-search/src/main/java/com/yahoo/search
parenta0deac28d2261734f6c3be07c4a4041b0f8d52af (diff)
Validate rank profiles early
Diffstat (limited to 'container-search/src/main/java/com/yahoo/search')
-rw-r--r--container-search/src/main/java/com/yahoo/search/schema/RankProfile.java18
-rw-r--r--container-search/src/main/java/com/yahoo/search/schema/Schema.java4
-rw-r--r--container-search/src/main/java/com/yahoo/search/schema/SchemaInfo.java29
3 files changed, 38 insertions, 13 deletions
diff --git a/container-search/src/main/java/com/yahoo/search/schema/RankProfile.java b/container-search/src/main/java/com/yahoo/search/schema/RankProfile.java
index 39d4a389e6f..85bb3915975 100644
--- a/container-search/src/main/java/com/yahoo/search/schema/RankProfile.java
+++ b/container-search/src/main/java/com/yahoo/search/schema/RankProfile.java
@@ -21,6 +21,9 @@ public class RankProfile {
private final boolean hasRankFeatures;
private final Map<String, TensorType> inputs;
+ // Assigned when this is added to a schema
+ private Schema schema = null;
+
private RankProfile(Builder builder) {
this.name = builder.name;
this.hasSummaryFeatures = builder.hasSummaryFeatures;
@@ -30,6 +33,16 @@ public class RankProfile {
public String name() { return name; }
+ /** Returns the schema owning this, or null if this is not added to a schema */
+ public Schema schema() { return schema; }
+
+ void setSchema(Schema schema) {
+ if ( this.schema != null)
+ throw new IllegalStateException("Cannot add rank profile '" + name + "' to schema '" + schema.name() +
+ "' as it is already added to schema '" + this.schema.name() + "'");
+ this.schema = schema;
+ }
+
/** Returns true if this rank profile has summary features. */
public boolean hasSummaryFeatures() { return hasSummaryFeatures; }
@@ -42,8 +55,7 @@ public class RankProfile {
@Override
public boolean equals(Object o) {
if (o == this) return true;
- if ( ! (o instanceof RankProfile)) return false;
- RankProfile other = (RankProfile)o;
+ if ( ! (o instanceof RankProfile other)) return false;
if ( ! other.name.equals(this.name)) return false;
if ( other.hasSummaryFeatures != this.hasSummaryFeatures) return false;
if ( other.hasRankFeatures != this.hasRankFeatures) return false;
@@ -58,7 +70,7 @@ public class RankProfile {
@Override
public String toString() {
- return "rank profile '" + name + "'";
+ return "rank profile '" + name + "'" + (schema == null ? "" : " in " + schema);
}
public static class Builder {
diff --git a/container-search/src/main/java/com/yahoo/search/schema/Schema.java b/container-search/src/main/java/com/yahoo/search/schema/Schema.java
index 2ab5a30fbd7..c20aa1e81bd 100644
--- a/container-search/src/main/java/com/yahoo/search/schema/Schema.java
+++ b/container-search/src/main/java/com/yahoo/search/schema/Schema.java
@@ -27,6 +27,7 @@ public class Schema {
this.name = builder.name;
this.rankProfiles = Collections.unmodifiableMap(builder.rankProfiles);
this.documentSummaries = Collections.unmodifiableMap(builder.documentSummaries);
+ rankProfiles.values().forEach(rankProfile -> rankProfile.setSchema(this));
}
public String name() { return name; }
@@ -36,8 +37,7 @@ public class Schema {
@Override
public boolean equals(Object o) {
if (o == this) return true;
- if ( ! (o instanceof Schema)) return false;
- Schema other = (Schema)o;
+ if ( ! (o instanceof Schema other)) return false;
if ( ! other.name.equals(this.name)) return false;
if ( ! other.rankProfiles.equals(this.rankProfiles)) return false;
if ( ! other.documentSummaries.equals(this.documentSummaries)) return false;
diff --git a/container-search/src/main/java/com/yahoo/search/schema/SchemaInfo.java b/container-search/src/main/java/com/yahoo/search/schema/SchemaInfo.java
index 6482070bc03..d29964ea9c5 100644
--- a/container-search/src/main/java/com/yahoo/search/schema/SchemaInfo.java
+++ b/container-search/src/main/java/com/yahoo/search/schema/SchemaInfo.java
@@ -9,6 +9,7 @@ import com.yahoo.search.config.IndexInfoConfig;
import com.yahoo.search.config.SchemaInfoConfig;
import com.yahoo.tensor.TensorType;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
@@ -17,6 +18,7 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.stream.Collectors;
/**
* Information about all the schemas configured in the application this container is a part of.
@@ -124,6 +126,13 @@ public class SchemaInfo {
return schemas.stream().filter(schema -> names.contains(schema.name())).toList();
}
+ private List<RankProfile> profilesNamed(String name) {
+ return schemas.stream()
+ .filter(schema -> schema.rankProfiles().containsKey(name))
+ .map(schema -> schema.rankProfiles().get(name))
+ .toList();
+ }
+
/**
* Returns the type of the given rank feature name in the given profile,
* if it can be uniquely determined.
@@ -131,23 +140,27 @@ public class SchemaInfo {
* @param rankFeature the rank feature name, a string on the form "query(name)"
* @param rankProfile the name of the rank profile in which to locate the input declaration
* @return the type of the declared input, or null if it is not declared or the rank profile is not found
- * @throws IllegalArgumentException if the feature is declared in this rank profile in multiple schemas
+ * @throws IllegalArgumentException if the given rank profile does not exist in any schema, or the
+ * feature is declared in this rank profile in multiple schemas
* of this session with conflicting types
*/
public TensorType rankProfileInput(String rankFeature, String rankProfile) {
+ if (schemas.isEmpty()) return null; // no matching schemas - validated elsewhere
+ List<RankProfile> profiles = profilesNamed(rankProfile);
+ if (profiles.isEmpty())
+ throw new IllegalArgumentException("No profile named '" + rankProfile + "' exists in schemas [" +
+ schemas.stream().map(Schema::name).collect(Collectors.joining(", ")) + "]");
TensorType foundType = null;
- Schema declaringSchema = null;
- for (Schema schema : schemas) {
- RankProfile profile = schema.rankProfiles().get(rankProfile);
- if (profile == null) continue;
+ RankProfile declaringProfile = null;
+ for (RankProfile profile : profiles) {
TensorType newlyFoundType = profile.inputs().get(rankFeature);
if (newlyFoundType == null) continue;
if (foundType != null && ! newlyFoundType.equals(foundType))
throw new IllegalArgumentException("Conflicting input type declarations for '" + rankFeature + "': " +
- "Declared as " + foundType + " in " + profile + " in " + declaringSchema +
- ", and as " + newlyFoundType + " in " + profile + " in " + schema);
+ "Declared as " + foundType + " in " + declaringProfile +
+ ", and as " + newlyFoundType + " in " + profile);
foundType = newlyFoundType;
- declaringSchema = schema;
+ declaringProfile = profile;
}
return foundType;
}