This is an automated email from the ASF dual-hosted git repository. liyang pushed a commit to branch kylin5 in repository https://gitbox.apache.org/repos/asf/kylin.git
commit dc344ce2fff2b2ca1ece1955b98c4e4130fecbd3 Author: Yu Gan <yu....@kyligence.io> AuthorDate: Fri Aug 25 16:01:23 2023 +0800 KYLIN-5800 & KYLIN-5812 Support scalar subquery join aggregate pushdown --- .../org/apache/kylin/common/KylinConfigBase.java | 4 + .../query/rules/ScalarSubqueryJoinRuleTest.java | 112 +++ .../query/rules/ScalarSubqueryJoinRuleTest.xml | 778 ++++++++++++++++++++ .../query/sql_scalar_subquery/query01.sql | 26 + .../query/sql_scalar_subquery/query02.sql | 30 + .../query/sql_scalar_subquery/query03.sql | 32 + .../query/sql_scalar_subquery/query04.sql | 28 + .../query/sql_scalar_subquery/query05.sql | 37 + .../query/sql_scalar_subquery/query06.sql | 35 + .../query/sql_scalar_subquery/query07.sql | 33 + .../query/sql_scalar_subquery/query08.sql | 36 + .../query/sql_scalar_subquery/query09.sql | 36 + .../query/sql_scalar_subquery/query10.sql | 33 + .../query/sql_scalar_subquery/query11.sql | 32 + .../query/sql_scalar_subquery/query12.sql | 41 ++ .../query/sql_scalar_subquery/query13.sql | 36 + .../query/sql_scalar_subquery/query14.sql | 32 + .../query/sql_scalar_subquery/query15.sql | 27 + .../query/sql_scalar_subquery/query16.sql | 33 + .../query/sql_scalar_subquery/query17.sql | 31 + .../query/sql_scalar_subquery/query18.sql | 65 ++ .../query/sql_scalar_subquery/query19.sql | 26 + .../apache/kylin/query/relnode/KapValuesRel.java | 21 +- .../apache/kylin/query/relnode/OLAPValuesRel.java | 13 +- .../kyligence/kap/query/optrule/KAPValuesRule.java | 11 +- .../kap/query/optrule/ScalarSubqueryJoinRule.java | 799 +++++++++++++++++++++ .../org/apache/kylin/query/engine/QueryExec.java | 4 + .../java/org/apache/kylin/query/util/HepUtils.java | 20 +- 28 files changed, 2393 insertions(+), 18 deletions(-) diff --git a/src/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java b/src/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java index 8b9a0308f7..64b4a775d4 100644 --- a/src/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java +++ b/src/core-common/src/main/java/org/apache/kylin/common/KylinConfigBase.java @@ -2532,6 +2532,10 @@ public abstract class KylinConfigBase implements Serializable { return Boolean.parseBoolean(getOptional("kylin.query.calcite.aggregate-pushdown-enabled", FALSE)); } + public boolean isScalarSubqueryJoinEnabled() { + return Boolean.parseBoolean(getOptional("kylin.query.scalar-subquery-join-enabled", FALSE)); + } + public int getCalciteBindableCacheSize() { return Integer.parseInt(getOptional("kylin.query.calcite.bindable.cache.maxSize", "10")); } diff --git a/src/kylin-it/src/test/java/org/apache/kylin/query/rules/ScalarSubqueryJoinRuleTest.java b/src/kylin-it/src/test/java/org/apache/kylin/query/rules/ScalarSubqueryJoinRuleTest.java new file mode 100644 index 0000000000..0c8c75ac89 --- /dev/null +++ b/src/kylin-it/src/test/java/org/apache/kylin/query/rules/ScalarSubqueryJoinRuleTest.java @@ -0,0 +1,112 @@ +/* + * 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. + */ + +package org.apache.kylin.query.rules; + +import java.io.IOException; +import java.util.List; + +import org.apache.calcite.plan.RelOptRule; +import org.apache.calcite.rel.rules.AggregateProjectMergeRule; +import org.apache.calcite.rel.rules.ProjectMergeRule; +import org.apache.calcite.test.DiffRepository; +import org.apache.kylin.common.KylinConfig; +import org.apache.kylin.common.util.Pair; +import org.apache.kylin.guava30.shaded.common.collect.ImmutableList; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import io.kyligence.kap.query.optrule.AggregateProjectReduceRule; +import io.kyligence.kap.query.optrule.KapAggregateRule; +import io.kyligence.kap.query.optrule.KapJoinRule; +import io.kyligence.kap.query.optrule.KapProjectRule; +import io.kyligence.kap.query.optrule.ScalarSubqueryJoinRule; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class ScalarSubqueryJoinRuleTest extends CalciteRuleTestBase { + + private final String project = "default"; + private final String sqlFolder = "query/sql_scalar_subquery"; + // + private final DiffRepository diff = DiffRepository.lookup(ScalarSubqueryJoinRuleTest.class); + + @Before + public void setup() { + createTestMetadata(); + } + + @After + public void cleanUp() { + cleanupTestMetadata(); + } + + @Override + protected DiffRepository getDiffRepo() { + return diff; + } + + @Test + public void testPushDownAggregate() throws IOException { + KylinConfig config = KylinConfig.getInstanceFromEnv(); + List<Pair<String, String>> queries = readALLSQLs(config, project, sqlFolder); + List<RelOptRule> rulesToAdd = getTransformRules(); + + queries.forEach(p -> doCheckTransform(p.getFirst(), p.getSecond(), rulesToAdd)); + } + + private void doCheckTransform(String prefix, String sql, List<RelOptRule> rulesToAdd) { + checkSQLPostOptimize(project, sql, prefix, null, rulesToAdd); + } + + @Test + @Ignore("Dev only") + public void testSingle() throws IOException { + KylinConfig config = KylinConfig.getInstanceFromEnv(); + List<RelOptRule> rulesToAdd = getTransformRules(); + Pair<String, String> q = readOneSQL(config, project, sqlFolder, "query03.sql"); + doCheckTransform(q.getFirst(), q.getSecond(), rulesToAdd); + } + + @Test + @Ignore("Dev only") + public void dumpPlans() throws IOException { + List<Pair<String, String>> queries = readALLSQLs(KylinConfig.getInstanceFromEnv(), project, sqlFolder); + CalciteRuleTestBase.StringOutput output = new CalciteRuleTestBase.StringOutput(false); + final List<RelOptRule> rulesToAdd = getTransformRules(); + queries.forEach(p -> checkSQLPostOptimize(project, p.getSecond(), p.getFirst(), output, rulesToAdd)); + output.dump(log); + } + + private List<RelOptRule> getTransformRules() { + return ImmutableList.of(// basic rules + KapAggregateRule.INSTANCE, // + KapProjectRule.INSTANCE, // + KapJoinRule.INSTANCE, // + // relative rules + ProjectMergeRule.INSTANCE, // + AggregateProjectMergeRule.INSTANCE, // + AggregateProjectReduceRule.INSTANCE, // + // target rules + ScalarSubqueryJoinRule.AGG_JOIN, // + ScalarSubqueryJoinRule.AGG_PRJ_JOIN, // + ScalarSubqueryJoinRule.AGG_PRJ_FLT_JOIN); + } +} diff --git a/src/kylin-it/src/test/resources/org/apache/kylin/query/rules/ScalarSubqueryJoinRuleTest.xml b/src/kylin-it/src/test/resources/org/apache/kylin/query/rules/ScalarSubqueryJoinRuleTest.xml new file mode 100644 index 0000000000..55c9a36a16 --- /dev/null +++ b/src/kylin-it/src/test/resources/org/apache/kylin/query/rules/ScalarSubqueryJoinRuleTest.xml @@ -0,0 +1,778 @@ +<?xml version="1.0" ?> +<!-- + 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. +--> + +<Root> + <TestCase name="testPushDownAggregate"> + <Resource name="query01.planBefore"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapAggregateRel(group-set=[[0, 1]], groups=[null], TOTAL=[SUM($2)], ctx=[]) + KapProjectRel(D_DATEKEY=[$1], DATE_TIME=[$0], D_YEAR=[$5], ctx=[]) + KapJoinRel(condition=[=($0, $1)], joinType=[left], ctx=[]) + KapProjectRel(DATE_TIME=['1995-03-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) +]]> + </Resource> + <Resource name="query01.planAfter"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapProjectRel(D_DATEKEY=[$1], DATE_TIME=[$0], TOTAL=[$2], ctx=[]) + KapAggregateRel(group-set=[[0, 1]], groups=[null], TOTAL=[SUM($2)], ctx=[]) + KapJoinRel(condition=[=($0, $1)], joinType=[left], ctx=[]) + KapProjectRel(DATE_TIME=['1995-03-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapAggregateRel(group-set=[[0]], groups=[null], TOTAL=[SUM($4)], ctx=[]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) +]]> + </Resource> + <Resource name="query02.planBefore"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapAggregateRel(group-set=[[0, 1]], groups=[null], TOTAL=[SUM($2)], ctx=[]) + KapProjectRel(D_DATEKEY=[$1], DATE_TIME=[$0], D_YEAR=[$5], ctx=[]) + KapJoinRel(condition=[=($0, $1)], joinType=[left], ctx=[]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapProjectRel(DATE_TIME=['1995-03-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-03'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) +]]> + </Resource> + <Resource name="query02.planAfter"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapProjectRel(D_DATEKEY=[$1], DATE_TIME=[$0], TOTAL=[$2], ctx=[]) + KapAggregateRel(group-set=[[0, 1]], groups=[null], TOTAL=[SUM($2)], ctx=[]) + KapJoinRel(condition=[=($0, $1)], joinType=[left], ctx=[]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapProjectRel(DATE_TIME=['1995-03-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-03'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapAggregateRel(group-set=[[0]], groups=[null], TOTAL=[SUM($4)], ctx=[]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) +]]> + </Resource> + <Resource name="query03.planBefore"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapAggregateRel(group-set=[[0, 1]], groups=[null], EXPR$2=[COUNT()], SY=[SUM($2)], ctx=[]) + KapProjectRel(D_DATE=[$2], DATE_TIME=[$0], D_YEAR=[$5], ctx=[]) + KapNonEquiJoinRel(condition=[AND(<=($2, $0), >=($2, CONCAT(SUBSTRING($0, 1, 8), '01')))], joinType=[left], ctx=[]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapProjectRel(DATE_TIME=['1995-03-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-03'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) +]]> + </Resource> + <Resource name="query03.planAfter"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapProjectRel(D_DATE=[$1], DATE_TIME=[$0], EXPR$2=[$2], SY=[$3], ctx=[]) + KapAggregateRel(group-set=[[0, 1]], groups=[null], EXPR$2=[$SUM0($2)], SY=[SUM($3)], ctx=[]) + KapProjectRel(DATE_TIME=[$0], D_DATE=[$1], $f2=[CASE(IS NULL($2), CAST(1):BIGINT, $2)], SY=[$3], ctx=[]) + KapNonEquiJoinRel(condition=[AND(<=($1, $0), >=($1, CONCAT(SUBSTRING($0, 1, 8), '01')))], joinType=[left], ctx=[]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapProjectRel(DATE_TIME=['1995-03-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-03'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapAggregateRel(group-set=[[1]], groups=[null], EXPR$2=[COUNT()], SY=[SUM($4)], ctx=[]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) +]]> + </Resource> + <Resource name="query04.planBefore"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapProjectRel(D_DATEKEY=[$0], TOTAL=[$2], ctx=[]) + KapAggregateRel(group-set=[[0, 1]], groups=[null], TOTAL=[SUM($2)], ctx=[]) + KapProjectRel(D_DATEKEY=[$1], DATE_TIME=[$0], D_YEAR=[$5], ctx=[]) + KapJoinRel(condition=[=($0, $1)], joinType=[left], ctx=[]) + KapProjectRel(DATE_TIME=['1995-03-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) +]]> + </Resource> + <Resource name="query04.planAfter"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapProjectRel(D_DATEKEY=[$1], TOTAL=[$2], ctx=[]) + KapAggregateRel(group-set=[[0, 1]], groups=[null], TOTAL=[SUM($2)], ctx=[]) + KapJoinRel(condition=[=($0, $1)], joinType=[left], ctx=[]) + KapProjectRel(DATE_TIME=['1995-03-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapAggregateRel(group-set=[[0]], groups=[null], TOTAL=[SUM($4)], ctx=[]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) +]]> + </Resource> + <Resource name="query05.planBefore"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapProjectRel(SD=[$3], D_DATE=[$0], EXPR$2=[$4], DATE_TIME=[$1], SY=[$5], SR=[$6], LO_ORDERDATE=[$2], ctx=[]) + KapAggregateRel(group-set=[[0, 1, 2]], groups=[null], SD=[SUM($3)], EXPR$2=[COUNT()], SY=[SUM($4)], SR=[SUM($5)], ctx=[]) + KapProjectRel(D_DATE=[$2], DATE_TIME=[$0], LO_ORDERDATE=[$23], D_DATEKEY=[$1], D_YEAR=[$5], LO_REVENUE=[$30], ctx=[]) + KapJoinRel(condition=[=($0, $23)], joinType=[inner], ctx=[]) + KapNonEquiJoinRel(condition=[AND(<=($2, $0), >=($2, CONCAT(SUBSTRING($0, 1, 8), '01')))], joinType=[left], ctx=[]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapProjectRel(DATE_TIME=['1995-03-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-03'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) + KapTableScan(table=[[SSB, LINEORDER]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]]) +]]> + </Resource> + <Resource name="query05.planAfter"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapProjectRel(SD=[$3], D_DATE=[$1], EXPR$2=[$4], DATE_TIME=[$0], SY=[$5], SR=[$6], LO_ORDERDATE=[$2], ctx=[]) + KapAggregateRel(group-set=[[0, 1, 2]], groups=[null], SD=[SUM($8)], EXPR$2=[$SUM0($9)], SY=[SUM($10)], SR=[SUM($11)], ctx=[]) + KapProjectRel(DATE_TIME=[$0], D_DATE=[$1], LO_ORDERDATE=[$5], EXPR$2=[$3], SY=[$4], SD=[$2], $f1=[$6], SR=[$7], $f8=[CAST(*($2, $6)):BIGINT], $f9=[*($3, $6)], $f10=[CAST(*($4, $6)):BIGINT], $f11=[CAST(*($3, $7)):BIGINT], ctx=[]) + KapJoinRel(condition=[=($0, $5)], joinType=[inner], ctx=[]) + KapAggregateRel(group-set=[[0, 1]], groups=[null], SD=[SUM($2)], EXPR$2=[$SUM0($3)], SY=[SUM($4)], ctx=[]) + KapProjectRel(DATE_TIME=[$0], D_DATE=[$1], SD=[$2], $f3=[CASE(IS NULL($3), CAST(1):BIGINT, $3)], SY=[$4], ctx=[]) + KapNonEquiJoinRel(condition=[AND(<=($1, $0), >=($1, CONCAT(SUBSTRING($0, 1, 8), '01')))], joinType=[left], ctx=[]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapProjectRel(DATE_TIME=['1995-03-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-03'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapAggregateRel(group-set=[[1]], groups=[null], SD=[SUM($0)], EXPR$2=[COUNT()], SY=[SUM($4)], ctx=[]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) + KapAggregateRel(group-set=[[5]], groups=[null], agg#0=[COUNT()], SR=[SUM($12)], ctx=[]) + KapTableScan(table=[[SSB, LINEORDER]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]]) +]]> + </Resource> + <Resource name="query06.planBefore"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapAggregateRel(group-set=[[0, 1]], groups=[null], EXPR$2=[COUNT()], SY=[SUM($2)], ctx=[]) + KapProjectRel(D_DATE=[$4], DATE_TIME=[$0], D_YEAR=[$2], ctx=[]) + KapNonEquiJoinRel(condition=[AND(<=($4, $0), >=($4, CONCAT(SUBSTRING($0, 1, 8), '01')))], joinType=[left], ctx=[]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapProjectRel(DATE_TIME=['1995-03-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-03'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(D_DATEKEY=[$0], D_YEAR=[$4], D_HOLIDAYFL=[$15], D_DATE=[$1], ctx=[]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) +]]> + </Resource> + <Resource name="query06.planAfter"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapProjectRel(D_DATE=[$1], DATE_TIME=[$0], EXPR$2=[$2], SY=[$3], ctx=[]) + KapAggregateRel(group-set=[[0, 1]], groups=[null], EXPR$2=[$SUM0($2)], SY=[SUM($3)], ctx=[]) + KapProjectRel(DATE_TIME=[$0], D_DATE=[$1], $f2=[CASE(IS NULL($2), CAST(1):BIGINT, $2)], SY=[$3], ctx=[]) + KapNonEquiJoinRel(condition=[AND(<=($1, $0), >=($1, CONCAT(SUBSTRING($0, 1, 8), '01')))], joinType=[left], ctx=[]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapProjectRel(DATE_TIME=['1995-03-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-03'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapAggregateRel(group-set=[[1]], groups=[null], EXPR$2=[COUNT()], SY=[SUM($4)], ctx=[]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) +]]> + </Resource> + <Resource name="query07.planBefore"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapAggregateRel(group-set=[[0, 1]], groups=[null], EXPR$2=[COUNT()], SY=[SUM($2)], ctx=[]) + KapProjectRel(D_DATE=[$1], DATE_TIME=[$17], D_YEAR=[$4], ctx=[]) + KapNonEquiJoinRel(condition=[AND(<=($1, $17), >=($1, CONCAT(SUBSTRING($17, 1, 8), '01')))], joinType=[left], ctx=[]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapProjectRel(DATE_TIME=['1995-03-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-03'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) +]]> + </Resource> + <Resource name="query07.planAfter"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapAggregateRel(group-set=[[0, 3]], groups=[null], EXPR$2=[$SUM0($1)], SY=[SUM($2)], ctx=[]) + KapNonEquiJoinRel(condition=[AND(<=($0, $3), >=($0, CONCAT(SUBSTRING($3, 1, 8), '01')))], joinType=[left], ctx=[]) + KapAggregateRel(group-set=[[1]], groups=[null], EXPR$2=[COUNT()], SY=[SUM($4)], ctx=[]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapProjectRel(DATE_TIME=['1995-03-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-03'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) +]]> + </Resource> + <Resource name="query08.planBefore"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapAggregateRel(group-set=[[0, 1]], groups=[null], EXPR$2=[COUNT()], SY=[SUM($2)], ctx=[]) + KapProjectRel(D_DATE=[$3], DATE_TIME=[$4], D_YEAR=[$1], ctx=[]) + KapNonEquiJoinRel(condition=[AND(<=($3, $4), >=($3, CONCAT(SUBSTRING($4, 1, 8), '01')))], joinType=[left], ctx=[]) + KapProjectRel(D_DATEKEY=[$0], D_YEAR=[$4], D_HOLIDAYFL=[$15], D_DATE=[$1], ctx=[]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapProjectRel(DATE_TIME=['1995-03-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-03'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) +]]> + </Resource> + <Resource name="query08.planAfter"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapAggregateRel(group-set=[[0, 3]], groups=[null], EXPR$2=[$SUM0($1)], SY=[SUM($2)], ctx=[]) + KapNonEquiJoinRel(condition=[AND(<=($0, $3), >=($0, CONCAT(SUBSTRING($3, 1, 8), '01')))], joinType=[left], ctx=[]) + KapAggregateRel(group-set=[[1]], groups=[null], EXPR$2=[COUNT()], SY=[SUM($4)], ctx=[]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapProjectRel(DATE_TIME=['1995-03-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-03'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) +]]> + </Resource> + <Resource name="query09.planBefore"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapAggregateRel(group-set=[[0, 1]], groups=[null], EXPR$2=[COUNT()], SY=[SUM($2)], ctx=[]) + KapProjectRel(D_DATE=[$4], DATE_TIME=[$0], D_YEAR=[$3], ctx=[]) + KapNonEquiJoinRel(condition=[AND(<=($4, $0), >=($4, CONCAT(SUBSTRING($0, 1, 8), '01')))], joinType=[left], ctx=[]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapProjectRel(DATE_TIME=['1995-03-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-03'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(D_DATEKEY=[$0], EXPR$1=[$3], D_YEAR=[$2], D_DATE=[$1], ctx=[]) + KapAggregateRel(group-set=[[0, 1, 2]], groups=[null], EXPR$1=[SUM($2)], ctx=[]) + KapProjectRel(D_DATEKEY=[$0], D_DATE=[$1], D_YEAR=[$4], ctx=[]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) +]]> + </Resource> + <Resource name="query09.planAfter"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapProjectRel(D_DATE=[$1], DATE_TIME=[$0], EXPR$2=[$2], SY=[$3], ctx=[]) + KapAggregateRel(group-set=[[0, 1]], groups=[null], EXPR$2=[$SUM0($2)], SY=[SUM($3)], ctx=[]) + KapProjectRel(DATE_TIME=[$0], D_DATE=[$1], $f2=[CASE(IS NULL($2), CAST(1):BIGINT, $2)], SY=[$3], ctx=[]) + KapNonEquiJoinRel(condition=[AND(<=($1, $0), >=($1, CONCAT(SUBSTRING($0, 1, 8), '01')))], joinType=[left], ctx=[]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapProjectRel(DATE_TIME=['1995-03-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-03'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapAggregateRel(group-set=[[1]], groups=[null], EXPR$2=[COUNT()], SY=[SUM($2)], ctx=[]) + KapAggregateRel(group-set=[[0, 1, 4]], groups=[null], EXPR$1=[SUM($4)], ctx=[]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) +]]> + </Resource> + <Resource name="query10.planBefore"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapProjectRel(EXPR$0=[$1], SY=[$2], ctx=[]) + KapAggregateRel(group-set=[[0]], groups=[null], EXPR$0=[COUNT()], SY=[SUM($1)], ctx=[]) + KapProjectRel(DATE_TIME=[$0], D_YEAR=[$5], ctx=[]) + KapNonEquiJoinRel(condition=[AND(<=(CAST($1):BIGINT, CAST($0):BIGINT NOT NULL), >=(CAST($1):BIGINT, CAST(CONCAT(SUBSTRING($0, 1, 8), '01')):BIGINT NOT NULL))], joinType=[left], ctx=[]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapProjectRel(DATE_TIME=['1995-03-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['2300-03-03'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-03'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-03'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) +]]> + </Resource> + <Resource name="query10.planAfter"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapProjectRel(EXPR$0=[$1], SY=[$2], ctx=[]) + KapAggregateRel(group-set=[[0]], groups=[null], EXPR$0=[$SUM0($2)], SY=[SUM($3)], ctx=[]) + KapProjectRel(DATE_TIME=[$0], D_DATEKEY=[$1], $f2=[CASE(IS NULL($2), CAST(1):BIGINT, $2)], SY=[$3], ctx=[]) + KapNonEquiJoinRel(condition=[AND(<=(CAST($1):BIGINT, CAST($0):BIGINT NOT NULL), >=(CAST($1):BIGINT, CAST(CONCAT(SUBSTRING($0, 1, 8), '01')):BIGINT NOT NULL))], joinType=[left], ctx=[]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapProjectRel(DATE_TIME=['1995-03-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['2300-03-03'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-03'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-03'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapAggregateRel(group-set=[[0]], groups=[null], EXPR$0=[COUNT()], SY=[SUM($4)], ctx=[]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) +]]> + </Resource> + <Resource name="query11.planBefore"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapAggregateRel(group-set=[[]], groups=[null], EXPR$0=[COUNT()], SY=[SUM($0)], ctx=[]) + KapProjectRel(D_YEAR=[$5], ctx=[]) + KapNonEquiJoinRel(condition=[AND(<=(CAST($1):BIGINT, CAST($0):BIGINT NOT NULL), >=(CAST($1):BIGINT, CAST(CONCAT(SUBSTRING($0, 1, 8), '01')):BIGINT NOT NULL))], joinType=[left], ctx=[]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapProjectRel(DATE_TIME=['1995-03-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['2300-03-03'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-03'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-03'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) +]]> + </Resource> + <Resource name="query11.planAfter"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapAggregateRel(group-set=[[]], groups=[null], EXPR$0=[$SUM0($2)], SY=[SUM($3)], ctx=[]) + KapProjectRel(DATE_TIME=[$0], D_DATEKEY=[$1], $f2=[CASE(IS NULL($2), CAST(1):BIGINT, $2)], SY=[$3], ctx=[]) + KapNonEquiJoinRel(condition=[AND(<=(CAST($1):BIGINT, CAST($0):BIGINT NOT NULL), >=(CAST($1):BIGINT, CAST(CONCAT(SUBSTRING($0, 1, 8), '01')):BIGINT NOT NULL))], joinType=[left], ctx=[]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapProjectRel(DATE_TIME=['1995-03-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['2300-03-03'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-03'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-03'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapAggregateRel(group-set=[[0]], groups=[null], EXPR$0=[COUNT()], SY=[SUM($4)], ctx=[]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) +]]> + </Resource> + <Resource name="query12.planBefore"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapProjectRel(DATE_TIME=[$0], EXPR$1=[$1], EXPR$2=[$2], EXPR$3=[$3], EXPR$4=[$3], EXPR$5=[$4], SY=[$5], SR=[$6], ctx=[]) + KapAggregateRel(group-set=[[0]], groups=[null], EXPR$1=[COUNT($1, $2)], EXPR$2=[COUNT($1)], EXPR$3=[COUNT()], EXPR$5=[COUNT($2)], SY=[SUM($3)], SR=[SUM($4)], ctx=[]) + KapProjectRel(DATE_TIME=[$0], D_HOLIDAYFL=[$16], LO_CUSTKEY=[$20], D_YEAR=[$5], LO_REVENUE=[$30], ctx=[]) + KapJoinRel(condition=[=($0, $23)], joinType=[inner], ctx=[]) + KapNonEquiJoinRel(condition=[AND(<=($2, $0), >=($2, CONCAT(SUBSTRING($0, 1, 8), '01')))], joinType=[left], ctx=[]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapProjectRel(DATE_TIME=['1995-03-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['2050-03-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-03'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) + KapTableScan(table=[[SSB, LINEORDER]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]]) +]]> + </Resource> + <Resource name="query12.planAfter"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapProjectRel(DATE_TIME=[$0], EXPR$1=[$1], EXPR$2=[$2], EXPR$3=[$3], EXPR$4=[$3], EXPR$5=[$4], SY=[$5], SR=[$6], ctx=[]) + KapAggregateRel(group-set=[[0]], groups=[null], EXPR$1=[$SUM0($8)], EXPR$2=[$SUM0($9)], EXPR$3=[$SUM0($10)], EXPR$5=[$SUM0($11)], SY=[SUM($12)], SR=[SUM($13)], ctx=[]) + KapProjectRel(DATE_TIME=[$0], $f1=[$1], EXPR$3=[$2], SY=[$3], LO_ORDERDATE=[$4], $f10=[$5], $f2=[$6], SR=[$7], $f8=[*($1, $5)], $f9=[*($1, $6)], $f1011=[*($2, $6)], $f11=[*($2, $5)], $f12=[CAST(*($3, $6)):BIGINT], $f13=[CAST(*($2, $7)):BIGINT], ctx=[]) + KapJoinRel(condition=[=($0, $4)], joinType=[inner], ctx=[]) + KapAggregateRel(group-set=[[0]], groups=[null], agg#0=[$SUM0($2)], EXPR$3=[$SUM0($3)], SY=[SUM($4)], ctx=[]) + KapProjectRel(DATE_TIME=[$0], D_DATE=[$1], $f2=[CASE(IS NULL($2), CAST(0):BIGINT, $2)], $f3=[CASE(IS NULL($3), CAST(1):BIGINT, $3)], SY=[$4], ctx=[]) + KapNonEquiJoinRel(condition=[AND(<=($1, $0), >=($1, CONCAT(SUBSTRING($0, 1, 8), '01')))], joinType=[left], ctx=[]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapProjectRel(DATE_TIME=['1995-03-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['2050-03-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-03'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapAggregateRel(group-set=[[1]], groups=[null], agg#0=[COUNT($15)], EXPR$3=[COUNT()], SY=[SUM($4)], ctx=[]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) + KapAggregateRel(group-set=[[5]], groups=[null], agg#0=[COUNT($2)], agg#1=[COUNT()], SR=[SUM($12)], ctx=[]) + KapTableScan(table=[[SSB, LINEORDER]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]]) +]]> + </Resource> + <Resource name="query13.planBefore"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapProjectRel(D_DATEKEY=[$2], MIN_DAYOFWEEK=[$3], DATE_TIME=[$1], D_DATE=[$0], ctx=[]) + KapAggregateRel(group-set=[[0, 1, 2]], groups=[null], MIN_DAYOFWEEK=[COUNT($3)], ctx=[]) + KapProjectRel(D_DATE=[$1], DATE_TIME=[$17], D_DATEKEY=[$0], D_DAYOFWEEK=[$2], ctx=[]) + KapJoinRel(condition=[=($0, $17)], joinType=[inner], ctx=[]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[false], ctx=[], all=[false]) + KapProjectRel(DATE_TIME=['1995-03-29'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-04-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-29'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-04-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-05-17'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) +]]> + </Resource> + <Resource name="query13.planAfter"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapProjectRel(D_DATEKEY=[$0], MIN_DAYOFWEEK=[$3], DATE_TIME=[$2], D_DATE=[$1], ctx=[]) + KapAggregateRel(group-set=[[0, 1, 3]], groups=[null], MIN_DAYOFWEEK=[$SUM0($2)], ctx=[]) + KapJoinRel(condition=[=($0, $3)], joinType=[inner], ctx=[]) + KapAggregateRel(group-set=[[0, 1]], groups=[null], MIN_DAYOFWEEK=[COUNT($2)], ctx=[]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[false], ctx=[], all=[false]) + KapProjectRel(DATE_TIME=['1995-03-29'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-04-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-29'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-04-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-05-17'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) +]]> + </Resource> + <Resource name="query14.planBefore"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapProjectRel(D_DATEKEY=[$1], SUM_YEAR=[$2], DATE_TIME=[$0], ctx=[]) + KapAggregateRel(group-set=[[0, 1]], groups=[null], SUM_YEAR=[COUNT($2)], ctx=[]) + KapProjectRel(DATE_TIME=[$0], D_DATEKEY=[$1], D_YEAR=[$5], ctx=[]) + KapJoinRel(condition=[=($0, $1)], joinType=[left], ctx=[]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[false], ctx=[], all=[false]) + KapProjectRel(DATE_TIME=['1995-03-29'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-04-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-29'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-04-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-05-17'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) +]]> + </Resource> + <Resource name="query14.planAfter"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapProjectRel(D_DATEKEY=[$1], SUM_YEAR=[$2], DATE_TIME=[$0], ctx=[]) + KapAggregateRel(group-set=[[0, 1]], groups=[null], SUM_YEAR=[$SUM0($2)], ctx=[]) + KapProjectRel(DATE_TIME=[$0], D_DATEKEY=[$1], $f2=[CASE(IS NULL($2), CAST(0):BIGINT, $2)], ctx=[]) + KapJoinRel(condition=[=($0, $1)], joinType=[left], ctx=[]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[false], ctx=[], all=[false]) + KapProjectRel(DATE_TIME=['1995-03-29'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-04-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-29'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-04-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-05-17'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapAggregateRel(group-set=[[0]], groups=[null], SUM_YEAR=[COUNT($4)], ctx=[]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) +]]> + </Resource> + <Resource name="query15.planBefore"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapProjectRel(C_NAME=[$0], COUNT_ORDER=[$2], LO_ORDERDATE=[$1], SUM_CUSTKEY=[$3], ctx=[]) + KapAggregateRel(group-set=[[0, 1]], groups=[null], COUNT_ORDER=[COUNT($2)], SUM_CUSTKEY=[SUM($3)], ctx=[]) + KapProjectRel(C_NAME=[$22], LO_ORDERDATE=[$5], LO_ORDERKEY=[$0], C_CUSTKEY=[$21], ctx=[]) + KapJoinRel(condition=[=($2, $21)], joinType=[inner], ctx=[]) + KapTableScan(table=[[SSB, LINEORDER]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]]) + KapTableScan(table=[[SSB, CUSTOMER]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7]]) +]]> + </Resource> + <Resource name="query15.planAfter"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapProjectRel(C_NAME=[$1], COUNT_ORDER=[$2], LO_ORDERDATE=[$0], SUM_CUSTKEY=[$3], ctx=[]) + KapAggregateRel(group-set=[[5, 22]], groups=[null], COUNT_ORDER=[COUNT($0)], SUM_CUSTKEY=[SUM($21)], ctx=[]) + KapJoinRel(condition=[=($2, $21)], joinType=[inner], ctx=[]) + KapTableScan(table=[[SSB, LINEORDER]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]]) + KapTableScan(table=[[SSB, CUSTOMER]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7]]) +]]> + </Resource> + <Resource name="query16.planBefore"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapProjectRel(D_DATEKEY=[$1], COUNT_YEAR=[$2], DATE_TIME=[$0], ctx=[]) + KapAggregateRel(group-set=[[0, 1]], groups=[null], COUNT_YEAR=[COUNT($2)], ctx=[]) + KapProjectRel(DATE_TIME=[$0], D_DATEKEY=[$1], D_YEAR=[$5], ctx=[]) + KapFilterRel(condition=[=($4, 'May')], ctx=[]) + KapJoinRel(condition=[=($0, $1)], joinType=[left], ctx=[]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[false], ctx=[], all=[false]) + KapProjectRel(DATE_TIME=['1995-03-29'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-04-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-29'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-04-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-05-17'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) +]]> + </Resource> + <Resource name="query16.planAfter"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapProjectRel(D_DATEKEY=[$1], COUNT_YEAR=[$2], DATE_TIME=[$0], ctx=[]) + KapAggregateRel(group-set=[[0, 1]], groups=[null], COUNT_YEAR=[COUNT($5)], ctx=[]) + KapFilterRel(condition=[=($4, 'May')], ctx=[]) + KapJoinRel(condition=[=($0, $1)], joinType=[left], ctx=[]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[false], ctx=[], all=[false]) + KapProjectRel(DATE_TIME=['1995-03-29'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-04-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-29'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-04-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-05-17'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapTableScan(table=[[SSB, DATES]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]]) +]]> + </Resource> + <Resource name="query17.planBefore"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapProjectRel(C_NAME=[$0], COUNT_ORDER=[$3], LO_ORDERDATE=[$1], DATE_TIME=[$2], SUM_CUSTKEY=[$4], ctx=[]) + KapAggregateRel(group-set=[[0, 1, 2]], groups=[null], COUNT_ORDER=[COUNT($3)], SUM_CUSTKEY=[SUM($4)], ctx=[]) + KapProjectRel(C_NAME=[$22], LO_ORDERDATE=[$5], DATE_TIME=[$29], LO_ORDERKEY=[$0], C_CUSTKEY=[$21], ctx=[]) + KapJoinRel(condition=[=($5, $29)], joinType=[inner], ctx=[]) + KapJoinRel(condition=[=($2, $21)], joinType=[inner], ctx=[]) + KapTableScan(table=[[SSB, LINEORDER]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]]) + KapTableScan(table=[[SSB, CUSTOMER]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7]]) + KapProjectRel(DATE_TIME=['1996-01-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) +]]> + </Resource> + <Resource name="query17.planAfter"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapProjectRel(C_NAME=[$1], COUNT_ORDER=[$3], LO_ORDERDATE=[$0], DATE_TIME=[$2], SUM_CUSTKEY=[$4], ctx=[]) + KapAggregateRel(group-set=[[0, 1, 4]], groups=[null], COUNT_ORDER=[$SUM0($2)], SUM_CUSTKEY=[SUM($3)], ctx=[]) + KapJoinRel(condition=[=($0, $4)], joinType=[inner], ctx=[]) + KapAggregateRel(group-set=[[5, 22]], groups=[null], COUNT_ORDER=[COUNT($0)], SUM_CUSTKEY=[SUM($21)], ctx=[]) + KapJoinRel(condition=[=($2, $21)], joinType=[inner], ctx=[]) + KapTableScan(table=[[SSB, LINEORDER]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]]) + KapTableScan(table=[[SSB, CUSTOMER]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7]]) + KapProjectRel(DATE_TIME=['1996-01-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) +]]> + </Resource> + <Resource name="query18.planBefore"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapProjectRel(C_NAME=[$0], COUNT_ORDER=[$4], LO_ORDERDATE=[$1], DATE_TIME=[$2], DATE_TIME0=[$3], SUM_CUSTKEY=[$5], ctx=[]) + KapAggregateRel(group-set=[[0, 1, 2, 3]], groups=[null], COUNT_ORDER=[COUNT($4)], SUM_CUSTKEY=[SUM($5)], ctx=[]) + KapProjectRel(C_NAME=[$3], LO_ORDERDATE=[$1], DATE_TIME=[$0], $f3=[$5], LO_ORDERKEY=[$2], C_CUSTKEY=[$4], ctx=[]) + KapJoinRel(condition=[=($0, $1)], joinType=[left], ctx=[]) + KapProjectRel(DATE_TIME=['1996-01-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(LO_ORDERDATE=[$0], LO_ORDERKEY=[$1], C_NAME=[$2], C_CUSTKEY=[$3], DATE_TIME=[$4], ctx=[]) + KapProjectRel(LO_ORDERDATE=[$0], LO_ORDERKEY=[$1], C_NAME=[$2], C_CUSTKEY=[$3], DATE_TIME=[$5], ctx=[]) + KapJoinRel(condition=[=($0, $5)], joinType=[inner], ctx=[]) + KapProjectRel(LO_ORDERDATE=[$5], LO_ORDERKEY=[$0], C_NAME=[$22], C_CUSTKEY=[$21], DATE_TIME=[$29], ctx=[]) + KapJoinRel(condition=[=($5, $29)], joinType=[inner], ctx=[]) + KapJoinRel(condition=[=($2, $21)], joinType=[inner], ctx=[]) + KapTableScan(table=[[SSB, LINEORDER]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]]) + KapTableScan(table=[[SSB, CUSTOMER]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7]]) + KapUnionRel(all=[false], ctx=[], all=[false]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[false], ctx=[], all=[false]) + KapProjectRel(DATE_TIME=['1995-03-29'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-04-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-29'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-04-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1996-01-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-06-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1996-01-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) +]]> + </Resource> + <Resource name="query18.planAfter"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapProjectRel(C_NAME=[$2], COUNT_ORDER=[$4], LO_ORDERDATE=[$1], DATE_TIME=[$0], DATE_TIME0=[$3], SUM_CUSTKEY=[$5], ctx=[]) + KapAggregateRel(group-set=[[0, 1, 2, 3]], groups=[null], COUNT_ORDER=[$SUM0($4)], SUM_CUSTKEY=[SUM($5)], ctx=[]) + KapProjectRel(DATE_TIME=[$0], LO_ORDERDATE=[$1], C_NAME=[$2], DATE_TIME0=[$3], $f4=[CASE(IS NULL($4), CAST(0):BIGINT, $4)], SUM_CUSTKEY=[$5], ctx=[]) + KapJoinRel(condition=[=($0, $1)], joinType=[left], ctx=[]) + KapProjectRel(DATE_TIME=['1996-01-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapAggregateRel(group-set=[[0, 1, 4]], groups=[null], COUNT_ORDER=[$SUM0($2)], SUM_CUSTKEY=[SUM($3)], ctx=[]) + KapJoinRel(condition=[=($0, $4)], joinType=[inner], ctx=[]) + KapAggregateRel(group-set=[[0, 1]], groups=[null], COUNT_ORDER=[$SUM0($2)], SUM_CUSTKEY=[SUM($3)], ctx=[]) + KapJoinRel(condition=[=($0, $4)], joinType=[inner], ctx=[]) + KapAggregateRel(group-set=[[5, 22]], groups=[null], COUNT_ORDER=[COUNT($0)], SUM_CUSTKEY=[SUM($21)], ctx=[]) + KapJoinRel(condition=[=($2, $21)], joinType=[inner], ctx=[]) + KapTableScan(table=[[SSB, LINEORDER]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]]) + KapTableScan(table=[[SSB, CUSTOMER]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7]]) + KapUnionRel(all=[false], ctx=[], all=[false]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[true], ctx=[], all=[true]) + KapUnionRel(all=[false], ctx=[], all=[false]) + KapProjectRel(DATE_TIME=['1995-03-29'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-04-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-03-29'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-04-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1996-01-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1995-06-01'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) + KapProjectRel(DATE_TIME=['1996-01-02'], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) +]]> + </Resource> + <Resource name="query19.planBefore"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapProjectRel(EXPR$0=[$2], LO_ORDERDATE=[$0], DATE_TIME=[$1], ctx=[]) + KapAggregateRel(group-set=[[0, 1]], groups=[null], EXPR$0=[SUM($2)], ctx=[]) + KapProjectRel(LO_ORDERDATE=[$5], DATE_TIME=[$18], $f2=[*($9, 3)], ctx=[]) + KapJoinRel(condition=[=($5, $18)], joinType=[inner], ctx=[]) + KapTableScan(table=[[SSB, P_LINEORDER]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]]) + KapProjectRel(DATE_TIME=[19931014], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) +]]> + </Resource> + <Resource name="query19.planAfter"> + <![CDATA[ +KapOLAPToEnumerableConverter + KapProjectRel(EXPR$0=[$2], LO_ORDERDATE=[$0], DATE_TIME=[$1], ctx=[]) + KapAggregateRel(group-set=[[0, 1]], groups=[null], EXPR$0=[SUM($2)], ctx=[]) + KapProjectRel(LO_ORDERDATE=[$5], DATE_TIME=[$18], $f2=[*($9, 3)], ctx=[]) + KapJoinRel(condition=[=($5, $18)], joinType=[inner], ctx=[]) + KapTableScan(table=[[SSB, P_LINEORDER]], ctx=[], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]]) + KapProjectRel(DATE_TIME=[19931014], ctx=[]) + KapValuesRel(tuples=[[{ 0 }]]) +]]> + </Resource> + + </TestCase> +</Root> \ No newline at end of file diff --git a/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query01.sql b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query01.sql new file mode 100644 index 0000000000..b757e10ec3 --- /dev/null +++ b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query01.sql @@ -0,0 +1,26 @@ +-- +-- 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 D_DATEKEY, + DATE_TIME, + sum(D_YEAR) total +FROM (SELECT '1995-03-01' AS DATE_TIME) dt + LEFT JOIN SSB.DATES t2 ON dt.DATE_TIME = t2.D_DATEKEY +GROUP BY D_DATEKEY, + DATE_TIME \ No newline at end of file diff --git a/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query02.sql b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query02.sql new file mode 100644 index 0000000000..dec0698161 --- /dev/null +++ b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query02.sql @@ -0,0 +1,30 @@ +-- +-- 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 D_DATEKEY, + DATE_TIME, + sum(D_YEAR) total +FROM (SELECT '1995-03-01' AS DATE_TIME + UNION ALL + SELECT '1995-03-02' AS DATE_TIME + UNION ALL + SELECT '1995-03-03' AS DATE_TIME) dt + LEFT JOIN SSB.DATES t2 ON dt.DATE_TIME = t2.D_DATEKEY +GROUP BY D_DATEKEY, + DATE_TIME \ No newline at end of file diff --git a/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query03.sql b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query03.sql new file mode 100644 index 0000000000..a7221b72cc --- /dev/null +++ b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query03.sql @@ -0,0 +1,32 @@ +-- +-- 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 D_DATE, + DATE_TIME, + count(*), + sum(D_YEAR) sy +FROM (SELECT '1995-03-01' AS DATE_TIME + UNION ALL + SELECT '1995-03-02' AS DATE_TIME + UNION ALL + SELECT '1995-03-03' AS DATE_TIME) t1 + LEFT JOIN SSB.DATES t2 ON t2.D_DATE <= t1.DATE_TIME + AND t2.D_DATE >= CONCAT(SUBSTR(t1.DATE_TIME, 1, 8), '01') +GROUP BY D_DATE, + DATE_TIME \ No newline at end of file diff --git a/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query04.sql b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query04.sql new file mode 100644 index 0000000000..30d8a26b5c --- /dev/null +++ b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query04.sql @@ -0,0 +1,28 @@ +-- +-- 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 D_DATEKEY, + total +FROM (SELECT D_DATEKEY, + DATE_TIME, + sum(D_YEAR) total + FROM (SELECT '1995-03-01' AS DATE_TIME) dt + LEFT JOIN SSB.DATES t2 ON dt.DATE_TIME = t2.D_DATEKEY + GROUP BY D_DATEKEY, + DATE_TIME) \ No newline at end of file diff --git a/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query05.sql b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query05.sql new file mode 100644 index 0000000000..710afa2e03 --- /dev/null +++ b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query05.sql @@ -0,0 +1,37 @@ +-- +-- 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 sum(D_DATEKEY) as sd, + D_DATE, + count(*), + DATE_TIME, + sum(D_YEAR) sy, + sum(LO_REVENUE) sr, + LO_ORDERDATE +FROM (SELECT '1995-03-01' AS DATE_TIME + UNION ALL + SELECT '1995-03-02' AS DATE_TIME + UNION ALL + SELECT '1995-03-03' AS DATE_TIME) t1 + LEFT JOIN SSB.DATES t2 ON t2.D_DATE <= t1.DATE_TIME + AND t2.D_DATE >= CONCAT(SUBSTR(t1.DATE_TIME, 1, 8), '01') + INNER JOIN SSB.LINEORDER t3 ON t3.LO_ORDERDATE = t1.DATE_TIME +GROUP BY D_DATE, + DATE_TIME, + LO_ORDERDATE \ No newline at end of file diff --git a/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query06.sql b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query06.sql new file mode 100644 index 0000000000..9c765a7b12 --- /dev/null +++ b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query06.sql @@ -0,0 +1,35 @@ +-- +-- 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 D_DATE, + DATE_TIME, + count(*), + sum(D_YEAR) sy +FROM (SELECT '1995-03-01' AS DATE_TIME + UNION ALL + SELECT '1995-03-02' AS DATE_TIME + UNION ALL + SELECT '1995-03-03' AS DATE_TIME) t1 + LEFT JOIN ( + SELECT D_DATEKEY, D_YEAR, D_HOLIDAYFL, D_DATE + from SSB.DATES +) t2 ON t2.D_DATE <= t1.DATE_TIME + AND t2.D_DATE >= CONCAT(SUBSTR(t1.DATE_TIME, 1, 8), '01') +GROUP BY D_DATE, + DATE_TIME \ No newline at end of file diff --git a/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query07.sql b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query07.sql new file mode 100644 index 0000000000..85ce225b0e --- /dev/null +++ b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query07.sql @@ -0,0 +1,33 @@ +-- +-- 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 D_DATE, + DATE_TIME, + count(*), + sum(D_YEAR) sy +FROM SSB.DATES t1 + LEFT JOIN (SELECT '1995-03-01' AS DATE_TIME + UNION ALL + SELECT '1995-03-02' AS DATE_TIME + UNION ALL + SELECT '1995-03-03' AS DATE_TIME) t2 + ON t1.D_DATE <= t2.DATE_TIME + AND t1.D_DATE >= CONCAT(SUBSTR(t2.DATE_TIME, 1, 8), '01') +GROUP BY D_DATE, + DATE_TIME \ No newline at end of file diff --git a/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query08.sql b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query08.sql new file mode 100644 index 0000000000..2981e00b2c --- /dev/null +++ b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query08.sql @@ -0,0 +1,36 @@ +-- +-- 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 D_DATE, + DATE_TIME, + count(*), + sum(D_YEAR) sy +FROM ( + SELECT D_DATEKEY, D_YEAR, D_HOLIDAYFL, D_DATE + from SSB.DATES + ) t1 + LEFT JOIN (SELECT '1995-03-01' AS DATE_TIME + UNION ALL + SELECT '1995-03-02' AS DATE_TIME + UNION ALL + SELECT '1995-03-03' AS DATE_TIME) t2 + ON t1.D_DATE <= t2.DATE_TIME + AND t1.D_DATE >= CONCAT(SUBSTR(t2.DATE_TIME, 1, 8), '01') +GROUP BY D_DATE, + DATE_TIME \ No newline at end of file diff --git a/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query09.sql b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query09.sql new file mode 100644 index 0000000000..571cb26cdd --- /dev/null +++ b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query09.sql @@ -0,0 +1,36 @@ +-- +-- 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 D_DATE, + DATE_TIME, + count(*), + sum(D_YEAR) sy +FROM (SELECT '1995-03-01' AS DATE_TIME + UNION ALL + SELECT '1995-03-02' AS DATE_TIME + UNION ALL + SELECT '1995-03-03' AS DATE_TIME) t1 + LEFT JOIN ( + SELECT D_DATEKEY, SUM(D_YEAR), D_YEAR, D_DATE + from SSB.DATES + GROUP BY D_DATEKEY, D_DATE, D_YEAR +) t2 ON t2.D_DATE <= t1.DATE_TIME + AND t2.D_DATE >= CONCAT(SUBSTR(t1.DATE_TIME, 1, 8), '01') +GROUP BY D_DATE, + DATE_TIME \ No newline at end of file diff --git a/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query10.sql b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query10.sql new file mode 100644 index 0000000000..3db46727bc --- /dev/null +++ b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query10.sql @@ -0,0 +1,33 @@ +-- +-- 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 count(*), + sum(D_YEAR) sy +FROM (SELECT '1995-03-01' AS DATE_TIME + UNION ALL + SELECT '1995-03-02' AS DATE_TIME + UNION ALL + SELECT '2300-03-03' AS DATE_TIME + UNION ALL + SELECT '1995-03-03' AS DATE_TIME + UNION ALL + SELECT '1995-03-03' AS DATE_TIME) t1 + LEFT JOIN SSB.DATES t2 ON t2.D_DATEKEY <= t1.DATE_TIME + AND t2.D_DATEKEY >= CONCAT(SUBSTR(t1.DATE_TIME, 1, 8), '01') +GROUP BY DATE_TIME diff --git a/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query11.sql b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query11.sql new file mode 100644 index 0000000000..29e3687de6 --- /dev/null +++ b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query11.sql @@ -0,0 +1,32 @@ +-- +-- 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 count(*), + sum(D_YEAR) sy +FROM (SELECT '1995-03-01' AS DATE_TIME + UNION ALL + SELECT '1995-03-02' AS DATE_TIME + UNION ALL + SELECT '2300-03-03' AS DATE_TIME + UNION ALL + SELECT '1995-03-03' AS DATE_TIME + UNION ALL + SELECT '1995-03-03' AS DATE_TIME) t1 + LEFT JOIN SSB.DATES t2 ON t2.D_DATEKEY <= t1.DATE_TIME + AND t2.D_DATEKEY >= CONCAT(SUBSTR(t1.DATE_TIME, 1, 8), '01') diff --git a/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query12.sql b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query12.sql new file mode 100644 index 0000000000..218cc57a5d --- /dev/null +++ b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query12.sql @@ -0,0 +1,41 @@ +-- +-- 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 DATE_TIME, + count(D_HOLIDAYFL, LO_CUSTKEY), + count(D_HOLIDAYFL), + count(*), + count(1), + count(LO_CUSTKEY), + sum(D_YEAR) sy, + sum(LO_REVENUE) sr +FROM (SELECT '1995-03-01' AS DATE_TIME + UNION ALL + SELECT '2050-03-02' AS DATE_TIME + UNION ALL + SELECT '1995-03-02' AS DATE_TIME + UNION ALL + SELECT '1995-03-02' AS DATE_TIME + UNION ALL + SELECT '1995-03-03' AS DATE_TIME) t1 + LEFT JOIN SSB.DATES t2 + ON t2.D_DATE <= t1.DATE_TIME + AND t2.D_DATE >= CONCAT(SUBSTR(t1.DATE_TIME, 1, 8), '01') + INNER JOIN SSB.LINEORDER t3 ON t3.LO_ORDERDATE = t1.DATE_TIME +GROUP BY DATE_TIME diff --git a/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query13.sql b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query13.sql new file mode 100644 index 0000000000..a026843a08 --- /dev/null +++ b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query13.sql @@ -0,0 +1,36 @@ +-- +-- 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 DATES.D_DATEKEY, + count(DATES.D_DAYOFWEEK) min_dayofweek, + DT.DATE_TIME, + DATES.D_DATE +from SSB.DATES + inner join + (select '1995-03-29' as DATE_TIME + union + select '1995-04-01' as DATE_TIME + union all + select '1995-03-29' as DATE_TIME + union all + select '1995-04-01' as DATE_TIME + union all + select '1995-05-17' as DATE_TIME) DT + on DT.DATE_TIME = DATES.D_DATEKEY +group by DATES.D_DATE, date_time, DATES.D_DATEKEY diff --git a/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query14.sql b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query14.sql new file mode 100644 index 0000000000..fea673ec28 --- /dev/null +++ b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query14.sql @@ -0,0 +1,32 @@ +-- +-- 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 DATES.D_DATEKEY, count(DATES.D_YEAR) sum_year, DT.DATE_TIME +from (select '1995-03-29' as DATE_TIME + union + select '1995-04-01' as DATE_TIME + union all + select '1995-03-29' as DATE_TIME + union all + select '1995-04-01' as DATE_TIME + union all + select '1995-05-17' as DATE_TIME) DT + left join SSB.DATES + on DT.DATE_TIME = DATES.D_DATEKEY +group by dt.date_time, DATES.D_DATEKEY diff --git a/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query15.sql b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query15.sql new file mode 100644 index 0000000000..760bb2d3d2 --- /dev/null +++ b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query15.sql @@ -0,0 +1,27 @@ +-- +-- 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 CUSTOMER.C_NAME, + count(LINEORDER.LO_ORDERKEY) count_order, + LINEORDER.LO_ORDERDATE, + sum(CUSTOMER.C_CUSTKEY) sum_custkey +FROM SSB.LINEORDER + INNER JOIN SSB.CUSTOMER ON LINEORDER.LO_CUSTKEY = CUSTOMER.C_CUSTKEY +GROUP BY CUSTOMER.C_NAME, + LINEORDER.LO_ORDERDATE diff --git a/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query16.sql b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query16.sql new file mode 100644 index 0000000000..1415b5025e --- /dev/null +++ b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query16.sql @@ -0,0 +1,33 @@ +-- +-- 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 DATES.D_DATEKEY, count(DATES.D_YEAR) count_year, DT.DATE_TIME +from (select '1995-03-29' as DATE_TIME + union + select '1995-04-01' as DATE_TIME + union all + select '1995-03-29' as DATE_TIME + union all + select '1995-04-01' as DATE_TIME + union all + select '1995-05-17' as DATE_TIME) DT + left join SSB.DATES on DT.DATE_TIME = DATES.D_DATEKEY +where DATES.D_MONTH = 'May' +group by dt.date_time, DATES.D_DATEKEY + diff --git a/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query17.sql b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query17.sql new file mode 100644 index 0000000000..7ca20a33a6 --- /dev/null +++ b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query17.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 CUSTOMER.C_NAME, + count(LINEORDER.LO_ORDERKEY) count_order, + LINEORDER.LO_ORDERDATE, + dt.DATE_TIME, + sum(CUSTOMER.C_CUSTKEY) sum_custkey +FROM "SSB"."LINEORDER" as "LINEORDER" + INNER JOIN "SSB"."CUSTOMER" as "CUSTOMER" + on "LINEORDER"."LO_CUSTKEY" = "CUSTOMER"."C_CUSTKEY" + inner join (select '1996-01-02' as DATE_TIME) dt + on LINEORDER.LO_ORDERDATE = dt.DATE_TIME +group by CUSTOMER.C_NAME, LINEORDER.LO_ORDERDATE, dt.DATE_TIME + diff --git a/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query18.sql b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query18.sql new file mode 100644 index 0000000000..fc433c7e4b --- /dev/null +++ b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query18.sql @@ -0,0 +1,65 @@ +-- +-- 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 li.C_NAME, + count(li.LO_ORDERKEY) count_order, + li.LO_ORDERDATE, + dt1.DATE_TIME, + li.DATE_TIME, + sum(li.C_CUSTKEY) sum_custkey +FROM (SELECT '1996-01-02' AS DATE_TIME) dt1 + LEFT JOIN + (SELECT third.LO_ORDERDATE, + third.LO_ORDERKEY, + third.C_NAME, + third.C_CUSTKEY, + third.DATE_TIME + FROM (SELECT dt2.LO_ORDERDATE, + dt2.LO_ORDERKEY, + dt2.C_NAME, + dt2.C_CUSTKEY, + dt4.DATE_TIME + FROM (SELECT LINEORDER.LO_ORDERDATE, + LINEORDER.LO_ORDERKEY, + CUSTOMER.C_NAME, + CUSTOMER.C_CUSTKEY, + dt.DATE_TIME + FROM "SSB"."LINEORDER" AS "LINEORDER" + INNER JOIN "SSB"."CUSTOMER" AS "CUSTOMER" + ON "LINEORDER"."LO_CUSTKEY" = "CUSTOMER"."C_CUSTKEY" + INNER JOIN + (SELECT '1995-03-29' AS DATE_TIME + UNION + SELECT '1995-04-01' AS DATE_TIME + UNION ALL + SELECT '1995-03-29' AS DATE_TIME + UNION ALL + SELECT '1995-04-01' AS DATE_TIME + UNION ALL + SELECT '1996-01-02' AS DATE_TIME + UNION + SELECT CASE WHEN 1 = 1 THEN '1995-06-01' ELSE '1995-07-01' END AS DATE_TIME) dt + ON LINEORDER.LO_ORDERDATE = dt.DATE_TIME) dt2 + INNER JOIN + (SELECT '1996-01-02' AS DATE_TIME) dt4 ON dt2.LO_ORDERDATE = dt4.DATE_TIME) third) li + ON dt1.DATE_TIME = li.LO_ORDERDATE +GROUP BY li.C_NAME, + li.LO_ORDERDATE, + dt1.DATE_TIME, + li.DATE_TIME \ No newline at end of file diff --git a/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query19.sql b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query19.sql new file mode 100644 index 0000000000..fe4e25e39c --- /dev/null +++ b/src/kylin-it/src/test/resources/query/sql_scalar_subquery/query19.sql @@ -0,0 +1,26 @@ +-- +-- 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. +-- + +-- SQL not supported when there was RexCall in AggregateCall arguments. +select sum(LINEORDER.LO_EXTENDEDPRICE * 3), + LINEORDER.LO_ORDERDATE, + dt.DATE_TIME +from SSB.P_LINEORDER as LINEORDER + inner join (select 19931014 as DATE_TIME) dt + on LINEORDER.LO_ORDERDATE = dt.DATE_TIME +group by LO_ORDERDATE, dt.DATE_TIME \ No newline at end of file diff --git a/src/query-common/src/main/java/org/apache/kylin/query/relnode/KapValuesRel.java b/src/query-common/src/main/java/org/apache/kylin/query/relnode/KapValuesRel.java index 352c108961..cf8188d0ed 100644 --- a/src/query-common/src/main/java/org/apache/kylin/query/relnode/KapValuesRel.java +++ b/src/query-common/src/main/java/org/apache/kylin/query/relnode/KapValuesRel.java @@ -18,17 +18,15 @@ package org.apache.kylin.query.relnode; +import java.util.List; import java.util.Set; import org.apache.calcite.plan.RelOptCluster; import org.apache.calcite.plan.RelTraitSet; -import org.apache.calcite.rel.RelCollationTraitDef; -import org.apache.calcite.rel.RelDistributionTraitDef; -import org.apache.calcite.rel.metadata.RelMdCollation; -import org.apache.calcite.rel.metadata.RelMdDistribution; -import org.apache.calcite.rel.metadata.RelMetadataQuery; +import org.apache.calcite.rel.RelNode; import org.apache.calcite.rel.type.RelDataType; import org.apache.calcite.rex.RexLiteral; +import org.apache.kylin.guava30.shaded.common.base.Preconditions; import org.apache.kylin.guava30.shaded.common.collect.Sets; import org.apache.kylin.query.util.ICutContextStrategy; @@ -37,18 +35,15 @@ import com.google.common.collect.ImmutableList; public class KapValuesRel extends OLAPValuesRel implements KapRel { private Set<OLAPContext> subContexts = Sets.newHashSet(); - private KapValuesRel(RelOptCluster cluster, RelDataType rowType, ImmutableList<ImmutableList<RexLiteral>> tuples, + public KapValuesRel(RelOptCluster cluster, RelDataType rowType, ImmutableList<ImmutableList<RexLiteral>> tuples, RelTraitSet traitSet) { super(cluster, rowType, tuples, traitSet); } - public static KapValuesRel create(RelOptCluster cluster, final RelDataType rowType, - final ImmutableList<ImmutableList<RexLiteral>> tuples) { - final RelMetadataQuery mq = cluster.getMetadataQuery(); - final RelTraitSet traitSet = cluster.traitSetOf(OLAPRel.CONVENTION) - .replaceIfs(RelCollationTraitDef.INSTANCE, () -> RelMdCollation.values(mq, rowType, tuples)) - .replaceIf(RelDistributionTraitDef.INSTANCE, () -> RelMdDistribution.values(rowType, tuples)); - return new KapValuesRel(cluster, rowType, tuples, traitSet); + @Override + public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) { + Preconditions.checkArgument(inputs.isEmpty()); + return new KapValuesRel(getCluster(), rowType, tuples, replaceTraitSet(getCluster(), rowType, tuples)); } @Override diff --git a/src/query-common/src/main/java/org/apache/kylin/query/relnode/OLAPValuesRel.java b/src/query-common/src/main/java/org/apache/kylin/query/relnode/OLAPValuesRel.java index 098e7712f8..55992e448f 100644 --- a/src/query-common/src/main/java/org/apache/kylin/query/relnode/OLAPValuesRel.java +++ b/src/query-common/src/main/java/org/apache/kylin/query/relnode/OLAPValuesRel.java @@ -38,6 +38,7 @@ import org.apache.calcite.rel.metadata.RelMetadataQuery; import org.apache.calcite.rel.type.RelDataType; import org.apache.calcite.rel.type.RelDataTypeField; import org.apache.calcite.rex.RexLiteral; +import org.apache.kylin.guava30.shaded.common.base.Preconditions; import org.apache.kylin.guava30.shaded.common.collect.Lists; import org.apache.kylin.metadata.model.TblColRef; @@ -69,8 +70,8 @@ public class OLAPValuesRel extends Values implements OLAPRel { @Override public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) { - assert inputs.isEmpty(); - return create(getCluster(), rowType, tuples); + Preconditions.checkArgument(inputs.isEmpty()); + return new OLAPValuesRel(getCluster(), rowType, tuples, replaceTraitSet(getCluster(), rowType, tuples)); } @Override @@ -119,4 +120,12 @@ public class OLAPValuesRel extends Values implements OLAPRel { public EnumerableRel implementEnumerable(List<EnumerableRel> inputs) { return EnumerableValues.create(getCluster(), getRowType(), getTuples()); } + + public static RelTraitSet replaceTraitSet(RelOptCluster cluster, RelDataType rowType, // + ImmutableList<ImmutableList<RexLiteral>> tuples) { + final RelMetadataQuery mq = cluster.getMetadataQuery(); + return cluster.traitSetOf(OLAPRel.CONVENTION) + .replaceIfs(RelCollationTraitDef.INSTANCE, () -> RelMdCollation.values(mq, rowType, tuples)) + .replaceIf(RelDistributionTraitDef.INSTANCE, () -> RelMdDistribution.values(rowType, tuples)); + } } diff --git a/src/query/src/main/java/io/kyligence/kap/query/optrule/KAPValuesRule.java b/src/query/src/main/java/io/kyligence/kap/query/optrule/KAPValuesRule.java index f9db2c1ba9..de867da672 100644 --- a/src/query/src/main/java/io/kyligence/kap/query/optrule/KAPValuesRule.java +++ b/src/query/src/main/java/io/kyligence/kap/query/optrule/KAPValuesRule.java @@ -18,11 +18,15 @@ package io.kyligence.kap.query.optrule; import org.apache.calcite.plan.Convention; +import org.apache.calcite.plan.RelOptCluster; +import org.apache.calcite.plan.RelTraitSet; import org.apache.calcite.rel.RelNode; import org.apache.calcite.rel.convert.ConverterRule; import org.apache.calcite.rel.core.Values; -import org.apache.kylin.query.relnode.OLAPRel; +import org.apache.calcite.rel.type.RelDataType; import org.apache.kylin.query.relnode.KapValuesRel; +import org.apache.kylin.query.relnode.OLAPRel; +import org.apache.kylin.query.relnode.OLAPValuesRel; public class KAPValuesRule extends ConverterRule { public static final KAPValuesRule INSTANCE = new KAPValuesRule(); @@ -34,6 +38,9 @@ public class KAPValuesRule extends ConverterRule { @Override public RelNode convert(RelNode rel) { Values values = (Values) rel; - return KapValuesRel.create(values.getCluster(), values.getRowType(), values.getTuples()); + RelOptCluster cluster = values.getCluster(); + RelDataType rowType = values.getRowType(); + RelTraitSet relTraits = OLAPValuesRel.replaceTraitSet(cluster, rowType, values.getTuples()); + return new KapValuesRel(cluster, rowType, values.getTuples(), relTraits); } } diff --git a/src/query/src/main/java/io/kyligence/kap/query/optrule/ScalarSubqueryJoinRule.java b/src/query/src/main/java/io/kyligence/kap/query/optrule/ScalarSubqueryJoinRule.java new file mode 100644 index 0000000000..e4b335334d --- /dev/null +++ b/src/query/src/main/java/io/kyligence/kap/query/optrule/ScalarSubqueryJoinRule.java @@ -0,0 +1,799 @@ +/* + * 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. + */ + +package io.kyligence.kap.query.optrule; + +import java.math.BigDecimal; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import org.apache.calcite.linq4j.Ord; +import org.apache.calcite.plan.RelOptRule; +import org.apache.calcite.plan.RelOptRuleCall; +import org.apache.calcite.plan.RelOptRuleOperand; +import org.apache.calcite.plan.RelOptUtil; +import org.apache.calcite.plan.hep.HepRelVertex; +import org.apache.calcite.rel.RelNode; +import org.apache.calcite.rel.core.AggregateCall; +import org.apache.calcite.rel.core.Join; +import org.apache.calcite.rel.core.RelFactories; +import org.apache.calcite.rel.metadata.RelMetadataQuery; +import org.apache.calcite.rex.RexBuilder; +import org.apache.calcite.rex.RexCall; +import org.apache.calcite.rex.RexInputRef; +import org.apache.calcite.rex.RexNode; +import org.apache.calcite.rex.RexUtil; +import org.apache.calcite.sql.SqlAggFunction; +import org.apache.calcite.sql.SqlSplittableAggFunction; +import org.apache.calcite.sql.fun.SqlStdOperatorTable; +import org.apache.calcite.tools.RelBuilder; +import org.apache.calcite.tools.RelBuilderFactory; +import org.apache.calcite.util.ImmutableBitSet; +import org.apache.calcite.util.mapping.Mapping; +import org.apache.calcite.util.mapping.MappingType; +import org.apache.calcite.util.mapping.Mappings; +import org.apache.kylin.guava30.shaded.common.base.Preconditions; +import org.apache.kylin.guava30.shaded.common.collect.ImmutableList; +import org.apache.kylin.guava30.shaded.common.collect.Lists; +import org.apache.kylin.guava30.shaded.common.collect.Maps; +import org.apache.kylin.query.relnode.KapAggregateRel; +import org.apache.kylin.query.relnode.KapFilterRel; +import org.apache.kylin.query.relnode.KapJoinRel; +import org.apache.kylin.query.relnode.KapNonEquiJoinRel; +import org.apache.kylin.query.relnode.KapProjectRel; +import org.apache.kylin.query.relnode.KapValuesRel; + +public class ScalarSubqueryJoinRule extends RelOptRule { + + // JOIN_PREDICATE from guava's Predicate, + + public static final ScalarSubqueryJoinRule AGG_JOIN = new ScalarSubqueryJoinRule(// + operand(KapAggregateRel.class, // + operand(Join.class, // + null, j -> j instanceof KapJoinRel || j instanceof KapNonEquiJoinRel, any())), + RelFactories.LOGICAL_BUILDER, "ScalarSubqueryJoinRule:AGG_JOIN"); + + public static final ScalarSubqueryJoinRule AGG_PRJ_JOIN = new ScalarSubqueryJoinRule(// + operand(KapAggregateRel.class, // + operand(KapProjectRel.class, // + operand(Join.class, // + null, j -> j instanceof KapJoinRel || j instanceof KapNonEquiJoinRel, any()))), + RelFactories.LOGICAL_BUILDER, "ScalarSubqueryJoinRule:AGG_PRJ_JOIN"); + + public static final ScalarSubqueryJoinRule AGG_PRJ_FLT_JOIN = new ScalarSubqueryJoinRule(// + operand(KapAggregateRel.class, // + operand(KapProjectRel.class, // + operand(KapFilterRel.class, // + operand(Join.class, // + null, // + j -> j instanceof KapJoinRel || j instanceof KapNonEquiJoinRel, any())))), // + RelFactories.LOGICAL_BUILDER, "ScalarSubqueryJoinRule:AGG_PRJ_FLT_JOIN"); + + public ScalarSubqueryJoinRule(RelOptRuleOperand operand, RelBuilderFactory relBuilderFactory, String description) { + super(operand, relBuilderFactory, description); + } + + @Override + public boolean matches(RelOptRuleCall call) { + Join join = call.rel(call.rels.length - 1); + switch (join.getJoinType()) { + case INNER: + case LEFT: + break; + default: + return false; + } + + KapAggregateRel aggregate = call.rel(0); + if (!aggregate.isSimpleGroupType() || aggregate.getAggCallList().isEmpty()) { + return false; + } + + // If any aggregate functions do not support splitting, bail outer + // If any aggregate call has a filter or is distinct, bail out. + // To-do: Count-distinct is currently not supported, + // but this can be achieved in case of scalar-subquery with distinct values. + if (aggregate.getAggCallList().stream().anyMatch(a -> a.hasFilter() // + || a.isDistinct() // + || Objects.isNull(a.getAggregation().unwrap(SqlSplittableAggFunction.class)))) { + return false; + } + + return !(call.rel(1) instanceof KapProjectRel) || canApplyRule(call.rel(1)); + } + + @Override + public void onMatch(RelOptRuleCall call) { + Transposer transposer = new Transposer(call); + if (!transposer.canTranspose()) { + return; + } + + RelNode relNode = transposer.getTransposedRel(); + call.transformTo(relNode); + } + + private boolean canApplyRule(KapProjectRel project) { + if (project.getProjects().stream().anyMatch(RexCall.class::isInstance)) { + // to-do: maybe we should support this. + return false; + } + final ImmutableBitSet.Builder builder = ImmutableBitSet.builder(); + project.getProjects().forEach(p -> builder.addAll(RelOptUtil.InputFinder.bits(p))); + // Avoid re-entry of rule. + return project.getProjects().size() <= builder.build().cardinality(); + } + + private <E> SqlSplittableAggFunction.Registry<E> createRegistry(final List<E> list) { + return e -> { + int i = list.indexOf(e); + if (i < 0) { + i = list.size(); + list.add(e); + } + return i; + }; + } + + private class Transposer { + // base variables + private final RelOptRuleCall call; + private final AggregateUnit aggUnit; + private final Join join; + + // join sides + private final LeftSide left; + private final RightSide right; + + // maintainer + public Transposer(RelOptRuleCall ruleCall) { + // call -> "aggunit, join" + call = ruleCall; + aggUnit = createAggUnit(ruleCall); + join = ruleCall.rel(ruleCall.rels.length - 1); + + // join sides + RelMetadataQuery mq = call.getMetadataQuery(); + ImmutableBitSet joinCondSet = RelOptUtil.InputFinder.bits(join.getCondition()); + ImmutableBitSet aggUnitJoinSet = aggUnit.getUnitSet().union(joinCondSet); + left = new LeftSide(join.getLeft(), join.getInput(0), mq, aggUnitJoinSet); + right = new RightSide(left, join.getRight(), join.getInput(1), mq, aggUnitJoinSet); + } + + public boolean canTranspose() { + if (left.hasRelValues() && right.isAggregable()) { + return true; + } + + return right.hasRelValues() && left.isAggregable(); + } + + public RelNode getTransposedRel() { + // builders + final RelBuilder relBuilder = call.builder(); + final RexBuilder rexBuilder = aggUnit.getRexBuilder(); + + // below aggregate + left.modifyAggregate(aggUnit, relBuilder, rexBuilder); + right.modifyAggregate(aggUnit, relBuilder, rexBuilder); + + // aggunit-join mapping + final Mapping aggUnitJoinMapping = getAggUnitJoinMapping(); + + // create new join + final RexNode joinCond = RexUtil.apply(aggUnitJoinMapping, join.getCondition()); + relBuilder.push(left.getNewInput()).push(right.getNewInput()).join(join.getJoinType(), joinCond); + + if (aggUnit instanceof AggregateProjectFilter) { + // create new filter + // To-do: maybe we could also push down the relative filter. + final RexNode filterCond = RexUtil.apply(aggUnitJoinMapping, // + ((AggregateProjectFilter) aggUnit).getFilterCond()); + relBuilder.filter(filterCond); + } + + // agg-project mapping + final Mapping projectMapping = getProjectMapping(relBuilder, aggUnitJoinMapping); + + // aggregate above to sum up the sub-totals + final List<RexNode> projectList = // + Mappings.apply(projectMapping, // + Lists.newArrayList(rexBuilder.identityProjects(relBuilder.peek().getRowType()))); + + final List<AggregateCall> aggCallList = Lists.newArrayList(); + aggregateAbove(projectList, aggCallList, relBuilder, rexBuilder); + + // create new project + relBuilder.project(projectList); + + // above aggregate + // To-do: maybe we could convert aggregate into projects when inner-join. + final RelBuilder.GroupKey groupKey = // + relBuilder.groupKey(Mappings.apply(projectMapping, // + Mappings.apply(aggUnitJoinMapping, aggUnit.getGroupSet())), // + Mappings.apply2(projectMapping, // + Mappings.apply2(aggUnitJoinMapping, aggUnit.getGroupSets()))); + relBuilder.aggregate(groupKey, aggCallList); + + return relBuilder.build(); + } + + private Mapping getProjectMapping(final RelBuilder relBuilder, final Mapping aggMapping) { + final List<Integer> fieldList = // + IntStream.range(0, relBuilder.peek().getRowType().getFieldList().size()) // + .boxed().collect(Collectors.toList()); + final List<Integer> groupList = // + aggUnit.getGroupList().stream().map(aggMapping::getTarget).collect(Collectors.toList()); + + // [i0, i1, i2, i3, i4] -> [i1, i3, i0, i2, i4] + final Mapping projectMapping = // + Mappings.create(MappingType.BIJECTION, fieldList.size(), fieldList.size()); + + Ord.zip(fieldList).forEach(o -> projectMapping.set(o.i, o.e)); + Ord.zip(groupList).forEach(o -> projectMapping.set(o.e, o.i)); + + return projectMapping; + } + + private AggregateUnit createAggUnit(RelOptRuleCall call) { + if (call.rels.length > 3) { + return new AggregateProjectFilter(call.rel(0), call.rel(1), call.rel(2)); + } + if (call.rels.length > 2) { + return new AggregateProject(call.rel(0), call.rel(1)); + } + return new AggregateUnit(call.rel(0)); + } + + private void aggregateAbove(final List<RexNode> projectList, // + final List<AggregateCall> aggCallList, // + final RelBuilder relBuilder, // + final RexBuilder rexBuilder) { + final int newLeftWidth = left.getNewInputFieldCount(); + final int groupIndicatorCount = aggUnit.getGroupIndicatorCount(); + final SqlSplittableAggFunction.Registry<RexNode> projectRegistry = createRegistry(projectList); + Ord.zip(aggUnit.getAggCallList()).forEach(aggCallOrd -> { + // No need to care about args' mapping. + AggregateCall aggCall = aggCallOrd.e; + SqlAggFunction aggFunc = aggCall.getAggregation(); + SqlSplittableAggFunction splitAggFunc = Preconditions + .checkNotNull(aggFunc.unwrap(SqlSplittableAggFunction.class)); + Integer lst = left.getAggOrdinal(aggCallOrd.i); + Integer rst = right.getAggOrdinal(aggCallOrd.i); + final AggregateCall newAggCall = // + splitAggFunc.topSplit(rexBuilder, projectRegistry, groupIndicatorCount, // + relBuilder.peek().getRowType(), aggCall, // + Objects.isNull(lst) ? -1 : lst, // + Objects.isNull(rst) ? -1 : rst + newLeftWidth); + + if (aggCall.getAggregation() == SqlStdOperatorTable.COUNT // + && newAggCall.getAggregation() == SqlStdOperatorTable.SUM0) { + aboveCountSum0(rexBuilder, aggCall, newAggCall, projectList); + } + + aggCallList.add(newAggCall); + }); + } + + private void aboveCountSum0(final RexBuilder rexBuilder, // + AggregateCall aggCall, // + AggregateCall newAggCall, // + final List<RexNode> projectList) { + // COUNT(*), COUNT(1), COUNT(COL), COUNT(COL1, COL2, ...) + final boolean nullAsOne = aggCall.getArgList().isEmpty(); + newAggCall.getArgList().forEach(i -> { + // old project node + RexNode p = projectList.get(i); + // when-then-else + List<RexNode> wte = Lists.newLinkedList(); + wte.add(rexBuilder.makeCall(SqlStdOperatorTable.IS_NULL, p)); + if (nullAsOne) { + wte.add(rexBuilder.makeLiteral(BigDecimal.ONE, p.getType(), true)); + } else { + wte.add(rexBuilder.makeZeroLiteral(p.getType())); + } + + wte.add(p); + // new project node + RexNode np = rexBuilder.makeCall(p.getType(), SqlStdOperatorTable.CASE, wte); + projectList.set(i, np); + }); + } + + private Mapping getAggUnitJoinMapping() { + final Map<Integer, Integer> map = Maps.newHashMap(); + map.putAll(left.getAggUnitJoinMap()); + map.putAll(right.getAggUnitJoinMap()); + final int sourceCount = join.getRowType().getFieldCount(); + final int targetCount = left.getNewInputFieldCount() + right.getNewInputFieldCount(); + return (Mapping) Mappings.target(map::get, sourceCount, targetCount); + } + + } // end of Transposer + + private static class AggregateUnit { + // base variables + protected final KapAggregateRel aggregate; + + // immediate variables + private RexBuilder rexBuilder; + + public AggregateUnit(KapAggregateRel aggregate) { + this.aggregate = aggregate; + } + + public RexBuilder getRexBuilder() { + if (Objects.isNull(rexBuilder)) { + rexBuilder = aggregate.getCluster().getRexBuilder(); + } + return rexBuilder; + } + + public ImmutableBitSet getUnitSet() { + return getGroupSet(); + } + + public ImmutableBitSet getGroupSet() { + return aggregate.getGroupSet(); + } + + public ImmutableList<ImmutableBitSet> getGroupSets() { + return ImmutableList.<ImmutableBitSet> builder().addAll(aggregate.groupSets).build(); + } + + public int getGroupCount() { + return aggregate.getGroupCount(); + } + + public int getGroupIndicatorCount() { + return getGroupCount() + aggregate.getIndicatorCount(); + } + + public List<AggregateCall> getAggCallList() { + return aggregate.getAggCallList(); + } + + public List<Integer> getGroupList() { + return aggregate.getGroupSet().asList(); + } + + } // end of AggregateUnit + + private static class AggregateProject extends AggregateUnit { + // base variables + private final KapProjectRel project; + private final Mappings.TargetMapping targetMapping; + + // immediate variables + private ImmutableBitSet groupSet; + private ImmutableList<ImmutableBitSet> groupSets; + private List<AggregateCall> aggCallList; + + public AggregateProject(KapAggregateRel aggregate, KapProjectRel project) { + super(aggregate); + this.project = project; + this.targetMapping = createTargetMapping(); + } + + @Override + public ImmutableBitSet getGroupSet() { + if (Objects.isNull(groupSet)) { + groupSet = Mappings.apply((Mapping) targetMapping, aggregate.getGroupSet()); + } + return groupSet; + } + + @Override + public ImmutableList<ImmutableBitSet> getGroupSets() { + if (Objects.isNull(groupSets)) { + groupSets = ImmutableList.<ImmutableBitSet> builder() // + .addAll(Mappings.apply2((Mapping) targetMapping, aggregate.getGroupSets())) // + .build(); + } + return groupSets; + } + + @Override + public List<AggregateCall> getAggCallList() { + if (Objects.isNull(aggCallList)) { + aggCallList = aggregate.getAggCallList().stream() // + .map(a -> a.transform(targetMapping)) // + .collect(Collectors.collectingAndThen(Collectors.toList(), // + Collections::unmodifiableList)); + } + return aggCallList; + } + + @Override + public List<Integer> getGroupList() { + return super.getGroupList().stream().map(targetMapping::getTarget).collect(Collectors.toList()); + } + + private Mappings.TargetMapping createTargetMapping() { + if (Objects.isNull(project.getMapping())) { + return Mappings.createIdentity(project.getRowType().getFieldCount()); + } + return project.getMapping().inverse(); + } + + } // end of AggregateProject + + private static class AggregateProjectFilter extends AggregateProject { + + private final KapFilterRel filter; + + public AggregateProjectFilter(KapAggregateRel aggregate, KapProjectRel project, KapFilterRel filter) { + super(aggregate, project); + this.filter = filter; + } + + @Override + public ImmutableBitSet getUnitSet() { + ImmutableBitSet filterSet = RelOptUtil.InputFinder.bits(filter.getCondition()); + return getGroupSet().union(filterSet); + } + + public RexNode getFilterCond() { + return filter.getCondition(); + } + + } // end of AggregateProjectFilter + + private abstract class JoinSide { + // base variables + private final boolean isRelValues; + private final boolean hasRelValues; + private final RelNode input; + private final ImmutableBitSet aggUnitJoinSet; + + // util variables + protected ImmutableBitSet fieldSet; + protected ImmutableBitSet sideAggUnitJoinSet; + protected ImmutableBitSet belowAggGroupSet; + + // immediate variables + private Map<Integer, Integer> aggOrdinalMap; + private List<AggregateCall> belowAggCallList; + private SqlSplittableAggFunction.Registry<AggregateCall> belowAggCallRegistry; + + private RelNode newInput; + + private Map<Integer, Integer> aggUnitJoinMap; + + public JoinSide(RelNode relNode, RelNode input, ImmutableBitSet aggUnitJoinSet) { + this.isRelValues = isRelValues(relNode); + this.hasRelValues = hasRelValues(relNode); + this.input = input; + this.aggUnitJoinSet = aggUnitJoinSet; + } + + public boolean hasRelValues() { + return hasRelValues; + } + + public boolean isRelValues() { + return isRelValues; + } + + public abstract boolean isAggregable(); + + public RelNode getNewInput() { + return newInput; + } + + public Integer getAggOrdinal(int i) { + return getAggOrdinalMap().get(i); + } + + public Map<Integer, Integer> getAggUnitJoinMap() { + if (Objects.isNull(aggUnitJoinMap)) { + final int belowOffset = getBelowOffset(); + final Map<Integer, Integer> map = Maps.newHashMap(); + Ord.zip(getSideAggUnitJoinSet()).forEach(o -> map.put(o.e, belowOffset + o.i)); + aggUnitJoinMap = map; + } + return aggUnitJoinMap; + } + + public void modifyAggregate(AggregateUnit aggUnit, RelBuilder relBuilder, RexBuilder rexBuilder) { + if (isRelValues()) { + newInput = convertSingleton(aggUnit, relBuilder, rexBuilder); + return; + } + + if (isAggregable()) { + newInput = convertSplit(aggUnit, relBuilder, rexBuilder); + return; + } + + newInput = convertSingleton(aggUnit, relBuilder, rexBuilder); + } + + protected final boolean hasRelValues(RelNode node) { + if (node instanceof HepRelVertex) { + RelNode current = ((HepRelVertex) node).getCurrentRel(); + if (current instanceof Join) { + final Join join = (Join) current; + return isRelValues(join.getLeft()) || isRelValues(join.getRight()); + } + return isRelValues(node); + } + return false; + } + + protected final boolean isRelValues(RelNode node) { + if (node instanceof HepRelVertex) { + RelNode current = ((HepRelVertex) node).getCurrentRel(); + if (current instanceof KapValuesRel) { + return true; + } + + if (current.getInputs().isEmpty()) { + return false; + } + + return current.getInputs().stream().allMatch(this::isRelValues); + } + return false; + } + + protected final boolean isAggregable(RelNode input, RelMetadataQuery mq) { + // No need to do aggregation. There is nothing to be gained by this rule. + Boolean unique = mq.areColumnsUnique(input, getBelowAggGroupSet()); + return Objects.isNull(unique) || !unique; + } + + protected int getInputFieldCount() { + return input.getRowType().getFieldCount(); + } + + protected int getNewInputFieldCount() { + return Preconditions.checkNotNull(newInput).getRowType().getFieldCount(); + } + + protected abstract int getOffset(); + + protected abstract int getBelowOffset(); + + protected abstract Mappings.TargetMapping getTargetMapping(); + + private Map<Integer, Integer> getAggOrdinalMap() { + if (Objects.isNull(aggOrdinalMap)) { + aggOrdinalMap = Maps.newHashMap(); + } + return aggOrdinalMap; + } + + private void registryAggCall(int i, int offset, AggregateCall aggCall) { + getAggOrdinalMap().put(i, offset + registry(aggCall)); + } + + private void registryOther(int i, int ordinal) { + getAggOrdinalMap().put(i, ordinal); + } + + private ImmutableBitSet getFieldSet() { + if (Objects.isNull(fieldSet)) { + int offset = getOffset(); + fieldSet = ImmutableBitSet.range(offset, offset + getInputFieldCount()); + } + return fieldSet; + } + + private ImmutableBitSet getBelowAggGroupSet() { + if (Objects.isNull(belowAggGroupSet)) { + int offset = getOffset(); + belowAggGroupSet = getSideAggUnitJoinSet().shift(-offset); + } + return belowAggGroupSet; + } + + private ImmutableBitSet getSideAggUnitJoinSet() { + if (Objects.isNull(sideAggUnitJoinSet)) { + ImmutableBitSet fieldSet0 = getFieldSet(); + sideAggUnitJoinSet = Preconditions.checkNotNull(aggUnitJoinSet).intersect(fieldSet0); + } + return sideAggUnitJoinSet; + } + + private RelNode convertSplit(AggregateUnit aggUnit, RelBuilder relBuilder, RexBuilder rexBuilder) { + final ImmutableBitSet fields = getFieldSet(); + final int oldGroupSetCount = aggUnit.getGroupCount(); + final int newGroupSetCount = getBelowAggGroupSet().cardinality(); + Ord.zip(aggUnit.getAggCallList()).forEach(aggCallOrd -> { + AggregateCall aggCall = aggCallOrd.e; + SqlAggFunction aggFunc = aggCall.getAggregation(); + SqlSplittableAggFunction splitAggFunc = Preconditions + .checkNotNull(aggFunc.unwrap(SqlSplittableAggFunction.class)); + ImmutableBitSet aggArgSet = ImmutableBitSet.of(aggCall.getArgList()); + final AggregateCall newAggCall; + if (fields.contains(aggArgSet)) { + // convert split + AggregateCall splitAggCall = splitAggFunc.split(aggCall, getTargetMapping()); + newAggCall = splitAggCall.adaptTo(input, splitAggCall.getArgList(), splitAggCall.filterArg, // + oldGroupSetCount, newGroupSetCount); + } else { + newAggCall = splitOther(splitAggFunc, rexBuilder, aggCall, fields, aggArgSet); + } + + if (Objects.isNull(newAggCall)) { + return; + } + registryAggCall(aggCallOrd.i, newGroupSetCount, newAggCall); + }); + + return relBuilder.push(input) // + .aggregate(relBuilder.groupKey(belowAggGroupSet, null), // + Preconditions.checkNotNull(belowAggCallList)) // + .build(); + } + + private AggregateCall splitOther(SqlSplittableAggFunction splitAggFunc, // + RexBuilder rexBuilder, // + AggregateCall aggCall, // + ImmutableBitSet fields, // + ImmutableBitSet args) { + // Thinking...aggCall not transformed? + AggregateCall other = splitAggFunc.other(rexBuilder.getTypeFactory(), aggCall); + if (Objects.isNull(other)) { + return null; + } + + ImmutableBitSet newArgSet = Mappings.apply((Mapping) getTargetMapping(), args.intersect(fields)); + return AggregateCall.create(other.getAggregation(), other.isDistinct(), // + other.isApproximate(), newArgSet.asList(), // + other.filterArg, other.getType(), other.getName()); + + } + + private RelNode convertSingleton(AggregateUnit aggUnit, RelBuilder relBuilder, RexBuilder rexBuilder) { + relBuilder.push(input); + final ImmutableBitSet fieldSet0 = getFieldSet(); + final List<RexNode> projectList = Lists.newArrayList(); + getBelowAggGroupSet().forEach(i -> projectList.add(relBuilder.field(i))); + Ord.zip(aggUnit.getAggCallList()).forEach(aggCallOrd -> { + AggregateCall aggCall = aggCallOrd.e; + SqlAggFunction aggFunc = aggCall.getAggregation(); + SqlSplittableAggFunction splitAggFunc = Preconditions + .checkNotNull(aggFunc.unwrap(SqlSplittableAggFunction.class)); + if (aggCall.getArgList().isEmpty()) { + return; + } + ImmutableBitSet aggArgSet = ImmutableBitSet.of(aggCall.getArgList()); + if (!fieldSet0.contains(aggArgSet)) { + return; + } + + // convert singleton + RexNode singleton = splitAggFunc.singleton(rexBuilder, input.getRowType(), // + aggCall.transform(getTargetMapping())); + if (singleton instanceof RexInputRef) { + registryOther(aggCallOrd.i, ((RexInputRef) singleton).getIndex()); + return; + } + int ordinal = projectList.size(); + projectList.add(singleton); + registryOther(aggCallOrd.i, ordinal); + }); + + relBuilder.project(projectList); + + return relBuilder.build(); + } + + private int registry(AggregateCall aggCall) { + if (Objects.isNull(belowAggCallRegistry)) { + if (Objects.isNull(belowAggCallList)) { + belowAggCallList = Lists.newArrayList(); + } + belowAggCallRegistry = createRegistry(belowAggCallList); + } + return belowAggCallRegistry.register(aggCall); + } + + } // end of side + + private class LeftSide extends JoinSide { + + private final boolean isAggregable; + + private final Mappings.TargetMapping targetMapping; + + public LeftSide(RelNode relNode, RelNode input, RelMetadataQuery mq, ImmutableBitSet aggUnitJoinSet) { + super(relNode, input, aggUnitJoinSet); + this.isAggregable = isAggregable(input, mq); + this.targetMapping = createTargetMapping(); + } + + @Override + public boolean isAggregable() { + return isAggregable; + } + + @Override + protected int getOffset() { + return 0; + } + + @Override + protected int getBelowOffset() { + return 0; + } + + @Override + protected Mappings.TargetMapping getTargetMapping() { + return targetMapping; + } + + private Mappings.TargetMapping createTargetMapping() { + int fieldCount = getInputFieldCount(); + return Mappings.createIdentity(fieldCount); + } + + } // end of LeftSide + + private class RightSide extends JoinSide { + + private final LeftSide left; + + private final boolean isAggregable; + + private final Mappings.TargetMapping targetMapping; + + public RightSide(LeftSide left, // + RelNode relNode, RelNode input, // + RelMetadataQuery mq, ImmutableBitSet aggUnitJoinSet) { + super(relNode, input, aggUnitJoinSet); + this.left = left; + this.isAggregable = isAggregable(input, mq); + this.targetMapping = createTargetMapping(); + } + + @Override + public boolean isAggregable() { + return isAggregable; + } + + @Override + protected int getOffset() { + return left.getInputFieldCount(); + } + + @Override + protected int getBelowOffset() { + return left.getNewInputFieldCount(); + } + + @Override + protected Mappings.TargetMapping getTargetMapping() { + return targetMapping; + } + + private Mappings.TargetMapping createTargetMapping() { + int offset = getOffset(); + int fieldCount = getInputFieldCount(); + return Mappings.createShiftMapping(fieldCount + offset, 0, offset, fieldCount); + } + + } // end of RightSide + +} diff --git a/src/query/src/main/java/org/apache/kylin/query/engine/QueryExec.java b/src/query/src/main/java/org/apache/kylin/query/engine/QueryExec.java index 51e4e4261d..dc0572b6f8 100644 --- a/src/query/src/main/java/org/apache/kylin/query/engine/QueryExec.java +++ b/src/query/src/main/java/org/apache/kylin/query/engine/QueryExec.java @@ -267,6 +267,10 @@ public class QueryExec { postOptRules.addAll(HepUtils.AggPushDownRules); } + if(kylinConfig.isScalarSubqueryJoinEnabled()) { + postOptRules.addAll(HepUtils.ScalarSubqueryJoinRules); + } + if (kylinConfig.isOptimizedSumCastDoubleRuleEnabled()) { postOptRules.addAll(HepUtils.SumCastDoubleRules); } diff --git a/src/query/src/main/java/org/apache/kylin/query/util/HepUtils.java b/src/query/src/main/java/org/apache/kylin/query/util/HepUtils.java index bea632f49f..92be45067d 100644 --- a/src/query/src/main/java/org/apache/kylin/query/util/HepUtils.java +++ b/src/query/src/main/java/org/apache/kylin/query/util/HepUtils.java @@ -25,11 +25,13 @@ import org.apache.calcite.plan.RelOptRule; import org.apache.calcite.plan.hep.HepPlanner; import org.apache.calcite.plan.hep.HepProgram; import org.apache.calcite.rel.RelNode; +import org.apache.calcite.rel.rules.AggregateProjectMergeRule; import org.apache.calcite.rel.rules.FilterMergeRule; +import org.apache.calcite.rel.rules.ProjectMergeRule; import org.apache.calcite.rel.rules.ProjectRemoveRule; - import org.apache.kylin.guava30.shaded.common.collect.ImmutableList; +import io.kyligence.kap.query.optrule.AggregateProjectReduceRule; import io.kyligence.kap.query.optrule.CountDistinctCaseWhenFunctionRule; import io.kyligence.kap.query.optrule.FilterJoinConditionMergeRule; import io.kyligence.kap.query.optrule.FilterSimplifyRule; @@ -49,6 +51,7 @@ import io.kyligence.kap.query.optrule.KapProjectMergeRule; import io.kyligence.kap.query.optrule.KapProjectRule; import io.kyligence.kap.query.optrule.KapSumCastTransposeRule; import io.kyligence.kap.query.optrule.KapSumTransCastToThenRule; +import io.kyligence.kap.query.optrule.ScalarSubqueryJoinRule; import io.kyligence.kap.query.optrule.SumBasicOperatorRule; import io.kyligence.kap.query.optrule.SumCaseWhenFunctionRule; import io.kyligence.kap.query.optrule.SumConstantConvertRule; @@ -97,6 +100,21 @@ public class HepUtils { KapJoinRule.INSTANCE ); + public static final ImmutableList<RelOptRule> ScalarSubqueryJoinRules = ImmutableList.of( + // base rules + KapAggregateRule.INSTANCE, // + KapProjectRule.INSTANCE, // + KapJoinRule.INSTANCE, // + // relative rules + ProjectMergeRule.INSTANCE, // + AggregateProjectMergeRule.INSTANCE, // + AggregateProjectReduceRule.INSTANCE, // + // target rules + ScalarSubqueryJoinRule.AGG_JOIN, // + ScalarSubqueryJoinRule.AGG_PRJ_JOIN, // + ScalarSubqueryJoinRule.AGG_PRJ_FLT_JOIN + ); + public static final ImmutableList<RelOptRule> CountDistinctExprRules = ImmutableList.of( CountDistinctCaseWhenFunctionRule.INSTANCE, KapProjectRule.INSTANCE,