読者です 読者をやめる 読者になる 読者になる

解決!OUTER JOIN問題

OSS/Linux

SE-PostgreSQLでOUTER JOINを使った場合、PostgreSQLの行フィルタリングの制約からサブクエリへの書き換えを行って対処していることは既に書いた通りである。
http://kaigai.sblo.jp/article/3860897.html

しかし単純に以下のように書き換えてしまうと、LEFT OUTER JOINの左側テーブルのシステム列が参照できなくなるという問題があった。

SELECT * FROM t1 LEFT OUTER JOIN t2;

SELECT * FROM
(SELECT * FROM t1 WHERE sepgsql_tuple_perms(t1, ...)) AS t1
LEFT OUTER JOIN t2 ON sepgsql_tuple_perms(t2, ...)
しかしよく考えてみれば単純な話で、書き換えたサブクエリの中身が「SELECT * FROM ...」だから悪いのだ。要は、次のように書き換えればOK
SELECT security_context, tableoid, * FROM t1 LEFT OUTER JOIN t2;

SELECT *, t1.security_context, t1.tableoid FROM
(SELECT *, security_context, tableoid FROM t1
WHERE sepgsql_tuple_perms(t1, ...)) AS t1
LEFT OUTER JOIN t2 ON sepgsql_tuple_perms(t2, ...)
つまり、サブクエリの中でシステム列を参照し、その結果を上位のクエリが参照すれば同じ結果を得られる。

LEFT OUTER JOINで結合するテーブルのシステム列なんか参照するか!?
とも思ったが、pg_dumpの中ではLEFT OUTER JOINした上でシステム列を参照しており、バックアップ/リストアを(スマートに)実装するためにはぜひとも解決しておきたい問題だったのである。