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