34.8. Интерфейс быстрого пути
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
в этом случае не важны.
Если функция возвращает NULL, в *result_len
записывается -1
, а *result_buf
не изменяется.
Обратите внимание, что при использовании этого интерфейса невозможно обработать множества значений в результате. Кроме того, функция должна быть обычной функцией, а не процедурой, агрегатной или оконной функцией.
5.12. Other Database Objects
Tables are the central objects in a relational database structure, because they hold your data. But they are not the only objects that exist in a database. Many other kinds of objects can be created to make the use and management of the data more efficient or convenient. They are not discussed in this chapter, but we give you a list here so that you are aware of what is possible:
Views
Functions and operators
Data types and domains
Triggers and rewrite rules
Detailed information on these topics appears in Part V.