×
Мы обрабатываем cookies, чтобы сделать наш сайт удобнее и персонализированнее для вас. Подробнее: политика использования «cookies» и «политики конфиденциальности».

Для самостоятельной настройки ознакомьтесь с инструкцией

Дополнительные настройки cookies в браузерах

Файлы cookie автоматически загружаются в ваш браузер при посещении веб-сайта. У вас есть возможность управлять этими файлами. Если Вы не согласны с использованием файлов cookies, запретите их сохранение на своём устройстве, удалите уже имеющиеся файлы cookies через настройки браузера или прекратите использование сайта.

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

Инструкция по отключению cookies
Принять
Настроить
Отклонить

ДОКУМЕНТАЦИЯ

Выберите версию, форк и язык для СУБД Digital Q.DataBase, чтобы прочитать или скачать всю документацию.
Техподдержка
Документация
Диасофт
Авторские права © 2016–2025 ООО "Диасофт Экосистема"
Скачать всю документацию:

5.1.17. Упаковка связанных объектов в

5.1.17.1. Файлы расширений
5.1.17.2. Перемещаемость расширений
5.1.17.3. Конфигурационные таблицы расширений
5.1.17.4. Обновление расширений
5.1.17.5. Установка расширений с помощью сценариев обновления
5.1.17.6. Вопросы безопасности расширений
5.1.17.7. Пример расширения

Полезное расширение для Digital Q.DataBase обычно включает несколько объектов SQL; например, для нового типа данных потребуются новые функции, новые операторы и, вероятно, новые классы операторов индекса. Сбор всех этих объектов в единый пакет позволяет упростить управление базой данных. Digital Q.DataBase называет такой пакет расширение. Для определения расширения вам потребуется как минимум файл сценария содержащий SQL команды для создания объектов расширения, а также управляющий файл определяющий несколько основных свойств самого расширения. Если расширение включает код на языке C, обычно также создается файл общей библиотеки, в который компилируется данный код. После подготовки этих файлов простая CREATE EXTENSION команда загружает объекты в вашу базу данных.

Основное преимущество использования расширения вместо простого запуска SQL скрипта для загрузки множества «разрозненных» объектов в базу данных заключается в том, что Digital Q.DataBase затем определит, что объекты расширения взаимосвязаны. Вы можете удалить все объекты одной DROP EXTENSION командой (нет необходимости поддерживать отдельный «скрипт удаления» скрипт). Более того, pg_dump знает, что не следует выгружать в дамп отдельные объекты, входящие в состав расширения — вместо этого в дампы будет просто включена CREATE EXTENSION команда. Это значительно упрощает миграцию на новую версию расширения, которая может содержать больше объектов или отличаться по составу от старой версии. Однако обратите внимание, что при загрузке такого дампа в новую базу данных необходимо наличие управляющего файла (control file), скрипта и других файлов расширения.

Digital Q.DataBase не позволит вам удалить отдельный объект, входящий в расширение, за исключением удаления всего расширения целиком. Также, хотя вы можете изменять определение объекта, являющегося членом расширения (например, с помощью CREATE OR REPLACE FUNCTION для функции), следует учитывать, что изменённое определение не будет выгружено при помощи pg_dump. Подобное изменение обычно целесообразно только в том случае, если вы одновременно вносите такое же изменение в файл сценария расширения. (Однако существуют специальные положения для таблиц, содержащих конфигурационные данные; см. Раздел 5.1.17.3.) В рабочих средах, как правило, лучше создать скрипт обновления расширения для внесения изменений в объекты, входящие в состав расширения.

Скрипт расширения может устанавливать права доступа к объектам, входящим в расширение, с помощью GRANT и REVOKE операторов. Результирующий набор прав доступа для каждого объекта (если они заданы) будет сохранён в pg_init_privs системном каталоге. Когда pg_dump используется, CREATE EXTENSION команда будет включена в дамп, за которой последует набор GRANT и REVOKE операторов, необходимых для приведения прав доступа к объектам в соответствие с их состоянием на момент создания дампа.

