Hi

2015-08-26 13:12 GMT+02:00 Pavel Stehule <pavel.steh...@gmail.com>:

> Hi
>
> 2015-07-29 21:05 GMT+02:00 Pavel Stehule <pavel.steh...@gmail.com>:
>
>> Hi
>>
>> here is proof concept patch
>>
>> It should be cleaned, but it demonstrates a work well
>>
>> [pavel@localhost psql]$ ./psql  -C 'select 10 x; select 20 y;'  -C "\l"
>> postgres
>>  x
>> ----
>>  10
>> (1 row)
>>
>>  y
>> ----
>>  20
>> (1 row)
>>
>>                                   List of databases
>>    Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access
>> privileges
>>
>> -----------+----------+----------+-------------+-------------+-----------------------
>>  postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
>>  template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
>> =c/postgres          +
>>            |          |          |             |             |
>> postgres=CTc/postgres
>>  template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
>> =c/postgres          +
>>            |          |          |             |             |
>> postgres=CTc/postgres
>> (3 rows)
>>
>>
>> 2015-07-28 18:46 GMT+02:00 Andrew Dunstan <and...@dunslane.net>:
>>
>>>
>>> On 07/28/2015 11:52 AM, Pavel Stehule wrote:
>>>
>>>>
>>>>
>>>> 2015-07-28 15:16 GMT+02:00 Andrew Dunstan <and...@dunslane.net <mailto:
>>>> and...@dunslane.net>>:
>>>>
>>>>
>>>>     On 07/28/2015 12:08 AM, Pavel Stehule wrote:
>>>>
>>>>
>>>>
>>>>         2015-07-28 5:24 GMT+02:00 Pavel Stehule
>>>>         <pavel.steh...@gmail.com <mailto:pavel.steh...@gmail.com>
>>>>         <mailto:pavel.steh...@gmail.com
>>>>         <mailto:pavel.steh...@gmail.com>>>:
>>>>
>>>>
>>>>
>>>>             2015-07-27 21:57 GMT+02:00 Andrew Dunstan
>>>>         <and...@dunslane.net <mailto:and...@dunslane.net>
>>>>             <mailto:and...@dunslane.net <mailto:and...@dunslane.net>>>:
>>>>
>>>>
>>>>
>>>>                 On 07/27/2015 02:53 PM, Pavel Stehule wrote:
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>                     I am trying to run parallel execution
>>>>
>>>>                     psql -At -c "select datname from pg_database"
>>>>         postgres |
>>>>                     xargs -n 1 -P 3 psql -c "select current_database()"
>>>>
>>>>
>>>>
>>>>
>>>>                 I don't think it's going to be a hugely important
>>>>         feature, but
>>>>                 I don't see a problem with creating a new option (-C
>>>> seems
>>>>                 fine) which would have the same effect as if the
>>>> arguments
>>>>                 were contatenated into a file which is then used with
>>>>         -f. IIRC
>>>>                 -c has some special characteristics which means it's
>>>>         probably
>>>>                 best not to try to extend it for this feature.
>>>>
>>>>
>>>>             ok, I'll try to write patch.
>>>>
>>>>
>>>>         I have a question. Can be -C option multiple?
>>>>
>>>>         The SQL is without problem, but what about \x command?
>>>>
>>>>         postgres=# \dt \dn select 10;
>>>>         No relations found.
>>>>         List of schemas
>>>>         ┌──────┬───────┐
>>>>         │ Name │ Owner │
>>>>         ╞══════╪═══════╡
>>>>         └──────┴───────┘
>>>>         (0 rows)
>>>>
>>>>         \dn: extra argument "10;" ignored
>>>>
>>>>
>>>>
>>>>     I don't understand the question.
>>>>
>>>>     You should include one sql or psql command per -C option, ISTM. e.g.
>>>>
>>>>         psql -C '\dt' -C '\dn' -C 'select 10;'
>>>>
>>>>
>>>>     Isn't that what we're talking about with this whole proposal?
>>>>
>>>>
>>>>
>>>> I am searching some agreement, how to solve a current "-c" limits. I am
>>>> 100% for >>> psql -C '\dt' -C '\dn' -C 'select 10;' <<<
>>>>
>>>>
>>>>
>>> I think you're probably best off leaving -c alone. If there are issues
>>> to be solved for -c they should be handled separately from the feature we
>>> agree on.
>>>
>>> cheers
>>>
>>> andrew
>>>
>>>
>>>
>>>
>>
> here is finished patch - cleaned, tested - the significant change is using
> -g --group-command instead "-C"
>
> [pavel@localhost psql]$ ./psql postgres -g "select 10; select 20" -g
> "select 30"
>  ?column?
> ----------
>        10
> (1 row)
>
>  ?column?
> ----------
>        20
> (1 row)
>
>  ?column?
> ----------
>        30
> (1 row)
>
> Regards
>
>
with -1 option support




