summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@oath.com>2021-04-28 20:52:15 +0200
committerGitHub <noreply@github.com>2021-04-28 20:52:15 +0200
commite0c3677ad6674b8452ba07e85e9b07fa7858b73e (patch)
tree4caa387b0fe97af7dce997abad839625d138ebbc
parentc1f94ef7e3f9cdfc2fbcb65812c95c742aed3c56 (diff)
parent2ee3e1d2e9fdda8d10a91e616e3a4f8d758d7dbe (diff)
Merge pull request #17641 from vespa-engine/bratseth/query-profile-references
Use owner's dimensions in BackedOverridableQueryProfile
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/search/DeclaredQueryProfileVariants.java20
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/search/QueryProfiles.java19
-rw-r--r--config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java8
-rw-r--r--config-model/src/test/java/com/yahoo/searchdefinition/processing/TensorFieldTestCase.java1
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/container/search/test/QueryProfilesTestCase.java73
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/ml/ModelEvaluationTest.java1
-rw-r--r--container-search/src/main/java/com/yahoo/search/federation/FederationSearcher.java1
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/BackedOverridableQueryProfile.java18
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/QueryProfile.java11
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVariant.java4
-rw-r--r--container-search/src/test/java/com/yahoo/search/query/profile/test/QueryProfileVariantsTestCase.java31
11 files changed, 122 insertions, 65 deletions
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/search/DeclaredQueryProfileVariants.java b/config-model/src/main/java/com/yahoo/vespa/model/container/search/DeclaredQueryProfileVariants.java
index c3fea385e8d..ab9f51ff0ad 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/search/DeclaredQueryProfileVariants.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/search/DeclaredQueryProfileVariants.java
@@ -15,7 +15,7 @@ import java.util.*;
*/
public class DeclaredQueryProfileVariants {
- private final Map<String, VariantQueryProfile> variantQueryProfiles =new LinkedHashMap<>();
+ private final Map<String, VariantQueryProfile> variantQueryProfiles = new LinkedHashMap<>();
public DeclaredQueryProfileVariants(QueryProfile profile) {
// Recreates the declared view (settings per set of dimensions)
@@ -67,26 +67,26 @@ public class DeclaredQueryProfileVariants {
// having the variants
for (Map.Entry<String,Object> entry : profile.declaredContent().entrySet()) {
if ( ! (entry.getValue() instanceof QueryProfile)) continue;
- QueryProfile subProfile=(QueryProfile)entry.getValue();
+ QueryProfile subProfile = (QueryProfile)entry.getValue();
// Export if defined implicitly in this, or if this contains overrides
if (!subProfile.isExplicit() || subProfile instanceof OverridableQueryProfile) {
- String entryPrefix=prefix + entry.getKey() + ".";
- dereferenceCompoundedVariants(subProfile.getVariants(),entryPrefix);
- dereferenceCompoundedVariants(subProfile,entryPrefix);
+ String entryPrefix = prefix + entry.getKey() + ".";
+ dereferenceCompoundedVariants(subProfile.getVariants(), entryPrefix);
+ dereferenceCompoundedVariants(subProfile, entryPrefix);
}
}
- if (profile.getVariants()==null) return;
+ if (profile.getVariants() == null) return;
// We need to do the same dereferencing to overridables pointed to by variants of this
for (Map.Entry<String,QueryProfileVariants.FieldValues> fieldValueEntry : profile.getVariants().getFieldValues().entrySet()) {
for (QueryProfileVariants.FieldValue fieldValue : fieldValueEntry.getValue().asList()) {
if ( ! (fieldValue.getValue() instanceof QueryProfile)) continue;
- QueryProfile subProfile=(QueryProfile)fieldValue.getValue();
+ QueryProfile subProfile = (QueryProfile)fieldValue.getValue();
// Export if defined implicitly in this, or if this contains overrides
if (!subProfile.isExplicit() || subProfile instanceof OverridableQueryProfile) {
- String entryPrefix=prefix + fieldValueEntry.getKey() + ".";
- dereferenceCompoundedVariants(subProfile.getVariants(),entryPrefix);
- dereferenceCompoundedVariants(subProfile,entryPrefix);
+ String entryPrefix = prefix + fieldValueEntry.getKey() + ".";
+ dereferenceCompoundedVariants(subProfile.getVariants(), entryPrefix);
+ dereferenceCompoundedVariants(subProfile, entryPrefix);
}
}
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/search/QueryProfiles.java b/config-model/src/main/java/com/yahoo/vespa/model/container/search/QueryProfiles.java
index 3227646041a..e5ed20e19ec 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/search/QueryProfiles.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/search/QueryProfiles.java
@@ -65,12 +65,13 @@ public class QueryProfiles implements Serializable, QueryProfilesConfig.Producer
if ( registry.getTypeRegistry().hasApplicationTypes() && registry.allComponents().isEmpty()) {
logger.logApplicationPackage(Level.WARNING, "This application define query profile types, but has " +
- "no query profiles referencing them so they have no effect. " +
- (tensorFields.isEmpty()
- ? ""
- : "In particular, the tensors (" + String.join(", ", tensorFields) +
- ") will be interpreted as strings, not tensors if sent in requests. ") +
- "See https://docs.vespa.ai/en/query-profiles.html");
+ "no query profiles referencing them so they have no effect. " +
+ (tensorFields.isEmpty() ? ""
+ : "In particular, the tensors (" +
+ String.join(", ", tensorFields) +
+ ") will be interpreted as strings, " +
+ "not tensors if sent in requests. ") +
+ "See https://docs.vespa.ai/en/query-profiles.html");
}
}
@@ -100,7 +101,7 @@ public class QueryProfiles implements Serializable, QueryProfilesConfig.Producer
for (QueryProfile inherited : profile.inherited())
qB.inherit(inherited.getId().stringValue());
- if (profile.getVariants()!=null) {
+ if (profile.getVariants() != null) {
for (String dimension : profile.getVariants().getDimensions())
qB.dimensions(dimension);
}
@@ -180,7 +181,7 @@ public class QueryProfiles implements Serializable, QueryProfilesConfig.Producer
QueryProfilesConfig.Queryprofile.Queryprofilevariant.Reference.Builder refB = new QueryProfilesConfig.Queryprofile.Queryprofilevariant.Reference.Builder();
createVariantReferenceFieldConfig(refB, fullName, ((BackedOverridableQueryProfile) subProfile).getBacking().getId().stringValue());
qpB.reference(refB);
- addVariantFieldChildren(qpB, subProfile,fullName + ".");
+ addVariantFieldChildren(qpB, subProfile, fullName + ".");
}
}
else { // a primitive
@@ -208,7 +209,7 @@ public class QueryProfiles implements Serializable, QueryProfilesConfig.Producer
}
qB.queryprofilevariant(varB);
}
- }
+ }
private void createReferenceFieldConfig(QueryProfilesConfig.Queryprofile.Reference.Builder refB, QueryProfile profile,
String fullName, String localName, String stringValue) {
diff --git a/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java b/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java
index 13c0b1e8256..10019b00f61 100644
--- a/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java
+++ b/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java
@@ -954,10 +954,6 @@ public class ModelProvisioningTest {
assertEquals("1|*", cluster.getRootGroup().getPartitions().get());
assertEquals(0, cluster.getRootGroup().getNodes().size());
assertEquals(2, cluster.getRootGroup().getSubgroups().size());
- System.out.println("Nodes in group 0: ");
- cluster.getRootGroup().getSubgroups().get(0).getNodes().forEach(n -> System.out.println(" " + n));
- System.out.println("Nodes in group 1: ");
- cluster.getRootGroup().getSubgroups().get(1).getNodes().forEach(n -> System.out.println(" " + n));
}
@Test
@@ -987,10 +983,6 @@ public class ModelProvisioningTest {
assertEquals("1|*", cluster.getRootGroup().getPartitions().get());
assertEquals(0, cluster.getRootGroup().getNodes().size());
assertEquals(2, cluster.getRootGroup().getSubgroups().size());
- System.out.println("Nodes in group 0: ");
- cluster.getRootGroup().getSubgroups().get(0).getNodes().forEach(n -> System.out.println(" " + n));
- System.out.println("Nodes in group 1: ");
- cluster.getRootGroup().getSubgroups().get(1).getNodes().forEach(n -> System.out.println(" " + n));
}
@Test
diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/processing/TensorFieldTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/processing/TensorFieldTestCase.java
index 84ddf4f2d51..cbe748fb5d8 100644
--- a/config-model/src/test/java/com/yahoo/searchdefinition/processing/TensorFieldTestCase.java
+++ b/config-model/src/test/java/com/yahoo/searchdefinition/processing/TensorFieldTestCase.java
@@ -143,7 +143,6 @@ public class TensorFieldTestCase {
private void assertHnswIndexParams(String indexSpec, int maxLinksPerNode, int neighborsToExploreAtInsert) throws ParseException {
var sd = getSdWithIndexSpec(indexSpec);
- System.out.println(sd);
var search = createFromString(sd).getSearch();
var attr = search.getAttribute("t1");
var params = attr.hnswIndexParams();
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/search/test/QueryProfilesTestCase.java b/config-model/src/test/java/com/yahoo/vespa/model/container/search/test/QueryProfilesTestCase.java
index fc6c5aeb387..1a0d8fba606 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/container/search/test/QueryProfilesTestCase.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/container/search/test/QueryProfilesTestCase.java
@@ -6,7 +6,9 @@ import com.yahoo.search.Query;
import com.yahoo.search.query.profile.DimensionValues;
import com.yahoo.search.query.profile.QueryProfile;
import com.yahoo.search.query.profile.QueryProfileRegistry;
+import com.yahoo.search.query.profile.QueryProfileVariant;
import com.yahoo.search.query.profile.compiled.CompiledQueryProfile;
+import com.yahoo.search.query.profile.compiled.CompiledQueryProfileRegistry;
import com.yahoo.search.query.profile.config.QueryProfileConfigurer;
import com.yahoo.search.query.profile.config.QueryProfileXMLReader;
import com.yahoo.search.query.profile.types.FieldDescription;
@@ -36,6 +38,39 @@ public class QueryProfilesTestCase {
private final static String root="src/test/java/com/yahoo/vespa/model/container/search/test/";
@Test
+ public void testVariantReference() {
+ QueryProfileRegistry registry = new QueryProfileRegistry();
+
+ QueryProfile parent = new QueryProfile("parent");
+ parent.set("b", 48, registry);
+ registry.register(parent);
+
+ QueryProfile referenced = new QueryProfile("referenced");
+ referenced.addInherited(parent);
+ referenced.setDimensions(new String[] { "d2", "d3" });
+ registry.register(referenced);
+
+ QueryProfile base = new QueryProfile("base");
+ base.setDimensions(new String[] { "d1", "d2", "d3" });
+ base.set("a", referenced, new String[] { null, null, "d3-val" }, registry);
+ base.set("a.b", 1, new String[] { null, null, "d3-val" }, registry);
+ QueryProfileVariant aVariants = base.getVariants().getVariants().get(0);
+ QueryProfile a = (QueryProfile)aVariants.values().get("a");
+ assertEquals("[d1, d2, d3]", a.getDimensions().toString());
+ registry.register(base);
+
+ QueryProfiles profiles = new QueryProfiles(registry, new TestableDeployLogger());
+ QueryProfileRegistry registryFromConfig = QueryProfileConfigurer.createFromConfig(profiles.getConfig());
+ var directValue = registry.findQueryProfile("base")
+ .get("a.b",
+ new String[] { "default", null, "d3-val"});
+ var throughConfigValue = registryFromConfig.findQueryProfile("base")
+ .get("a.b",
+ new String[] { "default", null, "d3-val"});
+ assertEquals(directValue.toString(), throughConfigValue.toString());
+ }
+
+ @Test
public void testVariants() {
QueryProfileRegistry registry = new QueryProfileXMLReader().read(root + "variants");
QueryProfiles profiles = new QueryProfiles(registry, new TestableDeployLogger());
@@ -57,40 +92,40 @@ public class QueryProfilesTestCase {
@Test
public void testQueryProfiles() throws IOException {
- final boolean mandatory=true;
- final boolean overridable=true;
- QueryProfileRegistry registry=new QueryProfileRegistry();
- QueryProfileTypeRegistry typeRegistry=registry.getTypeRegistry();
+ final boolean mandatory = true;
+ final boolean overridable = true;
+ QueryProfileRegistry registry = new QueryProfileRegistry();
+ QueryProfileTypeRegistry typeRegistry = registry.getTypeRegistry();
- QueryProfileType userType=new QueryProfileType("user");
+ QueryProfileType userType = new QueryProfileType("user");
userType.setStrict(true);
- userType.addField(new FieldDescription("robot", FieldType.fromString("boolean",typeRegistry), "machine automaton", mandatory, !overridable));
- userType.addField(new FieldDescription("ads", FieldType.fromString("string",typeRegistry), mandatory, overridable));
- userType.addField(new FieldDescription("age", FieldType.fromString("integer",typeRegistry), !mandatory, overridable));
+ userType.addField(new FieldDescription("robot", FieldType.fromString("boolean", typeRegistry), "machine automaton", mandatory, !overridable));
+ userType.addField(new FieldDescription("ads", FieldType.fromString("string", typeRegistry), mandatory, overridable));
+ userType.addField(new FieldDescription("age", FieldType.fromString("integer", typeRegistry), !mandatory, overridable));
typeRegistry.register(userType);
- QueryProfileType rootType=new QueryProfileType("root");
- QueryProfileType nativeProfile=typeRegistry.getComponent("native");
+ QueryProfileType rootType = new QueryProfileType("root");
+ QueryProfileType nativeProfile = typeRegistry.getComponent("native");
assertNotNull(nativeProfile);
assertTrue(nativeProfile.isBuiltin());
rootType.inherited().add(nativeProfile);
rootType.setMatchAsPath(true);
- rootType.addField(new FieldDescription("user", FieldType.fromString("query-profile:user",typeRegistry), mandatory, overridable));
+ rootType.addField(new FieldDescription("user", FieldType.fromString("query-profile:user", typeRegistry), mandatory, overridable));
typeRegistry.register(rootType);
- QueryProfileType marketType=new QueryProfileType("market");
+ QueryProfileType marketType = new QueryProfileType("market");
marketType.inherited().add(rootType);
- marketType.addField(new FieldDescription("market", FieldType.fromString("string",typeRegistry), !mandatory, !overridable));
+ marketType.addField(new FieldDescription("market", FieldType.fromString("string", typeRegistry), !mandatory, !overridable));
typeRegistry.register(marketType);
- QueryProfile defaultProfile=new QueryProfile("default");
+ QueryProfile defaultProfile = new QueryProfile("default");
defaultProfile.set("ranking","production23", registry);
defaultProfile.set("representation.defaultIndex", "title", registry);
defaultProfile.setOverridable("representation.defaultIndex", false, DimensionValues.empty);
registry.register(defaultProfile);
- QueryProfile test=new QueryProfile("test");
- test.set("tracelevel",2,registry);
+ QueryProfile test = new QueryProfile("test");
+ test.set("tracelevel",2, registry);
registry.register(test);
QueryProfile genericUser = new QueryProfile("genericUser");
@@ -110,11 +145,11 @@ public class QueryProfilesTestCase {
root.set("defaultage", "7d", registry);
registry.register(root);
- QueryProfile marketUser=new QueryProfile("marketUser");
+ QueryProfile marketUser = new QueryProfile("marketUser");
marketUser.setType(userType);
marketUser.addInherited(genericUser);
- marketUser.set("ads","none",registry);
- marketUser.set("age",25,registry);
+ marketUser.set("ads","none", registry);
+ marketUser.set("age",25, registry);
registry.register(marketUser);
QueryProfile market = new QueryProfile("root/market");
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/ml/ModelEvaluationTest.java b/config-model/src/test/java/com/yahoo/vespa/model/ml/ModelEvaluationTest.java
index 1aaa1669377..fc6a4ee2783 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/ml/ModelEvaluationTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/ml/ModelEvaluationTest.java
@@ -90,7 +90,6 @@ public class ModelEvaluationTest {
RankProfilesConfig.Builder b = new RankProfilesConfig.Builder();
cluster.getConfig(b);
RankProfilesConfig config = new RankProfilesConfig(b);
- // System.out.println(config);
RankingConstantsConfig.Builder cb = new RankingConstantsConfig.Builder();
cluster.getConfig(cb);
diff --git a/container-search/src/main/java/com/yahoo/search/federation/FederationSearcher.java b/container-search/src/main/java/com/yahoo/search/federation/FederationSearcher.java
index 8d1f8212dbf..f6bf91f5f85 100644
--- a/container-search/src/main/java/com/yahoo/search/federation/FederationSearcher.java
+++ b/container-search/src/main/java/com/yahoo/search/federation/FederationSearcher.java
@@ -303,7 +303,6 @@ public class FederationSearcher extends ForkingSearcher {
Object value = getSourceOrProviderProperty(original, key, sourceName, providerName, window.get(key));
if (value != null)
outgoing.properties().set(key, value);
- if (value != null) System.out.println("Setting " + key + " = " + value);
}
}
}
diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/BackedOverridableQueryProfile.java b/container-search/src/main/java/com/yahoo/search/query/profile/BackedOverridableQueryProfile.java
index 0bb36d87f64..9eab6629a45 100644
--- a/container-search/src/main/java/com/yahoo/search/query/profile/BackedOverridableQueryProfile.java
+++ b/container-search/src/main/java/com/yahoo/search/query/profile/BackedOverridableQueryProfile.java
@@ -31,7 +31,7 @@ public class BackedOverridableQueryProfile extends OverridableQueryProfile imple
* @param backingProfile the backing profile, which is assumed read only, never null
*/
public BackedOverridableQueryProfile(QueryProfile backingProfile) {
- Validator.ensureNotNull("An overridable query profile must be backed by a real query profile",backingProfile);
+ Validator.ensureNotNull("An overridable query profile must be backed by a real query profile", backingProfile);
setType(backingProfile.getType());
this.backingProfile = backingProfile;
}
@@ -49,7 +49,7 @@ public class BackedOverridableQueryProfile extends OverridableQueryProfile imple
protected Object localLookup(String localName, DimensionBinding dimensionBinding) {
Object valueInThis = super.localLookup(localName, dimensionBinding);
if (valueInThis != null) return valueInThis;
- return backingProfile.localLookup(localName, dimensionBinding);
+ return backingProfile.localLookup(localName, dimensionBinding.createFor(backingProfile.getDimensions()));
}
protected Boolean isLocalInstanceOverridable(String localName) {
@@ -88,17 +88,17 @@ public class BackedOverridableQueryProfile extends OverridableQueryProfile imple
}
@Override
- protected void visitVariants(boolean allowContent,QueryProfileVisitor visitor,DimensionBinding dimensionBinding) {
+ protected void visitVariants(boolean allowContent, QueryProfileVisitor visitor, DimensionBinding dimensionBinding) {
super.visitVariants(allowContent, visitor, dimensionBinding);
if (visitor.isDone()) return;
- backingProfile.visitVariants(allowContent, visitor, dimensionBinding);
+ backingProfile.visitVariants(allowContent, visitor, dimensionBinding.createFor(backingProfile.getDimensions()));
}
@Override
protected void visitInherited(boolean allowContent, QueryProfileVisitor visitor, DimensionBinding dimensionBinding, QueryProfile owner) {
super.visitInherited(allowContent, visitor, dimensionBinding, owner);
if (visitor.isDone()) return;
- backingProfile.visitInherited(allowContent, visitor, dimensionBinding,owner);
+ backingProfile.visitInherited(allowContent, visitor, dimensionBinding.createFor(backingProfile.getDimensions()), owner);
}
/** Returns a value from the content of this: The value in this, or the value from the backing if not set in this */
@@ -113,12 +113,12 @@ public class BackedOverridableQueryProfile extends OverridableQueryProfile imple
* All the values in this, and all values in the backing where an overriding value is not set in this
*/
@Override
- protected Map<String,Object> getContent() {
- Map<String,Object> thisContent=super.getContent();
- Map<String,Object> backingContent=backingProfile.getContent();
+ protected Map<String, Object> getContent() {
+ Map<String,Object> thisContent = super.getContent();
+ Map<String,Object> backingContent = backingProfile.getContent();
if (thisContent.isEmpty()) return backingContent; // Shortcut
if (backingContent.isEmpty()) return thisContent; // Shortcut
- Map<String,Object> content=new HashMap<>(backingContent);
+ Map<String, Object> content = new HashMap<>(backingContent);
content.putAll(thisContent);
return content;
}
diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfile.java b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfile.java
index 4371955ae63..d3da2fd076a 100644
--- a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfile.java
+++ b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfile.java
@@ -604,7 +604,7 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable
}
/** Sets the value of a node in <i>this</i> profile - the local name given must not be nested (contain dots) */
- protected QueryProfile setLocalNode(String localName, Object value,QueryProfileType parentType,
+ protected QueryProfile setLocalNode(String localName, Object value, QueryProfileType parentType,
DimensionBinding dimensionBinding, QueryProfileRegistry registry) {
if (parentType != null && type == null && ! isFrozen())
type = parentType;
@@ -622,9 +622,10 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable
static Object combineValues(Object newValue, Object existingValue) {
if (newValue instanceof QueryProfile) {
QueryProfile newProfile = (QueryProfile)newValue;
- if ( existingValue == null || ! (existingValue instanceof QueryProfile)) {
- if (!isModifiable(newProfile))
+ if ( ! (existingValue instanceof QueryProfile)) {
+ if ( ! isModifiable(newProfile)) {
newProfile = new BackedOverridableQueryProfile(newProfile); // Make the query profile reference overridable
+ }
newProfile.value = existingValue;
return newProfile;
}
@@ -829,7 +830,6 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable
validateName(localName);
value = convertToSubstitutionString(value);
-
if (dimensionBinding.isNull()) {
Object combinedValue = value instanceof QueryProfile
? combineValues(value, content == null ? null : content.get(localName))
@@ -838,9 +838,8 @@ public class QueryProfile extends FreezableSimpleComponent implements Cloneable
content.put(localName, combinedValue);
}
else {
- if (variants == null) {
+ if (variants == null)
variants = new QueryProfileVariants(dimensionBinding.getDimensions(), this);
- }
variants.set(localName, dimensionBinding.getValues(), value);
}
}
diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVariant.java b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVariant.java
index f6c43eab8a0..855befad658 100644
--- a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVariant.java
+++ b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVariant.java
@@ -37,7 +37,7 @@ public class QueryProfileVariant implements Cloneable, Comparable<QueryProfileVa
* Returns the live reference to the values of this. This may be modified
* if this is not frozen.
*/
- public Map<String,Object> values() {
+ public Map<String, Object> values() {
if (values == null) {
if (frozen)
return Collections.emptyMap();
@@ -68,6 +68,8 @@ public class QueryProfileVariant implements Cloneable, Comparable<QueryProfileVa
Object oldValue = values.get(key);
Object combinedOrNull = QueryProfile.combineValues(newValue, oldValue);
+ if (combinedOrNull instanceof BackedOverridableQueryProfile) // Use the owner's, not the referenced dimensions
+ ((QueryProfile) combinedOrNull).setDimensions(owner.getDimensions().toArray(new String[0]));
if (combinedOrNull != null)
values.put(key, combinedOrNull);
return combinedOrNull;
diff --git a/container-search/src/test/java/com/yahoo/search/query/profile/test/QueryProfileVariantsTestCase.java b/container-search/src/test/java/com/yahoo/search/query/profile/test/QueryProfileVariantsTestCase.java
index 89217bb7f0c..a592d40d2e9 100644
--- a/container-search/src/test/java/com/yahoo/search/query/profile/test/QueryProfileVariantsTestCase.java
+++ b/container-search/src/test/java/com/yahoo/search/query/profile/test/QueryProfileVariantsTestCase.java
@@ -10,6 +10,7 @@ import com.yahoo.search.query.profile.BackedOverridableQueryProfile;
import com.yahoo.search.query.profile.QueryProfile;
import com.yahoo.search.query.profile.QueryProfileProperties;
import com.yahoo.search.query.profile.QueryProfileRegistry;
+import com.yahoo.search.query.profile.QueryProfileVariant;
import com.yahoo.search.query.profile.compiled.CompiledQueryProfile;
import com.yahoo.search.query.profile.compiled.CompiledQueryProfileRegistry;
import com.yahoo.search.query.profile.compiled.ValueWithSource;
@@ -103,6 +104,36 @@ public class QueryProfileVariantsTestCase {
cRegistry.getComponent("test").get("a.b", Map.of("d1", "d1v")));
}
+ /**
+ * Tests referencing a variant which modifies the dimension set,
+ * and also setting a value within that variants subspace.
+ */
+ @Test
+ public void testVariantReference() {
+ QueryProfileRegistry registry = new QueryProfileRegistry();
+
+ QueryProfile parent = new QueryProfile("parent");
+ parent.set("b", 48, registry);
+ registry.register(parent);
+
+ QueryProfile referenced = new QueryProfile("referenced");
+ referenced.addInherited(parent);
+ referenced.setDimensions(new String[] {"d2", "d3"});
+ registry.register(referenced);
+
+ QueryProfile base = new QueryProfile("base");
+ base.setDimensions(new String[]{"d1", "d2", "d3"});
+ base.set("a", referenced, new String[] {null, null, "d3-val"}, registry);
+ assertEquals("Variant dimensions are not overridden by the referenced dimensions",
+ "[d1, d2, d3]",
+ ((QueryProfile)base.getVariants().getVariants().get(0).values().get("a")).getDimensions().toString());
+ base.set("a.b", 1, new String[] {null, null, "d3-val"}, registry);
+ QueryProfileVariant aVariants = base.getVariants().getVariants().get(0);
+ assertEquals("Variant dimensions are not overridden by the referenced dimensions",
+ "[d1, d2, d3]",
+ ((QueryProfile)base.getVariants().getVariants().get(0).values().get("a")).getDimensions().toString());
+ }
+
@Test
public void testReference() {
QueryProfileRegistry registry = new QueryProfileRegistry();