diff options
author | Jon Bratseth <bratseth@gmail.com> | 2021-04-28 15:49:57 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@gmail.com> | 2021-04-28 15:49:57 +0200 |
commit | 2ee3e1d2e9fdda8d10a91e616e3a4f8d758d7dbe (patch) | |
tree | c20f09ad439cb4f2854a27b2a77dbd250c6b3b4d | |
parent | 357de578bc8d79c71ddb6bbbcf37d11d46902020 (diff) |
Use owner's dimensions in BackedOverridableQueryProfile
Use owner's dimensions rather than the backed's in
BackedObverridableQueryProfile. This matters when a profile
references a profile with different but overlapping dimensions
and both the owner and referred profile assigns values for
the same paths, within their respective dimension spaces.
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 86668fe3098..caa5357febe 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 @@ -947,10 +947,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 @@ -980,10 +976,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(); |