aboutsummaryrefslogtreecommitdiff
path: root/src/backend/rewrite/rewriteDefine.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/rewrite/rewriteDefine.c')
-rw-r--r--src/backend/rewrite/rewriteDefine.c71
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);
}