com.yahoo.schema.processing.IndexingInputs Maven / Gradle / Ivy
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.schema.processing;
import com.yahoo.config.application.api.DeployLogger;
import com.yahoo.schema.RankProfileRegistry;
import com.yahoo.schema.Schema;
import com.yahoo.schema.document.SDField;
import com.yahoo.vespa.indexinglanguage.ExpressionConverter;
import com.yahoo.vespa.indexinglanguage.ExpressionVisitor;
import com.yahoo.vespa.indexinglanguage.expressions.Expression;
import com.yahoo.vespa.indexinglanguage.expressions.InputExpression;
import com.yahoo.vespa.indexinglanguage.expressions.ScriptExpression;
import com.yahoo.vespa.indexinglanguage.expressions.StatementExpression;
import com.yahoo.vespa.model.container.search.QueryProfiles;
/**
* This processor modifies all indexing scripts so that they input the value of the owning field by default. It also
* ensures that all fields used as input exist.
*
* @author Simon Thoresen Hult
*/
public class IndexingInputs extends Processor {
public IndexingInputs(Schema schema, DeployLogger deployLogger, RankProfileRegistry rankProfileRegistry, QueryProfiles queryProfiles) {
super(schema, deployLogger, rankProfileRegistry, queryProfiles);
}
@Override
public void process(boolean validate, boolean documentsOnly) {
for (SDField field : schema.allConcreteFields()) {
ScriptExpression script = field.getIndexingScript();
if (script == null) continue;
script = (ScriptExpression)new DefaultToCurrentField(field).convert(script);
script = (ScriptExpression)new EnsureInputExpression(field).convert(script);
if (validate)
new VerifyInputExpression(schema, field).visit(script);
field.setIndexingScript(schema.getName(), script);
}
}
private static class DefaultToCurrentField extends ExpressionConverter {
final SDField field;
DefaultToCurrentField(SDField field) {
this.field = field;
}
@Override
protected boolean shouldConvert(Expression exp) {
return exp instanceof InputExpression && ((InputExpression)exp).getFieldName() == null;
}
@Override
protected Expression doConvert(Expression exp) {
return new InputExpression(field.getName());
}
}
private static class EnsureInputExpression extends ExpressionConverter {
final SDField field;
EnsureInputExpression(SDField field) {
this.field = field;
}
@Override
protected boolean shouldConvert(Expression exp) {
return exp instanceof StatementExpression
&& ( field.isDocumentField() || ( field.getAttribute() != null && field.getAttribute().isMutable()));
}
@Override
protected Expression doConvert(Expression exp) {
if (exp.requiredInputType() != null) {
return new StatementExpression(new InputExpression(field.getName()), exp);
} else {
return exp;
}
}
}
private class VerifyInputExpression extends ExpressionVisitor {
private final Schema schema;
private final SDField field;
public VerifyInputExpression(Schema schema, SDField field) {
this.schema = schema;
this.field = field;
}
@Override
protected void doVisit(Expression exp) {
if ( ! (exp instanceof InputExpression)) return;
var referencedFieldName = ((InputExpression)exp).getFieldName();
var referencedField = schema.getField(referencedFieldName);
if (referencedField == null || ! referencedField.hasFullIndexingDocprocRights())
fail(schema, field, "Indexing script refers to field '" + referencedFieldName +
"' which is neither a field in " + schema.getDocument() + " nor a mutable attribute");
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy