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

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


The following commit(s) were added to refs/heads/kylin5 by this push:
     new 4a6e1893f5 KYLIN-6034 fix columns of OlapContext when top node is 
OlapWindowRel
4a6e1893f5 is described below

commit 4a6e1893f5fc0dd9b332e63be268e32587ae1c99
Author: Xuecheng Shan <[email protected]>
AuthorDate: Tue Jul 9 11:12:57 2024 +0800

    KYLIN-6034 fix columns of OlapContext when top node is OlapWindowRel
    
    Co-authored-by: Xuecheng Shan <[email protected]>
---
 .../query/engine/WindowFunctionPlannerTest.java    | 162 +++++++++++++++++++++
 .../query/sql_window_olap_context/query00.sql      |  20 +++
 .../query/sql_window_olap_context/query01.sql      |  21 +++
 .../query/sql_window_olap_context/query02.sql      |  20 +++
 .../query/sql_window_olap_context/query03.sql      |  20 +++
 .../query/sql_window_olap_context/query04.sql      |  21 +++
 .../query/sql_window_olap_context/query05.sql      |  28 ++++
 .../apache/kylin/query/relnode/ContextUtil.java    |   6 +-
 .../apache/kylin/query/relnode/OlapWindowRel.java  |  26 +++-
 9 files changed, 322 insertions(+), 2 deletions(-)

diff --git 
a/src/kylin-it/src/test/java/org/apache/kylin/query/engine/WindowFunctionPlannerTest.java
 
