postgresql 6.5.1 multi-byte (MB) support README 1999/7/11 作成 石井達夫 t-ishii@sra.co.jp http://www.sra.co.jp/people/t-ishii/PostgreSQL/ はじめに: PostgreSQL におけるマルチバイトサポートは以下のような特徴を持っています。 1.マルチバイト文字として、日本語、中国語などの各国の EUC、Unicode、 mule internal code, ISO-8859-* がデータベース作成時に選択可能。 データベースにはこのコードのまま格納されます。 2.テーブル名にマルチバイト文字が使用可能(ただし、OS がマルチバイト のファイル名を許していることが必要) 3.カラム名にマルチバイト文字が使用可能 4.データそのものにもマルチバイト文字が使用可能 5.マルチバイト文字の正規表現検索が使用可能 6.マルチバイト文字の LIKE 検索が使用可能 7.character_length(), position(), substring() でのマルチバイト サポート 8.環境変数 PGCLIENTENCODING により、フロントエンド側のエンコーディング がバックエンド側と異る場合に、自動的にコード変換を行ないます。 インストール: デフォルトのコンフィギュレーションでは PostgreSQL はマルチバイトを サポートしていません。マルチバイトサポートを有効にする方法を説明します。 たとえば日本語 EUC を主に利用する場合は、configure 起動時に以下のよ うに指定します。 % configure --with-mb=EUC_JP エンコーディングとしては EUC_JP の他、以下が指定できます。 SQL_ASCII ASCII EUC_JP 日本語 EUC EUC_CN GB をベースにした中文EUC。code set 2 は SS2+2バイトコード = 3バイト表現です。 EUC_KR 韓国語 EUC。 EUC_TW 台湾の EUC。code set 2 は SS2+面番号+2バイトコード = 4バイト表現です。 UNICODE UTF-8。ただしサポートするのは UCS-2 の範囲、 すなわち 0xffff までです。 MULE_INTERNAL mule の内部コード。ただし、Type N の不定長文字は サポートしていません。 LATIN* ISO8859 Latin シリーズ。* は 1 から 5 まで指定 できます。 キリル文字 KOI8(KOI8-R), WIN(CP1251), ALT(CP866)をサポート しています。もちろん ISO 8859-5 も使用可能です。 この場合、"LATIN5" として指定して下さい。 選択の目安としては、英語と日本語しか使わない場合は EUC_JP(同様に、中 国語しか使わない場合は EUC_CN... などとなります)、その他の言語も使いた い場合は UNICODE もしくは MULE_INTERNAL となるでしょう。 なお、configure で選択したエンコーディングは、あくまで initdb のための デフォルト値程度の意味しかありません(initdb では引数でエンコーディングが 指定できます)。したがって、異なるエンコーディングを使用するために わざわざPostgreSQL をリコンパイルする必要ありません。 initdb は shell script なので、デフォルトのエンコーディングは script を 適当なエディタで編集することにより簡単に変更できます。initdb の 42行目 付近に、 MULTIBYTE=EUC_JP のような行があるので、= 以降を希望するエンコーディングに変えるだけです。 注意:MULE_INTERNAL を選ぶと、たくさんの文字集合に対応できて便利です が、正規表現で複数の文字集合にまたがるような範囲指定(たとえば、[a-範] とか、[abc範囲]のような)は使えません。複数の範囲指定で異なる文字集合 を使うのは構いません(たとえば [abc][範-囲])。また、[^a] のような表現 は、"a" の属する文字集合(この場合、US-ASCII)において "a" 以外である ことを表します。決して漢字や平仮名など "a" 以外をすべて表すわけでは ないことに注意して下さい。 インストールは普通に行ないます。インストールの詳細は INSTALL という テキストファイルを御覧下さい。また、 http://www.sra.co.jp/people/t-ishii/PostgreSQL/ でも簡単なインストー ル方法を紹介しています。 initdb/createdb/create database におけるエンコーディングの指定について initdb では以下のオプションでエンコーディングが指定できます。 -e エンコーディング -pgencoding エンコーディング ここで指定したエンコーディングは、以後 createdb/create database でエ ンコーディングを省略した場合に設定されるエンコーディングになります。 -e または -pgencoding オプションを省略した場合は、configure で指定し たエンコーディングが採用されます。 createdb では以下のオプションでエンコーディングが指定できます。 -E エンコーディング create database では以下のオプションでエンコーディングが指定できます。 CREATE DATABASE dbanme WITH ENCODING = 'エンコーディング'; LOCATION を同時に指定する場合は以下のようになります。 CREATE DATABASE dbanme WITH LOCATION = 'path' ENCODING = 'エンコーディング'; createdb/create database は、エンコーディング指定を省略した場合は、initdb で指定したエンコーディングが採用されます。これは、initdb が作成する テンプレートデータベース(template1)の encoding アトリビュートを継承 するからです。 データベースのエンコーディングは、psql の \l や、SQL 文の select * from pg_database で参照できます。 datname |datdba|encoding|datpath -------------+------+--------+------------- template1 | 1739| 1|template1 postgres | 1739| 0|postgres euc_jp | 1739| 1|euc_jp euc_kr | 1739| 3|euc_kr euc_cn | 1739| 2|euc_cn unicode | 1739| 5|unicode mule_internal| 1739| 6|mule_internal encoding カラムの数値がそのデータベースのエンコーディングを表します (エンコーディングID)。エンコーディング ID をエンコーディング名に変換 するには、pg_encoding コマンドを使用します。たとえば、 $ pg_encoding 1 EUC_JP のようになります。なお、pg_encoding は数字以外が与えられるとエンコー ディング名と見倣してエンコーディングIDを返します。 $ pg_encoding EUC_JP 1 環境変数 PGCLIENTENCODING について: 環境変数 PGCLIENTENCODING が設定されていない場合、libpq はセッション 開始時にバックエンド側にエンコーディングを問い合わせ、その値を環境変数 PGCLIENTENCODING に設定します。 環境変数 PGCLIENTENCODING が設定されている場合はその値が優先され、バッ クエンド側と異なるエンコーディングが使用できます。設定可能なエンコー ディングは、上記に加え、SJIS (シフトJIS)、BiG5 それに WIN1250 (Windows用のチェコ語)が指定できます。 ちなみに、SJIS は JISX0201 の 1バイトカナ、いわゆる「半角カタ カナ」もサポートしています(決して「半角カタカナ」の使用をお勧 めしているわけじゃないですが)。 たとえば、MB=EUC_JP で PostgeSQL がインストールされている場合、 postmaster を立ち上げるときに環境変数 PGCLIENTENCODING に SJIS を設 定すると、フロントエンドは SJIS コードで PostgreSQL にアクセスできるよ うになります。ただし、データベースに格納されるデータ自体はあくまで MB で指定した EUC_JP のままです。 フロントエンド側でセッション毎にエンコーディングを変えることもできま す。セッション開始時に環境変数 PGCLIENTENCODING がセットされていると、 それがフロントエンド側のエンコーディングに採用されます。この機能を利 用すると、あるユーザは EUC_JP で、別なユーザは SJIS で同じデータベー スにアクセスするというようなことができるようになります。 MB=MULE_INTERNAL で PostgreSQL をインストールしておくと、普段は EUC_JP でフロントエンドを利用し、複数の文字集合を混在させるときだけク ライアントを MULE_INTERNAL に設定するなどの使い分けができて便利です。 ただ、一般に EUC_JP に比べ、MULE_INTERNAL によるデータ表現はややスペー スを喰うので、そのへんは考慮しておく必要があります。たとえば、2バイ トで表現できる漢字は MULE_INTERNAL では 3バイトを要します。 注意しておく必要があるのは、バックエンド側のエンコーディングとフロン トエンド側のエンコーディングがいつも相互変換できるとは限らないことで す。極端な話、バックエンド側が EUC_JP なのに、フロントエンド側が EUC_KR だったらどうなるでしょう。 この場合 PostgreSQL は変換できないコードを 16進表現に変換してしまい ます。たとえば、"(bdae)" のように。なお、この 16進表現は mule internalcode のコードであることに注意して下さい。これは、直接フロン トエンド <--> バックエンドのエンコーディングを変換するのではなく、一 度内部表現である mule internal code を経由しているためです。 フロントエンド側のエンコーディングの設定は、"set client_encoding" コ マンドでも可能です。たとえば、 set client_encoding to 'sjis'; でフロントエンド側のエンコーディングを SJIS に設定できます。実際、ク ライアントがバックエンドに接続する際には libpq の中で "set client_encoding" コマンドを発行しています。セッション中に set client_encoding" コマンドを発行すれば、動的にエンコーディングの切替え ができますが、その際には環境変数 PGCLIENTENCODING を同時にフロントエ ンドアプリケーションの中で設定し直す必要があります。(psql には現在こ の機能がないため、事実上動的にフロントエンド側のエンコーディングを設 定することができません。) 現在設定されているフロントエンド側のエンコーディングは show client_encoding; で参照できます。また、 reset client_encoding; は、デフォルトのフロントエンドエンコーディング設定に復帰させます。 postmasterを立ち上げるときに環境変数 PGCLIENTENCODING が設定されてい るとそのエンコーディングに、そうでなければコンパイル時に指定したバッ クエンド側のエンコーディングと同じになります。 制限事項: SJIS を使用する場合、PostgreSQL のフロントエンドでまともに対応している のは psql だけです。Tcl/Tk、そのほかは対応してません。 謝辞: o 各種文字セット、コード系について、日本語 PostgreSQL メーリングリスト のメンバの方からアドバイスを頂きました。ここに感謝します。 また、SJIS 対応については、市川@お茶大さんのパッチを参考にさせてい ただきました。 参考: Pavel Behal氏により提供されたWIN1250サポートですが、Windows環境での 利用の仕方について参考になるドキュメントが付属しているので、ここに添 付しておきます。 ------------------------------------------------------------------- Version: 0.91 for PgSQL 6.5 Author: Pavel Behal Revised by: Tatsuo Ishii Email: behal@opf.slu.cz Licence: The Same as PostgreSQL Sorry for my Eglish and C code, I'm not native :-) !!!!!!!!!!!!!!!!!!!!!!!!! NO WARRANTY !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Instalation: ------------ 1) Change three affected files in source directories (I don't have time to create proper patch diffs, I don't know how) [PostgreSQL 6.5.1ではこのステップは必要ありません。-- 石井] 2) Compile with enabled locale and multibyte set to LATIN2 3) Setup properly your instalation, do not forget to create locale variables in your profile (environment). Ex. (may not be exactly true): LC_ALL=cs_CZ.ISO8859-2 LC_COLLATE=cs_CZ.ISO8859-2 LC_CTYPE=cs_CZ.ISO8859-2 LC_MONETARY=cs_CZ.ISO8859-2 LC_NUMERIC=cs_CZ.ISO8859-2 LC_TIME=cs_CZ.ISO8859-2 4) You have to start the postmaster with locales set! 5) Try it with Czech language, it have to sort 5) Install ODBC driver for PgSQL into your M$ Windows 6) Setup properly your data source. Include this line in your ODBC configuration dialog in field "Connect Settings:" : SET CLIENT_ENCODING = 'WIN1250'; 7) Now try it again, but in Windows with ODBC. Description: ------------ - Depends on proper system locales, tested with RH6.0 and Slackware 3.6, with cs_CZ.iso8859-2 loacle - Never try to set-up server multibyte database encoding to WIN1250, always use LATIN2 instead. There is not WIN1250 locale in Unix - WIN1250 encoding is useable only for M$W ODBC clients. The characters are on thy fly re-coded, to be displayed and stored back properly Important: ---------- - it reorders your sort order depending on your LC_... setting, so don't be confused with regression tests, they don't use locale - "ch" is corectly sorted only in some newer locales (Ex. RH6.0) - you have to insert money as '162,50' (with comma in aphostrophes!) - not tested properly ------------------------------------------------------------------- 改定履歴: 1999/7/11 WIN1250(Windows用のチェコ語)サポートを追加しました。 * WIN1250 がフロントエンド側のエンコーディングとして利用できるよ うになりました。この場合、バックエンド側のエンコーディングは LATIN2 または MULE_INTERNAL とします。 (contributed by Pavel Behal) * backend/utils/mb/conv.cにおける型の不整合を修正しました。 (contributed by Tomoaki Nishiyama) * これらは6.5.1に反映されます。 1999/3/23 キリル文字サポート追加他(6.5 に反映済) * エンコーディングとして KOI8(KOI8-R), WIN(CP1251), ALT(CP866) を サポートしています。これらは、フロントエンド、バックエンド、 どちらのエンコーディングとしても使用可能であり、エンコーディングの 相互変換が可能です。また、従来からサポートしている ISO 8859-5 も 同様に使用可能です。 キリル文字サポートは、Oleg Broytmann 氏の リクエスト及び協力により実現しました。これは、従来からある RCODE サポートの機能を取り込むものでもあります。 * MB と locale を同時に指定した場合に大文字/小文字を無視した 正規表現検索が正常に動作しないバグを修正 1999/1/26 Big5 サポート追加(6.4.2-patched/6.5 に反映済) * Big5 がフロントエンド側のエンコーディングとして利用できるよ うになりました。この場合、バックエンド側のエンコーディングは EUC_TW または MULE_INTERNAL とします。 * EUC_TW の regression test ケースを追加 (contributed by Jonah Kuo ) 1998/12/16 本ドキュメント修正(6.4.2 に反映済)。 * Makefile.custom で MB=EUC_JP などと設定する方法は 6.4 以降 サポートされていないので削除した。 * 文字コード → エンコーディング、クライアント→フロントエンド サーバ→バックエンド にそれぞれ語句を修正。 1998/12/15 6.4 向けバグ修正パッチリリース(6.4.2 に反映済)。 * SQL_ASCII サポートのバグ修正 1998/11/21 6.4 向けバグ修正パッチリリース(6.4.2 に反映済)。 * BINARY CURSOR の問題を修正 * pg_dumpall のバグ修正 1998/11/5 6.4 リリース。 * pg_database の encoding カラムが MB が有効でないときにも 追加されるようになった。そのため、MB が有効でないときには、 ASCII のエンコーディングを表す SQL_ASCII を新しいエンコーディング として追加した。これにともない、エンコーディング名に対応する エンコーディングIDが SQL_ASCII を 0 とする番号に変更になった。 1998/7/22 6.4 α向けにパッチをリリース。 * initdb/createdb/create database でバックエンド側の エンコーディングを設定きる機能実装。このため、システムカタロ グの pg_database に新しいカラム encoding を追加(MBが有効な時だけ) * copy が PGCLIENTENCODING に対応 * SQL92 の "SET NAMES" をサポート(MBが有効な時だけ) * LATIN2-5 をサポート * regression test に unicode のテストケースを追加 * MB 専用の regression テストディレクトリ test/mb を追加 * ソースファイルの置き場所を大幅見直し。MB 関係は include/mb, backend/utils/mb に置くようにした 1998/5/25 バグ修正(mb_b3.patch として pgsql-jp ML にリリース、 本家では 6.4 snapshot に取り込まれる予定) 1998/5/18 機能追加/バグ修正(mb_b2.patch として pgsql-jp ML にリリース、 本家では 6.4 snapshot に取り込まれる予定) * 環境変数 PGCLIENTENCODING のサポート。フロントエンド側の エンコーディングを指定する。現在、SJIS, EUC_*, MULE_INTERNAL, LATIN1 が指定できる。また、 set client_encoding to 'sjis'; でも可能 * 8bit 文字が渡ると問題が起きる箇所にできるだけ対応 1998/4/21 機能追加/バグ修正(mb_b1.patch として pgsql-jp ML にリリース、 本家では 6.4 snapshot に取り込まれている) * character_length(), position(), substring() のマルチバイト 対応 * octet_length() 追加 → initdb のやり直し必要 * configure のオプションに MB サポート追加 (ex. configure --with-mb=EUC_JP) * EUC_KR の regression test 追加 ("Soonmyung. Hong" さん提供) * EUC_JP の regression test に character_length(), position(), substring(), octet_length() 追加 * regress.sh の SystemV における非互換性修正 * toupper(), tolower() に 8bit 文字が渡ると落ちることが あるのを修正 1998/3/25 PostgreSQL 6.3.1 リリース、MB PL2 が取り込まれる 1998/3/10 PL2 をリリース * EUC_JP, EUC_CN, MULE_INTERNAL の regression test を追加 (EUC_CN のデータは he@sra.co.jp さん提供) * regexp において、isalpha などに unsigend char 以外の値が 渡らないようにガードをかける * 英語のドキュメントを追加 * MB を定義しない場合に発生するバグを修正 1998/3/1 PL1 をリリース 以上。