You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ti...@apache.org on 2025/03/04 14:22:10 UTC

(ignite) branch master updated: IGNITE-24688 Add FilterCorrelate rule into HEP planner phase (#11905)

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

timoninmaxim 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 3ce3f208bed IGNITE-24688 Add FilterCorrelate rule into HEP planner phase (#11905)
3ce3f208bed is described below

commit 3ce3f208bed1a2d4bdcfb09aabb528334e484beb
Author: Maksim Timonin <ti...@apache.org>
AuthorDate: Tue Mar 4 17:22:02 2025 +0300

    IGNITE-24688 Add FilterCorrelate rule into HEP planner phase (#11905)
---
 .../query/calcite/prepare/PlannerPhase.java        |   1 +
 .../CorrelatedNestedLoopJoinPlannerTest.java       | 106 +++++++--------------
 2 files changed, 36 insertions(+), 71 deletions(-)

diff --git a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/PlannerPhase.java b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/PlannerPhase.java
index 8e82d494047..7dc61997a0d 100644
--- a/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/PlannerPhase.java
+++ b/modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/prepare/PlannerPhase.java
@@ -106,6 +106,7 @@ public enum PlannerPhase {
                     CoreRules.FILTER_SET_OP_TRANSPOSE,
                     CoreRules.JOIN_CONDITION_PUSH,
                     CoreRules.FILTER_INTO_JOIN,
+                    CoreRules.FILTER_CORRELATE,
                     CoreRules.FILTER_PROJECT_TRANSPOSE
                 )
             );
diff --git a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/CorrelatedNestedLoopJoinPlannerTest.java b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/CorrelatedNestedLoopJoinPlannerTest.java
index 06051ccb0ff..fa9f5f2b44b 100644
--- a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/CorrelatedNestedLoopJoinPlannerTest.java
+++ b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/CorrelatedNestedLoopJoinPlannerTest.java
@@ -18,18 +18,19 @@
 package org.apache.ignite.internal.processors.query.calcite.planner;
 
 import java.util.List;
+import java.util.function.Predicate;
+
 import org.apache.calcite.plan.RelOptUtil;
-import org.apache.calcite.rel.type.RelDataTypeFactory;
+import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.rex.RexFieldAccess;
 import org.apache.ignite.internal.processors.query.calcite.prepare.bounds.ExactBounds;
 import org.apache.ignite.internal.processors.query.calcite.prepare.bounds.SearchBounds;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteCorrelatedNestedLoopJoin;
+import org.apache.ignite.internal.processors.query.calcite.rel.IgniteFilter;
 import org.apache.ignite.internal.processors.query.calcite.rel.IgniteIndexScan;
 import org.apache.ignite.internal.processors.query.calcite.rel.IgniteRel;
 import org.apache.ignite.internal.processors.query.calcite.schema.IgniteSchema;
-import org.apache.ignite.internal.processors.query.calcite.trait.IgniteDistribution;
 import org.apache.ignite.internal.processors.query.calcite.trait.IgniteDistributions;
-import org.apache.ignite.internal.processors.query.calcite.type.IgniteTypeFactory;
-import org.apache.ignite.internal.processors.query.calcite.type.IgniteTypeSystem;
 import org.junit.Test;
 
 /**
@@ -42,39 +43,9 @@ public class CorrelatedNestedLoopJoinPlannerTest extends AbstractPlannerTest {
      */
     @Test
     public void testValidIndexExpressions() throws Exception {
-        IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
-        IgniteTypeFactory f = new IgniteTypeFactory(IgniteTypeSystem.INSTANCE);
-
-        publicSchema.addTable(
-            "T0",
-            new TestTable(
-                new RelDataTypeFactory.Builder(f)
-                    .add("ID", f.createJavaType(Integer.class))
-                    .add("JID", f.createJavaType(Integer.class))
-                    .add("VAL", f.createJavaType(String.class))
-                    .build()) {
-
-                @Override public IgniteDistribution distribution() {
-                    return IgniteDistributions.broadcast();
-                }
-            }
-        );
-
-        publicSchema.addTable(
-            "T1",
-            new TestTable(
-                new RelDataTypeFactory.Builder(f)
-                    .add("ID", f.createJavaType(Integer.class))
-                    .add("JID", f.createJavaType(Integer.class))
-                    .add("VAL", f.createJavaType(String.class))
-                    .build()) {
-
-                @Override public IgniteDistribution distribution() {
-                    return IgniteDistributions.broadcast();
-                }
-            }
-                .addIndex("t1_jid_idx", 1, 0)
-        );
+        IgniteSchema publicSchema = createSchema(
+            testTable("T0"),
+            testTable("T1").addIndex("t1_jid_idx", 1, 0));
 
         String sql = "select * " +
             "from t0 " +
@@ -111,40 +82,9 @@ public class CorrelatedNestedLoopJoinPlannerTest extends AbstractPlannerTest {
      */
     @Test
     public void testInvalidIndexExpressions() throws Exception {
-        IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
-        IgniteTypeFactory f = new IgniteTypeFactory(IgniteTypeSystem.INSTANCE);
-
-        publicSchema.addTable(
-            "T0",
-            new TestTable(
-                new RelDataTypeFactory.Builder(f)
-                    .add("ID", f.createJavaType(Integer.class))
-                    .add("JID", f.createJavaType(Integer.class))
-                    .add("VAL", f.createJavaType(String.class))
-                    .build()) {
-
-                @Override public IgniteDistribution distribution() {
-                    return IgniteDistributions.broadcast();
-                }
-            }
-                .addIndex("t0_jid_idx", 1, 0)
-        );
-
-        publicSchema.addTable(
-            "T1",
-            new TestTable(
-                new RelDataTypeFactory.Builder(f)
-                    .add("ID", f.createJavaType(Integer.class))
-                    .add("JID", f.createJavaType(Integer.class))
-                    .add("VAL", f.createJavaType(String.class))
-                    .build()) {
-
-                @Override public IgniteDistribution distribution() {
-                    return IgniteDistributions.broadcast();
-                }
-            }
-                .addIndex("t1_jid_idx", 1, 0)
-        );
+        IgniteSchema publicSchema = createSchema(
+            testTable("T0").addIndex("t0_jid_idx", 1, 0),
+            testTable("T1").addIndex("t1_jid_idx", 1, 0));
 
         String sql = "select * " +
             "from t0 " +
@@ -160,4 +100,28 @@ public class CorrelatedNestedLoopJoinPlannerTest extends AbstractPlannerTest {
 
         checkSplitAndSerialization(phys, publicSchema);
     }
+
+    /** */
+    @Test
+    public void testFilterPushDown() throws Exception {
+        IgniteSchema publicSchema = createSchema(
+            testTable("T0"),
+            testTable("T1"));
+
+        String sql = "select * " +
+                "from t0 " +
+                "where t0.val > 'value' and exists (select * from t1 where t0.jid = t1.jid);";
+
+        Predicate<RelNode> check =
+            hasChildThat(isInstanceOf(IgniteCorrelatedNestedLoopJoin.class)
+                .and(input(0, isTableScan("T0").and(n -> n.condition() != null))))
+            .and(hasChildThat(isInstanceOf(IgniteFilter.class)).negate());
+
+        assertPlan(sql, publicSchema, check);
+    }
+
+    /** */
+    private TestTable testTable(String name) {
+        return createTable(name, IgniteDistributions.broadcast(), "ID", Integer.class, "JID", Integer.class, "VAL", String.class);
+    }
 }