From 1da2feea83f43736c14732910d6af49dcae11b76 Mon Sep 17 00:00:00 2001
From: Bruce Momjian <bruce@momjian.us>
Date: Tue, 12 Sep 2000 04:33:18 +0000
Subject: [PATCH] Previous patch backed out.

Here is a patch against CVS (without my earlier patch)
to disallow

LOCK x

if x is a view.

It does not use the SPI interface.

--
Mark Hollomon
---
 doc/TODO                       |  2 +-
 src/backend/commands/command.c | 91 ++++++++++++++++++++++++----------
 2 files changed, 66 insertions(+), 27 deletions(-)

diff --git a/doc/TODO b/doc/TODO
index f903ba053df..804d52a3a4b 100644
--- a/doc/TODO
+++ b/doc/TODO
@@ -35,7 +35,7 @@ VIEWS
 * Views containing aggregates sometimes fail(Jan)
 * Creating view and inheriting the view causes view* to show
   duplicates(inherit) 
-* Disallow LOCK on view
+* -Disallow LOCK on view(Mark Hollomon)
 
 MISC
 
diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c
index 668858d0772..d0de9e2e4de 100644
--- a/src/backend/commands/command.c
+++ b/src/backend/commands/command.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.99 2000/09/12 04:30:08 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.100 2000/09/12 04:33:18 momjian Exp $
  *
  * NOTES
  *	  The PerformAddAttribute() code, like most of the relation
@@ -26,6 +26,7 @@
 #include "catalog/indexing.h"
 #include "catalog/pg_attrdef.h"
 #include "catalog/pg_opclass.h"
+#include "catalog/pg_rewrite.h"
 #include "commands/command.h"
 #include "executor/spi.h"
 #include "catalog/heap.h"
@@ -55,7 +56,8 @@
 
 
 static bool needs_toast_table(Relation rel);
-static bool is_view(char *relname, char *command);
+static bool is_viewr(char *relname);
+static bool is_view(Relation rel);
 
 
 
@@ -1100,7 +1102,7 @@ AlterTableAddConstraint(char *relationName,
 #endif
 
 	/* check to see if the table to be constrained is a view. */
-	if (is_view(relationName, "ALTER TABLE"))
+	if (is_viewr(relationName))
 		 elog(ERROR, "ALTER TABLE: Cannot add constraints to views.");
 		
 	switch (nodeTag(newConstraint))
@@ -1250,7 +1252,7 @@ AlterTableAddConstraint(char *relationName,
 				}
 
 				/* check to see if the referenced table is a view. */
-				if (is_view(fkconstraint->pktable_name, "ALTER TABLE"))
+				if (is_viewr(fkconstraint->pktable_name))
 				 elog(ERROR, "ALTER TABLE: Cannot add constraints to views.");
 
 				/*
@@ -1698,11 +1700,11 @@ LockTableCommand(LockStmt *lockstmt)
 	Relation	rel;
 	int			aclresult;
 
-	if (is_view(lockstmt->relname, "LOCK TABLE")) 
-			elog(ERROR, "LOCK TABLE: cannot lock a view");
-
 	rel = heap_openr(lockstmt->relname, NoLock);
 
+	if (is_view(rel)) 
+			elog(ERROR, "LOCK TABLE: cannot lock a view");
+
 	if (lockstmt->mode == AccessShareLock)
 		aclresult = pg_aclcheck(lockstmt->relname, GetUserId(), ACL_RD);
 	else
@@ -1719,26 +1721,63 @@ LockTableCommand(LockStmt *lockstmt)
 
 static
 bool
-is_view (char * relname, char *command)
+is_viewr(char *name)
 {
-	bool retval;
-	char rulequery[41+NAMEDATALEN]; 
-	void *qplan;
-	char nulls[1]="";
-
-	sprintf(rulequery, "select * from pg_views where viewname='%s'", relname);
-	if (SPI_connect()!=SPI_OK_CONNECT)
-		elog(ERROR, "%s: Unable to determine if %s is a view - SPI_connect failure..", command, relname);
-	qplan=SPI_prepare(rulequery, 0, NULL);
-	if (!qplan)
-		elog(ERROR, "%s: Unable to determine if %s is a view - SPI_prepare failure.", command, relname);
-	qplan=SPI_saveplan(qplan);
-	if (SPI_execp(qplan, NULL, nulls, 1)!=SPI_OK_SELECT) 
-		elog(ERROR, "%s: Unable to determine if %s is a view - SPI_execp failure.", command, relname);
-
-	retval = (SPI_processed != 0);
-  if (SPI_finish() != SPI_OK_FINISH)
-	 elog(NOTICE, "SPI_finish() failed in %s", command);
+	Relation rel = heap_openr(name, NoLock);
+
+	bool retval = is_view(rel);
+
+	heap_close(rel, NoLock);
+
+	return retval;
+}
+
+static
+bool
+is_view (Relation rel)
+{
+	Relation	RewriteRelation;
+	HeapScanDesc scanDesc;
+	ScanKeyData scanKeyData;
+	HeapTuple	tuple;
+	Form_pg_rewrite data;
+
+
+	bool retval = 0;
+
+	/*
+	 * Open the pg_rewrite relation.
+	 */
+	RewriteRelation = heap_openr(RewriteRelationName, RowExclusiveLock);
+
+	/*
+	 * Scan the RuleRelation ('pg_rewrite') for all the tuples that has
+	 * the same ev_class as the relation being checked.
+	 */
+	ScanKeyEntryInitialize(&scanKeyData,
+						   0,
+						   Anum_pg_rewrite_ev_class,
+						   F_OIDEQ,
+						   ObjectIdGetDatum(rel->rd_id));
+	scanDesc = heap_beginscan(RewriteRelation,
+							  0, SnapshotNow, 1, &scanKeyData);
+
+	while (HeapTupleIsValid(tuple = heap_getnext(scanDesc, 0)))
+	{
+		if (tuple->t_data != NULL) 
+		{
+			data = (Form_pg_rewrite) GETSTRUCT(tuple);
+			if (data->ev_type == '1')
+			{
+				retval = 1;
+				break;
+			}
+		}
+
+	}
 
+	heap_endscan(scanDesc);
+	heap_close(RewriteRelation, RowExclusiveLock);
+	
   return retval;
 }
-- 
GitLab