quote_literal の罠。
2004年8月6日 コンピュータ さて、dblink での Sanitize。
8/5の日記では prepare を使えばいいと書いたが、
dblink では文字列で渡すわけだから結局問題を解決できない。
そういうわけで、文字列を escape するようにしていく。
postgresql には文字列を escape する関数 quote_literal がある。
これを使えばすぐだろう。
・・・って考えは甘かった。
dblink では query を文字列で渡す。
SELECT foo(’XXX’,yyy)
を dblink に埋め込むと
dblink(’SELECT foo(’’XXX’’,yyy)’)
って感じになる。ここで、xxx,yyy を変数にすると
dblink(’SELECT foo(’’’ || v_xxx || ’’’,’ || v_yyy::text || ’)’)
って感じ。これを Stored Function に埋め込むと
dblink(’’SELECT foo(’’’’’’ || v_xxx || ’’’’’’,’’ || v_yyy::text || ’’)’’)
と ’ がいっぱいになってかなり変態的。
で、ここで、quote_literal を入れてみる。
dblink(’’SELECT foo(’’’’’’ || quote_literal(v_xxx) || ’’’’’’,’’ || v_yyy::text || ’’)’’)
ってやったら・・・エラーが出て動かなくなった。
で、なかなか解決できない。うぐぐぐぐ・・・・。
PHP の場合、pg_escape_string という、
「文字列中の Single Quote 等を escape する」関数があるが、
それはこんな感じで使う。
$sql = "SELECT foo(’" . pg_escape_string($xxx) . "’,$yyy);";
しかし、PostgreSQL の quote_literal は
実は「文字列を引用符で括る」関数で、
ついでに 「文字列中の Single Quote 等を escape する」関数だった。
そういうわけで、正しくは
dblink(’’SELECT foo(’|| quote_literal(v_xxx) || ’’,’’ || v_yyy::text || ’’)’’)
と少しすっきりした形が正しかった。
これだけで半日つぶしたよぉ・・・・。
8/5の日記では prepare を使えばいいと書いたが、
dblink では文字列で渡すわけだから結局問題を解決できない。
そういうわけで、文字列を escape するようにしていく。
postgresql には文字列を escape する関数 quote_literal がある。
これを使えばすぐだろう。
・・・って考えは甘かった。
dblink では query を文字列で渡す。
SELECT foo(’XXX’,yyy)
を dblink に埋め込むと
dblink(’SELECT foo(’’XXX’’,yyy)’)
って感じになる。ここで、xxx,yyy を変数にすると
dblink(’SELECT foo(’’’ || v_xxx || ’’’,’ || v_yyy::text || ’)’)
って感じ。これを Stored Function に埋め込むと
dblink(’’SELECT foo(’’’’’’ || v_xxx || ’’’’’’,’’ || v_yyy::text || ’’)’’)
と ’ がいっぱいになってかなり変態的。
で、ここで、quote_literal を入れてみる。
dblink(’’SELECT foo(’’’’’’ || quote_literal(v_xxx) || ’’’’’’,’’ || v_yyy::text || ’’)’’)
ってやったら・・・エラーが出て動かなくなった。
で、なかなか解決できない。うぐぐぐぐ・・・・。
PHP の場合、pg_escape_string という、
「文字列中の Single Quote 等を escape する」関数があるが、
それはこんな感じで使う。
$sql = "SELECT foo(’" . pg_escape_string($xxx) . "’,$yyy);";
しかし、PostgreSQL の quote_literal は
実は「文字列を引用符で括る」関数で、
ついでに 「文字列中の Single Quote 等を escape する」関数だった。
そういうわけで、正しくは
dblink(’’SELECT foo(’|| quote_literal(v_xxx) || ’’,’’ || v_yyy::text || ’’)’’)
と少しすっきりした形が正しかった。
これだけで半日つぶしたよぉ・・・・。
コメント