check-table-not-used-when-create-partition-of-1.patch
text/plain
Filename: check-table-not-used-when-create-partition-of-1.patch
Type: text/plain
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/commands/tablecmds.c | 9 | 0 |
| src/test/regress/expected/create_table.out | 13 | 0 |
| src/test/regress/sql/create_table.sql | 11 | 0 |
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 3e112b4ef4..7b3d05d08b 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -1990,8 +1990,17 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
if (!is_partition)
relation = heap_openrv(parent, ShareUpdateExclusiveLock);
else
+ {
relation = heap_openrv(parent, AccessExclusiveLock);
+ /*
+ * Check for active uses of the relation in the current
+ * transaction, such as being used in some manner by an enclosing
+ * command, like by insert's tuple routing.
+ */
+ CheckTableNotInUse(relation, "CREATE TABLE PARTITION OF");
+ }
+
/*
* We do not allow partitioned tables and partitions to participate in
* regular inheritance.
diff --git a/src/test/regress/expected/create_table.out b/src/test/regress/expected/create_table.out
index 744b9990a6..ac806e9bf3 100644
--- a/src/test/regress/expected/create_table.out
+++ b/src/test/regress/expected/create_table.out
@@ -910,3 +910,16 @@ ERROR: cannot create a temporary relation as partition of permanent relation "p
create temp table temp_part partition of temp_parted default; -- ok
drop table perm_parted cascade;
drop table temp_parted cascade;
+-- check that adding partitions to a table while it is being used is prevented
+create table check_not_in_use (a int) partition by list (a);
+create function add_part_func () returns trigger language plpgsql as $$
+ begin
+ execute 'create table check_not_in_use1 partition of check_not_in_use default';
+ end $$;
+create trigger add_part_trig before insert on check_not_in_use
+ for each statement execute procedure add_part_func();
+insert into check_not_in_use values (1);
+ERROR: cannot CREATE TABLE PARTITION OF "check_not_in_use" because it is being used by active queries in this session
+CONTEXT: SQL statement "create table check_not_in_use1 partition of check_not_in_use default"
+PL/pgSQL function add_part_func() line 3 at EXECUTE
+drop table check_not_in_use;
diff --git a/src/test/regress/sql/create_table.sql b/src/test/regress/sql/create_table.sql
index 81fa7658b0..a34dd8f0e7 100644
--- a/src/test/regress/sql/create_table.sql
+++ b/src/test/regress/sql/create_table.sql
@@ -730,3 +730,14 @@ create temp table temp_part partition of perm_parted default; -- error
create temp table temp_part partition of temp_parted default; -- ok
drop table perm_parted cascade;
drop table temp_parted cascade;
+
+-- check that adding partitions to a table while it is being used is prevented
+create table check_not_in_use (a int) partition by list (a);
+create function add_part_func () returns trigger language plpgsql as $$
+ begin
+ execute 'create table check_not_in_use1 partition of check_not_in_use default';
+ end $$;
+create trigger add_part_trig before insert on check_not_in_use
+ for each statement execute procedure add_part_func();
+insert into check_not_in_use values (1);
+drop table check_not_in_use;