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

Reply via email to