PostgreSQLは、サーバへの簡単な関数呼び出しを送信する近道 (fast-path) インタフェースを用意しています。
この関数はどちらかというと廃れたものです。 同様の性能やそれ以上の機能を、関数呼び出しを定義したプリペアド文を設定することで達成できるからです。 そして、その文をパラメータと結果をバイナリ転送するように実行すれば、近道関数呼び出しを置き換えることになります。
PQfn関数は近道インタフェースを使ってサーバ関数の実行を要求します。
PGresult *PQfn(PGconn *conn,
int fnid,
int *result_buf,
int *result_len,
int result_is_int,
const PQArgBlock *args,
int nargs);
typedef struct
{
int len;
int isint;
union
{
int *ptr;
int integer;
} u;
} PQArgBlock;
fnid引数は実行する関数のOIDです。
argsとnargsは関数に渡すパラメータを定義します。
これらは関数宣言における引数リストに一致しなければなりません。
パラメータ構造体のisintが真の場合、u.integerの値はサーバに指定長の整数として送信されます。
(これは2もしくは4バイトでなければなりません。)
この時、適切なバイト順の交換が行なわれます。
isintが偽の場合は、*u.ptrで指定されたバイト数が無処理で送信されます。
関数のパラメータデータ型をバイナリ転送で行うために、このデータはサーバで想定する書式である必要があります。
(u.ptrをint *型と宣言するのは歴史的なものです。void *と考えた方が良いでしょう。)
result_bufは関数の戻り値を格納するバッファを指しています。
呼び出し側は戻り値を格納するのに十分な領域を確保しておかなければいけません。
(ライブラリ側ではこの検査はしていません!)
バイト単位での結果の実データ長はresult_lenが指す整数で返されます。
結果が2、4バイト整数だと想定できるならresult_is_intを1に、そうでなければ0を設定します。
result_is_intを1にすれば、必要に応じて値のバイト順を入れ換えるようlibpqに指示することになります。
そしてクライアントマシン上で正しいint値となるように転送します。
4バイト整数は認められた結果の大きさで*result_bufに転送されることに注意してください。
result_is_intが0の場合は、バックエンドが送ったバイナリ書式のバイト列を何も修正せずに返します。
(この場合、result_bufはvoid *型と考えた方が良いでしょう。)
PQfnは常に有効なPGresult*を返します。
結果を使う前にはまず、結果ステータスを調べておくべきでしょう。
結果が必要なくなった時点で、PQclearによって、PGresultを解放するのは、呼び出し側の責任です。
このインタフェースを使用した場合、NULL引数やNULL結果、セット値の結果を扱うことができないことに注意してください。