summaryrefslogtreecommitdiffstats
path: root/config-model
diff options
context:
space:
mode:
authorGeir Storli <geirst@yahooinc.com>2022-07-12 14:52:33 +0000
committerGeir Storli <geirst@yahooinc.com>2022-07-12 14:52:33 +0000
commitf26d6b65159ffe87cae54038131a7ed89c8bfd79 (patch)
tree2ad6d2a24c48f0da19d6eba88bc65bb99b940935 /config-model
parent04107d40dc4bc0b83d8cfbf06ad746be45e2ec85 (diff)
Validate that complex fields do not have struct fields with 'indexing: index'.
This is not supported for indexed search clusters, and should be replaced with 'indexing: attribute'.
Diffstat (limited to 'config-model')
-rw-r--r--config-model/src/main/java/com/yahoo/schema/document/ImmutableImportedSDField.java5
-rw-r--r--config-model/src/main/java/com/yahoo/schema/document/ImmutableSDField.java8
-rw-r--r--config-model/src/main/java/com/yahoo/schema/document/SDField.java9
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/ComplexFieldsWithStructFieldAttributesValidator.java (renamed from config-model/src/main/java/com/yahoo/vespa/model/application/validation/ComplexAttributeFieldsValidator.java)4
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/ComplexFieldsWithStructFieldIndexesValidator.java72
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java3
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/ComplexFieldsValidatorTestCase.java (renamed from config-model/src/test/java/com/yahoo/vespa/model/application/validation/ComplexAttributeFieldsValidatorTestCase.java)26
7 files changed, 123 insertions, 4 deletions
diff --git a/config-model/src/main/java/com/yahoo/schema/document/ImmutableImportedSDField.java b/config-model/src/main/java/com/yahoo/schema/document/ImmutableImportedSDField.java
index 335942de99d..221280dc1e4 100644
--- a/config-model/src/main/java/com/yahoo/schema/document/ImmutableImportedSDField.java
+++ b/config-model/src/main/java/com/yahoo/schema/document/ImmutableImportedSDField.java
@@ -83,6 +83,11 @@ public class ImmutableImportedSDField implements ImmutableSDField {
}
@Override
+ public boolean wasConfiguredToDoIndexing() {
+ return importedField.targetField().wasConfiguredToDoIndexing();
+ }
+
+ @Override
public DataType getDataType() {
return importedField.targetField().getDataType();
}
diff --git a/config-model/src/main/java/com/yahoo/schema/document/ImmutableSDField.java b/config-model/src/main/java/com/yahoo/schema/document/ImmutableSDField.java
index 44e442811ba..37cbb3a8171 100644
--- a/config-model/src/main/java/com/yahoo/schema/document/ImmutableSDField.java
+++ b/config-model/src/main/java/com/yahoo/schema/document/ImmutableSDField.java
@@ -45,6 +45,14 @@ public interface ImmutableSDField {
*/
boolean wasConfiguredToDoAttributing();
+ /**
+ * Whether this field at some time was configured to do indexing.
+ *
+ * This function can typically return a different value than doesIndexing(),
+ * which uses the final state of the underlying indexing script instead.
+ */
+ boolean wasConfiguredToDoIndexing();
+
DataType getDataType();
Index getIndex(String name);
diff --git a/config-model/src/main/java/com/yahoo/schema/document/SDField.java b/config-model/src/main/java/com/yahoo/schema/document/SDField.java
index 943d6c6fc14..2d79d89a2a0 100644
--- a/config-model/src/main/java/com/yahoo/schema/document/SDField.java
+++ b/config-model/src/main/java/com/yahoo/schema/document/SDField.java
@@ -117,6 +117,7 @@ public class SDField extends Field implements TypedKey, ImmutableSDField {
private boolean isExtraField = false;
private boolean wasConfiguredToDoAttributing = false;
+ private boolean wasConfiguredToDoIndexing = false;
/**
* Creates a new field. This method is only used to create reserved fields.
@@ -381,6 +382,11 @@ public class SDField extends Field implements TypedKey, ImmutableSDField {
return wasConfiguredToDoAttributing;
}
+ @Override
+ public boolean wasConfiguredToDoIndexing() {
+ return wasConfiguredToDoIndexing;
+ }
+
/** Parse an indexing expression which will use the simple linguistics implementation suitable for testing */
public void parseIndexingScript(String script) {
parseIndexingScript(script, new SimpleLinguistics(), Embedder.throwsOnUse.asMap());
@@ -408,6 +414,9 @@ public class SDField extends Field implements TypedKey, ImmutableSDField {
if (!wasConfiguredToDoAttributing()) {
wasConfiguredToDoAttributing = doesAttributing();
}
+ if (!wasConfiguredToDoIndexing()) {
+ wasConfiguredToDoIndexing = doesIndexing();
+ }
if (!usesStructOrMap()) {
new ExpressionVisitor() {
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/ComplexFieldsWithStructFieldAttributesValidator.java
index 01bf846d4cb..8515c34a377 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/ComplexFieldsWithStructFieldAttributesValidator.java
@@ -22,7 +22,7 @@ import java.util.stream.Collectors;
*
* @author geirst
*/
-public class ComplexAttributeFieldsValidator extends Validator {
+public class ComplexFieldsWithStructFieldAttributesValidator extends Validator {
@Override
public void validate(VespaModel model, DeployState deployState) {
@@ -39,7 +39,7 @@ public class ComplexAttributeFieldsValidator extends Validator {
private static void validateComplexFields(String clusterName, Schema schema) {
String unsupportedFields = schema.allFields()
.filter(field -> isUnsupportedComplexField(field))
- .map(ComplexAttributeFieldsValidator::toString)
+ .map(ComplexFieldsWithStructFieldAttributesValidator::toString)
.collect(Collectors.joining(", "));
if (!unsupportedFields.isEmpty()) {
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/ComplexFieldsWithStructFieldIndexesValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/ComplexFieldsWithStructFieldIndexesValidator.java
new file mode 100644
index 00000000000..bbbb0c08bf4
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/ComplexFieldsWithStructFieldIndexesValidator.java
@@ -0,0 +1,72 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.model.application.validation;
+
+import com.yahoo.config.model.deploy.DeployState;
+import com.yahoo.schema.Schema;
+import com.yahoo.schema.document.ImmutableSDField;
+import com.yahoo.vespa.model.VespaModel;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Validates that complex fields (of type struct or map) do not have any struct fields with 'indexing: index'.
+ * This is not supported and will confuse the user if not validated.
+ *
+ * Only applies for indexed search clusters.
+ *
+ * @author geirst
+ */
+public class ComplexFieldsWithStructFieldIndexesValidator extends Validator {
+
+ @Override
+ public void validate(VespaModel model, DeployState deployState) {
+ for (var cluster : model.getSearchClusters()) {
+ if (cluster.isStreaming()) {
+ continue;
+ }
+ for (var spec : cluster.schemas().values()) {
+ validateComplexFields(cluster.getClusterName(), spec.fullSchema());
+ }
+ }
+ }
+
+ private static void validateComplexFields(String clusterName, Schema schema) {
+ String unsupportedFields = schema.allFields()
+ .filter(field -> hasStructFieldsWithIndex(field))
+ .map(ComplexFieldsWithStructFieldIndexesValidator::toString)
+ .collect(Collectors.joining(", "));
+
+ if (!unsupportedFields.isEmpty()) {
+ throw new IllegalArgumentException(
+ String.format("For cluster '%s', schema '%s': The following complex fields have struct fields with 'indexing: index' which is not supported: %s. " +
+ "Change to 'indexing: attribute' instead",
+ clusterName, schema.getName(), unsupportedFields));
+ }
+ }
+
+ private static boolean hasStructFieldsWithIndex(ImmutableSDField field) {
+ return (field.usesStructOrMap() && hasStructFieldsWithIndex(field.getStructFields()));
+ }
+
+ private static String toString(ImmutableSDField field) {
+ return field.getName() + " (" + String.join(", ", getStructFieldsWithIndex(field.getStructFields())) + ")";
+ }
+
+ private static boolean hasStructFieldsWithIndex(Collection<? extends ImmutableSDField> structFields) {
+ return !getStructFieldsWithIndex(structFields).isEmpty();
+ }
+
+ private static List<String> getStructFieldsWithIndex(Collection<? extends ImmutableSDField> structFields) {
+ var result = new ArrayList<String>();
+ for (var structField : structFields) {
+ if (structField.wasConfiguredToDoIndexing()) {
+ result.add(structField.getName());
+ }
+ result.addAll(getStructFieldsWithIndex(structField.getStructFields()));
+ }
+ return result;
+ }
+}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java
index ce61d3edc3b..dab1eeccc96 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java
@@ -71,7 +71,8 @@ public class Validation {
new SchemasDirValidator().validate(model, deployState);
new BundleValidator().validate(model, deployState);
new SearchDataTypeValidator().validate(model, deployState);
- new ComplexAttributeFieldsValidator().validate(model, deployState);
+ new ComplexFieldsWithStructFieldAttributesValidator().validate(model, deployState);
+ new ComplexFieldsWithStructFieldIndexesValidator().validate(model, deployState);
new StreamingValidator().validate(model, deployState);
new RankSetupValidator(validationParameters.ignoreValidationErrors()).validate(model, deployState);
new NoPrefixForIndexes().validate(model, deployState);
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/ComplexFieldsValidatorTestCase.java
index 85050aa0cf9..11e4ae855a5 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/ComplexFieldsValidatorTestCase.java
@@ -22,7 +22,7 @@ import static com.yahoo.config.model.test.TestUtil.joinLines;
/**
* @author geirst
*/
-public class ComplexAttributeFieldsValidatorTestCase {
+public class ComplexFieldsValidatorTestCase {
@SuppressWarnings("deprecation")
@Rule
@@ -78,6 +78,30 @@ public class ComplexAttributeFieldsValidatorTestCase {
}
@Test
+ public void throws_when_complex_fields_have_struct_fields_with_index() throws IOException, SAXException {
+ exceptionRule.expect(IllegalArgumentException.class);
+ exceptionRule.expectMessage("For cluster 'mycluster', schema 'test': " +
+ "The following complex fields have struct fields with 'indexing: index' which is not supported: " +
+ "topics (topics.id, topics.label). Change to 'indexing: attribute' instead");
+ createModelAndValidate(joinLines(
+ "schema test {",
+ "document test {",
+ "struct topic {",
+ " field id type string {}",
+ " field label type string {}",
+ " field desc type string {}",
+ "}",
+ "field topics type array<topic> {",
+ " indexing: summary",
+ " struct-field id { indexing: index }",
+ " struct-field label { indexing: index | attribute }",
+ " struct-field desc { indexing: attribute }",
+ "}",
+ "}",
+ "}"));
+ }
+
+ @Test
public void validation_passes_when_only_supported_struct_field_attributes_are_used() throws IOException, SAXException {
createModelAndValidate(joinLines("search test {",
" document test {",