Digital Q.DataBase в настоящее время не поддерживает скрипты расширения, выполняющие CREATE POLICY или SECURITY LABEL операторов. Предполагается, что они будут установлены после создания расширения. Все политики RLS и метки безопасности для объектов расширения будут включены в дампы, созданные pg_dump.

Механизм расширения также предусматривает возможность упаковки скриптов изменения, корректирующих определения объектов SQL, содержащихся в расширении. Например, если версия 1.1 расширения добавляет одну функцию и изменяет тело другой функции по сравнению с версией 1.0, автор расширения может предоставить скрипт обновления который вносит только эти два изменения. Команда ALTER EXTENSION UPDATE затем может быть использована для применения этих изменений и отслеживания того, какая версия расширения фактически установлена в данной базе данных.

Типы объектов SQL, которые могут быть членами расширения, приведены в описании команды ALTER EXTENSION. Примечательно, что объекты, действующие на уровне всего кластера баз данных, такие как базы данных, роли и табличные пространства, не могут быть членами расширения, так как расширение определено только в пределах одной базы данных. (Хотя создание таких объектов в скрипте расширения не запрещено, в случае их создания они не будут отслеживаться как часть расширения). Также следует отметить, что если таблица может являться участником расширения, то её вспомогательные объекты, такие как индексы, не считаются участниками расширения напрямую. Другим важным моментом является то, что схемы могут принадлежать расширениям, но не наоборот: расширение как таковое имеет неквалифицированное имя и не существует «внутри» какой-либо схемы. Тем не менее, объекты, входящие в состав расширения, будут принадлежать схемам во всех случаях, когда это предусмотрено для соответствующих типов объектов. В зависимости от конкретного случая расширение может как владеть, так и не владеть схемами, в которых находятся входящие в него объекты.

Если скрипт расширения создает какие-либо временные объекты (например, временные таблицы), такие объекты считаются участниками расширения до конца текущего сеанса, но автоматически удаляются по его завершении, как и любые другие временные объекты. Это является исключением из правила, согласно которому объекты-участники расширения не могут быть удалены без удаления расширения целиком.

5.1.17.1. Файлы расширений #

Данные CREATE EXTENSION команда использует управляющий файл для каждого расширения; имя этого файла должно совпадать с именем расширения и иметь суффикс .control, и они должны быть размещены в каталоге установки SHAREDIR/extension директория. Также должен присутствовать как минимум один SQL файл сценария, соответствующий шаблону именования расширение--версия.sql (например, foo--1.0.sql для версии 1.0 расширения foo). По умолчанию файл(ы) сценария также размещаются в SHAREDIR/extension каталоге; но в управляющем файле может быть указан другой каталог для файлов сценариев.

Формат управляющего файла расширения аналогичен формату файла postgresql.conf , а именно списку parameter_name = присваиваний значений, по одному в строке. Допускаются пустые строки и комментарии, начинающиеся с # # are allowed. Обязательно заключайте в кавычки любое значение, не являющееся простым словом или числом.

В управляющем файле можно задать следующие параметры:

directory (string) #

Каталог, содержащий SQL файл(ы) сценария расширения. Если абсолютный путь не указан, имя указывается относительно каталога установки SHAREDIR directory. The поведение по умолчанию эквивалентно указанию directory = 'расширение'.

default_version (string) #

Версия расширения по умолчанию (та, которая будет установлена, если версия не указана в CREATE EXTENSION). Хотя этот параметр можно опустить, это приведет к CREATE EXTENSION ошибке, если параметр VERSION отсутствует, поэтому обычно не рекомендуется так поступать.

комментарий (string) #

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

кодировка (string) #

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

module_pathname (string) #

Значение этого параметра будет подставляться вместо каждого вхождения параметра MODULE_PATHNAME в файлах сценариев. Если значение не задано, подстановка не производится. Обычно для этого параметра устанавливается значение $libdir/shared_library_name и затем MODULE_PATHNAME используется в CREATE FUNCTION командах для функций на языке C, чтобы в файлах сценариев не требовалось жестко прописывать имя общей библиотеки.

