@@ -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)
312312if (te -> section != SECTION_NONE )
313313curSection = 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 */
495494if (ropt -> createDB )
496495{
497496if (strcmp (te -> desc ,"DATABASE" )!= 0 &&
498497strcmp (te -> desc ,"DATABASE PROPERTIES" )!= 0 )
499498continue ;
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 */
509502if (((te -> reqs & (REQ_SCHEMA |REQ_DATA ))!= 0 )&& te -> dropStmt )
@@ -752,25 +745,6 @@ restore_toc_entry(ArchiveHandle *AH, TocEntry *te, bool is_parallel)
752745
753746AH -> 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 */
775749if (!ropt -> suppressDumpWarnings && strcmp (te -> desc ,"WARNING" )== 0 )
776750{
@@ -780,6 +754,9 @@ restore_toc_entry(ArchiveHandle *AH, TocEntry *te, bool is_parallel)
780754write_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+
783760defnDumped = false;
784761
785762/*
@@ -1191,7 +1168,7 @@ PrintTOCSummary(Archive *AHX)
11911168if (te -> section != SECTION_NONE )
11921169curSection = te -> section ;
11931170if (ropt -> verbose ||
1194- (_tocEntryRequired (te ,curSection ,ropt )& (REQ_SCHEMA |REQ_DATA ))!= 0 )
1171+ (_tocEntryRequired (te ,curSection ,AH )& (REQ_SCHEMA |REQ_DATA ))!= 0 )
11951172{
11961173char * sanitized_name ;
11971174char * 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{
28302814teReqs res = REQ_SCHEMA |REQ_DATA ;
2815+ RestoreOptions * ropt = AH -> public .ropt ;
28312816
28322817/* ENCODING and STDSTRINGS items are treated specially */
28332818if (strcmp (te -> desc ,"ENCODING" )== 0 ||
28342819strcmp (te -> desc ,"STDSTRINGS" )== 0 )
28352820return 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 */
28382841if (ropt -> aclsSkip && _tocEntryIsACL (te ))
28392842return 0 ;
@@ -2842,11 +2845,11 @@ _tocEntryRequired(TocEntry *te, teSection curSection, RestoreOptions *ropt)
28422845if (ropt -> no_publications && strcmp (te -> desc ,"PUBLICATION" )== 0 )
28432846return 0 ;
28442847
2845- /* If it's securitylabels , maybe ignore it */
2848+ /* If it'sa securitylabel , maybe ignore it */
28462849if (ropt -> no_security_labels && strcmp (te -> desc ,"SECURITY LABEL" )== 0 )
28472850return 0 ;
28482851
2849- /* If it's asubcription , maybe ignore it */
2852+ /* If it's asubscription , maybe ignore it */
28502853if (ropt -> no_subscriptions && strcmp (te -> desc ,"SUBSCRIPTION" )== 0 )
28512854return 0 ;
28522855
@@ -2870,65 +2873,118 @@ _tocEntryRequired(TocEntry *te, teSection curSection, RestoreOptions *ropt)
28702873return 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 ])
28862878return 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 )
29022891return 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 )
29092915return 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 )
29152925return 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 ))
29172927return 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
29242979return 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 */
29332989if (!te -> hadDumper )
29342990{
@@ -2952,6 +3008,10 @@ _tocEntryRequired(TocEntry *te, teSection curSection, RestoreOptions *ropt)
29523008res = 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)
29633023if (ropt -> schemaOnly )
29643024{
29653025/*
2966- * The sequence_data option overridesschema-only for SEQUENCE SET.
3026+ * The sequence_data option overridesschemaOnly for SEQUENCE SET.
29673027 *
2968- * In binary-upgrade mode, even withschema-only set, we do not mask
2969- * out large objects. Only large object definitions, comments and
2970- * otherinformation should be generated in binary-upgrade mode ( not
2971- *the actual data).
3028+ * In binary-upgrade mode, even withschemaOnly set, we do not mask
3029+ * out large objects.( Only large object definitions, comments and
3030+ * othermetadata should be generated in binary-upgrade mode, not the
3031+ * actual data, but that need not concern us here.)
29723032 */
29733033if (!(ropt -> sequence_data && strcmp (te -> desc ,"SEQUENCE SET" )== 0 )&&
29743034!(ropt -> binary_upgrade &&
@@ -2986,14 +3046,6 @@ _tocEntryRequired(TocEntry *te, teSection curSection, RestoreOptions *ropt)
29863046if (ropt -> dataOnly )
29873047res = 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-
29973049return res ;
29983050}
29993051