Skip to content

Commit 21603eb

Browse files
committed
[AQUMV] Support LIMIT/OFFSET/FETCH clause on origin query.
If origin query has LIMIT clause, we could process it on view query. We could process FETCH too as ORDER BY is supported on origin query. create incremental materialized view mv as select c1 as mc1, c2 as mc2, c3 as mc3, c4 as mc4 from t1 where c1 > 90; Origin querys: select c2 from t1 where c1 > 90 limit 3 offset 4; select c2 from t1 where c1 > 90 order by c3, c4 fetch first 3 rows with ties; Could be rewritten to: select mc2 from mv order by mc1 limit 3 offset 4; select mc2 from mv order by mc3, mc4 fetch first 3 rows with ties; Authored-by: Zhang Mingli avamingli@gmail.com
1 parent c226e0c commit 21603eb

3 files changed

Lines changed: 318 additions & 1 deletion

File tree

src/backend/optimizer/plan/aqumv.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ answer_query_using_materialized_views(PlannerInfo *root,
209209
viewQuery->hasDistinctOn ||
210210
viewQuery->hasModifyingCTE ||
211211
viewQuery->hasSubLinks ||
212+
(limit_needed(viewQuery)) ||
212213
(viewQuery->groupClause != NIL) ||
213214
/* IVM doesn't support belows now, just in case. */
214215
(viewQuery->rowMarks != NIL) ||
@@ -261,6 +262,14 @@ answer_query_using_materialized_views(PlannerInfo *root,
261262
subroot->aggtransinfos = NIL;
262263
subroot->parse = viewQuery;
263264

265+
/*
266+
* AQUMV_FIXME:
267+
* We copy from root currently, but it's not true
268+
* if we support LIMIT node on view query.
269+
*/
270+
subroot->tuple_fraction = root->tuple_fraction;
271+
subroot->limit_tuples = root->limit_tuples;
272+
264273
/*
265274
* AQUMV
266275
* We have to rewrite now before we do the real Equivalent
@@ -345,6 +354,9 @@ answer_query_using_materialized_views(PlannerInfo *root,
345354
viewQuery->groupingSets = parse->groupingSets;
346355
viewQuery->sortClause = parse->sortClause;
347356
viewQuery->distinctClause = parse->distinctClause;
357+
viewQuery->limitOption = parse->limitOption;
358+
viewQuery->limitCount = parse->limitCount;
359+
viewQuery->limitOffset = parse->limitOffset;
348360

349361
/*
350362
* AQUMV
@@ -398,7 +410,6 @@ answer_query_using_materialized_views(PlannerInfo *root,
398410
* We don't use STD_FUZZ_FACTOR for cost comparisons like compare_path_costs_fuzzily here.
399411
* The STD_FUZZ_FACTOR is used to reduce paths of a rel, and keep the significantly ones.
400412
* But in AQUMV, we always have only one best path of rel at the last to compare.
401-
* TODO: limit clause and startup_cost.
402413
*/
403414
if (mv_final_rel->cheapest_total_path->total_cost < current_rel->cheapest_total_path->total_cost)
404415
{

src/test/regress/expected/aqumv.out

Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2163,6 +2163,259 @@ select distinct on(c1 - 1) c1, c2 from aqumv_t6 where c1 > 90 order by c1 - 1, c
21632163
(10 rows)
21642164

21652165
\pset null ''
2166+
abort;
2167+
-- Test LIMIT
2168+
begin;
2169+
create table aqumv_t7(c1 int, c2 int, c3 int, c4 int) distributed by (c1);
2170+
insert into aqumv_t7 select i, i+1, i+2, i+3 from generate_series(1, 100) i;
2171+
insert into aqumv_t7 select i, i+1, i+2, i+3 from generate_series(1, 100) i;
2172+
analyze aqumv_t7;
2173+
create incremental materialized view aqumv_mvt7_0 as
2174+
select c3 as cm3, c1 as mc1, c2 as mc2
2175+
from aqumv_t7 where c1 > 90;
2176+
analyze aqumv_mvt7_0;
2177+
-- LIMIT
2178+
set local enable_answer_query_using_materialized_views = off;
2179+
explain(costs off, verbose)
2180+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3;
2181+
QUERY PLAN
2182+
-----------------------------------------------------------------------------------
2183+
Limit
2184+
Output: c2, c3
2185+
-> Gather Motion 3:1 (slice1; segments: 3)
2186+
Output: c2, c3
2187+
Merge Key: c2, c3
2188+
-> Limit
2189+
Output: c2, c3
2190+
-> Sort
2191+
Output: c2, c3
2192+
Sort Key: aqumv_t7.c2, aqumv_t7.c3
2193+
-> Seq Scan on public.aqumv_t7
2194+
Output: c2, c3
2195+
Filter: (aqumv_t7.c1 > 90)
2196+
Settings: enable_answer_query_using_materialized_views = 'off', optimizer = 'off'
2197+
Optimizer: Postgres query optimizer
2198+
(15 rows)
2199+
2200+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3;
2201+
c2 | c3
2202+
----+----
2203+
92 | 93
2204+
92 | 93
2205+
93 | 94
2206+
(3 rows)
2207+
2208+
set local enable_answer_query_using_materialized_views = on;
2209+
explain(costs off, verbose)
2210+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3;
2211+
QUERY PLAN
2212+
----------------------------------------------------------------------------------
2213+
Limit
2214+
Output: mc2, cm3
2215+
-> Gather Motion 3:1 (slice1; segments: 3)
2216+
Output: mc2, cm3
2217+
Merge Key: mc2, cm3
2218+
-> Limit
2219+
Output: mc2, cm3
2220+
-> Sort
2221+
Output: mc2, cm3
2222+
Sort Key: aqumv_mvt7_0.mc2, aqumv_mvt7_0.cm3
2223+
-> Seq Scan on public.aqumv_mvt7_0
2224+
Output: mc2, cm3
2225+
Settings: enable_answer_query_using_materialized_views = 'on', optimizer = 'off'
2226+
Optimizer: Postgres query optimizer
2227+
(14 rows)
2228+
2229+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3;
2230+
c2 | c3
2231+
----+----
2232+
92 | 93
2233+
92 | 93
2234+
93 | 94
2235+
(3 rows)
2236+
2237+
-- OFFSET
2238+
set local enable_answer_query_using_materialized_views = off;
2239+
explain(costs off, verbose)
2240+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3 offset 4;
2241+
QUERY PLAN
2242+
-----------------------------------------------------------------------------------
2243+
Limit
2244+
Output: c2, c3
2245+
-> Gather Motion 3:1 (slice1; segments: 3)
2246+
Output: c2, c3
2247+
Merge Key: c2, c3
2248+
-> Limit
2249+
Output: c2, c3
2250+
-> Sort
2251+
Output: c2, c3
2252+
Sort Key: aqumv_t7.c2, aqumv_t7.c3
2253+
-> Seq Scan on public.aqumv_t7
2254+
Output: c2, c3
2255+
Filter: (aqumv_t7.c1 > 90)
2256+
Settings: enable_answer_query_using_materialized_views = 'off', optimizer = 'off'
2257+
Optimizer: Postgres query optimizer
2258+
(15 rows)
2259+
2260+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3 offset 4;
2261+
c2 | c3
2262+
----+----
2263+
94 | 95
2264+
94 | 95
2265+
95 | 96
2266+
(3 rows)
2267+
2268+
set local enable_answer_query_using_materialized_views = on;
2269+
explain(costs off, verbose)
2270+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3 offset 4;
2271+
QUERY PLAN
2272+
----------------------------------------------------------------------------------
2273+
Limit
2274+
Output: mc2, cm3
2275+
-> Gather Motion 3:1 (slice1; segments: 3)
2276+
Output: mc2, cm3
2277+
Merge Key: mc2, cm3
2278+
-> Limit
2279+
Output: mc2, cm3
2280+
-> Sort
2281+
Output: mc2, cm3
2282+
Sort Key: aqumv_mvt7_0.mc2, aqumv_mvt7_0.cm3
2283+
-> Seq Scan on public.aqumv_mvt7_0
2284+
Output: mc2, cm3
2285+
Settings: enable_answer_query_using_materialized_views = 'on', optimizer = 'off'
2286+
Optimizer: Postgres query optimizer
2287+
(14 rows)
2288+
2289+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3 offset 4;
2290+
c2 | c3
2291+
----+----
2292+
94 | 95
2293+
94 | 95
2294+
95 | 96
2295+
(3 rows)
2296+
2297+
-- FETCH
2298+
set local enable_answer_query_using_materialized_views = off;
2299+
explain(costs off, verbose)
2300+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows only;
2301+
QUERY PLAN
2302+
-----------------------------------------------------------------------------------
2303+
Limit
2304+
Output: c2, c3
2305+
-> Gather Motion 3:1 (slice1; segments: 3)
2306+
Output: c2, c3
2307+
Merge Key: c2, c3
2308+
-> Limit
2309+
Output: c2, c3
2310+
-> Sort
2311+
Output: c2, c3
2312+
Sort Key: aqumv_t7.c2, aqumv_t7.c3
2313+
-> Seq Scan on public.aqumv_t7
2314+
Output: c2, c3
2315+
Filter: (aqumv_t7.c1 > 90)
2316+
Settings: enable_answer_query_using_materialized_views = 'off', optimizer = 'off'
2317+
Optimizer: Postgres query optimizer
2318+
(15 rows)
2319+
2320+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows only;
2321+
c2 | c3
2322+
----+----
2323+
92 | 93
2324+
92 | 93
2325+
93 | 94
2326+
(3 rows)
2327+
2328+
set local enable_answer_query_using_materialized_views = on;
2329+
explain(costs off, verbose)
2330+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows only;
2331+
QUERY PLAN
2332+
----------------------------------------------------------------------------------
2333+
Limit
2334+
Output: mc2, cm3
2335+
-> Gather Motion 3:1 (slice1; segments: 3)
2336+
Output: mc2, cm3
2337+
Merge Key: mc2, cm3
2338+
-> Limit
2339+
Output: mc2, cm3
2340+
-> Sort
2341+
Output: mc2, cm3
2342+
Sort Key: aqumv_mvt7_0.mc2, aqumv_mvt7_0.cm3
2343+
-> Seq Scan on public.aqumv_mvt7_0
2344+
Output: mc2, cm3
2345+
Settings: enable_answer_query_using_materialized_views = 'on', optimizer = 'off'
2346+
Optimizer: Postgres query optimizer
2347+
(14 rows)
2348+
2349+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows only;
2350+
c2 | c3
2351+
----+----
2352+
92 | 93
2353+
92 | 93
2354+
93 | 94
2355+
(3 rows)
2356+
2357+
-- WITH TIES
2358+
set local enable_answer_query_using_materialized_views = off;
2359+
explain(costs off, verbose)
2360+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows with ties;
2361+
QUERY PLAN
2362+
-----------------------------------------------------------------------------------
2363+
Limit
2364+
Output: c2, c3
2365+
-> Gather Motion 3:1 (slice1; segments: 3)
2366+
Output: c2, c3
2367+
Merge Key: c2, c3
2368+
-> Limit
2369+
Output: c2, c3
2370+
-> Sort
2371+
Output: c2, c3
2372+
Sort Key: aqumv_t7.c2, aqumv_t7.c3
2373+
-> Seq Scan on public.aqumv_t7
2374+
Output: c2, c3
2375+
Filter: (aqumv_t7.c1 > 90)
2376+
Settings: enable_answer_query_using_materialized_views = 'off', optimizer = 'off'
2377+
Optimizer: Postgres query optimizer
2378+
(15 rows)
2379+
2380+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows with ties;
2381+
c2 | c3
2382+
----+----
2383+
92 | 93
2384+
92 | 93
2385+
93 | 94
2386+
93 | 94
2387+
(4 rows)
2388+
2389+
set local enable_answer_query_using_materialized_views = on;
2390+
explain(costs off, verbose)
2391+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows with ties;
2392+
QUERY PLAN
2393+
----------------------------------------------------------------------------------
2394+
Limit
2395+
Output: mc2, cm3
2396+
-> Gather Motion 3:1 (slice1; segments: 3)
2397+
Output: mc2, cm3
2398+
Merge Key: mc2, cm3
2399+
-> Limit
2400+
Output: mc2, cm3
2401+
-> Sort
2402+
Output: mc2, cm3
2403+
Sort Key: aqumv_mvt7_0.mc2, aqumv_mvt7_0.cm3
2404+
-> Seq Scan on public.aqumv_mvt7_0
2405+
Output: mc2, cm3
2406+
Settings: enable_answer_query_using_materialized_views = 'on', optimizer = 'off'
2407+
Optimizer: Postgres query optimizer
2408+
(14 rows)
2409+
2410+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows with ties;
2411+
c2 | c3
2412+
----+----
2413+
92 | 93
2414+
92 | 93
2415+
93 | 94
2416+
93 | 94
2417+
(4 rows)
2418+
21662419
abort;
21672420
reset optimizer;
21682421
reset enable_answer_query_using_materialized_views;

src/test/regress/sql/aqumv.sql

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,59 @@ select distinct on(c1 - 1) c1, c2 from aqumv_t6 where c1 > 90 order by c1 - 1, c
527527
\pset null ''
528528
abort;
529529

530+
-- Test LIMIT
531+
begin;
532+
create table aqumv_t7(c1 int, c2 int, c3 int, c4 int) distributed by (c1);
533+
insert into aqumv_t7 select i, i+1, i+2, i+3 from generate_series(1, 100) i;
534+
insert into aqumv_t7 select i, i+1, i+2, i+3 from generate_series(1, 100) i;
535+
analyze aqumv_t7;
536+
537+
create incremental materialized view aqumv_mvt7_0 as
538+
select c3 as cm3, c1 as mc1, c2 as mc2
539+
from aqumv_t7 where c1 > 90;
540+
analyze aqumv_mvt7_0;
541+
542+
-- LIMIT
543+
set local enable_answer_query_using_materialized_views = off;
544+
explain(costs off, verbose)
545+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3;
546+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3;
547+
set local enable_answer_query_using_materialized_views = on;
548+
explain(costs off, verbose)
549+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3;
550+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3;
551+
552+
-- OFFSET
553+
set local enable_answer_query_using_materialized_views = off;
554+
explain(costs off, verbose)
555+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3 offset 4;
556+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3 offset 4;
557+
set local enable_answer_query_using_materialized_views = on;
558+
explain(costs off, verbose)
559+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3 offset 4;
560+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 limit 3 offset 4;
561+
562+
-- FETCH
563+
set local enable_answer_query_using_materialized_views = off;
564+
explain(costs off, verbose)
565+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows only;
566+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows only;
567+
set local enable_answer_query_using_materialized_views = on;
568+
explain(costs off, verbose)
569+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows only;
570+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows only;
571+
572+
-- WITH TIES
573+
set local enable_answer_query_using_materialized_views = off;
574+
explain(costs off, verbose)
575+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows with ties;
576+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows with ties;
577+
set local enable_answer_query_using_materialized_views = on;
578+
explain(costs off, verbose)
579+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows with ties;
580+
select c2, c3 from aqumv_t7 where c1 > 90 order by c2, c3 fetch first 3 rows with ties;
581+
582+
abort;
530583

531584
reset optimizer;
532585
reset enable_answer_query_using_materialized_views;

0 commit comments

Comments
 (0)