2015-11-30 15:17 GMT+01:00 Michael Paquier <michael.paqu...@gmail.com>:

> On Thu, Nov 26, 2015 at 4:21 AM, Pavel Stehule wrote:
> > Attached patch per Tom Lane proposal.
> >
> > * multiple -c -f options are supported, the order of options is respected
> > * the statements for one -c options are executed in transactions
> > * Iacob's doc patch merged
>
>  enum _actions
>  {
>         ACT_NOTHING = 0,
> -       ACT_SINGLE_SLASH,
>         ACT_LIST_DB,
> -       ACT_SINGLE_QUERY,
> -       ACT_FILE
> +       ACT_FILE_STDIN
>  };
>
> Removing some items from the list of potential actions and creating a
> new sublist listing action types is a bit weird. Why not grouping them
> together and allow for example -l as well in the list of things that
> is considered as a repeatable action? It seems to me that we could
> simplify the code this way, and instead of ACT_NOTHING we could check
> if the list of actions is empty or not.
>

fixed

Regards

Pavel


> --
> Michael
>
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
new file mode 100644
index 5899bb4..2928c92
*** a/doc/src/sgml/ref/psql-ref.sgml
--- b/doc/src/sgml/ref/psql-ref.sgml
*************** PostgreSQL documentation
*** 38,46 ****
       <productname>PostgreSQL</productname>. It enables you to type in
       queries interactively, issue them to
       <productname>PostgreSQL</productname>, and see the query results.
!      Alternatively, input can be from a file. In addition, it provides a
!      number of meta-commands and various shell-like features to
!      facilitate writing scripts and automating a wide variety of tasks.
      </para>
   </refsect1>
  
--- 38,47 ----
       <productname>PostgreSQL</productname>. It enables you to type in
       queries interactively, issue them to
       <productname>PostgreSQL</productname>, and see the query results.
!      Alternatively, input can be from a file or from command line
!      arguments. In addition, it provides a number of meta-commands and various
!      shell-like features to facilitate writing scripts and automating a wide
!      variety of tasks.
      </para>
   </refsect1>
  
*************** PostgreSQL documentation
*** 89,126 ****
        <term><option>--command=<replaceable class="parameter">command</replaceable></></term>
        <listitem>
        <para>
!       Specifies that <application>psql</application> is to execute one
!       command string, <replaceable class="parameter">command</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>
        <para>
!       <replaceable class="parameter">command</replaceable> must be either
!       a command string that is completely parsable by the server (i.e.,
!       it contains no <application>psql</application>-specific features),
!       or a single backslash command. Thus you cannot mix
!       <acronym>SQL</acronym> and <application>psql</application>
!       meta-commands with this option. To achieve that, you could
!       pipe the string into <application>psql</application>, for example:
!       <literal>echo '\x \\ SELECT * FROM foo;' | psql</literal>.
        (<literal>\\</> is the separator meta-command.)
        </para>
        <para>
!        If the command string contains multiple SQL commands, they are
!        processed in a single transaction, unless there are explicit
!        <command>BEGIN</>/<command>COMMIT</> commands included in the
!        string to divide it into multiple transactions.  This is
!        different from the behavior when the same string is fed to
!        <application>psql</application>'s standard input.  Also, only
!        the result of the last SQL command is returned.
        </para>
        <para>
!        Because of these legacy behaviors, putting more than one command in
!        the <option>-c</option> string often has unexpected results.  It's
!        better to feed multiple commands to <application>psql</application>'s
!        standard input, either using <application>echo</application> as
!        illustrated above, or via a shell here-document, for example:
  <programlisting>
  psql &lt;&lt;EOF
  \x
--- 90,134 ----
        <term><option>--command=<replaceable class="parameter">command</replaceable></></term>
        <listitem>
        <para>
!       Specifies that <application>psql</application> is to execute the given
!       command string, <replaceable class="parameter">command</replaceable>.
!       This option can be repeated and combined in any order with
!       the <option>-f</option> option.
        </para>
        <para>
!       <replaceable class="parameter">command</replaceable> must be either a
!       command string that is completely parsable by the server (i.e., it
!       contains no <application>psql</application>-specific features), or a
!       single backslash command. Thus you cannot mix
!       <acronym>SQL</acronym> and <application>psql</application> meta-commands
!       with this option. To achieve that, you could use
!       repeated <option>-c</option> options or pipe the string
!       into <application>psql</application>, for example:
!       <literal>psql -c '\x' -c 'SELECT * FROM foo;'</literal> or
!       <literal>echo '\x \\ SELECT * FROM foo;' | psql</literal>
        (<literal>\\</> is the separator meta-command.)
        </para>
        <para>
