Skip to content

Commit

Permalink
Allow any numeric type from arithmetic subexpressions
Browse files Browse the repository at this point in the history
  • Loading branch information
bratseth committed Nov 9, 2024
1 parent ad127ba commit fddc998
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.indexinglanguage.expressions;

import com.yahoo.document.DataType;
import com.yahoo.document.NumericDataType;
import com.yahoo.document.datatypes.DoubleFieldValue;
import com.yahoo.document.datatypes.FieldValue;

/**
* A DataType representing any numeric type. This is (so far) only needed during type resolution of indexing pipelines
* so it is placed here.
*
* @author bratseth
*/
class AnyNumericDataType extends NumericDataType {

static final AnyNumericDataType instance = new AnyNumericDataType();

private AnyNumericDataType() {
super("numeric", DataType.lastPredefinedDataTypeId() + 2, DoubleFieldValue.class, new UnsupportedFactory());
}

@Override
public boolean isAssignableFrom(DataType other) {
return other instanceof NumericDataType;
}

@Override
public boolean isAssignableTo(DataType other) {
return other instanceof AnyNumericDataType || other instanceof AnyDataType;
}

@Override
public boolean isValueCompatible(FieldValue value) {
return isAssignableFrom(value.getDataType());
}

@Override
public FieldValue createFieldValue() { throw new UnsupportedOperationException(); }

private static class UnsupportedFactory extends Factory {

public FieldValue create() {
throw new UnsupportedOperationException();
}

public FieldValue create(String value) {
throw new UnsupportedOperationException();
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ public ArithmeticExpression(Expression left, Operator op, Expression right) {

@Override
public ArithmeticExpression convertChildren(ExpressionConverter converter) {
// TODO: branch()?
return new ArithmeticExpression(converter.convert(left), op, converter.convert(right));
}

Expand All @@ -77,8 +76,8 @@ public DataType setInputType(DataType inputType, VerificationContext context) {
@Override
public DataType setOutputType(DataType outputType, VerificationContext context) {
super.setOutputType(outputType, context);
DataType leftInput = left.setOutputType(outputType, context);
DataType rightInput = right.setOutputType(outputType, context);
DataType leftInput = left.setOutputType(AnyNumericDataType.instance, context);
DataType rightInput = right.setOutputType(AnyNumericDataType.instance, context);
if (leftInput.isAssignableTo(rightInput))
return rightInput;
else if (rightInput.isAssignableTo(leftInput))
Expand All @@ -97,9 +96,9 @@ protected void doVerify(VerificationContext context) {
private DataType resultingType(DataType left, DataType right) {
if (left == null || right == null)
return null;
if (!(left instanceof NumericDataType))
if ( ! (left instanceof NumericDataType))
throw new VerificationException(this, "The first argument must be a number, but has type " + left.getName());
if (!(right instanceof NumericDataType))
if ( ! (right instanceof NumericDataType))
throw new VerificationException(this, "The second argument must be a number, but has type " + right.getName());

if (left == DataType.FLOAT || left == DataType.DOUBLE || right == DataType.FLOAT || right == DataType.DOUBLE) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ public DataType setInputType(DataType inputType, VerificationContext context) {
@Override
public DataType setOutputType(DataType outputType, VerificationContext context) {
if ( ! value.getDataType().isAssignableTo(outputType))
throw new VerificationException(this, "Produces type " + value.getDataType() + ", but type " +
outputType + " is required");
throw new VerificationException(this, "Produces type " + value.getDataType().getName() + ", but type " +
outputType.getName() + " is required");
return super.setOutputType(outputType, context);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.yahoo.document.Field;
import com.yahoo.document.datatypes.Array;
import com.yahoo.document.datatypes.BoolFieldValue;
import com.yahoo.document.datatypes.FloatFieldValue;
import com.yahoo.document.datatypes.IntegerFieldValue;
import com.yahoo.document.datatypes.LongFieldValue;
import com.yahoo.document.datatypes.MapFieldValue;
Expand Down Expand Up @@ -218,4 +219,21 @@ public void testForEachFollowedByGetVar() {
assertEquals("value2", ((StringFieldValue)adapter.values.get("id")).getString());
}

@Test
public void testFloatAndIntArithmetic() {
var tester = new ScriptTester();
var expression = tester.expressionFrom("input myFloat * 10 | attribute myFloat");

SimpleTestAdapter adapter = new SimpleTestAdapter();
var myFloat = new Field("myFloat", DataType.FLOAT);
adapter.createField(myFloat);
adapter.setValue("myFloat", new FloatFieldValue(1.3f));

expression.verify(adapter);

ExecutionContext context = new ExecutionContext(adapter);
expression.execute(context);
assertEquals(13.0f, ((FloatFieldValue)adapter.values.get("myFloat")).getFloat(), 0.000001);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.yahoo.document.DataType;
import com.yahoo.document.datatypes.FieldValue;
import com.yahoo.document.datatypes.IntegerFieldValue;
import com.yahoo.vespa.indexinglanguage.ScriptTester;
import com.yahoo.vespa.indexinglanguage.SimpleTestAdapter;
import org.junit.Test;

Expand Down

0 comments on commit fddc998

Please sign in to comment.