Skip to content

Commit 2e27d4c

Browse files
committed
Fix ORDER BY lost after AQUMV join rewrite
The rewrite cleared sortClause, so grouping_planner() skipped adding a Sort node — queries with ORDER BY returned unsorted results from the MV scan. Fix: preserve sortClause and copy ressortgroupref to rewritten target entries so the upper planner generates Sort correctly. Before: Limit -> Gather -> Limit -> Seq Scan on mv After: Limit -> Gather -> Limit -> Sort -> Seq Scan on mv
1 parent e9abbe0 commit 2e27d4c

File tree

2 files changed

+17
-10
lines changed

2 files changed

+17
-10
lines changed

src/backend/optimizer/plan/aqumv.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,6 +1206,7 @@ answer_query_using_materialized_views_for_join(PlannerInfo *root, AqumvContext a
12061206
(AttrNumber) attnum,
12071207
old_tle->resname,
12081208
false);
1209+
new_tle->ressortgroupref = old_tle->ressortgroupref;
12091210
new_tlist = lappend(new_tlist, new_tle);
12101211
}
12111212

@@ -1243,11 +1244,11 @@ answer_query_using_materialized_views_for_join(PlannerInfo *root, AqumvContext a
12431244
viewQuery->jointree = makeFromExpr(list_make1(makeNode(RangeTblRef)), NULL);
12441245
((RangeTblRef *) linitial(viewQuery->jointree->fromlist))->rtindex = 1;
12451246

1246-
/* Clear aggregation/grouping/sorting state — all materialized. */
1247+
/* Clear aggregation/grouping state — already materialized in MV. */
12471248
viewQuery->hasAggs = false;
12481249
viewQuery->groupClause = NIL;
12491250
viewQuery->havingQual = NULL;
1250-
viewQuery->sortClause = NIL;
1251+
/* Keep sortClause: upper planner needs it to add Sort node. */
12511252
viewQuery->distinctClause = NIL;
12521253
viewQuery->hasDistinctOn = false;
12531254
viewQuery->hasWindowFuncs = false;

src/test/regress/expected/matview_data.out

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2077,14 +2077,17 @@ explain(costs off)
20772077
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
20782078
where o.status = 'shipped'
20792079
order by o.order_id limit 5;
2080-
QUERY PLAN
2081-
-------------------------------------------------
2080+
QUERY PLAN
2081+
-------------------------------------------------------
20822082
Limit
20832083
-> Gather Motion 3:1 (slice1; segments: 3)
2084+
Merge Key: order_id
20842085
-> Limit
2085-
-> Seq Scan on mv_aqj_limit_test
2086+
-> Sort
2087+
Sort Key: order_id
2088+
-> Seq Scan on mv_aqj_limit_test
20862089
Optimizer: Postgres query optimizer
2087-
(5 rows)
2090+
(8 rows)
20882091

20892092
-- 27. Match: FETCH FIRST WITH TIES exact match
20902093
create materialized view mv_aqj_with_ties as
@@ -2138,14 +2141,17 @@ explain(costs off)
21382141
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id
21392142
where o.status = 'pending'
21402143
order by o.order_id fetch first 5 rows with ties;
2141-
QUERY PLAN
2142-
------------------------------------------------
2144+
QUERY PLAN
2145+
------------------------------------------------------
21432146
Limit
21442147
-> Gather Motion 3:1 (slice1; segments: 3)
2148+
Merge Key: order_id
21452149
-> Limit
2146-
-> Seq Scan on mv_aqj_with_ties
2150+
-> Sort
2151+
Sort Key: order_id
2152+
-> Seq Scan on mv_aqj_with_ties
21472153
Optimizer: Postgres query optimizer
2148-
(5 rows)
2154+
(8 rows)
21492155

21502156
select o.order_id, o.amount
21512157
from aqj_orders o join aqj_customers c on o.customer_id = c.customer_id

0 commit comments

Comments
 (0)