0003-split-try_partitionwise_join.patch
text/x-patch
Filename: 0003-split-try_partitionwise_join.patch
Type: text/x-patch
Part: 1
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch 0003
Subject: split try_partitionwise_join
| File | + | − |
|---|---|---|
| src/backend/optimizer/path/joinrels.c | 78 | 68 |
From 04ff682ae15136a987d97c3ef6ec571327979019 Mon Sep 17 00:00:00 2001
From: Tomas Vondra <tv@fuzzy.cz>
Date: Thu, 26 Mar 2020 01:15:04 +0100
Subject: [PATCH 3/5] split try_partitionwise_join
---
src/backend/optimizer/path/joinrels.c | 146 ++++++++++++++------------
1 file changed, 78 insertions(+), 68 deletions(-)
diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c
index 0b082fc915..314b0267c3 100644
--- a/src/backend/optimizer/path/joinrels.c
+++ b/src/backend/optimizer/path/joinrels.c
@@ -1333,71 +1333,12 @@ restriction_is_constant_false(List *restrictlist,
return false;
}
-/*
- * Assess whether join between given two partitioned relations can be broken
- * down into joins between matching partitions; a technique called
- * "partitionwise join"
- *
- * Partitionwise join is possible when a. Joining relations have same
- * partitioning scheme b. There exists an equi-join between the partition keys
- * of the two relations.
- *
- * Partitionwise join is planned as follows (details: optimizer/README.)
- *
- * 1. Create the RelOptInfos for joins between matching partitions i.e
- * child-joins and add paths to them.
- *
- * 2. Construct Append or MergeAppend paths across the set of child joins.
- * This second phase is implemented by generate_partitionwise_join_paths().
- *
- * The RelOptInfo, SpecialJoinInfo and restrictlist for each child join are
- * obtained by translating the respective parent join structures.
- */
static void
-try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
- RelOptInfo *joinrel, SpecialJoinInfo *parent_sjinfo,
- List *parent_restrictlist)
+compute_partition_bounds(PlannerInfo *root, RelOptInfo *rel1,
+ RelOptInfo *rel2, RelOptInfo *joinrel,
+ SpecialJoinInfo *parent_sjinfo,
+ List **parts1, List **parts2)
{
- bool rel1_is_simple = IS_SIMPLE_REL(rel1);
- bool rel2_is_simple = IS_SIMPLE_REL(rel2);
- List *parts1 = NIL;
- List *parts2 = NIL;
- ListCell *lcr1 = NULL;
- ListCell *lcr2 = NULL;
- int cnt_parts;
-
- /* Guard against stack overflow due to overly deep partition hierarchy. */
- check_stack_depth();
-
- /* Nothing to do, if the join relation is not partitioned. */
- if (joinrel->part_scheme == NULL || joinrel->nparts == 0)
- return;
-
- /* The join relation should have consider_partitionwise_join set. */
- Assert(joinrel->consider_partitionwise_join);
-
- /*
- * We can not perform partitionwise join if either of the joining relations
- * is not partitioned.
- */
- if (!IS_PARTITIONED_REL(rel1) || !IS_PARTITIONED_REL(rel2))
- return;
-
- Assert(REL_HAS_ALL_PART_PROPS(rel1) && REL_HAS_ALL_PART_PROPS(rel2));
-
- /* The joining relations should have consider_partitionwise_join set. */
- Assert(rel1->consider_partitionwise_join &&
- rel2->consider_partitionwise_join);
-
- /*
- * The partition scheme of the join relation should match that of the
- * joining relations.
- */
- Assert(joinrel->part_scheme == rel1->part_scheme &&
- joinrel->part_scheme == rel2->part_scheme);
-
- Assert(!(joinrel->merged && (joinrel->nparts <= 0)));
-
/*
* If we don't have the partition bounds for the join rel yet, try to
* compute those along with pairs of partitions to be joined.
@@ -1440,13 +1381,13 @@ try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
part_scheme->partcollation,
rel1, rel2,
parent_sjinfo->jointype,
- &parts1, &parts2);
+ parts1, parts2);
if (boundinfo == NULL)
{
joinrel->nparts = 0;
return;
}
- nparts = list_length(parts1);
+ nparts = list_length(*parts1);
joinrel->merged = true;
}
@@ -1472,11 +1413,80 @@ try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
if (joinrel->merged)
{
get_matching_part_pairs(root, joinrel, rel1, rel2,
- &parts1, &parts2);
- Assert(list_length(parts1) == joinrel->nparts);
- Assert(list_length(parts2) == joinrel->nparts);
+ parts1, parts2);
+ Assert(list_length(*parts1) == joinrel->nparts);
+ Assert(list_length(*parts2) == joinrel->nparts);
}
}
+}
+
+/*
+ * Assess whether join between given two partitioned relations can be broken
+ * down into joins between matching partitions; a technique called
+ * "partitionwise join"
+ *
+ * Partitionwise join is possible when a. Joining relations have same
+ * partitioning scheme b. There exists an equi-join between the partition keys
+ * of the two relations.
+ *
+ * Partitionwise join is planned as follows (details: optimizer/README.)
+ *
+ * 1. Create the RelOptInfos for joins between matching partitions i.e
+ * child-joins and add paths to them.
+ *
+ * 2. Construct Append or MergeAppend paths across the set of child joins.
+ * This second phase is implemented by generate_partitionwise_join_paths().
+ *
+ * The RelOptInfo, SpecialJoinInfo and restrictlist for each child join are
+ * obtained by translating the respective parent join structures.
+ */
+static void
+try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
+ RelOptInfo *joinrel, SpecialJoinInfo *parent_sjinfo,
+ List *parent_restrictlist)
+{
+ bool rel1_is_simple = IS_SIMPLE_REL(rel1);
+ bool rel2_is_simple = IS_SIMPLE_REL(rel2);
+ List *parts1 = NIL;
+ List *parts2 = NIL;
+ ListCell *lcr1 = NULL;
+ ListCell *lcr2 = NULL;
+ int cnt_parts;
+
+ /* Guard against stack overflow due to overly deep partition hierarchy. */
+ check_stack_depth();
+
+ /* Nothing to do, if the join relation is not partitioned. */
+ if (joinrel->part_scheme == NULL || joinrel->nparts == 0)
+ return;
+
+ /* The join relation should have consider_partitionwise_join set. */
+ Assert(joinrel->consider_partitionwise_join);
+
+ /*
+ * We can not perform partitionwise join if either of the joining relations
+ * is not partitioned.
+ */
+ if (!IS_PARTITIONED_REL(rel1) || !IS_PARTITIONED_REL(rel2))
+ return;
+
+ Assert(REL_HAS_ALL_PART_PROPS(rel1) && REL_HAS_ALL_PART_PROPS(rel2));
+
+ /* The joining relations should have consider_partitionwise_join set. */
+ Assert(rel1->consider_partitionwise_join &&
+ rel2->consider_partitionwise_join);
+
+ /*
+ * The partition scheme of the join relation should match that of the
+ * joining relations.
+ */
+ Assert(joinrel->part_scheme == rel1->part_scheme &&
+ joinrel->part_scheme == rel2->part_scheme);
+
+ Assert(!(joinrel->merged && (joinrel->nparts <= 0)));
+
+ compute_partition_bounds(root, rel1, rel2, joinrel, parent_sjinfo,
+ &parts1, &parts2);
if (joinrel->merged)
{
--
2.17.1