Skip to content

Commit e8d5dd6

Browse files
committed
Get rid of duplicate child RTE for a partitioned table.
We've been creating duplicate RTEs for partitioned tables just because we do so for regular inheritance parent tables. But unlike regular-inheritance parents which are themselves regular tables and thus need to be scanned, partitioned tables don't need the extra RTE. This makes the conditions for building a child RTE the same as those for building an AppendRelInfo, allowing minor simplification in expand_single_inheritance_child. Since the planner's actual processing is driven off the AppendRelInfo list, nothing much changes beyond that, we just have one fewer useless RTE entry. Amit Langote, reviewed and hacked a bit by me Discussion: https://postgr.es/m/9d7c5112-cb99-6a47-d3be-cf1ee6862a1d@lab.ntt.co.jp
1 parent 1af25ca commit e8d5dd6

File tree

2 files changed

+45
-43
lines changed

2 files changed

+45
-43
lines changed

contrib/postgres_fdw/expected/postgres_fdw.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8435,7 +8435,7 @@ SELECT t1.a,t2.b,t2.c FROM fprt1 t1 LEFT JOIN (SELECT * FROM fprt2 WHERE a < 10)
84358435
Foreign Scan
84368436
Output: t1.a, ftprt2_p1.b, ftprt2_p1.c
84378437
Relations: (public.ftprt1_p1 t1) LEFT JOIN (public.ftprt2_p1 fprt2)
8438-
Remote SQL: SELECT r6.a, r9.b, r9.c FROM (public.fprt1_p1 r6 LEFT JOIN public.fprt2_p1 r9 ON (((r6.a = r9.b)) AND ((r6.b = r9.a)) AND ((r9.a < 10)))) WHERE ((r6.a < 10)) ORDER BY r6.a ASC NULLS LAST, r9.b ASC NULLS LAST, r9.c ASC NULLS LAST
8438+
Remote SQL: SELECT r5.a, r7.b, r7.c FROM (public.fprt1_p1 r5 LEFT JOIN public.fprt2_p1 r7 ON (((r5.a = r7.b)) AND ((r5.b = r7.a)) AND ((r7.a < 10)))) WHERE ((r5.a < 10)) ORDER BY r5.a ASC NULLS LAST, r7.b ASC NULLS LAST, r7.c ASC NULLS LAST
84398439
(4 rows)
84408440

84418441
SELECT t1.a,t2.b,t2.c FROM fprt1 t1 LEFT JOIN (SELECT * FROM fprt2 WHERE a < 10) t2 ON (t1.a = t2.b and t1.b = t2.a) WHERE t1.a < 10 ORDER BY 1,2,3;

src/backend/optimizer/util/inherit.c

Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,10 @@ expand_inherited_tables(PlannerInfo *root)
9090
* A childless table is never considered to be an inheritance set. For
9191
* regular inheritance, a parent RTE must always have at least two associated
9292
* AppendRelInfos: one corresponding to the parent table as a simple member of
93-
* inheritance set and one or more corresponding to the actual children.
94-
* Since a partitioned table is not scanned, it might have only one associated
95-
* AppendRelInfo.
93+
* the inheritance set and one or more corresponding to the actual children.
94+
* (But a partitioned table might have only one associated AppendRelInfo,
95+
* since it's not itself scanned and hence doesn't need a second RTE to
96+
* represent itself as a member of the set.)
9697
*/
9798
static void
9899
expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti)
@@ -145,6 +146,9 @@ expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti)
145146
/* Scan the inheritance set and expand it */
146147
if (oldrelation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
147148
{
149+
/*
150+
* Partitioned table, so set up for partitioning.
151+
*/
148152
Assert(rte->relkind == RELKIND_PARTITIONED_TABLE);
149153

150154
if (root->glob->partition_directory == NULL)
@@ -161,6 +165,11 @@ expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti)
161165
}
162166
else
163167
{
168+
/*
169+
* Ordinary table, so process traditional-inheritance children. (Note
170+
* that partitioned tables are not allowed to have inheritance
171+
* children, so it's not possible for both cases to apply.)
172+
*/
164173
List *appinfos = NIL;
165174
RangeTblEntry *childrte;
166175
Index childRTindex;
@@ -182,8 +191,7 @@ expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti)
182191
}
183192

184193
/*
185-
* This table has no partitions. Expand any plain inheritance
186-
* children in the order the OIDs were returned by
194+
* Expand inheritance children in the order the OIDs were returned by
187195
* find_all_inheritors.
188196
*/
189197
foreach(l, inhOIDs)
@@ -273,11 +281,6 @@ expand_partitioned_rtentry(PlannerInfo *root, RangeTblEntry *parentrte,
273281
root->partColsUpdated =
274282
has_partition_attrs(parentrel, parentrte->updatedCols, NULL);
275283

276-
/* First expand the partitioned table itself. */
277-
expand_single_inheritance_child(root, parentrte, parentRTindex, parentrel,
278-
top_parentrc, parentrel,
279-
appinfos, &childrte, &childRTindex);
280-
281284
/*
282285
* If the partitioned table has no partitions, treat this as the
283286
* non-inheritance case.
@@ -288,6 +291,11 @@ expand_partitioned_rtentry(PlannerInfo *root, RangeTblEntry *parentrte,
288291
return;
289292
}
290293

294+
/*
295+
* Create a child RTE for each partition. Note that unlike traditional
296+
* inheritance, we don't need a child RTE for the partitioned table
297+
* itself, because it's not going to be scanned.
298+
*/
291299
for (i = 0; i < partdesc->nparts; i++)
292300
{
293301
Oid childOID = partdesc->oids[i];
@@ -321,8 +329,7 @@ expand_partitioned_rtentry(PlannerInfo *root, RangeTblEntry *parentrte,
321329

322330
/*
323331
* expand_single_inheritance_child
324-
* Build a RangeTblEntry and an AppendRelInfo, if appropriate, plus
325-
* maybe a PlanRowMark.
332+
* Build a RangeTblEntry and an AppendRelInfo, plus maybe a PlanRowMark.
326333
*
327334
* We now expand the partition hierarchy level by level, creating a
328335
* corresponding hierarchy of AppendRelInfos and RelOptInfos, where each
@@ -371,9 +378,11 @@ expand_single_inheritance_child(PlannerInfo *root, RangeTblEntry *parentrte,
371378
childrte->relid = childOID;
372379
childrte->relkind = childrel->rd_rel->relkind;
373380
/* A partitioned child will need to be expanded further. */
374-
if (childOID != parentOID &&
375-
childrte->relkind == RELKIND_PARTITIONED_TABLE)
381+
if (childrte->relkind == RELKIND_PARTITIONED_TABLE)
382+
{
383+
Assert(childOID != parentOID);
376384
childrte->inh = true;
385+
}
377386
else
378387
childrte->inh = false;
379388
childrte->requiredPerms = 0;
@@ -383,36 +392,29 @@ expand_single_inheritance_child(PlannerInfo *root, RangeTblEntry *parentrte,
383392
*childRTindex_p = childRTindex;
384393

385394
/*
386-
* We need an AppendRelInfo if paths will be built for the child RTE. If
387-
* childrte->inh is true, then we'll always need to generate append paths
388-
* for it. If childrte->inh is false, we must scan it if it's not a
389-
* partitioned table; but if it is a partitioned table, then it never has
390-
* any data of its own and need not be scanned.
395+
* Build an AppendRelInfo struct for each parent/child pair.
391396
*/
392-
if (childrte->relkind != RELKIND_PARTITIONED_TABLE || childrte->inh)
393-
{
394-
appinfo = make_append_rel_info(parentrel, childrel,
395-
parentRTindex, childRTindex);
396-
*appinfos = lappend(*appinfos, appinfo);
397+
appinfo = make_append_rel_info(parentrel, childrel,
398+
parentRTindex, childRTindex);
399+
*appinfos = lappend(*appinfos, appinfo);
397400

398-
/*
399-
* Translate the column permissions bitmaps to the child's attnums (we
400-
* have to build the translated_vars list before we can do this). But
401-
* if this is the parent table, leave copyObject's result alone.
402-
*
403-
* Note: we need to do this even though the executor won't run any
404-
* permissions checks on the child RTE. The insertedCols/updatedCols
405-
* bitmaps may be examined for trigger-firing purposes.
406-
*/
407-
if (childOID != parentOID)
408-
{
409-
childrte->selectedCols = translate_col_privs(parentrte->selectedCols,
410-
appinfo->translated_vars);
411-
childrte->insertedCols = translate_col_privs(parentrte->insertedCols,
412-
appinfo->translated_vars);
413-
childrte->updatedCols = translate_col_privs(parentrte->updatedCols,
414-
appinfo->translated_vars);
415-
}
401+
/*
402+
* Translate the column permissions bitmaps to the child's attnums (we
403+
* have to build the translated_vars list before we can do this). But if
404+
* this is the parent table, we can leave copyObject's result alone.
405+
*
406+
* Note: we need to do this even though the executor won't run any
407+
* permissions checks on the child RTE. The insertedCols/updatedCols
408+
* bitmaps may be examined for trigger-firing purposes.
409+
*/
410+
if (childOID != parentOID)
411+
{
412+
childrte->selectedCols = translate_col_privs(parentrte->selectedCols,
413+
appinfo->translated_vars);
414+
childrte->insertedCols = translate_col_privs(parentrte->insertedCols,
415+
appinfo->translated_vars);
416+
childrte->updatedCols = translate_col_privs(parentrte->updatedCols,
417+
appinfo->translated_vars);
416418
}
417419

418420
/*

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy