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*
ポインタを返します。
成功した場合はPGRES_COMMAND_OK
、問題が発生した場合はPGRES_FATAL_ERROR
のステータスが返されます。
結果を使う前にはまず、結果ステータスを調べておくべきでしょう。
結果が必要なくなった時点で、PQclear
によって、PGresult
を解放するのは、呼び出し側の責任です。
関数にNULL引数を渡すには、そのパラメータ構造体のlen
フィールドを-1
に設定します。
isint
フィールドとu
フィールドは無関係です。
この関数がNULLを返す場合、*result_len
は-1
に設定され、*result_buf
は変更されません。
このインタフェースを使用した場合、セット値の結果を扱うことができないことに注意してください。 また、関数は、集約関数、ウィンドウ関数またはプロシージャではなく、プレーンな関数である必要があります。