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 <1714585...@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 <1714585...@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);