@@ -239,7 +239,6 @@ DefineQueryRewrite(const char *rulename,
239239 Relation event_relation ;
240240 ListCell * l ;
241241 Query * query ;
242- bool RelisBecomingView = false;
243242 Oid ruleId = InvalidOid ;
244243 ObjectAddress address ;
245244
@@ -311,7 +310,18 @@ DefineQueryRewrite(const char *rulename,
311310 /*
312311 * Rules ON SELECT are restricted to view definitions
313312 *
314- * So there cannot be INSTEAD NOTHING, ...
313+ * So this had better be a view, ...
314+ */
315+ if (event_relation -> rd_rel -> relkind != RELKIND_VIEW &&
316+ event_relation -> rd_rel -> relkind != RELKIND_MATVIEW )
317+ ereport (ERROR ,
318+ (errcode (ERRCODE_WRONG_OBJECT_TYPE ),
319+ errmsg ("relation \"%s\" cannot have ON SELECT rules" ,
320+ RelationGetRelationName (event_relation )),
321+ errdetail_relkind_not_supported (event_relation -> rd_rel -> relkind )));
322+
323+ /*
324+ * ... there cannot be INSTEAD NOTHING, ...
315325 */
316326 if (action == NIL )
317327 ereport (ERROR ,
@@ -407,93 +417,6 @@ DefineQueryRewrite(const char *rulename,
407417 ViewSelectRuleName )));
408418 rulename = pstrdup (ViewSelectRuleName );
409419 }
410-
411- /*
412- * Are we converting a relation to a view?
413- *
414- * If so, check that the relation is empty because the storage for the
415- * relation is going to be deleted. Also insist that the rel not be
416- * involved in partitioning, nor have any triggers, indexes, child or
417- * parent tables, RLS policies, or RLS enabled. (Note: some of these
418- * tests are too strict, because they will reject relations that once
419- * had such but don't anymore. But we don't really care, because this
420- * whole business of converting relations to views is just an obsolete
421- * kluge to allow dump/reload of views that participate in circular
422- * dependencies.)
423- */
424- if (event_relation -> rd_rel -> relkind != RELKIND_VIEW &&
425- event_relation -> rd_rel -> relkind != RELKIND_MATVIEW )
426- {
427- TableScanDesc scanDesc ;
428- Snapshot snapshot ;
429- TupleTableSlot * slot ;
430-
431- if (event_relation -> rd_rel -> relkind == RELKIND_PARTITIONED_TABLE )
432- ereport (ERROR ,
433- (errcode (ERRCODE_WRONG_OBJECT_TYPE ),
434- errmsg ("cannot convert partitioned table \"%s\" to a view" ,
435- RelationGetRelationName (event_relation ))));
436-
437- /* only case left: */
438- Assert (event_relation -> rd_rel -> relkind == RELKIND_RELATION );
439-
440- if (event_relation -> rd_rel -> relispartition )
441- ereport (ERROR ,
442- (errcode (ERRCODE_WRONG_OBJECT_TYPE ),
443- errmsg ("cannot convert partition \"%s\" to a view" ,
444- RelationGetRelationName (event_relation ))));
445-
446- snapshot = RegisterSnapshot (GetLatestSnapshot ());
447- scanDesc = table_beginscan (event_relation , snapshot , 0 , NULL );
448- slot = table_slot_create (event_relation , NULL );
449- if (table_scan_getnextslot (scanDesc , ForwardScanDirection , slot ))
450- ereport (ERROR ,
451- (errcode (ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE ),
452- errmsg ("could not convert table \"%s\" to a view because it is not empty" ,
453- RelationGetRelationName (event_relation ))));
454- ExecDropSingleTupleTableSlot (slot );
455- table_endscan (scanDesc );
456- UnregisterSnapshot (snapshot );
457-
458- if (event_relation -> rd_rel -> relhastriggers )
459- ereport (ERROR ,
460- (errcode (ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE ),
461- errmsg ("could not convert table \"%s\" to a view because it has triggers" ,
462- RelationGetRelationName (event_relation )),
463- errhint ("In particular, the table cannot be involved in any foreign key relationships." )));
464-
465- if (event_relation -> rd_rel -> relhasindex )
466- ereport (ERROR ,
467- (errcode (ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE ),
468- errmsg ("could not convert table \"%s\" to a view because it has indexes" ,
469- RelationGetRelationName (event_relation ))));
470-
471- if (event_relation -> rd_rel -> relhassubclass )
472- ereport (ERROR ,
473- (errcode (ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE ),
474- errmsg ("could not convert table \"%s\" to a view because it has child tables" ,
475- RelationGetRelationName (event_relation ))));
476-
477- if (has_superclass (RelationGetRelid (event_relation )))
478- ereport (ERROR ,
479- (errcode (ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE ),
480- errmsg ("could not convert table \"%s\" to a view because it has parent tables" ,
481- RelationGetRelationName (event_relation ))));
482-
483- if (event_relation -> rd_rel -> relrowsecurity )
484- ereport (ERROR ,
485- (errcode (ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE ),
486- errmsg ("could not convert table \"%s\" to a view because it has row security enabled" ,
487- RelationGetRelationName (event_relation ))));
488-
489- if (relation_has_policies (event_relation ))
490- ereport (ERROR ,
491- (errcode (ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE ),
492- errmsg ("could not convert table \"%s\" to a view because it has row security policies" ,
493- RelationGetRelationName (event_relation ))));
494-
495- RelisBecomingView = true;
496- }
497420 }
498421 else
499422 {
@@ -569,94 +492,6 @@ DefineQueryRewrite(const char *rulename,
569492 SetRelationRuleStatus (event_relid , true);
570493 }
571494
572- /* ---------------------------------------------------------------------
573- * If the relation is becoming a view:
574- * - delete the associated storage files
575- * - get rid of any system attributes in pg_attribute; a view shouldn't
576- * have any of those
577- * - remove the toast table; there is no need for it anymore, and its
578- * presence would make vacuum slightly more complicated
579- * - set relkind to RELKIND_VIEW, and adjust other pg_class fields
580- * to be appropriate for a view
581- *
582- * NB: we had better have AccessExclusiveLock to do this ...
583- * ---------------------------------------------------------------------
584- */
585- if (RelisBecomingView )
586- {
587- Relation relationRelation ;
588- Oid toastrelid ;
589- HeapTuple classTup ;
590- Form_pg_class classForm ;
591-
592- relationRelation = table_open (RelationRelationId , RowExclusiveLock );
593- toastrelid = event_relation -> rd_rel -> reltoastrelid ;
594-
595- /* drop storage while table still looks like a table */
596- RelationDropStorage (event_relation );
597- DeleteSystemAttributeTuples (event_relid );
598-
599- /*
600- * Drop the toast table if any. (This won't take care of updating the
601- * toast fields in the relation's own pg_class entry; we handle that
602- * below.)
603- */
604- if (OidIsValid (toastrelid ))
605- {
606- ObjectAddress toastobject ;
607-
608- /*
609- * Delete the dependency of the toast relation on the main
610- * relation so we can drop the former without dropping the latter.
611- */
612- deleteDependencyRecordsFor (RelationRelationId , toastrelid ,
613- false);
614-
615- /* Make deletion of dependency record visible */
616- CommandCounterIncrement ();
617-
618- /* Now drop toast table, including its index */
619- toastobject .classId = RelationRelationId ;
620- toastobject .objectId = toastrelid ;
621- toastobject .objectSubId = 0 ;
622- performDeletion (& toastobject , DROP_RESTRICT ,
623- PERFORM_DELETION_INTERNAL );
624- }
625-
626- /*
627- * SetRelationRuleStatus may have updated the pg_class row, so we must
628- * advance the command counter before trying to update it again.
629- */
630- CommandCounterIncrement ();
631-
632- /*
633- * Fix pg_class entry to look like a normal view's, including setting
634- * the correct relkind and removal of reltoastrelid of the toast table
635- * we potentially removed above.
636- */
637- classTup = SearchSysCacheCopy1 (RELOID , ObjectIdGetDatum (event_relid ));
638- if (!HeapTupleIsValid (classTup ))
639- elog (ERROR , "cache lookup failed for relation %u" , event_relid );
640- classForm = (Form_pg_class ) GETSTRUCT (classTup );
641-
642- classForm -> relam = InvalidOid ;
643- classForm -> reltablespace = InvalidOid ;
644- classForm -> relpages = 0 ;
645- classForm -> reltuples = -1 ;
646- classForm -> relallvisible = 0 ;
647- classForm -> reltoastrelid = InvalidOid ;
648- classForm -> relhasindex = false;
649- classForm -> relkind = RELKIND_VIEW ;
650- classForm -> relfrozenxid = InvalidTransactionId ;
651- classForm -> relminmxid = InvalidMultiXactId ;
652- classForm -> relreplident = REPLICA_IDENTITY_NOTHING ;
653-
654- CatalogTupleUpdate (relationRelation , & classTup -> t_self , classTup );
655-
656- heap_freetuple (classTup );
657- table_close (relationRelation , RowExclusiveLock );
658- }
659-
660495 ObjectAddressSet (address , RewriteRelationId , ruleId );
661496
662497 /* Close rel, but keep lock till commit... */
0 commit comments