Skip to content
Merged
31 changes: 31 additions & 0 deletions core/src/main/java/org/apache/druid/math/expr/ApplyFunction.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,18 @@ public interface ApplyFunction
*/
Set<Expr> getArrayInputs(List<Expr> args);

/**
* Returns true if apply function produces an array output. All {@link ApplyFunction} implementations are expected to
* exclusively produce either scalar or array values.
*/
default boolean hasArrayOutput(LambdaExpr lambdaExpr)
{
return false;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What if a function might sometimes return an array and might sometimes return a scalar? Is that:

  • Not allowed (functions should not differ in their return types in this way)
  • Allowed, and hasArrayOutput should be true
  • Allowed, and hasArrayOutput should be false

Please adjust the javadocs appropriately.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This should not be allowed imo, but I think we'll have to discuss this further when we get around to adding full type inference to the expression system. I will adjust the javadoc to state it should not be done currently.

}

/**
* Validate apply function arguments, throwing an exception if incorrect
*/
void validateArguments(LambdaExpr lambdaExpr, List<Expr> args);

/**
Expand All @@ -69,6 +81,12 @@ public interface ApplyFunction
*/
abstract class BaseMapFunction implements ApplyFunction
{
@Override
public boolean hasArrayOutput(LambdaExpr lambdaExpr)
{
return true;
}

/**
* Evaluate {@link LambdaExpr} against every index position of an {@link IndexableMapLambdaObjectBinding}
*/
Expand Down Expand Up @@ -260,6 +278,13 @@ ExprEval applyFold(LambdaExpr lambdaExpr, Object accumulator, IndexableFoldLambd
}
return ExprEval.bestEffortOf(accumulator);
}

@Override
public boolean hasArrayOutput(LambdaExpr lambdaExpr)
{
Expr.BindingDetails lambdaBindingDetails = lambdaExpr.analyzeInputs();
return lambdaBindingDetails.isOutputArray();
}
}

/**
Expand Down Expand Up @@ -397,6 +422,12 @@ public String name()
return NAME;
}

@Override
public boolean hasArrayOutput(LambdaExpr lambdaExpr)
{
return true;
}

@Override
public ExprEval apply(LambdaExpr lambdaExpr, List<Expr> argsExpr, Expr.ObjectBinding bindings)
{
Expand Down
Loading