From 5d1cb1beda9a4d3c020933e85715cdd2423e5ba7 Mon Sep 17 00:00:00 2001 From: amit Date: Fri, 2 Nov 2018 15:26:37 +0900 Subject: [PATCH v5 2/2] 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 ba76c3f9b9..7f742dba7b 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -13291,6 +13291,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 ed2c591fc6..2cfc5debf1 100644 --- a/src/test/regress/expected/temp.out +++ b/src/test/regress/expected/temp.out @@ -213,3 +213,26 @@ select * from temp_parted_oncommit_test; (0 rows) drop table temp_parted_oncommit_test; +-- another case where a child table is gone by the time it's ON COMMIT +-- action is executed (whatever it is) due to the ON COMMIT DROP action +-- on its parent +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 0274bdb13f..59b11c4894 100644 --- a/src/test/regress/sql/temp.sql +++ b/src/test/regress/sql/temp.sql @@ -162,3 +162,18 @@ commit; -- temp_parted_oncommit_test1 must've been emptied during the commit select * from temp_parted_oncommit_test; drop table temp_parted_oncommit_test; + +-- another case where a child table is gone by the time it's ON COMMIT +-- action is executed (whatever it is) due to the ON COMMIT DROP action +-- on its parent +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