From 37c97e6b9879b130a80305fd794a9e721332cb98 Mon Sep 17 00:00:00 2001 From: amit Date: Fri, 2 Nov 2018 15:26:37 +0900 Subject: [PATCH] Check relation still exists before applying ON COMMIT action --- src/backend/commands/tablecmds.c | 17 +++++++++++++++++ src/test/regress/expected/temp.out | 23 +++++++++++++++++++++++ src/test/regress/sql/temp.sql | 15 +++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 6048334c75..5b17a8679d 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -13353,6 +13353,23 @@ PreCommit_on_commit_actions(void) } if (oids_to_truncate != NIL) { + List *tmp = oids_to_truncate; + + /* + * Check that relations we're about to truncate still exist. Some of + * them might be inheritance children, which would be gone as a result + * of their parent being dropped due to ONCOMMIT_DROP action of its + * own. + */ + oids_to_truncate = NIL; + foreach(l, tmp) + { + Oid relid = lfirst_oid(l); + + if (SearchSysCacheExists1(RELOID, ObjectIdGetDatum(relid))) + oids_to_truncate = lappend_oid(oids_to_truncate, relid); + } + heap_truncate(oids_to_truncate); CommandCounterIncrement(); /* XXX needed? */ } diff --git a/src/test/regress/expected/temp.out b/src/test/regress/expected/temp.out index a769abe9bb..70be46ca1d 100644 --- a/src/test/regress/expected/temp.out +++ b/src/test/regress/expected/temp.out @@ -216,3 +216,26 @@ select * from temp_parted_oncommit; (0 rows) drop table temp_parted_oncommit; +-- Another case where a child table is gone by the time it's ON COMMIT +-- action is executed due to the ON COMMIT DROP action on its parent +-- There are tests for both a partitioned table and regular inheritance. +begin; +create temp table temp_parted_oncommit_test (a int) partition by list (a) on commit drop; +create temp table temp_parted_oncommit_test1 partition of temp_parted_oncommit_test for values in (1) on commit delete rows; +insert into temp_parted_oncommit_test values (1); +create temp table temp_inh_oncommit_test (a int) on commit drop; +create temp table temp_inh_oncommit_test1 () inherits(temp_inh_oncommit_test) on commit delete rows; +insert into temp_inh_oncommit_test1 values (1); +commit; +NOTICE: drop cascades to table temp_inh_oncommit_test1 +-- zero rows in both cases +select relname from pg_class where relname like 'temp_parted_oncommit_test%'; + relname +--------- +(0 rows) + +select relname from pg_class where relname like 'temp_inh_oncommit_test%'; + relname +--------- +(0 rows) + diff --git a/src/test/regress/sql/temp.sql b/src/test/regress/sql/temp.sql index 1074c7cfac..ad8c5cb85a 100644 --- a/src/test/regress/sql/temp.sql +++ b/src/test/regress/sql/temp.sql @@ -165,3 +165,18 @@ commit; -- partitions are emptied by the previous commit select * from temp_parted_oncommit; drop table temp_parted_oncommit; + +-- Another case where a child table is gone by the time it's ON COMMIT +-- action is executed due to the ON COMMIT DROP action on its parent +-- There are tests for both a partitioned table and regular inheritance. +begin; +create temp table temp_parted_oncommit_test (a int) partition by list (a) on commit drop; +create temp table temp_parted_oncommit_test1 partition of temp_parted_oncommit_test for values in (1) on commit delete rows; +insert into temp_parted_oncommit_test values (1); +create temp table temp_inh_oncommit_test (a int) on commit drop; +create temp table temp_inh_oncommit_test1 () inherits(temp_inh_oncommit_test) on commit delete rows; +insert into temp_inh_oncommit_test1 values (1); +commit; +-- zero rows in both cases +select relname from pg_class where relname like 'temp_parted_oncommit_test%'; +select relname from pg_class where relname like 'temp_inh_oncommit_test%'; -- 2.11.0