[
https://issues.apache.org/jira/browse/FLINK-35498?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17852333#comment-17852333
]
xuyang commented on FLINK-35498:
--------------------------------
Copied from this available pr:
Currently, we depend on asm to extract method parameter names. We custom a
MethodVisitor to visit local variable tables in file `{{{}.class`{}}}, and then
cut the first `{{{}N`{}}} local variable names as the method parameter names.
However, if there are multi blocks about one local variable, the first
`{{{}N`{}}} local variable names could be same, and then wrongly be extracted,
and crashed when validating the conflict of them(the new logic added in 1.19).
This pr will use the slot index in `{{{}.class`{}}} file to extract the method
parameter names, because method parameter names are always at the head in the
'slot index' list([Chapter 3.6. Receiving
Arguments|https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-3.html])
Take the test function
`{{{}ExtractionUtilsTest#MultiLocalVariableBlocksWithoutInitializationClass`{}}}
as an example:
* Before fix:
# extract parameter names from asm:
{{`[localVariable, localVariable, localVariable, this, generic, genericFuture,
listOfGenericFuture, array, localVariable]`}}
# get the first 4 after offset 1(expected {{this}} in index 0)
{{`[localVariable, localVariable, this, generic]`}}
This is because in local variable table, there are multi {{localVariable}} with
different lifecycle in different blocks.
* After fix:
# extract parameter names from asm:
{{`[this, generic, genericFuture, listOfGenericFuture, array, localVariable]`}}
# get the first 4 after offset 1(expected {{this}} in index 0)
{{`[generic, genericFuture, listOfGenericFuture, array]`}}
That's what we expected.
Further more, if the local variable has been initialized before `{{{}if
statement`{}}}, its lifecycle is across all `{{{}if`{}}} blocks, and there is
no need to init new local variable {{localVariable}} for it. Otherwize,
`{{{}localVariable`{}}} in multi blocks are actually not visible although it is
declared at first, and jvm will create multi `{{{}localVariable`{}}} for
different blocks and add it in local variable table(You can see in local
variable table, although these `{{{}localVariable{}}}`'s slots are same, but
their start label and end label are different).
> Unexpected argument name conflict error when do extract method params from udf
> ------------------------------------------------------------------------------
>
> Key: FLINK-35498
> URL: https://issues.apache.org/jira/browse/FLINK-35498
> Project: Flink
> Issue Type: Bug
> Components: Table SQL / Planner
> Affects Versions: 1.19.0, 1.20.0
> Reporter: lincoln lee
> Assignee: xuyang
> Priority: Major
> Labels: pull-request-available
> Attachments: image-2024-06-02-23-09-17-768.png
>
>
> Follow the steps to reproduce the error:
> test case:
> {code:java}
> util.addTemporarySystemFunction("myudf", new TestXyz)
> util.tableEnv.explainSql("select myudf(f1, f2) from t")
> {code}
>
> udf: TestXyz
> {code:java}
> public class TestXyz extends ScalarFunction {
> public String eval(String s1, String s2) {
> // will not fail if add initialization
> String localV1;
> if (s1 == null) {
> if (s2 != null) {
> localV1 = s2;
> } else {
> localV1 = s2 + s1;
> }
> } else {
> if ("xx".equals(s2)) {
> localV1 = s1.length() >= s2.length() ? s1 : s2;
> } else {
> localV1 = s1;
> }
> }
> if (s1 == null) {
> return s2 + localV1;
> }
> if (s2 == null) {
> return s1;
> }
> return s1.length() >= s2.length() ? s1 + localV1 : s2;
> }
> }
> {code}
>
> error stack:
> {code:java}
> Caused by: org.apache.flink.table.api.ValidationException: Unable to extract
> a type inference from method:
> public java.lang.String
> org.apache.flink.table.planner.runtime.utils.TestXyz.eval(java.lang.String,java.lang.String)
> at
> org.apache.flink.table.types.extraction.ExtractionUtils.extractionError(ExtractionUtils.java:362)
> at
> org.apache.flink.table.types.extraction.BaseMappingExtractor.extractResultMappings(BaseMappingExtractor.java:154)
> at
> org.apache.flink.table.types.extraction.BaseMappingExtractor.extractOutputMapping(BaseMappingExtractor.java:100)
> ... 53 more
> Caused by: org.apache.flink.table.api.ValidationException: Argument name
> conflict, there are at least two argument names that are the same.
> at
> org.apache.flink.table.types.extraction.ExtractionUtils.extractionError(ExtractionUtils.java:362)
> at
> org.apache.flink.table.types.extraction.ExtractionUtils.extractionError(ExtractionUtils.java:357)
> at
> org.apache.flink.table.types.extraction.FunctionSignatureTemplate.of(FunctionSignatureTemplate.java:73)
> at
> org.apache.flink.table.types.extraction.BaseMappingExtractor.lambda$createParameterSignatureExtraction$9(BaseMappingExtractor.java:381)
> at
> org.apache.flink.table.types.extraction.BaseMappingExtractor.putExtractedResultMappings(BaseMappingExtractor.java:298)
> at
> org.apache.flink.table.types.extraction.BaseMappingExtractor.collectMethodMappings(BaseMappingExtractor.java:244)
> at
> org.apache.flink.table.types.extraction.BaseMappingExtractor.extractResultMappings(BaseMappingExtractor.java:137)
> ... 54 more
> {code}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)