Commit 1555566d authored by Robert Haas's avatar Robert Haas

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
parent 1ab973ab
......@@ -1287,14 +1287,35 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
ListCell *l;
List *partitioned_rels = NIL;
RangeTblEntry *rte;
bool build_partitioned_rels = false;
/*
* A plain relation will already have a PartitionedChildRelInfo if it is
* partitioned. For a subquery RTE, no PartitionedChildRelInfo exists; we
* collect all partitioned_rels associated with any child. (This assumes
* that we don't need to look through multiple levels of subquery RTEs; if
* we ever do, we could create a PartitionedChildRelInfo with the
* accumulated list of partitioned_rels which would then be found when
* populated our parent rel with paths. For the present, that appears to
* be unnecessary.)
*/
rte = planner_rt_fetch(rel->relid, root);
switch (rte->rtekind)
{
case RTE_RELATION:
if (rte->relkind == RELKIND_PARTITIONED_TABLE)
{
partitioned_rels = get_partitioned_child_rels(root, rel->relid);
/* The root partitioned table is included as a child rel */
partitioned_rels =
get_partitioned_child_rels(root, rel->relid);
Assert(list_length(partitioned_rels) >= 1);
}
break;
case RTE_SUBQUERY:
build_partitioned_rels = true;
break;
default:
elog(ERROR, "unexpcted rtekind: %d", (int) rte->rtekind);
}
/*
* For every non-dummy child, remember the cheapest path. Also, identify
......@@ -1306,6 +1327,19 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
RelOptInfo *childrel = lfirst(l);
ListCell *lcp;
/*
* If we need to build partitioned_rels, accumulate the partitioned
* rels for this child.
*/
if (build_partitioned_rels)
{
List *cprels;
cprels = get_partitioned_child_rels(root, childrel->relid);
partitioned_rels = list_concat(partitioned_rels,
list_copy(cprels));
}
/*
* If child has an unparameterized cheapest-total path, add that to
* the unparameterized Append path we are constructing for the parent.
......
......@@ -6076,7 +6076,8 @@ plan_cluster_use_sort(Oid tableOid, Oid indexOid)
* Returns a list of the RT indexes of the partitioned child relations
* with rti as the root parent RT index.
*
* Note: Only call this function on RTEs known to be partitioned tables.
* Note: This function might get called even for range table entries that
* are not partitioned tables; in such a case, it will simply return NIL.
*/
List *
get_partitioned_child_rels(PlannerInfo *root, Index rti)
......@@ -6095,8 +6096,5 @@ get_partitioned_child_rels(PlannerInfo *root, Index rti)
}
}
/* The root partitioned table is included as a child rel */
Assert(list_length(result) >= 1);
return result;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment