This is an automated email from the ASF dual-hosted git repository.

alexpl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new 9a4ddbf8d7f IGNITE-27662 SQL Calcite: Add IS NOT DISTINCT FROM support 
for HASH JOIN - Fixes #12659.
9a4ddbf8d7f is described below

commit 9a4ddbf8d7fe46b984c1383bb7a235d043dd698d
Author: Aleksey Plekhanov <[email protected]>
AuthorDate: Wed Jan 28 14:09:07 2026 +0300

    IGNITE-27662 SQL Calcite: Add IS NOT DISTINCT FROM support for HASH JOIN - 
Fixes #12659.
    
    Signed-off-by: Aleksey Plekhanov <[email protected]>
---
 .../query/calcite/exec/exp/agg/GroupKey.java       |  20 +-
 .../query/calcite/exec/rel/HashJoinNode.java       |  16 +-
 .../query/calcite/rule/HashJoinConverterRule.java  |   4 -
 .../calcite/integration/JoinIntegrationTest.java   | 282 ++++++++++-----------
 .../query/calcite/planner/HashJoinPlannerTest.java |  10 +-
 5 files changed, 164 insertions(+), 168 deletions(-)

diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/agg/GroupKey.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/agg/GroupKey.java
index 657c64a8891..f9e7a42dc6a 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/agg/GroupKey.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/agg/GroupKey.java
@@ -18,6 +18,7 @@
 package org.apache.ignite.internal.processors.query.calcite.exec.exp.agg;
 
 import java.util.Objects;
+import org.apache.calcite.util.ImmutableBitSet;
 import org.apache.ignite.binary.BinaryObjectException;
 import org.apache.ignite.binary.BinaryRawReader;
 import org.apache.ignite.binary.BinaryRawWriter;
