Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 4b40e44

Browse files
committed
Fix failure with textual partition hash keys.
Commit 5e1963f overlooked two places in partbounds.c that now need to pass a collation identifier to the hash functions for a partition key column. Amit Langote, per report from Jesper Pedersen Discussion: https://postgr.es/m/a620f85a-42ab-e0f3-3337-b04b97e2e2f5@redhat.com
1 parent 47169c2 commit 4b40e44

File tree

3 files changed

+39
-13
lines changed

3 files changed

+39
-13
lines changed

src/backend/partitioning/partbounds.c

+15-13
Original file line numberDiff line numberDiff line change
@@ -2742,7 +2742,8 @@ compute_partition_hash_value(int partnatts, FmgrInfo *partsupfunc, Oid *partcoll
27422742
* datatype-specific hash functions of each partition key
27432743
* attribute.
27442744
*/
2745-
hash = FunctionCall2Coll(&partsupfunc[i], partcollation[i], values[i], seed);
2745+
hash = FunctionCall2Coll(&partsupfunc[i], partcollation[i],
2746+
values[i], seed);
27462747

27472748
/* Form a single 64-bit hash value */
27482749
rowHash = hash_combine64(rowHash, DatumGetUInt64(hash));
@@ -2777,7 +2778,8 @@ satisfies_hash_partition(PG_FUNCTION_ARGS)
27772778
int16 variadic_typlen;
27782779
bool variadic_typbyval;
27792780
char variadic_typalign;
2780-
FmgrInfo partsupfunc[PARTITION_MAX_KEYS];
2781+
Oid partcollid[PARTITION_MAX_KEYS];
2782+
FmgrInfo partsupfunc[FLEXIBLE_ARRAY_MEMBER];
27812783
} ColumnsHashData;
27822784
Oid parentId;
27832785
int modulus;
@@ -2850,6 +2852,8 @@ satisfies_hash_partition(PG_FUNCTION_ARGS)
28502852
my_extra = (ColumnsHashData *) fcinfo->flinfo->fn_extra;
28512853
my_extra->relid = parentId;
28522854
my_extra->nkeys = key->partnatts;
2855+
memcpy(my_extra->partcollid, key->partcollation,
2856+
key->partnatts * sizeof(Oid));
28532857

28542858
/* check argument types and save fmgr_infos */
28552859
for (j = 0; j < key->partnatts; ++j)
@@ -2866,7 +2870,6 @@ satisfies_hash_partition(PG_FUNCTION_ARGS)
28662870
&key->partsupfunc[j],
28672871
fcinfo->flinfo->fn_mcxt);
28682872
}
2869-
28702873
}
28712874
else
28722875
{
@@ -2885,6 +2888,7 @@ satisfies_hash_partition(PG_FUNCTION_ARGS)
28852888
&my_extra->variadic_typlen,
28862889
&my_extra->variadic_typbyval,
28872890
&my_extra->variadic_typalign);
2891+
my_extra->partcollid[0] = key->partcollation[0];
28882892

28892893
/* check argument types */
28902894
for (j = 0; j < key->partnatts; ++j)
@@ -2926,11 +2930,10 @@ satisfies_hash_partition(PG_FUNCTION_ARGS)
29262930
if (PG_ARGISNULL(argno))
29272931
continue;
29282932

2929-
Assert(OidIsValid(my_extra->partsupfunc[i].fn_oid));
2930-
2931-
hash = FunctionCall2(&my_extra->partsupfunc[i],
2932-
PG_GETARG_DATUM(argno),
2933-
seed);
2933+
hash = FunctionCall2Coll(&my_extra->partsupfunc[i],
2934+
my_extra->partcollid[i],
2935+
PG_GETARG_DATUM(argno),
2936+
seed);
29342937

29352938
/* Form a single 64-bit hash value */
29362939
rowHash = hash_combine64(rowHash, DatumGetUInt64(hash));
@@ -2965,11 +2968,10 @@ satisfies_hash_partition(PG_FUNCTION_ARGS)
29652968
if (isnull[i])
29662969
continue;
29672970

2968-
Assert(OidIsValid(my_extra->partsupfunc[0].fn_oid));
2969-
2970-
hash = FunctionCall2(&my_extra->partsupfunc[0],
2971-
datum[i],
2972-
seed);
2971+
hash = FunctionCall2Coll(&my_extra->partsupfunc[0],
2972+
my_extra->partcollid[0],
2973+
datum[i],
2974+
seed);
29732975

29742976
/* Form a single 64-bit hash value */
29752977
rowHash = hash_combine64(rowHash, DatumGetUInt64(hash));

src/test/regress/expected/hash_part.out

+14
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,20 @@ ERROR: number of partitioning columns (2) does not match number of partition ke
9999
SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0,
100100
variadic array[now(), now()]);
101101
ERROR: column 1 of the partition key has type "integer", but supplied value is of type "timestamp with time zone"
102+
-- check satisfies_hash_partition passes correct collation
103+
create table text_hashp (a text) partition by hash (a);
104+
create table text_hashp0 partition of text_hashp for values with (modulus 2, remainder 0);
105+
create table text_hashp1 partition of text_hashp for values with (modulus 2, remainder 1);
106+
-- The result here should always be true, because 'xxx' must belong to
107+
-- one of the two defined partitions
108+
select satisfies_hash_partition('text_hashp'::regclass, 2, 0, 'xxx'::text) OR
109+
satisfies_hash_partition('text_hashp'::regclass, 2, 1, 'xxx'::text) AS satisfies;
110+
satisfies
111+
-----------
112+
t
113+
(1 row)
114+
102115
-- cleanup
103116
DROP TABLE mchash;
104117
DROP TABLE mcinthash;
118+
DROP TABLE text_hashp;

src/test/regress/sql/hash_part.sql

+10
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,16 @@ SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0,
7575
SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0,
7676
variadic array[now(), now()]);
7777

78+
-- check satisfies_hash_partition passes correct collation
79+
create table text_hashp (a text) partition by hash (a);
80+
create table text_hashp0 partition of text_hashp for values with (modulus 2, remainder 0);
81+
create table text_hashp1 partition of text_hashp for values with (modulus 2, remainder 1);
82+
-- The result here should always be true, because 'xxx' must belong to
83+
-- one of the two defined partitions
84+
select satisfies_hash_partition('text_hashp'::regclass, 2, 0, 'xxx'::text) OR
85+
satisfies_hash_partition('text_hashp'::regclass, 2, 1, 'xxx'::text) AS satisfies;
86+
7887
-- cleanup
7988
DROP TABLE mchash;
8089
DROP TABLE mcinthash;
90+
DROP TABLE text_hashp;

0 commit comments

Comments
 (0)