b/src/kylin-it/src/test/java/org/apache/kylin/query/engine/WindowFunctionPlannerTest.java
new file mode 100644
index 0000000000..1f8244f01c
--- /dev/null
+++ 
b/src/kylin-it/src/test/java/org/apache/kylin/query/engine/WindowFunctionPlannerTest.java
@@ -0,0 +1,162 @@
+/*
+ * 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.engine;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.sql.parser.SqlParseException;
+import org.apache.kylin.common.QueryContext;
+import org.apache.kylin.common.util.Pair;
+import org.apache.kylin.guava30.shaded.common.collect.Sets;
+import org.apache.kylin.metadata.model.TblColRef;
+import org.apache.kylin.metadata.realization.NoRealizationFoundException;
+import org.apache.kylin.query.relnode.ContextUtil;
+import org.apache.kylin.query.relnode.OlapContext;
+import org.apache.kylin.query.relnode.OlapLimitRel;
+import org.apache.kylin.query.relnode.OlapWindowRel;
+import org.apache.kylin.query.rules.CalciteRuleTestBase;
+import org.apache.kylin.query.util.QueryContextCutter;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class WindowFunctionPlannerTest extends CalciteRuleTestBase {
+
+    String project = "default";
+
+    QueryExec queryExec;
+
+    @Before
+    public void setup() {
+        createTestMetadata();
+        queryExec = new QueryExec(project, getTestConfig());
+    }
+
+    private void prepareOlapContext(String sql) throws SqlParseException {
+        RelNode relNode = queryExec.parseAndOptimize(sql);
+        List<RelNode> optimizedRelNodes = queryExec.postOptimize(relNode);
+
+        try {
+            QueryContextCutter.selectRealization(project, 
optimizedRelNodes.get(0),
+                    QueryContext.current().isForModeling());
+        } catch (NoRealizationFoundException e) {
+            log.info("No realization found for sql: {}", sql);
+        }
+    }
+
+    private String getSql(String fileName) throws IOException {
+        Pair<String, String> sql = readOneSQL(getTestConfig(), project, 
"query/sql_window_olap_context", fileName);
+        return sql.getSecond();
+    }
+
+    @Test
+    public void testSelectStarAndWindow() throws SqlParseException, 
IOException {
+        prepareOlapContext(getSql("query00.sql"));
+
+        Assert.assertEquals(1, ContextUtil.listContexts().size());
+        OlapContext olapContext = ContextUtil.listContexts().get(0);
+        Assert.assertEquals(17, olapContext.getAllColumns().size());
+        Assert.assertTrue(olapContext.getTopNode() instanceof OlapWindowRel);
+    }
+
+    @Test
+    public void testSelectStarAndWindowWithLimit() throws SqlParseException, 
IOException {
+        prepareOlapContext(getSql("query01.sql"));
+
+        Assert.assertEquals(1, ContextUtil.listContexts().size());
+        OlapContext olapContext = ContextUtil.listContexts().get(0);
+        Assert.assertEquals(17, olapContext.getAllColumns().size());
+        Assert.assertTrue(olapContext.getTopNode() instanceof OlapLimitRel);
+    }
+
+    @Test
+    public void testSelectOnlyWindow() throws IOException, SqlParseException {
+        prepareOlapContext(getSql("query02.sql"));
+
+        Assert.assertEquals(1, ContextUtil.listContexts().size());
+        OlapContext olapContext = ContextUtil.listContexts().get(0);
+        Set<TblColRef> allColumns = olapContext.getAllColumns();
+        Assert.assertEquals(2, allColumns.size());
+        Set<String> expectedColumns = 
Sets.newHashSet("SSB.LINEORDER.LO_ORDERDATE", "SSB.LINEORDER.LO_QUANTITY");
+        allColumns.forEach(tblColRef -> expectedColumns
+                .remove(tblColRef.getTableRef().getTableIdentity() + '.' + 
tblColRef.getColumnDesc().getName()));
+        Assert.assertTrue(expectedColumns.isEmpty());
+    }
+
+    @Test
+    public void testSelectWindowAndSpecifiedColumn() throws IOException, 
SqlParseException {
+        prepareOlapContext(getSql("query03.sql"));
+
+        Assert.assertEquals(1, ContextUtil.listContexts().size());
+        OlapContext olapContext = ContextUtil.listContexts().get(0);
+        Set<TblColRef> allColumns = olapContext.getAllColumns();
+        Assert.assertEquals(3, allColumns.size());
+        Set<String> expectedColumns = 
Sets.newHashSet("SSB.LINEORDER.LO_ORDERDATE", "SSB.LINEORDER.LO_QUANTITY",
+                "SSB.LINEORDER.LO_CUSTKEY");
+        allColumns.forEach(tblColRef -> expectedColumns
+                .remove(tblColRef.getTableRef().getTableIdentity() + '.' + 
tblColRef.getColumnDesc().getName()));
+        Assert.assertTrue(expectedColumns.isEmpty());
+    }
+
+    @Test
+    public void testSelectWindowAndFilter() throws IOException, 
SqlParseException {
+        prepareOlapContext(getSql("query04.sql"));
+
+        Assert.assertEquals(1, ContextUtil.listContexts().size());
+        OlapContext olapContext = ContextUtil.listContexts().get(0);
+        Set<TblColRef> allColumns = olapContext.getAllColumns();
+        Assert.assertEquals(4, allColumns.size());
+        Set<String> expectedColumns = 
Sets.newHashSet("SSB.LINEORDER.LO_ORDERDATE", "SSB.LINEORDER.LO_QUANTITY",
+                "SSB.LINEORDER.LO_CUSTKEY", "SSB.LINEORDER.LO_PARTKEY");
+        allColumns.forEach(tblColRef -> expectedColumns
+                .remove(tblColRef.getTableRef().getTableIdentity() + '.' + 
tblColRef.getColumnDesc().getName()));
+        Assert.assertTrue(expectedColumns.isEmpty());
+    }
+
+    @Test
+    public void testSubQueryWithWidow() throws IOException, SqlParseException {
+        prepareOlapContext(getSql("query05.sql"));
+
+        Assert.assertEquals(2, ContextUtil.listContexts().size());
+
+        OlapContext olapContext1 = ContextUtil.listContexts().get(0);
+        Set<TblColRef> allColumns1 = olapContext1.getAllColumns();
+        Assert.assertEquals(4, allColumns1.size());
+        Set<String> expectedColumns1 = 
Sets.newHashSet("SSB.LINEORDER.LO_ORDERDATE", "SSB.LINEORDER.LO_QUANTITY",
+                "SSB.LINEORDER.LO_ORDERKEY", "SSB.LINEORDER.LO_PARTKEY");
+        allColumns1.forEach(tblColRef -> expectedColumns1
+                .remove(tblColRef.getTableRef().getTableIdentity() + '.' + 
tblColRef.getColumnDesc().getName()));
+        Assert.assertTrue(expectedColumns1.isEmpty());
+
+        OlapContext olapContext2 = ContextUtil.listContexts().get(1);
+        Set<TblColRef> allColumns2 = olapContext2.getAllColumns();
+        Assert.assertEquals(5, allColumns2.size());
+        Set<String> expectedColumns2 = 
Sets.newHashSet("SSB.LINEORDER.LO_ORDERDATE", "SSB.LINEORDER.LO_QUANTITY",
+                "SSB.LINEORDER.LO_ORDERKEY", "SSB.LINEORDER.LO_PARTKEY", 
"SSB.LINEORDER.LO_CUSTKEY");
+        allColumns2.forEach(tblColRef -> expectedColumns2
+                .remove(tblColRef.getTableRef().getTableIdentity() + '.' + 
tblColRef.getColumnDesc().getName()));
+        Assert.assertTrue(expectedColumns2.isEmpty());
+    }
+}
diff --git 
a/src/kylin-it/src/test/resources/query/sql_window_olap_context/query00.sql 
b/src/kylin-it/src/test/resources/query/sql_window_olap_context/query00.sql
new file mode 100644
index 0000000000..c00f0ab8eb
--- /dev/null
+++ b/src/kylin-it/src/test/resources/query/sql_window_olap_context/query00.sql
@@ -0,0 +1,20 @@
+--
+-- 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 *, ROW_NUMBER() OVER (PARTITION BY LO_ORDERDATE ORDER BY LO_QUANTITY) 
AS RN
+FROM SSB.LINEORDER
\ No newline at end of file
diff --git 
a/src/kylin-it/src/test/resources/query/sql_window_olap_context/query01.sql 
b/src/kylin-it/src/test/resources/query/sql_window_olap_context/query01.sql
new file mode 100644
index 0000000000..f248deb293
--- /dev/null
+++ b/src/kylin-it/src/test/resources/query/sql_window_olap_context/query01.sql
@@ -0,0 +1,21 @@
+--
+-- 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 *, ROW_NUMBER() OVER (PARTITION BY LO_ORDERDATE ORDER BY LO_QUANTITY) 
AS RN
+FROM SSB.LINEORDER
+LIMIT 100
\ No newline at end of file
diff --git 
a/src/kylin-it/src/test/resources/query/sql_window_olap_context/query02.sql 
b/src/kylin-it/src/test/resources/query/sql_window_olap_context/query02.sql
new file mode 100644
index 0000000000..832667e729
--- /dev/null
+++ b/src/kylin-it/src/test/resources/query/sql_window_olap_context/query02.sql
@@ -0,0 +1,20 @@
+--
+-- 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 ROW_NUMBER() OVER (PARTITION BY LO_ORDERDATE ORDER BY LO_QUANTITY) AS RN
+FROM SSB.LINEORDER
\ No newline at end of file
diff --git 
a/src/kylin-it/src/test/resources/query/sql_window_olap_context/query03.sql 
b/src/kylin-it/src/test/resources/query/sql_window_olap_context/query03.sql
new file mode 100644
index 0000000000..3cdacbb2b4
--- /dev/null
+++ b/src/kylin-it/src/test/resources/query/sql_window_olap_context/query03.sql
@@ -0,0 +1,20 @@
+--
+-- 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 LO_ORDERDATE, LO_CUSTKEY, ROW_NUMBER() OVER (PARTITION BY LO_ORDERDATE 
ORDER BY LO_QUANTITY) AS RN
+FROM SSB.LINEORDER
\ No newline at end of file
diff --git 
a/src/kylin-it/src/test/resources/query/sql_window_olap_context/query04.sql 
b/src/kylin-it/src/test/resources/query/sql_window_olap_context/query04.sql
new file mode 100644
index 0000000000..d00a6c404b
--- /dev/null
+++ b/src/kylin-it/src/test/resources/query/sql_window_olap_context/query04.sql
@@ -0,0 +1,21 @@
+--
+-- 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 LO_ORDERDATE, LO_CUSTKEY, ROW_NUMBER() OVER (PARTITION BY LO_ORDERDATE 
ORDER BY LO_QUANTITY) AS RN
+FROM SSB.LINEORDER
+WHERE LO_PARTKEY < 1000
\ No newline at end of file
diff --git 
a/src/kylin-it/src/test/resources/query/sql_window_olap_context/query05.sql 
b/src/kylin-it/src/test/resources/query/sql_window_olap_context/query05.sql
new file mode 100644
index 0000000000..7872fce655
--- /dev/null
+++ b/src/kylin-it/src/test/resources/query/sql_window_olap_context/query05.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 t1.LO_ORDERDATE, t1.LO_ORDERKEY, t2.LO_CUSTKEY, t1.RN_1, t2.RN_2
+from
+(SELECT *, ROW_NUMBER() OVER (PARTITION BY LO_ORDERDATE ORDER BY LO_QUANTITY) 
AS RN_1
+ FROM SSB.LINEORDER
+where LO_PARTKEY<1000) t1
+left join
+(SELECT *, ROW_NUMBER() OVER (PARTITION BY LO_ORDERDATE ORDER BY LO_QUANTITY) 
AS RN_2
+ FROM SSB.LINEORDER
+where LO_PARTKEY>2000) t2
+on t1.LO_ORDERKEY=t2.LO_ORDERKEY
\ No newline at end of file
diff --git 
a/src/query-common/src/main/java/org/apache/kylin/query/relnode/ContextUtil.java
 
b/src/query-common/src/main/java/org/apache/kylin/query/relnode/ContextUtil.java
index 661a30cb8f..6d819573e4 100644
--- 
a/src/query-common/src/main/java/org/apache/kylin/query/relnode/ContextUtil.java
+++ 
b/src/query-common/src/main/java/org/apache/kylin/query/relnode/ContextUtil.java
@@ -105,8 +105,12 @@ public class ContextUtil {
             ((OlapRel) 
rel).getColumnRowType().getAllColumns().stream().filter(context::isOriginAndBelongToCtxTables)
                     .forEach(context.getAllColumns()::add);
         } else if (rel instanceof OlapWindowRel) {
-            ((OlapWindowRel) 
rel).getGroupingColumns().stream().filter(context::isOriginAndBelongToCtxTables)
+            OlapWindowRel olapWindowRel = (OlapWindowRel) rel;
+            
olapWindowRel.getGroupingColumns().stream().filter(context::isOriginAndBelongToCtxTables)
                     .forEach(context.getAllColumns()::add);
+            if (!olapWindowRel.isExistParentProjectNeedPushInfo()) {
+                amendAllColsIfNoAgg(olapWindowRel.getInput());
+            }
         } else if (rel instanceof OlapJoinRel) {
             amendAllColsIfNoAgg(rel.getInput(0));
             amendAllColsIfNoAgg(rel.getInput(1));
diff --git 
a/src/query-common/src/main/java/org/apache/kylin/query/relnode/OlapWindowRel.java
 
b/src/query-common/src/main/java/org/apache/kylin/query/relnode/OlapWindowRel.java
index 6d7afe0e1f..48cd6d7fa2 100644
--- 
a/src/query-common/src/main/java/org/apache/kylin/query/relnode/OlapWindowRel.java
+++ 
b/src/query-common/src/main/java/org/apache/kylin/query/relnode/OlapWindowRel.java
@@ -20,6 +20,7 @@ package org.apache.kylin.query.relnode;
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Deque;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -55,6 +56,8 @@ public class OlapWindowRel extends Window implements OlapRel {
     @Setter
     private Set<OlapContext> subContexts = Sets.newHashSet();
 
+    private boolean existParentProjectNeedPushInfo;
+
     public OlapWindowRel(RelOptCluster cluster, RelTraitSet traitSet, RelNode 
input, List<RexLiteral> constants,
             RelDataType rowType, List<Window.Group> groups) {
         super(cluster, traitSet, input, constants, rowType, groups);
@@ -87,12 +90,33 @@ public class OlapWindowRel extends Window implements 
OlapRel {
         if (context != null) {
             this.context.setHasWindow(true);
             if (this == context.getTopNode() && !context.isHasAgg())
-                ContextUtil.amendAllColsIfNoAgg(this);
+                amendContextColumns(olapImpl);
         } else {
             ContextUtil.updateSubContexts(getGroupingColumns(), subContexts);
         }
     }
 
+    private void amendContextColumns(OlapImpl olapImpl) {
+        this.existParentProjectNeedPushInfo = 
checkParentProjectNeedPushInfo(olapImpl.getParentNodeStack());
+        ContextUtil.amendAllColsIfNoAgg(this);
+    }
+
+    public boolean checkParentProjectNeedPushInfo(Deque<RelNode> allParents) {
+        for (RelNode parent : allParents) {
+            if (parent instanceof OlapProjectRel) {
+                OlapProjectRel parentProject = (OlapProjectRel) parent;
+                if (parentProject.isNeedPushInfoToSubCtx()) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    public boolean isExistParentProjectNeedPushInfo() {
+        return existParentProjectNeedPushInfo;
+    }
+
     protected ColumnRowType buildColumnRowType() {
         OlapRel olapChild = (OlapRel) getInput(0);
         ColumnRowType inputColumnRowType = olapChild.getColumnRowType();

Reply via email to