Skip to content

Commit 01e366b

Browse files
author
Alexander Korotkov
committed
Merge branch 'master' of github.com:postgrespro/pg_pathman
2 parents e86abbb + b1fb1e4 commit 01e366b

12 files changed

+1608
-1181
lines changed

dsm_array.c

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
/* ------------------------------------------------------------------------
2+
*
3+
* init.c
4+
* This module allocates large DSM segment to store arrays,
5+
* initializes it with block structure and provides functions to
6+
* allocate and free arrays
7+
*
8+
* Copyright (c) 2015-2016, Postgres Professional
9+
*
10+
* ------------------------------------------------------------------------
11+
*/
112
#include "pathman.h"
213
#include "storage/shmem.h"
314
#include "storage/dsm.h"
@@ -68,9 +79,6 @@ init_dsm_segment(size_t blocks_count, size_t block_size)
6879
{
6980
bool ret;
7081

71-
/* lock here */
72-
LWLockAcquire(dsm_init_lock, LW_EXCLUSIVE);
73-
7482
/* if there is already an existing segment then attach to it */
7583
if (dsm_cfg->segment_handle != 0)
7684
{
@@ -100,9 +108,6 @@ init_dsm_segment(size_t blocks_count, size_t block_size)
100108
*/
101109
dsm_pin_mapping(segment);
102110

103-
/* unlock here */
104-
LWLockRelease(dsm_init_lock);
105-
106111
return ret;
107112
}
108113

@@ -248,6 +253,32 @@ free_dsm_array(DsmArray *arr)
248253
arr->length = 0;
249254
}
250255

256+
void
257+
resize_dsm_array(DsmArray *arr, size_t entry_size, size_t length)
258+
{
259+
void *array_data;
260+
size_t array_data_size;
261+
void *buffer;
262+
263+
/* Copy data from array to temporary buffer */
264+
array_data = dsm_array_get_pointer(arr);
265+
array_data_size = arr->length * entry_size;
266+
buffer = palloc(array_data_size);
267+
memcpy(buffer, array_data, array_data_size);
268+
269+
/* Free array */
270+
free_dsm_array(arr);
271+
272+
/* Allocate new array */
273+
alloc_dsm_array(arr, entry_size, length);
274+
275+
/* Copy data to new array */
276+
array_data = dsm_array_get_pointer(arr);
277+
memcpy(array_data, buffer, array_data_size);
278+
279+
pfree(buffer);
280+
}
281+
251282
void *
252283
dsm_array_get_pointer(const DsmArray* arr)
253284
{

expected/pg_pathman.out

Lines changed: 119 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ CREATE SCHEMA pathman;
33
CREATE EXTENSION pg_pathman SCHEMA pathman;
44
CREATE SCHEMA test;
55
CREATE TABLE test.hash_rel (
6-
id SERIAL PRIMARY KEY,
7-
value INTEGER);
6+
id SERIAL PRIMARY KEY,
7+
value INTEGER);
88
INSERT INTO test.hash_rel VALUES (1, 1);
99
INSERT INTO test.hash_rel VALUES (2, 2);
1010
INSERT INTO test.hash_rel VALUES (3, 3);
@@ -48,9 +48,9 @@ SELECT COUNT(*) FROM ONLY test.hash_rel;
4848
(1 row)
4949

5050
CREATE TABLE test.range_rel (
51-
id SERIAL PRIMARY KEY,
52-
dt TIMESTAMP,
53-
txt TEXT);
51+
id SERIAL PRIMARY KEY,
52+
dt TIMESTAMP,
53+
txt TEXT);
5454
CREATE INDEX ON test.range_rel (dt);
5555
INSERT INTO test.range_rel (dt, txt)
5656
SELECT g, md5(g::TEXT) FROM generate_series('2015-01-01', '2015-04-30', '1 day'::interval) as g;
@@ -80,8 +80,8 @@ SELECT COUNT(*) FROM ONLY test.range_rel;
8080
(1 row)
8181

8282
CREATE TABLE test.num_range_rel (
83-
id SERIAL PRIMARY KEY,
84-
txt TEXT);
83+
id SERIAL PRIMARY KEY,
84+
txt TEXT);
8585
SELECT pathman.create_range_partitions('test.num_range_rel', 'id', 0, 1000, 4);
8686
NOTICE: sequence "num_range_rel_seq" does not exist, skipping
8787
NOTICE: Copying data to partitions...
@@ -103,7 +103,7 @@ SELECT COUNT(*) FROM ONLY test.num_range_rel;
103103
(1 row)
104104

