Сортировка PostgreSQL с кириллицей "ь"

Просто взгляните, пожалуйста:

WITH toks AS (
  SELECT tok
    FROM
      unnest('{ь, а, чь, ча, чль, чла}'::text[]) AS tok
  ORDER BY tok COLLATE "uk_UA"
)
SELECT ROW_NUMBER() OVER() AS "#", tok FROM toks
ORDER BY tok COLLATE "uk_UA"

PostgreSQL 9.3 (ubuntu) дает мне этот результат:

 # | tok 
---+-----
 1 | а
 2 | ча
 3 | чль
 4 | чла
 5 | чь
 6 | ь
(6 rows)

Здесь строки 1, 2, 5 и 6 сортируются правильно ("ь" идет после "а"), а строки 3 и 4 сортируются неправильно ("а" идет после "ь").

Все буквы кириллицы, я проверил столько раз.

Пожалуйста, что не так и как обходиться. (

UPDATE: это ошибка, которая была исправлена в основном в последнее время: https://sourceware.org/bugzilla/show_bug.cgi?id=17293

UPDATE2: Пожалуйста, обратите внимание на мой собственный ответ ниже.

Ответ 1

Итак, решения были выполнены на следующих этапах:

  • Искал Интернет и http://linux.org.ua/ для любой информации; found http://linux.org.ua/cgi-bin/yabb/YaBB.pl?num=1407783417/6#6
  • Помечено в отчете об ошибке: https://sourceware.org/bugzilla/show_bug.cgi?id=17293, исправлено 2015-05-26
  • Проверено glibc версия (2.19 сейчас)
  • Схватил патч; отредактировал патч (удалил раздел для Makefile)
  • Поддержан /usr/share/i18n/locales/uk_UA вверх
  • Исправлено с помощью [cd /usr/share/i18n/;] patch --dry-run -p2 < locales_uk_UA_softsign.diff --- затем без --dry-run.
  • locale-gen
  • service postgresql restart

Ответ 2

PostgreSQL полагается на локаль операционной системы для сортировки.

Посмотрите, как Ubuntu 14.04 сортирует этот список:

# locale-gen uk_UA.UTF-8
Generating locales...
  uk_UA.UTF-8... done
Generation complete.

# cat >file
ь
а
чь
ча
чль
чла

# LC_ALL=uk_UA.UTF-8 sort file
а
ча
чль
чла
чь
ь

В комментариях вы говорите, что это разные, но то, что я получаю, - это точно такой же порядок, что и ваш запрос.

Действительно чль предшествует чла, который интуитивно странный, но я не знаю кириллицы.

Вы можете посмотреть /usr/share/i18n/locales/uk_UA для определения языкового стандарта и вывести его как ошибку ubuntu пакетов locales.