requires (string) #

Список имен расширений, от которых зависит данное расширение, например requires = 'foo, bar'. Эти расширения должны быть установлены до того, как может быть установлено данное расширение.

no_relocate (string) #

Список имен расширений, от которых зависит данное расширение; такие расширения не должны иметь возможности изменять свои схемы с помощью команды ALTER EXTENSION ... SET SCHEMA. Это необходимо, если сценарий данного расширения ссылается на имя схемы требуемого расширения (используя синтаксис @extschema:имя@ ), что не позволяет отслеживать переименования.

superuser (boolean) #

Если этот параметр имеет значение true (что является значением по умолчанию), только суперпользователи могут создавать расширение или обновлять его до новой версии (но см. также параметр trustedниже). Если установлено значение false, то требуются только привилегии, необходимые для выполнения команд в сценарии установки или обновления are required. Обычно здесь следует устанавливать значение true, true если какие-либо из команд сценария требуют прав суперпользователя. (Такие команды в любом случае завершатся ошибкой, но удобнее вывести сообщение об ошибке заранее.)

trusted (boolean) #

Данный параметр, если для него установлено значение true (которое не является значением по умолчанию), позволяет некоторым пользователям, не являющимся суперпользователями, устанавливать расширение, которое имеет superuser устанавливается в true. В частности, установка будет разрешена любому пользователю, имеющему CREATE право в текущей базе данных. Когда пользователь, выполняющий операцию, CREATE EXTENSION не является суперпользователем, но имеет разрешение на установку в силу данного параметра, сценарий установки или обновления запускается от имени начального суперпользователя, а не от имени вызывающего пользователя. Этот параметр не имеет значения, если superuser является false. Как правило, данный параметр не следует устанавливать в значение true для расширений, которые могут предоставлять доступ к функциям, которые в противном случае доступны только суперпользователю, например доступ к файловой системе. Кроме того, пометка расширения как доверенного (trusted) требует значительных дополнительных усилий по обеспечению безопасности сценариев установки и обновления расширения; см. Раздел 5.1.17.6.

перемещаемое (boolean) #

Расширение является перемещаемое предусмотрена ли возможность перемещения содержащихся в нем объектов в другую схему после первоначального создания расширения. Значение по умолчанию — false, то есть расширение не является перемещаемым. См. Раздел 5.1.17.2 для получения дополнительной информации.

схема (string) #

Данный параметр может быть установлен только для неперемещаемых расширений. Он предписывает загрузку расширения строго в указанную схему и ни в какую другую. Система схема параметр учитывается только при первоначальном создании расширения, а не при его обновлении. См. Раздел 5.1.17.2 для получения дополнительной информации.

Помимо основного управляющего файла расширение.control, расширение может иметь вспомогательные управляющие файлы, именованные в стиле расширение--версия.control. При наличии они должны располагаться в каталоге файлов сценариев. Вспомогательные управляющие файлы имеют тот же формат, что и основной управляющий файл. Любые параметры, заданные во вспомогательном управляющем файле, переопределяют значения из основного управляющего файла при установке или обновлении до этой версии расширения. Однако данные параметры directory и default_version не могут быть заданы во вторичном управляющем файле.

Входящие в состав расширения SQL файлы сценариев могут содержать любые SQL-команды, за исключением команд управления транзакциями (BEGIN, COMMITи т. д.) и команд, которые невозможно выполнить внутри блока транзакции (таких как VACUUM). Это обусловлено тем, что файлы сценариев неявно выполняются внутри блока транзакции.

Входящие в состав расширения SQL файлы сценариев также могут содержать строки, начинающиеся с \echo, которые будут игнорироваться механизмом расширения (интерпретироваться как комментарии). Данная возможность обычно используется для генерации ошибки, если файл сценария передается в psql вместо загрузки с помощью CREATE EXTENSION (см. пример сценария в Раздел 5.1.17.7). В противном случае пользователи могут случайно загрузить содержимое расширения как обычные «разрозненных» объекты, а не как расширение, что создаст ситуацию, которую довольно трудно исправить.

