私は現在、デフォルトで大文字と小文字を区別する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'
);
私の比較が期待どおりに動作しない理由と、それを実行する方法を誰かが知っていますか?
Windowsビルドに同梱されているICUのバージョンはかなり古いバージョンなので、それが理由かもしれません。
やってみる
CREATE COLLATION collat_ci (
provider = 'icu',
locale = '@colStrength=secondary',
deterministic = false
);
これは古いICUバージョンで動作するはずです。