Skip to content

Commit 55639f9

Browse files
committed
Merge branch 'rel_future_beta' into rel_future_multilevel, conflicts solved
2 parents a4a506b + 63dccb6 commit 55639f9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

82 files changed

+9363
-2924
lines changed

.editorconfig

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[*]
2+
indent_style = tab
3+
indent_size = 4

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,5 @@ regression.out
1212
pg_pathman--*.sql
1313
tags
1414
cscope*
15+
Dockerfile
16+
testgres

.travis.yml

+18-15
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,28 @@
11
os:
2-
- linux
2+
- linux
33

44
sudo: required
55
dist: trusty
66

77
language: c
88

9-
compiler:
10-
- clang
11-
- gcc
9+
services:
10+
- docker
1211

13-
before_install:
14-
- sudo sh ./travis/apt.postgresql.org.sh
12+
install:
13+
- echo "FROM ${DOCKER_IMAGE}" > Dockerfile
14+
- docker-compose build
1515

16-
env:
17-
- PGVERSION=9.6 CHECK_CODE=true
18-
- PGVERSION=9.6 CHECK_CODE=false
19-
- PGVERSION=9.5 CHECK_CODE=true
20-
- PGVERSION=9.5 CHECK_CODE=false
21-
22-
script: bash ./travis/pg-travis-test.sh
16+
script:
17+
- docker-compose run $(bash <(curl -s https://codecov.io/env)) tests
2318

24-
after_success:
25-
- bash <(curl -s https://codecov.io/bash)
19+
env:
20+
- DOCKER_IMAGE=pathman/pg95_clang_check_code
21+
- DOCKER_IMAGE=pathman/pg95_cppcheck
22+
- DOCKER_IMAGE=pathman/pg95_pathman_tests
23+
- DOCKER_IMAGE=pathman/pg96_clang_check_code
24+
- DOCKER_IMAGE=pathman/pg96_cppcheck
25+
- DOCKER_IMAGE=pathman/pg96_pathman_tests
26+
- DOCKER_IMAGE=pathman/pg10_clang_check_code
27+
- DOCKER_IMAGE=pathman/pg10_cppcheck
28+
- DOCKER_IMAGE=pathman/pg10_pathman_tests

Dockerfile.tmpl

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
FROM postgres:${PG_VERSION}-alpine
2+
3+
ENV LANG=C.UTF-8 PGDATA=/pg/data
4+
5+
RUN if [ "${CHECK_CODE}" = "clang" ] ; then \
6+
echo 'http://dl-3.alpinelinux.org/alpine/edge/main' > /etc/apk/repositories; \
7+
apk --no-cache add clang-analyzer make musl-dev gcc; \
8+
fi
9+
10+
RUN if [ "${CHECK_CODE}" = "cppcheck" ] ; then \
11+
apk --no-cache add cppcheck --repository http://dl-cdn.alpinelinux.org/alpine/v3.6/community; \
12+
fi
13+
14+
RUN if [ "${CHECK_CODE}" = "false" ] ; then \
15+
echo 'http://dl-3.alpinelinux.org/alpine/edge/main' > /etc/apk/repositories; \
16+
apk --no-cache add curl python3 gcc make musl-dev cmocka-dev;\
17+
pip3 install virtualenv;\
18+
fi
19+
20+
RUN mkdir -p /pg/data && \
21+
mkdir /pg/pg_pathman && \
22+
chown postgres:postgres ${PGDATA} && \
23+
chmod a+rwx /usr/local/lib/postgresql && \
24+
chmod a+rwx /usr/local/share/postgresql/extension
25+
26+
ONBUILD ADD . /pg/pg_pathman
27+
ONBUILD WORKDIR /pg/pg_pathman
28+
ONBUILD RUN chmod -R go+rwX /pg/pg_pathman
29+
ONBUILD USER postgres
30+
ONBUILD ENTRYPOINT PGDATA=${PGDATA} CHECK_CODE=${CHECK_CODE} bash run_tests.sh

META.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "pg_pathman",
33
"abstract": "Partitioning tool",
44
"description": "The `pg_pathman` module provides optimized partitioning mechanism and functions to manage partitions.",
5-
"version": "1.3.2",
5+
"version": "1.4.1",
66
"maintainer": [
77
"Ildar Musin <i.musin@postgrespro.ru>",
88
"Dmitry Ivanov <d.ivanov@postgrespro.ru>",
@@ -22,9 +22,9 @@
2222
"generated_by": "Ildar Musin",
2323
"provides": {
2424
"pg_pathman": {
25-
"file": "pg_pathman--1.3.sql",
25+
"file": "pg_pathman--1.4.sql",
2626
"docfile": "README.md",
27-
"version": "1.3.2",
27+
"version": "1.4.1",
2828
"abstract": "Partitioning tool"
2929
}
3030
},

Makefile

+16-7
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,26 @@ OBJS = src/init.o src/relation_info.o src/utils.o src/partition_filter.o \
77
src/pl_funcs.o src/pl_range_funcs.o src/pl_hash_funcs.o src/pathman_workers.o \
88
src/hooks.o src/nodes_common.o src/xact_handling.o src/utility_stmt_hooking.o \
99
src/planner_tree_modification.o src/debug_print.o src/partition_creation.o \
10-
src/compat/pg_compat.o src/compat/relation_tags.o src/compat/expand_rte_hook.o \
11-
src/compat/rowmarks_fix.o $(WIN32RES)
10+
src/compat/pg_compat.o src/compat/relation_tags.o src/compat/rowmarks_fix.o \
11+
$(WIN32RES)
1212

13-
PG_CPPFLAGS = -I$(CURDIR)/src/include
13+
override PG_CPPFLAGS += -I$(CURDIR)/src/include
1414

1515
EXTENSION = pg_pathman
1616

17-
EXTVERSION = 1.4
17+
EXTVERSION = 1.5
1818

1919
DATA_built = pg_pathman--$(EXTVERSION).sql
2020

2121
DATA = pg_pathman--1.0--1.1.sql \
2222
pg_pathman--1.1--1.2.sql \
23-
pg_pathman--1.2--1.3.sql
23+
pg_pathman--1.2--1.3.sql \
24+
pg_pathman--1.3--1.4.sql
2425

2526
PGFILEDESC = "pg_pathman - partitioning tool for PostgreSQL"
2627

27-
REGRESS = pathman_basic \
28+
REGRESS = pathman_array_qual \
29+
pathman_basic \
2830
pathman_bgw \
2931
pathman_calamity \
3032
pathman_callbacks \
@@ -39,12 +41,13 @@ REGRESS = pathman_basic \
3941
pathman_lateral \
4042
pathman_mergejoin \
4143
pathman_only \
44+
pathman_param_upd_del \
4245
pathman_permissions \
46+
pathman_rebuild_updates \
4347
pathman_rowmarks \
4448
pathman_runtime_nodes \
4549
pathman_subpartitions \
4650
pathman_update_trigger \
47-
pathman_updates \
4851
pathman_utility_stmt
4952

5053

@@ -83,3 +86,9 @@ python_tests:
8386

8487
cmocka_tests:
8588
$(MAKE) -C tests/cmocka check
89+
90+
clean_gcov:
91+
find . \
92+
-name "*.gcda" -delete -o \
93+
-name "*.gcno" -delete -o \
94+
-name "*.gcov" -delete

README.md

+82-35
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@
77

88
The `pg_pathman` module provides optimized partitioning mechanism and functions to manage partitions.
99

10-
The extension is compatible with PostgreSQL 9.5+.
10+
The extension is compatible with:
11+
* PostgreSQL 9.5, 9.6, 10;
12+
* Postgres Pro Standard 9.5, 9.6;
13+
* Postgres Pro Enterprise;
14+
15+
By the way, we have a growing Wiki [out there](https://github.com/postgrespro/pg_pathman/wiki).
1116

1217
## Overview
1318
**Partitioning** means splitting one large table into smaller pieces. Each row in such table is moved to a single partition according to the partitioning key. PostgreSQL supports partitioning via table inheritance: each partition must be created as a child table with CHECK CONSTRAINT. For example:
@@ -41,6 +46,7 @@ More interesting features are yet to come. Stay tuned!
4146
## Feature highlights
4247

4348
* HASH and RANGE partitioning schemes;
49+
* Partitioning by expression and composite key;
4450
* Both automatic and manual partition management;
4551
* Support for integer, floating point, date and other types, including domains;
4652
* Effective query planning for partitioned tables (JOINs, subselects etc);
@@ -55,9 +61,11 @@ More interesting features are yet to come. Stay tuned!
5561
* Various GUC toggles and configurable settings.
5662

5763
## Roadmap
64+
65+
* Multi-level partitioning (ver 1.5);
66+
* Improved referential integrity + foreign keys on partitioned tables (ver 1.5);
5867

59-
* Implement LIST partitioning scheme;
60-
* Optimize hash join (both tables are partitioned by join key).
68+
Take a look at [this page](https://github.com/postgrespro/pg_pathman/wiki/Roadmap);
6169

6270
## Installation guide
6371
To install `pg_pathman`, execute this in the module's directory:
@@ -97,47 +105,49 @@ SET pg_pathman.enable = t;
97105
### Partition creation
98106
```plpgsql
99107
create_hash_partitions(relation REGCLASS,
100-
attribute TEXT,
108+
expr TEXT,
101109
partitions_count INTEGER,
102110
partition_data BOOLEAN DEFAULT TRUE,
103111
partition_names TEXT[] DEFAULT NULL,
104112
tablespaces TEXT[] DEFAULT NULL)
105113
```
106-
Performs HASH partitioning for `relation` by integer key `attribute`. The `partitions_count` parameter specifies the number of partitions to create; it cannot be changed afterwards. If `partition_data` is `true` then all the data will be automatically copied from the parent table to partitions. Note that data migration may took a while to finish and the table will be locked until transaction commits. See `partition_table_concurrently()` for a lock-free way to migrate data. Partition creation callback is invoked for each partition if set beforehand (see `set_init_callback()`).
114+
Performs HASH partitioning for `relation` by partitioning expression `expr`. The `partitions_count` parameter specifies the number of partitions to create; it cannot be changed afterwards. If `partition_data` is `true` then all the data will be automatically copied from the parent table to partitions. Note that data migration may took a while to finish and the table will be locked until transaction commits. See `partition_table_concurrently()` for a lock-free way to migrate data. Partition creation callback is invoked for each partition if set beforehand (see `set_init_callback()`).
107115

108116
```plpgsql
109-
create_range_partitions(relation REGCLASS,
110-
attribute TEXT,
111-
start_value ANYELEMENT,
112-
p_interval ANYELEMENT,
113-
p_count INTEGER DEFAULT NULL
114-
partition_data BOOLEAN DEFAULT TRUE)
117+
create_range_partitions(relation REGCLASS,
118+
expression TEXT,
119+
start_value ANYELEMENT,
120+
p_interval ANYELEMENT,
121+
p_count INTEGER DEFAULT NULL
122+
partition_data BOOLEAN DEFAULT TRUE)
123+
124+
create_range_partitions(relation REGCLASS,
125+
expression TEXT,
126+
start_value ANYELEMENT,
127+
p_interval INTERVAL,
128+
p_count INTEGER DEFAULT NULL,
129+
partition_data BOOLEAN DEFAULT TRUE)
115130

116-
create_range_partitions(relation REGCLASS,
117-
attribute TEXT,
118-
start_value ANYELEMENT,
119-
p_interval INTERVAL,
120-
p_count INTEGER DEFAULT NULL,
121-
partition_data BOOLEAN DEFAULT TRUE)
131+
create_range_partitions(relation REGCLASS,
132+
expression TEXT,
133+
bounds ANYARRAY,
134+
partition_names TEXT[] DEFAULT NULL,
135+
tablespaces TEXT[] DEFAULT NULL,
136+
partition_data BOOLEAN DEFAULT TRUE)
122137
```
123-
Performs RANGE partitioning for `relation` by partitioning key `attribute`, `start_value` argument specifies initial value, `p_interval` sets the default range for auto created partitions or partitions created with `append_range_partition()` or `prepend_range_partition()` (if `NULL` then auto partition creation feature won't work), `p_count` is the number of premade partitions (if not set then `pg_pathman` tries to determine it based on attribute values). Partition creation callback is invoked for each partition if set beforehand.
138+
Performs RANGE partitioning for `relation` by partitioning expression `expr`, `start_value` argument specifies initial value, `p_interval` sets the default range for auto created partitions or partitions created with `append_range_partition()` or `prepend_range_partition()` (if `NULL` then auto partition creation feature won't work), `p_count` is the number of premade partitions (if not set then `pg_pathman` tries to determine it based on expression's values). The `bounds` array can be built using `generate_range_bounds()`. Partition creation callback is invoked for each partition if set beforehand.
124139

125140
```plpgsql
126-
create_partitions_from_range(relation REGCLASS,
127-
attribute TEXT,
128-
start_value ANYELEMENT,
129-
end_value ANYELEMENT,
130-
p_interval ANYELEMENT,
131-
partition_data BOOLEAN DEFAULT TRUE)
141+
generate_range_bounds(p_start ANYELEMENT,
142+
p_interval INTERVAL,
143+
p_count INTEGER)
132144

133-
create_partitions_from_range(relation REGCLASS,
134-
attribute TEXT,
135-
start_value ANYELEMENT,
136-
end_value ANYELEMENT,
137-
p_interval INTERVAL,
138-
partition_data BOOLEAN DEFAULT TRUE)
145+
generate_range_bounds(p_start ANYELEMENT,
146+
p_interval ANYELEMENT,
147+
p_count INTEGER)
139148
```
140-
Performs RANGE-partitioning from specified range for `relation` by partitioning key `attribute`. Partition creation callback is invoked for each partition if set beforehand.
149+
Builds `bounds` array for `create_range_partitions()`.
150+
141151

142152
### Data migration
143153

@@ -157,7 +167,7 @@ Stops a background worker performing a concurrent partitioning task. Note: worke
157167
```plpgsql
158168
create_hash_update_trigger(parent REGCLASS)
159169
```
160-
Creates the trigger on UPDATE for HASH partitions. The UPDATE trigger isn't created by default because of the overhead. It's useful in cases when the key attribute might change.
170+
Creates the trigger on UPDATE for HASH partitions. The UPDATE trigger isn't created by default because of the overhead. It's useful in cases when the partitioning expression's value might change.
161171
```plpgsql
162172
create_range_update_trigger(parent REGCLASS)
163173
```
@@ -241,6 +251,25 @@ drop_partitions(parent REGCLASS,
241251
```
242252
Drop partitions of the `parent` table (both foreign and local relations). If `delete_data` is `false`, the data is copied to the parent table first. Default is `false`.
243253

254+
To remove partitioned table along with all partitions fully, use conventional
255+
`DROP TABLE relation CASCADE`. However, care should be taken in somewhat rare
256+
case when you are running logical replication and `DROP` was executed by
257+
replication apply worker, e.g. via trigger on replicated table. `pg_pathman`
258+
uses `pathman_ddl_trigger` event trigger to remove the record about dropped
259+
table from `pathman_config`, and this trigger by default won't fire on replica,
260+
leading to inconsistent state when `pg_pathman` thinks that the table still
261+
exists, but in fact it doesn't. If this is the case, configure this trigger to
262+
fire on replica too:
263+
264+
```plpgsql
265+
ALTER EVENT TRIGGER pathman_ddl_trigger ENABLE ALWAYS;
266+
```
267+
268+
Physical replication doesn't have this problem since DDL as well as
269+
`pathman_config` table is replicated too; master and slave PostgreSQL instances
270+
are basically identical, and it is only harmful to keep this trigger in `ALWAYS`
271+
mode.
272+
244273

245274
### Additional parameters
246275

@@ -297,9 +326,10 @@ When INSERTing new data beyond the partitioning range, use SpawnPartitionsWorker
297326
```plpgsql
298327
CREATE TABLE IF NOT EXISTS pathman_config (
299328
partrel REGCLASS NOT NULL PRIMARY KEY,
300-
attname TEXT NOT NULL,
329+
expr TEXT NOT NULL,
301330
parttype INTEGER NOT NULL,
302-
range_interval TEXT);
331+
range_interval TEXT,
332+
cooked_expr TEXT);
303333
```
304334
This table stores a list of partitioned tables.
305335

@@ -341,7 +371,7 @@ RETURNS TABLE (
341371
parent REGCLASS,
342372
partition REGCLASS,
343373
parttype INT4,
344-
partattr TEXT,
374+
expr TEXT,
345375
range_min TEXT,
346376
range_max TEXT)
347377
AS 'pg_pathman', 'show_partition_list_internal'
@@ -352,6 +382,23 @@ AS SELECT * FROM show_partition_list();
352382
```
353383
This view lists all existing partitions, as well as their parents and range boundaries (NULL for HASH partitions).
354384

385+
#### `pathman_cache_stats` --- per-backend memory consumption
386+
```plpgsql
387+
-- helper SRF function
388+
CREATE OR REPLACE FUNCTION @extschema@.show_cache_stats()
389+
RETURNS TABLE (
390+
context TEXT,
391+
size INT8,
392+
used INT8,
393+
entries INT8)
394+
AS 'pg_pathman', 'show_cache_stats_internal'
395+
LANGUAGE C STRICT;
396+
397+
CREATE OR REPLACE VIEW @extschema@.pathman_cache_stats
398+
AS SELECT * FROM @extschema@.show_cache_stats();
399+
```
400+
Shows memory consumption of various caches.
401+
355402

356403
## Custom plan nodes
357404
`pg_pathman` provides a couple of [custom plan nodes](https://wiki.postgresql.org/wiki/CustomScanAPI) which aim to reduce execution time, namely:

docker-compose.yml

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
tests:
2+
build: .

0 commit comments

Comments
 (0)