Skip to content

Commit 91a7769

Browse files
committed
* module renamed to pg_pathman
* tests added * minor fixes
1 parent 2f38bd2 commit 91a7769

14 files changed

+176
-64
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
*.o
22
*.so
3-
pathman--*.sql
3+
pg_pathman--*.sql

Makefile

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1-
# contrib/pathman/Makefile
1+
# contrib/pg_pathman/Makefile
22

3-
MODULE_big = pathman
4-
OBJS = init.o pathman.o dsm_array.o rangeset.o pl_funcs.o $(WIN32RES)
3+
MODULE_big = pg_pathman
4+
OBJS = init.o pg_pathman.o dsm_array.o rangeset.o pl_funcs.o $(WIN32RES)
55

6-
EXTENSION = pathman
6+
EXTENSION = pg_pathman
77
EXTVERSION = 0.1
88
DATA_built = $(EXTENSION)--$(EXTVERSION).sql
9-
PGFILEDESC = "pathman - partitioning tool"
9+
PGFILEDESC = "pg_pathman - partitioning tool"
1010

11-
REGRESS = pathman
11+
REGRESS = pg_pathman
1212
EXTRA_CLEAN = $(EXTENSION)--$(EXTVERSION).sql
1313

1414
ifdef USE_PGXS
1515
PG_CONFIG = pg_config
1616
PGXS := $(shell $(PG_CONFIG) --pgxs)
1717
include $(PGXS)
1818
else
19-
subdir = contrib/pathman
19+
subdir = contrib/pg_pathman
2020
top_builddir = ../..
2121
include $(top_builddir)/src/Makefile.global
2222
include $(top_srcdir)/contrib/contrib-global.mk

README.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
# pathman
1+
# pg_pathman
22

3-
The `pathman` module provides optimized partitioning mechanism and functions to manage partitions.
3+
The `pg_pathman` module provides optimized partitioning mechanism and functions to manage partitions.
44

5-
## pathman Concepts
5+
## pg_pathman Concepts
66

77
Partitioning refers to splitting one large table into smaller pieces. Each row in such table assigns to a single partition based on partitioning key. Common partitioning strategies are:
88

@@ -20,7 +20,7 @@ CREATE TABLE test_2 (CHECK ( id >= 200 AND id < 300 )) INHERITS (test);
2020

2121
Despite the flexibility of this approach it has weakness. If query uses filtering the optimizer forced to perform an exhaustive search and check constraints for each partition to determine partitions from which it should select data. If the number of partitions is large the overhead may be significant.
2222

23-
The `pathman` module provides functions to manage partitions and partitioning mechanism optimized based on knowledge of the partitions structure. It stores partitioning configuration in the `pathman_config` table, each row of which contains single entry for partitioned table (relation name, partitioning key and type). During initialization the `pathman` module caches information about child partitions in shared memory in form convenient to perform rapid search. When user executes SELECT query pathman analyzes conditions tree looking for conditions like:
23+
The `pg_pathman` module provides functions to manage partitions and partitioning mechanism optimized based on knowledge of the partitions structure. It stores partitioning configuration in the `pathman_config` table, each row of which contains single entry for partitioned table (relation name, partitioning key and type). During initialization the `pg_pathman` module caches information about child partitions in shared memory in form convenient to perform rapid search. When user executes SELECT query pg_pathman analyzes conditions tree looking for conditions like:
2424

2525
```
2626
VARIABLE OP CONST
@@ -31,25 +31,25 @@ where `VARIABLE` is partitioning key, `OP` is comparison operator (supported ope
3131
WHERE id = 150
3232
```
3333

34-
Based on partitioning type and operator the `pathman` searches corresponding partitions and builds the plan.
34+
Based on partitioning type and operator the `pg_pathman` searches corresponding partitions and builds the plan.
3535

3636
## Installation
3737

