PostgreSQL 9.6 - みんな大好きpsql
ということで、今日はみんな大好き psql の9.6改造項目について、実際に動かして試してみましたよ。
psqlがあればGUIクライアント要らないよねw
なお、今回のエントリ、ちょい長いです。
複数のコマンド指定、複数のコマンドファイル指定
リリースノートの記述。
Support multiple -c and -f command-line options (Pavel Stehule, Catalin Iacob)
To allow this with sane behavior, one backwards incompatibility had to be introduced: -c no longer implies --no-psqlrc.
要するに、-c コマンド文字列 や -f コマンドファイル名 が複数記述可能になったっぽい。
試してみよう。
[nuko@localhost ~]$ psql postgres -c "SELECT pg_backend_pid()" -c "SELECT pg_backend_pid()"
pg_backend_pid
----------------
12699
(1 row)
pg_backend_pid
----------------
12699
(1 row)どうやら、この挙動を見る限りでは、複数回 -c オプションで指定したときには、同じセッション内で動作するっぽいですね。
じゃあ、次は複数の-fオプション指定。
こんな2つのファイルを用意する。
[nuko@localhost ~]$ cat /tmp/file1.txt BEGIN; SELECT pg_backend_pid(); [nuko@localhost ~]$ cat /tmp/file2.txt SELECT pg_backend_pid(); COMMIT;
トランザクション途中でファイルを分割していることに注目。
で、これを複数同時に指定してみる。
[nuko@localhost ~]$ psql postgres -f /tmp/file1.txt -f /tmp/file2.txt
BEGIN
pg_backend_pid
----------------
12416
(1 row)
pg_backend_pid
----------------
12416
(1 row)
COMMIT複数のファイルにまたがってトランザクションが継続しているのがわかりますね。
(そうでなければ、最後のCOMMITで"WARNING: there is no transaction in progress"と怒られるはず。
まあ、これはあると嬉しい機能ですよね。
クロスタブ集計ビュー
Add a \crosstabview command that prints the results of a query in a cross-tabulated display
面白いけど、謎機能その1。
たとえば、こんなクエリを発行して、以下の様な結果を取得する。
tmp=# TABLE sales ;
date | item | sales
------------+-------+-------
2016-05-16 | Ramen | 1650
2016-05-16 | Curry | 2500
2016-05-16 | Udon | 500
2016-05-16 | Soba | 600
2016-05-17 | Ramen | 2400
2016-05-17 | Curry | 800
2016-05-18 | Ramen | 1400
2016-05-18 | Curry | 1600
2016-05-18 | Udon | 1000
(9 rows)この状態で、以下の様な9.6新規のpsqlのメタコマンドを発行する。
tmp=# \crosstabview date item sales
date | Ramen | Curry | Udon | Soba
------------+-------+-------+------+------
2016-05-16 | 1650 | 2500 | 500 | 600
2016-05-17 | 2400 | 800 | |
2016-05-18 | 1400 | 1600 | 1000 |
(3 rows)なんかクロスタブ集計っぽい結果が出てきたw
\crosstab メタコマンドは3つないし4つの引数をとる。
1つ目は縦側の列、2つ目は横側の列、3つ目はセルに相当する列を指定。
4つ目の引数にはソートしたい列名を指定する。
面白い機能なんだけど、
なぜpsql上でクロスタブ集計ぽいことしたかったのか、という疑問はある。いいぞ、もっとやれw
\errverbose
Add an \errverbose command that shows the last server error at full verbosity
直前のエラー情報詳細を表示してくれるメタコマンド。
tmp=# SELECT hoge;
ERROR: column "hoge" does not exist
LINE 1: SELECT hoge;
^
tmp=# \errverbose
ERROR: 42703: column "hoge" does not exist
LINE 1: SELECT hoge;
^
LOCATION: errorMissingColumn, parse_relation.c:3090
tmp=# SELECT 1;
?column?
----------
1
(1 row)
tmp=# \errverbose
ERROR: 42703: column "hoge" does not exist
LINE 1: SELECT hoge;
^
LOCATION: errorMissingColumn, parse_relation.c:3090現実社会でもいるよね。
いつまでも失敗を覚えてぐちぐち蒸し返す奴ってwww
\evコマンドと\svコマンド
Add \ev and \sv commands for editing and showing view definitions
\ev コマンドは、クエリエディタコマンド \e をちょい拡張したもので、ビュー編集テンプレートをエディタに表示してくれる。
CREATE VIEW AS SELECT -- something...
似たような機能として、 \ef (関数のテンプレート表示)があったけど、それのView版ね。
\sv はビュー生成時のクエリを表示してくれるメタコマンド。こんな感じ。
tmp=# \sv sales_date
CREATE OR REPLACE VIEW public.sales_date AS
SELECT sales.date,
sum(sales.sales) AS sum
FROM sales
GROUP BY sales.date
\gexec
Add a \gexec command that executes a query and re-submits the result(s) as new queries
最初はよくわかんなかったけど、最後に実行した実行結果を、SQLとして実行するというメタコマンド。
つまり、\gexec の直前に実行するクエリは
SQLを生成するクエリ
である必要がある。変態ですね。
実例を示したほうが早いかな。
まず、こんなクエリを実行する。
tmp=# SELECT 'SELECT now()' FROM (SELECT generate_series(1,2)) AS t; ?column? -------------- SELECT now() SELECT now() (2 rows)
2行の SELECT now() という文字列が結果として返却される。
この状態で、 \gexecを実行すると・・・
tmp=# \gexec
now
-------------------------------
2016-05-18 20:31:06.846529+09
(1 row)
now
-------------------------------
2016-05-18 20:31:06.846616+09
(1 row)さっきの結果文字列 SELECT now() が2回実行される。
さて、この結果を見るとわかると思うけど、個々のクエリは別トランザクションとして実行されている。
が、これは \gexec の問題ではなく、psqlの自動コミットモードがデフォルトで on になっているため。
なので、自動コミットモードを off にすると、2回とも now() は同じ時刻を返却する(同一トランザクションになるので)。
tmp=# \set AUTOCOMMIT off
tmp=# ;
tmp=# SELECT 'SELECT now()' FROM (SELECT generate_series(1,2)) AS t;
?column?
--------------
SELECT now()
SELECT now()
(2 rows)
tmp=# \gexec
now
-------------------------------
2016-05-18 22:26:15.190622+09
(1 row)
now
-------------------------------
2016-05-18 22:26:15.190622+09
(1 row)