PostgreSQL 9.2のJSON型
今日はPostgreSQL 9.2からサポートされたJSON型について試してみることにする。
パース処理
test=# SELECT '{"key1":"val1","key2":"val2"}'::json; json ------------------------------- {"key1":"val1","key2":"val2"} (1 row) test=# SELECT '{"key1":"val1","key2":["val2-1","val2-2"]}'::json; json -------------------------------------------- {"key1":"val1","key2":["val2-1","val2-2"]} (1 row) test=# SELECT '{"key1":"val1","key2":{"key2-1":"val2-1","key2-2":["val2-2-1","val2-2-2"]}}'::json; json ----------------------------------------------------------------------------- {"key1":"val1","key2":{"key2-1":"val2-1","key2-2":["val2-2-1","val2-2-2"]}} (1 row)
特に問題はなさそう。配列もオブジェクトのネストも対応している。
test=# SELECT '{"key1":"値1","key2":"val2"}'::json; ERROR: invalid input syntax for type json LINE 1: SELECT '{"key1":"値1","key2":"val2"}'::json; ^ DETAIL: line 1: Character "▒" must be escaped. test=# SELECT '{"キー1":"val1","key2":"val2"}'::json; ERROR: invalid input syntax for type json LINE 1: SELECT '{"キー1":"val1","key2":"val2"}'::json; ^ DETAIL: line 1: Character "▒" must be escaped. test=#
日本語に関しては、キーにも値にも指定するとパースに失敗する・・・。日本語をサポートしていない仕様のか?いやいや、そんなことはないはず。このtestというデータベース自体はUTF8エンコーディングのはずなのに。上記のSELECT文もUTF8のキャラクタしか含んでいないから、パース出来てもいいはずなのだが。
$ psql -l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+--------+----------+---------+-------+------------------- postgres | harada | UTF8 | C | C | template0 | harada | UTF8 | C | C | =c/harada + | | | | | harada=CTc/harada template1 | harada | UTF8 | C | C | =c/harada + | | | | | harada=CTc/harada test | harada | UTF8 | C | C | (4 rows) $
これは、まだbeta版ってこともあるし、やっぱりバグってことなのかな。明後日のJPUGの勉強会のときに知ってそうな人に聞いてみよう。
JSON関数
9.2では残念ながらJSON関連の関数は、ほとんどサポートされていない。サポートされているのは、配列→JSON文字列変換の関数(array_to_json)と、行型→JSON文字列変換(row_to_json)の関数のみ。
test=# SELECT ARRAY[1, 10, 100]; array ------------ {1,10,100} (1 row) test=# SELECT array_to_json(ARRAY[1, 10, 100]); array_to_json --------------- [1,10,100] (1 row) test=# SELECT ROW(1, 'aaa', now()); row ----------------------------------------- (1,aaa,"2012-05-24 19:55:12.559679+09") (1 row) test=# SELECT row_to_json(ROW(1, 'aaa', now())); row_to_json ---------------------------------------------------------- {"f1":1,"f2":"aaa","f3":"2012-05-24 19:55:26.783458+09"} (1 row) test=#
行コンストラクタの結果をrow_to_json()に渡すとキーが勝手に付与されるのか。ちょっとこの挙動は気持ちが悪い気がする。
複合型を作って、その複合型にcastした結果をrow_to_json()に渡すと、複合型に記述したカラム名をキーにはしてくれるようだが・・・。
test=# CREATE TYPE foo_type AS (id int, data text, ts timestamp); CREATE TYPE test=# SELECT row_to_json(ROW(1, 'aaa', now())::foo_type); row_to_json --------------------------------------------------------- {"id":1,"data":"aaa","ts":"2012-05-24 20:03:46.758499"} (1 row) test=#
今日はここまで。
これから試したいこと
今日はここまでと書いたけど、素のPostgreSQLのままだとこのくらいしか検証するものがないような気がする。
- JSON文字列内を評価する関数がないので、どうにか評価する方法を考えたい。
- これを使ってどういうアプリケーションが作れるのか。
このへんをこれからしばらく、ゆるゆると試してみようかと。