Если скрипт расширения содержит строку @extowner@, то эта строка заменяется на (заключенное в соответствующие кавычки) имя пользователя, вызывающего команду CREATE EXTENSION или ALTER EXTENSION. Как правило, эта функциональность используется расширениями, помеченными как доверенные, для назначения владельцем выбранных объектов вызывающего пользователя вместо суперпользователя начальной загрузки. (Однако при этом следует проявлять осторожность. Например, назначение владельцем функции на языке C пользователя, не являющегося суперпользователем, создаст условия для повышения привилегий этого пользователя.)

В то время как файлы сценариев могут содержать любые символы, разрешенные указанной кодировкой, управляющие файлы должны содержать только символы ASCII, так как для Digital Q.DataBase знать, в какой кодировке представлен управляющий файл. На практике это имеет значение только в том случае, если необходимо использовать символы, отличные от ASCII, в комментариях к расширению. В данном случае рекомендуется не использовать управляющий файл комментарий параметр, но вместо этого используйте COMMENT ON EXTENSION внутри файла сценария для задания комментария.

5.1.17.2. Перемещаемость расширений #

Пользователи часто стремятся загрузить объекты, содержащиеся в расширении, в схему, отличную от той, которую предполагал автор расширения. Существует три поддерживаемых уровня перемещаемости:

  • Полностью перемещаемое расширение может быть перенесено в другую схему в любое время, даже после его загрузки в базу данных. Это выполняется с помощью команды ALTER EXTENSION SET SCHEMA которая автоматически переносит все входящие в состав объекты в новую схему. Как правило, это возможно только в том случае, если расширение не содержит внутренних допущений о том, в какой именно схеме находятся его объекты. Кроме того, все объекты расширения изначально должны находиться в одной схеме (не считая объектов, не принадлежащих ни к одной схеме, таких как процедурные языки). Чтобы пометить полностью перемещаемое расширение перемещаемым путем установки relocatable = true в его управляющем файле.

  • Расширение может быть перемещаемым в процессе установки, но не после её завершения. Обычно это требуется, если в файле сценария расширения необходимо явно ссылаться на целевую схему, например, при настройке search_path свойств SQL-функций. Для такого расширения установите relocatable = false в его управляющем файле и используйте @extschema@ для обращения к целевой схеме в файле сценария. Все вхождения этой строки будут заменяется фактическим именем целевой схемы (в двойных кавычках, если необходимо) перед выполнением сценария. Пользователь может задать целевую схему с помощью SCHEMA параметра команды CREATE EXTENSION.

  • Если расширение вообще не поддерживает перенос, установите relocatable = false в его управляющем файле, а также задайте для схема имя предполагаемой целевой схемы. Это предотвратит использование SCHEMA параметра команды CREATE EXTENSION, если только в нем не указана та же схема, что и в управляющем файле. Такой выбор обычно необходим, если расширение содержит внутренние допущения об имени своей схемы, которые нельзя заменить использованием @extschema@. Механизм @extschema@ подстановки доступен и в этом случае, хотя его эффективность ограничена, так как имя схемы определяется управляющим файлом.

Во всех случаях файл сценария будет выполняться с параметром search_path, search_path изначально установленным на целевую схему; то есть, CREATE EXTENSION выполняется эквивалент следующего:

SET LOCAL search_path TO @extschema@, pg_temp;

Это позволяет объектам, создаваемым файлом сценария, попадать в целевую схему. Файл сценария может изменять search_path search_path по своему усмотрению, но обычно это нежелательно. search_path восстанавливается в прежнее значение по завершении CREATE EXTENSION.

Целевая схема определяется схема параметром в управляющем файле, если он указан, в противном случае — SCHEMA опцией команды CREATE EXTENSION , если она указана, в противном случае — текущей схемой создания объектов по умолчанию (первой в search_pathвызывающей стороны). Когда в управляющем файле схема используется параметр schema, целевая схема будет создана, если она еще не существует, но в двух других случаях она уже должна существовать.

