@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* 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 "parser/parse_relation.h"
# include "rewrite/rewriteDefine.h"
# include "rewrite/rewriteDefine.h"
# include "rewrite/rewriteSupport.h"
# include "rewrite/rewriteSupport.h"
# include "utils/syscache.h"
# include "storage/smgr.h"
# include "commands/view.h"
# include "commands/view.h"
@ -162,6 +164,7 @@ DefineQueryRewrite(RuleStmt *stmt)
* event_qualP ;
* event_qualP ;
List * l ;
List * l ;
Query * query ;
Query * query ;
bool RelisBecomingView = false ;
/*
/*
* If we are installing an ON SELECT rule , we had better grab
* 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 "
elog ( ERROR , " rule actions on NEW currently not supported "
" \n \t use triggers instead " ) ;
" \n \t use 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 */
/* discard rule if it's null action and not INSTEAD; it's a no-op */
if ( action ! = NULL | | is_instead )
if ( action ! = NULL | | is_instead )
{
{
Relation relationRelation ;
HeapTuple tuple ;
Relation idescs [ Num_pg_class_indices ] ;
event_qualP = nodeToString ( event_qual ) ;
event_qualP = nodeToString ( event_qual ) ;
actionP = nodeToString ( action ) ;
actionP = nodeToString ( action ) ;
@ -351,14 +382,50 @@ 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
* 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
* rule .
* 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... */
/* Close rel, but keep lock till commit... */
heap_close ( event_relation , NoLock ) ;
heap_close ( event_relation , NoLock ) ;
}
}