Skip to content

Commit 813e6d8

Browse files
committed
pathman: additional checks to prevent table partitioning in case when partitions count doesnt enough to hold all data (not finished)
1 parent 2eaa019 commit 813e6d8

File tree

6 files changed

+112
-12
lines changed

6 files changed

+112
-12
lines changed

contrib/pg_pathman/init.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ load_config(void)
5555
new_segment_created = init_dsm_segment(INITIAL_BLOCKS_COUNT, 32);
5656

5757
/* if config is not loaded */
58-
if (shmem_cfg && shmem_cfg->config_loaded)
58+
if (shmem_cfg && !shmem_cfg->config_loaded)
5959
{
6060
LWLockAcquire(load_config_lock, LW_EXCLUSIVE);
6161
load_relations_hashtable(new_segment_created);

contrib/pg_pathman/init.sql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ BEGIN
6767
-- RAISE NOTICE '% rows have been copied', p_total;
6868
RETURN;
6969

70-
EXCEPTION WHEN others THEN
71-
PERFORM on_remove_partitions(p_parent::regclass::integer);
72-
RAISE EXCEPTION '% %', SQLERRM, SQLSTATE;
70+
-- EXCEPTION WHEN others THEN
71+
-- PERFORM on_remove_partitions(p_parent::regclass::integer);
72+
-- RAISE EXCEPTION '% %', SQLERRM, SQLSTATE;
7373
END
7474
$$
7575
LANGUAGE plpgsql;

contrib/pg_pathman/pathman.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,5 +161,6 @@ int range_binary_search(const RangeRelation *rangerel, FmgrInfo *cmp_func, Datum
161161
char *get_extension_schema(void);
162162
FmgrInfo *get_cmp_func(Oid type1, Oid type2);
163163
Oid create_partitions_bg_worker(Oid relid, Datum value, Oid value_type);
164+
Oid create_partitions(Oid relid, Datum value, Oid value_type);
164165

165166
#endif /* PATHMAN_H */

contrib/pg_pathman/pl_funcs.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#include "access/nbtree.h"
77
#include "access/xact.h"
88
#include "catalog/pg_type.h"
9-
// #include "executor/spi.h"
9+
#include "executor/spi.h"
1010
#include "storage/lmgr.h"
1111

1212

@@ -136,7 +136,14 @@ find_or_create_range_partition(PG_FUNCTION_ARGS)
136136
}
137137

138138
/* Start background worker to create new partitions */
139+
elog(WARNING, "Starting worker");
139140
child_oid = create_partitions_bg_worker(relid, value, value_type);
141+
elog(WARNING, "BACKEND PID >>>%d<<<", MyProcPid);
142+
// sleep(10);
143+
// SPI_connect();
144+
// child_oid = create_partitions(relid, value, value_type);
145+
// SPI_finish();
146+
// elog(WARNING, "Worker finished");
140147

141148
/* Release lock */
142149
LWLockRelease(load_config_lock);

contrib/pg_pathman/range.sql

Lines changed: 92 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ $$
1414
DECLARE
1515
v_value TEXT;
1616
i INTEGER;
17+
sql TEXT;
1718
BEGIN
1819
p_relation := @extschema@.validate_relname(p_relation);
1920

@@ -28,6 +29,22 @@ BEGIN
2829
EXECUTE format('DROP SEQUENCE IF EXISTS %s_seq', p_relation);
2930
EXECUTE format('CREATE SEQUENCE %s_seq START 1', p_relation);
3031

32+
/* check boundaries */
33+
sql := format('SELECT @extschema@.check_boundaries(''%s'', ''%s'', ''%s'', ''%s''::%s)'
34+
, p_relation
35+
, p_attribute
36+
, p_start_value
37+
, p_start_value + p_interval*p_count
38+
, pg_typeof(p_start_value));
39+
RAISE NOTICE 'sql: %', sql;
40+
41+
EXECUTE format('SELECT @extschema@.check_boundaries(''%s'', ''%s'', ''%s'', ''%s''::%s)'
42+
, p_relation
43+
, p_attribute
44+
, p_start_value
45+
, p_start_value + p_interval*p_count
46+
, pg_typeof(p_start_value));
47+
3148
INSERT INTO @extschema@.pathman_config (relname, attname, parttype)
3249
VALUES (p_relation, p_attribute, 2);
3350

@@ -81,6 +98,12 @@ BEGIN
8198
EXECUTE format('DROP SEQUENCE IF EXISTS %s_seq', p_relation);
8299
EXECUTE format('CREATE SEQUENCE %s_seq START 1', p_relation);
83100

101+
/* check boundaries */
102+
PERFORM @extschema@.check_boundaries(p_relation
103+
, p_attribute
104+
, p_start_value
105+
, p_start_value + p_interval*p_count);
106+
84107
INSERT INTO @extschema@.pathman_config (relname, attname, parttype)
85108
VALUES (p_relation, p_attribute, 2);
86109

@@ -103,6 +126,11 @@ BEGIN
103126
PERFORM @extschema@.partition_data(p_relation);
104127

105128
RETURN p_count;
129+
130+
EXCEPTION WHEN others THEN
131+
EXECUTE format('DROP TABLE %s CASCADE', p_relation);
132+
PERFORM on_remove_partitions(p_relation::regclass::integer);
133+
RAISE EXCEPTION '% %', SQLERRM, SQLSTATE;
106134
END
107135
$$ LANGUAGE plpgsql;
108136

@@ -138,6 +166,12 @@ BEGIN
138166
EXECUTE format('DROP SEQUENCE IF EXISTS %s_seq', p_relation);
139167
EXECUTE format('CREATE SEQUENCE %s_seq START 1', p_relation);
140168

169+
/* check boundaries */
170+
PERFORM @extschema@.check_boundaries(p_relation
171+
, p_attribute
172+
, p_start_value
173+
, p_end_value);
174+
141175
INSERT INTO @extschema@.pathman_config (relname, attname, parttype)
142176
VALUES (p_relation, p_attribute, 2);
143177

@@ -157,7 +191,7 @@ BEGIN
157191
PERFORM @extschema@.on_create_partitions(p_relation::regclass::oid);
158192

159193
/* Copy data */
160-
PERFORM @extschema@.partition_data(p_relation);
194+
-- PERFORM @extschema@.partition_data(p_relation);
161195

162196
RETURN i;
163197
END
@@ -191,6 +225,12 @@ BEGIN
191225
EXECUTE format('DROP SEQUENCE IF EXISTS %s_seq', p_relation);
192226
EXECUTE format('CREATE SEQUENCE %s_seq START 1', p_relation);
193227

228+
/* check boundaries */
229+
PERFORM @extschema@.check_boundaries(p_relation
230+
, p_attribute
231+
, p_start_value
232+
, p_end_value);
233+
194234
INSERT INTO @extschema@.pathman_config (relname, attname, parttype)
195235
VALUES (p_relation, p_attribute, 2);
196236

@@ -209,12 +249,54 @@ BEGIN
209249
PERFORM @extschema@.on_create_partitions(p_relation::regclass::oid);
210250

211251
/* Copy data */
212-
PERFORM @extschema@.partition_data(p_relation);
252+
-- PERFORM @extschema@.partition_data(p_relation);
213253

214254
RETURN i;
215255
END
216256
$$ LANGUAGE plpgsql;
217257

258+
/*
259+
*
260+
*/
261+
CREATE OR REPLACE FUNCTION @extschema@.check_boundaries(
262+
p_relname TEXT
263+
, p_attribute TEXT
264+
, p_start_value ANYELEMENT
265+
, p_end_value ANYELEMENT)
266+
RETURNS VOID AS
267+
$$
268+
DECLARE
269+
v_min p_start_value%TYPE;
270+
v_max p_start_value%TYPE;
271+
v_count INTEGER;
272+
BEGIN
273+
RAISE NOTICE 'check_boundaries(%)', p_relname;
274+
/* Get min and max values */
275+
EXECUTE format('SELECT count(*), min(%s), max(%s) FROM %s WHERE NOT %s IS NULL',
276+
p_attribute, p_attribute, p_relname, p_attribute)
277+
INTO v_count, v_min, v_max;
278+
279+
RAISE NOTICE '>>> MIN, MAX <<< %, %, %', v_count, v_min, v_max;
280+
281+
/* check if column has NULL values */
282+
IF v_count > 0 AND (v_min IS NULL OR v_max IS NULL) THEN
283+
RAISE EXCEPTION '''%'' column has NULL values', p_attribute;
284+
END IF;
285+
286+
/* check lower boundary */
287+
IF p_start_value < v_min THEN
288+
RAISE EXCEPTION 'Start value is less than minimum value of ''%'''
289+
, p_attribute;
290+
END IF;
291+
292+
/* check upper boundary */
293+
IF p_end_value >= v_max THEN
294+
RAISE EXCEPTION 'End value is greater than maximum value of ''%'''
295+
, p_attribute;
296+
END IF;
297+
END
298+
$$ LANGUAGE plpgsql;
299+
218300
/*
219301
* Formats range condition. Utility function.
220302
*/
@@ -271,7 +353,12 @@ BEGIN
271353

272354
/* get next value from sequence */
273355
v_part_num := nextval(format('%s_seq', p_parent_relname));
274-
v_child_relname := format('%s_%s', p_parent_relname, v_part_num);
356+
v_child_relname := format('%s_%s'
357+
, p_parent_relname
358+
, v_part_num);
359+
-- v_child_relname := format('%s_%s'
360+
-- , p_parent_relname
361+
-- , regexp_replace(p_start_value::text, '[ :-]*', '', 'g'));
275362

276363
/* Skip existing partitions */
277364
IF EXISTS (SELECT * FROM pg_tables WHERE tablename = v_child_relname) THEN
@@ -775,7 +862,7 @@ DECLARE
775862
v_part TEXT;
776863
BEGIN
777864
IF p_new_value >= p_max THEN
778-
WHILE (p_max + i * (p_max - p_min)) <= p_new_value OR i > 1000
865+
WHILE (p_max + i * (p_max - p_min)) <= p_new_value AND i < 1000
779866
LOOP
780867
v_part := @extschema@.create_single_range_partition(
781868
@extschema@.get_schema_qualified_name(p_relid::regclass, '.')
@@ -786,7 +873,7 @@ BEGIN
786873
END LOOP;
787874
ELSIF p_new_value <= p_min THEN
788875

789-
WHILE (p_min - i * (p_max - p_min)) >= p_new_value OR i > 1000
876+
WHILE (p_min - i * (p_max - p_min)) >= p_new_value AND i < 1000
790877
LOOP
791878
v_part := @extschema@.create_single_range_partition(
792879
@extschema@.get_schema_qualified_name(p_relid::regclass, '.')

contrib/pg_pathman/worker.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
static dsm_segment *segment;
2323

2424
static void bg_worker_main(Datum main_arg);
25-
static Oid create_partitions(Oid relid, Datum value, Oid value_type);
25+
// static Oid create_partitions(Oid relid, Datum value, Oid value_type);
2626

2727
typedef struct PartitionArgs
2828
{
@@ -102,6 +102,8 @@ bg_worker_main(Datum main_arg)
102102
PartitionArgs *args;
103103
dsm_handle handle = DatumGetInt32(main_arg);
104104

105+
elog(WARNING, "Worker started. Handle %d", handle);
106+
105107
/* Create resource owner */
106108
CurrentResourceOwner = ResourceOwnerCreate(NULL, "CreatePartitionsWorker");
107109

@@ -134,7 +136,7 @@ bg_worker_main(Datum main_arg)
134136
/*
135137
* Create partitions and return an OID of the partition that contain value
136138
*/
137-
static Oid
139+
Oid
138140
create_partitions(Oid relid, Datum value, Oid value_type)
139141
{
140142
int ret;
@@ -153,6 +155,9 @@ create_partitions(Oid relid, Datum value, Oid value_type)
153155
FmgrInfo cmp_func;
154156
char *schema;
155157

158+
// elog(WARNING, "WORKER PID >>>%d<<<", MyProcPid);
159+
// sleep(10);
160+
156161
schema = get_extension_schema();
157162

158163
prel = get_pathman_relation_info(relid, NULL);

0 commit comments

Comments
 (0)