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
не изменяется.)
Обратите внимание, что при использовании этого интерфейса невозможно обработать множества значений в результате. Кроме того, функция должна быть обычной функцией, а не процедурой, агрегатной или оконной функцией.