0001-Check-relation-still-exists-before-applying-ON-COMMI.patch

text/plain

Filename: 0001-Check-relation-still-exists-before-applying-ON-COMMI.patch
Type: text/plain
Part: 0
Message: ON COMMIT actions and inheritance

Patch

Format: format-patch
Series: patch 0001
Subject: Check relation still exists before applying ON COMMIT action
File+
src/backend/commands/tablecmds.c 17 0
src/test/regress/expected/temp.out 23 0
src/test/regress/sql/temp.sql 15 0
From 37c97e6b9879b130a80305fd794a9e721332cb98 Mon Sep 17 00:00:00 2001
From: amit <amitlangote09@gmail.com>
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