Idea Feedback: psql \h misses -> Offers Links?

Started by Kirk Wolakover 1 year ago9 messages
#1Kirk Wolak
wolakk@gmail.com

Hackers,
I often use the ctrl-click on the link after getting help in psql. A
great feature.

Challenge, when there is no help, you don't get any link.

My thought process is to add a default response that would take them to
https://www.postgresql.org/search/?u=%2Fdocs%2F16%2F&q={TOKEN}
<https://www.postgresql.org/search/?u=%2Fdocs%2F16%2F&amp;q=%7BTOKEN%7D&gt;

*Example:*
\h current_setting
No help available for "current_setting".
Try \h with no arguments to see available help.

https://www.postgresql.org/search/?u=%2Fdocs%2F16%2F&amp;q=current_setting

To me, this is a huge step in helping me get to the docs.

This is Question 1: Do others see the potential value here?

Question 2: What if we allowed the users to set some extra link Templates
using \pset??

\pset help_assist_link_1 = https://www.google.com/search?q={token}&#39;
\pset help_assist_link_2 = '
https://wiki.postgresql.org/index.php?title=Special%3ASearch&amp;search={token}&amp;go=Go
<https://wiki.postgresql.org/index.php?title=Special%3ASearch&amp;search=%7Btoken%7D&amp;go=Go&gt;
'

Such that the output, this time would be:
*Example:*
\h current_setting
No help available for "current_setting".
Try \h with no arguments to see available help.

https://www.postgresql.org/search/?u=%2Fdocs%2F16%2F&amp;q=current_setting

https://www.google.com/search?q=current_setting
https://wiki.postgresql.org/index.php?title=Special%3ASearch&amp;search=current_setting&amp;go=Go

This Latter feature, I would consider applying to even successful searches?
[Based on Feedback here]

Thoughts?

