mirror of
https://github.com/postgres/postgres.git
synced 2025-06-03 00:02:26 -04:00
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 ...
This commit is contained in:
parent
367bc8f1af
commit
39ee0f55d7
@ -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)
|
|||||||
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)
|
|||||||
/*
|
/*
|
||||||
* ... 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* 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
|
||||||
@ -398,8 +396,8 @@ DefineQueryRewrite(RuleStmt *stmt)
|
|||||||
*/
|
*/
|
||||||
relationRelation = heap_openr(RelationRelationName, RowExclusiveLock);
|
relationRelation = heap_openr(RelationRelationName, RowExclusiveLock);
|
||||||
tuple = SearchSysCacheTupleCopy(RELOID,
|
tuple = SearchSysCacheTupleCopy(RELOID,
|
||||||
ObjectIdGetDatum(ev_relid),
|
ObjectIdGetDatum(ev_relid),
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
Assert(HeapTupleIsValid(tuple));
|
Assert(HeapTupleIsValid(tuple));
|
||||||
|
|
||||||
/* Do the update */
|
/* Do the update */
|
||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user