lvyanquan commented on code in PR #4474:
URL: https://github.com/apache/flink-cdc/pull/4474#discussion_r3619220940
##########
flink-cdc-composer/src/test/resources/specs/comparison.yaml:
##########
@@ -165,6 +165,26 @@
DataChangeEvent{tableId=foo.bar.baz, before=[-1, 天地玄黄宇宙洪荒, true, true,
true, false], after=[], op=DELETE, meta=()}
DataChangeEvent{tableId=foo.bar.baz, before=[], after=[0, null, true,
false, true, false], op=INSERT, meta=()}
DataChangeEvent{tableId=foo.bar.baz, before=[0, null, true, false, true,
false], after=[], op=DELETE, meta=()}
+- do: IsUnknown Op
+ projection: id_, bool_, bool_ IS UNKNOWN AS comp_1, bool_ IS NOT UNKNOWN AS
comp_2, (bool_ AND CAST(NULL AS BOOLEAN)) IS UNKNOWN AS comp_3
+ primary-key: id_
+ expect: |-
+ CreateTableEvent{tableId=foo.bar.baz, schema=columns={`id_` BIGINT NOT
NULL 'Identifier',`bool_` BOOLEAN 'George' 'false',`comp_1` BOOLEAN,`comp_2`
BOOLEAN,`comp_3` BOOLEAN}, primaryKeys=id_, options=()}
+ DataChangeEvent{tableId=foo.bar.baz, before=[], after=[1, true, false,
true, true], op=INSERT, meta=()}
+ DataChangeEvent{tableId=foo.bar.baz, before=[1, true, false, true, true],
after=[-1, false, false, true, false], op=UPDATE, meta=()}
+ DataChangeEvent{tableId=foo.bar.baz, before=[-1, false, false, true,
false], after=[], op=DELETE, meta=()}
+ DataChangeEvent{tableId=foo.bar.baz, before=[], after=[0, null, true,
false, true], op=INSERT, meta=()}
+ DataChangeEvent{tableId=foo.bar.baz, before=[0, null, true, false, true],
after=[], op=DELETE, meta=()}
+- do: Distinct From Op
+ projection: id_, int_ IS DISTINCT FROM 4 AS comp_1, int_ IS NOT DISTINCT
FROM 4 AS comp_2, CAST(NULL AS INT) IS DISTINCT FROM int_ AS comp_3, CAST(NULL
AS INT) IS NOT DISTINCT FROM int_ AS comp_4
+ primary-key: id_
+ expect: |-
+ CreateTableEvent{tableId=foo.bar.baz, schema=columns={`id_` BIGINT NOT
NULL 'Identifier',`comp_1` BOOLEAN,`comp_2` BOOLEAN,`comp_3` BOOLEAN,`comp_4`
BOOLEAN}, primaryKeys=id_, options=()}
+ DataChangeEvent{tableId=foo.bar.baz, before=[], after=[1, false, true,
true, false], op=INSERT, meta=()}
+ DataChangeEvent{tableId=foo.bar.baz, before=[1, false, true, true, false],
after=[-1, true, false, true, false], op=UPDATE, meta=()}
+ DataChangeEvent{tableId=foo.bar.baz, before=[-1, true, false, true,
false], after=[], op=DELETE, meta=()}
+ DataChangeEvent{tableId=foo.bar.baz, before=[], after=[0, true, false,
false, true], op=INSERT, meta=()}
+ DataChangeEvent{tableId=foo.bar.baz, before=[0, true, false, false, true],
after=[], op=DELETE, meta=()}
Review Comment:
Lacks end-to-end tests for:
- NOT LIKE ... ESCAPE
- SIMILAR TO ... ESCAPE
- NOT SIMILAR TO ... ESCAPE
- NULL inputs for these expressions
##########
flink-cdc-runtime/src/main/java/org/apache/flink/cdc/runtime/parser/JaninoCompiler.java:
##########
@@ -322,6 +334,27 @@ 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 "
Review Comment:
A possible optimization is to generate different code based on operand
nullability:
- If both operands are non-null, use native &&/||.
- If only the left operand is non-null, use a conditional expression:
- AND: left ? right : Boolean.FALSE
- OR: left ? Boolean.TRUE : right
- If the left operand is nullable, keep the current Supplier fallback to
preserve three-valued logic and short-circuit evaluation.
This avoids unnecessary per-record Supplier allocations in common non-null
cases.
##########
docs/content.zh/docs/core-concept/transform.md:
##########
@@ -120,8 +120,8 @@ Flink CDC 使用 [Calcite](https://calcite.apache.org/) 来解析表达式并且
| value1 >= value2 | greaterThanOrEqual(value1, value2)
| 如果 value1 大于等于 value2,返回 TRUE;如果 value1 或 value2 为 NULL,返回 FALSE。 |
| value1 < value2 | lessThan(value1, value2)
| 如果 value1 小于 value2,返回 TRUE;如果 value1 或 value2 为 NULL,返回 FALSE。 |
| value1 <= value2 | lessThanOrEqual(value1, value2)
| 如果 value1 小于等于 value2,返回 TRUE;如果 value1 或 value2 为 NULL,返回 FALSE。 |
-| value IS NULL | null == value
| 如果 value 为 NULL,返回 TRUE。 |
-| value IS NOT NULL | null != value
| 如果 value 不为 NULL,返回 TRUE。 |
+| value IS NULL | isNull(value)
| 如果 value 为 NULL,返回 TRUE。 |
+| value IS NOT NULL | isNotNull(value)
| 如果 value 不为 NULL,返回 TRUE。 |
Review Comment:
The following functions are not documented:
- IS DISTINCT FROM
- IS NOT DISTINCT FROM
- LIKE ... ESCAPE
- NOT LIKE ... ESCAPE
- SIMILAR TO
- NOT SIMILAR TO
- SIMILAR TO ... ESCAPE
- NOT SIMILAR TO ... ESCAPE
Moreover, the two forms of LIKE are handled differently:
- Two-argument LIKE: uses Java regular expression semantics.
- LIKE with ESCAPE: uses SQL % and _ wildcard semantics.
--
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]