On Wed, Dec 14, 2011 at 10:57:25AM -0500, Robert Haas wrote:
> On Wed, Dec 14, 2011 at 4:45 AM, Magnus Hagander <mag...@hagander.net> wrote:
> >>> * There are a number of things that are always written to stdout, that
> >>> there is no way to redirect. In some cases it's interactive prompts -
> >>> makes sense - but also for example the output of \timing goes to
> >>> stdout always. Is there some specific logic behind what/when this
> >>> should be done?
> >>
> >> Everything that is not an error goes to stdout, no?  Except the query
> >> output, if you change it.
> >>
> >> Maybe the way to do what you want is to invent a new setting that
> >> temporarily changes stdout.
> >
> > Yeah, that might be it. Or I need separate settings for "put errors in
> > the query output stream" and "put non-query-output-but-also-non-errors
> > in the query output stream". The effect would be the same, I guess...
> 
> That seems an awful lot harder (and messier) than just changing the
> all the call sites to use the same error-reporting function.

I have done as you suggested with the attached patch.

-- 
  Bruce Momjian  <br...@momjian.us>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com

  + It's impossible for everything to be true. +
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
new file mode 100644
index 205bb50..dc04399
*** a/src/bin/psql/command.c
--- b/src/bin/psql/command.c
*************** HandleSlashCmds(PsqlScanState scan_state
*** 110,116 ****
  	if (status == PSQL_CMD_UNKNOWN)
  	{
  		if (pset.cur_cmd_interactive)
! 			fprintf(stderr, _("Invalid command \\%s. Try \\? for help.\n"), cmd);
  		else
  			psql_error("invalid command \\%s\n", cmd);
  		status = PSQL_CMD_ERROR;
--- 110,116 ----
  	if (status == PSQL_CMD_UNKNOWN)
  	{
  		if (pset.cur_cmd_interactive)
! 			psql_error("Invalid command \\%s. Try \\? for help.\n", cmd);
  		else
  			psql_error("invalid command \\%s\n", cmd);
  		status = PSQL_CMD_ERROR;
*************** exec_command(const char *cmd,
*** 904,910 ****
  
  		if (strcmp(pw1, pw2) != 0)
  		{
! 			fprintf(stderr, _("Passwords didn't match.\n"));
  			success = false;
  		}
  		else
--- 904,910 ----
  
  		if (strcmp(pw1, pw2) != 0)
  		{
! 			psql_error("Passwords didn't match.\n");
  			success = false;
  		}
  		else
*************** exec_command(const char *cmd,
*** 922,928 ****
  
  			if (!encrypted_password)
  			{
! 				fprintf(stderr, _("Password encryption failed.\n"));
  				success = false;
  			}
  			else
--- 922,928 ----
  
  			if (!encrypted_password)
  			{
! 				psql_error("Password encryption failed.\n");
  				success = false;
  			}
  			else
*************** exec_command(const char *cmd,
*** 1441,1447 ****
  		while ((value = psql_scan_slash_option(scan_state,
  											   OT_NORMAL, NULL, true)))
  		{
! 			fprintf(stderr, "+ opt(%d) = |%s|\n", i++, value);
  			free(value);
  		}
  	}
--- 1441,1447 ----
  		while ((value = psql_scan_slash_option(scan_state,
  											   OT_NORMAL, NULL, true)))
  		{
! 			psql_error("+ opt(%d) = |%s|\n", i++, value);
  			free(value);
  		}
  	}
*************** do_connect(char *dbname, char *user, cha
*** 1519,1525 ****
  		 *	to connect to the wrong database by using defaults, so require
  		 *	all parameters to be specified.
  		 */
! 		fputs(_("All connection parameters must be supplied because no database connection exists\n"), stderr);
  		return false;
  	}
  
--- 1519,1526 ----
  		 *	to connect to the wrong database by using defaults, so require
  		 *	all parameters to be specified.
  		 */
! 		psql_error("All connection parameters must be supplied because no "
! 				   "database connection exists\n");
  		return false;
  	}
  
*************** do_connect(char *dbname, char *user, cha
*** 1608,1614 ****
  
  			/* pset.db is left unmodified */
  			if (o_conn)
! 				fputs(_("Previous connection kept\n"), stderr);
  		}
  		else
  		{
--- 1609,1615 ----
  
  			/* pset.db is left unmodified */
  			if (o_conn)
! 				psql_error("Previous connection kept\n");
  		}
  		else
  		{
diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c
new file mode 100644
index 330d5ce..f5bd0f6
*** a/src/bin/psql/common.c
--- b/src/bin/psql/common.c
*************** pg_strdup(const char *string)
*** 42,48 ****
  
  	if (!string)
  	{
! 		fprintf(stderr, _("%s: pg_strdup: cannot duplicate null pointer (internal error)\n"),
  				pset.progname);
  		exit(EXIT_FAILURE);
  	}
--- 42,48 ----
  
  	if (!string)
  	{
! 		psql_error("%s: pg_strdup: cannot duplicate null pointer (internal error)\n",
  				pset.progname);
  		exit(EXIT_FAILURE);
  	}
*************** psql_error(const char *fmt,...)
*** 161,167 ****
  	va_list		ap;
  
  	fflush(stdout);
! 	if (pset.queryFout != stdout)
  		fflush(pset.queryFout);
  
  	if (pset.inputfile)
--- 161,167 ----
  	va_list		ap;
  
  	fflush(stdout);
! 	if (pset.queryFout && pset.queryFout != stdout)
  		fflush(pset.queryFout);
  
  	if (pset.inputfile)
*************** static PGcancel *volatile cancelConn = N
*** 219,224 ****
--- 219,225 ----
  static CRITICAL_SECTION cancelConnLock;
  #endif
  
+ /* Used from signal handlers, no buffering */
  #define write_stderr(str)	write(fileno(stderr), str, strlen(str))
  
  
*************** CheckConnection(void)
*** 350,368 ****
  			exit(EXIT_BADCONN);
  		}
  
! 		fputs(_("The connection to the server was lost. Attempting reset: "), stderr);
  		PQreset(pset.db);
  		OK = ConnectionUp();
  		if (!OK)
  		{
! 			fputs(_("Failed.\n"), stderr);
  			PQfinish(pset.db);
  			pset.db = NULL;
  			ResetCancelConn();
  			UnsyncVariables();
  		}
  		else
! 			fputs(_("Succeeded.\n"), stderr);
  	}
  
  	return OK;
--- 351,369 ----
  			exit(EXIT_BADCONN);
  		}
  
! 		psql_error("The connection to the server was lost. Attempting reset: ");
  		PQreset(pset.db);
  		OK = ConnectionUp();
  		if (!OK)
  		{
! 			psql_error("Failed.\n");
  			PQfinish(pset.db);
  			pset.db = NULL;
  			ResetCancelConn();
  			UnsyncVariables();
  		}
  		else
! 			psql_error("Succeeded.\n");
  	}
  
  	return OK;
