PostgreSQLはを使用していますパラメータ付きのステートメントの拡張クエリプロトコルですが、これらのパラメータは関数パラメータと必ずしも同じではありません。
あなたはこのような関数呼び出しを送信する場合、the C APIを用いた例を使用するには:
res = PQexec(conn, "SELECT myfun(42)");
それは'Q'
(クエリ)識別子を持つパケットで送信されます。
あなたはこのようにそれを送信する場合:
const Oid types[1] = { INT4OID };
const char * const vals[1] = { "42" };
res = PQexecParams(conn, "SELECT myfun($1)", 1, types, vals, NULL, NULL, 0);
クエリが
'P'
(
解析)の識別子と、次の
'B'
(
バインド)に送られると、パラメータを持つパケットで送信されます
パケット。
しかし、それは、関数呼び出しとは何の関係もありません同じことが、このようなクエリのために発生します:
SELECT val FROM mytab WHERE id = $1;
あなたはあなたの目標は、フロントエンド・バックエンドプロトコルに耳を傾け、すべての関数呼び出しをフィルタリングすることであると言いますパラメータが渡されます。
これは非常に難しい作業です。基本的には、サーバに送信されたSQL文を解析する必要があることを意味します。つまり、PostgreSQLのパーサの少なくとも一部を複製する必要があります。構文解析された文を覚えて、バインドパケットからパラメータを注入する必要があります。それに加えて
、私の心に来て2つの質問:この方法を使用すると、関数の内部発行関数呼び出しをキャッチすることができませんことを
を重要ですか?
どのようにあなたは、このようなケースで渡されたパラメータを決定します:
SELECT myfun((SELECT val FROM tab WHERE id = 42));
またはこの:
SELECT myfun(CAST(otherfun(42) || '0' AS integer));
は、たぶん、あなたが望むものを達成するためのより良い方法がハッキングのように、ありますPostgreSQLサーバを起動し、関数が実際に呼び出される場所で情報を抽出します。
ありがとうございます、あなたが言ったこの2つの問題は私の問題でもありましたが、今は単純な呼び出しに焦点を当てます。ハッキングサーバーは、プロキシとして動作する必要があるため、オプションではありません。 – Hamed
postgreSQLはパラメータ付きのステートメントの拡張クエリプロトコルを使用しているので、例えば、準備済みのステートメントと同じ名前と同じパラメータを持つ関数があれば、サーバーは正しいものを選択して実行するようになりますクライアントコール? 'select'または' execute'ステートメントだけを使用していますか? – Hamed
あいまいさはありません。準備された文は、SQL関数['EXECUTE'](https://www.postgresql.org/docs/current/static/sql-execute.html)または[' PQexecPrepared'](https:// www.postgresql.org/docs/current/static/libpq-exec.html#LIBPQ-PQEXECPREPARED)。どちらの場合も、関数名は存在しません。 –