!        Each command string passed to <option>-c</option> is sent to the server
!        as a single query. Because of this, the server executes it as a single
!        transaction, even if a command string contains
!        multiple <acronym>SQL</acronym> commands, unless there are
!        explicit <command>BEGIN</>/<command>COMMIT</> commands included in the
!        string to divide it into multiple transactions.  Also, the server only
!        returns the result of the last <acronym>SQL</acronym> command to the
!        client.  This is different from the behavior when the same string with
!        multiple <acronym>SQL</acronym> commands is fed
!        to <application>psql</application>'s standard input because
!        then <application>psql</application> sends each <acronym>SQL</acronym>
!        command separately.
        </para>
        <para>
!        Because of the execution as a single query, putting more than one
!        command in the <option>-c</option> string often has unexpected results.
!        It's better to use repeated <option>-c</option> commands or feed
!        multiple commands to <application>psql</application>'s standard input,
!        either using <application>echo</application> as illustrated above, or
!        via a shell here-document, for example:
  <programlisting>
  psql &lt;&lt;EOF
  \x
*************** EOF
*** 183,193 ****
        <term><option>--file=<replaceable class="parameter">filename</replaceable></></term>
        <listitem>
        <para>
!       Use the file <replaceable class="parameter">filename</replaceable>
!       as the source of commands instead of reading commands interactively.
!       After the file is processed, <application>psql</application>
!       terminates. This is in many ways equivalent to the meta-command
!       <command>\i</command>.
        </para>
  
        <para>
--- 191,203 ----
        <term><option>--file=<replaceable class="parameter">filename</replaceable></></term>
        <listitem>
        <para>
!       Use the file <replaceable class="parameter">filename</replaceable> as
!       the source of commands instead of reading commands interactively.  This
!       option can be repeated and combined in any order with
!       the <option>-c</option> option.  After the commands in
!       every <option>-c</option> command string and <option>-f</option> file
!       are processed, <application>psql</application> terminates.  This option
!       is in many ways equivalent to the meta-command <command>\i</command>.
        </para>
  
        <para>
*************** EOF
*** 539,558 ****
        <term><option>--single-transaction</option></term>
        <listitem>
         <para>
!         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>
!         If the script itself uses <command>BEGIN</>, <command>COMMIT</>,
          or <command>ROLLBACK</>, this option will not have the desired
!         effects.
!         Also, if the script contains any command that cannot be executed
!         inside a transaction block, specifying this option will cause that
!         command (and hence the whole transaction) to fail.
         </para>
        </listitem>
       </varlistentry>
--- 549,569 ----
        <term><option>--single-transaction</option></term>
        <listitem>
         <para>
!         When <application>psql</application> executes commands from a script
!         and/or a <option>-c</option> option, adding this option
!         wraps <command>BEGIN</>/<command>COMMIT</> around all of those
!         commands as a whole to execute them as a single transaction.  This
!         ensures that either all the commands complete successfully, or no
!         changes are applied.
         </para>
  
         <para>
!         If the commands themselves
!         contain <command>BEGIN</>, <command>COMMIT</>,
          or <command>ROLLBACK</>, this option will not have the desired
!         effects.  Also, if an individual command cannot be executed inside a
!         transaction block, specifying this option will cause the whole
!         transaction to fail.
         </para>
        </listitem>
       </varlistentry>
*************** PSQL_EDITOR_LINENUMBER_ARG='--line '
*** 3725,3731 ****
     <term><filename>psqlrc</filename> and <filename>~/.psqlrc</filename></term>
     <listitem>
      <para>
!      Unless it is passed an <option>-X</option> or <option>-c</option> option,
       <application>psql</application> attempts to read and execute commands
       from the system-wide startup file (<filename>psqlrc</filename>) and then
       the user's personal startup file (<filename>~/.psqlrc</filename>), after
--- 3736,3742 ----
     <term><filename>psqlrc</filename> and <filename>~/.psqlrc</filename></term>
     <listitem>
      <para>
!      Unless it is passed an <option>-X</option> option,
       <application>psql</application> attempts to read and execute commands
       from the system-wide startup file (<filename>psqlrc</filename>) and then
       the user's personal startup file (<filename>~/.psqlrc</filename>), after
