SET citus.next_shard_id TO 20050000; CREATE USER collationuser; CREATE SCHEMA collation_tests AUTHORIZATION collationuser; CREATE SCHEMA collation_tests2 AUTHORIZATION collationuser; SET search_path to collation_tests; CREATE COLLATION german_phonebook (provider = icu, locale = 'de-u-co-phonebk'); SET citus.enable_ddl_propagation TO off; CREATE COLLATION german_phonebook_unpropagated (provider = icu, locale = 'de-u-co-phonebk'); SET citus.enable_ddl_propagation TO on; \c - - - :worker_1_port SELECT c.collname, nsp.nspname, a.rolname FROM pg_collation c JOIN pg_namespace nsp ON nsp.oid = c.collnamespace JOIN pg_authid a ON a.oid = c.collowner WHERE collname like 'german_phonebook%' ORDER BY 1,2,3; collname | nspname | rolname --------------------------------------------------------------------- german_phonebook | collation_tests | postgres (1 row) \c - - - :master_port SET search_path to collation_tests; CREATE TABLE test_propagate(id int, t1 text COLLATE german_phonebook, t2 text COLLATE german_phonebook_unpropagated); INSERT INTO test_propagate VALUES (1, 'aesop', U&'\00E4sop'), (2, U&'Vo\1E9Er', 'Vossr'); SELECT create_distributed_table('test_propagate', 'id'); NOTICE: Copying data from local table... NOTICE: copying the data has completed DETAIL: The local data in the table is no longer visible, but is still on disk. HINT: To remove the local data, run: SELECT truncate_local_data_after_distributing_table($$collation_tests.test_propagate$$) create_distributed_table --------------------------------------------------------------------- (1 row) -- Test COLLATE is pushed down SELECT * FROM collation_tests.test_propagate WHERE t2 < 'b'; id | t1 | t2 --------------------------------------------------------------------- 1 | aesop | äsop (1 row) SELECT * FROM collation_tests.test_propagate WHERE t2 < 'b' COLLATE "C"; id | t1 | t2 --------------------------------------------------------------------- 2 | Voẞr | Vossr (1 row) SELECT * FROM collation_tests.test_propagate WHERE t2 COLLATE "C" < 'b'; id | t1 | t2 --------------------------------------------------------------------- 2 | Voẞr | Vossr (1 row) -- Test COLLATE is pushed down with aggregate function SET citus.next_shard_id TO 20060000; CREATE TABLE test_collate_pushed_down_aggregate (a int, b int); SELECT create_distributed_table('test_collate_pushed_down_aggregate', 'a'); create_distributed_table --------------------------------------------------------------------- (1 row) SELECT alter_distributed_table('test_collate_pushed_down_aggregate', shard_count := 2, cascade_to_colocated:=false); NOTICE: creating a new table for collation_tests.test_collate_pushed_down_aggregate NOTICE: moving the data of collation_tests.test_collate_pushed_down_aggregate NOTICE: dropping the old collation_tests.test_collate_pushed_down_aggregate NOTICE: renaming the new table to collation_tests.test_collate_pushed_down_aggregate alter_distributed_table --------------------------------------------------------------------- (1 row) SET citus.log_remote_commands TO true; SELECT ALL MIN((lower(CAST(test_collate_pushed_down_aggregate.a AS VARCHAR)) COLLATE "C")) FROM ONLY test_collate_pushed_down_aggregate; NOTICE: issuing SELECT min((lower(((a)::character varying)::text) COLLATE "C")) AS min FROM ONLY collation_tests.test_collate_pushed_down_aggregate_20060004 test_collate_pushed_down_aggregate WHERE true DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx NOTICE: issuing SELECT min((lower(((a)::character varying)::text) COLLATE "C")) AS min FROM ONLY collation_tests.test_collate_pushed_down_aggregate_20060005 test_collate_pushed_down_aggregate WHERE true DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx min --------------------------------------------------------------------- (1 row) RESET citus.log_remote_commands; -- Test range table with collated distribution column CREATE TABLE test_range(key text COLLATE german_phonebook, val int); SELECT create_distributed_table('test_range', 'key', 'range'); create_distributed_table --------------------------------------------------------------------- (1 row) SELECT master_create_empty_shard('test_range') AS new_shard_id \gset UPDATE pg_dist_shard SET shardminvalue = 'a', shardmaxvalue = 'f' WHERE shardid = :new_shard_id; SELECT master_create_empty_shard('test_range') AS new_shard_id \gset UPDATE pg_dist_shard SET shardminvalue = 'G', shardmaxvalue = 'Z' WHERE shardid = :new_shard_id; -- without german_phonebook collation, this would fail INSERT INTO test_range VALUES (U&'\00E4sop', 1), (U&'Vo\1E9Er', 2); -- without german_phonebook collation, this would not be router executable SET client_min_messages TO debug; SELECT * FROM test_range WHERE key > 'Ab' AND key < U&'\00E4z'; DEBUG: Creating router plan key | val --------------------------------------------------------------------- äsop | 1 (1 row) \c - - - :worker_1_port SELECT c.collname, nsp.nspname, a.rolname FROM pg_collation c JOIN pg_namespace nsp ON nsp.oid = c.collnamespace JOIN pg_authid a ON a.oid = c.collowner WHERE collname like 'german_phonebook%' ORDER BY 1,2,3; collname | nspname | rolname --------------------------------------------------------------------- german_phonebook | collation_tests | postgres german_phonebook_unpropagated | collation_tests | postgres (2 rows) \c - - - :master_port ALTER COLLATION collation_tests.german_phonebook RENAME TO german_phonebook2; ALTER COLLATION collation_tests.german_phonebook2 SET SCHEMA collation_tests2; ALTER COLLATION collation_tests2.german_phonebook2 OWNER TO collationuser; \c - - - :worker_1_port SELECT c.collname, nsp.nspname, a.rolname FROM pg_collation c JOIN pg_namespace nsp ON nsp.oid = c.collnamespace JOIN pg_authid a ON a.oid = c.collowner WHERE collname like 'german_phonebook%' ORDER BY 1,2,3; collname | nspname | rolname --------------------------------------------------------------------- german_phonebook2 | collation_tests2 | collationuser german_phonebook_unpropagated | collation_tests | postgres (2 rows) \c - - - :master_port SET client_min_messages TO error; -- suppress cascading objects dropping DROP SCHEMA collation_tests CASCADE; DROP SCHEMA collation_tests2 CASCADE; DROP USER collationuser; \c - - - :worker_1_port -- test creating a collation on a worker CREATE COLLATION another_german_phonebook (provider = icu, locale = 'de-u-co-phonebk'); ERROR: operation is not allowed on this node HINT: Connect to the coordinator and run it again. -- test if creating a collation on a worker on a local -- schema raises the right error SET citus.enable_ddl_propagation TO off; CREATE SCHEMA collation_creation_on_worker; SET citus.enable_ddl_propagation TO on; CREATE COLLATION collation_creation_on_worker.another_german_phonebook (provider = icu, locale = 'de-u-co-phonebk'); ERROR: operation is not allowed on this node HINT: Connect to the coordinator and run it again. SET citus.enable_ddl_propagation TO off; DROP SCHEMA collation_creation_on_worker; SET citus.enable_ddl_propagation TO on; \c - - - :master_port -- will skip trying to propagate the collation due to temp schema CREATE COLLATION pg_temp.temp_collation (provider = icu, locale = 'de-u-co-phonebk'); WARNING: "collation pg_temp_xxx.temp_collation" has dependency on unsupported object "schema pg_temp_xxx" DETAIL: "collation pg_temp_xxx.temp_collation" will be created only locally SET client_min_messages TO ERROR; CREATE USER alter_collation_user; SELECT 1 FROM run_command_on_workers('CREATE USER alter_collation_user'); ?column? --------------------------------------------------------------------- 1 1 (2 rows) RESET client_min_messages; CREATE COLLATION alter_collation FROM "C"; ALTER COLLATION alter_collation OWNER TO alter_collation_user; SELECT result FROM run_command_on_all_nodes(' SELECT collowner::regrole FROM pg_collation WHERE collname = ''alter_collation''; '); result --------------------------------------------------------------------- alter_collation_user alter_collation_user alter_collation_user (3 rows) DROP COLLATION alter_collation; SET client_min_messages TO ERROR; DROP USER alter_collation_user; SELECT 1 FROM run_command_on_workers('DROP USER alter_collation_user'); ?column? --------------------------------------------------------------------- 1 1 (2 rows) RESET client_min_messages;