web-dev-qa-db-ja.com

デフォルトの照合が機能していませんか?

私のpsqlserver 11インスタンスのデフォルトの照合が、明示的な照合で使用する場合とは異なる結果を返す理由がわかりません。

詳細:

show LC_CTYPE;        -- de-AT
show LC_COLLATE;      -- de-AT

デフォルトの照合を使用すると、予期しない出力が得られます。

demo=# SELECT unnest(array['a','B', 'A']) order by 1;
 unnest 
--------
 A
 B
 a
(3 rows)

デフォルトの照合を明示的に追加すると、期待される出力が得られます。

demo=# SELECT unnest(array['a','B', 'A']) collate "de-AT-x-icu" ORDER BY 1;
 unnest 
--------
 a
 A
 B
(3 rows)

照合順序de-AT-x-icuは、上記のLC_COLLATEおよびLC_COLTYPEのデフォルト値をそのまま使用します。

SELECT collname, collcollate, collctype
FROM pg_collation
where collname like '%de-AT%';

  collname   | collcollate | collctype 
-------------+-------------+-----------
 de-AT-x-icu | de-AT       | de-AT

だから私は両方のクエリが同じ結果を返すはずだと思います:何が欠けていますか?

より詳しい情報:

  • postgresqlバージョン11.5
  • Dockerコンテナー内のOS:
    Linux 8660fb4cef84 4.9.184-linuxkit #1 SMP Tue Jul 2 22:58:16 UTC 2019 x86_64 Linux
3
TmTron

推測してみましょう。Cライブラリとしてmuslを使用するAlpine Linuxを使用していて、デフォルトでICU照合順序を使用しています。

既知 Alpine Linuxの照合順序が期待どおりに機能しないことが問題の原因です。それがPostgreSQLのせいかどうかはわかりません。

とにかく、glibcを使用する別のLinuxディストリビューションを使用する必要があります。

2
Laurenz Albe

たくさんの投稿、ドキュメント、素晴らしいコメントをここで読んだ後、ケースを要約してみます(何か問題がある場合はコメントを残してください)。

@Laurenz Albeが正しいことがわかりました。私はdocker image timescale/timescaledb:1.5.0-pg11Docker-Hub link )を使用していました。
これらの画像は通常-Alpineで終わるため、これはアルパインに基づく可能性があるとは思いませんでした。しかし、これは慣例にすぎないので、私はそれらの Dockerfile ...を確認する必要がありました.

現在dockerhubで利用できるのはアルパインベースのtimescale-dbイメージのみであるようです:参照 timescaledb-docker#78

docker-hub postgres のドキュメントには、次のように記載されています。

postgres:-Alpine
この画像は、人気のAlpine Linuxプロジェクトに基づいています。主な警告は、musllibcはglibcや友人ではなく、特定のソフトウェアがlibc要件の深さに応じて問題に遭遇する可能性があります。

つまり、docker-imageは musl を使用します glibcとの違い があります。重要な違いの1つは、os-command localeが使用できないことです。
init-db parameters でdocker-containerを開始する場合: POSTGRES_INITDB_ARGS=--lc-collate=de-AT --lc-ctype=de-AT、コンソールに警告があります:

running bootstrap script ... ok
performing post-bootstrap initialization ... sh: locale: not found
2019-11-04 16:48:16.725 UTC [26] WARNING:  no usable system locales were found
ok

そのため、dbは実際に、提供されたロケール/照合は無視されることを正しく教えてくれました。

非常に混乱しているのは、次のステートメントでもinitdbパラメータによって設定された値が表示されていることです。

show LC_CTYPE;    -- de-AT
show LC_COLLATE;  -- de-AT

しかし、@ DanielVéritéがコメントで指摘したように、これらはデフォルトでは使用されません。

postgres-Alpine Dockerfile を見ると、イメージが ic サポートを有効にして構築されていることがわかります(--with-icu)。
したがって、クエリでicu照合を直接使用すると(たとえば、collate "de-AT-x-icu")、静的にリンクされたicu libを使用し、os依存のglib-cに問い合わせる必要がないため、機能します。

0
TmTron