summaryrefslogtreecommitdiffstats
path: root/config-model
diff options
context:
space:
mode:
authorGeir Storli <geirst@oath.com>2018-08-29 14:05:36 +0200
committerGeir Storli <geirst@oath.com>2018-08-29 14:21:08 +0200
commitae38db15dee838d8e6dcf9eaeabf08690a53af0e (patch)
treecf6ed06379933ed6bd085708b305f1be30f89dea /config-model
parent4b4ee6503ad05926218b9a0d01a6ac0846bdf71c (diff)
Relax validation of complex attribute fields by only considering the defined struct field attributes.
The struct type itself can contain fields of any type, but only primitive struct field attributes are supported in the complex field (array or map) using the struct type.
Diffstat (limited to 'config-model')
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/derived/AttributeFields.java12
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/document/ComplexAttributeFieldUtils.java100
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/processing/ImplicitSummaries.java2
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/ComplexAttributeFieldsValidator.java2
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/StructFieldAttributeChangeValidator.java53
-rw-r--r--config-model/src/test/java/com/yahoo/searchdefinition/document/ComplexAttributeFieldUtilsTestCase.java48
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/ComplexAttributeFieldsValidatorTestCase.java32
7 files changed, 144 insertions, 105 deletions
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/derived/AttributeFields.java b/config-model/src/main/java/com/yahoo/searchdefinition/derived/AttributeFields.java
index a3580a404a3..a8f6dd09497 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/derived/AttributeFields.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/derived/AttributeFields.java
@@ -6,9 +6,9 @@ import com.yahoo.document.DataType;
import com.yahoo.document.PositionDataType;
import com.yahoo.searchdefinition.Search;
import com.yahoo.searchdefinition.document.Attribute;
+import com.yahoo.searchdefinition.document.ComplexAttributeFieldUtils;
import com.yahoo.searchdefinition.document.ImmutableSDField;
import com.yahoo.searchdefinition.document.Ranking;
-import com.yahoo.searchdefinition.document.SDDocumentType;
import com.yahoo.searchdefinition.document.Sorting;
import com.yahoo.vespa.config.search.AttributesConfig;
import com.yahoo.vespa.indexinglanguage.expressions.ToPositionExpression;
@@ -51,14 +51,14 @@ public class AttributeFields extends Derived implements AttributesConfig.Produce
/** Derives everything from a field */
@Override
protected void derive(ImmutableSDField field, Search search) {
- if (unsupportedFieldType(field, search.getDocument())) {
+ if (unsupportedFieldType(field)) {
return; // Ignore complex struct and map fields for indexed search (only supported for streaming search)
}
if (field.isImportedField()) {
deriveImportedAttributes(field);
- } else if (isArrayOfSimpleStruct(field, search.getDocument())) {
+ } else if (isArrayOfSimpleStruct(field)) {
deriveArrayOfSimpleStruct(field);
- } else if (isMapOfSimpleStruct(field, search.getDocument())) {
+ } else if (isMapOfSimpleStruct(field)) {
deriveMapOfSimpleStruct(field);
} else if (isMapOfPrimitiveType(field)) {
deriveMapOfPrimitiveType(field);
@@ -67,9 +67,9 @@ public class AttributeFields extends Derived implements AttributesConfig.Produce
}
}
- private static boolean unsupportedFieldType(ImmutableSDField field, SDDocumentType docType) {
+ private static boolean unsupportedFieldType(ImmutableSDField field) {
return (field.usesStructOrMap() &&
- !isSupportedComplexField(field, docType) &&
+ !isSupportedComplexField(field) &&
!field.getDataType().equals(PositionDataType.INSTANCE) &&
!field.getDataType().equals(DataType.getArray(PositionDataType.INSTANCE)));
}
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/document/ComplexAttributeFieldUtils.java b/config-model/src/main/java/com/yahoo/searchdefinition/document/ComplexAttributeFieldUtils.java
index 72eb1c96e0f..c3ac8c77173 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/document/ComplexAttributeFieldUtils.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/document/ComplexAttributeFieldUtils.java
@@ -3,15 +3,9 @@ package com.yahoo.searchdefinition.document;
import com.yahoo.document.ArrayDataType;
import com.yahoo.document.DataType;
-import com.yahoo.document.Field;
import com.yahoo.document.MapDataType;
import com.yahoo.document.PositionDataType;
import com.yahoo.document.StructDataType;
-import com.yahoo.document.TemporaryStructuredDataType;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Optional;
/**
* Utils used to check whether a complex field supports being represented as struct field attributes.
@@ -21,64 +15,42 @@ import java.util.Optional;
* - map of primitive type to simple struct
* - map of primitive type to primitive type
*
+ * A simple struct can contain fields of any type, but only fields of primitive type can be defined as
+ * struct field attributes in the complex field using the simple struct.
+ *
* @author geirst
*/
public class ComplexAttributeFieldUtils {
- public static boolean isSupportedComplexField(ImmutableSDField field, SDDocumentType docType) {
- return (isArrayOfSimpleStruct(field, docType) ||
- isMapOfSimpleStruct(field, docType) ||
+ public static boolean isSupportedComplexField(ImmutableSDField field) {
+ return (isArrayOfSimpleStruct(field) ||
+ isMapOfSimpleStruct(field) ||
isMapOfPrimitiveType(field));
}
- public static boolean isSupportedComplexField(DataType fieldType) {
- return (isArrayOfSimpleStruct(fieldType) ||
- isMapOfSimpleStruct(fieldType) ||
- isMapOfPrimitiveType(fieldType));
- }
-
- public static boolean isArrayOfSimpleStruct(ImmutableSDField field, SDDocumentType docType) {
- return isArrayOfSimpleStruct(field.getDataType(), Optional.of(docType));
- }
-
- public static boolean isArrayOfSimpleStruct(DataType fieldType) {
- return isArrayOfSimpleStruct(fieldType, Optional.empty());
- }
-
- private static boolean isArrayOfSimpleStruct(DataType fieldType, Optional<SDDocumentType> docType) {
- if (fieldType instanceof ArrayDataType) {
- ArrayDataType arrayType = (ArrayDataType)fieldType;
- return isSimpleStruct(arrayType.getNestedType(), docType);
+ public static boolean isArrayOfSimpleStruct(ImmutableSDField field) {
+ if (field.getDataType() instanceof ArrayDataType) {
+ ArrayDataType arrayType = (ArrayDataType)field.getDataType();
+ return isStructWithPrimitiveStructFieldAttributes(arrayType.getNestedType(), field);
} else {
return false;
}
}
- public static boolean isMapOfSimpleStruct(ImmutableSDField field, SDDocumentType docType) {
- return isMapOfSimpleStruct(field.getDataType(), Optional.of(docType));
- }
-
- public static boolean isMapOfSimpleStruct(DataType fieldType) {
- return isMapOfSimpleStruct(fieldType, Optional.empty());
- }
-
- private static boolean isMapOfSimpleStruct(DataType fieldType, Optional<SDDocumentType> docType) {
- if (fieldType instanceof MapDataType) {
- MapDataType mapType = (MapDataType)fieldType;
+ public static boolean isMapOfSimpleStruct(ImmutableSDField field) {
+ if (field.getDataType() instanceof MapDataType) {
+ MapDataType mapType = (MapDataType)field.getDataType();
return isPrimitiveType(mapType.getKeyType()) &&
- isSimpleStruct(mapType.getValueType(), docType);
+ isStructWithPrimitiveStructFieldAttributes(mapType.getValueType(),
+ field.getStructField("value"));
} else {
return false;
}
}
public static boolean isMapOfPrimitiveType(ImmutableSDField field) {
- return isMapOfPrimitiveType(field.getDataType());
- }
-
- public static boolean isMapOfPrimitiveType(DataType fieldType) {
- if (fieldType instanceof MapDataType) {
- MapDataType mapType = (MapDataType)fieldType;
+ if (field.getDataType() instanceof MapDataType) {
+ MapDataType mapType = (MapDataType)field.getDataType();
return isPrimitiveType(mapType.getKeyType()) &&
isPrimitiveType(mapType.getValueType());
} else {
@@ -86,17 +58,15 @@ public class ComplexAttributeFieldUtils {
}
}
- private static boolean isSimpleStruct(DataType type, Optional<SDDocumentType> docType) {
+ private static boolean isStructWithPrimitiveStructFieldAttributes(DataType type, ImmutableSDField field) {
if (type instanceof StructDataType &&
!(type.equals(PositionDataType.INSTANCE))) {
- StructDataType structType = (StructDataType) type;
- Collection<Field> structFields = getStructFields(structType, docType);
- if (structFields.isEmpty()) {
- return false;
- }
- for (Field innerField : structFields) {
- if (!isPrimitiveType(innerField.getDataType())) {
- return false;
+ for (ImmutableSDField structField : field.getStructFields()) {
+ Attribute attribute = structField.getAttributes().get(structField.getName());
+ if (attribute != null) {
+ if (!isPrimitiveType(attribute)) {
+ return false;
+ }
}
}
return true;
@@ -105,20 +75,12 @@ public class ComplexAttributeFieldUtils {
}
}
- private static Collection<Field> getStructFields(StructDataType structType, Optional<SDDocumentType> docType) {
- // The struct data type might be unresolved at this point. If so we use the document type to resolve it.
- if (docType.isPresent() && (structType instanceof TemporaryStructuredDataType)) {
- SDDocumentType realStructType = docType.get().getOwnedType(structType.getName());
- if (structType != null) {
- return realStructType.getDocumentType().getFields();
- }
- return Collections.emptyList();
- } else {
- return structType.getFields();
- }
+ private static boolean isPrimitiveType(Attribute attribute) {
+ return attribute.getCollectionType().equals(Attribute.CollectionType.SINGLE) &&
+ isPrimitiveType(attribute.getDataType());
}
- private static boolean isPrimitiveType(DataType dataType) {
+ public static boolean isPrimitiveType(DataType dataType) {
return dataType.equals(DataType.BYTE) ||
dataType.equals(DataType.INT) ||
dataType.equals(DataType.LONG) ||
@@ -127,10 +89,10 @@ public class ComplexAttributeFieldUtils {
dataType.equals(DataType.STRING);
}
- public static boolean isComplexFieldWithOnlyStructFieldAttributes(ImmutableSDField field, SDDocumentType docType) {
- if (isArrayOfSimpleStruct(field, docType)) {
+ public static boolean isComplexFieldWithOnlyStructFieldAttributes(ImmutableSDField field) {
+ if (isArrayOfSimpleStruct(field)) {
return hasOnlyStructFieldAttributes(field);
- } else if (isMapOfSimpleStruct(field, docType)) {
+ } else if (isMapOfSimpleStruct(field)) {
return hasSingleAttribute(field.getStructField("key")) &&
hasOnlyStructFieldAttributes(field.getStructField("value"));
} else if (isMapOfPrimitiveType(field)) {
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/processing/ImplicitSummaries.java b/config-model/src/main/java/com/yahoo/searchdefinition/processing/ImplicitSummaries.java
index 2d2fc10d9c5..b51524b7e62 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/processing/ImplicitSummaries.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/processing/ImplicitSummaries.java
@@ -83,7 +83,7 @@ public class ImplicitSummaries extends Processor {
}
}
- if (addedSummaryField != null && isComplexFieldWithOnlyStructFieldAttributes(field, search.getDocument())) {
+ if (addedSummaryField != null && isComplexFieldWithOnlyStructFieldAttributes(field)) {
addedSummaryField.setTransform(SummaryTransform.ATTRIBUTECOMBINER);
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/ComplexAttributeFieldsValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/ComplexAttributeFieldsValidator.java
index 005c1dd8b2e..bc89d0dfcf5 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/ComplexAttributeFieldsValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/ComplexAttributeFieldsValidator.java
@@ -61,7 +61,7 @@ public class ComplexAttributeFieldsValidator extends Validator {
}
private static boolean isSupportedComplexField(ImmutableSDField field) {
- return (ComplexAttributeFieldUtils.isSupportedComplexField(field.getDataType()) ||
+ return (ComplexAttributeFieldUtils.isSupportedComplexField(field) ||
field.getDataType().equals(PositionDataType.INSTANCE) ||
field.getDataType().equals(DataType.getArray(PositionDataType.INSTANCE)));
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/StructFieldAttributeChangeValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/StructFieldAttributeChangeValidator.java
index 520494f1697..341861e3c7e 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/StructFieldAttributeChangeValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/search/StructFieldAttributeChangeValidator.java
@@ -10,6 +10,7 @@ import com.yahoo.document.StructDataType;
import com.yahoo.documentmodel.NewDocumentType;
import com.yahoo.searchdefinition.derived.AttributeFields;
import com.yahoo.searchdefinition.document.Attribute;
+import com.yahoo.searchdefinition.document.ComplexAttributeFieldUtils;
import com.yahoo.vespa.model.application.validation.change.VespaConfigChangeAction;
import com.yahoo.vespa.model.application.validation.change.VespaRefeedAction;
@@ -20,10 +21,6 @@ import java.util.List;
import java.util.StringTokenizer;
import java.util.stream.Collectors;
-import static com.yahoo.searchdefinition.document.ComplexAttributeFieldUtils.isArrayOfSimpleStruct;
-import static com.yahoo.searchdefinition.document.ComplexAttributeFieldUtils.isMapOfPrimitiveType;
-import static com.yahoo.searchdefinition.document.ComplexAttributeFieldUtils.isMapOfSimpleStruct;
-
/**
* Validates the changes between the current and next set of struct field attributes in a document database.
@@ -66,7 +63,7 @@ public class StructFieldAttributeChangeValidator {
private List<VespaConfigChangeAction> validateAddAttributeAspect(Context current, Context next, ValidationOverrides overrides, Instant now) {
return next.structFieldAttributes.stream()
- .filter(nextAttr -> current.hasFieldFor(nextAttr) &&
+ .filter(nextAttr -> current.hasFieldForStructFieldAttribute(nextAttr) &&
!current.hasStructFieldAttribute(nextAttr))
.map(nextAttr -> VespaRefeedAction.of("field-type-change",
overrides,
@@ -94,23 +91,23 @@ public class StructFieldAttributeChangeValidator {
.anyMatch(attr -> attr.getName().equals(structFieldAttribute.getName()));
}
- public boolean hasFieldFor(Attribute structFieldAttribute) {
+ public boolean hasFieldForStructFieldAttribute(Attribute structFieldAttribute) {
StringTokenizer fieldNames = new StringTokenizer(structFieldAttribute.getName(), ".");
if (!fieldNames.nextToken().equals(field.getName())) {
return false;
}
- if (isArrayOfSimpleStruct(dataType())) {
+ if (isArrayOfStructType(dataType())) {
StructDataType nestedType = (StructDataType)((ArrayDataType)dataType()).getNestedType();
- if (hasLastFieldInStructType(fieldNames, nestedType)) {
+ if (hasLastFieldNameInStructType(fieldNames, nestedType)) {
return true;
}
- } else if (isMapOfSimpleStruct(dataType())) {
+ } else if (isMapOfStructType(dataType())) {
MapDataType mapType = (MapDataType)dataType();
StructDataType valueType = (StructDataType)mapType.getValueType();
String subFieldName = fieldNames.nextToken();
if (subFieldName.equals("key") && !fieldNames.hasMoreTokens()) {
return true;
- } else if (subFieldName.equals("value") && hasLastFieldInStructType(fieldNames, valueType)) {
+ } else if (subFieldName.equals("value") && hasLastFieldNameInStructType(fieldNames, valueType)) {
return true;
}
} else if (isMapOfPrimitiveType(dataType())) {
@@ -123,10 +120,42 @@ public class StructFieldAttributeChangeValidator {
return false;
}
- private static boolean hasLastFieldInStructType(StringTokenizer fieldNames, StructDataType structType) {
- return structType.getField(fieldNames.nextToken()) != null && !fieldNames.hasMoreTokens();
+ private static boolean isArrayOfStructType(DataType type) {
+ if (type instanceof ArrayDataType) {
+ ArrayDataType arrayType = (ArrayDataType)type;
+ return isStructType(arrayType.getNestedType());
+ } else {
+ return false;
+ }
+ }
+
+ private static boolean isMapOfStructType(DataType type) {
+ if (type instanceof MapDataType) {
+ MapDataType mapType = (MapDataType)type;
+ return ComplexAttributeFieldUtils.isPrimitiveType(mapType.getKeyType()) &&
+ isStructType(mapType.getValueType());
+ } else {
+ return false;
+ }
}
+ public static boolean isMapOfPrimitiveType(DataType type) {
+ if (type instanceof MapDataType) {
+ MapDataType mapType = (MapDataType)type;
+ return ComplexAttributeFieldUtils.isPrimitiveType(mapType.getKeyType()) &&
+ ComplexAttributeFieldUtils.isPrimitiveType(mapType.getValueType());
+ } else {
+ return false;
+ }
+ }
+
+ private static boolean isStructType(DataType type) {
+ return (type instanceof StructDataType);
+ }
+
+ private static boolean hasLastFieldNameInStructType(StringTokenizer fieldNames, StructDataType structType) {
+ return structType.getField(fieldNames.nextToken()) != null && !fieldNames.hasMoreTokens();
+ }
}
}
diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/document/ComplexAttributeFieldUtilsTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/document/ComplexAttributeFieldUtilsTestCase.java
index 91a89c204c9..3f45b28b994 100644
--- a/config-model/src/test/java/com/yahoo/searchdefinition/document/ComplexAttributeFieldUtilsTestCase.java
+++ b/config-model/src/test/java/com/yahoo/searchdefinition/document/ComplexAttributeFieldUtilsTestCase.java
@@ -25,20 +25,16 @@ public class ComplexAttributeFieldUtilsTestCase {
return field;
}
- public SDDocumentType docType() {
- return search.getDocument();
- }
-
public boolean isSupportedComplexField() {
- return ComplexAttributeFieldUtils.isSupportedComplexField(field(), docType());
+ return ComplexAttributeFieldUtils.isSupportedComplexField(field());
}
public boolean isArrayOfSimpleStruct() {
- return ComplexAttributeFieldUtils.isArrayOfSimpleStruct(field(), docType());
+ return ComplexAttributeFieldUtils.isArrayOfSimpleStruct(field());
}
public boolean isMapOfSimpleStruct() {
- return ComplexAttributeFieldUtils.isMapOfSimpleStruct(field(), docType());
+ return ComplexAttributeFieldUtils.isMapOfSimpleStruct(field());
}
public boolean isMapOfPrimitiveType() {
@@ -46,7 +42,7 @@ public class ComplexAttributeFieldUtilsTestCase {
}
public boolean isComplexFieldWithOnlyStructFieldAttributes() {
- return ComplexAttributeFieldUtils.isComplexFieldWithOnlyStructFieldAttributes(field(), docType());
+ return ComplexAttributeFieldUtils.isComplexFieldWithOnlyStructFieldAttributes(field());
}
}
@@ -57,7 +53,7 @@ public class ComplexAttributeFieldUtilsTestCase {
" document test {",
" struct elem {",
" field name type string {}",
- " field weight type string {}",
+ " field weight type int {}",
" }",
sdFieldContent,
" }",
@@ -72,7 +68,7 @@ public class ComplexAttributeFieldUtilsTestCase {
" document test {",
" struct elem {",
" field name type string {}",
- " field weight type array<string> {}",
+ " field weights type array<int> {}",
" }",
sdFieldContent,
" }",
@@ -194,7 +190,7 @@ public class ComplexAttributeFieldUtilsTestCase {
ComplexFixture f = new ComplexFixture("elem_array",
joinLines("field elem_array type array<elem> {",
" struct-field name { indexing: attribute }",
- " struct-field weight { indexing: attribute }",
+ " struct-field weights { indexing: attribute }",
"}"));
assertFalse(f.isSupportedComplexField());
assertFalse(f.isArrayOfSimpleStruct());
@@ -207,7 +203,7 @@ public class ComplexAttributeFieldUtilsTestCase {
joinLines("field elem_map type map<int, elem> {",
" indexing: summary",
" struct-field key { indexing: attribute }",
- " struct-field value.weight { indexing: attribute }",
+ " struct-field value.weights { indexing: attribute }",
"}"));
assertFalse(f.isSupportedComplexField());
assertFalse(f.isArrayOfSimpleStruct());
@@ -217,4 +213,32 @@ public class ComplexAttributeFieldUtilsTestCase {
}
}
+ @Test
+ public void only_struct_field_attributes_are_considered_when_tagging_a_complex_field() throws ParseException {
+ {
+ ComplexFixture f = new ComplexFixture("elem_array",
+ joinLines("field elem_array type array<elem> {",
+ " struct-field name { indexing: attribute }",
+ "}"));
+ assertTrue(f.isSupportedComplexField());
+ assertTrue(f.isArrayOfSimpleStruct());
+ assertFalse(f.isMapOfSimpleStruct());
+ assertFalse(f.isMapOfPrimitiveType());
+ assertFalse(f.isComplexFieldWithOnlyStructFieldAttributes());
+ }
+ {
+ ComplexFixture f = new ComplexFixture("elem_map",
+ joinLines("field elem_map type map<int, elem> {",
+ " indexing: summary",
+ " struct-field key { indexing: attribute }",
+ " struct-field value.name { indexing: attribute }",
+ "}"));
+ assertTrue(f.isSupportedComplexField());
+ assertFalse(f.isArrayOfSimpleStruct());
+ assertTrue(f.isMapOfSimpleStruct());
+ assertFalse(f.isMapOfPrimitiveType());
+ assertFalse(f.isComplexFieldWithOnlyStructFieldAttributes());
+ }
+ }
+
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ComplexAttributeFieldsValidatorTestCase.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ComplexAttributeFieldsValidatorTestCase.java
index 6483933385d..3ba3745f46e 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ComplexAttributeFieldsValidatorTestCase.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/ComplexAttributeFieldsValidatorTestCase.java
@@ -31,18 +31,42 @@ public class ComplexAttributeFieldsValidatorTestCase {
exceptionRule.expect(IllegalArgumentException.class);
exceptionRule.expectMessage("For cluster 'mycluster', search 'test': " +
"The following complex fields do not support using struct field attributes: " +
- "struct_array (struct_array.s1), struct_map (struct_map.key, struct_map.value.s1). " +
+ "struct_array (struct_array.f1), struct_map (struct_map.key, struct_map.value.f1). " +
"Only supported for the following complex field types: array or map of struct with primitive types, map of primitive types");
createModelAndValidate(joinLines("search test {",
" document test {",
- " struct s { field s1 type array<int> {} }",
+ " struct s { field f1 type array<int> {} }",
" field struct_array type array<s> {",
- " struct-field s1 { indexing: attribute }",
+ " struct-field f1 { indexing: attribute }",
" }",
" field struct_map type map<string,s> {",
" struct-field key { indexing: attribute }",
- " struct-field value.s1 { indexing: attribute }",
+ " struct-field value.f1 { indexing: attribute }",
+ " }",
+ " }",
+ "}"));
+ }
+
+ @Test
+ public void validation_passes_when_only_supported_struct_field_attributes_are_used() throws IOException, SAXException {
+ createModelAndValidate(joinLines("search test {",
+ " document test {",
+ " struct s1 {",
+ " field f1 type string {}",
+ " field f2 type int {}",
+ " }",
+ " struct s2 {",
+ " field f3 type string {}",
+ " field f4 type array<int> {}",
+ " field f5 type array<s1> {}",
+ " }",
+ " field struct_array type array<s2> {",
+ " struct-field f3 { indexing: attribute }",
+ " }",
+ " field struct_map type map<string,s2> {",
+ " struct-field key { indexing: attribute }",
+ " struct-field value.f3 { indexing: attribute }",
" }",
" }",
"}"));