38-
To install pathman run in pathman directory:
38+
To install pg_pathman run in pg_pathman directory:
3939
```
4040
make install USE_PGXS=1
4141
```
4242
Modify shared_preload_libraries parameter in postgres.conf as following:
4343
```
44-
shared_preload_libraries = 'pathman'
44+
shared_preload_libraries = 'pg_pathman'
4545
```
4646
It will require to restart the PostgreSQL instance. Then execute following query in psql:
4747
```
4848
CREATE SCHEMA pathman;
49-
CREATE EXTENSION pathman SCHEMA pathman;
49+
CREATE EXTENSION pg_pathman SCHEMA pathman;
5050
```
5151

52-
## Pathman Functions
52+
## pg_pathman Functions
5353

5454
### Partitions Creation
5555
```
@@ -113,7 +113,7 @@ Prepends new partition with the range equal to the range of the first partition.
113113
```
114114
disable_partitioning(relation TEXT)
115115
```
116-
Disables `pathman` partitioning mechanism for the specified parent table and removes an insert trigger. Partitions itself remain unchanged.
116+
Disables `pg_pathman` partitioning mechanism for the specified parent table and removes an insert trigger. Partitions itself remain unchanged.
117117

118118
## Examples
119119
### HASH

README.rus.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
# pathman
1+
# pg_pathman
22

3-
Модуль `pathman` предоставляет оптимизированный механизм секционирования, а также функции для создания и управления секциями.
3+
Модуль `pg_pathman` предоставляет оптимизированный механизм секционирования, а также функции для создания и управления секциями.
44

5-
## Концепция pathman
5+
## Концепция pg_pathman
66

77
Секционирование -- это способ разбиения одной большой таблицы на множество меньших по размеру. Для каждой записи можно однозначно определить секцию, в которой она должна храниться посредством вычисления ключа. Традиционно выделяют три стратегии секционирования:
88

@@ -20,9 +20,9 @@ CREATE TABLE test_2 (CHECK ( id >= 200 AND id < 300 )) INHERITS (test);
2020

2121
Несмотря на гибкость, этот механизм обладает недостатками. Так при фильтрации данных оптимизатор вынужден перебирать все дочерние секции и сравнивать условие запроса с CHECK CONSTRAINT-ами секции, чтобы определить из каких секций ему следует загружать данные. При большом количестве секций это создает дополнительные накладные расходы, которые могут свести на нет выигрыш в производительности от применения секционирования.
2222

23-
Модуль `pathman` предоставляет функции для создания и управления
23+
Модуль `pg_pathman` предоставляет функции для создания и управления
2424
секциями (см. следующий раздел) и механизм секционирования,
25-
оптимизированный с учетом знания о структуре дочерних таблиц. Конфигурация сохраняется таблице `pathman_config`, каждая строка которой содержит запись для одной секционированной таблицы (название таблицы, атрибут и тип разбиения). В процессе инициализации модуля в разделяемую память сохраняется конфигурация дочерних таблиц в удобном для поиска формате. Получив запрос типа `SELECT` к секционированной таблице, `pathman` анализирует дерево условий запроса и выделяет из него условия вида:
25+
оптимизированный с учетом знания о структуре дочерних таблиц. Конфигурация сохраняется таблице `pathman_config`, каждая строка которой содержит запись для одной секционированной таблицы (название таблицы, атрибут и тип разбиения). В процессе инициализации модуля в разделяемую память сохраняется конфигурация дочерних таблиц в удобном для поиска формате. Получив запрос типа `SELECT` к секционированной таблице, `pg_pathman` анализирует дерево условий запроса и выделяет из него условия вида:
2626

2727
```
2828
ПЕРЕМЕННАЯ ОПЕРАТОР КОНСТАНТА
@@ -32,22 +32,22 @@ CREATE TABLE test_2 (CHECK ( id >= 200 AND id < 300 )) INHERITS (test);
3232
```
3333
WHERE id = 150
3434
```
35-
Затем основываясь на стратегии секционирования и условиях запроса `pathman` выбирает соответствующие секции и строит план.
35+
Затем основываясь на стратегии секционирования и условиях запроса `pg_pathman` выбирает соответствующие секции и строит план.
3636

3737
## Installation
3838

