web-dev-qa-db-ja.com

大文字と小文字を区別しない照合は、依然として大文字と小文字を区別する

私は現在、デフォルトで大文字と小文字を区別するinテキスト列を含むテーブルを作成しようとしています。これは、データベースで検索を実行するサードパーティのプログラムがあるためです。このプログラムで使用されるSELECTステートメントは変更できません。

抽象的問題は、この検索で​​大文字と小文字を区別しないようにする必要があることですが、現在は大文字と小文字が区別されます。

私はPostgres 12がこの動作を可能にする非決定的照合をサポートしていることを読みました。

ドイツのWindowsマシンにPostgresサーバー(バージョンPostgreSQL 12.1、Visual C++ビルド1914、64ビットでコンパイル)をインストールしています。

テストのために、テスト用の新しいデータベースを作成しました。

CREATE DATABASE collation_test
    WITH 
    OWNER = postgres
    ENCODING = 'UTF8'
    CONNECTION LIMIT = -1;

このデータベースで、次の照合を作成しました これらの照合に関する記事

CREATE COLLATION collat_ci (
  provider = 'icu',
  locale = 'und-u-ks-level2',
  deterministic = false
);

この後、この照合をテストするためのテーブルが必要でした

CREATE TABLE public.person
(
    "Id" bigint NOT NULL,
    "Name" text COLLATE public.collat_ci,
    PRIMARY KEY ("Id")
);

ALTER TABLE public.person
    OWNER to postgres;

INSERT INTO person VALUES
(1, 'Robin'),
(2, 'robin');

そこで、次の選択クエリを試しました。

SELECT 
(
    SELECT "Name" FROM person p1 WHERE p1."Id" = 1
)
= 'Robin';

データベース内のテキストと指定されたリテラルが完全に一致するので、期待どおりにtrueを返しました。

しかし、小文字のrを使用して同じことを試みると、照合のために一致すると予想されますが、falseが返されます。

SELECT 
(
    SELECT "Name" FROM person p1 WHERE p1."Id" = 1
)
= 'robin';

挿入された両方の行の名前を互いに比較しようとしたとき、結果としてfalseがまだ得られました。

SELECT 
(
    SELECT "Name" FROM person p1 WHERE p1."Id" = 1 --'Robin'
)
=
(
    SELECT "Name" FROM person p2 WHERE p2."Id" = 2 --'robin'
);

私の比較が期待どおりに動作しない理由と、それを実行する方法を誰かが知っていますか?

5
Robin B

Windowsビルドに同梱されているICUのバージョンはかなり古いバージョンなので、それが理由かもしれません。

やってみる

CREATE COLLATION collat_ci (
  provider = 'icu',
  locale = '@colStrength=secondary',
  deterministic = false
);

これは古いICUバージョンで動作するはずです。

8
Laurenz Albe