From 39ee0f55d7a88432b3e2b1184daa318f689b5f32 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Tue, 12 Sep 2000 20:38:09 +0000
Subject: [PATCH] Fix relation-to-view conversion so that it doesn't try to
 convert a plain relation to a view when you create an ON INSERT/UPDATE/DELETE
 rule ...

---
 src/backend/rewrite/rewriteDefine.c | 68 ++++++++++++++---------------
 1 file changed, 33 insertions(+), 35 deletions(-)

diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c
index 8444bd91384..da0d84ad9d5 100644
--- a/src/backend/rewrite/rewriteDefine.c
+++ b/src/backend/rewrite/rewriteDefine.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.51 2000/09/12 04:49:09 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.52 2000/09/12 20:38:09 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -200,40 +200,16 @@ DefineQueryRewrite(RuleStmt *stmt)
 	foreach(l, action)
 	{
 		query = (Query *) lfirst(l);
-		if (query->resultRelation == 1)
+		if (query->resultRelation == PRS2_OLD_VARNO)
 		{
 			elog(ERROR, "rule actions on OLD currently not supported"
 				 "\n\tuse views or triggers instead");
 		}
-		if (query->resultRelation == 2)
+		if (query->resultRelation == PRS2_NEW_VARNO)
 		{
 			elog(ERROR, "rule actions on NEW currently not supported"
 				 "\n\tuse triggers instead");
 		}
-
-		if (event_relation->rd_rel->relkind != RELKIND_VIEW)
-		{
-			HeapScanDesc  scanDesc;
-			HeapTuple	  tuple;
-			/*
-			 * A relation is about to become a view.
-			 * check that the relation is empty because
-			 * the storage for the relation is going to
-			 * be deleted.
-			 */
-
-			scanDesc = heap_beginscan(event_relation, 0, SnapshotNow, 0, NULL);
-			tuple = heap_getnext(scanDesc, 0);
-			if (HeapTupleIsValid(tuple))
-				elog(ERROR, "relation %s is not empty. Cannot convert to view", event_obj->relname);
-
-			/* don't need heap_freetuple because we never got a valid tuple */
-			heap_endscan(scanDesc);
-
-
-			RelisBecomingView = true;
-		}
-
 	}
 
 	/*
@@ -333,7 +309,6 @@ DefineQueryRewrite(RuleStmt *stmt)
 		/*
 		 * ... and finally the rule must be named _RETviewname.
 		 */
-
 		expected_name = MakeRetrieveViewRuleName(event_obj->relname);
 		if (strcmp(expected_name, stmt->rulename) != 0)
 		{
@@ -341,6 +316,29 @@ DefineQueryRewrite(RuleStmt *stmt)
 				 event_obj->relname, expected_name);
 		}
 		pfree(expected_name);
+
+		/*
+		 * Are we converting a relation to a view?
+		 *
+		 * If so, check that the relation is empty because the storage
+		 * for the relation is going to be deleted.
+		 */
+		if (event_relation->rd_rel->relkind != RELKIND_VIEW)
+		{
+			HeapScanDesc  scanDesc;
+			HeapTuple	  tuple;
+
+			scanDesc = heap_beginscan(event_relation, 0, SnapshotNow, 0, NULL);
+			tuple = heap_getnext(scanDesc, 0);
+			if (HeapTupleIsValid(tuple))
+				elog(ERROR, "Relation \"%s\" is not empty. Cannot convert it to view",
+					 event_obj->relname);
+
+			/* don't need heap_freetuple because we never got a valid tuple */
+			heap_endscan(scanDesc);
+
+			RelisBecomingView = true;
+		}
 	}
 
 	/*
@@ -363,7 +361,7 @@ DefineQueryRewrite(RuleStmt *stmt)
 				 is_instead, event_attype);
 
 	/* discard rule if it's null action and not INSTEAD; it's a no-op */
-	if (action != NULL || is_instead)
+	if (action != NIL || is_instead)
 	{
 		Relation	relationRelation;
 		HeapTuple	tuple;
@@ -382,8 +380,8 @@ DefineQueryRewrite(RuleStmt *stmt)
 
 		/*
 		 * Set pg_class 'relhasrules' field TRUE for event relation.
-		 * Also modify the 'relkind' field to show that the relation is
-		 * now a view.
+		 * If appropriate, also modify the 'relkind' field to show that
+		 * the relation is now a view.
 		 *
 		 * Important side effect: an SI notice is broadcast to force all
 		 * backends (including me!) to update relcache entries with the new
@@ -398,8 +396,8 @@ DefineQueryRewrite(RuleStmt *stmt)
 		 */
 		relationRelation = heap_openr(RelationRelationName, RowExclusiveLock);
 		tuple = SearchSysCacheTupleCopy(RELOID,
-									ObjectIdGetDatum(ev_relid),
-									0, 0, 0);
+										ObjectIdGetDatum(ev_relid),
+										0, 0, 0);
 		Assert(HeapTupleIsValid(tuple));
 
 		/* Do the update */
@@ -420,12 +418,12 @@ DefineQueryRewrite(RuleStmt *stmt)
 
 	/*
 	 * IF the relation is becoming a view, delete the storage
-	 * files associated with it.
+	 * files associated with it.  NB: we had better have AccessExclusiveLock
+	 * to do this ...
 	 */
 	if (RelisBecomingView)
 		smgrunlink(DEFAULT_SMGR, event_relation);
 
-
 	/* Close rel, but keep lock till commit... */
 	heap_close(event_relation, NoLock);
 }
-- 
GitLab