> Pavel
>
commit bef661b7c822f4fe9f004bf55645a3e47e514bc8
Author: Pavel Stehule <pavel.steh...@gooddata.com>
Date:   Wed Aug 26 13:03:56 2015 +0200

    inital

diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index f996865..750c4ae 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -223,6 +223,20 @@ EOF
     </varlistentry>
 
     <varlistentry>
+      <term><option>-g <replaceable class="parameter">command(s)</replaceable></></term>
+      <term><option>--group-command=<replaceable class="parameter">command(s)</replaceable></></term>
+      <listitem>
+      <para>
+      Specifies that <application>psql</application> is to execute one or
+      more command strings, <replaceable class="parameter">commands</replaceable>,
+      and then exit. This is useful in shell scripts. Start-up files
+      (<filename>psqlrc</filename> and <filename>~/.psqlrc</filename>) are
+      ignored with this option.
+      </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
       <term><option>-h <replaceable class="parameter">hostname</replaceable></></term>
       <term><option>--host=<replaceable class="parameter">hostname</replaceable></></term>
       <listitem>
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 6181a61..277e980 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -2292,7 +2292,6 @@ process_file(char *filename, bool single_txn, bool use_relative_path)
 	int			result;
 	char	   *oldfilename;
 	char		relpath[MAXPGPATH];
-	PGresult   *res;
 
 	if (!filename)
 	{
@@ -2337,37 +2336,8 @@ process_file(char *filename, bool single_txn, bool use_relative_path)
 	oldfilename = pset.inputfile;
 	pset.inputfile = filename;
 
-	if (single_txn)
-	{
-		if ((res = PSQLexec("BEGIN")) == NULL)
-		{
-			if (pset.on_error_stop)
-			{
-				result = EXIT_USER;
-				goto error;
-			}
-		}
-		else
-			PQclear(res);
-	}
-
-	result = MainLoop(fd);
+	result = MainLoop(fd, single_txn);
 
-	if (single_txn)
-	{
-		if ((res = PSQLexec("COMMIT")) == NULL)
-		{
-			if (pset.on_error_stop)
-			{
-				result = EXIT_USER;
-				goto error;
-			}
-		}
-		else
-			PQclear(res);
-	}
-
-error:
 	if (fd != stdin)
 		fclose(fd);
 
@@ -2375,8 +2345,6 @@ error:
 	return result;
 }
 
