Skip to content

Commit 6bcd9d8

Browse files
committed
[PGPRO-7880] Need to check relation Oid before locking
It need to do before relation locking: locking of invalid Oid causes an error on replica Tags: pg_pathman
1 parent 92f0734 commit 6bcd9d8

9 files changed

+43
-20
lines changed

expected/pathman_calamity.out

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ SELECT validate_relname(NULL);
320320
ERROR: relation should not be NULL
321321
/* check function validate_expression() */
322322
SELECT validate_expression(1::regclass, NULL); /* not ok */
323-
ERROR: relation "1" does not exist
323+
ERROR: identifier "1" must be normal Oid
324324
SELECT validate_expression(NULL::regclass, NULL); /* not ok */
325325
ERROR: 'relid' should not be NULL
326326
SELECT validate_expression('calamity.part_test', NULL); /* not ok */
@@ -426,19 +426,19 @@ SELECT build_sequence_name(NULL) IS NULL;
426426

427427
/* check function partition_table_concurrently() */
428428
SELECT partition_table_concurrently(1::REGCLASS); /* not ok */
429-
ERROR: relation "1" has no partitions
429+
ERROR: identifier "1" must be normal Oid
430430
SELECT partition_table_concurrently('pg_class', 0); /* not ok */
431431
ERROR: 'batch_size' should not be less than 1 or greater than 10000
432432
SELECT partition_table_concurrently('pg_class', 1, 1E-5); /* not ok */
433433
ERROR: 'sleep_time' should not be less than 0.5
434434
SELECT partition_table_concurrently('pg_class'); /* not ok */
435-
ERROR: relation "pg_class" has no partitions
435+
ERROR: identifier "1259" must be normal Oid
436436
/* check function stop_concurrent_part_task() */
437437
SELECT stop_concurrent_part_task(1::REGCLASS); /* not ok */
438438
ERROR: cannot find worker for relation "1"
439439
/* check function drop_range_partition_expand_next() */
440440
SELECT drop_range_partition_expand_next('pg_class'); /* not ok */
441-
ERROR: relation "pg_class" is not a partition
441+
ERROR: identifier "1259" must be normal Oid
442442
SELECT drop_range_partition_expand_next(NULL) IS NULL;
443443
?column?
444444
----------
@@ -560,7 +560,7 @@ DROP FUNCTION calamity.dummy_cb(arg jsonb);
560560
SELECT add_to_pathman_config(NULL, 'val'); /* no table */
561561
ERROR: 'parent_relid' should not be NULL
562562
SELECT add_to_pathman_config(0::REGCLASS, 'val'); /* no table (oid) */
563-
ERROR: relation "0" does not exist
563+
ERROR: identifier "0" must be normal Oid
564564
SELECT add_to_pathman_config('calamity.part_test', NULL); /* no expr */
565565
ERROR: 'expression' should not be NULL
566566
SELECT add_to_pathman_config('calamity.part_test', 'V_A_L'); /* wrong expr */

expected/pathman_calamity_1.out

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ SELECT validate_relname(NULL);
320320
ERROR: relation should not be NULL
321321
/* check function validate_expression() */
322322
SELECT validate_expression(1::regclass, NULL); /* not ok */
323-
ERROR: relation "1" does not exist
323+
ERROR: identifier "1" must be normal Oid
324324
SELECT validate_expression(NULL::regclass, NULL); /* not ok */
325325
ERROR: 'relid' should not be NULL
326326
SELECT validate_expression('calamity.part_test', NULL); /* not ok */
@@ -426,19 +426,19 @@ SELECT build_sequence_name(NULL) IS NULL;
426426

427427
/* check function partition_table_concurrently() */
428428
SELECT partition_table_concurrently(1::REGCLASS); /* not ok */
429-
ERROR: relation "1" has no partitions
429+
ERROR: identifier "1" must be normal Oid
430430
SELECT partition_table_concurrently('pg_class', 0); /* not ok */
431431
ERROR: 'batch_size' should not be less than 1 or greater than 10000
432432
SELECT partition_table_concurrently('pg_class', 1, 1E-5); /* not ok */
433433
ERROR: 'sleep_time' should not be less than 0.5
434434
SELECT partition_table_concurrently('pg_class'); /* not ok */
435-
ERROR: relation "pg_class" has no partitions
435+
ERROR: identifier "1259" must be normal Oid
436436
/* check function stop_concurrent_part_task() */
437437
SELECT stop_concurrent_part_task(1::REGCLASS); /* not ok */
438438
ERROR: cannot find worker for relation "1"
439439
/* check function drop_range_partition_expand_next() */
440440
SELECT drop_range_partition_expand_next('pg_class'); /* not ok */
441-
ERROR: relation "pg_class" is not a partition
441+
ERROR: identifier "1259" must be normal Oid
442442
SELECT drop_range_partition_expand_next(NULL) IS NULL;
443443
?column?
444444
----------
@@ -560,7 +560,7 @@ DROP FUNCTION calamity.dummy_cb(arg jsonb);
560560
SELECT add_to_pathman_config(NULL, 'val'); /* no table */
561561
ERROR: 'parent_relid' should not be NULL
562562
SELECT add_to_pathman_config(0::REGCLASS, 'val'); /* no table (oid) */
563-
ERROR: relation "0" does not exist
563+
ERROR: identifier "0" must be normal Oid
564564
SELECT add_to_pathman_config('calamity.part_test', NULL); /* no expr */
565565
ERROR: 'expression' should not be NULL
566566
SELECT add_to_pathman_config('calamity.part_test', 'V_A_L'); /* wrong expr */

