postgres での空文字とNULL
postgres は空文字とNULLを区別する。
検証用テーブル
test=# \d test
Table "public.test"
Column | Type | Modifiers
--------+-----------------------+-----------
text1 | character varying(20) |
text2 | character varying(20) |
test=#
空文字を投入
test=# INSERT INTO test VALUES ('text2 is zero length', '');
INSERT 0 1
test=# SELECT * from test where text2 = '';
text1 | text2
----------------------+-------
text2 is zero length |
(1 row)
NULLを投入
test=# INSERT INTO test (text1) VALUES ('text2 is null');
INSERT 0 1
test=# SELECT * from test where text2 is null;
text1 | text2
---------------+-------
text2 is null |
(1 row)
pg_dump してみる
[hoge@fuga]$ pg_dump test -at test ・・・ COPY test (text1, text2) FROM stdin; text2 is zero length text2 is null \N \. ・・・
分かりづらいが、空文字は空文字で出力されている("text2 is zero length"の右にタブと改行)
NULLは"\N"
テキストモードでcopy してみる
[hoge@fuga]$ psql test -c "COPY (SELECT * FROM test) TO STDOUT" text2 is zero length text2 is null \N [hoge@fuga]$
CSVでcopy してみる
[hoge@fuga]$ psql test -c "COPY (SELECT * FROM test) TO STDOUT CSV" text2 is zero length,"" text2 is null, [hoge@fuga]$
空文字は""、NULLは空文字で出力されている。
おまけ:カラム中のタブ
COPYでタブを含むデータを出力すると\tで表現される。マニュアルによると、COPY FROM はこの \t をタブとして認識してくれるらしい。
test=# TRUNCATE test ;
TRUNCATE TABLE
test=# INSERT INTO test VALUES ('text2 include tab', 'a\tb');
WARNING: nonstandard use of escape in a string literal
LINE 1: INSERT INTO test VALUES ('text2 include tab', 'a\tb');
^
HINT: Use the escape string syntax for escapes, e.g., E'\r\n'.
INSERT 0 1
test=# SELECT * from test ;
text1 | text2
-------------------+--------
text2 include tab | a\x09b
(1 row)
test=#
[hoge@fuga]$ psql test -c "COPY test TO STDOUT"
text2 include tab a\tb
[hoge@fuga]$