From 1a0d6417998cdc5466dae0e358a934345c5ae960 Mon Sep 17 00:00:00 2001 From: Jon Bratseth Date: Fri, 31 Jan 2025 12:03:30 +0100 Subject: [PATCH 1/3] Revert "Revert "Bratseth/type inference cleanup"" This reverts commit 44ca51241503fdcde698e3bfaa605a840a850bda. --- .../yahoo/schema/processing/ExactMatch.java | 5 +- .../schema/processing/IndexingValidation.java | 21 +++--- .../schema/processing/IndexingValues.java | 2 +- .../yahoo/search/yql/YqlParserTestCase.java | 8 +++ .../indexinglanguage/FieldValueConverter.java | 26 ++----- .../ValueTransformProvider.java | 16 ++--- .../expressions/BusyWaitExpression.java | 3 + .../expressions/ConstantExpression.java | 2 +- .../expressions/EchoExpression.java | 3 + .../expressions/ExactExpression.java | 3 + .../expressions/Expression.java | 67 ++++++------------ .../expressions/ForEachExpression.java | 13 ++-- .../expressions/GuardExpression.java | 3 + .../expressions/IfThenExpression.java | 8 ++- .../expressions/InputExpression.java | 3 +- .../expressions/NGramExpression.java | 3 + .../expressions/NowExpression.java | 3 +- .../OptimizePredicateExpression.java | 4 ++ .../expressions/OutputExpression.java | 6 +- .../expressions/ParenthesisExpression.java | 3 + .../expressions/RandomExpression.java | 2 +- .../expressions/ScriptExpression.java | 7 ++ .../expressions/SetLanguageExpression.java | 3 + .../expressions/SetVarExpression.java | 3 + .../expressions/SleepExpression.java | 3 + .../expressions/StatementExpression.java | 5 ++ .../expressions/SwitchExpression.java | 9 ++- .../expressions/ThisExpression.java | 3 + .../expressions/ToBoolExpression.java | 2 +- .../expressions/TokenizeExpression.java | 3 + .../expressions/VerificationContext.java | 11 --- .../EmbeddingScriptTestCase.java | 20 ++---- .../EmbeddingScriptTester.java | 8 +-- .../GenerateExpressionTestCase.java | 8 +-- .../indexinglanguage/ScriptTestCase.java | 68 ++++++++++++++++--- .../expressions/ArithmeticTestCase.java | 4 +- .../expressions/CatTestCase.java | 30 -------- .../expressions/ClearStateTestCase.java | 6 +- .../expressions/EchoTestCase.java | 5 +- .../expressions/ExpressionAssert.java | 17 +++-- .../expressions/ExpressionAssertTestCase.java | 8 --- .../expressions/ExpressionTestCase.java | 23 +------ .../expressions/ForEachTestCase.java | 44 +----------- .../expressions/GetVarTestCase.java | 2 +- .../expressions/HostNameTestCase.java | 5 +- .../expressions/InputTestCase.java | 2 +- .../expressions/JoinTestCase.java | 8 +-- .../LiteralBoolExpressionTestCase.java | 4 +- .../expressions/NowTestCase.java | 5 +- .../OptimizePredicateTestCase.java | 12 ++-- .../expressions/OutputAssert.java | 1 - .../expressions/RandomTestCase.java | 5 +- .../expressions/SelectInputTestCase.java | 2 +- .../expressions/SetValueTestCase.java | 5 +- .../expressions/SetVarTestCase.java | 4 +- .../expressions/SimpleExpression.java | 13 +++- .../expressions/SimpleExpressionTestCase.java | 4 +- .../expressions/StatementTestCase.java | 2 - .../expressions/SwitchTestCase.java | 8 +-- .../expressions/ThisTestCase.java | 7 +- .../expressions/ToBoolTestCase.java | 7 +- .../expressions/ToByteTestCase.java | 7 +- .../expressions/ToDoubleTestCase.java | 7 +- .../expressions/ToFloatTestCase.java | 7 +- .../expressions/ToIntegerTestCase.java | 7 +- .../expressions/ToLongTestCase.java | 7 +- .../expressions/ToStringTestCase.java | 7 +- .../expressions/ToWsetTestCase.java | 7 +- .../VerificationContextTestCase.java | 16 ----- 69 files changed, 284 insertions(+), 371 deletions(-) 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 4313ceb4be10..10d78c4b3870 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,10 +90,9 @@ private void exactMatchSettingsForField(SDField field) { private static class MyProvider extends TypedTransformProvider { - private int maxTokenLength; + private final 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 fe63776118a1..56d50285dbcc 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.createdOutputType() != null) { + if (expression.isMutating()) { prevNames.clear(); } return false; @@ -98,9 +98,8 @@ 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(); } @@ -110,16 +109,14 @@ 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) { @@ -131,7 +128,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"; @@ -142,7 +139,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 cac31bea7437..faa9216ef74a 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.createdOutputType() != null) { + } else if (exp.isMutating()) { 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 4aa6c65ad8f7..ad907d9149bd 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,6 +581,14 @@ 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 b18d1f1dc890..b83c731d1267 100644 --- a/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/FieldValueConverter.java +++ b/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/FieldValueConverter.java @@ -12,26 +12,14 @@ */ public abstract class FieldValueConverter { - @SuppressWarnings({ "unchecked" }) + @SuppressWarnings({ "rawtypes", "unchecked" }) public final FieldValue convert(FieldValue value) { - 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); - } + 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); 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 437d5549c971..7c8dcbaa8e82 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 exp) { - if (transformClass.isInstance(exp)) { + protected final boolean shouldConvert(Expression expression) { + if (transformClass.isInstance(expression)) { if (transformed) { duplicate = true; return true; @@ -34,16 +34,8 @@ protected final boolean shouldConvert(Expression exp) { transformed = true; return false; } - if (exp.createdOutputType() != null) { - transformed = false; - return false; - } - if ( ! requiresTransform(exp)) { - return false; - } - if (transformed) { - return false; - } + if ( ! requiresTransform(expression)) 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 6483dd62f238..05fda004b360 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,6 +12,9 @@ */ 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 1220576fe77a..5a2534cdca91 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 null; + return AnyDataType.instance; } @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 1f22989b21cf..126c78db4cca 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,6 +20,9 @@ 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 cb1df30983d7..61916b8f7976 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,6 +37,9 @@ 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 e8032ff65f9c..3a28264c6f02 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,6 +44,12 @@ 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. @@ -152,50 +158,38 @@ public final void verify(DocumentType type) { verify(new DocumentTypeAdapter(type)); } - public final Document verify(Document doc) { - return verify(new SimpleAdapterFactory(), doc); + public final void verify(Document doc) { + verify(new SimpleAdapterFactory(), doc); } - public final Document verify(AdapterFactory factory, Document doc) { - return verify(factory.newDocumentAdapter(doc)); + public final void verify(AdapterFactory factory, Document doc) { + verify(factory.newDocumentAdapter(doc)); } - public final Document verify(DocumentAdapter adapter) { + public final void verify(DocumentAdapter adapter) { verify((FieldTypeAdapter)adapter); - return adapter.getFullOutput(); + adapter.getFullOutput(); } - public final DocumentUpdate verify(DocumentUpdate upd) { - return verify(new SimpleAdapterFactory(), upd); + public final void verify(DocumentUpdate upd) { + verify(new SimpleAdapterFactory(), upd); } - 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(AdapterFactory factory, DocumentUpdate upd) { + for (UpdateAdapter adapter : factory.newUpdateAdapterList(upd)) + verify(adapter); } - public final DocumentUpdate verify(UpdateAdapter adapter) { + public final void verify(UpdateAdapter adapter) { verify((FieldTypeAdapter)adapter); - return adapter.getOutput(); } - public final DataType verify(FieldTypeAdapter adapter) { - return verify(new VerificationContext(adapter)); + public final void verify(FieldTypeAdapter adapter) { + verify(new VerificationContext(adapter)); } - public final DataType verify(VerificationContext context) { + public final void verify(VerificationContext context) { doVerify(context); - return context.getCurrentType(); } protected void doVerify(VerificationContext context) {} @@ -246,14 +240,6 @@ 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(); } @@ -276,17 +262,6 @@ 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 8e23745e67be..6b0931f89acb 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,6 +32,9 @@ public ForEachExpression(Expression expression) { this.expression = Objects.requireNonNull(expression); } + @Override + public boolean isMutating() { return expression.isMutating(); } + public Expression getInnerExpression() { return expression; } @Override @@ -167,12 +170,8 @@ 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) { - VerificationContext verificationContext = new VerificationContext(context.getFieldValue()); - context.fillVariableTypes(verificationContext); - verificationContext.setCurrentType(input.getDataType()).verify(this); - next = verificationContext.getCurrentType().createFieldValue(); - } + if (next == null) + next = getOutputType().createFieldValue(); context.setCurrentValue(next); } else if (input instanceof Struct || input instanceof Map) { context.setCurrentValue(new ExecutionConverter(context, expression).convert(input)); @@ -227,7 +226,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.createdOutputType()), map.size()); + var values = new Array<>(new ArrayDataType(expression.getOutputType()), 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 e92dc4278af1..1775fd73f3e0 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,6 +23,9 @@ 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 a2af300a0de0..a49dfb732580 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,6 +11,7 @@ import com.yahoo.vespa.objects.ObjectPredicate; import java.math.BigDecimal; +import java.util.Objects; /** * @author Simon Thoresen Hult @@ -56,6 +57,11 @@ 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()); @@ -178,7 +184,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 ( ! equals(ifFalse, exp.ifFalse)) return false; + if ( ! Objects.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 81d262808a4d..1268b3b541bf 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,6 +9,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Objects; /** * @author Simon Thoresen Hult @@ -77,7 +78,7 @@ public String toString() { @Override public boolean equals(Object obj) { if ( ! (obj instanceof InputExpression rhs)) return false; - if ( ! equals(fieldName, rhs.fieldName)) return false; + if ( ! Objects.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 7621906cfee5..fa08ba730cd7 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,6 +38,9 @@ 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 50ade192e4b9..3da2e4df7888 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,7 +26,8 @@ public NowExpression(Timer timer) { @Override public DataType setInputType(DataType inputType, VerificationContext context) { - return super.setInputType(inputType, context); + super.setInputType(inputType, context); + return DataType.LONG; } @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 4d1e60cc5a84..3cbc6dcc6851 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,6 +28,10 @@ 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 e6682045366c..b33c212ccff0 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,6 +7,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Objects; /** * @author Simon Thoresen Hult @@ -21,6 +22,9 @@ public OutputExpression(String image, String fieldName) { this.fieldName = fieldName; } + @Override + public boolean isMutating() { return false; } + public String getFieldName() { return fieldName; } @Override @@ -60,7 +64,7 @@ public String toString() { @Override public boolean equals(Object obj) { if (!(obj instanceof OutputExpression rhs)) return false; - if (!equals(fieldName, rhs.fieldName)) return false; + if (!Objects.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 78b4e998728d..0e659946460e 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,6 +19,9 @@ 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 ee60a16a0e7e..162a2b9d1435 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 (!equals(max, rhs.max)) return false; + if (!Objects.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 6c28719d80a3..02b0274d870f 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,6 +44,13 @@ 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 2e419db14348..2c993fc5b05d 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,6 +11,9 @@ */ 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 0d3f2cad6f68..9c1a1b324fdf 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,6 +14,9 @@ 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 54174868ba99..f5e768296a55 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,6 +12,9 @@ */ 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 c419519d2688..3c641dd3798c 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,6 +42,11 @@ 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 38a7c720b4e8..6c3e5a9048ba 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,6 +14,7 @@ import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Objects; /** * @author Simon Thoresen Hult @@ -34,6 +35,9 @@ public SwitchExpression(Map cases, Expression this.cases.putAll(cases); } + @Override + public boolean isMutating() { return false; } + public boolean isEmpty() { return defaultExp == null && cases.isEmpty(); } @@ -73,7 +77,8 @@ public DataType setInputType(DataType inputType, VerificationContext context) { public DataType setOutputType(DataType outputType, VerificationContext context) { super.setOutputType(outputType, context); - setOutputType(outputType, defaultExp, context); + if (defaultExp != null) + setOutputType(outputType, defaultExp, context); for (Expression expression : cases.values()) setOutputType(outputType, expression, context); return DataType.STRING; @@ -160,7 +165,7 @@ public String toString() { public boolean equals(Object obj) { if (!(obj instanceof SwitchExpression rhs)) return false; if (!cases.equals(rhs.cases)) return false; - if (!equals(defaultExp, rhs.defaultExp)) return false; + if (!Objects.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 31a0d862b9c5..42de4e694726 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,6 +8,9 @@ */ 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 2d388453ab8a..4eb2734c0e70 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 f7e14887a508..400788e52cc0 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,6 +22,9 @@ 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 64ea7c0af434..47ce3c6d6763 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,11 +27,6 @@ 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); @@ -57,12 +52,6 @@ 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 7a7062abf910..72b2ea87386c 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/EmbeddingScriptTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/EmbeddingScriptTestCase.java @@ -86,9 +86,7 @@ public void testArrayEmbed() { adapter.setValue("myTextArray", array); expression.setStatementOutput(new DocumentType("myDocument"), tensorField); - // Necessary to resolve output type - VerificationContext verificationContext = new VerificationContext(adapter); - assertEquals(new ArrayDataType(new TensorDataType(tensorType)), expression.verify(verificationContext)); + expression.verify(new VerificationContext(adapter)); ExecutionContext context = new ExecutionContext(adapter); context.setCurrentValue(array); @@ -123,9 +121,7 @@ public void testArrayEmbedWithConcatenation() { expression.setStatementOutput(new DocumentType("myDocument"), tensorField); - // Necessary to resolve output type - VerificationContext verificationContext = new VerificationContext(adapter); - assertEquals(new TensorDataType(tensorType), expression.verify(verificationContext)); + expression.verify(new VerificationContext(adapter)); ExecutionContext context = new ExecutionContext(adapter); context.setCurrentValue(array); @@ -156,9 +152,7 @@ public void testArrayEmbedTo2dMixedTensor() { adapter.setValue("myTextArray", array); expression.setStatementOutput(new DocumentType("myDocument"), tensorField); - // Necessary to resolve output type - VerificationContext verificationContext = new VerificationContext(adapter); - assertEquals(new TensorDataType(tensorType), expression.verify(verificationContext)); + expression.verify(new VerificationContext(adapter)); ExecutionContext context = new ExecutionContext(adapter); context.setCurrentValue(array); @@ -189,7 +183,7 @@ public void testArrayEmbedTo3dMixedTensor() { adapter.setValue("myTextArray", array); expression.setStatementOutput(new DocumentType("myDocument"), tensorField); - assertEquals(new TensorDataType(tensorType), expression.verify(new VerificationContext(adapter))); + expression.verify(new VerificationContext(adapter)); ExecutionContext context = new ExecutionContext(adapter); context.setCurrentValue(array); @@ -291,9 +285,7 @@ public void testEmbedToSparseTensor() { adapter.setValue("text", text); expression.setStatementOutput(new DocumentType("myDocument"), tensorField); - // Necessary to resolve output type - VerificationContext verificationContext = new VerificationContext(adapter); - assertEquals(new TensorDataType(tensorType), expression.verify(verificationContext)); + expression.verify(new VerificationContext(adapter)); ExecutionContext context = new ExecutionContext(adapter); context.setCurrentValue(text); @@ -349,7 +341,7 @@ public void testArrayEmbedTo2MappedTensor() { adapter.setValue("myTextArray", array); expression.setStatementOutput(new DocumentType("myDocument"), tensorField); - assertEquals(new TensorDataType(tensorType), expression.verify(new VerificationContext(adapter))); + 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 e4171e60a709..11a8de96ea7b 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/EmbeddingScriptTester.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/EmbeddingScriptTester.java @@ -47,9 +47,7 @@ public void testStatement(String expressionString, String input, String targetTe adapter.setValue("myText", new StringFieldValue(input)); expression.setStatementOutput(new DocumentType("myDocument"), tensorField); - // Necessary to resolve output type - VerificationContext verificationContext = new VerificationContext(adapter); - assertEquals(TensorDataType.class, expression.verify(verificationContext).getClass()); + expression.verify(new VerificationContext(adapter)); ExecutionContext context = new ExecutionContext(adapter); expression.execute(context); @@ -75,9 +73,7 @@ public void testStatement2(String expressionString, String input, String targetT adapter.setValue("myText", new StringFieldValue(input)); expression.setStatementOutput(new DocumentType("myDocument"), tensorField); - // Necessary to resolve output type - VerificationContext verificationContext = new VerificationContext(adapter); - assertEquals(TensorDataType.class, expression.verify(verificationContext).getClass()); + expression.verify(new VerificationContext(adapter)); 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 70e6b086c0dc..0fb21e40c345 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/GenerateExpressionTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/GenerateExpressionTestCase.java @@ -162,9 +162,7 @@ public void testWithArrayInputArrayOutput() { adapter.setValue("myArray", inputArray); expression.setStatementOutput(new DocumentType("myDocument"), outputField); - // Necessary to resolve output type - VerificationContext verificationContext = new VerificationContext(adapter); - assertEquals(new ArrayDataType(DataType.STRING), expression.verify(verificationContext)); + expression.verify(new VerificationContext(adapter)); ExecutionContext context = new ExecutionContext(adapter); expression.execute(context); @@ -230,9 +228,7 @@ public void testGeneratorWithStringInputArrayOutput() { expression.setStatementOutput(new DocumentType("myDocument"), outputField); - // Necessary to resolve output type - VerificationContext verificationContext = new VerificationContext(adapter); - assertEquals(new ArrayDataType(DataType.STRING), expression.verify(verificationContext)); + expression.verify(new VerificationContext(adapter)); 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 cce45a86146f..6ed3feb0230c 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/ScriptTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/ScriptTestCase.java @@ -6,6 +6,7 @@ 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; @@ -13,6 +14,7 @@ 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; @@ -141,8 +143,7 @@ public void testIntHash() throws ParseException { adapter.createField(intField); adapter.setValue("myText", new StringFieldValue("input text")); - VerificationContext verificationContext = new VerificationContext(adapter); - assertEquals(DataType.INT, expression.verify(verificationContext)); + expression.verify(new VerificationContext(adapter)); ExecutionContext context = new ExecutionContext(adapter); expression.execute(context); @@ -164,8 +165,7 @@ public void testIntArrayHash() throws ParseException { array.add(new StringFieldValue("second")); adapter.setValue("myTextArray", array); - VerificationContext verificationContext = new VerificationContext(adapter); - assertEquals(new ArrayDataType(DataType.INT), expression.verify(verificationContext)); + expression.verify(new VerificationContext(adapter)); ExecutionContext context = new ExecutionContext(adapter); expression.execute(context); @@ -185,8 +185,7 @@ public void testLongHash() throws ParseException { adapter.createField(intField); adapter.setValue("myText", new StringFieldValue("input text")); - VerificationContext verificationContext = new VerificationContext(adapter); - assertEquals(DataType.LONG, expression.verify(verificationContext)); + expression.verify(new VerificationContext(adapter)); ExecutionContext context = new ExecutionContext(adapter); expression.execute(context); @@ -208,8 +207,7 @@ public void testZCurveArray() throws ParseException { array.add(new StringFieldValue("50;60")); adapter.setValue("location_str", array); - VerificationContext verificationContext = new VerificationContext(adapter); - assertEquals(DataType.getArray(DataType.LONG), expression.verify(verificationContext)); + expression.verify(new VerificationContext(adapter)); ExecutionContext context = new ExecutionContext(adapter); expression.execute(context); @@ -363,4 +361,58 @@ 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 a2b2d960463c..a481e0dc5a5b 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) { - assertEquals(expected, newArithmetic(SimpleExpression.newOutput(lhs), op, - SimpleExpression.newOutput(rhs)).verify(new VerificationContext(new SimpleTestAdapter()))); + 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 a656bd5f756d..5b4ba1995209 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,14 +82,6 @@ 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")), @@ -172,22 +164,6 @@ 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() { { @@ -250,10 +226,4 @@ 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 ee09313f8e86..77577de2739a 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,10 +32,8 @@ public void requireThatExecutionContextIsCleared() { @Test public void requireThatExpressionCanBeVerified() { - Expression exp = new ClearStateExpression(); - assertVerify(null, exp, null); - assertVerify(DataType.INT, exp, null); - assertVerify(DataType.STRING, exp, null); + assertVerify(DataType.INT, new ClearStateExpression(), DataType.INT); + assertVerify(DataType.STRING, new ClearStateExpression(), DataType.STRING); } @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 a210def9b2cc..cbd52e8b15c3 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,9 +51,8 @@ public void requireThatValueIsEchoed() { @Test public void requireThatExpressionCanBeVerified() { - Expression exp = new EchoExpression(); - assertVerify(DataType.INT, exp, DataType.INT); - assertVerify(DataType.STRING, exp, DataType.STRING); + assertVerify(DataType.INT, new EchoExpression(), DataType.INT); + assertVerify(DataType.STRING, new EchoExpression(), 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 f75765567bea..e30c1f7e5f18 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,16 +13,19 @@ */ class ExpressionAssert { - public static void assertVerifyCtx(Expression expression, DataType expectedValueAfter, VerificationContext context) { - assertEquals(expectedValueAfter, expression.verify(context)); + public static void assertVerifyCtx(Expression expression, VerificationContext context) { + expression.verify(context); } - public static void assertVerify(DataType valueBefore, Expression expression, DataType expectedValueAfter) { - assertVerifyCtx(expression, expectedValueAfter, new VerificationContext(new SimpleTestAdapter()).setCurrentType(valueBefore)); + 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 assertVerifyThrows(String expectedMessage, DataType valueBefore, Expression expression) { - assertVerifyThrows(expectedMessage, expression, new VerificationContext(new SimpleTestAdapter()).setCurrentType(valueBefore)); + assertVerifyThrows(expectedMessage, expression, valueBefore, new VerificationContext(new SimpleTestAdapter()).setCurrentType(valueBefore)); } interface CreateExpression { @@ -42,9 +45,9 @@ public static void assertVerifyThrows(String expectedMessage, CreateExpression c assertEquals(expectedMessage, e.getMessage()); } } - public static void assertVerifyThrows(String expectedMessage, Expression expression, VerificationContext context) { + public static void assertVerifyThrows(String expectedMessage, Expression expression, DataType inputType, VerificationContext context) { try { - expression.setInputType(context.getCurrentType(), context); + expression.setInputType(inputType, 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 28de6e6a1b98..6c6863a3467f 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,14 +16,6 @@ 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 ed862931c3e6..e84579c5572d 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,7 +9,6 @@ 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; @@ -18,14 +17,6 @@ */ 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); @@ -37,15 +28,6 @@ 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); } @@ -54,10 +36,6 @@ 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); } @@ -86,4 +64,5 @@ 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 79f8c81a8c9b..29e580e188c7 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()), type); + assertVerify(type, new ForEachExpression(new SimpleExpression(DataType.INT, DataType.INT)), 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,19 +113,6 @@ 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 { @@ -136,22 +123,6 @@ 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()); @@ -170,19 +141,6 @@ 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 89be7daaeef7..b3c1f59ab1df 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); - assertEquals(DataType.STRING, new GetVarExpression("foo").verify(ctx)); + 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 82d8d6e5393a..eb1e1db529b8 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,10 +27,7 @@ public void requireThatHashCodeAndEqualsAreImplemented() { @Test public void requireThatExpressionCanBeVerified() { - Expression exp = new HostNameExpression(); - assertVerify(null, exp, DataType.STRING); - assertVerify(DataType.INT, exp, DataType.STRING); - assertVerify(DataType.STRING, exp, DataType.STRING); + assertVerify(AnyDataType.instance, new HostNameExpression(), 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 22a0b2366808..b7878b6aadda 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")); - assertEquals(DataType.STRING, new InputExpression("foo").verify(adapter)); + 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 72e58f4e57bc..70562659f358 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), 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); + 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(";")); } @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 ab45136f4d71..776e68adcec0 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,9 +31,7 @@ public void requireThatHashCodeAndEqualsAreImplemented() { @Test public void requireThatExpressionCanBeVerified() { - Expression exp = new LiteralBoolExpression(true); - assertVerify(DataType.INT, exp, DataType.BOOL); - assertVerify(DataType.STRING, exp, DataType.BOOL); + assertVerify(AnyDataType.instance, new LiteralBoolExpression(true), 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 4e9d51744b14..d11d6f353780 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,10 +34,7 @@ public void requireThatHashCodeAndEqualsAreImplemented() { @Test public void requireThatExpressionCanBeVerified() { - Expression exp = new NowExpression(); - assertVerify(null, exp, DataType.LONG); - assertVerify(DataType.INT, exp, DataType.LONG); - assertVerify(DataType.STRING, exp, DataType.LONG); + assertVerify(AnyDataType.instance, new NowExpression(), 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 89e0de62fa54..b0b69a94ac69 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, context); + ExpressionAssert.assertVerifyThrows(prefix + "Variable 'arity' must have type int", exp, DataType.PREDICATE, context); context.setVariable("arity", DataType.INT); - assertVerifyCtx(exp, DataType.PREDICATE, context); + assertVerifyCtx(exp, context); context.setVariable("lower_bound", DataType.INT); - ExpressionAssert.assertVerifyThrows(prefix + "Variable 'lower_bound' must have type long", exp, context); + ExpressionAssert.assertVerifyThrows(prefix + "Variable 'lower_bound' must have type long", exp, DataType.PREDICATE, context); context.setVariable("lower_bound", DataType.LONG); - assertVerifyCtx(exp, DataType.PREDICATE, context); + assertVerifyCtx(exp, context); context.setVariable("upper_bound", DataType.INT); - ExpressionAssert.assertVerifyThrows(prefix + "Variable 'upper_bound' must have type long", exp, context); + ExpressionAssert.assertVerifyThrows(prefix + "Variable 'upper_bound' must have type long", exp, DataType.PREDICATE, context); context.setVariable("upper_bound", DataType.LONG); - assertVerifyCtx(exp, DataType.PREDICATE, context); + assertVerifyCtx(exp, 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 897240535ed7..5d455b5884f4 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,7 +36,6 @@ 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 ada30f7d5ae7..b299e7e091a5 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,10 +33,7 @@ public void requireThatHashCodeAndEqualsAreImplemented() { @Test public void requireThatExpressionCanBeVerified() { - Expression exp = new RandomExpression(); - assertVerify(null, exp, DataType.INT); - assertVerify(DataType.INT, exp, DataType.INT); - assertVerify(DataType.STRING, exp, DataType.INT); + assertVerify(AnyDataType.instance, new RandomExpression(), 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 708fcee9fe05..88bc2bae8e65 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) { - assertEquals(value, exp.verify(new VerificationContext(adapter).setCurrentType(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 7ef79efa62cf..7ad6767bd3a5 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,10 +35,7 @@ public void requireThatHashCodeAndEqualsAreImplemented() { @Test public void requireThatExpressionCanBeVerified() { - Expression exp = new ConstantExpression(new StringFieldValue("foo")); - assertVerify(null, exp, DataType.STRING); - assertVerify(DataType.INT, exp, DataType.STRING); - assertVerify(DataType.STRING, exp, DataType.STRING); + assertVerify(AnyDataType.instance, new ConstantExpression(new StringFieldValue("foo")), 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 66b34e5109dc..a8b5a67d4f6b 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, exp, DataType.INT); - assertVerify(DataType.STRING, exp, DataType.STRING); + assertVerify(DataType.INT, new SetVarExpression("foo"), DataType.INT); + assertVerify(DataType.STRING, new SetVarExpression("foo"), 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 4f4f78b0d658..a418ac50057b 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,6 +4,8 @@ import com.yahoo.document.DataType; import com.yahoo.document.datatypes.FieldValue; +import java.util.Objects; + /** * @author Simon Thoresen Hult */ @@ -24,6 +26,11 @@ 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; } @@ -84,10 +91,10 @@ public int hashCode() { public boolean equals(Object o) { if (!(o instanceof SimpleExpression other)) return false; if (hasExecuteValue != other.hasExecuteValue) return false; - if (!equals(executeValue, other.executeValue)) return false; + if (!Objects.equals(executeValue, other.executeValue)) return false; if (hasVerifyValue != other.hasVerifyValue) return false; - if (!equals(verifyValue, other.verifyValue)) return false; - if (!equals(createdOutput, other.createdOutput)) return false; + if (!Objects.equals(verifyValue, other.verifyValue)) return false; + if (!Objects.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 f01400957e71..48fde32b650b 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()); - assertNull(exp.verify(new SimpleTestAdapter())); + exp.verify(new SimpleTestAdapter()); assertEquals(DataType.INT, new SimpleExpression().setCreatedOutput(DataType.INT).createdOutputType()); - assertEquals(DataType.INT, new SimpleExpression().setVerifyValue(DataType.INT).verify(new SimpleTestAdapter())); + 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 5aada78f6f72..33386b321477 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,8 +85,6 @@ 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 c82fc594d447..b657e1434cb8 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.STRING); // does not touch output + assertVerify(DataType.STRING, exp, DataType.INT); 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,10 +71,8 @@ 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 a01d200e1ce1..6162a50483e6 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,10 +26,9 @@ public void requireThatHashCodeAndEqualsAreImplemented() { @Test public void requireThatExpressionCanBeVerified() { - 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); + 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()); } @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 3fe5dd8778d8..da55e11878ad 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,10 +30,9 @@ public void requireThatHashCodeAndEqualsAreImplemented() { @Test public void requireThatExpressionCanBeVerified() { - 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); + 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()); } @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 341f1e9c92ff..3b629d9407af 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,10 +29,9 @@ public void requireThatHashCodeAndEqualsAreImplemented() { @Test public void requireThatExpressionCanBeVerified() { - 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); + 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()); } @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 07d5b0ddeb5f..68ddb7a04004 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,10 +29,9 @@ public void requireThatHashCodeAndEqualsAreImplemented() { @Test public void requireThatExpressionCanBeVerified() { - 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); + 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()); } @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 cf9a124128e1..6cdd81209b08 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,10 +29,9 @@ public void requireThatHashCodeAndEqualsAreImplemented() { @Test public void requireThatExpressionCanBeVerified() { - 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); + 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()); } @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 a182f40e829a..ea42cf7efe71 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,10 +29,9 @@ public void requireThatHashCodeAndEqualsAreImplemented() { @Test public void requireThatExpressionCanBeVerified() { - 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); + 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()); } @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 b047edc0eb12..8ed52a535ac8 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,10 +29,9 @@ public void requireThatHashCodeAndEqualsAreImplemented() { @Test public void requireThatExpressionCanBeVerified() { - 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); + 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()); } @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 e73e604c1cc4..4d9a74892fb2 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,10 +29,9 @@ public void requireThatHashCodeAndEqualsAreImplemented() { @Test public void requireThatExpressionCanBeVerified() { - 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); + 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()); } @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 ca5c207a7b86..b2ae816e84c5 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,11 +55,12 @@ public void requireThatValueIsConverted() { } private static void assertVerify(boolean createIfNonExistent, boolean removeIfZero) { - Expression expression = new ToWsetExpression(createIfNonExistent, removeIfZero); - ExpressionAssert.assertVerify(DataType.INT, expression, + ExpressionAssert.assertVerify(DataType.INT, new ToWsetExpression(createIfNonExistent, removeIfZero), DataType.getWeightedSet(DataType.INT, createIfNonExistent, removeIfZero)); - ExpressionAssert.assertVerify(DataType.STRING, expression, + ExpressionAssert.assertVerify(DataType.STRING, new ToWsetExpression(createIfNonExistent, removeIfZero), 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 2f821907d943..61a089178a2a 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,14 +13,6 @@ */ 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()); @@ -29,14 +21,6 @@ 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()); From 691fea474d61634a14de789459ecaedd8546a853 Mon Sep 17 00:00:00 2001 From: Jon Bratseth Date: Sun, 2 Feb 2025 22:02:26 +0100 Subject: [PATCH 2/3] Allow the inner type to be assignable not equal --- .../java/com/yahoo/document/ArrayDataType.java | 2 +- .../com/yahoo/document/CollectionDataType.java | 8 +++----- .../indexinglanguage/EmbeddingScriptTestCase.java | 14 ++++++++++++++ .../vespa/indexinglanguage/ScriptTestCase.java | 1 + 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/document/src/main/java/com/yahoo/document/ArrayDataType.java b/document/src/main/java/com/yahoo/document/ArrayDataType.java index 05b578f74457..4bb53bf6f77a 100644 --- a/document/src/main/java/com/yahoo/document/ArrayDataType.java +++ b/document/src/main/java/com/yahoo/document/ArrayDataType.java @@ -42,7 +42,7 @@ public Class getValueClass() { @Override public FieldPath buildFieldPath(String remainFieldName) { - if (remainFieldName.length() > 0 && remainFieldName.charAt(0) == '[') { + if (!remainFieldName.isEmpty() && remainFieldName.charAt(0) == '[') { int endPos = remainFieldName.indexOf(']'); if (endPos == -1) { throw new IllegalArgumentException("Array subscript must be closed with ]"); diff --git a/document/src/main/java/com/yahoo/document/CollectionDataType.java b/document/src/main/java/com/yahoo/document/CollectionDataType.java index 98be8d4709f5..0d328b6ee03b 100644 --- a/document/src/main/java/com/yahoo/document/CollectionDataType.java +++ b/document/src/main/java/com/yahoo/document/CollectionDataType.java @@ -46,11 +46,9 @@ public PrimitiveDataType getPrimitiveType() { @Override public boolean isValueCompatible(FieldValue value) { - if (!(value instanceof CollectionFieldValue)) { - return false; - } - CollectionFieldValue cfv = (CollectionFieldValue) value; - return equals(cfv.getDataType()); + if (!(value instanceof CollectionFieldValue collectionValue)) return false; + if (collectionValue.getDataType().getClass() != this.getClass()) return false; + return collectionValue.getDataType().getNestedType().isAssignableTo(this.getNestedType()); } @Override 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..2ddfcc1670e7 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/EmbeddingScriptTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/EmbeddingScriptTestCase.java @@ -360,4 +360,18 @@ public void testArrayEmbedTo2MappedTensor() { sparse2DTensor.getTensor().get()); } + @Test + public void testIt() { + var tester = new EmbeddingScriptTester(Map.of("emb1", new EmbeddingScriptTester.MockMappedEmbedder("myDocument.sections_embeddings"))); + var expression = tester.expressionFrom("input sections | for_each { ( _ || \"\") } | embed emb1 passage | attribute sections_embeddings | index sections_embeddings"); + + SimpleTestAdapter adapter = new SimpleTestAdapter(); + adapter.createField(new Field("sections", new ArrayDataType(DataType.STRING))); + TensorType tensorType = TensorType.fromSpec("tensor(passage{}, token{})"); + var tensorField = new Field("sections_embeddings", new TensorDataType(tensorType)); + adapter.createField(tensorField); + + expression.verify(new VerificationContext(adapter)); + } + } 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..c1c9f505f3a2 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/ScriptTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/ScriptTestCase.java @@ -33,6 +33,7 @@ /** * @author Simon Thoresen Hult + * @author bratseth */ public class ScriptTestCase { From b72e6f0d53871f086d9bda68754a3a3ce614d180 Mon Sep 17 00:00:00 2001 From: Jon Bratseth Date: Mon, 3 Feb 2025 11:26:11 +0100 Subject: [PATCH 3/3] Correct isAssignableTo in MapDataType --- .../java/com/yahoo/document/MapDataType.java | 6 +- .../expressions/AnyDataTypeTestCase.java | 72 +++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/AnyDataTypeTestCase.java diff --git a/document/src/main/java/com/yahoo/document/MapDataType.java b/document/src/main/java/com/yahoo/document/MapDataType.java index 54b5b7bcca07..268eb0257f3b 100644 --- a/document/src/main/java/com/yahoo/document/MapDataType.java +++ b/document/src/main/java/com/yahoo/document/MapDataType.java @@ -1,6 +1,7 @@ // Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.document; +import com.yahoo.document.datatypes.CollectionFieldValue; import com.yahoo.document.datatypes.FieldValue; import com.yahoo.document.datatypes.MapFieldValue; @@ -41,7 +42,10 @@ public MapDataType clone() { @Override public boolean isValueCompatible(FieldValue value) { - return value.getDataType().equals(this); + if (!(value instanceof MapFieldValue mapValue)) return false; + if (mapValue.getDataType().getClass() != this.getClass()) return false; + return mapValue.getDataType().getKeyType().isAssignableTo(this.getKeyType()) && + mapValue.getDataType().getValueType().isAssignableTo(this.getValueType()); } public DataType getKeyType() { diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/AnyDataTypeTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/AnyDataTypeTestCase.java new file mode 100644 index 000000000000..e04c4d51e33e --- /dev/null +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/expressions/AnyDataTypeTestCase.java @@ -0,0 +1,72 @@ +package com.yahoo.vespa.indexinglanguage.expressions; + +import com.yahoo.document.DataType; +import com.yahoo.document.MapDataType; +import org.junit.Test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * @author bratseth + */ +public class AnyDataTypeTestCase { + + @Test + public void testArrayAssignableTo() { + var intArray = DataType.getArray(DataType.INT); + var anyArray = DataType.getArray(AnyDataType.instance); + assertTrue(intArray.isAssignableTo(intArray)); + assertTrue(anyArray.isAssignableTo(anyArray)); + assertTrue(intArray.isAssignableTo(anyArray)); + assertFalse(anyArray.isAssignableTo(intArray)); + + var annArray = DataType.getArray(AnyNumericDataType.instance); + assertTrue(annArray.isAssignableTo(annArray)); + assertFalse(annArray.isAssignableTo(intArray)); + assertTrue(annArray.isAssignableTo(anyArray)); + assertFalse(anyArray.isAssignableTo(annArray)); + } + + @Test + public void testMapAssignableTo() { + var intIntMap = MapDataType.getMap(DataType.INT, DataType.INT); + var anyAnyMap = MapDataType.getMap(AnyDataType.instance, AnyDataType.instance); + var anyIntMap = MapDataType.getMap(AnyDataType.instance, DataType.INT); + var intAnyMap = MapDataType.getMap(DataType.INT, AnyDataType.instance); + + assertTrue(intIntMap.isAssignableTo(intIntMap)); + assertTrue(anyAnyMap.isAssignableTo(anyAnyMap)); + assertTrue(anyIntMap.isAssignableTo(anyIntMap)); + assertTrue(intAnyMap.isAssignableTo(intAnyMap)); + + assertTrue(intIntMap.isAssignableTo(anyAnyMap)); + assertTrue(intIntMap.isAssignableTo(anyIntMap)); + assertTrue(intIntMap.isAssignableTo(intAnyMap)); + + assertFalse(anyAnyMap.isAssignableTo(intIntMap)); + assertFalse(anyIntMap.isAssignableTo(intIntMap)); + assertFalse(intAnyMap.isAssignableTo(intIntMap)); + + var annAnnMap = MapDataType.getMap(AnyNumericDataType.instance, AnyNumericDataType.instance); + var annIntMap = MapDataType.getMap(AnyNumericDataType.instance, DataType.INT); + var intAnnMap = MapDataType.getMap(DataType.INT, AnyNumericDataType.instance); + + assertTrue(annAnnMap.isAssignableTo(annAnnMap)); + assertTrue(annIntMap.isAssignableTo(annIntMap)); + assertTrue(intAnnMap.isAssignableTo(intAnnMap)); + + assertFalse(annAnnMap.isAssignableTo(intIntMap)); + assertFalse(annIntMap.isAssignableTo(intIntMap)); + assertFalse(intAnnMap.isAssignableTo(intIntMap)); + + assertTrue(annAnnMap.isAssignableTo(anyAnyMap)); + assertTrue(annIntMap.isAssignableTo(anyIntMap)); + assertTrue(intAnnMap.isAssignableTo(intAnyMap)); + + assertFalse(anyAnyMap.isAssignableTo(annAnnMap)); + assertFalse(anyIntMap.isAssignableTo(annIntMap)); + assertFalse(intAnyMap.isAssignableTo(intAnnMap)); + } + +}