This is an automated email from the ASF dual-hosted git repository.
maxyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudberry.git
The following commit(s) were added to refs/heads/main by this push:
new d0e9daf227c [AQUMV] Directly compute queries from materialized views
with GROUP BY.
d0e9daf227c is described below
commit d0e9daf227cfeca1266b228be1d15e482162100f
Author: Zhang Mingli <[email protected]>
AuthorDate: Thu Jun 5 14:19:35 2025 +0800
[AQUMV] Directly compute queries from materialized views with GROUP BY.
This commit enhances the AQUMV system by enabling it to compute queries
directly from materialized views that already contain a GROUP BY clause.
This improvement allows us to bypass additional GROUP BY operations
during query execution, resulting in faster and more efficient
performance.
For example, with a materialized view defined as follows:
```sql
CREATE MATERIALIZED VIEW mv_group_1 AS
SELECT c, b, COUNT(b) AS count_b FROM t0 WHERE a > 3 GROUP BY c, b;
```
An original query like:
```sql
SELECT COUNT(b), b, c FROM t0 WHERE a > 3 GROUP BY b, c;
```
is rewritten to:
```sql
SELECT count_b, b, c FROM mv_group_1;
```
The plan looks like:
```sql
explain(costs off, verbose)
select count(b), b, c from t0 where a > 3 group by b, c;
QUERY PLAN
---------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
Output: count, b, c
-> Seq Scan on aqumv.mv_group_1
Output: count, b, c
Settings: enable_answer_query_using_materialized_views = 'on',
optimizer = 'off'
Optimizer: Postgres query optimizer
(6 rows)
```
The two SQL queries yield equivalent results, even though the selected
columns are in a different order. Since mv_group_1 already contains the
aggregated results and all rows have a column a value greater than 3,
there is no need for additional filtering or GROUP BY operations.
This enhancement eliminates redundant computations, leading to
significant time savings. Fetching results directly from these views
reduces overall execution time, improving responsiveness for complex
queries. This is particularly beneficial for large datasets, allowing
efficient data analysis without performance degradation.
The feature also applies to Dynamic Tables and Incremental Materialized
Views.
Authored-by: Zhang Mingli [email protected]
---
src/backend/optimizer/plan/aqumv.c | 110 ++++++++-
src/test/regress/expected/aqumv.out | 471 ++++++++++++++++++++++++++++++++++++
src/test/regress/sql/aqumv.sql | 100 ++++++++
3 files changed, 676 insertions(+), 5 deletions(-)
diff --git a/src/backend/optimizer/plan/aqumv.c
b/src/backend/optimizer/plan/aqumv.c
index 63e82d759b0..4a576061780 100644
--- a/src/backend/optimizer/plan/aqumv.c
+++ b/src/backend/optimizer/plan/aqumv.c
@@ -74,6 +74,13 @@ static Node *aqumv_adjust_sub_matched_expr_mutator(Node
*node, aqumv_equivalent_
static bool contain_var_or_aggstar_clause_walker(Node *node, void *context);
static bool check_partition(Query *parse, Oid origin_rel_oid);
+static bool
+groupby_query_rewrite(PlannerInfo *subroot,
+ Query *parse,
+ Query *viewQuery,
+
aqumv_equivalent_transformation_context *context,
+ AqumvContext aqumv_context);
+
typedef struct
{
int complexity;
@@ -358,19 +365,23 @@ answer_query_using_materialized_views(PlannerInfo *root,
AqumvContext aqumv_cont
if (!parse->hasAggs && viewQuery->hasAggs)
continue;
- if (parse->hasAggs && viewQuery->hasAggs)
+ if (parse->groupClause != NIL && viewQuery->groupClause != NIL)
+ {
+ if (!groupby_query_rewrite(subroot, parse, viewQuery,
context, aqumv_context))
+ continue;
+ }
+ else if (parse->hasAggs && viewQuery->hasAggs)
{
+ /* Both don't have group by. */
+ {
if (parse->hasDistinctOn ||
parse->distinctClause != NIL ||
- parse->groupClause != NIL || /* TODO: GROUP BY
*/
parse->groupingSets != NIL ||
parse->groupDistinct)
continue;
- /* No Group by now. */
if (viewQuery->hasDistinctOn ||
viewQuery->distinctClause != NIL ||
- viewQuery->groupClause != NIL ||
viewQuery->groupingSets != NIL ||
viewQuery->groupDistinct ||
viewQuery->havingQual != NULL || /* HAVING
clause is not supported on IMMV yet. */
@@ -388,7 +399,7 @@ answer_query_using_materialized_views(PlannerInfo *root,
AqumvContext aqumv_cont
*/
if (parse->sortClause != NIL || viewQuery->sortClause
!= NIL)
{
- /* Earse view's sort caluse, it's ok to let
alone view's target list. */
+ /* Erase view's sort caluse, it's ok to let
alone view's target list. */
viewQuery->sortClause = NIL;
}
@@ -463,6 +474,7 @@ answer_query_using_materialized_views(PlannerInfo *root,
AqumvContext aqumv_cont
/* Select from a mv never have that.*/
subroot->append_rel_list = NIL;
+ }
}
else
{
@@ -896,3 +908,91 @@ check_partition(Query *parse, Oid origin_rel_oid)
}
return true;
}
+
+static bool
+groupby_query_rewrite(PlannerInfo *subroot,
+ Query *parse,
+ Query *viewQuery,
+
aqumv_equivalent_transformation_context *context,
+ AqumvContext aqumv_context)
+{
+ List *post_quals = NIL;
+ List *mv_final_tlist = NIL;
+
+ if (!parse->hasAggs || !viewQuery->hasAggs)
+ return false;
+
+ /* Both have Group by and aggregation. */
+ if (parse->groupClause == NIL || viewQuery->groupClause == NIL)
+ return false;
+
+ if (parse->hasDistinctOn ||
+ parse->distinctClause != NIL ||
+ parse->groupingSets != NIL ||
+ parse->sortClause != NIL ||
+ limit_needed(parse) ||
+ parse->havingQual != NULL ||
+ parse->groupDistinct)
+ return false;
+
+ if (viewQuery->hasDistinctOn ||
+ viewQuery->distinctClause != NIL ||
+ viewQuery->groupingSets != NIL ||
+ viewQuery->groupDistinct ||
+ viewQuery->havingQual != NULL ||
+ viewQuery->sortClause != NIL ||
+ limit_needed(viewQuery))
+ return false;
+
+ if (tlist_has_srf(parse))
+ return false;
+
+ preprocess_qual_conditions(subroot, (Node *) viewQuery->jointree);
+
+ if(!aqumv_process_from_quals(parse->jointree->quals,
viewQuery->jointree->quals, &post_quals))
+ return false;
+
+ if (post_quals != NIL)
+ return false;
+
+ /*
+ * There should be no post_quals for now, erase those from view.
+ */
+ viewQuery->jointree->quals = NULL;
+
+ if (list_difference(parse->groupClause, viewQuery->groupClause))
+ return false;
+
+ if (list_difference(viewQuery->groupClause, parse->groupClause))
+ return false;
+
+ /*
+ * Group By clauses are equal, erase those from view.
+ */
+ viewQuery->groupClause = NIL;
+
+ if(!aqumv_process_targetlist(context,
aqumv_context->raw_processed_tlist, &mv_final_tlist))
+ return false;
+
+ viewQuery->targetList = mv_final_tlist;
+ /* SRF is not supported now, but correct the field. */
+ viewQuery->hasTargetSRFs = parse->hasTargetSRFs;
+ viewQuery->hasAggs = false;
+ subroot->agginfos = NIL;
+ subroot->aggtransinfos = NIL;
+ subroot->hasNonPartialAggs = false;
+ subroot->hasNonSerialAggs = false;
+ subroot->numOrderedAggs = false;
+ /* CBDB specifical */
+ subroot->hasNonCombine = false;
+ subroot->numPureOrderedAggs = false;
+ /*
+ * NB: Update processed_tlist again in case that tlist has been changed.
+ */
+ subroot->processed_tlist = NIL;
+ preprocess_targetlist(subroot);
+
+ /* Select from a mv never have that.*/
+ subroot->append_rel_list = NIL;
+ return true;
+}
diff --git a/src/test/regress/expected/aqumv.out
b/src/test/regress/expected/aqumv.out
index 463b0b37032..926ef05cd32 100644
--- a/src/test/regress/expected/aqumv.out
+++ b/src/test/regress/expected/aqumv.out
@@ -3374,6 +3374,477 @@ select * from t_insert;
1000
(1 row)
+abort;
+-- Test view has Group By
+begin;
+create table t0 as select i as a, i+1 as b , i+2 as c, i+3 as d from
generate_series(1, 5) i;
+NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named
'a' as the Apache Cloudberry data distribution key for this table.
+HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make
sure column(s) chosen are the optimal data distribution key to minimize skew.
+insert into t0 select * from t0;
+insert into t0 select * from t0;
+insert into t0 select * from t0;
+insert into t0 select * from t0;
+insert into t0 select * from t0;
+insert into t0 select * from t0;
+insert into t0 select * from t0;
+insert into t0 select * from t0;
+insert into t0 select * from t0;
+analyze t0;
+create materialized view mv_group_0 as select c, b, sum(a), count(b) from t0
group by b, c;
+NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named
'b, c' as the Apache Cloudberry data distribution key for this table.
+HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make
sure column(s) chosen are the optimal data distribution key to minimize skew.
+create materialized view mv_group_1 as select c, b, count(b) from t0 where a >
3 group by c, b;
+NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named
'c, b' as the Apache Cloudberry data distribution key for this table.
+HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make
sure column(s) chosen are the optimal data distribution key to minimize skew.
+analyze mv_group_0;
+analyze mv_group_1;
+-- no qual, exactly match
+set local enable_answer_query_using_materialized_views = off;
+explain(costs off, verbose)
+select c, b, sum(a), count(b) from t0 group by b, c;
+ QUERY PLAN
+-----------------------------------------------------------------------------------
+ Gather Motion 3:1 (slice1; segments: 3)
+ Output: c, b, (sum(a)), (count(b))
+ -> Finalize HashAggregate
+ Output: c, b, sum(a), count(b)
+ Group Key: t0.b, t0.c
+ -> Redistribute Motion 3:3 (slice2; segments: 3)
+ Output: c, b, (PARTIAL sum(a)), (PARTIAL count(b))
+ Hash Key: b, c
+ -> Partial HashAggregate
+ Output: c, b, PARTIAL sum(a), PARTIAL count(b)
+ Group Key: t0.b, t0.c
+ -> Seq Scan on aqumv.t0
+ Output: a, b, c, d
+ Settings: enable_answer_query_using_materialized_views = 'off', optimizer =
'off'
+ Optimizer: Postgres query optimizer
+(15 rows)
+
+select c, b, sum(a), count(b) from t0 group by b, c;
+ c | b | sum | count
+---+---+------+-------
+ 6 | 5 | 2048 | 512
+ 3 | 2 | 512 | 512
+ 5 | 4 | 1536 | 512
+ 4 | 3 | 1024 | 512
+ 7 | 6 | 2560 | 512
+(5 rows)
+
+set local enable_answer_query_using_materialized_views = on;
+explain(costs off, verbose)
+select c, b, sum(a), count(b) from t0 group by b, c;
+ QUERY PLAN
+----------------------------------------------------------------------------------
+ Gather Motion 3:1 (slice1; segments: 3)
+ Output: c, b, sum, count
+ -> Seq Scan on aqumv.mv_group_0
+ Output: c, b, sum, count
+ Settings: enable_answer_query_using_materialized_views = 'on', optimizer =
'off'
+ Optimizer: Postgres query optimizer
+(6 rows)
+
+select c, b, sum(a), count(b) from t0 group by b, c;
+ c | b | sum | count
+---+---+------+-------
+ 6 | 5 | 2048 | 512
+ 3 | 2 | 512 | 512
+ 5 | 4 | 1536 | 512
+ 4 | 3 | 1024 | 512
+ 7 | 6 | 2560 | 512
+(5 rows)
+
+-- no qual, different order
+set local enable_answer_query_using_materialized_views = off;
+explain(costs off, verbose)
+select b, sum(a), c, count(b) from t0 group by c, b;
+ QUERY PLAN
+-----------------------------------------------------------------------------------
+ Gather Motion 3:1 (slice1; segments: 3)
+ Output: b, (sum(a)), c, (count(b))
+ -> Finalize HashAggregate
+ Output: b, sum(a), c, count(b)
+ Group Key: t0.c, t0.b
+ -> Redistribute Motion 3:3 (slice2; segments: 3)
+ Output: b, c, (PARTIAL sum(a)), (PARTIAL count(b))
+ Hash Key: c, b
+ -> Partial HashAggregate
+ Output: b, c, PARTIAL sum(a), PARTIAL count(b)
+ Group Key: t0.c, t0.b
+ -> Seq Scan on aqumv.t0
+ Output: a, b, c, d
+ Settings: enable_answer_query_using_materialized_views = 'off', optimizer =
'off'
+ Optimizer: Postgres query optimizer
+(15 rows)
+
+select b, sum(a), c, count(b) from t0 group by c, b;
+ b | sum | c | count
+---+------+---+-------
+ 6 | 2560 | 7 | 512
+ 4 | 1536 | 5 | 512
+ 5 | 2048 | 6 | 512
+ 3 | 1024 | 4 | 512
+ 2 | 512 | 3 | 512
+(5 rows)
+
+set local enable_answer_query_using_materialized_views = on;
+explain(costs off, verbose)
+select b, sum(a), c, count(b) from t0 group by c, b;
+ QUERY PLAN
+----------------------------------------------------------------------------------
+ Gather Motion 3:1 (slice1; segments: 3)
+ Output: b, sum, c, count
+ -> Seq Scan on aqumv.mv_group_0
+ Output: b, sum, c, count
+ Settings: enable_answer_query_using_materialized_views = 'on', optimizer =
'off'
+ Optimizer: Postgres query optimizer
+(6 rows)
+
+select b, sum(a), c, count(b) from t0 group by c, b;
+ b | sum | c | count
+---+------+---+-------
+ 5 | 2048 | 6 | 512
+ 2 | 512 | 3 | 512
+ 4 | 1536 | 5 | 512
+ 3 | 1024 | 4 | 512
+ 6 | 2560 | 7 | 512
+(5 rows)
+
+-- no qual, different expr
+set local enable_answer_query_using_materialized_views = off;
+explain(costs off, verbose)
+select b + c + 1, sum(a) + count(b) from t0 group by c, b;
+ QUERY PLAN
+-----------------------------------------------------------------------------------
+ Gather Motion 3:1 (slice1; segments: 3)
+ Output: (((b + c) + 1)), ((sum(a) + count(b))), c, b
+ -> Finalize HashAggregate
+ Output: ((b + c) + 1), (sum(a) + count(b)), c, b
+ Group Key: t0.c, t0.b
+ -> Redistribute Motion 3:3 (slice2; segments: 3)
+ Output: c, b, (PARTIAL sum(a)), (PARTIAL count(b))
+ Hash Key: c, b
+ -> Partial HashAggregate
+ Output: c, b, PARTIAL sum(a), PARTIAL count(b)
+ Group Key: t0.c, t0.b
+ -> Seq Scan on aqumv.t0
+ Output: a, b, c, d
+ Settings: enable_answer_query_using_materialized_views = 'off', optimizer =
'off'
+ Optimizer: Postgres query optimizer
+(15 rows)
+
+select b + c + 1, sum(a) + count(b) from t0 group by c, b;
+ ?column? | ?column?
+----------+----------
+ 8 | 1536
+ 14 | 3072
+ 10 | 2048
+ 12 | 2560
+ 6 | 1024
+(5 rows)
+
+set local enable_answer_query_using_materialized_views = on;
+explain(costs off, verbose)
+select b + c + 1, sum(a) + count(b) from t0 group by c, b;
+ QUERY PLAN
+----------------------------------------------------------------------------------
+ Gather Motion 3:1 (slice1; segments: 3)
+ Output: (((b + c) + 1)), ((sum + count)), c, b
+ -> Seq Scan on aqumv.mv_group_0
+ Output: ((b + c) + 1), (sum + count), c, b
+ Settings: enable_answer_query_using_materialized_views = 'on', optimizer =
'off'
+ Optimizer: Postgres query optimizer
+(6 rows)
+
+select b + c + 1, sum(a) + count(b) from t0 group by c, b;
+ ?column? | ?column?
+----------+----------
+ 8 | 1536
+ 14 | 3072
+ 12 | 2560
+ 6 | 1024
+ 10 | 2048
+(5 rows)
+
+-- no qual, should not match
+set local enable_answer_query_using_materialized_views = off;
+explain(costs off, verbose)
+select c, count(b) from t0 group by c ;
+ QUERY PLAN
+-----------------------------------------------------------------------------------
+ Gather Motion 3:1 (slice1; segments: 3)
+ Output: c, (count(b))
+ -> Finalize HashAggregate
+ Output: c, count(b)
+ Group Key: t0.c
+ -> Redistribute Motion 3:3 (slice2; segments: 3)
+ Output: c, (PARTIAL count(b))
+ Hash Key: c
+ -> Partial HashAggregate
+ Output: c, PARTIAL count(b)
+ Group Key: t0.c
+ -> Seq Scan on aqumv.t0
+ Output: a, b, c, d
+ Settings: enable_answer_query_using_materialized_views = 'off', optimizer =
'off'
+ Optimizer: Postgres query optimizer
+(15 rows)
+
+select c, count(b) from t0 group by c ;
+ c | count
+---+-------
+ 4 | 512
+ 3 | 512
+ 7 | 512
+ 5 | 512
+ 6 | 512
+(5 rows)
+
+set local enable_answer_query_using_materialized_views = on;
+explain(costs off, verbose)
+select c, count(b) from t0 group by c ;
+ QUERY PLAN
+----------------------------------------------------------------------------------
+ Gather Motion 3:1 (slice1; segments: 3)
+ Output: c, (count(b))
+ -> Finalize HashAggregate
+ Output: c, count(b)
+ Group Key: t0.c
+ -> Redistribute Motion 3:3 (slice2; segments: 3)
+ Output: c, (PARTIAL count(b))
+ Hash Key: c
+ -> Partial HashAggregate
+ Output: c, PARTIAL count(b)
+ Group Key: t0.c
+ -> Seq Scan on aqumv.t0
+ Output: a, b, c, d
+ Settings: enable_answer_query_using_materialized_views = 'on', optimizer =
'off'
+ Optimizer: Postgres query optimizer
+(15 rows)
+
+select c, count(b) from t0 group by c ;
+ c | count
+---+-------
+ 4 | 512
+ 3 | 512
+ 7 | 512
+ 5 | 512
+ 6 | 512
+(5 rows)
+
+-- with qual, exactly match
+set local enable_answer_query_using_materialized_views = off;
+explain(costs off, verbose)
+select c, b, count(b) from t0 where a > 3 group by c, b;
+ QUERY PLAN
+-----------------------------------------------------------------------------------
+ Gather Motion 3:1 (slice1; segments: 3)
+ Output: c, b, (count(b))
+ -> Finalize HashAggregate
+ Output: c, b, count(b)
+ Group Key: t0.c, t0.b
+ -> Redistribute Motion 3:3 (slice2; segments: 3)
+ Output: c, b, (PARTIAL count(b))
+ Hash Key: c, b
+ -> Partial HashAggregate
+ Output: c, b, PARTIAL count(b)
+ Group Key: t0.c, t0.b
+ -> Seq Scan on aqumv.t0
+ Output: a, b, c, d
+ Filter: (t0.a > 3)
+ Settings: enable_answer_query_using_materialized_views = 'off', optimizer =
'off'
+ Optimizer: Postgres query optimizer
+(16 rows)
+
+select c, b, count(b) from t0 where a > 3 group by c, b;
+ c | b | count
+---+---+-------
+ 7 | 6 | 512
+ 6 | 5 | 512
+(2 rows)
+
+set local enable_answer_query_using_materialized_views = on;
+explain(costs off, verbose)
+select c, b, count(b) from t0 where a > 3 group by c, b;
+ QUERY PLAN
+----------------------------------------------------------------------------------
+ Gather Motion 3:1 (slice1; segments: 3)
+ Output: c, b, count
+ -> Seq Scan on aqumv.mv_group_1
+ Output: c, b, count
+ Settings: enable_answer_query_using_materialized_views = 'on', optimizer =
'off'
+ Optimizer: Postgres query optimizer
+(6 rows)
+
+select c, b, count(b) from t0 where a > 3 group by c, b;
+ c | b | count
+---+---+-------
+ 7 | 6 | 512
+ 6 | 5 | 512
+(2 rows)
+
+-- with qual, different order
+set local enable_answer_query_using_materialized_views = off;
+explain(costs off, verbose)
+select count(b), b, c from t0 where a > 3 group by b, c;
+ QUERY PLAN
+-----------------------------------------------------------------------------------
+ Gather Motion 3:1 (slice1; segments: 3)
+ Output: (count(b)), b, c
+ -> Finalize HashAggregate
+ Output: count(b), b, c
+ Group Key: t0.b, t0.c
+ -> Redistribute Motion 3:3 (slice2; segments: 3)
+ Output: b, c, (PARTIAL count(b))
+ Hash Key: b, c
+ -> Partial HashAggregate
+ Output: b, c, PARTIAL count(b)
+ Group Key: t0.b, t0.c
+ -> Seq Scan on aqumv.t0
+ Output: a, b, c, d
+ Filter: (t0.a > 3)
+ Settings: enable_answer_query_using_materialized_views = 'off', optimizer =
'off'
+ Optimizer: Postgres query optimizer
+(16 rows)
+
+select count(b), b, c from t0 where a > 3 group by b, c;
+ count | b | c
+-------+---+---
+ 512 | 5 | 6
+ 512 | 6 | 7
+(2 rows)
+
+set local enable_answer_query_using_materialized_views = on;
+explain(costs off, verbose)
+select count(b), b, c from t0 where a > 3 group by b, c;
+ QUERY PLAN
+----------------------------------------------------------------------------------
+ Gather Motion 3:1 (slice1; segments: 3)
+ Output: count, b, c
+ -> Seq Scan on aqumv.mv_group_1
+ Output: count, b, c
+ Settings: enable_answer_query_using_materialized_views = 'on', optimizer =
'off'
+ Optimizer: Postgres query optimizer
+(6 rows)
+
+select count(b), b, c from t0 where a > 3 group by b, c;
+ count | b | c
+-------+---+---
+ 512 | 6 | 7
+ 512 | 5 | 6
+(2 rows)
+
+-- with qual, different expr
+set local enable_answer_query_using_materialized_views = off;
+explain(costs off, verbose)
+select count(b) + 1, b + 1, c from t0 where a > 3 group by b, c;
+ QUERY PLAN
+-----------------------------------------------------------------------------------
+ Gather Motion 3:1 (slice1; segments: 3)
+ Output: ((count(b) + 1)), ((b + 1)), c, b
+ -> Finalize HashAggregate
+ Output: (count(b) + 1), (b + 1), c, b
+ Group Key: t0.b, t0.c
+ -> Redistribute Motion 3:3 (slice2; segments: 3)
+ Output: c, b, (PARTIAL count(b))
+ Hash Key: b, c
+ -> Partial HashAggregate
+ Output: c, b, PARTIAL count(b)
+ Group Key: t0.b, t0.c
+ -> Seq Scan on aqumv.t0
+ Output: a, b, c, d
+ Filter: (t0.a > 3)
+ Settings: enable_answer_query_using_materialized_views = 'off', optimizer =
'off'
+ Optimizer: Postgres query optimizer
+(16 rows)
+
+select count(b) + 1, b + 1, c from t0 where a > 3 group by b, c;
+ ?column? | ?column? | c
+----------+----------+---
+ 513 | 6 | 6
+ 513 | 7 | 7
+(2 rows)
+
+set local enable_answer_query_using_materialized_views = on;
+explain(costs off, verbose)
+select count(b) + 1, b + 1, c from t0 where a > 3 group by b, c;
+ QUERY PLAN
+----------------------------------------------------------------------------------
+ Gather Motion 3:1 (slice1; segments: 3)
+ Output: ((count + 1)), ((b + 1)), c, b
+ -> Seq Scan on aqumv.mv_group_1
+ Output: (count + 1), (b + 1), c, b
+ Settings: enable_answer_query_using_materialized_views = 'on', optimizer =
'off'
+ Optimizer: Postgres query optimizer
+(6 rows)
+
+select count(b) + 1, b + 1, c from t0 where a > 3 group by b, c;
+ ?column? | ?column? | c
+----------+----------+---
+ 513 | 7 | 7
+ 513 | 6 | 6
+(2 rows)
+
+-- with qual, should not match
+set local enable_answer_query_using_materialized_views = off;
+explain(costs off, verbose)
+select b, c, count(b) from t0 where a > 3 and b > 1 group by b, c;
+ QUERY PLAN
+-----------------------------------------------------------------------------------
+ Gather Motion 3:1 (slice1; segments: 3)
+ Output: b, c, (count(b))
+ -> Finalize HashAggregate
+ Output: b, c, count(b)
+ Group Key: t0.b, t0.c
+ -> Redistribute Motion 3:3 (slice2; segments: 3)
+ Output: b, c, (PARTIAL count(b))
+ Hash Key: b, c
+ -> Partial HashAggregate
+ Output: b, c, PARTIAL count(b)
+ Group Key: t0.b, t0.c
+ -> Seq Scan on aqumv.t0
+ Output: a, b, c, d
+ Filter: ((t0.a > 3) AND (t0.b > 1))
+ Settings: enable_answer_query_using_materialized_views = 'off', optimizer =
'off'
+ Optimizer: Postgres query optimizer
+(16 rows)
+
+select b, c, count(b) from t0 where a > 3 and b > 1 group by b, c;
+ b | c | count
+---+---+-------
+ 5 | 6 | 512
+ 6 | 7 | 512
+(2 rows)
+
+set local enable_answer_query_using_materialized_views = on;
+explain(costs off, verbose)
+select b, c, count(b) from t0 where a > 3 and b > 1 group by b, c;
+ QUERY PLAN
+----------------------------------------------------------------------------------
+ Gather Motion 3:1 (slice1; segments: 3)
+ Output: b, c, (count(b))
+ -> Finalize HashAggregate
+ Output: b, c, count(b)
+ Group Key: t0.b, t0.c
+ -> Redistribute Motion 3:3 (slice2; segments: 3)
+ Output: b, c, (PARTIAL count(b))
+ Hash Key: b, c
+ -> Partial HashAggregate
+ Output: b, c, PARTIAL count(b)
+ Group Key: t0.b, t0.c
+ -> Seq Scan on aqumv.t0
+ Output: a, b, c, d
+ Filter: ((t0.a > 3) AND (t0.b > 1))
+ Settings: enable_answer_query_using_materialized_views = 'on', optimizer =
'off'
+ Optimizer: Postgres query optimizer
+(16 rows)
+
+select b, c, count(b) from t0 where a > 3 and b > 1 group by b, c;
+ b | c | count
+---+---+-------
+ 5 | 6 | 512
+ 6 | 7 | 512
+(2 rows)
+
abort;
reset optimizer;
reset enable_answer_query_using_materialized_views;
diff --git a/src/test/regress/sql/aqumv.sql b/src/test/regress/sql/aqumv.sql
index 87fe401c2ab..35690d220e8 100644
--- a/src/test/regress/sql/aqumv.sql
+++ b/src/test/regress/sql/aqumv.sql
@@ -874,6 +874,106 @@ insert into t_insert select count(a) from t_select;
select * from t_insert;
abort;
+-- Test view has Group By
+begin;
+create table t0 as select i as a, i+1 as b , i+2 as c, i+3 as d from
generate_series(1, 5) i;
+insert into t0 select * from t0;
+insert into t0 select * from t0;
+insert into t0 select * from t0;
+insert into t0 select * from t0;
+insert into t0 select * from t0;
+insert into t0 select * from t0;
+insert into t0 select * from t0;
+insert into t0 select * from t0;
+insert into t0 select * from t0;
+analyze t0;
+create materialized view mv_group_0 as select c, b, sum(a), count(b) from t0
group by b, c;
+create materialized view mv_group_1 as select c, b, count(b) from t0 where a >
3 group by c, b;
+analyze mv_group_0;
+analyze mv_group_1;
+
+-- no qual, exactly match
+set local enable_answer_query_using_materialized_views = off;
+explain(costs off, verbose)
+select c, b, sum(a), count(b) from t0 group by b, c;
+select c, b, sum(a), count(b) from t0 group by b, c;
+set local enable_answer_query_using_materialized_views = on;
+explain(costs off, verbose)
+select c, b, sum(a), count(b) from t0 group by b, c;
+select c, b, sum(a), count(b) from t0 group by b, c;
+
+-- no qual, different order
+set local enable_answer_query_using_materialized_views = off;
+explain(costs off, verbose)
+select b, sum(a), c, count(b) from t0 group by c, b;
+select b, sum(a), c, count(b) from t0 group by c, b;
+set local enable_answer_query_using_materialized_views = on;
+explain(costs off, verbose)
+select b, sum(a), c, count(b) from t0 group by c, b;
+select b, sum(a), c, count(b) from t0 group by c, b;
+
+-- no qual, different expr
+set local enable_answer_query_using_materialized_views = off;
+explain(costs off, verbose)
+select b + c + 1, sum(a) + count(b) from t0 group by c, b;
+select b + c + 1, sum(a) + count(b) from t0 group by c, b;
+set local enable_answer_query_using_materialized_views = on;
+explain(costs off, verbose)
+select b + c + 1, sum(a) + count(b) from t0 group by c, b;
+select b + c + 1, sum(a) + count(b) from t0 group by c, b;
+
+-- no qual, should not match
+set local enable_answer_query_using_materialized_views = off;
+explain(costs off, verbose)
+select c, count(b) from t0 group by c ;
+select c, count(b) from t0 group by c ;
+set local enable_answer_query_using_materialized_views = on;
+explain(costs off, verbose)
+select c, count(b) from t0 group by c ;
+select c, count(b) from t0 group by c ;
+
+-- with qual, exactly match
+set local enable_answer_query_using_materialized_views = off;
+explain(costs off, verbose)
+select c, b, count(b) from t0 where a > 3 group by c, b;
+select c, b, count(b) from t0 where a > 3 group by c, b;
+set local enable_answer_query_using_materialized_views = on;
+explain(costs off, verbose)
+select c, b, count(b) from t0 where a > 3 group by c, b;
+select c, b, count(b) from t0 where a > 3 group by c, b;
+
+-- with qual, different order
+set local enable_answer_query_using_materialized_views = off;
+explain(costs off, verbose)
+select count(b), b, c from t0 where a > 3 group by b, c;
+select count(b), b, c from t0 where a > 3 group by b, c;
+set local enable_answer_query_using_materialized_views = on;
+explain(costs off, verbose)
+select count(b), b, c from t0 where a > 3 group by b, c;
+select count(b), b, c from t0 where a > 3 group by b, c;
+
+-- with qual, different expr
+set local enable_answer_query_using_materialized_views = off;
+explain(costs off, verbose)
+select count(b) + 1, b + 1, c from t0 where a > 3 group by b, c;
+select count(b) + 1, b + 1, c from t0 where a > 3 group by b, c;
+set local enable_answer_query_using_materialized_views = on;
+explain(costs off, verbose)
+select count(b) + 1, b + 1, c from t0 where a > 3 group by b, c;
+select count(b) + 1, b + 1, c from t0 where a > 3 group by b, c;
+
+-- with qual, should not match
+set local enable_answer_query_using_materialized_views = off;
+explain(costs off, verbose)
+select b, c, count(b) from t0 where a > 3 and b > 1 group by b, c;
+select b, c, count(b) from t0 where a > 3 and b > 1 group by b, c;
+set local enable_answer_query_using_materialized_views = on;
+explain(costs off, verbose)
+select b, c, count(b) from t0 where a > 3 and b > 1 group by b, c;
+select b, c, count(b) from t0 where a > 3 and b > 1 group by b, c;
+
+abort;
+
reset optimizer;
reset enable_answer_query_using_materialized_views;
-- start_ignore
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]