@@ -70,7 +70,7 @@ static void _selectOutputSchema(ArchiveHandle *AH, const char *schemaName);
7070static void _selectTablespace (ArchiveHandle * AH , const char * tablespace );
7171static void processEncodingEntry (ArchiveHandle * AH , TocEntry * te );
7272static void processStdStringsEntry (ArchiveHandle * AH , TocEntry * te );
73- static teReqs _tocEntryRequired (TocEntry * te , teSection curSection , RestoreOptions * ropt );
73+ static teReqs _tocEntryRequired (TocEntry * te , teSection curSection , ArchiveHandle * AH );
7474static RestorePass _tocEntryRestorePass (TocEntry * te );
7575static bool _tocEntryIsACL (TocEntry * te );
7676static void _disableTriggersIfNecessary (ArchiveHandle * AH , TocEntry * te );
@@ -312,7 +312,7 @@ ProcessArchiveRestoreOptions(Archive *AHX)
312312 if (te -> section != SECTION_NONE )
313313 curSection = te -> section ;
314314
315- te -> reqs = _tocEntryRequired (te , curSection , ropt );
315+ te -> reqs = _tocEntryRequired (te , curSection , AH );
316316 }
317317
318318 /* Enforce strict names checking */
@@ -488,22 +488,15 @@ RestoreArchive(Archive *AHX)
488488 * In createDB mode, issue a DROP *only* for the database as a
489489 * whole. Issuing drops against anything else would be wrong,
490490 * because at this point we're connected to the wrong database.
491- * Conversely, if we're not in createDB mode, we'd better not
492- * issue a DROP against the database at all. (The DATABASE
493- * PROPERTIES entry, if any, works like the DATABASE entry.)
491+ * (The DATABASE PROPERTIES entry, if any, should be treated like
492+ * the DATABASE entry.)
494493 */
495494 if (ropt -> createDB )
496495 {
497496 if (strcmp (te -> desc , "DATABASE" ) != 0 &&
498497 strcmp (te -> desc , "DATABASE PROPERTIES" ) != 0 )
499498 continue ;
500499 }
501- else
502- {
503- if (strcmp (te -> desc , "DATABASE" ) == 0 ||
504- strcmp (te -> desc , "DATABASE PROPERTIES" ) == 0 )
505- continue ;
506- }
507500
508501 /* Otherwise, drop anything that's selected and has a dropStmt */
509502 if (((te -> reqs & (REQ_SCHEMA | REQ_DATA )) != 0 ) && te -> dropStmt )
@@ -752,25 +745,6 @@ restore_toc_entry(ArchiveHandle *AH, TocEntry *te, bool is_parallel)
752745
753746 AH -> currentTE = te ;
754747
755- /* Work out what, if anything, we want from this entry */
756- reqs = te -> reqs ;
757-
758- /*
759- * Ignore DATABASE and related entries unless createDB is specified. We
760- * must check this here, not in _tocEntryRequired, because !createDB
761- * should not prevent emitting these entries to an archive file.
762- */
763- if (!ropt -> createDB &&
764- (strcmp (te -> desc , "DATABASE" ) == 0 ||
765- strcmp (te -> desc , "DATABASE PROPERTIES" ) == 0 ||
766- (strcmp (te -> desc , "ACL" ) == 0 &&
767- strncmp (te -> tag , "DATABASE " , 9 ) == 0 ) ||
768- (strcmp (te -> desc , "COMMENT" ) == 0 &&
769- strncmp (te -> tag , "DATABASE " , 9 ) == 0 ) ||
770- (strcmp (te -> desc , "SECURITY LABEL" ) == 0 &&
771- strncmp (te -> tag , "DATABASE " , 9 ) == 0 )))
772- reqs = 0 ;
773-
774748 /* Dump any relevant dump warnings to stderr */
775749 if (!ropt -> suppressDumpWarnings && strcmp (te -> desc , "WARNING" ) == 0 )
776750 {
@@ -780,6 +754,9 @@ restore_toc_entry(ArchiveHandle *AH, TocEntry *te, bool is_parallel)
780754 write_msg (modulename , "warning from original dump file: %s\n" , te -> copyStmt );
781755 }
782756
757+ /* Work out what, if anything, we want from this entry */
758+ reqs = te -> reqs ;
759+
783760 defnDumped = false;
784761
785762 /*
@@ -1191,7 +1168,7 @@ PrintTOCSummary(Archive *AHX)
11911168 if (te -> section != SECTION_NONE )
11921169 curSection = te -> section ;
11931170 if (ropt -> verbose ||
1194- (_tocEntryRequired (te , curSection , ropt ) & (REQ_SCHEMA | REQ_DATA )) != 0 )
1171+ (_tocEntryRequired (te , curSection , AH ) & (REQ_SCHEMA | REQ_DATA )) != 0 )
11951172 {
11961173 char * sanitized_name ;
11971174 char * sanitized_schema ;
@@ -2824,16 +2801,42 @@ StrictNamesCheck(RestoreOptions *ropt)
28242801 }
28252802}
28262803
2804+ /*
2805+ * Determine whether we want to restore this TOC entry.
2806+ *
2807+ * Returns 0 if entry should be skipped, or some combination of the
2808+ * REQ_SCHEMA and REQ_DATA bits if we want to restore schema and/or data
2809+ * portions of this TOC entry, or REQ_SPECIAL if it's a special entry.
2810+ */
28272811static teReqs
2828- _tocEntryRequired (TocEntry * te , teSection curSection , RestoreOptions * ropt )
2812+ _tocEntryRequired (TocEntry * te , teSection curSection , ArchiveHandle * AH )
28292813{
28302814 teReqs res = REQ_SCHEMA | REQ_DATA ;
2815+ RestoreOptions * ropt = AH -> public .ropt ;
28312816
28322817 /* ENCODING and STDSTRINGS items are treated specially */
28332818 if (strcmp (te -> desc , "ENCODING" ) == 0 ||
28342819 strcmp (te -> desc , "STDSTRINGS" ) == 0 )
28352820 return REQ_SPECIAL ;
28362821
2822+ /*
2823+ * DATABASE and DATABASE PROPERTIES also have a special rule: they are
2824+ * restored in createDB mode, and not restored otherwise, independently of
2825+ * all else.
2826+ */
2827+ if (strcmp (te -> desc , "DATABASE" ) == 0 ||
2828+ strcmp (te -> desc , "DATABASE PROPERTIES" ) == 0 )
2829+ {
2830+ if (ropt -> createDB )
2831+ return REQ_SCHEMA ;
2832+ else
2833+ return 0 ;
2834+ }
2835+
2836+ /*
2837+ * Process exclusions that affect certain classes of TOC entries.
2838+ */
2839+
28372840 /* If it's an ACL, maybe ignore it */
28382841 if (ropt -> aclsSkip && _tocEntryIsACL (te ))
28392842 return 0 ;
@@ -2842,11 +2845,11 @@ _tocEntryRequired(TocEntry *te, teSection curSection, RestoreOptions *ropt)
28422845 if (ropt -> no_publications && strcmp (te -> desc , "PUBLICATION" ) == 0 )
28432846 return 0 ;
28442847
2845- /* If it's security labels , maybe ignore it */
2848+ /* If it's a security label , maybe ignore it */
28462849 if (ropt -> no_security_labels && strcmp (te -> desc , "SECURITY LABEL" ) == 0 )
28472850 return 0 ;
28482851
2849- /* If it's a subcription , maybe ignore it */
2852+ /* If it's a subscription , maybe ignore it */
28502853 if (ropt -> no_subscriptions && strcmp (te -> desc , "SUBSCRIPTION" ) == 0 )
28512854 return 0 ;
28522855
@@ -2870,65 +2873,118 @@ _tocEntryRequired(TocEntry *te, teSection curSection, RestoreOptions *ropt)
28702873 return 0 ;
28712874 }
28722875
2873- /* Check options for selective dump/restore */
2874- if (ropt -> schemaNames .head != NULL )
2875- {
2876- /* If no namespace is specified, it means all. */
2877- if (!te -> namespace )
2878- return 0 ;
2879- if (!(simple_string_list_member (& ropt -> schemaNames , te -> namespace )))
2880- return 0 ;
2881- }
2882-
2883- if (ropt -> schemaExcludeNames .head != NULL &&
2884- te -> namespace &&
2885- simple_string_list_member (& ropt -> schemaExcludeNames , te -> namespace ))
2876+ /* Ignore it if rejected by idWanted[] (cf. SortTocFromFile) */
2877+ if (ropt -> idWanted && !ropt -> idWanted [te -> dumpId - 1 ])
28862878 return 0 ;
28872879
2888- if (ropt -> selTypes )
2880+ /*
2881+ * Check options for selective dump/restore.
2882+ */
2883+ if (strcmp (te -> desc , "ACL" ) == 0 ||
2884+ strcmp (te -> desc , "COMMENT" ) == 0 ||
2885+ strcmp (te -> desc , "SECURITY LABEL" ) == 0 )
28892886 {
2890- if (strcmp (te -> desc , "TABLE" ) == 0 ||
2891- strcmp (te -> desc , "TABLE DATA" ) == 0 ||
2892- strcmp (te -> desc , "VIEW" ) == 0 ||
2893- strcmp (te -> desc , "FOREIGN TABLE" ) == 0 ||
2894- strcmp (te -> desc , "MATERIALIZED VIEW" ) == 0 ||
2895- strcmp (te -> desc , "MATERIALIZED VIEW DATA" ) == 0 ||
2896- strcmp (te -> desc , "SEQUENCE" ) == 0 ||
2897- strcmp (te -> desc , "SEQUENCE SET" ) == 0 )
2887+ /* Database properties react to createDB, not selectivity options. */
2888+ if (strncmp (te -> tag , "DATABASE " , 9 ) == 0 )
28982889 {
2899- if (!ropt -> selTable )
2900- return 0 ;
2901- if (ropt -> tableNames .head != NULL && (!(simple_string_list_member (& ropt -> tableNames , te -> tag ))))
2890+ if (!ropt -> createDB )
29022891 return 0 ;
29032892 }
2904- else if (strcmp (te -> desc , "INDEX" ) == 0 )
2893+ else if (ropt -> schemaNames .head != NULL ||
2894+ ropt -> schemaExcludeNames .head != NULL ||
2895+ ropt -> selTypes )
29052896 {
2906- if (!ropt -> selIndex )
2907- return 0 ;
2908- if (ropt -> indexNames .head != NULL && (!(simple_string_list_member (& ropt -> indexNames , te -> tag ))))
2897+ /*
2898+ * In a selective dump/restore, we want to restore these dependent
2899+ * TOC entry types only if their parent object is being restored.
2900+ * Without selectivity options, we let through everything in the
2901+ * archive. Note there may be such entries with no parent, eg
2902+ * non-default ACLs for built-in objects.
2903+ *
2904+ * This code depends on the parent having been marked already,
2905+ * which should be the case; if it isn't, perhaps due to
2906+ * SortTocFromFile rearrangement, skipping the dependent entry
2907+ * seems prudent anyway.
2908+ *
2909+ * Ideally we'd handle, eg, table CHECK constraints this way too.
2910+ * But it's hard to tell which of their dependencies is the one to
2911+ * consult.
2912+ */
2913+ if (te -> nDeps != 1 ||
2914+ TocIDRequired (AH , te -> dependencies [0 ]) == 0 )
29092915 return 0 ;
29102916 }
2911- else if (strcmp (te -> desc , "FUNCTION" ) == 0 ||
2912- strcmp (te -> desc , "PROCEDURE" ) == 0 )
2917+ }
2918+ else
2919+ {
2920+ /* Apply selective-restore rules for standalone TOC entries. */
2921+ if (ropt -> schemaNames .head != NULL )
29132922 {
2914- if (!ropt -> selFunction )
2923+ /* If no namespace is specified, it means all. */
2924+ if (!te -> namespace )
29152925 return 0 ;
2916- if (ropt -> functionNames . head != NULL && (!( simple_string_list_member (& ropt -> functionNames , te -> tag )) ))
2926+ if (! simple_string_list_member (& ropt -> schemaNames , te -> namespace ))
29172927 return 0 ;
29182928 }
2919- else if (strcmp (te -> desc , "TRIGGER" ) == 0 )
2929+
2930+ if (ropt -> schemaExcludeNames .head != NULL &&
2931+ te -> namespace &&
2932+ simple_string_list_member (& ropt -> schemaExcludeNames , te -> namespace ))
2933+ return 0 ;
2934+
2935+ if (ropt -> selTypes )
29202936 {
2921- if (!ropt -> selTrigger )
2922- return 0 ;
2923- if (ropt -> triggerNames .head != NULL && (!(simple_string_list_member (& ropt -> triggerNames , te -> tag ))))
2937+ if (strcmp (te -> desc , "TABLE" ) == 0 ||
2938+ strcmp (te -> desc , "TABLE DATA" ) == 0 ||
2939+ strcmp (te -> desc , "VIEW" ) == 0 ||
2940+ strcmp (te -> desc , "FOREIGN TABLE" ) == 0 ||
2941+ strcmp (te -> desc , "MATERIALIZED VIEW" ) == 0 ||
2942+ strcmp (te -> desc , "MATERIALIZED VIEW DATA" ) == 0 ||
2943+ strcmp (te -> desc , "SEQUENCE" ) == 0 ||
2944+ strcmp (te -> desc , "SEQUENCE SET" ) == 0 )
2945+ {
2946+ if (!ropt -> selTable )
2947+ return 0 ;
2948+ if (ropt -> tableNames .head != NULL &&
2949+ !simple_string_list_member (& ropt -> tableNames , te -> tag ))
2950+ return 0 ;
2951+ }
2952+ else if (strcmp (te -> desc , "INDEX" ) == 0 )
2953+ {
2954+ if (!ropt -> selIndex )
2955+ return 0 ;
2956+ if (ropt -> indexNames .head != NULL &&
2957+ !simple_string_list_member (& ropt -> indexNames , te -> tag ))
2958+ return 0 ;
2959+ }
2960+ else if (strcmp (te -> desc , "FUNCTION" ) == 0 ||
2961+ strcmp (te -> desc , "AGGREGATE" ) == 0 ||
2962+ strcmp (te -> desc , "PROCEDURE" ) == 0 )
2963+ {
2964+ if (!ropt -> selFunction )
2965+ return 0 ;
2966+ if (ropt -> functionNames .head != NULL &&
2967+ !simple_string_list_member (& ropt -> functionNames , te -> tag ))
2968+ return 0 ;
2969+ }
2970+ else if (strcmp (te -> desc , "TRIGGER" ) == 0 )
2971+ {
2972+ if (!ropt -> selTrigger )
2973+ return 0 ;
2974+ if (ropt -> triggerNames .head != NULL &&
2975+ !simple_string_list_member (& ropt -> triggerNames , te -> tag ))
2976+ return 0 ;
2977+ }
2978+ else
29242979 return 0 ;
29252980 }
2926- else
2927- return 0 ;
29282981 }
29292982
29302983 /*
2931- * Check if we had a dataDumper. Indicates if the entry is schema or data
2984+ * Determine whether the TOC entry contains schema and/or data components,
2985+ * and mask off inapplicable REQ bits. If it had a dataDumper, assume
2986+ * it's both schema and data. Otherwise it's probably schema-only, but
2987+ * there are exceptions.
29322988 */
29332989 if (!te -> hadDumper )
29342990 {
@@ -2952,6 +3008,10 @@ _tocEntryRequired(TocEntry *te, teSection curSection, RestoreOptions *ropt)
29523008 res = res & ~REQ_DATA ;
29533009 }
29543010
3011+ /* If there's no definition command, there's no schema component */
3012+ if (!te -> defn || !te -> defn [0 ])
3013+ res = res & ~REQ_SCHEMA ;
3014+
29553015 /*
29563016 * Special case: <Init> type with <Max OID> tag; this is obsolete and we
29573017 * always ignore it.
@@ -2963,12 +3023,12 @@ _tocEntryRequired(TocEntry *te, teSection curSection, RestoreOptions *ropt)
29633023 if (ropt -> schemaOnly )
29643024 {
29653025 /*
2966- * The sequence_data option overrides schema-only for SEQUENCE SET.
3026+ * The sequence_data option overrides schemaOnly for SEQUENCE SET.
29673027 *
2968- * In binary-upgrade mode, even with schema-only set, we do not mask
2969- * out large objects. Only large object definitions, comments and
2970- * other information should be generated in binary-upgrade mode ( not
2971- * the actual data).
3028+ * In binary-upgrade mode, even with schemaOnly set, we do not mask
3029+ * out large objects. ( Only large object definitions, comments and
3030+ * other metadata should be generated in binary-upgrade mode, not the
3031+ * actual data, but that need not concern us here.)
29723032 */
29733033 if (!(ropt -> sequence_data && strcmp (te -> desc , "SEQUENCE SET" ) == 0 ) &&
29743034 !(ropt -> binary_upgrade &&
@@ -2986,14 +3046,6 @@ _tocEntryRequired(TocEntry *te, teSection curSection, RestoreOptions *ropt)
29863046 if (ropt -> dataOnly )
29873047 res = res & REQ_DATA ;
29883048
2989- /* Mask it if we don't have a schema contribution */
2990- if (!te -> defn || strlen (te -> defn ) == 0 )
2991- res = res & ~REQ_SCHEMA ;
2992-
2993- /* Finally, if there's a per-ID filter, limit based on that as well */
2994- if (ropt -> idWanted && !ropt -> idWanted [te -> dumpId - 1 ])
2995- return 0 ;
2996-
29973049 return res ;
29983050}
29993051
0 commit comments