Thanks to visit codestin.com
Credit goes to postgrespro.ru

33.7. Интерфейс быстрого пути

PostgreSQL предоставляет интерфейс для передачи серверу простых вызовов функций по быстрому пути.

Подсказка

Этот интерфейс несколько устарел, поскольку можно достичь подобной производительности и большей функциональности путём создания подготовленного оператора, определяющего вызов функции. Последующее выполнение этого оператора с передачей параметров и результатов в двоичном виде можно считать заменой вызову по быстрому пути.

Функция 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 структуры, передаваемой в качестве параметра, имеет значение true, тогда значение u.integer передаётся серверу в виде целого числа указанной длины (это должно быть 2 или 4 байта); при этом устанавливается нужный порядок байтов. Когда isint имеет значение false, тогда указанное число байт по адресу *u.ptr отправляется без какой-либо обработки; данные должны быть представлены в формате, которого ожидает сервер для передачи в двоичном виде данных того типа, что и аргументы функции. (Объявление поля u.ptr, как имеющего тип int *, является историческим; было бы лучше рассматривать его как тип void *.) result_buf указывает на буфер, в который должно быть помещено возвращаемое значение функции. Вызывающий код должен выделить достаточное место для сохранения возвращаемого значения. (Это никак не проверяется!) Фактическая длина результирующего значения в байтах будет возвращена в переменной целого типа, на которую указывает result_len. Если ожидается получение двух- или четырёхбайтового целочисленного результата, то присвойте параметру result_is_int значение 1, в противном случае назначьте ему 0. Когда параметр result_is_int равен 1, libpq переставляет байты в передаваемом значении, если это необходимо, так, чтобы оно было доставлено на клиентскую машину в виде правильного значения типа int; обратите внимание, что по адресу *result_buf доставляется четырёхбайтовое целое для любого допустимого размера результата. Когда result_is_int равен 0, тогда строка байтов в двоичном формате, отправленная сервером, будет возвращена немодифицированной. (В этом случае лучше рассматривать result_buf как имеющий тип void *.)

PQfn всегда возвращает действительный указатель на объект PGresult со статусом PGRES_COMMAND_OK при успешном выполнении функции или PGRES_FATAL_ERROR, если произошла какая-то ошибка. Перед использованием результата нужно сначала проверить его статус. Вызывающая функция отвечает за освобождение памяти, занимаемой объектом PGresult, когда он больше не нужен, с помощью PQclear.

Чтобы передать функции аргумент NULL, запишите в поле len этой структуры значение -1; поля isint и u в этом случае не важны. (Но это работает только при подключении по протоколу 3.0 и новее.)

Если функция возвращает NULL, в *result_len записывается -1, а *result_buf не изменяется. (Это работает только при подключении по протоколу 3.0 и новее; в протоколе 2.0 ни *result_len, ни *result_buf не изменяется.)

Обратите внимание, что при использовании этого интерфейса невозможно обработать множества значений в результате. Кроме того, функция должна быть обычной, а не агрегатной или оконной.