Commit 39ee0f55 authored by Tom Lane's avatar Tom Lane

Fix relation-to-view conversion so that it doesn't try to convert a plain

relation to a view when you create an ON INSERT/UPDATE/DELETE rule ...
parent 367bc8f1
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.51 2000/09/12 04:49:09 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.52 2000/09/12 20:38:09 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -200,40 +200,16 @@ DefineQueryRewrite(RuleStmt *stmt) ...@@ -200,40 +200,16 @@ DefineQueryRewrite(RuleStmt *stmt)
foreach(l, action) foreach(l, action)
{ {
query = (Query *) lfirst(l); query = (Query *) lfirst(l);
if (query->resultRelation == 1) if (query->resultRelation == PRS2_OLD_VARNO)
{ {
elog(ERROR, "rule actions on OLD currently not supported" elog(ERROR, "rule actions on OLD currently not supported"
"\n\tuse views or triggers instead"); "\n\tuse views or triggers instead");
} }
if (query->resultRelation == 2) if (query->resultRelation == PRS2_NEW_VARNO)
{ {
elog(ERROR, "rule actions on NEW currently not supported" elog(ERROR, "rule actions on NEW currently not supported"
"\n\tuse triggers instead"); "\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;
}
} }
/* /*
...@@ -333,7 +309,6 @@ DefineQueryRewrite(RuleStmt *stmt) ...@@ -333,7 +309,6 @@ DefineQueryRewrite(RuleStmt *stmt)
/* /*
* ... and finally the rule must be named _RETviewname. * ... and finally the rule must be named _RETviewname.
*/ */
expected_name = MakeRetrieveViewRuleName(event_obj->relname); expected_name = MakeRetrieveViewRuleName(event_obj->relname);
if (strcmp(expected_name, stmt->rulename) != 0) if (strcmp(expected_name, stmt->rulename) != 0)
{ {
...@@ -341,6 +316,29 @@ DefineQueryRewrite(RuleStmt *stmt) ...@@ -341,6 +316,29 @@ DefineQueryRewrite(RuleStmt *stmt)
event_obj->relname, expected_name); event_obj->relname, expected_name);
} }
pfree(expected_name); pfree(expected_name);
/*
* Are we converting a relation to a view?
*
* If so, check that the relation is empty because the storage
* for the relation is going to be deleted.
*/
if (event_relation->rd_rel->relkind != RELKIND_VIEW)
{
HeapScanDesc scanDesc;
HeapTuple tuple;
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 it to view",
event_obj->relname);
/* don't need heap_freetuple because we never got a valid tuple */
heap_endscan(scanDesc);
RelisBecomingView = true;
}
} }
/* /*
...@@ -363,7 +361,7 @@ DefineQueryRewrite(RuleStmt *stmt) ...@@ -363,7 +361,7 @@ DefineQueryRewrite(RuleStmt *stmt)
is_instead, event_attype); is_instead, event_attype);
/* discard rule if it's null action and not INSTEAD; it's a no-op */ /* discard rule if it's null action and not INSTEAD; it's a no-op */
if (action != NULL || is_instead) if (action != NIL || is_instead)
{ {
Relation relationRelation; Relation relationRelation;
HeapTuple tuple; HeapTuple tuple;
...@@ -382,8 +380,8 @@ DefineQueryRewrite(RuleStmt *stmt) ...@@ -382,8 +380,8 @@ DefineQueryRewrite(RuleStmt *stmt)
/* /*
* Set pg_class 'relhasrules' field TRUE for event relation. * Set pg_class 'relhasrules' field TRUE for event relation.
* Also modify the 'relkind' field to show that the relation is * If appropriate, also modify the 'relkind' field to show that
* now a view. * the relation is now a view.
* *
* Important side effect: an SI notice is broadcast to force all * Important side effect: an SI notice is broadcast to force all
* backends (including me!) to update relcache entries with the new * backends (including me!) to update relcache entries with the new
...@@ -420,12 +418,12 @@ DefineQueryRewrite(RuleStmt *stmt) ...@@ -420,12 +418,12 @@ DefineQueryRewrite(RuleStmt *stmt)
/* /*
* IF the relation is becoming a view, delete the storage * IF the relation is becoming a view, delete the storage
* files associated with it. * files associated with it. NB: we had better have AccessExclusiveLock
* to do this ...
*/ */
if (RelisBecomingView) if (RelisBecomingView)
smgrunlink(DEFAULT_SMGR, event_relation); smgrunlink(DEFAULT_SMGR, event_relation);
/* Close rel, but keep lock till commit... */ /* Close rel, but keep lock till commit... */
heap_close(event_relation, NoLock); heap_close(event_relation, NoLock);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment