Skip to content

Commit 1736a6c

Browse files
committed
Use ChunkAppend when the path is parameterized with clauses and not ordered
If it's parameterized with clauses, there's opportunity to use runtime chunk exclusion.
1 parent 4dab7e8 commit 1736a6c

3 files changed

Lines changed: 62 additions & 7 deletions

File tree

src/planner/planner.c

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,16 +1018,34 @@ static inline bool
10181018
should_chunk_append(Hypertable *ht, PlannerInfo *root, RelOptInfo *rel, Path *path, bool ordered,
10191019
int order_attno)
10201020
{
1021-
if (path->param_info != NULL && ordered)
1021+
if (path->param_info != NULL)
10221022
{
1023+
if (ordered)
1024+
{
1025+
/*
1026+
* Ordered ChunkAppend might create MergeAppend path for individual
1027+
* chunks when we have space partitioning or partial chunks. MergeAppend
1028+
* paths cannot be parameterized. Refuse to use parameterized ordered
1029+
* ChunkAppend altogether, because the more precise conditions are
1030+
* difficult to check.
1031+
*/
1032+
return false;
1033+
}
1034+
1035+
if (path->param_info->ppi_clauses != NIL)
1036+
{
1037+
/*
1038+
* If we have any parameterized clauses, we can apply runtime chunk
1039+
* exclusion.
1040+
*/
1041+
return true;
1042+
}
1043+
10231044
/*
1024-
* Ordered ChunkAppend might create MergeAppend path for individual
1025-
* chunks when we have space partitioning or partial chunks. MergeAppend
1026-
* paths cannot be parameterized. Refuse to use parameterized ordered
1027-
* ChunkAppend altogether, because the more precise conditions are
1028-
* difficult to check.
1045+
* The path can be parameterized but not have any parameterized clauses,
1046+
* effectively if it's a cross join written as LATERAL. Check the other
1047+
* conditions for chunk append in this case.
10291048
*/
1030-
return false;
10311049
}
10321050

10331051
if (

tsl/test/shared/expected/parameterized_chunkappend-17.out

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,33 @@ ORDER BY devices.device_id, win.id
4343
-> Index Only Scan using _hyper_X_X_chunk_metrics_device_id_time_idx on _hyper_X_X_chunk (actual rows=360.00 loops=3)
4444
Index Cond: ((device_id = devices.device_id) AND ("time" >= "*VALUES*".column2) AND ("time" < "*VALUES*".column3) AND ("time" > (now() - '@ 100 years'::interval)))
4545

46+
:PREFIX
47+
SELECT time FROM unnest(array['2000-01-10 1:00+0'::timestamptz]) AS vars(v)
48+
JOIN metrics ON time = vars.v;
49+
--- QUERY PLAN ---
50+
Nested Loop (actual rows=5.00 loops=1)
51+
-> Function Scan on unnest vars (actual rows=1.00 loops=1)
52+
-> Custom Scan (ChunkAppend) on metrics (actual rows=5.00 loops=1)
53+
Chunks excluded during runtime: 2
54+
-> Index Only Scan using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed)
55+
Index Cond: ("time" = vars.v)
56+
-> Index Only Scan using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (actual rows=5.00 loops=1)
57+
Index Cond: ("time" = vars.v)
58+
-> Index Only Scan using _hyper_X_X_chunk_metrics_time_idx on _hyper_X_X_chunk (never executed)
59+
Index Cond: ("time" = vars.v)
60+
61+
:PREFIX
62+
SELECT count(s.w) FROM unnest(array[1]::int[]) AS vars(v)
63+
LEFT JOIN LATERAL (SELECT vars.v AS w FROM metrics) s ON true;
64+
--- QUERY PLAN ---
65+
Aggregate (actual rows=1.00 loops=1)
66+
-> Nested Loop Left Join (actual rows=68370.00 loops=1)
67+
-> Function Scan on unnest vars (actual rows=1.00 loops=1)
68+
-> Append (actual rows=68370.00 loops=1)
69+
-> Seq Scan on _hyper_X_X_chunk (actual rows=17990.00 loops=1)
70+
-> Seq Scan on _hyper_X_X_chunk (actual rows=25190.00 loops=1)
71+
-> Seq Scan on _hyper_X_X_chunk (actual rows=25190.00 loops=1)
72+
4673
RESET enable_hashjoin;
4774
RESET enable_mergejoin;
4875
RESET enable_material;

tsl/test/shared/sql/parameterized_chunkappend.sql.in

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,20 @@ GROUP BY devices.device_id, win.id
2828
ORDER BY devices.device_id, win.id
2929
;
3030

31+
:PREFIX
32+
SELECT time FROM unnest(array['2000-01-10 1:00+0'::timestamptz]) AS vars(v)
33+
JOIN metrics ON time = vars.v;
34+
35+
:PREFIX
36+
SELECT count(s.w) FROM unnest(array[1]::int[]) AS vars(v)
37+
LEFT JOIN LATERAL (SELECT vars.v AS w FROM metrics) s ON true;
38+
39+
3140
RESET enable_hashjoin;
3241
RESET enable_mergejoin;
3342
RESET enable_material;
3443

44+
3545
-- #9607: PlaceHolderVar in runtime chunk exclusion clauses used to trip
3646
-- pull_var_clause with flag 0. GROUP BY ROLLUP on a view over a hypertable
3747
-- combined with a join and a generic plan can produce such PlaceHolderVars.

0 commit comments

Comments
 (0)