Если какие-либо необходимые расширения перечислены в requires в управляющем файле их целевые схемы добавляются к исходному значению параметра search_path, следующему за целевой схемой нового расширения. Это позволяет обеспечить видимость их объектов для файла сценария нового расширения.

В целях обеспечения безопасности pg_temp автоматически добавляется в конец search_path во всех случаях.

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

Если расширение ссылается на объекты, принадлежащие другому расширению, рекомендуется использовать квалифицированные имена (с указанием схемы). Для этого укажите @extschema:имя@ в файле сценария расширения, где имя — это имя другого расширения (которое должно быть перечислено в данном расширении requires список). Эта строка будет заменена именем (в двойных кавычках, если необходимо) целевой схемы этого расширения. Хотя такая нотация избавляет от необходимости делать жестко заданные предположения об именах схем в файле сценария расширения, её использование может привести к внедрению имени схемы другого расширения в установленные объекты данного расширения. (Как правило, это происходит, когда @extschema:имя@ используется внутри строкового литерала, такого как тело функции или search_path параметр. В других случаях ссылка на объект во время синтаксического анализа преобразуется в OID и не требует последующего поиска.) Если имя схемы другого расширения внедрено таким образом, следует предотвратить перемещение другого расширения после установки вашего, добавив имя другого расширения в no_relocate список.

5.1.17.3. Конфигурационные таблицы расширений #

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

Для решения этой проблемы в файле сценария расширения можно пометить созданную таблицу или последовательность как конфигурационное отношение, что позволит pg_dump включить содержимое таблицы или последовательности (но не её определение) в дампы. Для этого вызовите функцию pg_extension_config_dump(regclass, text) после создания таблицы или последовательности, например

CREATE TABLE my_config (key text, value text);
CREATE SEQUENCE my_config_seq;

SELECT pg_catalog.pg_extension_config_dump('my_config', '');
SELECT pg_catalog.pg_extension_config_dump('my_config_seq', '');

Таким способом можно пометить любое количество таблиц или последовательностей. Последовательности, связанные со serial или bigserial столбцами, также могут быть помечены.

Когда второй аргумент функции pg_extension_config_dump является пустой строкой, всё содержимое таблицы выгружается с помощью pg_dump. Обычно это корректно только в том случае, если таблица изначально пуста в том виде, в каком она была создана скриптом расширения. Если в таблице содержатся как исходные данные, так и данные, добавленные пользователем, второй аргумент функции pg_extension_config_dump предоставляет условие WHERE которое выбирает данные для выгрузки. Например, можно сделать следующее:

CREATE TABLE my_config (key text, value text, standard_entry boolean);

SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entry');

и затем обеспечить, чтобы значение standard_entry было истинным только в строках, созданных скриптом расширения.

Для последовательностей второй аргумент функции pg_extension_config_dump не имеет эффекта.

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

Вы можете изменить условие фильтрации, связанное с конфигурационной таблицей, вызвав pg_extension_config_dump снова. (Обычно это полезно в скрипте обновления расширения.) Единственный способ снять с таблицы статус конфигурационной — это отсоединить её от расширения с помощью ALTER EXTENSION ... DROP TABLE.

Обратите внимание, что связи по внешним ключам между этими таблицами определяют порядок, в котором они выгружаются утилитой pg_dump. В частности, pg_dump попытается выгрузить целевую таблицу (на которую ссылаются) перед ссылающейся таблицей. Поскольку связи по внешним ключам устанавливаются во время выполнения CREATE EXTENSION (до загрузки данных в таблицы), циклические зависимости не поддерживаются. При наличии циклических зависимостей данные все равно будут выгружены, однако восстановить такой дамп напрямую будет невозможно, и потребуется вмешательство пользователя.

Последовательности, связанные со serial или bigserial столбцами должны быть явно помечены для выгрузки своего состояния. Пометки их родительского отношения недостаточно для этой цели.

5.1.17.4. Обновление расширений #

