yuxiqian commented on code in PR #4474:
URL: https://github.com/apache/flink-cdc/pull/4474#discussion_r3621108186
##########
flink-cdc-runtime/src/main/java/org/apache/flink/cdc/runtime/parser/JaninoCompiler.java:
##########
@@ -322,6 +335,131 @@ private static Java.Rvalue generateUnaryOperation(
return new Java.UnaryOperation(Location.NOWHERE, operator, atom);
}
+ private static Java.Rvalue generateFunctionOperation(String functionName,
Java.Rvalue[] atoms) {
+ return new Java.MethodInvocation(Location.NOWHERE, null, functionName,
atoms);
+ }
+
+ private static Java.Rvalue generateLazyBinaryFunctionOperation(
+ Context context, SqlBasicCall sqlBasicCall, String functionName,
Java.Rvalue[] atoms) {
+ if (atoms.length != 2) {
+ throw new ParseException("Unrecognized expression: " +
sqlBasicCall.toString());
+ }
+ Java.Rvalue rightOperandSupplier =
+ new Java.AmbiguousName(
+ Location.NOWHERE,
+ new String[] {
+ "new java.util.function.Supplier<Boolean>() {
public Boolean get() { return "
+ + atoms[1]
+ + "; } }"
+ });
+ return generateFunctionOperation(
+ functionName, new Java.Rvalue[] {atoms[0],
rightOperandSupplier});
+ }
+
+ private static Java.Rvalue generateLogicalBinaryOperation(
+ Context context, SqlBasicCall sqlBasicCall, Java.Rvalue[] atoms,
boolean isAnd) {
+ if (atoms.length != 2) {
+ throw new ParseException("Unrecognized expression: " +
sqlBasicCall.toString());
+ }
+ boolean leftNullable = isExpressionNullable(context,
sqlBasicCall.getOperandList().get(0));
+ boolean rightNullable = isExpressionNullable(context,
sqlBasicCall.getOperandList().get(1));
+ if (!leftNullable && !rightNullable) {
+ return generateBinaryOperation(context, sqlBasicCall, atoms, isAnd
? "&&" : "||");
+ }
+ if (!leftNullable) {
+ return generateLeftNonNullableLogicalOperation(atoms, isAnd);
+ }
+ // TODO: This nullable-left path still relies on JIT escape analysis
to optimize
+ // per-evaluation Supplier allocation. Introduce statement-level
codegen
+ // (for example, GeneratedExpression/ScriptEvaluator) to avoid the
potential cost.
+ return generateLazyBinaryFunctionOperation(
+ context, sqlBasicCall, isAnd ? "and" : "or", atoms);
+ }
+
+ private static Java.Rvalue generateLeftNonNullableLogicalOperation(
+ Java.Rvalue[] atoms, boolean isAnd) {
+ if (isAnd) {
+ return new Java.ConditionalExpression(
+ Location.NOWHERE,
+ atoms[0],
+ atoms[1],
+ new Java.AmbiguousName(Location.NOWHERE, new String[]
{"Boolean.FALSE"}));
+ }
+ return new Java.ConditionalExpression(
+ Location.NOWHERE,
+ atoms[0],
+ new Java.AmbiguousName(Location.NOWHERE, new String[]
{"Boolean.TRUE"}),
+ atoms[1]);
+ }
+
+ private static boolean isExpressionNullable(Context context, SqlNode
sqlNode) {
+ if (sqlNode instanceof SqlIdentifier) {
+ return isIdentifierNullable(context, (SqlIdentifier) sqlNode);
+ }
+ if (sqlNode instanceof SqlLiteral) {
+ return ((SqlLiteral) sqlNode).getValue() == null;
+ }
+ if (sqlNode instanceof SqlBasicCall) {
+ return isBasicCallNullable(context, (SqlBasicCall) sqlNode);
+ }
+ return true;
+ }
Review Comment:
Instead of deducing `isIdentifierNullable` at the Janino compiler level, can
we check the corresponding `RelNode` nullability during Calcite validation?
Current implementation is OK though, as the compilation happens just once.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]