@@ -239,7 +239,6 @@ DefineQueryRewrite(const char *rulename,
239
239
Relation event_relation ;
240
240
ListCell * l ;
241
241
Query * query ;
242
- bool RelisBecomingView = false;
243
242
Oid ruleId = InvalidOid ;
244
243
ObjectAddress address ;
245
244
@@ -311,7 +310,18 @@ DefineQueryRewrite(const char *rulename,
311
310
/*
312
311
* Rules ON SELECT are restricted to view definitions
313
312
*
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, ...
315
325
*/
316
326
if (action == NIL )
317
327
ereport (ERROR ,
@@ -407,93 +417,6 @@ DefineQueryRewrite(const char *rulename,
407
417
ViewSelectRuleName )));
408
418
rulename = pstrdup (ViewSelectRuleName );
409
419
}
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
- }
497
420
}
498
421
else
499
422
{
@@ -569,94 +492,6 @@ DefineQueryRewrite(const char *rulename,
569
492
SetRelationRuleStatus (event_relid , true);
570
493
}
571
494
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
-
660
495
ObjectAddressSet (address , RewriteRelationId , ruleId );
661
496
662
497
/* Close rel, but keep lock till commit... */
0 commit comments