@@ -72,7 +72,7 @@ static void processEncodingEntry(ArchiveHandle *AH, TocEntry *te);
72
72
static void processStdStringsEntry (ArchiveHandle * AH , TocEntry * te );
73
73
static void processSearchPathEntry (ArchiveHandle * AH , TocEntry * te );
74
74
static int _tocEntryRequired (TocEntry * te , teSection curSection , ArchiveHandle * AH );
75
- static RestorePass _tocEntryRestorePass (TocEntry * te );
75
+ static RestorePass _tocEntryRestorePass (ArchiveHandle * AH , TocEntry * te );
76
76
static bool _tocEntryIsACL (TocEntry * te );
77
77
static void _disableTriggersIfNecessary (ArchiveHandle * AH , TocEntry * te );
78
78
static void _enableTriggersIfNecessary (ArchiveHandle * AH , TocEntry * te );
@@ -102,7 +102,8 @@ static void pending_list_append(TocEntry *l, TocEntry *te);
102
102
static void pending_list_remove (TocEntry * te );
103
103
static int TocEntrySizeCompareQsort (const void * p1 , const void * p2 );
104
104
static int TocEntrySizeCompareBinaryheap (void * p1 , void * p2 , void * arg );
105
- static void move_to_ready_heap (TocEntry * pending_list ,
105
+ static void move_to_ready_heap (ArchiveHandle * AH ,
106
+ TocEntry * pending_list ,
106
107
binaryheap * ready_heap ,
107
108
RestorePass pass );
108
109
static TocEntry * pop_next_work_item (binaryheap * ready_heap ,
@@ -748,7 +749,7 @@ RestoreArchive(Archive *AHX)
748
749
if ((te -> reqs & (REQ_SCHEMA | REQ_DATA | REQ_STATS )) == 0 )
749
750
continue ; /* ignore if not to be dumped at all */
750
751
751
- switch (_tocEntryRestorePass (te ))
752
+ switch (_tocEntryRestorePass (AH , te ))
752
753
{
753
754
case RESTORE_PASS_MAIN :
754
755
(void ) restore_toc_entry (AH , te , false);
@@ -767,7 +768,7 @@ RestoreArchive(Archive *AHX)
767
768
for (te = AH -> toc -> next ; te != AH -> toc ; te = te -> next )
768
769
{
769
770
if ((te -> reqs & (REQ_SCHEMA | REQ_DATA | REQ_STATS )) != 0 &&
770
- _tocEntryRestorePass (te ) == RESTORE_PASS_ACL )
771
+ _tocEntryRestorePass (AH , te ) == RESTORE_PASS_ACL )
771
772
(void ) restore_toc_entry (AH , te , false);
772
773
}
773
774
}
@@ -777,7 +778,7 @@ RestoreArchive(Archive *AHX)
777
778
for (te = AH -> toc -> next ; te != AH -> toc ; te = te -> next )
778
779
{
779
780
if ((te -> reqs & (REQ_SCHEMA | REQ_DATA | REQ_STATS )) != 0 &&
780
- _tocEntryRestorePass (te ) == RESTORE_PASS_POST_ACL )
781
+ _tocEntryRestorePass (AH , te ) == RESTORE_PASS_POST_ACL )
781
782
(void ) restore_toc_entry (AH , te , false);
782
783
}
783
784
}
@@ -3219,7 +3220,7 @@ _tocEntryRequired(TocEntry *te, teSection curSection, ArchiveHandle *AH)
3219
3220
* See notes with the RestorePass typedef in pg_backup_archiver.h.
3220
3221
*/
3221
3222
static RestorePass
3222
- _tocEntryRestorePass (TocEntry * te )
3223
+ _tocEntryRestorePass (ArchiveHandle * AH , TocEntry * te )
3223
3224
{
3224
3225
/* "ACL LANGUAGE" was a crock emitted only in PG 7.4 */
3225
3226
if (strcmp (te -> desc , "ACL" ) == 0 ||
@@ -3240,6 +3241,26 @@ _tocEntryRestorePass(TocEntry *te)
3240
3241
strncmp (te -> tag , "EVENT TRIGGER " , 14 ) == 0 )
3241
3242
return RESTORE_PASS_POST_ACL ;
3242
3243
3244
+ /*
3245
+ * If statistics data is dependent on materialized view data, it must be
3246
+ * deferred to RESTORE_PASS_POST_ACL.
3247
+ */
3248
+ if (strcmp (te -> desc , "STATISTICS DATA" ) == 0 )
3249
+ {
3250
+ for (int i = 0 ; i < te -> nDeps ; i ++ )
3251
+ {
3252
+ DumpId depid = te -> dependencies [i ];
3253
+
3254
+ if (depid <= AH -> maxDumpId && AH -> tocsByDumpId [depid ] != NULL )
3255
+ {
3256
+ TocEntry * otherte = AH -> tocsByDumpId [depid ];
3257
+
3258
+ if (strcmp (otherte -> desc , "MATERIALIZED VIEW DATA" ) == 0 )
3259
+ return RESTORE_PASS_POST_ACL ;
3260
+ }
3261
+ }
3262
+ }
3263
+
3243
3264
/* All else can be handled in the main pass. */
3244
3265
return RESTORE_PASS_MAIN ;
3245
3266
}
@@ -4249,7 +4270,7 @@ restore_toc_entries_prefork(ArchiveHandle *AH, TocEntry *pending_list)
4249
4270
* not set skipped_some in this case, since by assumption no main-pass
4250
4271
* items could depend on these.
4251
4272
*/
4252
- if (_tocEntryRestorePass (next_work_item ) != RESTORE_PASS_MAIN )
4273
+ if (_tocEntryRestorePass (AH , next_work_item ) != RESTORE_PASS_MAIN )
4253
4274
do_now = false;
4254
4275
4255
4276
if (do_now )
@@ -4331,7 +4352,7 @@ restore_toc_entries_parallel(ArchiveHandle *AH, ParallelState *pstate,
4331
4352
* process in the current restore pass.
4332
4353
*/
4333
4354
AH -> restorePass = RESTORE_PASS_MAIN ;
4334
- move_to_ready_heap (pending_list , ready_heap , AH -> restorePass );
4355
+ move_to_ready_heap (AH , pending_list , ready_heap , AH -> restorePass );
4335
4356
4336
4357
/*
4337
4358
* main parent loop
@@ -4380,7 +4401,7 @@ restore_toc_entries_parallel(ArchiveHandle *AH, ParallelState *pstate,
4380
4401
/* Advance to next restore pass */
4381
4402
AH -> restorePass ++ ;
4382
4403
/* That probably allows some stuff to be made ready */
4383
- move_to_ready_heap (pending_list , ready_heap , AH -> restorePass );
4404
+ move_to_ready_heap (AH , pending_list , ready_heap , AH -> restorePass );
4384
4405
/* Loop around to see if anything's now ready */
4385
4406
continue ;
4386
4407
}
@@ -4551,7 +4572,8 @@ TocEntrySizeCompareBinaryheap(void *p1, void *p2, void *arg)
4551
4572
* which applies the same logic one-at-a-time.)
4552
4573
*/
4553
4574
static void
4554
- move_to_ready_heap (TocEntry * pending_list ,
4575
+ move_to_ready_heap (ArchiveHandle * AH ,
4576
+ TocEntry * pending_list ,
4555
4577
binaryheap * ready_heap ,
4556
4578
RestorePass pass )
4557
4579
{
@@ -4564,7 +4586,7 @@ move_to_ready_heap(TocEntry *pending_list,
4564
4586
next_te = te -> pending_next ;
4565
4587
4566
4588
if (te -> depCount == 0 &&
4567
- _tocEntryRestorePass (te ) == pass )
4589
+ _tocEntryRestorePass (AH , te ) == pass )
4568
4590
{
4569
4591
/* Remove it from pending_list ... */
4570
4592
pending_list_remove (te );
@@ -4958,7 +4980,7 @@ reduce_dependencies(ArchiveHandle *AH, TocEntry *te,
4958
4980
* memberships changed.
4959
4981
*/
4960
4982
if (otherte -> depCount == 0 &&
4961
- _tocEntryRestorePass (otherte ) == AH -> restorePass &&
4983
+ _tocEntryRestorePass (AH , otherte ) == AH -> restorePass &&
4962
4984
otherte -> pending_prev != NULL &&
4963
4985
ready_heap != NULL )
4964
4986
{
0 commit comments