9
9
*
10
10
*
11
11
* IDENTIFICATION
12
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump_sort.c,v 1.6 2004/08/29 05:06:53 momjian Exp $
12
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump_sort.c,v 1.7 2004/12/14 22:16:32 tgl Exp $
13
13
*
14
14
*-------------------------------------------------------------------------
15
15
*/
@@ -639,7 +639,8 @@ repairTypeFuncLoop(DumpableObject *typeobj, DumpableObject *funcobj)
639
639
/*
640
640
* Because we force a view to depend on its ON SELECT rule, while there
641
641
* will be an implicit dependency in the other direction, we need to break
642
- * the loop. We can always do this by removing the implicit dependency.
642
+ * the loop. If there are no other objects in the loop then we can remove
643
+ * the implicit dependency and leave the ON SELECT rule non-separate.
643
644
*/
644
645
static void
645
646
repairViewRuleLoop (DumpableObject * viewobj ,
@@ -649,6 +650,29 @@ repairViewRuleLoop(DumpableObject *viewobj,
649
650
removeObjectDependency (ruleobj , viewobj -> dumpId );
650
651
}
651
652
653
+ /*
654
+ * However, if there are other objects in the loop, we must break the loop
655
+ * by making the ON SELECT rule a separately-dumped object.
656
+ *
657
+ * Because findLoop() finds shorter cycles before longer ones, it's likely
658
+ * that we will have previously fired repairViewRuleLoop() and removed the
659
+ * rule's dependency on the view. Put it back to ensure the rule won't be
660
+ * emitted before the view...
661
+ */
662
+ static void
663
+ repairViewRuleMultiLoop (DumpableObject * viewobj ,
664
+ DumpableObject * ruleobj )
665
+ {
666
+ /* remove view's dependency on rule */
667
+ removeObjectDependency (viewobj , ruleobj -> dumpId );
668
+ /* pretend view is a plain table and dump it that way */
669
+ ((TableInfo * ) viewobj )-> relkind = 'r' ; /* RELKIND_RELATION */
670
+ /* mark rule as needing its own dump */
671
+ ((RuleInfo * ) ruleobj )-> separate = true;
672
+ /* put back rule's dependency on view */
673
+ addObjectDependency (ruleobj , viewobj -> dumpId );
674
+ }
675
+
652
676
/*
653
677
* Because we make tables depend on their CHECK constraints, while there
654
678
* will be an automatic dependency in the other direction, we need to break
@@ -765,7 +789,8 @@ repairDependencyLoop(DumpableObject **loop,
765
789
loop [0 ]-> objType == DO_TABLE &&
766
790
loop [1 ]-> objType == DO_RULE &&
767
791
((RuleInfo * ) loop [1 ])-> ev_type == '1' &&
768
- ((RuleInfo * ) loop [1 ])-> is_instead )
792
+ ((RuleInfo * ) loop [1 ])-> is_instead &&
793
+ ((RuleInfo * ) loop [1 ])-> ruletable == (TableInfo * ) loop [0 ])
769
794
{
770
795
repairViewRuleLoop (loop [0 ], loop [1 ]);
771
796
return ;
@@ -774,12 +799,35 @@ repairDependencyLoop(DumpableObject **loop,
774
799
loop [1 ]-> objType == DO_TABLE &&
775
800
loop [0 ]-> objType == DO_RULE &&
776
801
((RuleInfo * ) loop [0 ])-> ev_type == '1' &&
777
- ((RuleInfo * ) loop [0 ])-> is_instead )
802
+ ((RuleInfo * ) loop [0 ])-> is_instead &&
803
+ ((RuleInfo * ) loop [0 ])-> ruletable == (TableInfo * ) loop [1 ])
778
804
{
779
805
repairViewRuleLoop (loop [1 ], loop [0 ]);
780
806
return ;
781
807
}
782
808
809
+ /* Indirect loop involving view and ON SELECT rule */
810
+ if (nLoop > 2 )
811
+ {
812
+ for (i = 0 ; i < nLoop ; i ++ )
813
+ {
814
+ if (loop [i ]-> objType == DO_TABLE )
815
+ {
816
+ for (j = 0 ; j < nLoop ; j ++ )
817
+ {
818
+ if (loop [j ]-> objType == DO_RULE &&
819
+ ((RuleInfo * ) loop [j ])-> ev_type == '1' &&
820
+ ((RuleInfo * ) loop [j ])-> is_instead &&
821
+ ((RuleInfo * ) loop [j ])-> ruletable == (TableInfo * ) loop [i ])
822
+ {
823
+ repairViewRuleMultiLoop (loop [i ], loop [j ]);
824
+ return ;
825
+ }
826
+ }
827
+ }
828
+ }
829
+ }
830
+
783
831
/* Table and CHECK constraint */
784
832
if (nLoop == 2 &&
785
833
loop [0 ]-> objType == DO_TABLE &&
0 commit comments