Процедурные языки

QHB позволяет писать пользовательские функции на других языках помимо SQL и C/RUST. Эти другие языки обычно называются процедурными языкам (procedural language, PL). Для функции, написанной на процедурном языке, сервер баз данных не имеет встроенных возможностей для интерпретации исходного текста функции. Вместо этого такая задача передается специальному обработчику, досконально знающему данный язык. Обработчик может либо выполнять всю работу по интерпретации, синтаксическому анализу, выполнению и т. д. сам, либо служить «связующим звеном» между QHB и существующей реализацией языка программирования. Сам обработчик является функцией на языке C/RUST, скомпилированной в общий объект и загружаемой по требованию, как и любая другая функция на C/RUST.

В настоящее время в стандартном дистрибутиве QHB доступен язык PL/pgSQL (глава PL/pgSQL); другие языки могут быть созданы пользователями самостоятельно. Существуют и другие процедурные языки, поддержка которых не включена в базовый дистрибутив. Кроме того, пользователи могут реализовать и другие языки; основы разработки нового процедурного языка рассматриваются в главе Написание обработчика процедурного языка.

Установка процедурных языков

Процедурный язык должен быть «установлен» в каждой базе данных, где он будет использоваться. Однако процедурные языки, установленные в базе данных template1, автоматически становятся доступными во всех впоследствии создаваемых базах данных, так как их записи в template1 будут скопированы командой CREATE DATABASE. Таким образом, администратор базы данных может решать, какие языки будут доступны в определенных базах данных, и при желании может сделать некоторые языки доступными по умолчанию.

Для установки в текущей базе данных языков, поставляемых со стандартным дистрибутивом, необходимо только выполнить CREATE EXTENSION имя_языка. Описанная ниже ручная процедура рекомендуется только для установки языков, которые не были упакованы как расширения.

Ручная процедура установки процедурных языков

Процедурный язык устанавливается в базе данных в пять этапов, которые должны выполняться суперпользователем базы данных. В большинстве случаев требуемые команды SQL должны быть упакованы в виде установочного скрипта «расширения», чтобы для их выполнения можно было использовать команду CREATE EXTENSION.

  1. Разделяемый объект для функции обработки языка должен быть скомпилирован и установлен в соответствующий каталог библиотеки. Это работает по тому же принципу, что и сборка и установка модулей с обычными пользовательскими функциями C/RUST; см. подраздел Компиляция и связывание динамически загружаемых функций. Зачастую обработчик языка будет зависеть от внешней библиотеки, обеспечивающей фактический механизм языка программирования; в этом случае она также должна быть установлена.

  2. Обработчик следует создать командой

    CREATE FUNCTION имя_функции_обработки()
        RETURNS language_handler
        AS 'путь-к-разделяемому-объекту'
        LANGUAGE C;
    

    Специальный возвращаемый тип language_handler сообщает СУБД, что эта функция не возвращает ни один из определенных типов данных SQL и не может напрямую использоваться в операторах SQL.

  3. Дополнительно обработчик языка может предоставить функцию для «встраиваемого кода», выполняющую обработку блоков анонимного кода (команды DO), написанных на этом языке. Если функция для встраиваемого кода предоставляется языком, необходимо объявить ее следующей командой:

    CREATE FUNCTION имя_функции_для_встраиваемого_кода(internal)
        RETURNS void
        AS 'путь-к-разделяемому-объекту'
        LANGUAGE C;
    
  4. Дополнительно обработчик языка может предоставить функцию-«валидатор», проверяющую правильность определения функции без фактического ее выполнения. Функция проверки, если имеется, вызывается командой CREATE FUNCTION. Если функция проверки предоставляется языком, необходимо объявить ее следующей командой:

    CREATE FUNCTION имя_функции_проверки(oid)
        RETURNS void
        AS 'путь-к-разделяемому-объекту'
        LANGUAGE C STRICT;
    
  5. Наконец, процедурный язык следует объявить командой:

    CREATE [TRUSTED] LANGUAGE имя_языка
        HANDLER имя_функции_обработки
        [INLINE имя_функции_для_встраиваемого_кода]
        [VALIDATOR имя_функции_проверки] ;
    

    Необязательное ключевое слово TRUSTED указывает, что язык не предоставляет доступ к данным, которого у пользователя не было бы без него. Доверенные языки предназначены для обычных пользователей базы данных (без прав суперпользователя) и позволяют им безопасно создавать функции и процедуры. Поскольку функции на процедурном языке выполняются внутри сервера баз данных, флаг TRUSTED следует указывать только для языков, не позволяющим обращаться к внутренним компонентам сервера баз данных или файловой системе. Язык PL/pgSQL считается доверенным.

При установке QHB по умолчанию обработчик для языка PL/pgSQL собирается и устанавливается в каталог «library». Более того, сам язык PL/pgSQL установлен во всех базах данных.