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

liyang pushed a commit to branch kylin5
in repository https://gitbox.apache.org/repos/asf/kylin.git

commit f2d5f586ad87196621d3a93d5133f3595cfc5b4b
Author: Hao Chen <hao_...@qq.com>
AuthorDate: Sat Nov 4 16:10:54 2023 +0800

    KYLIN-5865 Supports OlapFilterJoinRule.FILTER_ON_JOIN
    
    Co-authored-by: hao.chen <hao.c...@kyligence.io>
---
 pom.xml                                            |  2 +-
 .../kylin/query/engine/SumExprPlannerTest.java     |  7 ++-
 .../kylin/query/engine/SumExprPlannerTest.xml      | 11 +++--
 .../org/apache/kylin/query/engine/QueryExec.java   | 16 +++----
 .../kylin/query/optrule/OlapFilterJoinRule.java    | 53 ++++++++++++++++++++++
 5 files changed, 74 insertions(+), 15 deletions(-)

diff --git a/pom.xml b/pom.xml
index 8c1883868c..091ee90583 100644
--- a/pom.xml
+++ b/pom.xml
@@ -138,7 +138,7 @@
         <scala-retry>0.3.0</scala-retry>
 
         <!-- Calcite Version -->
-        <calcite.version>1.116.0-kylin-4.x-r037</calcite.version>
+        <calcite.version>1.116.0-kylin-4.x-r038</calcite.version>
         <avatica.version>4.x_1.10-r01</avatica.version>
 
         <!-- Hadoop Common deps, keep compatible with hadoop2.version -->
diff --git 
a/src/kylin-it/src/test/java/org/apache/kylin/query/engine/SumExprPlannerTest.java
 
b/src/kylin-it/src/test/java/org/apache/kylin/query/engine/SumExprPlannerTest.java
index fb73616ba3..7472e9368a 100644
--- 
a/src/kylin-it/src/test/java/org/apache/kylin/query/engine/SumExprPlannerTest.java
+++ 
b/src/kylin-it/src/test/java/org/apache/kylin/query/engine/SumExprPlannerTest.java
@@ -21,16 +21,19 @@ package org.apache.kylin.query.engine;
 import java.io.IOException;
 import java.util.List;
 
+import org.apache.calcite.plan.RelOptRule;
 import org.apache.calcite.test.DiffRepository;
 import org.apache.kylin.common.KylinConfig;
 import org.apache.kylin.common.util.Pair;
 import org.apache.kylin.guava30.shaded.common.collect.ImmutableList;
+import org.apache.kylin.guava30.shaded.common.collect.Lists;
 import org.apache.kylin.query.optrule.OlapAggFilterTransposeRule;
 import org.apache.kylin.query.optrule.OlapAggJoinTransposeRule;
 import org.apache.kylin.query.optrule.OlapAggProjectMergeRule;
 import org.apache.kylin.query.optrule.OlapAggProjectTransposeRule;
 import org.apache.kylin.query.optrule.OlapAggregateRule;
 import org.apache.kylin.query.optrule.OlapCountDistinctJoinRule;
+import org.apache.kylin.query.optrule.OlapFilterJoinRule;
 import org.apache.kylin.query.optrule.OlapJoinRule;
 import org.apache.kylin.query.optrule.OlapProjectRule;
 import org.apache.kylin.query.optrule.OlapSumCastTransposeRule;
@@ -203,7 +206,9 @@ public class SumExprPlannerTest extends CalciteRuleTestBase 
{
                 + "  ) a\n" //
                 + "where  LO_COMMITDATE = ( select max(LO_COMMITDATE) from 
ssb.P_LINEORDER )";
         openSumCaseWhen();
-        checkSQL("ssb", sql, null, null);
+        List<RelOptRule> rules = Lists.newArrayList(HepUtils.SumExprRules);
+        rules.add(OlapFilterJoinRule.FILTER_ON_JOIN);
+        super.checkSQLPostOptimize("ssb", sql, null, null, rules);
     }
 
     @Test
diff --git 
a/src/kylin-it/src/test/resources/org/apache/kylin/query/engine/SumExprPlannerTest.xml
 
