*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.142 2000/08/03 19:19:08 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.143 2000/09/12 04:49:06 momjian Exp $
*
*
* INTERFACE ROUTINES
/*
* We create the disk file for this relation here
*/
- heap_storage_create(new_rel_desc);
+ if (relkind != RELKIND_VIEW)
+ heap_storage_create(new_rel_desc);
+
/* ----------------
* ok, the relation has been cataloged, so close our relations
* and return the oid of the newly created relation.
* unlink the relation's physical file and finish up.
* ----------------
*/
- if (! rel->rd_unlinked)
+ if (rel->rd_rel->relkind != RELKIND_VIEW && ! rel->rd_unlinked)
smgrunlink(DEFAULT_SMGR, rel);
rel->rd_unlinked = true;
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.100 2000/09/12 04:33:18 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.101 2000/09/12 04:49:06 momjian Exp $
*
* NOTES
* The PerformAddAttribute() code, like most of the relation
#endif
rel = heap_openr(relationName, AccessExclusiveLock);
+ if ( rel->rd_rel->relkind == RELKIND_VIEW )
+ elog(ERROR, "ALTER TABLE: %s is a view", relationName);
+
myrelid = RelationGetRelid(rel);
heap_close(rel, NoLock);
rel = heap_openr(relationName, AccessExclusiveLock);
+ /* make sure it is not a view */
+ if (rel->rd_rel->relkind == RELKIND_VIEW)
+ elog(ERROR, "ALTER TABLE: cannot add constraint to a view");
+
/*
* Scan all of the rows, looking for a false match
*/
elog(ERROR, "ALTER TABLE / ADD CONSTRAINT: Unable to reference temporary table from permanent table constraint.");
}
- /* 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
* doesn't delete rows out from under us.
*/
pkrel = heap_openr(fkconstraint->pktable_name, AccessExclusiveLock);
- if (pkrel == NULL)
- elog(ERROR, "referenced table \"%s\" not found",
+ if (pkrel == NULL)
+ elog(ERROR, "referenced table \"%s\" not found",
+ fkconstraint->pktable_name);
+
+ if (pkrel->rd_rel->relkind != RELKIND_RELATION)
+ elog(ERROR, "referenced table \"%s\" not a relation",
fkconstraint->pktable_name);
+
/*
* Grab an exclusive lock on the fk table, and then scan
elog(ERROR, "table \"%s\" not found",
relationName);
+ if (rel->rd_rel->relkind != RELKIND_RELATION)
+ elog(ERROR, "referencing table \"%s\" not a relation", relationName);
+
/* First we check for limited correctness of the constraint */
rel_attrs = pkrel->rd_att->attrs;
* allow to create TOAST tables for views. But why not - someone
* can insert into a view, so it shouldn't be impossible to hide
* huge data there :-)
+ * Not any more.
*/
if (((Form_pg_class) GETSTRUCT(reltup))->relkind != RELKIND_RELATION)
{
rel = heap_openr(lockstmt->relname, NoLock);
+ if (rel->rd_rel->relkind != RELKIND_RELATION)
+ elog(ERROR, "LOCK TABLE: %s is not a table", lockstmt->relname);
+
if (is_view(rel))
elog(ERROR, "LOCK TABLE: cannot lock a view");
#include "catalog/pg_shadow.h"
#include "catalog/pg_trigger.h"
#include "catalog/pg_type.h"
+#include "catalog/pg_class.h"
#include "commands/comment.h"
#include "miscadmin.h"
#include "parser/parse.h"
switch (reltype)
{
case (INDEX):
- if (relkind != 'i')
+ if (relkind != RELKIND_INDEX)
elog(ERROR, "relation '%s' is not an index", relname);
break;
case (TABLE):
- if (relkind != 'r')
+ if (relkind != RELKIND_RELATION)
elog(ERROR, "relation '%s' is not a table", relname);
break;
case (VIEW):
- if (relkind != 'r')
+ if (relkind != RELKIND_VIEW)
elog(ERROR, "relation '%s' is not a view", relname);
break;
case (SEQUENCE):
- if (relkind != 'S')
+ if (relkind != RELKIND_SEQUENCE)
elog(ERROR, "relation '%s' is not a sequence", relname);
break;
}
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.164 2000/09/06 14:15:16 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.165 2000/09/12 04:49:07 momjian Exp $
*
*-------------------------------------------------------------------------
if (rkind != RELKIND_RELATION)
{
- elog(NOTICE, "Vacuum: can not process index and certain system tables");
+ elog(NOTICE, "Vacuum: can not process indecies, views and certain system tables");
continue;
}
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: view.c,v 1.46 2000/09/12 04:15:56 momjian Exp $
+ * $Id: view.c,v 1.47 2000/09/12 04:49:07 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
* finally create the relation...
*/
- DefineRelation(&createStmt, RELKIND_RELATION);
+ DefineRelation(&createStmt, RELKIND_VIEW);
}
/*------------------------------------------------------------------
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.125 2000/09/06 14:15:17 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.126 2000/09/12 04:49:08 momjian Exp $
*
*-------------------------------------------------------------------------
*/
elog(ERROR, "You can't change toast relation %s",
RelationGetRelationName(resultRelationDesc));
+ if (resultRelationDesc->rd_rel->relkind == RELKIND_VIEW)
+ elog(ERROR, "You can't change view relation %s",
+ RelationGetRelationName(resultRelationDesc));
+
resultRelationInfo = makeNode(RelationInfo);
resultRelationInfo->ri_RangeTableIndex = resultRelationIndex;
resultRelationInfo->ri_RelationDesc = resultRelationDesc;
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.50 2000/09/12 04:15:57 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.51 2000/09/12 04:49:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include "parser/parse_relation.h"
#include "rewrite/rewriteDefine.h"
#include "rewrite/rewriteSupport.h"
+#include "utils/syscache.h"
+#include "storage/smgr.h"
#include "commands/view.h"
*event_qualP;
List *l;
Query *query;
+ bool RelisBecomingView = false;
/*
* If we are installing an ON SELECT rule, we had better grab
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;
+ }
+
}
/*
/* discard rule if it's null action and not INSTEAD; it's a no-op */
if (action != NULL || is_instead)
{
+ Relation relationRelation;
+ HeapTuple tuple;
+ Relation idescs[Num_pg_class_indices];
+
event_qualP = nodeToString(event_qual);
actionP = nodeToString(action);
/*
* Set pg_class 'relhasrules' field TRUE for event relation.
+ * 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
* rule.
+ *
+ * NOTE : Used to call setRelhasrulesInRelation. The code
+ * was inlined so that two updates were not needed. mhh 31-aug-2000
+ */
+
+ /*
+ * Find the tuple to update in pg_class, using syscache for the lookup.
*/
- setRelhasrulesInRelation(ev_relid, true);
+ relationRelation = heap_openr(RelationRelationName, RowExclusiveLock);
+ tuple = SearchSysCacheTupleCopy(RELOID,
+ ObjectIdGetDatum(ev_relid),
+ 0, 0, 0);
+ Assert(HeapTupleIsValid(tuple));
+
+ /* Do the update */
+ ((Form_pg_class) GETSTRUCT(tuple))->relhasrules = true;
+ if (RelisBecomingView)
+ ((Form_pg_class) GETSTRUCT(tuple))->relkind = RELKIND_VIEW;
+
+ heap_update(relationRelation, &tuple->t_self, tuple, NULL);
+
+ /* Keep the catalog indices up to date */
+ CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
+ CatalogIndexInsert(idescs, Num_pg_class_indices, relationRelation, tuple);
+ CatalogCloseIndices(Num_pg_class_indices, idescs);
+
+ heap_freetuple(tuple);
+ heap_close(relationRelation, RowExclusiveLock);
}
+ /*
+ * IF the relation is becoming a view, delete the storage
+ * files associated with it.
+ */
+ if (RelisBecomingView)
+ smgrunlink(DEFAULT_SMGR, event_relation);
+
+
/* Close rel, but keep lock till commit... */
heap_close(event_relation, NoLock);
}
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.38 2000/06/30 07:04:23 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.39 2000/09/12 04:49:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
*/
event_relation = heap_open(eventRelationOid, AccessExclusiveLock);
+ /* do not allow the removal of a view's SELECT rule */
+ if (event_relation->rd_rel->relkind == RELKIND_VIEW &&
+ ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_type == '1' )
+ elog(ERROR, "Cannot remove a view's SELECT rule");
+
hasMoreRules = event_relation->rd_rules != NULL &&
event_relation->rd_rules->numLocks > 1;
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.92 2000/09/06 14:15:21 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.93 2000/09/12 04:49:11 momjian Exp $
*
*-------------------------------------------------------------------------
*/
if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
elog(ERROR, "TRUNCATE cannot be used on sequences. '%s' is a sequence",
relname);
+ if (rel->rd_rel->relkind == RELKIND_VIEW)
+ elog(ERROR, "TRUNCATE cannot be used on views. '%s' is a sequence",
+ relname);
heap_close(rel, NoLock);
#ifndef NO_SECURITY
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.110 2000/08/30 08:48:55 inoue Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.111 2000/09/12 04:49:13 momjian Exp $
*
*-------------------------------------------------------------------------
*/
* by the storage manager code to rd_fd.
* ----------------
*/
- fd = smgropen(DEFAULT_SMGR, relation);
+ if (relation->rd_rel->relkind != RELKIND_VIEW) {
+ fd = smgropen(DEFAULT_SMGR, relation);
- Assert(fd >= -1);
- if (fd == -1)
- elog(NOTICE, "RelationIdBuildRelation: smgropen(%s): %m",
- NameStr(relation->rd_rel->relname));
+ Assert(fd >= -1);
+ if (fd == -1)
+ elog(NOTICE, "RelationBuildDesc: smgropen(%s): %m",
+ NameStr(relation->rd_rel->relname));
- relation->rd_fd = fd;
+ relation->rd_fd = fd;
+ } else {
+ relation->rd_fd = -1;
+ }
/* ----------------
* insert newly created relation into proper relcaches,
if (RelationIsValid(rd))
{
- if (rd->rd_fd == -1)
+ if (rd->rd_fd == -1 && rd->rd_rel->relkind != RELKIND_VIEW)
{
rd->rd_fd = smgropen(DEFAULT_SMGR, rd);
Assert(rd->rd_fd != -1 || rd->rd_unlinked);
if (RelationIsValid(rd))
{
- if (rd->rd_fd == -1)
+ if (rd->rd_fd == -1 && rd->rd_rel->relkind != RELKIND_VIEW)
{
rd->rd_fd = smgropen(DEFAULT_SMGR, rd);
Assert(rd->rd_fd != -1 || rd->rd_unlinked);
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: catversion.h,v 1.43 2000/08/23 06:04:43 thomas Exp $
+ * $Id: catversion.h,v 1.44 2000/09/12 04:49:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 200008221
+#define CATALOG_VERSION_NO 200009111
#endif
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_class.h,v 1.39 2000/07/03 23:10:05 wieck Exp $
+ * $Id: pg_class.h,v 1.40 2000/09/12 04:49:15 momjian Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
#define RELKIND_SEQUENCE 'S' /* SEQUENCE relation */
#define RELKIND_UNCATALOGED 'u' /* temporary heap */
#define RELKIND_TOASTVALUE 't' /* moved off huge values */
+#define RELKIND_VIEW 'v' /* view */
#endif /* PG_CLASS_H */
-- Look for illegal values in pg_class fields
SELECT p1.oid, p1.relname
FROM pg_class as p1
-WHERE p1.relkind NOT IN ('r', 'i', 's', 'S', 't');
+WHERE p1.relkind NOT IN ('r', 'i', 's', 'S', 't', 'v');
oid | relname
-----+---------
(0 rows)
SELECT p1.oid, p1.relname
FROM pg_class as p1
-WHERE p1.relkind NOT IN ('r', 'i', 's', 'S', 't');
+WHERE p1.relkind NOT IN ('r', 'i', 's', 'S', 't', 'v');
-- Indexes should have an access method, others not.