Re: multiple -f support

Started by Mark Wongover 15 years ago7 messages
#1Mark Wong
markwkm@gmail.com
1 attachment(s)

Hi all,

I took a stab at changing this up a little bit. I pushed the logic
that David introduced down into process_file(). In doing so I changed
up the declaration of process_file() to accept an additional parameter
specifying how many files are being passed to the function. Doing it
this way also makes use of the logic for the current single
transaction flag without turning it into dead code.

I also added a check to return EXIT_FAILURE if any error was thrown
from any of the sql files used, thus stopping execution of any further
file. Gabrielle tells me the error echoed in this event is not clear
so there is still a little more work that needs to be done.

Regards,
Mark

Attachments:

psql-f-v2.patchapplication/octet-stream; name=psql-f-v2.patchDownload
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 8e9880f..3ad1d9e 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -691,7 +691,7 @@ exec_command(const char *cmd,
 		else
 		{
 			expand_tilde(&fname);
-			success = (process_file(fname, false) == EXIT_SUCCESS);
+			success = (process_file((char **) fname, 1, false) == EXIT_SUCCESS);
 			free(fname);
 		}
 	}
@@ -1714,32 +1714,15 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf, bool *edited)
  * MainLoop() error code.
  */
 int
-process_file(char *filename, bool single_txn)
+process_file(char **filename, int num_files, bool single_txn)
 {
-	FILE	   *fd;
-	int			result;
+	int			i;
+	int			result = EXIT_FAILURE;
 	char	   *oldfilename;
 	PGresult   *res;
 
-	if (!filename)
-		return EXIT_FAILURE;
-
-	if (strcmp(filename, "-") != 0)
-	{
-		canonicalize_path(filename);
-		fd = fopen(filename, PG_BINARY_R);
-	}
-	else
-		fd = stdin;
-
-	if (!fd)
-	{
-		psql_error("%s: %s\n", filename, strerror(errno));
-		return EXIT_FAILURE;
-	}
 
 	oldfilename = pset.inputfile;
-	pset.inputfile = filename;
 
 	if (single_txn)
 	{
@@ -1752,7 +1735,35 @@ process_file(char *filename, bool single_txn)
 			PQclear(res);
 	}
 
-	result = MainLoop(fd);
+	for (i = 0; i < num_files; i++)
+	{
+		FILE *fd;
+
+		if (!filename[i])
+			return EXIT_FAILURE;
+
+		if (strcmp(filename[i], "-") != 0)
+		{
+			canonicalize_path(filename[i]);
+			fd = fopen(filename[i], PG_BINARY_R);
+		}
+		else
+			fd = stdin;
+
+		if (!fd)
+		{
+			psql_error("%s: %s\n", filename[i], strerror(errno));
+			return EXIT_FAILURE;
+		}
+
+		pset.inputfile = filename[i];
+
+		result = MainLoop(fd);
+		if (result != EXIT_SUCCESS)
+			return EXIT_FAILURE;
+
+		fclose(fd);
+	}
 
 	if (single_txn)
 	{
@@ -1765,7 +1776,6 @@ process_file(char *filename, bool single_txn)
 			PQclear(res);
 	}
 
-	fclose(fd);
 	pset.inputfile = oldfilename;
 	return result;
 }
diff --git a/src/bin/psql/command.h b/src/bin/psql/command.h
index 09093b3..1467190 100644
--- a/src/bin/psql/command.h
+++ b/src/bin/psql/command.h
@@ -27,7 +27,7 @@ typedef enum _backslashResult
 extern backslashResult HandleSlashCmds(PsqlScanState scan_state,
 				PQExpBuffer query_buf);
 