105105
INSERT INTO test.num_range_rel
106-
SELECT g, md5(g::TEXT) FROM generate_series(1, 3000) as g;
106+
SELECT g, md5(g::TEXT) FROM generate_series(1, 3000) as g;
107107
SELECT COUNT(*) FROM test.num_range_rel;
108108
count
109109
-------
@@ -380,6 +380,34 @@ EXPLAIN (COSTS OFF) SELECT * FROM test.range_rel WHERE (dt >= '2015-01-15' AND d
380380
-> Seq Scan on range_rel_4
381381
(8 rows)
382382

383+
/*
384+
* Test CTE query
385+
*/
386+
EXPLAIN (COSTS OFF)
387+
WITH ttt AS (SELECT * FROM test.range_rel WHERE dt >= '2015-02-01' AND dt < '2015-03-15')
388+
SELECT * FROM ttt;
389+
QUERY PLAN
390+
--------------------------------------------------------------------------------------------
391+
CTE Scan on ttt
392+
CTE ttt
393+
-> Append
394+
-> Seq Scan on range_rel_2
395+
-> Index Scan using range_rel_3_dt_idx on range_rel_3
396+
Index Cond: (dt < 'Sun Mar 15 00:00:00 2015'::timestamp without time zone)
397+
(6 rows)
398+
399+
EXPLAIN (COSTS OFF)
400+
WITH ttt AS (SELECT * FROM test.hash_rel WHERE value = 2)
401+
SELECT * FROM ttt;
402+
QUERY PLAN
403+
--------------------------------------
404+
CTE Scan on ttt
405+
CTE ttt
406+
-> Append
407+
-> Seq Scan on hash_rel_2
408+
Filter: (value = 2)
409+
(5 rows)
410+
383411
/*
384412
* Test split and merge
385413
*/
@@ -560,6 +588,18 @@ EXPLAIN (COSTS OFF) SELECT * FROM test.range_rel WHERE dt BETWEEN '2014-11-15' A
560588
Index Cond: (dt <= 'Thu Jan 15 00:00:00 2015'::timestamp without time zone)
561589
(4 rows)
562590

591+
CREATE TABLE test.range_rel_test1 (
592+
id SERIAL PRIMARY KEY,
593+
dt TIMESTAMP,
594+
txt TEXT,
595+
abc INTEGER);
596+
SELECT pathman.attach_range_partition('test.range_rel', 'test.range_rel_test1', '2013-01-01'::DATE, '2014-01-01'::DATE);
597+
ERROR: Partition must have the exact same structure as parent P0001
598+
CREATE TABLE test.range_rel_test2 (
599+
id SERIAL PRIMARY KEY,
600+
dt TIMESTAMP);
601+
SELECT pathman.attach_range_partition('test.range_rel', 'test.range_rel_test2', '2013-01-01'::DATE, '2014-01-01'::DATE);
602+
ERROR: Partition must have the exact same structure as parent P0001
563603
/*
564604
* Clean up
565605
*/
@@ -620,8 +660,8 @@ DROP TABLE test.range_rel CASCADE;
620660
NOTICE: drop cascades to 7 other objects
621661
/* Test automatic partition creation */
622662
CREATE TABLE test.range_rel (
623-
id SERIAL PRIMARY KEY,
624-
dt TIMESTAMP NOT NULL);
663+
id SERIAL PRIMARY KEY,
664+
dt TIMESTAMP NOT NULL);
625665
SELECT pathman.create_range_partitions('test.range_rel', 'dt', '2015-01-01'::DATE, '10 days'::INTERVAL, 1);
626666
NOTICE: Copying data to partitions...
627667
create_range_partitions
@@ -670,8 +710,8 @@ SELECT * FROM pathman.pathman_config;
670710

671711
/* Check overlaps */
672712
CREATE TABLE test.num_range_rel (
673-
id SERIAL PRIMARY KEY,
674-
txt TEXT);
713+
id SERIAL PRIMARY KEY,
714+
txt TEXT);
675715
SELECT pathman.create_range_partitions('test.num_range_rel', 'id', 1000, 1000, 4);
676716
NOTICE: Copying data to partitions...
677717
create_range_partitions
@@ -726,8 +766,8 @@ DROP EXTENSION pg_pathman;
726766
CREATE EXTENSION pg_pathman;
727767
/* Hash */
728768
CREATE TABLE hash_rel (
729-
id SERIAL PRIMARY KEY,
730-
value INTEGER NOT NULL);
769+
id SERIAL PRIMARY KEY,
770+
value INTEGER NOT NULL);
731771
INSERT INTO hash_rel (value) SELECT g FROM generate_series(1, 10000) as g;
732772
SELECT create_hash_partitions('hash_rel', 'value', 3);
733773
NOTICE: function hash_rel_hash_insert_trigger_func() does not exist, skipping
@@ -752,9 +792,10 @@ EXPLAIN (COSTS OFF) SELECT * FROM hash_rel WHERE id = 1234;
752792

