*** 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; + }