-extern int	process_file(char *filename, bool single_txn);
+extern int	process_file(char **filename, int num_files, bool single_txn);
 
 extern bool do_pset(const char *param,
 		const char *value,
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index 61c7f11..31969f1 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -43,6 +43,8 @@ PsqlSettings pset;
 #define PSQLRC		"psqlrc.conf"
 #endif
 
+#define FILE_ALLOC_BLOCKS 16
+
 /*
  * Structures to pass information between the option parsing routine
  * and the main function
@@ -68,6 +70,8 @@ struct adhoc_opts
 	bool		no_readline;
 	bool		no_psqlrc;
 	bool		single_txn;
+	int			num_files;
+	char	  **files;
 };
 
 static void parse_psql_options(int argc, char *argv[],
@@ -243,14 +247,16 @@ main(int argc, char *argv[])
 	 */
 
 	/*
-	 * process file given by -f
+	 * process file(s) given by -f
 	 */
 	if (options.action == ACT_FILE)
 	{
 		if (!options.no_psqlrc)
 			process_psqlrc(argv[0]);
 
-		successResult = process_file(options.action_string, options.single_txn);
+		successResult = process_file(options.files, options.num_files,
+				options.single_txn);
+		free(options.files);
 	}
 
 	/*
@@ -398,7 +404,12 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options)
 				break;
 			case 'f':
 				options->action = ACT_FILE;
-				options->action_string = optarg;
+				options->num_files++;
+				if (!((options->num_files - 1) % FILE_ALLOC_BLOCKS)) {
+					options->files = realloc(options->files, sizeof(char *) *
+							(options->num_files + FILE_ALLOC_BLOCKS));
+				}
+				options->files[options->num_files - 1] = optarg;
 				break;
 			case 'F':
 				pset.popt.topt.fieldSep = pg_strdup(optarg);
@@ -598,9 +609,9 @@ process_psqlrc_file(char *filename)
 	sprintf(psqlrc, "%s-%s", filename, PG_VERSION);
 
 	if (access(psqlrc, R_OK) == 0)
-		(void) process_file(psqlrc, false);
+		(void) process_file((char **) psqlrc, 1, false);
 	else if (access(filename, R_OK) == 0)
-		(void) process_file(filename, false);
+		(void) process_file((char **) filename, 1, false);
 	free(psqlrc);
 }
 
#2Bruce Momjian
bruce@momjian.us
In reply to: Mark Wong (#1)

I assume having psql support multiple -f files is not a high priority or
something we don't want.

---------------------------------------------------------------------------

Mark Wong wrote:

Hi all,

I took a stab at changing this up a little bit. I pushed the logic
that David introduced down into process_file(). In doing so I changed
up the declaration of process_file() to accept an additional parameter
specifying how many files are being passed to the function. Doing it
this way also makes use of the logic for the current single
transaction flag without turning it into dead code.

I also added a check to return EXIT_FAILURE if any error was thrown
from any of the sql files used, thus stopping execution of any further
file. Gabrielle tells me the error echoed in this event is not clear
so there is still a little more work that needs to be done.

Regards,
Mark

[ Attachment, skipping... ]

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

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

+ It's impossible for everything to be true. +

#3Robert Haas
robertmhaas@gmail.com
In reply to: Bruce Momjian (#2)

On Sun, Feb 6, 2011 at 11:16 AM, Bruce Momjian <bruce@momjian.us> wrote:

I assume having psql support multiple -f files is not a high priority or
something we don't want.

IIRC, nobody objected to the basic concept, and it seems useful. I
thought we were pretty close to committing something along those lines
at one point, actually. I don't remember exactly where the wheels
came off.

Maybe a TODO?

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

#4Simon Riggs
simon@2ndQuadrant.com
In reply to: Robert Haas (#3)

On Sun, 2011-02-06 at 12:07 -0500, Robert Haas wrote:

On Sun, Feb 6, 2011 at 11:16 AM, Bruce Momjian <bruce@momjian.us> wrote:

I assume having psql support multiple -f files is not a high priority or
something we don't want.

IIRC, nobody objected to the basic concept, and it seems useful. I
thought we were pretty close to committing something along those lines
at one point, actually. I don't remember exactly where the wheels
came off.

Maybe a TODO?

As Andrew pointed out, IIRC, you can do this with a little shell
programming already.

--
Simon Riggs http://www.2ndQuadrant.com/books/
PostgreSQL Development, 24x7 Support, Training and Services

#5Bruce Momjian
bruce@momjian.us
In reply to: Robert Haas (#3)

Robert Haas wrote:

On Sun, Feb 6, 2011 at 11:16 AM, Bruce Momjian <bruce@momjian.us> wrote:

I assume having psql support multiple -f files is not a high priority or
something we don't want.

IIRC, nobody objected to the basic concept, and it seems useful. I
thought we were pretty close to committing something along those lines
at one point, actually. I don't remember exactly where the wheels
came off.

Maybe a TODO?

Added to the psql section:

|Allow processing of multiple -f (file) options

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

+ It's impossible for everything to be true. +

#6David Christensen
david@endpoint.com
In reply to: Bruce Momjian (#5)

On Mar 11, 2011, at 6:17 AM, Bruce Momjian wrote:

Robert Haas wrote:

On Sun, Feb 6, 2011 at 11:16 AM, Bruce Momjian <bruce@momjian.us> wrote:

I assume having psql support multiple -f files is not a high priority or
something we don't want.

IIRC, nobody objected to the basic concept, and it seems useful. I
thought we were pretty close to committing something along those lines
at one point, actually. I don't remember exactly where the wheels
came off.

Maybe a TODO?

Added to the psql section:

|Allow processing of multiple -f (file) options

The original patch was a fairly trivial WIP one, which I started working on to add support for multiple -c flags interspersed as well. I haven't looked at it in quite some time, though; there had been some concerns about how it worked in single-transaction mode and some other issues I don't recall off the top of my head.

On this topic, I was thinking that it may be useful to provide an alternate multi-file syntax, a la git, with any argument following '--' in the argument list being interpreted as a file to process; i.e.,:

$ psql -U user [option] database -- file1.sql file2.sql file3.sql

This would allow things like shell expansion to work as expected:

$ ls
01-schema.sql 02-data1.sql 03-fixups.sql

$ psql database -- *.sql

etc.

Regards,

David
--
David Christensen
End Point Corporation
david@endpoint.com

#7Robert Haas
robertmhaas@gmail.com
In reply to: David Christensen (#6)

On Fri, Mar 11, 2011 at 11:30 AM, David Christensen <david@endpoint.com> wrote:

On Mar 11, 2011, at 6:17 AM, Bruce Momjian wrote:

Robert Haas wrote:

On Sun, Feb 6, 2011 at 11:16 AM, Bruce Momjian <bruce@momjian.us> wrote:

I assume having psql support multiple -f files is not a high priority or
something we don't want.

IIRC, nobody objected to the basic concept, and it seems useful.  I
thought we were pretty close to committing something along those lines
at one point, actually.  I don't remember exactly where the wheels
came off.

Maybe a TODO?

Added to the psql section:

      |Allow processing of multiple -f (file) options

The original patch was a fairly trivial WIP one, which I started working on to add support for multiple -c flags interspersed as well.  I haven't looked at it in quite some time, though; there had been some concerns about how it worked in single-transaction mode and some other issues I don't recall off the top of my head.

On this topic, I was thinking that it may be useful to provide an alternate multi-file syntax, a la git, with any argument following '--' in the argument list being interpreted as a file to process; i.e.,:

$ psql -U user [option] database -- file1.sql file2.sql file3.sql

This would allow things like shell expansion to work as expected:

$ ls
01-schema.sql    02-data1.sql    03-fixups.sql

$ psql database -- *.sql

etc.

+1.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company