komamitsu.logスマートフォン用の表示で見るkomamitsu.logこの広告は、90日以上更新していないブログに表示しています。14日目の記事で、現在12/21です。DataのDataTanksというオプションサービスでPostgreSQLが利用されているためちょっと関係していると個人的に考えています。DataTanksそのものについては、こちらの記事に良く纏められているのでご参照ください!qiita.comこのDataTanks、ベースであるPostgreSQLのFDWを用いた外部テーブルを利用することが多く、かつBIツールと接続して利用することが多い、のですが幾つかのBIツールからPostgreSQL上の外部テーブルにアクセスできない(BIツールが外部テーブルの存在を検知できない)問題に気がつきました。workaroundとしては、この外部テーブルをVIEWで包めばBIツールからアクセスできるようになるのですが、あまりスマートではありません。そこで、対応案を考えてみた、というのが今回のお話です。途中まで書いていた記事の内容が思いっきり被っていたので強引に方向展開した訳ではありません。何が問題なのか?例えば、TableauをPostgreSQLのデータベースに接続させると以下のようなクエリーが飛んできます。あるものの一覧を取得しています。あるため、このクエリ条件の対象とはならず、Tableauからは認識されません。すれば良いのか?色々調べてみると同様の問題が某所のサポートページに載っているのを発見しましたが、BIツール側で対応しそうな雰囲気は無さそうでした。追加できないか検討してみました。他の拡張ライブラリを見るとanalyze済みのQuery構造体にアクセスしているものが幾つかありました。利用するとanalyze後に任意の関数を呼んでもらえそうです。上記のフックにその関数を指定しMakefile書いて.soを生成しインストールpostgresql.confのshared_preload_librariesにそのライブラリ名を指定しPostgreSQLを起動とやってみたところ、期待通りにクエリの発行時にログが出力されたので、これは余裕で行けるのでは?感が高まりました。Query構造体をチェック拡張ライブラリ内でフックに指定した関数にはanalyze済みのQuery構造体が渡ってきます。クエリなのかどうか?が判断できそうです。Query構造体にはrtableというスキャン対象のテーブル情報が詰まったRangeTblEntry構造体とjointreeというpredicatesが詰まっているFromExpr構造体が含まれています。relidが含まれており、これを辿ってRelationData構造体経由でpg_class用の構造体にアクセスできそうです。ちなみにPostgreSQLの実装内ではList構造体が使われることが多いのですが、便利な一方、実際の型が読み取れないのでgrepやctagsでコードを追いにくいなぁと思いました。あるかチェックできます。次に当該クエリがテーブル種別を表すrelkindを参照しているかどうかチェックし、参照している場合はクエリ上におけるrelkindの登場位置を覚えておきます。この情報は後ほど利用します。チェックの仕方はRangeTblEntry構造体に含まれるerefのcolnamesをなめていけば可能そうです。勝ったも同然な気持ちでいました。Alias;クエリの条件書き換えPostgreSQLにはexpression_tree_walker()というNodeをtraverseするための関数が用意されています。それ用の関数を自分で書くのは面倒だなぁと思っていたのでとても助かりました。これが無かったらこの拡張ライブラリは半日で書けなかったと思います。expression_tree_walkerにはvisitorとしての処理を行う関数を渡してあげるのですが、この関数内では以下のことを行うようにしました。'v'")を考慮しOpExprも見るべきなのですが、BIツールから発行されるクエリーで今のところそのようなものを観測していないこと、及び、このケースのクエリ書き換えの場合、traverse対象Nodeの上位Nodeを書き換える必要があり素人にはちょっと面倒くさそう、といった理由で未実装となっています。以上のような感じで実装してみたところ、無事想定するクエリを書き換えることができました。requestを頂けると有難いです。今後は、以下のような場合に問題が出そうなので、もう少し情報を集めつつ、必要であれば発動条件の制限をしていこうかと思っています。pg_catalog.pg_class.relkind経由でテーブルを列挙し、標準テーブルのみ扱うことを想定し外部テーブルを扱うと問題があるケース今回初めてPostgreSQLの拡張ライブラリを書いてみたのですが、簡単に色々なことができるので非常に面白かったです。いうMulticornを用いたFDWを書いたのですが、機会があればCで書き直せそうだなぁと思いました。月別アーカイブはてなブログをはじめよう!komamitsuさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。