kylin-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From liy...@apache.org
Subject [2/2] kylin git commit: KYLIN-2636 optimize case when in group by
Date Mon, 22 May 2017 11:46:00 GMT
KYLIN-2636 optimize case when in group by


Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/94cd373f
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/94cd373f
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/94cd373f

Branch: refs/heads/2.0.x
Commit: 94cd373fba89784263c25bc71ecdf612a7c333cf
Parents: 5d79404
Author: Hongbin Ma <mahongbin@apache.org>
Authored: Mon May 22 16:45:24 2017 +0800
Committer: Hongbin Ma <mahongbin@apache.org>
Committed: Mon May 22 19:42:24 2017 +0800

----------------------------------------------------------------------
 .../resources/query/sql_subquery/query32.sql    | 14 +++++
 .../resources/query/sql_subquery/query33.sql    | 14 +++++
 .../resources/query/sql_subquery/query34.sql    | 14 +++++
 .../kylin/query/relnode/OLAPProjectRel.java     | 61 +++++++++++++++++++-
 4 files changed, 102 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kylin/blob/94cd373f/kylin-it/src/test/resources/query/sql_subquery/query32.sql
----------------------------------------------------------------------
diff --git a/kylin-it/src/test/resources/query/sql_subquery/query32.sql b/kylin-it/src/test/resources/query/sql_subquery/query32.sql
new file mode 100644
index 0000000..394ea15
--- /dev/null
+++ b/kylin-it/src/test/resources/query/sql_subquery/query32.sql
@@ -0,0 +1,14 @@
+
+  select  sum(price) as sum_price,  (case when '1'='1' then test_cal_dt.week_beg_dt when
'1'='2' then test_kylin_fact.lstg_site_id else test_kylin_fact.leaf_categ_id end) as xxx 
+  from test_kylin_fact
+  inner JOIN edw.test_cal_dt as test_cal_dt
+  ON test_kylin_fact.cal_dt = test_cal_dt.cal_dt
+  inner JOIN test_category_groupings
+  ON test_kylin_fact.leaf_categ_id = test_category_groupings.leaf_categ_id AND test_kylin_fact.lstg_site_id
= test_category_groupings.site_id
+  inner JOIN edw.test_sites as test_sites
+  ON test_kylin_fact.lstg_site_id = test_sites.site_id
+  
+  where case when '1'='1' then test_kylin_fact.cal_dt < date'2012-04-01' when '1'='2'
then  test_cal_dt.week_beg_dt > date'2012-04-01' else  test_kylin_fact.lstg_site_id is
not null end and lstg_format_name='FP-GTC' 
+  
+  group by case when '1'='1' then test_cal_dt.week_beg_dt when '1'='2' then test_kylin_fact.lstg_site_id
else test_kylin_fact.leaf_categ_id end
+ 

http://git-wip-us.apache.org/repos/asf/kylin/blob/94cd373f/kylin-it/src/test/resources/query/sql_subquery/query33.sql
----------------------------------------------------------------------
diff --git a/kylin-it/src/test/resources/query/sql_subquery/query33.sql b/kylin-it/src/test/resources/query/sql_subquery/query33.sql
new file mode 100644
index 0000000..08ecc8e
--- /dev/null
+++ b/kylin-it/src/test/resources/query/sql_subquery/query33.sql
@@ -0,0 +1,14 @@
+
+  select  sum(price) as sum_price,  lstg_format_name,(case when '2'='1' then test_kylin_fact.lstg_site_id
 when '2'='2' then test_cal_dt.week_beg_dt else test_kylin_fact.leaf_categ_id end) as xxx

+  from test_kylin_fact
+  inner JOIN edw.test_cal_dt as test_cal_dt
+  ON test_kylin_fact.cal_dt = test_cal_dt.cal_dt
+  inner JOIN test_category_groupings
+  ON test_kylin_fact.leaf_categ_id = test_category_groupings.leaf_categ_id AND test_kylin_fact.lstg_site_id
= test_category_groupings.site_id
+  inner JOIN edw.test_sites as test_sites
+  ON test_kylin_fact.lstg_site_id = test_sites.site_id
+  
+  where case  when '2'='1' then  test_cal_dt.week_beg_dt > date'2012-04-01' when '2'='2'
then test_kylin_fact.cal_dt < date'2012-04-01' else  test_kylin_fact.lstg_site_id is not
null end
+  
+  group by case  when '2'='1' then test_kylin_fact.lstg_site_id  when '2'='2' then test_cal_dt.week_beg_dt
else test_kylin_fact.leaf_categ_id end,lstg_format_name
+ 

http://git-wip-us.apache.org/repos/asf/kylin/blob/94cd373f/kylin-it/src/test/resources/query/sql_subquery/query34.sql
----------------------------------------------------------------------
diff --git a/kylin-it/src/test/resources/query/sql_subquery/query34.sql b/kylin-it/src/test/resources/query/sql_subquery/query34.sql
new file mode 100644
index 0000000..0dda9aa
--- /dev/null
+++ b/kylin-it/src/test/resources/query/sql_subquery/query34.sql
@@ -0,0 +1,14 @@
+
+  select  sum(price) as sum_price,  (case when '3'='1' then test_cal_dt.week_beg_dt else
  test_kylin_fact.cal_dt  end) as xxx 
