diff options
Diffstat (limited to 'src/backend/rewrite/rewriteDefine.c')
-rw-r--r-- | src/backend/rewrite/rewriteDefine.c | 71 |
1 files changed, 69 insertions, 2 deletions
diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c index c9315f6d338..8444bd91384 100644 --- a/src/backend/rewrite/rewriteDefine.c +++ b/src/backend/rewrite/rewriteDefine.c @@ -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 + */ + + /* + * 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); } |