Add new psql help topics, accessible to both --help and \?.

Add --help=<topic> for the commandline, and \? <topic> as a backslash
command, to show more help than the invocations without parameters
do. "commands", "variables" and "options" currently exist as help
topics describing, respectively, backslash commands, psql variables,
and commandline switches. Without parameters the help commands show
their previous topic.

Some further wordsmithing or extending of the added help content might
be needed; but there seems little benefit delaying the overall feature
further.

Author: Pavel Stehule, editorialized by many

Reviewed-By: Andres Freund, Petr Jelinek, Fujii Masao, MauMau, Abhijit
    Menon-Sen and Erik Rijkers.

Discussion: CAFj8pRDVGuC-nXBfe2CK8vpyzd2Dsr9GVpbrATAnZO=2YQ0s2Q@mail.gmail.com,
    CAFj8pRA54AbTv2RXDTRxiAd8hy8wxmoVLqhJDRCwEnhdd7OUkw@mail.gmail.com
This commit is contained in:
Andres Freund 2014-09-09 22:19:14 +02:00
parent 0709b7ee72
commit 07c8651dd9
6 changed files with 222 additions and 61 deletions

View File

@ -560,11 +560,17 @@ EOF
<varlistentry>
<term><option>-?</></term>
<term><option>--help</></term>
<term><option>--help[=<replaceable class="parameter">topic</>]</option></term>
<listitem>
<para>
Show help about <application>psql</application> command line
arguments, and exit.
Show help about <application>psql</application> and exit. The optional
<replaceable class="parameter">topic</> parameter (defaulting
to <literal>options</literal>) selects which part of psql is
explained: <literal>commands</> describes <application>psql</>'s
backslash commands; <literal>options</> describes the commandline
switches that can be passed to <application>psql</>;
and <literal>variables</> shows help about about psql configuration
variables.
</para>
</listitem>
</varlistentry>
@ -2574,10 +2580,17 @@ testdb=&gt; <userinput>\setenv LESS -imx4F</userinput>
<varlistentry>
<term><literal>\?</literal></term>
<term><literal>\? [ <replaceable class="parameter">topic</> ]</literal></term>
<listitem>
<para>
Shows help information about the backslash commands.
Shows help information. The optional
<replaceable class="parameter">topic</> parameter
(defaulting to <literal>commands</>) selects which part of psql is
explained: <literal>commands</> describes <application>psql</>'s
backslash commands; <literal>options</> describes the commandline
switches that can be passed to <application>psql</>;
and <literal>variables</> shows help about about psql configuration
variables.
</para>
</listitem>
</varlistentry>

View File

@ -1491,7 +1491,19 @@ exec_command(const char *cmd,
/* \? -- slash command help */
else if (strcmp(cmd, "?") == 0)
slashUsage(pset.popt.topt.pager);
{
char *opt0 = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, false);
if (!opt0 || strcmp(opt0, "commands") == 0)
slashUsage(pset.popt.topt.pager);
else if (strcmp(opt0, "options") == 0)
usage(pset.popt.topt.pager);
else if (strcmp(opt0, "variables") == 0)
helpVariables(pset.popt.topt.pager);
else
slashUsage(pset.popt.topt.pager);
}
#if 0

View File

@ -46,11 +46,12 @@
#define ON(var) (var ? _("on") : _("off"))
void
usage(void)
usage(unsigned short int pager)
{
const char *env;
const char *user;
char *errstr;
FILE *output;
/* Find default user, in case we need it. */
user = getenv("PGUSER");
@ -64,77 +65,83 @@ usage(void)
}
}
printf(_("psql is the PostgreSQL interactive terminal.\n\n"));
printf(_("Usage:\n"));
printf(_(" psql [OPTION]... [DBNAME [USERNAME]]\n\n"));
output = PageOutput(59, pager);
printf(_("General options:\n"));
fprintf(output, _("psql is the PostgreSQL interactive terminal.\n\n"));
fprintf(output, _("Usage:\n"));
fprintf(output, _(" psql [OPTION]... [DBNAME [USERNAME]]\n\n"));
fprintf(output, _("General options:\n"));
/* Display default database */
env = getenv("PGDATABASE");
if (!env)
env = user;
printf(_(" -c, --command=COMMAND run only single command (SQL or internal) and exit\n"));
printf(_(" -d, --dbname=DBNAME database name to connect to (default: \"%s\")\n"), env);
printf(_(" -f, --file=FILENAME execute commands from file, then exit\n"));
printf(_(" -l, --list list available databases, then exit\n"));
printf(_(" -v, --set=, --variable=NAME=VALUE\n"
" set psql variable NAME to VALUE\n"));
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"
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, _(" -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"));
fprintf(output, _(" -V, --version output version information, then exit\n"));
fprintf(output, _(" -X, --no-psqlrc do not read startup file (~/.psqlrc)\n"));
fprintf(output, _(" -1 (\"one\"), --single-transaction\n"
" execute as a single transaction (if non-interactive)\n"));
printf(_(" -?, --help show this help, then exit\n"));
fprintf(output, _(" -?, --help[=options] show this help, then exit\n"));
fprintf(output, _(" --help=variables show a list of all specially treated variables, then exit\n"));
fprintf(output, _(" --help=commands show a list of backslash commands, then exit\n"));
printf(_("\nInput and output options:\n"));
printf(_(" -a, --echo-all echo all input from script\n"));
printf(_(" -b, --echo-errors echo failed commands\n"));
printf(_(" -e, --echo-queries echo commands sent to server\n"));
printf(_(" -E, --echo-hidden display queries that internal commands generate\n"));
printf(_(" -L, --log-file=FILENAME send session log to file\n"));
printf(_(" -n, --no-readline disable enhanced command line editing (readline)\n"));
printf(_(" -o, --output=FILENAME send query results to file (or |pipe)\n"));
printf(_(" -q, --quiet run quietly (no messages, only query output)\n"));
printf(_(" -s, --single-step single-step mode (confirm each query)\n"));
printf(_(" -S, --single-line single-line mode (end of line terminates SQL command)\n"));
fprintf(output, _("\nInput and output options:\n"));
fprintf(output, _(" -a, --echo-all echo all input from script\n"));
fprintf(output, _(" -b, --echo-errors echo failed commands\n"));
fprintf(output, _(" -e, --echo-queries echo commands sent to server\n"));
fprintf(output, _(" -E, --echo-hidden display queries that internal commands generate\n"));
fprintf(output, _(" -L, --log-file=FILENAME send session log to file\n"));
fprintf(output, _(" -n, --no-readline disable enhanced command line editing (readline)\n"));
fprintf(output, _(" -o, --output=FILENAME send query results to file (or |pipe)\n"));
fprintf(output, _(" -q, --quiet run quietly (no messages, only query output)\n"));
fprintf(output, _(" -s, --single-step single-step mode (confirm each query)\n"));
fprintf(output, _(" -S, --single-line single-line mode (end of line terminates SQL command)\n"));
printf(_("\nOutput format options:\n"));
printf(_(" -A, --no-align unaligned table output mode\n"));
printf(_(" -F, --field-separator=STRING\n"
fprintf(output, _("\nOutput format options:\n"));
fprintf(output, _(" -A, --no-align unaligned table output mode\n"));
fprintf(output, _(" -F, --field-separator=STRING\n"
" field separator for unaligned output (default: \"%s\")\n"),
DEFAULT_FIELD_SEP);
printf(_(" -H, --html HTML table output mode\n"));
printf(_(" -P, --pset=VAR[=ARG] set printing option VAR to ARG (see \\pset command)\n"));
printf(_(" -R, --record-separator=STRING\n"
fprintf(output, _(" -H, --html HTML table output mode\n"));
fprintf(output, _(" -P, --pset=VAR[=ARG] set printing option VAR to ARG (see \\pset command)\n"));
fprintf(output, _(" -R, --record-separator=STRING\n"
" record separator for unaligned output (default: newline)\n"));
printf(_(" -t, --tuples-only print rows only\n"));
printf(_(" -T, --table-attr=TEXT set HTML table tag attributes (e.g., width, border)\n"));
printf(_(" -x, --expanded turn on expanded table output\n"));
printf(_(" -z, --field-separator-zero\n"
fprintf(output, _(" -t, --tuples-only print rows only\n"));
fprintf(output, _(" -T, --table-attr=TEXT set HTML table tag attributes (e.g., width, border)\n"));
fprintf(output, _(" -x, --expanded turn on expanded table output\n"));
fprintf(output, _(" -z, --field-separator-zero\n"
" set field separator for unaligned output to zero byte\n"));
printf(_(" -0, --record-separator-zero\n"
fprintf(output, _(" -0, --record-separator-zero\n"
" set record separator for unaligned output to zero byte\n"));
printf(_("\nConnection options:\n"));
fprintf(output, _("\nConnection options:\n"));
/* Display default host */
env = getenv("PGHOST");
printf(_(" -h, --host=HOSTNAME database server host or socket directory (default: \"%s\")\n"),
fprintf(output, _(" -h, --host=HOSTNAME database server host or socket directory (default: \"%s\")\n"),
env ? env : _("local socket"));
/* Display default port */
env = getenv("PGPORT");
printf(_(" -p, --port=PORT database server port (default: \"%s\")\n"),
fprintf(output, _(" -p, --port=PORT database server port (default: \"%s\")\n"),
env ? env : DEF_PGPORT_STR);
/* Display default user */
env = getenv("PGUSER");
if (!env)
env = user;
printf(_(" -U, --username=USERNAME database user name (default: \"%s\")\n"), env);
printf(_(" -w, --no-password never prompt for password\n"));
printf(_(" -W, --password force password prompt (should happen automatically)\n"));
fprintf(output, _(" -U, --username=USERNAME database user name (default: \"%s\")\n"), env);
fprintf(output, _(" -w, --no-password never prompt for password\n"));
fprintf(output, _(" -W, --password force password prompt (should happen automatically)\n"));
printf(_("\nFor more information, type \"\\?\" (for internal commands) or \"\\help\" (for SQL\n"
fprintf(output, _("\nFor more information, type \"\\?\" (for internal commands) or \"\\help\" (for SQL\n"
"commands) from within psql, or consult the psql section in the PostgreSQL\n"
"documentation.\n\n"));
printf(_("Report bugs to <pgsql-bugs@postgresql.org>.\n"));
fprintf(output, _("Report bugs to <pgsql-bugs@postgresql.org>.\n"));
ClosePager(output);
}
@ -159,11 +166,18 @@ slashUsage(unsigned short int pager)
fprintf(output, _(" \\copyright show PostgreSQL usage and distribution terms\n"));
fprintf(output, _(" \\g [FILE] or ; execute query (and send results to file or |pipe)\n"));
fprintf(output, _(" \\gset [PREFIX] execute query and store results in psql variables\n"));
fprintf(output, _(" \\h [NAME] help on syntax of SQL commands, * for all commands\n"));
fprintf(output, _(" \\q quit psql\n"));
fprintf(output, _(" \\watch [SEC] execute query every SEC seconds\n"));
fprintf(output, "\n");
fprintf(output, _("Help\n"));
fprintf(output, _(" \\? [commands] description of all psql backslash commands\n"));
fprintf(output, _(" \\? options description of all psql commandline options\n"));
fprintf(output, _(" \\? variables description of all psql configuration variables\n"));
fprintf(output, _(" \\h [NAME] help on syntax of SQL commands, * for all commands\n"));
fprintf(output, "\n");
fprintf(output, _("Query Buffer\n"));
fprintf(output, _(" \\e [FILE] [LINE] edit the query buffer (or file) with external editor\n"));
fprintf(output, _(" \\ef [FUNCNAME [LINE]] edit function definition with external editor\n"));
@ -280,6 +294,106 @@ slashUsage(unsigned short int pager)
}
/*
* helpVariables
*
* show list of available variables (options) from command line
*/
void
helpVariables(unsigned short int pager)
{
FILE *output;
output = PageOutput(81, pager);
fprintf(output, _("List of specially treated variables.\n"));
fprintf(output, _("psql variables:\n"));
fprintf(output, _("Usage:\n"));
fprintf(output, _(" psql --set=NAME=VALUE\n or \\set NAME VALUE in interactive mode\n\n"));
fprintf(output, _(" AUTOCOMMIT if set, successful SQL commands are automatically committed\n"));
fprintf(output, _(" COMP_KEYWORD_CASE determine the case used to complete SQL keywords\n"
" [lower, upper, preserve-lower, preserve-upper]\n"));
fprintf(output, _(" DBNAME the currently connected database name\n"));
fprintf(output, _(" ECHO control what input is written to standard output\n"
" [all, errors, none, queries]\n"));
fprintf(output, _(" ECHO_HIDDEN display internal queries executed by backslash commands when it is set\n"
" or with [noexec] just show without execution\n"));
fprintf(output, _(" ENCODING current client character set encoding\n"));
fprintf(output, _(" FETCH_COUNT the number of result rows to fetch and display at a time\n"
" (default: 0=unlimited)\n"));
fprintf(output, _(" HISTCONTROL control history list [ignorespace, ignoredups, ignoreboth]\n"));
fprintf(output, _(" HISTFILE file name used to store the history list\n"));
fprintf(output, _(" HISTSIZE the number of commands to store in the command history\n"));
fprintf(output, _(" HOST the currently connected database server\n"));
fprintf(output, _(" IGNOREEOF if unset, sending an EOF to interactive session terminates application\n"));
fprintf(output, _(" LASTOID the value of last affected OID\n"));
fprintf(output, _(" ON_ERROR_ROLLBACK if set, an error doesn't stop a transaction (uses implicit SAVEPOINTs)\n"));
fprintf(output, _(" ON_ERROR_STOP stop batch execution after error\n"));
fprintf(output, _(" PORT server port of the current connection\n"));
fprintf(output, _(" PROMPT1 specify the standard psql prompt\n"));
fprintf(output, _(" PROMPT2 specify the prompt used when a statement continues from a previous line\n"));
fprintf(output, _(" PROMPT3 specify the prompt used during COPY ... FROM STDIN\n"));
fprintf(output, _(" QUIET run quietly (same as -q option)\n"));
fprintf(output, _(" SINGLELINE end of line terminates SQL command mode (same as -S option)\n"));
fprintf(output, _(" SINGLESTEP single-step mode (same as -s option)\n"));
fprintf(output, _(" USER the currently connected database user\n"));
fprintf(output, _(" VERBOSITY control verbosity of error reports [default, verbose, terse]\n"));
fprintf(output, _("\nDisplay influencing variables:\n"));
fprintf(output, _("Usage:\n"));
fprintf(output, _(" psql --pset=NAME[=VALUE]\n or \\pset NAME [VALUE] in interactive mode\n\n"));
fprintf(output, _(" border border style (number)\n"));
fprintf(output, _(" columns set the target width for the wrapped format\n"));
fprintf(output, _(" expanded (or x) toggle expanded output\n"));
fprintf(output, _(" fieldsep field separator for unaligned output (default '|')\n"));
fprintf(output, _(" fieldsep_zero set field separator in unaligned mode to zero\n"));
fprintf(output, _(" format set output format [unaligned, aligned, wrapped, html, latex, ..]\n"));
fprintf(output, _(" footer enable or disable display of the table footer [on, off]\n"));
fprintf(output, _(" linestyle set the border line drawing style [ascii, old-ascii, unicode]\n"));
fprintf(output, _(" null set the string to be printed in place of a null value\n"));
fprintf(output, _(" numericlocale enable or disable display of a locale-specific character to separate\n"
" groups of digits [on, off]\n"));
fprintf(output, _(" pager control when an external pager is used [yes, no, always]\n"));
fprintf(output, _(" recordsep specify the record (line) separator to use in unaligned output format\n"));
fprintf(output, _(" recordsep_zero set the record separator to use in unaligned output format to a zero byte.\n"));
fprintf(output, _(" tableattr (or T) specify attributes for table tag in html format or proportional\n"
" column width of left aligned data type in latex format\n"));
fprintf(output, _(" title set the table title for any subsequently printed tables\n"));
fprintf(output, _(" tuples_only if set, only actual table data is shown\n"));
fprintf(output, _("\nEnvironment variables:\n"));
fprintf(output, _("Usage:\n"));
#ifndef WIN32
fprintf(output, _(" NAME=VALUE [NAME=VALUE] psql ...\n or \\setenv NAME [VALUE] in interactive mode\n\n"));
#else
fprintf(output, _(" set NAME=VALUE\n psql ...\n or \\setenv NAME VALUE in interactive mode\n\n"));
#endif
fprintf(output, _(" COLUMNS number of columns for wrapped format\n"));
fprintf(output, _(" PAGER name of external pager program\n"));
fprintf(output, _(" PGAPPNAME same as the application_name connection parameter\n"));
fprintf(output, _(" PGDATABASE same as the dbname connection parameter\n"));
fprintf(output, _(" PGHOST same as the host connection parameter\n"));
fprintf(output, _(" PGPORT same as the port connection parameter\n"));
fprintf(output, _(" PGUSER same as the user connection parameter\n"));
fprintf(output, _(" PGPASSWORD connection password (not recommended)\n"));
fprintf(output, _(" PGPASSFILE password file name\n"));
fprintf(output, _(" PSQL_EDITOR, EDITOR, VISUAL\n"
" editor used by the \\e and \\ef commands\n"));
fprintf(output, _(" PSQL_EDITOR_LINENUMBER_ARG\n"
" how to specify a line number when invoking the editor\n"));
fprintf(output, _(" PSQL_HISTORY alternative location for the command history file\n"));
fprintf(output, _(" PSQLRC alternative location for the user's .psqlrc file\n"));
fprintf(output, _(" SHELL shell used by the \\! command\n"));
fprintf(output, _(" TMPDIR directory for temporary files\n"));
ClosePager(output);
}
/*
* helpSQL -- help with SQL commands

View File

@ -8,10 +8,12 @@
#ifndef HELP_H
#define HELP_H
void usage(void);
void usage(unsigned short int pager);
void slashUsage(unsigned short int pager);
void helpVariables(unsigned short int pager);
void helpSQL(const char *topic, unsigned short int pager);
void print_copyright(void);

View File

@ -77,6 +77,8 @@ static void process_psqlrc_file(char *filename);
static void showVersion(void);
static void EstablishVariableSpace(void);
#define NOPAGER 0
/*
*
* main
@ -95,9 +97,9 @@ main(int argc, char *argv[])
if (argc > 1)
{
if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
if ((strcmp(argv[1], "-?") == 0) || (argc == 2 && (strcmp(argv[1], "--help") == 0)))
{
usage();
usage(NOPAGER);
exit(EXIT_SUCCESS);
}
if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
@ -383,7 +385,7 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options)
{"password", no_argument, NULL, 'W'},
{"expanded", no_argument, NULL, 'x'},
{"no-psqlrc", no_argument, NULL, 'X'},
{"help", no_argument, NULL, '?'},
{"help", optional_argument, NULL, 1},
{NULL, 0, NULL, 0}
};
@ -557,20 +559,31 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options)
break;
case '?':
/* Actual help option given */
if (strcmp(argv[optind - 1], "--help") == 0 || strcmp(argv[optind - 1], "-?") == 0)
if (strcmp(argv[optind - 1], "-?") == 0)
{
usage();
usage(NOPAGER);
exit(EXIT_SUCCESS);
}
/* unknown option reported by getopt */
else
goto unknown_option;
break;
case 1:
{
fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
pset.progname);
exit(EXIT_FAILURE);
if (!optarg || strcmp(optarg, "options") == 0)
usage(NOPAGER);
else if (optarg && strcmp(optarg, "commands") == 0)
slashUsage(NOPAGER);
else if (optarg && strcmp(optarg, "variables") == 0)
helpVariables(NOPAGER);
else
goto unknown_option;
exit(EXIT_SUCCESS);
}
break;
default:
unknown_option:
fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
pset.progname);
exit(EXIT_FAILURE);

View File

@ -3543,6 +3543,13 @@ psql_completion(const char *text, int start, int end)
/* Backslash commands */
/* TODO: \dc \dd \dl */
else if (strcmp(prev_wd, "\\?") == 0)
{
static const char *const my_list[] =
{"commands", "options", "variables", NULL};
COMPLETE_WITH_LIST_CS(my_list);
}
else if (strcmp(prev_wd, "\\connect") == 0 || strcmp(prev_wd, "\\c") == 0)
COMPLETE_WITH_QUERY(Query_for_list_of_databases);