Hi I am sending a new patch - without checking wildcard chars.
Regards Pavel 2015-07-23 7:22 GMT+02:00 Kyotaro HORIGUCHI <horiguchi.kyot...@lab.ntt.co.jp >: > Hello, > > > > 2015-07-19 20:54 GMT+02:00 Pavel Stehule <pavel.steh...@gmail.com>: > > >> I am sending updated version. It implements new long option > > >> "--strict-names". If this option is used, then for any entered name > > >> (without any wildcard char) must be found least one object. This > option has > > >> not impact on patters (has wildcards chars). > > I share the same option with Tom that it should behave in same > way regardless of the appearance of wildcards. > > You replied Tom as this > > > the behave is same - only one real identifier is allowed > > But the description above about this patch apparently says that > they are differently handled. And > expand_(schema|table)_name_patterns does the further differently > thing from both of Tom's suggestion and what mentioned in your > reply to that. I will mention for this topic again in this mail. > > # Might "only one real ident is allowed" mean "at most one > # match", but not "exactly one match"? > > They do like this when strict-names. > > - Not allow no match for non-wildcarded names. > > - Allow no match for any wildcarded name spec and finally > allowing *all* of them don't match anyting. > > This looks to me quite confusing. > > > >> When this option is not used, > > >> then behave is 100% same as before (with same numbers of SQL queries > for -t > > >> option). It is based on Oleksandr's documentation (and lightly > modified > > >> philosophy), and cleaned my previous patch. A test on wildchard > existency > > >> "strcspn(cell->val, "?*")" cannot be used, because it doesn't > calculate > > >> quotes (but a replace has few lines only). > > The new name "processSQLName" looks a bit > bogus. processSQLNameIntenral would be a name commonly seen in > such cases. > > > >> There is a possibility to remove a wildcard char test and require > least > > >> one entry for patters too. But I am thinking, when somebody > explicitly uses > > >> any wildcard, then he calculate with a possibility of empty result. > > Why do you think so? Wild cards are usually used to glob multiple > names at once. One or more matches are expected for many or > perhaps most cases, I think. Since so, if someone anticipate that > some of his patterns have no match, I think he shouldn't specify > --strict-names option at all. > > Furthermore, I don't think no one wants to use both wildcarded > and non-wildcarded name specs at once but this is a little out of > scope. > > I'd like to have opinions from others about this point. > > > > other variant is using --strict-names behave as default (and implement > > > negative option like --disable-strict-names or some similar). > > This contradicts Josh's request. (which I'm not totally agree:p) > > > Note: originally I though, we have to fix it and change the default > behave. > > But with special option, we don't need it. This option in help is signal > > for user, so some is risky. > > regards, > > > -- > Kyotaro Horiguchi > NTT Open Source Software Center >
diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml new file mode 100644 index 7467e86..7c071fb *** a/doc/src/sgml/ref/pg_dump.sgml --- b/doc/src/sgml/ref/pg_dump.sgml *************** PostgreSQL documentation *** 545,550 **** --- 545,566 ---- </varlistentry> <varlistentry> + <term><option>--strict-names</></term> + <listitem> + <para> + Require that table and/or schema match at least one entity each. + Without any entity in the database to be dumped, an error message + is printed and dump is aborted. + </para> + <para> + This option has no effect on the exclude table and schema patterns + (and also <option>--exclude-table-data</>): not matching any entities + isn't considered an error. + </para> + </listitem> + </varlistentry> + + <varlistentry> <term><option>-T <replaceable class="parameter">table</replaceable></option></term> <term><option>--exclude-table=<replaceable class="parameter">table</replaceable></option></term> <listitem> diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c new file mode 100644 index 0e036b8..54618fa *** a/src/bin/pg_dump/pg_dump.c --- b/src/bin/pg_dump/pg_dump.c *************** static const char *username_subquery; *** 97,102 **** --- 97,105 ---- /* 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_mode = 0; + /* * Object inclusion/exclusion lists * *************** static void setup_connection(Archive *AH *** 131,140 **** static ArchiveFormat parseArchiveFormat(const char *format, ArchiveMode *mode); static void expand_schema_name_patterns(Archive *fout, SimpleStringList *patterns, ! SimpleOidList *oids); static void expand_table_name_patterns(Archive *fout, SimpleStringList *patterns, ! SimpleOidList *oids); 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); --- 134,145 ---- static ArchiveFormat parseArchiveFormat(const char *format, ArchiveMode *mode); static void expand_schema_name_patterns(Archive *fout, SimpleStringList *patterns, ! SimpleOidList *oids, ! bool strict_mode); static void expand_table_name_patterns(Archive *fout, SimpleStringList *patterns, ! SimpleOidList *oids, ! bool strict_mode); 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); *************** main(int argc, char **argv) *** 332,337 **** --- 337,343 ---- {"section", required_argument, NULL, 5}, {"serializable-deferrable", no_argument, &dopt.serializable_deferrable, 1}, {"snapshot", required_argument, NULL, 6}, + {"strict-mode", no_argument, &strict_mode, 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}, *************** main(int argc, char **argv) *** 684,710 **** if (schema_include_patterns.head != NULL) { expand_schema_name_patterns(fout, &schema_include_patterns, ! &schema_include_oids); 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); /* 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); 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); expand_table_name_patterns(fout, &tabledata_exclude_patterns, ! &tabledata_exclude_oids); /* non-matching exclusion patterns aren't an error */ --- 690,721 ---- if (schema_include_patterns.head != NULL) { expand_schema_name_patterns(fout, &schema_include_patterns, ! &schema_include_oids, ! strict_mode); 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, ! 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, ! strict_mode); 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, ! false); expand_table_name_patterns(fout, &tabledata_exclude_patterns, ! &tabledata_exclude_oids, ! false); /* non-matching exclusion patterns aren't an error */ *************** help(const char *progname) *** 899,904 **** --- 910,917 ---- 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-mode 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")); *************** parseArchiveFormat(const char *format, A *** 1129,1135 **** static void expand_schema_name_patterns(Archive *fout, SimpleStringList *patterns, ! SimpleOidList *oids) { PQExpBuffer query; PGresult *res; --- 1142,1149 ---- static void expand_schema_name_patterns(Archive *fout, SimpleStringList *patterns, ! SimpleOidList *oids, ! bool strict_mode) { PQExpBuffer query; PGresult *res; *************** expand_schema_name_patterns(Archive *fou *** 1145,1182 **** 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. */ 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); ! for (i = 0; i < PQntuples(res); i++) ! { ! simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0))); } - PQclear(res); destroyPQExpBuffer(query); } /* * Find the OIDs of all tables matching the given list of patterns, ! * and append them to the given OID list. */ static void expand_table_name_patterns(Archive *fout, ! SimpleStringList *patterns, SimpleOidList *oids) { PQExpBuffer query; PGresult *res; --- 1159,1199 ---- query = createPQExpBuffer(); /* ! * This might sometimes result in duplicate entries in the OID list, ! * but we don't care. */ for (cell = patterns->head; cell; cell = cell->next) { 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); ! if (strict_mode && PQntuples(res) == 0) ! exit_horribly(NULL, "Schema \"%s\" not found.\n", cell->val); ! for (i = 0; i < PQntuples(res); i++) ! { ! simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0))); ! } ! ! PQclear(res); ! resetPQExpBuffer(query); } destroyPQExpBuffer(query); } /* * Find the OIDs of all tables matching the given list of patterns, ! * and append them to the given OID list. */ static void expand_table_name_patterns(Archive *fout, ! SimpleStringList *patterns, SimpleOidList *oids, ! bool strict_mode) { PQExpBuffer query; PGresult *res; *************** expand_table_name_patterns(Archive *fout *** 1189,1202 **** 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. */ 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" --- 1206,1224 ---- query = createPQExpBuffer(); /* + * In this case we expect possibly longer list of patterns. If it is not + * necessary, we try to minimize number of SQL executions and try to build + * one larger query. But strict_mode requires immediate exec for any pattern. + * * We use UNION ALL rather than UNION; 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 (!strict_mode && cell != patterns->head) appendPQExpBufferStr(query, "UNION ALL\n"); + appendPQExpBuffer(query, "SELECT c.oid" "\nFROM pg_catalog.pg_class c" *************** expand_table_name_patterns(Archive *fout *** 1207,1222 **** 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); ! for (i = 0; i < PQntuples(res); i++) { ! simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0))); } - PQclear(res); destroyPQExpBuffer(query); } --- 1229,1263 ---- processSQLNamePattern(GetConnection(fout), query, cell->val, true, false, "n.nspname", "c.relname", NULL, "pg_catalog.pg_table_is_visible(c.oid)"); ! if (strict_mode) ! { ! res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); ! if (strict_mode && PQntuples(res) == 0) ! exit_horribly(NULL, "Table \"%s\" not found.\n", cell->val); ! for (i = 0; i < PQntuples(res); i++) ! { ! simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0))); ! } ! ! PQclear(res); ! resetPQExpBuffer(query); ! } ! } ! ! if (!strict_mode) { ! res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); ! ! for (i = 0; i < PQntuples(res); i++) ! { ! simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0))); ! } ! ! PQclear(res); } destroyPQExpBuffer(query); }
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers