[ 
https://issues.apache.org/jira/browse/CALCITE-6018?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18137336#comment-18137336
 ] 

Vladimir Sitnikov commented on CALCITE-6018:
--------------------------------------------

[~xuzifu666], I'd rather not merge [PR 
5386|https://github.com/apache/calcite/pull/5386] as it is. 
{{Parameter.nullable()}} adds a Calcite-specific way to declare nullness, which 
goes against the state of the art in Java: nullness is part of the type and is 
declared with type-use annotations such as jspecify. I requested changes on the 
PR. It also has two defects:

* The {{@Nullable}} check never sees jspecify or Checker Framework annotations. 
Both are {{TYPE_USE}} annotations, and {{Method.getParameterAnnotations()}} 
returns declaration annotations only, so {{testNullableParameter}} passes 
without the annotation.
* Every primitive parameter annotated with {{@Parameter}} becomes nullable, 
because {{nullable()}} defaults to {{true}}.

I'd narrow the scope to jspecify, although the description named Checker 
Framework too. jspecify records its default in the bytecode ({{@NullMarked}}). 
Checker Framework's non-null default leaves no trace there, so Calcite cannot 
tell which unannotated types are non-null. Kotlin's 
{{org.jetbrains.annotations}} have {{CLASS}} retention, so reflection cannot 
read them at all. Proposed rule:

* Read {{method.getAnnotatedParameterTypes()}} and match the jspecify 
annotations by fully qualified name, so Calcite needs no jspecify dependency.
* An unannotated reference type is non-null only inside null-marked scope: the 
innermost {{@NullMarked}} or {{@NullUnmarked}} on the method, enclosing 
classes, package, or module decides. Elsewhere it keeps today's nullable 
default, so UDFs without jspecify annotations keep their types.
* Primitives stay {{NOT NULL}}.

Open question: what should a {{NOT NULL}} parameter mean in SQL? In the PR's 
test UDF {{MY_NONNULL_PARAM}} the parameter is {{NOT NULL}}, yet 
{{my_nonnull_param(cast(null as varchar))}} validates and returns {{NULL}}. 
Should the validator reject such a call, or does the change only affect the 
reported parameter type?

> Support nullable parameters in UDFs
> -----------------------------------
>
>                 Key: CALCITE-6018
>                 URL: https://issues.apache.org/jira/browse/CALCITE-6018
>             Project: Calcite
>          Issue Type: Improvement
>          Components: core
>    Affects Versions: 1.35.0
>            Reporter: Vladimir Sitnikov
>            Assignee: Yu Xu
>            Priority: Major
>              Labels: pull-request-available
>
> Currently Calcite treats almost all the parameters as non-nullable. There's 
> {{@Parameter(optional=true)}}, however, it mixes "optionality" vs 
> "nullability".
> In other words, I would like to have nullable, non-optional parameters in 
> UDFs.
> For instance, Calcite could pick up nullness information from annotations 
> (e.g. `@Nullable`). For instance, Kotlin compiler generates the annotations 
> automatically, so I think supporting more-or-less standard tools like 
> jspecify and checkerframework should be preferred over Calcite-only 
> annotations.
> ---
> Sample usage: {{retainedSize}} is declared as 
> https://github.com/vlsi/mat-calcite-plugin/blob/4d4aa2284eeec69bc51da0c2e769ded06ef9ab97/MatCalcitePlugin/src/com/github/vlsi/mat/calcite/functions/HeapFunctions.java#L129,
>  and I want to declare that {{retainedSize}} is fine to receive {{null}} 
> parameter.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to