You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kylin.apache.org by xx...@apache.org on 2022/12/16 07:01:34 UTC

[kylin] 03/15: KYLIN-5355 support constant query like `select max(1) from t`

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

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

commit 0e83e2291af1de9632e822405fed5cd6b8ea3fc0
Author: fanshu.kong <17...@qq.com>
AuthorDate: Mon Oct 17 15:36:38 2022 +0800

    KYLIN-5355  support constant query like `select max(1) from t`
    
    Co-authored-by: fanshu.kong <17...@qq.com>
---
 .../java/org/apache/kylin/query/relnode/OLAPJoinRel.java    |  4 +++-
 .../org/apache/kylin/rest/service/QueryServiceTest.java     |  3 ++-
 .../query/engine/exec/calcite/CalciteQueryPlanExec.java     |  3 ---
 .../query/engine/exec/sparder/SparderQueryPlanExec.java     | 13 ++++++++++++-
 4 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/src/query-common/src/main/java/org/apache/kylin/query/relnode/OLAPJoinRel.java b/src/query-common/src/main/java/org/apache/kylin/query/relnode/OLAPJoinRel.java
index 062669242d..749f8d089c 100644
--- a/src/query-common/src/main/java/org/apache/kylin/query/relnode/OLAPJoinRel.java
+++ b/src/query-common/src/main/java/org/apache/kylin/query/relnode/OLAPJoinRel.java
@@ -303,7 +303,9 @@ public class OLAPJoinRel extends EnumerableJoin implements OLAPRel {
 
         PhysType physType = PhysTypeImpl.of(implementor.getTypeFactory(), getRowType(), pref.preferArray());
         RelOptTable factTable = context.firstTableScan.getTable();
-        MethodCallExpression exprCall = Expressions.call(factTable.getExpression(OLAPTable.class), "executeOLAPQuery",
+        // query result is error like select min(2+2), max(2) from EmptyTable
+        String execFunc = context.isConstantQueryWithAggregations() ? "executeSimpleAggregationQuery" : "executeOLAPQuery";
+        MethodCallExpression exprCall = Expressions.call(factTable.getExpression(OLAPTable.class), execFunc,
                 implementor.getRootExpression(), Expressions.constant(context.id));
         return implementor.result(physType, Blocks.toBlock(exprCall));
     }
diff --git a/src/query-service/src/test/java/org/apache/kylin/rest/service/QueryServiceTest.java b/src/query-service/src/test/java/org/apache/kylin/rest/service/QueryServiceTest.java
index 5011e83b98..3a6f6670da 100644
--- a/src/query-service/src/test/java/org/apache/kylin/rest/service/QueryServiceTest.java
+++ b/src/query-service/src/test/java/org/apache/kylin/rest/service/QueryServiceTest.java
@@ -1676,7 +1676,8 @@ public class QueryServiceTest extends NLocalFileMetadataTestCase {
     public void testQueryWithConstant() throws SQLException {
         doTestQueryWithConstant("select current_timestamp");
         doTestQueryWithConstant("select 1,2,3,4,5");
-
+        doTestQueryWithConstant("select max(1) from TEST_ACCOUNT inner join TEST_MEASURE "
+                + "on TEST_ACCOUNT.ACCOUNT_ID = TEST_MEASURE.ID1");
     }
 
     private void doTestQueryWithConstant(String testSql) {
diff --git a/src/query/src/main/java/org/apache/kylin/query/engine/exec/calcite/CalciteQueryPlanExec.java b/src/query/src/main/java/org/apache/kylin/query/engine/exec/calcite/CalciteQueryPlanExec.java
index 3a8514e253..3d03f5772e 100644
--- a/src/query/src/main/java/org/apache/kylin/query/engine/exec/calcite/CalciteQueryPlanExec.java
+++ b/src/query/src/main/java/org/apache/kylin/query/engine/exec/calcite/CalciteQueryPlanExec.java
@@ -39,7 +39,6 @@ import org.apache.kylin.common.QueryTrace;
 import org.apache.kylin.common.util.DateFormat;
 import org.apache.kylin.query.engine.exec.QueryPlanExec;
 import org.apache.kylin.query.engine.meta.MutableDataContext;
-import org.apache.kylin.query.relnode.KapRel;
 
 /**
  * implement and execute a physical plan with Calcite
@@ -51,8 +50,6 @@ public class CalciteQueryPlanExec implements QueryPlanExec {
     public List<List<String>> execute(RelNode rel, MutableDataContext dataContext) {
         QueryContext.currentTrace().startSpan(QueryTrace.EXECUTION);
         initContextVars(dataContext);
-        // allocate the olapContext anyway since it's being checked by some unit tests
-        new KapRel.OLAPContextImplementor().allocateContext((KapRel) rel.getInput(0), rel);
 
         List<List<String>> result = doExecute(rel, dataContext);
 
diff --git a/src/query/src/main/java/org/apache/kylin/query/engine/exec/sparder/SparderQueryPlanExec.java b/src/query/src/main/java/org/apache/kylin/query/engine/exec/sparder/SparderQueryPlanExec.java
index 225c110baf..95b6139c52 100644
--- a/src/query/src/main/java/org/apache/kylin/query/engine/exec/sparder/SparderQueryPlanExec.java
+++ b/src/query/src/main/java/org/apache/kylin/query/engine/exec/sparder/SparderQueryPlanExec.java
@@ -36,6 +36,7 @@ import org.apache.kylin.metadata.cube.cuboid.NLayoutCandidate;
 import org.apache.kylin.metadata.cube.model.IndexEntity;
 import org.apache.kylin.query.engine.exec.ExecuteResult;
 import org.apache.kylin.query.engine.exec.QueryPlanExec;
+import org.apache.kylin.query.engine.exec.calcite.CalciteQueryPlanExec;
 import org.apache.kylin.query.engine.meta.MutableDataContext;
 import org.apache.kylin.query.engine.meta.SimpleDataContext;
 import org.apache.kylin.query.relnode.ContextUtil;
@@ -70,12 +71,18 @@ public class SparderQueryPlanExec implements QueryPlanExec {
         // select realizations
         selectRealization(rel);
 
+        val contexts = ContextUtil.listContexts();
+        for (OLAPContext context : contexts) {
+            if (hasEmptyRealization(context)) {
+                return new CalciteQueryPlanExec().executeToIterable(rel, dataContext);
+            }
+        }
+
         // skip if no segment is selected
         // check contentQuery and runConstantQueryLocally for UT cases to make sure SparderEnv.getDF is not null
         // TODO refactor IT tests and remove this runConstantQueryLocally checking
         if (!(dataContext instanceof SimpleDataContext) || !(((SimpleDataContext) dataContext)).isContentQuery()
                 || KapConfig.wrap(((SimpleDataContext) dataContext).getKylinConfig()).runConstantQueryLocally()) {
-            val contexts = ContextUtil.listContexts();
             for (OLAPContext context : contexts) {
                 if (context.olapSchema != null && context.storageContext.isEmptyLayout() && !context.isHasAgg()) {
                     QueryContext.fillEmptyResultSetMetrics();
@@ -110,6 +117,10 @@ public class SparderQueryPlanExec implements QueryPlanExec {
                 && !QueryContext.current().getSecondStorageUsageMap().isEmpty();
     }
 
+    private static boolean hasEmptyRealization(OLAPContext context) {
+        return context.realization == null && context.isConstantQueryWithAggregations();
+    }
+
     protected ExecuteResult internalCompute(QueryEngine queryEngine, DataContext dataContext, RelNode rel) {
         try {
             return queryEngine.computeToIterable(dataContext, rel);