[
https://issues.apache.org/jira/browse/CALCITE-7853?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
ASF GitHub Bot updated CALCITE-7853:
------------------------------------
Labels: pull-request-available (was: )
> Lambda with no parameters throws NullPointerException when called through
> FunctionExpression.getFunction()
> ----------------------------------------------------------------------------------------------------------
>
> Key: CALCITE-7853
> URL: https://issues.apache.org/jira/browse/CALCITE-7853
> Project: Calcite
> Issue Type: Bug
> Components: linq4j
> Affects Versions: 1.42.0
> Reporter: Vladimir Sitnikov
> Priority: Major
> Labels: pull-request-available
>
> I build a linq4j lambda that takes no parameters, ask for its function with
> {{getFunction()}}, and call {{apply()}}. The call throws
> {{NullPointerException}} instead of returning the lambda's value. A lambda
> with parameters works through the same path (see
> {{ExpressionTest.testCompile}}).
> h3. Reproduction
> {code:java}
> import org.apache.calcite.linq4j.function.Function0;
> import org.apache.calcite.linq4j.tree.Expressions;
> String x =
> Expressions.<Function0<String>>lambda(Expressions.constant("abc"))
> .getFunction()
> .apply();
> {code}
> h3. Expected
> {{apply()}} returns {{"abc"}}, the value of the lambda body.
> h3. Actual
> {noformat}
> java.lang.NullPointerException: Cannot read the array length because "args"
> is null
> at
> org.apache.calcite.linq4j.tree.FunctionExpression.lambda$compile$0(FunctionExpression.java:88)
> at
> org.apache.calcite.linq4j.tree.FunctionExpression.lambda$getFunction$0(FunctionExpression.java:107)
> at jdk.proxy3/jdk.proxy3.$Proxy13.apply(Unknown Source)
> at
> org.apache.calcite.linq4j.test.ExpressionTest.testLambdaWithoutParametersViaGetFunction(ExpressionTest.java:1191)
> {noformat}
> Reproduced on main at commit 8f27e24a02 with Amazon Corretto 21.0.9. The same
> {{getFunction()}} code is in calcite-1.42.0; I did not run the reproduction
> on that release.
> h3. Analysis
> The symptom and reproduction above stand without this section.
> {{getFunction()}} wraps the compiled lambda in a {{java.lang.reflect.Proxy}}
> whose handler calls {{Invokable.dynamicInvoke(args)}}. The
> [InvocationHandler.invoke|https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/reflect/InvocationHandler.html#invoke(java.lang.Object,java.lang.reflect.Method,java.lang.Object%5B%5D)]
> contract says {{args}} is {{null}} if the interface method takes no
> arguments, and the invokable built by {{compile()}} reads {{args.length}}.
> Passing an empty array when {{args}} is {{null}} fixes it.
> Found while reviewing CALCITE-7736 ([PR
> #5213|https://github.com/apache/calcite/pull/5213]), which carries the same
> fix inside the nullness migration; this issue extracts it so it can land on
> its own.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)