expected/pathman_calamity_2.out

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ SELECT validate_relname(NULL);
320320
ERROR: relation should not be NULL
321321
/* check function validate_expression() */
322322
SELECT validate_expression(1::regclass, NULL); /* not ok */
323-
ERROR: relation "1" does not exist
323+
ERROR: identifier "1" must be normal Oid
324324
SELECT validate_expression(NULL::regclass, NULL); /* not ok */
325325
ERROR: 'relid' should not be NULL
326326
SELECT validate_expression('calamity.part_test', NULL); /* not ok */
@@ -426,19 +426,19 @@ SELECT build_sequence_name(NULL) IS NULL;
426426

427427
/* check function partition_table_concurrently() */
428428
SELECT partition_table_concurrently(1::REGCLASS); /* not ok */
429-
ERROR: relation "1" has no partitions
429+
ERROR: identifier "1" must be normal Oid
430430
SELECT partition_table_concurrently('pg_class', 0); /* not ok */
431431
ERROR: 'batch_size' should not be less than 1 or greater than 10000
432432
SELECT partition_table_concurrently('pg_class', 1, 1E-5); /* not ok */
433433
ERROR: 'sleep_time' should not be less than 0.5
434434
SELECT partition_table_concurrently('pg_class'); /* not ok */
435-
ERROR: relation "pg_class" has no partitions
435+
ERROR: identifier "1259" must be normal Oid
436436
/* check function stop_concurrent_part_task() */
437437
SELECT stop_concurrent_part_task(1::REGCLASS); /* not ok */
438438
ERROR: cannot find worker for relation "1"
439439
/* check function drop_range_partition_expand_next() */
440440
SELECT drop_range_partition_expand_next('pg_class'); /* not ok */
441-
ERROR: relation "pg_class" is not a partition
441+
ERROR: identifier "1259" must be normal Oid
442442
SELECT drop_range_partition_expand_next(NULL) IS NULL;
443443
?column?
444444
----------
@@ -560,7 +560,7 @@ DROP FUNCTION calamity.dummy_cb(arg jsonb);
560560
SELECT add_to_pathman_config(NULL, 'val'); /* no table */
561561
ERROR: 'parent_relid' should not be NULL
562562
SELECT add_to_pathman_config(0::REGCLASS, 'val'); /* no table (oid) */
563-
ERROR: relation "0" does not exist
563+
ERROR: identifier "0" must be normal Oid
564564
SELECT add_to_pathman_config('calamity.part_test', NULL); /* no expr */
565565
ERROR: 'expression' should not be NULL
566566
SELECT add_to_pathman_config('calamity.part_test', 'V_A_L'); /* wrong expr */

expected/pathman_calamity_3.out

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ SELECT validate_relname(NULL);
324324
ERROR: relation should not be NULL
325325
/* check function validate_expression() */
326326
SELECT validate_expression(1::regclass, NULL); /* not ok */
327-
ERROR: relation "1" does not exist
327+
ERROR: identifier "1" must be normal Oid
328328
SELECT validate_expression(NULL::regclass, NULL); /* not ok */
329329
ERROR: 'relid' should not be NULL
330330
SELECT validate_expression('calamity.part_test', NULL); /* not ok */
@@ -430,19 +430,19 @@ SELECT build_sequence_name(NULL) IS NULL;
430430

