xuzifu666 commented on code in PR #5110:
URL: https://github.com/apache/calcite/pull/5110#discussion_r3610265306


##########
core/src/test/resources/sql/sub-query.iq:
##########
@@ -4339,14 +4339,14 @@ select * from "scott".emp where (mgr, deptno) not in 
((1, 2), (3, null), (cast(n
 
 !ok
 !if (use_old_decorr) {
-EnumerableCalc(expr#0..13=[{inputs}], expr#14=[0], expr#15=[=($t8, $t14)], 
expr#16=[IS NULL($t3)], expr#17=[IS NULL($t7)], expr#18=[IS NOT NULL($t12)], 
expr#19=[AND($t13, $t18)], expr#20=[<($t9, $t8)], expr#21=[OR($t16, $t17, $t19, 
$t18, $t20)], expr#22=[IS NOT TRUE($t21)], expr#23=[OR($t15, $t22)], 
proj#0..7=[{exprs}], $condition=[$t23])
+EnumerableCalc(expr#0..12=[{inputs}], expr#13=[0], expr#14=[=($t8, $t13)], 
expr#15=[IS NULL($t12)], expr#16=[>=($t9, $t8)], expr#17=[IS NOT NULL($t3)], 
expr#18=[IS NOT NULL($t7)], expr#19=[AND($t15, $t16, $t17, $t18)], 
expr#20=[OR($t14, $t19)], proj#0..7=[{exprs}], $condition=[$t20])

Review Comment:
   Redundant terms within OR(...) are absorbed by IS NOT NULL/IS NULL-related 
terms, shortening the expression.



##########
core/src/test/resources/sql/sub-query.iq:
##########
@@ -4339,14 +4339,14 @@ select * from "scott".emp where (mgr, deptno) not in 
((1, 2), (3, null), (cast(n
 
 !ok
 !if (use_old_decorr) {
-EnumerableCalc(expr#0..13=[{inputs}], expr#14=[0], expr#15=[=($t8, $t14)], 
expr#16=[IS NULL($t3)], expr#17=[IS NULL($t7)], expr#18=[IS NOT NULL($t12)], 
expr#19=[AND($t13, $t18)], expr#20=[<($t9, $t8)], expr#21=[OR($t16, $t17, $t19, 
$t18, $t20)], expr#22=[IS NOT TRUE($t21)], expr#23=[OR($t15, $t22)], 
proj#0..7=[{exprs}], $condition=[$t23])
+EnumerableCalc(expr#0..12=[{inputs}], expr#13=[0], expr#14=[=($t8, $t13)], 
expr#15=[IS NULL($t12)], expr#16=[>=($t9, $t8)], expr#17=[IS NOT NULL($t3)], 
expr#18=[IS NOT NULL($t7)], expr#19=[AND($t15, $t16, $t17, $t18)], 
expr#20=[OR($t14, $t19)], proj#0..7=[{exprs}], $condition=[$t20])
   EnumerableNestedLoopJoin(condition=[AND(OR(IS NULL($10), =(CAST($3):INTEGER, 
$10)), OR(IS NULL($11), =(CAST($7):INTEGER, $11)))], joinType=[left])
     EnumerableNestedLoopJoin(condition=[true], joinType=[inner])
       EnumerableTableScan(table=[[scott, EMP]])
       EnumerableAggregate(group=[{}], c=[COUNT()], ck=[COUNT() FILTER $0])
         EnumerableCalc(expr#0..1=[{inputs}], expr#2=[IS NOT NULL($t0)], 
expr#3=[IS NOT NULL($t1)], expr#4=[OR($t2, $t3)], $f2=[$t4])
           EnumerableValues(tuples=[[{ 3, null }, { null, null }, { 1, 2 }]])
-    EnumerableCalc(expr#0..1=[{inputs}], expr#2=[true], expr#3=[IS NOT 
NULL($t0)], expr#4=[IS NOT NULL($t1)], expr#5=[AND($t3, $t4)], expr#6=[OR($t3, 
$t4)], proj#0..2=[{exprs}], $f20=[$t5], $condition=[$t6])
+    EnumerableCalc(expr#0..1=[{inputs}], expr#2=[true], expr#3=[IS NOT 
NULL($t0)], expr#4=[IS NOT NULL($t1)], expr#5=[OR($t3, $t4)], 
proj#0..2=[{exprs}], $condition=[$t5])

Review Comment:
   The original plan involved calculating two columns simultaneously:
   ```
   expr#3=[IS NOT NULL($t0)]
   expr#4=[IS NOT NULL($t1)]
   expr#5=[AND($t3, $t4)]       -- Neither column is empty
   expr#6=[OR($t3, $t4)]        -- At least one non-empty column
   ```
   After simplification, the upper-level condition only requires "at least one 
non-null column" to handle the NULL semantics of NOT IN; AND($t3, $t4) has been 
absorbed:
   ```
   expr#3=[IS NOT NULL($t0)]
   expr#4=[IS NOT NULL($t1)]
   expr#5=[OR($t3, $t4)]
   ```



##########
core/src/test/resources/sql/sub-query.iq:
##########
@@ -4324,7 +4324,7 @@ EnumerableCalc(expr#0..14=[{inputs}], expr#15=[0], 
expr#16=[=($t8, $t15)], expr#
           EnumerableAggregate(group=[{}], c=[COUNT()], ck=[COUNT() FILTER $0])
             EnumerableValues(tuples=[[{ true }, { true }]])
     EnumerableSort(sort0=[$0], dir0=[ASC])
-      EnumerableCalc(expr#0..1=[{inputs}], expr#2=[true], expr#3=[IS NOT 
NULL($t1)], proj#0..3=[{exprs}])
+      EnumerableCalc(expr#0..1=[{inputs}], expr#2=[true], proj#0..2=[{exprs}])

Review Comment:
   After the main Calc node is simplified, the subquery no longer needs to 
additionally output the `IS NOT NULL($t1)` column, resulting in this structure.



##########
core/src/test/resources/sql/sub-query.iq:
##########
@@ -4315,7 +4315,7 @@ select * from "scott".emp where (empno, deptno) not in 
((1, 2), (3, null));
 
 !ok
 !if (use_old_decorr) {
-EnumerableCalc(expr#0..14=[{inputs}], expr#15=[0], expr#16=[=($t8, $t15)], 
expr#17=[IS NULL($t7)], expr#18=[IS NOT NULL($t13)], expr#19=[AND($t14, $t18)], 
expr#20=[<($t9, $t8)], expr#21=[OR($t17, $t19, $t18, $t20)], expr#22=[IS NOT 
TRUE($t21)], expr#23=[OR($t16, $t22)], proj#0..7=[{exprs}], $condition=[$t23])
+EnumerableCalc(expr#0..13=[{inputs}], expr#14=[0], expr#15=[=($t8, $t14)], 
expr#16=[IS NULL($t13)], expr#17=[>=($t9, $t8)], expr#18=[IS NOT NULL($t7)], 
expr#19=[AND($t16, $t17, $t18)], expr#20=[OR($t15, $t19)], proj#0..7=[{exprs}], 
$condition=[$t20])

Review Comment:
   Since `IS NOT NULL($t13)` is already part of the `OR` clause and is subsumed 
by `AND($t14, IS NOT NULL($t13))`, the term `AND($t14, IS NOT NULL($t13))` is 
absorbed by `IS NOT NULL($t13)`. After converting `NOT(<)` to `>=` and 
reordering the variables, we obtain:
   ```
   OR(=($t8, 0), AND(IS NULL($t13), >=($t9, $t8), IS NOT NULL($t7)))
   ```



##########
core/src/test/resources/sql/sub-query.iq:
##########
@@ -4381,7 +4381,7 @@ select * from "scott".emp where (empno, deptno) not in 
((7369, 20), (7499, 30));
 
 !ok
 !if (use_old_decorr) {
-EnumerableCalc(expr#0..15=[{inputs}], expr#16=[0], expr#17=[=($t8, $t16)], 
expr#18=[IS NULL($t7)], expr#19=[IS NOT NULL($t14)], expr#20=[AND($t15, $t19)], 
expr#21=[<($t9, $t8)], expr#22=[OR($t18, $t20, $t19, $t21)], expr#23=[IS NOT 
TRUE($t22)], expr#24=[OR($t17, $t23)], proj#0..7=[{exprs}], $condition=[$t24])
+EnumerableCalc(expr#0..14=[{inputs}], expr#15=[0], expr#16=[=($t8, $t15)], 
expr#17=[IS NULL($t14)], expr#18=[>=($t9, $t8)], expr#19=[IS NOT NULL($t7)], 
expr#20=[AND($t17, $t18, $t19)], expr#21=[OR($t16, $t20)], proj#0..7=[{exprs}], 
$condition=[$t21])

Review Comment:
   Similarly, the expression is compressed because the `OR(...)` clause 
resulting from the expansion of `NOT IN` contains redundant terms that can be 
absorbed.



##########
core/src/test/resources/sql/sub-query.iq:
##########
@@ -4391,7 +4391,7 @@ EnumerableCalc(expr#0..15=[{inputs}], expr#16=[0], 
expr#17=[=($t8, $t16)], expr#
             EnumerableCalc(expr#0..1=[{inputs}], expr#2=[true], $f2=[$t2])
               EnumerableValues(tuples=[[{ 7369, 20 }, { 7499, 30 }]])
     EnumerableSort(sort0=[$0], sort1=[$1], dir0=[ASC], dir1=[ASC])
-      EnumerableCalc(expr#0..1=[{inputs}], expr#2=[true], proj#0..2=[{exprs}], 
$f20=[$t2])
+      EnumerableCalc(expr#0..1=[{inputs}], expr#2=[true], proj#0..2=[{exprs}])

Review Comment:
   After simplification in Calc, the helper column $f20 is no longer needed.



##########
core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java:
##########
@@ -322,9 +322,8 @@ class JdbcAdapterTest {
             + "          JdbcProject($f2=[OR(IS NOT NULL($7), IS NOT 
NULL($1))])\n"
             + "            JdbcTableScan(table=[[SCOTT, EMP]])\n"
             + "    JdbcToEnumerableConverter\n"
-            + "      JdbcAggregate(group=[{0, 1}], i=[LITERAL_AGG(true)], 
em=[MAX($2)])\n"
-            + "        JdbcProject(DEPTNO=[$7], ENAME=[CAST($1):VARCHAR(14)],"
-            + " $f2=[AND(IS NOT NULL($7), IS NOT NULL($1))])\n"
+            + "      JdbcAggregate(group=[{0, 1}], i=[LITERAL_AGG(true)])\n"

Review Comment:
   The intermediate variable `$f2` is no longer needed in the condition; `OR(IS 
NULL($7), IS NULL($1))` suffices. Consequently:
   `$f2=[AND(IS NOT NULL($7), IS NOT NULL($1))]` is removed from `JdbcProject`;
   `em=[MAX($2)]` is removed from `JdbcAggregate`;
   At the same time, `JdbcFilter(condition=[OR(IS NOT NULL($7), IS NULL($1))])` 
is added to the subquery side to filter out rows where both columns are `NULL` 
at an earlier stage.



-- 
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]

Reply via email to