Skip to content

Commit 25c9246

Browse files
committed
pathman: check if new partition name is already exists
1 parent f6bb11c commit 25c9246

File tree

4 files changed

+52
-29
lines changed

4 files changed

+52
-29
lines changed

contrib/pg_pathman/pathman.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ RangeRelation *get_pathman_range_relation(Oid relid, bool *found);
182182
int range_binary_search(const RangeRelation *rangerel, FmgrInfo *cmp_func, Datum value, bool *fountPtr);
183183
char *get_extension_schema(void);
184184
FmgrInfo *get_cmp_func(Oid type1, Oid type2);
185-
Oid create_partitions_bg_worker(Oid relid, Datum value, Oid value_type);
186-
Oid create_partitions(Oid relid, Datum value, Oid value_type);
185+
Oid create_partitions_bg_worker(Oid relid, Datum value, Oid value_type, bool *crashed);
186+
Oid create_partitions(Oid relid, Datum value, Oid value_type, bool *crashed);
187187

188188
#endif /* PATHMAN_H */

contrib/pg_pathman/pl_funcs.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ find_or_create_range_partition(PG_FUNCTION_ARGS)
135135
PG_RETURN_NULL();
136136
else
137137
{
138-
Oid child_oid;
138+
Oid child_oid;
139+
bool crashed = false;
139140

140141
/* Lock config before appending new partitions */
141142
LWLockAcquire(pmstate->load_config_lock, LW_EXCLUSIVE);
@@ -156,16 +157,19 @@ find_or_create_range_partition(PG_FUNCTION_ARGS)
156157
}
157158

158159
/* Start background worker to create new partitions */
159-
child_oid = create_partitions_bg_worker(relid, value, value_type);
160+
child_oid = create_partitions_bg_worker(relid, value, value_type, &crashed);
160161

161162
// SPI_connect();
162-
// child_oid = create_partitions(relid, value, value_type);
163+
// child_oid = create_partitions(relid, value, value_type, &crashed);
163164
// SPI_finish();
164165
// elog(WARNING, "Worker finished");
165166

166167
/* Release locks */
167-
LWLockRelease(pmstate->edit_partitions_lock);
168-
LWLockRelease(pmstate->load_config_lock);
168+
if (!crashed)
169+
{
170+
LWLockRelease(pmstate->edit_partitions_lock);
171+
LWLockRelease(pmstate->load_config_lock);
172+
}
169173

170174
/* Repeat binary search */
171175
ranges = dsm_array_get_pointer(&rangerel->ranges);

contrib/pg_pathman/range.sql

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -385,17 +385,24 @@ DECLARE
385385

386386
v_part_num INT;
387387
v_sql TEXT;
388-
-- v_type TEXT;
389388
v_cond TEXT;
389+
v_child_relname_exists INTEGER := 1;
390390
BEGIN
391391
v_attname := attname FROM @extschema@.pathman_config
392392
WHERE relname = p_parent_relname;
393393

394394
/* get next value from sequence */
395-
v_part_num := nextval(format('%s_seq', p_parent_relname));
396-
v_child_relname := format('%s_%s'
397-
, p_parent_relname
398-
, v_part_num);
395+
LOOP
396+
v_part_num := nextval(format('%s_seq', p_parent_relname));
397+
v_child_relname := format('%s_%s'
398+
, p_parent_relname
399+
, v_part_num);
400+
v_child_relname_exists := count(*)
401+
FROM pg_class
402+
WHERE relnamespace::regnamespace || '.' || relname = v_child_relname
403+
LIMIT 1;
404+
EXIT WHEN v_child_relname_exists = 0;
405+
END LOOP;
399406
-- v_child_relname := format('%s_%s'
400407
-- , p_parent_relname
401408
-- , regexp_replace(p_start_value::text, '[ :-]*', '', 'g'));

contrib/pg_pathman/worker.c

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,34 +26,35 @@ static void bg_worker_main(Datum main_arg);
2626

2727
typedef struct PartitionArgs
2828
{
29-
Oid dbid;
30-
Oid relid;
29+
Oid dbid;
30+
Oid relid;
3131
#ifdef HAVE_INT64_TIMESTAMP
3232
int64 value;
3333
#else
3434
double value;
3535
#endif
36-
Oid value_type;
36+
Oid value_type;
3737
bool by_val;
38-
Oid result;
38+
Oid result;
39+
bool crashed;
3940
} PartitionArgs;
4041