39-
Для установки pathman выполните в директории модуля команду:
39+
Для установки pg_pathman выполните в директории модуля команду:
4040
```
4141
make install USE_PGXS=1
4242
```
4343
Модифицируйте параметр shared_preload_libraries в конфигурационном файле postgres.conf:
4444
```
45-
shared_preload_libraries = 'pathman'
45+
shared_preload_libraries = 'pg_pathman'
4646
```
4747
Для вступления изменений в силу потребуется перезагрузка сервера PostgreSQL. Затем выполните в psql:
4848
```
4949
CREATE SCHEMA pathman;
50-
CREATE EXTENSION pathman SCHEMA pathman;
50+
CREATE EXTENSION pg_pathman SCHEMA pathman;
5151
```
5252

5353
## Функции pathman
@@ -114,7 +114,7 @@ prepend_partition(p_relation TEXT)
114114
```
115115
disable_partitioning(relation TEXT)
116116
```
117-
Отключает механизм секционирования `pathman` для заданной таблицы и удаляет триггер на вставку. При этом созданные ранее секции остаются без изменений.
117+
Отключает механизм секционирования `pg_pathman` для заданной таблицы и удаляет триггер на вставку. При этом созданные ранее секции остаются без изменений.
118118

119119
## Примеры использования
120120
### HASH

conf.add

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
shared_preload_libraries='pathman'
1+
shared_preload_libraries='pg_pathman'

expected/pathman.out renamed to expected/pg_pathman.out

Lines changed: 88 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
\set VERBOSITY terse
22
CREATE SCHEMA pathman;
3-
CREATE EXTENSION pathman SCHEMA pathman;
3+
CREATE EXTENSION pg_pathman SCHEMA pathman;
44
CREATE SCHEMA test;
55
CREATE TABLE test.hash_rel (
66
id SERIAL PRIMARY KEY,
@@ -17,6 +17,7 @@ CREATE TABLE test.range_rel (
1717
id SERIAL PRIMARY KEY,
1818
dt TIMESTAMP,
1919
txt TEXT);
20+
CREATE INDEX ON test.range_rel (dt);
2021
SELECT pathman.create_range_partitions('test.range_rel', 'dt', '2015-01-01'::DATE, '1 month'::INTERVAL, 3);
2122
NOTICE: sequence "range_rel_seq" does not exist, skipping
2223
create_range_partitions
@@ -34,14 +35,17 @@ NOTICE: sequence "num_range_rel_seq" does not exist, skipping
3435

3536
(1 row)
3637

37-
INSERT INTO test.num_range_rel SELECT g, md5(g::TEXT) FROM generate_series(1, 3000) as g;
38-
VACUUM;
38+
INSERT INTO test.num_range_rel
39+
SELECT g, md5(g::TEXT) FROM generate_series(1, 3000) as g;
40+
INSERT INTO test.range_rel (dt, txt)
41+
SELECT g, md5(g::TEXT) FROM generate_series('2015-01-01', '2015-04-30', '1 day'::interval) as g;
3942
INSERT INTO test.hash_rel VALUES (1, 1);
4043
INSERT INTO test.hash_rel VALUES (2, 2);
4144
INSERT INTO test.hash_rel VALUES (3, 3);
4245
INSERT INTO test.hash_rel VALUES (4, 4);
4346
INSERT INTO test.hash_rel VALUES (5, 5);
4447
INSERT INTO test.hash_rel VALUES (6, 6);
48+
VACUUM;
4549
/* update triggers test */
4650
SELECT pathman.create_hash_update_trigger('test.hash_rel');
4751
create_hash_update_trigger
@@ -155,6 +159,46 @@ EXPLAIN (COSTS OFF) SELECT * FROM test.num_range_rel WHERE (id >= 500 AND id < 1
155159
-> Seq Scan on num_range_rel_4
156160
(8 rows)
157161

162+
EXPLAIN (COSTS OFF) SELECT * FROM test.range_rel WHERE dt > '2015-02-15';
163+
QUERY PLAN
164+
--------------------------------------------------------------------------------
165+
Append
166+
-> Seq Scan on range_rel_2
167+
Filter: (dt > 'Sun Feb 15 00:00:00 2015'::timestamp without time zone)
168+
-> Seq Scan on range_rel_3
169+
-> Seq Scan on range_rel_4
170+
(5 rows)
171+
172+
EXPLAIN (COSTS OFF) SELECT * FROM test.range_rel WHERE dt >= '2015-02-01' AND dt < '2015-03-01';
173+
QUERY PLAN
174+
-------------------------------
175+
Append
176+
-> Seq Scan on range_rel_2
177+
(2 rows)
178+
179+
EXPLAIN (COSTS OFF) SELECT * FROM test.range_rel WHERE dt >= '2015-02-15' AND dt < '2015-03-15';
180+
QUERY PLAN
181+
---------------------------------------------------------------------------------
182+
Append
183+
-> Seq Scan on range_rel_2
184+
Filter: (dt >= 'Sun Feb 15 00:00:00 2015'::timestamp without time zone)
185+
-> Seq Scan on range_rel_3
186+
Filter: (dt < 'Sun Mar 15 00:00:00 2015'::timestamp without time zone)
187+
(5 rows)
188+
189+
EXPLAIN (COSTS OFF) SELECT * FROM test.range_rel WHERE (dt >= '2015-01-15' AND dt < '2015-02-15') OR (dt > '2015-03-15');
190+
QUERY PLAN
191+
---------------------------------------------------------------------------------
192+
Append
193+
-> Seq Scan on range_rel_1
194+
Filter: (dt >= 'Thu Jan 15 00:00:00 2015'::timestamp without time zone)
195+
-> Seq Scan on range_rel_2
196+
Filter: (dt < 'Sun Feb 15 00:00:00 2015'::timestamp without time zone)
197+
-> Seq Scan on range_rel_3
198+
Filter: (dt > 'Sun Mar 15 00:00:00 2015'::timestamp without time zone)
199+
-> Seq Scan on range_rel_4
200+
(8 rows)
201+
158202
SET enable_indexscan = ON;
159203
SET enable_bitmapscan = OFF;
160204
SET enable_seqscan = OFF;
@@ -225,6 +269,46 @@ EXPLAIN (COSTS OFF) SELECT * FROM test.num_range_rel WHERE (id >= 500 AND id < 1
225269
-> Seq Scan on num_range_rel_4
226270
(8 rows)
227271

272+
EXPLAIN (COSTS OFF) SELECT * FROM test.range_rel WHERE dt > '2015-02-15';
273+
QUERY PLAN
274+
------------------------------------------------------------------------------------
275+
Append
276+
-> Index Scan using range_rel_2_dt_idx on range_rel_2
277+
Index Cond: (dt > 'Sun Feb 15 00:00:00 2015'::timestamp without time zone)
278+
-> Seq Scan on range_rel_3
279+
-> Seq Scan on range_rel_4
280+
(5 rows)
281+
282+
EXPLAIN (COSTS OFF) SELECT * FROM test.range_rel WHERE dt >= '2015-02-01' AND dt < '2015-03-01';
283+
QUERY PLAN
284+
-------------------------------
285+
Append
286+
-> Seq Scan on range_rel_2
287+
(2 rows)
288+
289+
EXPLAIN (COSTS OFF) SELECT * FROM test.range_rel WHERE dt >= '2015-02-15' AND dt < '2015-03-15';
290+
QUERY PLAN
291+
-------------------------------------------------------------------------------------
292+
Append
293+
-> Index Scan using range_rel_2_dt_idx on range_rel_2
294+
Index Cond: (dt >= 'Sun Feb 15 00:00:00 2015'::timestamp without time zone)
295+
-> Index Scan using range_rel_3_dt_idx on range_rel_3
296+
Index Cond: (dt < 'Sun Mar 15 00:00:00 2015'::timestamp without time zone)
297+
(5 rows)
298+
299+
EXPLAIN (COSTS OFF) SELECT * FROM test.range_rel WHERE (dt >= '2015-01-15' AND dt < '2015-02-15') OR (dt > '2015-03-15');
300+
QUERY PLAN
301+
-------------------------------------------------------------------------------------
302+
Append
303+
-> Index Scan using range_rel_1_dt_idx on range_rel_1
304+
Index Cond: (dt >= 'Thu Jan 15 00:00:00 2015'::timestamp without time zone)
305+
-> Index Scan using range_rel_2_dt_idx on range_rel_2
306+
Index Cond: (dt < 'Sun Feb 15 00:00:00 2015'::timestamp without time zone)
307+
-> Index Scan using range_rel_3_dt_idx on range_rel_3
308+
Index Cond: (dt > 'Sun Mar 15 00:00:00 2015'::timestamp without time zone)
309+
-> Seq Scan on range_rel_4
310+
(8 rows)
311+
228312
/*
229313
* Test split and merge
230314
*/
@@ -340,4 +424,4 @@ SELECT pathman.drop_range_partitions('test.num_range_rel');
340424
(1 row)
341425

342426
DROP TABLE test.num_range_rel CASCADE;
343-
DROP EXTENSION pathman;
427+
DROP EXTENSION pg_pathman;

init.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ get_extension_schema()
4848
int ret;
4949
bool isnull;
5050

51-
ret = SPI_exec("SELECT extnamespace::regnamespace::text FROM pg_extension WHERE extname = 'pathman'", 0);
51+
ret = SPI_exec("SELECT extnamespace::regnamespace::text FROM pg_extension WHERE extname = 'pg_pathman'", 0);
5252
if (ret > 0 && SPI_tuptable != NULL && SPI_processed > 0)
5353
{
5454
TupleDesc tupdesc = SPI_tuptable->tupdesc;
@@ -78,10 +78,10 @@ load_relations_hashtable(bool reinitialize)
7878
ListCell *lc;
7979
char *schema;
8080
PartRelationInfo *prel;
81-
char sql[] = "SELECT pg_class.relfilenode, pg_attribute.attnum, pathman_config.parttype, pg_attribute.atttypid "
82-
"FROM %s.pathman_config "
83-
"JOIN pg_class ON pg_class.relfilenode = pathman_config.relname::regclass::oid "
84-
"JOIN pg_attribute ON pg_attribute.attname = pathman_config.attname "
81+
char sql[] = "SELECT pg_class.relfilenode, pg_attribute.attnum, cfg.parttype, pg_attribute.atttypid "
82+
"FROM %s.pathman_config as cfg "
83+
"JOIN pg_class ON pg_class.relfilenode = cfg.relname::regclass::oid "
84+
"JOIN pg_attribute ON pg_attribute.attname = cfg.attname "
8585
"AND attrelid = pg_class.relfilenode";
8686
char *query;
8787

@@ -288,16 +288,16 @@ load_check_constraints(Oid parent_oid)
288288
/* Copy oids to prel */
289289
for(i=0; i < proc; i++)
290290
children[i] = ranges[i].child_oid;
291-
}
292291

293-
/* Check if some ranges overlap */
294-
for(i=0; i < proc-1; i++)
295-
{
296-
if (ranges[i].max > ranges[i+1].min)
292+
/* Check if some ranges overlap */
293+
for(i=0; i < proc-1; i++)
297294
{
298-
elog(WARNING, "Partitions %u and %u overlap. Disabling pathman for relation %u...",
299-
ranges[i].child_oid, ranges[i+1].child_oid, parent_oid);
300-
hash_search(relations, (const void *) &parent_oid, HASH_REMOVE, &found);
295+
if (ranges[i].max > ranges[i+1].min)
296+
{
297+
elog(WARNING, "Partitions %u and %u overlap. Disabling pathman for relation %u...",
298+
ranges[i].child_oid, ranges[i+1].child_oid, parent_oid);
299+
hash_search(relations, (const void *) &parent_oid, HASH_REMOVE, &found);
300+
}
301301
}
302302
}
303303
}

pathman.control

Lines changed: 0 additions & 4 deletions
This file was deleted.

0 commit comments

Comments
 (0)