diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c index c8770ccfee..460f023134 100644 --- a/src/backend/partitioning/partbounds.c +++ b/src/backend/partitioning/partbounds.c @@ -2777,7 +2777,8 @@ satisfies_hash_partition(PG_FUNCTION_ARGS) int16 variadic_typlen; bool variadic_typbyval; char variadic_typalign; - FmgrInfo partsupfunc[PARTITION_MAX_KEYS]; + Oid partcollid[PARTITION_MAX_KEYS]; + FmgrInfo partsupfunc[FLEXIBLE_ARRAY_MEMBER]; } ColumnsHashData; Oid parentId; int modulus; @@ -2851,6 +2852,8 @@ satisfies_hash_partition(PG_FUNCTION_ARGS) my_extra->relid = parentId; my_extra->nkeys = key->partnatts; + memcpy(my_extra->partcollid, key->partcollation, + key->partnatts * sizeof(Oid)); /* check argument types and save fmgr_infos */ for (j = 0; j < key->partnatts; ++j) { @@ -2885,6 +2888,7 @@ satisfies_hash_partition(PG_FUNCTION_ARGS) &my_extra->variadic_typlen, &my_extra->variadic_typbyval, &my_extra->variadic_typalign); + my_extra->partcollid[0] = key->partcollation[0]; /* check argument types */ for (j = 0; j < key->partnatts; ++j) @@ -2928,9 +2932,10 @@ satisfies_hash_partition(PG_FUNCTION_ARGS) Assert(OidIsValid(my_extra->partsupfunc[i].fn_oid)); - hash = FunctionCall2(&my_extra->partsupfunc[i], - PG_GETARG_DATUM(argno), - seed); + hash = FunctionCall2Coll(&my_extra->partsupfunc[i], + my_extra->partcollid[i], + PG_GETARG_DATUM(argno), + seed); /* Form a single 64-bit hash value */ rowHash = hash_combine64(rowHash, DatumGetUInt64(hash)); @@ -2967,9 +2972,10 @@ satisfies_hash_partition(PG_FUNCTION_ARGS) Assert(OidIsValid(my_extra->partsupfunc[0].fn_oid)); - hash = FunctionCall2(&my_extra->partsupfunc[0], - datum[i], - seed); + hash = FunctionCall2Coll(&my_extra->partsupfunc[0], + my_extra->partcollid[0], + datum[i], + seed); /* Form a single 64-bit hash value */ rowHash = hash_combine64(rowHash, DatumGetUInt64(hash)); diff --git a/src/test/regress/expected/hash_part.out b/src/test/regress/expected/hash_part.out index 731d26fc3d..8db316be27 100644 --- a/src/test/regress/expected/hash_part.out +++ b/src/test/regress/expected/hash_part.out @@ -99,6 +99,20 @@ ERROR: number of partitioning columns (2) does not match number of partition ke SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, variadic array[now(), now()]); ERROR: column 1 of the partition key has type "integer", but supplied value is of type "timestamp with time zone" +-- check satisfies_hash_partition passes correct collation +create table text_hashp (a text) partition by hash (a); +create table text_hashp0 partition of text_hashp for values with (modulus 2, remainder 0); +create table text_hashp1 partition of text_hashp for values with (modulus 2, remainder 1); +-- The result here should always be true, because 'xxx' must belong to +-- one of the two defined partitions +select satisfies_hash_partition('text_hashp'::regclass, 2, 0, 'xxx'::text) OR + satisfies_hash_partition('text_hashp'::regclass, 2, 1, 'xxx'::text) AS satisfies; + satisfies +----------- + t +(1 row) + -- cleanup DROP TABLE mchash; DROP TABLE mcinthash; +DROP TABLE text_hashp; diff --git a/src/test/regress/sql/hash_part.sql b/src/test/regress/sql/hash_part.sql index f457ac344c..30601b913e 100644 --- a/src/test/regress/sql/hash_part.sql +++ b/src/test/regress/sql/hash_part.sql @@ -75,6 +75,16 @@ SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, variadic array[now(), now()]); +-- check satisfies_hash_partition passes correct collation +create table text_hashp (a text) partition by hash (a); +create table text_hashp0 partition of text_hashp for values with (modulus 2, remainder 0); +create table text_hashp1 partition of text_hashp for values with (modulus 2, remainder 1); +-- The result here should always be true, because 'xxx' must belong to +-- one of the two defined partitions +select satisfies_hash_partition('text_hashp'::regclass, 2, 0, 'xxx'::text) OR + satisfies_hash_partition('text_hashp'::regclass, 2, 1, 'xxx'::text) AS satisfies; + -- cleanup DROP TABLE mchash; DROP TABLE mcinthash; +DROP TABLE text_hashp;