You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kylin.apache.org by ka...@apache.org on 2017/05/24 10:43:17 UTC
[46/50] [abbrv] kylin git commit: KYLIN-2636 optimize case when in
group by
KYLIN-2636 optimize case when in group by
KYLIN-2636 bug fix
Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/79c75015
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/79c75015
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/79c75015
Branch: refs/heads/KYLIN-2606
Commit: 79c75015e49b2216f6e8ca9ec0cedbff72737821
Parents: 2c54989
Author: Hongbin Ma <ma...@apache.org>
Authored: Mon May 22 16:45:24 2017 +0800
Committer: Hongbin Ma <ma...@apache.org>
Committed: Tue May 23 20:30:06 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/79c75015/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/79c75015/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/79c75015/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/79c75015/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..e7b09a3 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(1))) {
+ 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) {