diff --git a/config-model/src/main/java/com/yahoo/schema/processing/ExactMatch.java b/config-model/src/main/java/com/yahoo/schema/processing/ExactMatch.java index 10d78c4b3870..4313ceb4be10 100644 --- a/config-model/src/main/java/com/yahoo/schema/processing/ExactMatch.java +++ b/config-model/src/main/java/com/yahoo/schema/processing/ExactMatch.java @@ -90,9 +90,10 @@ private void exactMatchSettingsForField(SDField field) { private static class MyProvider extends TypedTransformProvider { - private final int maxTokenLength; + private int maxTokenLength; - MyProvider(Schema schema, int maxTokenLength) { + MyProvider(Schema schema, int maxTokenLength) + { super(ExactExpression.class, schema); this.maxTokenLength = maxTokenLength; } diff --git a/config-model/src/main/java/com/yahoo/schema/processing/IndexingValidation.java b/config-model/src/main/java/com/yahoo/schema/processing/IndexingValidation.java index 56d50285dbcc..fe63776118a1 100644 --- a/config-model/src/main/java/com/yahoo/schema/processing/IndexingValidation.java +++ b/config-model/src/main/java/com/yahoo/schema/processing/IndexingValidation.java @@ -75,7 +75,7 @@ protected boolean shouldConvert(Expression expression) { outputs.add(fieldName); prevNames.add(fieldName); } - if (expression.isMutating()) { + if (expression.createdOutputType() != null) { prevNames.clear(); } return false; @@ -98,8 +98,9 @@ private static class MyAdapter implements FieldTypeAdapter { @Override public DataType getInputType(Expression exp, String fieldName) { SDField field = schema.getDocumentField(fieldName); - if (field == null) - throw new VerificationException(exp, "Input field '" + fieldName + "' not found"); + if (field == null) { + throw new VerificationException(exp, "Input field '" + fieldName + "' not found."); + } return field.getDataType(); } @@ -109,14 +110,16 @@ public void tryOutputType(Expression expression, String fieldName, DataType valu DataType fieldType; if (expression instanceof AttributeExpression) { Attribute attribute = schema.getAttribute(fieldName); - if (attribute == null) - throw new VerificationException(expression, "Attribute '" + fieldName + "' not found"); + if (attribute == null) { + throw new VerificationException(expression, "Attribute '" + fieldName + "' not found."); + } fieldDesc = "attribute"; fieldType = attribute.getDataType(); } else if (expression instanceof IndexExpression) { SDField field = schema.getConcreteField(fieldName); - if (field == null) - throw new VerificationException(expression, "Index field '" + fieldName + "' not found"); + if (field == null) { + throw new VerificationException(expression, "Index field '" + fieldName + "' not found."); + } fieldDesc = "index field"; fieldType = field.getDataType(); } else if (expression instanceof SummaryExpression) { @@ -128,7 +131,7 @@ public void tryOutputType(Expression expression, String fieldName, DataType valu fieldDesc = "document field"; fieldType = sdField.getDataType(); } else { - throw new VerificationException(expression, "Summary field '" + fieldName + "' not found"); + throw new VerificationException(expression, "Summary field '" + fieldName + "' not found."); } } else { fieldDesc = "summary field"; @@ -139,7 +142,7 @@ public void tryOutputType(Expression expression, String fieldName, DataType valu } if ( ! fieldType.isAssignableFrom(valueType)) throw new VerificationException(expression, "Can not assign " + valueType.getName() + " to " + fieldDesc + - " '" + fieldName + "' which is " + fieldType.getName()); + " '" + fieldName + "' which is " + fieldType.getName() + "."); } } diff --git a/config-model/src/main/java/com/yahoo/schema/processing/IndexingValues.java b/config-model/src/main/java/com/yahoo/schema/processing/IndexingValues.java index faa9216ef74a..cac31bea7437 100644 --- a/config-model/src/main/java/com/yahoo/schema/processing/IndexingValues.java +++ b/config-model/src/main/java/com/yahoo/schema/processing/IndexingValues.java @@ -57,7 +57,7 @@ protected boolean shouldConvert(Expression exp) { } if (exp instanceof InputExpression && ((InputExpression)exp).getFieldName().equals(field.getName())) { mutatedBy = null; - } else if (exp.isMutating()) { + } else if (exp.createdOutputType() != null) { mutatedBy = exp; } return false; diff --git a/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java b/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java index ad907d9149bd..4aa6c65ad8f7 100644 --- a/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java @@ -581,14 +581,6 @@ void testConnectivity() { "which does not exist in the query.")); } - @Test - void testWeight() { - QueryTree parsed = parse("select * from sources * where " + - "weakAnd(field1 contains ({weight: 120}'term1'), " + - " field1 contains ({weight: 70}'term2'))"); - assertEquals("WEAKAND(100) field1:term1!120 field1:term2!70", parsed.toString()); - } - @Test void testAnnotatedPhrase() { QueryTree parsed = diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/FieldValueConverter.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/FieldValueConverter.java index b83c731d1267..b18d1f1dc890 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/FieldValueConverter.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/FieldValueConverter.java @@ -12,14 +12,26 @@ */ public abstract class FieldValueConverter { - @SuppressWarnings({ "rawtypes", "unchecked" }) + @SuppressWarnings({ "unchecked" }) public final FieldValue convert(FieldValue value) { - if (value == null) return null; - if (shouldConvert(value)) return doConvert(value); - if (value instanceof Array arrayValue) return convertArray(arrayValue); - if (value instanceof MapFieldValue mapValue) return convertMap(mapValue); - if (value instanceof WeightedSet weightedSetValue) return convertWset(weightedSetValue); - if (value instanceof StructuredFieldValue structuredFieldValue) return convertStructured(structuredFieldValue); + if (value == null) { + return null; + } + if (shouldConvert(value)) { + return doConvert(value); + } + if (value instanceof Array) { + return convertArray((Array)value); + } + if (value instanceof MapFieldValue) { + return convertMap((MapFieldValue)value); + } + if (value instanceof WeightedSet) { + return convertWset((WeightedSet)value); + } + if (value instanceof StructuredFieldValue) { + return convertStructured((StructuredFieldValue)value); + } return value; } diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/ValueTransformProvider.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/ValueTransformProvider.java index 7c8dcbaa8e82..437d5549c971 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/ValueTransformProvider.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/ValueTransformProvider.java @@ -25,8 +25,8 @@ public final ExpressionConverter branch() { } @Override - protected final boolean shouldConvert(Expression expression) { - if (transformClass.isInstance(expression)) { + protected final boolean shouldConvert(Expression exp) { + if (transformClass.isInstance(exp)) { if (transformed) { duplicate = true; return true; @@ -34,8 +34,16 @@ protected final boolean shouldConvert(Expression expression) { transformed = true; return false; } - if ( ! requiresTransform(expression)) return false; - if (transformed) return false; + if (exp.createdOutputType() != null) { + transformed = false; + return false; + } + if ( ! requiresTransform(exp)) { + return false; + } + if (transformed) { + return false; + } return true; } diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/BusyWaitExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/BusyWaitExpression.java index 05fda004b360..6483dd62f238 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/BusyWaitExpression.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/BusyWaitExpression.java @@ -12,9 +12,6 @@ */ public final class BusyWaitExpression extends Expression { - @Override - public boolean isMutating() { return false; } - @Override protected void doExecute(ExecutionContext context) { FieldValue value = context.getCurrentValue(); diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ConstantExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ConstantExpression.java index 5a2534cdca91..1220576fe77a 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ConstantExpression.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ConstantExpression.java @@ -37,7 +37,7 @@ public DataType setOutputType(DataType outputType, VerificationContext context) throw new VerificationException(this, "Produces type " + value.getDataType().getName() + ", but type " + outputType.getName() + " is required"); super.setOutputType(outputType, context); - return AnyDataType.instance; + return null; } @Override diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/EchoExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/EchoExpression.java index 126c78db4cca..1f22989b21cf 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/EchoExpression.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/EchoExpression.java @@ -20,9 +20,6 @@ public EchoExpression(PrintStream out) { this.out = out; } - @Override - public boolean isMutating() { return false; } - public PrintStream getOutputStream() { return out; } @Override diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ExactExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ExactExpression.java index 61916b8f7976..cb1df30983d7 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ExactExpression.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ExactExpression.java @@ -37,9 +37,6 @@ public ExactExpression(int maxTokenLength) { this(OptionalInt.of(maxTokenLength)); } - @Override - public boolean isMutating() { return false; } - @Override public DataType setInputType(DataType inputType, VerificationContext context) { return super.setInputType(inputType, DataType.STRING, context); diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/Expression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/Expression.java index 3a28264c6f02..e8032ff65f9c 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/Expression.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/Expression.java @@ -44,12 +44,6 @@ public abstract class Expression extends Selectable { /** Returns whether this expression requires an input value. */ public boolean requiresInput() { return true; } - /** - * Returns whether this expression outputs a different value than what it gets as input. - * Annotating a string value does not count as modifying it. - */ - public boolean isMutating() { return true; } - /** * Returns an expression where the children of this has been converted using the given converter. * This default implementation returns this as it has no children. @@ -158,38 +152,50 @@ public final void verify(DocumentType type) { verify(new DocumentTypeAdapter(type)); } - public final void verify(Document doc) { - verify(new SimpleAdapterFactory(), doc); + public final Document verify(Document doc) { + return verify(new SimpleAdapterFactory(), doc); } - public final void verify(AdapterFactory factory, Document doc) { - verify(factory.newDocumentAdapter(doc)); + public final Document verify(AdapterFactory factory, Document doc) { + return verify(factory.newDocumentAdapter(doc)); } - public final void verify(DocumentAdapter adapter) { + public final Document verify(DocumentAdapter adapter) { verify((FieldTypeAdapter)adapter); - adapter.getFullOutput(); + return adapter.getFullOutput(); } - public final void verify(DocumentUpdate upd) { - verify(new SimpleAdapterFactory(), upd); + public final DocumentUpdate verify(DocumentUpdate upd) { + return verify(new SimpleAdapterFactory(), upd); } - public final void verify(AdapterFactory factory, DocumentUpdate upd) { - for (UpdateAdapter adapter : factory.newUpdateAdapterList(upd)) - verify(adapter); + public final DocumentUpdate verify(AdapterFactory factory, DocumentUpdate upd) { + DocumentUpdate ret = null; + for (UpdateAdapter adapter : factory.newUpdateAdapterList(upd)) { + DocumentUpdate output = verify(adapter); + if (output == null) { + // ignore + } else if (ret != null) { + ret.addAll(output); + } else { + ret = output; + } + } + return ret; } - public final void verify(UpdateAdapter adapter) { + public final DocumentUpdate verify(UpdateAdapter adapter) { verify((FieldTypeAdapter)adapter); + return adapter.getOutput(); } - public final void verify(FieldTypeAdapter adapter) { - verify(new VerificationContext(adapter)); + public final DataType verify(FieldTypeAdapter adapter) { + return verify(new VerificationContext(adapter)); } - public final void verify(VerificationContext context) { + public final DataType verify(VerificationContext context) { doVerify(context); + return context.getCurrentType(); } protected void doVerify(VerificationContext context) {} @@ -240,6 +246,14 @@ public final FieldValue execute(ExecutionContext context) { if (input == null) return null; } doExecute(context); + DataType outputType = createdOutputType(); + if (outputType != null) { + FieldValue output = context.getCurrentValue(); + if (output != null && !outputType.isValueCompatible(output)) { + throw new IllegalStateException("Expression '" + this + "' expected " + outputType.getName() + + " output, got " + output.getDataType().getName()); + } + } return context.getCurrentValue(); } @@ -262,6 +276,17 @@ public static Expression newInstance(ScriptParserContext context) throws ParseEx return ScriptParser.parseExpression(context); } + protected static boolean equals(Object lhs, Object rhs) { + if (lhs == null) { + return rhs == null; + } else { + if (rhs == null) { + return false; + } + return lhs.equals(rhs); + } + } + // Convenience For testing public static Document execute(Expression expression, Document doc) { expression.verify(doc); diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ForEachExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ForEachExpression.java index 6b0931f89acb..8e23745e67be 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ForEachExpression.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ForEachExpression.java @@ -32,9 +32,6 @@ public ForEachExpression(Expression expression) { this.expression = Objects.requireNonNull(expression); } - @Override - public boolean isMutating() { return expression.isMutating(); } - public Expression getInnerExpression() { return expression; } @Override @@ -170,8 +167,12 @@ protected void doExecute(ExecutionContext context) { FieldValue input = context.getCurrentValue(); if (input instanceof Array || input instanceof WeightedSet) { FieldValue next = new ExecutionConverter(context, expression).convert(input); - if (next == null) - next = getOutputType().createFieldValue(); + if (next == null) { + VerificationContext verificationContext = new VerificationContext(context.getFieldValue()); + context.fillVariableTypes(verificationContext); + verificationContext.setCurrentType(input.getDataType()).verify(this); + next = verificationContext.getCurrentType().createFieldValue(); + } context.setCurrentValue(next); } else if (input instanceof Struct || input instanceof Map) { context.setCurrentValue(new ExecutionConverter(context, expression).convert(input)); @@ -226,7 +227,7 @@ protected boolean shouldConvert(FieldValue value) { /** Converts a map into an array by passing each entry through the expression. */ @Override protected FieldValue convertMap(MapFieldValue map) { - var values = new Array<>(new ArrayDataType(expression.getOutputType()), map.size()); + var values = new Array<>(new ArrayDataType(expression.createdOutputType()), map.size()); for (var entry : map.entrySet()) values.add(doConvert(new MapEntryFieldValue(entry.getKey(), entry.getValue()))); return values; diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/GuardExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/GuardExpression.java index 1775fd73f3e0..e92dc4278af1 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/GuardExpression.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/GuardExpression.java @@ -23,9 +23,6 @@ public GuardExpression(Expression innerExpression) { shouldExecute = shouldExecute(innerExpression); } - @Override - public boolean isMutating() { return innerExpression.isMutating(); } - @Override public boolean requiresInput() { return innerExpression.requiresInput(); } diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/IfThenExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/IfThenExpression.java index a49dfb732580..a2af300a0de0 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/IfThenExpression.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/IfThenExpression.java @@ -11,7 +11,6 @@ import com.yahoo.vespa.objects.ObjectPredicate; import java.math.BigDecimal; -import java.util.Objects; /** * @author Simon Thoresen Hult @@ -57,11 +56,6 @@ public IfThenExpression(Expression lhs, Comparator cmp, Expression right, Expres this.ifFalse = ifFalse; } - @Override - public boolean isMutating() { - return ifTrue.isMutating() || (ifFalse != null && ifFalse.isMutating()); - } - @Override public boolean requiresInput() { return left.requiresInput() || right.requiresInput() || ifTrue.requiresInput() || (ifFalse != null && ifFalse.requiresInput()); @@ -184,7 +178,7 @@ public boolean equals(Object obj) { if ( ! comparator.equals(exp.comparator)) return false; if ( ! right.equals(exp.right)) return false; if ( ! ifTrue.equals(exp.ifTrue)) return false; - if ( ! Objects.equals(ifFalse, exp.ifFalse)) return false; + if ( ! equals(ifFalse, exp.ifFalse)) return false; return true; } diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/InputExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/InputExpression.java index 1268b3b541bf..81d262808a4d 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/InputExpression.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/InputExpression.java @@ -9,7 +9,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.Objects; /** * @author Simon Thoresen Hult @@ -78,7 +77,7 @@ public String toString() { @Override public boolean equals(Object obj) { if ( ! (obj instanceof InputExpression rhs)) return false; - if ( ! Objects.equals(fieldName, rhs.fieldName)) return false; + if ( ! equals(fieldName, rhs.fieldName)) return false; return true; } diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/NGramExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/NGramExpression.java index fa08ba730cd7..7621906cfee5 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/NGramExpression.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/NGramExpression.java @@ -38,9 +38,6 @@ public NGramExpression(Linguistics linguistics, int gramSize) { this.gramSize = gramSize; } - @Override - public boolean isMutating() { return false; } - public Linguistics getLinguistics() { return linguistics; } public int getGramSize() { return gramSize; } diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/NowExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/NowExpression.java index 3da2e4df7888..50ade192e4b9 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/NowExpression.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/NowExpression.java @@ -26,8 +26,7 @@ public NowExpression(Timer timer) { @Override public DataType setInputType(DataType inputType, VerificationContext context) { - super.setInputType(inputType, context); - return DataType.LONG; + return super.setInputType(inputType, context); } @Override diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/OptimizePredicateExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/OptimizePredicateExpression.java index 3cbc6dcc6851..4d1e60cc5a84 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/OptimizePredicateExpression.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/OptimizePredicateExpression.java @@ -28,10 +28,6 @@ public OptimizePredicateExpression() { this.optimizer = optimizer; } - // Not technically true, but the semantics are not changed. */ - @Override - public boolean isMutating() { return false; } - @Override public DataType setInputType(DataType inputType, VerificationContext context) { return super.setInputType(inputType, DataType.PREDICATE, context); diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/OutputExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/OutputExpression.java index b33c212ccff0..e6682045366c 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/OutputExpression.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/OutputExpression.java @@ -7,7 +7,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.Objects; /** * @author Simon Thoresen Hult @@ -22,9 +21,6 @@ public OutputExpression(String image, String fieldName) { this.fieldName = fieldName; } - @Override - public boolean isMutating() { return false; } - public String getFieldName() { return fieldName; } @Override @@ -64,7 +60,7 @@ public String toString() { @Override public boolean equals(Object obj) { if (!(obj instanceof OutputExpression rhs)) return false; - if (!Objects.equals(fieldName, rhs.fieldName)) return false; + if (!equals(fieldName, rhs.fieldName)) return false; return true; } diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ParenthesisExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ParenthesisExpression.java index 0e659946460e..78b4e998728d 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ParenthesisExpression.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ParenthesisExpression.java @@ -19,9 +19,6 @@ public ParenthesisExpression(Expression innerExpression) { this.innerExpression = innerExpression; } - @Override - public boolean isMutating() { return innerExpression.isMutating(); } - @Override public boolean requiresInput() { return innerExpression.requiresInput(); } diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/RandomExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/RandomExpression.java index 162a2b9d1435..ee60a16a0e7e 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/RandomExpression.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/RandomExpression.java @@ -62,7 +62,7 @@ public String toString() { @Override public boolean equals(Object obj) { if (!(obj instanceof RandomExpression rhs)) return false; - if (!Objects.equals(max, rhs.max)) return false; + if (!equals(max, rhs.max)) return false; return true; } diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ScriptExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ScriptExpression.java index 02b0274d870f..6c28719d80a3 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ScriptExpression.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ScriptExpression.java @@ -44,13 +44,6 @@ public ScriptExpression convertChildren(ExpressionConverter converter) { .toList()); } - @Override - public boolean isMutating() { - var expressions = asList(); - if (expressions.isEmpty()) return false; - return (expressions.get(expressions.size() - 1)).isMutating(); - } - @Override public boolean requiresInput() { return expressions().stream().anyMatch(statement -> statement.requiresInput()); diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/SetLanguageExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/SetLanguageExpression.java index 2c993fc5b05d..2e419db14348 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/SetLanguageExpression.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/SetLanguageExpression.java @@ -11,9 +11,6 @@ */ public final class SetLanguageExpression extends Expression { - @Override - public boolean isMutating() { return false; } - @Override public DataType setInputType(DataType inputType, VerificationContext context) { return super.setInputType(inputType, DataType.STRING, context); diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/SetVarExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/SetVarExpression.java index 9c1a1b324fdf..0d3f2cad6f68 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/SetVarExpression.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/SetVarExpression.java @@ -14,9 +14,6 @@ public SetVarExpression(String varName) { this.varName = varName; } - @Override - public boolean isMutating() { return false; } - public String getVariableName() { return varName; } @Override diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/SleepExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/SleepExpression.java index f5e768296a55..54174868ba99 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/SleepExpression.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/SleepExpression.java @@ -12,9 +12,6 @@ */ public final class SleepExpression extends Expression { - @Override - public boolean isMutating() { return false; } - @Override protected void doVerify(VerificationContext context) { } diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/StatementExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/StatementExpression.java index 3c641dd3798c..c419519d2688 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/StatementExpression.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/StatementExpression.java @@ -42,11 +42,6 @@ private StatementExpression(Iterable list, Object unused) { inputFields = List.copyOf(InputExpression.InputFieldNameExtractor.runOn(this)); } - @Override - public boolean isMutating() { - return expressions().stream().anyMatch(expression -> expression.isMutating()); - } - /** Returns the input fields which are (perhaps optionally) consumed by some expression in this statement. */ public List getInputFields() { return inputFields; } diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/SwitchExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/SwitchExpression.java index 6c3e5a9048ba..38a7c720b4e8 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/SwitchExpression.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/SwitchExpression.java @@ -14,7 +14,6 @@ import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; -import java.util.Objects; /** * @author Simon Thoresen Hult @@ -35,9 +34,6 @@ public SwitchExpression(Map cases, Expression this.cases.putAll(cases); } - @Override - public boolean isMutating() { return false; } - public boolean isEmpty() { return defaultExp == null && cases.isEmpty(); } @@ -77,8 +73,7 @@ public DataType setInputType(DataType inputType, VerificationContext context) { public DataType setOutputType(DataType outputType, VerificationContext context) { super.setOutputType(outputType, context); - if (defaultExp != null) - setOutputType(outputType, defaultExp, context); + setOutputType(outputType, defaultExp, context); for (Expression expression : cases.values()) setOutputType(outputType, expression, context); return DataType.STRING; @@ -165,7 +160,7 @@ public String toString() { public boolean equals(Object obj) { if (!(obj instanceof SwitchExpression rhs)) return false; if (!cases.equals(rhs.cases)) return false; - if (!Objects.equals(defaultExp, rhs.defaultExp)) return false; + if (!equals(defaultExp, rhs.defaultExp)) return false; return true; } diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ThisExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ThisExpression.java index 42de4e694726..31a0d862b9c5 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ThisExpression.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ThisExpression.java @@ -8,9 +8,6 @@ */ public final class ThisExpression extends Expression { - @Override - public boolean isMutating() { return false; } - @Override protected void doVerify(VerificationContext context) { if (context.getCurrentType() == null) diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ToBoolExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ToBoolExpression.java index 4eb2734c0e70..2d388453ab8a 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ToBoolExpression.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ToBoolExpression.java @@ -17,7 +17,7 @@ public final class ToBoolExpression extends Expression { public DataType setInputType(DataType input, VerificationContext context) { super.setInputType(input, context); if (input == null) return null; - if ( ! (input.isAssignableTo(DataType.STRING)) && ! (input instanceof NumericDataType)) + if ( ! (input.isAssignableTo(DataType.STRING) && ! (input instanceof NumericDataType))) throw new VerificationException(this, "Input must be a string or number, but got " + input.getName()); return DataType.BOOL; } diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/TokenizeExpression.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/TokenizeExpression.java index 400788e52cc0..f7e14887a508 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/TokenizeExpression.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/TokenizeExpression.java @@ -22,9 +22,6 @@ public TokenizeExpression(Linguistics linguistics, AnnotatorConfig config) { this.config = config; } - @Override - public boolean isMutating() { return false; } - public Linguistics getLinguistics() { return linguistics; } public AnnotatorConfig getConfig() { return config; } diff --git a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/VerificationContext.java b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/VerificationContext.java index 47ce3c6d6763..64ea7c0af434 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/VerificationContext.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/VerificationContext.java @@ -27,6 +27,11 @@ public VerificationContext verify(Expression expression) { return this; } + /** Returns the type of the field processed by this. */ + public DataType getFieldType(Expression expression) { + return fieldTypes.getInputType(expression, getOutputField()); + } + /** Returns the type of the given field. */ public DataType getFieldType(String fieldName, Expression expression) { return fieldTypes.getInputType(expression, fieldName); @@ -52,6 +57,12 @@ public VerificationContext setVariable(String name, DataType value) { return this; } + /** + * Returns the name of the (last) output field of the statement this is executed as a part of, + * or null if none or not yet verified + */ + public String getOutputField() { return outputField; } + /** Sets the name of the (last) output field of the statement this is executed as a part of */ public void setOutputField(String outputField) { this.outputField = outputField; } diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/EmbeddingScriptTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/EmbeddingScriptTestCase.java index 72b2ea87386c..7a7062abf910 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/EmbeddingScriptTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/EmbeddingScriptTestCase.java @@ -86,7 +86,9 @@ public void testArrayEmbed() { adapter.setValue("myTextArray", array); expression.setStatementOutput(new DocumentType("myDocument"), tensorField); - expression.verify(new VerificationContext(adapter)); + // Necessary to resolve output type + VerificationContext verificationContext = new VerificationContext(adapter); + assertEquals(new ArrayDataType(new TensorDataType(tensorType)), expression.verify(verificationContext)); ExecutionContext context = new ExecutionContext(adapter); context.setCurrentValue(array); @@ -121,7 +123,9 @@ public void testArrayEmbedWithConcatenation() { expression.setStatementOutput(new DocumentType("myDocument"), tensorField); - expression.verify(new VerificationContext(adapter)); + // Necessary to resolve output type + VerificationContext verificationContext = new VerificationContext(adapter); + assertEquals(new TensorDataType(tensorType), expression.verify(verificationContext)); ExecutionContext context = new ExecutionContext(adapter); context.setCurrentValue(array); @@ -152,7 +156,9 @@ public void testArrayEmbedTo2dMixedTensor() { adapter.setValue("myTextArray", array); expression.setStatementOutput(new DocumentType("myDocument"), tensorField); - expression.verify(new VerificationContext(adapter)); + // Necessary to resolve output type + VerificationContext verificationContext = new VerificationContext(adapter); + assertEquals(new TensorDataType(tensorType), expression.verify(verificationContext)); ExecutionContext context = new ExecutionContext(adapter); context.setCurrentValue(array); @@ -183,7 +189,7 @@ public void testArrayEmbedTo3dMixedTensor() { adapter.setValue("myTextArray", array); expression.setStatementOutput(new DocumentType("myDocument"), tensorField); - expression.verify(new VerificationContext(adapter)); + assertEquals(new TensorDataType(tensorType), expression.verify(new VerificationContext(adapter))); ExecutionContext context = new ExecutionContext(adapter); context.setCurrentValue(array); @@ -285,7 +291,9 @@ public void testEmbedToSparseTensor() { adapter.setValue("text", text); expression.setStatementOutput(new DocumentType("myDocument"), tensorField); - expression.verify(new VerificationContext(adapter)); + // Necessary to resolve output type + VerificationContext verificationContext = new VerificationContext(adapter); + assertEquals(new TensorDataType(tensorType), expression.verify(verificationContext)); ExecutionContext context = new ExecutionContext(adapter); context.setCurrentValue(text); @@ -341,7 +349,7 @@ public void testArrayEmbedTo2MappedTensor() { adapter.setValue("myTextArray", array); expression.setStatementOutput(new DocumentType("myDocument"), tensorField); - expression.verify(new VerificationContext(adapter)); + assertEquals(new TensorDataType(tensorType), expression.verify(new VerificationContext(adapter))); ExecutionContext context = new ExecutionContext(adapter); context.setCurrentValue(array); diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/EmbeddingScriptTester.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/EmbeddingScriptTester.java index 11a8de96ea7b..e4171e60a709 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/EmbeddingScriptTester.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/EmbeddingScriptTester.java @@ -47,7 +47,9 @@ public void testStatement(String expressionString, String input, String targetTe adapter.setValue("myText", new StringFieldValue(input)); expression.setStatementOutput(new DocumentType("myDocument"), tensorField); - expression.verify(new VerificationContext(adapter)); + // Necessary to resolve output type + VerificationContext verificationContext = new VerificationContext(adapter); + assertEquals(TensorDataType.class, expression.verify(verificationContext).getClass()); ExecutionContext context = new ExecutionContext(adapter); expression.execute(context); @@ -73,7 +75,9 @@ public void testStatement2(String expressionString, String input, String targetT adapter.setValue("myText", new StringFieldValue(input)); expression.setStatementOutput(new DocumentType("myDocument"), tensorField); - expression.verify(new VerificationContext(adapter)); + // Necessary to resolve output type + VerificationContext verificationContext = new VerificationContext(adapter); + assertEquals(TensorDataType.class, expression.verify(verificationContext).getClass()); ExecutionContext context = new ExecutionContext(adapter); expression.execute(context); diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/GenerateExpressionTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/GenerateExpressionTestCase.java index 0fb21e40c345..70e6b086c0dc 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/GenerateExpressionTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/GenerateExpressionTestCase.java @@ -162,7 +162,9 @@ public void testWithArrayInputArrayOutput() { adapter.setValue("myArray", inputArray); expression.setStatementOutput(new DocumentType("myDocument"), outputField); - expression.verify(new VerificationContext(adapter)); + // Necessary to resolve output type + VerificationContext verificationContext = new VerificationContext(adapter); + assertEquals(new ArrayDataType(DataType.STRING), expression.verify(verificationContext)); ExecutionContext context = new ExecutionContext(adapter); expression.execute(context); @@ -228,7 +230,9 @@ public void testGeneratorWithStringInputArrayOutput() { expression.setStatementOutput(new DocumentType("myDocument"), outputField); - expression.verify(new VerificationContext(adapter)); + // Necessary to resolve output type + VerificationContext verificationContext = new VerificationContext(adapter); + assertEquals(new ArrayDataType(DataType.STRING), expression.verify(verificationContext)); ExecutionContext context = new ExecutionContext(adapter); expression.execute(context); diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/ScriptTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/ScriptTestCase.java index 6ed3feb0230c..cce45a86146f 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/ScriptTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/ScriptTestCase.java @@ -6,7 +6,6 @@ import com.yahoo.document.Document; import com.yahoo.document.DocumentType; import com.yahoo.document.Field; -import com.yahoo.document.WeightedSetDataType; import com.yahoo.document.datatypes.Array; import com.yahoo.document.datatypes.BoolFieldValue; import com.yahoo.document.datatypes.FloatFieldValue; @@ -14,7 +13,6 @@ import com.yahoo.document.datatypes.LongFieldValue; import com.yahoo.document.datatypes.StringFieldValue; import com.yahoo.document.datatypes.UriFieldValue; -import com.yahoo.document.datatypes.WeightedSet; import com.yahoo.vespa.indexinglanguage.expressions.AttributeExpression; import com.yahoo.vespa.indexinglanguage.expressions.ExecutionContext; import com.yahoo.vespa.indexinglanguage.expressions.Expression; @@ -143,7 +141,8 @@ public void testIntHash() throws ParseException { adapter.createField(intField); adapter.setValue("myText", new StringFieldValue("input text")); - expression.verify(new VerificationContext(adapter)); + VerificationContext verificationContext = new VerificationContext(adapter); + assertEquals(DataType.INT, expression.verify(verificationContext)); ExecutionContext context = new ExecutionContext(adapter); expression.execute(context); @@ -165,7 +164,8 @@ public void testIntArrayHash() throws ParseException { array.add(new StringFieldValue("second")); adapter.setValue("myTextArray", array); - expression.verify(new VerificationContext(adapter)); + VerificationContext verificationContext = new VerificationContext(adapter); + assertEquals(new ArrayDataType(DataType.INT), expression.verify(verificationContext)); ExecutionContext context = new ExecutionContext(adapter); expression.execute(context); @@ -185,7 +185,8 @@ public void testLongHash() throws ParseException { adapter.createField(intField); adapter.setValue("myText", new StringFieldValue("input text")); - expression.verify(new VerificationContext(adapter)); + VerificationContext verificationContext = new VerificationContext(adapter); + assertEquals(DataType.LONG, expression.verify(verificationContext)); ExecutionContext context = new ExecutionContext(adapter); expression.execute(context); @@ -207,7 +208,8 @@ public void testZCurveArray() throws ParseException { array.add(new StringFieldValue("50;60")); adapter.setValue("location_str", array); - expression.verify(new VerificationContext(adapter)); + VerificationContext verificationContext = new VerificationContext(adapter); + assertEquals(DataType.getArray(DataType.LONG), expression.verify(verificationContext)); ExecutionContext context = new ExecutionContext(adapter); expression.execute(context); @@ -361,58 +363,4 @@ public void testToUri() { assertEquals(new UriFieldValue("https://vespa.ai"), adapter.values.get("myUri")); } - @SuppressWarnings("unchecked") - @Test - public void testForEachWithWeightedSet() { - var tester = new ScriptTester(); - var expression = tester.expressionFrom("input myWeightedSet | for_each { to_int } | attribute myInts"); - - SimpleTestAdapter adapter = new SimpleTestAdapter(); - var myWeightedSet = new WeightedSet(WeightedSetDataType.getWeightedSet(DataType.STRING)); - adapter.createField(new Field("myWeightedSet", myWeightedSet.getDataType())); - adapter.setValue("myWeightedSet", myWeightedSet); - adapter.createField(new Field("myInts", WeightedSetDataType.getWeightedSet(DataType.INT))); - - expression.verify(adapter); - ExecutionContext context = new ExecutionContext(adapter); - expression.execute(context); - assertTrue(((WeightedSet)adapter.values.get("myInts")).isEmpty()); - - myWeightedSet.put(new StringFieldValue("3"), 37); - adapter.createField(new Field("myWeightedSet", myWeightedSet.getDataType())); - adapter.setValue("myWeightedSet", myWeightedSet); - adapter.createField(new Field("myInts", WeightedSetDataType.getWeightedSet(DataType.INT))); - - expression.verify(adapter); - expression.execute(context); - assertEquals(37, ((WeightedSet)adapter.values.get("myInts")).get(new IntegerFieldValue(3)).intValue()); - } - - @SuppressWarnings("unchecked") - @Test - public void testForEachArray() { - var tester = new ScriptTester(); - var expression = tester.expressionFrom("input myArray | for_each { to_int } | attribute myInts"); - - SimpleTestAdapter adapter = new SimpleTestAdapter(); - var myArray = new Array(DataType.getArray(DataType.STRING)); - adapter.createField(new Field("myArray", myArray.getDataType())); - adapter.setValue("myArray", myArray); - adapter.createField(new Field("myInts", DataType.getArray(DataType.INT))); - - expression.verify(adapter); - ExecutionContext context = new ExecutionContext(adapter); - expression.execute(context); - assertTrue(((Array)adapter.values.get("myInts")).isEmpty()); - - myArray.add(new StringFieldValue("37")); - adapter.createField(new Field("myArray", myArray.getDataType())); - adapter.setValue("myArray", myArray); - adapter.createField(new Field("myInts", DataType.getArray(DataType.INT))); - - expression.verify(adapter); - expression.execute(context); - assertEquals(37, ((Array)adapter.values.get("myInts")).get(0).getInteger()); - } - } diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ArithmeticTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ArithmeticTestCase.java index a481e0dc5a5b..a2b2d960463c 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ArithmeticTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ArithmeticTestCase.java @@ -136,8 +136,8 @@ private void assertResult(FieldValue lhs, Operator op, FieldValue rhs, FieldValu } private void assertType(DataType lhs, Operator op, DataType rhs, DataType expected) { - newArithmetic(SimpleExpression.newOutput(lhs), op, SimpleExpression.newOutput(rhs)) - .verify(new VerificationContext(new SimpleTestAdapter())); + assertEquals(expected, newArithmetic(SimpleExpression.newOutput(lhs), op, + SimpleExpression.newOutput(rhs)).verify(new VerificationContext(new SimpleTestAdapter()))); assertEquals(expected, newArithmetic(lhs.createFieldValue(6), op, rhs.createFieldValue(9)).execute().getDataType()); } diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/CatTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/CatTestCase.java index 5b4ba1995209..a656bd5f756d 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/CatTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/CatTestCase.java @@ -82,6 +82,14 @@ public void requireThatPrimitivesCanNotBeNull() { assertNull(evaluate(DataType.INT, null, DataType.INT, new IntegerFieldValue(69))); } + @Test + public void requireThatPrimitiveVerificationWorks() { + assertEquals(DataType.STRING, evaluate(DataType.getArray(DataType.STRING), DataType.STRING)); + assertEquals(DataType.STRING, evaluate(DataType.STRING, DataType.getArray(DataType.STRING))); + assertEquals(DataType.STRING, evaluate(DataType.getWeightedSet(DataType.STRING), DataType.STRING)); + assertEquals(DataType.STRING, evaluate(DataType.STRING, DataType.getWeightedSet(DataType.STRING))); + } + @Test public void inputValueIsAvailableToAllInnerExpressions() { var expression = new StatementExpression(new ConstantExpression(new StringFieldValue("foo")), @@ -164,6 +172,22 @@ public void requireThatWsetsCanBeNull() { assertEquals(Integer.valueOf(9), ((WeightedSet)val).get(new StringFieldValue("6"))); } + @Test + public void requireThatCollectionTypesMustBeCompatible() { + assertEquals(DataType.getArray(DataType.STRING), evaluate(DataType.getArray(DataType.STRING), + DataType.getArray(DataType.STRING))); + assertEquals(DataType.STRING, evaluate(DataType.getArray(DataType.STRING), DataType.getArray(DataType.INT))); + assertEquals(DataType.STRING, + evaluate(DataType.getArray(DataType.STRING), DataType.getWeightedSet(DataType.STRING))); + + assertEquals(DataType.getWeightedSet(DataType.STRING), evaluate(DataType.getWeightedSet(DataType.STRING), + DataType.getWeightedSet(DataType.STRING))); + assertEquals(DataType.STRING, + evaluate(DataType.getWeightedSet(DataType.STRING), DataType.getWeightedSet(DataType.INT))); + assertEquals(DataType.STRING, + evaluate(DataType.getWeightedSet(DataType.STRING), DataType.getArray(DataType.STRING))); + } + @Test public void requireThatCollectionValuesMustBeCompatible() { { @@ -226,4 +250,10 @@ private static FieldValue evaluate(DataType typeA, FieldValue valA, DataType typ return context.getCurrentValue(); } + private static DataType evaluate(DataType typeA, DataType typeB) { + SimpleTestAdapter adapter = new SimpleTestAdapter(new Field("a", typeA), new Field("b", typeB)); + VerificationContext ctx = new VerificationContext(adapter); + new CatExpression(new InputExpression("a"), new InputExpression("b")).verify(ctx); + return ctx.getCurrentType(); + } } diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ClearStateTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ClearStateTestCase.java index 77577de2739a..ee09313f8e86 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ClearStateTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ClearStateTestCase.java @@ -32,8 +32,10 @@ public void requireThatExecutionContextIsCleared() { @Test public void requireThatExpressionCanBeVerified() { - assertVerify(DataType.INT, new ClearStateExpression(), DataType.INT); - assertVerify(DataType.STRING, new ClearStateExpression(), DataType.STRING); + Expression exp = new ClearStateExpression(); + assertVerify(null, exp, null); + assertVerify(DataType.INT, exp, null); + assertVerify(DataType.STRING, exp, null); } @Test diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/EchoTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/EchoTestCase.java index cbd52e8b15c3..a210def9b2cc 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/EchoTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/EchoTestCase.java @@ -51,8 +51,9 @@ public void requireThatValueIsEchoed() { @Test public void requireThatExpressionCanBeVerified() { - assertVerify(DataType.INT, new EchoExpression(), DataType.INT); - assertVerify(DataType.STRING, new EchoExpression(), DataType.STRING); + Expression exp = new EchoExpression(); + assertVerify(DataType.INT, exp, DataType.INT); + assertVerify(DataType.STRING, exp, DataType.STRING); } } diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ExpressionAssert.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ExpressionAssert.java index e30c1f7e5f18..f75765567bea 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ExpressionAssert.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ExpressionAssert.java @@ -13,19 +13,16 @@ */ class ExpressionAssert { - public static void assertVerifyCtx(Expression expression, VerificationContext context) { - expression.verify(context); + public static void assertVerifyCtx(Expression expression, DataType expectedValueAfter, VerificationContext context) { + assertEquals(expectedValueAfter, expression.verify(context)); } - public static void assertVerify(DataType inputType, Expression expression, DataType outputType) { - var context = new VerificationContext(new SimpleTestAdapter()).setCurrentType(inputType); - assertVerifyCtx(expression, context); - assertEquals(outputType, expression.setInputType(inputType, context)); - assertEquals(inputType, expression.setOutputType(outputType, context)); + public static void assertVerify(DataType valueBefore, Expression expression, DataType expectedValueAfter) { + assertVerifyCtx(expression, expectedValueAfter, new VerificationContext(new SimpleTestAdapter()).setCurrentType(valueBefore)); } public static void assertVerifyThrows(String expectedMessage, DataType valueBefore, Expression expression) { - assertVerifyThrows(expectedMessage, expression, valueBefore, new VerificationContext(new SimpleTestAdapter()).setCurrentType(valueBefore)); + assertVerifyThrows(expectedMessage, expression, new VerificationContext(new SimpleTestAdapter()).setCurrentType(valueBefore)); } interface CreateExpression { @@ -45,9 +42,9 @@ public static void assertVerifyThrows(String expectedMessage, CreateExpression c assertEquals(expectedMessage, e.getMessage()); } } - public static void assertVerifyThrows(String expectedMessage, Expression expression, DataType inputType, VerificationContext context) { + public static void assertVerifyThrows(String expectedMessage, Expression expression, VerificationContext context) { try { - expression.setInputType(inputType, context); + expression.setInputType(context.getCurrentType(), context); expression.verify(context); fail("Expected exception"); } catch (VerificationException e) { diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ExpressionAssertTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ExpressionAssertTestCase.java index 6c6863a3467f..28de6e6a1b98 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ExpressionAssertTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ExpressionAssertTestCase.java @@ -16,6 +16,14 @@ public class ExpressionAssertTestCase { @Test public void requireThatAssertVerifyMethodThrowsWhenAppropriate() { Throwable thrown = null; + try { + assertVerify(DataType.INT, new SimpleExpression(), DataType.STRING); + } catch (Throwable t) { + thrown = t; + } + assertNotNull(thrown); + + thrown = null; try { assertVerifyThrows("unchecked expected exception message", DataType.INT, new SimpleExpression() ); diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ExpressionTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ExpressionTestCase.java index e84579c5572d..ed862931c3e6 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ExpressionTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ExpressionTestCase.java @@ -9,6 +9,7 @@ import org.junit.Test; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -17,6 +18,14 @@ */ public class ExpressionTestCase { + @Test + public void requireThatOutputTypeIsCheckedAfterExecute() { + assertExecute(newCreatedOutput(DataType.INT, (FieldValue)null), null); + assertExecute(newCreatedOutput(DataType.INT, new IntegerFieldValue(69)), null); + assertExecuteThrows(newCreatedOutput(DataType.INT, new StringFieldValue("foo")), null, + new IllegalStateException("expected int output, got string")); + } + @Test public void requireThatInputTypeIsCheckedBeforeVerify() { assertVerify(newRequiredInput(DataType.INT), DataType.INT); @@ -28,6 +37,15 @@ public void requireThatInputTypeIsCheckedBeforeVerify() { "Invalid expression 'SimpleExpression': Expected int input, got string"); } + @Test + public void requireThatEqualsMethodWorks() { + assertTrue(Expression.equals(null, null)); + assertTrue(Expression.equals(1, 1)); + assertFalse(Expression.equals(1, 2)); + assertFalse(Expression.equals(1, null)); + assertFalse(Expression.equals(null, 2)); + } + private static Expression newRequiredInput(DataType requiredInput) { return new SimpleExpression(requiredInput); } @@ -36,6 +54,10 @@ private static Expression newCreatedOutput(DataType createdOutput, FieldValue ac return new SimpleExpression().setCreatedOutput(createdOutput).setExecuteValue(actualOutput); } + private static Expression newCreatedOutput(DataType createdOutput, DataType actualOutput) { + return new SimpleExpression().setCreatedOutput(createdOutput).setVerifyValue(actualOutput); + } + private static void assertExecute(Expression exp, FieldValue val) { exp.execute(val); } @@ -64,5 +86,4 @@ private static void assertVerifyThrows(Expression exp, DataType val, String expe assertEquals(expectedException, e.getMessage()); } } - } diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ForEachTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ForEachTestCase.java index 29e580e188c7..79f8c81a8c9b 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ForEachTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ForEachTestCase.java @@ -62,7 +62,7 @@ public void requireThatExpressionCanBeVerified() { public void requireThatStructFieldCompatibilityIsVerified() { StructDataType type = new StructDataType("my_struct"); type.addField(new Field("foo", DataType.INT)); - assertVerify(type, new ForEachExpression(new SimpleExpression(DataType.INT, DataType.INT)), type); + assertVerify(type, new ForEachExpression(new SimpleExpression()), type); assertVerifyThrows("Invalid expression 'SimpleExpression': Expected string input, got int", type, new ForEachExpression(SimpleExpression.newConversion(DataType.STRING, DataType.INT))); assertVerifyThrows("Invalid expression 'for_each { SimpleExpression }': Struct field 'foo' has type int but expression produces string", type, new ForEachExpression(SimpleExpression.newConversion(DataType.INT, DataType.STRING))); } @@ -113,6 +113,19 @@ public void requireThatArrayCanBeConverted() { assertEquals(new IntegerFieldValue(9), after.get(1)); } + @Test + public void requireThatEmptyArrayCanBeConverted() { + ExecutionContext ctx = new ExecutionContext(new SimpleTestAdapter()); + ctx.setCurrentValue(new Array(DataType.getArray(DataType.STRING))); + + new ForEachExpression(new ToIntegerExpression()).execute(ctx); + + FieldValue val = ctx.getCurrentValue(); + assertTrue(val instanceof Array); + assertEquals(DataType.INT, ((Array)val).getDataType().getNestedType()); + assertTrue(((Array)val).isEmpty()); + } + @Test public void requireThatIllegalInputValueThrows() { try { @@ -123,6 +136,22 @@ public void requireThatIllegalInputValueThrows() { } } + @Test + public void requireThatArrayWithNullCanBeConverted() { + ExecutionContext ctx = new ExecutionContext(new SimpleTestAdapter()); + Array arr = new Array<>(DataType.getArray(DataType.STRING)); + arr.add(new StringFieldValue("foo")); + ctx.setCurrentValue(arr); + + new ForEachExpression(SimpleExpression.newConversion(DataType.STRING, DataType.INT) + .setExecuteValue(null)).execute(ctx); + + FieldValue val = ctx.getCurrentValue(); + assertTrue(val instanceof Array); + assertEquals(DataType.INT, ((Array)val).getDataType().getNestedType()); + assertTrue(((Array)val).isEmpty()); + } + @Test public void requireThatWsetCanBeConverted() { ExecutionContext ctx = new ExecutionContext(new SimpleTestAdapter()); @@ -141,6 +170,19 @@ public void requireThatWsetCanBeConverted() { assertEquals(Integer.valueOf(6), after.get(new IntegerFieldValue(9))); } + @Test + public void requireThatEmptyWsetCanBeConverted() { + ExecutionContext ctx = new ExecutionContext(new SimpleTestAdapter()); + ctx.setCurrentValue(new WeightedSet(DataType.getWeightedSet(DataType.STRING))); + + new ForEachExpression(new ToIntegerExpression()).execute(ctx); + + FieldValue val = ctx.getCurrentValue(); + assertTrue(val instanceof WeightedSet); + assertEquals(DataType.INT, ((WeightedSet)val).getDataType().getNestedType()); + assertTrue(((WeightedSet)val).isEmpty()); + } + @Test public void requireThatStructContentCanBeConverted() { StructDataType type = new StructDataType("my_type"); diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/GetVarTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/GetVarTestCase.java index b3c1f59ab1df..89be7daaeef7 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/GetVarTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/GetVarTestCase.java @@ -39,7 +39,7 @@ public void requireThatExpressionCanBeVerified() { VerificationContext ctx = new VerificationContext(new SimpleTestAdapter()); ctx.setVariable("foo", DataType.STRING); - new GetVarExpression("foo").verify(ctx); + assertEquals(DataType.STRING, new GetVarExpression("foo").verify(ctx)); try { new GetVarExpression("bar").verify(ctx); fail(); diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/HostNameTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/HostNameTestCase.java index eb1e1db529b8..82d8d6e5393a 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/HostNameTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/HostNameTestCase.java @@ -27,7 +27,10 @@ public void requireThatHashCodeAndEqualsAreImplemented() { @Test public void requireThatExpressionCanBeVerified() { - assertVerify(AnyDataType.instance, new HostNameExpression(), DataType.STRING); + Expression exp = new HostNameExpression(); + assertVerify(null, exp, DataType.STRING); + assertVerify(DataType.INT, exp, DataType.STRING); + assertVerify(DataType.STRING, exp, DataType.STRING); } @Test diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/InputTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/InputTestCase.java index b7878b6aadda..22a0b2366808 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/InputTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/InputTestCase.java @@ -41,7 +41,7 @@ public void requireThatHashCodeAndEqualsAreImplemented() { public void requireThatExpressionCanBeVerified() { SimpleTestAdapter adapter = new SimpleTestAdapter(new Field("foo", DataType.STRING)); adapter.setOutputValue(null, "foo", new StringFieldValue("69")); - new InputExpression("foo").verify(adapter); + assertEquals(DataType.STRING, new InputExpression("foo").verify(adapter)); try { new InputExpression("bar").verify(adapter); fail(); diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/JoinTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/JoinTestCase.java index 70562659f358..72e58f4e57bc 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/JoinTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/JoinTestCase.java @@ -36,10 +36,10 @@ public void requireThatHashCodeAndEqualsAreImplemented() { @Test public void requireThatExpressionCanBeVerified() { Expression exp = new JoinExpression(";"); - assertVerify(DataType.getArray(DataType.INT), new JoinExpression(";"), DataType.STRING); - assertVerify(DataType.getArray(DataType.STRING), new JoinExpression(";"), DataType.STRING); - assertVerifyThrows("Invalid expression 'join \";\"': Expected Array input, got no value", null, new JoinExpression(";")); - assertVerifyThrows("Invalid expression 'join \";\"': Expected Array input, got type int", DataType.INT, new JoinExpression(";")); + assertVerify(DataType.getArray(DataType.INT), exp, DataType.STRING); + assertVerify(DataType.getArray(DataType.STRING), exp, DataType.STRING); + assertVerifyThrows("Invalid expression 'join \";\"': Expected Array input, got no value", null, exp); + assertVerifyThrows("Invalid expression 'join \";\"': Expected Array input, got type int", DataType.INT, exp); } @Test diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/LiteralBoolExpressionTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/LiteralBoolExpressionTestCase.java index 776e68adcec0..ab45136f4d71 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/LiteralBoolExpressionTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/LiteralBoolExpressionTestCase.java @@ -31,7 +31,9 @@ public void requireThatHashCodeAndEqualsAreImplemented() { @Test public void requireThatExpressionCanBeVerified() { - assertVerify(AnyDataType.instance, new LiteralBoolExpression(true), DataType.BOOL); + Expression exp = new LiteralBoolExpression(true); + assertVerify(DataType.INT, exp, DataType.BOOL); + assertVerify(DataType.STRING, exp, DataType.BOOL); } @Test diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/NowTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/NowTestCase.java index d11d6f353780..4e9d51744b14 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/NowTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/NowTestCase.java @@ -34,7 +34,10 @@ public void requireThatHashCodeAndEqualsAreImplemented() { @Test public void requireThatExpressionCanBeVerified() { - assertVerify(AnyDataType.instance, new NowExpression(), DataType.LONG); + Expression exp = new NowExpression(); + assertVerify(null, exp, DataType.LONG); + assertVerify(DataType.INT, exp, DataType.LONG); + assertVerify(DataType.STRING, exp, DataType.LONG); } @Test diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/OptimizePredicateTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/OptimizePredicateTestCase.java index b0b69a94ac69..89e0de62fa54 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/OptimizePredicateTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/OptimizePredicateTestCase.java @@ -87,17 +87,17 @@ public void requireThatExpressionCanBeVerified() { VerificationContext context = new VerificationContext(new SimpleTestAdapter()).setCurrentType(DataType.PREDICATE); context.setVariable("arity", DataType.STRING); - ExpressionAssert.assertVerifyThrows(prefix + "Variable 'arity' must have type int", exp, DataType.PREDICATE, context); + ExpressionAssert.assertVerifyThrows(prefix + "Variable 'arity' must have type int", exp, context); context.setVariable("arity", DataType.INT); - assertVerifyCtx(exp, context); + assertVerifyCtx(exp, DataType.PREDICATE, context); context.setVariable("lower_bound", DataType.INT); - ExpressionAssert.assertVerifyThrows(prefix + "Variable 'lower_bound' must have type long", exp, DataType.PREDICATE, context); + ExpressionAssert.assertVerifyThrows(prefix + "Variable 'lower_bound' must have type long", exp, context); context.setVariable("lower_bound", DataType.LONG); - assertVerifyCtx(exp, context); + assertVerifyCtx(exp, DataType.PREDICATE, context); context.setVariable("upper_bound", DataType.INT); - ExpressionAssert.assertVerifyThrows(prefix + "Variable 'upper_bound' must have type long", exp, DataType.PREDICATE, context); + ExpressionAssert.assertVerifyThrows(prefix + "Variable 'upper_bound' must have type long", exp, context); context.setVariable("upper_bound", DataType.LONG); - assertVerifyCtx(exp, context); + assertVerifyCtx(exp, DataType.PREDICATE, context); } } diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/OutputAssert.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/OutputAssert.java index 5d455b5884f4..897240535ed7 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/OutputAssert.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/OutputAssert.java @@ -36,6 +36,7 @@ public static void assertVerify(OutputExpression exp) { public static void assertVerify(FieldTypeAdapter adapter, DataType value, Expression exp) { var context = new VerificationContext(adapter).setCurrentType(value); assertEquals(value, exp.setInputType(value, context)); + assertEquals(value, context.verify(exp).getCurrentType()); } public static void assertVerifyThrows(FieldTypeAdapter adapter, DataType value, Expression exp, diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/RandomTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/RandomTestCase.java index b299e7e091a5..ada30f7d5ae7 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/RandomTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/RandomTestCase.java @@ -33,7 +33,10 @@ public void requireThatHashCodeAndEqualsAreImplemented() { @Test public void requireThatExpressionCanBeVerified() { - assertVerify(AnyDataType.instance, new RandomExpression(), DataType.INT); + Expression exp = new RandomExpression(); + assertVerify(null, exp, DataType.INT); + assertVerify(DataType.INT, exp, DataType.INT); + assertVerify(DataType.STRING, exp, DataType.INT); } @Test diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/SelectInputTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/SelectInputTestCase.java index 88bc2bae8e65..708fcee9fe05 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/SelectInputTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/SelectInputTestCase.java @@ -76,7 +76,7 @@ public void requireThatSelectedExpressionIsRun() { } private static void assertVerify(FieldTypeAdapter adapter, DataType value, Expression exp) { - exp.verify(new VerificationContext(adapter).setCurrentType(value)); + assertEquals(value, exp.verify(new VerificationContext(adapter).setCurrentType(value))); } private static void assertVerifyThrows(FieldTypeAdapter adapter, Expression exp, String expectedException) { diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/SetValueTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/SetValueTestCase.java index 7ad6767bd3a5..7ef79efa62cf 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/SetValueTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/SetValueTestCase.java @@ -35,7 +35,10 @@ public void requireThatHashCodeAndEqualsAreImplemented() { @Test public void requireThatExpressionCanBeVerified() { - assertVerify(AnyDataType.instance, new ConstantExpression(new StringFieldValue("foo")), DataType.STRING); + Expression exp = new ConstantExpression(new StringFieldValue("foo")); + assertVerify(null, exp, DataType.STRING); + assertVerify(DataType.INT, exp, DataType.STRING); + assertVerify(DataType.STRING, exp, DataType.STRING); } @Test diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/SetVarTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/SetVarTestCase.java index a8b5a67d4f6b..66b34e5109dc 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/SetVarTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/SetVarTestCase.java @@ -37,8 +37,8 @@ public void requireThatHashCodeAndEqualsAreImplemented() { @Test public void requireThatExpressionCanBeVerified() { Expression exp = new SetVarExpression("foo"); - assertVerify(DataType.INT, new SetVarExpression("foo"), DataType.INT); - assertVerify(DataType.STRING, new SetVarExpression("foo"), DataType.STRING); + assertVerify(DataType.INT, exp, DataType.INT); + assertVerify(DataType.STRING, exp, DataType.STRING); assertVerifyThrows("Invalid expression 'set_var foo': Expected input, but no input is provided", null, exp); try { diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/SimpleExpression.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/SimpleExpression.java index a418ac50057b..4f4f78b0d658 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/SimpleExpression.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/SimpleExpression.java @@ -4,8 +4,6 @@ import com.yahoo.document.DataType; import com.yahoo.document.datatypes.FieldValue; -import java.util.Objects; - /** * @author Simon Thoresen Hult */ @@ -26,11 +24,6 @@ public SimpleExpression(DataType requiredInput) { this.requiredInput = requiredInput; } - public SimpleExpression(DataType requiredInput, DataType createdOutput) { - this.requiredInput = requiredInput; - this.createdOutput = createdOutput; - } - @Override public boolean requiresInput() { return requiredInput != null; } @@ -91,10 +84,10 @@ public int hashCode() { public boolean equals(Object o) { if (!(o instanceof SimpleExpression other)) return false; if (hasExecuteValue != other.hasExecuteValue) return false; - if (!Objects.equals(executeValue, other.executeValue)) return false; + if (!equals(executeValue, other.executeValue)) return false; if (hasVerifyValue != other.hasVerifyValue) return false; - if (!Objects.equals(verifyValue, other.verifyValue)) return false; - if (!Objects.equals(createdOutput, other.createdOutput)) return false; + if (!equals(verifyValue, other.verifyValue)) return false; + if (!equals(createdOutput, other.createdOutput)) return false; return true; } diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/SimpleExpressionTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/SimpleExpressionTestCase.java index 48fde32b650b..f01400957e71 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/SimpleExpressionTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/SimpleExpressionTestCase.java @@ -20,10 +20,10 @@ public void requireThatAccessorsWork() { SimpleExpression exp = new SimpleExpression(); assertNull(exp.createdOutputType()); assertNull(exp.execute()); - exp.verify(new SimpleTestAdapter()); + assertNull(exp.verify(new SimpleTestAdapter())); assertEquals(DataType.INT, new SimpleExpression().setCreatedOutput(DataType.INT).createdOutputType()); - new SimpleExpression().setVerifyValue(DataType.INT).verify(new SimpleTestAdapter()); + assertEquals(DataType.INT, new SimpleExpression().setVerifyValue(DataType.INT).verify(new SimpleTestAdapter())); assertEquals(new IntegerFieldValue(69), new SimpleExpression().setExecuteValue(new IntegerFieldValue(69)).execute()); } diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/StatementTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/StatementTestCase.java index 33386b321477..5aada78f6f72 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/StatementTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/StatementTestCase.java @@ -85,6 +85,8 @@ public void requireThatInternalVerificationIsPerformed() { exp = newStatement(SimpleExpression.newOutput(DataType.INT), SimpleExpression.newConversion(DataType.INT, DataType.STRING)); assertVerify(null, exp, DataType.STRING); + assertVerify(DataType.INT, exp, DataType.STRING); + assertVerify(DataType.STRING, exp, DataType.STRING); } @Test diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/SwitchTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/SwitchTestCase.java index b657e1434cb8..c82fc594d447 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/SwitchTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/SwitchTestCase.java @@ -62,7 +62,7 @@ public void requireThatHashCodeAndEqualsAreImplemented() { public void requireThatExpressionCanBeVerified() { Expression foo = SimpleExpression.newConversion(DataType.STRING, DataType.INT); Expression exp = new SwitchExpression(Map.of("foo", foo)); - assertVerify(DataType.STRING, exp, DataType.INT); + assertVerify(DataType.STRING, exp, DataType.STRING); // does not touch output assertVerifyThrows("Invalid expression 'switch { case \"foo\": SimpleExpression; }': Expected string input, but no input is provided", null, exp); assertVerifyThrows("Invalid expression 'switch { case \"foo\": SimpleExpression; }': Expected string input, got int", DataType.INT, exp); } @@ -71,8 +71,10 @@ public void requireThatExpressionCanBeVerified() { public void requireThatCasesAreVerified() { Map cases = new HashMap<>(); cases.put("foo", SimpleExpression.newRequired(DataType.INT)); - assertVerifyThrows("Invalid expression 'SimpleExpression': Expected int input, got string", DataType.STRING, new SwitchExpression(cases)); - assertVerifyThrows("Invalid expression 'SimpleExpression': Expected int input, got string", DataType.STRING, new SwitchExpression(Map.of(), SimpleExpression.newRequired(DataType.INT))); + assertVerifyThrows("Invalid expression 'SimpleExpression': Expected int input, got string", DataType.STRING, new SwitchExpression(cases) + ); + assertVerifyThrows("Invalid expression 'SimpleExpression': Expected int input, got string", DataType.STRING, new SwitchExpression(Map.of(), SimpleExpression.newRequired(DataType.INT)) + ); } @Test diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ThisTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ThisTestCase.java index 6162a50483e6..a01d200e1ce1 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ThisTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ThisTestCase.java @@ -26,9 +26,10 @@ public void requireThatHashCodeAndEqualsAreImplemented() { @Test public void requireThatExpressionCanBeVerified() { - assertVerify(DataType.INT, new ThisExpression(), DataType.INT); - assertVerify(DataType.STRING, new ThisExpression(), DataType.STRING); - assertVerifyThrows("Invalid expression 'this': Expected input, but no input is provided", null, new ThisExpression()); + Expression exp = new ThisExpression(); + assertVerify(DataType.INT, exp, DataType.INT); + assertVerify(DataType.STRING, exp, DataType.STRING); + assertVerifyThrows("Invalid expression 'this': Expected input, but no input is provided", null, exp); } @Test diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToBoolTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToBoolTestCase.java index da55e11878ad..3fe5dd8778d8 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToBoolTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToBoolTestCase.java @@ -30,9 +30,10 @@ public void requireThatHashCodeAndEqualsAreImplemented() { @Test public void requireThatExpressionCanBeVerified() { - assertVerify(DataType.INT, new ToBoolExpression(), DataType.BOOL); - assertVerify(DataType.STRING, new ToBoolExpression(), DataType.BOOL); - assertVerifyThrows("Invalid expression 'to_bool': Expected input, but no input is provided", null, new ToBoolExpression()); + Expression exp = new ToBoolExpression(); + assertVerify(DataType.INT, exp, DataType.BOOL); + assertVerify(DataType.STRING, exp, DataType.BOOL); + assertVerifyThrows("Invalid expression 'to_bool': Expected input, but no input is provided", null, exp); } @Test diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToByteTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToByteTestCase.java index 3b629d9407af..341f1e9c92ff 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToByteTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToByteTestCase.java @@ -29,9 +29,10 @@ public void requireThatHashCodeAndEqualsAreImplemented() { @Test public void requireThatExpressionCanBeVerified() { - assertVerify(DataType.INT, new ToByteExpression(), DataType.BYTE); - assertVerify(DataType.STRING, new ToByteExpression(), DataType.BYTE); - assertVerifyThrows("Invalid expression 'to_byte': Expected input, but no input is provided", null, new ToByteExpression()); + Expression exp = new ToByteExpression(); + assertVerify(DataType.INT, exp, DataType.BYTE); + assertVerify(DataType.STRING, exp, DataType.BYTE); + assertVerifyThrows("Invalid expression 'to_byte': Expected input, but no input is provided", null, exp); } @Test diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToDoubleTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToDoubleTestCase.java index 68ddb7a04004..07d5b0ddeb5f 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToDoubleTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToDoubleTestCase.java @@ -29,9 +29,10 @@ public void requireThatHashCodeAndEqualsAreImplemented() { @Test public void requireThatExpressionCanBeVerified() { - assertVerify(DataType.INT, new ToDoubleExpression(), DataType.DOUBLE); - assertVerify(DataType.STRING, new ToDoubleExpression(), DataType.DOUBLE); - assertVerifyThrows("Invalid expression 'to_double': Expected input, but no input is provided", null, new ToDoubleExpression()); + Expression exp = new ToDoubleExpression(); + assertVerify(DataType.INT, exp, DataType.DOUBLE); + assertVerify(DataType.STRING, exp, DataType.DOUBLE); + assertVerifyThrows("Invalid expression 'to_double': Expected input, but no input is provided", null, exp); } @Test diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToFloatTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToFloatTestCase.java index 6cdd81209b08..cf9a124128e1 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToFloatTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToFloatTestCase.java @@ -29,9 +29,10 @@ public void requireThatHashCodeAndEqualsAreImplemented() { @Test public void requireThatExpressionCanBeVerified() { - assertVerify(DataType.INT, new ToFloatExpression(), DataType.FLOAT); - assertVerify(DataType.STRING, new ToFloatExpression(), DataType.FLOAT); - assertVerifyThrows("Invalid expression 'to_float': Expected input, but no input is provided", null, new ToFloatExpression()); + Expression exp = new ToFloatExpression(); + assertVerify(DataType.INT, exp, DataType.FLOAT); + assertVerify(DataType.STRING, exp, DataType.FLOAT); + assertVerifyThrows("Invalid expression 'to_float': Expected input, but no input is provided", null, exp); } @Test diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToIntegerTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToIntegerTestCase.java index ea42cf7efe71..a182f40e829a 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToIntegerTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToIntegerTestCase.java @@ -29,9 +29,10 @@ public void requireThatHashCodeAndEqualsAreImplemented() { @Test public void requireThatExpressionCanBeVerified() { - assertVerify(DataType.INT, new ToIntegerExpression(), DataType.INT); - assertVerify(DataType.STRING, new ToIntegerExpression(), DataType.INT); - assertVerifyThrows("Invalid expression 'to_int': Expected input, but no input is provided", null, new ToIntegerExpression()); + Expression exp = new ToIntegerExpression(); + assertVerify(DataType.INT, exp, DataType.INT); + assertVerify(DataType.STRING, exp, DataType.INT); + assertVerifyThrows("Invalid expression 'to_int': Expected input, but no input is provided", null, exp); } @Test diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToLongTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToLongTestCase.java index 8ed52a535ac8..b047edc0eb12 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToLongTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToLongTestCase.java @@ -29,9 +29,10 @@ public void requireThatHashCodeAndEqualsAreImplemented() { @Test public void requireThatExpressionCanBeVerified() { - assertVerify(DataType.INT, new ToLongExpression(), DataType.LONG); - assertVerify(DataType.STRING, new ToLongExpression(), DataType.LONG); - assertVerifyThrows("Invalid expression 'to_long': Expected input, but no input is provided", null, new ToLongExpression()); + Expression exp = new ToLongExpression(); + assertVerify(DataType.INT, exp, DataType.LONG); + assertVerify(DataType.STRING, exp, DataType.LONG); + assertVerifyThrows("Invalid expression 'to_long': Expected input, but no input is provided", null, exp); } @Test diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToStringTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToStringTestCase.java index 4d9a74892fb2..e73e604c1cc4 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToStringTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToStringTestCase.java @@ -29,9 +29,10 @@ public void requireThatHashCodeAndEqualsAreImplemented() { @Test public void requireThatExpressionCanBeVerified() { - assertVerify(DataType.INT, new ToStringExpression(), DataType.STRING); - assertVerify(DataType.STRING, new ToStringExpression(), DataType.STRING); - assertVerifyThrows("Invalid expression 'to_string': Expected input, but no input is provided", null, new ToStringExpression()); + Expression exp = new ToStringExpression(); + assertVerify(DataType.INT, exp, DataType.STRING); + assertVerify(DataType.STRING, exp, DataType.STRING); + assertVerifyThrows("Invalid expression 'to_string': Expected input, but no input is provided", null, exp); } @Test diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToWsetTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToWsetTestCase.java index b2ae816e84c5..ca5c207a7b86 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToWsetTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/ToWsetTestCase.java @@ -55,12 +55,11 @@ public void requireThatValueIsConverted() { } private static void assertVerify(boolean createIfNonExistent, boolean removeIfZero) { - ExpressionAssert.assertVerify(DataType.INT, new ToWsetExpression(createIfNonExistent, removeIfZero), + Expression expression = new ToWsetExpression(createIfNonExistent, removeIfZero); + ExpressionAssert.assertVerify(DataType.INT, expression, DataType.getWeightedSet(DataType.INT, createIfNonExistent, removeIfZero)); - ExpressionAssert.assertVerify(DataType.STRING, new ToWsetExpression(createIfNonExistent, removeIfZero), + ExpressionAssert.assertVerify(DataType.STRING, expression, DataType.getWeightedSet(DataType.STRING, createIfNonExistent, removeIfZero)); - - Expression expression = new ToWsetExpression(createIfNonExistent, removeIfZero); assertVerifyThrows("Invalid expression '" + expression + "': " + "Expected input, but no input is provided", null, expression); } diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/VerificationContextTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/VerificationContextTestCase.java index 61a089178a2a..2f821907d943 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/VerificationContextTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/VerificationContextTestCase.java @@ -13,6 +13,14 @@ */ public class VerificationContextTestCase { + @Test + public void requireThatValueCanBeSet() { + VerificationContext ctx = new VerificationContext(new SimpleTestAdapter()); + DataType val = DataType.STRING; + ctx.setCurrentType(val); + assertSame(val, ctx.getCurrentType()); + } + @Test public void requireThatVariablesCanBeSet() { VerificationContext ctx = new VerificationContext(new SimpleTestAdapter()); @@ -21,6 +29,14 @@ public void requireThatVariablesCanBeSet() { assertSame(val, ctx.getVariable("foo")); } + @Test + public void requireThatClearRemovesValue() { + VerificationContext ctx = new VerificationContext(new SimpleTestAdapter()); + ctx.setCurrentType(DataType.STRING); + ctx.clear(); + assertNull(ctx.getCurrentType()); + } + @Test public void requireThatClearRemovesVariables() { VerificationContext ctx = new VerificationContext(new SimpleTestAdapter());