Thread: Patch for server-side encoding issues

Patch for server-side encoding issues

From
Itagaki Takahiro
Date:
Here is a WIP patch to solve server-side encoding issues.
It includes "Solution of the file name problem of copy on windows" patch.
    http://archives.postgresql.org/message-id/20090413184335.39BE.52131E4D@oss.ntt.co.jp

It could solve the following issues. They are not only in Windows nor
Japan-specific problems. They could also occur if you use databases
with mulitple encodings or database with non-platform-native encoding
even on POSIX platforms.

<1> Non-ascii file paths for database that encoding is different from
    platform's encoding (that comes from $LANG or Windows codepage),
    especially for COPY TO/FROM.

<2> Use appropriate encoding for non-text server log (console, syslog
    and eventlog). The encoding is the same as <1>.

<3> Use appropriate encoding for text server log (stderr and csvlog),
    especially database cluster has databases with a variety of encoding.
    New GUC parameter 'log_encoding' specifies the encoding in server log.

<4> (incomplete) Avoid encoding conversion error in printing server log
    and messages for client. Instead of error, print '?' if there is no
    equivalent character in the target encoding.

For <4>, I use PG_TRY and PG_CATCH for now, but it must be a bad manner.
Instead, I'm thinking that convertion procedures will take an optional
argument whether it should raise error or not. However, we need to
modify all of conversion functions to do so.

More research is needed against following situations:
  - NLS messages
  - Module path for LOAD
  - Arguments for system(), including archive_command and restore_command
  - Query texts for other database in pg_stat_activity and pg_stat_statements

Comments welcome. Please notify me if I'm missing something.


Here is a sample code to test the patch.

(client_encoding = sjis / system encoding = sjis)
----
C:\home\>createdb utfdb --encoding=utf8 --locale=C
C:\home\>createdb eucdb --encoding=eucjp --locale=C

C:\home\>psql utfdb -c "COPY (SELECT 1) TO 'C:/home/日本語ファイル.txt'"
C:\home\>psql utfdb -c "SELECT '日本語' WITH ERROR"
ERROR:  syntax error at or near "WITH ERROR"
LINE 1: SELECT '日本語' WITH ERROR
                        ^

C:\home\>psql eucdb -c "COPY (SELECT 1) TO 'C:/home/日本語ファイル.txt'"
C:\home\>psql eucdb -c "SELECT '日本語' WITH ERROR"
ERROR:  syntax error at or near "WITH ERROR"
LINE 1: SELECT '日本語' WITH ERROR
                        ^
----

Regards,
---
ITAGAKI Takahiro
NTT Open Source Software Center

Attachment

Re: Patch for server-side encoding issues

From
"Hiroshi Saito"
Date:
Hi.

----- Original Message ----- 
From: "Itagaki Takahiro" <itagaki.takahiro@oss.ntt.co.jp>


> Here is a WIP patch to solve server-side encoding issues.
> It includes "Solution of the file name problem of copy on windows" patch.
>    http://archives.postgresql.org/message-id/20090413184335.39BE.52131E4D@oss.ntt.co.jp
>
> It could solve the following issues. They are not only in Windows nor
> Japan-specific problems. They could also occur if you use databases
> with mulitple encodings or database with non-platform-native encoding
> even on POSIX platforms.
>
> <1> Non-ascii file paths for database that encoding is different from
>    platform's encoding (that comes from $LANG or Windows codepage),
>    especially for COPY TO/FROM.
>
> <2> Use appropriate encoding for non-text server log (console, syslog
>    and eventlog). The encoding is the same as <1>.
>
> <3> Use appropriate encoding for text server log (stderr and csvlog),
>    especially database cluster has databases with a variety of encoding.
>    New GUC parameter 'log_encoding' specifies the encoding in server log.
>
> <4> (incomplete) Avoid encoding conversion error in printing server log
>    and messages for client. Instead of error, print '?' if there is no
>    equivalent character in the target encoding.
>
> For <4>, I use PG_TRY and PG_CATCH for now, but it must be a bad manner.
> Instead, I'm thinking that convertion procedures will take an optional
> argument whether it should raise error or not. However, we need to
> modify all of conversion functions to do so.
>
> More research is needed against following situations:
>  - NLS messages
>  - Module path for LOAD
>  - Arguments for system(), including archive_command and restore_command
>  - Query texts for other database in pg_stat_activity and pg_stat_statements
>
> Comments welcome. Please notify me if I'm missing something.

