From be690e291d59e8d0c9f4df59abe09f1ff6cc0da9 Mon Sep 17 00:00:00 2001
From: Robert Haas <rhaas@postgresql.org>
Date: Thu, 9 Aug 2012 09:59:45 -0400
Subject: [PATCH] Make psql -1 < file behave as expected.

Previously, the -1 option was silently ignored.

Also, emit an error if -1 is used in a context where it won't be
respected, to avoid user confusion.

Original patch by Fabien COELHO, but this version is quite different
from the original submission.
---
 doc/src/sgml/ref/psql-ref.sgml | 10 +++++-----
 src/bin/psql/command.c         |  8 +++++---
 src/bin/psql/help.c            |  2 +-
 src/bin/psql/startup.c         | 27 +++++++++++++++++++++++----
 4 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index 1ba5ea8dabc..340328f4b56 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -512,11 +512,11 @@ PostgreSQL documentation
       <term><option>--single-transaction</option></term>
       <listitem>
        <para>
-        When <application>psql</application> executes a script with the
-        <option>-f</> option, adding this option wraps
-        <command>BEGIN</>/<command>COMMIT</> around the script to execute it
-        as a single transaction.  This ensures that either all the commands
-        complete successfully, or no changes are applied.
+        When <application>psql</application> executes a script, adding
+        this option wraps <command>BEGIN</>/<command>COMMIT</> around the
+        script to execute it as a single transaction.  This ensures that
+        either all the commands complete successfully, or no changes are
+        applied.
        </para>
 
        <para>
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 8abadb26c49..6ead800aeb1 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -2043,9 +2043,11 @@ process_file(char *filename, bool single_txn, bool use_relative_path)
 	PGresult   *res;
 
 	if (!filename)
-		return EXIT_FAILURE;
-
-	if (strcmp(filename, "-") != 0)
+	{
+		fd = stdin;
+		filename = NULL;
+	}
+	else if (strcmp(filename, "-") != 0)
 	{
 		canonicalize_path(filename);
 
diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c
index 3ebf7cc5262..8793201570d 100644
--- a/src/bin/psql/help.c
+++ b/src/bin/psql/help.c
@@ -97,7 +97,7 @@ usage(void)
 	printf(_("  -V, --version            output version information, then exit\n"));
 	printf(_("  -X, --no-psqlrc          do not read startup file (~/.psqlrc)\n"));
 	printf(_("  -1 (\"one\"), --single-transaction\n"
-			 "                           execute command file as a single transaction\n"));
+			 "                           execute as a single transaction (if non-interactive)\n"));
 	printf(_("  -?, --help               show this help, then exit\n"));
 
 	printf(_("\nInput and output options:\n"));
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index 9a6306b8cf2..8ba8f704218 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -150,6 +150,27 @@ main(int argc, char *argv[])
 
 	parse_psql_options(argc, argv, &options);
 
+	/*
+	 * If no action was specified and we're in non-interactive mode, treat
+	 * it as if the user had specified "-f -".  This lets single-transaction
+	 * mode work in this case.
+	 */
+	if (options.action == ACT_NOTHING && pset.notty)
+	{
+		options.action = ACT_FILE;
+		options.action_string = NULL;
+	}
+
+	/* Bail out if -1 was specified but will be ignored. */
+	if (options.single_txn && options.action != ACT_FILE)
+	{
+		if (options.action == ACT_NOTHING)
+			fprintf(stderr,_("%s: -1 can only be used in non-interactive mode\n"), pset.progname);
+		else
+			fprintf(stderr,_("%s: -1 is incompatible with -c and -l\n"), pset.progname);
+		exit(EXIT_FAILURE);
+	}
+
 	if (!pset.popt.topt.fieldSep.separator &&
 		!pset.popt.topt.fieldSep.separator_zero)
 	{
@@ -309,11 +330,9 @@ main(int argc, char *argv[])
 			process_psqlrc(argv[0]);
 
 		connection_warnings(true);
-		if (!pset.quiet && !pset.notty)
+		if (!pset.quiet)
 			printf(_("Type \"help\" for help.\n\n"));
-		if (!pset.notty)
-			initializeInput(options.no_readline ? 0 : 1);
-
+		initializeInput(options.no_readline ? 0 : 1);
 		successResult = MainLoop(stdin);
 	}
 
-- 
GitLab