mirror of
https://github.com/postgres/postgres.git
synced 2025-06-25 01:02:05 +03:00
This patch implements a different "relkind"
for views. Views are now have a "relkind" of RELKIND_VIEW instead of RELKIND_RELATION. Also, views no longer have actual heap storage files. The following changes were made 1. CREATE VIEW sets the new relkind 2. The executor complains if a DELETE or INSERT references a view. 3. DROP RULE complains if an attempt is made to delete a view SELECT rule. 4. CREATE RULE "_RETmytable" AS ON SELECT TO mytable DO INSTEAD ... 1. checks to make sure mytable is empty. 2. sets the relkind to RELKIND_VIEW. 3. deletes the heap storage files. 5. LOCK myview is not allowed. :) 6. the regression test type_sanity was changed to account for the new relkind value. 7. CREATE INDEX ON myview ... is not allowed. 8. VACUUM myview is not allowed. VACUUM automatically skips views when do the entire database. 9. TRUNCATE myview is not allowed. THINGS LEFT TO THINK ABOUT o pg_views o pg_dump o pgsql (\d \dv) o Do we really want to be able to inherit from views? o Is 'DROP TABLE myview' OK? -- Mark Hollomon
This commit is contained in:
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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 $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -23,6 +23,8 @@
|
||||
#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"
|
||||
|
||||
|
||||
@ -162,6 +164,7 @@ DefineQueryRewrite(RuleStmt *stmt)
|
||||
*event_qualP;
|
||||
List *l;
|
||||
Query *query;
|
||||
bool RelisBecomingView = false;
|
||||
|
||||
/*
|
||||
* If we are installing an ON SELECT rule, we had better grab
|
||||
@ -207,6 +210,30 @@ DefineQueryRewrite(RuleStmt *stmt)
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -338,6 +365,10 @@ DefineQueryRewrite(RuleStmt *stmt)
|
||||
/* 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);
|
||||
|
||||
@ -351,14 +382,50 @@ DefineQueryRewrite(RuleStmt *stmt)
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
setRelhasrulesInRelation(ev_relid, true);
|
||||
|
||||
/*
|
||||
* Find the tuple to update in pg_class, using syscache for the lookup.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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 $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -103,6 +103,11 @@ RemoveRewriteRule(char *ruleName)
|
||||
*/
|
||||
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;
|
||||
|
||||
|
Reference in New Issue
Block a user