テーブルがUNLOGGEDで作られたものか調べたい

先日のpgbench UNLOGGEDの調査をしていて思ったんだけど、今のpsqlの\dコマンドでは、どのテーブルがUNLOGGEDになっているのかが一覧からは分からない・・・。

foo=# \d
List of relations
Schema | Name | Type | Owner

                                                              • -

public | foo | table | pgxml
public | foo_u | table | pgxml
(2 rows)

テーブル名を指定すると一応は表示されるけど・・・
foo=# \d foo_u
Unlogged table "public.foo_u"
Column | Type | Modifiers

                                                          • -

id | integer |
data | text |

foo=#

測定のことを考えると、できれば一覧でUNLOGGEDか見たいな〜という気もするので、ビューで作って見ることにする。
とりあえず、\dの背景で生成されるSQL文をサーバログに出力し、そこにUNLOGGEDの情報を追加すればいいはず。
で、UNLOGGEDの情報ってどこで管理しているのかと調べると、pg_classのrelpersistenceに設定されているようだ。

  • "p"なら普通のテーブル(persistent)
  • "u"なら(unlogged)

なので、こんな感じのビューを作ってみる。

CREATE VIEW tablelsit_with_persistent AS (SELECT n.nspname as "Schema",
c.relname as "Name",
CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 'view' WHEN 'i' THEN 'index' WHEN 'S' THEN 'sequence' WHEN 's' THEN 'special' WHEN 'f' THEN 'foreign table' END as "Type",
pg_catalog.pg_get_userbyid(c.relowner) as "Owner",
c.relpersistence as "Persistent"
FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind IN ('r','v','S','f','')
AND n.nspname <> 'pg_catalog'
AND n.nspname <> 'information_schema'
AND n.nspname !~ '^pg_toast'
AND pg_catalog.pg_table_is_visible(c.oid)
ORDER BY 1,2);
5行目にrelpersistenceのカラムを追加しただけ。CASE WHENとかで格好良く編集するのは面倒なのでやらないw

で、このビューを登録してSELECT文で参照すると

foo=# select * from tablelsit_with_persistent ;
Schema | Name | Type | Owner | Persistent

                                                                                                                                • -

public | foo | table | pgxml | p
public | foo_u | table | pgxml | u
public | tablelsit_with_persistent | view | pgxml | p
(3 rows)

foo=#

うむ、一応出力はできた。
でも、いちいちSELECT文をタイプするのがちと面倒。なので、psqlの\setを使って短縮してみる。
foo=# \set DD  select * from "tablelsit_with_persistent"
foo=# :DD;
Schema | Name | Type | Owner | Persistent

                                                                                                                                • -

public | foo | table | pgxml | p
public | foo_u | table | pgxml | u
public | tablelsit_with_persistent | view | pgxml | p
(3 rows)

foo=#

ビュー名を二重引用符で括っているのは、\setがブランク区切りで第2引数以降を解釈しちゃうから。二重引用符を付けないと :DD; で展開しようとしたときに
select*fromtablelsit_with_persistent;
のような不正なSQLになってしまう。ビュー名を二重引用符でくくると
select*from"tablelsit_with_persistent";
になるので解釈可能。ちょっと危うい感じだけど。

てゆーか、次のバージョンでPersistent情報を"\d+"とかで表示してくれると嬉しいかも・・・