@@ -118,11 +119,20 @@ public class GroupKey<Row> implements Binarylizable {
      * not allowed.
      */
     public static <Row> @Nullable GroupKey<Row> of(Row r, RowHandler<Row> hnd, 
boolean allowNulls) {
-        if (!allowNulls) {
-            for (int i = 0; i < hnd.columnCount(r); i++) {
-                if (hnd.get(i, r) == null)
-                    return null;
-            }
+        if (!allowNulls)
+            return of(r, hnd, ImmutableBitSet.of());
+
+        return new GroupKey<>(r, hnd);
+    }
+
+    /**
+     * @return Group key for provided row. Can be {@code null} if key fields 
of row contain NULL values and nulls are
+     * not allowed for these columns.
+     */
+    public static <Row> @Nullable GroupKey<Row> of(Row r, RowHandler<Row> hnd, 
ImmutableBitSet allowNulls) {
+        for (int i = 0; i < hnd.columnCount(r); i++) {
+            if (hnd.get(i, r) == null && !allowNulls.get(i))
+                return null;
         }
 
         return new GroupKey<>(r, hnd);
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/HashJoinNode.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/HashJoinNode.java
index 45aa2d778dd..fbdec244838 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/HashJoinNode.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/HashJoinNode.java
@@ -26,6 +26,7 @@ import java.util.Map;
 import java.util.function.BiPredicate;
 import org.apache.calcite.rel.core.JoinRelType;
 import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.util.ImmutableBitSet;
 import 
org.apache.ignite.internal.processors.query.calcite.exec.ExecutionContext;
 import 
org.apache.ignite.internal.processors.query.calcite.exec.MappingRowHandler;
 import org.apache.ignite.internal.processors.query.calcite.exec.RowHandler;
@@ -49,6 +50,9 @@ public abstract class HashJoinNode<Row> extends 
AbstractRightMaterializedJoinNod
     /** */
     private final boolean keepRowsWithNull;
 
+    /** */
+    private final ImmutableBitSet allowNulls;
+
     /** Output row handler. */
     protected final RowHandler<Row> outRowHnd;
 
@@ -83,6 +87,7 @@ public abstract class HashJoinNode<Row> extends 
AbstractRightMaterializedJoinNod
     ) {
         super(ctx, rowType);
 
+        allowNulls = info.allowNulls();
         this.keepRowsWithNull = keepRowsWithNull;
 
         leftRowHnd = new MappingRowHandler<>(ctx.rowHandler(), 
info.leftKeys.toIntArray());
@@ -146,7 +151,7 @@ public abstract class HashJoinNode<Row> extends 
AbstractRightMaterializedJoinNod
 
     /** */
     protected Collection<Row> lookup(Row row) {
-        GroupKey<Row> key = GroupKey.of(row, leftRowHnd, false);
+        GroupKey<Row> key = GroupKey.of(row, leftRowHnd, allowNulls);
 
         if (key == null)
             return Collections.emptyList();
@@ -171,14 +176,15 @@ public abstract class HashJoinNode<Row> extends 
AbstractRightMaterializedJoinNod
         assert downstream() != null;
         assert waitingRight > 0;
 
-        nodeMemoryTracker.onRowAdded(row);
-
         waitingRight--;
 
-        GroupKey<Row> key = GroupKey.of(row, rightRowHnd, keepRowsWithNull);
+        GroupKey<Row> key = keepRowsWithNull ? GroupKey.of(row, rightRowHnd) : 
GroupKey.of(row, rightRowHnd, allowNulls);
+
+        if (key != null) {
+            nodeMemoryTracker.onRowAdded(row);
 
-        if (key != null)
             hashStore.computeIfAbsent(key, k -> new 
TouchedArrayList<>()).add(row);
+        }
 
         if (waitingRight == 0)
             rightSource().request(waitingRight = IN_BUFFER_SIZE);
diff --git 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/HashJoinConverterRule.java
 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/HashJoinConverterRule.java
index d0008289373..de1016d3c51 100644
--- 
a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/HashJoinConverterRule.java
+++ 
b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rule/HashJoinConverterRule.java
@@ -55,10 +55,6 @@ public class HashJoinConverterRule extends 
AbstractIgniteJoinConverterRule {
         if (joinInfo.pairs().isEmpty())
             return false;
 
-        // IS NOT DISTINCT is currently not supported by HashJoin
-        if (joinInfo.allowNulls().cardinality() > 0)
-            return false;
-
         // Current limitation: unmatched products on left or right part 
requires special handling of non-equi condition
         // on execution level.
         return joinInfo.isEqui() || 
NON_EQ_CONDITIONS_SUPPORT.contains(join.getJoinType());
diff --git 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/JoinIntegrationTest.java
 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/JoinIntegrationTest.java
index 29579c9a2f4..1343afe37b3 100644
--- 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/JoinIntegrationTest.java
+++ 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/JoinIntegrationTest.java
@@ -26,8 +26,6 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 
-import static org.junit.Assume.assumeFalse;
-
 /** */
 @RunWith(Parameterized.class)
 public class JoinIntegrationTest extends 
AbstractBasicIntegrationTransactionalTest {
@@ -70,8 +68,6 @@ public class JoinIntegrationTest extends 
AbstractBasicIntegrationTransactionalTe
     /** */
     @Test
     public void testIsNotDistinctWithEquiConditionFrom() {
-        assumeFalse(joinType == JoinType.HASH);
-
         // 'IS NOT DISTINCT' is first.
         assertQuery("select t1.c2, t1.c3, t2.c2, t2.c3 from t1 join t2 on 
t1.c2 is not distinct from t2.c2 and t1.c3 = t2.c3 - 1")
             .returns(null, 2, null, 3)
@@ -299,57 +295,54 @@ public class JoinIntegrationTest extends 
AbstractBasicIntegrationTransactionalTe
             .returns(null, 3, 3, 3, 3)
             .check();
 
-        // HASH join doesn't support IS NOT DISTINCT.
-        if (joinType != JoinType.HASH) {
-            assertQuery("select t1.c2, t2.c3 from t1 join t2 on t1.c2 is not 
distinct from t2.c3 order by t1.c2, t2.c3")
-                .returns(1, 1)
-                .returns(2, 2)
-                .returns(3, 3)
-                .returns(3, 3)
-                .returns(3, 3)
-                .returns(3, 3)
-                .returns(4, 4)
-                .returns(null, null)
-                .check();
+        assertQuery("select t1.c2, t2.c3 from t1 join t2 on t1.c2 is not 
distinct from t2.c3 order by t1.c2, t2.c3")
+            .returns(1, 1)
+            .returns(2, 2)
+            .returns(3, 3)
+            .returns(3, 3)
+            .returns(3, 3)
+            .returns(3, 3)
+            .returns(4, 4)
+            .returns(null, null)
+            .check();
 
-            assertQuery("select t1.c2, t1.c3, t2.c1, t2.c3 from t1 join t2 on 
t1.c2 is not distinct from t2.c3 and " +
-                "t1.c3 is not distinct from t2.c1 order by t1.c2, t1.c3, 
t2.c1, t2.c3")
-                .returns(1, 1, 1, 1)
-                .returns(2, 2, 2, 2)
-                .returns(3, 3, 3, 3)
-                .returns(3, 3, 3, 3)
-                .returns(4, 4, 4, 4)
-                .returns(null, 2, 2, null)
-                .check();
+        assertQuery("select t1.c2, t1.c3, t2.c1, t2.c3 from t1 join t2 on 
t1.c2 is not distinct from t2.c3 and " +
+            "t1.c3 is not distinct from t2.c1 order by t1.c2, t1.c3, t2.c1, 
t2.c3")
+            .returns(1, 1, 1, 1)
+            .returns(2, 2, 2, 2)
+            .returns(3, 3, 3, 3)
+            .returns(3, 3, 3, 3)
+            .returns(4, 4, 4, 4)
+            .returns(null, 2, 2, null)
+            .check();
 
-            assertQuery("select t1.c2, t1.c3, t2.c3 from t1 join t2 on t1.c2 
is not distinct from t2.c3 and t1.c3 > 3")
-                .returns(4, 4, 4)
-                .check();
+        assertQuery("select t1.c2, t1.c3, t2.c3 from t1 join t2 on t1.c2 is 
not distinct from t2.c3 and t1.c3 > 3")
+            .returns(4, 4, 4)
+            .check();
 
-            // MERGE JOIN doesn't support non-equi conditions.
-            if (joinType != JoinType.MERGE) {
-                assertQuery("select t1.c2, t1.c3, t2.c2+3 as t2c2, t2.c3 from 
t1 join t2 on t1.c2 is not distinct from t2.c3 and " +
-                    "t1.c3<t2.c2+3 order by t1.c2, t1.c3, t2c2, t2.c3")
-                    .returns(1, 1, 4, 1)
-                    .returns(2, 2, 5, 2)
-                    .returns(3, 3, 6, 3)
-                    .returns(4, 4, 7, 4)
-                    .returns(null, 2, 5, null)
-                    .check();
-            }
-
-            assertQuery("select t1.c2, t1.c3, t2.c1, t2.c3 from t1 join t2 on 
t1.c2 is not distinct from t2.c3 and " +
-                "t1.c3 = t2.c1 order by t1.c2, t1.c3, t2.c1, t2.c3")
-                .returns(1, 1, 1, 1)
-                .returns(2, 2, 2, 2)
-                .returns(3, 3, 3, 3)
-                .returns(3, 3, 3, 3)
-                .returns(4, 4, 4, 4)
-                .returns(null, 2, 2, null)
+        // MERGE JOIN doesn't support non-equi conditions.
+        if (joinType != JoinType.MERGE) {
+            assertQuery("select t1.c2, t1.c3, t2.c2+3 as t2c2, t2.c3 from t1 
join t2 on t1.c2 is not distinct from t2.c3 and " +
+                "t1.c3<t2.c2+3 order by t1.c2, t1.c3, t2c2, t2.c3")
+                .returns(1, 1, 4, 1)
+                .returns(2, 2, 5, 2)
+                .returns(3, 3, 6, 3)
+                .returns(4, 4, 7, 4)
+                .returns(null, 2, 5, null)
                 .check();
         }
 
-        // HASH JOIN doesn't support: IS NOT DISTINCT, completely non-equi 
conditions, additional non-equi conditions
+        assertQuery("select t1.c2, t1.c3, t2.c1, t2.c3 from t1 join t2 on 
t1.c2 is not distinct from t2.c3 and " +
+            "t1.c3 = t2.c1 order by t1.c2, t1.c3, t2.c1, t2.c3")
+            .returns(1, 1, 1, 1)
+            .returns(2, 2, 2, 2)
+            .returns(3, 3, 3, 3)
+            .returns(3, 3, 3, 3)
+            .returns(4, 4, 4, 4)
+            .returns(null, 2, 2, null)
+            .check();
+
+        // HASH JOIN doesn't support: completely non-equi conditions, 
additional non-equi conditions
         // except INNER and SEMI joins.
         // MERGE JOIN doesn't support: non-equi conditions.
         if (joinType == JoinType.HASH || joinType == JoinType.MERGE)
@@ -596,43 +589,40 @@ public class JoinIntegrationTest extends 
AbstractBasicIntegrationTransactionalTe
             .returns(null, 3, 3, 3, 3)
             .check();
 
-        // HASH join doesn't support IS NOT DISTINCT.
-        if (joinType != JoinType.HASH) {
-            assertQuery("select t1.c2, t2.c3 from t1 left join t2 on t1.c2 is 
not distinct from t2.c3 order by t1.c2, t2.c3")
-                .returns(1, 1)
-                .returns(2, 2)
-                .returns(3, 3)
-                .returns(3, 3)
-                .returns(3, 3)
-                .returns(3, 3)
-                .returns(4, 4)
-                .returns(null, null)
-                .check();
+        assertQuery("select t1.c2, t2.c3 from t1 left join t2 on t1.c2 is not 
distinct from t2.c3 order by t1.c2, t2.c3")
+            .returns(1, 1)
+            .returns(2, 2)
+            .returns(3, 3)
+            .returns(3, 3)
+            .returns(3, 3)
+            .returns(3, 3)
+            .returns(4, 4)
+            .returns(null, null)
+            .check();
 
-            assertQuery("select t1.c2, t1.c3, t2.c1, t2.c3 from t1 left join 
t2 on t1.c2 is not distinct from t2.c3 and " +
-                "t1.c3 is not distinct from t2.c1 order by t1.c2, t1.c3, 
t2.c1, t2.c3")
-                .returns(1, 1, 1, 1)
-                .returns(2, 2, 2, 2)
-                .returns(3, 3, 3, 3)
-                .returns(3, 3, 3, 3)
-                .returns(3, null, null, null)
-                .returns(4, 4, 4, 4)
-                .returns(null, 2, 2, null)
-                .check();
+        assertQuery("select t1.c2, t1.c3, t2.c1, t2.c3 from t1 left join t2 on 
t1.c2 is not distinct from t2.c3 and " +
+            "t1.c3 is not distinct from t2.c1 order by t1.c2, t1.c3, t2.c1, 
t2.c3")
+            .returns(1, 1, 1, 1)
+            .returns(2, 2, 2, 2)
+            .returns(3, 3, 3, 3)
+            .returns(3, 3, 3, 3)
+            .returns(3, null, null, null)
+            .returns(4, 4, 4, 4)
+            .returns(null, 2, 2, null)
+            .check();
 
-            assertQuery("select t1.c2, t1.c3, t2.c1, t2.c3 from t1 left join 
t2 on t1.c2 is not distinct from t2.c3 and " +
-                "t1.c3 = t2.c1 order by t1.c2, t1.c3, t2.c1, t2.c3")
-                .returns(1, 1, 1, 1)
-                .returns(2, 2, 2, 2)
-                .returns(3, 3, 3, 3)
-                .returns(3, 3, 3, 3)
-                .returns(3, null, null, null)
-                .returns(4, 4, 4, 4)
-                .returns(null, 2, 2, null)
-                .check();
-        }
+        assertQuery("select t1.c2, t1.c3, t2.c1, t2.c3 from t1 left join t2 on 
t1.c2 is not distinct from t2.c3 and " +
+            "t1.c3 = t2.c1 order by t1.c2, t1.c3, t2.c1, t2.c3")
+            .returns(1, 1, 1, 1)
+            .returns(2, 2, 2, 2)
+            .returns(3, 3, 3, 3)
+            .returns(3, 3, 3, 3)
+            .returns(3, null, null, null)
+            .returns(4, 4, 4, 4)
+            .returns(null, 2, 2, null)
+            .check();
 
-        // HASH JOIN doesn't support: IS NOT DISTINCT, completely non-equi 
conditions, additional non-equi conditions
+        // HASH JOIN doesn't support: completely non-equi conditions, 
additional non-equi conditions
         // except INNER and SEMI joins.
         // MERGE JOIN doesn't support: non-equi conditions.
         if (joinType == JoinType.MERGE || joinType == JoinType.HASH)
@@ -947,41 +937,38 @@ public class JoinIntegrationTest extends 
AbstractBasicIntegrationTransactionalTe
             .returns(2, 2, 2, 2, null)
             .check();
 
-        // HASH join doesn't support IS NOT DISTINCT.
-        if (joinType != JoinType.HASH) {
-            assertQuery("select t1.c2, t2.c3 from t1 right join t2 on t1.c2 is 
not distinct from t2.c3 order by t1.c2, t2.c3")
-                .returns(1, 1)
-                .returns(2, 2)
-                .returns(3, 3)
-                .returns(3, 3)
-                .returns(3, 3)
-                .returns(3, 3)
-                .returns(4, 4)
-                .returns(null, null)
-                .check();
+        assertQuery("select t1.c2, t2.c3 from t1 right join t2 on t1.c2 is not 
distinct from t2.c3 order by t1.c2, t2.c3")
+            .returns(1, 1)
+            .returns(2, 2)
+            .returns(3, 3)
+            .returns(3, 3)
+            .returns(3, 3)
+            .returns(3, 3)
+            .returns(4, 4)
+            .returns(null, null)
+            .check();
 
-            assertQuery("select t1.c2, t1.c3, t2.c1, t2.c3 from t1 right join 
t2 on t1.c2 is not distinct from t2.c3 and " +
-                "t1.c3 is not distinct from t2.c1 order by t1.c2, t1.c3, 
t2.c1, t2.c3")
-                .returns(1, 1, 1, 1)
-                .returns(2, 2, 2, 2)
-                .returns(3, 3, 3, 3)
-                .returns(3, 3, 3, 3)
-                .returns(4, 4, 4, 4)
-                .returns(null, 2, 2, null)
-                .check();
+        assertQuery("select t1.c2, t1.c3, t2.c1, t2.c3 from t1 right join t2 
on t1.c2 is not distinct from t2.c3 and " +
+            "t1.c3 is not distinct from t2.c1 order by t1.c2, t1.c3, t2.c1, 
t2.c3")
+            .returns(1, 1, 1, 1)
+            .returns(2, 2, 2, 2)
+            .returns(3, 3, 3, 3)
+            .returns(3, 3, 3, 3)
+            .returns(4, 4, 4, 4)
+            .returns(null, 2, 2, null)
+            .check();
 
-            assertQuery("select t1.c2, t1.c3, t2.c1, t2.c3 from t1 right join 
t2 on t1.c2 is not distinct from t2.c3 and " +
-                "t1.c3 = t2.c1 order by t1.c2, t1.c3, t2.c1, t2.c3")
-                .returns(1, 1, 1, 1)
-                .returns(2, 2, 2, 2)
-                .returns(3, 3, 3, 3)
-                .returns(3, 3, 3, 3)
-                .returns(4, 4, 4, 4)
-                .returns(null, 2, 2, null)
-                .check();
-        }
+        assertQuery("select t1.c2, t1.c3, t2.c1, t2.c3 from t1 right join t2 
on t1.c2 is not distinct from t2.c3 and " +
+            "t1.c3 = t2.c1 order by t1.c2, t1.c3, t2.c1, t2.c3")
+            .returns(1, 1, 1, 1)
+            .returns(2, 2, 2, 2)
+            .returns(3, 3, 3, 3)
+            .returns(3, 3, 3, 3)
+            .returns(4, 4, 4, 4)
+            .returns(null, 2, 2, null)
+            .check();
 
-        // HASH JOIN doesn't support: IS NOT DISTINCT, completely non-equi 
conditions, additional non-equi conditions
+        // HASH JOIN doesn't support: completely non-equi conditions, 
additional non-equi conditions
         // except INNER and SEMI joins.
         // MERGE JOIN doesn't support: non-equi conditions.
         if (joinType == JoinType.MERGE || joinType == JoinType.HASH)
@@ -1066,43 +1053,40 @@ public class JoinIntegrationTest extends 
AbstractBasicIntegrationTransactionalTe
             .returns(null, null, null, 3, null, 3)
             .check();
 
-        // HASH join doesn't support IS NOT DISTINCT.
-        if (joinType != JoinType.HASH) {
-            assertQuery("select t1.c2, t2.c3 from t1 full join t2 on t1.c2 is 
not distinct from t2.c3 order by t1.c2, t2.c3")
-                .returns(1, 1)
-                .returns(2, 2)
-                .returns(3, 3)
-                .returns(3, 3)
-                .returns(3, 3)
-                .returns(3, 3)
-                .returns(4, 4)
-                .returns(null, null)
-                .check();
+        assertQuery("select t1.c2, t2.c3 from t1 full join t2 on t1.c2 is not 
distinct from t2.c3 order by t1.c2, t2.c3")
+            .returns(1, 1)
+            .returns(2, 2)
+            .returns(3, 3)
+            .returns(3, 3)
+            .returns(3, 3)
+            .returns(3, 3)
+            .returns(4, 4)
+            .returns(null, null)
+            .check();
 
-            assertQuery("select t1.c2, t1.c3, t2.c1, t2.c3 from t1 full join 
t2 on t1.c2 is not distinct from t2.c3 and " +
-                "t1.c3 is not distinct from t2.c1 order by t1.c2, t1.c3, 
t2.c1, t2.c3")
-                .returns(1, 1, 1, 1)
-                .returns(2, 2, 2, 2)
-                .returns(3, 3, 3, 3)
-                .returns(3, 3, 3, 3)
-                .returns(3, null, null, null)
-                .returns(4, 4, 4, 4)
-                .returns(null, 2, 2, null)
-                .check();
+        assertQuery("select t1.c2, t1.c3, t2.c1, t2.c3 from t1 full join t2 on 
t1.c2 is not distinct from t2.c3 and " +
+            "t1.c3 is not distinct from t2.c1 order by t1.c2, t1.c3, t2.c1, 
t2.c3")
+            .returns(1, 1, 1, 1)
+            .returns(2, 2, 2, 2)
+            .returns(3, 3, 3, 3)
+            .returns(3, 3, 3, 3)
+            .returns(3, null, null, null)
+            .returns(4, 4, 4, 4)
+            .returns(null, 2, 2, null)
+            .check();
 
-            assertQuery("select t1.c2, t1.c3, t2.c1, t2.c3 from t1 full join 
t2 on t1.c2 is not distinct from t2.c3 and " +
-                "t1.c3 = t2.c1 order by t1.c2, t1.c3, t2.c1, t2.c3")
-                .returns(1, 1, 1, 1)
-                .returns(2, 2, 2, 2)
-                .returns(3, 3, 3, 3)
-                .returns(3, 3, 3, 3)
-                .returns(3, null, null, null)
-                .returns(4, 4, 4, 4)
-                .returns(null, 2, 2, null)
-                .check();
-        }
+        assertQuery("select t1.c2, t1.c3, t2.c1, t2.c3 from t1 full join t2 on 
t1.c2 is not distinct from t2.c3 and " +
+            "t1.c3 = t2.c1 order by t1.c2, t1.c3, t2.c1, t2.c3")
+            .returns(1, 1, 1, 1)
+            .returns(2, 2, 2, 2)
+            .returns(3, 3, 3, 3)
+            .returns(3, 3, 3, 3)
+            .returns(3, null, null, null)
+            .returns(4, 4, 4, 4)
+            .returns(null, 2, 2, null)
+            .check();
 
-        // HASH JOIN doesn't support: IS NOT DISTINCT, completely non-equi 
conditions, additional non-equi conditions
+        // HASH JOIN doesn't support: completely non-equi conditions, 
additional non-equi conditions
         // except INNER and SEMI joins.
         // MERGE JOIN doesn't support: non-equi conditions.
         if (joinType == JoinType.MERGE || joinType == JoinType.HASH)
diff --git 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/HashJoinPlannerTest.java
 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/HashJoinPlannerTest.java
index 33ad96c64fe..88a95c20fce 100644
--- 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/HashJoinPlannerTest.java
+++ 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/HashJoinPlannerTest.java
@@ -116,11 +116,11 @@ public class HashJoinPlannerTest extends 
AbstractPlannerTest {
             F.asList("select t1.c1 from t1 %s join t2 on t1.id = t2.id and 
t1.c1=t2.c1", true, false),
             F.asList("select t1.c1 from t1 %s join t2 using(c1)", true, false),
             F.asList("select t1.c1 from t1 %s join t2 on t1.c1 = 1", false, 
false),
-            F.asList("select t1.c1 from t1 %s join t2 ON t1.id is not distinct 
from t2.c1", false, false),
-            F.asList("select t1.c1 from t1 %s join t2 ON t1.id is not distinct 
from t2.c1 and t1.c1 is not distinct from t2.id",
-                false, false),
-            F.asList("select t1.c1 from t1 %s join t2 ON t1.id is not distinct 
from t2.c1 and t1.c1 = t2.id", false, false),
-            F.asList("select t1.c1 from t1 %s join t2 ON t1.id is not distinct 
from t2.c1 and t1.c1 > t2.id", false, true),
+            F.asList("select t1.c1 from t1 %s join t2 ON t1.id is not distinct 
from t2.c1", true, false),
+            F.asList("select t1.c1 from t1 %s join t2 ON t1.id is not distinct 
from t2.c1 and t1.c1 is not distinct from  t2.id",
+                true, false),
+            F.asList("select t1.c1 from t1 %s join t2 ON t1.id is not distinct 
from t2.c1 and t1.c1 = t2.id", true, false),
+            F.asList("select t1.c1 from t1 %s join t2 ON t1.id is not distinct 
from t2.c1 and t1.c1 > t2.id", true, true),
             F.asList("select t1.c1 from t1 %s join t2 on t1.c1 = ?", false, 
false),
             F.asList("select t1.c1 from t1 %s join t2 on t1.c1 = 
OCTET_LENGTH('TEST')", false, false),
             F.asList("select t1.c1 from t1 %s join t2 on t1.c1 = 
LOG10(t1.c1)", false, false),

Reply via email to