Postgres, кажется, игнорирует мою сортировку по умолчанию - PullRequest
2 голосов
/ 27 сентября 2019

Я хочу установить сортировку postgres по умолчанию для сортировки en-US-x-icu, поэтому я установил для переменных окружения LC_CTYPE и LC_COLLATE это значение.Postgres, кажется, видит их и говорит, что использует это сопоставление:

:mctapi=# select datname, datcollate, datctype from pg_database where datname='mctapi';
 datname | datcollate  |  datctype
---------+-------------+-------------
 mctapi  | en-US-x-icu | en-US-x-icu

:mctapi=# show lc_collate;
 lc_collate
-------------
 en-US-x-icu
(1 row)

:mctapi=# show lc_ctype;
  lc_ctype
-------------
 en-US-x-icu
(1 row)

Однако, если я явно не установлю en-US-x-icu в качестве сопоставления, я получу C сопоставление:

:mctapi=# select distinct organization_name from plans order by organization_name limit 5;
            organization_name
------------------------------------------
 AMH Health
 ATRIO Health Plans
 Aetna Medicare
 AgeRight Advantage
 AgeRight Advantage Health Plan (HMO SNP)
(5 rows)

:mctapi=# select distinct organization_name collate "en-US-x-icu" from plans order by organization_name limit 5;
            organization_name
------------------------------------------
 Aetna Medicare
 AgeRight Advantage
 AgeRight Advantage Health Plan (HMO SNP)
 Allwell
 AMH Health
(5 rows)

:mctapi=# select distinct organization_name collate "C" from plans order by organization_name limit 5;
            organization_name
------------------------------------------
 AMH Health
 ATRIO Health Plans
 Aetna Medicare
 AgeRight Advantage
 AgeRight Advantage Health Plan (HMO SNP)
(5 rows)

Что мне нужно сделать, чтобы postgres использовал en-US-x-icu в качестве сортировки по умолчанию в моей базе данных без явной установки параметра сортировки?Почему сортировка выполняется по C, хотя я и просил его отсортировать по en-US-x-icu?

(для чего это стоит: рассматриваемая база данных - это изображение mdillon/postgis:10-alpine, работающее в docker compose. Iна самом деле не хотелось бы уходить от альпийского изображения, но я могу, если его невозможно использовать.)

(обновление: изменение на неальпийское изображение изменило сортировку на en_US.UTF8, так какзадокументировано в документации к докеру postgres ниже и исправил порядок сортировки этой таблицы. Мне все еще хотелось бы знать, почему мой параметр LC_COLLATE не изменил порядок сортировки в alpine, потому что я бы лучше использовал это изображение)

(обновление 2: база данных была создана без параметров кодирования, и я не обновлял pg_database вручную, единственное, что я изменил, это переменные среды LC_CTYPE и LC_COLLATE.

Эта версия postgres была скомпилирована с --with-icu, как вы можете видеть здесь: https://github.com/docker-library/postgres/blob/master/10/alpine/Dockerfile#L113, и https://www.postgresql.org/docs/10/collation.html#COLLATION-MANAGING, конечно, мне кажется, что в моей версии postgres можно использовать локали ICU.

Может быть уместно, что, если я сброслю LC_COLLATE и LC_CTYPE и заново создаю свою базу данных, у нее будут значения сортировки и ctype en_US.UTF8, но эта локаль не существует в образе Alpine, содержащем базу данных, выходя из этой ситуации:

:mctapi=# select datname, datcollate, datctype from pg_database where datname='mctapi';
 datname | datcollate |  datctype
---------+------------+------------
 mctapi  | en_US.utf8 | en_US.utf8
(1 row)

:mctapi=# select distinct organization_name collate "en_US.utf8" from plans order by organization_name limit 5;
ERROR:  collation "en_US.utf8" for encoding "UTF8" does not exist

)

(последнее обновление: я согласен с Laurenz по поводу общей разбитости postgres на альпийском в отношении локалей, и я действительно ценю его взгляд на проблему,Я до сих пор не очень понимаю, почему ICU не работает как LC_COLLATE, или почему он работает , когда упомянуто явно, но я только что согласился, что не могу использовать образ альпийского докера и переехална основанный на Debian.)

Ссылки:

1: https://www.postgresql.org/docs/10/locale.html

2: https://www.postgresql.org/docs/10/collation.html

3: https://www.postgresql.org/docs/10/sql-expressions.html#SQL-SYNTAX-COLLATE-EXPRS

4: https://wiki.postgresql.org/wiki/FAQ#Why_do_my_strings_sort_incorrectly.3F

5: https://github.com/docker-library/docs/tree/master/postgres#locale-customization

1 Ответ

3 голосов
/ 27 сентября 2019

Вы не можете использовать ничего, кроме сопоставлений библиотеки C в CREATE DATABASE.Это недокументированное ограничение, которое, вероятно, будет снято в v13.Для справки см. этот и этот поток.

Итак, сначала я был удивлен, что вам удалось создать эту базу данных, поскольку ваше сопоставление - это сопоставление ICU, котороеобычно доступна только через отдельную библиотеку ICU.

Я обнаружил проблему Silverstripe , которая жалуется на одно и то же, так что, по крайней мере, вы не одиноки.Дискуссия там ни к чему не приведет, поскольку они, похоже, не знают ни Alpine Linux, ни PostgreSQL.

Дальнейшие исследования, основанные на ваших комментариях, показывают, что Alpine Linux не использует glibc, но musl как библиотека CПохоже, что реализация сортировок в musl еще не завершена, по крайней мере, я нахожу это в дорожной карте :

Цели вехи для musl 1.2.0

Следующие предварительные цели для того, что составило бы «мусл 1.2.0», были установлены.В настоящее время нет ожидаемой даты выпуска 1.2.0.

[...] - Улучшена поддержка локали и многоязычности

LC_COLLATE поддержка заказов на сопоставлениекроме простого порядка кодов

Это, кажется, объясняет ваш опыт.

Использование другого дистрибутива Linux с рабочими параметрами сортировки - путь вперед.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...