lock.patch

text/plain

Filename: lock.patch
Type: text/plain
Part: 0
Message: disallow LOCK on a view - the Tom Lane remix

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: context
File+
command.c 75 29
*** command.c.orig	Tue Aug 29 10:39:42 2000
--- command.c	Tue Aug 29 14:58:24 2000
***************
*** 26,31 ****
--- 26,32 ----
  #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"
***************
*** 54,59 ****
--- 55,64 ----
  
  
  static bool needs_toast_table(Relation rel);
+ static bool is_viewr(char *relname);
+ static bool is_view(Relation rel);
+ 
+ 
  
  
  /* --------------------------------
***************
*** 1086,1094 ****
  AlterTableAddConstraint(char *relationName,
  						bool inh, Node *newConstraint)
  {
- 	char rulequery[41+NAMEDATALEN]; 
- 	void *qplan;
- 	char nulls[1]="";
  
  	if (newConstraint == NULL)
  		elog(ERROR, "ALTER TABLE / ADD CONSTRAINT passed invalid constraint.");
--- 1091,1096 ----
***************
*** 1099,1117 ****
  #endif
  
  	/* check to see if the table to be constrained is a view. */
! 	sprintf(rulequery, "select * from pg_views where viewname='%s'", relationName);
! 	if (SPI_connect()!=SPI_OK_CONNECT)
! 		elog(ERROR, "ALTER TABLE: Unable to determine if %s is a view - SPI_connect failure..", relationName);
!         qplan=SPI_prepare(rulequery, 0, NULL);
! 	if (!qplan)
! 		elog(ERROR, "ALTER TABLE: Unable to determine if %s is a view - SPI_prepare failure.", relationName);
! 	qplan=SPI_saveplan(qplan);
! 	if (SPI_execp(qplan, NULL, nulls, 1)!=SPI_OK_SELECT) 
! 		elog(ERROR, "ALTER TABLE: Unable to determine if %s is a view - SPI_execp failure.", relationName);
!         if (SPI_processed != 0)
!                 elog(ERROR, "ALTER TABLE: Cannot add constraints to views.");
!         if (SPI_finish() != SPI_OK_FINISH)
!                 elog(NOTICE, "SPI_finish() failed in ALTER TABLE");
  		
  	switch (nodeTag(newConstraint))
  	{
--- 1101,1108 ----
  #endif
  
  	/* check to see if the table to be constrained is a view. */
! 	if (is_viewr(relationName))
! 		 elog(ERROR, "ALTER TABLE: Cannot add constraints to views.");
  		
  	switch (nodeTag(newConstraint))
  	{
***************
*** 1254,1272 ****
  				}
  
  				/* check to see if the referenced table is a view. */
! 				sprintf(rulequery, "select * from pg_views where viewname='%s'", fkconstraint->pktable_name);
! 				if (SPI_connect()!=SPI_OK_CONNECT)
! 					elog(ERROR, "ALTER TABLE: Unable to determine if %s is a view.", relationName);
! 			        qplan=SPI_prepare(rulequery, 0, NULL);
! 				if (!qplan)
! 					elog(ERROR, "ALTER TABLE: Unable to determine if %s is a view.", relationName);
! 				qplan=SPI_saveplan(qplan);
! 				if (SPI_execp(qplan, NULL, nulls, 1)!=SPI_OK_SELECT) 
! 					elog(ERROR, "ALTER TABLE: Unable to determine if %s is a view.", relationName);
! 			        if (SPI_processed != 0)
! 			                elog(ERROR, "ALTER TABLE: Cannot add constraints to views.");
! 			        if (SPI_finish() != SPI_OK_FINISH)
! 			                elog(NOTICE, "SPI_finish() failed in RI_FKey_check()");
  
  				/*
  				 * Grab an exclusive lock on the pk table, so that someone
--- 1245,1252 ----
  				}
  
  				/* check to see if the referenced table is a view. */
! 				if (is_viewr(fkconstraint->pktable_name))
! 				 elog(ERROR, "ALTER TABLE: Cannot add constraints to views.");
  
  				/*
  				 * Grab an exclusive lock on the pk table, so that someone
***************
*** 1637,1642 ****
--- 1617,1625 ----
  
  	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, GetPgUserName(), ACL_RD);
  	else
***************
*** 1650,1652 ****
--- 1633,1698 ----
  	heap_close(rel, NoLock);	/* close rel, keep lock */
  }
  
+ 
+ static
+ bool
+ is_viewr(char *name)
+ {
+ 	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;
+ }