*************** PSQL_EDITOR_LINENUMBER_ARG='--line '
*** 3819,3824 ****
--- 3830,3842 ----
        </para>
        </listitem>
  
+       <listitem>
+       <para>
+        Before <productname>PostgreSQL</productname> 9.6, <option>-c</option>
+        used to imply <option>-X</option> and therefore it wouldn't
+        read <filename>psqlrc</filename> files, that is no longer the case.
+       </para>
+       </listitem>
      </itemizedlist>
   </refsect1>
  
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
new file mode 100644
index 438a4ec..d642803
*** a/src/bin/psql/command.c
--- b/src/bin/psql/command.c
*************** exec_command(const char *cmd,
*** 916,922 ****
  			include_relative = (strcmp(cmd, "ir") == 0
  								|| strcmp(cmd, "include_relative") == 0);
  			expand_tilde(&fname);
! 			success = (process_file(fname, false, include_relative) == EXIT_SUCCESS);
  			free(fname);
  		}
  	}
--- 916,922 ----
  			include_relative = (strcmp(cmd, "ir") == 0
  								|| strcmp(cmd, "include_relative") == 0);
  			expand_tilde(&fname);
! 			success = (process_file(fname, include_relative) == EXIT_SUCCESS);
  			free(fname);
  		}
  	}