+  from test_kylin_fact
+  inner JOIN edw.test_cal_dt as test_cal_dt
+  ON test_kylin_fact.cal_dt = test_cal_dt.cal_dt
+  inner JOIN test_category_groupings
+  ON test_kylin_fact.leaf_categ_id = test_category_groupings.leaf_categ_id AND test_kylin_fact.lstg_site_id
= test_category_groupings.site_id
+  inner JOIN edw.test_sites as test_sites
+  ON test_kylin_fact.lstg_site_id = test_sites.site_id
+  
+  where case when '3'='1' then test_kylin_fact.cal_dt < date'2012-04-01' else  test_cal_dt.week_beg_dt
 > date'2012-04-01' end and lstg_format_name='FP-GTC' 
+  
+  group by case when '3'='1' then test_cal_dt.week_beg_dt  else   test_kylin_fact.cal_dt
end
+ 

http://git-wip-us.apache.org/repos/asf/kylin/blob/94cd373f/query/src/main/java/org/apache/kylin/query/relnode/OLAPProjectRel.java
----------------------------------------------------------------------
diff --git a/query/src/main/java/org/apache/kylin/query/relnode/OLAPProjectRel.java b/query/src/main/java/org/apache/kylin/query/relnode/OLAPProjectRel.java
index 399a337..b749d85 100644
--- a/query/src/main/java/org/apache/kylin/query/relnode/OLAPProjectRel.java
+++ b/query/src/main/java/org/apache/kylin/query/relnode/OLAPProjectRel.java
@@ -18,6 +18,8 @@
 
 package org.apache.kylin.query.relnode;
 
+import static org.apache.kylin.metadata.filter.CompareTupleFilter.CompareResultType;
+
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.LinkedList;
@@ -46,13 +48,16 @@ import org.apache.calcite.rex.RexLiteral;
 import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.rex.RexOver;
 import org.apache.calcite.rex.RexProgram;
+import org.apache.calcite.sql.SqlKind;
 import org.apache.calcite.sql.SqlOperator;
+import org.apache.calcite.sql.fun.SqlCaseOperator;
 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
 import org.apache.calcite.sql.validate.SqlUserDefinedFunction;
 import org.apache.kylin.metadata.model.TblColRef;
 import org.apache.kylin.metadata.model.TblColRef.InnerDataTypeEnum;
 
 import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
 
 /**
  */
@@ -208,12 +213,66 @@ public class OLAPProjectRel extends Project implements OLAPRel {
             }
         }
 
-        for (RexNode operand : call.getOperands()) {
+        List<RexNode> children = limitTranslateScope(call.getOperands(), operator);
+
+        for (RexNode operand : children) {
             translateRexNode(operand, inputColumnRowType, fieldName, sourceCollector);
         }
         return TblColRef.newInnerColumn(fieldName, InnerDataTypeEnum.LITERAL, call.toString());
     }
 
+    //in most cases it will return children itself
+    private List<RexNode> limitTranslateScope(List<RexNode> children, SqlOperator
operator) {
+
+        //group by case when 1 = 1 then x 1 = 2 then y else z 
+        if (operator instanceof SqlCaseOperator) {
+            int unknownWhenCalls = 0;
+            for (int i = 0; i < children.size() - 1; i += 2) {
+                if (children.get(i) instanceof RexCall) {
+                    RexCall whenCall = (RexCall) children.get(i);
+                    CompareResultType compareResultType = getCompareResultType(whenCall);
+                    if (compareResultType == CompareResultType.AlwaysTrue) {
+                        return Lists.newArrayList(children.get(i), children.get(i + 1));
+                    } else if (compareResultType == CompareResultType.Unknown) {
+                        unknownWhenCalls++;
+                    }
+                }
+            }
+
+            if (unknownWhenCalls == 0) {
+                return Lists.newArrayList(children.get(children.size() - 1));
+            }
+        }
+
+        return children;
+    }
+
+    private CompareResultType getCompareResultType(RexCall whenCall) {
+        List<RexNode> operands = whenCall.getOperands();
+        if (SqlKind.EQUALS == whenCall.getKind() && operands != null && operands.size()
== 2) {
+            if (operands.get(0).equals(operands.get(1))) {
+                return CompareResultType.AlwaysTrue;
+            }
+
+            if (isConstant(operands.get(0)) && isConstant(operands.get(0))) {
+                return CompareResultType.AlwaysFalse;
+            }
+        }
+        return CompareResultType.Unknown;
+    }
+
+    private boolean isConstant(RexNode rexNode) {
+        if (rexNode instanceof RexLiteral) {
+            return true;
+        }
+
+        if (rexNode instanceof RexCall && SqlKind.CAST.equals(rexNode.getKind())
&& ((RexCall) rexNode).getOperands().get(0) instanceof RexLiteral) {
+            return true;
+        }
+
+        return false;
+    }
+
     @Override
     public EnumerableRel implementEnumerable(List<EnumerableRel> inputs) {
         if (getInput() instanceof OLAPFilterRel) {


Mime
View raw message