mirror of https://github.com/citusdata/citus.git
Handle new option colliculocale in CREATE COLLATION logic
In PG15, there is an added option to use ICU as global locale provider. pg_collation has three locale-related fields: collcollate and collctype, which are libc-related fields, and a new one colliculocale, which is the ICU-related field. Only the libc-related fields or the ICU-related field is set, never both. Relevant PG commits: f2553d43060edb210b36c63187d52a632448e1d2 54637508f87bd5f07fb9406bac6b08240283be3bpg_15_iso_fix
parent
ab802038da
commit
c8888e19d1
|
@ -63,15 +63,53 @@ CreateCollationDDLInternal(Oid collationId, Oid *collowner, char **quotedCollati
|
||||||
const char *collname = NameStr(collationForm->collname);
|
const char *collname = NameStr(collationForm->collname);
|
||||||
bool collisdeterministic = collationForm->collisdeterministic;
|
bool collisdeterministic = collationForm->collisdeterministic;
|
||||||
|
|
||||||
|
char *collcollate;
|
||||||
|
char *collctype;
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
#if PG_VERSION_NUM >= PG_VERSION_15
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In PG15, there is an added option to use ICU as global locale provider.
|
||||||
|
* pg_collation has three locale-related fields: collcollate and collctype,
|
||||||
|
* which are libc-related fields, and a new one colliculocale, which is the
|
||||||
|
* ICU-related field. Only the libc-related fields or the ICU-related field
|
||||||
|
* is set, never both.
|
||||||
|
*/
|
||||||
|
char *colliculocale;
|
||||||
bool isnull;
|
bool isnull;
|
||||||
|
|
||||||
Datum datum = SysCacheGetAttr(COLLOID, heapTuple, Anum_pg_collation_collcollate,
|
Datum datum = SysCacheGetAttr(COLLOID, heapTuple, Anum_pg_collation_collcollate,
|
||||||
&isnull);
|
&isnull);
|
||||||
Assert(!isnull);
|
if (!isnull)
|
||||||
char *collcollate = TextDatumGetCString(datum);
|
{
|
||||||
|
collcollate = TextDatumGetCString(datum);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
collcollate = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
datum = SysCacheGetAttr(COLLOID, heapTuple, Anum_pg_collation_collctype, &isnull);
|
datum = SysCacheGetAttr(COLLOID, heapTuple, Anum_pg_collation_collctype, &isnull);
|
||||||
Assert(!isnull);
|
if (!isnull)
|
||||||
char *collctype = TextDatumGetCString(datum);
|
{
|
||||||
|
collctype = TextDatumGetCString(datum);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
collctype = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
datum = SysCacheGetAttr(COLLOID, heapTuple, Anum_pg_collation_colliculocale, &isnull);
|
||||||
|
if (!isnull)
|
||||||
|
{
|
||||||
|
colliculocale = TextDatumGetCString(datum);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
colliculocale = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssertArg((collcollate && collctype) || colliculocale);
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -79,8 +117,8 @@ CreateCollationDDLInternal(Oid collationId, Oid *collowner, char **quotedCollati
|
||||||
* pstrdup() to match the interface of 15 so that we consistently free the
|
* pstrdup() to match the interface of 15 so that we consistently free the
|
||||||
* result later.
|
* result later.
|
||||||
*/
|
*/
|
||||||
char *collcollate = pstrdup(NameStr(collationForm->collcollate));
|
collcollate = pstrdup(NameStr(collationForm->collcollate));
|
||||||
char *collctype = pstrdup(NameStr(collationForm->collctype));
|
collctype = pstrdup(NameStr(collationForm->collctype));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (collowner != NULL)
|
if (collowner != NULL)
|
||||||
|
@ -106,6 +144,33 @@ CreateCollationDDLInternal(Oid collationId, Oid *collowner, char **quotedCollati
|
||||||
"CREATE COLLATION %s (provider = '%s'",
|
"CREATE COLLATION %s (provider = '%s'",
|
||||||
*quotedCollationName, providerString);
|
*quotedCollationName, providerString);
|
||||||
|
|
||||||
|
#if PG_VERSION_NUM >= PG_VERSION_15
|
||||||
|
if (colliculocale)
|
||||||
|
{
|
||||||
|
appendStringInfo(&collationNameDef,
|
||||||
|
", locale = %s",
|
||||||
|
quote_literal_cstr(colliculocale));
|
||||||
|
pfree(colliculocale);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (strcmp(collcollate, collctype) == 0)
|
||||||
|
{
|
||||||
|
appendStringInfo(&collationNameDef,
|
||||||
|
", locale = %s",
|
||||||
|
quote_literal_cstr(collcollate));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
appendStringInfo(&collationNameDef,
|
||||||
|
", lc_collate = %s, lc_ctype = %s",
|
||||||
|
quote_literal_cstr(collcollate),
|
||||||
|
quote_literal_cstr(collctype));
|
||||||
|
}
|
||||||
|
pfree(collcollate);
|
||||||
|
pfree(collctype);
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (strcmp(collcollate, collctype) == 0)
|
if (strcmp(collcollate, collctype) == 0)
|
||||||
{
|
{
|
||||||
appendStringInfo(&collationNameDef,
|
appendStringInfo(&collationNameDef,
|
||||||
|
@ -122,6 +187,7 @@ CreateCollationDDLInternal(Oid collationId, Oid *collowner, char **quotedCollati
|
||||||
|
|
||||||
pfree(collcollate);
|
pfree(collcollate);
|
||||||
pfree(collctype);
|
pfree(collctype);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!collisdeterministic)
|
if (!collisdeterministic)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
--
|
||||||
|
-- PG15
|
||||||
|
--
|
||||||
|
SHOW server_version \gset
|
||||||
|
SELECT substring(:'server_version', '\d+')::int > 14 AS server_version_above_fourteen
|
||||||
|
\gset
|
||||||
|
\if :server_version_above_fourteen
|
||||||
|
\else
|
||||||
|
\q
|
||||||
|
\endif
|
||||||
|
CREATE SCHEMA pg15;
|
||||||
|
SET search_path TO pg15;
|
||||||
|
SET citus.next_shard_id TO 960000;
|
||||||
|
SET citus.shard_count TO 4;
|
||||||
|
--
|
||||||
|
-- In PG15, there is an added option to use ICU as global locale provider.
|
||||||
|
-- pg_collation has three locale-related fields: collcollate and collctype,
|
||||||
|
-- which are libc-related fields, and a new one colliculocale, which is the
|
||||||
|
-- ICU-related field. Only the libc-related fields or the ICU-related field
|
||||||
|
-- is set, never both.
|
||||||
|
-- Relevant PG commits:
|
||||||
|
-- f2553d43060edb210b36c63187d52a632448e1d2
|
||||||
|
-- 54637508f87bd5f07fb9406bac6b08240283be3b
|
||||||
|
--
|
||||||
|
-- fail, needs "locale"
|
||||||
|
CREATE COLLATION german_phonebook_test (provider = icu, lc_collate = 'de-u-co-phonebk');
|
||||||
|
ERROR: parameter "locale" must be specified
|
||||||
|
-- fail, needs "locale"
|
||||||
|
CREATE COLLATION german_phonebook_test (provider = icu, lc_collate = 'de-u-co-phonebk', lc_ctype = 'de-u-co-phonebk');
|
||||||
|
ERROR: parameter "locale" must be specified
|
||||||
|
-- works
|
||||||
|
CREATE COLLATION german_phonebook_test (provider = icu, locale = 'de-u-co-phonebk');
|
||||||
|
-- with icu provider, colliculocale will be set, collcollate and collctype will be null
|
||||||
|
SELECT result FROM run_command_on_all_nodes('
|
||||||
|
SELECT collcollate FROM pg_collation WHERE collname = ''german_phonebook_test'';
|
||||||
|
');
|
||||||
|
result
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT result FROM run_command_on_all_nodes('
|
||||||
|
SELECT collctype FROM pg_collation WHERE collname = ''german_phonebook_test'';
|
||||||
|
');
|
||||||
|
result
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT result FROM run_command_on_all_nodes('
|
||||||
|
SELECT colliculocale FROM pg_collation WHERE collname = ''german_phonebook_test'';
|
||||||
|
');
|
||||||
|
result
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
de-u-co-phonebk
|
||||||
|
de-u-co-phonebk
|
||||||
|
de-u-co-phonebk
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
-- with non-icu provider, colliculocale will be null, collcollate and collctype will be set
|
||||||
|
CREATE COLLATION default_provider (provider = libc, lc_collate = "POSIX", lc_ctype = "POSIX");
|
||||||
|
SELECT result FROM run_command_on_all_nodes('
|
||||||
|
SELECT collcollate FROM pg_collation WHERE collname = ''default_provider'';
|
||||||
|
');
|
||||||
|
result
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
POSIX
|
||||||
|
POSIX
|
||||||
|
POSIX
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT result FROM run_command_on_all_nodes('
|
||||||
|
SELECT collctype FROM pg_collation WHERE collname = ''default_provider'';
|
||||||
|
');
|
||||||
|
result
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
POSIX
|
||||||
|
POSIX
|
||||||
|
POSIX
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT result FROM run_command_on_all_nodes('
|
||||||
|
SELECT colliculocale FROM pg_collation WHERE collname = ''default_provider'';
|
||||||
|
');
|
||||||
|
result
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
-- Clean up
|
||||||
|
DROP SCHEMA pg15 CASCADE;
|
||||||
|
NOTICE: drop cascades to 2 other objects
|
||||||
|
DETAIL: drop cascades to collation german_phonebook_test
|
||||||
|
drop cascades to collation default_provider
|
|
@ -0,0 +1,9 @@
|
||||||
|
--
|
||||||
|
-- PG15
|
||||||
|
--
|
||||||
|
SHOW server_version \gset
|
||||||
|
SELECT substring(:'server_version', '\d+')::int > 14 AS server_version_above_fourteen
|
||||||
|
\gset
|
||||||
|
\if :server_version_above_fourteen
|
||||||
|
\else
|
||||||
|
\q
|
|
@ -58,6 +58,7 @@ test: cte_inline recursive_view_local_table values sequences_with_different_type
|
||||||
test: pg13 pg12
|
test: pg13 pg12
|
||||||
# run pg14 sequentially as it syncs metadata
|
# run pg14 sequentially as it syncs metadata
|
||||||
test: pg14
|
test: pg14
|
||||||
|
test: pg15
|
||||||
test: drop_column_partitioned_table
|
test: drop_column_partitioned_table
|
||||||
test: tableam
|
test: tableam
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
--
|
||||||
|
-- PG15
|
||||||
|
--
|
||||||
|
SHOW server_version \gset
|
||||||
|
SELECT substring(:'server_version', '\d+')::int > 14 AS server_version_above_fourteen
|
||||||
|
\gset
|
||||||
|
\if :server_version_above_fourteen
|
||||||
|
\else
|
||||||
|
\q
|
||||||
|
\endif
|
||||||
|
|
||||||
|
CREATE SCHEMA pg15;
|
||||||
|
SET search_path TO pg15;
|
||||||
|
SET citus.next_shard_id TO 960000;
|
||||||
|
SET citus.shard_count TO 4;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- In PG15, there is an added option to use ICU as global locale provider.
|
||||||
|
-- pg_collation has three locale-related fields: collcollate and collctype,
|
||||||
|
-- which are libc-related fields, and a new one colliculocale, which is the
|
||||||
|
-- ICU-related field. Only the libc-related fields or the ICU-related field
|
||||||
|
-- is set, never both.
|
||||||
|
-- Relevant PG commits:
|
||||||
|
-- f2553d43060edb210b36c63187d52a632448e1d2
|
||||||
|
-- 54637508f87bd5f07fb9406bac6b08240283be3b
|
||||||
|
--
|
||||||
|
|
||||||
|
-- fail, needs "locale"
|
||||||
|
CREATE COLLATION german_phonebook_test (provider = icu, lc_collate = 'de-u-co-phonebk');
|
||||||
|
|
||||||
|
-- fail, needs "locale"
|
||||||
|
CREATE COLLATION german_phonebook_test (provider = icu, lc_collate = 'de-u-co-phonebk', lc_ctype = 'de-u-co-phonebk');
|
||||||
|
|
||||||
|
-- works
|
||||||
|
CREATE COLLATION german_phonebook_test (provider = icu, locale = 'de-u-co-phonebk');
|
||||||
|
|
||||||
|
-- with icu provider, colliculocale will be set, collcollate and collctype will be null
|
||||||
|
SELECT result FROM run_command_on_all_nodes('
|
||||||
|
SELECT collcollate FROM pg_collation WHERE collname = ''german_phonebook_test'';
|
||||||
|
');
|
||||||
|
SELECT result FROM run_command_on_all_nodes('
|
||||||
|
SELECT collctype FROM pg_collation WHERE collname = ''german_phonebook_test'';
|
||||||
|
');
|
||||||
|
SELECT result FROM run_command_on_all_nodes('
|
||||||
|
SELECT colliculocale FROM pg_collation WHERE collname = ''german_phonebook_test'';
|
||||||
|
');
|
||||||
|
|
||||||
|
-- with non-icu provider, colliculocale will be null, collcollate and collctype will be set
|
||||||
|
CREATE COLLATION default_provider (provider = libc, lc_collate = "POSIX", lc_ctype = "POSIX");
|
||||||
|
|
||||||
|
SELECT result FROM run_command_on_all_nodes('
|
||||||
|
SELECT collcollate FROM pg_collation WHERE collname = ''default_provider'';
|
||||||
|
');
|
||||||
|
SELECT result FROM run_command_on_all_nodes('
|
||||||
|
SELECT collctype FROM pg_collation WHERE collname = ''default_provider'';
|
||||||
|
');
|
||||||
|
SELECT result FROM run_command_on_all_nodes('
|
||||||
|
SELECT colliculocale FROM pg_collation WHERE collname = ''default_provider'';
|
||||||
|
');
|
||||||
|
|
||||||
|
-- Clean up
|
||||||
|
DROP SCHEMA pg15 CASCADE;
|
Loading…
Reference in New Issue