#2Peter Eisentraut
peter@eisentraut.org
In reply to: Kirk Wolak (#1)
Re: Idea Feedback: psql \h misses -> Offers Links?

On 17.04.24 19:47, Kirk Wolak wrote:

*Example:*
\h current_setting
No help available for "current_setting".
Try \h with no arguments to see available help.

https://www.postgresql.org/search/?u=%2Fdocs%2F16%2F&amp;q=current_setting
<https://www.postgresql.org/search/?u=%2Fdocs%2F16%2F&amp;q=current_setting&gt;

One problem is that this search URL does not actually produce any useful
information about current_setting.

#3Kirk Wolak
wolakk@gmail.com
In reply to: Peter Eisentraut (#2)
Re: Idea Feedback: psql \h misses -> Offers Links?

On Thu, Apr 18, 2024 at 2:37 PM Peter Eisentraut <peter@eisentraut.org>
wrote:

On 17.04.24 19:47, Kirk Wolak wrote:

*Example:*
\h current_setting
No help available for "current_setting".
Try \h with no arguments to see available help.

https://www.postgresql.org/search/?u=%2Fdocs%2F16%2F&amp;q=current_setting
<https://www.postgresql.org/search/?u=%2Fdocs%2F16%2F&amp;q=current_setting&gt;

One problem is that this search URL does not actually produce any useful
information about current_setting.

I see what you mean, but doesn't that imply our web search feature is

weak? That's the full name of an existing function, and it's in the index.
But it cannot be found if searched from the website?

In reply to: Kirk Wolak (#3)
Re: Idea Feedback: psql \h misses -> Offers Links?

Kirk Wolak <wolakk@gmail.com> writes:

On Thu, Apr 18, 2024 at 2:37 PM Peter Eisentraut <peter@eisentraut.org>
wrote:

On 17.04.24 19:47, Kirk Wolak wrote:

*Example:*
\h current_setting
No help available for "current_setting".
Try \h with no arguments to see available help.

https://www.postgresql.org/search/?u=%2Fdocs%2F16%2F&amp;q=current_setting
<https://www.postgresql.org/search/?u=%2Fdocs%2F16%2F&amp;q=current_setting&gt;

One problem is that this search URL does not actually produce any useful
information about current_setting.

I see what you mean, but doesn't that imply our web search feature is
weak? That's the full name of an existing function, and it's in the index.
But it cannot be found if searched from the website?

While I do think we could do a better job of providing links directly to
the documentation of functions and config parameters, I wouldn't say
that the search result is _completely_ useless in this case. The first
hit is https://www.postgresql.org/docs/16/functions-admin.html, which is
where current_setting() is documented (it's even the first function on
that page, but that's just luck in this case).

- ilmari

#5Peter Eisentraut
peter@eisentraut.org
In reply to: Kirk Wolak (#3)
Re: Idea Feedback: psql \h misses -> Offers Links?

On 18.04.24 23:29, Kirk Wolak wrote:

On Thu, Apr 18, 2024 at 2:37 PM Peter Eisentraut <peter@eisentraut.org
<mailto:peter@eisentraut.org>> wrote:

On 17.04.24 19:47, Kirk Wolak wrote:

*Example:*
\h current_setting
No help available for "current_setting".
Try \h with no arguments to see available help.

https://www.postgresql.org/search/?u=%2Fdocs%2F16%2F&amp;q=current_setting <https://www.postgresql.org/search/?u=%2Fdocs%2F16%2F&amp;q=current_setting&gt;

<https://www.postgresql.org/search/?u=%2Fdocs%2F16%2F&amp;q=current_setting <https://www.postgresql.org/search/?u=%2Fdocs%2F16%2F&amp;q=current_setting&gt;&gt;

One problem is that this search URL does not actually produce any
useful
information about current_setting.

I see what you mean, but doesn't that imply our web search feature is
weak?  That's the full name of an existing function, and it's in the
index. But it cannot be found if searched from the website?

Maybe it's weak, or maybe we are using it wrong, I don't know.

\h has always been (a) local help, and (b) help specifically about SQL
commands. If we are going to vastly expand the scope, we need to think
it through more thoroughly. I could see some kind of \onlinehelp
command, or maybe even redesigning \h altogether.

Also, as you say, the function is in the documentation index, so there
should be a deterministic way to go directly to exactly the target
destination. Maybe the full-text search functionality of the web site
is the wrong interface for that.

#6Euler Taveira
euler@eulerto.com
In reply to: Kirk Wolak (#1)
Re: Idea Feedback: psql \h misses -> Offers Links?

On Wed, Apr 17, 2024, at 2:47 PM, Kirk Wolak wrote:

I often use the ctrl-click on the link after getting help in psql. A great feature.

Challenge, when there is no help, you don't get any link.

My thought process is to add a default response that would take them to
https://www.postgresql.org/search/?u=%2Fdocs%2F16%2F&amp;q={TOKEN} <https://www.postgresql.org/search/?u=%2Fdocs%2F16%2F&amp;q=%7BTOKEN%7D&gt;

*Example:*
\h current_setting
No help available for "current_setting".
Try \h with no arguments to see available help.

That's because current_setting is a function. Help says:

postgres=# \?
.
.
.
Help
\? [commands] show help on backslash commands
\? options show help on psql command-line options
\? variables show help on special variables
\h [NAME] help on syntax of SQL commands, * for all commands

It is just for SQL commands.

https://www.postgresql.org/search/?u=%2Fdocs%2F16%2F&amp;q=current_setting

To me, this is a huge step in helping me get to the docs.

This is Question 1: Do others see the potential value here?

Yes. However, I expect an exact and direct answer. There will be cases that the
first result is not the one you are looking for. (You are expecting the
function or parameter description but other page is on the top because it is
more relevant.) The referred URL does not point you to the direct link.
Instead, you have to click again to be able to check the content.

Question 2: What if we allowed the users to set some extra link Templates using \pset??

\pset help_assist_link_1 = https://www.google.com/search?q={token} <https://www.google.com/search?q=%7Btoken%7D&gt;&#39;
\pset help_assist_link_2 = 'https://wiki.postgresql.org/index.php?title=Special%3ASearch&amp;search={token}&amp;go=Go <https://wiki.postgresql.org/index.php?title=Special%3ASearch&amp;search=%7Btoken%7D&amp;go=Go&gt;&#39;

That's a different idea. Are you proposing to provide URLs if this psql
variable is set and it doesn't find an entry (say \h foo)? I'm not sure if it
is a good idea to allow third-party URLs (even if it is configurable).

IMO we should expand \h to list documentation references for functions and GUCs
using SGML files. We already did it for SQL commands. Another broader idea is
to build an inverted index similar to what Index [1]https://www.postgresql.org/docs/current/bookindex.html provides. The main problem
with this approach is to create a dependency between documentation build and
psql. Maybe there is a reasonable way to obtain the links for each term.

[1]: https://www.postgresql.org/docs/current/bookindex.html

--
Euler Taveira
EDB https://www.enterprisedb.com/

#7Andrey M. Borodin
x4mmm@yandex-team.ru
In reply to: Kirk Wolak (#1)
1 attachment(s)
Re: Idea Feedback: psql \h misses -> Offers Links?

On 17 Apr 2024, at 22:47, Kirk Wolak <wolakk@gmail.com> wrote:

Thoughts?

Today we had a hacking session with Nik and Kirk. We produced a patch to assess how these links might look like.

Also we needed a url_encode() and found none in a codebase. It would be nice to have this as an SQL-callable function.

Thanks!

Best regards, Andrey Borodin.

Attachments:

v1-0001-Add-URLs-to-h-in-psql-when-there-is-no-match.patchapplication/octet-stream; name=v1-0001-Add-URLs-to-h-in-psql-when-there-is-no-match.patch; x-unix-mode=0644Download
From 199b87deb39c393562d96dec56c565e25ae76edc Mon Sep 17 00:00:00 2001
From: "Andrey M. Borodin" <x4mmm@night.Dlink>
Date: Thu, 2 May 2024 22:28:15 +0500
Subject: [PATCH v1] Add URLs to \h in psql when there is no match

---
 src/bin/psql/help.c     | 44 ++++++++++++++++++++++++++++++++++++++++-
 src/bin/psql/settings.h |  3 +++
 src/bin/psql/startup.c  | 11 +++++++++++
 3 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c
index 4e79a819d8..703597289e 100644
--- a/src/bin/psql/help.c
+++ b/src/bin/psql/help.c
@@ -422,6 +422,8 @@ helpVariables(unsigned short int pager)
 		  "    specifies the prompt used when a statement continues from a previous line\n");
 	HELP0("  PROMPT3\n"
 		  "    specifies the prompt used during COPY ... FROM STDIN\n");
+	HELP0("  HELP_URLS\n"
+		  "    specifies |-separated array of URLs with \%s\n");
 	HELP0("  QUIET\n"
 		  "    run quietly (same as -q option)\n");
 	HELP0("  ROW_COUNT\n"
@@ -558,6 +560,30 @@ helpVariables(unsigned short int pager)
 }
 
 
+static char *url_encode(const char *input) {
+	/* Allocate enough space for the encoded string */
+	char *output = calloc(strlen(input) * 3 + 1, sizeof(char));
+	int output_pos = 0;
+
+	for (int i = 0; input[i]; i++) {
+		unsigned char c = input[i];
+		if (c == ' ') {
+			output[output_pos++] = '%';
+			output[output_pos++] = '2';
+			output[output_pos++] = '0';
+		} else if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '-' || c == '_' || c == '.' || c == '~') {
+			output[output_pos++] = c;
+		} else {
+			output[output_pos++] = '%';
+			output[output_pos++] = "0123456789ABCDEF"[c >> 4];
+			output[output_pos++] = "0123456789ABCDEF"[c & 0xF];
+		}
+	}
+
+	return output;
+}
+
+
 /*
  * helpSQL -- help with SQL commands
  *
@@ -713,10 +739,26 @@ helpSQL(const char *topic, unsigned short int pager)
 		/* If we never found anything, report that */
 		if (!output)
 		{
+			char* urls;
+			char* url;
+			char* encoded_topic;
 			output = PageOutput(2, pager ? &(pset.popt.topt) : NULL);
 			fprintf(output, _("No help available for \"%s\".\n"
-							  "Try \\h with no arguments to see available help.\n"),
+							  "Try \\h with no arguments to see available help or search online:\n"),
 					topic);
+			/* TODO: URL encode topic*/
+			encoded_topic = url_encode(topic);
+			urls = pstrdup(pset.help_urls);
+			url = strtok(urls,"|");
+			while (url != NULL)
+			{
+				fprintf(output, "\nURL: ");
+				fprintf(output, url, encoded_topic);
+				fprintf(output, "\n");
+				url = strtok(NULL, "|");
+			}
+			fprintf(output, "\n");
+			free(encoded_topic);
 		}
 
 		ClosePager(output);
diff --git a/src/bin/psql/settings.h b/src/bin/psql/settings.h
index 505f99d8e4..0be1300738 100644
--- a/src/bin/psql/settings.h
+++ b/src/bin/psql/settings.h
@@ -27,6 +27,8 @@
 #define DEFAULT_PROMPT2 "%/%R%x%# "
 #define DEFAULT_PROMPT3 ">> "
 
+#define DEFAULT_HELP_URLS "https://www.postgresql.org/search/?q=%s"
+
 /*
  * Note: these enums should generally be chosen so that zero corresponds
  * to the default behavior.
@@ -151,6 +153,7 @@ typedef struct _psqlSettings
 	const char *prompt1;
 	const char *prompt2;
 	const char *prompt3;
+	const char *help_urls;
 	PGVerbosity verbosity;		/* current error verbosity level */
 	bool		show_all_results;
 	PGContextVisibility show_context;	/* current context display level */
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index 036caaec2f..824297fd57 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -203,6 +203,7 @@ main(int argc, char *argv[])
 	SetVariable(pset.vars, "PROMPT1", DEFAULT_PROMPT1);
 	SetVariable(pset.vars, "PROMPT2", DEFAULT_PROMPT2);
 	SetVariable(pset.vars, "PROMPT3", DEFAULT_PROMPT3);
+	SetVariable(pset.vars, "HELP_URLS", DEFAULT_HELP_URLS);
 	SetVariableBool(pset.vars, "SHOW_ALL_RESULTS");
 
 	parse_psql_options(argc, argv, &options);
@@ -1115,6 +1116,13 @@ prompt3_hook(const char *newval)
 	return true;
 }
 
+static bool
+help_urls_hook(const char *newval)
+{
+	pset.help_urls = newval ? newval : "";
+	return true;
+}
+
 static char *
 verbosity_substitute_hook(char *newval)
 {
@@ -1250,6 +1258,9 @@ EstablishVariableSpace(void)
 	SetVariableHooks(pset.vars, "PROMPT3",
 					 NULL,
 					 prompt3_hook);
+	SetVariableHooks(pset.vars, "HELP_URLS",
+					 NULL,
+					 help_urls_hook);
 	SetVariableHooks(pset.vars, "VERBOSITY",
 					 verbosity_substitute_hook,
 					 verbosity_hook);
-- 
2.37.1 (Apple Git-137.1)

#8Pavel Stehule
pavel.stehule@gmail.com
In reply to: Andrey M. Borodin (#7)
Re: Idea Feedback: psql \h misses -> Offers Links?

čt 2. 5. 2024 v 19:50 odesílatel Andrey M. Borodin <x4mmm@yandex-team.ru>
napsal:

On 17 Apr 2024, at 22:47, Kirk Wolak <wolakk@gmail.com> wrote:

Thoughts?

Today we had a hacking session with Nik and Kirk. We produced a patch to
assess how these links might look like.

Also we needed a url_encode() and found none in a codebase. It would be
nice to have this as an SQL-callable function.

+1

it was requested more times

Pavel

Show quoted text

Thanks!

Best regards, Andrey Borodin.

#9Kirk Wolak
wolakk@gmail.com
In reply to: Euler Taveira (#6)
Re: Idea Feedback: psql \h misses -> Offers Links?

On Fri, Apr 19, 2024 at 10:14 AM Euler Taveira <euler@eulerto.com> wrote:

On Wed, Apr 17, 2024, at 2:47 PM, Kirk Wolak wrote:

...

This is Question 1: Do others see the potential value here?

Yes. However, I expect an exact and direct answer. There will be cases
that the
first result is not the one you are looking for. (You are expecting the
function or parameter description but other page is on the top because it
is
more relevant.) The referred URL does not point you to the direct link.
Instead, you have to click again to be able to check the content.

Again, this does get to the point that the current search feature at
postgresql.org could be better. I would like to see that improved as
well...

Question 2: What if we allowed the users to set some extra link Templates
using \pset??

\pset help_assist_link_1 = https://www.google.com/search?q={token}&#39;
\pset help_assist_link_2 = '
https://wiki.postgresql.org/index.php?title=Special%3ASearch&amp;search={token}&amp;go=Go
<https://wiki.postgresql.org/index.php?title=Special%3ASearch&amp;search=%7Btoken%7D&amp;go=Go&gt;
'

That's a different idea. Are you proposing to provide URLs if this psql
variable is set and it doesn't find an entry (say \h foo)? I'm not sure if
it
is a good idea to allow third-party URLs (even if it is configurable).

If you want to check the patch Andrey published. We basically set the
default value to the set variable, and then allowed the user to override
that value with multiple pipe (|) separated URLs. It does BEG the question
if this is cool for hackers. Personally, I like the option as there are
probably a few resources worth checking against. But if someone doesn't
change the default, they get a good enough answer.

IMO we should expand \h to list documentation references for functions and
GUCs
using SGML files. We already did it for SQL commands. Another broader idea
is
to build an inverted index similar to what Index [1] provides. The main
problem
with this approach is to create a dependency between documentation build
and
psql. Maybe there is a reasonable way to obtain the links for each term.

[1] https://www.postgresql.org/docs/current/bookindex.html

I don't want to add more dependencies into psql to the documentation for a
ton of stuff. To me, if we had a better search page on the website for
finding things, it would be great. I have been resigned to just googling
"postgresql <topic>" because google does a better job searching
postgresql.org than the postgresql.org site does (even when it is a known
indexed item like a function name).

Thanks for the feedback.