diff --git a/src/backend/optimizer/plan/aqumv.c b/src/backend/optimizer/plan/aqumv.c index cefd868771e..238e719d7c1 100644 --- a/src/backend/optimizer/plan/aqumv.c +++ b/src/backend/optimizer/plan/aqumv.c @@ -209,6 +209,7 @@ answer_query_using_materialized_views(PlannerInfo *root, viewQuery->hasDistinctOn || viewQuery->hasModifyingCTE || viewQuery->hasSubLinks || + (limit_needed(viewQuery)) || (viewQuery->groupClause != NIL) || /* IVM doesn't support belows now, just in case. */ (viewQuery->rowMarks != NIL) || @@ -261,6 +262,14 @@ answer_query_using_materialized_views(PlannerInfo *root, subroot->aggtransinfos = NIL; subroot->parse = viewQuery; + /* + * AQUMV_FIXME: + * We copy from root currently, but it's not true + * if we support LIMIT node on view query. + */ + subroot->tuple_fraction = root->tuple_fraction; + subroot->limit_tuples = root->limit_tuples; + /* * AQUMV * We have to rewrite now before we do the real Equivalent @@ -345,6 +354,9 @@ answer_query_using_materialized_views(PlannerInfo *root, viewQuery->groupingSets = parse->groupingSets; viewQuery->sortClause = parse->sortClause; viewQuery->distinctClause = parse->distinctClause; + viewQuery->limitOption = parse->limitOption; + viewQuery->limitCount = parse->limitCount; + viewQuery->limitOffset = parse->limitOffset; /* * AQUMV @@ -398,7 +410,6 @@ answer_query_using_materialized_views(PlannerInfo *root, * We don't use STD_FUZZ_FACTOR for cost comparisons like compare_path_costs_fuzzily here. * The STD_FUZZ_FACTOR is used to reduce paths of a rel, and keep the significantly ones. * But in AQUMV, we always have only one best path of rel at the last to compare. - * TODO: limit clause and startup_cost. */ if (mv_final_rel->cheapest_total_path->total_cost < current_rel->cheapest_total_path->total_cost) { diff --git a/src/test/regress/expected/aqumv.out b/src/test/regress/expected/aqumv.out index 0694dbcae97..80ec2f2507c 100644 --- a/src/test/regress/expected/aqumv.out +++ b/src/test/regress/expected/aqumv.out @@ -2163,6 +2163,259 @@ select distinct on(c1 - 1) c1, c2 from aqumv_t6 where c1 > 90 order by c1 - 1, c (10 rows) \pset null '' +abort; +-- Test LIMIT +begin; +create table aqumv_t7(c1 int, c2 int, c3 int, c4 int) distributed by (c1); +insert into aqumv_t7 select i, i+1, i+2, i+3 from generate_series(1, 100) i; +insert into aqumv_t7 select i, i+1, i+2, i+3 from generate_series(1, 100) i; +analyze aqumv_t7; +create incremental materialized view aqumv_mvt7_0 as + select c3 as cm3, c1 as mc1, c2 as mc2 + from aqumv_t7 where c1 > 90; +analyze aqumv_mvt7_0; +-- LIMIT +set local enable_answer_query_using_materialized_views = off; +explain(costs off, verbose) +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3; + QUERY PLAN +----------------------------------------------------------------------------------- + Limit + Output: c2, c3 + -> Gather Motion 3:1 (slice1; segments: 3) + Output: c2, c3 + Merge Key: c2, c3 + -> Limit + Output: c2, c3 + -> Sort + Output: c2, c3 + Sort Key: aqumv_t7.c2, aqumv_t7.c3 + -> Seq Scan on public.aqumv_t7 + Output: c2, c3 + Filter: (aqumv_t7.c1 > 90) + Settings: enable_answer_query_using_materialized_views = 'off', optimizer = 'off' + Optimizer: Postgres query optimizer +(15 rows) + +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3; + c2 | c3 +----+---- + 92 | 93 + 92 | 93 + 93 | 94 +(3 rows) + +set local enable_answer_query_using_materialized_views = on; +explain(costs off, verbose) +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3; + QUERY PLAN +---------------------------------------------------------------------------------- + Limit + Output: mc2, cm3 + -> Gather Motion 3:1 (slice1; segments: 3) + Output: mc2, cm3 + Merge Key: mc2, cm3 + -> Limit + Output: mc2, cm3 + -> Sort + Output: mc2, cm3 + Sort Key: aqumv_mvt7_0.mc2, aqumv_mvt7_0.cm3 + -> Seq Scan on public.aqumv_mvt7_0 + Output: mc2, cm3 + Settings: enable_answer_query_using_materialized_views = 'on', optimizer = 'off' + Optimizer: Postgres query optimizer +(14 rows) + +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3; + c2 | c3 +----+---- + 92 | 93 + 92 | 93 + 93 | 94 +(3 rows) + +-- OFFSET +set local enable_answer_query_using_materialized_views = off; +explain(costs off, verbose) +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3 offset 4; + QUERY PLAN +----------------------------------------------------------------------------------- + Limit + Output: c2, c3 + -> Gather Motion 3:1 (slice1; segments: 3) + Output: c2, c3 + Merge Key: c2, c3 + -> Limit + Output: c2, c3 + -> Sort + Output: c2, c3 + Sort Key: aqumv_t7.c2, aqumv_t7.c3 + -> Seq Scan on public.aqumv_t7 + Output: c2, c3 + Filter: (aqumv_t7.c1 > 90) + Settings: enable_answer_query_using_materialized_views = 'off', optimizer = 'off' + Optimizer: Postgres query optimizer +(15 rows) + +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3 offset 4; + c2 | c3 +----+---- + 94 | 95 + 94 | 95 + 95 | 96 +(3 rows) + +set local enable_answer_query_using_materialized_views = on; +explain(costs off, verbose) +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3 offset 4; + QUERY PLAN +---------------------------------------------------------------------------------- + Limit + Output: mc2, cm3 + -> Gather Motion 3:1 (slice1; segments: 3) + Output: mc2, cm3 + Merge Key: mc2, cm3 + -> Limit + Output: mc2, cm3 + -> Sort + Output: mc2, cm3 + Sort Key: aqumv_mvt7_0.mc2, aqumv_mvt7_0.cm3 + -> Seq Scan on public.aqumv_mvt7_0 + Output: mc2, cm3 + Settings: enable_answer_query_using_materialized_views = 'on', optimizer = 'off' + Optimizer: Postgres query optimizer +(14 rows) + +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3 offset 4; + c2 | c3 +----+---- + 94 | 95 + 94 | 95 + 95 | 96 +(3 rows) + +-- FETCH +set local enable_answer_query_using_materialized_views = off; +explain(costs off, verbose) +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows only; + QUERY PLAN +----------------------------------------------------------------------------------- + Limit + Output: c2, c3 + -> Gather Motion 3:1 (slice1; segments: 3) + Output: c2, c3 + Merge Key: c2, c3 + -> Limit + Output: c2, c3 + -> Sort + Output: c2, c3 + Sort Key: aqumv_t7.c2, aqumv_t7.c3 + -> Seq Scan on public.aqumv_t7 + Output: c2, c3 + Filter: (aqumv_t7.c1 > 90) + Settings: enable_answer_query_using_materialized_views = 'off', optimizer = 'off' + Optimizer: Postgres query optimizer +(15 rows) + +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows only; + c2 | c3 +----+---- + 92 | 93 + 92 | 93 + 93 | 94 +(3 rows) + +set local enable_answer_query_using_materialized_views = on; +explain(costs off, verbose) +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows only; + QUERY PLAN +---------------------------------------------------------------------------------- + Limit + Output: mc2, cm3 + -> Gather Motion 3:1 (slice1; segments: 3) + Output: mc2, cm3 + Merge Key: mc2, cm3 + -> Limit + Output: mc2, cm3 + -> Sort + Output: mc2, cm3 + Sort Key: aqumv_mvt7_0.mc2, aqumv_mvt7_0.cm3 + -> Seq Scan on public.aqumv_mvt7_0 + Output: mc2, cm3 + Settings: enable_answer_query_using_materialized_views = 'on', optimizer = 'off' + Optimizer: Postgres query optimizer +(14 rows) + +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows only; + c2 | c3 +----+---- + 92 | 93 + 92 | 93 + 93 | 94 +(3 rows) + +-- WITH TIES +set local enable_answer_query_using_materialized_views = off; +explain(costs off, verbose) +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows with ties; + QUERY PLAN +----------------------------------------------------------------------------------- + Limit + Output: c2, c3 + -> Gather Motion 3:1 (slice1; segments: 3) + Output: c2, c3 + Merge Key: c2, c3 + -> Limit + Output: c2, c3 + -> Sort + Output: c2, c3 + Sort Key: aqumv_t7.c2, aqumv_t7.c3 + -> Seq Scan on public.aqumv_t7 + Output: c2, c3 + Filter: (aqumv_t7.c1 > 90) + Settings: enable_answer_query_using_materialized_views = 'off', optimizer = 'off' + Optimizer: Postgres query optimizer +(15 rows) + +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows with ties; + c2 | c3 +----+---- + 92 | 93 + 92 | 93 + 93 | 94 + 93 | 94 +(4 rows) + +set local enable_answer_query_using_materialized_views = on; +explain(costs off, verbose) +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows with ties; + QUERY PLAN +---------------------------------------------------------------------------------- + Limit + Output: mc2, cm3 + -> Gather Motion 3:1 (slice1; segments: 3) + Output: mc2, cm3 + Merge Key: mc2, cm3 + -> Limit + Output: mc2, cm3 + -> Sort + Output: mc2, cm3 + Sort Key: aqumv_mvt7_0.mc2, aqumv_mvt7_0.cm3 + -> Seq Scan on public.aqumv_mvt7_0 + Output: mc2, cm3 + Settings: enable_answer_query_using_materialized_views = 'on', optimizer = 'off' + Optimizer: Postgres query optimizer +(14 rows) + +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows with ties; + c2 | c3 +----+---- + 92 | 93 + 92 | 93 + 93 | 94 + 93 | 94 +(4 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 86af470541f..3fcb47ed631 100644 --- a/src/test/regress/sql/aqumv.sql +++ b/src/test/regress/sql/aqumv.sql @@ -527,6 +527,59 @@ select distinct on(c1 - 1) c1, c2 from aqumv_t6 where c1 > 90 order by c1 - 1, c \pset null '' abort; +-- Test LIMIT +begin; +create table aqumv_t7(c1 int, c2 int, c3 int, c4 int) distributed by (c1); +insert into aqumv_t7 select i, i+1, i+2, i+3 from generate_series(1, 100) i; +insert into aqumv_t7 select i, i+1, i+2, i+3 from generate_series(1, 100) i; +analyze aqumv_t7; + +create incremental materialized view aqumv_mvt7_0 as + select c3 as cm3, c1 as mc1, c2 as mc2 + from aqumv_t7 where c1 > 90; +analyze aqumv_mvt7_0; + +-- LIMIT +set local enable_answer_query_using_materialized_views = off; +explain(costs off, verbose) +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3; +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3; +set local enable_answer_query_using_materialized_views = on; +explain(costs off, verbose) +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3; +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3; + +-- OFFSET +set local enable_answer_query_using_materialized_views = off; +explain(costs off, verbose) +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3 offset 4; +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3 offset 4; +set local enable_answer_query_using_materialized_views = on; +explain(costs off, verbose) +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3 offset 4; +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3 offset 4; + +-- FETCH +set local enable_answer_query_using_materialized_views = off; +explain(costs off, verbose) +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows only; +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows only; +set local enable_answer_query_using_materialized_views = on; +explain(costs off, verbose) +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows only; +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows only; + +-- WITH TIES +set local enable_answer_query_using_materialized_views = off; +explain(costs off, verbose) +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows with ties; +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows with ties; +set local enable_answer_query_using_materialized_views = on; +explain(costs off, verbose) +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows with ties; +select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows with ties; + +abort; reset optimizer; reset enable_answer_query_using_materialized_views;