*************** SendQuery(const char *query)
*** 910,916 ****
  	{
  		if (on_error_rollback_warning == false && pset.sversion < 80000)
  		{
! 			fprintf(stderr, _("The server (version %d.%d) does not support savepoints for ON_ERROR_ROLLBACK.\n"),
  					pset.sversion / 10000, (pset.sversion / 100) % 100);
  			on_error_rollback_warning = true;
  		}
--- 911,917 ----
  	{
  		if (on_error_rollback_warning == false && pset.sversion < 80000)
  		{
! 			psql_error("The server (version %d.%d) does not support savepoints for ON_ERROR_ROLLBACK.\n",
  					pset.sversion / 10000, (pset.sversion / 100) % 100);
  			on_error_rollback_warning = true;
  		}
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
new file mode 100644
index 14985ba..c2bcc5a
*** a/src/bin/psql/describe.c
--- b/src/bin/psql/describe.c
*************** describeTablespaces(const char *pattern,
*** 132,138 ****
  
  	if (pset.sversion < 80000)
  	{
! 		fprintf(stderr, _("The server (version %d.%d) does not support tablespaces.\n"),
  				pset.sversion / 10000, (pset.sversion / 100) % 100);
  		return true;
  	}
--- 132,138 ----
  
  	if (pset.sversion < 80000)
  	{
! 		psql_error("The server (version %d.%d) does not support tablespaces.\n",
  				pset.sversion / 10000, (pset.sversion / 100) % 100);
  		return true;
  	}
*************** describeFunctions(const char *functypes,
*** 219,231 ****
  
  	if (strlen(functypes) != strspn(functypes, "antwS+"))
  	{
! 		fprintf(stderr, _("\\df only takes [antwS+] as options\n"));
  		return true;
  	}
  
  	if (showWindow && pset.sversion < 80400)
  	{
! 		fprintf(stderr, _("\\df does not take a \"w\" option with server version %d.%d\n"),
  				pset.sversion / 10000, (pset.sversion / 100) % 100);
  		return true;
  	}
--- 219,231 ----
  
  	if (strlen(functypes) != strspn(functypes, "antwS+"))
  	{
! 		psql_error("\\df only takes [antwS+] as options\n");
  		return true;
  	}
  
  	if (showWindow && pset.sversion < 80400)
  	{
! 		psql_error("\\df does not take a \"w\" option with server version %d.%d\n",
  				pset.sversion / 10000, (pset.sversion / 100) % 100);
  		return true;
  	}
*************** listDefaultACLs(const char *pattern)
*** 786,792 ****
  
  	if (pset.sversion < 90000)
  	{
! 		fprintf(stderr, _("The server (version %d.%d) does not support altering default privileges.\n"),
  				pset.sversion / 10000, (pset.sversion / 100) % 100);
  		return true;
  	}
--- 786,792 ----
  
  	if (pset.sversion < 90000)
  	{
! 		psql_error("The server (version %d.%d) does not support altering default privileges.\n",
  				pset.sversion / 10000, (pset.sversion / 100) % 100);
  		return true;
  	}
*************** describeTableDetails(const char *pattern
*** 1052,1058 ****
  	if (PQntuples(res) == 0)
  	{
  		if (!pset.quiet)
! 			fprintf(stderr, _("Did not find any relation named \"%s\".\n"),
  					pattern);
  		PQclear(res);
  		return false;
--- 1052,1058 ----
  	if (PQntuples(res) == 0)
  	{
  		if (!pset.quiet)
! 			psql_error("Did not find any relation named \"%s\".\n",
  					pattern);
  		PQclear(res);
  		return false;
*************** describeOneTableDetails(const char *sche
*** 1225,1232 ****
  	if (PQntuples(res) == 0)
  	{
  		if (!pset.quiet)
! 			fprintf(stderr, _("Did not find any relation with OID %s.\n"),
! 					oid);
  		goto error_return;
  	}
  
--- 1225,1231 ----
  	if (PQntuples(res) == 0)
  	{
  		if (!pset.quiet)
! 			psql_error("Did not find any relation with OID %s.\n", oid);
  		goto error_return;
  	}
  
*************** listCollations(const char *pattern, bool
*** 3126,3132 ****
  
  	if (pset.sversion < 90100)
  	{
! 		fprintf(stderr, _("The server (version %d.%d) does not support collations.\n"),
  				pset.sversion / 10000, (pset.sversion / 100) % 100);
  		return true;
  	}
--- 3125,3131 ----
  
  	if (pset.sversion < 90100)
  	{
! 		psql_error("The server (version %d.%d) does not support collations.\n",
  				pset.sversion / 10000, (pset.sversion / 100) % 100);
  		return true;
  	}
*************** listTSParsers(const char *pattern, bool
*** 3257,3263 ****
  
  	if (pset.sversion < 80300)
  	{
! 		fprintf(stderr, _("The server (version %d.%d) does not support full text search.\n"),
  				pset.sversion / 10000, (pset.sversion / 100) % 100);
  		return true;
  	}
--- 3256,3262 ----
  
  	if (pset.sversion < 80300)
  	{
! 		psql_error("The server (version %d.%d) does not support full text search.\n",
  				pset.sversion / 10000, (pset.sversion / 100) % 100);
  		return true;
  	}
*************** listTSParsersVerbose(const char *pattern
*** 3334,3340 ****
  	if (PQntuples(res) == 0)
  	{
  		if (!pset.quiet)
! 			fprintf(stderr, _("Did not find any text search parser named \"%s\".\n"),
  					pattern);
  		PQclear(res);
  		return false;
--- 3333,3339 ----
  	if (PQntuples(res) == 0)
  	{
  		if (!pset.quiet)
! 			psql_error("Did not find any text search parser named \"%s\".\n",
  					pattern);
  		PQclear(res);
  		return false;
*************** listTSDictionaries(const char *pattern,
*** 3490,3496 ****
  
  	if (pset.sversion < 80300)
  	{
! 		fprintf(stderr, _("The server (version %d.%d) does not support full text search.\n"),
  				pset.sversion / 10000, (pset.sversion / 100) % 100);
  		return true;
  	}
--- 3489,3495 ----
  
  	if (pset.sversion < 80300)
  	{
! 		psql_error("The server (version %d.%d) does not support full text search.\n",
  				pset.sversion / 10000, (pset.sversion / 100) % 100);
  		return true;
  	}
*************** listTSTemplates(const char *pattern, boo
*** 3558,3564 ****
  
  	if (pset.sversion < 80300)
  	{
! 		fprintf(stderr, _("The server (version %d.%d) does not support full text search.\n"),
  				pset.sversion / 10000, (pset.sversion / 100) % 100);
  		return true;
  	}
--- 3557,3563 ----
  
  	if (pset.sversion < 80300)
  	{
! 		psql_error("The server (version %d.%d) does not support full text search.\n",
  				pset.sversion / 10000, (pset.sversion / 100) % 100);
  		return true;
  	}
*************** listTSConfigs(const char *pattern, bool
*** 3626,3632 ****
  
  	if (pset.sversion < 80300)
  	{
! 		fprintf(stderr, _("The server (version %d.%d) does not support full text search.\n"),
  				pset.sversion / 10000, (pset.sversion / 100) % 100);
  		return true;
  	}
--- 3625,3631 ----
  
  	if (pset.sversion < 80300)
  	{
! 		psql_error("The server (version %d.%d) does not support full text search.\n",
  				pset.sversion / 10000, (pset.sversion / 100) % 100);
  		return true;
  	}
*************** listTSConfigsVerbose(const char *pattern
*** 3704,3710 ****
  	if (PQntuples(res) == 0)
  	{
  		if (!pset.quiet)
! 			fprintf(stderr, _("Did not find any text search configuration named \"%s\".\n"),
  					pattern);
  		PQclear(res);
  		return false;
--- 3703,3709 ----
  	if (PQntuples(res) == 0)
  	{
  		if (!pset.quiet)
! 			psql_error("Did not find any text search configuration named \"%s\".\n",
  					pattern);
  		PQclear(res);
  		return false;
*************** listForeignDataWrappers(const char *patt
*** 3824,3830 ****
  
  	if (pset.sversion < 80400)
  	{
! 		fprintf(stderr, _("The server (version %d.%d) does not support foreign-data wrappers.\n"),
  				pset.sversion / 10000, (pset.sversion / 100) % 100);
  		return true;
  	}
--- 3823,3829 ----
  
  	if (pset.sversion < 80400)
  	{
! 		psql_error("The server (version %d.%d) does not support foreign-data wrappers.\n",
  				pset.sversion / 10000, (pset.sversion / 100) % 100);
  		return true;
  	}
*************** listForeignServers(const char *pattern,
*** 3904,3910 ****
  
  	if (pset.sversion < 80400)
  	{
! 		fprintf(stderr, _("The server (version %d.%d) does not support foreign servers.\n"),
  				pset.sversion / 10000, (pset.sversion / 100) % 100);
  		return true;
  	}
--- 3903,3909 ----
  
  	if (pset.sversion < 80400)
  	{
! 		psql_error("The server (version %d.%d) does not support foreign servers.\n",
  				pset.sversion / 10000, (pset.sversion / 100) % 100);
  		return true;
  	}
*************** listUserMappings(const char *pattern, bo
*** 3983,3989 ****
  
  	if (pset.sversion < 80400)
  	{
! 		fprintf(stderr, _("The server (version %d.%d) does not support user mappings.\n"),
  				pset.sversion / 10000, (pset.sversion / 100) % 100);
  		return true;
  	}
--- 3982,3988 ----
  
  	if (pset.sversion < 80400)
  	{
! 		psql_error("The server (version %d.%d) does not support user mappings.\n",
  				pset.sversion / 10000, (pset.sversion / 100) % 100);
  		return true;
  	}
*************** listForeignTables(const char *pattern, b
*** 4041,4047 ****
  
  	if (pset.sversion < 90100)
  	{
! 		fprintf(stderr, _("The server (version %d.%d) does not support foreign tables.\n"),
  				pset.sversion / 10000, (pset.sversion / 100) % 100);
  		return true;
  	}
--- 4040,4046 ----
  
  	if (pset.sversion < 90100)
  	{
! 		psql_error("The server (version %d.%d) does not support foreign tables.\n",
  				pset.sversion / 10000, (pset.sversion / 100) % 100);
  		return true;
  	}
*************** listExtensions(const char *pattern)
*** 4115,4121 ****
  
  	if (pset.sversion < 90100)
  	{
! 		fprintf(stderr, _("The server (version %d.%d) does not support extensions.\n"),
  				pset.sversion / 10000, (pset.sversion / 100) % 100);
  		return true;
  	}
--- 4114,4120 ----
  
  	if (pset.sversion < 90100)
  	{
! 		psql_error("The server (version %d.%d) does not support extensions.\n",
  				pset.sversion / 10000, (pset.sversion / 100) % 100);
  		return true;
  	}
*************** listExtensionContents(const char *patter
*** 4169,4175 ****
  
  	if (pset.sversion < 90100)
  	{
! 		fprintf(stderr, _("The server (version %d.%d) does not support extensions.\n"),
  				pset.sversion / 10000, (pset.sversion / 100) % 100);
  		return true;
  	}
--- 4168,4174 ----
  
  	if (pset.sversion < 90100)
  	{
! 		psql_error("The server (version %d.%d) does not support extensions.\n",
  				pset.sversion / 10000, (pset.sversion / 100) % 100);
  		return true;
  	}
*************** listExtensionContents(const char *patter
*** 4196,4205 ****
  		if (!pset.quiet)
  		{
  			if (pattern)
! 				fprintf(stderr, _("Did not find any extension named \"%s\".\n"),
  						pattern);
  			else
! 				fprintf(stderr, _("Did not find any extensions.\n"));
  		}
  		PQclear(res);
  		return false;
--- 4195,4204 ----
  		if (!pset.quiet)
  		{
  			if (pattern)
! 				psql_error("Did not find any extension named \"%s\".\n",
  						pattern);
  			else
! 				psql_error("Did not find any extensions.\n");
  		}
  		PQclear(res);
  		return false;
diff --git a/src/bin/psql/large_obj.c b/src/bin/psql/large_obj.c
new file mode 100644
index ea95be1..dc6ff37
*** a/src/bin/psql/large_obj.c
--- b/src/bin/psql/large_obj.c
*************** do_lo_export(const char *loid_arg, const
*** 155,161 ****
  	/* of course this status is documented nowhere :( */
  	if (status != 1)
  	{
! 		fputs(PQerrorMessage(pset.db), stderr);
  		return fail_lo_xact("\\lo_export", own_transaction);
  	}
  
--- 155,161 ----
  	/* of course this status is documented nowhere :( */
  	if (status != 1)
  	{
! 		psql_error("%s", PQerrorMessage(pset.db));
  		return fail_lo_xact("\\lo_export", own_transaction);
  	}
  
*************** do_lo_import(const char *filename_arg, c
*** 190,196 ****
  
  	if (loid == InvalidOid)
  	{
! 		fputs(PQerrorMessage(pset.db), stderr);
  		return fail_lo_xact("\\lo_import", own_transaction);
  	}
  
--- 190,196 ----
  
  	if (loid == InvalidOid)
  	{
! 		psql_error("%s", PQerrorMessage(pset.db));
  		return fail_lo_xact("\\lo_import", own_transaction);
  	}
  
*************** do_lo_unlink(const char *loid_arg)
*** 252,258 ****
  
  	if (status == -1)
  	{
! 		fputs(PQerrorMessage(pset.db), stderr);
  		return fail_lo_xact("\\lo_unlink", own_transaction);
  	}
  
--- 252,258 ----
  
  	if (status == -1)
  	{
! 		psql_error("%s", PQerrorMessage(pset.db));
  		return fail_lo_xact("\\lo_unlink", own_transaction);
  	}
  
-- 
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