On Sat, Oct 7, 2017 at 1:04 AM, Robert Haas <robertmh...@gmail.com> wrote: > > Committed. I hope that makes things less red rather than more, > because I'm going to be AFK for a few hours anyway. >
Here's the last patch, dealing with the dummy relations, rebased. With this fix every join order of a partitioned join can be considered partitioned. (This wasn't the case earlier when dummy relation was involved.). So, we can allocate the child-join RelOptInfo array in build_joinrel_partition_info(), instead of waiting for an appropriate pair to arrive in try_partition_wise_join(). -- Best Wishes, Ashutosh Bapat EnterpriseDB Corporation The Postgres Database Company
From 4bf8ca38719aee730ed57a7f14522384b1ced7b0 Mon Sep 17 00:00:00 2001 From: Ashutosh Bapat <ashutosh.ba...@enterprisedb.com> Date: Tue, 29 Aug 2017 12:37:14 +0530 Subject: [PATCH] Support partition-wise join for dummy partitioned relation. Current partition-wise join implementation treats dummy relations as unpartitioned since the child relations may not be marked dummy and may not have their pathlists set (See set_rel_size() and set_rel_pathlist()). Since children do not have paths set, they can not be used to form a child-join. This patch marks the children of dummy partitioned relations as dummy, thus allowing partition-wise join when one of the joining relations is dummy. If the dummy partitioned relation is a base relation, its children are base relations as well and we will be marking base relation dummy during join planning. But this shouldn't be a problem since populate_joinrel_with_paths() already does that to an inner relation of left join. Ashutosh Bapat. --- src/backend/optimizer/path/allpaths.c | 7 +------ src/backend/optimizer/path/joinrels.c | 24 ++++++++++++------------ src/backend/optimizer/util/relnode.c | 5 +++++ 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 5535b63..b46fb5b 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -3261,12 +3261,7 @@ generate_partition_wise_join_paths(PlannerInfo *root, RelOptInfo *rel) if (IS_DUMMY_REL(rel)) return; - /* - * Nothing to do if the relation is not partitioned. An outer join - * relation which had empty inner relation in every pair will have rest of - * the partitioning properties set except the child-join RelOptInfos. See - * try_partition_wise_join() for more explanation. - */ + /* Nothing to do if the relation is not partitioned. */ if (rel->nparts <= 0 || rel->part_rels == NULL) return; diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c index 2b868c5..1578dea 100644 --- a/src/backend/optimizer/path/joinrels.c +++ b/src/backend/optimizer/path/joinrels.c @@ -1321,14 +1321,19 @@ try_partition_wise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, /* * 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. + * partitioned table. Mark such children as dummy so that we can add paths + * to child-joins. */ - if (IS_DUMMY_REL(rel1) || IS_DUMMY_REL(rel2)) - return; + if (IS_DUMMY_REL(rel1)) + { + for (cnt_parts = 0; cnt_parts < rel1->nparts; cnt_parts++) + mark_dummy_rel(rel1->part_rels[cnt_parts]); + } + if (IS_DUMMY_REL(rel2)) + { + for (cnt_parts = 0; cnt_parts < rel2->nparts; cnt_parts++) + mark_dummy_rel(rel2->part_rels[cnt_parts]); + } /* * Since this join relation is partitioned, all the base relations @@ -1361,11 +1366,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 diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c index 3bd1063..21fd29f 100644 --- a/src/backend/optimizer/util/relnode.c +++ b/src/backend/optimizer/util/relnode.c @@ -1746,4 +1746,9 @@ build_joinrel_partition_info(RelOptInfo *joinrel, RelOptInfo *outer_rel, joinrel->partexprs[cnt] = partexpr; joinrel->nullable_partexprs[cnt] = nullable_partexpr; } + + /* Allocate space to hold child-joins RelOptInfos. */ + joinrel->part_rels = + (RelOptInfo **) palloc0(sizeof(RelOptInfo *) * joinrel->nparts); + } -- 1.7.9.5
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers