Skip to content

Commit 560564d

Browse files
committed
Enable hash partitioning of text arrays
hash_array_extended() needs to pass PG_GET_COLLATION() to the hash function of the element type. Otherwise, the hash function of a collation-aware data type such as text will error out, since the introduction of nondeterministic collation made hash functions require a collation, too. The consequence of this is that before this change, hash partitioning using an array over text in the partition key would not work. Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi> Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Reviewed-by: Michael Paquier <michael@paquier.xyz> Discussion: https://www.postgresql.org/message-id/flat/32c1fdae-95c6-5dc6-058a-a90330a3b621%40enterprisedb.com
1 parent 37d2ff3 commit 560564d

File tree

3 files changed

+77
-1
lines changed

3 files changed

+77
-1
lines changed

src/backend/utils/adt/arrayfuncs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4071,7 +4071,7 @@ hash_array_extended(PG_FUNCTION_ARGS)
40714071
typalign = typentry->typalign;
40724072

40734073
InitFunctionCallInfoData(*locfcinfo, &typentry->hash_extended_proc_finfo, 2,
4074-
InvalidOid, NULL, NULL);
4074+
PG_GET_COLLATION(), NULL, NULL);
40754075

40764076
/* Loop over source data */
40774077
nitems = ArrayGetNItems(ndims, dims);

src/test/regress/expected/collate.icu.utf8.out

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,6 +1212,30 @@ SELECT * FROM test6 WHERE b = 'äbc' COLLATE ctest_nondet;
12121212
2 | äbc
12131213
(2 rows)
12141214

1215+
-- same with arrays
1216+
CREATE TABLE test6a (a int, b text[]);
1217+
INSERT INTO test6a VALUES (1, ARRAY[U&'\00E4bc']);
1218+
INSERT INTO test6a VALUES (2, ARRAY[U&'\0061\0308bc']);
1219+
SELECT * FROM test6a;
1220+
a | b
1221+
---+-------
1222+
1 | {äbc}
1223+
2 | {äbc}
1224+
(2 rows)
1225+
1226+
SELECT * FROM test6a WHERE b = ARRAY['äbc'] COLLATE ctest_det;
1227+
a | b
1228+
---+-------
1229+
1 | {äbc}
1230+
(1 row)
1231+
1232+
SELECT * FROM test6a WHERE b = ARRAY['äbc'] COLLATE ctest_nondet;
1233+
a | b
1234+
---+-------
1235+
1 | {äbc}
1236+
2 | {äbc}
1237+
(2 rows)
1238+
12151239
CREATE COLLATION case_sensitive (provider = icu, locale = '');
12161240
CREATE COLLATION case_insensitive (provider = icu, locale = '@colStrength=secondary', deterministic = false);
12171241
SELECT 'abc' <= 'ABC' COLLATE case_sensitive, 'abc' >= 'ABC' COLLATE case_sensitive;
@@ -1839,6 +1863,19 @@ SELECT (SELECT count(*) FROM test22_0) = (SELECT count(*) FROM test22_1);
18391863
t
18401864
(1 row)
18411865

1866+
-- same with arrays
1867+
CREATE TABLE test22a (a int, b text[] COLLATE case_sensitive) PARTITION BY HASH (b);
1868+
CREATE TABLE test22a_0 PARTITION OF test22a FOR VALUES WITH (MODULUS 2, REMAINDER 0);
1869+
CREATE TABLE test22a_1 PARTITION OF test22a FOR VALUES WITH (MODULUS 2, REMAINDER 1);
1870+
INSERT INTO test22a VALUES (1, ARRAY['def']);
1871+
INSERT INTO test22a VALUES (2, ARRAY['DEF']);
1872+
-- they end up in different partitions
1873+
SELECT (SELECT count(*) FROM test22a_0) = (SELECT count(*) FROM test22a_1);
1874+
?column?
1875+
----------
1876+
t
1877+
(1 row)
1878+
18421879
CREATE TABLE test23 (a int, b text COLLATE case_insensitive) PARTITION BY HASH (b);
18431880
CREATE TABLE test23_0 PARTITION OF test23 FOR VALUES WITH (MODULUS 2, REMAINDER 0);
18441881
CREATE TABLE test23_1 PARTITION OF test23 FOR VALUES WITH (MODULUS 2, REMAINDER 1);
@@ -1851,6 +1888,19 @@ SELECT (SELECT count(*) FROM test23_0) <> (SELECT count(*) FROM test23_1);
18511888
t
18521889
(1 row)
18531890

1891+
-- same with arrays
1892+
CREATE TABLE test23a (a int, b text[] COLLATE case_insensitive) PARTITION BY HASH (b);
1893+
CREATE TABLE test23a_0 PARTITION OF test23a FOR VALUES WITH (MODULUS 2, REMAINDER 0);
1894+
CREATE TABLE test23a_1 PARTITION OF test23a FOR VALUES WITH (MODULUS 2, REMAINDER 1);
1895+
INSERT INTO test23a VALUES (1, ARRAY['def']);
1896+
INSERT INTO test23a VALUES (2, ARRAY['DEF']);
1897+
-- they end up in the same partition (but it's platform-dependent which one)
1898+
SELECT (SELECT count(*) FROM test23a_0) <> (SELECT count(*) FROM test23a_1);
1899+
?column?
1900+
----------
1901+
t
1902+
(1 row)
1903+
18541904
CREATE TABLE test30 (a int, b char(3) COLLATE case_insensitive) PARTITION BY LIST (b);
18551905
CREATE TABLE test30_1 PARTITION OF test30 FOR VALUES IN ('abc');
18561906
INSERT INTO test30 VALUES (1, 'abc');

src/test/regress/sql/collate.icu.utf8.sql

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,14 @@ SELECT * FROM test6;
478478
SELECT * FROM test6 WHERE b = 'äbc' COLLATE ctest_det;
479479
SELECT * FROM test6 WHERE b = 'äbc' COLLATE ctest_nondet;
480480

481+
-- same with arrays
482+
CREATE TABLE test6a (a int, b text[]);
483+
INSERT INTO test6a VALUES (1, ARRAY[U&'\00E4bc']);
484+
INSERT INTO test6a VALUES (2, ARRAY[U&'\0061\0308bc']);
485+
SELECT * FROM test6a;
486+
SELECT * FROM test6a WHERE b = ARRAY['äbc'] COLLATE ctest_det;
487+
SELECT * FROM test6a WHERE b = ARRAY['äbc'] COLLATE ctest_nondet;
488+
481489
CREATE COLLATION case_sensitive (provider = icu, locale = '');
482490
CREATE COLLATION case_insensitive (provider = icu, locale = '@colStrength=secondary', deterministic = false);
483491

@@ -680,6 +688,15 @@ INSERT INTO test22 VALUES (2, 'DEF');
680688
-- they end up in different partitions
681689
SELECT (SELECT count(*) FROM test22_0) = (SELECT count(*) FROM test22_1);
682690

691+
-- same with arrays
692+
CREATE TABLE test22a (a int, b text[] COLLATE case_sensitive) PARTITION BY HASH (b);
693+
CREATE TABLE test22a_0 PARTITION OF test22a FOR VALUES WITH (MODULUS 2, REMAINDER 0);
694+
CREATE TABLE test22a_1 PARTITION OF test22a FOR VALUES WITH (MODULUS 2, REMAINDER 1);
695+
INSERT INTO test22a VALUES (1, ARRAY['def']);
696+
INSERT INTO test22a VALUES (2, ARRAY['DEF']);
697+
-- they end up in different partitions
698+
SELECT (SELECT count(*) FROM test22a_0) = (SELECT count(*) FROM test22a_1);
699+
683700
CREATE TABLE test23 (a int, b text COLLATE case_insensitive) PARTITION BY HASH (b);
684701
CREATE TABLE test23_0 PARTITION OF test23 FOR VALUES WITH (MODULUS 2, REMAINDER 0);
685702
CREATE TABLE test23_1 PARTITION OF test23 FOR VALUES WITH (MODULUS 2, REMAINDER 1);
@@ -688,6 +705,15 @@ INSERT INTO test23 VALUES (2, 'DEF');
688705
-- they end up in the same partition (but it's platform-dependent which one)
689706
SELECT (SELECT count(*) FROM test23_0) <> (SELECT count(*) FROM test23_1);
690707

708+
-- same with arrays
709+
CREATE TABLE test23a (a int, b text[] COLLATE case_insensitive) PARTITION BY HASH (b);
710+
CREATE TABLE test23a_0 PARTITION OF test23a FOR VALUES WITH (MODULUS 2, REMAINDER 0);
711+
CREATE TABLE test23a_1 PARTITION OF test23a FOR VALUES WITH (MODULUS 2, REMAINDER 1);
712+
INSERT INTO test23a VALUES (1, ARRAY['def']);
713+
INSERT INTO test23a VALUES (2, ARRAY['DEF']);
714+
-- they end up in the same partition (but it's platform-dependent which one)
715+
SELECT (SELECT count(*) FROM test23a_0) <> (SELECT count(*) FROM test23a_1);
716+
691717
CREATE TABLE test30 (a int, b char(3) COLLATE case_insensitive) PARTITION BY LIST (b);
692718
CREATE TABLE test30_1 PARTITION OF test30 FOR VALUES IN ('abc');
693719
INSERT INTO test30 VALUES (1, 'abc');

0 commit comments

Comments
 (0)