Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@
import static org.elasticsearch.xpack.esql.core.type.DataType.isMillisOrNanos;
import static org.elasticsearch.xpack.esql.core.type.DataType.isSpatialPoint;
import static org.elasticsearch.xpack.esql.core.type.DataType.isTimeDuration;
import static org.elasticsearch.xpack.esql.core.type.DataType.isUnsignedLong;

/**
* Decay a numeric, spatial or date type value based on the distance of it to an origin.
Expand Down Expand Up @@ -237,8 +236,6 @@ private TypeResolution validateOriginAndScale(DataType valueType) {
);
} else if (isMillisOrNanos(valueType)) {
return validateOriginAndScale(DataType::isMillisOrNanos, "datetime or date_nanos", DataType::isTimeDuration, "time_duration");
} else if (isUnsignedLong(valueType)) {
return validateOriginAndScale(DataType::isUnsignedLong, "unsigned long", DataType::isUnsignedLong, "unsigned_long");
} else {
return validateOriginAndScale(DataType::isNumeric, "numeric", DataType::isNumeric, "numeric");
}
Expand Down Expand Up @@ -290,8 +287,8 @@ public EvalOperator.ExpressionEvaluator.Factory toEvaluator(ToEvaluator toEvalua
FoldContext foldCtx = toEvaluator.foldCtx();

// Constants
Object originFolded = origin.fold(foldCtx);
Object scaleFolded = getFoldedScale(foldCtx, valueDataType);
Object originFolded = convertToExpectedType(origin.fold(foldCtx), origin.dataType(), valueDataType);
Object scaleFolded = convertToExpectedType(getFoldedScale(foldCtx, valueDataType), scale.dataType(), valueDataType);
Object offsetFolded = getOffset(foldCtx, valueDataType, offsetExpr);
Double decayFolded = decayExpr != null ? (Double) decayExpr.fold(foldCtx) : DEFAULT_DECAY;
DecayFunction decayFunction = DecayFunction.fromBytesRef(typeExpr != null ? (BytesRef) typeExpr.fold(foldCtx) : DEFAULT_FUNCTION);
Expand Down Expand Up @@ -674,4 +671,36 @@ private Object getDefaultOffset(DataType valueDataType) {
};
}

private Object convertToExpectedType(Object value, DataType valueType, DataType targetType) {
if (targetType == INTEGER && value instanceof Integer) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can use EsqlDataTypeConverter.convert() here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return value;
}
if (targetType == LONG && value instanceof Long) {
return value;
}
if (targetType == UNSIGNED_LONG && value instanceof Long) {
return value;
}
if (targetType == DOUBLE && value instanceof Double) {
return value;
}

// Unsigned longs are represented using (Long.MIN_VALUE, Long.MAX_VALUE), therefore we need to convert
// if the targetType is not "unsigned_long"
if (valueType == UNSIGNED_LONG && targetType != UNSIGNED_LONG) {
value = NumericUtils.unsignedLongToDouble(((Number) value).longValue());
}

if (value instanceof Number num) {
return switch (targetType) {
case INTEGER -> num.intValue();
case LONG, UNSIGNED_LONG -> num.longValue();
case DOUBLE -> num.doubleValue();
default -> value;
};
}

return value;
}

}
Loading