4142
/*
4243
* Starts background worker that will create new partitions,
4344
* waits till it finishes the job and returns the result (new partition oid)
4445
*/
4546
Oid
46-
create_partitions_bg_worker(Oid relid, Datum value, Oid value_type)
47+
create_partitions_bg_worker(Oid relid, Datum value, Oid value_type, bool *crashed)
4748
{
4849
BackgroundWorker worker;
4950
BackgroundWorkerHandle *worker_handle;
5051
BgwHandleStatus status;
5152
dsm_segment *segment;
5253
dsm_handle segment_handle;
5354
pid_t pid;
54-
PartitionArgs *args;
55+
PartitionArgs *args;
5556
Oid child_oid;
56-
TypeCacheEntry *tce;
57+
TypeCacheEntry *tce;
5758

5859
/* Create a dsm segment for the worker to pass arguments */
5960
segment = dsm_create(sizeof(PartitionArgs), 0);
@@ -98,6 +99,7 @@ create_partitions_bg_worker(Oid relid, Datum value, Oid value_type)
9899

99100
/* Wait till the worker finishes its job */
100101
status = WaitForBackgroundWorkerShutdown(worker_handle);
102+
*crashed = args->crashed;
101103
child_oid = args->result;
102104

103105
/* Free dsm segment */
@@ -112,7 +114,7 @@ create_partitions_bg_worker(Oid relid, Datum value, Oid value_type)
112114
static void
113115
bg_worker_main(Datum main_arg)
114116
{
115-
PartitionArgs *args;
117+
PartitionArgs *args;
116118
dsm_handle handle = DatumGetInt32(main_arg);
117119

118120
/* Create resource owner */
@@ -134,7 +136,7 @@ bg_worker_main(Datum main_arg)
134136
PushActiveSnapshot(GetTransactionSnapshot());
135137

136138
/* Create partitions */
137-
args->result = create_partitions(args->relid, PATHMAN_GET_DATUM(args->value, args->by_val), args->value_type);
139+
args->result = create_partitions(args->relid, PATHMAN_GET_DATUM(args->value, args->by_val), args->value_type, &args->crashed);
138140

139141
/* Cleanup */
140142
SPI_finish();
@@ -148,7 +150,7 @@ bg_worker_main(Datum main_arg)
148150
* Create partitions and return an OID of the partition that contain value
149151
*/
150152
Oid
151-
create_partitions(Oid relid, Datum value, Oid value_type)
153+
create_partitions(Oid relid, Datum value, Oid value_type, bool *crashed)
152154
{
153155
int ret;
154156
RangeEntry *ranges;
@@ -163,6 +165,7 @@ create_partitions(Oid relid, Datum value, Oid value_type)
163165
FmgrInfo cmp_func;
164166
char *schema;
165167

168+
*crashed = false;
166169
schema = get_extension_schema();
167170

168171
prel = get_pathman_relation_info(relid, NULL);
@@ -178,16 +181,25 @@ create_partitions(Oid relid, Datum value, Oid value_type)
178181
/* Perform PL procedure */
179182
sql = psprintf("SELECT %s.append_partitions_on_demand_internal($1, $2)",
180183
schema);
181-
ret = SPI_execute_with_args(sql, 2, oids, vals, nulls, false, 0);
182-
if (ret > 0)
184+
PG_TRY();
183185
{
184-
/* Update relation info */
185-
free_dsm_array(&rangerel->ranges);
186-
free_dsm_array(&prel->children);
187-
load_check_constraints(relid, GetCatalogSnapshot(relid));
186+
ret = SPI_execute_with_args(sql, 2, oids, vals, nulls, false, 0);
187+
if (ret > 0)
188+
{
189+
/* Update relation info */
190+
free_dsm_array(&rangerel->ranges);
191+
free_dsm_array(&prel->children);
192+
load_check_constraints(relid, GetCatalogSnapshot(relid));
193+
}
188194
}
189-
else
195+
PG_CATCH();
196+
{
190197
elog(WARNING, "Attempt to create new partitions failed");
198+
if (crashed != NULL)
199+
*crashed = true;
200+
return 0;
201+
}
202+
PG_END_TRY();
191203

192204
/* Repeat binary search */
193205
ranges = dsm_array_get_pointer(&rangerel->ranges);

0 commit comments

Comments
 (0)