-
Notifications
You must be signed in to change notification settings - Fork 13.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FLINK-15266] Fix NPE for case operator code gen in blink planner #10594
[FLINK-15266] Fix NPE for case operator code gen in blink planner #10594
Conversation
Thanks a lot for your contribution to the Apache Flink project. I'm the @flinkbot. I help the community Automated ChecksLast check on commit 2c31b9b (Mon Dec 16 13:03:48 UTC 2019) Warnings:
Mention the bot in a comment to re-run the automated checks. Review Progress
Please see the Pull Request Review Guide for a full explanation of the review process. The Bot is tracking the review progress through labels. Labels are applied according to the order of the review items. For consensus, approval by a Flink committer of PMC member is required Bot commandsThe @flinkbot bot supports the following commands:
|
CI report:
Bot commandsThe @flinkbot bot supports the following commands:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for fixing this! Could you also add a test case?
Please fix the code style error as well. |
Hi @libenchao , do you have time to add some tests for this? As this is a blocker issue of release 1.10, if you don't have enough time, I can help to improve the fixing. |
@KurtYoung @wuchong Thanks for the review. Sorry for the late reply. About the tests, I've been working around. I'd appreciate it if you could give some advice here. I come out with two testing methods:
|
Hi @libenchao , thanks for fixing, I'll review this. |
About the tests: This case, I think you can try # 1 first. |
@@ -1278,7 +1278,11 @@ object ScalarOperatorGens { | |||
val falseAction = generateIfElse(ctx, operands, resultType, i + 2) | |||
|
|||
val Seq(resultTerm, nullTerm) = newNames("result", "isNull") | |||
val resultTypeTerm = primitiveTypeTermForType(resultType) | |||
val resultTypeTerm = if (trueAction.resultType.isNullable || falseAction.resultType.isNullable) { | |||
boxedTypeTermForType(resultType) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should not modify here. We always use primitiveTypeTermForType
as much as possible.
boxedTypeTermForType(resultType) | ||
} else { | ||
primitiveTypeTermForType(resultType) | ||
} | ||
|
||
val operatorCode = if (ctx.nullCheck) { | ||
s""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the reason is here, should first check nullTerm
, if it is true, should not assign resultTerm
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the review. The result for NPE is that we assign null
to a primitive type variable here, if we not assign resultTerm
when nullTerm
is true
, then resultTerm
will not be null
at last. IMHO, this should be null
for resultTerm
.
Or we can make ${trueAction.resultTerm}
be the resultTerm
for the returned GeneratedExpression
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ignore my above comment...
I've got your point, and will update the code very soon.
@@ -1287,12 +1287,16 @@ object ScalarOperatorGens { | |||
|boolean $nullTerm; | |||
|if (${condition.resultTerm}) { | |||
| ${trueAction.code} | |||
| $resultTerm = ${trueAction.resultTerm}; | |||
| if (!${trueAction.nullTerm}) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will lead to a risk, if trueAction.nullTerm
is a expression instead of a variable, maybe will some problem, so I suggest you:
$nullTerm = ${trueAction.nullTerm};
if (!$nullTerm) {
$resultTerm = ${trueAction.resultTerm};
}
At least, we can ensure nullTerm
is just a variable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure, thanks for the suggestion.
code updated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW, I encountered below error running ScalarOperatorsTest
after updating the code:
java.lang.VerifyError: Expecting a stackmap frame at branch target 32
Exception Details:
Location:
TestFunction$163.map(Ljava/lang/Object;)Ljava/lang/Object; @19: ifne
Reason:
Expected stackmap frame at this location.
Bytecode:
0x0000000: 2bc0 000e 4d2c 100d b900 1402 0036 0401
0x0000010: 4e15 049a 000d 2c10 0d05 b900 1803 004e
0x0000020: 2d3a 4415 049a 000e 2ab4 001c 1944 b600
0x0000030: 223a 442c 05b9 0014 0200 3632 0236 3115
......
It seems to be a bug in Janino. After I searched Janino's issues, I found this janino-compiler/janino#90 (comment)
Have you ever met the same problem?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Never encounter... But maybe because our code generate code has some problem, we can run again after fixing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello! This might be a bit unrelated, but I am developing on flink and I am also running into a very similar VerifyError
pointing to a Janino code generated method (specifically in the Flink protobuf row serialization codepath). How did you workaround/resolve this issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kurnoolsaketh We didn't solve it, it just disappeared.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
interesting.. thanks for the info.
| $nullTerm = ${trueAction.nullTerm}; | ||
| if (!$nullTerm) { | ||
| $resultTerm = ${trueAction.resultTerm}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need assign resultTerm
to a default value too.
val defaultValue = primitiveDefaultValue(resultType)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for the reminder. done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM after travis passing.
@flinkbot run travis |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the fixing @libenchao and thanks for the reviewing @JingsongLi .
Looks good to me too.
Will merge it.
…EN operator in blink planner (#10594)
…EN operator in blink planner (#10594)
What is the purpose of the change
This pr fixes the NPE bug in blink case operator code gen as described in FLINK-15266.
Brief change log
For case operator result type, generate primitive type only when trueAction and falseAction both return non-null types.
Verifying this change
Does this pull request potentially affect one of the following parts:
@Public(Evolving)
: (no)Documentation