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

gavinchou pushed a commit to branch branch-3.0
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-3.0 by this push:
     new 4d810394f9c [improvement](mtmv) Support to partition prune when query 
rewrite by sync materialized view (#38527)
4d810394f9c is described below

commit 4d810394f9cceb399c81050f25eedc9fde1386c6
Author: seawinde <149132972+seawi...@users.noreply.github.com>
AuthorDate: Tue Aug 6 10:25:43 2024 +0800

    [improvement](mtmv) Support to partition prune when query rewrite by sync 
materialized view (#38527)
    
    ## Proposed changes
    
    Support to partition prune when query rewrite by sync materialized view
    such as table def is as following:
    ```sql
            CREATE TABLE IF NOT EXISTS test_unique (
            `time` DATETIME NULL COMMENT '查询时间',
            `app_name` VARCHAR(64) NULL COMMENT '标识',
            `event_id` VARCHAR(128) NULL COMMENT '标识',
            `decision` VARCHAR(32) NULL COMMENT '枚举值',
            `id` VARCHAR(35) NOT NULL COMMENT 'od',
            `code` VARCHAR(64) NULL COMMENT '标识',
            `event_type` VARCHAR(32) NULL COMMENT '事件类型'
            )
            UNIQUE KEY(time)
            PARTITION BY RANGE(time)
            (
             FROM ("2024-07-01 00:00:00") TO ("2024-07-15 00:00:00") INTERVAL 1 
HOUR
            )
            DISTRIBUTED BY HASH(time)
            BUCKETS 3 PROPERTIES ("replication_num" = "1");
    ```
    sync materialized view def is
    
    ```sql
    create materialized view as
        select
        app_name,
        event_id,
        time,
        count(*)
        from
        test_duplicate
        group by
        app_name,
        event_id,
        time;
    ```
    
    if your query is following, if rewritten by sync materialized view
    successfully, should partition prune
    ```sql
        select
        app_name,
        event_id,
        time,
        count(*)
        from
        test_duplicate
        where time < '2024-07-05 01:00:00'
        group by
        app_name,
        time,
        event_id;
    
    ```
---
 .../mv/AbstractMaterializedViewRule.java           |   2 +-
 .../mv/AsyncMaterializationContext.java            |  13 +-
 .../exploration/mv/MaterializationContext.java     |   2 +-
 .../exploration/mv/MaterializedViewUtils.java      |  34 +--
 .../exploration/mv/SyncMaterializationContext.java |  25 +-
 .../doris/nereids/mv/IdStatisticsMapTest.java      |   3 +-
 .../data/mv_p0/partition_prune/partition_prune.out |  43 ++++
 .../suites/auth_p0/test_select_column_auth.groovy  |   4 +-
 .../mv_p0/partition_prune/partition_prune.groovy   | 257 +++++++++++++++++++++
 9 files changed, 346 insertions(+), 37 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/AbstractMaterializedViewRule.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/AbstractMaterializedViewRule.java
index f51f1098949..b34faaf1250 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/AbstractMaterializedViewRule.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/AbstractMaterializedViewRule.java
@@ -233,7 +233,7 @@ public abstract class AbstractMaterializedViewRule 
implements ExplorationRuleFac
                 continue;
             }
             Plan rewrittenPlan;
-            Plan mvScan = materializationContext.getScanPlan();
+            Plan mvScan = materializationContext.getScanPlan(queryStructInfo);
             Plan queryPlan = queryStructInfo.getTopPlan();
             if (compensatePredicates.isAlwaysTrue()) {
                 rewrittenPlan = mvScan;
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/AsyncMaterializationContext.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/AsyncMaterializationContext.java
index b555f71e04d..0d88672fed6 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/AsyncMaterializationContext.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/AsyncMaterializationContext.java
@@ -27,6 +27,7 @@ import org.apache.doris.nereids.CascadesContext;
 import org.apache.doris.nereids.rules.exploration.mv.mapping.ExpressionMapping;
 import org.apache.doris.nereids.trees.plans.ObjectId;
 import org.apache.doris.nereids.trees.plans.Plan;
+import org.apache.doris.nereids.trees.plans.PreAggStatus;
 import org.apache.doris.nereids.trees.plans.RelationId;
 import org.apache.doris.nereids.trees.plans.algebra.Relation;
 import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
@@ -56,7 +57,8 @@ public class AsyncMaterializationContext extends 
MaterializationContext {
      */
     public AsyncMaterializationContext(MTMV mtmv, Plan mvPlan, Plan 
mvOriginalPlan, List<Table> baseTables,
             List<Table> baseViews, CascadesContext cascadesContext, StructInfo 
structInfo) {
-        super(mvPlan, mvOriginalPlan, 
MaterializedViewUtils.generateMvScanPlan(mtmv, cascadesContext),
+        super(mvPlan, mvOriginalPlan, 
MaterializedViewUtils.generateMvScanPlan(mtmv, mtmv.getBaseIndexId(),
+                        mtmv.getPartitionIds(), PreAggStatus.on(), 
cascadesContext),
                 cascadesContext, structInfo);
         this.mtmv = mtmv;
     }
@@ -67,7 +69,8 @@ public class AsyncMaterializationContext extends 
MaterializationContext {
 
     @Override
     Plan doGenerateScanPlan(CascadesContext cascadesContext) {
-        return MaterializedViewUtils.generateMvScanPlan(this.mtmv, 
cascadesContext);
+        return MaterializedViewUtils.generateMvScanPlan(this.mtmv, 
this.mtmv.getBaseIndexId(),
+                this.mtmv.getPartitionIds(), PreAggStatus.on(), 
cascadesContext);
     }
 
     @Override
@@ -107,7 +110,8 @@ public class AsyncMaterializationContext extends 
MaterializationContext {
             return Optional.empty();
         }
         RelationId relationId = null;
-        Optional<LogicalOlapScan> logicalOlapScan = 
this.getScanPlan().collectFirst(LogicalOlapScan.class::isInstance);
+        Optional<LogicalOlapScan> logicalOlapScan = this.getScanPlan(null)
+                .collectFirst(LogicalOlapScan.class::isInstance);
         if (logicalOlapScan.isPresent()) {
             relationId = logicalOlapScan.get().getRelationId();
         }
@@ -127,7 +131,8 @@ public class AsyncMaterializationContext extends 
MaterializationContext {
         );
     }
 
-    public Plan getScanPlan() {
+    @Override
+    public Plan getScanPlan(StructInfo queryInfo) {
         return scanPlan;
     }
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/MaterializationContext.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/MaterializationContext.java
index 0f1768e29ce..bd1dcee1bbb 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/MaterializationContext.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/MaterializationContext.java
@@ -276,7 +276,7 @@ public abstract class MaterializationContext {
         return originalPlan;
     }
 
-    public Plan getScanPlan() {
+    public Plan getScanPlan(StructInfo queryStructInfo) {
         return scanPlan;
     }
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/MaterializedViewUtils.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/MaterializedViewUtils.java
index 835b01c00b2..b76a27e37bc 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/MaterializedViewUtils.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/MaterializedViewUtils.java
@@ -18,7 +18,6 @@
 package org.apache.doris.nereids.rules.exploration.mv;
 
 import org.apache.doris.catalog.Column;
-import org.apache.doris.catalog.MTMV;
 import org.apache.doris.catalog.OlapTable;
 import org.apache.doris.catalog.PartitionType;
 import org.apache.doris.catalog.TableIf;
@@ -222,35 +221,20 @@ public class MaterializedViewUtils {
      * when query rewrite, because one plan may hit the materialized view 
repeatedly and the mv scan output
      * should be different
      */
-    public static Plan generateMvScanPlan(MTMV materializedView, 
CascadesContext cascadesContext) {
+    public static Plan generateMvScanPlan(OlapTable table, long indexId,
+            List<Long> partitionIds,
+            PreAggStatus preAggStatus,
+            CascadesContext cascadesContext) {
         return new LogicalOlapScan(
                 cascadesContext.getStatementContext().getNextRelationId(),
-                materializedView,
-                materializedView.getFullQualifiers(),
+                table,
+                ImmutableList.of(table.getQualifiedDbName()),
                 ImmutableList.of(),
-                materializedView.getPartitionIds(),
-                materializedView.getBaseIndexId(),
-                PreAggStatus.on(),
-                ImmutableList.of(),
-                // this must be empty, or it will be used to sample
-                ImmutableList.of(),
-                Optional.empty());
-    }
-
-    /**
-     * LIke above but generate scan plan for sync materialized view
-     */
-    public static Plan generateMvScanPlan(OlapTable olapTable, long indexId, 
CascadesContext cascadesContext) {
-        return new LogicalOlapScan(
-                cascadesContext.getStatementContext().getNextRelationId(),
-                olapTable,
-                ImmutableList.of(olapTable.getQualifiedDbName()),
-                // this must be empty, or it will be used to sample
-                ImmutableList.of(),
-                olapTable.getPartitionIds(),
+                partitionIds,
                 indexId,
-                PreAggStatus.unset(),
+                preAggStatus,
                 ImmutableList.of(),
+                // this must be empty, or it will be used to sample
                 ImmutableList.of(),
                 Optional.empty());
     }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/SyncMaterializationContext.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/SyncMaterializationContext.java
index 1f50e069891..ea9e80cf7e6 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/SyncMaterializationContext.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/SyncMaterializationContext.java
@@ -23,6 +23,7 @@ import org.apache.doris.common.Pair;
 import org.apache.doris.nereids.CascadesContext;
 import org.apache.doris.nereids.trees.plans.ObjectId;
 import org.apache.doris.nereids.trees.plans.Plan;
+import org.apache.doris.nereids.trees.plans.PreAggStatus;
 import org.apache.doris.nereids.trees.plans.RelationId;
 import org.apache.doris.nereids.trees.plans.algebra.Relation;
 import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
@@ -54,7 +55,8 @@ public class SyncMaterializationContext extends 
MaterializationContext {
     public SyncMaterializationContext(Plan mvPlan, Plan mvOriginalPlan, 
OlapTable olapTable,
             long indexId, String indexName, CascadesContext cascadesContext, 
Statistics statistics) {
         super(mvPlan, mvOriginalPlan,
-                MaterializedViewUtils.generateMvScanPlan(olapTable, indexId, 
cascadesContext), cascadesContext, null);
+                MaterializedViewUtils.generateMvScanPlan(olapTable, indexId, 
olapTable.getPartitionIds(),
+                        PreAggStatus.unset(), cascadesContext), 
cascadesContext, null);
         this.olapTable = olapTable;
         this.indexId = indexId;
         this.indexName = indexName;
@@ -63,7 +65,8 @@ public class SyncMaterializationContext extends 
MaterializationContext {
 
     @Override
     Plan doGenerateScanPlan(CascadesContext cascadesContext) {
-        return MaterializedViewUtils.generateMvScanPlan(olapTable, indexId, 
cascadesContext);
+        return MaterializedViewUtils.generateMvScanPlan(olapTable, indexId, 
olapTable.getPartitionIds(),
+                PreAggStatus.unset(), cascadesContext);
     }
 
     @Override
@@ -96,13 +99,29 @@ public class SyncMaterializationContext extends 
MaterializationContext {
     @Override
     Optional<Pair<Id, Statistics>> getPlanStatistics(CascadesContext 
cascadesContext) {
         RelationId relationId = null;
-        Optional<LogicalOlapScan> scanObj = 
this.getScanPlan().collectFirst(LogicalOlapScan.class::isInstance);
+        Optional<LogicalOlapScan> scanObj = this.getScanPlan(null)
+                .collectFirst(LogicalOlapScan.class::isInstance);
         if (scanObj.isPresent()) {
             relationId = scanObj.get().getRelationId();
         }
         return Optional.of(Pair.of(relationId, 
normalizeStatisticsColumnExpression(statistics)));
     }
 
+    @Override
+    public Plan getScanPlan(StructInfo queryStructInfo) {
+        if (queryStructInfo == null) {
+            return scanPlan;
+        }
+        if (queryStructInfo.getRelations().size() == 1
+                && queryStructInfo.getRelations().get(0) instanceof 
LogicalOlapScan
+                && !((LogicalOlapScan) 
queryStructInfo.getRelations().get(0)).getSelectedPartitionIds().isEmpty()
+                && scanPlan instanceof LogicalOlapScan) {
+            return ((LogicalOlapScan) scanPlan).withSelectedPartitionIds(
+                    ((LogicalOlapScan) 
queryStructInfo.getRelations().get(0)).getSelectedPartitionIds());
+        }
+        return scanPlan;
+    }
+
     /**
      * Calc the relation is chosen finally or not
      */
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/mv/IdStatisticsMapTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/mv/IdStatisticsMapTest.java
index 4b0ca184955..a4c05fa81e6 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/mv/IdStatisticsMapTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/mv/IdStatisticsMapTest.java
@@ -75,7 +75,8 @@ public class IdStatisticsMapTest extends SqlTestBase {
                 .analyze()
                 .rewrite();
         // scan plan output will be refreshed after mv rewrite successfully, 
so need tmp store
-        Set<Slot> materializationScanOutput = 
c1.getMaterializationContexts().get(0).getScanPlan().getOutputSet();
+        Set<Slot> materializationScanOutput = 
c1.getMaterializationContexts().get(0)
+                .getScanPlan(null).getOutputSet();
         tmpPlanChecker
                 .optimize()
                 .printlnBestPlanTree();
diff --git a/regression-test/data/mv_p0/partition_prune/partition_prune.out 
b/regression-test/data/mv_p0/partition_prune/partition_prune.out
new file mode 100644
index 00000000000..9f21fbbd0f1
--- /dev/null
+++ b/regression-test/data/mv_p0/partition_prune/partition_prune.out
@@ -0,0 +1,43 @@
+-- This file is automatically generated. You should know what you did if you 
want to edit this
+-- !query1_before --
+aa     bc      2024-07-03T01:15:30     1
+ad     be      2024-07-03T07:06:30     1
+af     bf      2024-07-04T10:01:30     1
+ag     bc      2024-07-04T10:01:35     1
+as     bd      2024-07-03T01:15:30     1
+
+-- !query1_after --
+aa     bc      2024-07-03T01:15:30     1
+ad     be      2024-07-03T07:06:30     1
+af     bf      2024-07-04T10:01:30     1
+ag     bc      2024-07-04T10:01:35     1
+as     bd      2024-07-03T01:15:30     1
+
+-- !query2_before --
+2024-07-03T01:00       aa      bc
+2024-07-03T06:00       as      bd
+2024-07-03T07:00       ad      be
+2024-07-04T10:00       af      bf
+2024-07-04T12:00       ag      bc
+
+-- !query2_after --
+2024-07-03T01:00       aa      bc
+2024-07-03T06:00       as      bd
+2024-07-03T07:00       ad      be
+2024-07-04T10:00       af      bf
+2024-07-04T12:00       ag      bc
+
+-- !query3_before --
+aa     bc      2024-07-03T01:00        2.1
+ad     be      2024-07-03T07:00        3.1
+af     bf      2024-07-04T10:00        4.1
+ag     bc      2024-07-04T12:00        5.1
+as     bd      2024-07-03T06:00        1.1
+
+-- !query3_after --
+aa     bc      2024-07-03T01:00        2.1
+ad     be      2024-07-03T07:00        3.1
+af     bf      2024-07-04T10:00        4.1
+ag     bc      2024-07-04T12:00        5.1
+as     bd      2024-07-03T06:00        1.1
+
diff --git a/regression-test/suites/auth_p0/test_select_column_auth.groovy 
b/regression-test/suites/auth_p0/test_select_column_auth.groovy
index 8b3e9529551..3c3216d0500 100644
--- a/regression-test/suites/auth_p0/test_select_column_auth.groovy
+++ b/regression-test/suites/auth_p0/test_select_column_auth.groovy
@@ -39,8 +39,8 @@ suite("test_select_column_auth","p0,auth") {
         def validCluster = clusters[0][0]
         sql """GRANT USAGE_PRIV ON CLUSTER ${validCluster} TO ${user}""";
     }
-
     sql """create database ${dbName}"""
+    sql("""use ${dbName}""")
     sql """
         CREATE TABLE IF NOT EXISTS ${dbName}.`${tableName}` (
             id BIGINT,
@@ -55,7 +55,7 @@ suite("test_select_column_auth","p0,auth") {
     sql """create view ${dbName}.${mv_name} as select * from 
${dbName}.${tableName};"""
     sql """alter table ${dbName}.${tableName} add rollup 
${rollup_name}(username)"""
     sleep(5 * 1000)
-    sql """create materialized view ${mtmv_name} as select username from 
${dbName}.${tableName}"""
+    createMV("""create materialized view ${mtmv_name} as select username from 
${dbName}.${tableName}""")
     sleep(5 * 1000)
     sql """CREATE MATERIALIZED VIEW ${dbName}.${mtmv_name} 
         BUILD IMMEDIATE REFRESH AUTO ON MANUAL 
diff --git 
a/regression-test/suites/mv_p0/partition_prune/partition_prune.groovy 
b/regression-test/suites/mv_p0/partition_prune/partition_prune.groovy
new file mode 100644
index 00000000000..759c6a540d7
--- /dev/null
+++ b/regression-test/suites/mv_p0/partition_prune/partition_prune.groovy
@@ -0,0 +1,257 @@
+// 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.
+
+suite("partition_prune") {
+    String db = context.config.getDbNameByFile(context.file)
+    sql "use ${db}"
+    sql "set runtime_filter_mode=OFF";
+    sql "SET ignore_shape_nodes='PhysicalDistribute,PhysicalProject'"
+
+    sql """
+    drop table if exists test_duplicate;
+    """
+
+    sql """
+        CREATE TABLE IF NOT EXISTS test_duplicate (
+        `app_name` VARCHAR(64) NULL COMMENT '标识', 
+        `event_id` VARCHAR(128) NULL COMMENT '标识', 
+        `decision` VARCHAR(32) NULL COMMENT '枚举值', 
+        `time` DATETIME NULL COMMENT '查询时间', 
+        `id` VARCHAR(35) NOT NULL COMMENT 'od', 
+        `code` VARCHAR(64) NULL COMMENT '标识', 
+        `event_type` VARCHAR(32) NULL COMMENT '事件类型' 
+        )
+        DUPLICATE KEY(app_name, event_id)
+        PARTITION BY RANGE(time)                                               
                                                                                
                                                                                
 
+        (                                                                      
                                                                                
                                                                                
+         FROM ("2024-07-01 00:00:00") TO ("2024-07-15 00:00:00") INTERVAL 1 
HOUR                                                                            
                                                                                
                  
+        )     
+        DISTRIBUTED BY HASH(event_id)
+        BUCKETS 3 PROPERTIES ("replication_num" = "1");
+    """
+
+    sql """
+    insert into test_duplicate values
+    ('aa', 'bc', 'cc', '2024-07-03 01:15:30', 'dd', 'ee', 'ff'),
+    ('as', 'bd', 'cd', '2024-07-03 01:15:30', 'dd', 'ee', 'ff'),
+    ('ad', 'be', 'cc', '2024-07-03 07:06:30', 'dd', 'ee', 'ff'),
+    ('af', 'bf', 'ce', '2024-07-04 10:01:30', 'dd', 'ee', 'ff'),
+    ('ag', 'bc', 'cc', '2024-07-04 10:01:35', 'dd', 'ee', 'ff'),
+    ('aa', 'bc', 'cc', '2024-07-05 01:15:30', 'dd', 'ee', 'ff'),
+    ('as', 'bd', 'cd', '2024-07-05 06:09:30', 'dd', 'ee', 'ff'),
+    ('ad', 'be', 'cc', '2024-07-06 07:06:30', 'dd', 'ee', 'ff'),
+    ('af', 'bf', 'ce', '2024-07-07 10:01:30', 'dd', 'ee', 'ff'),
+    ('ag', 'bc', 'cc', '2024-07-08 12:55:30', 'dd', 'ee', 'ff');
+    """
+
+    sql """
+    drop table if exists test_unique;
+    """
+
+    sql """
+        CREATE TABLE IF NOT EXISTS test_unique (
+        `time` DATETIME NULL COMMENT '查询时间', 
+        `app_name` VARCHAR(64) NULL COMMENT '标识', 
+        `event_id` VARCHAR(128) NULL COMMENT '标识', 
+        `decision` VARCHAR(32) NULL COMMENT '枚举值', 
+        `id` VARCHAR(35) NOT NULL COMMENT 'od', 
+        `code` VARCHAR(64) NULL COMMENT '标识', 
+        `event_type` VARCHAR(32) NULL COMMENT '事件类型' 
+        )
+        UNIQUE KEY(time)
+        PARTITION BY RANGE(time)                                               
                                                                                
                                                                                
 
+        (                                                                      
                                                                                
                                                                                
+         FROM ("2024-07-01 00:00:00") TO ("2024-07-15 00:00:00") INTERVAL 1 
HOUR                                                                            
                                                                                
                  
+        )     
+        DISTRIBUTED BY HASH(time)
+        BUCKETS 3 PROPERTIES ("replication_num" = "1");
+    """
+
+    sql """
+    insert into test_unique values
+    ('2024-07-03 01:00:00', 'aa', 'bc', 'cc', 'dd', 'ee', 'ff'),
+    ('2024-07-03 06:00:00', 'as', 'bd', 'cd', 'dd', 'ee', 'ff'),
+    ('2024-07-03 07:00:00', 'ad', 'be', 'cc', 'dd', 'ee', 'ff'),
+    ('2024-07-04 10:00:00', 'af', 'bf', 'ce', 'dd', 'ee', 'ff'),
+    ('2024-07-04 12:00:00', 'ag', 'bc', 'cc', 'dd', 'ee', 'ff'),
+    ('2024-07-05 01:00:00', 'aa', 'bc', 'cc', 'dd', 'ee', 'ff'),
+    ('2024-07-05 06:00:00', 'as', 'bd', 'cd', 'dd', 'ee', 'ff'),
+    ('2024-07-06 07:00:00', 'ad', 'be', 'cc', 'dd', 'ee', 'ff'),
+    ('2024-07-07 10:00:00', 'af', 'bf', 'ce', 'dd', 'ee', 'ff'),
+    ('2024-07-08 12:00:00', 'ag', 'bc', 'cc', 'dd', 'ee', 'ff');
+    """
+
+    sql """
+    drop table if exists test_aggregate;
+    """
+
+    sql """
+        CREATE TABLE IF NOT EXISTS test_aggregate (
+        `app_name` VARCHAR(64) NULL COMMENT '标识', 
+        `event_id` VARCHAR(128) NULL COMMENT '标识', 
+        `time` DATETIME NULL COMMENT '查询时间',
+        `price` DOUBLE SUM DEFAULT '0' COMMENT '价格'
+        )
+        AGGREGATE KEY(app_name, event_id, time)
+        PARTITION BY RANGE(time)                                               
                                                                                
                                                                                
 
+        (                                                                      
                                                                                
                                                                                
+         FROM ("2024-07-01 00:00:00") TO ("2024-07-15 00:00:00") INTERVAL 1 
HOUR                                                                            
                                                                                
                  
+        )     
+        DISTRIBUTED BY HASH(event_id)
+        BUCKETS 3 PROPERTIES ("replication_num" = "1");
+    """
+
+    sql """
+    insert into test_aggregate values
+    ('aa', 'bc', '2024-07-03 01:00:00', 2.1),
+    ('as', 'bd', '2024-07-03 06:00:00', 1.1),
+    ('ad', 'be', '2024-07-03 07:00:00', 3.1),
+    ('af', 'bf', '2024-07-04 10:00:00', 4.1),
+    ('ag', 'bc', '2024-07-04 12:00:00', 5.1),
+    ('aa', 'bc', '2024-07-05 01:00:00', 6.1),
+    ('as', 'bd', '2024-07-05 06:00:00', 7.1),
+    ('ad', 'be', '2024-07-06 07:00:00', 8.1),
+    ('af', 'bf', '2024-07-07 10:00:00', 9.1),
+    ('ag', 'bc', '2024-07-08 12:00:00', 10.1);
+    """
+
+    // test partition prune in duplicate table
+
+    def mv1 = """
+    select
+    app_name,
+    event_id,
+    time,
+    count(*)
+    from 
+    test_duplicate
+    group by
+    app_name,
+    event_id,
+    time;
+    """
+
+    def query1 = """
+    select
+    app_name,
+    event_id,
+    time,
+    count(*)
+    from 
+    test_duplicate
+    where time < '2024-07-05 01:00:00'
+    group by
+    app_name,
+    time,
+    event_id;
+    """
+
+    order_qt_query1_before "${query1}"
+    createMV("""
+    CREATE MATERIALIZED VIEW mv1
+    AS
+    ${mv1}
+    """)
+    explain {
+        sql("""${query1}""")
+        check {result ->
+            result.contains("(mv1)") && result.contains("partitions=3")
+        }
+    }
+    order_qt_query1_after "${query1}"
+
+    // test partition prune in unique table
+    def mv2 = """
+    select
+    time,
+    app_name,
+    event_id
+    from 
+    test_unique;
+    """
+
+    def query2 = """
+    select
+    time,
+    app_name,
+    event_id
+    from 
+    test_unique
+    where time < '2024-07-05 01:00:00';
+    """
+
+    order_qt_query2_before "${query2}"
+    createMV("""
+    CREATE MATERIALIZED VIEW mv2
+    AS
+    ${mv2}
+    """)
+    explain {
+        sql("""${query2}""")
+        check {result ->
+            result.contains("(mv2)") && result.contains("partitions=5")
+        }
+    }
+    order_qt_query2_after "${query2}"
+
+    // test partition prune in aggregate table
+    def mv3 = """
+    select
+    app_name,
+    event_id,
+    time,
+    sum(price)
+    from 
+    test_aggregate
+    where time < '2024-07-11 01:00:00'
+    group by
+    app_name,
+    event_id,
+    time;
+    """
+
+    def query3 = """
+    select
+    app_name,
+    event_id,
+    time,
+    sum(price)
+    from 
+    test_aggregate
+    where time < '2024-07-05 01:00:00'
+    group by
+    app_name,
+    time,
+    event_id;
+    """
+
+
+    order_qt_query3_before "${query3}"
+    createMV("""
+    CREATE MATERIALIZED VIEW mv3
+    AS
+    ${mv3}
+    """)
+    explain {
+        sql("""${query3}""")
+        check {result ->
+            result.contains("(mv3)") && result.contains("partitions=5")
+        }
+    }
+    order_qt_query3_after "${query3}"
+
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to