Установка расширения

Устанавливаем файлы расширения:

student$ sudo make install -C /home/student/uom PG_CONFIG=/usr/local/pgsql/bin/pg_config
make: Entering directory '/home/student/uom'
/bin/mkdir -p '/usr/local/pgsql/share/extension'
/bin/mkdir -p '/usr/local/pgsql/share/extension'
/usr/bin/install -c -m 644 .//uom.control '/usr/local/pgsql/share/extension/'
/usr/bin/install -c -m 644 .//uom--1.0.sql .//uom--1.2.sql .//uom--1.0--1.1.sql .//uom--1.1--1.2.sql  '/usr/local/pgsql/share/extension/'
make: Leaving directory '/home/student/uom'

Проверим, что расширение доступно для загрузки в базу данных:

=> SELECT * FROM pg_available_extensions WHERE name = 'uom';
 name | default_version | installed_version |       comment        
------+-----------------+-------------------+----------------------
 uom  | 1.2             |                   | Units of Measurement
(1 row)

Создание расширения в базе данных

Создаем расширение uom в новой базе:

=> CREATE DATABASE admin_extensions;
CREATE DATABASE
=> \c admin_extensions
You are now connected to database "admin_extensions" as user "postgres".
=> CREATE EXTENSION uom;
CREATE EXTENSION

Версия расширения соответствует значению параметра default_version:

=> \dx uom
               List of installed extensions
 Name | Version | Schema |           Description           
------+---------+--------+---------------------------------
 uom  | 1.2     | public | Единицы измерения. uom--1.2.sql
(1 row)

Поскольку для версии 1.2 есть файл uom--1.2.sql, то он и используется для создания расширения. А для тех, кто хочет перейти с 1.1 или с 1.0, имеются соответствующие пути обновления.

Расширение справочника

Добавляем футы и дюймы. Столбец predefined заполняется значением по умолчанию (false):

=> INSERT INTO uom_ref VALUES ('фут', 0.3048);
INSERT 0 1
=> INSERT INTO uom_ref VALUES ('дюйм', 0.0254);
INSERT 0 1

Сколько же дюймов в футе?

=> SELECT uom2uom(1, 'фут', 'дюйм');
       uom2uom       
---------------------
 12.0000000000000000
(1 row)

Изменение доступа

Создаем отдельную роль для доступа к таблице uom_ref:

=> CREATE ROLE util;
CREATE ROLE

Читать из таблицы может только новая роль:

=> GRANT SELECT ON uom_ref TO util;
GRANT
=> REVOKE SELECT ON uom_ref FROM public;
REVOKE

pg_dump и объекты расширений

Информация о том, содержимое каких таблиц будет выгружать pg_dump, сохраняется в pg_extension:

=> SELECT extname, extconfig::regclass[], extcondition 
    FROM pg_extension
    WHERE extname = 'uom';
 extname | extconfig |       extcondition       
---------+-----------+--------------------------
 uom     | {uom_ref} | {"WHERE NOT predefined"}
(1 row)

Запускаем pg_dump:

student$ pg_dump -d admin_extensions
--
-- PostgreSQL database dump
--

-- Dumped from database version 10.6
-- Dumped by pg_dump version 10.6

SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET client_min_messages = warning;
SET row_security = off;

--
-- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: 
--

CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;


--
-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: 
--

COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';


--
-- Name: uom; Type: EXTENSION; Schema: -; Owner: 
--

CREATE EXTENSION IF NOT EXISTS uom WITH SCHEMA public;


--
-- Name: EXTENSION uom; Type: COMMENT; Schema: -; Owner: 
--

COMMENT ON EXTENSION uom IS 'Единицы измерения. uom--1.2.sql';


--
-- Data for Name: uom_ref; Type: TABLE DATA; Schema: public; Owner: postgres
--

COPY public.uom_ref (name, k, predefined) FROM stdin;
фут	0.3048	f
дюйм	0.0254	f
\.


--
-- Name: TABLE uom_ref; Type: ACL; Schema: public; Owner: postgres
--

REVOKE SELECT ON TABLE public.uom_ref FROM PUBLIC;
GRANT SELECT ON TABLE public.uom_ref TO util;


--
-- PostgreSQL database dump complete
--

Проверим, как pg_dump выгружает объекты расширения:

Для того, чтобы правильно выгрузить права доступа, в системном каталоге сохраняется информация о правах на объекты, выданные скриптами создания расширений:

=> SELECT objoid::regclass, initprivs FROM pg_init_privs WHERE privtype = 'e';
 objoid  |                initprivs                
---------+-----------------------------------------
 uom_ref | {postgres=arwdDxt/postgres,=r/postgres}
(1 row)

Без этого было бы невозможно сформировать команду REVOKE.