Postgresql 12 - сортировка не работает Windows/Linux

Я установил Postgresql 12 как на Windows, так и на Linux CentOS 8.

Для моего проекта мне нужно было создать собственную сортировку ICU и применить ее ко всем символьным столбцам (либо при создании столбца, либо в порядке запросов = предпочтительно).

Прежде чем сделать это, я попытался сделать простой тестовый пример, чтобы проверить, работает ли он так, как ожидалось... и это не так.

Простая таблица с некоторыми числовыми и буквенными данными

DROP TABLE IF EXISTS TBL;
CREATE TABLE TBL ( TEXT1 CHARACTER(5), TEXT2 CHARACTER(5) );
INSERT INTO TBL VALUES
 ('aaaaa', 'aaaaa')
,('aaaaa', '00000')
,('aaaaa', 'bbbbb')
,('aaaaa', '11111')

,('bbbbb', '22222')
,('00000', '22222')
,('ccccc', '22222')
,('11111', '22222');

Сопоставление для упорядочивания цифр после латинских символов из официальной документации https://www.postgresql.org/docs/12/collation.html

CREATE COLLATION digitslast (provider = icu, locale = 'en-u-kr-latn-digit');
CREATE COLLATION digitslast (provider = icu, locale = 'en@colReorder=latn-digit');
    Sort digits after Latin letters. (The default is digits before letters.)

Запросы на тестирование

1/ SELECT * FROM TBL;
2/ SELECT * FROM TBL ORDER BY TEXT1, TEXT2;
3/ SELECT * FROM TBL ORDER BY TEXT1 COLLATE digitslast;
4/ SELECT * FROM TBL ORDER BY TEXT2 COLLATE digitslast;
5/ SELECT * FROM TBL ORDER BY TEXT1 COLLATE digitslast, TEXT2 COLLATE digitslast;
6/ SELECT * FROM TBL ORDER BY TEXT2 COLLATE digitslast, TEXT1 COLLATE digitslast;

Результаты в Windows = сопоставление вообще не работает

1/ OK = TEXT1 + TEXT2 = digits before letters
2/ OK = TEXT1 + TEXT2 = digits before letters
3/ KO = TEXT1 + TEXT2 = digits before letters
4/ KO = TEXT1 + TEXT2 = digits before letters
5/ KO = TEXT1 + TEXT2 = digits before letters
6/ KO = TEXT1 + TEXT2 = digits before letters

Результаты на Linux Centos 8 = сопоставление работает только для 1-го столбца из ORDER BY

1/ OK = TEXT1 + TEXT2 = digits before letters
2/ OK = TEXT1 + TEXT2 = digits before letters
3/ OK = TEXT1 = digits after letters + TEXT2 = digits before letters
4/ OK = TEXT1 = digits before letters + TEXT2 = digits after letters
5/ KO = TEXT1 = digits after letters + TEXT2 = digits before letters
6/ KO = TEXT1 = digits before letters + TEXT2 = digits after letters

Если я применил предложение COLLATE к столбцам таблицы, оно также не работает.

ICU 53 упакован для всех установок Postgresql 12, а аргумент --with-icu присутствует в конфигурации Postgresql.

Кто-нибудь знает, как заставить этот простой тестовый пример работать?

Существует предложение расширения для ICU с https://postgresql.verite.pro/blog/2018/07/25/icu-extension.html.

  • Это расширение добавляет некоторые функции, которые, возможно, работают лучше, чем стандарты Postgresql.
  • Нужно ли мне добавить его из исходного кода Postgresql и скомпилировать мою собственную версию Postgresql, чтобы сделать его пригодным для использования?

Другая связанная проблема не имеет ответа для Postgresql 10: Как я могу использовать Сортировка Postgres в ОС Windows?

Связанные записи из блога Postgresql


person Arnaud Perrier    schedule 23.07.2020    source источник
comment
Также не работает на AWS Aurora на базе Postgresql. Использование расширения ICU может решить мою проблему, но его необходимо добавить в сам дистрибутив (необходимо скомпилировать postgresql с расширением перед его установкой): это не очень хороший выбор для обслуживания (навыки компиляции процедуры на третьем программном обеспечении).   -  person Arnaud Perrier    schedule 27.07.2020
comment
Для тех, кто любит платные СУБД: отлично и легко работает с Oracle, например, с помощью COLLATE EBCDIC.   -  person Arnaud Perrier    schedule 27.07.2020


Ответы (1)


Я отправил свою проблему в сообщения об ошибках postgresql (#16570) и получил несколько ответов от сопровождающих postgresql.

https://www.postgresql.org/message-id/16570-58cc04e1a6ef3c3f%40postgresql.org

Установщик Postgresql для Windows от EnterpriseDb поставляется с ICU версии 53. Установщик Postgresql Linux Centos 8 поставляется с ICU версии 60.

До версии ICU 54 синтаксический анализ атрибутов сортировки выполнялся Postgres. Метод синтаксического анализа не реализует атрибут colReorder (документация Posgtesql должна быть обновлена).

Документация Postgreql уточняет, что для примеров, использующих вложенные теги k*, требуется версия ICU не ниже 54.

CREATE COLLATION digitslast (поставщик = icu, locale = 'en-u-kr-latn-digit'); ===› для отделений интенсивной терапии ›= 54

CREATE COLLATION последние цифры (поставщик = icu, locale = 'en@colReorder=latn-digit'); ===› для ICU ‹ 54 (colReorder не реализован: нет способа заставить это работать)

Создана новая проблема для обновления версии ICU в установщике Windows (по техническим причинам, таким как переиндексация, совместимость версий и т. д.; будет сложно сделать ее доступной для выпуска Postgresql 13). https://www.postgresql.org/message-id/[email protected]

В Linux Centos 8 с ICU версии 60 все еще существует проблема при применении сопоставления к нескольким аргументам в предложении ORDER BY (учитывается только сопоставление для первого аргумента).

person Arnaud Perrier    schedule 05.08.2020