static void mark_create_done(ArchiveHandle *AH, TocEntry *te);
static void inhibit_data_for_failed_table(ArchiveHandle *AH, TocEntry *te);
+static void StrictNamesCheck(RestoreOptions *ropt);
+
+
/*
* Allocate a new DumpOptions block containing all default values.
*/
te->reqs = _tocEntryRequired(te, curSection, ropt);
}
+
+ /* Enforce strict names checking */
+ if (ropt->strict_names)
+ StrictNamesCheck(ropt);
}
/* Public */
}
}
+ /* Enforce strict names checking */
+ if (ropt->strict_names)
+ StrictNamesCheck(ropt);
+
if (ropt->filename)
RestoreOutput(AH, sav);
}
te->defn);
}
+static void
+StrictNamesCheck(RestoreOptions *ropt)
+{
+ const char *missing_name;
+
+ Assert(ropt->strict_names);
+
+ if (ropt->schemaNames.head != NULL)
+ {
+ missing_name = simple_string_list_not_touched(&ropt->schemaNames);
+ if (missing_name != NULL)
+ exit_horribly(modulename, "Schema \"%s\" not found.\n", missing_name);
+ }
+
+ if (ropt->tableNames.head != NULL)
+ {
+ missing_name = simple_string_list_not_touched(&ropt->tableNames);
+ if (missing_name != NULL)
+ exit_horribly(modulename, "Table \"%s\" not found.\n", missing_name);
+ }
+
+ if (ropt->indexNames.head != NULL)
+ {
+ missing_name = simple_string_list_not_touched(&ropt->indexNames);
+ if (missing_name != NULL)
+ exit_horribly(modulename, "Index \"%s\" not found.\n", missing_name);
+ }
+
+ if (ropt->functionNames.head != NULL)
+ {
+ missing_name = simple_string_list_not_touched(&ropt->functionNames);
+ if (missing_name != NULL)
+ exit_horribly(modulename, "Function \"%s\" not found.\n", missing_name);
+ }
+
+ if (ropt->triggerNames.head != NULL)
+ {
+ missing_name = simple_string_list_not_touched(&ropt->triggerNames);
+ if (missing_name != NULL)
+ exit_horribly(modulename, "Trigger \"%s\" not found.\n", missing_name);
+ }
+}
+
static teReqs
_tocEntryRequired(TocEntry *te, teSection curSection, RestoreOptions *ropt)
{
/* obsolete as of 7.3: */
static Oid g_last_builtin_oid; /* value of the last builtin oid */
+/* The specified names/patterns should to match at least one entity */
+static int strict_names = 0;
+
/*
* Object inclusion/exclusion lists
*
static ArchiveFormat parseArchiveFormat(const char *format, ArchiveMode *mode);
static void expand_schema_name_patterns(Archive *fout,
SimpleStringList *patterns,
- SimpleOidList *oids);
+ SimpleOidList *oids,
+ bool strict_names);
static void expand_table_name_patterns(Archive *fout,
SimpleStringList *patterns,
- SimpleOidList *oids);
+ SimpleOidList *oids,
+ bool strict_names);
static NamespaceInfo *findNamespace(Archive *fout, Oid nsoid, Oid objoid);
static void dumpTableData(Archive *fout, DumpOptions *dopt, TableDataInfo *tdinfo);
static void refreshMatViewData(Archive *fout, TableDataInfo *tdinfo);
{"section", required_argument, NULL, 5},
{"serializable-deferrable", no_argument, &dopt.serializable_deferrable, 1},
{"snapshot", required_argument, NULL, 6},
+ {"strict-names", no_argument, &strict_names, 1},
{"use-set-session-authorization", no_argument, &dopt.use_setsessauth, 1},
{"no-security-labels", no_argument, &dopt.no_security_labels, 1},
{"no-synchronized-snapshots", no_argument, &dopt.no_synchronized_snapshots, 1},
if (schema_include_patterns.head != NULL)
{
expand_schema_name_patterns(fout, &schema_include_patterns,
- &schema_include_oids);
+ &schema_include_oids,
+ strict_names);
if (schema_include_oids.head == NULL)
exit_horribly(NULL, "No matching schemas were found\n");
}
expand_schema_name_patterns(fout, &schema_exclude_patterns,
- &schema_exclude_oids);
+ &schema_exclude_oids,
+ false);
/* non-matching exclusion patterns aren't an error */
/* Expand table selection patterns into OID lists */
if (table_include_patterns.head != NULL)
{
expand_table_name_patterns(fout, &table_include_patterns,
- &table_include_oids);
+ &table_include_oids,
+ strict_names);
if (table_include_oids.head == NULL)
exit_horribly(NULL, "No matching tables were found\n");
}
expand_table_name_patterns(fout, &table_exclude_patterns,
- &table_exclude_oids);
+ &table_exclude_oids,
+ false);
expand_table_name_patterns(fout, &tabledata_exclude_patterns,
- &tabledata_exclude_oids);
+ &tabledata_exclude_oids,
+ false);
/* non-matching exclusion patterns aren't an error */
printf(_(" --section=SECTION dump named section (pre-data, data, or post-data)\n"));
printf(_(" --serializable-deferrable wait until the dump can run without anomalies\n"));
printf(_(" --snapshot=SNAPSHOT use given synchronous snapshot for the dump\n"));
+ printf(_(" --strict-names require table and/or schema include patterns to\n"
+ " match at least one entity each\n"));
printf(_(" --use-set-session-authorization\n"
" use SET SESSION AUTHORIZATION commands instead of\n"
" ALTER OWNER commands to set ownership\n"));
static void
expand_schema_name_patterns(Archive *fout,
SimpleStringList *patterns,
- SimpleOidList *oids)
+ SimpleOidList *oids,
+ bool strict_names)
{
PQExpBuffer query;
PGresult *res;
query = createPQExpBuffer();
/*
- * We use UNION ALL rather than UNION; this might sometimes result in
- * duplicate entries in the OID list, but we don't care.
+ * This might sometimes result in duplicate entries in the OID list,
+ * but we don't care.
*/
for (cell = patterns->head; cell; cell = cell->next)
{
- if (cell != patterns->head)
- appendPQExpBufferStr(query, "UNION ALL\n");
appendPQExpBuffer(query,
"SELECT oid FROM pg_catalog.pg_namespace n\n");
processSQLNamePattern(GetConnection(fout), query, cell->val, false,
false, NULL, "n.nspname", NULL, NULL);
- }
- res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
+ res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
+ if (strict_names && PQntuples(res) == 0)
+ exit_horribly(NULL, "No matching table(s) were found for pattern \"%s\"\n", cell->val);
- for (i = 0; i < PQntuples(res); i++)
- {
- simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0)));
+ for (i = 0; i < PQntuples(res); i++)
+ {
+ simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0)));
+ }
+
+ PQclear(res);
+ resetPQExpBuffer(query);
}
- PQclear(res);
destroyPQExpBuffer(query);
}
/*
* Find the OIDs of all tables matching the given list of patterns,
- * and append them to the given OID list.
+ * and append them to the given OID list.
*/
static void
expand_table_name_patterns(Archive *fout,
- SimpleStringList *patterns, SimpleOidList *oids)
+ SimpleStringList *patterns, SimpleOidList *oids,
+ bool strict_names)
{
PQExpBuffer query;
PGresult *res;
query = createPQExpBuffer();
/*
- * We use UNION ALL rather than UNION; this might sometimes result in
- * duplicate entries in the OID list, but we don't care.
+ * this might sometimes result in duplicate entries in the OID list,
+ * but we don't care.
*/
for (cell = patterns->head; cell; cell = cell->next)
{
- if (cell != patterns->head)
- appendPQExpBufferStr(query, "UNION ALL\n");
appendPQExpBuffer(query,
"SELECT c.oid"
"\nFROM pg_catalog.pg_class c"
processSQLNamePattern(GetConnection(fout), query, cell->val, true,
false, "n.nspname", "c.relname", NULL,
"pg_catalog.pg_table_is_visible(c.oid)");
- }
- res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
+ res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
+ if (strict_names && PQntuples(res) == 0)
+ exit_horribly(NULL, "No matching table(s) were found for pattern \"%s\"\n", cell->val);
- for (i = 0; i < PQntuples(res); i++)
- {
- simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0)));
+ for (i = 0; i < PQntuples(res); i++)
+ {
+ simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0)));
+ }
+
+ PQclear(res);
+ resetPQExpBuffer(query);
}
- PQclear(res);
destroyPQExpBuffer(query);
}
static int outputNoTablespaces = 0;
static int use_setsessauth = 0;
static int no_security_labels = 0;
+ static int strict_names = 0;
struct option cmdopts[] = {
{"clean", 0, NULL, 'c'},
{"no-tablespaces", no_argument, &outputNoTablespaces, 1},
{"role", required_argument, NULL, 2},
{"section", required_argument, NULL, 3},
+ {"strict-names", no_argument, &strict_names, 1},
{"use-set-session-authorization", no_argument, &use_setsessauth, 1},
{"no-security-labels", no_argument, &no_security_labels, 1},
exit_nicely(1);
}
opts->if_exists = if_exists;
+ opts->strict_names = strict_names;
if (opts->formatName)
{
printf(_(" --no-security-labels do not restore security labels\n"));
printf(_(" --no-tablespaces do not restore tablespace assignments\n"));
printf(_(" --section=SECTION restore named section (pre-data, data, or post-data)\n"));
+ printf(_(" --strict-names require table and/or schema include patterns to\n"
+ " match at least one entity each\n"));
printf(_(" --use-set-session-authorization\n"
" use SET SESSION AUTHORIZATION commands instead of\n"
" ALTER OWNER commands to set ownership\n"));