-
-
 static const char *
 _align2string(enum printFormat in)
 {
diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c
index d3e3114..55aa423 100644
--- a/src/bin/psql/help.c
+++ b/src/bin/psql/help.c
@@ -79,6 +79,8 @@ usage(unsigned short int pager)
 	fprintf(output, _("  -c, --command=COMMAND    run only single command (SQL or internal) and exit\n"));
 	fprintf(output, _("  -d, --dbname=DBNAME      database name to connect to (default: \"%s\")\n"), env);
 	fprintf(output, _("  -f, --file=FILENAME      execute commands from file, then exit\n"));
+	fprintf(output, _("  -g, --group-command=COMMAND\n"
+					  "                           run more groups of commands (SQL or internal) and exit\n"));
 	fprintf(output, _("  -l, --list               list available databases, then exit\n"));
 	fprintf(output, _("  -v, --set=, --variable=NAME=VALUE\n"
 					  "                           set psql variable NAME to VALUE e.g.: -v ON_ERROR_STOP=1\n"));
diff --git a/src/bin/psql/mainloop.c b/src/bin/psql/mainloop.c
index b6cef94..4147238 100644
--- a/src/bin/psql/mainloop.c
+++ b/src/bin/psql/mainloop.c
@@ -24,8 +24,8 @@
  * This loop is re-entrant. May be called by \i command
  *	which reads input from a file.
  */
-int
-MainLoop(FILE *source)
+static int
+_MainLoop(FILE *source)
 {
 	PsqlScanState scan_state;	/* lexer working state */
 	volatile PQExpBuffer query_buf;		/* buffer for query being accumulated */
@@ -43,6 +43,7 @@ MainLoop(FILE *source)
 	volatile promptStatus_t prompt_status = PROMPT_READY;
 	volatile int count_eof = 0;
 	volatile bool die_on_error = false;
+	GroupCommand *cmd = pset.group_commands;
 
 	/* Save the prior command source */
 	FILE	   *prev_cmd_source;
@@ -135,6 +136,20 @@ MainLoop(FILE *source)
 				prompt_status = PROMPT_READY;
 			line = gets_interactive(get_prompt(prompt_status));
 		}
+		else if (pset.group_commands != NULL)
+		{
+			/* Is there some unprocessed group command? */
+			if (cmd != NULL)
+			{
+				line = cmd->actions;
+				cmd = cmd->next;
+			}
+			else
+			{
+				successResult = EXIT_SUCCESS;
+				break;
+			}
+		}
 		else
 		{
 			line = gets_fromFile(source);
@@ -451,6 +466,43 @@ MainLoop(FILE *source)
 	return successResult;
 }	/* MainLoop() */
 
+/*
+ * Transactional MainLoop
+ *
+ * allow to execute all statements in single transaction
+ */
+int
+MainLoop(FILE *source, bool single_txn)
+{
+	int			result;
+	PGresult   *res;
+
+	if (single_txn)
+	{
+		if ((res = PSQLexec("BEGIN")) == NULL)
+		{
+			if (pset.on_error_stop)
+				return EXIT_USER;
+		}
+		else
+			PQclear(res);
+	}
+
+	result = _MainLoop(source);
+
+	if (single_txn)
+	{
+		if ((res = PSQLexec("COMMIT")) == NULL)
+		{
+			if (pset.on_error_stop)
+				return EXIT_USER;
+		}
+		else
+			PQclear(res);
+	}
+
+	return result;
+}
 
 /*
  * psqlscan.c is #include'd here instead of being compiled on its own.
diff --git a/src/bin/psql/mainloop.h b/src/bin/psql/mainloop.h
index 8f1325c..53c9a11 100644
--- a/src/bin/psql/mainloop.h
+++ b/src/bin/psql/mainloop.h
@@ -10,6 +10,6 @@
 
 #include "postgres_fe.h"
 
-int			MainLoop(FILE *source);
+int			MainLoop(FILE *source, bool single_txn);
 
 #endif   /* MAINLOOP_H */
diff --git a/src/bin/psql/settings.h b/src/bin/psql/settings.h
index d34dc28..d23d67a 100644
--- a/src/bin/psql/settings.h
+++ b/src/bin/psql/settings.h
@@ -77,6 +77,12 @@ enum trivalue
 	TRI_YES
 };
 
+typedef struct _GroupCommand
+{
+	char *actions;
+	struct _GroupCommand *next;
+} GroupCommand;
+
 typedef struct _psqlSettings
 {
 	PGconn	   *db;				/* connection to backend */
@@ -129,6 +135,7 @@ typedef struct _psqlSettings
 	const char *prompt2;
 	const char *prompt3;
 	PGVerbosity verbosity;		/* current error verbosity level */
+	GroupCommand *group_commands;
 } PsqlSettings;
 
 extern PsqlSettings pset;
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index 28ba75a..4c9383f 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -54,7 +54,8 @@ enum _actions
 	ACT_SINGLE_SLASH,
 	ACT_LIST_DB,
 	ACT_SINGLE_QUERY,