753793
/* Range */
754794
CREATE TABLE range_rel (
755-
id SERIAL PRIMARY KEY,
756-
dt TIMESTAMP NOT NULL);
757-
INSERT INTO range_rel (dt) SELECT g FROM generate_series('2010-01-01'::date, '2010-12-31'::date, '1 day') as g;
795+
id SERIAL PRIMARY KEY,
796+
dt TIMESTAMP NOT NULL,
797+
value INTEGER);
798+
INSERT INTO range_rel (dt, value) SELECT g, extract(day from g) FROM generate_series('2010-01-01'::date, '2010-12-31'::date, '1 day') as g;
758799
SELECT create_range_partitions('range_rel', 'dt', '2010-01-01'::date, '1 month'::interval, 12);
759800
NOTICE: sequence "range_rel_seq" does not exist, skipping
760801
NOTICE: Copying data to partitions...
@@ -817,6 +858,65 @@ EXPLAIN (COSTS OFF) SELECT * FROM range_rel WHERE dt > '2010-12-15';
817858
-> Seq Scan on range_rel_14
818859
(4 rows)
819860

861+
/* Temporary table for JOINs */
862+
CREATE TABLE tmp (id INTEGER NOT NULL, value INTEGER NOT NULL);
863+
INSERT INTO tmp VALUES (1, 1), (2, 2);
864+
/* Test UPDATE and DELETE */
865+
EXPLAIN (COSTS OFF) UPDATE range_rel SET value = 111 WHERE dt = '2010-06-15';
866+
QUERY PLAN
867+
--------------------------------------------------------------------------------
868+
Update on range_rel_6
869+
-> Seq Scan on range_rel_6
870+
Filter: (dt = 'Tue Jun 15 00:00:00 2010'::timestamp without time zone)
871+
(3 rows)
872+
873+
UPDATE range_rel SET value = 111 WHERE dt = '2010-06-15';
874+
SELECT * FROM range_rel WHERE dt = '2010-06-15';
875+
id | dt | value
876+
-----+--------------------------+-------
877+
166 | Tue Jun 15 00:00:00 2010 | 111
878+
(1 row)
879+
880+
EXPLAIN (COSTS OFF) DELETE FROM range_rel WHERE dt = '2010-06-15';
881+
QUERY PLAN
882+
--------------------------------------------------------------------------------
883+
Delete on range_rel_6
884+
-> Seq Scan on range_rel_6
885+
Filter: (dt = 'Tue Jun 15 00:00:00 2010'::timestamp without time zone)
886+
(3 rows)
887+
888+
DELETE FROM range_rel WHERE dt = '2010-06-15';
889+
SELECT * FROM range_rel WHERE dt = '2010-06-15';
890+
id | dt | value
891+
----+----+-------
892+
(0 rows)
893+
894+
EXPLAIN (COSTS OFF) UPDATE range_rel r SET value = t.value FROM tmp t WHERE r.dt = '2010-01-01' AND r.id = t.id;
895+
QUERY PLAN
896+
--------------------------------------------------------------------------------------------
897+
Update on range_rel_1 r
898+
-> Hash Join
899+
Hash Cond: (t.id = r.id)
900+
-> Seq Scan on tmp t
901+
-> Hash
902+
-> Index Scan using range_rel_1_pkey on range_rel_1 r
903+
Filter: (dt = 'Fri Jan 01 00:00:00 2010'::timestamp without time zone)
904+
(7 rows)
905+
906+
UPDATE range_rel r SET value = t.value FROM tmp t WHERE r.dt = '2010-01-01' AND r.id = t.id;
907+
EXPLAIN (COSTS OFF) DELETE FROM range_rel r USING tmp t WHERE r.dt = '2010-01-02' AND r.id = t.id;
908+
QUERY PLAN
909+
--------------------------------------------------------------------------------------------
910+
Delete on range_rel_1 r
911+
-> Hash Join
912+
Hash Cond: (t.id = r.id)
913+
-> Seq Scan on tmp t
914+
-> Hash
915+
-> Index Scan using range_rel_1_pkey on range_rel_1 r
916+
Filter: (dt = 'Sat Jan 02 00:00:00 2010'::timestamp without time zone)
917+
(7 rows)
918+
919+
DELETE FROM range_rel r USING tmp t WHERE r.dt = '2010-01-02' AND r.id = t.id;
820920
/* Create range partitions from whole range */
821921
SELECT drop_range_partitions('range_rel');
822922
NOTICE: 0 rows copied from range_rel_15
@@ -828,11 +928,11 @@ NOTICE: 31 rows copied from range_rel_10
828928
NOTICE: 30 rows copied from range_rel_9
829929
NOTICE: 31 rows copied from range_rel_8
830930
NOTICE: 31 rows copied from range_rel_7
831-
NOTICE: 30 rows copied from range_rel_6
931+
NOTICE: 29 rows copied from range_rel_6
832932
NOTICE: 31 rows copied from range_rel_5
833933
NOTICE: 30 rows copied from range_rel_4
834934
NOTICE: 31 rows copied from range_rel_3
835-
NOTICE: 45 rows copied from range_rel_1
935+
NOTICE: 44 rows copied from range_rel_1
836936
drop_range_partitions
837937
-----------------------
838938
14

0 commit comments

Comments
 (0)