b/src/kylin-it/src/test/resources/org/apache/kylin/query/engine/SumExprPlannerTest.xml
index b112b5ab17..95a3e8ab94 100644
--- 
a/src/kylin-it/src/test/resources/org/apache/kylin/query/engine/SumExprPlannerTest.xml
+++ 
b/src/kylin-it/src/test/resources/org/apache/kylin/query/engine/SumExprPlannerTest.xml
@@ -1446,12 +1446,13 @@ OlapToEnumerableConverter
 OlapToEnumerableConverter
   OlapAggregateRel(group-set=[[]], groups=[null], EXPR$0=[SUM($0)], ctx=[])
     OlapProjectRel($f0=[CASE(=($0, 20230501), $1, null)], ctx=[])
-      OlapJoinRel(condition=[=($0, $3)], joinType=[inner], ctx=[])
-        OlapProjectRel(LO_COMMITDATE=[$15], LO_DISCOUNT=[$11], 
LO_ORDERDATE=[$5], ctx=[])
-          OlapTableScan(table=[[SSB, P_LINEORDER]], ctx=[], fields=[[0, 1, 2, 
3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]])
-        OlapAggregateRel(group-set=[[]], groups=[null], EXPR$0=[MAX($0)], 
ctx=[])
-          OlapProjectRel(LO_COMMITDATE=[$15], ctx=[])
+      OlapFilterRel(condition=[=($0, $3)], ctx=[])
+        OlapJoinRel(condition=[true], joinType=[left], ctx=[])
+          OlapProjectRel(LO_COMMITDATE=[$15], LO_DISCOUNT=[$11], 
LO_ORDERDATE=[$5], ctx=[])
             OlapTableScan(table=[[SSB, P_LINEORDER]], ctx=[], fields=[[0, 1, 
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]])
+          OlapAggregateRel(group-set=[[]], groups=[null], EXPR$0=[MAX($0)], 
ctx=[])
+            OlapProjectRel(LO_COMMITDATE=[$15], ctx=[])
+              OlapTableScan(table=[[SSB, P_LINEORDER]], ctx=[], fields=[[0, 1, 
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]])
 ]]>
         </Resource>
         <Resource name="planAfter">
diff --git 
a/src/query/src/main/java/org/apache/kylin/query/engine/QueryExec.java 
b/src/query/src/main/java/org/apache/kylin/query/engine/QueryExec.java
index 775069338e..122a23b3db 100644
--- a/src/query/src/main/java/org/apache/kylin/query/engine/QueryExec.java
+++ b/src/query/src/main/java/org/apache/kylin/query/engine/QueryExec.java
@@ -68,6 +68,7 @@ import org.apache.kylin.query.engine.exec.SparderPlanExec;
 import org.apache.kylin.query.engine.meta.SimpleDataContext;
 import org.apache.kylin.query.engine.view.ViewAnalyzer;
 import org.apache.kylin.query.mask.QueryResultMasks;
+import org.apache.kylin.query.optrule.OlapFilterJoinRule;
 import org.apache.kylin.query.optrule.SumConstantConvertRule;
 import org.apache.kylin.query.relnode.ContextUtil;
 import org.apache.kylin.query.relnode.OlapAggregateRel;
@@ -291,15 +292,14 @@ public class QueryExec {
             postOptRules.addAll(HepUtils.FilterReductionRules);
         }
 
-        if (!postOptRules.isEmpty()) {
-            RelNode transformed = HepUtils.runRuleCollection(node, 
postOptRules, false);
-            if (transformed != node && allowAlternativeQueryPlan) {
-                return Lists.newArrayList(transformed, node);
-            } else {
-                return Lists.newArrayList(transformed);
-            }
+        postOptRules.add(OlapFilterJoinRule.FILTER_ON_JOIN);
+
+        RelNode transformed = HepUtils.runRuleCollection(node, postOptRules, 
false);
+        if (transformed != node && allowAlternativeQueryPlan) {
+            return Lists.newArrayList(transformed, node);
+        } else {
+            return Lists.newArrayList(transformed);
         }
-        return Lists.newArrayList(node);
     }
 
     @VisibleForTesting
