KYLIN-2597 Deal with trivial expression in filters like x = 1+2

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

Branch: refs/heads/KYLIN-2624
Commit: 529b1be2f9f0f1c7bfb2798928b8c6c60cb581ea
Parents: 9a812d5
Author: Hongbin Ma <mahong...@apache.org>
Authored: Tue May 9 17:30:03 2017 +0800
Committer: Dong Li <lid...@apache.org>
Committed: Tue May 9 20:30:21 2017 +0800

----------------------------------------------------------------------
 .../test/resources/query/sql_limit/query03.sql  | 31 +++++++++++
 .../kylin/query/relnode/OLAPFilterRel.java      | 55 ++++++++++++++++++++
 2 files changed, 86 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kylin/blob/529b1be2/kylin-it/src/test/resources/query/sql_limit/query03.sql
----------------------------------------------------------------------
diff --git a/kylin-it/src/test/resources/query/sql_limit/query03.sql 
b/kylin-it/src/test/resources/query/sql_limit/query03.sql
new file mode 100644
index 0000000..4844395
--- /dev/null
+++ b/kylin-it/src/test/resources/query/sql_limit/query03.sql
@@ -0,0 +1,31 @@
+--
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements.  See the NOTICE file
+-- distributed with this work for additional information
+-- regarding copyright ownership.  The ASF licenses this file
+-- to you under the Apache License, Version 2.0 (the
+-- "License"); you may not use this file except in compliance
+-- with the License.  You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+SELECT 
+ test_kylin_fact.lstg_format_name ,test_kylin_fact.cal_dt , 
sum(test_kylin_fact.price) as GMV, count(*) as TRANS_CNT 
+ 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 test_kylin_fact.seller_id = 10000002 + 4 
+ 
+ group by  seller_id,test_kylin_fact.cal_dt,lstg_format_name
+ limit 10

http://git-wip-us.apache.org/repos/asf/kylin/blob/529b1be2/query/src/main/java/org/apache/kylin/query/relnode/OLAPFilterRel.java
----------------------------------------------------------------------
diff --git 
a/query/src/main/java/org/apache/kylin/query/relnode/OLAPFilterRel.java 
b/query/src/main/java/org/apache/kylin/query/relnode/OLAPFilterRel.java
index 0ee9204..06ad0c6 100755
--- a/query/src/main/java/org/apache/kylin/query/relnode/OLAPFilterRel.java
+++ b/query/src/main/java/org/apache/kylin/query/relnode/OLAPFilterRel.java
@@ -18,6 +18,7 @@
 
 package org.apache.kylin.query.relnode;
 
+import java.math.BigDecimal;
 import java.util.GregorianCalendar;
 import java.util.HashMap;
 import java.util.LinkedList;
@@ -68,6 +69,7 @@ import org.apache.kylin.metadata.filter.function.Functions;
 import org.apache.kylin.metadata.model.TblColRef;
 
 import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 
@@ -140,6 +142,16 @@ public class OLAPFilterRel extends Filter implements 
OLAPRel {
             case OTHER_FUNCTION:
                 filter = Functions.getFunctionTupleFilter(op.getName());
                 break;
+            case PLUS:
+            case MINUS:
+            case TIMES:
+            case DIVIDE:
+                TupleFilter f = dealWithTrivialExpr(call);
+                if (f != null) {
+                    // is a trivial expr
+                    return f;
+                }
+                //else go to default
             default:
                 filter = new 
UnsupportedTupleFilter(FilterOperatorEnum.UNSUPPORTED);
                 break;
@@ -166,6 +178,49 @@ public class OLAPFilterRel extends Filter implements 
OLAPRel {
             return filter;
         }
 
+        //KYLIN-2597 - Deal with trivial expression in filters like x = 1 + 2 
+        private TupleFilter dealWithTrivialExpr(RexCall call) {
+            ImmutableList<RexNode> operators = call.operands;
+            if (operators.size() != 2) {
+                return null;
+            }
+
+            BigDecimal left = null;
+            BigDecimal right = null;
+            for (RexNode rexNode : operators) {
+                if (!(rexNode instanceof RexLiteral)) {
+                    return null;// only trivial expr with constants
+                }
+
+                RexLiteral temp = (RexLiteral) rexNode;
+                if (temp.getType().getFamily() != SqlTypeFamily.NUMERIC || 
!(temp.getValue() instanceof BigDecimal)) {
+                    return null;// only numeric constants now
+                }
+
+                if (left == null) {
+                    left = (BigDecimal) temp.getValue();
+                } else {
+                    right = (BigDecimal) temp.getValue();
+                }
+            }
+
+            Preconditions.checkNotNull(left);
+            Preconditions.checkNotNull(right);
+            
+            switch (call.op.getKind()) {
+            case PLUS:
+                return new ConstantTupleFilter(left.add(right).toString());
+            case MINUS:
+                return new 
ConstantTupleFilter(left.subtract(right).toString());
+            case TIMES:
+                return new 
ConstantTupleFilter(left.multiply(right).toString());
+            case DIVIDE:
+                return new ConstantTupleFilter(left.divide(right).toString());
+            default:
+                return null;
+            }
+        }
+
         private TupleFilter cast(TupleFilter filter, RelDataType type) {
             if ((filter instanceof ConstantTupleFilter) == false) {
                 return filter;

Reply via email to