Одним из преимуществ механизма расширений является наличие удобных способов управления обновлениями SQL-команд, определяющих объекты расширения. Это реализуется путем связывания имени или номера версии с каждой выпущенной версией установочного скрипта расширения. Кроме того, если вы хотите, чтобы пользователи могли динамически обновлять свои базы данных с одной версии на следующую, следует предоставить скрипты обновления , которые вносят необходимые изменения для перехода от одной версии к следующей. Имена скриптов обновления строятся по шаблону расширение--old_version--target_version.sql (например, foo--1.0--1.1.sql содержит команды для изменения версии 1.0 расширения foo на версию 1.1).

При условии наличия подходящего сценария обновления команда ALTER EXTENSION UPDATE обновит установленное расширение до указанной новой версии. Сценарий обновления выполняется в той же среде, которую CREATE EXTENSION предоставляет для сценариев установки: в частности, search_path настраивается аналогичным образом, и любые новые объекты, созданные сценарием, автоматически добавляются в расширение. Кроме того, если сценарий удаляет объекты, входящие в расширение, они автоматически исключаются из его состава.

Если расширение имеет вторичные управляющие файлы, то параметры управления, используемые для сценария обновления, соответствуют целевой (новой) версии сценария.

ALTER EXTENSION может выполнять последовательности файлов сценариев обновления для выполнения запрошенного обновления. Например, если доступны только foo--1.0--1.1.sql и foo--1.1--2.0.sql и , ALTER EXTENSION применяет их последовательно, если запрошено обновление до версии 2.0 в то время как версия 1.0 уже установлена.

Digital Q.DataBase не делает никаких предположений о свойствах имен версий: например, системе неизвестно, следует ли 1.1 за 1.0. Система просто сопоставляет доступные имена версий и выбирает путь, требующий применения наименьшего количества сценариев обновления. (Имя версии может быть любой строкой, не содержащей -- а также начальных и конечных -.)

В некоторых случаях целесообразно предоставить «downgrade» сценарии, например foo--1.1--1.0.sql для обеспечения возможности отмены изменений, связанных с версией 1.1. В этом случае следует учитывать вероятность того, что сценарий отката может быть применен неожиданно, если он образует более короткий путь обновления. Рискованная ситуация возникает тогда, когда существует «прямой путь» — сценарий обновления, обеспечивающий переход сразу через несколько версий, и одновременно с ним сценарий отката к начальной точке этого прямого пути. В такой ситуации выполнение отката с последующим переходом по прямому пути может потребовать меньше шагов, чем последовательное обновление версий. Если сценарий отката удаляет какие-либо невосстановимые объекты, это приведет к нежелательным результатам.

Для проверки непредвиденных путей обновления используйте следующую команду:

SELECT * FROM pg_extension_update_paths('extension_name');

Здесь показана каждая пара различных известных имен версий для указанного расширения вместе с последовательностью шагов в пути обновления, которая будет использована для перехода от исходной версии к целевой, или NULL если доступный путь обновления отсутствует. Путь отображается в текстовом виде с -- разделителями. Вы можете использовать regexp_split_to_array(path,'--') если вам удобнее использовать формат массива.

5.1.17.5. Установка расширений с помощью сценариев обновления #

Расширение, существующее в течение некоторого времени, вероятно, будет представлено в нескольких версиях, для которых автору потребуется написать сценарии обновления. Например, если вы выпустили foo расширение в версиях 1.0, 1.1и 1.2, должны присутствовать сценарии обновления foo--1.0--1.1.sql и foo--1.1--1.2.sql. До версии Digital Q.DataBase 10 также требовалось создавать новые файлы сценариев foo--1.1.sql и foo--1.2.sql которые напрямую собирают более новые версии расширения, иначе более новые версии нельзя было установить напрямую, а только путем установки 1.0 и последующего обновления. Это было трудоемко и приводило к дублированию, но теперь в этом нет необходимости, так как CREATE EXTENSION может автоматически следовать цепочкам обновлений. Например, если доступны только файлы сценариев foo--1.0.sql, foo--1.0--1.1.sql, и foo--1.1--1.2.sql то запрос на установку версии 1.2 удовлетворяется путем последовательного выполнения этих трех сценариев. Обработка выполняется так же, как если бы вы сначала установили 1.0 а затем обновили до 1.2. (Как и в случае с ALTER EXTENSION UPDATE, если доступно несколько путей, предпочтение отдается кратчайшему.) Организация файлов сценариев расширения в таком стиле позволяет сократить объем работ по сопровождению, необходимых для выпуска небольших обновлений.

