diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/executor/execPartition.c | 4 | ||||
-rw-r--r-- | src/backend/partitioning/partbounds.c | 114 | ||||
-rw-r--r-- | src/backend/partitioning/partprune.c | 30 |
3 files changed, 42 insertions, 106 deletions
diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c index e326888862c..93e2cdd0207 100644 --- a/src/backend/executor/execPartition.c +++ b/src/backend/executor/execPartition.c @@ -1323,16 +1323,14 @@ get_partition_for_tuple(PartitionDispatch pd, Datum *values, bool *isnull) { case PARTITION_STRATEGY_HASH: { - int greatest_modulus; uint64 rowHash; - greatest_modulus = get_hash_partition_greatest_modulus(boundinfo); rowHash = compute_partition_hash_value(key->partnatts, key->partsupfunc, key->partcollation, values, isnull); - part_index = boundinfo->indexes[rowHash % greatest_modulus]; + part_index = boundinfo->indexes[rowHash % boundinfo->nindexes]; } break; diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c index cebd1c1dca5..895943a2e15 100644 --- a/src/backend/partitioning/partbounds.c +++ b/src/backend/partitioning/partbounds.c @@ -92,7 +92,6 @@ static int partition_range_bsearch(int partnatts, FmgrInfo *partsupfunc, Oid *partcollation, PartitionBoundInfo boundinfo, PartitionRangeBound *probe, bool *is_equal); -static int get_partition_bound_num_indexes(PartitionBoundInfo b); static Expr *make_partition_op_expr(PartitionKey key, int keynum, uint16 strategy, Expr *arg1, Expr *arg2); static Oid get_partition_operator(PartitionKey key, int col, @@ -266,6 +265,7 @@ create_hash_bounds(PartitionBoundSpec **boundspecs, int nparts, boundinfo->ndatums = ndatums; boundinfo->datums = (Datum **) palloc0(ndatums * sizeof(Datum *)); + boundinfo->nindexes = greatest_modulus; boundinfo->indexes = (int *) palloc(greatest_modulus * sizeof(int)); for (i = 0; i < greatest_modulus; i++) boundinfo->indexes[i] = -1; @@ -398,6 +398,7 @@ create_list_bounds(PartitionBoundSpec **boundspecs, int nparts, boundinfo->ndatums = ndatums; boundinfo->datums = (Datum **) palloc0(ndatums * sizeof(Datum *)); + boundinfo->nindexes = ndatums; boundinfo->indexes = (int *) palloc(ndatums * sizeof(int)); /* @@ -593,8 +594,9 @@ create_range_bounds(PartitionBoundSpec **boundspecs, int nparts, /* * For range partitioning, an additional value of -1 is stored as the last - * element. + * element of the indexes[] array. */ + boundinfo->nindexes = ndatums + 1; boundinfo->indexes = (int *) palloc((ndatums + 1) * sizeof(int)); for (i = 0; i < ndatums; i++) @@ -675,45 +677,41 @@ partition_bounds_equal(int partnatts, int16 *parttyplen, bool *parttypbyval, if (b1->ndatums != b2->ndatums) return false; + if (b1->nindexes != b2->nindexes) + return false; + if (b1->null_index != b2->null_index) return false; if (b1->default_index != b2->default_index) return false; - if (b1->strategy == PARTITION_STRATEGY_HASH) + /* For all partition strategies, the indexes[] arrays have to match */ + for (i = 0; i < b1->nindexes; i++) { - int greatest_modulus = get_hash_partition_greatest_modulus(b1); - - /* - * If two hash partitioned tables have different greatest moduli, - * their partition schemes don't match. - */ - if (greatest_modulus != get_hash_partition_greatest_modulus(b2)) + if (b1->indexes[i] != b2->indexes[i]) return false; + } + /* Finally, compare the datums[] arrays */ + if (b1->strategy == PARTITION_STRATEGY_HASH) + { /* * We arrange the partitions in the ascending order of their moduli * and remainders. Also every modulus is factor of next larger * modulus. Therefore we can safely store index of a given partition * in indexes array at remainder of that partition. Also entries at * (remainder + N * modulus) positions in indexes array are all same - * for (modulus, remainder) specification for any partition. Thus - * datums array from both the given bounds are same, if and only if - * their indexes array will be same. So, it suffices to compare - * indexes array. - */ - for (i = 0; i < greatest_modulus; i++) - if (b1->indexes[i] != b2->indexes[i]) - return false; - -#ifdef USE_ASSERT_CHECKING - - /* - * Nonetheless make sure that the bounds are indeed same when the + * for (modulus, remainder) specification for any partition. Thus the + * datums arrays from the given bounds are the same, if and only if + * their indexes arrays are the same. So, it suffices to compare the + * indexes arrays. + * + * Nonetheless make sure that the bounds are indeed the same when the * indexes match. Hash partition bound stores modulus and remainder * at b1->datums[i][0] and b1->datums[i][1] position respectively. */ +#ifdef USE_ASSERT_CHECKING for (i = 0; i < b1->ndatums; i++) Assert((b1->datums[i][0] == b2->datums[i][0] && b1->datums[i][1] == b2->datums[i][1])); @@ -759,15 +757,7 @@ partition_bounds_equal(int partnatts, int16 *parttyplen, bool *parttypbyval, parttypbyval[j], parttyplen[j])) return false; } - - if (b1->indexes[i] != b2->indexes[i]) - return false; } - - /* There are ndatums+1 indexes in case of range partitions */ - if (b1->strategy == PARTITION_STRATEGY_RANGE && - b1->indexes[i] != b2->indexes[i]) - return false; } return true; } @@ -783,17 +773,16 @@ partition_bounds_copy(PartitionBoundInfo src, PartitionBoundInfo dest; int i; int ndatums; + int nindexes; int partnatts; - int num_indexes; dest = (PartitionBoundInfo) palloc(sizeof(PartitionBoundInfoData)); dest->strategy = src->strategy; ndatums = dest->ndatums = src->ndatums; + nindexes = dest->nindexes = src->nindexes; partnatts = key->partnatts; - num_indexes = get_partition_bound_num_indexes(src); - /* List partitioned tables have only a single partition key. */ Assert(key->strategy != PARTITION_STRATEGY_LIST || partnatts == 1); @@ -851,8 +840,8 @@ partition_bounds_copy(PartitionBoundInfo src, } } - dest->indexes = (int *) palloc(sizeof(int) * num_indexes); - memcpy(dest->indexes, src->indexes, sizeof(int) * num_indexes); + dest->indexes = (int *) palloc(sizeof(int) * nindexes); + memcpy(dest->indexes, src->indexes, sizeof(int) * nindexes); dest->null_index = src->null_index; dest->default_index = src->default_index; @@ -1016,7 +1005,7 @@ check_new_partition_bound(char *relname, Relation parent, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("every hash partition modulus must be a factor of the next larger modulus"))); - greatest_modulus = get_hash_partition_greatest_modulus(boundinfo); + greatest_modulus = boundinfo->nindexes; remainder = spec->remainder; /* @@ -1380,18 +1369,15 @@ check_default_partition_contents(Relation parent, Relation default_rel, /* * get_hash_partition_greatest_modulus * - * Returns the greatest modulus of the hash partition bound. The greatest - * modulus will be at the end of the datums array because hash partitions are - * arranged in the ascending order of their moduli and remainders. + * Returns the greatest modulus of the hash partition bound. + * This is no longer used in the core code, but we keep it around + * in case external modules are using it. */ int get_hash_partition_greatest_modulus(PartitionBoundInfo bound) { Assert(bound && bound->strategy == PARTITION_STRATEGY_HASH); - Assert(bound->datums && bound->ndatums > 0); - Assert(DatumGetInt32(bound->datums[bound->ndatums - 1][0]) > 0); - - return DatumGetInt32(bound->datums[bound->ndatums - 1][0]); + return bound->nindexes; } /* @@ -1789,46 +1775,6 @@ qsort_partition_rbound_cmp(const void *a, const void *b, void *arg) } /* - * get_partition_bound_num_indexes - * - * Returns the number of the entries in the partition bound indexes array. - */ -static int -get_partition_bound_num_indexes(PartitionBoundInfo bound) -{ - int num_indexes; - - Assert(bound); - - switch (bound->strategy) - { - case PARTITION_STRATEGY_HASH: - - /* - * The number of the entries in the indexes array is same as the - * greatest modulus. - */ - num_indexes = get_hash_partition_greatest_modulus(bound); - break; - - case PARTITION_STRATEGY_LIST: - num_indexes = bound->ndatums; - break; - - case PARTITION_STRATEGY_RANGE: - /* Range partitioned table has an extra index. */ - num_indexes = bound->ndatums + 1; - break; - - default: - elog(ERROR, "unexpected partition strategy: %d", - (int) bound->strategy); - } - - return num_indexes; -} - -/* * get_partition_operator * * Return oid of the operator of the given strategy for the given partition diff --git a/src/backend/partitioning/partprune.c b/src/backend/partitioning/partprune.c index 040fc9b5be7..0f891b3d745 100644 --- a/src/backend/partitioning/partprune.c +++ b/src/backend/partitioning/partprune.c @@ -789,7 +789,10 @@ get_matching_partitions(PartitionPruneContext *context, List *pruning_steps) scan_default = final_result->scan_default; while ((i = bms_next_member(final_result->bound_offsets, i)) >= 0) { - int partindex = context->boundinfo->indexes[i]; + int partindex; + + Assert(i < context->boundinfo->nindexes); + partindex = context->boundinfo->indexes[i]; if (partindex < 0) { @@ -2518,20 +2521,19 @@ get_matching_hash_bounds(PartitionPruneContext *context, for (i = 0; i < partnatts; i++) isnull[i] = bms_is_member(i, nullkeys); - greatest_modulus = get_hash_partition_greatest_modulus(boundinfo); rowHash = compute_partition_hash_value(partnatts, partsupfunc, partcollation, values, isnull); + greatest_modulus = boundinfo->nindexes; if (partindices[rowHash % greatest_modulus] >= 0) result->bound_offsets = bms_make_singleton(rowHash % greatest_modulus); } else { - /* Getting here means at least one hash partition exists. */ - Assert(boundinfo->ndatums > 0); + /* Report all valid offsets into the boundinfo->indexes array. */ result->bound_offsets = bms_add_range(NULL, 0, - boundinfo->ndatums - 1); + boundinfo->nindexes - 1); } /* @@ -3392,30 +3394,20 @@ perform_pruning_combine_step(PartitionPruneContext *context, PartitionPruneStepCombine *cstep, PruneStepResult **step_results) { - ListCell *lc1; - PruneStepResult *result = NULL; + PruneStepResult *result = (PruneStepResult *) palloc0(sizeof(PruneStepResult)); bool firststep; + ListCell *lc1; /* * A combine step without any source steps is an indication to not perform * any partition pruning. Return all datum indexes in that case. */ - result = (PruneStepResult *) palloc0(sizeof(PruneStepResult)); - if (list_length(cstep->source_stepids) == 0) + if (cstep->source_stepids == NIL) { PartitionBoundInfo boundinfo = context->boundinfo; - int rangemax; - - /* - * Add all valid offsets into the boundinfo->indexes array. For range - * partitioning, boundinfo->indexes contains (boundinfo->ndatums + 1) - * valid entries; otherwise there are boundinfo->ndatums. - */ - rangemax = context->strategy == PARTITION_STRATEGY_RANGE ? - boundinfo->ndatums : boundinfo->ndatums - 1; result->bound_offsets = - bms_add_range(result->bound_offsets, 0, rangemax); + bms_add_range(NULL, 0, boundinfo->nindexes - 1); result->scan_default = partition_bound_has_default(boundinfo); result->scan_null = partition_bound_accepts_nulls(boundinfo); return result; |