[PATCH] print help from psql when user tries to run pg_restore, pg_dump etc

Started by Craig Ringerabout 6 years ago2 messages
#1Craig Ringer
craig@2ndquadrant.com
1 attachment(s)

New users frequently attempt to run PostgreSQL's command line utilities
from the psql prompt.

They tend to be confused when this appears to do absolutely nothing:

psql=> pg_restore
psql->

since they're generally not going to semicolon-terminate the command either.

The attached patch detects common command names when they appear first on a
new input line prints a help message. If the buffer is empty a more
detailed message is printed and the input is swallowed. Otherwise, much
like how we handle "help" etc,
a short message is printed and the input is still added to the buffer.

psql=> pg_restore
"pg_restore" is a command line utility program.
Use it from the system terminal or command prompt not from psql.
psql=>
psql=> select 1
psql-> pg_restore
"pg_restore" is a command-line utility program not a psql command. See
"help".
psql->

Wording advice would be welcome.

I'd be tempted to backpatch this, since it's one of the things I see users
confused by most often now - right up there with pg_hba.conf issues,
forgetting a semicolon in psql, etc.

--
Craig Ringer http://www.2ndQuadrant.com/
2ndQuadrant - PostgreSQL Solutions for the Enterprise

Attachments:

0001-print-help-in-psql-when-users-try-to-run-pg_dump-etc.patchtext/x-patch; charset=US-ASCII; name=0001-print-help-in-psql-when-users-try-to-run-pg_dump-etc.patchDownload
From 451b564fa8714ff4ba21725b183913d651b1c925 Mon Sep 17 00:00:00 2001
From: Craig Ringer <craig@2ndquadrant.com>
Date: Fri, 6 Dec 2019 12:50:58 +0800
Subject: [PATCH] print help in psql when users try to run pg_dump etc

New users frequently attempt to run PostgreSQL's command line utilities
from the psql prompt. Detect this and emit a useful help message:

    psql=> pg_restore
    "pg_restore" is a command line utility program.
    Use it from the system terminal or command prompt not from psql.
    psql=>

Previously we'd just add the command to the buffer - and since the user
wouldn't generally follow it with a semicolon they'd see no response except a
prompt change:

    psql=> pg_restore
    psql->
---
 src/bin/psql/mainloop.c | 48 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/src/bin/psql/mainloop.c b/src/bin/psql/mainloop.c
index f7b1b94599..2c65b7a862 100644
--- a/src/bin/psql/mainloop.c
+++ b/src/bin/psql/mainloop.c
@@ -353,6 +353,54 @@ MainLoop(FILE *source)
 #else
 				puts(_("Use control-C to quit."));
 #endif
+
+			/*
+			 * New users tend to be confused about the command line utilities
+			 * pg_dump, pg_restore, createdb, etc, and try to run them
+			 * interatively in psql. Detect this and emit a suitable hint.
+			 *
+			 * We check for them even when the buffer is non-empty because
+			 * users frequently try multiple commands without semicolons when
+			 * trying to misuse psql as a command-line shell. Like with "help"
+			 * etc, the text is still added to the buffer unless it's the
+			 * first word on an empty buffer.
+			 */
+			if (line[0] == 'p' || line[0] == 'c' || line[0] == 'd')
+			{
+				if (strncmp(line, "pg_restore", sizeof("pg_restore")) == 0
+					|| strncmp(line, "pg_dump", sizeof("pg_dump")) == 0
+					|| strncmp(line, "createdb", sizeof("createdb")) == 0
+					|| strncmp(line, "dropdb", sizeof("dropdb")) == 0
+					|| strncmp(line, "createuser", sizeof("createuser")) == 0
+					|| strncmp(line, "dropuser", sizeof("dropuser")) == 0)
+				{
+					char		cmdname[12];
+
+					strlcpy(&cmdname[0], line,
+							Min(strcspn(line, " \r\n") + 1, sizeof(cmdname)));
+					if (query_buf->len != 0)
+					{
+						/*
+						 * Print a short hint but don't swallow the input if
+						 * there's already something in the buffer.
+						 */
+						printf(_("\"%s\" is a command-line utility program "
+								 "not a psql command.\n"),
+							   cmdname);
+					}
+					else
+					{
+						/* Swallow the input and emit more help */
+						printf(_("\"%s\" is a command line utility program.\n"
+								 "Use it from the system terminal or command "
+								 "prompt not from psql.\n"),
+							   cmdname);
+						free(line);
+						fflush(stdout);
+						continue;
+					}
+				}
+			}
 		}
 
 		/* echo back if flag is set, unless interactive */
-- 
2.23.0

#2Fabien COELHO
coelho@cri.ensmp.fr
In reply to: Craig Ringer (#1)
Re: [PATCH] print help from psql when user tries to run pg_restore, pg_dump etc

Hello Craig,

New users frequently attempt to run PostgreSQL's command line utilities
from the psql prompt.

Alas, that is true.

I also have the reverse, i.e. SQL commands fed to bash, which does not
like it much.

They tend to be confused when this appears to do absolutely nothing:

psql=> pg_restore
psql->

since they're generally not going to semicolon-terminate the command either.

The attached patch detects common command names when they appear first on a
new input line prints a help message. If the buffer is empty a more
detailed message is printed and the input is swallowed. Otherwise, much
like how we handle "help" etc,
a short message is printed and the input is still added to the buffer.

psql=> pg_restore
"pg_restore" is a command line utility program.
Use it from the system terminal or command prompt not from psql.

… prompt, not from psql. (added comma?)

psql=>
psql=> select 1
psql-> pg_restore
"pg_restore" is a command-line utility program not a psql command. See
"help".
psql->

Wording advice would be welcome.

I'd be tempted to backpatch this, since it's one of the things I see users
confused by most often now - right up there with pg_hba.conf issues,
forgetting a semicolon in psql, etc.

I doubt that backpathing is reasonable.

Are we that sure that there is no legitimate reason to enter such lines on
psql, eg:

psql=> SELECT '
psql'> pg_whatever ...'
psql-> ...

Although I can confirm that the problem exists, I'm unsure about whether
psql should fix it. What are the opinions around?

--
Fabien.