disallow LOCK on a view - the Tom Lane remix
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
mhh@mindspring.com
Attachments:
lock.patchtext/plain; charset=us-asciiDownload
*** 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;
+ }
* Mark Hollomon <mhh@mindspring.com> [000829 17:13] wrote:
On Tue, Aug 29, 2000 at 04:14:00PM -0700, Alfred Perlstein wrote:
Ok, I'm wondering if this patch will cause problems locking a table
that has had:CREATE RULE "_RETfoo" AS ON SELECT TO foo DO INSTEAD SELECT * FROM foo1;
I need to be able to lock the table 'foo' exclusively while I swap
out the underlying rule to forward to another table.Yes, it would. 'foo' would be seen as view.
Okay, this gives me a reason to to do it the hard way.
I will try to add a relisview attribute to pg_class.
That way, we can differentiate between tables with rules
and things created with 'CREATE VIEW'.Hmmm... guess I'll need to change the definition of the pg_views
view as well.
Ok, thanks I appreciate you taking my situation into consideration.
thanks,
--
-Alfred Perlstein - [bright@wintelcom.net|alfred@freebsd.org]
Import Notes
Reply to msg id not found: 20000829210300.B25366@mindspring.com
Tom Lane wrote:
BTW, this seems to be a counterexample for my prior suggestion that
pg_class should have a "relviewrule" OID column. If it did, you'd
have to update that field when doing something like the above.
Pain-in-the-neck factor looms large...
I was already considering the possiblity of a 'ALTER VIEW' command that
would effectively allow you do that.
CREATE VIEW bar as select * from foo1;
ALTER VIEW bar as select * from foo2;
It would update the "relviewrule" field.
--
Mark Hollomon
mhh@nortelnetworks.com
ESN 451-9008 (302)454-9008
OK, previous patch unapplied, and this patch was applied.
Here is a patch against CVS (without my earlier patch)
to disallowLOCK x
if x is a view.
It does not use the SPI interface.
--
Mark Hollomon
mhh@mindspring.com
[ Attachment, skipping... ]
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 853-3000
+ If your life is a hard drive, | 830 Blythe Avenue
+ Christ can be your backup. | Drexel Hill, Pennsylvania 19026