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
From 451b564fa8714ff4ba21725b183913d651b1c925 Mon Sep 17 00:00:00 2001
From: Craig Ringer <cr...@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

Reply via email to