diff --git 
a/src/query/src/main/java/org/apache/kylin/query/optrule/OlapFilterJoinRule.java
 
b/src/query/src/main/java/org/apache/kylin/query/optrule/OlapFilterJoinRule.java
index b04d65b991..26ffe41ddb 100644
--- 
a/src/query/src/main/java/org/apache/kylin/query/optrule/OlapFilterJoinRule.java
+++ 
b/src/query/src/main/java/org/apache/kylin/query/optrule/OlapFilterJoinRule.java
@@ -21,6 +21,7 @@ package org.apache.kylin.query.optrule;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 import java.util.stream.Collectors;
 
 import org.apache.calcite.plan.RelOptRule;
@@ -35,9 +36,12 @@ import org.apache.calcite.rel.core.Filter;
 import org.apache.calcite.rel.core.Join;
 import org.apache.calcite.rel.core.JoinRelType;
 import org.apache.calcite.rel.core.RelFactories;
+import org.apache.calcite.rel.rules.FilterJoinRule;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeField;
 import org.apache.calcite.rex.RexBuilder;
+import org.apache.calcite.rex.RexCall;
+import org.apache.calcite.rex.RexInputRef;
 import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.rex.RexPermuteInputsShuttle;
 import org.apache.calcite.rex.RexUtil;
@@ -48,6 +52,7 @@ import org.apache.calcite.util.mapping.Mappings;
 import org.apache.kylin.guava30.shaded.common.collect.ImmutableList;
 import org.apache.kylin.guava30.shaded.common.collect.Lists;
 import org.apache.kylin.guava30.shaded.common.collect.Sets;
+import org.apache.kylin.metadata.model.util.ComputedColumnUtil;
 import org.apache.kylin.query.util.RexUtils;
 
 /**
@@ -56,6 +61,54 @@ import org.apache.kylin.query.util.RexUtils;
  *
  */
 public class OlapFilterJoinRule extends RelOptRule {
+
+    public static final FilterJoinRule FILTER_ON_JOIN = new 
FilterJoinRule.FilterIntoJoinRule(true,
+            RelFactories.LOGICAL_BUILDER, FilterJoinRule.TRUE_PREDICATE) {
+
+        // https://olapio.atlassian.net/browse/AL-8813
+        @Override
+        protected boolean canPushIntoFromAbove(Filter filter) {
+            if (filter == null) {
+                return false;
+            }
+
+            if (isFilterContainsCC(filter)) {
+                return false;
+            }
+
+            RexNode condition = filter.getCondition();
+            if (condition.isA(SqlKind.AND)) {
+                RexCall call = (RexCall) condition;
+                return 
call.getOperands().stream().allMatch(this::isSimpleInputRefCondition);
+            }
+            return isSimpleInputRefCondition(condition);
+        }
+
+        private boolean isFilterContainsCC(Filter filter) {
+            RexNode condition = filter.getCondition();
+            if (condition == null) {
+                return false;
+            }
+
+            Set<RexInputRef> allInputRefs = 
RexUtils.getAllInputRefs(condition);
+            List<RelDataTypeField> fieldList = 
filter.getRowType().getFieldList();
+            return allInputRefs.stream().anyMatch(inputRef -> 
fieldList.get(inputRef.getIndex()).getName()
+                    .startsWith(ComputedColumnUtil.CC_NAME_PREFIX));
+        }
+
+        // for example: table1.col1 = table2.col1 can be pushed into the below 
join relNode,
+        // however, table1.col1 + table1.col2 = table2.col1 can't be pushed.
+        private boolean isSimpleInputRefCondition(RexNode condition) {
+            if (condition.isA(SqlKind.EQUALS)) {
+                RexCall call = (RexCall) condition;
+                RexNode left = call.getOperands().get(0);
+                RexNode right = call.getOperands().get(1);
+                return left instanceof RexInputRef && right instanceof 
RexInputRef;
+            }
+            return false;
+        }
+    };
+
     public static final OlapFilterJoinRule OLAP_FILTER_ON_JOIN_JOIN = new 
OlapFilterJoinRule(
             operand(Filter.class,
                     operand(Join.class,

Reply via email to