SlideShare a Scribd company logo
www.postgrespro.ru
РАСШИРЕНИЯ ДЛЯ POSTGRESQL
Hacking PostgreSQL
10.03.2016
2
Содержание
1. Расширение (contrib)
2. Новый тип данных
3. SPI (Server Programming Interface)
4. Особенности функций на Си
5. SRF (Set-Returning Function)
3
Расширение (contrib)
●
Инфраструктура сборки PGXS
●
PGXN (PostgreSQL Extension Network)
●
PgFoundry
●
Управляется каталогом pg_extension
SELECT * FROM pg_extension;
-[ RECORD 1 ]--+--------
extname | plpgsql
extowner | 10
extnamespace | 11
extrelocatable | f
extversion | 1.0
extconfig |
extcondition |
4
Управление расширением
CREATE EXTENSION [ IF NOT EXISTS ] extension_name
[ WITH ] [ SCHEMA schema_name ]
[ VERSION version ]
[ FROM old_version ]
DROP EXTENSION [ IF EXISTS ] extension_name [, ...]
[ CASCADE | RESTRICT ]
ALTER EXTENSION extension_name UPDATE [ TO new_version ]
ALTER EXTENSION extension_name SET SCHEMA new_schema
ALTER EXTENSION extension_name ADD member_object
ALTER EXTENSION extension_name DROP member_object
5
Объекты в расширении
AGGREGATE agg_name (agg_type [, ...] ) |
CAST (source_type AS target_type) |
COLLATION object_name |
CONVERSION object_name |
DOMAIN object_name |
FOREIGN DATA WRAPPER object_name |
FOREIGN TABLE object_name |
FUNCTION function_name ( [ [ argmode ] [ argname ]
argtype [, ...] ] ) |
OPERATOR operator_name (left_type, right_type) |
OPERATOR CLASS object_name USING index_method |
OPERATOR FAMILY object_name USING index_method |
6
Объекты в расширении
[ PROCEDURAL ] LANGUAGE object_name |
SCHEMA object_name |
SEQUENCE object_name |
SERVER object_name |
TABLE object_name |
TEXT SEARCH CONFIGURATION object_name |
TEXT SEARCH DICTIONARY object_name |
TEXT SEARCH PARSER object_name |
TEXT SEARCH TEMPLATE object_name |
TYPE object_name |
VIEW object_name
7
Из чего состоит расширение?
pg_example.control – управляющий файл
pg_example.c – исходный текст на C
Makefile – файл для сборки с помощью GNU make
pg_example--1.0.sql – SQL-скрипт, создающий
объекты БД
sql/pg_example.sql – регрессионные тесты
data/example.data – данные для регрессионных
тестов
expected/pg_example.out – ожидаемые результаты
README.txt
8
pg_example.control
# pg_example extention
comment = 'my first extension'
default_version = '1.0'
module_pathname = '$libdir/pg_example'
relocatable = true
directory #Каталог, содержащий файл(ы) SQL скриптов
encoding #Кодировка набора символов, используемая файлами
скриптов
requires #Расширения, от которых зависит данное расширение
superuser #Нужны ли права суперпользователя для
установки/обновления расширения
schema #Схема, в которую должно быть загружено расширение.
Только для не relocatable
9
Makefile
# pg_example/Makefile
# Название собираемого .so файла
MODULE_big = pg_example
# Список .o файлов, из которых собирается .so
OBJS = pg_example.o
# Название расширения
EXTENSION = pg_example
DATA = pg_example—1.0.sql
# Список тестов
REGRESS = pg_example
10
Makefile (2)
ifdef USE_PGXS
# Если USE_PGXS установлено, то нужные для сборки файлы
# PostgreSQL находятся с помощью утилиты pg_config
PG_CONFIG = pg_config
PGXS := $( shell $( PG_CONFIG ) --pgxs )
include $(PGXS)
else
# Если нет, то считается что расширение помещено в папку
# contrib исходников PostgreSQL
subdir = contrib/pg_example
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
include $(top_srcdir)/contrib/contrib-global.mk
endif
11
Содержание
1. Расширение (contrib)
2. Новый тип данных
3. SPI (Server Programming Interface)
4. Особенности функций на Си
5. SRF (Set-Returning Function)
12
pair
Простейшая реализация типа данных пара key/value
/* pg_example--1.0.sql */
CREATE TYPE pair AS ( k text, v text );
CREATE OR REPLACE FUNCTION pair(anyelement, anyelement)
RETURNS pair LANGUAGE SQL AS 'SELECT ROW($1, $2)::pair';
CREATE OPERATOR ~> (
LEFTARG = anyelement,
RIGHTARG = anyelement,
PROCEDURE = pair
);
13
pair
CREATE EXTENSION pg_example;
CREATE TABLE keyvalue(kv pair);
INSERT INTO keyvalue VALUES ('key'::text~>'value'::text),
('foo'::text~>'bar'::text);
SELECT * FROM keyvalue;
SELECT (kv).k, (kv).v FROM keyvalue ORDER BY (kv).k;
kv
-------------
(key,value)
(foo,bar)
k | v
-----+-------
foo | bar
key | value
14
contrib/hstore
Реализация key/value типа данных.
Предшественник json.
Документация модуля hstore
Презентация про hstore.
15
CREATE TYPE
CREATE TYPE hstore (
INTERNALLENGTH = -1,
INPUT = hstore_in,
OUTPUT = hstore_out,
RECEIVE = hstore_recv,
SEND = hstore_send,
STORAGE = extended
);
pg_type
---------------+------------
typname | hstore
typnamespace | 2200
typowner | 16384
typlen | -1
typbyval | f
typinput | hstore_in
typoutput | hstore_out
typreceive | hstore_recv
typsend | hstore_send
typstorage | x (extended)
.......
16
hstore_in
CREATE FUNCTION
hstore_in(cstring)
RETURNS hstore
AS '$libdir/hstore',
'hstore_in'
LANGUAGE C STRICT
IMMUTABLE;
pg_proc
----------------+---------------
proname | hstore_in
pronamespace | 2200
proowner | 16384
prolang | 13
procost | 1
prorows | 0
provariadic | 0
prorettype | 16385 (hstore)
proargtypes | 2275 (cstring)
prosrc | hstore_in
probin | $libdir/hstore
.......
17
Новый оператор
CREATE OPERATOR -> (
LEFTARG = hstore,
RIGHTARG = text,
PROCEDURE = fetchval
);
pg_operator
-------------+------------
oprname | ->
oprnamespace | 2200
oprowner | 16384
oprkind | b
oprleft | 16385 (hstore)
Oprright | 25 (text)
oprresult | 25
oprcom | 0
oprnegate | 0
oprcode | fetchval
18
Функция для оператора
CREATE FUNCTION
fetchval(hstore,text)
RETURNS text
AS '$libdir/hstore',
'hstore_fetchval'
LANGUAGE C STRICT
IMMUTABLE;
pg_proc
----------------+----------------
proname | fetchval
pronamespace | 2200
proowner | 16384
prolang | 13
procost | 1
prosrc | hstore_fetchval
probin | $libdir/hstore
proconfig |
proacl |
.......
19
Индексная поддержка
CREATE OPERATOR CLASS gist_hstore_ops
DEFAULT FOR TYPE hstore USING gist
AS
OPERATOR 7 @> ,
OPERATOR 9 ?(hstore,text) ,
OPERATOR 10 ?|(hstore,text[]) ,
OPERATOR 11 ?&(hstore,text[]) ,
OPERATOR 13 @ ,
FUNCTION 1 ghstore_consistent (internal, hstore,
smallint, oid, internal),
FUNCTION 2 ghstore_union (internal, internal),
FUNCTION 3 ghstore_compress (internal),
FUNCTION 4 ghstore_decompress (internal),
FUNCTION 5 ghstore_penalty (internal, internal,
internal),
FUNCTION 6 ghstore_picksplit (internal, internal),
FUNCTION 7 ghstore_same (ghstore, ghstore, internal),
STORAGE ghstore;
20
Ещё примеры
●
math3d
●
IMCS (In-Memory Columnar Store)
21
Содержание
1. Расширение (contrib)
2. Новый тип данных
3. SPI (Server Programming Interface)
4. Особенности функций на Си
5. SRF (Set-Returning Function)
22
SPI. Функции
SPI - Server Programming Interface
●
Процедурные языки
(PL/pgSQL, PL/python, PL/perl, PL/R ...)
●
API для расширений (pg_paxos api)
●
Триггеры (contrib/spi)
23
SPI. Функции
●
SPI_connect / SPI_finish
●
SPI_push / SPI_pop
●
SPI_execute / SPI_exec
●
SPI_prepare
●
SPI_execute_plan
●
SPI_keepplan / SPI_saveplan
24
SPI. Функции (2)
●
SPI_gettype / SPI_gettypeid
●
SPI_getrelname / SPI_getnspnam
●
SPI_copytuple
●
SPI_returntuple
●
SPI_modifytuple
25
SPI. Функции (3)
●
SPI_palloc
●
SPI_repalloc
●
SPI_pfree
26
SPI. Timetravel
timetravel ('date_on', 'date_off'
[,'insert_user',
'update_user',
'delete_user' ] )
set_timetravel(relname, on)
get_timetravel(relename)
27
SPI. Timetravel
CREATE EXTENSION timetravel;
CREATE TABLE tttest(
price_id int4, price_val int4,
price_on abstime, price_off abstime);
CREATE UNIQUE INDEX tttest_idx ON tttest
(price_id,price_off);
CREATE TRIGGER timetravel
BEFORE INSERT OR DELETE OR UPDATE ON tttest
FOR EACH ROW EXECUTE PROCEDURE timetravel
(price_on, price_off);
28
SPI. Timetravel. INSERT
INSERT INTO tttest VALUES (1, 1, NULL, NULL);
INSERT INTO tttest(price_id, price_val)VALUES (2, 2);
INSERT INTO tttest(price_id, price_val, price_off)
VALUES (3, 3, 'infinity');
price_id | price_val | price_on | price_off
---------+-----------+------------------------+-----------
1 | 1 | 2016-03-07 17:59:46+03 | infinity
2 | 2 | 2016-03-07 18:00:09+03 | infinity
3 | 3 | 2016-03-07 18:00:32+03 | infinity
29
SPI. Timetravel. INSERT
if (TRIGGER_FIRED_BY_INSERT(trigdata→tg_event))
isinsert = true;
…
if (isinsert)
{
oldtimeon = SPI_getbinval(trigtuple,
tupdesc, attnum[a_time_on], &isnull);
if (isnull)
/* Установить в a_time_on
* значение GetCurrentAbsoluteTime */
rettuple = SPI_modifytuple(rel, trigtuple,
chnattrs, chattrs, newvals, newnulls);
return PointerGetDatum(rettuple);
30
SPI. Timetravel. DELETE
DELETE FROM tttest WHERE price_id = 1;
price_id | price_val | price_on | price_off
----------+-----------+------------------------+------------------------
2 | 2 | 2016-03-07 18:00:09+03 | infinity
3 | 3 | 2016-03-07 18:00:32+03 | infinity
1 | 1 | 2016-03-07 17:59:46+03 | 2016-03-07 18:04:16+03
31
SPI. Timetravel. UPDATE
UPDATE tttest SET price_val = 30 WHERE price_id = 3;
price_id | price_val | price_on | price_off
----------+-----------+------------------------+------------------------
2 | 2 | 2016-03-07 18:00:09+03 | infinity
1 | 1 | 2016-03-07 17:59:46+03 | 2016-03-07 18:04:16+03
3 | 3 | 2016-03-07 18:00:32+03 | 2016-03-07 18:06:19+03
3 | 30 | 2016-03-07 18:06:19+03 | infinity
32
SPI. Timetravel. SELECT
SELECT * FROM tttest WHERE price_off = 'infinity';
price_id | price_val | price_on | price_off
----------+-----------+------------------------+------------------------
2 | 2 | 2016-03-07 18:00:09+03 | infinity
3 | 30 | 2016-03-07 18:06:19+03 | infinity
33
SPI. Timetravel. CHANGE DATE
SELECT set_timetravel('tttest', 0);
UPDATE tttest SET price_on = '01-Jan-1990 00:00:01'
WHERE price_id = 3 AND price_off <> 'infinity';
SELECT set_timetrave l('tttest', 1);
SELECT * FROM tttest WHERE price_id = 3
AND price_on <= '10-Jan-1990'
AND price_off > '10-Jan-1990';
price_id | price_val | price_on | price_off
----------+-----------+------------------------+------------------------
3 | 3 | 1990-01-01 00:00:01+03 | 2016-03-07 18:06:19+03
34
Ещё примеры SPI
●
pg_pathman
●
pg_paxos
35
Недостатки SPI
●
Низкая скорость
●
Доступ только к HeapTuples
36
Содержание
1. Расширение (contrib)
2. Новый тип данных
3. SPI (Server Programming Interface)
4. Особенности функций на Си
5. SRF (Set-Returning Function)
37
Datum
●
Datum – абстрактный тип данных в PostgreSQL
●
Значения, которые помещаются в Datum, могут
быть переданы по значению, остальные
передаются по указателю.
●
Аргументы функции и возвращаемые значения
передаются как Datum.
●
src/include/postgres.h
●
src/include/utils/datum.h
38
Datum (2)
typedef uintptr_t Datum;
#define DatumGetPointer(X) ((Pointer) (X))
#define PointerGetDatum(X) ((Datum) (X))
#define DatumGetInt32(X) ((int32) GET_4_BYTES(X))
#define Int32GetDatum(X) ((Datum) SET_4_BYTES(X))
Size datumGetSize(Datum value, bool typByVal, int typLen);
Datum datumCopy(Datum value, bool typByVal, int typLen);
bool datumIsEqual(Datum value1, Datum value2,
bool typByVal, int typLen);
39
Function manager
●
src/backend/utils/fmgr/README
●
src/include/fmgr.h
●
src/include/funcapi.h
40
PG_MODULE_MAGIC
#include "fmgr.h"
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
void _PG_init(void)
{
/* Define custom GUC variables */
/* Install hooks */
}
/* Source code */
41
Calling convention 1
/* Standard parameter list for fmgr-compatible functions */
#define PG_FUNCTION_ARGS FunctionCallInfo fcinfo
/* Макросы для доступа к параметрам */
#define PG_GETARG_DATUM(n) (fcinfo->arg[n])
#define PG_GETARG_INT32(n) DatumGetInt32(PG_GETARG_DATUM(n))
#define PG_NARGS() (fcinfo->nargs)
#define PG_ARGISNULL(n) (fcinfo->argnull[n])
/* Макросы для возврата параметров */
#define PG_RETURN_DATUM(x) return (x)
#define PG_RETURN_VOID() return (Datum) 0
#define PG_RETURN_NULL()
42
Пример
/* функция на Си */
PG_FUNCTION_INFO_V1(add_one)
Datum
add_one(PG_FUNCTION_ARGS)
{
int32 arg = PG_GETARG_INT32(0);
PG_RETURN_INT32(arg + 1);
}
/* SQL объявление функции */
CREATE FUNCTION add_one(integer) RETURNS integer
AS 'DIRECTORY/funcs', 'add_one'
LANGUAGE C STRICT;
43
Работа с Tuple
#include "funcapi.h"
/* Узнать возвращаемый тип данных,
* и, если он составной, получить TupleDesc */
TypeFuncClass get_call_result_type(
FunctionCallInfo fcinfo,
Oid *resultTypeId,
TupleDesc *resultTupleDesc)
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
HeapTuple heap_form_tuple(
TupleDesc tupdesc,
Datum *values, bool *isnull)
HeapTupleGetDatum(HeapTuple tuple)
44
Ещё примеры SRF
●
src/include/access/tupdesc.h
●
src/backend/access/common/tupdesc.c
45
Содержание
1. Расширение (contrib)
2. Новый тип данных
3. SPI (Server Programming Interface)
4. Особенности функций на Си
5. SRF (Set-Returning Function)
46
SRF
●
35.9.9. Returning Sets
●
src/include/funcapi.h
47
SRF (Set Returning Functions)
#Определить, что функция вызвана первый раз
SRF_IS_FIRSTCALL()
#Инициализировать FuncCallContext при первом вызове
SRF_FIRSTCALL_INIT()
#Очистить контекст при каждом последующем вызове
SRF_PERCALL_SETUP()
#Вернуть очередное значение функции
SRF_RETURN_NEXT(funcctx, result)
#Завершить выполнение SRF, сбросить контекст
SRF_RETURN_DONE(funcctx)
48
SRF (1)
Datum
my_Set_Returning_Function(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
Datum result;
MemoryContext oldcontext;
<user defined declarations>
49
SRF (2)
...
if (SRF_IS_FIRSTCALL())
{
funcctx = SRF_FIRSTCALL_INIT();
/* switch context when allocating stuff
* to be used in later calls */
oldcontext = MemoryContextSwitchTo(
funcctx->multi_call_memory_ctx);
<user defined code>
<if returning composite>
<build TupleDesc, and perhaps AttInMetaData>
<endif returning composite>
<user defined code>
/* return to original context
* when allocating transient memory */
MemoryContextSwitchTo(oldcontext);
}
50
SRF (3)
...
<user defined code>
funcctx = SRF_PERCALL_SETUP();
<user defined code>
if (funcctx->call_cntr < funcctx->max_calls)
{
<user defined code>
<obtain result Datum>
SRF_RETURN_NEXT(funcctx, result);
}
else
SRF_RETURN_DONE(funcctx);
}
51
contrib/pg_buffercache
pg_buffercache – информация о shared
buffers в реальном времени
52
pg_buffercache--1.1.sql
CREATE FUNCTION pg_buffercache_pages()
RETURNS SETOF RECORD
AS 'MODULE_PATHNAME', 'pg_buffercache_pages'
LANGUAGE C;
CREATE VIEW pg_buffercache AS
SELECT P.* FROM pg_buffercache_pages() AS P
(bufferid integer, relfilenode oid,
reltablespace oid, reldatabase oid,
relforknumber int2, relblocknumber int8,
isdirty bool, usagecount int2,
pinning_backends int4);
53
pg_buffercache_pages.c
PG_FUNCTION_INFO_V1(pg_buffercache_pages);
Datum
pg_buffercache_pages(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
Datum result;
MemoryContext oldcontext;
BufferCachePagesContext *fctx; /*User function context.*/
TupleDesc tupledesc;
TupleDesc expected_tupledesc;
HeapTuple tuple;
/* Продолжение по ссылке pg_buffercache_pages */
54
Ещё примеры SRF
●
generate_series
●
contrib/pageinspect
55
Домашнее задание
●
Написать на hacking@postgrespro.ru, какими
расширениями вы часто пользуетесь и каких вам очень
не хватает.
●
Написать, используя SPI, расширение, которое на любое
изменение строки добавляет в зарезервированные
столбцы текущее время и имя пользователя.
●
Ревью amcheck (B-Tree integrity checking tool).
●
Написать расширение bufferinspect по аналогии с
pageinspect для страниц в разделяемой памяти. Можно
добавить дополнительные функции в pg_buffercache.
●
Расширение dirtyread, которое позволяет прочитать
(насколько возможно) битый файл из другой базы.
56
Продолжение следует...
В следующий раз:
– Обзор source tree
– Путь разных запросов от получения
текста до выдачи результата
www.postgrespro.ru
СПАСИБО ЗА ВНИМАНИЕ!
ВОПРОСЫ?
Hacking PostgreSQL
10.03.2016
hacking@postgrespro.ru

More Related Content

What's hot (20)

PDF
Беспроблемная эксплуатация PostgreSQL
Дмитрий Васильев
 
PDF
Call of Postgres: Advanced Operations (part 2)
Alexey Lesovsky
 
PDF
PostgreSQL on sas/ssd/nvme/nvdimm
Дмитрий Васильев
 
ODP
Scaling PostgreSQL
Дмитрий Васильев
 
PDF
Мониторинг ожиданий в PostgreSQL / Курбангалиев Ильдус (Postgres Professional)
Ontico
 
PDF
Семь тысяч Rps, один go
Badoo Development
 
PDF
Streaming replication in practice
Alexey Lesovsky
 
PDF
Hunting for a C++ package manager
corehard_by
 
PDF
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
Ontico
 
PDF
5 способов деплоя PHP-кода в условиях хайлоада / Юрий Насретдинов (Badoo)
Ontico
 
PDF
2014.10.15 Сергей Бурладян, Avito.ru
Nikolay Samokhvalov
 
PPTX
Быстрое развёртывание шаблонов и статики в Mail.ru, Николай Кондратов
Fuenteovejuna
 
PDF
"Деплой кода процедур" Мурат Кабилов (Avito)
AvitoTech
 
PDF
Девять кругов ада или PostgreSQL Vacuum / Алексей Лесовский (PostgreSQL-Consu...
Ontico
 
PDF
"Отказоустойчивый standby PostgreSQL (HAProxy + PgBouncer)" Виктор Ягофаров (...
AvitoTech
 
PDF
Отладка и устранение проблем в PostgreSQL Streaming Replication.
Alexey Lesovsky
 
PDF
Александр Крашенинников "Hadoop High Availability: опыт Badoo"
IT Event
 
PPTX
Чем заняться вечером, если я знаю сколько будет ++i + ++i / Андрей Бородин (Y...
Ontico
 
PDF
Реализация восстановления после аварий / Сергей Бурладян (Avito)
Ontico
 
PDF
От Make к Ansible
Ivan Grishaev
 
Беспроблемная эксплуатация PostgreSQL
Дмитрий Васильев
 
Call of Postgres: Advanced Operations (part 2)
Alexey Lesovsky
 
PostgreSQL on sas/ssd/nvme/nvdimm
Дмитрий Васильев
 
Мониторинг ожиданий в PostgreSQL / Курбангалиев Ильдус (Postgres Professional)
Ontico
 
Семь тысяч Rps, один go
Badoo Development
 
Streaming replication in practice
Alexey Lesovsky
 
Hunting for a C++ package manager
corehard_by
 
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
Ontico
 
5 способов деплоя PHP-кода в условиях хайлоада / Юрий Насретдинов (Badoo)
Ontico
 
2014.10.15 Сергей Бурладян, Avito.ru
Nikolay Samokhvalov
 
Быстрое развёртывание шаблонов и статики в Mail.ru, Николай Кондратов
Fuenteovejuna
 
"Деплой кода процедур" Мурат Кабилов (Avito)
AvitoTech
 
Девять кругов ада или PostgreSQL Vacuum / Алексей Лесовский (PostgreSQL-Consu...
Ontico
 
"Отказоустойчивый standby PostgreSQL (HAProxy + PgBouncer)" Виктор Ягофаров (...
AvitoTech
 
Отладка и устранение проблем в PostgreSQL Streaming Replication.
Alexey Lesovsky
 
Александр Крашенинников "Hadoop High Availability: опыт Badoo"
IT Event
 
Чем заняться вечером, если я знаю сколько будет ++i + ++i / Андрей Бородин (Y...
Ontico
 
Реализация восстановления после аварий / Сергей Бурладян (Avito)
Ontico
 
От Make к Ansible
Ivan Grishaev
 

Viewers also liked (20)

PDF
Useful PostgreSQL Extensions
EDB
 
PPT
SlideRocket
Olya Biloshevskaya
 
PPT
Тайм-менеджмент: основні принципи, міфи та способи планування часу
Olya Biloshevskaya
 
PPT
La desconcentración del poder en Venezuela
kareleympot
 
PPT
الصلاة
Asma Sousou
 
PDF
Prodvigator.bg
NetpeakBG
 
PPTX
Успешен SEO кейс в Ecommerce. Една история в родните условия.
NetpeakBG
 
PPTX
Google AdWords & SEO Together
NetpeakBG
 
PPTX
Как да разберем интересите на посетителите
NetpeakBG
 
PPTX
Тенденции в SEO през 2014
NetpeakBG
 
PDF
Biznes modeli pidpriyemstva
Olya Biloshevskaya
 
PPTX
SEO Работилница #1: семантика и Prodvigator.bg за анализ на ключови думи и ко...
NetpeakBG
 
PPT
English club (ec)
Sofa Mahmudah Ariyani
 
PPTX
profile diri
Sofa Mahmudah Ariyani
 
PDF
Инструменти Noindex и Nofollow
NetpeakBG
 
PDF
Въведения в дигиталния маркетинг и SEO в Софтуерния университет.
NetpeakBG
 
PPTX
Трафиково SEO — преход от позиции към трафик
NetpeakBG
 
PPTX
Как работи Prodvigator.bg
NetpeakBG
 
PPTX
Difference between animal cell and plant cell
aryanrs
 
PDF
Automation in seo. Tools and tricks
NetpeakBG
 
Useful PostgreSQL Extensions
EDB
 
SlideRocket
Olya Biloshevskaya
 
Тайм-менеджмент: основні принципи, міфи та способи планування часу
Olya Biloshevskaya
 
La desconcentración del poder en Venezuela
kareleympot
 
الصلاة
Asma Sousou
 
Prodvigator.bg
NetpeakBG
 
Успешен SEO кейс в Ecommerce. Една история в родните условия.
NetpeakBG
 
Google AdWords & SEO Together
NetpeakBG
 
Как да разберем интересите на посетителите
NetpeakBG
 
Тенденции в SEO през 2014
NetpeakBG
 
Biznes modeli pidpriyemstva
Olya Biloshevskaya
 
SEO Работилница #1: семантика и Prodvigator.bg за анализ на ключови думи и ко...
NetpeakBG
 
English club (ec)
Sofa Mahmudah Ariyani
 
profile diri
Sofa Mahmudah Ariyani
 
Инструменти Noindex и Nofollow
NetpeakBG
 
Въведения в дигиталния маркетинг и SEO в Софтуерния университет.
NetpeakBG
 
Трафиково SEO — преход от позиции към трафик
NetpeakBG
 
Как работи Prodvigator.bg
NetpeakBG
 
Difference between animal cell and plant cell
aryanrs
 
Automation in seo. Tools and tricks
NetpeakBG
 
Ad

Similar to Расширения для PostgreSQL (20)

PPT
SAMag2007 Conference: PostgreSQL 8.3 presentation
Nikolay Samokhvalov
 
PPT
Kleshnin A. PostGIS-open solution for spatial data-database
Anton Biatov
 
PPTX
DSLs in Lisp and Clojure
Vasil Remeniuk
 
PPTX
Взломать Web-сайт на ASP.NET? Сложно, но можно!
Vladimir Kochetkov
 
PDF
"Опыт внедрения автоматизации на PHP проектах (Docker, Gitlab CI)"
Artjoker
 
PDF
Расширяемость PostgreSQL для хакеров и архитекторов / Олег Бартунов, Александ...
Ontico
 
PPTX
Оптимизация трассирования с использованием Expression templates
Platonov Sergey
 
PPTX
Оптимизация трассирования с использованием Expression templates
Platonov Sergey
 
PPTX
OpenACC short review
Andrei Poliakov
 
ODP
Использование хранимых процедур в MySQL (Константин Осипов)
Ontico
 
PDF
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Yandex
 
PDF
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
Mail.ru Group
 
PDF
ITCrowd - Метапрограммирование
ITCrowd Almaty
 
PDF
Web осень 2013 лекция 6
Technopark
 
PDF
Как мы делаем модули PHP в Badoo – Антон Довгаль
Badoo Development
 
PDF
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Yandex
 
PPTX
Netmap (by luigi rizzo) простой и удобный opensource фреймворк для обработк...
Ontico
 
PDF
Лекция 2. Всё, что вы хотели знать о функциях в Python.
Roman Brovko
 
PDF
Инструментируй это
Roman Dvornov
 
PDF
20160303 Hacking PostgreSQL Тема 02 Сообщество PostgreSQL и инструменты разра...
Rais Charipov
 
SAMag2007 Conference: PostgreSQL 8.3 presentation
Nikolay Samokhvalov
 
Kleshnin A. PostGIS-open solution for spatial data-database
Anton Biatov
 
DSLs in Lisp and Clojure
Vasil Remeniuk
 
Взломать Web-сайт на ASP.NET? Сложно, но можно!
Vladimir Kochetkov
 
"Опыт внедрения автоматизации на PHP проектах (Docker, Gitlab CI)"
Artjoker
 
Расширяемость PostgreSQL для хакеров и архитекторов / Олег Бартунов, Александ...
Ontico
 
Оптимизация трассирования с использованием Expression templates
Platonov Sergey
 
Оптимизация трассирования с использованием Expression templates
Platonov Sergey
 
OpenACC short review
Andrei Poliakov
 
Использование хранимых процедур в MySQL (Константин Осипов)
Ontico
 
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Yandex
 
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
Mail.ru Group
 
ITCrowd - Метапрограммирование
ITCrowd Almaty
 
Web осень 2013 лекция 6
Technopark
 
Как мы делаем модули PHP в Badoo – Антон Довгаль
Badoo Development
 
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Yandex
 
Netmap (by luigi rizzo) простой и удобный opensource фреймворк для обработк...
Ontico
 
Лекция 2. Всё, что вы хотели знать о функциях в Python.
Roman Brovko
 
Инструментируй это
Roman Dvornov
 
20160303 Hacking PostgreSQL Тема 02 Сообщество PostgreSQL и инструменты разра...
Rais Charipov
 
Ad

More from Anastasia Lubennikova (6)

PDF
Advanced backup methods (Postgres@CERN)
Anastasia Lubennikova
 
PDF
PgconfSV compression
Anastasia Lubennikova
 
PDF
Btree. Explore the heart of PostgreSQL.
Anastasia Lubennikova
 
PDF
Page compression. PGCON_2016
Anastasia Lubennikova
 
PDF
Архитектура и новые возможности B-tree
Anastasia Lubennikova
 
PDF
Indexes don't mean slow inserts.
Anastasia Lubennikova
 
Advanced backup methods (Postgres@CERN)
Anastasia Lubennikova
 
PgconfSV compression
Anastasia Lubennikova
 
Btree. Explore the heart of PostgreSQL.
Anastasia Lubennikova
 
Page compression. PGCON_2016
Anastasia Lubennikova
 
Архитектура и новые возможности B-tree
Anastasia Lubennikova
 
Indexes don't mean slow inserts.
Anastasia Lubennikova
 

Расширения для PostgreSQL

  • 2. 2 Содержание 1. Расширение (contrib) 2. Новый тип данных 3. SPI (Server Programming Interface) 4. Особенности функций на Си 5. SRF (Set-Returning Function)
  • 3. 3 Расширение (contrib) ● Инфраструктура сборки PGXS ● PGXN (PostgreSQL Extension Network) ● PgFoundry ● Управляется каталогом pg_extension SELECT * FROM pg_extension; -[ RECORD 1 ]--+-------- extname | plpgsql extowner | 10 extnamespace | 11 extrelocatable | f extversion | 1.0 extconfig | extcondition |
  • 4. 4 Управление расширением CREATE EXTENSION [ IF NOT EXISTS ] extension_name [ WITH ] [ SCHEMA schema_name ] [ VERSION version ] [ FROM old_version ] DROP EXTENSION [ IF EXISTS ] extension_name [, ...] [ CASCADE | RESTRICT ] ALTER EXTENSION extension_name UPDATE [ TO new_version ] ALTER EXTENSION extension_name SET SCHEMA new_schema ALTER EXTENSION extension_name ADD member_object ALTER EXTENSION extension_name DROP member_object
  • 5. 5 Объекты в расширении AGGREGATE agg_name (agg_type [, ...] ) | CAST (source_type AS target_type) | COLLATION object_name | CONVERSION object_name | DOMAIN object_name | FOREIGN DATA WRAPPER object_name | FOREIGN TABLE object_name | FUNCTION function_name ( [ [ argmode ] [ argname ] argtype [, ...] ] ) | OPERATOR operator_name (left_type, right_type) | OPERATOR CLASS object_name USING index_method | OPERATOR FAMILY object_name USING index_method |
  • 6. 6 Объекты в расширении [ PROCEDURAL ] LANGUAGE object_name | SCHEMA object_name | SEQUENCE object_name | SERVER object_name | TABLE object_name | TEXT SEARCH CONFIGURATION object_name | TEXT SEARCH DICTIONARY object_name | TEXT SEARCH PARSER object_name | TEXT SEARCH TEMPLATE object_name | TYPE object_name | VIEW object_name
  • 7. 7 Из чего состоит расширение? pg_example.control – управляющий файл pg_example.c – исходный текст на C Makefile – файл для сборки с помощью GNU make pg_example--1.0.sql – SQL-скрипт, создающий объекты БД sql/pg_example.sql – регрессионные тесты data/example.data – данные для регрессионных тестов expected/pg_example.out – ожидаемые результаты README.txt
  • 8. 8 pg_example.control # pg_example extention comment = 'my first extension' default_version = '1.0' module_pathname = '$libdir/pg_example' relocatable = true directory #Каталог, содержащий файл(ы) SQL скриптов encoding #Кодировка набора символов, используемая файлами скриптов requires #Расширения, от которых зависит данное расширение superuser #Нужны ли права суперпользователя для установки/обновления расширения schema #Схема, в которую должно быть загружено расширение. Только для не relocatable
  • 9. 9 Makefile # pg_example/Makefile # Название собираемого .so файла MODULE_big = pg_example # Список .o файлов, из которых собирается .so OBJS = pg_example.o # Название расширения EXTENSION = pg_example DATA = pg_example—1.0.sql # Список тестов REGRESS = pg_example
  • 10. 10 Makefile (2) ifdef USE_PGXS # Если USE_PGXS установлено, то нужные для сборки файлы # PostgreSQL находятся с помощью утилиты pg_config PG_CONFIG = pg_config PGXS := $( shell $( PG_CONFIG ) --pgxs ) include $(PGXS) else # Если нет, то считается что расширение помещено в папку # contrib исходников PostgreSQL subdir = contrib/pg_example top_builddir = ../.. include $(top_builddir)/src/Makefile.global include $(top_srcdir)/contrib/contrib-global.mk endif
  • 11. 11 Содержание 1. Расширение (contrib) 2. Новый тип данных 3. SPI (Server Programming Interface) 4. Особенности функций на Си 5. SRF (Set-Returning Function)
  • 12. 12 pair Простейшая реализация типа данных пара key/value /* pg_example--1.0.sql */ CREATE TYPE pair AS ( k text, v text ); CREATE OR REPLACE FUNCTION pair(anyelement, anyelement) RETURNS pair LANGUAGE SQL AS 'SELECT ROW($1, $2)::pair'; CREATE OPERATOR ~> ( LEFTARG = anyelement, RIGHTARG = anyelement, PROCEDURE = pair );
  • 13. 13 pair CREATE EXTENSION pg_example; CREATE TABLE keyvalue(kv pair); INSERT INTO keyvalue VALUES ('key'::text~>'value'::text), ('foo'::text~>'bar'::text); SELECT * FROM keyvalue; SELECT (kv).k, (kv).v FROM keyvalue ORDER BY (kv).k; kv ------------- (key,value) (foo,bar) k | v -----+------- foo | bar key | value
  • 14. 14 contrib/hstore Реализация key/value типа данных. Предшественник json. Документация модуля hstore Презентация про hstore.
  • 15. 15 CREATE TYPE CREATE TYPE hstore ( INTERNALLENGTH = -1, INPUT = hstore_in, OUTPUT = hstore_out, RECEIVE = hstore_recv, SEND = hstore_send, STORAGE = extended ); pg_type ---------------+------------ typname | hstore typnamespace | 2200 typowner | 16384 typlen | -1 typbyval | f typinput | hstore_in typoutput | hstore_out typreceive | hstore_recv typsend | hstore_send typstorage | x (extended) .......
  • 16. 16 hstore_in CREATE FUNCTION hstore_in(cstring) RETURNS hstore AS '$libdir/hstore', 'hstore_in' LANGUAGE C STRICT IMMUTABLE; pg_proc ----------------+--------------- proname | hstore_in pronamespace | 2200 proowner | 16384 prolang | 13 procost | 1 prorows | 0 provariadic | 0 prorettype | 16385 (hstore) proargtypes | 2275 (cstring) prosrc | hstore_in probin | $libdir/hstore .......
  • 17. 17 Новый оператор CREATE OPERATOR -> ( LEFTARG = hstore, RIGHTARG = text, PROCEDURE = fetchval ); pg_operator -------------+------------ oprname | -> oprnamespace | 2200 oprowner | 16384 oprkind | b oprleft | 16385 (hstore) Oprright | 25 (text) oprresult | 25 oprcom | 0 oprnegate | 0 oprcode | fetchval
  • 18. 18 Функция для оператора CREATE FUNCTION fetchval(hstore,text) RETURNS text AS '$libdir/hstore', 'hstore_fetchval' LANGUAGE C STRICT IMMUTABLE; pg_proc ----------------+---------------- proname | fetchval pronamespace | 2200 proowner | 16384 prolang | 13 procost | 1 prosrc | hstore_fetchval probin | $libdir/hstore proconfig | proacl | .......
  • 19. 19 Индексная поддержка CREATE OPERATOR CLASS gist_hstore_ops DEFAULT FOR TYPE hstore USING gist AS OPERATOR 7 @> , OPERATOR 9 ?(hstore,text) , OPERATOR 10 ?|(hstore,text[]) , OPERATOR 11 ?&(hstore,text[]) , OPERATOR 13 @ , FUNCTION 1 ghstore_consistent (internal, hstore, smallint, oid, internal), FUNCTION 2 ghstore_union (internal, internal), FUNCTION 3 ghstore_compress (internal), FUNCTION 4 ghstore_decompress (internal), FUNCTION 5 ghstore_penalty (internal, internal, internal), FUNCTION 6 ghstore_picksplit (internal, internal), FUNCTION 7 ghstore_same (ghstore, ghstore, internal), STORAGE ghstore;
  • 21. 21 Содержание 1. Расширение (contrib) 2. Новый тип данных 3. SPI (Server Programming Interface) 4. Особенности функций на Си 5. SRF (Set-Returning Function)
  • 22. 22 SPI. Функции SPI - Server Programming Interface ● Процедурные языки (PL/pgSQL, PL/python, PL/perl, PL/R ...) ● API для расширений (pg_paxos api) ● Триггеры (contrib/spi)
  • 23. 23 SPI. Функции ● SPI_connect / SPI_finish ● SPI_push / SPI_pop ● SPI_execute / SPI_exec ● SPI_prepare ● SPI_execute_plan ● SPI_keepplan / SPI_saveplan
  • 24. 24 SPI. Функции (2) ● SPI_gettype / SPI_gettypeid ● SPI_getrelname / SPI_getnspnam ● SPI_copytuple ● SPI_returntuple ● SPI_modifytuple
  • 26. 26 SPI. Timetravel timetravel ('date_on', 'date_off' [,'insert_user', 'update_user', 'delete_user' ] ) set_timetravel(relname, on) get_timetravel(relename)
  • 27. 27 SPI. Timetravel CREATE EXTENSION timetravel; CREATE TABLE tttest( price_id int4, price_val int4, price_on abstime, price_off abstime); CREATE UNIQUE INDEX tttest_idx ON tttest (price_id,price_off); CREATE TRIGGER timetravel BEFORE INSERT OR DELETE OR UPDATE ON tttest FOR EACH ROW EXECUTE PROCEDURE timetravel (price_on, price_off);
  • 28. 28 SPI. Timetravel. INSERT INSERT INTO tttest VALUES (1, 1, NULL, NULL); INSERT INTO tttest(price_id, price_val)VALUES (2, 2); INSERT INTO tttest(price_id, price_val, price_off) VALUES (3, 3, 'infinity'); price_id | price_val | price_on | price_off ---------+-----------+------------------------+----------- 1 | 1 | 2016-03-07 17:59:46+03 | infinity 2 | 2 | 2016-03-07 18:00:09+03 | infinity 3 | 3 | 2016-03-07 18:00:32+03 | infinity
  • 29. 29 SPI. Timetravel. INSERT if (TRIGGER_FIRED_BY_INSERT(trigdata→tg_event)) isinsert = true; … if (isinsert) { oldtimeon = SPI_getbinval(trigtuple, tupdesc, attnum[a_time_on], &isnull); if (isnull) /* Установить в a_time_on * значение GetCurrentAbsoluteTime */ rettuple = SPI_modifytuple(rel, trigtuple, chnattrs, chattrs, newvals, newnulls); return PointerGetDatum(rettuple);
  • 30. 30 SPI. Timetravel. DELETE DELETE FROM tttest WHERE price_id = 1; price_id | price_val | price_on | price_off ----------+-----------+------------------------+------------------------ 2 | 2 | 2016-03-07 18:00:09+03 | infinity 3 | 3 | 2016-03-07 18:00:32+03 | infinity 1 | 1 | 2016-03-07 17:59:46+03 | 2016-03-07 18:04:16+03
  • 31. 31 SPI. Timetravel. UPDATE UPDATE tttest SET price_val = 30 WHERE price_id = 3; price_id | price_val | price_on | price_off ----------+-----------+------------------------+------------------------ 2 | 2 | 2016-03-07 18:00:09+03 | infinity 1 | 1 | 2016-03-07 17:59:46+03 | 2016-03-07 18:04:16+03 3 | 3 | 2016-03-07 18:00:32+03 | 2016-03-07 18:06:19+03 3 | 30 | 2016-03-07 18:06:19+03 | infinity
  • 32. 32 SPI. Timetravel. SELECT SELECT * FROM tttest WHERE price_off = 'infinity'; price_id | price_val | price_on | price_off ----------+-----------+------------------------+------------------------ 2 | 2 | 2016-03-07 18:00:09+03 | infinity 3 | 30 | 2016-03-07 18:06:19+03 | infinity
  • 33. 33 SPI. Timetravel. CHANGE DATE SELECT set_timetravel('tttest', 0); UPDATE tttest SET price_on = '01-Jan-1990 00:00:01' WHERE price_id = 3 AND price_off <> 'infinity'; SELECT set_timetrave l('tttest', 1); SELECT * FROM tttest WHERE price_id = 3 AND price_on <= '10-Jan-1990' AND price_off > '10-Jan-1990'; price_id | price_val | price_on | price_off ----------+-----------+------------------------+------------------------ 3 | 3 | 1990-01-01 00:00:01+03 | 2016-03-07 18:06:19+03
  • 36. 36 Содержание 1. Расширение (contrib) 2. Новый тип данных 3. SPI (Server Programming Interface) 4. Особенности функций на Си 5. SRF (Set-Returning Function)
  • 37. 37 Datum ● Datum – абстрактный тип данных в PostgreSQL ● Значения, которые помещаются в Datum, могут быть переданы по значению, остальные передаются по указателю. ● Аргументы функции и возвращаемые значения передаются как Datum. ● src/include/postgres.h ● src/include/utils/datum.h
  • 38. 38 Datum (2) typedef uintptr_t Datum; #define DatumGetPointer(X) ((Pointer) (X)) #define PointerGetDatum(X) ((Datum) (X)) #define DatumGetInt32(X) ((int32) GET_4_BYTES(X)) #define Int32GetDatum(X) ((Datum) SET_4_BYTES(X)) Size datumGetSize(Datum value, bool typByVal, int typLen); Datum datumCopy(Datum value, bool typByVal, int typLen); bool datumIsEqual(Datum value1, Datum value2, bool typByVal, int typLen);
  • 40. 40 PG_MODULE_MAGIC #include "fmgr.h" #ifdef PG_MODULE_MAGIC PG_MODULE_MAGIC; #endif void _PG_init(void) { /* Define custom GUC variables */ /* Install hooks */ } /* Source code */
  • 41. 41 Calling convention 1 /* Standard parameter list for fmgr-compatible functions */ #define PG_FUNCTION_ARGS FunctionCallInfo fcinfo /* Макросы для доступа к параметрам */ #define PG_GETARG_DATUM(n) (fcinfo->arg[n]) #define PG_GETARG_INT32(n) DatumGetInt32(PG_GETARG_DATUM(n)) #define PG_NARGS() (fcinfo->nargs) #define PG_ARGISNULL(n) (fcinfo->argnull[n]) /* Макросы для возврата параметров */ #define PG_RETURN_DATUM(x) return (x) #define PG_RETURN_VOID() return (Datum) 0 #define PG_RETURN_NULL()
  • 42. 42 Пример /* функция на Си */ PG_FUNCTION_INFO_V1(add_one) Datum add_one(PG_FUNCTION_ARGS) { int32 arg = PG_GETARG_INT32(0); PG_RETURN_INT32(arg + 1); } /* SQL объявление функции */ CREATE FUNCTION add_one(integer) RETURNS integer AS 'DIRECTORY/funcs', 'add_one' LANGUAGE C STRICT;
  • 43. 43 Работа с Tuple #include "funcapi.h" /* Узнать возвращаемый тип данных, * и, если он составной, получить TupleDesc */ TypeFuncClass get_call_result_type( FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc) TupleDesc BlessTupleDesc(TupleDesc tupdesc) HeapTuple heap_form_tuple( TupleDesc tupdesc, Datum *values, bool *isnull) HeapTupleGetDatum(HeapTuple tuple)
  • 45. 45 Содержание 1. Расширение (contrib) 2. Новый тип данных 3. SPI (Server Programming Interface) 4. Особенности функций на Си 5. SRF (Set-Returning Function)
  • 47. 47 SRF (Set Returning Functions) #Определить, что функция вызвана первый раз SRF_IS_FIRSTCALL() #Инициализировать FuncCallContext при первом вызове SRF_FIRSTCALL_INIT() #Очистить контекст при каждом последующем вызове SRF_PERCALL_SETUP() #Вернуть очередное значение функции SRF_RETURN_NEXT(funcctx, result) #Завершить выполнение SRF, сбросить контекст SRF_RETURN_DONE(funcctx)
  • 48. 48 SRF (1) Datum my_Set_Returning_Function(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; Datum result; MemoryContext oldcontext; <user defined declarations>
  • 49. 49 SRF (2) ... if (SRF_IS_FIRSTCALL()) { funcctx = SRF_FIRSTCALL_INIT(); /* switch context when allocating stuff * to be used in later calls */ oldcontext = MemoryContextSwitchTo( funcctx->multi_call_memory_ctx); <user defined code> <if returning composite> <build TupleDesc, and perhaps AttInMetaData> <endif returning composite> <user defined code> /* return to original context * when allocating transient memory */ MemoryContextSwitchTo(oldcontext); }
  • 50. 50 SRF (3) ... <user defined code> funcctx = SRF_PERCALL_SETUP(); <user defined code> if (funcctx->call_cntr < funcctx->max_calls) { <user defined code> <obtain result Datum> SRF_RETURN_NEXT(funcctx, result); } else SRF_RETURN_DONE(funcctx); }
  • 51. 51 contrib/pg_buffercache pg_buffercache – информация о shared buffers в реальном времени
  • 52. 52 pg_buffercache--1.1.sql CREATE FUNCTION pg_buffercache_pages() RETURNS SETOF RECORD AS 'MODULE_PATHNAME', 'pg_buffercache_pages' LANGUAGE C; CREATE VIEW pg_buffercache AS SELECT P.* FROM pg_buffercache_pages() AS P (bufferid integer, relfilenode oid, reltablespace oid, reldatabase oid, relforknumber int2, relblocknumber int8, isdirty bool, usagecount int2, pinning_backends int4);
  • 53. 53 pg_buffercache_pages.c PG_FUNCTION_INFO_V1(pg_buffercache_pages); Datum pg_buffercache_pages(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; Datum result; MemoryContext oldcontext; BufferCachePagesContext *fctx; /*User function context.*/ TupleDesc tupledesc; TupleDesc expected_tupledesc; HeapTuple tuple; /* Продолжение по ссылке pg_buffercache_pages */
  • 55. 55 Домашнее задание ● Написать на [email protected], какими расширениями вы часто пользуетесь и каких вам очень не хватает. ● Написать, используя SPI, расширение, которое на любое изменение строки добавляет в зарезервированные столбцы текущее время и имя пользователя. ● Ревью amcheck (B-Tree integrity checking tool). ● Написать расширение bufferinspect по аналогии с pageinspect для страниц в разделяемой памяти. Можно добавить дополнительные функции в pg_buffercache. ● Расширение dirtyread, которое позволяет прочитать (насколько возможно) битый файл из другой базы.
  • 56. 56 Продолжение следует... В следующий раз: – Обзор source tree – Путь разных запросов от получения текста до выдачи результата