aboutsummaryrefslogtreecommitdiffstats
path: root/container-search
diff options
context:
space:
mode:
authorGeir Storli <geirst@oath.com>2018-09-04 15:24:34 +0000
committerGeir Storli <geirst@oath.com>2018-09-04 15:34:45 +0000
commitea78663a3544923aed4251f04ad05564b659b3db (patch)
tree54feb882b197fb0a12d76342df9b56fce02dd169 /container-search
parent75b4d9d72f5ff932e8fcd3665419ff7cc9a0bf3a (diff)
Extend grouping validator to handle map syntax on an attribute vector.
Diffstat (limited to 'container-search')
-rw-r--r--container-search/src/main/java/com/yahoo/search/grouping/GroupingValidator.java18
-rw-r--r--container-search/src/test/java/com/yahoo/search/grouping/GroupingValidatorTestCase.java68
2 files changed, 73 insertions, 13 deletions
diff --git a/container-search/src/main/java/com/yahoo/search/grouping/GroupingValidator.java b/container-search/src/main/java/com/yahoo/search/grouping/GroupingValidator.java
index d96f490909e..790b5c4e601 100644
--- a/container-search/src/main/java/com/yahoo/search/grouping/GroupingValidator.java
+++ b/container-search/src/main/java/com/yahoo/search/grouping/GroupingValidator.java
@@ -75,8 +75,22 @@ public class GroupingValidator extends Searcher {
public void visitExpression(GroupingExpression exp) {
if (exp instanceof AttributeValue) {
String name = ((AttributeValue)exp).getAttributeName();
- if (!attributeNames.contains(name)) {
- throw new UnavailableAttributeException(clusterName, name);
+ int leftBracePos = name.indexOf('{');
+ if (leftBracePos == -1) {
+ if (!attributeNames.contains(name)) {
+ throw new UnavailableAttributeException(clusterName, name);
+ }
+ } else {
+ String baseName = name.substring(0, leftBracePos);
+ String keyName = baseName + ".key";
+ if (!attributeNames.contains(keyName)) {
+ throw new UnavailableAttributeException(clusterName, keyName);
+ }
+ int rightBracePos = name.lastIndexOf('}');
+ String valueName = baseName + ".value" + name.substring(rightBracePos + 1);
+ if (!attributeNames.contains(valueName)) {
+ throw new UnavailableAttributeException(clusterName, valueName);
+ }
}
}
}
diff --git a/container-search/src/test/java/com/yahoo/search/grouping/GroupingValidatorTestCase.java b/container-search/src/test/java/com/yahoo/search/grouping/GroupingValidatorTestCase.java
index 0a2def8738e..055ea5929db 100644
--- a/container-search/src/test/java/com/yahoo/search/grouping/GroupingValidatorTestCase.java
+++ b/container-search/src/test/java/com/yahoo/search/grouping/GroupingValidatorTestCase.java
@@ -7,19 +7,21 @@ import com.yahoo.search.Query;
import com.yahoo.search.config.ClusterConfig;
import com.yahoo.search.grouping.request.GroupingOperation;
import com.yahoo.search.searchchain.Execution;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
import java.util.Arrays;
import java.util.Collection;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
/**
* @author Simon Thoresen Hult
*/
public class GroupingValidatorTestCase {
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
@Test
public void requireThatAvailableAttributesDoNotThrow() {
validateGrouping("myCluster", Arrays.asList("foo", "bar"),
@@ -28,14 +30,10 @@ public class GroupingValidatorTestCase {
@Test
public void requireThatUnavailableAttributesThrow() {
- try {
- validateGrouping("myCluster", Arrays.asList("foo"),
- "all(group(foo) each(output(max(bar))))");
- fail("Validator should throw exception because attribute 'bar' is unavailable.");
- } catch (UnavailableAttributeException e) {
- assertEquals("myCluster", e.getClusterName());
- assertEquals("bar", e.getAttributeName());
- }
+ thrown.expect(UnavailableAttributeException.class);
+ thrown.expectMessage(createMessage("myCluster", "bar"));
+ validateGrouping("myCluster", Arrays.asList("foo"),
+ "all(group(foo) each(output(max(bar))))");
}
@Test
@@ -45,6 +43,54 @@ public class GroupingValidatorTestCase {
validateGrouping("myCluster", Arrays.asList("foo"), query);
}
+ @Test
+ public void available_primitive_map_attribute_does_not_throw() {
+ validateGrouping("myCluster", Arrays.asList("map.key", "map.value"),
+ "all(group(map{\"foo\"}) each(output(count())))");
+ }
+
+ @Test
+ public void unavailable_primitive_map_key_attribute_throws() {
+ thrown.expect(UnavailableAttributeException.class);
+ thrown.expectMessage(createMessage("myCluster", "map.key"));
+ validateGrouping("myCluster", Arrays.asList("null"),
+ "all(group(map{\"foo\"}) each(output(count())))");
+ }
+
+ @Test
+ public void unavailable_primitive_map_value_attribute_throws() {
+ thrown.expect(UnavailableAttributeException.class);
+ thrown.expectMessage(createMessage("myCluster", "map.value"));
+ validateGrouping("myCluster", Arrays.asList("map.key"),
+ "all(group(map{\"foo\"}) each(output(count())))");
+ }
+
+ @Test
+ public void available_struct_map_attribute_does_not_throw() {
+ validateGrouping("myCluster", Arrays.asList("map.key", "map.value.name"),
+ "all(group(map{\"foo\"}.name) each(output(count())))");
+ }
+
+ @Test
+ public void unavailable_struct_map_key_attribute_throws() {
+ thrown.expect(UnavailableAttributeException.class);
+ thrown.expectMessage(createMessage("myCluster", "map.key"));
+ validateGrouping("myCluster", Arrays.asList("null"),
+ "all(group(map{\"foo\"}.name) each(output(count())))");
+ }
+
+ @Test
+ public void unavailable_struct_map_value_attribute_throws() {
+ thrown.expect(UnavailableAttributeException.class);
+ thrown.expectMessage(createMessage("myCluster", "map.value.name"));
+ validateGrouping("myCluster", Arrays.asList("map.key"),
+ "all(group(map{\"foo\"}.name) each(output(count())))");
+ }
+
+ private static String createMessage(String clusterName, String attributeName) {
+ return "Grouping request references attribute '" + attributeName + "' which is not available in cluster '" + clusterName + "'.";
+ }
+
private static Query createQuery(String groupingExpression) {
Query query = new Query();
GroupingRequest req = GroupingRequest.newInstance(query);