Skip to content

Commit 9bfd282

Browse files
committed
Enable use of Memoize atop an Append that came from UNION ALL.
create_append_path() would only apply get_baserel_parampathinfo when the path is for a partitioned table, but it's also potentially useful for paths for UNION ALL appendrels. Specifically, that supports building a Memoize path atop this one. While we're in the vicinity, delete some dead code in create_merge_append_plan(): there's no need for it to support parameterized MergeAppend paths, and it doesn't look like that is going to change anytime soon. It'll be easy enough to undo this when/if it becomes useful. Richard Guo Discussion: https://postgr.es/m/CAMbWs4_ABSu4PWG2rE1q10tJugEXHWgru3U8dAgkoFvgrb6aEA@mail.gmail.com
1 parent 0dc4019 commit 9bfd282

File tree

4 files changed

+44
-18
lines changed

4 files changed

+44
-18
lines changed

src/backend/optimizer/plan/createplan.c

+2-10
Original file line numberDiff line numberDiff line change
@@ -1531,16 +1531,8 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path,
15311531

15321532
prunequal = extract_actual_clauses(rel->baserestrictinfo, false);
15331533

1534-
if (best_path->path.param_info)
1535-
{
1536-
List *prmquals = best_path->path.param_info->ppi_clauses;
1537-
1538-
prmquals = extract_actual_clauses(prmquals, false);
1539-
prmquals = (List *) replace_nestloop_params(root,
1540-
(Node *) prmquals);
1541-
1542-
prunequal = list_concat(prunequal, prmquals);
1543-
}
1534+
/* We don't currently generate any parameterized MergeAppend paths */
1535+
Assert(best_path->path.param_info == NULL);
15441536

15451537
if (prunequal != NIL)
15461538
node->part_prune_index = make_partition_pruneinfo(root, rel,

src/backend/optimizer/util/pathnode.c

+10-8
Original file line numberDiff line numberDiff line change
@@ -1256,15 +1256,17 @@ create_append_path(PlannerInfo *root,
12561256
pathnode->path.pathtarget = rel->reltarget;
12571257

12581258
/*
1259-
* When generating an Append path for a partitioned table, there may be
1260-
* parameterized quals that are useful for run-time pruning. Hence,
1261-
* compute path.param_info the same way as for any other baserel, so that
1262-
* such quals will be available for make_partition_pruneinfo(). (This
1263-
* would not work right for a non-baserel, ie a scan on a non-leaf child
1264-
* partition, and it's not necessary anyway in that case. Must skip it if
1265-
* we don't have "root", too.)
1259+
* If this is for a baserel (not a join or non-leaf partition), we prefer
1260+
* to apply get_baserel_parampathinfo to construct a full ParamPathInfo
1261+
* for the path. This supports building a Memoize path atop this path,
1262+
* and if this is a partitioned table the info may be useful for run-time
1263+
* pruning (cf make_partition_pruneinfo()).
1264+
*
1265+
* However, if we don't have "root" then that won't work and we fall back
1266+
* on the simpler get_appendrel_parampathinfo. There's no point in doing
1267+
* the more expensive thing for a dummy path, either.
12661268
*/
1267-
if (root && rel->reloptkind == RELOPT_BASEREL && IS_PARTITIONED_REL(rel))
1269+
if (rel->reloptkind == RELOPT_BASEREL && root && subpaths != NIL)
12681270
pathnode->path.param_info = get_baserel_parampathinfo(root,
12691271
rel,
12701272
required_outer);

src/test/regress/expected/memoize.out

+24
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,30 @@ SELECT * FROM prt t1 INNER JOIN prt t2 ON t1.a = t2.a;', false);
236236
Heap Fetches: N
237237
(21 rows)
238238

239+
-- Ensure memoize works with parameterized union-all Append path
240+
SET enable_partitionwise_join TO off;
241+
SELECT explain_memoize('
242+
SELECT * FROM prt_p1 t1 INNER JOIN
243+
(SELECT * FROM prt_p1 UNION ALL SELECT * FROM prt_p2) t2
244+
ON t1.a = t2.a;', false);
245+
explain_memoize
246+
-------------------------------------------------------------------------------------
247+
Nested Loop (actual rows=16 loops=N)
248+
-> Index Only Scan using iprt_p1_a on prt_p1 t1 (actual rows=4 loops=N)
249+
Heap Fetches: N
250+
-> Memoize (actual rows=4 loops=N)
251+
Cache Key: t1.a
252+
Cache Mode: logical
253+
Hits: 3 Misses: 1 Evictions: Zero Overflows: 0 Memory Usage: NkB
254+
-> Append (actual rows=4 loops=N)
255+
-> Index Only Scan using iprt_p1_a on prt_p1 (actual rows=4 loops=N)
256+
Index Cond: (a = t1.a)
257+
Heap Fetches: N
258+
-> Index Only Scan using iprt_p2_a on prt_p2 (actual rows=0 loops=N)
259+
Index Cond: (a = t1.a)
260+
Heap Fetches: N
261+
(14 rows)
262+
239263
DROP TABLE prt;
240264
RESET enable_partitionwise_join;
241265
-- Exercise Memoize code that flushes the cache when a parameter changes which

src/test/regress/sql/memoize.sql

+8
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,14 @@ ANALYZE prt;
121121
SELECT explain_memoize('
122122
SELECT * FROM prt t1 INNER JOIN prt t2 ON t1.a = t2.a;', false);
123123

124+
-- Ensure memoize works with parameterized union-all Append path
125+
SET enable_partitionwise_join TO off;
126+
127+
SELECT explain_memoize('
128+
SELECT * FROM prt_p1 t1 INNER JOIN
129+
(SELECT * FROM prt_p1 UNION ALL SELECT * FROM prt_p2) t2
130+
ON t1.a = t2.a;', false);
131+
124132
DROP TABLE prt;
125133

126134
RESET enable_partitionwise_join;

0 commit comments

Comments
 (0)