*************** do_edit(const char *filename_arg, PQExpB
*** 2284,2296 ****
   * the file from where the currently processed file (if any) is located.
   */
  int
! process_file(char *filename, bool single_txn, bool use_relative_path)
  {
  	FILE	   *fd;
  	int			result;
  	char	   *oldfilename;
  	char		relpath[MAXPGPATH];
- 	PGresult   *res;
  
  	if (!filename)
  	{
--- 2284,2295 ----
   * the file from where the currently processed file (if any) is located.
   */
  int
! process_file(char *filename, bool use_relative_path)
  {
  	FILE	   *fd;
  	int			result;
  	char	   *oldfilename;
  	char		relpath[MAXPGPATH];
  
  	if (!filename)
  	{
*************** process_file(char *filename, bool single
*** 2335,2371 ****
  	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);
  
- 	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);
  
--- 2334,2341 ----
diff --git a/src/bin/psql/command.h b/src/bin/psql/command.h
new file mode 100644
index 54385e8..c817600
*** a/src/bin/psql/command.h
--- b/src/bin/psql/command.h
*************** typedef enum _backslashResult
*** 27,33 ****
  extern backslashResult HandleSlashCmds(PsqlScanState scan_state,
  				PQExpBuffer query_buf);
  
! extern int	process_file(char *filename, bool single_txn, bool use_relative_path);
  
  extern bool do_pset(const char *param,
  		const char *value,
--- 27,33 ----
  extern backslashResult HandleSlashCmds(PsqlScanState scan_state,
  				PQExpBuffer query_buf);
  
! extern int	process_file(char *filename, bool use_relative_path);
  
  extern bool do_pset(const char *param,
  		const char *value,
diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c
new file mode 100644
index 0e266a3..96e5225
*** a/src/bin/psql/common.c
--- b/src/bin/psql/common.c
*************** recognized_connection_string(const char
*** 1886,1888 ****
--- 1886,1911 ----
  {
  	return uri_prefix_length(connstr) != 0 || strchr(connstr, '=') != NULL;
  }
+ 
+ /*
+  * Support for list of actions. The SimpleStringList cannot be used due possible
+  * combination different actions with the requirement to save the order.
+  */
+ void
+ simple_action_list_append(SimpleActionList *list, int action, const char *val)
+ {
+ 	SimpleActionListCell  *cell;
+ 
+ 	cell = (SimpleActionListCell *)
+ 		pg_malloc(offsetof(SimpleActionListCell, val) + strlen(val) + 1);
+ 
+ 	cell->next = NULL;
+ 	cell->action = action;
+ 	strcpy(cell->val, val);
+ 
+ 	if (list->tail)
+ 		list->tail->next = cell;
+ 	else
+ 		list->head = cell;
+ 	list->tail = cell;
+ }
diff --git a/src/bin/psql/common.h b/src/bin/psql/common.h
new file mode 100644
index caf31d1..6bdee98
*** a/src/bin/psql/common.h
--- b/src/bin/psql/common.h
***************
*** 14,21 ****
--- 14,44 ----
  
  #include "print.h"
  
+ enum _actions
+ {
+ 	ACT_LIST_DB,
+ 	ACT_SINGLE_QUERY,
+ 	ACT_SINGLE_SLASH,
+ 	ACT_FILE
+ };
+ 
+ typedef struct SimpleActionListCell
+ {
+ 	struct SimpleActionListCell *next;
+ 	int 		action;
+ 	char		val[FLEXIBLE_ARRAY_MEMBER];
+ } SimpleActionListCell;
+ 
+ typedef struct SimpleActionList
+ {
+ 	SimpleActionListCell *head;
+ 	SimpleActionListCell *tail;
+ } SimpleActionList;
+ 
  #define atooid(x)  ((Oid) strtoul((x), NULL, 10))
  
+ extern void simple_action_list_append(SimpleActionList *list, int action, const char *val);
+ 
  extern bool setQFout(const char *fname);
  
  extern void psql_error(const char *fmt,...) pg_attribute_printf(1, 2);
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
new file mode 100644
index 7aa997d..3f909df
*** a/src/bin/psql/startup.c
--- b/src/bin/psql/startup.c
*************** PsqlSettings pset;
*** 44,62 ****
  #define PSQLRC		"psqlrc.conf"
  #endif
  
- /*
-  * Structures to pass information between the option parsing routine
-  * and the main function
-  */
- enum _actions
- {
- 	ACT_NOTHING = 0,
- 	ACT_SINGLE_SLASH,
- 	ACT_LIST_DB,
- 	ACT_SINGLE_QUERY,
- 	ACT_FILE
- };
- 
  struct adhoc_opts
  {
  	char	   *dbname;
--- 44,49 ----
*************** struct adhoc_opts
*** 64,76 ****
  	char	   *port;
  	char	   *username;
  	char	   *logfilename;
- 	enum _actions action;
  	char	   *action_string;
  	bool		no_readline;
  	bool		no_psqlrc;
  	bool		single_txn;
  };
  
  static void parse_psql_options(int argc, char *argv[],
  				   struct adhoc_opts * options);
  static void process_psqlrc(char *argv0);
--- 51,65 ----
  	char	   *port;
  	char	   *username;
  	char	   *logfilename;
  	char	   *action_string;
  	bool		no_readline;
  	bool		no_psqlrc;
  	bool		single_txn;
+ 	bool		use_stdin;
+ 	SimpleActionList	actions;
  };
  
+ static bool use_default_dbname(struct adhoc_opts *options);
  static void parse_psql_options(int argc, char *argv[],
  				   struct adhoc_opts * options);
  static void process_psqlrc(char *argv0);
*************** main(int argc, char *argv[])
*** 159,164 ****
--- 148,157 ----
  	SetVariable(pset.vars, "PROMPT2", DEFAULT_PROMPT2);
  	SetVariable(pset.vars, "PROMPT3", DEFAULT_PROMPT3);
  
+ 	options.actions.head = NULL;
+ 	options.actions.tail = NULL;
+ 	options.use_stdin = false;
+ 
  	parse_psql_options(argc, argv, &options);
  
  	/*
*************** main(int argc, char *argv[])
*** 166,179 ****
  	 * 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 && options.action == ACT_NOTHING)
  	{
  		fprintf(stderr, _("%s: -1 can only be used in non-interactive mode\n"), pset.progname);
  		exit(EXIT_FAILURE);
--- 159,168 ----
  	 * as if the user had specified "-f -".  This lets single-transaction mode
  	 * work in this case.
  	 */
! 	options.use_stdin = options.actions.head == NULL && pset.notty;
  
  	/* Bail out if -1 was specified but will be ignored. */
! 	if (options.single_txn && !options.use_stdin && options.actions.head == NULL)
  	{
  		fprintf(stderr, _("%s: -1 can only be used in non-interactive mode\n"), pset.progname);
  		exit(EXIT_FAILURE);
*************** main(int argc, char *argv[])
*** 217,224 ****
  		keywords[3] = "password";
  		values[3] = password;
  		keywords[4] = "dbname";
! 		values[4] = (options.action == ACT_LIST_DB &&
! 					 options.dbname == NULL) ?
  			"postgres" : options.dbname;
  		keywords[5] = "fallback_application_name";
  		values[5] = pset.progname;
--- 206,212 ----
  		keywords[3] = "password";
  		values[3] = password;
  		keywords[4] = "dbname";
! 		values[4] = use_default_dbname(&options) ?
  			"postgres" : options.dbname;
  		keywords[5] = "fallback_application_name";
  		values[5] = pset.progname;
*************** main(int argc, char *argv[])
*** 259,276 ****
  
  	SyncVariables();
  
- 	if (options.action == ACT_LIST_DB)
- 	{
- 		int			success;
- 
- 		if (!options.no_psqlrc)
- 			process_psqlrc(argv[0]);
- 
- 		success = listAllDbs(NULL, false);
- 		PQfinish(pset.db);
- 		exit(success ? EXIT_SUCCESS : EXIT_FAILURE);
- 	}
- 
  	if (options.logfilename)
  	{
  		pset.logfile = fopen(options.logfilename, "a");
--- 247,252 ----
*************** main(int argc, char *argv[])
*** 279,332 ****
  					pset.progname, options.logfilename, strerror(errno));
  	}
  
! 	/*
! 	 * Now find something to do
! 	 */
  
  	/*
! 	 * process file 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, false);
! 	}
  
! 	/*
! 	 * process slash command if one was given to -c
! 	 */
! 	else if (options.action == ACT_SINGLE_SLASH)
! 	{
! 		PsqlScanState scan_state;
  
! 		if (pset.echo == PSQL_ECHO_ALL)
! 			puts(options.action_string);
  
! 		scan_state = psql_scan_create();
! 		psql_scan_setup(scan_state,
! 						options.action_string,
! 						strlen(options.action_string));
  
! 		successResult = HandleSlashCmds(scan_state, NULL) != PSQL_CMD_ERROR
! 			? EXIT_SUCCESS : EXIT_FAILURE;
  
! 		psql_scan_destroy(scan_state);
! 	}
  
! 	/*
! 	 * If the query given to -c was a normal one, send it
! 	 */
! 	else if (options.action == ACT_SINGLE_QUERY)
! 	{
! 		if (pset.echo == PSQL_ECHO_ALL)
! 			puts(options.action_string);
  
! 		successResult = SendQuery(options.action_string)
! 			? EXIT_SUCCESS : EXIT_FAILURE;
! 	}
  
  	/*
  	 * or otherwise enter interactive main loop
  	 */
--- 255,348 ----
  					pset.progname, options.logfilename, strerror(errno));
  	}
  
! 	if (!options.no_psqlrc)
! 		process_psqlrc(argv[0]);
  
  	/*
! 	 * Now find something to do
  	 */
! 	if (options.actions.head)
  	{
! 		PGresult		*res;
! 		SimpleActionListCell	*cell;
  
! 		successResult = EXIT_SUCCESS;		/* be compiler quiete */
  
! 		if (options.single_txn)
! 		{
! 			if ((res = PSQLexec("BEGIN")) == NULL)
! 			{
! 				if (pset.on_error_stop)
! 				{
! 					successResult = EXIT_USER;
! 					goto error;
! 				}
! 			}
! 			else
! 				PQclear(res);
! 		}
  
! 		for (cell = options.actions.head; cell; cell = cell->next)
! 		{
! 			if (cell->action == ACT_LIST_DB)
! 			{
! 				successResult = listAllDbs(NULL, false);
! 			}
! 			else if (cell->action == ACT_SINGLE_QUERY)
! 			{
! 				if (pset.echo == PSQL_ECHO_ALL)
! 					puts(cell->val);
  
! 				successResult = SendQuery(cell->val)
! 					? EXIT_SUCCESS : EXIT_FAILURE;
! 			}
! 			else if (cell->action == ACT_SINGLE_SLASH)
! 			{
! 				PsqlScanState scan_state;
  
! 				if (pset.echo == PSQL_ECHO_ALL)
! 					puts(cell->val);
  
! 				scan_state = psql_scan_create();
! 				psql_scan_setup(scan_state,
! 							cell->val,
! 							strlen(cell->val));
  
! 				successResult = HandleSlashCmds(scan_state, NULL) != PSQL_CMD_ERROR
! 					? EXIT_SUCCESS : EXIT_FAILURE;
  
! 				psql_scan_destroy(scan_state);
! 			}
! 			else
! 			{
! 				/* ACT_FILE */
! 				successResult = process_file(cell->val, false);
! 			}
! 
! 			if (successResult != EXIT_SUCCESS && pset.on_error_stop)
! 				break;
! 		}
! 
! 		if (options.use_stdin)
! 			successResult = process_file(NULL, false);
! 
! 		if (options.single_txn)
! 		{
! 			if ((res = PSQLexec("COMMIT")) == NULL)
! 			{
! 				if (pset.on_error_stop)
! 				{
! 					successResult = EXIT_USER;
! 					goto error;
! 				}
! 			}
! 			else
! 				PQclear(res);
! 		}
  
+ error:
+ 		;
+ 	}
  	/*
  	 * or otherwise enter interactive main loop
  	 */
*************** main(int argc, char *argv[])
*** 351,356 ****
--- 367,392 ----
  	return successResult;
  }
  
+ /*
+  * Default dbname "postgres" can be used when no other dbname
+  * is entered and when only action ACT_LIST_DB is used
+  */
+ static bool
+ use_default_dbname(struct adhoc_opts *options)
+ {
+ 	SimpleActionListCell	*cell;
+ 
+ 	if (options->dbname != NULL)
+ 		return false;
+ 
+ 	for (cell = options->actions.head; cell; cell = cell->next)
+ 	{
+ 		if (cell->action != ACT_LIST_DB)
+ 			return false;
+ 	}
+ 
+ 	return true;
+ }
  
  /*
   * Parse command line options
*************** parse_psql_options(int argc, char *argv[
*** 419,432 ****
  				SetVariable(pset.vars, "ECHO", "errors");
  				break;
  			case 'c':
- 				options->action_string = pg_strdup(optarg);
  				if (optarg[0] == '\\')
! 				{
! 					options->action = ACT_SINGLE_SLASH;
! 					options->action_string++;
! 				}
  				else
! 					options->action = ACT_SINGLE_QUERY;
  				break;
  			case 'd':
  				options->dbname = pg_strdup(optarg);
--- 455,468 ----
  				SetVariable(pset.vars, "ECHO", "errors");
  				break;
  			case 'c':
  				if (optarg[0] == '\\')
! 					simple_action_list_append(&options->actions,
! 								    ACT_SINGLE_SLASH,
! 								    pstrdup(optarg + 1));
  				else
! 					simple_action_list_append(&options->actions,
! 								    ACT_SINGLE_QUERY,
! 								    pstrdup(optarg));
  				break;
  			case 'd':
  				options->dbname = pg_strdup(optarg);
*************** parse_psql_options(int argc, char *argv[
*** 438,445 ****
  				SetVariableBool(pset.vars, "ECHO_HIDDEN");
  				break;
  			case 'f':
! 				options->action = ACT_FILE;
! 				options->action_string = pg_strdup(optarg);
  				break;
  			case 'F':
  				pset.popt.topt.fieldSep.separator = pg_strdup(optarg);
--- 474,482 ----
  				SetVariableBool(pset.vars, "ECHO_HIDDEN");
  				break;
  			case 'f':
! 				simple_action_list_append(&options->actions,
! 								ACT_FILE,
! 									    pg_strdup(optarg));
  				break;
  			case 'F':
  				pset.popt.topt.fieldSep.separator = pg_strdup(optarg);
*************** parse_psql_options(int argc, char *argv[
*** 452,458 ****
  				pset.popt.topt.format = PRINT_HTML;
  				break;
  			case 'l':
! 				options->action = ACT_LIST_DB;
  				break;
  			case 'L':
  				options->logfilename = pg_strdup(optarg);
--- 489,497 ----
  				pset.popt.topt.format = PRINT_HTML;
  				break;
  			case 'l':
! 				simple_action_list_append(&options->actions,
! 								ACT_LIST_DB,
! 									    pg_strdup(""));
  				break;
  			case 'L':
  				options->logfilename = pg_strdup(optarg);
*************** process_psqlrc_file(char *filename)
*** 674,684 ****
  
  	/* check for minor version first, then major, then no version */
  	if (access(psqlrc_minor, R_OK) == 0)
! 		(void) process_file(psqlrc_minor, false, false);
  	else if (access(psqlrc_major, R_OK) == 0)
! 		(void) process_file(psqlrc_major, false, false);
  	else if (access(filename, R_OK) == 0)
! 		(void) process_file(filename, false, false);
  
  	free(psqlrc_minor);
  	free(psqlrc_major);
--- 713,723 ----
  
  	/* check for minor version first, then major, then no version */
  	if (access(psqlrc_minor, R_OK) == 0)
! 		(void) process_file(psqlrc_minor, false);
  	else if (access(psqlrc_major, R_OK) == 0)
! 		(void) process_file(psqlrc_major, false);
  	else if (access(filename, R_OK) == 0)
! 		(void) process_file(filename, false);
  
  	free(psqlrc_minor);
  	free(psqlrc_major);
-- 
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