mirror of
https://github.com/postgres/postgres.git
synced 2025-07-08 11:42:09 +03:00
Fix possible crash in partition-wise join.
The previous code assumed that we'd always succeed in creating child-joins for a joinrel for which partition-wise join was considered, but that's not guaranteed, at least in the case where dummy rels are involved. Ashutosh Bapat, with some wordsmithing by me. Discussion: http://postgr.es/m/CAFjFpRf8=uyMYYfeTBjWDMs1tR5t--FgOe2vKZPULxxdYQ4RNw@mail.gmail.com
This commit is contained in:
@ -3425,20 +3425,8 @@ generate_partition_wise_join_paths(PlannerInfo *root, RelOptInfo *rel)
|
||||
if (!IS_JOIN_REL(rel))
|
||||
return;
|
||||
|
||||
/*
|
||||
* If we've already proven this join is empty, we needn't consider any
|
||||
* more paths for it.
|
||||
*/
|
||||
if (IS_DUMMY_REL(rel))
|
||||
return;
|
||||
|
||||
/*
|
||||
* We've nothing to do if the relation is not partitioned. An outer join
|
||||
* relation which had an empty inner relation in every pair will have the
|
||||
* rest of the partitioning properties set except the child-join
|
||||
* RelOptInfos. See try_partition_wise_join() for more details.
|
||||
*/
|
||||
if (rel->nparts <= 0 || rel->part_rels == NULL)
|
||||
/* We've nothing to do if the relation is not partitioned. */
|
||||
if (!IS_PARTITIONED_REL(rel))
|
||||
return;
|
||||
|
||||
/* Guard against stack overflow due to overly deep partition hierarchy. */
|
||||
@ -3452,6 +3440,8 @@ generate_partition_wise_join_paths(PlannerInfo *root, RelOptInfo *rel)
|
||||
{
|
||||
RelOptInfo *child_rel = part_rels[cnt_parts];
|
||||
|
||||
Assert(child_rel != NULL);
|
||||
|
||||
/* Add partition-wise join paths for partitioned child-joins. */
|
||||
generate_partition_wise_join_paths(root, child_rel);
|
||||
|
||||
|
@ -1318,17 +1318,6 @@ try_partition_wise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
|
||||
if (!IS_PARTITIONED_REL(joinrel))
|
||||
return;
|
||||
|
||||
/*
|
||||
* set_rel_pathlist() may not create paths in children of an empty
|
||||
* partitioned table and so we can not add paths to child-joins. So, deem
|
||||
* such a join as unpartitioned. When a partitioned relation is deemed
|
||||
* empty because all its children are empty, dummy path will be set in
|
||||
* each of the children. In such a case we could still consider the join
|
||||
* as partitioned, but it might not help much.
|
||||
*/
|
||||
if (IS_DUMMY_REL(rel1) || IS_DUMMY_REL(rel2))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Since this join relation is partitioned, all the base relations
|
||||
* participating in this join must be partitioned and so are all the
|
||||
@ -1360,11 +1349,6 @@ try_partition_wise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
|
||||
|
||||
nparts = joinrel->nparts;
|
||||
|
||||
/* Allocate space to hold child-joins RelOptInfos, if not already done. */
|
||||
if (!joinrel->part_rels)
|
||||
joinrel->part_rels =
|
||||
(RelOptInfo **) palloc0(sizeof(RelOptInfo *) * nparts);
|
||||
|
||||
/*
|
||||
* Create child-join relations for this partitioned join, if those don't
|
||||
* exist. Add paths to child-joins for a pair of child relations
|
||||
|
Reference in New Issue
Block a user