Skip to content

Commit 1555566

Browse files
committed
Set partitioned_rels appropriately when UNION ALL is used.
In most cases, this omission won't matter, because the appropriate locks will have been acquired during parse/plan or by AcquireExecutorLocks. But it's a bug all the same. Report by Ashutosh Bapat. Patch by me, reviewed by Amit Langote. Discussion: http://postgr.es/m/CAFjFpRdHb_ZnoDTuBXqrudWXh3H1ibLkr6nHsCFT96fSK4DXtA@mail.gmail.com
1 parent 1ab973a commit 1555566

File tree

2 files changed

+40
-8
lines changed

2 files changed

+40
-8
lines changed

src/backend/optimizer/path/allpaths.c

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,13 +1287,34 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
12871287
ListCell *l;
12881288
List *partitioned_rels = NIL;
12891289
RangeTblEntry *rte;
1290+
bool build_partitioned_rels = false;
12901291

1292+
/*
1293+
* A plain relation will already have a PartitionedChildRelInfo if it is
1294+
* partitioned. For a subquery RTE, no PartitionedChildRelInfo exists; we
1295+
* collect all partitioned_rels associated with any child. (This assumes
1296+
* that we don't need to look through multiple levels of subquery RTEs; if
1297+
* we ever do, we could create a PartitionedChildRelInfo with the
1298+
* accumulated list of partitioned_rels which would then be found when
1299+
* populated our parent rel with paths. For the present, that appears to
1300+
* be unnecessary.)
1301+
*/
12911302
rte = planner_rt_fetch(rel->relid, root);
1292-
if (rte->relkind == RELKIND_PARTITIONED_TABLE)
1303+
switch (rte->rtekind)
12931304
{
1294-
partitioned_rels = get_partitioned_child_rels(root, rel->relid);
1295-
/* The root partitioned table is included as a child rel */
1296-
Assert(list_length(partitioned_rels) >= 1);
1305+
case RTE_RELATION:
1306+
if (rte->relkind == RELKIND_PARTITIONED_TABLE)
1307+
{
1308+
partitioned_rels =
1309+
get_partitioned_child_rels(root, rel->relid);
1310+
Assert(list_length(partitioned_rels) >= 1);
1311+
}
1312+
break;
1313+
case RTE_SUBQUERY:
1314+
build_partitioned_rels = true;
1315+
break;
1316+
default:
1317+
elog(ERROR, "unexpcted rtekind: %d", (int) rte->rtekind);
12971318
}
12981319

12991320
/*
@@ -1306,6 +1327,19 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
13061327
RelOptInfo *childrel = lfirst(l);
13071328
ListCell *lcp;
13081329

1330+
/*
1331+
* If we need to build partitioned_rels, accumulate the partitioned
1332+
* rels for this child.
1333+
*/
1334+
if (build_partitioned_rels)
1335+
{
1336+
List *cprels;
1337+
1338+
cprels = get_partitioned_child_rels(root, childrel->relid);
1339+
partitioned_rels = list_concat(partitioned_rels,
1340+
list_copy(cprels));
1341+
}
1342+
13091343
/*
13101344
* If child has an unparameterized cheapest-total path, add that to
13111345
* the unparameterized Append path we are constructing for the parent.

src/backend/optimizer/plan/planner.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6076,7 +6076,8 @@ plan_cluster_use_sort(Oid tableOid, Oid indexOid)
60766076
* Returns a list of the RT indexes of the partitioned child relations
60776077
* with rti as the root parent RT index.
60786078
*
6079-
* Note: Only call this function on RTEs known to be partitioned tables.
6079+
* Note: This function might get called even for range table entries that
6080+
* are not partitioned tables; in such a case, it will simply return NIL.
60806081
*/
60816082
List *
60826083
get_partitioned_child_rels(PlannerInfo *root, Index rti)
@@ -6095,8 +6096,5 @@ get_partitioned_child_rels(PlannerInfo *root, Index rti)
60956096
}
60966097
}
60976098

6098-
/* The root partitioned table is included as a child rel */
6099-
Assert(list_length(result) >= 1);
6100-
61016099
return result;
61026100
}

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