Если вы используете вторичные (зависящие от версии) управляющие файлы с расширением, поддерживаемым в таком стиле, имейте в виду, что каждой версии требуется управляющий файл, даже если у нее нет отдельного сценария установки, так как этот управляющий файл будет определять способ выполнения неявного обновления до этой версии. Например, если foo--1.0.control определяет requires = 'bar' но fooв других управляющих файлах расширения это отсутствует, поэтому зависимость расширения от bar будет удалена при обновлении с 1.0 на другую версию.

5.1.17.6. Вопросы безопасности расширений #

Широко распространяемые расширения не должны делать предположений о базе данных, в которой они функционируют. Следовательно, функции, предоставляемые расширением, следует писать в защищенном стиле, исключающем возможность компрометации через атаки на путь поиска (search_path).

Для расширения, у которого свойство superuser установлено в значение true, также необходимо учитывать риски безопасности при выполнении действий в его скриптах установки и обновления. Злоумышленнику не составит труда создать объекты типа «троянский конь», которые скомпрометируют последующее выполнение небрежно написанного скрипта расширения, что позволит такому пользователю получить права суперпользователя.

Если расширение помечено как trusted, то схема установки может быть выбрана пользователем, выполняющим установку; при этом он может намеренно указать небезопасную схему в надежде получить права суперпользователя. Следовательно, доверенное расширение крайне уязвимо с точки зрения безопасности, и все команды его скриптов должны быть тщательно проверены, чтобы исключить любую возможность компрометации.

Рекомендации по безопасному написанию функций приведены в Раздел 5.1.17.6.1 ниже, а рекомендации по безопасному написанию установочных скриптов приведены в Раздел 5.1.17.6.2.

5.1.17.6.1. Меры безопасности для функций расширения #

Функции на языках SQL и PL, предоставляемые расширениями, подвержены риску атак через путь поиска (search_path) во время их выполнения, так как синтаксический разбор этих функций происходит в момент выполнения, а не в момент создания.

На CREATE FUNCTION странице справочного руководства содержатся рекомендации по написанию SECURITY DEFINER функций безопасным образом. Хорошей практикой считается применение этих методов для любой функции, предоставляемой расширением, так как она может быть вызвана пользователем с высокими привилегиями.

Если вы не можете настроить переменную search_path так, чтобы она содержала только безопасные схемы, исходите из того, что каждое неквалифицированное имя может указывать на объект, созданный злоумышленником. Опасайтесь конструкций, которые зависят от search_path неявно; например, IN и CASE выражение WHEN всегда выбирают оператор, используя путь поиска (search_path). Вместо них используйте OPERATOR(схема.=) ANY и CASE WHEN выражение.

Расширение общего назначения обычно не должно предполагать, что оно было установлено в защищенную схему; это означает, что даже квалифицированные (schema-qualified) ссылки на его собственные объекты не являются полностью безопасными. Например, если в расширении определена функция myschema.myfunc(bigint) то такой вызов, как myschema.myfunc(42) может быть перехвачен вредоносной функцией myschema.myfunc(integer). Необходимо следить за тем, чтобы типы данных параметров функций и операторов точно соответствовали объявленным типам аргументов, используя при необходимости явное приведение типов.

5.1.17.6.2. Вопросы безопасности скриптов расширения #

Скрипт установки или обновления расширения должен быть написан таким образом, чтобы защитить систему от атак через путь поиска (search_path), возможных при выполнении скрипта. Если ссылку на объект в скрипте удастся подменить другим объектом, не предусмотренным автором скрипта, безопасность может быть нарушена либо немедленно, либо позже, при использовании некорректно определенного объекта расширения.

Команды DDL, такие как CREATE FUNCTION и CREATE OPERATOR CLASS обычно безопасны, однако следует проявлять осторожность при использовании любых команд, содержащих в качестве компонента выражение общего назначения. Например, CREATE VIEW требует проверки, равно как и выражение DEFAULT выражение в CREATE FUNCTION.

Иногда в скрипте расширения может потребоваться выполнение SQL-команд общего назначения, например, для внесения изменений в системные каталоги, которые невозможны с помощью команд DDL. Такие команды следует выполнять в безопасном search_path; не следует считать путь, указанный в командах CREATE/ALTER EXTENSION безопасным. Рекомендуется временно установить параметр search_path в значение 'pg_catalog, pg_temp' и при необходимости явно указывать ссылки на схему установки расширения. (Данный подход также может быть полезен при создании представлений.) Примеры можно найти в модулях contrib в составе дистрибутива Digital Q.DataBase исходного кода.

Обеспечить полную безопасность ссылок между расширениями крайне сложно, в том числе из-за неопределенности относительно того, в какой схеме находится другое расширение. Риски снижаются, если оба расширения установлены в одной и той же схеме, так как это исключает возможность подстановки вредоносного объекта перед целевым расширением в пути поиска во время установки. search_path. Однако на данный момент механизмов, гарантирующих это, не существует. В настоящее время рекомендуется не помечать расширение как доверенное (trusted), если оно зависит от другого расширения, за исключением случаев, когда зависимое расширение всегда устанавливается в pg_catalog.

5.1.17.7. Пример расширения #

Ниже приведен полный пример SQL-только расширения: составного типа из двух элементов, который может хранить значения любого типа в своих полях с именами «k» и «v». Нетекстовые значения автоматически приводятся к типу text для хранения.

Файл сценария pair--1.0.sql выглядит следующим образом:

-- выдать ошибку, если сценарий запущен в psql напрямую, а не через CREATE EXTENSION
\echo Используйте "CREATE EXTENSION pair" для загрузки этого файла. \quit

CREATE TYPE pair AS ( k text, v text );

CREATE FUNCTION pair(text, text)
RETURNS pair LANGUAGE SQL AS 'SELECT ROW($1, $2)::@extschema@.pair;';

CREATE OPERATOR ~> (LEFTARG = text, RIGHTARG = text, FUNCTION = pair);

-- Параметр "SET search_path" проще в использовании, но квалифицированные имена работают быстрее.
CREATE FUNCTION lower(pair)
RETURNS pair LANGUAGE SQL
AS 'SELECT ROW(lower($1.k), lower($1.v))::@extschema@.pair;'
SET search_path = pg_temp;

CREATE FUNCTION pair_concat(pair, pair)
RETURNS pair LANGUAGE SQL
AS 'SELECT ROW($1.k OPERATOR(pg_catalog.||) $2.k,
               $1.v OPERATOR(pg_catalog.||) $2.v)::@extschema@.pair;';

Управляющий файл pair.control выглядит следующим образом:

# расширение pair
comment = 'Тип данных пары ключ/значение'
default_version = '1.0'
# нельзя перемещать из-за использования @extschema@
relocatable = false

Хотя для установки этих двух файлов в нужный каталог вряд ли понадобится makefile, вы можете использовать Makefile со следующим содержимым:

EXTENSION = pair
DATA = pair--1.0.sql

PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)

Этот makefile опирается на PGXS, который описан в Раздел 5.1.18. Команда make install установит управляющий файл и файлы сценариев в соответствующий каталог, указанный pg_config.

После установки файлов используйте команду CREATE EXTENSION для загрузки объектов в конкретную базу данных.

Наверх
свяжитесь
с нами
контакты
Для прямой связи с нами вы можете использовать контакты ниже, либо оставить заявку через форму обратной связи, и мы обязательно свяжемся с вами

*поля обязательные к заполнению