431431
/* check function partition_table_concurrently() */
432432
SELECT partition_table_concurrently(1::REGCLASS); /* not ok */
433-
ERROR: relation "1" has no partitions
433+
ERROR: identifier "1" must be normal Oid
434434
SELECT partition_table_concurrently('pg_class', 0); /* not ok */
435435
ERROR: 'batch_size' should not be less than 1 or greater than 10000
436436
SELECT partition_table_concurrently('pg_class', 1, 1E-5); /* not ok */
437437
ERROR: 'sleep_time' should not be less than 0.5
438438
SELECT partition_table_concurrently('pg_class'); /* not ok */
439-
ERROR: relation "pg_class" has no partitions
439+
ERROR: identifier "1259" must be normal Oid
440440
/* check function stop_concurrent_part_task() */
441441
SELECT stop_concurrent_part_task(1::REGCLASS); /* not ok */
442442
ERROR: cannot find worker for relation "1"
443443
/* check function drop_range_partition_expand_next() */
444444
SELECT drop_range_partition_expand_next('pg_class'); /* not ok */
445-
ERROR: relation "pg_class" is not a partition
445+
ERROR: identifier "1259" must be normal Oid
446446
SELECT drop_range_partition_expand_next(NULL) IS NULL;
447447
?column?
448448
----------
@@ -564,7 +564,7 @@ DROP FUNCTION calamity.dummy_cb(arg jsonb);
564564
SELECT add_to_pathman_config(NULL, 'val'); /* no table */
565565
ERROR: 'parent_relid' should not be NULL
566566
SELECT add_to_pathman_config(0::REGCLASS, 'val'); /* no table (oid) */
567-
ERROR: relation "0" does not exist
567+
ERROR: identifier "0" must be normal Oid
568568
SELECT add_to_pathman_config('calamity.part_test', NULL); /* no expr */
569569
ERROR: 'expression' should not be NULL
570570
SELECT add_to_pathman_config('calamity.part_test', 'V_A_L'); /* wrong expr */

src/include/utils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,5 +84,6 @@ Datum extract_binary_interval_from_text(Datum interval_text,
8484
Oid *interval_type);
8585
char **deconstruct_text_array(Datum array, int *array_size);
8686
RangeVar **qualified_relnames_to_rangevars(char **relnames, size_t nrelnames);
87+
void check_relation_oid(Oid relid);
8788

8889
#endif /* PATHMAN_UTILS_H */

src/pathman_workers.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,8 @@ partition_table_concurrently(PG_FUNCTION_ARGS)
712712
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
713713
errmsg("'sleep_time' should not be less than 0.5")));
714714

715+
check_relation_oid(relid);
716+
715717
/* Prevent concurrent function calls */
716718
LockRelationOid(relid, lockmode);
717719

src/pl_funcs.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,7 @@ validate_expression(PG_FUNCTION_ARGS)
673673
if (!PG_ARGISNULL(0))
674674
{
675675
relid = PG_GETARG_OID(0);
676+
check_relation_oid(relid);
676677
}
677678
else ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
678679
errmsg("'relid' should not be NULL")));
@@ -807,6 +808,7 @@ add_to_pathman_config(PG_FUNCTION_ARGS)
807808
if (!PG_ARGISNULL(0))
808809
{
809810
relid = PG_GETARG_OID(0);
811+
check_relation_oid(relid);
810812
}
811813
else ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
812814
errmsg("'parent_relid' should not be NULL")));
@@ -1037,6 +1039,8 @@ prevent_part_modification(PG_FUNCTION_ARGS)
10371039
{
10381040
Oid relid = PG_GETARG_OID(0);
10391041

1042+
check_relation_oid(relid);
1043+
10401044
/* Lock partitioned relation till transaction's end */
10411045
LockRelationOid(relid, ShareUpdateExclusiveLock);
10421046

@@ -1051,6 +1055,8 @@ prevent_data_modification(PG_FUNCTION_ARGS)
10511055
{
10521056
Oid relid = PG_GETARG_OID(0);
10531057

1058+
check_relation_oid(relid);
1059+
10541060
/*
10551061
* Check that isolation level is READ COMMITTED.
10561062
* Else we won't be able to see new rows

src/pl_range_funcs.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,7 @@ split_range_partition(PG_FUNCTION_ARGS)
499499
if (!PG_ARGISNULL(0))
500500
{
501501
partition1 = PG_GETARG_OID(0);
502+
check_relation_oid(partition1);
502503
}
503504
else ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
504505
errmsg("'partition1' should not be NULL")));
@@ -835,6 +836,8 @@ drop_range_partition_expand_next(PG_FUNCTION_ARGS)
835836
RangeEntry *ranges;
836837
int i;
837838

839+
check_relation_oid(partition);
840+
838841
/* Lock the partition we're going to drop */
839842
LockRelationOid(partition, AccessExclusiveLock);
840843

src/utils.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,3 +527,14 @@ qualified_relnames_to_rangevars(char **relnames, size_t nrelnames)
527527
return rangevars;
528528
}
529529

530+
/*
531+
* Checks that Oid is valid (it need to do before relation locking: locking of
532+
* invalid Oid causes an error on replica).
533+
*/
534+
void
535+
check_relation_oid(Oid relid)
536+
{
537+
if (relid < FirstNormalObjectId)
538+
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
539+
errmsg("identifier \"%u\" must be normal Oid", relid)));
540+
}

0 commit comments

Comments
 (0)