Although it is redundant, it looks at much help. It is, even if it may not
be welcomed in the country in many single byte areas. Then, they may think
that they are strange. However, I consider helping in the country using
multi-bytes other than Japan. example displayed on below with a server
message is shown. please see,

C:\work>initdb -E UTF-8 --no-locale
データベースシステム内のファイルの所有者は"HIROSHI"ユーザでした。
このユーザがサーバプロセスを所有しなければなりません。

データベースクラスタはロケールCで初期化されます。
デフォルトのテキスト検索設定はenglishに設定されました。

ディレクトリC:/tmp/日本語 dataの権限を設定しています ... ok
サブディレクトリを作成しています ... ok
デフォルトのmax_connectionsを選択しています ... 100
デフォルトの shared_buffers を選択しています ... 32MB
設定ファイルを作成しています ... ok
C:/tmp/日本語 data/base/1にtemplate1データベースを作成しています ... ok
pg_authidを初期化しています ... ok
依存関係を初期化しています ... ok
システムビューを作成しています ... ok
システムオブジェクトの定義をロードしています ... ok
変換を作成しています ... ok
ディレクトリを作成しています ... ok
組み込みオブジェクトに権限を設定しています ... ok
情報スキーマを作成しています ... ok
template1データベースをバキュームしています ... ok
template1からtemplate0へコピーしています ... ok
template1からpostgresへコピーしています ... ok

警告: ローカル接続向けに"trust"認証が有効です。
pg_hba.confを編集する、もしくは、次回initdbを実行する時に-Aオプショ
ンを使用することで変更することができます。

成功しました。以下を使用してデータベースサーバを起動することができます。
   "postmaster" -D "C:/tmp/日本語 data"
または   "pg_ctl" -D "C:/tmp/日本語 data" -l logfile start

C:\work>pg_ctl start
サーバは起動中です。

C:\work>LOG:  データベースシステムは2009-04-16 00:24:13 JSTにシャットダウンしま
した
LOG:  データベースシステムの接続受付準備が整いました。
LOG:  自動バキュームランチャプロセス

C:\work>psql postgres
psql (8.4beta1)
"help" でヘルプを表示します.

postgres=# create table 日本語(きー text);
CREATE TABLE
postgres=# insert into 日本語 values('どうかな');
INSERT 0 1
postgres=# copy 日本語 to 'C:/tmp/日本語 data/ニホンゴutf8.txt';
COPY 1
postgres=# delete from 日本語;
DELETE 1
postgres=# copy 日本語 from 'C:/tmp/日本語 data/ニホンゴutf8.txt';
COPY 1
postgres=# select * from 日本語;  きー
----------どうかな
(1 行)

postgres=# select a;
ERROR:  列"a"は存在しません(文字位置 8)
STATEMENT:  select a;
ERROR:  列"a"は存在しません
LINE 1: select a;              ^

postgres=# create database eucdb encoding = 'EUC_JP';
CREATE DATABASE
postgres=# \c eucdb
psql (8.4beta1)
データベース "eucdb" に接続しました。.
eucdb=# create table 日本語(きー text);
CREATE TABLE
eucdb=# insert into 日本語 values('どうかな');
INSERT 0 1
eucdb=# copy 日本語 to 'C:/tmp/日本語 data/ニホンゴeucjp.txt';
COPY 1
eucdb=# delete from 日本語;
DELETE 1
eucdb=# copy 日本語 from 'C:/tmp/日本語 data/ニホンゴeucjp.txt';
COPY 1
eucdb=# select * from 日本語;  きー
----------どうかな
(1 行)

eucdb=# select a;
ERROR:  列"a"は存在しません(文字位置 8)
STATEMENT:  select a;
ERROR:  列"a"は存在しません
LINE 1: select a;              ^

eucdb=# \q

C:\work>pg_ctl stop
LOG:  スマートシャットダウン要求を受け取りました
LOG:  自動バキュームランチャを停止しています
サーバ停止処理の完了を待っています....LOG:  シャットダウンしています
LOG:  データベースシステムはシャットダウンしました
完了
サーバは停止しました

=======================================================================

Therefore, I  vote +1.

Regards,
Hiroshi Saito