From 9d51a459c38d9e3cb7c39a09e6aa3e35461882a5 Mon Sep 17 00:00:00 2001 From: Etsuro Fujita Date: Tue, 12 Nov 2019 21:58:34 +0900 Subject: [PATCH 2/5] Modify partition_range_bounds_merge() --- src/backend/partitioning/partbounds.c | 594 ++++++++++++-------------- 1 file changed, 266 insertions(+), 328 deletions(-) diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c index f1458518716..4aebc71ebb9 100644 --- a/src/backend/partitioning/partbounds.c +++ b/src/backend/partitioning/partbounds.c @@ -81,6 +81,12 @@ typedef struct PartitionMap * did_remapping */ } PartitionMap; +#define compare_range_bounds(partnatts, partsupfunc, partcollations, \ + bound1, bound2) \ + (partition_rbound_cmp(partnatts, partsupfunc, partcollations, \ + (bound1)->datums, (bound1)->kind, (bound1)->lower, \ + bound2)) + static int32 qsort_partition_hbound_cmp(const void *a, const void *b); static int32 qsort_partition_list_value_cmp(const void *a, const void *b, void *arg); @@ -142,7 +148,6 @@ static bool process_outer_partition(PartitionMap *outer_map, int outer_index, int inner_default, JoinType jointype, - char strategy, int *next_index, int *default_index, int *merged_index); @@ -153,7 +158,6 @@ static bool process_inner_partition(PartitionMap *outer_map, int inner_index, int outer_default, JoinType jointype, - char strategy, int *next_index, int *default_index, int *merged_index); @@ -170,20 +174,31 @@ static PartitionBoundInfo build_merged_partition_bounds(char strategy, List *merged_datums, List *merged_indexes, List *merged_contents, int null_index, int default_index); -static int32 partition_range_bound_cmp(int partnatts, FmgrInfo *partsupfunc, - Oid *collations, PartitionRangeBound *bound1, - PartitionRangeBound *bound2); -static bool partition_range_cmp(int partnatts, FmgrInfo *supfuncs, - Oid *collations, PartitionRangeBound *lower_bound1, - PartitionRangeBound *upper_bound1, - PartitionRangeBound *lower_bound2, - PartitionRangeBound *upper_bound2, int *ub_cmpval, - int *lb_cmpval); -static bool partition_range_merge_next_lb(int partnatts, FmgrInfo *supfuncs, - Oid *collations, Datum *next_lb_datums, - PartitionRangeDatumKind *next_lb_kind, - List **merged_datums, List **merged_kinds, - List **merged_indexes); +static int get_range_partition(PartitionBoundInfo bi, int *lb_pos, + PartitionRangeBound *lb, PartitionRangeBound *ub); +static bool compare_range_partitions(int partnatts, FmgrInfo *partsupfuncs, + Oid *partcollations, + PartitionRangeBound *lower_bound1, + PartitionRangeBound *upper_bound1, + PartitionRangeBound *lower_bound2, + PartitionRangeBound *upper_bound2, + int *ub_cmpval, int *lb_cmpval); +static void get_merged_range_bounds(int partnatts, FmgrInfo *partsupfuncs, + Oid *partcollations, JoinType jointype, + PartitionRangeBound *left_lb, + PartitionRangeBound *left_ub, + PartitionRangeBound *right_lb, + PartitionRangeBound *right_ub, + PartitionRangeBound *merged_lb, + PartitionRangeBound *merged_ub); +static void add_merged_range_bounds(int partnatts, FmgrInfo *partsupfuncs, + Oid *partcollations, + PartitionRangeBound *merged_lb, + PartitionRangeBound *merged_ub, + int merged_index, + List **merged_datums, + List **merged_kinds, + List **merged_indexes); static bool merge_default_partitions(PartitionMap *outer_map, PartitionMap *inner_map, bool outer_has_default, @@ -3164,83 +3179,60 @@ partition_bounds_merge(int partnatts, } /* - * partition_get_range_bounds + * get_range_partition + * Returns the index of the range partition with the given lower bound * - * Given the index of lower bound in datums array, return lower and upper - * bounds and the index of the partition with that lower bound. + * *lb and *ub are set to the lower and upper bounds of the range partition + * respectively, and *lb_index is advanced to the next lower bound, if any. */ static int -partition_get_range_bounds(PartitionBoundInfo bi, int lb_index, - PartitionRangeBound *lower, - PartitionRangeBound *upper) +get_range_partition(PartitionBoundInfo bi, int *lb_index, + PartitionRangeBound *lb, PartitionRangeBound *ub) { - int part_index; + /* Return the index as -1 if we've exhausted all the lower bounds. */ + if (*lb_index >= bi->ndatums) + return -1; /* A lower bound should have at least one more bound after it. */ - Assert(lb_index < bi->ndatums - 1); - - /* The lower bound should correspond to a valid partition. */ - part_index = bi->indexes[lb_index + 1]; - Assert(part_index >= 0); - - lower->kind = bi->kind[lb_index]; - lower->datums = bi->datums[lb_index]; - lower->lower = true; - upper->kind = bi->kind[lb_index + 1]; - upper->datums = bi->datums[lb_index + 1]; - upper->lower = false; + Assert(*lb_index + 1 < bi->ndatums); - return part_index; -} - -/* - * partition_range_get_next_lb_index - * - * Given the index of lower bound in datums array return the - * index of lower bound of the next partition. When the given index corresponds - * to the last partition, return number of datums (ndatums). - */ -static int -partition_range_get_next_lb_index(PartitionBoundInfo bi, int lb_index) -{ - /* A lower bound should have at least one more bound after it. */ - Assert(lb_index < bi->ndatums - 1); + lb->index = bi->indexes[*lb_index]; + lb->kind = bi->kind[*lb_index]; + lb->datums = bi->datums[*lb_index]; + lb->lower = true; + ub->index = bi->indexes[*lb_index + 1]; + ub->kind = bi->kind[*lb_index + 1]; + ub->datums = bi->datums[*lb_index + 1]; + ub->lower = false; - /* The partition index corresponding to the upper bound should be valid. */ - Assert(bi->indexes[lb_index + 1] >= 0); + /* The partition index of an upper bound should be valid. */ + Assert(ub->index >= 0); /* - * If there are no bounds left beyond the upper bound, we have reached the - * last partition. + * Advance the lower bound; if there are no bounds left beyond the upper + * bound, we have reached the last lower bound. */ - if (lb_index + 2 < bi->ndatums) + if (*lb_index + 2 >= bi->ndatums) + *lb_index = bi->ndatums; + else { /* - * If the bound next to the upper bound corresponds to no partition, - * that's the next lower bound of the next partition. Otherwise, the - * current upper bound is the lower bound of the next partition. + * If the index assigned to the bound next to the upper bound isn't + * valid, that is the lower bound of the next range partition; else, + * the upper bound of the current range partition is also the lower + * bound of the next range partition. */ - if (bi->indexes[lb_index + 2] < 0) - return lb_index + 2; + if (bi->indexes[*lb_index + 2] < 0) + *lb_index = *lb_index + 2; else - return lb_index + 1; + *lb_index = *lb_index + 1; } - else - return bi->ndatums; -} -static int32 -partition_range_bound_cmp(int partnatts, FmgrInfo *partsupfunc, - Oid *partcollations, PartitionRangeBound *bound1, - PartitionRangeBound *bound2) -{ - return partition_rbound_cmp(partnatts, partsupfunc, partcollations, - bound1->datums, bound1->kind, bound1->lower, - bound2); + return ub->index; } /* - * partition_range_cmp + * compare_range_partitions * * Compare the bounds of two range partitions. Set ub_cmpval <, = or > 0, if the * first partition's upper bound is lower than, equal to or higher than the @@ -3251,12 +3243,13 @@ partition_range_bound_cmp(int partnatts, FmgrInfo *partsupfunc, * Return true, if the ranges overlap, otherwise return false. */ static bool -partition_range_cmp(int partnatts, FmgrInfo *partsupfuncs, Oid *partcollations, - PartitionRangeBound *lower_bound1, - PartitionRangeBound *upper_bound1, - PartitionRangeBound *lower_bound2, - PartitionRangeBound *upper_bound2, int *ub_cmpval, - int *lb_cmpval) +compare_range_partitions(int partnatts, FmgrInfo *partsupfuncs, + Oid *partcollations, + PartitionRangeBound *lower_bound1, + PartitionRangeBound *upper_bound1, + PartitionRangeBound *lower_bound2, + PartitionRangeBound *upper_bound2, + int *ub_cmpval, int *lb_cmpval) { bool overlap; @@ -3266,15 +3259,15 @@ partition_range_cmp(int partnatts, FmgrInfo *partsupfuncs, Oid *partcollations, * the partitions are not overlapping. All other cases indicate overlapping * partitions. */ - if (partition_range_bound_cmp(partnatts, partsupfuncs, partcollations, - lower_bound1, upper_bound2) > 0) + if (compare_range_bounds(partnatts, partsupfuncs, partcollations, + lower_bound1, upper_bound2) > 0) { overlap = false; *ub_cmpval = 1; *lb_cmpval = 1; } - else if (partition_range_bound_cmp(partnatts, partsupfuncs, partcollations, - lower_bound2, upper_bound1) > 0) + else if (compare_range_bounds(partnatts, partsupfuncs, partcollations, + lower_bound2, upper_bound1) > 0) { overlap = false; *ub_cmpval = -1; @@ -3283,35 +3276,34 @@ partition_range_cmp(int partnatts, FmgrInfo *partsupfuncs, Oid *partcollations, else { overlap = true; - *ub_cmpval = partition_range_bound_cmp(partnatts, partsupfuncs, - partcollations, upper_bound1, - upper_bound2); - *lb_cmpval = partition_range_bound_cmp(partnatts, partsupfuncs, - partcollations, lower_bound1, - lower_bound2); + *ub_cmpval = compare_range_bounds(partnatts, partsupfuncs, + partcollations, upper_bound1, + upper_bound2); + *lb_cmpval = compare_range_bounds(partnatts, partsupfuncs, + partcollations, lower_bound1, + lower_bound2); } return overlap; } /* - * partition_range_merge - * - * Merge the partition bounds of given two partitions such that the join - * between the given two partitions fits merged bounds. + * get_merged_range_bounds + * Given the bounds of range partitions to be join, determine the range + * bounds of the merged partition produced from the range partitions * - * "merged_upper" will be set to one of the given upper bounds and - * "merged_lower" will be set to one of the given lower bounds. + * *merged_lb and *merged_ub are set to the lower and upper bounds of the + * merged partition. */ static void -partition_range_merge(int partnatts, FmgrInfo *partsupfuncs, - Oid *partcollations, JoinType jointype, - PartitionRangeBound *left_lb, - PartitionRangeBound *left_ub, - PartitionRangeBound *right_lb, - PartitionRangeBound *right_ub, - PartitionRangeBound **merged_lb, - PartitionRangeBound **merged_ub) +get_merged_range_bounds(int partnatts, FmgrInfo *partsupfuncs, + Oid *partcollations, JoinType jointype, + PartitionRangeBound *left_lb, + PartitionRangeBound *left_ub, + PartitionRangeBound *right_lb, + PartitionRangeBound *right_ub, + PartitionRangeBound *merged_lb, + PartitionRangeBound *merged_ub) { /* * An outer join will have all the rows from the outer side, so merged @@ -3324,41 +3316,37 @@ partition_range_merge(int partnatts, FmgrInfo *partsupfuncs, { case JOIN_LEFT: case JOIN_ANTI: - *merged_ub = left_ub; - *merged_lb = left_lb; + *merged_ub = *left_ub; + *merged_lb = *left_lb; break; case JOIN_INNER: case JOIN_SEMI: - if (partition_range_bound_cmp(partnatts, partsupfuncs, - partcollations, left_ub, - right_ub) < 0) - *merged_ub = left_ub; + if (compare_range_bounds(partnatts, partsupfuncs, partcollations, + left_ub, right_ub) < 0) + *merged_ub = *left_ub; else - *merged_ub = right_ub; + *merged_ub = *right_ub; - if (partition_range_bound_cmp(partnatts, partsupfuncs, - partcollations, left_lb, - right_lb) > 0) - *merged_lb = left_lb; + if (compare_range_bounds(partnatts, partsupfuncs, partcollations, + left_lb, right_lb) > 0) + *merged_lb = *left_lb; else - *merged_lb = right_lb; + *merged_lb = *right_lb; break; case JOIN_FULL: - if (partition_range_bound_cmp(partnatts, partsupfuncs, - partcollations, left_ub, - right_ub) > 0) - *merged_ub = left_ub; + if (compare_range_bounds(partnatts, partsupfuncs, partcollations, + left_ub, right_ub) > 0) + *merged_ub = *left_ub; else - *merged_ub = right_ub; + *merged_ub = *right_ub; - if (partition_range_bound_cmp(partnatts, partsupfuncs, - partcollations, left_lb, - right_lb) < 0) - *merged_lb = left_lb; + if (compare_range_bounds(partnatts, partsupfuncs, partcollations, + left_lb, right_lb) < 0) + *merged_lb = *left_lb; else - *merged_lb = right_lb; + *merged_lb = *right_lb; break; default: @@ -3367,16 +3355,19 @@ partition_range_merge(int partnatts, FmgrInfo *partsupfuncs, } /* - * Add the lower bound of the next range to the list of bounds, if the lower - * bound is higher or equal to the previous upper bound. If successful return - * true, otherwise false. + * add_merged_range_bounds + * Add the range bounds of a merged partition to the lists of range + * bounds */ -static bool -partition_range_merge_next_lb(int partnatts, FmgrInfo *partsupfuncs, - Oid *partcollations, Datum *next_lb_datums, - PartitionRangeDatumKind *next_lb_kind, - List **merged_datums, List **merged_kinds, - List **merged_indexes) +static void +add_merged_range_bounds(int partnatts, FmgrInfo *partsupfuncs, + Oid *partcollations, + PartitionRangeBound *merged_lb, + PartitionRangeBound *merged_ub, + int merged_index, + List **merged_datums, + List **merged_kinds, + List **merged_indexes) { int cmpval; @@ -3389,38 +3380,43 @@ partition_range_merge_next_lb(int partnatts, FmgrInfo *partsupfuncs, { PartitionRangeBound prev_ub; - prev_ub.datums = llast(*merged_datums); - prev_ub.kind = llast(*merged_kinds); + Assert(*merged_kinds && *merged_indexes); + + /* Get the last upper bound. */ + prev_ub.index = llast_int(*merged_indexes); + prev_ub.datums = (Datum *) llast(*merged_datums); + prev_ub.kind = (PartitionRangeDatumKind *) llast(*merged_kinds); prev_ub.lower = false; + /* + * We pass to partition_rbound_cmp() lower1 as false to prevent it + * from considering the last upper bound to be smaller than the lower + * bound of the merged partition when the values of the two range + * bounds compare equal. + */ cmpval = partition_rbound_cmp(partnatts, partsupfuncs, partcollations, - next_lb_datums, next_lb_kind, false, - &prev_ub); + merged_lb->datums, merged_lb->kind, + false, &prev_ub); + Assert(cmpval >= 0); } /* - * The lower bound is lower than the last upper bound, thus does not fit - * the bounds created so far and hence can not be merged with the existing - * bounds. - */ - if (cmpval < 0) - return false; - - /* - * Add bounds of the new merged partition. If the next lower bound is - * higher than the last upper bound, add new range with index - * corresponding to the lower bound as -1. If the merged lower bound - * is same as the last merged upper bound, the last upper bound will be - * reused as the lower bound of the next range. + * If the lower bound is higher than the last upper bound, add the lower + * bound with the index as -1 indicating that that is a lower bound; else, + * the last upper bound will be reused as the lower bound of the merged + * partition, so skip this. */ if (cmpval > 0) { - *merged_datums = lappend(*merged_datums, next_lb_datums); - *merged_kinds = lappend(*merged_kinds, next_lb_kind); + *merged_datums = lappend(*merged_datums, merged_lb->datums); + *merged_kinds = lappend(*merged_kinds, merged_lb->kind); *merged_indexes = lappend_int(*merged_indexes, -1); } - return true; + /* Add the upper bound and index of the merged partition. */ + *merged_datums = lappend(*merged_datums, merged_ub->datums); + *merged_kinds = lappend(*merged_kinds, merged_ub->kind); + *merged_indexes = lappend_int(*merged_indexes, merged_index); } /* @@ -3444,13 +3440,19 @@ partition_range_bounds_merge(int partnatts, FmgrInfo *partsupfuncs, int inner_default = inner_bi->default_index; PartitionMap outer_map; PartitionMap inner_map; + int outer_part; + int inner_part; + int outer_lb_index; + int inner_lb_index; + PartitionRangeBound outer_lb; + PartitionRangeBound outer_ub; + PartitionRangeBound inner_lb; + PartitionRangeBound inner_ub; int next_index = 0; int default_index = -1; List *merged_datums = NIL; List *merged_kinds = NIL; List *merged_indexes = NIL; - int outer_lb_index; - int inner_lb_index; Assert(outer_bi->strategy == inner_bi->strategy && outer_bi->strategy == PARTITION_STRATEGY_RANGE); @@ -3471,29 +3473,25 @@ partition_range_bounds_merge(int partnatts, FmgrInfo *partsupfuncs, * datum in PartitionBoundInfo::datums of that side. */ outer_lb_index = inner_lb_index = 0; - while (outer_lb_index < outer_bi->ndatums || - inner_lb_index < inner_bi->ndatums) + outer_part = get_range_partition(outer_bi, &outer_lb_index, + &outer_lb, &outer_ub); + inner_part = get_range_partition(inner_bi, &inner_lb_index, + &inner_lb, &inner_ub); + while (outer_part >= 0 || inner_part >= 0) { - PartitionRangeBound *merged_lb = NULL; - PartitionRangeBound *merged_ub = NULL; + PartitionRangeBound merged_lb; + PartitionRangeBound merged_ub; int merged_index = -1; - PartitionRangeBound outer_lb; - PartitionRangeBound outer_ub; - PartitionRangeBound inner_lb; - PartitionRangeBound inner_ub; - int outer_part = -1; - int inner_part = -1; bool overlap; int ub_cmpval; int lb_cmpval; - /* Get the range bounds of the next pair of partitions. */ - if (outer_lb_index < outer_bi->ndatums) - outer_part = partition_get_range_bounds(outer_bi, outer_lb_index, - &outer_lb, &outer_ub); - if (inner_lb_index < inner_bi->ndatums) - inner_part = partition_get_range_bounds(inner_bi, inner_lb_index, - &inner_lb, &inner_ub); + if (outer_part >= 0) + Assert(outer_map.merged_indexes[outer_part] == -1 && + outer_map.merged[outer_part] == false); + if (inner_part >= 0) + Assert(inner_map.merged_indexes[inner_part] == -1 && + inner_map.merged[inner_part] == false); /* * We run this loop till both the sides finish. This allows to avoid @@ -3505,25 +3503,30 @@ partition_range_bounds_merge(int partnatts, FmgrInfo *partsupfuncs, * side. That way we advance the partitions on that side till all of * them are exhausted. */ - if (outer_lb_index >= outer_bi->ndatums) + if (outer_part == -1) { overlap = false; ub_cmpval = 1; lb_cmpval = 1; } - else if (inner_lb_index >= inner_bi->ndatums) + else if (inner_part == -1) { overlap = false; ub_cmpval = -1; lb_cmpval = -1; } else - overlap = partition_range_cmp(partnatts, partsupfuncs, partcollations, - &outer_lb, &outer_ub, &inner_lb, - &inner_ub, &ub_cmpval, &lb_cmpval); + overlap = compare_range_partitions(partnatts, partsupfuncs, + partcollations, + &outer_lb, &outer_ub, + &inner_lb, &inner_ub, + &ub_cmpval, &lb_cmpval); if (overlap) { + PartitionRangeBound save_outer_ub; + PartitionRangeBound save_inner_ub; + /* * The rows from overlapping portion of ranges on both sides may * join, hence the corresponding pair of partitions form a joining @@ -3531,152 +3534,117 @@ partition_range_bounds_merge(int partnatts, FmgrInfo *partsupfuncs, * and its index by merging the bounds according to the type of * join. */ - partition_range_merge(partnatts, partsupfuncs, partcollations, - jointype, &outer_lb, &outer_ub, &inner_lb, - &inner_ub, &merged_lb, &merged_ub); + get_merged_range_bounds(partnatts, partsupfuncs, partcollations, + jointype, &outer_lb, &outer_ub, &inner_lb, + &inner_ub, &merged_lb, &merged_ub); + /* + * Both partitions are not merged yet, so they should be merged + * successfully. + */ merged_index = map_and_merge_partitions(&outer_map, &inner_map, outer_part, inner_part, &next_index); + Assert(merged_index >= 0); - if (merged_index < 0) - { - /* Failed to match the partitions. */ - return NULL; - } + /* Save the upper bounds of both partitions for use below. */ + save_outer_ub = outer_ub; + save_inner_ub = inner_ub; + + /* Move to the next pair of partitions. */ + outer_part = get_range_partition(outer_bi, &outer_lb_index, + &outer_lb, &outer_ub); + inner_part = get_range_partition(inner_bi, &inner_lb_index, + &inner_lb, &inner_ub); /* - * If the ranges overlap but don't exactly match, a row from - * non-overlapping portion of the range from one side of join may - * find its join partner in the previous or next overlapping - * partition or default partition on the other side , if such a - * partition exists. All those cases, if true, will cause one - * partition from that side to match at least two partitions on the - * other side; a case that we do not support now. Previous - * partition has been delt with in the previous iteration of this - * loop, next partition will be delt in the next iteration. We will - * deal with the default partition here. + * If the range of a partition on one side overlaps the range of + * the next partition on the other side, that will cause the + * partition on one side to match at least two partitions on the + * other side, which is the case that we currently don't support + * partitioned join for; give up. */ - if ((lb_cmpval < 0 && inner_has_default) || - /* Non-overlapping range on the lower side of outer range. */ - (lb_cmpval > 0 && outer_has_default) || - /* Non-overlapping range on the lower side of inner range. */ - (ub_cmpval < 0 && outer_has_default) || - /* Non-overlapping range on the upper side of inner range. */ - (ub_cmpval > 0 && inner_has_default)) - /* Non-overlapping range on the upper side of outer range. */ + if (ub_cmpval > 0 && inner_part >= 0 && + compare_range_bounds(partnatts, partsupfuncs, partcollations, + &save_outer_ub, &inner_lb) > 0) + return NULL; + if (ub_cmpval < 0 && outer_part >= 0 && + compare_range_bounds(partnatts, partsupfuncs, partcollations, + &outer_lb, &save_inner_ub) < 0) return NULL; - } - - if (ub_cmpval == 0) - { - /* Upper bounds of both the ranges match. */ - Assert(overlap); - /* Move to the next pair of partitions. */ - Assert(outer_lb_index < outer_bi->ndatums); - Assert(inner_lb_index < inner_bi->ndatums); - outer_lb_index = partition_range_get_next_lb_index(outer_bi, - outer_lb_index); - inner_lb_index = partition_range_get_next_lb_index(inner_bi, - inner_lb_index); + /* + * A row from a non-overlapping portion (if any) of a partition + * on one side might find its join partner in the default + * partition (if any) on the other side, causing the same + * situation as above; if so, give up. + */ + if ((outer_has_default && (lb_cmpval > 0 || ub_cmpval < 0)) || + (inner_has_default && (lb_cmpval < 0 || ub_cmpval > 0))) + return NULL; } else if (ub_cmpval < 0) { /* Upper bound of inner range higher than that of the outer. */ - if (overlap) - { - /* We have already dealt with overlapping ranges. */ - } - else - { - if (inner_has_default || IS_OUTER_JOIN(jointype)) - { - if (!process_outer_partition(&outer_map, - &inner_map, - outer_has_default, - inner_has_default, - outer_part, - inner_default, - jointype, - outer_bi->strategy, - &next_index, - &default_index, - &merged_index)) - return NULL; - } + merged_lb = outer_lb; + merged_ub = outer_ub; - merged_lb = &outer_lb; - merged_ub = &outer_ub; + if (inner_has_default || IS_OUTER_JOIN(jointype)) + { + if (!process_outer_partition(&outer_map, + &inner_map, + outer_has_default, + inner_has_default, + outer_part, + inner_default, + jointype, + &next_index, + &default_index, + &merged_index)) + return NULL; } /* Move to the next partition on the outer side. */ - Assert(outer_lb_index < outer_bi->ndatums); - outer_lb_index = partition_range_get_next_lb_index(outer_bi, - outer_lb_index); + outer_part = get_range_partition(outer_bi, &outer_lb_index, + &outer_lb, &outer_ub); } else { + /* Upper bound of outer range higher than that of the inner. */ Assert(ub_cmpval > 0); - /* Upper bound of outer range higher than that of the inner. */ - if (overlap) - { - /* We have already dealt with overlapping ranges. */ - } - else - { - if (outer_has_default || jointype == JOIN_FULL) - { - if (!process_inner_partition(&outer_map, - &inner_map, - outer_has_default, - inner_has_default, - inner_part, - outer_default, - jointype, - outer_bi->strategy, - &next_index, - &default_index, - &merged_index)) - return NULL; - } + merged_lb = inner_lb; + merged_ub = inner_ub; - merged_lb = &inner_lb; - merged_ub = &inner_ub; + if (outer_has_default || jointype == JOIN_FULL) + { + if (!process_inner_partition(&outer_map, + &inner_map, + outer_has_default, + inner_has_default, + inner_part, + outer_default, + jointype, + &next_index, + &default_index, + &merged_index)) + return NULL; } /* Move to the next partition on the inner side. */ - Assert(inner_lb_index < inner_bi->ndatums); - inner_lb_index = partition_range_get_next_lb_index(inner_bi, - inner_lb_index); + inner_part = get_range_partition(inner_bi, &inner_lb_index, + &inner_lb, &inner_ub); } - if (merged_index < 0) + if (merged_index >= 0) { - /* We didn't find a new merged partition. */ - continue; + /* Add the range bounds of the merged partition. */ + add_merged_range_bounds(partnatts, partsupfuncs, partcollations, + &merged_lb, &merged_ub, merged_index, + &merged_datums, &merged_kinds, + &merged_indexes); } - - /* - * We have a valid partition index for the next partition of join. The - * partition should have valid range. - */ - Assert(merged_lb && merged_ub); - - /* Try merging new lower bound with the last upper bound. */ - if (!partition_range_merge_next_lb(partnatts, partsupfuncs, - partcollations, - merged_lb->datums, - merged_lb->kind, &merged_datums, - &merged_kinds, &merged_indexes)) - return NULL; - - /* Add upper bound with the merged partition index. */ - merged_datums = lappend(merged_datums, merged_ub->datums); - merged_kinds = lappend(merged_kinds, merged_ub->kind); - merged_indexes = lappend_int(merged_indexes, merged_index); } /* Merge default partitions if any. */ @@ -3696,6 +3664,10 @@ partition_range_bounds_merge(int partnatts, FmgrInfo *partsupfuncs, else Assert(default_index == -1); + /* + * Unlike the case for list partitioning, we wouldn't have re-merged + * partitions, so did_remapping should be left alone. + */ Assert(!outer_map.did_remapping && !inner_map.did_remapping); /* Use maps to match partition from the joining relations. */ @@ -3856,7 +3828,6 @@ partition_list_bounds_merge(FmgrInfo *partsupfunc, Oid *partcollation, o_index, inner_default, jointype, - outer_bi->strategy, &next_index, &default_index, &merged_index)) @@ -3886,7 +3857,6 @@ partition_list_bounds_merge(FmgrInfo *partsupfunc, Oid *partcollation, i_index, outer_default, jointype, - outer_bi->strategy, &next_index, &default_index, &merged_index)) @@ -4150,7 +4120,6 @@ process_outer_partition(PartitionMap *outer_map, int outer_index, int inner_default, JoinType jointype, - char strategy, int *next_index, int *default_index, int *merged_index) @@ -4203,22 +4172,8 @@ process_outer_partition(PartitionMap *outer_map, Assert(IS_OUTER_JOIN(jointype)); Assert(jointype != JOIN_RIGHT); - /* - * In range partitioning, if the given outer partition is already - * merged (eg, because we found an overlapping range earlier), we know - * where it fits in the join result; nothing to do in that case. Else - * create a new merged partition. - */ if (outer_map->merged_indexes[outer_index] >= 0) - { - if (strategy == PARTITION_STRATEGY_LIST) - *merged_index = outer_map->merged_indexes[outer_index]; - else - { - Assert(strategy == PARTITION_STRATEGY_RANGE); - *merged_index = -1; - } - } + *merged_index = outer_map->merged_indexes[outer_index]; else *merged_index = merge_partition_with_dummy(outer_map, outer_index, next_index); @@ -4242,7 +4197,6 @@ process_inner_partition(PartitionMap *outer_map, int inner_index, int outer_default, JoinType jointype, - char strategy, int *next_index, int *default_index, int *merged_index) @@ -4295,22 +4249,8 @@ process_inner_partition(PartitionMap *outer_map, { Assert(jointype == JOIN_FULL); - /* - * In range partitioning, if the given inner partition is already - * merged (eg, because we found an overlapping range earlier), we know - * where it fits in the join result; nothing to do in that case. Else - * create a new merged partition. - */ if (inner_map->merged_indexes[inner_index] >= 0) - { - if (strategy == PARTITION_STRATEGY_LIST) - *merged_index = inner_map->merged_indexes[inner_index]; - else - { - Assert(strategy == PARTITION_STRATEGY_RANGE); - *merged_index = -1; - } - } + *merged_index = inner_map->merged_indexes[inner_index]; else *merged_index = merge_partition_with_dummy(inner_map, inner_index, next_index); @@ -4628,7 +4568,6 @@ merge_null_partitions(PartitionBoundInfo outer_bi, PartitionBoundInfo inner_bi, outer_bi->null_index, inner_bi->default_index, jointype, - outer_bi->strategy, next_index, default_index, &merged_index)) @@ -4655,7 +4594,6 @@ merge_null_partitions(PartitionBoundInfo outer_bi, PartitionBoundInfo inner_bi, inner_bi->null_index, outer_bi->default_index, jointype, - outer_bi->strategy, next_index, default_index, &merged_index)) -- 2.18.0