suibianwanwank commented on code in PR #3921:
URL: https://github.com/apache/calcite/pull/3921#discussion_r1721232015


##########
core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java:
##########
@@ -2169,57 +2142,106 @@ public static boolean equalType(String desc0, 
MutableRel rel0, String desc1,
   }
 
   /**
-   * Check if filter under join can be pulled up,
+   * Check if calc under join can be pulled up,
    * when meeting JoinOnCalc of query unify to Join of target.
    * Working in rules: {@link JoinOnLeftCalcToJoinUnifyRule} <br/>
    * {@link JoinOnRightCalcToJoinUnifyRule} <br/>
    * {@link JoinOnCalcsToJoinUnifyRule} <br/>
    */
-  private static boolean canPullUpFilterUnderJoin(JoinRelType joinType,
-      @Nullable RexNode leftFilterRexNode, @Nullable RexNode 
rightFilterRexNode) {
-    if (joinType == JoinRelType.INNER) {
-      return true;
-    }
-    if (joinType == JoinRelType.LEFT
-        && (rightFilterRexNode == null || rightFilterRexNode.isAlwaysTrue())) {
-      return true;
-    }
-    if (joinType == JoinRelType.RIGHT
-        && (leftFilterRexNode == null || leftFilterRexNode.isAlwaysTrue())) {
-      return true;
+  private static boolean canPullUpCalcUnderJoin(JoinRelType joinType,
+      @Nullable Pair<RexNode, List<RexNode>> qInput0Explained,
+      @Nullable Pair<RexNode, List<RexNode>> qInput1Explained) {
+    if (qInput0Explained != null
+        && joinType.generatesNullsOn(0)
+        && !isCalcStrong(qInput0Explained)) {
+      return false;
     }
-    if (joinType == JoinRelType.FULL
-        && ((rightFilterRexNode == null || rightFilterRexNode.isAlwaysTrue())
-        && (leftFilterRexNode == null || leftFilterRexNode.isAlwaysTrue()))) {
-      return true;
+    if (qInput1Explained != null
+        && joinType.generatesNullsOn(1)
+        && !isCalcStrong(qInput1Explained)) {
+      return false;
     }
-    return false;
+    return true;
+  }
+
+  /** Determines if all projects are strong and the condition is always true. 
*/
+  private static boolean isCalcStrong(Pair<RexNode, List<RexNode>> 
inputExplained) {
+    final RexNode cond = requireNonNull(inputExplained.left, "condition");
+    final List<RexNode> projs = requireNonNull(inputExplained.right, 
"projects");
+    return cond.isAlwaysTrue() && projs.stream().allMatch(STRONG::isNull);
   }
 
   /**
-   * Check if project under join can be pulled up,
-   * when meeting JoinOnCalc of query unify to Join of target.
+   * Generates project expressions by shifting and adjusting the nullability 
of expressions
+   * based on the provided join targets and inputs.
+   *
+   * <p>Used in the Join rewrite to pull up the calc in query
+   * to the join in mv to ensure operator equivalence. (Already make sure that 
pull up is valid).
    * Working in rules: {@link JoinOnLeftCalcToJoinUnifyRule} <br/>
    * {@link JoinOnRightCalcToJoinUnifyRule} <br/>
    * {@link JoinOnCalcsToJoinUnifyRule} <br/>
    */
-  private static boolean canPullUpProjectUnderJoin(JoinRelType joinType,
-      @Nullable List<RexNode> leftProjects, @Nullable List<RexNode> 
rightProjects) {
-    if (leftProjects != null && joinType.generatesNullsOn(0)
-        && !allProjectsNullable(leftProjects)) {
-      return false;
-    }
-    if (rightProjects != null && joinType.generatesNullsOn(1)
-        && !allProjectsNullable(rightProjects)) {
-      return false;
+  private static List<RexNode> shiftAndAdjustProjectExpr(MutableJoin query, 
MutableJoin target,
+      RexBuilder rexBuilder, int leftCount,
+      @Nullable List<RexNode> qInput0Projs, @Nullable List<RelDataTypeField> 
qInput0InputFields,
+      @Nullable List<RexNode> qInput1Projs, @Nullable List<RelDataTypeField> 
qInput1InputFields) {
+
+    int[] adjustments0 = new int[target.rowType.getFieldCount()];
+    int[] adjustments1 = new int[target.rowType.getFieldCount()];
+
+    if (qInput1Projs != null) {
+      Arrays.fill(adjustments1, fieldCnt(target.getLeft()));
+    }
+
+    // In cases such as JoinOnLeftCalcToJoinUnifyRule and 
JoinOnCalcsToJoinUnifyRule rules,
+    // the left calc need to be pulled up the target, initialize the converter.
+    RelOptUtil.RexInputConverter converter0 =
+        new RelOptUtil.RexInputConverter(rexBuilder, qInput0InputFields,
+            target.rowType.getFieldList(), adjustments0);
+
+    // In cases such as JoinOnRightCalcToJoinUnifyRule and 
JoinOnCalcsToJoinUnifyRule rules,
+    // the right calc need to be pulled up the target, initialize the 
converter.
+    RelOptUtil.RexInputConverter converter1 =
+        new RelOptUtil.RexInputConverter(rexBuilder, qInput1InputFields,
+            target.rowType.getFieldList(), adjustments1);
+
+    final List<RexNode> compenProjs = new ArrayList<>();

Review Comment:
   This retains the naming of the previous code, I'm guessing this means 
compensation.



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