diff --git a/src/backend/catalog/partition.c b/src/backend/catalog/partition.c index 5b201d6..15d6170 100644 --- a/src/backend/catalog/partition.c +++ b/src/backend/catalog/partition.c @@ -711,32 +711,27 @@ partition_bounds_equal(PartitionKey key, int greatest_modulus; /* - * Compare greatest modulus of hash partition bound which - * is the last element of datums array. + * If two hash partitioned tables have different greatest moduli or + * same moduli with different number of partitions, their partition + * schemes don't match. For hash partitioned table, the greatest + * modulus is given by the last datum and number of partitions is given + * by ndatums. */ if (b1->datums[b1->ndatums - 1][0] != b2->datums[b2->ndatums - 1][0]) return false; - /* Compare number of partitions */ if (b1->ndatums != b2->ndatums) return false; /* - * If two hash partitioned tables have different greatest moduli or - * same moduli with different number of partitions, their partition - * schemes don't match. If they have same greatest moduli, and number - * of partitions, they all have same hash partition bound i.e. modulus - * and remainder, and the partitions are ordered by modulus, then by - * remainders, thus indexes array will be an identity i.e. index[i] = i. - * If the partition corresponding to a given remainder exists, it will - * have same index entry for both partitioned tables or if it's missing - * it will be -1. Thus if indexes array matches, corresponding datums - * array matches. If there are multiple remainders corresponding to a - * given partition, their partitions are ordered by the hash partition - * bound, thus if indexes array matches, both of the tables have same - * indexes arrays, in both the tables remainders corresponding to - * multiple partitions all have same hash partition bound and thus same - * modulus. Thus again if the indexes are same, datums are same. + * We arrange the partitions in the ascending order of their modulus + * and remainders. Also every modulus is factor of next larger modulus. + * This means that the index of a given partition is same as the + * 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. */ greatest_modulus = DatumGetInt32(b1->datums[b1->ndatums - 1][0]); for (i = 0; i < greatest_modulus; i++) @@ -745,9 +740,12 @@ partition_bounds_equal(PartitionKey key, #ifdef USE_ASSERT_CHECKING { + /* - * Hash partition bound stores modulus and remainder at - * b1->datums[i][0] and b1->datums[i][1] position respectively. + * Nonetheless make sure that the bounds are indeed same when the + * indexes match. Hash partition bound stores modulus and + * remainder at b1->datums[i][0] and b1->datums[i][1] position + * respectively. */ for (i = 0; i < b1->ndatums; i++) Assert((b1->datums[i][0] == b2->datums[i][0] && diff --git a/src/test/regress/sql/create_table.sql b/src/test/regress/sql/create_table.sql index 834cba2..06ee5f0 100644 --- a/src/test/regress/sql/create_table.sql +++ b/src/test/regress/sql/create_table.sql @@ -320,9 +320,8 @@ CREATE TABLE partitioned ( a int ) PARTITION BY RANGE (a, a); --- cannot have collation for hash partition key column (although grammar allows). --- Since hash opclasses provide only equality, not ordering, so that collation --- is irrelevant here. +-- Since hash opclasses provide only equality and not ordering, collation +-- is irrelevant for hash partitioning. CREATE TABLE partitioned ( a text ) PARTITION BY HASH (a collate "C");