-	ACT_FILE
+	ACT_FILE,
+	ACT_GROUP_COMMANDS
 };
 
 struct adhoc_opts
@@ -158,6 +159,8 @@ main(int argc, char *argv[])
 	SetVariable(pset.vars, "PROMPT2", DEFAULT_PROMPT2);
 	SetVariable(pset.vars, "PROMPT3", DEFAULT_PROMPT3);
 
+	pset.group_commands = NULL;
+
 	parse_psql_options(argc, argv, &options);
 
 	/*
@@ -326,6 +329,13 @@ main(int argc, char *argv[])
 			? EXIT_SUCCESS : EXIT_FAILURE;
 	}
 
+	else if (options.action == ACT_GROUP_COMMANDS)
+	{
+		pset.notty = true;
+		SetVariableBool(pset.vars, "SINGLELINE");
+		successResult = MainLoop(NULL, options.single_txn);
+	}
+
 	/*
 	 * or otherwise enter interactive main loop
 	 */
@@ -338,7 +348,7 @@ main(int argc, char *argv[])
 		if (!pset.quiet)
 			printf(_("Type \"help\" for help.\n\n"));
 		initializeInput(options.no_readline ? 0 : 1);
-		successResult = MainLoop(stdin);
+		successResult = MainLoop(stdin, false);
 	}
 
 	/* clean up */
@@ -370,6 +380,7 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options)
 		{"file", required_argument, NULL, 'f'},
 		{"field-separator", required_argument, NULL, 'F'},
 		{"field-separator-zero", no_argument, NULL, 'z'},
+		{"group-command", required_argument, NULL, 'g'},
 		{"host", required_argument, NULL, 'h'},
 		{"html", no_argument, NULL, 'H'},
 		{"list", no_argument, NULL, 'l'},
@@ -401,9 +412,12 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options)
 	int			optindex;
 	int			c;
 
+	bool			cmd_opt_is_used = false;
+	bool			group_cmd_opt_is_used = false;
+
 	memset(options, 0, sizeof *options);
 
-	while ((c = getopt_long(argc, argv, "aAbc:d:eEf:F:h:HlL:no:p:P:qR:sStT:U:v:VwWxXz?01",
+	while ((c = getopt_long(argc, argv, "aAbc:d:eEf:F:g:h:HlL:no:p:P:qR:sStT:U:v:VwWxXz?01",
 							long_options, &optindex)) != -1)
 	{
 		switch (c)
@@ -418,6 +432,8 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options)
 				SetVariable(pset.vars, "ECHO", "errors");
 				break;
 			case 'c':
+				cmd_opt_is_used = true;
+
 				options->action_string = pg_strdup(optarg);
 				if (optarg[0] == '\\')
 				{
@@ -444,6 +460,27 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options)
 				pset.popt.topt.fieldSep.separator = pg_strdup(optarg);
 				pset.popt.topt.fieldSep.separator_zero = false;
 				break;
+			case 'g':
+				{
+					GroupCommand *cmd = pg_malloc(sizeof(GroupCommand));
+					GroupCommand *ptr = pset.group_commands;
+
+					group_cmd_opt_is_used = true;
+
+					if (ptr == NULL)
+						pset.group_commands = cmd;
+					else
+					{
+						while (ptr->next != NULL)
+							ptr =  ptr->next;
+
+						ptr->next = cmd;
+					}
+					cmd->next = NULL;
+					cmd->actions = pg_strdup(optarg);
+					options->action = ACT_GROUP_COMMANDS;
+				}
+				break;
 			case 'h':
 				options->host = pg_strdup(optarg);
 				break;
@@ -600,6 +637,13 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options)
 		}
 	}
 
+	if (cmd_opt_is_used && group_cmd_opt_is_used)
+	{
+		fprintf(stderr, _("%s: options -c/--command and -g/--group_command cannot be used together\n"),
+				pset.progname);
+		exit(EXIT_FAILURE);
+	}
+
 	/*
 	 * if we still have arguments, use it as the database name and username
 	 */
-- 
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