linorosa commented on code in PR #4135:
URL: https://github.com/apache/calcite/pull/4135#discussion_r1913739734


##########
core/src/test/java/org/apache/calcite/plan/RelOptUtilTest.java:
##########
@@ -420,6 +421,228 @@ private void splitJoinConditionHelper(RexNode joinCond, 
List<Integer> expLeftKey
     assertThat(actRightKeys, is(expRightKeys));
   }
 
+  /**
+   * Test that {@link 
RelOptUtil#collapseExpandedIsNotDistinctFromExpr(RexCall, RexBuilder)}
+   * collapses an expanded version of IS NOT DISTINCT using OR.
+   */
+  @Test void testCollapseExpandedIsNotDistinctFromUsingOr() {
+    final RexBuilder rexBuilder = relBuilder.getRexBuilder();
+
+    final RexNode leftEmpNo =
+        RexInputRef.of(empScan.getRowType().getFieldNames().indexOf("EMPNO"),
+            empDeptJoinRelFields);
+    final RexNode rightEmpNo =
+        RexInputRef.of(empRow.getFieldCount() + 
deptRow.getFieldNames().indexOf("EMPNO"),
+            empDeptJoinRelFields);
+
+    RexNode expanded = relBuilder.isNotDistinctFrom(leftEmpNo, rightEmpNo);
+
+    RexNode collapsed =
+        RelOptUtil.collapseExpandedIsNotDistinctFromExpr((RexCall) expanded, 
rexBuilder);
+
+    RexNode expected =
+        rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_DISTINCT_FROM, 
leftEmpNo, rightEmpNo);
+
+    assertThat(collapsed, is(expected));
+  }
+
+  /**
+   * Test that {@link 
RelOptUtil#collapseExpandedIsNotDistinctFromExpr(RexCall, RexBuilder)}
+   * collapses an expanded version of IS NOT DISTINCT using CASE.
+   */
+  @Test void testCollapseExpandedIsNotDistinctFromUsingCase() {
+    final RexBuilder rexBuilder = relBuilder.getRexBuilder();
+
+    final RexNode leftEmpNo =
+        RexInputRef.of(empScan.getRowType().getFieldNames().indexOf("EMPNO"),
+            empDeptJoinRelFields);
+    final RexNode rightEmpNo =
+        RexInputRef.of(empRow.getFieldCount() + 
deptRow.getFieldNames().indexOf("EMPNO"),
+            empDeptJoinRelFields);
+
+    RexNode expanded =
+        relBuilder.call(SqlStdOperatorTable.CASE, relBuilder.isNull(leftEmpNo),
+            relBuilder.isNull(rightEmpNo),
+            relBuilder.isNull(rightEmpNo),
+            relBuilder.isNull(leftEmpNo),
+            relBuilder.equals(leftEmpNo, rightEmpNo));
+
+    RexNode collapsed =
+        RelOptUtil.collapseExpandedIsNotDistinctFromExpr((RexCall) expanded, 
rexBuilder);
+
+    RexNode expected =
+        rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_DISTINCT_FROM, 
leftEmpNo, rightEmpNo);
+
+    assertThat(collapsed, is(expected));
+  }
+
+  /**
+   * Test that {@link 
RelOptUtil#collapseExpandedIsNotDistinctFromExpr(RexCall, RexBuilder)}
+   * collapses an expression with expanded versions of IS NOT DISTINCT using 
OR and CASE.
+   */
+  @Test void testCollapseExpandedIsNotDistinctFromUsingOrAndCase() {
+    final RexBuilder rexBuilder = relBuilder.getRexBuilder();
+
+    final RexNode leftEmpNo =
+        RexInputRef.of(empScan.getRowType().getFieldNames().indexOf("EMPNO"),
+            empDeptJoinRelFields);
+    final RexNode rightEmpNo =
+        RexInputRef.of(empRow.getFieldCount() + 
deptRow.getFieldNames().indexOf("EMPNO"),
+            empDeptJoinRelFields);
+
+    final RexNode leftDeptNo =
+        RexInputRef.of(empScan.getRowType().getFieldNames().indexOf("DEPTNO"),
+            empDeptJoinRelFields);
+    final RexNode rightDeptNo =
+        RexInputRef.of(empRow.getFieldCount() + 
deptRow.getFieldNames().indexOf("DEPTNO"),
+            empDeptJoinRelFields);
+
+    // An IS NOT DISTINCT FROM expanded in "CASE" shape
+    RexNode expandedCase =
+        relBuilder.call(SqlStdOperatorTable.CASE, relBuilder.isNull(leftEmpNo),
+            relBuilder.isNull(rightEmpNo),
+            relBuilder.isNull(rightEmpNo),
+            relBuilder.isNull(leftEmpNo),
+            relBuilder.equals(leftEmpNo, rightEmpNo));
+
+    // An IS NOT DISTINCT FROM expanded in "OR" shape
+    RexNode expandedOr =
+        relBuilder.call(
+            SqlStdOperatorTable.OR, relBuilder.call(SqlStdOperatorTable.AND,
+                relBuilder.isNull(leftDeptNo),
+                relBuilder.isNull(rightDeptNo)),
+            relBuilder.call(SqlStdOperatorTable.EQUALS, leftDeptNo, 
rightDeptNo));
+
+    RexNode expanded = relBuilder.and(expandedOr, expandedCase);
+
+    RexNode collapsed =
+        RelOptUtil.collapseExpandedIsNotDistinctFromExpr((RexCall) expanded, 
rexBuilder);
+
+    RexNode expected =
+        rexBuilder.makeCall(
+            // Expected is nullable because `expandedCase` is nullable
+            
relBuilder.getTypeFactory().createTypeWithNullability(expanded.getType(), true),
+            SqlStdOperatorTable.AND,
+            ImmutableList.of(
+                rexBuilder.makeCall(
+                    SqlStdOperatorTable.IS_NOT_DISTINCT_FROM,
+                    leftEmpNo,
+                    rightEmpNo),
+                rexBuilder.makeCall(
+                    SqlStdOperatorTable.IS_NOT_DISTINCT_FROM,
+                    leftDeptNo,
+                    rightDeptNo)));
+
+    assertThat(collapsed, is(expected));
+  }
+
+  /**
+   * Test that {@link 
RelOptUtil#collapseExpandedIsNotDistinctFromExpr(RexCall, RexBuilder)}
+   * recursively collapses expanded versions of IS NOT DISTINCT.
+   */
+  @Test void testCollapseExpandedIsNotDistinctFromRecursively() {
+    final RexBuilder rexBuilder = relBuilder.getRexBuilder();
+
+    final RexNode leftEmpNo =
+        RexInputRef.of(empScan.getRowType().getFieldNames().indexOf("EMPNO"),
+            empDeptJoinRelFields);
+    final RexNode rightEmpNo =
+        RexInputRef.of(empRow.getFieldCount() + 
deptRow.getFieldNames().indexOf("EMPNO"),
+            empDeptJoinRelFields);
+
+    RexNode expanded =
+        relBuilder.isNotDistinctFrom(
+            relBuilder.isNotDistinctFrom(leftEmpNo, rightEmpNo),
+            relBuilder.isNotDistinctFrom(leftEmpNo, rightEmpNo));
+
+    RexNode collapsed =
+        RelOptUtil.collapseExpandedIsNotDistinctFromExpr((RexCall) expanded, 
rexBuilder);
+
+    RexNode expected =
+        rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_DISTINCT_FROM,
+            rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_DISTINCT_FROM,
+                leftEmpNo,
+                rightEmpNo),
+
+            rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_DISTINCT_FROM,
+                leftEmpNo,
+                rightEmpNo));
+
+    assertThat(collapsed, is(expected));
+  }
+
+  /**
+   * Test that {@link 
RelOptUtil#collapseExpandedIsNotDistinctFromExpr(RexCall, RexBuilder)}
+   * will collapse IS NOT DISTINCT FROM nested within RexNodes.
+   */
+  @Test void testCollapseExpandedIsNotDistinctFromInsideRexNode() {
+    final RexBuilder rexBuilder = relBuilder.getRexBuilder();
+
+    final RexNode leftEmpNo =
+        RexInputRef.of(empScan.getRowType().getFieldNames().indexOf("EMPNO"),
+            empDeptJoinRelFields);
+    final RexNode rightEmpNo =
+        RexInputRef.of(empRow.getFieldCount() + 
deptRow.getFieldNames().indexOf("EMPNO"),
+            empDeptJoinRelFields);
+
+    RexNode expandedIsNotDistinctFrom = 
relBuilder.isNotDistinctFrom(leftEmpNo, rightEmpNo);
+    RexNode expanded =
+        relBuilder.call(SqlStdOperatorTable.NULLIF,
+            relBuilder.not(expandedIsNotDistinctFrom),
+            relBuilder.isNotNull(expandedIsNotDistinctFrom));
+
+    RexNode collapsed =
+        RelOptUtil.collapseExpandedIsNotDistinctFromExpr((RexCall) expanded, 
rexBuilder);
+
+    RexNode collapsedIsNotDistinctFrom =
+        rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_DISTINCT_FROM, 
leftEmpNo, rightEmpNo);
+    RexNode expected =
+        rexBuilder.makeCall(
+            SqlStdOperatorTable.NULLIF,
+            relBuilder.not(collapsedIsNotDistinctFrom),
+            relBuilder.isNotNull(collapsedIsNotDistinctFrom));
+
+    assertThat(collapsed, is(expected));
+  }
+
+  /**
+   * Test that {@link 
RelOptUtil#collapseExpandedIsNotDistinctFromExpr(RexCall, RexBuilder)}
+   * can handle collapsing IS NOT DISTINCT FROM composed of other RexNodes.
+   */
+  @Test void testCollapseExpandedIsNotDistinctFromOnContainingRexNodes() {
+    final RexBuilder rexBuilder = relBuilder.getRexBuilder();
+
+    final RexNode leftEmpNo =

Review Comment:
   sure thing, I added some comments now



-- 
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: commits-unsubscr...@calcite.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to